From 35c340779af55f6b8d501de79988b0345b311c70 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 3 Dec 2019 15:38:29 +0100 Subject: [PATCH 0001/1616] worktree: mimic 'git worktree add' behavior. When adding a worktree using 'git worktree add ', if a reference named 'refs/heads/$(basename )' already exist, it is checkouted in the worktree. Mimic this behavior in libgit2. Signed-off-by: Gregory Herrero --- src/worktree.c | 26 +++++++++++++++++----- tests/worktree/worktree.c | 47 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/worktree.c b/src/worktree.c index ef4ebfda83c..c5edcb86bf2 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -278,7 +278,8 @@ int git_worktree_add(git_worktree **out, git_repository *repo, const char *name, const char *worktree, const git_worktree_add_options *opts) { - git_buf gitdir = GIT_BUF_INIT, wddir = GIT_BUF_INIT, buf = GIT_BUF_INIT; + git_buf gitdir = GIT_BUF_INIT, wddir = GIT_BUF_INIT; + git_buf buf = GIT_BUF_INIT, ref_buf = GIT_BUF_INIT; git_reference *ref = NULL, *head = NULL; git_commit *commit = NULL; git_repository *wt = NULL; @@ -365,12 +366,24 @@ int git_worktree_add(git_worktree **out, git_repository *repo, if ((err = git_reference_dup(&ref, wtopts.ref)) < 0) goto out; } else { - if ((err = git_repository_head(&head, repo)) < 0) - goto out; - if ((err = git_commit_lookup(&commit, repo, &head->target.oid)) < 0) - goto out; - if ((err = git_branch_create(&ref, repo, name, commit, false)) < 0) + if ((err = git_buf_printf(&ref_buf, "refs/heads/%s", name)) < 0) goto out; + if (!git_reference_lookup(&ref, repo, ref_buf.ptr)) { + if (git_branch_is_checked_out(ref)) { + git_error_set(GIT_ERROR_WORKTREE, + "reference %s is already checked out", + ref_buf.ptr); + err = -1; + goto out; + } + } else { + if ((err = git_repository_head(&head, repo)) < 0) + goto out; + if ((err = git_commit_lookup(&commit, repo, &head->target.oid)) < 0) + goto out; + if ((err = git_branch_create(&ref, repo, name, commit, false)) < 0) + goto out; + } } /* Set worktree's HEAD */ @@ -392,6 +405,7 @@ int git_worktree_add(git_worktree **out, git_repository *repo, git_buf_dispose(&gitdir); git_buf_dispose(&wddir); git_buf_dispose(&buf); + git_buf_dispose(&ref_buf); git_reference_free(ref); git_reference_free(head); git_commit_free(commit); diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index 5e99dbf616b..9ef08320163 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -216,6 +216,46 @@ void test_worktree_worktree__init(void) git_repository_free(repo); } +void test_worktree_worktree__add_remove_add(void) +{ + git_worktree *wt; + git_repository *repo; + git_reference *branch; + git_buf path = GIT_BUF_INIT; + + git_worktree_prune_options opts = GIT_WORKTREE_PRUNE_OPTIONS_INIT; + + /* Add the worktree */ + cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-add-remove-add")); + cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-add-remove-add", path.ptr, NULL)); + + /* Open and verify created repo */ + cl_git_pass(git_repository_open(&repo, path.ptr)); + cl_assert(git__suffixcmp(git_repository_workdir(repo), "worktree-add-remove-add/") == 0); + cl_git_pass(git_branch_lookup(&branch, repo, "worktree-add-remove-add", GIT_BRANCH_LOCAL)); + git_repository_free(repo); + + /* Prune the worktree */ + opts.flags = GIT_WORKTREE_PRUNE_VALID|GIT_WORKTREE_PRUNE_WORKING_TREE; + cl_git_pass(git_worktree_prune(wt, &opts)); + cl_assert(!git_path_exists(wt->gitdir_path)); + cl_assert(!git_path_exists(wt->gitlink_path)); + git_worktree_free(wt); + + /* Add the worktree back */ + cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-add-remove-add", path.ptr, NULL)); + + /* Open and verify created repo */ + cl_git_pass(git_repository_open(&repo, path.ptr)); + cl_assert(git__suffixcmp(git_repository_workdir(repo), "worktree-add-remove-add/") == 0); + cl_git_pass(git_branch_lookup(&branch, repo, "worktree-add-remove-add", GIT_BRANCH_LOCAL)); + + git_buf_dispose(&path); + git_worktree_free(wt); + git_reference_free(branch); + git_repository_free(repo); +} + void test_worktree_worktree__add_locked(void) { git_worktree *wt; @@ -250,12 +290,13 @@ void test_worktree_worktree__init_existing_branch(void) cl_git_pass(git_repository_head(&head, fixture.repo)); cl_git_pass(git_commit_lookup(&commit, fixture.repo, &head->target.oid)); - cl_git_pass(git_branch_create(&branch, fixture.repo, "worktree-new", commit, false)); + cl_git_pass(git_branch_create(&branch, fixture.repo, "worktree-new-exist", commit, false)); - cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-new")); - cl_git_fail(git_worktree_add(&wt, fixture.repo, "worktree-new", path.ptr, NULL)); + cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-new-exist")); + cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-new-exist", path.ptr, NULL)); git_buf_dispose(&path); + git_worktree_free(wt); git_commit_free(commit); git_reference_free(head); git_reference_free(branch); From ea5028ab68584268ba9055e76eb99e5e2e6cac8e Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 24 Jan 2020 12:46:59 +0100 Subject: [PATCH 0002/1616] worktree: add flag to allow re-using existing branches for new worktrees In this commit's parent, we have introduced logic that will automatically re-use of existing branches if the new worktree name matches the branch name. While this is a handy feature, it changes behaviour in a backwards-incompatible way and might thus surprise users. Furthermore, it's impossible to tell whether we have created the worktree with a new or an existing reference. To fix this, introduce a new option `checkout_existing` that toggles this behaviour. Only if the flag is set will we now allow re-use of existing branches, while it's set to "off" by default. --- include/git2/worktree.h | 9 ++++---- src/worktree.c | 47 +++++++++++++-------------------------- tests/worktree/worktree.c | 32 +++++++++++++++++--------- 3 files changed, 41 insertions(+), 47 deletions(-) diff --git a/include/git2/worktree.h b/include/git2/worktree.h index 049511da121..3f1acbdb0ff 100644 --- a/include/git2/worktree.h +++ b/include/git2/worktree.h @@ -84,12 +84,13 @@ GIT_EXTERN(int) git_worktree_validate(const git_worktree *wt); typedef struct git_worktree_add_options { unsigned int version; - int lock; /**< lock newly created worktree */ - git_reference *ref; /**< reference to use for the new worktree HEAD */ + int lock; /**< lock newly created worktree */ + int checkout_existing; /**< allow checkout of existing branch matching worktree name */ + git_reference *ref; /**< reference to use for the new worktree HEAD */ } git_worktree_add_options; -#define GIT_WORKTREE_ADD_OPTIONS_VERSION 1 -#define GIT_WORKTREE_ADD_OPTIONS_INIT {GIT_WORKTREE_ADD_OPTIONS_VERSION,0,NULL} +#define GIT_WORKTREE_ADD_OPTIONS_VERSION 2 +#define GIT_WORKTREE_ADD_OPTIONS_INIT {GIT_WORKTREE_ADD_OPTIONS_VERSION,0,0,NULL} /** * Initialize git_worktree_add_options structure diff --git a/src/worktree.c b/src/worktree.c index c5edcb86bf2..5e4255b91e9 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -278,8 +278,7 @@ int git_worktree_add(git_worktree **out, git_repository *repo, const char *name, const char *worktree, const git_worktree_add_options *opts) { - git_buf gitdir = GIT_BUF_INIT, wddir = GIT_BUF_INIT; - git_buf buf = GIT_BUF_INIT, ref_buf = GIT_BUF_INIT; + git_buf gitdir = GIT_BUF_INIT, wddir = GIT_BUF_INIT, buf = GIT_BUF_INIT; git_reference *ref = NULL, *head = NULL; git_commit *commit = NULL; git_repository *wt = NULL; @@ -304,11 +303,21 @@ int git_worktree_add(git_worktree **out, git_repository *repo, goto out; } - if (git_branch_is_checked_out(wtopts.ref)) { - git_error_set(GIT_ERROR_WORKTREE, "reference is already checked out"); - err = -1; + if ((err = git_reference_dup(&ref, wtopts.ref)) < 0) goto out; - } + } else if (wtopts.checkout_existing && git_branch_lookup(&ref, repo, name, GIT_BRANCH_LOCAL) == 0) { + /* Do nothing */ + } else if ((err = git_repository_head(&head, repo)) < 0 || + (err = git_commit_lookup(&commit, repo, &head->target.oid)) < 0 || + (err = git_branch_create(&ref, repo, name, commit, false)) < 0) { + goto out; + } + + if (git_branch_is_checked_out(ref)) { + git_error_set(GIT_ERROR_WORKTREE, "reference %s is already checked out", + git_reference_name(ref)); + err = -1; + goto out; } /* Create gitdir directory ".git/worktrees/" */ @@ -361,31 +370,6 @@ int git_worktree_add(git_worktree **out, git_repository *repo, || (err = write_wtfile(gitdir.ptr, "gitdir", &buf)) < 0) goto out; - /* Set up worktree reference */ - if (wtopts.ref) { - if ((err = git_reference_dup(&ref, wtopts.ref)) < 0) - goto out; - } else { - if ((err = git_buf_printf(&ref_buf, "refs/heads/%s", name)) < 0) - goto out; - if (!git_reference_lookup(&ref, repo, ref_buf.ptr)) { - if (git_branch_is_checked_out(ref)) { - git_error_set(GIT_ERROR_WORKTREE, - "reference %s is already checked out", - ref_buf.ptr); - err = -1; - goto out; - } - } else { - if ((err = git_repository_head(&head, repo)) < 0) - goto out; - if ((err = git_commit_lookup(&commit, repo, &head->target.oid)) < 0) - goto out; - if ((err = git_branch_create(&ref, repo, name, commit, false)) < 0) - goto out; - } - } - /* Set worktree's HEAD */ if ((err = git_repository_create_head(gitdir.ptr, git_reference_name(ref))) < 0) goto out; @@ -405,7 +389,6 @@ int git_worktree_add(git_worktree **out, git_repository *repo, git_buf_dispose(&gitdir); git_buf_dispose(&wddir); git_buf_dispose(&buf); - git_buf_dispose(&ref_buf); git_reference_free(ref); git_reference_free(head); git_commit_free(commit); diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index 9ef08320163..6a709476a1b 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -218,12 +218,12 @@ void test_worktree_worktree__init(void) void test_worktree_worktree__add_remove_add(void) { - git_worktree *wt; - git_repository *repo; - git_reference *branch; - git_buf path = GIT_BUF_INIT; - + git_worktree_add_options add_opts = GIT_WORKTREE_ADD_OPTIONS_INIT; git_worktree_prune_options opts = GIT_WORKTREE_PRUNE_OPTIONS_INIT; + git_buf path = GIT_BUF_INIT; + git_reference *branch; + git_repository *repo; + git_worktree *wt; /* Add the worktree */ cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-add-remove-add")); @@ -233,6 +233,7 @@ void test_worktree_worktree__add_remove_add(void) cl_git_pass(git_repository_open(&repo, path.ptr)); cl_assert(git__suffixcmp(git_repository_workdir(repo), "worktree-add-remove-add/") == 0); cl_git_pass(git_branch_lookup(&branch, repo, "worktree-add-remove-add", GIT_BRANCH_LOCAL)); + git_reference_free(branch); git_repository_free(repo); /* Prune the worktree */ @@ -242,18 +243,21 @@ void test_worktree_worktree__add_remove_add(void) cl_assert(!git_path_exists(wt->gitlink_path)); git_worktree_free(wt); - /* Add the worktree back */ - cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-add-remove-add", path.ptr, NULL)); + /* Add the worktree back with default options should fail. */ + cl_git_fail(git_worktree_add(&wt, fixture.repo, "worktree-add-remove-add", path.ptr, &add_opts)); + /* If allowing checkout of existing branches, it should succeed. */ + add_opts.checkout_existing = 1; + cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-add-remove-add", path.ptr, &add_opts)); /* Open and verify created repo */ cl_git_pass(git_repository_open(&repo, path.ptr)); cl_assert(git__suffixcmp(git_repository_workdir(repo), "worktree-add-remove-add/") == 0); cl_git_pass(git_branch_lookup(&branch, repo, "worktree-add-remove-add", GIT_BRANCH_LOCAL)); + git_reference_free(branch); + git_repository_free(repo); git_buf_dispose(&path); git_worktree_free(wt); - git_reference_free(branch); - git_repository_free(repo); } void test_worktree_worktree__add_locked(void) @@ -283,6 +287,7 @@ void test_worktree_worktree__add_locked(void) void test_worktree_worktree__init_existing_branch(void) { + git_worktree_add_options opts = GIT_WORKTREE_ADD_OPTIONS_INIT; git_reference *head, *branch; git_commit *commit; git_worktree *wt; @@ -293,7 +298,12 @@ void test_worktree_worktree__init_existing_branch(void) cl_git_pass(git_branch_create(&branch, fixture.repo, "worktree-new-exist", commit, false)); cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-new-exist")); - cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-new-exist", path.ptr, NULL)); + + /* Add the worktree back with default options should fail. */ + cl_git_fail(git_worktree_add(&wt, fixture.repo, "worktree-new-exist", path.ptr, NULL)); + /* If allowing checkout of existing branches, it should succeed. */ + opts.checkout_existing = 1; + cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-new-exist", path.ptr, &opts)); git_buf_dispose(&path); git_worktree_free(wt); @@ -421,7 +431,7 @@ void test_worktree_worktree__name(void) cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_assert_equal_s(git_worktree_name(wt), "testrepo-worktree"); - + git_worktree_free(wt); } From 5b2cd75587826148c2c2d189371fe49847f06ec9 Mon Sep 17 00:00:00 2001 From: Ian Hattendorf Date: Mon, 3 Feb 2020 16:24:02 -0700 Subject: [PATCH 0003/1616] winhttp: support optional client cert --- src/transports/winhttp.c | 78 ++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index ee8cb154355..9d3f05d0b93 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -864,42 +864,68 @@ static int do_send_request(winhttp_stream *s, size_t len, bool chunked) static int send_request(winhttp_stream *s, size_t len, bool chunked) { - int request_failed = 0, cert_valid = 1, error = 0; - DWORD ignore_flags; + int request_failed = 1, cert_valid, client_cert_requested, error, attempts = 0; + DWORD ignore_flags, send_request_error; git_error_clear(); - if ((error = do_send_request(s, len, chunked)) < 0) { - if (GetLastError() != ERROR_WINHTTP_SECURE_FAILURE) { - git_error_set(GIT_ERROR_OS, "failed to send request"); - return -1; - } - request_failed = 1; - cert_valid = 0; - } + while (request_failed && attempts++ < 3) { + request_failed = 0; + cert_valid = 1; + client_cert_requested = 0; + if ((error = do_send_request(s, len, chunked)) < 0) { + send_request_error = GetLastError(); + request_failed = 1; + switch (send_request_error) { + case ERROR_WINHTTP_SECURE_FAILURE: { + cert_valid = 0; + break; + } + case ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED: { + client_cert_requested = 1; + break; + } + default: { + git_error_set(GIT_ERROR_OS, "failed to send request"); + return -1; + } + } + } - git_error_clear(); - if ((error = certificate_check(s, cert_valid)) < 0) { - if (!git_error_last()) - git_error_set(GIT_ERROR_OS, "user cancelled certificate check"); + if (!request_failed || send_request_error == ERROR_WINHTTP_SECURE_FAILURE) { + git_error_clear(); + if ((error = certificate_check(s, cert_valid)) < 0) { + if (!git_error_last()) + git_error_set(GIT_ERROR_OS, "user cancelled certificate check"); - return error; - } + return error; + } + } - /* if neither the request nor the certificate check returned errors, we're done */ - if (!request_failed) - return 0; + /* if neither the request nor the certificate check returned errors, we're done */ + if (!request_failed) + return 0; - ignore_flags = no_check_cert_flags; + if (!cert_valid) { + ignore_flags = no_check_cert_flags; + if (!WinHttpSetOption(s->request, WINHTTP_OPTION_SECURITY_FLAGS, &ignore_flags, sizeof(ignore_flags))) { + git_error_set(GIT_ERROR_OS, "failed to set security options"); + return -1; + } + } - if (!WinHttpSetOption(s->request, WINHTTP_OPTION_SECURITY_FLAGS, &ignore_flags, sizeof(ignore_flags))) { - git_error_set(GIT_ERROR_OS, "failed to set security options"); - return -1; + if (client_cert_requested) { + /* + * Client certificates are not supported, explicitly tell the server that + * (it's possible a client certificate was requested but is not required) + */ + if (!WinHttpSetOption(s->request, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0)) { + git_error_set(GIT_ERROR_OS, "failed to set client cert context"); + return -1; + } + } } - if ((error = do_send_request(s, len, chunked)) < 0) - git_error_set(GIT_ERROR_OS, "failed to send request with unchecked certificate"); - return error; } From 1697e90f90162a41e2c98cb7354fc69b0b7ec630 Mon Sep 17 00:00:00 2001 From: Ian Hattendorf Date: Thu, 6 Feb 2020 09:22:46 -0700 Subject: [PATCH 0004/1616] winhttp: variable and switch case scoping --- src/transports/winhttp.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index 9d3f05d0b93..98e80ab7efc 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -864,31 +864,28 @@ static int do_send_request(winhttp_stream *s, size_t len, bool chunked) static int send_request(winhttp_stream *s, size_t len, bool chunked) { - int request_failed = 1, cert_valid, client_cert_requested, error, attempts = 0; + int request_failed = 1, error, attempts = 0; DWORD ignore_flags, send_request_error; git_error_clear(); while (request_failed && attempts++ < 3) { + int cert_valid = 1; + int client_cert_requested = 0; request_failed = 0; - cert_valid = 1; - client_cert_requested = 0; if ((error = do_send_request(s, len, chunked)) < 0) { send_request_error = GetLastError(); request_failed = 1; switch (send_request_error) { - case ERROR_WINHTTP_SECURE_FAILURE: { + case ERROR_WINHTTP_SECURE_FAILURE: cert_valid = 0; break; - } - case ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED: { + case ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED: client_cert_requested = 1; break; - } - default: { + default: git_error_set(GIT_ERROR_OS, "failed to send request"); return -1; - } } } From b8aedc84ca8023fac781097fc5fdaabf43def825 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Thu, 6 Feb 2020 21:29:24 -0800 Subject: [PATCH 0005/1616] use consistent whitespace before comments --- include/git2/errors.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/git2/errors.h b/include/git2/errors.h index 5c85c4d6ce5..b4cb87f7a76 100644 --- a/include/git2/errors.h +++ b/include/git2/errors.h @@ -42,14 +42,14 @@ typedef enum { GIT_ECONFLICT = -13, /**< Checkout conflicts prevented operation */ GIT_ELOCKED = -14, /**< Lock file prevented operation */ GIT_EMODIFIED = -15, /**< Reference value does not match expected */ - GIT_EAUTH = -16, /**< Authentication error */ - GIT_ECERTIFICATE = -17, /**< Server certificate is invalid */ + GIT_EAUTH = -16, /**< Authentication error */ + GIT_ECERTIFICATE = -17, /**< Server certificate is invalid */ GIT_EAPPLIED = -18, /**< Patch/merge has already been applied */ - GIT_EPEEL = -19, /**< The requested peel operation is not possible */ - GIT_EEOF = -20, /**< Unexpected EOF */ - GIT_EINVALID = -21, /**< Invalid operation or input */ + GIT_EPEEL = -19, /**< The requested peel operation is not possible */ + GIT_EEOF = -20, /**< Unexpected EOF */ + GIT_EINVALID = -21, /**< Invalid operation or input */ GIT_EUNCOMMITTED = -22, /**< Uncommitted changes in index prevented operation */ - GIT_EDIRECTORY = -23, /**< The operation is not valid for a directory */ + GIT_EDIRECTORY = -23, /**< The operation is not valid for a directory */ GIT_EMERGECONFLICT = -24, /**< A merge conflict exists and cannot continue */ GIT_PASSTHROUGH = -30, /**< A user-configured callback refused to act */ From d4d26e8d679639ca324812717c3997d0fa6ce096 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Fri, 7 Feb 2020 09:57:52 -0800 Subject: [PATCH 0006/1616] changelog: note new error class GIT_ERROR_HTTP Updates #5389 --- docs/changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index c7516490151..72973b3af17 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -66,6 +66,8 @@ v0.28 + 1 The breaking change is that the `username` member of the underlying struct is now hidden, and a new `git_cred_get_username` function has been provided. +* Some errors of class `GIT_ERROR_NET` now have class `GIT_ERROR_HTTP`. + ### Breaking CMake configuration changes * The CMake option to use a system http-parser library, instead of the From 216165ecfa6bdea6a000a1b69617b54f48203f87 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Fri, 7 Feb 2020 10:06:28 -0800 Subject: [PATCH 0007/1616] transports: use GIT_EAUTH for authentication failures When the failure is clearly an auth failure (as opposed to possibly an auth failure), use the error code GIT_EAUTH instead of GIT_ERROR. While we're here, fix a typo and improve an error message. Fixes #5389. --- docs/changelog.md | 1 + src/transports/auth.c | 2 +- src/transports/auth_negotiate.c | 2 +- src/transports/auth_ntlm.c | 2 +- src/transports/http.c | 12 ++++++------ src/transports/httpclient.c | 4 ++-- src/transports/ssh.c | 8 ++++---- src/transports/winhttp.c | 8 ++++---- 8 files changed, 20 insertions(+), 19 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 72973b3af17..af80d48cfc5 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -67,6 +67,7 @@ v0.28 + 1 is now hidden, and a new `git_cred_get_username` function has been provided. * Some errors of class `GIT_ERROR_NET` now have class `GIT_ERROR_HTTP`. + Most authentication failures now have error code `GIT_EAUTH` instead of `GIT_ERROR`. ### Breaking CMake configuration changes diff --git a/src/transports/auth.c b/src/transports/auth.c index 4aa3df02146..51763e35926 100644 --- a/src/transports/auth.c +++ b/src/transports/auth.c @@ -18,7 +18,7 @@ static int basic_next_token( { git_credential_userpass_plaintext *cred; git_buf raw = GIT_BUF_INIT; - int error = -1; + int error = GIT_EAUTH; GIT_UNUSED(ctx); diff --git a/src/transports/auth_negotiate.c b/src/transports/auth_negotiate.c index 8a614b81a3a..a04efce702f 100644 --- a/src/transports/auth_negotiate.c +++ b/src/transports/auth_negotiate.c @@ -260,7 +260,7 @@ static int negotiate_init_context( if (!ctx->oid) { git_error_set(GIT_ERROR_NET, "negotiate authentication is not supported"); - return -1; + return GIT_EAUTH; } git_buf_puts(&ctx->target, "HTTP@"); diff --git a/src/transports/auth_ntlm.c b/src/transports/auth_ntlm.c index 02a861f0763..645aa34d56a 100644 --- a/src/transports/auth_ntlm.c +++ b/src/transports/auth_ntlm.c @@ -84,7 +84,7 @@ static int ntlm_next_token( git_buf input_buf = GIT_BUF_INIT; const unsigned char *msg; size_t challenge_len, msg_len; - int error = -1; + int error = GIT_EAUTH; assert(buf && ctx && ctx->ntlm); diff --git a/src/transports/http.c b/src/transports/http.c index 66731b0ce13..e83d6d726e3 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -159,7 +159,7 @@ static int handle_auth( if (error > 0) { git_error_set(GIT_ERROR_HTTP, "%s authentication required but no callback set", server_type); - error = -1; + error = GIT_EAUTH; } if (!error) @@ -176,7 +176,7 @@ GIT_INLINE(int) handle_remote_auth( if (response->server_auth_credtypes == 0) { git_error_set(GIT_ERROR_HTTP, "server requires authentication that we do not support"); - return -1; + return GIT_EAUTH; } /* Otherwise, prompt for credentials. */ @@ -198,7 +198,7 @@ GIT_INLINE(int) handle_proxy_auth( if (response->proxy_auth_credtypes == 0) { git_error_set(GIT_ERROR_HTTP, "proxy requires authentication that we do not support"); - return -1; + return GIT_EAUTH; } /* Otherwise, prompt for credentials. */ @@ -256,7 +256,7 @@ static int handle_response( } else if (response->status == GIT_HTTP_STATUS_UNAUTHORIZED || response->status == GIT_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED) { git_error_set(GIT_ERROR_HTTP, "unexpected authentication failure"); - return -1; + return GIT_EAUTH; } if (response->status != GIT_HTTP_STATUS_OK) { @@ -413,7 +413,7 @@ static int http_stream_read( if (stream->state == HTTP_STATE_SENDING_REQUEST) { git_error_set(GIT_ERROR_HTTP, "too many redirects or authentication replays"); - error = -1; + error = GIT_ERROR; /* not GIT_EAUTH, because the exact cause is unclear */ goto done; } @@ -551,7 +551,7 @@ static int http_stream_write( if (stream->state == HTTP_STATE_NONE) { git_error_set(GIT_ERROR_HTTP, "too many redirects or authentication replays"); - error = -1; + error = GIT_ERROR; /* not GIT_EAUTH because the exact cause is unclear */ goto done; } diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index f5c2ce58d11..d8d72273736 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -585,8 +585,8 @@ static int apply_credentials( if (auth->connection_affinity) free_auth_context(server); } else if (!token.size) { - git_error_set(GIT_ERROR_HTTP, "failed to respond to authentication challange"); - error = -1; + git_error_set(GIT_ERROR_HTTP, "failed to respond to authentication challenge"); + error = GIT_EAUTH; goto done; } diff --git a/src/transports/ssh.c b/src/transports/ssh.c index 68b3cbedab7..a605aecff22 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -461,13 +461,13 @@ static int request_creds(git_credential **out, ssh_subtransport *t, const char * if (no_callback) { git_error_set(GIT_ERROR_SSH, "authentication required but no callback set"); - return -1; + return GIT_EAUTH; } if (!(cred->credtype & auth_methods)) { cred->free(cred); - git_error_set(GIT_ERROR_SSH, "callback returned unsupported credentials type"); - return -1; + git_error_set(GIT_ERROR_SSH, "authentication callback returned unsupported credentials type"); + return GIT_EAUTH; } *out = cred; @@ -805,7 +805,7 @@ static int list_auth_methods(int *out, LIBSSH2_SESSION *session, const char *use /* either error, or the remote accepts NONE auth, which is bizarre, let's punt */ if (list == NULL && !libssh2_userauth_authenticated(session)) { ssh_error(session, "Failed to retrieve list of SSH authentication methods"); - return -1; + return GIT_EAUTH; } ptr = list; diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index ee8cb154355..ce1eb3951b5 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -146,7 +146,7 @@ static int apply_userpass_credentials(HINTERNET request, DWORD target, int mecha native_scheme = WINHTTP_AUTH_SCHEME_BASIC; } else { git_error_set(GIT_ERROR_HTTP, "invalid authentication scheme"); - error = -1; + error = GIT_EAUTH; goto done; } @@ -185,7 +185,7 @@ static int apply_default_credentials(HINTERNET request, DWORD target, int mechan native_scheme = WINHTTP_AUTH_SCHEME_NTLM; } else { git_error_set(GIT_ERROR_HTTP, "invalid authentication scheme"); - return -1; + return GIT_EAUTH; } /* @@ -602,7 +602,7 @@ static int parse_unauthorized_response( */ if (!WinHttpQueryAuthSchemes(request, &supported, &first, &target)) { git_error_set(GIT_ERROR_OS, "failed to parse supported auth schemes"); - return -1; + return GIT_EAUTH; } if (WINHTTP_AUTH_SCHEME_NTLM & supported) { @@ -972,7 +972,7 @@ static int winhttp_stream_read( /* Enforce a reasonable cap on the number of replays */ if (replay_count++ >= GIT_HTTP_REPLAY_MAX) { git_error_set(GIT_ERROR_HTTP, "too many redirects or authentication replays"); - return -1; + return GIT_ERROR; /* not GIT_EAUTH because the exact cause is not clear */ } /* Connect if necessary */ From 6a10b80201fe26288b60bf7dda568408e75ffb88 Mon Sep 17 00:00:00 2001 From: Ian Hattendorf Date: Wed, 24 Jun 2020 08:53:46 -0700 Subject: [PATCH 0008/1616] winhttp: clarify invalid cert case --- src/transports/winhttp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index 98e80ab7efc..89cbaeb4775 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -889,7 +889,7 @@ static int send_request(winhttp_stream *s, size_t len, bool chunked) } } - if (!request_failed || send_request_error == ERROR_WINHTTP_SECURE_FAILURE) { + if (!request_failed || !cert_valid) { git_error_clear(); if ((error = certificate_check(s, cert_valid)) < 0) { if (!git_error_last()) From 0668384efe29a4d92ce1e9d1108187599ac9a067 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 2 Aug 2018 21:38:40 +0200 Subject: [PATCH 0009/1616] repo: basic graft API This represents (old-style) grafted commits, a.k.a an array of overridden parents for a commit's OID. --- src/graft.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/graft.h | 29 +++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 src/graft.c create mode 100644 src/graft.h diff --git a/src/graft.c b/src/graft.c new file mode 100644 index 00000000000..21d32fb3846 --- /dev/null +++ b/src/graft.c @@ -0,0 +1,80 @@ +/* + * 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 "graft.h" + +int git__graft_register(git_graftmap *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_oidmap_set(grafts, &graft->oid, graft)) < 0) + goto cleanup; + + return 0; + +cleanup: + git_array_clear(graft->parents); + git__free(graft); + return error; +} + +int git__graft_unregister(git_graftmap *grafts, const git_oid *oid) +{ + git_commit_graft *graft; + int error; + + assert(grafts && oid); + + if ((graft = git_oidmap_get(grafts, oid)) == NULL) + return GIT_ENOTFOUND; + + if ((error = git_oidmap_delete(grafts, oid)) < 0) + return error; + + git__free(graft); + + return 0; +} + +void git__graft_clear(git_graftmap *grafts) +{ + git_commit_graft *graft; + + assert(grafts); + + git_oidmap_foreach_value(grafts, graft, { + git__free(graft->parents.ptr); + git__free(graft); + }); + + git_oidmap_clear(grafts); +} + +int git__graft_for_oid(git_commit_graft **out, git_graftmap *grafts, const git_oid *oid) +{ + assert(out && grafts && oid); + if ((*out = git_oidmap_get(grafts, oid)) == NULL) + return GIT_ENOTFOUND; + return 0; +} diff --git a/src/graft.h b/src/graft.h new file mode 100644 index 00000000000..e2afb971131 --- /dev/null +++ b/src/graft.h @@ -0,0 +1,29 @@ +/* + * 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; + +/* A special type of git_oidmap with git_commit_grafts as values */ +typedef git_oidmap git_graftmap; + +int git__graft_register(git_graftmap *grafts, const git_oid *oid, git_array_oid_t parents); +int git__graft_unregister(git_graftmap *grafts, const git_oid *oid); +void git__graft_clear(git_graftmap *grafts); + +int git__graft_for_oid(git_commit_graft **out, git_graftmap *grafts, const git_oid *oid); + +#endif From 919501a92dbafac6e6e876aa7160c3f46f8afe55 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 2 Aug 2018 21:38:42 +0200 Subject: [PATCH 0010/1616] repo: load grafts on open This wires git_repository to open the .git/info/grafts file and load its contents as git_commit_grafts objects. --- src/buffer.h | 5 +++ src/commit.c | 1 + src/repository.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ src/repository.h | 4 +++ 4 files changed, 91 insertions(+) diff --git a/src/buffer.h b/src/buffer.h index 6b717d2e90c..fc8fe140055 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -219,4 +219,9 @@ int git_buf_splice( const char *data, size_t nb_to_insert); +/* warning: this will wreck your buf contents */ +#define git_buf_foreach_line(line_start, line_end, line_num, buf) \ + while (((line_start) = git__strsep(&(buf)->ptr, "\n")) != NULL && \ + ((line_end) = (line_start) + strlen((line_start))) != NULL && ++(line_num)) + #endif diff --git a/src/commit.c b/src/commit.c index cf9902d022b..e2003d2181a 100644 --- a/src/commit.c +++ b/src/commit.c @@ -22,6 +22,7 @@ #include "object.h" #include "array.h" #include "oidarray.h" +#include "graft.h" void git_commit__free(void *_commit) { diff --git a/src/repository.c b/src/repository.c index 5e818fb8289..bcd91509d3d 100644 --- a/src/repository.c +++ b/src/repository.c @@ -148,6 +148,9 @@ int git_repository__cleanup(git_repository *repo) git_cache_clear(&repo->objects); git_attr_cache_flush(repo); + git__graft_clear(repo->grafts); + git_oidmap_free(repo->grafts); + set_config(repo, NULL); set_index(repo, NULL); set_odb(repo, NULL); @@ -254,6 +257,9 @@ static git_repository *repository_alloc(void) /* set all the entries in the configmap cache to `unset` */ git_repository__configmap_lookup_cache_clear(repo); + if (git_oidmap_new(&repo->grafts) < 0) + goto on_error; + return repo; on_error: @@ -574,6 +580,78 @@ static int find_repo( return error; } +static int load_grafts(git_repository *repo) +{ + git_buf graft_path = GIT_BUF_INIT; + git_buf contents = GIT_BUF_INIT; + git_buf dup_contents; + const char *line_start; + const char *line_end; + int line_num = 0; + int error, updated; + git_array_oid_t parents = GIT_ARRAY_INIT; + + if ((error = git_repository_item_path(&graft_path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0) + return error; + + if (git_buf_joinpath(&graft_path, graft_path.ptr, "grafts")) { + git_buf_dispose(&graft_path); + return error; + } + + error = git_futils_readbuffer_updated(&contents, git_buf_cstr(&graft_path), &repo->graft_checksum, &updated); + git_buf_dispose(&graft_path); + + if (error == GIT_ENOTFOUND || !updated) + return 0; + + if (error < 0) + goto cleanup; + + if (updated) { + git__graft_clear(repo->grafts); + } + + dup_contents.ptr = contents.ptr; + git_buf_foreach_line(line_start, line_end, line_num, &dup_contents) { + git_oid graft_oid, parent_oid; + + error = git_oid_fromstrn(&graft_oid, line_start, GIT_OID_HEXSZ); + if (error < 0) { + git_error_set(GIT_ERROR_REPOSITORY, "Invalid OID at line %d", line_num); + error = -1; + } + line_start += GIT_OID_HEXSZ; + + if (*(line_start++) == ' ') { + while (git_oid_fromstrn(&parent_oid, line_start, GIT_OID_HEXSZ) == 0) { + git_oid *id = git_array_alloc(parents); + + git_oid_cpy(id, &parent_oid); + line_start += GIT_OID_HEXSZ; + if (line_start >= line_end) { + break; + } + line_start += 1; + } + } + + if (git__graft_register(repo->grafts, &graft_oid, parents) < 0) { + git_error_set(GIT_ERROR_REPOSITORY, "Invalid graft at line %d", line_num); + error = -1; + goto cleanup; + } + git_array_clear(parents); + line_num++; + } + +cleanup: + git_array_clear(parents); + git_buf_dispose(&contents); + + return error; +} + int git_repository_open_bare( git_repository **repo_ptr, const char *bare_path) @@ -863,6 +941,9 @@ int git_repository_open_ext( if ((error = check_extensions(config, version) < 0)) goto cleanup; + if ((error = load_grafts(repo)) < 0) + goto cleanup; + if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) repo->is_bare = 1; else { diff --git a/src/repository.h b/src/repository.h index bafdb589697..98d266d839b 100644 --- a/src/repository.h +++ b/src/repository.h @@ -24,6 +24,7 @@ #include "attrcache.h" #include "submodule.h" #include "diff_driver.h" +#include "graft.h" #define DOT_GIT ".git" #define GIT_DIR DOT_GIT "/" @@ -152,6 +153,9 @@ struct git_repository { unsigned int lru_counter; + git_graftmap *grafts; + git_oid graft_checksum; + git_atomic attr_session_key; git_configmap_value configmap_cache[GIT_CONFIGMAP_CACHE_MAX]; From 3c17f22976d62e5fc2743186b4b1b567aadf104a Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 10 Oct 2019 11:32:16 +0200 Subject: [PATCH 0011/1616] repo: load shallow roots --- include/git2/repository.h | 12 +++++++ src/repository.c | 75 +++++++++++++++++++++++++++++++++++++++ src/repository.h | 6 ++++ 3 files changed, 93 insertions(+) diff --git a/include/git2/repository.h b/include/git2/repository.h index 9ddcd340420..5a27cf08e8d 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -11,6 +11,7 @@ #include "types.h" #include "oid.h" #include "buffer.h" +#include "oidarray.h" /** * @file git2/repository.h @@ -874,6 +875,17 @@ GIT_EXTERN(const char *) git_repository_get_namespace(git_repository *repo); */ GIT_EXTERN(int) git_repository_is_shallow(git_repository *repo); +/** + * Determine the shallow roots of the repository + * + * This oidarray is owned by the library. Do not free it. + * + * @param out An array of shallow oids. + * @param repo The repository + * @return 0 on success, an error otherwise. + */ +GIT_EXTERN(int) git_repository_shallow_roots(git_oidarray *out, git_repository *repo); + /** * Retrieve the configured identity to use for reflogs * diff --git a/src/repository.c b/src/repository.c index bcd91509d3d..da27f545b15 100644 --- a/src/repository.c +++ b/src/repository.c @@ -151,6 +151,8 @@ int git_repository__cleanup(git_repository *repo) git__graft_clear(repo->grafts); git_oidmap_free(repo->grafts); + git_array_clear(repo->shallow_oids); + set_config(repo, NULL); set_index(repo, NULL); set_odb(repo, NULL); @@ -2978,6 +2980,79 @@ 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; + char *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); + 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_oids; + goto cleanup; + } + + git_array_clear(repo->shallow_oids); + + buffer = contents.ptr; + while ((line = git__strsep(&buffer, "\n")) != NULL) { + git_oid *oid = git_array_alloc(repo->shallow_oids); + + 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_oids); + 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_oids); + error = -1; + goto cleanup; + } + + *out = repo->shallow_oids; + +cleanup: + git_buf_dispose(&contents); + + 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_buf path = GIT_BUF_INIT; diff --git a/src/repository.h b/src/repository.h index 98d266d839b..f7c25f589e7 100644 --- a/src/repository.h +++ b/src/repository.h @@ -25,6 +25,7 @@ #include "submodule.h" #include "diff_driver.h" #include "graft.h" +#include "oidarray.h" #define DOT_GIT ".git" #define GIT_DIR DOT_GIT "/" @@ -156,6 +157,9 @@ struct git_repository { git_graftmap *grafts; git_oid graft_checksum; + git_oid shallow_checksum; + git_array_oid_t shallow_oids; + git_atomic attr_session_key; git_configmap_value configmap_cache[GIT_CONFIGMAP_CACHE_MAX]; @@ -259,4 +263,6 @@ extern size_t git_repository__reserved_names_posix_len; bool git_repository__reserved_names( git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs); +int git_repository__shallow_roots(git_array_oid_t *out, git_repository *repo); + #endif From a8b1d5156cf25c6b24feb084c55e8133b43d6390 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 2 Aug 2018 21:40:51 +0200 Subject: [PATCH 0012/1616] repo: graft shallow roots on open --- src/repository.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/repository.c b/src/repository.c index da27f545b15..977c7100285 100644 --- a/src/repository.c +++ b/src/repository.c @@ -654,6 +654,27 @@ static int load_grafts(git_repository *repo) return error; } +static int load_shallow(git_repository *repo) +{ + int error = 0; + git_array_oid_t roots = GIT_ARRAY_INIT; + git_array_oid_t parents = GIT_ARRAY_INIT; + size_t i; + git_oid *graft_oid; + + /* Graft shallow roots */ + if ((error = git_repository__shallow_roots(&roots, repo)) < 0) { + return error; + } + + git_array_foreach(roots, i, graft_oid) { + if ((error = git__graft_register(repo->grafts, graft_oid, parents)) < 0) { + return error; + } + } + return 0; +} + int git_repository_open_bare( git_repository **repo_ptr, const char *bare_path) @@ -946,6 +967,9 @@ int git_repository_open_ext( if ((error = load_grafts(repo)) < 0) goto cleanup; + if ((error = load_shallow(repo)) < 0) + goto cleanup; + if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) repo->is_bare = 1; else { From a35cc402fa615b316ab1a02d700de3c36482ad39 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 2 Aug 2018 21:38:43 +0200 Subject: [PATCH 0013/1616] commit: apply grafts when parsing --- src/commit.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/commit.c b/src/commit.c index e2003d2181a..ac8fb32501b 100644 --- a/src/commit.c +++ b/src/commit.c @@ -412,10 +412,6 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig buffer += tree_len; } - /* - * TODO: commit grafts! - */ - while (git_oid__parse(&parent_id, &buffer, buffer_end, "parent ") == 0) { git_oid *new_id = git_array_alloc(commit->parent_ids); GIT_ERROR_CHECK_ALLOC(new_id); @@ -499,7 +495,29 @@ 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) { - return commit_parse(commit, git_odb_object_data(odb_obj), git_odb_object_size(odb_obj), 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; + + /* Perform necessary grafts */ + if (git__graft_for_oid(&graft, repo->grafts, git_odb_object_id(odb_obj)) != GIT_ENOTFOUND) { + 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(void *_commit, git_odb_object *odb_obj) From d54c00814bbba7eb39c43a8556e1720674cab3f3 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 2 Aug 2018 21:38:45 +0200 Subject: [PATCH 0014/1616] tests: graft commits --- tests/grafts/basic.c | 122 ++++++++++++++++ tests/grafts/shallow.c | 130 ++++++++++++++++++ tests/repo/shallow.c | 39 ------ tests/resources/grafted.git/HEAD | 1 + tests/resources/grafted.git/config | 6 + tests/resources/grafted.git/info/grafts | 3 + .../05/12adebd3782157f0d5c9b22b043f87b4aaff9e | Bin 0 -> 133 bytes .../1c/18e80a276611bb9b146590616bbc5aebdf2945 | Bin 0 -> 170 bytes .../1c/3f11eca55d76bc1bf7353ca7e4226246d353ed | Bin 0 -> 46 bytes .../2a/f02ebff1fc0142d2380c98758d81c67b365869 | Bin 0 -> 73 bytes .../2b/ecadd3f1ecad07a054392421edf9c0e1c375b2 | Bin 0 -> 74 bytes .../2f/3053cbff8a4ca2f0666de364ddb734a28a31a9 | Bin 0 -> 133 bytes .../45/342912745ba6f8893b1e126df4653a4355df1a | Bin 0 -> 50 bytes .../48/b2b333732644eafb385771a992b923fa88f135 | Bin 0 -> 49 bytes .../5d/31bf4b437e1191b6c709c665f1bd329d0ed0bf | Bin 0 -> 74 bytes .../66/cc22a015f6ca75b34c82d28f78ba663876bade | 2 + .../6c/f192eb71cd3243c9fbbe2551012c4449de3fcf | Bin 0 -> 36 bytes .../7c/9da502b2744b70522bb694cd607fb00104a233 | Bin 0 -> 76 bytes .../8a/00e91619098618be97c0d2ceabb05a2c58edd9 | 2 + .../a0/4de168dd5c43aa2af594d794d62e922f8b3b34 | Bin 0 -> 42 bytes .../b2/b4f9e5fe5dacbb2f98bd71d1dc86c7b571ddd1 | Bin 0 -> 54 bytes .../ba/54010f8d41532eb130eba420f50248881f7fc2 | Bin 0 -> 37 bytes .../d7/224d49d6d5aff6ade596ed74f4bcd4f77b29e2 | 2 + .../db/8e43f297a313c439530c977b733aaa8c10d54e | Bin 0 -> 35 bytes .../e4/14f42f4e6bc6934563a2349a8600f0ab68618e | Bin 0 -> 139 bytes .../e6/7b587a57850c69f6f9351ee10c7c8a41dacc78 | Bin 0 -> 74 bytes .../f0/7330bc2e4ed4bd0bf2301505f6c6bbad01aa2a | Bin 0 -> 77 bytes .../f5/03807ffa920e407a600cfaee96b7152259acc7 | 2 + tests/resources/grafted.git/refs/heads/bottom | 1 + tests/resources/grafted.git/refs/heads/branch | 1 + tests/resources/grafted.git/refs/heads/master | 1 + tests/resources/grafted.git/refs/heads/top | 1 + 32 files changed, 274 insertions(+), 39 deletions(-) create mode 100644 tests/grafts/basic.c create mode 100644 tests/grafts/shallow.c delete mode 100644 tests/repo/shallow.c create mode 100644 tests/resources/grafted.git/HEAD create mode 100644 tests/resources/grafted.git/config create mode 100644 tests/resources/grafted.git/info/grafts create mode 100644 tests/resources/grafted.git/objects/05/12adebd3782157f0d5c9b22b043f87b4aaff9e create mode 100644 tests/resources/grafted.git/objects/1c/18e80a276611bb9b146590616bbc5aebdf2945 create mode 100644 tests/resources/grafted.git/objects/1c/3f11eca55d76bc1bf7353ca7e4226246d353ed create mode 100644 tests/resources/grafted.git/objects/2a/f02ebff1fc0142d2380c98758d81c67b365869 create mode 100644 tests/resources/grafted.git/objects/2b/ecadd3f1ecad07a054392421edf9c0e1c375b2 create mode 100644 tests/resources/grafted.git/objects/2f/3053cbff8a4ca2f0666de364ddb734a28a31a9 create mode 100644 tests/resources/grafted.git/objects/45/342912745ba6f8893b1e126df4653a4355df1a create mode 100644 tests/resources/grafted.git/objects/48/b2b333732644eafb385771a992b923fa88f135 create mode 100644 tests/resources/grafted.git/objects/5d/31bf4b437e1191b6c709c665f1bd329d0ed0bf create mode 100644 tests/resources/grafted.git/objects/66/cc22a015f6ca75b34c82d28f78ba663876bade create mode 100644 tests/resources/grafted.git/objects/6c/f192eb71cd3243c9fbbe2551012c4449de3fcf create mode 100644 tests/resources/grafted.git/objects/7c/9da502b2744b70522bb694cd607fb00104a233 create mode 100644 tests/resources/grafted.git/objects/8a/00e91619098618be97c0d2ceabb05a2c58edd9 create mode 100644 tests/resources/grafted.git/objects/a0/4de168dd5c43aa2af594d794d62e922f8b3b34 create mode 100644 tests/resources/grafted.git/objects/b2/b4f9e5fe5dacbb2f98bd71d1dc86c7b571ddd1 create mode 100644 tests/resources/grafted.git/objects/ba/54010f8d41532eb130eba420f50248881f7fc2 create mode 100644 tests/resources/grafted.git/objects/d7/224d49d6d5aff6ade596ed74f4bcd4f77b29e2 create mode 100644 tests/resources/grafted.git/objects/db/8e43f297a313c439530c977b733aaa8c10d54e create mode 100644 tests/resources/grafted.git/objects/e4/14f42f4e6bc6934563a2349a8600f0ab68618e create mode 100644 tests/resources/grafted.git/objects/e6/7b587a57850c69f6f9351ee10c7c8a41dacc78 create mode 100644 tests/resources/grafted.git/objects/f0/7330bc2e4ed4bd0bf2301505f6c6bbad01aa2a create mode 100644 tests/resources/grafted.git/objects/f5/03807ffa920e407a600cfaee96b7152259acc7 create mode 100644 tests/resources/grafted.git/refs/heads/bottom create mode 100644 tests/resources/grafted.git/refs/heads/branch create mode 100644 tests/resources/grafted.git/refs/heads/master create mode 100644 tests/resources/grafted.git/refs/heads/top diff --git a/tests/grafts/basic.c b/tests/grafts/basic.c new file mode 100644 index 00000000000..39755ee8224 --- /dev/null +++ b/tests/grafts/basic.c @@ -0,0 +1,122 @@ +#include "clar_libgit2.h" + +#include "futils.h" +#include "graft.h" + +static git_repository *g_repo; + +void test_grafts_basic__initialize(void) +{ + g_repo = cl_git_sandbox_init("grafted.git"); +} + +void test_grafts_basic__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_grafts_basic__graft_add(void) +{ + git_oid oid_src, *oid1; + git_commit_graft *graft; + git_graftmap *grafts; + git_array_oid_t parents = GIT_ARRAY_INIT; + + cl_git_pass(git_oidmap_new(&grafts)); + + cl_assert(oid1 = git_array_alloc(parents)); + cl_git_pass(git_oid_fromstr(&oid_src, "2f3053cbff8a4ca2f0666de364ddb734a28a31a9")); + git_oid_cpy(oid1, &oid_src); + + git_oid_fromstr(&oid_src, "f503807ffa920e407a600cfaee96b7152259acc7"); + cl_git_pass(git__graft_register(grafts, &oid_src, parents)); + git_array_clear(parents); + + cl_assert_equal_i(1, git_oidmap_size(grafts)); + cl_git_pass(git__graft_for_oid(&graft, grafts, &oid_src)); + cl_assert_equal_s("f503807ffa920e407a600cfaee96b7152259acc7", git_oid_tostr_s(&graft->oid)); + cl_assert_equal_i(1, git_array_size(graft->parents)); + cl_assert_equal_s("2f3053cbff8a4ca2f0666de364ddb734a28a31a9", git_oid_tostr_s(git_array_get(graft->parents, 0))); + + git__graft_clear(grafts); + git_oidmap_free(grafts); +} + +void test_grafts_basic__grafted_revwalk(void) +{ + git_revwalk *w; + git_oid oids[10]; + size_t i = 0; + git_commit *commit; + + cl_git_pass(git_revwalk_new(&w, g_repo)); + cl_git_pass(git_revwalk_push_ref(w, "refs/heads/branch")); + + cl_git_pass(git_revwalk_next(&oids[i++], w)); + cl_assert_equal_s(git_oid_tostr_s(&oids[0]), "8a00e91619098618be97c0d2ceabb05a2c58edd9"); + cl_git_pass(git_revwalk_next(&oids[i++], w)); + cl_assert_equal_s(git_oid_tostr_s(&oids[1]), "f503807ffa920e407a600cfaee96b7152259acc7"); + cl_git_pass(git_revwalk_next(&oids[i++], w)); + cl_assert_equal_s(git_oid_tostr_s(&oids[2]), "2f3053cbff8a4ca2f0666de364ddb734a28a31a9"); + + cl_git_fail_with(GIT_ITEROVER, git_revwalk_next(&oids[i++], w)); + + cl_git_pass(git_commit_lookup(&commit, g_repo, &oids[0])); + + cl_assert_equal_i(1, git_commit_parentcount(commit)); + + git_commit_free(commit); + git_revwalk_free(w); +} + +void test_grafts_basic__grafted_objects(void) +{ + git_oid oid; + git_commit *commit; + + cl_git_pass(git_oid_fromstr(&oid, "f503807ffa920e407a600cfaee96b7152259acc7")); + cl_git_pass(git_commit_lookup(&commit, g_repo, &oid)); + cl_assert_equal_i(1, git_commit_parentcount(commit)); + git_commit_free(commit); + + cl_git_pass(git_oid_fromstr(&oid, "0512adebd3782157f0d5c9b22b043f87b4aaff9e")); + cl_git_pass(git_commit_lookup(&commit, g_repo, &oid)); + cl_assert_equal_i(1, git_commit_parentcount(commit)); + git_commit_free(commit); + + cl_git_pass(git_oid_fromstr(&oid, "66cc22a015f6ca75b34c82d28f78ba663876bade")); + cl_git_pass(git_commit_lookup(&commit, g_repo, &oid)); + cl_assert_equal_i(4, git_commit_parentcount(commit)); + git_commit_free(commit); +} + +void test_grafts_basic__grafted_merge_revwalk(void) +{ + git_revwalk *w; + git_oid oids[10]; + size_t i = 0; + + cl_git_pass(git_revwalk_new(&w, g_repo)); + cl_git_pass(git_revwalk_push_ref(w, "refs/heads/bottom")); + + cl_git_pass(git_revwalk_next(&oids[i++], w)); + cl_assert_equal_s(git_oid_tostr_s(&oids[i - 1]), "66cc22a015f6ca75b34c82d28f78ba663876bade"); + cl_git_pass(git_revwalk_next(&oids[i++], w)); + cl_assert_equal_s(git_oid_tostr_s(&oids[i - 1]), "e414f42f4e6bc6934563a2349a8600f0ab68618e"); + cl_git_pass(git_revwalk_next(&oids[i++], w)); + cl_assert_equal_s(git_oid_tostr_s(&oids[i - 1]), "8a00e91619098618be97c0d2ceabb05a2c58edd9"); + cl_git_pass(git_revwalk_next(&oids[i++], w)); + cl_assert_equal_s(git_oid_tostr_s(&oids[i - 1]), "1c18e80a276611bb9b146590616bbc5aebdf2945"); + cl_git_pass(git_revwalk_next(&oids[i++], w)); + cl_assert_equal_s(git_oid_tostr_s(&oids[i - 1]), "d7224d49d6d5aff6ade596ed74f4bcd4f77b29e2"); + cl_git_pass(git_revwalk_next(&oids[i++], w)); + cl_assert_equal_s(git_oid_tostr_s(&oids[i - 1]), "0512adebd3782157f0d5c9b22b043f87b4aaff9e"); + cl_git_pass(git_revwalk_next(&oids[i++], w)); + cl_assert_equal_s(git_oid_tostr_s(&oids[i - 1]), "f503807ffa920e407a600cfaee96b7152259acc7"); + cl_git_pass(git_revwalk_next(&oids[i++], w)); + cl_assert_equal_s(git_oid_tostr_s(&oids[i - 1]), "2f3053cbff8a4ca2f0666de364ddb734a28a31a9"); + + cl_git_fail_with(GIT_ITEROVER, git_revwalk_next(&oids[i++], w)); + + git_revwalk_free(w); +} diff --git a/tests/grafts/shallow.c b/tests/grafts/shallow.c new file mode 100644 index 00000000000..e4a0f741f0b --- /dev/null +++ b/tests/grafts/shallow.c @@ -0,0 +1,130 @@ +#include "clar_libgit2.h" +#include "futils.h" + +static git_repository *g_repo; +static git_oid g_shallow_oid; + +void test_grafts_shallow__initialize(void) +{ + cl_git_pass(git_oid_fromstr(&g_shallow_oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); +} + +void test_grafts_shallow__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_grafts_shallow__no_shallow_file(void) +{ + g_repo = cl_git_sandbox_init("testrepo.git"); + cl_assert_equal_i(0, git_repository_is_shallow(g_repo)); +} + +void test_grafts_shallow__empty_shallow_file(void) +{ + g_repo = cl_git_sandbox_init("testrepo.git"); + cl_git_mkfile("testrepo.git/shallow", ""); + cl_assert_equal_i(0, git_repository_is_shallow(g_repo)); +} + +void test_grafts_shallow__shallow_repo(void) +{ + g_repo = cl_git_sandbox_init("shallow.git"); + cl_assert_equal_i(1, git_repository_is_shallow(g_repo)); +} + +void test_grafts_shallow__clears_errors(void) +{ + g_repo = cl_git_sandbox_init("testrepo.git"); + cl_assert_equal_i(0, git_repository_is_shallow(g_repo)); + cl_assert_equal_p(NULL, git_error_last()); +} + +void test_grafts_shallow__shallow_oids(void) +{ + git_oidarray oids, oids2; + g_repo = cl_git_sandbox_init("shallow.git"); + + cl_git_pass(git_repository_shallow_roots(&oids, g_repo)); + cl_assert_equal_i(1, oids.count); + cl_assert_equal_oid(&g_shallow_oid, &oids.ids[0]); + + cl_git_pass(git_repository_shallow_roots(&oids2, g_repo)); + cl_assert_equal_p(oids.ids, oids2.ids); +} + +void test_grafts_shallow__cache_clearing(void) +{ + git_oidarray oids, oids2; + git_oid tmp_oid; + + git_oid_fromstr(&tmp_oid, "0000000000000000000000000000000000000000"); + g_repo = cl_git_sandbox_init("shallow.git"); + + cl_git_pass(git_repository_shallow_roots(&oids, g_repo)); + cl_assert_equal_i(1, oids.count); + cl_assert_equal_oid(&g_shallow_oid, &oids.ids[0]); + + cl_git_mkfile("shallow.git/shallow", + "be3563ae3f795b2b4353bcce3a527ad0a4f7f644\n" + "0000000000000000000000000000000000000000\n" + ); + + cl_git_pass(git_repository_shallow_roots(&oids2, g_repo)); + cl_assert_equal_i(2, oids2.count); + cl_assert_equal_oid(&g_shallow_oid, &oids2.ids[0]); + cl_assert_equal_oid(&tmp_oid, &oids2.ids[1]); + + cl_git_pass(p_unlink("shallow.git/shallow")); + cl_git_pass(git_repository_shallow_roots(&oids, g_repo)); + cl_assert_equal_i(0, oids.count); + git_oidarray_free(&oids); +} + +void test_grafts_shallow__errors_on_borked(void) +{ + git_oidarray oids; + + g_repo = cl_git_sandbox_init("shallow.git"); + + cl_git_mkfile("shallow.git/shallow", "lolno"); + + cl_git_fail_with(-1, git_repository_shallow_roots(&oids, g_repo)); + + cl_git_mkfile("shallow.git/shallow", "lolno\n"); + + cl_git_fail_with(-1, git_repository_shallow_roots(&oids, g_repo)); +} + +void test_grafts_shallow__revwalk_behavior(void) +{ + git_revwalk *w; + git_oid oid_1, oid_2, oid_3; + + g_repo = cl_git_sandbox_init("shallow.git"); + + cl_git_pass(git_revwalk_new(&w, g_repo)); + cl_git_pass(git_revwalk_push_head(w)); + + cl_git_pass(git_revwalk_next(&oid_1, w)); // a65fedf39aefe402d3bb6e24df4d4f5fe4547750 + cl_git_pass(git_revwalk_next(&oid_2, w)); // be3563ae3f795b2b4353bcce3a527ad0a4f7f644 + cl_git_fail_with(GIT_ITEROVER, git_revwalk_next(&oid_3, w)); + + cl_assert_equal_s(git_oid_tostr_s(&oid_1), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); + cl_assert_equal_s(git_oid_tostr_s(&oid_2), "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + + git_revwalk_free(w); +} + +void test_grafts_shallow__grafted_object(void) +{ + git_commit *commit; + + g_repo = cl_git_sandbox_init("shallow.git"); + + cl_git_pass(git_commit_lookup(&commit, g_repo, &g_shallow_oid)); + + cl_assert_equal_i(0, git_commit_parentcount(commit)); + + git_commit_free(commit); +} diff --git a/tests/repo/shallow.c b/tests/repo/shallow.c deleted file mode 100644 index adb7a9e44b5..00000000000 --- a/tests/repo/shallow.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "clar_libgit2.h" -#include "futils.h" - -static git_repository *g_repo; - -void test_repo_shallow__initialize(void) -{ -} - -void test_repo_shallow__cleanup(void) -{ - cl_git_sandbox_cleanup(); -} - -void test_repo_shallow__no_shallow_file(void) -{ - g_repo = cl_git_sandbox_init("testrepo.git"); - cl_assert_equal_i(0, git_repository_is_shallow(g_repo)); -} - -void test_repo_shallow__empty_shallow_file(void) -{ - g_repo = cl_git_sandbox_init("testrepo.git"); - cl_git_mkfile("testrepo.git/shallow", ""); - cl_assert_equal_i(0, git_repository_is_shallow(g_repo)); -} - -void test_repo_shallow__shallow_repo(void) -{ - g_repo = cl_git_sandbox_init("shallow.git"); - cl_assert_equal_i(1, git_repository_is_shallow(g_repo)); -} - -void test_repo_shallow__clears_errors(void) -{ - g_repo = cl_git_sandbox_init("testrepo.git"); - cl_assert_equal_i(0, git_repository_is_shallow(g_repo)); - cl_assert_equal_p(NULL, git_error_last()); -} diff --git a/tests/resources/grafted.git/HEAD b/tests/resources/grafted.git/HEAD new file mode 100644 index 00000000000..cb089cd89a7 --- /dev/null +++ b/tests/resources/grafted.git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/tests/resources/grafted.git/config b/tests/resources/grafted.git/config new file mode 100644 index 00000000000..e6da231579b --- /dev/null +++ b/tests/resources/grafted.git/config @@ -0,0 +1,6 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = true + ignorecase = true + precomposeunicode = true diff --git a/tests/resources/grafted.git/info/grafts b/tests/resources/grafted.git/info/grafts new file mode 100644 index 00000000000..bb9df8c0a80 --- /dev/null +++ b/tests/resources/grafted.git/info/grafts @@ -0,0 +1,3 @@ +f503807ffa920e407a600cfaee96b7152259acc7 2f3053cbff8a4ca2f0666de364ddb734a28a31a9 +0512adebd3782157f0d5c9b22b043f87b4aaff9e 2f3053cbff8a4ca2f0666de364ddb734a28a31a9 +66cc22a015f6ca75b34c82d28f78ba663876bade e414f42f4e6bc6934563a2349a8600f0ab68618e 8a00e91619098618be97c0d2ceabb05a2c58edd9 1c18e80a276611bb9b146590616bbc5aebdf2945 2f3053cbff8a4ca2f0666de364ddb734a28a31a9 diff --git a/tests/resources/grafted.git/objects/05/12adebd3782157f0d5c9b22b043f87b4aaff9e b/tests/resources/grafted.git/objects/05/12adebd3782157f0d5c9b22b043f87b4aaff9e new file mode 100644 index 0000000000000000000000000000000000000000..16880d596e5be78d02e1ea264f4b2ee69d02c680 GIT binary patch literal 133 zcmV;00DAv;oTZIH3d0}}0DJZodoP6D7!5)R?V&H|3)EdxAu1&H|Aq7kJq^rZCbm*? z2Xf}pcM&kGDWoY(dKMx_!NwU~wALgFtVhQvj3Fui>F>6~vuCMQ;N{EFD%_5fgZ%V; nEk18UY-Is5sL{-X4z4&Ns(7xu{1s6T=3G}uc@wR^E=)i_XyrVi literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/1c/18e80a276611bb9b146590616bbc5aebdf2945 b/tests/resources/grafted.git/objects/1c/18e80a276611bb9b146590616bbc5aebdf2945 new file mode 100644 index 0000000000000000000000000000000000000000..2c057b85d87270c2fb5dd4f9ee40b4c34158b122 GIT binary patch literal 170 zcmV;b09F5ZoTZOF3IZ_@My+#-=>^Ho<`+b4Y;8P2HZ!9OCXwBU*H`oiRu8`7@x9zi znLD6~o4zmuCeg@~$RJq{1_{TYa}3@F3PW~&8l4R;sz+M5b|8;v$V75vlZZ>iHaaG6 z#7votct2reRO#7oZGlstxmJctDr>8-U%%Y(Z$4g2n(w>Z$^izeM{Pg)09%b(tNgv% Y`7en&^9y9Y^9Z@s{z+KX8>doGwo)cfs{jB1 literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/1c/3f11eca55d76bc1bf7353ca7e4226246d353ed b/tests/resources/grafted.git/objects/1c/3f11eca55d76bc1bf7353ca7e4226246d353ed new file mode 100644 index 0000000000000000000000000000000000000000..b92a3047f1804ae188cc86555e7179093185915b GIT binary patch literal 46 zcmV+}0MY+=oJ-2dPf{>8V2I2wRVYf$%`Zz;D9K1wNXyJgRY=ayD@n~ODc0ix0Qf`< E_1_m1iU0rr literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/2a/f02ebff1fc0142d2380c98758d81c67b365869 b/tests/resources/grafted.git/objects/2a/f02ebff1fc0142d2380c98758d81c67b365869 new file mode 100644 index 0000000000000000000000000000000000000000..ed3f874a7bddb6d5d2f46ac5823f8181b09105dd GIT binary patch literal 73 zcmV-P0Ji^loGU3xO;s>6WiT`_Ff%bxNXyJgWw_nv{Av1P;Ukv8JkzU-tyc92T=hee fH)hxs!pPt27_7I^;Pn!PuS^~t^7V%Rkc%1M+}9*@ literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/2b/ecadd3f1ecad07a054392421edf9c0e1c375b2 b/tests/resources/grafted.git/objects/2b/ecadd3f1ecad07a054392421edf9c0e1c375b2 new file mode 100644 index 0000000000000000000000000000000000000000..724eedbb2ecf35e1e3f3ba08ec2445092841ba5f GIT binary patch literal 74 zcmV-Q0JZ;koGU3xO;s>6WiT`_Ff%bxNXyJgWw_nv{Av1P;Ukv8JkzU-tyc92T=hee gH)fEr7kslcwrr2|cT=0?Pn43}E(gB_0GnVNGu+-H00000 literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/2f/3053cbff8a4ca2f0666de364ddb734a28a31a9 b/tests/resources/grafted.git/objects/2f/3053cbff8a4ca2f0666de364ddb734a28a31a9 new file mode 100644 index 0000000000000000000000000000000000000000..3d124a6735246418d158e34e43266d782f20f0b9 GIT binary patch literal 133 zcmV;00DAv;oTZIH3d0}}0DJZodoKjt)u<3kFFo|!7p!5^3Q-}k|1Ts@=xJaMGjl5? zcQDak`X&N4Buqr)2}f&%mqfvNZ#YIw5ozHN7DG<)w}09OkDjGgfftv(RhagJgPi*Q nE}Yk4Zsi8XX^dmk7U8N8VQ|dLFUd$P(orbR$xP2E$*ELG$xKU2ElSNRQAo?oNj2dD I05rx9iB#hjJ^%m! literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/48/b2b333732644eafb385771a992b923fa88f135 b/tests/resources/grafted.git/objects/48/b2b333732644eafb385771a992b923fa88f135 new file mode 100644 index 0000000000000000000000000000000000000000..ac640636beb3e853d58759fdcbe76da2e6396e3e GIT binary patch literal 49 zcmV-10M7q-oGU3xO;s>9VlXr?Ff%bxNXyJgWw_nv{Av1P;Ukv8JkzU-tyc92T=fG0 H3L_4b`6Lx1 literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/5d/31bf4b437e1191b6c709c665f1bd329d0ed0bf b/tests/resources/grafted.git/objects/5d/31bf4b437e1191b6c709c665f1bd329d0ed0bf new file mode 100644 index 0000000000000000000000000000000000000000..47a05377ef383fe0018c4ae10588e3aa6e87115a GIT binary patch literal 74 zcmV-Q0JZ;koGU3xO;s>6WiT`_Ff%bxNXyJgWw_nv{Av1P;Ukv8JkzU-tyc92T=hee gH)dGi`!M5fjPok3uT!p1xu!QszuVdb0JJ+B_4OnqA^-pY literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/66/cc22a015f6ca75b34c82d28f78ba663876bade b/tests/resources/grafted.git/objects/66/cc22a015f6ca75b34c82d28f78ba663876bade new file mode 100644 index 00000000000..c68b2cd4fb1 --- /dev/null +++ b/tests/resources/grafted.git/objects/66/cc22a015f6ca75b34c82d28f78ba663876bade @@ -0,0 +1,2 @@ +xœ¥ŽM +Â0F]ç³Ê$™üDÜx=Á4N´Ð4ÒFϯÔ#¸úàñx|©–260dvmñap1° Ñaò}ö¹·N‹hL!E&}ã”BTO^dn ¤)“É$~øê–œ·l,õ=bF|ô:ŠâW{ÔÎm”y¸rYë ‡uÛN~øt/Ñ«M, \ No newline at end of file diff --git a/tests/resources/grafted.git/objects/6c/f192eb71cd3243c9fbbe2551012c4449de3fcf b/tests/resources/grafted.git/objects/6c/f192eb71cd3243c9fbbe2551012c4449de3fcf new file mode 100644 index 0000000000000000000000000000000000000000..a437f24320485d43a36754c301df4ec942291628 GIT binary patch literal 36 scmb=J<9+I+e~^Ju630o8&=Y6%y+SokdazFFbX{3hRTaZ9g^SY$02^Em9RL6T literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/7c/9da502b2744b70522bb694cd607fb00104a233 b/tests/resources/grafted.git/objects/7c/9da502b2744b70522bb694cd607fb00104a233 new file mode 100644 index 0000000000000000000000000000000000000000..b363584fd9ab216bee5892efa1ce7ae800d72ec3 GIT binary patch literal 76 zcmV-S0JHyioGU3xO;xb8U@$Z=Ff%bxNXyJgWw_nv{Av1P;Ukv8JkzU-tyc92T=hee iHzK6Kgu&HBQ>Y|**^f?ZIicJysaDRR_oV>MU?ur-;U+Nv literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/8a/00e91619098618be97c0d2ceabb05a2c58edd9 b/tests/resources/grafted.git/objects/8a/00e91619098618be97c0d2ceabb05a2c58edd9 new file mode 100644 index 00000000000..887778a60a0 --- /dev/null +++ b/tests/resources/grafted.git/objects/8a/00e91619098618be97c0d2ceabb05a2c58edd9 @@ -0,0 +1,2 @@ +xœ¥ŽA +Â0E]ç³Êt’4Dtá <Á$™Ô@“Jï¯Ô#¸úðïý°”’ч¶Š@B§5ú@b$Ñ'ÒØ[´iƒ÷±g&V/^¥6Hõ ]J<ŠAÇbH,2Þõ–ÈŽ‚SünÏe…{ËR«ÀƒË¶T8oûvòÃשpž»°” |›­Ódàˆ„¨Â~µÉ_u‹1× RžÅ¨ßšNC \ No newline at end of file diff --git a/tests/resources/grafted.git/objects/a0/4de168dd5c43aa2af594d794d62e922f8b3b34 b/tests/resources/grafted.git/objects/a0/4de168dd5c43aa2af594d794d62e922f8b3b34 new file mode 100644 index 0000000000000000000000000000000000000000..1ed3ed906abd905893455c38a9597e7ef259df59 GIT binary patch literal 42 ycmb=J<9+I+e~^JuazTj4x%0XnXHK6vAMA1ZjAy8aj)sS?j#k(cCWb@G+%5p0ClPP} literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/b2/b4f9e5fe5dacbb2f98bd71d1dc86c7b571ddd1 b/tests/resources/grafted.git/objects/b2/b4f9e5fe5dacbb2f98bd71d1dc86c7b571ddd1 new file mode 100644 index 0000000000000000000000000000000000000000..2adc857219eb17dcbb6489b39e2e9d520e9ec1d0 GIT binary patch literal 54 zcmV-60LlM&oGU3xO;s>6WiT`_Ff%bxNXyJgWw_nv{Av1P;Ukv8JkzU-tyc92T=hee MH^Qm_0IJ^`DtJ*CmjD0& literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/ba/54010f8d41532eb130eba420f50248881f7fc2 b/tests/resources/grafted.git/objects/ba/54010f8d41532eb130eba420f50248881f7fc2 new file mode 100644 index 0000000000000000000000000000000000000000..52a8872747197a2a017978f343a13d5fafaa5b8c GIT binary patch literal 37 tcmb=J<9+I+e~^Ju$_Jf5{V)x0-BlqTzTT&O&iS0x4t&DI(D{Kg0ste34+H=J literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/d7/224d49d6d5aff6ade596ed74f4bcd4f77b29e2 b/tests/resources/grafted.git/objects/d7/224d49d6d5aff6ade596ed74f4bcd4f77b29e2 new file mode 100644 index 00000000000..5b41b6778f8 --- /dev/null +++ b/tests/resources/grafted.git/objects/d7/224d49d6d5aff6ade596ed74f4bcd4f77b29e2 @@ -0,0 +1,2 @@ +xœ¥A +Â0E]ç³ÊdÒDÜx=Á$™h¡I¤ž_­Gpõà/ÿ…šóÔ€,íÚ"ä%pŒ&é/Ñ1Úތԓ–˜Æ€¢ƒqÖ“zð"¥ZMÅGãÒÖ%Œ6ŒžÈcoÒà|ÏœÒ(ŠŸí^8·IJ¸r^kú±“ß|ºežæ.Ô|mÑ u„öHˆ*lW›ü%QÉõ%¦Y „ZÚ§bUoaRj \ No newline at end of file diff --git a/tests/resources/grafted.git/objects/db/8e43f297a313c439530c977b733aaa8c10d54e b/tests/resources/grafted.git/objects/db/8e43f297a313c439530c977b733aaa8c10d54e new file mode 100644 index 0000000000000000000000000000000000000000..b9cf5947b705184a4ba4a8e3d19140da9eb41356 GIT binary patch literal 35 rcmb=J<9+I+e~`hJl!A~G-n!u)r_XqXdgy3)`08jqV`3jUvmdN{IG$9V?CXd*oVbWUhyDfEtXG>Cwz>D)<3tabuo&5BD t&YadR)O>^9qDJfV#ljg0QH5jO literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/e6/7b587a57850c69f6f9351ee10c7c8a41dacc78 b/tests/resources/grafted.git/objects/e6/7b587a57850c69f6f9351ee10c7c8a41dacc78 new file mode 100644 index 0000000000000000000000000000000000000000..213f9ac22ef650e98e03036bd3ba542f0c498454 GIT binary patch literal 74 zcmV-Q0JZ;koGU3xO;s>6V=y!@Ff%bxNXyJgHDb8k=lp5+4m2we3; gQeeX1YN9Dr620t4r?s3=?w3?6=g|970GyW@mfHIx)c^nh literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/f0/7330bc2e4ed4bd0bf2301505f6c6bbad01aa2a b/tests/resources/grafted.git/objects/f0/7330bc2e4ed4bd0bf2301505f6c6bbad01aa2a new file mode 100644 index 0000000000000000000000000000000000000000..f2d64889207b6c5a5676af3ef9addc92077d3b14 GIT binary patch literal 77 zcmV-T0J8shoGU3xO;xb8U@$Z=Ff%bxNXyJgWw_nv{Av1P;Ukv8JkzU-tyc92T=hee jHzK6KgdykSq}PRKjhs*Z-lrPKsN>>!&;C3B_1!3bz$Ga8 literal 0 HcmV?d00001 diff --git a/tests/resources/grafted.git/objects/f5/03807ffa920e407a600cfaee96b7152259acc7 b/tests/resources/grafted.git/objects/f5/03807ffa920e407a600cfaee96b7152259acc7 new file mode 100644 index 00000000000..21436c177e9 --- /dev/null +++ b/tests/resources/grafted.git/objects/f5/03807ffa920e407a600cfaee96b7152259acc7 @@ -0,0 +1,2 @@ +xœ¥A +Â0E]ç³J&˜6)ºðž ™™Ô@“@ï¯Ô#¸ú·xŸZ)¹z{ê›D/É‹Mb9PŒ&yyBF&7Òí—™Q…wµ =K­ÏPöVáº;ÈOß–ò:P+3 Õƃ³6Z+:®»üQwæ\Hy£>zAƒ \ No newline at end of file diff --git a/tests/resources/grafted.git/refs/heads/bottom b/tests/resources/grafted.git/refs/heads/bottom new file mode 100644 index 00000000000..10513e69877 --- /dev/null +++ b/tests/resources/grafted.git/refs/heads/bottom @@ -0,0 +1 @@ +66cc22a015f6ca75b34c82d28f78ba663876bade diff --git a/tests/resources/grafted.git/refs/heads/branch b/tests/resources/grafted.git/refs/heads/branch new file mode 100644 index 00000000000..d0fe5c28390 --- /dev/null +++ b/tests/resources/grafted.git/refs/heads/branch @@ -0,0 +1 @@ +8a00e91619098618be97c0d2ceabb05a2c58edd9 diff --git a/tests/resources/grafted.git/refs/heads/master b/tests/resources/grafted.git/refs/heads/master new file mode 100644 index 00000000000..de809b9421a --- /dev/null +++ b/tests/resources/grafted.git/refs/heads/master @@ -0,0 +1 @@ +2f3053cbff8a4ca2f0666de364ddb734a28a31a9 diff --git a/tests/resources/grafted.git/refs/heads/top b/tests/resources/grafted.git/refs/heads/top new file mode 100644 index 00000000000..ce226110b8e --- /dev/null +++ b/tests/resources/grafted.git/refs/heads/top @@ -0,0 +1 @@ +1c18e80a276611bb9b146590616bbc5aebdf2945 From 22f201b158f4a3b7bfcf3bac2324ab3fa77bac06 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 3 Oct 2019 10:40:41 +0200 Subject: [PATCH 0015/1616] grafts: make the structure self-contained and opaque In order to increase maintainability in the future, we should try to make structures as self-contained and opaque to its users as possible. Thus it is probably not a good idea to just typedef `git_graftmap` to `git_oidmap`, as that will make it a lot harder in the future to extend the API in the future, if this need ever arises. Refactor the code to instead declare a real structure `git_grafts`, which is completely opaque to its callers. --- src/commit.c | 4 +- src/graft.c | 80 -------------------------- src/grafts.c | 115 ++++++++++++++++++++++++++++++++++++++ src/{graft.h => grafts.h} | 14 +++-- src/repository.c | 17 ++---- src/repository.h | 4 +- tests/grafts/basic.c | 17 +++--- 7 files changed, 141 insertions(+), 110 deletions(-) delete mode 100644 src/graft.c create mode 100644 src/grafts.c rename src/{graft.h => grafts.h} (50%) diff --git a/src/commit.c b/src/commit.c index ac8fb32501b..e06faafe781 100644 --- a/src/commit.c +++ b/src/commit.c @@ -22,7 +22,7 @@ #include "object.h" #include "array.h" #include "oidarray.h" -#include "graft.h" +#include "grafts.h" void git_commit__free(void *_commit) { @@ -504,7 +504,7 @@ int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned return error; /* Perform necessary grafts */ - if (git__graft_for_oid(&graft, repo->grafts, git_odb_object_id(odb_obj)) != GIT_ENOTFOUND) { + if (git_grafts_get(&graft, repo->grafts, git_odb_object_id(odb_obj)) != GIT_ENOTFOUND) { size_t idx; git_oid *oid; git_array_clear(commit->parent_ids); diff --git a/src/graft.c b/src/graft.c deleted file mode 100644 index 21d32fb3846..00000000000 --- a/src/graft.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 "graft.h" - -int git__graft_register(git_graftmap *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_oidmap_set(grafts, &graft->oid, graft)) < 0) - goto cleanup; - - return 0; - -cleanup: - git_array_clear(graft->parents); - git__free(graft); - return error; -} - -int git__graft_unregister(git_graftmap *grafts, const git_oid *oid) -{ - git_commit_graft *graft; - int error; - - assert(grafts && oid); - - if ((graft = git_oidmap_get(grafts, oid)) == NULL) - return GIT_ENOTFOUND; - - if ((error = git_oidmap_delete(grafts, oid)) < 0) - return error; - - git__free(graft); - - return 0; -} - -void git__graft_clear(git_graftmap *grafts) -{ - git_commit_graft *graft; - - assert(grafts); - - git_oidmap_foreach_value(grafts, graft, { - git__free(graft->parents.ptr); - git__free(graft); - }); - - git_oidmap_clear(grafts); -} - -int git__graft_for_oid(git_commit_graft **out, git_graftmap *grafts, const git_oid *oid) -{ - assert(out && grafts && oid); - if ((*out = git_oidmap_get(grafts, oid)) == NULL) - return GIT_ENOTFOUND; - return 0; -} diff --git a/src/grafts.c b/src/grafts.c new file mode 100644 index 00000000000..90490d0ac29 --- /dev/null +++ b/src/grafts.c @@ -0,0 +1,115 @@ +/* + * 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" + +struct git_grafts { + /* Map of `git_commit_graft`s */ + git_oidmap *commits; +}; + +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; +} + +void git_grafts_free(git_grafts *grafts) +{ + if (!grafts) + return; + 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_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_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); + + 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; +} + +size_t git_grafts_size(git_grafts *grafts) +{ + return git_oidmap_size(grafts->commits); +} diff --git a/src/graft.h b/src/grafts.h similarity index 50% rename from src/graft.h rename to src/grafts.h index e2afb971131..76e8d3f2966 100644 --- a/src/graft.h +++ b/src/grafts.h @@ -17,13 +17,15 @@ typedef struct { git_array_oid_t parents; } git_commit_graft; -/* A special type of git_oidmap with git_commit_grafts as values */ -typedef git_oidmap git_graftmap; +typedef struct git_grafts git_grafts; -int git__graft_register(git_graftmap *grafts, const git_oid *oid, git_array_oid_t parents); -int git__graft_unregister(git_graftmap *grafts, const git_oid *oid); -void git__graft_clear(git_graftmap *grafts); +int git_grafts_new(git_grafts **out); +void git_grafts_free(git_grafts *grafts); +void git_grafts_clear(git_grafts *grafts); -int git__graft_for_oid(git_commit_graft **out, git_graftmap *grafts, const git_oid *oid); +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); +size_t git_grafts_size(git_grafts *grafts); #endif diff --git a/src/repository.c b/src/repository.c index 977c7100285..57b91410711 100644 --- a/src/repository.c +++ b/src/repository.c @@ -147,10 +147,7 @@ int git_repository__cleanup(git_repository *repo) git_repository_submodule_cache_clear(repo); git_cache_clear(&repo->objects); git_attr_cache_flush(repo); - - git__graft_clear(repo->grafts); - git_oidmap_free(repo->grafts); - + git_grafts_free(repo->grafts); git_array_clear(repo->shallow_oids); set_config(repo, NULL); @@ -259,7 +256,7 @@ static git_repository *repository_alloc(void) /* set all the entries in the configmap cache to `unset` */ git_repository__configmap_lookup_cache_clear(repo); - if (git_oidmap_new(&repo->grafts) < 0) + if (git_grafts_new(&repo->grafts) < 0) goto on_error; return repo; @@ -610,9 +607,8 @@ static int load_grafts(git_repository *repo) if (error < 0) goto cleanup; - if (updated) { - git__graft_clear(repo->grafts); - } + if (updated) + git_grafts_clear(repo->grafts); dup_contents.ptr = contents.ptr; git_buf_foreach_line(line_start, line_end, line_num, &dup_contents) { @@ -638,7 +634,7 @@ static int load_grafts(git_repository *repo) } } - if (git__graft_register(repo->grafts, &graft_oid, parents) < 0) { + if (git_grafts_add(repo->grafts, &graft_oid, parents) < 0) { git_error_set(GIT_ERROR_REPOSITORY, "Invalid graft at line %d", line_num); error = -1; goto cleanup; @@ -668,9 +664,8 @@ static int load_shallow(git_repository *repo) } git_array_foreach(roots, i, graft_oid) { - if ((error = git__graft_register(repo->grafts, graft_oid, parents)) < 0) { + if ((error = git_grafts_add(repo->grafts, graft_oid, parents)) < 0) return error; - } } return 0; } diff --git a/src/repository.h b/src/repository.h index f7c25f589e7..fd7c274a8dc 100644 --- a/src/repository.h +++ b/src/repository.h @@ -24,7 +24,7 @@ #include "attrcache.h" #include "submodule.h" #include "diff_driver.h" -#include "graft.h" +#include "grafts.h" #include "oidarray.h" #define DOT_GIT ".git" @@ -154,7 +154,7 @@ struct git_repository { unsigned int lru_counter; - git_graftmap *grafts; + git_grafts *grafts; git_oid graft_checksum; git_oid shallow_checksum; diff --git a/tests/grafts/basic.c b/tests/grafts/basic.c index 39755ee8224..f91397002d0 100644 --- a/tests/grafts/basic.c +++ b/tests/grafts/basic.c @@ -1,7 +1,7 @@ #include "clar_libgit2.h" #include "futils.h" -#include "graft.h" +#include "grafts.h" static git_repository *g_repo; @@ -17,29 +17,28 @@ void test_grafts_basic__cleanup(void) void test_grafts_basic__graft_add(void) { + git_array_oid_t parents = GIT_ARRAY_INIT; git_oid oid_src, *oid1; git_commit_graft *graft; - git_graftmap *grafts; - git_array_oid_t parents = GIT_ARRAY_INIT; + git_grafts *grafts; - cl_git_pass(git_oidmap_new(&grafts)); + cl_git_pass(git_grafts_new(&grafts)); cl_assert(oid1 = git_array_alloc(parents)); cl_git_pass(git_oid_fromstr(&oid_src, "2f3053cbff8a4ca2f0666de364ddb734a28a31a9")); git_oid_cpy(oid1, &oid_src); git_oid_fromstr(&oid_src, "f503807ffa920e407a600cfaee96b7152259acc7"); - cl_git_pass(git__graft_register(grafts, &oid_src, parents)); + cl_git_pass(git_grafts_add(grafts, &oid_src, parents)); git_array_clear(parents); - cl_assert_equal_i(1, git_oidmap_size(grafts)); - cl_git_pass(git__graft_for_oid(&graft, grafts, &oid_src)); + cl_assert_equal_i(1, git_grafts_size(grafts)); + cl_git_pass(git_grafts_get(&graft, grafts, &oid_src)); cl_assert_equal_s("f503807ffa920e407a600cfaee96b7152259acc7", git_oid_tostr_s(&graft->oid)); cl_assert_equal_i(1, git_array_size(graft->parents)); cl_assert_equal_s("2f3053cbff8a4ca2f0666de364ddb734a28a31a9", git_oid_tostr_s(git_array_get(graft->parents, 0))); - git__graft_clear(grafts); - git_oidmap_free(grafts); + git_grafts_free(grafts); } void test_grafts_basic__grafted_revwalk(void) From 14a309ab384a8732f692e468ac56c0d1831fce2f Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 3 Oct 2019 11:17:10 +0200 Subject: [PATCH 0016/1616] repository: convert grafts parsing to use parse context Instead of using the newly introduced `git_buf_foreach_line`, which modifies the buffer itself, we should try to use our existing parsing infrastructure in "parse.h". Convert the grafts parsing code to make use of `git_parse_ctx`. Remove the `git_buf_foreach_line` macro, as grafts have been its sole user. --- src/buffer.h | 5 ---- src/repository.c | 68 +++++++++++++++++++++++------------------------- 2 files changed, 32 insertions(+), 41 deletions(-) diff --git a/src/buffer.h b/src/buffer.h index fc8fe140055..6b717d2e90c 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -219,9 +219,4 @@ int git_buf_splice( const char *data, size_t nb_to_insert); -/* warning: this will wreck your buf contents */ -#define git_buf_foreach_line(line_start, line_end, line_num, buf) \ - while (((line_start) = git__strsep(&(buf)->ptr, "\n")) != NULL && \ - ((line_end) = (line_start) + strlen((line_start))) != NULL && ++(line_num)) - #endif diff --git a/src/repository.c b/src/repository.c index 57b91410711..4465d8e7968 100644 --- a/src/repository.c +++ b/src/repository.c @@ -31,6 +31,7 @@ #include "annotated_commit.h" #include "submodule.h" #include "worktree.h" +#include "parse.h" #include "strmap.h" @@ -581,14 +582,11 @@ static int find_repo( static int load_grafts(git_repository *repo) { + git_array_oid_t parents = GIT_ARRAY_INIT; git_buf graft_path = GIT_BUF_INIT; git_buf contents = GIT_BUF_INIT; - git_buf dup_contents; - const char *line_start; - const char *line_end; - int line_num = 0; + git_parse_ctx parser; int error, updated; - git_array_oid_t parents = GIT_ARRAY_INIT; if ((error = git_repository_item_path(&graft_path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0) return error; @@ -598,54 +596,52 @@ static int load_grafts(git_repository *repo) return error; } - error = git_futils_readbuffer_updated(&contents, git_buf_cstr(&graft_path), &repo->graft_checksum, &updated); - git_buf_dispose(&graft_path); + error = git_futils_readbuffer_updated(&contents, git_buf_cstr(&graft_path), + &repo->graft_checksum, &updated); + if (error < 0 || error == GIT_ENOTFOUND || !updated) { + if (error == GIT_ENOTFOUND) + error = 0; + goto cleanup; + } - if (error == GIT_ENOTFOUND || !updated) - return 0; + git_grafts_clear(repo->grafts); - if (error < 0) + if ((error = git_parse_ctx_init(&parser, contents.ptr, contents.size)) < 0) goto cleanup; - if (updated) - git_grafts_clear(repo->grafts); - - dup_contents.ptr = contents.ptr; - git_buf_foreach_line(line_start, line_end, line_num, &dup_contents) { - git_oid graft_oid, parent_oid; + 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; - error = git_oid_fromstrn(&graft_oid, line_start, GIT_OID_HEXSZ); - if (error < 0) { - git_error_set(GIT_ERROR_REPOSITORY, "Invalid OID at line %d", line_num); - error = -1; - } + if (git_oid_fromstrn(&graft_oid, line_start, GIT_OID_HEXSZ) < 0) + goto invalid_oid; line_start += GIT_OID_HEXSZ; - if (*(line_start++) == ' ') { - while (git_oid_fromstrn(&parent_oid, line_start, GIT_OID_HEXSZ) == 0) { - git_oid *id = git_array_alloc(parents); + while (line_start < line_end && *line_start == ' ') { + git_oid *id = git_array_alloc(parents); + GIT_ERROR_CHECK_ALLOC(id); - git_oid_cpy(id, &parent_oid); - line_start += GIT_OID_HEXSZ; - if (line_start >= line_end) { - break; - } - line_start += 1; - } + if (git_oid_fromstrn(id, ++line_start, GIT_OID_HEXSZ) < 0) + goto invalid_oid; + line_start += GIT_OID_HEXSZ; } - if (git_grafts_add(repo->grafts, &graft_oid, parents) < 0) { - git_error_set(GIT_ERROR_REPOSITORY, "Invalid graft at line %d", line_num); - error = -1; + if ((error = git_grafts_add(repo->grafts, &graft_oid, parents)) < 0) goto cleanup; - } + git_array_clear(parents); - line_num++; + continue; + +invalid_oid: + git_error_set(GIT_ERROR_REPOSITORY, "invalid OID at line %" PRIuZ, parser.line_num); + error = -1; + goto cleanup; } cleanup: git_array_clear(parents); git_buf_dispose(&contents); + git_buf_dispose(&graft_path); return error; } From 05e286fba318d21147347a572b05b0d1dac79610 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 12 May 2020 11:30:27 +0200 Subject: [PATCH 0017/1616] grafts: move parsing into grafts module Parsing of grafts files is currently contained in the repository code. To make grafts-related logic more self-contained, move it into "grafts.c" instead. --- include/git2/errors.h | 3 +- src/grafts.c | 46 +++++++++++++ src/grafts.h | 1 + src/repository.c | 37 +---------- tests/grafts/parse.c | 149 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 199 insertions(+), 37 deletions(-) create mode 100644 tests/grafts/parse.c diff --git a/include/git2/errors.h b/include/git2/errors.h index 8887b329901..47a79b76ccb 100644 --- a/include/git2/errors.h +++ b/include/git2/errors.h @@ -108,7 +108,8 @@ typedef enum { GIT_ERROR_WORKTREE, GIT_ERROR_SHA1, GIT_ERROR_HTTP, - GIT_ERROR_INTERNAL + GIT_ERROR_INTERNAL, + GIT_ERROR_GRAFTS } git_error_t; /** diff --git a/src/grafts.c b/src/grafts.c index 90490d0ac29..8ae39f4ac0b 100644 --- a/src/grafts.c +++ b/src/grafts.c @@ -7,6 +7,8 @@ #include "grafts.h" +#include "parse.h" + struct git_grafts { /* Map of `git_commit_graft`s */ git_oidmap *commits; @@ -51,6 +53,50 @@ void git_grafts_clear(git_grafts *grafts) git_oidmap_clear(grafts->commits); } +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; diff --git a/src/grafts.h b/src/grafts.h index 76e8d3f2966..723792ded83 100644 --- a/src/grafts.h +++ b/src/grafts.h @@ -23,6 +23,7 @@ int git_grafts_new(git_grafts **out); void git_grafts_free(git_grafts *grafts); void git_grafts_clear(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); diff --git a/src/repository.c b/src/repository.c index 4465d8e7968..7721c3cd00a 100644 --- a/src/repository.c +++ b/src/repository.c @@ -31,7 +31,6 @@ #include "annotated_commit.h" #include "submodule.h" #include "worktree.h" -#include "parse.h" #include "strmap.h" @@ -582,10 +581,8 @@ static int find_repo( static int load_grafts(git_repository *repo) { - git_array_oid_t parents = GIT_ARRAY_INIT; git_buf graft_path = GIT_BUF_INIT; git_buf contents = GIT_BUF_INIT; - git_parse_ctx parser; int error, updated; if ((error = git_repository_item_path(&graft_path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0) @@ -604,42 +601,10 @@ static int load_grafts(git_repository *repo) goto cleanup; } - git_grafts_clear(repo->grafts); - - if ((error = git_parse_ctx_init(&parser, contents.ptr, contents.size)) < 0) - goto cleanup; - - 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 (git_oid_fromstrn(&graft_oid, line_start, GIT_OID_HEXSZ) < 0) - goto invalid_oid; - 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 (git_oid_fromstrn(id, ++line_start, GIT_OID_HEXSZ) < 0) - goto invalid_oid; - line_start += GIT_OID_HEXSZ; - } - - if ((error = git_grafts_add(repo->grafts, &graft_oid, parents)) < 0) - goto cleanup; - - git_array_clear(parents); - continue; - -invalid_oid: - git_error_set(GIT_ERROR_REPOSITORY, "invalid OID at line %" PRIuZ, parser.line_num); - error = -1; + if ((error = git_grafts_parse(repo->grafts, contents.ptr, contents.size)) < 0) goto cleanup; - } cleanup: - git_array_clear(parents); git_buf_dispose(&contents); git_buf_dispose(&graft_path); diff --git a/tests/grafts/parse.c b/tests/grafts/parse.c new file mode 100644 index 00000000000..de110c90110 --- /dev/null +++ b/tests/grafts/parse.c @@ -0,0 +1,149 @@ +#include "clar_libgit2.h" + +#include "grafts.h" + +#define OID0 "c0368f9f9743e950e6cfe1f45a649f8a9dfcd97e" +#define OID1 "cfc50a0db87ce908fb8a8c5b8f7b4ab96eee8643" +#define OID2 "6914d97cd08b9edf5e855fca211c750fa82fd80a" +#define OID3 "516521937d0e9ce9d0d836149a0702671f326b4a" +#define OID4 "e2c29d67ef2f217650196f94c796f0532b8caad6" +#define OID5 "79bcb936596cb50353fe7be28b7444e66e4a2842" +#define OID6 "b9c54107d57c17dbcaf646c4d52f66eb9e69d23d" +#define OID7 "9f8a746e9ad7b58cc840016bc3944d5ad262acb5" +#define OID8 "392f4beef7d0d15b2bc5b1abe1a754eba0ec36da" + +#define OID_TRUNCATED "392f4beef7d0d15b2bc5b1abe1a754eba0ec36d" +#define OID_NONHEX "9f8a746e9ax7b58cc840016bc3944d5ad262acb5" + +static git_grafts *grafts; + +void test_grafts_parse__initialize(void) +{ + cl_git_pass(git_grafts_new(&grafts)); +} + +void test_grafts_parse__cleanup(void) +{ + git_grafts_free(grafts); + grafts = NULL; +} + +static void assert_parse_succeeds(git_grafts *grafts, const char *string, size_t n) +{ + cl_git_pass(git_grafts_parse(grafts, string, strlen(string))); + cl_assert_equal_i(git_grafts_size(grafts), n); +} + +static void assert_parse_fails(git_grafts *grafts, const char *string) +{ + cl_git_fail(git_grafts_parse(grafts, string, strlen(string))); +} + +static void assert_graft_contains(git_grafts *grafts, const char *graft, size_t n, ...) +{ + git_commit_graft *commit; + git_oid oid; + va_list ap; + size_t i = 0; + + cl_git_pass(git_oid_fromstr(&oid, graft)); + cl_git_pass(git_grafts_get(&commit, grafts, &oid)); + cl_assert_equal_oid(&commit->oid, &oid); + cl_assert_equal_i(commit->parents.size, n); + + va_start(ap, n); + while (i < n) { + cl_git_pass(git_oid_fromstr(&oid, va_arg(ap, const char *))); + cl_assert_equal_oid(&commit->parents.ptr[i], &oid); + i++; + } + va_end(ap); +} + +void test_grafts_parse__single_oid(void) +{ + assert_parse_succeeds(grafts, OID1, 1); + assert_graft_contains(grafts, OID1, 0); +} + +void test_grafts_parse__single_oid_with_newline(void) +{ + assert_parse_succeeds(grafts, OID1 "\n", 1); + assert_graft_contains(grafts, OID1, 0); +} + +void test_grafts_parse__multiple_oids(void) +{ + assert_parse_succeeds(grafts, OID1 "\n" OID2 "\n" OID3, 3); + assert_graft_contains(grafts, OID1, 0); + assert_graft_contains(grafts, OID2, 0); + assert_graft_contains(grafts, OID3, 0); +} + +void test_grafts_parse__same_oid(void) +{ + assert_parse_succeeds(grafts, OID1 "\n" OID1, 1); + assert_graft_contains(grafts, OID1, 0); +} + +void test_grafts_parse__oid_with_parent(void) +{ + assert_parse_succeeds(grafts, OID1 " " OID2, 1); + assert_graft_contains(grafts, OID1, 1, OID2); +} + +void test_grafts_parse__oid_with_parent_and_newline(void) +{ + assert_parse_succeeds(grafts, OID1 " " OID2 "\n", 1); + assert_graft_contains(grafts, OID1, 1, OID2); +} + +void test_grafts_parse__oid_with_multiple_parents(void) +{ + assert_parse_succeeds(grafts, OID1 " " OID2 " " OID3 " " OID4 " " OID5, 1); + assert_graft_contains(grafts, OID1, 4, OID2, OID3, OID4, OID5); +} + +void test_grafts_parse__multiple_oids_with_multiple_parents(void) +{ + assert_parse_succeeds(grafts, + OID1 " " OID2 " " OID3 " " OID4 " " OID5 "\n" + OID6 " " OID7 " " OID8 "\n" , 2); + assert_graft_contains(grafts, OID1, 4, OID2, OID3, OID4, OID5); + assert_graft_contains(grafts, OID6, 2, OID7, OID8); +} + +void test_grafts_parse__multiple_spaces_fails(void) +{ + assert_parse_fails(grafts, OID1 " " OID2); +} + +void test_grafts_parse__trailing_space_fails(void) +{ + assert_parse_fails(grafts, OID1 " " OID2 " "); +} + +void test_grafts_parse__invalid_character_inbetween_fails(void) +{ + assert_parse_fails(grafts, OID1 " x " OID2); +} + +void test_grafts_parse__truncated_oid_fails(void) +{ + assert_parse_fails(grafts, OID_TRUNCATED); +} + +void test_grafts_parse__truncated_parent_fails(void) +{ + assert_parse_fails(grafts, OID1 " " OID_TRUNCATED); +} + +void test_grafts_parse__invalid_oid_fails(void) +{ + assert_parse_fails(grafts, OID_NONHEX); +} + +void test_grafts_parse__invalid_parent_fails(void) +{ + assert_parse_fails(grafts, OID1 " " OID_NONHEX); +} From a11026ecbb3575b02638ae060b20e77227e2291c Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 24 Oct 2019 13:30:24 +0200 Subject: [PATCH 0018/1616] repository: reuse grafts for shallow roots The shallow roots are in fact another user of the grafting mechanism, and in essence they do use the same file format for grafted commits. Thus, instead of hand-coding the parsing logic a second time, we can just reuse the `git_grafts` structure for shallow commits, as well. --- include/git2/repository.h | 3 +- src/grafts.c | 21 ++++++++ src/grafts.h | 1 + src/repository.c | 103 ++++++++++++-------------------------- src/repository.h | 4 +- tests/grafts/shallow.c | 21 ++++---- 6 files changed, 68 insertions(+), 85 deletions(-) diff --git a/include/git2/repository.h b/include/git2/repository.h index 5a27cf08e8d..59e938710c7 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -878,7 +878,8 @@ GIT_EXTERN(int) git_repository_is_shallow(git_repository *repo); /** * Determine the shallow roots of the repository * - * This oidarray is owned by the library. Do not free it. + * The resulting OID array needs to be free'd by calling + * `git_oidarray_free`. * * @param out An array of shallow oids. * @param repo The repository diff --git a/src/grafts.c b/src/grafts.c index 8ae39f4ac0b..23b012ce8eb 100644 --- a/src/grafts.c +++ b/src/grafts.c @@ -7,6 +7,7 @@ #include "grafts.h" +#include "oidarray.h" #include "parse.h" struct git_grafts { @@ -155,6 +156,26 @@ 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) +{ + 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/grafts.h b/src/grafts.h index 723792ded83..305b0d61adf 100644 --- a/src/grafts.h +++ b/src/grafts.h @@ -27,6 +27,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); size_t git_grafts_size(git_grafts *grafts); #endif diff --git a/src/repository.c b/src/repository.c index 7721c3cd00a..fc14ef4d6e2 100644 --- a/src/repository.c +++ b/src/repository.c @@ -148,7 +148,7 @@ int git_repository__cleanup(git_repository *repo) git_cache_clear(&repo->objects); git_attr_cache_flush(repo); git_grafts_free(repo->grafts); - git_array_clear(repo->shallow_oids); + git_grafts_free(repo->shallow_grafts); set_config(repo, NULL); set_index(repo, NULL); @@ -613,22 +613,22 @@ static int load_grafts(git_repository *repo) static int load_shallow(git_repository *repo) { - int error = 0; - git_array_oid_t roots = GIT_ARRAY_INIT; git_array_oid_t parents = GIT_ARRAY_INIT; + git_oidarray roots; + int error; size_t i; - git_oid *graft_oid; /* Graft shallow roots */ - if ((error = git_repository__shallow_roots(&roots, repo)) < 0) { - return error; - } + if ((error = git_repository_shallow_roots(&roots, repo)) < 0) + goto out; - git_array_foreach(roots, i, graft_oid) { - if ((error = git_grafts_add(repo->grafts, graft_oid, parents)) < 0) - return error; - } - return 0; + for (i = 0; i < roots.count; i++) + if ((error = git_grafts_add(repo->grafts, &roots.ids[i], parents)) < 0) + goto out; + +out: + git_oidarray_free(&roots); + return error; } int git_repository_open_bare( @@ -2960,79 +2960,38 @@ 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_oidarray *out, git_repository *repo) { - git_buf path = GIT_BUF_INIT; - git_buf contents = GIT_BUF_INIT; - int error, updated, line_num = 1; - char *line; - char *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); - git_buf_dispose(&path); + git_buf path = GIT_BUF_INIT, contents = GIT_BUF_INIT; + int error, updated = 0; - if (error < 0 && error != GIT_ENOTFOUND) - return error; - - /* cancel out GIT_ENOTFOUND */ - git_error_clear(); - error = 0; - - if (!updated) { - *out = repo->shallow_oids; - goto cleanup; - } + assert(out && repo); - git_array_clear(repo->shallow_oids); + memset(out, 0, sizeof(*out)); - buffer = contents.ptr; - while ((line = git__strsep(&buffer, "\n")) != NULL) { - git_oid *oid = git_array_alloc(repo->shallow_oids); + if (!repo->shallow_grafts && (error = git_grafts_new(&repo->shallow_grafts)) < 0) + goto error; - 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_oids); - error = -1; - goto cleanup; - } - ++line_num; + if ((error = git_buf_joinpath(&path, repo->gitdir, "shallow")) < 0 || + (error = git_futils_readbuffer_updated(&contents, git_buf_cstr(&path), + &repo->shallow_checksum, &updated)) < 0) { + if (error == GIT_ENOTFOUND) + error = 0; + goto error; } - if (*buffer) { - git_error_set(GIT_ERROR_REPOSITORY, "No EOL at line %d", line_num); - git_array_clear(repo->shallow_oids); - error = -1; - goto cleanup; - } + if (updated && (error = git_grafts_parse(repo->shallow_grafts, contents.ptr, contents.size)) < 0) + goto error; - *out = repo->shallow_oids; + if ((error = git_grafts_get_oids(out, repo->shallow_grafts)) < 0) + goto error; -cleanup: +error: + git_buf_dispose(&path); git_buf_dispose(&contents); - 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_buf path = GIT_BUF_INIT; diff --git a/src/repository.h b/src/repository.h index fd7c274a8dc..14b2665675e 100644 --- a/src/repository.h +++ b/src/repository.h @@ -157,8 +157,8 @@ struct git_repository { git_grafts *grafts; git_oid graft_checksum; + git_grafts *shallow_grafts; git_oid shallow_checksum; - git_array_oid_t shallow_oids; git_atomic attr_session_key; @@ -263,6 +263,4 @@ extern size_t git_repository__reserved_names_posix_len; bool git_repository__reserved_names( git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs); -int git_repository__shallow_roots(git_array_oid_t *out, git_repository *repo); - #endif diff --git a/tests/grafts/shallow.c b/tests/grafts/shallow.c index e4a0f741f0b..fc74de4385b 100644 --- a/tests/grafts/shallow.c +++ b/tests/grafts/shallow.c @@ -42,38 +42,41 @@ void test_grafts_shallow__clears_errors(void) void test_grafts_shallow__shallow_oids(void) { - git_oidarray oids, oids2; + git_oidarray oids; g_repo = cl_git_sandbox_init("shallow.git"); cl_git_pass(git_repository_shallow_roots(&oids, g_repo)); cl_assert_equal_i(1, oids.count); cl_assert_equal_oid(&g_shallow_oid, &oids.ids[0]); - cl_git_pass(git_repository_shallow_roots(&oids2, g_repo)); - cl_assert_equal_p(oids.ids, oids2.ids); + git_oidarray_free(&oids); } void test_grafts_shallow__cache_clearing(void) { - git_oidarray oids, oids2; + git_oidarray oids; git_oid tmp_oid; - git_oid_fromstr(&tmp_oid, "0000000000000000000000000000000000000000"); + cl_git_pass(git_oid_fromstr(&tmp_oid, "0000000000000000000000000000000000000000")); g_repo = cl_git_sandbox_init("shallow.git"); cl_git_pass(git_repository_shallow_roots(&oids, g_repo)); cl_assert_equal_i(1, oids.count); cl_assert_equal_oid(&g_shallow_oid, &oids.ids[0]); + git_oidarray_free(&oids); cl_git_mkfile("shallow.git/shallow", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644\n" "0000000000000000000000000000000000000000\n" ); - cl_git_pass(git_repository_shallow_roots(&oids2, g_repo)); - cl_assert_equal_i(2, oids2.count); - cl_assert_equal_oid(&g_shallow_oid, &oids2.ids[0]); - cl_assert_equal_oid(&tmp_oid, &oids2.ids[1]); + cl_git_pass(git_repository_shallow_roots(&oids, g_repo)); + cl_assert_equal_i(2, oids.count); + cl_assert((git_oid_equal(&g_shallow_oid, &oids.ids[0]) && + git_oid_equal(&tmp_oid, &oids.ids[1])) || + (git_oid_equal(&g_shallow_oid, &oids.ids[1]) && + git_oid_equal(&tmp_oid, &oids.ids[0]))); + git_oidarray_free(&oids); cl_git_pass(p_unlink("shallow.git/shallow")); cl_git_pass(git_repository_shallow_roots(&oids, g_repo)); From 70867f7c594ea6960c07d10fef32c932f7fa3bbb Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 3 Oct 2019 13:08:24 +0200 Subject: [PATCH 0019/1616] repository: disentangle shallow and normal grafts When loading shallow grafts, we add each of the grafting commits to the grafts backed by ".git/info/grafts". Keeping track of both grafts separately, but partially storing them in a common grafts structure is likely to lead to inconsistencies. In fact, there already are inconsistencies if refreshing shallow grafts at a later point, as we only refresh the shallows, but not the normal grafts in that case. Disentangle both grafting stores and instead check both separately when parsing commits. --- src/commit.c | 3 ++- src/repository.c | 11 ++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/commit.c b/src/commit.c index e06faafe781..b498fd77eb7 100644 --- a/src/commit.c +++ b/src/commit.c @@ -504,7 +504,8 @@ int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned return error; /* Perform necessary grafts */ - if (git_grafts_get(&graft, repo->grafts, git_odb_object_id(odb_obj)) != GIT_ENOTFOUND) { + 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); diff --git a/src/repository.c b/src/repository.c index fc14ef4d6e2..cad80845d32 100644 --- a/src/repository.c +++ b/src/repository.c @@ -613,22 +613,15 @@ static int load_grafts(git_repository *repo) static int load_shallow(git_repository *repo) { - git_array_oid_t parents = GIT_ARRAY_INIT; git_oidarray roots; int error; - size_t i; /* Graft shallow roots */ if ((error = git_repository_shallow_roots(&roots, repo)) < 0) - goto out; - - for (i = 0; i < roots.count; i++) - if ((error = git_grafts_add(repo->grafts, &roots.ids[i], parents)) < 0) - goto out; + return error; -out: git_oidarray_free(&roots); - return error; + return 0; } int git_repository_open_bare( From fd2398b2fc09e3ae292fb33f2ec2a45b6bf8e3e9 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 3 Oct 2019 13:24:25 +0200 Subject: [PATCH 0020/1616] grafts: move refresh logic into grafts code The refresh logic for both "normal" and shallow grafts are currently part of the repository code and implemented twice. Unify them into the grafts code by introducing two new functions to create grafts from a file and to refresh a grafts structure. --- src/grafts.c | 55 ++++++++++++++++++++++++++++++++++++ src/grafts.h | 2 ++ src/repository.c | 73 ++++++++++-------------------------------------- src/repository.h | 3 -- 4 files changed, 72 insertions(+), 61 deletions(-) diff --git a/src/grafts.c b/src/grafts.c index 23b012ce8eb..da5bd10504b 100644 --- a/src/grafts.c +++ b/src/grafts.c @@ -7,12 +7,17 @@ #include "grafts.h" +#include "futils.h" #include "oidarray.h" #include "parse.h" 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) @@ -31,10 +36,32 @@ int git_grafts_new(git_grafts **out) 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); @@ -54,6 +81,34 @@ void git_grafts_clear(git_grafts *grafts) 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; diff --git a/src/grafts.h b/src/grafts.h index 305b0d61adf..30062725e27 100644 --- a/src/grafts.h +++ b/src/grafts.h @@ -20,9 +20,11 @@ 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); 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); diff --git a/src/repository.c b/src/repository.c index cad80845d32..730f19c20c7 100644 --- a/src/repository.c +++ b/src/repository.c @@ -256,9 +256,6 @@ static git_repository *repository_alloc(void) /* set all the entries in the configmap cache to `unset` */ git_repository__configmap_lookup_cache_clear(repo); - if (git_grafts_new(&repo->grafts) < 0) - goto on_error; - return repo; on_error: @@ -581,49 +578,25 @@ static int find_repo( static int load_grafts(git_repository *repo) { - git_buf graft_path = GIT_BUF_INIT; - git_buf contents = GIT_BUF_INIT; - int error, updated; - - if ((error = git_repository_item_path(&graft_path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0) - return error; - - if (git_buf_joinpath(&graft_path, graft_path.ptr, "grafts")) { - git_buf_dispose(&graft_path); - return error; - } + git_buf path = GIT_BUF_INIT; + int error; - error = git_futils_readbuffer_updated(&contents, git_buf_cstr(&graft_path), - &repo->graft_checksum, &updated); - if (error < 0 || error == GIT_ENOTFOUND || !updated) { - if (error == GIT_ENOTFOUND) - error = 0; - goto cleanup; - } + if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || + (error = git_buf_joinpath(&path, path.ptr, "grafts")) < 0 || + (error = git_grafts_from_file(&repo->grafts, path.ptr)) < 0) + goto error; - if ((error = git_grafts_parse(repo->grafts, contents.ptr, contents.size)) < 0) - goto cleanup; + git_buf_clear(&path); -cleanup: - git_buf_dispose(&contents); - git_buf_dispose(&graft_path); + if ((error = git_buf_joinpath(&path, repo->gitdir, "shallow")) < 0 || + (error = git_grafts_from_file(&repo->shallow_grafts, path.ptr)) < 0) + goto error; +error: + git_buf_dispose(&path); return error; } -static int load_shallow(git_repository *repo) -{ - git_oidarray roots; - int error; - - /* Graft shallow roots */ - if ((error = git_repository_shallow_roots(&roots, repo)) < 0) - return error; - - git_oidarray_free(&roots); - return 0; -} - int git_repository_open_bare( git_repository **repo_ptr, const char *bare_path) @@ -916,9 +889,6 @@ int git_repository_open_ext( if ((error = load_grafts(repo)) < 0) goto cleanup; - if ((error = load_shallow(repo)) < 0) - goto cleanup; - if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) repo->is_bare = 1; else { @@ -2956,27 +2926,14 @@ int git_repository_state_cleanup(git_repository *repo) int git_repository_shallow_roots(git_oidarray *out, git_repository *repo) { git_buf path = GIT_BUF_INIT, contents = GIT_BUF_INIT; - int error, updated = 0; + int error; assert(out && repo); memset(out, 0, sizeof(*out)); - if (!repo->shallow_grafts && (error = git_grafts_new(&repo->shallow_grafts)) < 0) - goto error; - - if ((error = git_buf_joinpath(&path, repo->gitdir, "shallow")) < 0 || - (error = git_futils_readbuffer_updated(&contents, git_buf_cstr(&path), - &repo->shallow_checksum, &updated)) < 0) { - if (error == GIT_ENOTFOUND) - error = 0; - goto error; - } - - if (updated && (error = git_grafts_parse(repo->shallow_grafts, contents.ptr, contents.size)) < 0) - goto error; - - if ((error = git_grafts_get_oids(out, repo->shallow_grafts)) < 0) + if ((error = git_grafts_refresh(repo->shallow_grafts)) < 0 || + (error = git_grafts_get_oids(out, repo->shallow_grafts)) < 0) goto error; error: diff --git a/src/repository.h b/src/repository.h index 14b2665675e..81f2bc10114 100644 --- a/src/repository.h +++ b/src/repository.h @@ -155,10 +155,7 @@ struct git_repository { unsigned int lru_counter; git_grafts *grafts; - git_oid graft_checksum; - git_grafts *shallow_grafts; - git_oid shallow_checksum; git_atomic attr_session_key; From a4803c3c5ae2d3e038d56fcfe52215bc2364521a Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 10 Oct 2019 13:40:22 +0200 Subject: [PATCH 0021/1616] grafts: fix memory leak if replacing pre-existing graft If replacing an already existing graft in the grafts map, then we need to free the previous `git_commit_graft` structure. --- src/grafts.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/grafts.c b/src/grafts.c index da5bd10504b..55eb33615ab 100644 --- a/src/grafts.c +++ b/src/grafts.c @@ -174,6 +174,8 @@ int git_grafts_add(git_grafts *grafts, const git_oid *oid, git_array_oid_t paren } 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; @@ -198,6 +200,7 @@ int git_grafts_remove(git_grafts *grafts, const git_oid *oid) if ((error = git_oidmap_delete(grafts->commits, oid)) < 0) return error; + git__free(graft->parents.ptr); git__free(graft); return 0; From 79af067665c37b6dc0b31edb35596c362b0cd9a0 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 24 Oct 2019 13:54:42 +0200 Subject: [PATCH 0022/1616] repository: do not expose grafting mechanism Currently, we expose the function `git_repository_shallow_roots` to get all grafted roots of the repository. This already paints us into a corner, though, as we certainly need to experiment with some functionality of the grafting mechanism before we can happily expose some of its functionality. Most importantly, we need to get right when to refresh grafts and when not. Thus, this commit removes the public function with no public replacement. We should first try and see what usecases people come up with to e.g. expose the `git_grafts` mechanism directly in the future or do something different altogether. Instead, we provide an internal interface to get weak pointers to the grafting structs part of the repository itself. --- include/git2/repository.h | 12 --------- src/repository.c | 33 +++++++++++------------- src/repository.h | 2 ++ tests/grafts/shallow.c | 53 ++++++++++++++++++++------------------- 4 files changed, 43 insertions(+), 57 deletions(-) diff --git a/include/git2/repository.h b/include/git2/repository.h index 59e938710c7..aa81e384352 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -875,18 +875,6 @@ GIT_EXTERN(const char *) git_repository_get_namespace(git_repository *repo); */ GIT_EXTERN(int) git_repository_is_shallow(git_repository *repo); -/** - * Determine the shallow roots of the repository - * - * The resulting OID array needs to be free'd by calling - * `git_oidarray_free`. - * - * @param out An array of shallow oids. - * @param repo The repository - * @return 0 on success, an error otherwise. - */ -GIT_EXTERN(int) git_repository_shallow_roots(git_oidarray *out, git_repository *repo); - /** * Retrieve the configured identity to use for reflogs * diff --git a/src/repository.c b/src/repository.c index 730f19c20c7..bc5ee6ac059 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1263,6 +1263,20 @@ int git_repository_set_index(git_repository *repo, git_index *index) return 0; } +int git_repository_grafts__weakptr(git_grafts **out, git_repository *repo) +{ + assert(out && repo && repo->shallow_grafts); + *out = repo->grafts; + return 0; +} + +int git_repository_shallow_grafts__weakptr(git_grafts **out, git_repository *repo) +{ + assert(out && repo && repo->shallow_grafts); + *out = repo->shallow_grafts; + return 0; +} + int git_repository_set_namespace(git_repository *repo, const char *namespace) { git__free(repo->namespace); @@ -2923,25 +2937,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_oidarray *out, git_repository *repo) -{ - git_buf path = GIT_BUF_INIT, contents = GIT_BUF_INIT; - int error; - - assert(out && repo); - - memset(out, 0, sizeof(*out)); - - if ((error = git_grafts_refresh(repo->shallow_grafts)) < 0 || - (error = git_grafts_get_oids(out, repo->shallow_grafts)) < 0) - goto error; - -error: - git_buf_dispose(&path); - git_buf_dispose(&contents); - return error; -} - int git_repository_is_shallow(git_repository *repo) { git_buf path = GIT_BUF_INIT; diff --git a/src/repository.h b/src/repository.h index 81f2bc10114..5922bf02a07 100644 --- a/src/repository.h +++ b/src/repository.h @@ -211,6 +211,8 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo); int git_repository_odb__weakptr(git_odb **out, git_repository *repo); int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo); int git_repository_index__weakptr(git_index **out, git_repository *repo); +int git_repository_grafts__weakptr(git_grafts **out, git_repository *repo); +int git_repository_shallow_grafts__weakptr(git_grafts **out, git_repository *repo); /* * Configuration map cache diff --git a/tests/grafts/shallow.c b/tests/grafts/shallow.c index fc74de4385b..8fe3421f280 100644 --- a/tests/grafts/shallow.c +++ b/tests/grafts/shallow.c @@ -1,5 +1,8 @@ #include "clar_libgit2.h" + #include "futils.h" +#include "grafts.h" +#include "repository.h" static git_repository *g_repo; static git_oid g_shallow_oid; @@ -42,61 +45,59 @@ void test_grafts_shallow__clears_errors(void) void test_grafts_shallow__shallow_oids(void) { - git_oidarray oids; - g_repo = cl_git_sandbox_init("shallow.git"); + git_commit_graft *graft; + git_grafts *grafts; - cl_git_pass(git_repository_shallow_roots(&oids, g_repo)); - cl_assert_equal_i(1, oids.count); - cl_assert_equal_oid(&g_shallow_oid, &oids.ids[0]); + g_repo = cl_git_sandbox_init("shallow.git"); - git_oidarray_free(&oids); + cl_git_pass(git_repository_shallow_grafts__weakptr(&grafts, g_repo)); + cl_assert_equal_i(1, git_grafts_size(grafts)); + cl_git_pass(git_grafts_get(&graft, grafts, &g_shallow_oid)); } void test_grafts_shallow__cache_clearing(void) { - git_oidarray oids; + git_commit_graft *graft; + git_grafts *grafts; git_oid tmp_oid; cl_git_pass(git_oid_fromstr(&tmp_oid, "0000000000000000000000000000000000000000")); g_repo = cl_git_sandbox_init("shallow.git"); + cl_git_pass(git_repository_shallow_grafts__weakptr(&grafts, g_repo)); - cl_git_pass(git_repository_shallow_roots(&oids, g_repo)); - cl_assert_equal_i(1, oids.count); - cl_assert_equal_oid(&g_shallow_oid, &oids.ids[0]); - git_oidarray_free(&oids); + cl_assert_equal_i(1, git_grafts_size(grafts)); + cl_git_pass(git_grafts_get(&graft, grafts, &g_shallow_oid)); cl_git_mkfile("shallow.git/shallow", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644\n" "0000000000000000000000000000000000000000\n" ); - cl_git_pass(git_repository_shallow_roots(&oids, g_repo)); - cl_assert_equal_i(2, oids.count); - cl_assert((git_oid_equal(&g_shallow_oid, &oids.ids[0]) && - git_oid_equal(&tmp_oid, &oids.ids[1])) || - (git_oid_equal(&g_shallow_oid, &oids.ids[1]) && - git_oid_equal(&tmp_oid, &oids.ids[0]))); - git_oidarray_free(&oids); + cl_git_pass(git_grafts_refresh(grafts)); + cl_assert_equal_i(2, git_grafts_size(grafts)); + cl_git_pass(git_grafts_get(&graft, grafts, &g_shallow_oid)); + cl_git_pass(git_grafts_get(&graft, grafts, &tmp_oid)); cl_git_pass(p_unlink("shallow.git/shallow")); - cl_git_pass(git_repository_shallow_roots(&oids, g_repo)); - cl_assert_equal_i(0, oids.count); - git_oidarray_free(&oids); + cl_git_pass(git_grafts_refresh(grafts)); + cl_assert_equal_i(0, git_grafts_size(grafts)); } void test_grafts_shallow__errors_on_borked(void) { - git_oidarray oids; + git_grafts *grafts; g_repo = cl_git_sandbox_init("shallow.git"); cl_git_mkfile("shallow.git/shallow", "lolno"); - - cl_git_fail_with(-1, git_repository_shallow_roots(&oids, g_repo)); + cl_git_pass(git_repository_shallow_grafts__weakptr(&grafts, g_repo)); + cl_git_fail(git_grafts_refresh(grafts)); + cl_assert_equal_i(0, git_grafts_size(grafts)); cl_git_mkfile("shallow.git/shallow", "lolno\n"); - - cl_git_fail_with(-1, git_repository_shallow_roots(&oids, g_repo)); + cl_git_pass(git_repository_shallow_grafts__weakptr(&grafts, g_repo)); + cl_git_fail(git_grafts_refresh(grafts)); + cl_assert_equal_i(0, git_grafts_size(grafts)); } void test_grafts_shallow__revwalk_behavior(void) From 896b1db493245f5ecbbb328b4d1485e44d4a1e27 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Mon, 3 Aug 2020 07:17:52 -0700 Subject: [PATCH 0023/1616] Add a ThreadSanitizer build This change adds a ThreadSanitizer CI build rule. It's informative for now because there are still known places where there are races. Part of: #5592 --- .github/workflows/main.yml | 13 +++++++++++++ script/thread-sanitizer.supp | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 script/thread-sanitizer.supp diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 29507c8f03a..9c16127b300 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -109,6 +109,18 @@ jobs: SKIP_NEGOTIATE_TESTS: true ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 os: ubuntu-latest + - # Focal, Clang 10, OpenSSL, ThreadSanitizer + image: focal + env: + CC: clang-10 + CFLAGS: -fsanitize=thread -fno-optimize-sibling-calls -fno-omit-frame-pointer + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON + CMAKE_GENERATOR: Ninja + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 + TSAN_OPTIONS: suppressions=/home/libgit2/source/script/thread-sanitizer.supp second_deadlock_stack=1 + os: ubuntu-latest - # macOS os: macos-10.15 env: @@ -197,6 +209,7 @@ jobs: -e PKG_CONFIG_PATH \ -e SKIP_NEGOTIATE_TESTS \ -e SKIP_SSH_TESTS \ + -e TSAN_OPTIONS \ ${{ env.docker-registry-container-sha }} \ /bin/bash -c "mkdir build && cd build && ../azure-pipelines/build.sh && ../azure-pipelines/test.sh" else diff --git a/script/thread-sanitizer.supp b/script/thread-sanitizer.supp new file mode 100644 index 00000000000..757a0e79cd7 --- /dev/null +++ b/script/thread-sanitizer.supp @@ -0,0 +1,18 @@ +# In attr_file_free, the locks are acquired in the opposite order in which they +# are normally acquired. This is probably something worth fixing to have a +# consistent lock hierarchy that is easy to understand. +deadlock:attr_cache_lock + +# When invoking the time/timezone functions from git_signature_now(), they +# access libc methods that need to be instrumented to correctly analyze the +# data races. +called_from_lib:libc.so.6 + +# TODO(#5595): Remove these once the fixes land. +race:src/odb.c +race:git_repository_odb__weakptr +race:cache_store + +# TODO(#5595): Investigate and fix this. It can be triggered by the `thread` +# test suite. +race:git_filter_list__load_ext From d79bb1595ce3678b925da02542bc97f789697d97 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 11 Oct 2020 11:41:38 +0100 Subject: [PATCH 0024/1616] ntlm: update ntlm dependency for htonll Update ntlm to include an htonll that is not dependent on system libraries. --- deps/ntlmclient/compat.h | 34 --------------------------------- deps/ntlmclient/crypt_openssl.c | 2 +- deps/ntlmclient/ntlm.c | 10 +++++----- deps/ntlmclient/util.c | 16 +++++++++++++++- deps/ntlmclient/util.h | 3 ++- 5 files changed, 23 insertions(+), 42 deletions(-) diff --git a/deps/ntlmclient/compat.h b/deps/ntlmclient/compat.h index 6e5ef6466c2..befc7cc4fb3 100644 --- a/deps/ntlmclient/compat.h +++ b/deps/ntlmclient/compat.h @@ -21,40 +21,6 @@ # include #endif -#if defined(_WIN32) || defined(__APPLE__) -/* winsock and macOS > 10.9 have htonll already */ -#elif defined(__linux__) -/* See man page endian(3) */ -# include -# define htonll htobe64 -#elif defined(__NetBSD__) || defined(__OpenBSD__) -/* See man page htobe64(3) */ -# include -# define htonll htobe64 -#elif defined(__FreeBSD__) -/* See man page bwaps64(9) */ -# include -# define htonll htobe64 -#elif defined(sun) || defined(__sun) -/* See man page byteorder(3SOCKET) */ -# include -# include -# include - -# if !defined(htonll) -# if defined(_BIG_ENDIAN) -# define htonll(x) (x) -# else -# define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl((uint64_t)(x) >> 32)) -# endif -# endif -#elif defined(__HAIKU__) -# include -# define htonll B_HOST_TO_BENDIAN_INT64 -#else -# error "Please implement htonll for your platform" -#endif - #ifndef MIN # define MIN(x, y) (((x) < (y)) ? (x) : (y)) #endif diff --git a/deps/ntlmclient/crypt_openssl.c b/deps/ntlmclient/crypt_openssl.c index 785be10e50f..c0d36d891bc 100644 --- a/deps/ntlmclient/crypt_openssl.c +++ b/deps/ntlmclient/crypt_openssl.c @@ -71,7 +71,7 @@ static inline void HMAC_CTX_free(HMAC_CTX *ctx) static inline int HMAC_CTX_reset(HMAC_CTX *ctx) { HMAC_CTX_cleanup(ctx); - memzero(ctx, sizeof(HMAC_CTX)); + ntlm_memzero(ctx, sizeof(HMAC_CTX)); return 1; } diff --git a/deps/ntlmclient/ntlm.c b/deps/ntlmclient/ntlm.c index 74224bbea10..470a9014373 100644 --- a/deps/ntlmclient/ntlm.c +++ b/deps/ntlmclient/ntlm.c @@ -132,10 +132,10 @@ int ntlm_client_set_hostname( static void free_credentials(ntlm_client *ntlm) { if (ntlm->password) - memzero(ntlm->password, strlen(ntlm->password)); + ntlm_memzero(ntlm->password, strlen(ntlm->password)); if (ntlm->password_utf16) - memzero(ntlm->password_utf16, ntlm->password_utf16_len); + ntlm_memzero(ntlm->password_utf16, ntlm->password_utf16_len); free(ntlm->username); free(ntlm->username_upper); @@ -1125,7 +1125,7 @@ static bool generate_lm2_response(ntlm_client *ntlm, size_t lm2_len = 16; uint64_t local_nonce; - local_nonce = htonll(ntlm->nonce); + local_nonce = ntlm_htonll(ntlm->nonce); if (!ntlm_hmac_ctx_reset(ntlm->hmac_ctx) || !ntlm_hmac_md5_init(ntlm->hmac_ctx, @@ -1197,8 +1197,8 @@ static bool generate_ntlm2_response(ntlm_client *ntlm) /* the blob's integer values are in network byte order */ signature = htonl(0x01010000); - timestamp = htonll(ntlm->timestamp); - nonce = htonll(ntlm->nonce); + timestamp = ntlm_htonll(ntlm->timestamp); + nonce = ntlm_htonll(ntlm->nonce); /* construct the blob */ memcpy(&blob[0], &signature, 4); diff --git a/deps/ntlmclient/util.c b/deps/ntlmclient/util.c index d0e3e53be5a..07d10f6c609 100644 --- a/deps/ntlmclient/util.c +++ b/deps/ntlmclient/util.c @@ -8,14 +8,28 @@ #include #include +#include #include "compat.h" #include "util.h" -void memzero(void *data, size_t size) +void ntlm_memzero(void *data, size_t size) { volatile uint8_t *scan = (volatile uint8_t *)data; while (size--) *scan++ = 0x0; } + +uint64_t ntlm_htonll(uint64_t value) +{ + static union { + uint32_t i; + char c[8]; + } test = { 0x01020304 }; + + if (test.c[0] == 0x01) + return value; + else + return ((uint64_t)htonl(value) << 32) | htonl((uint64_t)value >> 32); +} diff --git a/deps/ntlmclient/util.h b/deps/ntlmclient/util.h index 1c1806ba37d..d4bb472ccc4 100644 --- a/deps/ntlmclient/util.h +++ b/deps/ntlmclient/util.h @@ -9,6 +9,7 @@ #ifndef PRIVATE_UTIL_H__ #define PRIVATE_UTIL_H__ -extern void memzero(void *data, size_t size); +extern void ntlm_memzero(void *data, size_t size); +extern uint64_t ntlm_htonll(uint64_t value); #endif /* PRIVATE_UTIL_H__ */ From fe12423a91015e6116773340a8936fece3251339 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 12 May 2020 13:08:22 +0100 Subject: [PATCH 0025/1616] init: move thread init to git_global_threads_init Instead of treating win32 thread initialization specially in the win32 git_libgit2_init function, add a git_global_threads_init function. --- src/global.c | 3 +-- src/thread-utils.h | 2 ++ src/unix/pthread.h | 3 ++- src/win32/thread.c | 2 +- src/win32/thread.h | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/global.c b/src/global.c index 9fe8cd5d381..4abb5e3875e 100644 --- a/src/global.c +++ b/src/global.c @@ -31,6 +31,7 @@ typedef int (*git_global_init_fn)(void); static git_global_init_fn git__init_callbacks[] = { git_allocator_global_init, + git_threads_global_init, git_hash_global_init, git_sysdir_global_init, git_filter_global_init, @@ -159,8 +160,6 @@ static int synchronized_threads_init(void) if ((_fls_index = FlsAlloc(fls_free)) == FLS_OUT_OF_INDEXES) return -1; - git_threads_init(); - if (git_mutex_init(&git__mwindow_mutex)) return -1; diff --git a/src/thread-utils.h b/src/thread-utils.h index ecb4909f554..8e1e7c97a96 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -235,6 +235,8 @@ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a) #else +GIT_INLINE(int) git_threads_global_init(void) { return 0; } + #define git_thread unsigned int #define git_thread_create(thread, start_routine, arg) 0 #define git_thread_join(id, status) (void)0 diff --git a/src/unix/pthread.h b/src/unix/pthread.h index 233561b4e0c..55f4ae227ee 100644 --- a/src/unix/pthread.h +++ b/src/unix/pthread.h @@ -12,7 +12,8 @@ typedef struct { pthread_t thread; } git_thread; -#define git_threads_init() (void)0 +GIT_INLINE(int) git_threads_global_init(void) { return 0; } + #define git_thread_create(git_thread_ptr, start_routine, arg) \ pthread_create(&(git_thread_ptr)->thread, NULL, start_routine, arg) #define git_thread_join(git_thread_ptr, status) \ diff --git a/src/win32/thread.c b/src/win32/thread.c index 42dba7f9740..0936c31687b 100644 --- a/src/win32/thread.c +++ b/src/win32/thread.c @@ -35,7 +35,7 @@ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter) return CLEAN_THREAD_EXIT; } -int git_threads_init(void) +int git_threads_global_init(void) { HMODULE hModule = GetModuleHandleW(L"kernel32"); diff --git a/src/win32/thread.h b/src/win32/thread.h index 41cbf015b59..8305036b4d6 100644 --- a/src/win32/thread.h +++ b/src/win32/thread.h @@ -35,7 +35,7 @@ typedef struct { } native; } git_rwlock; -int git_threads_init(void); +int git_threads_global_init(void); int git_thread_create(git_thread *GIT_RESTRICT, void *(*) (void *), From 521aa8c1c04c25a57b82e1279a4e91d8a07436aa Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 12 May 2020 13:21:26 +0100 Subject: [PATCH 0026/1616] win32: teach the allocator to deal with crtdbg Move the MSVC C runtime debugging bits into the allocator's global init function. --- src/alloc.c | 20 ++++++++++++++++++++ src/allocators/win32_crtdbg.c | 1 + src/global.c | 15 --------------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/alloc.c b/src/alloc.c index 51c4d80292e..7bfbbdaa8c0 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -10,6 +10,11 @@ #include "allocators/stdalloc.h" #include "allocators/win32_crtdbg.h" +#if defined(GIT_MSVC_CRTDBG) +# include "win32/w32_stack.h" +# include "win32/w32_crtdbg_stacktrace.h" +#endif + git_allocator git__allocator; static int setup_default_allocator(void) @@ -21,8 +26,23 @@ static int setup_default_allocator(void) #endif } +#if defined(GIT_MSVC_CRTDBG) +static void allocator_global_shutdown(void) +{ + git_win32__crtdbg_stacktrace_cleanup(); + git_win32__stack_cleanup(); +} +#endif + int git_allocator_global_init(void) { +#if defined(GIT_MSVC_CRTDBG) + git_win32__crtdbg_stacktrace_init(); + git_win32__stack_init(); + + git__on_shutdown(allocator_global_shutdown); +#endif + /* * We don't want to overwrite any allocator which has been set before * the init function is called. diff --git a/src/allocators/win32_crtdbg.c b/src/allocators/win32_crtdbg.c index 1187e2fcd83..c726268a840 100644 --- a/src/allocators/win32_crtdbg.c +++ b/src/allocators/win32_crtdbg.c @@ -9,6 +9,7 @@ #if defined(GIT_MSVC_CRTDBG) +#include "win32/w32_stack.h" #include "win32/w32_crtdbg_stacktrace.h" static void *crtdbg__malloc(size_t len, const char *file, int line) diff --git a/src/global.c b/src/global.c index 4abb5e3875e..d2a25a50448 100644 --- a/src/global.c +++ b/src/global.c @@ -19,11 +19,7 @@ #include "thread-utils.h" #include "git2/global.h" #include "transports/ssh.h" - -#if defined(GIT_MSVC_CRTDBG) #include "win32/w32_stack.h" -#include "win32/w32_crtdbg_stacktrace.h" -#endif git_mutex git__mwindow_mutex; @@ -72,12 +68,6 @@ static int init_common(void) size_t i; int ret; - /* Initialize the CRT debug allocator first, before our first malloc */ -#if defined(GIT_MSVC_CRTDBG) - git_win32__crtdbg_stacktrace_init(); - git_win32__stack_init(); -#endif - /* Initialize subsystems that have global state */ for (i = 0; i < ARRAY_SIZE(git__init_callbacks); i++) if ((ret = git__init_callbacks[i]()) != 0) @@ -200,11 +190,6 @@ int git_libgit2_shutdown(void) FlsFree(_fls_index); git_mutex_free(&git__mwindow_mutex); - -#if defined(GIT_MSVC_CRTDBG) - git_win32__crtdbg_stacktrace_cleanup(); - git_win32__stack_cleanup(); -#endif } /* Exit the lock */ From 6554b40e42df831d7fc9c623d34b2738227dd8a2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 13 May 2020 10:39:33 +0100 Subject: [PATCH 0027/1616] settings: localize global data Move the settings global data teardown into its own separate function, instead of intermingled with the global state. --- src/global.c | 9 +++------ src/global.h | 3 --- src/settings.c | 32 ++++++++++++++++++++++---------- src/settings.h | 11 +++++++++++ src/streams/openssl.c | 1 + src/transports/http.h | 1 + tests/core/useragent.c | 2 +- 7 files changed, 39 insertions(+), 20 deletions(-) create mode 100644 src/settings.h diff --git a/src/global.c b/src/global.c index d2a25a50448..06429776c08 100644 --- a/src/global.c +++ b/src/global.c @@ -11,6 +11,7 @@ #include "hash.h" #include "sysdir.h" #include "filter.h" +#include "settings.h" #include "merge_driver.h" #include "pool.h" #include "streams/registry.h" @@ -37,15 +38,14 @@ static git_global_init_fn git__init_callbacks[] = { git_openssl_stream_global_init, git_mbedtls_stream_global_init, git_mwindow_global_init, - git_pool_global_init + git_pool_global_init, + git_settings_global_init }; static git_global_shutdown_fn git__shutdown_callbacks[ARRAY_SIZE(git__init_callbacks)]; static git_atomic git__n_shutdown_callbacks; static git_atomic git__n_inits; -char *git__user_agent; -char *git__ssl_ciphers; void git__on_shutdown(git_global_shutdown_fn callback) { @@ -93,9 +93,6 @@ static void shutdown_common(void) if (cb != NULL) cb(); } - - git__free(git__user_agent); - git__free(git__ssl_ciphers); } /** diff --git a/src/global.h b/src/global.h index db41dad1fc5..2a7c7274c75 100644 --- a/src/global.h +++ b/src/global.h @@ -35,7 +35,4 @@ typedef void (*git_global_shutdown_fn)(void); extern void git__on_shutdown(git_global_shutdown_fn callback); -extern const char *git_libgit2__user_agent(void); -extern const char *git_libgit2__ssl_ciphers(void); - #endif diff --git a/src/settings.c b/src/settings.c index 69ebcb7abe6..0426093ea41 100644 --- a/src/settings.c +++ b/src/settings.c @@ -29,6 +29,28 @@ #include "streams/openssl.h" #include "streams/mbedtls.h" +/* Declarations for tuneable settings */ +extern size_t git_mwindow__window_size; +extern size_t git_mwindow__mapped_limit; +extern size_t git_mwindow__file_limit; +extern size_t git_indexer__max_objects; +extern bool git_disable_pack_keep_file_checks; + +char *git__user_agent; +char *git__ssl_ciphers; + +static void git_settings_global_shutdown(void) +{ + git__free(git__user_agent); + git__free(git__ssl_ciphers); +} + +int git_settings_global_init(void) +{ + git__on_shutdown(git_settings_global_shutdown); + return 0; +} + int git_libgit2_version(int *major, int *minor, int *rev) { *major = LIBGIT2_VER_MAJOR; @@ -56,13 +78,6 @@ int git_libgit2_features(void) ; } -/* Declarations for tuneable settings */ -extern size_t git_mwindow__window_size; -extern size_t git_mwindow__mapped_limit; -extern size_t git_mwindow__file_limit; -extern size_t git_indexer__max_objects; -extern bool git_disable_pack_keep_file_checks; - static int config_level_to_sysdir(int config_level) { int val = -1; @@ -88,9 +103,6 @@ static int config_level_to_sysdir(int config_level) return val; } -extern char *git__user_agent; -extern char *git__ssl_ciphers; - const char *git_libgit2__user_agent(void) { return git__user_agent; diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 00000000000..dc42ce93952 --- /dev/null +++ b/src/settings.h @@ -0,0 +1,11 @@ +/* + * 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. + */ + +extern int git_settings_global_init(void); + +extern const char *git_libgit2__user_agent(void); +extern const char *git_libgit2__ssl_ciphers(void); diff --git a/src/streams/openssl.c b/src/streams/openssl.c index 6a490d17d2e..58265c1ecb8 100644 --- a/src/streams/openssl.c +++ b/src/streams/openssl.c @@ -12,6 +12,7 @@ #include #include "global.h" +#include "settings.h" #include "posix.h" #include "stream.h" #include "streams/socket.h" diff --git a/src/transports/http.h b/src/transports/http.h index c02109cec07..5c360b88387 100644 --- a/src/transports/http.h +++ b/src/transports/http.h @@ -9,6 +9,7 @@ #define INCLUDE_transports_http_h__ #include "buffer.h" +#include "settings.h" #include "httpclient.h" #define GIT_HTTP_REPLAY_MAX 15 diff --git a/tests/core/useragent.c b/tests/core/useragent.c index c6c5220b2b2..2ce935bf546 100644 --- a/tests/core/useragent.c +++ b/tests/core/useragent.c @@ -1,5 +1,5 @@ #include "clar_libgit2.h" -#include "global.h" +#include "settings.h" void test_core_useragent__get(void) { From 8aa69f887afaced1389d1ae965d5f313b10da66b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 13 May 2020 10:48:13 +0100 Subject: [PATCH 0028/1616] mwindow: localize mutex Move the mwindow mutex into the mwindow code itself, initializing it in the mwindow global initialization function instead of in the global initializer. --- src/futils.c | 1 + src/global.c | 12 +----------- src/global.h | 5 ----- src/mwindow.c | 13 +++++++++++-- src/mwindow.h | 2 ++ 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/futils.c b/src/futils.c index 8c0f008b331..552a3fb486c 100644 --- a/src/futils.c +++ b/src/futils.c @@ -9,6 +9,7 @@ #include "global.h" #include "strmap.h" +#include "hash.h" #include #if GIT_WIN32 #include "win32/findfile.h" diff --git a/src/global.c b/src/global.c index 06429776c08..8b16166f2f9 100644 --- a/src/global.c +++ b/src/global.c @@ -12,6 +12,7 @@ #include "sysdir.h" #include "filter.h" #include "settings.h" +#include "mwindow.h" #include "merge_driver.h" #include "pool.h" #include "streams/registry.h" @@ -22,8 +23,6 @@ #include "transports/ssh.h" #include "win32/w32_stack.h" -git_mutex git__mwindow_mutex; - typedef int (*git_global_init_fn)(void); static git_global_init_fn git__init_callbacks[] = { @@ -147,9 +146,6 @@ static int synchronized_threads_init(void) if ((_fls_index = FlsAlloc(fls_free)) == FLS_OUT_OF_INDEXES) return -1; - if (git_mutex_init(&git__mwindow_mutex)) - return -1; - error = init_common(); return error; @@ -186,7 +182,6 @@ int git_libgit2_shutdown(void) shutdown_common(); FlsFree(_fls_index); - git_mutex_free(&git__mwindow_mutex); } /* Exit the lock */ @@ -229,11 +224,7 @@ static void cb__free_status(void *st) static void init_once(void) { - if ((init_error = git_mutex_init(&git__mwindow_mutex)) != 0) - return; - pthread_key_create(&_tls_key, &cb__free_status); - init_error = init_common(); } @@ -276,7 +267,6 @@ int git_libgit2_shutdown(void) git__free(ptr); pthread_key_delete(_tls_key); - git_mutex_free(&git__mwindow_mutex); _once_init = new_once; out: diff --git a/src/global.h b/src/global.h index 2a7c7274c75..f4e55eb6e58 100644 --- a/src/global.h +++ b/src/global.h @@ -9,9 +9,6 @@ #include "common.h" -#include "mwindow.h" -#include "hash.h" - typedef struct { git_error *last_error; git_error error_t; @@ -27,8 +24,6 @@ typedef struct { git_global_st *git__global_state(void); -extern git_mutex git__mwindow_mutex; - #define GIT_GLOBAL (git__global_state()) typedef void (*git_global_shutdown_fn)(void); diff --git a/src/mwindow.c b/src/mwindow.c index ac26452f4eb..78ac411bfa6 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -29,16 +29,21 @@ size_t git_mwindow__window_size = DEFAULT_WINDOW_SIZE; size_t git_mwindow__mapped_limit = DEFAULT_MAPPED_LIMIT; size_t git_mwindow__file_limit = DEFAULT_FILE_LIMIT; +/* Mutex to control access */ +git_mutex git__mwindow_mutex; + /* Whenever you want to read or modify this, grab git__mwindow_mutex */ git_mwindow_ctl git_mwindow__mem_ctl; /* Global list of mwindow files, to open packs once across repos */ git_strmap *git__pack_cache = NULL; -static void git_mwindow_files_free(void) +static void git_mwindow_global_shutdown(void) { git_strmap *tmp = git__pack_cache; + git_mutex_free(&git__mwindow_mutex); + git__pack_cache = NULL; git_strmap_free(tmp); } @@ -47,7 +52,11 @@ int git_mwindow_global_init(void) { assert(!git__pack_cache); - git__on_shutdown(git_mwindow_files_free); + git__on_shutdown(git_mwindow_global_shutdown); + + if (git_mutex_init(&git__mwindow_mutex) != 0) + return -1; + return git_strmap_new(&git__pack_cache); } diff --git a/src/mwindow.h b/src/mwindow.h index 1a391b055dc..7519fc36d6b 100644 --- a/src/mwindow.h +++ b/src/mwindow.h @@ -13,6 +13,8 @@ #include "map.h" #include "vector.h" +extern git_mutex git__mwindow_mutex; + typedef struct git_mwindow { struct git_mwindow *next; git_map window_map; From bc3919abc716088cf7c33bc08d48ee2bc434c398 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 11 Jul 2020 12:14:26 +0100 Subject: [PATCH 0029/1616] global init: check error message buffer allocation Ensure that we can allocate the error message buffer. In keeping with our typical policiess, we allow (small) memory leaks in the case where we're out of memory. --- src/global.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/global.c b/src/global.c index 8b16166f2f9..f67811a9511 100644 --- a/src/global.c +++ b/src/global.c @@ -203,7 +203,8 @@ git_global_st *git__global_state(void) if (!ptr) return NULL; - git_buf_init(&ptr->error_buf, 0); + if (git_buf_init(&ptr->error_buf, 0) < 0) + return NULL; FlsSetValue(_fls_index, ptr); return ptr; @@ -289,7 +290,9 @@ git_global_st *git__global_state(void) if (!ptr) return NULL; - git_buf_init(&ptr->error_buf, 0); + if (git_buf_init(&ptr->error_buf, 0) < 0) + return NULL; + pthread_setspecific(_tls_key, ptr); return ptr; } From 4853d94ca47a6f1ecaa7c24b9034ededcb7e5bff Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 14 May 2020 10:36:35 +0100 Subject: [PATCH 0030/1616] global: separate global state from thread-local state Our "global initialization" has accumulated some debris over the years. It was previously responsible for both running the various global initializers (that set up various subsystems) _and_ setting up the "global state", which is actually the thread-local state for things like error reporting. Separate the thread local state out into "threadstate". Use the normal subsystem initialization functions that we already have to set it up. This makes both the global initialization system and the threadstate system simpler to reason about. --- src/errors.c | 26 ++--- src/global.c | 251 +++++++++------------------------------------ src/global.h | 17 --- src/oid.c | 4 +- src/threadstate.c | 161 +++++++++++++++++++++++++++++ src/threadstate.h | 30 ++++++ src/win32/thread.c | 8 +- 7 files changed, 258 insertions(+), 239 deletions(-) create mode 100644 src/threadstate.c create mode 100644 src/threadstate.h diff --git a/src/errors.c b/src/errors.c index 8570226b441..d4da50da8d9 100644 --- a/src/errors.c +++ b/src/errors.c @@ -7,7 +7,7 @@ #include "common.h" -#include "global.h" +#include "threadstate.h" #include "posix.h" #include "buffer.h" @@ -22,18 +22,18 @@ static git_error g_git_oom_error = { static void set_error_from_buffer(int error_class) { - git_error *error = &GIT_GLOBAL->error_t; - git_buf *buf = &GIT_GLOBAL->error_buf; + git_error *error = &GIT_THREADSTATE->error_t; + git_buf *buf = &GIT_THREADSTATE->error_buf; error->message = buf->ptr; error->klass = error_class; - GIT_GLOBAL->last_error = error; + GIT_THREADSTATE->last_error = error; } static void set_error(int error_class, char *string) { - git_buf *buf = &GIT_GLOBAL->error_buf; + git_buf *buf = &GIT_THREADSTATE->error_buf; git_buf_clear(buf); if (string) { @@ -46,7 +46,7 @@ static void set_error(int error_class, char *string) void git_error_set_oom(void) { - GIT_GLOBAL->last_error = &g_git_oom_error; + GIT_THREADSTATE->last_error = &g_git_oom_error; } void git_error_set(int error_class, const char *fmt, ...) @@ -64,7 +64,7 @@ void git_error_vset(int error_class, const char *fmt, va_list ap) DWORD win32_error_code = (error_class == GIT_ERROR_OS) ? GetLastError() : 0; #endif int error_code = (error_class == GIT_ERROR_OS) ? errno : 0; - git_buf *buf = &GIT_GLOBAL->error_buf; + git_buf *buf = &GIT_THREADSTATE->error_buf; git_buf_clear(buf); if (fmt) { @@ -97,7 +97,7 @@ void git_error_vset(int error_class, const char *fmt, va_list ap) int git_error_set_str(int error_class, const char *string) { - git_buf *buf = &GIT_GLOBAL->error_buf; + git_buf *buf = &GIT_THREADSTATE->error_buf; assert(string); @@ -118,9 +118,9 @@ int git_error_set_str(int error_class, const char *string) void git_error_clear(void) { - if (GIT_GLOBAL->last_error != NULL) { + if (GIT_THREADSTATE->last_error != NULL) { set_error(0, NULL); - GIT_GLOBAL->last_error = NULL; + GIT_THREADSTATE->last_error = NULL; } errno = 0; @@ -131,13 +131,13 @@ void git_error_clear(void) const git_error *git_error_last(void) { - return GIT_GLOBAL->last_error; + return GIT_THREADSTATE->last_error; } int git_error_state_capture(git_error_state *state, int error_code) { - git_error *error = GIT_GLOBAL->last_error; - git_buf *error_buf = &GIT_GLOBAL->error_buf; + git_error *error = GIT_THREADSTATE->last_error; + git_buf *error_buf = &GIT_THREADSTATE->error_buf; memset(state, 0, sizeof(git_error_state)); diff --git a/src/global.c b/src/global.c index f67811a9511..c4e925b7390 100644 --- a/src/global.c +++ b/src/global.c @@ -8,6 +8,7 @@ #include "global.h" #include "alloc.h" +#include "threadstate.h" #include "hash.h" #include "sysdir.h" #include "filter.h" @@ -27,6 +28,7 @@ typedef int (*git_global_init_fn)(void); static git_global_init_fn git__init_callbacks[] = { git_allocator_global_init, + git_threadstate_global_init, git_threads_global_init, git_hash_global_init, git_sysdir_global_init, @@ -53,15 +55,6 @@ void git__on_shutdown(git_global_shutdown_fn callback) git__shutdown_callbacks[count - 1] = callback; } -static void git__global_state_cleanup(git_global_st *st) -{ - if (!st) - return; - - git__free(st->error_t.message); - st->error_t.message = NULL; -} - static int init_common(void) { size_t i; @@ -94,32 +87,6 @@ static void shutdown_common(void) } } -/** - * Handle the global state with TLS - * - * If libgit2 is built with GIT_THREADS enabled, - * the `git_libgit2_init()` function must be called - * before calling any other function of the library. - * - * This function allocates a TLS index (using pthreads - * or the native Win32 API) to store the global state - * on a per-thread basis. - * - * Any internal method that requires global state will - * then call `git__global_state()` which returns a pointer - * to the global state structure; this pointer is lazily - * allocated on each thread. - * - * Before shutting down the library, the - * `git_libgit2_shutdown` method must be called to free - * the previously reserved TLS index. - * - * If libgit2 is built without threading support, the - * `git__global_statestate()` call returns a pointer to a single, - * statically allocated global state. The `git_thread_` - * functions are not available in that case. - */ - /* * `git_libgit2_init()` allows subsystems to perform global setup, * which may take place in the global scope. An explicit memory @@ -130,42 +97,67 @@ static void shutdown_common(void) */ #if defined(GIT_THREADS) && defined(GIT_WIN32) -static DWORD _fls_index; -static volatile LONG _mutex = 0; +/* + * On Win32, we use a spinlock to provide locking semantics. This is + * lighter-weight than a proper critical section. + */ +static volatile LONG init_spinlock = 0; -static void WINAPI fls_free(void *st) +GIT_INLINE(int) init_lock(void) { - git__global_state_cleanup(st); - git__free(st); + while (InterlockedCompareExchange(&init_spinlock, 1, 0)) { Sleep(0); } + return 0; } -static int synchronized_threads_init(void) +GIT_INLINE(int) init_unlock(void) { - int error; + InterlockedExchange(&init_spinlock, 0); + return 0; +} - if ((_fls_index = FlsAlloc(fls_free)) == FLS_OUT_OF_INDEXES) - return -1; +#elif defined(GIT_THREADS) && defined(_POSIX_THREADS) - error = init_common(); +/* + * On POSIX, we need to use a proper mutex for locking. We might prefer + * a spinlock here, too, but there's no static initializer for a + * pthread_spinlock_t. + */ +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - return error; +GIT_INLINE(int) init_lock(void) +{ + return pthread_mutex_lock(&mutex) == 0 ? 0 : -1; } +GIT_INLINE(int) init_unlock(void) +{ + return pthread_mutex_unlock(&mutex) == 0 ? 0 : -1; +} + +#elif defined(GIT_THREADS) +# error unknown threading model +#else + +# define init_lock() 0 +# define init_unlock() 0 + +#endif + int git_libgit2_init(void) { int ret; - /* Enter the lock */ - while (InterlockedCompareExchange(&_mutex, 1, 0)) { Sleep(0); } + if (init_lock() < 0) + return -1; /* Only do work on a 0 -> 1 transition of the refcount */ if ((ret = git_atomic_inc(&git__n_inits)) == 1) { - if (synchronized_threads_init() < 0) + if (init_common() < 0) ret = -1; } - /* Exit the lock */ - InterlockedExchange(&_mutex, 0); + if (init_unlock() < 0) + return -1; return ret; } @@ -175,163 +167,16 @@ int git_libgit2_shutdown(void) int ret; /* Enter the lock */ - while (InterlockedCompareExchange(&_mutex, 1, 0)) { Sleep(0); } + if (init_lock() < 0) + return -1; /* Only do work on a 1 -> 0 transition of the refcount */ - if ((ret = git_atomic_dec(&git__n_inits)) == 0) { + if ((ret = git_atomic_dec(&git__n_inits)) == 0) shutdown_common(); - FlsFree(_fls_index); - } - /* Exit the lock */ - InterlockedExchange(&_mutex, 0); - - return ret; -} - -git_global_st *git__global_state(void) -{ - git_global_st *ptr; - - assert(git_atomic_get(&git__n_inits) > 0); - - if ((ptr = FlsGetValue(_fls_index)) != NULL) - return ptr; - - ptr = git__calloc(1, sizeof(git_global_st)); - if (!ptr) - return NULL; - - if (git_buf_init(&ptr->error_buf, 0) < 0) - return NULL; - - FlsSetValue(_fls_index, ptr); - return ptr; -} - -#elif defined(GIT_THREADS) && defined(_POSIX_THREADS) - -static pthread_key_t _tls_key; -static pthread_mutex_t _init_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_once_t _once_init = PTHREAD_ONCE_INIT; -int init_error = 0; - -static void cb__free_status(void *st) -{ - git__global_state_cleanup(st); - git__free(st); -} - -static void init_once(void) -{ - pthread_key_create(&_tls_key, &cb__free_status); - init_error = init_common(); -} - -int git_libgit2_init(void) -{ - int ret, err; - - if ((err = pthread_mutex_lock(&_init_mutex)) != 0) - return err; - - ret = git_atomic_inc(&git__n_inits); - err = pthread_once(&_once_init, init_once); - err |= pthread_mutex_unlock(&_init_mutex); - - if (err || init_error) - return err | init_error; - - return ret; -} - -int git_libgit2_shutdown(void) -{ - void *ptr = NULL; - pthread_once_t new_once = PTHREAD_ONCE_INIT; - int error, ret; - - if ((error = pthread_mutex_lock(&_init_mutex)) != 0) - return error; - - if ((ret = git_atomic_dec(&git__n_inits)) != 0) - goto out; - - /* Shut down any subsystems that have global state */ - shutdown_common(); - - ptr = pthread_getspecific(_tls_key); - pthread_setspecific(_tls_key, NULL); - - git__global_state_cleanup(ptr); - git__free(ptr); - - pthread_key_delete(_tls_key); - _once_init = new_once; - -out: - if ((error = pthread_mutex_unlock(&_init_mutex)) != 0) - return error; - - return ret; -} - -git_global_st *git__global_state(void) -{ - git_global_st *ptr; - - assert(git_atomic_get(&git__n_inits) > 0); - - if ((ptr = pthread_getspecific(_tls_key)) != NULL) - return ptr; - - ptr = git__calloc(1, sizeof(git_global_st)); - if (!ptr) - return NULL; - - if (git_buf_init(&ptr->error_buf, 0) < 0) - return NULL; - - pthread_setspecific(_tls_key, ptr); - return ptr; -} - -#else - -static git_global_st __state; - -int git_libgit2_init(void) -{ - int ret; - - /* Only init subsystems the first time */ - if ((ret = git_atomic_inc(&git__n_inits)) != 1) - return ret; - - if ((ret = init_common()) < 0) - return ret; - - return 1; -} - -int git_libgit2_shutdown(void) -{ - int ret; - - /* Shut down any subsystems that have global state */ - if ((ret = git_atomic_dec(&git__n_inits)) == 0) { - shutdown_common(); - git__global_state_cleanup(&__state); - memset(&__state, 0, sizeof(__state)); - } + if (init_unlock() < 0) + return -1; return ret; } - -git_global_st *git__global_state(void) -{ - return &__state; -} - -#endif /* GIT_THREADS */ diff --git a/src/global.h b/src/global.h index f4e55eb6e58..0364cab351e 100644 --- a/src/global.h +++ b/src/global.h @@ -9,23 +9,6 @@ #include "common.h" -typedef struct { - git_error *last_error; - git_error error_t; - git_buf error_buf; - char oid_fmt[GIT_OID_HEXSZ+1]; - - /* On Windows, this is the current child thread that was started by - * `git_thread_create`. This is used to set the thread's exit code - * when terminated by `git_thread_exit`. It is unused on POSIX. - */ - git_thread *current_thread; -} git_global_st; - -git_global_st *git__global_state(void); - -#define GIT_GLOBAL (git__global_state()) - typedef void (*git_global_shutdown_fn)(void); extern void git__on_shutdown(git_global_shutdown_fn callback); diff --git a/src/oid.c b/src/oid.c index 7831aca89be..a8ad3d2ee0d 100644 --- a/src/oid.c +++ b/src/oid.c @@ -9,7 +9,7 @@ #include "git2/oid.h" #include "repository.h" -#include "global.h" +#include "threadstate.h" #include #include @@ -107,7 +107,7 @@ int git_oid_pathfmt(char *str, const git_oid *oid) char *git_oid_tostr_s(const git_oid *oid) { - char *str = GIT_GLOBAL->oid_fmt; + char *str = GIT_THREADSTATE->oid_fmt; git_oid_nfmt(str, GIT_OID_HEXSZ + 1, oid); return str; } diff --git a/src/threadstate.c b/src/threadstate.c new file mode 100644 index 00000000000..4aa1c034a25 --- /dev/null +++ b/src/threadstate.c @@ -0,0 +1,161 @@ +/* + * 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 "threadstate.h" +#include "global.h" + +static void threadstate_dispose(git_threadstate *threadstate); + +/** + * Handle the thread-local state + * + * `git_threadstate_global_init` will be called as part + * of `git_libgit2_init` (which itself must be called + * before calling any other function in the library). + * + * This function allocates a TLS index (using pthreads + * or fiber-local storage in Win32) to store the per- + * thread state. + * + * Any internal method that requires thread-local state + * will then call `git_threadstate_get()` which returns a + * pointer to the thread-local state structure; this + * structure is lazily allocated on each thread. + * + * This mechanism will register a shutdown handler + * (`git_threadstate_global_shutdown`) which will free the + * TLS index. This shutdown handler will be called by + * `git_libgit2_shutdown`. + * + * If libgit2 is built without threading support, the + * `git_threadstate_get()` call returns a pointer to a single, + * statically allocated global state. The `git_thread_` + * functions are not available in that case. + */ + +#if defined(GIT_THREADS) && defined(GIT_WIN32) + +static DWORD fls_index; + +static void git_threadstate_global_shutdown(void) +{ + FlsFree(fls_index); +} + +static void WINAPI fls_free(void *threadstate) +{ + threadstate_dispose(threadstate); + git__free(threadstate); +} + +int git_threadstate_global_init(void) +{ + if ((fls_index = FlsAlloc(fls_free)) == FLS_OUT_OF_INDEXES) + return -1; + + git__on_shutdown(git_threadstate_global_shutdown); + + return 0; +} + +git_threadstate *git_threadstate_get(void) +{ + git_threadstate *threadstate; + + if ((threadstate = FlsGetValue(fls_index)) != NULL) + return threadstate; + + if ((threadstate = git__calloc(1, sizeof(git_threadstate))) == NULL || + git_buf_init(&threadstate->error_buf, 0) < 0) + return NULL; + + FlsSetValue(fls_index, threadstate); + return threadstate; +} + +#elif defined(GIT_THREADS) && defined(_POSIX_THREADS) + +static pthread_key_t tls_key; + +static void git_threadstate_global_shutdown(void) +{ + git_threadstate *threadstate; + + threadstate = pthread_getspecific(tls_key); + pthread_setspecific(tls_key, NULL); + + threadstate_dispose(threadstate); + git__free(threadstate); + + pthread_key_delete(tls_key); +} + +static void tls_free(void *threadstate) +{ + threadstate_dispose(threadstate); + git__free(threadstate); +} + +int git_threadstate_global_init(void) +{ + if (pthread_key_create(&tls_key, &tls_free) != 0) + return -1; + + git__on_shutdown(git_threadstate_global_shutdown); + + return 0; +} + +git_threadstate *git_threadstate_get(void) +{ + git_threadstate *threadstate; + + if ((threadstate = pthread_getspecific(tls_key)) != NULL) + return threadstate; + + if ((threadstate = git__calloc(1, sizeof(git_threadstate))) == NULL || + git_buf_init(&threadstate->error_buf, 0) < 0) + return NULL; + + pthread_setspecific(tls_key, threadstate); + return threadstate; +} + +#elif defined(GIT_THREADS) +# error unknown threading model +#else + +static git_threadstate threadstate; + +static void git_threadstate_global_shutdown(void) +{ + threadstate_dispose(&threadstate); + memset(&threadstate, 0, sizeof(git_threadstate); +} + +int git_threadstate_global_init(void) +{ + git__on_shutdown(git_threadstate_global_shutdown); + + return 0; +} + +git_threadstate *git_threadstate_get(void) +{ + return &threadstate; +} + +#endif + +static void threadstate_dispose(git_threadstate *threadstate) +{ + if (!threadstate) + return; + + git__free(threadstate->error_t.message); + threadstate->error_t.message = NULL; +} diff --git a/src/threadstate.h b/src/threadstate.h new file mode 100644 index 00000000000..9a4ef4d3a4f --- /dev/null +++ b/src/threadstate.h @@ -0,0 +1,30 @@ +/* + * 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_threadstate_h__ +#define INCLUDE_threadstate_h__ + +#include "common.h" + +typedef struct { + git_error *last_error; + git_error error_t; + git_buf error_buf; + char oid_fmt[GIT_OID_HEXSZ+1]; + + /* On Windows, this is the current child thread that was started by + * `git_thread_create`. This is used to set the thread's exit code + * when terminated by `git_thread_exit`. It is unused on POSIX. + */ + git_thread *current_thread; +} git_threadstate; + +extern int git_threadstate_global_init(void); +extern git_threadstate *git_threadstate_get(void); + +#define GIT_THREADSTATE (git_threadstate_get()) + +#endif diff --git a/src/win32/thread.c b/src/win32/thread.c index 0936c31687b..b9f8bc9d723 100644 --- a/src/win32/thread.c +++ b/src/win32/thread.c @@ -7,7 +7,7 @@ #include "thread.h" -#include "../global.h" +#include "../tlsdata.h" #define CLEAN_THREAD_EXIT 0x6F012842 @@ -28,7 +28,7 @@ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter) git_thread *thread = lpParameter; /* Set the current thread for `git_thread_exit` */ - GIT_GLOBAL->current_thread = thread; + GIT_TLSDATA->current_thread = thread; thread->result = thread->proc(thread->param); @@ -99,8 +99,8 @@ int git_thread_join( void git_thread_exit(void *value) { - assert(GIT_GLOBAL->current_thread); - GIT_GLOBAL->current_thread->result = value; + assert(GIT_TLSDATA->current_thread); + GIT_TLSDATA->current_thread->result = value; ExitThread(CLEAN_THREAD_EXIT); } From c40d2dc5ff2058bf04d816423507dec42e7dd0cc Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 15 May 2020 10:09:51 +0100 Subject: [PATCH 0031/1616] thread: restore the git_thread_exit tests We were never properly testing git_thread_exit. Do so. --- tests/threads/basic.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/threads/basic.c b/tests/threads/basic.c index ed4fd2f9b9d..2d7ddc26b99 100644 --- a/tests/threads/basic.c +++ b/tests/threads/basic.c @@ -54,6 +54,12 @@ static void *return_normally(void *param) { return param; } + +static void *exit_abruptly(void *param) +{ + git_thread_exit(param); + return NULL; +} #endif void test_threads_basic__exit(void) @@ -70,7 +76,7 @@ void test_threads_basic__exit(void) cl_assert_equal_sz(424242, (size_t)result); /* Ensure that the return value of `git_thread_exit` is returned. */ - cl_git_pass(git_thread_create(&thread, return_normally, (void *)232323)); + cl_git_pass(git_thread_create(&thread, exit_abruptly, (void *)232323)); cl_git_pass(git_thread_join(&thread, &result)); cl_assert_equal_sz(232323, (size_t)result); #endif From 8970acb750ecf4b86883d9ea1a8cb280517e6c86 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 15 May 2020 10:29:41 +0100 Subject: [PATCH 0032/1616] thread: don't use the global tlsdata for thread exit We want to store a pointer to emulate `pthread_exit` on Windows. Do this within the threading infrastructure so that it could potentially be re-used outside of the context of libgit2 itself. --- src/threadstate.h | 6 ------ src/win32/thread.c | 23 ++++++++++++++++++----- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/threadstate.h b/src/threadstate.h index 9a4ef4d3a4f..51810a9390f 100644 --- a/src/threadstate.h +++ b/src/threadstate.h @@ -14,12 +14,6 @@ typedef struct { git_error error_t; git_buf error_buf; char oid_fmt[GIT_OID_HEXSZ+1]; - - /* On Windows, this is the current child thread that was started by - * `git_thread_create`. This is used to set the thread's exit code - * when terminated by `git_thread_exit`. It is unused on POSIX. - */ - git_thread *current_thread; } git_threadstate; extern int git_threadstate_global_init(void); diff --git a/src/win32/thread.c b/src/win32/thread.c index b9f8bc9d723..dad32ef38a3 100644 --- a/src/win32/thread.c +++ b/src/win32/thread.c @@ -7,8 +7,6 @@ #include "thread.h" -#include "../tlsdata.h" - #define CLEAN_THREAD_EXIT 0x6F012842 typedef void (WINAPI *win32_srwlock_fn)(GIT_SRWLOCK *); @@ -19,6 +17,8 @@ static win32_srwlock_fn win32_srwlock_release_shared; static win32_srwlock_fn win32_srwlock_acquire_exclusive; static win32_srwlock_fn win32_srwlock_release_exclusive; +static DWORD fls_index; + /* The thread procedure stub used to invoke the caller's procedure * and capture the return value for later collection. Windows will * only hold a DWORD, but we need to be able to store an entire @@ -28,13 +28,18 @@ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter) git_thread *thread = lpParameter; /* Set the current thread for `git_thread_exit` */ - GIT_TLSDATA->current_thread = thread; + FlsSetValue(fls_index, thread); thread->result = thread->proc(thread->param); return CLEAN_THREAD_EXIT; } +static void git_threads_global_shutdown(void) +{ + FlsFree(fls_index); +} + int git_threads_global_init(void) { HMODULE hModule = GetModuleHandleW(L"kernel32"); @@ -52,6 +57,11 @@ int git_threads_global_init(void) GetProcAddress(hModule, "ReleaseSRWLockExclusive"); } + if ((fls_index = FlsAlloc(NULL)) == FLS_OUT_OF_INDEXES) + return -1; + + git__on_shutdown(git_threads_global_shutdown); + return 0; } @@ -99,8 +109,11 @@ int git_thread_join( void git_thread_exit(void *value) { - assert(GIT_TLSDATA->current_thread); - GIT_TLSDATA->current_thread->result = value; + git_thread *thread = FlsGetValue(fls_index); + + if (thread) + thread->result = value; + ExitThread(CLEAN_THREAD_EXIT); } From e316b0d3d64eb8f65f4109c1565d929b29e1d33a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 15 May 2020 11:47:09 +0100 Subject: [PATCH 0033/1616] runtime: move init/shutdown into the "runtime" Provide a mechanism for system components to register for initialization and shutdown of the libgit2 runtime. --- src/alloc.c | 4 +- src/filter.c | 4 +- src/futils.c | 2 +- src/global.c | 170 +++++------------------------------- src/global.h | 16 ---- src/hash/sha1/win32.c | 5 +- src/merge_driver.c | 4 +- src/mwindow.c | 13 +-- src/net.c | 2 +- src/netops.c | 2 +- src/runtime.c | 147 +++++++++++++++++++++++++++++++ src/runtime.h | 53 +++++++++++ src/settings.c | 5 +- src/streams/mbedtls.c | 6 +- src/streams/openssl.c | 10 +-- src/streams/registry.c | 5 +- src/streams/tls.c | 1 - src/sysdir.c | 6 +- src/threadstate.c | 16 ++-- src/trace.c | 2 +- src/transports/http.c | 1 - src/transports/httpclient.c | 1 - src/transports/ssh.c | 5 +- src/transports/winhttp.c | 1 - src/win32/posix_w32.c | 1 - src/win32/thread.c | 5 +- tests/pack/filelimit.c | 1 - 27 files changed, 262 insertions(+), 226 deletions(-) delete mode 100644 src/global.h create mode 100644 src/runtime.c create mode 100644 src/runtime.h diff --git a/src/alloc.c b/src/alloc.c index 7bfbbdaa8c0..6972e7b5986 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -6,6 +6,7 @@ */ #include "alloc.h" +#include "runtime.h" #include "allocators/stdalloc.h" #include "allocators/win32_crtdbg.h" @@ -40,7 +41,8 @@ int git_allocator_global_init(void) git_win32__crtdbg_stacktrace_init(); git_win32__stack_init(); - git__on_shutdown(allocator_global_shutdown); + if (git_runtime_shutdown_register(allocator_global_shutdown) < 0) + return -1; #endif /* diff --git a/src/filter.c b/src/filter.c index 09b57dc8021..86db5a5e370 100644 --- a/src/filter.c +++ b/src/filter.c @@ -11,7 +11,7 @@ #include "futils.h" #include "hash.h" #include "repository.h" -#include "global.h" +#include "runtime.h" #include "git2/sys/filter.h" #include "git2/config.h" #include "blob.h" @@ -206,7 +206,7 @@ int git_filter_global_init(void) GIT_FILTER_IDENT, ident, GIT_FILTER_IDENT_PRIORITY) < 0) error = -1; - git__on_shutdown(git_filter_global_shutdown); + error = git_runtime_shutdown_register(git_filter_global_shutdown); done: if (error) { diff --git a/src/futils.c b/src/futils.c index 552a3fb486c..2ad8a1b806a 100644 --- a/src/futils.c +++ b/src/futils.c @@ -7,7 +7,7 @@ #include "futils.h" -#include "global.h" +#include "runtime.h" #include "strmap.h" #include "hash.h" #include diff --git a/src/global.c b/src/global.c index c4e925b7390..e6b7f46f03d 100644 --- a/src/global.c +++ b/src/global.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "global.h" +#include "runtime.h" #include "alloc.h" #include "threadstate.h" @@ -24,159 +24,29 @@ #include "transports/ssh.h" #include "win32/w32_stack.h" -typedef int (*git_global_init_fn)(void); - -static git_global_init_fn git__init_callbacks[] = { - git_allocator_global_init, - git_threadstate_global_init, - git_threads_global_init, - git_hash_global_init, - git_sysdir_global_init, - git_filter_global_init, - git_merge_driver_global_init, - git_transport_ssh_global_init, - git_stream_registry_global_init, - git_openssl_stream_global_init, - git_mbedtls_stream_global_init, - git_mwindow_global_init, - git_pool_global_init, - git_settings_global_init -}; - -static git_global_shutdown_fn git__shutdown_callbacks[ARRAY_SIZE(git__init_callbacks)]; - -static git_atomic git__n_shutdown_callbacks; -static git_atomic git__n_inits; - -void git__on_shutdown(git_global_shutdown_fn callback) -{ - int count = git_atomic_inc(&git__n_shutdown_callbacks); - assert(count <= (int) ARRAY_SIZE(git__shutdown_callbacks) && count > 0); - git__shutdown_callbacks[count - 1] = callback; -} - -static int init_common(void) -{ - size_t i; - int ret; - - /* Initialize subsystems that have global state */ - for (i = 0; i < ARRAY_SIZE(git__init_callbacks); i++) - if ((ret = git__init_callbacks[i]()) != 0) - break; - - GIT_MEMORY_BARRIER; - - return ret; -} - -static void shutdown_common(void) -{ - int pos; - - /* Shutdown subsystems that have registered */ - for (pos = git_atomic_get(&git__n_shutdown_callbacks); - pos > 0; - pos = git_atomic_dec(&git__n_shutdown_callbacks)) { - - git_global_shutdown_fn cb = git__swap( - git__shutdown_callbacks[pos - 1], NULL); - - if (cb != NULL) - cb(); - } -} - -/* - * `git_libgit2_init()` allows subsystems to perform global setup, - * which may take place in the global scope. An explicit memory - * fence exists at the exit of `git_libgit2_init()`. Without this, - * CPU cores are free to reorder cache invalidation of `_tls_init` - * before cache invalidation of the subsystems' newly written global - * state. - */ -#if defined(GIT_THREADS) && defined(GIT_WIN32) - -/* - * On Win32, we use a spinlock to provide locking semantics. This is - * lighter-weight than a proper critical section. - */ -static volatile LONG init_spinlock = 0; - -GIT_INLINE(int) init_lock(void) -{ - while (InterlockedCompareExchange(&init_spinlock, 1, 0)) { Sleep(0); } - return 0; -} - -GIT_INLINE(int) init_unlock(void) -{ - InterlockedExchange(&init_spinlock, 0); - return 0; -} - -#elif defined(GIT_THREADS) && defined(_POSIX_THREADS) - -/* - * On POSIX, we need to use a proper mutex for locking. We might prefer - * a spinlock here, too, but there's no static initializer for a - * pthread_spinlock_t. - */ -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - -GIT_INLINE(int) init_lock(void) -{ - return pthread_mutex_lock(&mutex) == 0 ? 0 : -1; -} - -GIT_INLINE(int) init_unlock(void) -{ - return pthread_mutex_unlock(&mutex) == 0 ? 0 : -1; -} - -#elif defined(GIT_THREADS) -# error unknown threading model -#else - -# define init_lock() 0 -# define init_unlock() 0 - -#endif - int git_libgit2_init(void) { - int ret; - - if (init_lock() < 0) - return -1; - - /* Only do work on a 0 -> 1 transition of the refcount */ - if ((ret = git_atomic_inc(&git__n_inits)) == 1) { - if (init_common() < 0) - ret = -1; - } - - if (init_unlock() < 0) - return -1; - - return ret; + static git_runtime_init_fn init_fns[] = { + git_allocator_global_init, + git_threadstate_global_init, + git_threads_global_init, + git_hash_global_init, + git_sysdir_global_init, + git_filter_global_init, + git_merge_driver_global_init, + git_transport_ssh_global_init, + git_stream_registry_global_init, + git_openssl_stream_global_init, + git_mbedtls_stream_global_init, + git_mwindow_global_init, + git_pool_global_init, + git_settings_global_init + }; + + return git_runtime_init(init_fns, ARRAY_SIZE(init_fns)); } int git_libgit2_shutdown(void) { - int ret; - - /* Enter the lock */ - if (init_lock() < 0) - return -1; - - /* Only do work on a 1 -> 0 transition of the refcount */ - if ((ret = git_atomic_dec(&git__n_inits)) == 0) - shutdown_common(); - - /* Exit the lock */ - if (init_unlock() < 0) - return -1; - - return ret; + return git_runtime_shutdown(); } diff --git a/src/global.h b/src/global.h deleted file mode 100644 index 0364cab351e..00000000000 --- a/src/global.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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_global_h__ -#define INCLUDE_global_h__ - -#include "common.h" - -typedef void (*git_global_shutdown_fn)(void); - -extern void git__on_shutdown(git_global_shutdown_fn callback); - -#endif diff --git a/src/hash/sha1/win32.c b/src/hash/sha1/win32.c index c7369566598..b1266cca020 100644 --- a/src/hash/sha1/win32.c +++ b/src/hash/sha1/win32.c @@ -7,7 +7,7 @@ #include "win32.h" -#include "global.h" +#include "runtime.h" #include #include @@ -129,7 +129,8 @@ int git_hash_sha1_global_init(void) if ((error = hash_cng_prov_init()) < 0) error = hash_cryptoapi_prov_init(); - git__on_shutdown(sha1_shutdown); + if (!error) + error = git_runtime_shutdown_register(sha1_shutdown); return error; } diff --git a/src/merge_driver.c b/src/merge_driver.c index 666349b156b..b1f574801d9 100644 --- a/src/merge_driver.c +++ b/src/merge_driver.c @@ -8,7 +8,7 @@ #include "merge_driver.h" #include "vector.h" -#include "global.h" +#include "runtime.h" #include "merge.h" #include "git2/merge.h" #include "git2/sys/merge.h" @@ -209,7 +209,7 @@ int git_merge_driver_global_init(void) merge_driver_name__binary, &git_merge_driver__binary)) < 0) goto done; - git__on_shutdown(git_merge_driver_global_shutdown); + error = git_runtime_shutdown_register(git_merge_driver_global_shutdown); done: if (error < 0) diff --git a/src/mwindow.c b/src/mwindow.c index 78ac411bfa6..a852d6bf2f7 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -10,7 +10,7 @@ #include "vector.h" #include "futils.h" #include "map.h" -#include "global.h" +#include "runtime.h" #include "strmap.h" #include "pack.h" @@ -50,14 +50,15 @@ static void git_mwindow_global_shutdown(void) int git_mwindow_global_init(void) { - assert(!git__pack_cache); + int error; - git__on_shutdown(git_mwindow_global_shutdown); + assert(!git__pack_cache); - if (git_mutex_init(&git__mwindow_mutex) != 0) - return -1; + if ((error = git_mutex_init(&git__mwindow_mutex)) < 0 || + (error = git_strmap_new(&git__pack_cache)) < 0) + return error; - return git_strmap_new(&git__pack_cache); + return git_runtime_shutdown_register(git_mwindow_global_shutdown); } int git_mwindow_get_pack(struct git_pack_file **out, const char *path) diff --git a/src/net.c b/src/net.c index dbde626b52b..ac1bc429973 100644 --- a/src/net.c +++ b/src/net.c @@ -14,7 +14,7 @@ #include "posix.h" #include "buffer.h" #include "http_parser.h" -#include "global.h" +#include "runtime.h" #define DEFAULT_PORT_HTTP "80" #define DEFAULT_PORT_HTTPS "443" diff --git a/src/netops.c b/src/netops.c index 04ae824ccca..1ef2302931a 100644 --- a/src/netops.c +++ b/src/netops.c @@ -13,7 +13,7 @@ #include "posix.h" #include "buffer.h" #include "http_parser.h" -#include "global.h" +#include "runtime.h" int gitno_recv(gitno_buffer *buf) { diff --git a/src/runtime.c b/src/runtime.c new file mode 100644 index 00000000000..56110c49a3b --- /dev/null +++ b/src/runtime.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "common.h" +#include "runtime.h" + +static git_runtime_shutdown_fn shutdown_callback[32]; +static git_atomic shutdown_callback_count; + +static git_atomic init_count; + +static int init_common(git_runtime_init_fn init_fns[], size_t cnt) +{ + size_t i; + int ret; + + /* Initialize subsystems that have global state */ + for (i = 0; i < cnt; i++) { + if ((ret = init_fns[i]()) != 0) + break; + } + + GIT_MEMORY_BARRIER; + + return ret; +} + +static void shutdown_common(void) +{ + git_runtime_shutdown_fn cb; + int pos; + + for (pos = git_atomic_get(&shutdown_callback_count); + pos > 0; + pos = git_atomic_dec(&shutdown_callback_count)) { + cb = git__swap(shutdown_callback[pos - 1], NULL); + + if (cb != NULL) + cb(); + } +} + +int git_runtime_shutdown_register(git_runtime_shutdown_fn callback) +{ + int count = git_atomic_inc(&shutdown_callback_count); + + if (count > (int)ARRAY_SIZE(shutdown_callback) || count == 0) { + git_error_set(GIT_ERROR_INVALID, + "too many shutdown callbacks registered"); + git_atomic_dec(&shutdown_callback_count); + return -1; + } + + shutdown_callback[count - 1] = callback; + + return 0; +} + +#if defined(GIT_THREADS) && defined(GIT_WIN32) + +/* + * On Win32, we use a spinlock to provide locking semantics. This is + * lighter-weight than a proper critical section. + */ +static volatile LONG init_spinlock = 0; + +GIT_INLINE(int) init_lock(void) +{ + while (InterlockedCompareExchange(&init_spinlock, 1, 0)) { Sleep(0); } + return 0; +} + +GIT_INLINE(int) init_unlock(void) +{ + InterlockedExchange(&init_spinlock, 0); + return 0; +} + +#elif defined(GIT_THREADS) && defined(_POSIX_THREADS) + +/* + * On POSIX, we need to use a proper mutex for locking. We might prefer + * a spinlock here, too, but there's no static initializer for a + * pthread_spinlock_t. + */ +static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; + +GIT_INLINE(int) init_lock(void) +{ + return pthread_mutex_lock(&init_mutex) == 0 ? 0 : -1; +} + +GIT_INLINE(int) init_unlock(void) +{ + return pthread_mutex_unlock(&init_mutex) == 0 ? 0 : -1; +} + +#elif defined(GIT_THREADS) +# error unknown threading model +#else + +# define mutex_lock() 0 +# define mutex_unlock() 0 + +#endif + +int git_runtime_init(git_runtime_init_fn init_fns[], size_t cnt) +{ + int ret; + + if (init_lock() < 0) + return -1; + + /* Only do work on a 0 -> 1 transition of the refcount */ + if ((ret = git_atomic_inc(&init_count)) == 1) { + if (init_common(init_fns, cnt) < 0) + ret = -1; + } + + if (init_unlock() < 0) + return -1; + + return ret; +} + +int git_runtime_shutdown(void) +{ + int ret; + + /* Enter the lock */ + if (init_lock() < 0) + return -1; + + /* Only do work on a 1 -> 0 transition of the refcount */ + if ((ret = git_atomic_dec(&init_count)) == 0) + shutdown_common(); + + /* Exit the lock */ + if (init_unlock() < 0) + return -1; + + return ret; +} diff --git a/src/runtime.h b/src/runtime.h new file mode 100644 index 00000000000..be2e37a6016 --- /dev/null +++ b/src/runtime.h @@ -0,0 +1,53 @@ +/* + * 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_runtime_h__ +#define INCLUDE_runtime_h__ + +#include "common.h" + +typedef int (*git_runtime_init_fn)(void); +typedef void (*git_runtime_shutdown_fn)(void); + +/** + * Start up a new runtime. If this is the first time that this + * function is called within the context of the current library + * or executable, then the given `init_fns` will be invoked. If + * it is not the first time, they will be ignored. + * + * The given initialization functions _may_ register shutdown + * handlers using `git_runtime_shutdown_register` to be notified + * when the runtime is shutdown. + * + * @param init_fns The list of initialization functions to call + * @param cnt The number of init_fns + * @return The number of initializations performed (including this one) or an error + */ +int git_runtime_init(git_runtime_init_fn init_fns[], size_t cnt); + +/** + * Shut down the runtime. If this is the last shutdown call, + * such that there are no remaining `init` calls, then any + * shutdown hooks that have been registered will be invoked. + * + * The number of oustanding initializations will be returned. + * If this number is 0, then the runtime is shutdown. + * + * @return The number of outstanding initializations (after this one) or an error + */ +int git_runtime_shutdown(void); + +/** + * Register a shutdown handler for this runtime. This should be done + * by a function invoked by `git_runtime_init` to ensure that the + * appropriate locks are taken. + * + * @param callback The shutdown handler callback + * @return 0 or an error code + */ +int git_runtime_shutdown_register(git_runtime_shutdown_fn callback); + +#endif diff --git a/src/settings.c b/src/settings.c index 0426093ea41..4f69da3e91a 100644 --- a/src/settings.c +++ b/src/settings.c @@ -19,7 +19,7 @@ #include "alloc.h" #include "sysdir.h" #include "cache.h" -#include "global.h" +#include "runtime.h" #include "object.h" #include "odb.h" #include "refs.h" @@ -47,8 +47,7 @@ static void git_settings_global_shutdown(void) int git_settings_global_init(void) { - git__on_shutdown(git_settings_global_shutdown); - return 0; + return git_runtime_shutdown_register(git_settings_global_shutdown); } int git_libgit2_version(int *major, int *minor, int *rev) diff --git a/src/streams/mbedtls.c b/src/streams/mbedtls.c index cbe2f681a93..00daa55215a 100644 --- a/src/streams/mbedtls.c +++ b/src/streams/mbedtls.c @@ -11,7 +11,7 @@ #include -#include "global.h" +#include "runtime.h" #include "stream.h" #include "streams/socket.h" #include "netops.h" @@ -152,9 +152,7 @@ int git_mbedtls_stream_global_init(void) if (!loaded && crtpath != NULL && stat(crtpath, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) loaded = (git_mbedtls__set_cert_location(crtpath, 1) == 0); - git__on_shutdown(shutdown_ssl); - - return 0; + return git_runtime_shutdown_register(shutdown_ssl); cleanup: mbedtls_ctr_drbg_free(ctr_drbg); diff --git a/src/streams/openssl.c b/src/streams/openssl.c index 58265c1ecb8..0a0c2c5e5bb 100644 --- a/src/streams/openssl.c +++ b/src/streams/openssl.c @@ -11,7 +11,7 @@ #include -#include "global.h" +#include "runtime.h" #include "settings.h" #include "posix.h" #include "stream.h" @@ -286,9 +286,7 @@ int git_openssl_stream_global_init(void) if (init_bio_method() < 0) goto error; - git__on_shutdown(shutdown_ssl); - - return 0; + return git_runtime_shutdown_register(shutdown_ssl); error: git_error_set(GIT_ERROR_NET, "could not initialize openssl: %s", @@ -325,8 +323,8 @@ int git_openssl_set_locking(void) } CRYPTO_set_locking_callback(openssl_locking_function); - git__on_shutdown(shutdown_ssl_locking); - return 0; + return git_runtime_shutdown_register(shutdown_ssl_locking); + #elif !defined(OPENSSL_LEGACY_API) return 0; #else diff --git a/src/streams/registry.c b/src/streams/registry.c index 284431207ce..b3bf17a4e9b 100644 --- a/src/streams/registry.c +++ b/src/streams/registry.c @@ -9,7 +9,7 @@ #include "streams/registry.h" -#include "global.h" +#include "runtime.h" #include "streams/tls.h" #include "streams/mbedtls.h" #include "streams/openssl.h" @@ -33,8 +33,7 @@ int git_stream_registry_global_init(void) if (git_rwlock_init(&stream_registry.lock) < 0) return -1; - git__on_shutdown(shutdown_stream_registry); - return 0; + return git_runtime_shutdown_register(shutdown_stream_registry); } GIT_INLINE(void) stream_registration_cpy( diff --git a/src/streams/tls.c b/src/streams/tls.c index 6a251717b69..255a4a0f630 100644 --- a/src/streams/tls.c +++ b/src/streams/tls.c @@ -8,7 +8,6 @@ #include "git2/errors.h" #include "common.h" -#include "global.h" #include "streams/registry.h" #include "streams/tls.h" #include "streams/mbedtls.h" diff --git a/src/sysdir.c b/src/sysdir.c index 6dc78c8fd99..401b4a55e92 100644 --- a/src/sysdir.c +++ b/src/sysdir.c @@ -7,7 +7,7 @@ #include "sysdir.h" -#include "global.h" +#include "runtime.h" #include "buffer.h" #include "path.h" #include @@ -189,9 +189,7 @@ int git_sysdir_global_init(void) for (i = 0; !error && i < ARRAY_SIZE(git_sysdir__dirs); i++) error = git_sysdir__dirs[i].guess(&git_sysdir__dirs[i].buf); - git__on_shutdown(git_sysdir_global_shutdown); - - return error; + return git_runtime_shutdown_register(git_sysdir_global_shutdown); } static int git_sysdir_check_selector(git_sysdir_t which) diff --git a/src/threadstate.c b/src/threadstate.c index 4aa1c034a25..8e17124a25a 100644 --- a/src/threadstate.c +++ b/src/threadstate.c @@ -6,7 +6,7 @@ */ #include "threadstate.h" -#include "global.h" +#include "runtime.h" static void threadstate_dispose(git_threadstate *threadstate); @@ -57,9 +57,7 @@ int git_threadstate_global_init(void) if ((fls_index = FlsAlloc(fls_free)) == FLS_OUT_OF_INDEXES) return -1; - git__on_shutdown(git_threadstate_global_shutdown); - - return 0; + return git_runtime_shutdown_register(git_threadstate_global_shutdown); } git_threadstate *git_threadstate_get(void) @@ -105,9 +103,7 @@ int git_threadstate_global_init(void) if (pthread_key_create(&tls_key, &tls_free) != 0) return -1; - git__on_shutdown(git_threadstate_global_shutdown); - - return 0; + return git_runtime_shutdown_register(git_threadstate_global_shutdown); } git_threadstate *git_threadstate_get(void) @@ -134,14 +130,12 @@ static git_threadstate threadstate; static void git_threadstate_global_shutdown(void) { threadstate_dispose(&threadstate); - memset(&threadstate, 0, sizeof(git_threadstate); + memset(&threadstate, 0, sizeof(git_threadstate)); } int git_threadstate_global_init(void) { - git__on_shutdown(git_threadstate_global_shutdown); - - return 0; + return git_runtime_shutdown_register(git_tlsdata_global_shutdown); } git_threadstate *git_threadstate_get(void) diff --git a/src/trace.c b/src/trace.c index ec6a90aad2a..3acb64398d1 100644 --- a/src/trace.c +++ b/src/trace.c @@ -8,7 +8,7 @@ #include "trace.h" #include "buffer.h" -#include "global.h" +#include "runtime.h" #include "git2/trace.h" #ifdef GIT_TRACE diff --git a/src/transports/http.c b/src/transports/http.c index 66731b0ce13..fb1740c33c7 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -14,7 +14,6 @@ #include "buffer.h" #include "net.h" #include "netops.h" -#include "global.h" #include "remote.h" #include "git2/sys/credential.h" #include "smart.h" diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index ee936c81a64..6ec22f83768 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -10,7 +10,6 @@ #include "http_parser.h" #include "vector.h" #include "trace.h" -#include "global.h" #include "httpclient.h" #include "http.h" #include "auth.h" diff --git a/src/transports/ssh.c b/src/transports/ssh.c index 68b3cbedab7..f4ed05bb160 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -11,7 +11,7 @@ #include #endif -#include "global.h" +#include "runtime.h" #include "git2.h" #include "buffer.h" #include "net.h" @@ -934,8 +934,7 @@ int git_transport_ssh_global_init(void) return -1; } - git__on_shutdown(shutdown_ssh); - return 0; + return git_runtime_shutdown_register(shutdown_ssh); #else diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index f9736cd07f1..2a1f6f26f71 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -17,7 +17,6 @@ #include "smart.h" #include "remote.h" #include "repository.h" -#include "global.h" #include "http.h" #include "git2/sys/credential.h" diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index cacf986e8b5..5a5e92158ea 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -14,7 +14,6 @@ #include "utf-conv.h" #include "repository.h" #include "reparse.h" -#include "global.h" #include "buffer.h" #include #include diff --git a/src/win32/thread.c b/src/win32/thread.c index dad32ef38a3..51b005bc887 100644 --- a/src/win32/thread.c +++ b/src/win32/thread.c @@ -6,6 +6,7 @@ */ #include "thread.h" +#include "runtime.h" #define CLEAN_THREAD_EXIT 0x6F012842 @@ -60,9 +61,7 @@ int git_threads_global_init(void) if ((fls_index = FlsAlloc(NULL)) == FLS_OUT_OF_INDEXES) return -1; - git__on_shutdown(git_threads_global_shutdown); - - return 0; + return git_runtime_shutdown_register(git_threads_global_shutdown); } int git_thread_create( diff --git a/tests/pack/filelimit.c b/tests/pack/filelimit.c index 044679f3bd8..b39ab732758 100644 --- a/tests/pack/filelimit.c +++ b/tests/pack/filelimit.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "mwindow.h" -#include "global.h" #include #include "git2/sys/commit.h" From 1ec4702a51b1074fb7109a841dc95a192feb8525 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 11 Jul 2020 12:25:51 +0100 Subject: [PATCH 0034/1616] Rename global.c to libgit2.c Now that we've identified that our global settings really aren't global at all, and refactored the library to match that, change global.c to libgit2.c, which is especially nice since the prefix of the functions matches the filename. --- src/{global.c => libgit2.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{global.c => libgit2.c} (100%) diff --git a/src/global.c b/src/libgit2.c similarity index 100% rename from src/global.c rename to src/libgit2.c From 634c285a0eb016a2d144b35298dabc350d2e7576 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 11 Jul 2020 12:35:58 +0100 Subject: [PATCH 0035/1616] Move libgit2 settings into libgit2.c --- src/libgit2.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++-- src/libgit2.h | 13 ++ src/settings.c | 322 ------------------------------------------------ 3 files changed, 331 insertions(+), 331 deletions(-) create mode 100644 src/libgit2.h delete mode 100644 src/settings.c diff --git a/src/libgit2.c b/src/libgit2.c index e6b7f46f03d..316d8936527 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -5,25 +5,63 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "runtime.h" +#include "libgit2.h" +#include #include "alloc.h" -#include "threadstate.h" -#include "hash.h" -#include "sysdir.h" +#include "cache.h" +#include "common.h" #include "filter.h" -#include "settings.h" -#include "mwindow.h" +#include "hash.h" +#include "index.h" #include "merge_driver.h" #include "pool.h" +#include "mwindow.h" +#include "object.h" +#include "odb.h" +#include "refs.h" +#include "runtime.h" +#include "sysdir.h" +#include "thread-utils.h" +#include "threadstate.h" +#include "git2/global.h" #include "streams/registry.h" #include "streams/mbedtls.h" #include "streams/openssl.h" -#include "thread-utils.h" -#include "git2/global.h" +#include "transports/smart.h" +#include "transports/http.h" #include "transports/ssh.h" #include "win32/w32_stack.h" +#ifdef GIT_OPENSSL +# include +#endif + +#ifdef GIT_MBEDTLS +# include +#endif + +/* Declarations for tuneable settings */ +extern size_t git_mwindow__window_size; +extern size_t git_mwindow__mapped_limit; +extern size_t git_mwindow__file_limit; +extern size_t git_indexer__max_objects; +extern bool git_disable_pack_keep_file_checks; + +char *git__user_agent; +char *git__ssl_ciphers; + +static void libgit2_settings_global_shutdown(void) +{ + git__free(git__user_agent); + git__free(git__ssl_ciphers); +} + +static int git_libgit2_settings_global_init(void) +{ + return git_runtime_shutdown_register(libgit2_settings_global_shutdown); +} + int git_libgit2_init(void) { static git_runtime_init_fn init_fns[] = { @@ -40,7 +78,7 @@ int git_libgit2_init(void) git_mbedtls_stream_global_init, git_mwindow_global_init, git_pool_global_init, - git_settings_global_init + git_libgit2_settings_global_init }; return git_runtime_init(init_fns, ARRAY_SIZE(init_fns)); @@ -50,3 +88,274 @@ int git_libgit2_shutdown(void) { return git_runtime_shutdown(); } + +int git_libgit2_version(int *major, int *minor, int *rev) +{ + *major = LIBGIT2_VER_MAJOR; + *minor = LIBGIT2_VER_MINOR; + *rev = LIBGIT2_VER_REVISION; + + return 0; +} + +int git_libgit2_features(void) +{ + return 0 +#ifdef GIT_THREADS + | GIT_FEATURE_THREADS +#endif +#ifdef GIT_HTTPS + | GIT_FEATURE_HTTPS +#endif +#if defined(GIT_SSH) + | GIT_FEATURE_SSH +#endif +#if defined(GIT_USE_NSEC) + | GIT_FEATURE_NSEC +#endif + ; +} + +static int config_level_to_sysdir(int config_level) +{ + int val = -1; + + switch (config_level) { + case GIT_CONFIG_LEVEL_SYSTEM: + val = GIT_SYSDIR_SYSTEM; + break; + case GIT_CONFIG_LEVEL_XDG: + val = GIT_SYSDIR_XDG; + break; + case GIT_CONFIG_LEVEL_GLOBAL: + val = GIT_SYSDIR_GLOBAL; + break; + case GIT_CONFIG_LEVEL_PROGRAMDATA: + val = GIT_SYSDIR_PROGRAMDATA; + break; + default: + git_error_set( + GIT_ERROR_INVALID, "invalid config path selector %d", config_level); + } + + return val; +} + +const char *git_libgit2__user_agent(void) +{ + return git__user_agent; +} + +const char *git_libgit2__ssl_ciphers(void) +{ + return git__ssl_ciphers; +} + +int git_libgit2_opts(int key, ...) +{ + int error = 0; + va_list ap; + + va_start(ap, key); + + switch (key) { + case GIT_OPT_SET_MWINDOW_SIZE: + git_mwindow__window_size = va_arg(ap, size_t); + break; + + case GIT_OPT_GET_MWINDOW_SIZE: + *(va_arg(ap, size_t *)) = git_mwindow__window_size; + break; + + case GIT_OPT_SET_MWINDOW_MAPPED_LIMIT: + git_mwindow__mapped_limit = va_arg(ap, size_t); + break; + + case GIT_OPT_GET_MWINDOW_MAPPED_LIMIT: + *(va_arg(ap, size_t *)) = git_mwindow__mapped_limit; + break; + + case GIT_OPT_SET_MWINDOW_FILE_LIMIT: + git_mwindow__file_limit = va_arg(ap, size_t); + break; + + case GIT_OPT_GET_MWINDOW_FILE_LIMIT: + *(va_arg(ap, size_t *)) = git_mwindow__file_limit; + break; + + case GIT_OPT_GET_SEARCH_PATH: + if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0) { + git_buf *out = va_arg(ap, git_buf *); + const git_buf *tmp; + + git_buf_sanitize(out); + if ((error = git_sysdir_get(&tmp, error)) < 0) + break; + + error = git_buf_sets(out, tmp->ptr); + } + break; + + case GIT_OPT_SET_SEARCH_PATH: + if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0) + error = git_sysdir_set(error, va_arg(ap, const char *)); + break; + + case GIT_OPT_SET_CACHE_OBJECT_LIMIT: + { + git_object_t type = (git_object_t)va_arg(ap, int); + size_t size = va_arg(ap, size_t); + error = git_cache_set_max_object_size(type, size); + break; + } + + case GIT_OPT_SET_CACHE_MAX_SIZE: + git_cache__max_storage = va_arg(ap, ssize_t); + break; + + case GIT_OPT_ENABLE_CACHING: + git_cache__enabled = (va_arg(ap, int) != 0); + break; + + case GIT_OPT_GET_CACHED_MEMORY: + *(va_arg(ap, ssize_t *)) = git_cache__current_storage.val; + *(va_arg(ap, ssize_t *)) = git_cache__max_storage; + break; + + case GIT_OPT_GET_TEMPLATE_PATH: + { + git_buf *out = va_arg(ap, git_buf *); + const git_buf *tmp; + + git_buf_sanitize(out); + if ((error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0) + break; + + error = git_buf_sets(out, tmp->ptr); + } + break; + + case GIT_OPT_SET_TEMPLATE_PATH: + error = git_sysdir_set(GIT_SYSDIR_TEMPLATE, va_arg(ap, const char *)); + break; + + case GIT_OPT_SET_SSL_CERT_LOCATIONS: +#ifdef GIT_OPENSSL + { + const char *file = va_arg(ap, const char *); + const char *path = va_arg(ap, const char *); + error = git_openssl__set_cert_location(file, path); + } +#elif defined(GIT_MBEDTLS) + { + const char *file = va_arg(ap, const char *); + const char *path = va_arg(ap, const char *); + if (file) + error = git_mbedtls__set_cert_location(file, 0); + if (error && path) + error = git_mbedtls__set_cert_location(path, 1); + } +#else + git_error_set(GIT_ERROR_SSL, "TLS backend doesn't support certificate locations"); + error = -1; +#endif + break; + case GIT_OPT_SET_USER_AGENT: + git__free(git__user_agent); + git__user_agent = git__strdup(va_arg(ap, const char *)); + if (!git__user_agent) { + git_error_set_oom(); + error = -1; + } + + break; + + case GIT_OPT_ENABLE_STRICT_OBJECT_CREATION: + git_object__strict_input_validation = (va_arg(ap, int) != 0); + break; + + case GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION: + git_reference__enable_symbolic_ref_target_validation = (va_arg(ap, int) != 0); + break; + + case GIT_OPT_SET_SSL_CIPHERS: +#if (GIT_OPENSSL || GIT_MBEDTLS) + { + git__free(git__ssl_ciphers); + git__ssl_ciphers = git__strdup(va_arg(ap, const char *)); + if (!git__ssl_ciphers) { + git_error_set_oom(); + error = -1; + } + } +#else + git_error_set(GIT_ERROR_SSL, "TLS backend doesn't support custom ciphers"); + error = -1; +#endif + break; + + case GIT_OPT_GET_USER_AGENT: + { + git_buf *out = va_arg(ap, git_buf *); + git_buf_sanitize(out); + error = git_buf_sets(out, git__user_agent); + } + break; + + case GIT_OPT_ENABLE_OFS_DELTA: + git_smart__ofs_delta_enabled = (va_arg(ap, int) != 0); + break; + + case GIT_OPT_ENABLE_FSYNC_GITDIR: + git_repository__fsync_gitdir = (va_arg(ap, int) != 0); + break; + + case GIT_OPT_GET_WINDOWS_SHAREMODE: +#ifdef GIT_WIN32 + *(va_arg(ap, unsigned long *)) = git_win32__createfile_sharemode; +#endif + break; + + case GIT_OPT_SET_WINDOWS_SHAREMODE: +#ifdef GIT_WIN32 + git_win32__createfile_sharemode = va_arg(ap, unsigned long); +#endif + break; + + case GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION: + git_odb__strict_hash_verification = (va_arg(ap, int) != 0); + break; + + case GIT_OPT_SET_ALLOCATOR: + error = git_allocator_setup(va_arg(ap, git_allocator *)); + break; + + case GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY: + git_index__enforce_unsaved_safety = (va_arg(ap, int) != 0); + break; + + case GIT_OPT_SET_PACK_MAX_OBJECTS: + git_indexer__max_objects = va_arg(ap, size_t); + break; + + case GIT_OPT_GET_PACK_MAX_OBJECTS: + *(va_arg(ap, size_t *)) = git_indexer__max_objects; + break; + + case GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS: + git_disable_pack_keep_file_checks = (va_arg(ap, int) != 0); + break; + + case GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE: + git_http__expect_continue = (va_arg(ap, int) != 0); + break; + + default: + git_error_set(GIT_ERROR_INVALID, "invalid option key"); + error = -1; + } + + va_end(ap); + + return error; +} diff --git a/src/libgit2.h b/src/libgit2.h new file mode 100644 index 00000000000..6f92a8318bd --- /dev/null +++ b/src/libgit2.h @@ -0,0 +1,13 @@ +/* + * 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_libgit2_h__ +#define INCLUDE_libgit2_h__ + +extern const char *git_libgit2__user_agent(void); +extern const char *git_libgit2__ssl_ciphers(void); + +#endif diff --git a/src/settings.c b/src/settings.c deleted file mode 100644 index 4f69da3e91a..00000000000 --- a/src/settings.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ - -#include "common.h" - -#ifdef GIT_OPENSSL -# include -#endif - -#ifdef GIT_MBEDTLS -# include -#endif - -#include -#include "alloc.h" -#include "sysdir.h" -#include "cache.h" -#include "runtime.h" -#include "object.h" -#include "odb.h" -#include "refs.h" -#include "index.h" -#include "transports/smart.h" -#include "transports/http.h" -#include "streams/openssl.h" -#include "streams/mbedtls.h" - -/* Declarations for tuneable settings */ -extern size_t git_mwindow__window_size; -extern size_t git_mwindow__mapped_limit; -extern size_t git_mwindow__file_limit; -extern size_t git_indexer__max_objects; -extern bool git_disable_pack_keep_file_checks; - -char *git__user_agent; -char *git__ssl_ciphers; - -static void git_settings_global_shutdown(void) -{ - git__free(git__user_agent); - git__free(git__ssl_ciphers); -} - -int git_settings_global_init(void) -{ - return git_runtime_shutdown_register(git_settings_global_shutdown); -} - -int git_libgit2_version(int *major, int *minor, int *rev) -{ - *major = LIBGIT2_VER_MAJOR; - *minor = LIBGIT2_VER_MINOR; - *rev = LIBGIT2_VER_REVISION; - - return 0; -} - -int git_libgit2_features(void) -{ - return 0 -#ifdef GIT_THREADS - | GIT_FEATURE_THREADS -#endif -#ifdef GIT_HTTPS - | GIT_FEATURE_HTTPS -#endif -#if defined(GIT_SSH) - | GIT_FEATURE_SSH -#endif -#if defined(GIT_USE_NSEC) - | GIT_FEATURE_NSEC -#endif - ; -} - -static int config_level_to_sysdir(int config_level) -{ - int val = -1; - - switch (config_level) { - case GIT_CONFIG_LEVEL_SYSTEM: - val = GIT_SYSDIR_SYSTEM; - break; - case GIT_CONFIG_LEVEL_XDG: - val = GIT_SYSDIR_XDG; - break; - case GIT_CONFIG_LEVEL_GLOBAL: - val = GIT_SYSDIR_GLOBAL; - break; - case GIT_CONFIG_LEVEL_PROGRAMDATA: - val = GIT_SYSDIR_PROGRAMDATA; - break; - default: - git_error_set( - GIT_ERROR_INVALID, "invalid config path selector %d", config_level); - } - - return val; -} - -const char *git_libgit2__user_agent(void) -{ - return git__user_agent; -} - -const char *git_libgit2__ssl_ciphers(void) -{ - return git__ssl_ciphers; -} - -int git_libgit2_opts(int key, ...) -{ - int error = 0; - va_list ap; - - va_start(ap, key); - - switch (key) { - case GIT_OPT_SET_MWINDOW_SIZE: - git_mwindow__window_size = va_arg(ap, size_t); - break; - - case GIT_OPT_GET_MWINDOW_SIZE: - *(va_arg(ap, size_t *)) = git_mwindow__window_size; - break; - - case GIT_OPT_SET_MWINDOW_MAPPED_LIMIT: - git_mwindow__mapped_limit = va_arg(ap, size_t); - break; - - case GIT_OPT_GET_MWINDOW_MAPPED_LIMIT: - *(va_arg(ap, size_t *)) = git_mwindow__mapped_limit; - break; - - case GIT_OPT_SET_MWINDOW_FILE_LIMIT: - git_mwindow__file_limit = va_arg(ap, size_t); - break; - - case GIT_OPT_GET_MWINDOW_FILE_LIMIT: - *(va_arg(ap, size_t *)) = git_mwindow__file_limit; - break; - - case GIT_OPT_GET_SEARCH_PATH: - if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0) { - git_buf *out = va_arg(ap, git_buf *); - const git_buf *tmp; - - git_buf_sanitize(out); - if ((error = git_sysdir_get(&tmp, error)) < 0) - break; - - error = git_buf_sets(out, tmp->ptr); - } - break; - - case GIT_OPT_SET_SEARCH_PATH: - if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0) - error = git_sysdir_set(error, va_arg(ap, const char *)); - break; - - case GIT_OPT_SET_CACHE_OBJECT_LIMIT: - { - git_object_t type = (git_object_t)va_arg(ap, int); - size_t size = va_arg(ap, size_t); - error = git_cache_set_max_object_size(type, size); - break; - } - - case GIT_OPT_SET_CACHE_MAX_SIZE: - git_cache__max_storage = va_arg(ap, ssize_t); - break; - - case GIT_OPT_ENABLE_CACHING: - git_cache__enabled = (va_arg(ap, int) != 0); - break; - - case GIT_OPT_GET_CACHED_MEMORY: - *(va_arg(ap, ssize_t *)) = git_cache__current_storage.val; - *(va_arg(ap, ssize_t *)) = git_cache__max_storage; - break; - - case GIT_OPT_GET_TEMPLATE_PATH: - { - git_buf *out = va_arg(ap, git_buf *); - const git_buf *tmp; - - git_buf_sanitize(out); - if ((error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0) - break; - - error = git_buf_sets(out, tmp->ptr); - } - break; - - case GIT_OPT_SET_TEMPLATE_PATH: - error = git_sysdir_set(GIT_SYSDIR_TEMPLATE, va_arg(ap, const char *)); - break; - - case GIT_OPT_SET_SSL_CERT_LOCATIONS: -#ifdef GIT_OPENSSL - { - const char *file = va_arg(ap, const char *); - const char *path = va_arg(ap, const char *); - error = git_openssl__set_cert_location(file, path); - } -#elif defined(GIT_MBEDTLS) - { - const char *file = va_arg(ap, const char *); - const char *path = va_arg(ap, const char *); - if (file) - error = git_mbedtls__set_cert_location(file, 0); - if (error && path) - error = git_mbedtls__set_cert_location(path, 1); - } -#else - git_error_set(GIT_ERROR_SSL, "TLS backend doesn't support certificate locations"); - error = -1; -#endif - break; - case GIT_OPT_SET_USER_AGENT: - git__free(git__user_agent); - git__user_agent = git__strdup(va_arg(ap, const char *)); - if (!git__user_agent) { - git_error_set_oom(); - error = -1; - } - - break; - - case GIT_OPT_ENABLE_STRICT_OBJECT_CREATION: - git_object__strict_input_validation = (va_arg(ap, int) != 0); - break; - - case GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION: - git_reference__enable_symbolic_ref_target_validation = (va_arg(ap, int) != 0); - break; - - case GIT_OPT_SET_SSL_CIPHERS: -#if (GIT_OPENSSL || GIT_MBEDTLS) - { - git__free(git__ssl_ciphers); - git__ssl_ciphers = git__strdup(va_arg(ap, const char *)); - if (!git__ssl_ciphers) { - git_error_set_oom(); - error = -1; - } - } -#else - git_error_set(GIT_ERROR_SSL, "TLS backend doesn't support custom ciphers"); - error = -1; -#endif - break; - - case GIT_OPT_GET_USER_AGENT: - { - git_buf *out = va_arg(ap, git_buf *); - git_buf_sanitize(out); - error = git_buf_sets(out, git__user_agent); - } - break; - - case GIT_OPT_ENABLE_OFS_DELTA: - git_smart__ofs_delta_enabled = (va_arg(ap, int) != 0); - break; - - case GIT_OPT_ENABLE_FSYNC_GITDIR: - git_repository__fsync_gitdir = (va_arg(ap, int) != 0); - break; - - case GIT_OPT_GET_WINDOWS_SHAREMODE: -#ifdef GIT_WIN32 - *(va_arg(ap, unsigned long *)) = git_win32__createfile_sharemode; -#endif - break; - - case GIT_OPT_SET_WINDOWS_SHAREMODE: -#ifdef GIT_WIN32 - git_win32__createfile_sharemode = va_arg(ap, unsigned long); -#endif - break; - - case GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION: - git_odb__strict_hash_verification = (va_arg(ap, int) != 0); - break; - - case GIT_OPT_SET_ALLOCATOR: - error = git_allocator_setup(va_arg(ap, git_allocator *)); - break; - - case GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY: - git_index__enforce_unsaved_safety = (va_arg(ap, int) != 0); - break; - - case GIT_OPT_SET_PACK_MAX_OBJECTS: - git_indexer__max_objects = va_arg(ap, size_t); - break; - - case GIT_OPT_GET_PACK_MAX_OBJECTS: - *(va_arg(ap, size_t *)) = git_indexer__max_objects; - break; - - case GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS: - git_disable_pack_keep_file_checks = (va_arg(ap, int) != 0); - break; - - case GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE: - git_http__expect_continue = (va_arg(ap, int) != 0); - break; - - default: - git_error_set(GIT_ERROR_INVALID, "invalid option key"); - error = -1; - } - - va_end(ap); - - return error; -} From 4a0dceebe4038b2b14460956105100d159c2e628 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sun, 11 Oct 2020 17:53:10 -0700 Subject: [PATCH 0036/1616] Make the Windows leak detection more robust This change: * Increases MY_ROW_LIMIT to 2M, since it has been failing in #5595's tests since it's _super_ close to the limit. * Calls `git_repository_free()` on a `git_repository` that was being leaked only in Windows. * Marks the global `git_repository` on `tests/repo/init.c` as `NULL` after being freed to make any accidental access more noisy. * Uses `cl_assert_equal_i()` in `test_trace_windows_stacktrace__leaks` to make the test failures more actionable. * Renames the globals in `tests/repo/init.c` so that they don't start with an underscore. --- src/win32/w32_crtdbg_stacktrace.c | 2 +- tests/repo/init.c | 173 ++++++++++++++++-------------- tests/trace/windows/stacktrace.c | 21 ++-- 3 files changed, 102 insertions(+), 94 deletions(-) diff --git a/src/win32/w32_crtdbg_stacktrace.c b/src/win32/w32_crtdbg_stacktrace.c index cdb5ac1a5ad..22a353d589f 100644 --- a/src/win32/w32_crtdbg_stacktrace.c +++ b/src/win32/w32_crtdbg_stacktrace.c @@ -57,7 +57,7 @@ static CRITICAL_SECTION g_crtdbg_stacktrace_cs; * it and try again. */ -#define MY_ROW_LIMIT (1024 * 1024) +#define MY_ROW_LIMIT (2 * 1024 * 1024) static git_win32__crtdbg_stacktrace__row g_cs_rows[MY_ROW_LIMIT]; static git_win32__crtdbg_stacktrace__row *g_cs_index[MY_ROW_LIMIT]; diff --git a/tests/repo/init.c b/tests/repo/init.c index ba00d2918eb..b86e09a58bc 100644 --- a/tests/repo/init.c +++ b/tests/repo/init.c @@ -11,30 +11,30 @@ enum repo_mode { BARE_REPOSITORY = 1 }; -static git_repository *_repo = NULL; -static git_buf _global_path = GIT_BUF_INIT; +static git_repository *g_repo = NULL; +static git_buf g_global_path = GIT_BUF_INIT; void test_repo_init__initialize(void) { - _repo = NULL; + g_repo = NULL; git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, - &_global_path); + &g_global_path); } void test_repo_init__cleanup(void) { git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, - _global_path.ptr); - git_buf_dispose(&_global_path); + g_global_path.ptr); + git_buf_dispose(&g_global_path); cl_fixture_cleanup("tmp_global_path"); } static void cleanup_repository(void *path) { - git_repository_free(_repo); - _repo = NULL; + git_repository_free(g_repo); + g_repo = NULL; cl_fixture_cleanup((const char *)path); } @@ -49,9 +49,9 @@ static void ensure_repository_init( cl_assert(!git_path_isdir(working_directory)); - cl_git_pass(git_repository_init(&_repo, working_directory, is_bare)); + cl_git_pass(git_repository_init(&g_repo, working_directory, is_bare)); - workdir = git_repository_workdir(_repo); + workdir = git_repository_workdir(g_repo); if (workdir != NULL || expected_working_directory != NULL) { cl_assert( git__suffixcmp(workdir, expected_working_directory) == 0 @@ -59,19 +59,19 @@ static void ensure_repository_init( } cl_assert( - git__suffixcmp(git_repository_path(_repo), expected_path_repository) == 0 + git__suffixcmp(git_repository_path(g_repo), expected_path_repository) == 0 ); - cl_assert(git_repository_is_bare(_repo) == is_bare); + cl_assert(git_repository_is_bare(g_repo) == is_bare); #ifdef GIT_WIN32 if (!is_bare) { - DWORD fattrs = GetFileAttributes(git_repository_path(_repo)); + DWORD fattrs = GetFileAttributes(git_repository_path(g_repo)); cl_assert((fattrs & FILE_ATTRIBUTE_HIDDEN) != 0); } #endif - cl_assert(git_repository_is_empty(_repo)); + cl_assert(git_repository_is_empty(g_repo)); } void test_repo_init__standard_repo(void) @@ -112,13 +112,14 @@ void test_repo_init__bare_repo_escaping_current_workdir(void) cl_git_pass(chdir(git_buf_cstr(&path_repository))); /* Initialize a bare repo with a relative path escaping out of the current working directory */ - cl_git_pass(git_repository_init(&_repo, "../d/e.git", 1)); - cl_git_pass(git__suffixcmp(git_repository_path(_repo), "/a/b/d/e.git/")); + cl_git_pass(git_repository_init(&g_repo, "../d/e.git", 1)); + cl_git_pass(git__suffixcmp(git_repository_path(g_repo), "/a/b/d/e.git/")); - git_repository_free(_repo); + git_repository_free(g_repo); + g_repo = NULL; /* Open a bare repo with a relative path escaping out of the current working directory */ - cl_git_pass(git_repository_open(&_repo, "../d/e.git")); + cl_git_pass(git_repository_open(&g_repo, "../d/e.git")); cl_git_pass(chdir(git_buf_cstr(&path_current_workdir))); @@ -133,11 +134,12 @@ void test_repo_init__reinit_bare_repo(void) cl_set_cleanup(&cleanup_repository, "reinit.git"); /* Initialize the repository */ - cl_git_pass(git_repository_init(&_repo, "reinit.git", 1)); - git_repository_free(_repo); + cl_git_pass(git_repository_init(&g_repo, "reinit.git", 1)); + git_repository_free(g_repo); + g_repo = NULL; /* Reinitialize the repository */ - cl_git_pass(git_repository_init(&_repo, "reinit.git", 1)); + cl_git_pass(git_repository_init(&g_repo, "reinit.git", 1)); } void test_repo_init__reinit_too_recent_bare_repo(void) @@ -145,8 +147,8 @@ void test_repo_init__reinit_too_recent_bare_repo(void) git_config *config; /* Initialize the repository */ - cl_git_pass(git_repository_init(&_repo, "reinit.git", 1)); - git_repository_config(&config, _repo); + cl_git_pass(git_repository_init(&g_repo, "reinit.git", 1)); + git_repository_config(&config, g_repo); /* * Hack the config of the repository to make it look like it has @@ -155,10 +157,11 @@ void test_repo_init__reinit_too_recent_bare_repo(void) cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 42)); git_config_free(config); - git_repository_free(_repo); + git_repository_free(g_repo); + g_repo = NULL; /* Try to reinitialize the repository */ - cl_git_fail(git_repository_init(&_repo, "reinit.git", 1)); + cl_git_fail(git_repository_init(&g_repo, "reinit.git", 1)); cl_fixture_cleanup("reinit.git"); } @@ -172,15 +175,15 @@ void test_repo_init__additional_templates(void) ensure_repository_init("tester", 0, "tester/.git/", "tester/"); cl_git_pass( - git_buf_joinpath(&path, git_repository_path(_repo), "description")); + git_buf_joinpath(&path, git_repository_path(g_repo), "description")); cl_assert(git_path_isfile(git_buf_cstr(&path))); cl_git_pass( - git_buf_joinpath(&path, git_repository_path(_repo), "info/exclude")); + git_buf_joinpath(&path, git_repository_path(g_repo), "info/exclude")); cl_assert(git_path_isfile(git_buf_cstr(&path))); cl_git_pass( - git_buf_joinpath(&path, git_repository_path(_repo), "hooks")); + git_buf_joinpath(&path, git_repository_path(g_repo), "hooks")); cl_assert(git_path_isdir(git_buf_cstr(&path))); /* won't confirm specific contents of hooks dir since it may vary */ @@ -197,9 +200,9 @@ static void assert_config_entry_on_init_bytype( cl_set_cleanup(&cleanup_repository, "config_entry"); - cl_git_pass(git_repository_init(&_repo, repo_path, is_bare)); + cl_git_pass(git_repository_init(&g_repo, repo_path, is_bare)); - cl_git_pass(git_repository_config(&config, _repo)); + cl_git_pass(git_repository_config(&config, g_repo)); error = git_config_get_bool(¤t_value, config, config_key); git_config_free(config); @@ -215,7 +218,8 @@ static void assert_config_entry_on_init( const char *config_key, int expected_value) { assert_config_entry_on_init_bytype(config_key, expected_value, true); - git_repository_free(_repo); + git_repository_free(g_repo); + g_repo = NULL; assert_config_entry_on_init_bytype(config_key, expected_value, false); } @@ -262,10 +266,10 @@ void test_repo_init__symlinks_win32_enabled_by_global_config(void) * Create a new repository (can't use `assert_config_on_init` since we * want to examine configuration levels with more granularity.) */ - cl_git_pass(git_repository_init(&_repo, "config_entry/test.non.bare.git", false)); + cl_git_pass(git_repository_init(&g_repo, "config_entry/test.non.bare.git", false)); /* Ensure that core.symlinks remains set (via the global config). */ - cl_git_pass(git_repository_config(&config, _repo)); + cl_git_pass(git_repository_config(&config, g_repo)); cl_git_pass(git_config_get_bool(&val, config, "core.symlinks")); cl_assert_equal_i(1, val); @@ -278,6 +282,9 @@ void test_repo_init__symlinks_win32_enabled_by_global_config(void) git_config_free(repo_config); git_config_free(config); + + git_repository_free(g_repo); + g_repo = NULL; #endif } @@ -324,18 +331,18 @@ void test_repo_init__reinit_doesnot_overwrite_ignorecase(void) /* Init a new repo */ cl_set_cleanup(&cleanup_repository, "not.overwrite.git"); - cl_git_pass(git_repository_init(&_repo, "not.overwrite.git", 1)); + cl_git_pass(git_repository_init(&g_repo, "not.overwrite.git", 1)); /* Change the "core.ignorecase" config value to something unlikely */ - git_repository_config(&config, _repo); + git_repository_config(&config, g_repo); git_config_set_int32(config, "core.ignorecase", 42); git_config_free(config); - git_repository_free(_repo); - _repo = NULL; + git_repository_free(g_repo); + g_repo = NULL; /* Reinit the repository */ - cl_git_pass(git_repository_init(&_repo, "not.overwrite.git", 1)); - git_repository_config(&config, _repo); + cl_git_pass(git_repository_init(&g_repo, "not.overwrite.git", 1)); + git_repository_config(&config, g_repo); /* Ensure the "core.ignorecase" config value hasn't been updated */ cl_git_pass(git_config_get_int32(¤t_value, config, "core.ignorecase")); @@ -350,26 +357,26 @@ void test_repo_init__reinit_overwrites_filemode(void) /* Init a new repo */ cl_set_cleanup(&cleanup_repository, "overwrite.git"); - cl_git_pass(git_repository_init(&_repo, "overwrite.git", 1)); + cl_git_pass(git_repository_init(&g_repo, "overwrite.git", 1)); /* Change the "core.filemode" config value to something unlikely */ - cl_repo_set_bool(_repo, "core.filemode", !expected); + cl_repo_set_bool(g_repo, "core.filemode", !expected); - git_repository_free(_repo); - _repo = NULL; + git_repository_free(g_repo); + g_repo = NULL; /* Reinit the repository */ - cl_git_pass(git_repository_init(&_repo, "overwrite.git", 1)); + cl_git_pass(git_repository_init(&g_repo, "overwrite.git", 1)); /* Ensure the "core.filemode" config value has been reset */ - current_value = cl_repo_get_bool(_repo, "core.filemode"); + current_value = cl_repo_get_bool(g_repo, "core.filemode"); cl_assert_equal_i(expected, current_value); } void test_repo_init__sets_logAllRefUpdates_according_to_type_of_repository(void) { assert_config_entry_on_init_bytype("core.logallrefupdates", GIT_ENOTFOUND, true); - git_repository_free(_repo); + git_repository_free(g_repo); assert_config_entry_on_init_bytype("core.logallrefupdates", true, false); } @@ -378,16 +385,16 @@ void test_repo_init__extended_0(void) git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; /* without MKDIR this should fail */ - cl_git_fail(git_repository_init_ext(&_repo, "extended", &opts)); + cl_git_fail(git_repository_init_ext(&g_repo, "extended", &opts)); /* make the directory first, then it should succeed */ cl_git_pass(git_futils_mkdir("extended", 0775, 0)); - cl_git_pass(git_repository_init_ext(&_repo, "extended", &opts)); + cl_git_pass(git_repository_init_ext(&g_repo, "extended", &opts)); - cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "/extended/")); - cl_assert(!git__suffixcmp(git_repository_path(_repo), "/extended/.git/")); - cl_assert(!git_repository_is_bare(_repo)); - cl_assert(git_repository_is_empty(_repo)); + cl_assert(!git__suffixcmp(git_repository_workdir(g_repo), "/extended/")); + cl_assert(!git__suffixcmp(git_repository_path(g_repo), "/extended/.git/")); + cl_assert(!git_repository_is_bare(g_repo)); + cl_assert(git_repository_is_empty(g_repo)); cleanup_repository("extended"); } @@ -407,33 +414,33 @@ void test_repo_init__extended_1(void) opts.initial_head = "development"; opts.origin_url = "https://github.com/libgit2/libgit2.git"; - cl_git_pass(git_repository_init_ext(&_repo, "root/b/c.git", &opts)); + cl_git_pass(git_repository_init_ext(&g_repo, "root/b/c.git", &opts)); - cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "/c_wd/")); - cl_assert(!git__suffixcmp(git_repository_path(_repo), "/c.git/")); + cl_assert(!git__suffixcmp(git_repository_workdir(g_repo), "/c_wd/")); + cl_assert(!git__suffixcmp(git_repository_path(g_repo), "/c.git/")); cl_assert(git_path_isfile("root/b/c_wd/.git")); - cl_assert(!git_repository_is_bare(_repo)); + cl_assert(!git_repository_is_bare(g_repo)); /* repo will not be counted as empty because we set head to "development" */ - cl_assert(!git_repository_is_empty(_repo)); + cl_assert(!git_repository_is_empty(g_repo)); - cl_git_pass(git_path_lstat(git_repository_path(_repo), &st)); + cl_git_pass(git_path_lstat(git_repository_path(g_repo), &st)); cl_assert(S_ISDIR(st.st_mode)); if (cl_is_chmod_supported()) cl_assert((S_ISGID & st.st_mode) == S_ISGID); else cl_assert((S_ISGID & st.st_mode) == 0); - cl_git_pass(git_reference_lookup(&ref, _repo, "HEAD")); + cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD")); cl_assert(git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC); cl_assert_equal_s("refs/heads/development", git_reference_symbolic_target(ref)); git_reference_free(ref); - cl_git_pass(git_remote_lookup(&remote, _repo, "origin")); + cl_git_pass(git_remote_lookup(&remote, g_repo, "origin")); cl_assert_equal_s("origin", git_remote_name(remote)); cl_assert_equal_s(opts.origin_url, git_remote_url(remote)); git_remote_free(remote); - git_repository_free(_repo); + git_repository_free(g_repo); cl_fixture_cleanup("root"); } @@ -449,17 +456,17 @@ void test_repo_init__relative_gitdir(void) GIT_REPOSITORY_INIT_NO_DOTGIT_DIR; /* make the directory first, then it should succeed */ - cl_git_pass(git_repository_init_ext(&_repo, "root/b/my_repository", &opts)); + cl_git_pass(git_repository_init_ext(&g_repo, "root/b/my_repository", &opts)); - cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "root/b/c_wd/")); - cl_assert(!git__suffixcmp(git_repository_path(_repo), "root/b/my_repository/")); - cl_assert(!git_repository_is_bare(_repo)); - cl_assert(git_repository_is_empty(_repo)); + cl_assert(!git__suffixcmp(git_repository_workdir(g_repo), "root/b/c_wd/")); + cl_assert(!git__suffixcmp(git_repository_path(g_repo), "root/b/my_repository/")); + cl_assert(!git_repository_is_bare(g_repo)); + cl_assert(git_repository_is_empty(g_repo)); /* Verify that the gitlink and worktree entries are relative */ /* Verify worktree */ - assert_config_entry_value(_repo, "core.worktree", "../c_wd/"); + assert_config_entry_value(g_repo, "core.worktree", "../c_wd/"); /* Verify gitlink */ cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git")); @@ -485,18 +492,18 @@ void test_repo_init__relative_gitdir_2(void) GIT_REPOSITORY_INIT_NO_DOTGIT_DIR; /* make the directory first, then it should succeed */ - cl_git_pass(git_repository_init_ext(&_repo, "root/b/my_repository", &opts)); + cl_git_pass(git_repository_init_ext(&g_repo, "root/b/my_repository", &opts)); git_buf_dispose(&full_path); - cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "root/b/c_wd/")); - cl_assert(!git__suffixcmp(git_repository_path(_repo), "root/b/my_repository/")); - cl_assert(!git_repository_is_bare(_repo)); - cl_assert(git_repository_is_empty(_repo)); + cl_assert(!git__suffixcmp(git_repository_workdir(g_repo), "root/b/c_wd/")); + cl_assert(!git__suffixcmp(git_repository_path(g_repo), "root/b/my_repository/")); + cl_assert(!git_repository_is_bare(g_repo)); + cl_assert(git_repository_is_empty(g_repo)); /* Verify that the gitlink and worktree entries are relative */ /* Verify worktree */ - assert_config_entry_value(_repo, "core.worktree", "../c_wd/"); + assert_config_entry_value(g_repo, "core.worktree", "../c_wd/"); /* Verify gitlink */ cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git")); @@ -513,11 +520,11 @@ void test_repo_init__can_reinit_an_initialized_repository(void) cl_set_cleanup(&cleanup_repository, "extended"); cl_git_pass(git_futils_mkdir("extended", 0775, 0)); - cl_git_pass(git_repository_init(&_repo, "extended", false)); + cl_git_pass(git_repository_init(&g_repo, "extended", false)); cl_git_pass(git_repository_init(&reinit, "extended", false)); - cl_assert_equal_s(git_repository_path(_repo), git_repository_path(reinit)); + cl_assert_equal_s(git_repository_path(g_repo), git_repository_path(reinit)); git_repository_free(reinit); } @@ -529,10 +536,10 @@ void test_repo_init__init_with_initial_commit(void) cl_set_cleanup(&cleanup_repository, "committed"); /* Initialize the repository */ - cl_git_pass(git_repository_init(&_repo, "committed", 0)); + cl_git_pass(git_repository_init(&g_repo, "committed", 0)); /* Index will be automatically created when requested for a new repo */ - cl_git_pass(git_repository_index(&index, _repo)); + cl_git_pass(git_repository_index(&index, g_repo)); /* Create a file so we can commit it * @@ -558,7 +565,7 @@ void test_repo_init__init_with_initial_commit(void) /* Make sure we're ready to use git_signature_default :-) */ { git_config *cfg, *local; - cl_git_pass(git_repository_config(&cfg, _repo)); + cl_git_pass(git_repository_config(&cfg, g_repo)); cl_git_pass(git_config_open_level(&local, cfg, GIT_CONFIG_LEVEL_LOCAL)); cl_git_pass(git_config_set_string(local, "user.name", "Test User")); cl_git_pass(git_config_set_string(local, "user.email", "t@example.com")); @@ -572,12 +579,12 @@ void test_repo_init__init_with_initial_commit(void) git_oid tree_id, commit_id; git_tree *tree; - cl_git_pass(git_signature_default(&sig, _repo)); + cl_git_pass(git_signature_default(&sig, g_repo)); cl_git_pass(git_index_write_tree(&tree_id, index)); - cl_git_pass(git_tree_lookup(&tree, _repo, &tree_id)); + cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id)); cl_git_pass(git_commit_create_v( - &commit_id, _repo, "HEAD", sig, sig, + &commit_id, g_repo, "HEAD", sig, sig, NULL, "First", tree, 0)); git_tree_free(tree); @@ -674,8 +681,8 @@ void test_repo_init__defaultbranch_config(void) create_tmp_global_config("tmp_global_path", "init.defaultbranch", "my_default_branch"); - cl_git_pass(git_repository_init(&_repo, "repo", 0)); - cl_git_pass(git_reference_lookup(&head, _repo, "HEAD")); + cl_git_pass(git_repository_init(&g_repo, "repo", 0)); + cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_assert_equal_s("refs/heads/my_default_branch", git_reference_symbolic_target(head)); diff --git a/tests/trace/windows/stacktrace.c b/tests/trace/windows/stacktrace.c index 756ac68a398..34fcbcb894b 100644 --- a/tests/trace/windows/stacktrace.c +++ b/tests/trace/windows/stacktrace.c @@ -58,47 +58,48 @@ void test_trace_windows_stacktrace__leaks(void) GIT_WIN32__CRTDBG_STACKTRACE__QUIET | GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, "p1"); - cl_assert((leaks == 1)); + cl_assert_equal_i(1, leaks); p2 = git__malloc(5); leaks = git_win32__crtdbg_stacktrace__dump( GIT_WIN32__CRTDBG_STACKTRACE__QUIET | GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, "p1,p2"); - cl_assert((leaks == 2)); + cl_assert_equal_i(2, leaks); p3 = git__malloc(5); leaks = git_win32__crtdbg_stacktrace__dump( GIT_WIN32__CRTDBG_STACKTRACE__QUIET | GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, "p1,p2,p3"); - cl_assert((leaks == 3)); + cl_assert_equal_i(3, leaks); git__free(p2); leaks = git_win32__crtdbg_stacktrace__dump( GIT_WIN32__CRTDBG_STACKTRACE__QUIET | GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, "p1,p3"); - cl_assert((leaks == 2)); + cl_assert_equal_i(2, leaks); /* move the mark. only new leaks should appear afterwards */ error = git_win32__crtdbg_stacktrace__dump( GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK, NULL); - cl_assert((error == 0)); + /* cannot use cl_git_pass() since that may allocate memory. */ + cl_assert_equal_i(0, error); leaks = git_win32__crtdbg_stacktrace__dump( GIT_WIN32__CRTDBG_STACKTRACE__QUIET | GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, "not_p1,not_p3"); - cl_assert((leaks == 0)); + cl_assert_equal_i(0, leaks); p4 = git__malloc(5); leaks = git_win32__crtdbg_stacktrace__dump( GIT_WIN32__CRTDBG_STACKTRACE__QUIET | GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, "p4,not_p1,not_p3"); - cl_assert((leaks == 1)); + cl_assert_equal_i(1, leaks); git__free(p1); git__free(p3); @@ -106,21 +107,21 @@ void test_trace_windows_stacktrace__leaks(void) GIT_WIN32__CRTDBG_STACKTRACE__QUIET | GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, "p4"); - cl_assert((leaks == 1)); + cl_assert_equal_i(1, leaks); git__free(p4); leaks = git_win32__crtdbg_stacktrace__dump( GIT_WIN32__CRTDBG_STACKTRACE__QUIET | GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, "end"); - cl_assert((leaks == 0)); + cl_assert_equal_i(0, leaks); /* confirm current absolute leaks count matches beginning value. */ after = git_win32__crtdbg_stacktrace__dump( GIT_WIN32__CRTDBG_STACKTRACE__QUIET | GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_TOTAL, "total"); - cl_assert((before == after)); + cl_assert_equal_i(before, after); #endif } From fa3daa8259df6c09a7e075b0b959eabc791f92f9 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 13 Oct 2020 08:02:59 -0700 Subject: [PATCH 0037/1616] Define `git___load` when building with `-DTHREADSAFE=OFF` This should allow folks that build in non-thread-safe environments to still be able to build the library. Fixes: #5663 --- src/thread-utils.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/thread-utils.h b/src/thread-utils.h index ecb4909f554..3311672b4f0 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -311,6 +311,11 @@ GIT_INLINE(volatile void *) git___swap( return old; } +GIT_INLINE(volatile void *) git___load(void * volatile *ptr) +{ + return *ptr; +} + #ifdef GIT_ARCH_64 GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend) From 246bc3ccfe24f6c4ab5b866f77f7bf30791dec2e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 14 Oct 2020 15:05:11 +0100 Subject: [PATCH 0038/1616] threadstate: rename tlsdata when building w/o threads --- src/threadstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threadstate.c b/src/threadstate.c index 8e17124a25a..1c5ac60917f 100644 --- a/src/threadstate.c +++ b/src/threadstate.c @@ -135,7 +135,7 @@ static void git_threadstate_global_shutdown(void) int git_threadstate_global_init(void) { - return git_runtime_shutdown_register(git_tlsdata_global_shutdown); + return git_runtime_shutdown_register(git_threadstate_global_shutdown); } git_threadstate *git_threadstate_get(void) From 1822b0827a652d5c970a3a906e1801fb8251135b Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Tue, 20 Oct 2020 23:26:47 +0000 Subject: [PATCH 0039/1616] Include `${MBEDTLS_INCLUDE_DIR}` when compiling `crypt_mbedtls.c` Without this, mbedTLS installs in non-default install locations that are otherwise found by the `FindmbedTLS.cmake` module are not found by the C preprocessor at compile time. --- deps/ntlmclient/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/deps/ntlmclient/CMakeLists.txt b/deps/ntlmclient/CMakeLists.txt index 5fbf0d0f447..d933f4919ac 100644 --- a/deps/ntlmclient/CMakeLists.txt +++ b/deps/ntlmclient/CMakeLists.txt @@ -16,6 +16,7 @@ ELSEIF(USE_HTTPS STREQUAL "OpenSSL") SET(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c") ELSEIF(USE_HTTPS STREQUAL "mbedTLS") ADD_DEFINITIONS(-DCRYPT_MBEDTLS) + INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIR}) SET(SRC_NTLMCLIENT_CRYPTO "crypt_mbedtls.c") ELSE() MESSAGE(FATAL_ERROR "Unable to use libgit2's HTTPS backend (${USE_HTTPS}) for NTLM crypto") From d70979cf891279e20a00bb04ece2f0ce129dd7e4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 11 Oct 2020 12:26:34 +0100 Subject: [PATCH 0040/1616] refs: error checking in internal name validation Move `git_reference__is_valid_name` to `git_reference__name_is_valid`, which returns errors and sets an out boolean parameter. --- src/refs.c | 27 +++++++++++++++----- src/refs.h | 2 +- src/refspec.c | 71 +++++++++++++++++++++++++++++++-------------------- 3 files changed, 64 insertions(+), 36 deletions(-) diff --git a/src/refs.c b/src/refs.c index 51635a9e4cd..bb83d9b3c72 100644 --- a/src/refs.c +++ b/src/refs.c @@ -1287,19 +1287,32 @@ int git_reference_peel( return error; } -int git_reference__is_valid_name(const char *refname, unsigned int flags) +int git_reference__name_is_valid( + int *valid, + const char *refname, + unsigned int flags) { - if (git_reference__normalize_name(NULL, refname, flags) < 0) { - git_error_clear(); - return false; - } + int error; - return true; + *valid = 0; + + error = git_reference__normalize_name(NULL, refname, flags); + + if (!error) + *valid = 1; + else if (error == GIT_EINVALIDSPEC) + error = 0; + + return error; } int git_reference_is_valid_name(const char *refname) { - return git_reference__is_valid_name(refname, GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL); + int valid = 0; + + git_reference__name_is_valid(&valid, refname, GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL); + + return valid; } const char *git_reference__shorthand(const char *name) diff --git a/src/refs.h b/src/refs.h index e0ee03b0e2a..376a512f85d 100644 --- a/src/refs.h +++ b/src/refs.h @@ -85,7 +85,7 @@ git_reference *git_reference__realloc(git_reference **ptr_to_ref, const char *na int git_reference__normalize_name(git_buf *buf, const char *name, unsigned int flags); int git_reference__update_terminal(git_repository *repo, const char *ref_name, const git_oid *oid, const git_signature *sig, const char *log_message); -int git_reference__is_valid_name(const char *refname, unsigned int flags); +int git_reference__name_is_valid(int *valid, const char *name, unsigned int flags); int git_reference__is_branch(const char *ref_name); int git_reference__is_remote(const char *ref_name); int git_reference__is_tag(const char *ref_name); diff --git a/src/refspec.c b/src/refspec.c index 854240a8460..95b2830f831 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -21,7 +21,8 @@ int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch) size_t llen; int is_glob = 0; const char *lhs, *rhs; - int flags; + int valid = 0; + unsigned int flags; assert(refspec && input); @@ -75,57 +76,69 @@ int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch) if (is_fetch) { /* - * LHS - * - empty is allowed; it means HEAD. - * - otherwise it must be a valid looking ref. - */ + * LHS + * - empty is allowed; it means HEAD. + * - otherwise it must be a valid looking ref. + */ if (!*refspec->src) ; /* empty is ok */ - else if (!git_reference__is_valid_name(refspec->src, flags)) + else if (git_reference__name_is_valid(&valid, refspec->src, flags) < 0) + goto on_error; + else if (!valid) goto invalid; + /* - * RHS - * - missing is ok, and is same as empty. - * - empty is ok; it means not to store. - * - otherwise it must be a valid looking ref. - */ + * RHS + * - missing is ok, and is same as empty. + * - empty is ok; it means not to store. + * - otherwise it must be a valid looking ref. + */ if (!refspec->dst) ; /* ok */ else if (!*refspec->dst) ; /* ok */ - else if (!git_reference__is_valid_name(refspec->dst, flags)) + else if (git_reference__name_is_valid(&valid, refspec->dst, flags) < 0) + goto on_error; + else if (!valid) goto invalid; } else { /* - * LHS - * - empty is allowed; it means delete. - * - when wildcarded, it must be a valid looking ref. - * - otherwise, it must be an extended SHA-1, but - * there is no existing way to validate this. - */ + * LHS + * - empty is allowed; it means delete. + * - when wildcarded, it must be a valid looking ref. + * - otherwise, it must be an extended SHA-1, but + * there is no existing way to validate this. + */ if (!*refspec->src) ; /* empty is ok */ else if (is_glob) { - if (!git_reference__is_valid_name(refspec->src, flags)) + if (git_reference__name_is_valid(&valid, refspec->src, flags) < 0) + goto on_error; + else if (!valid) goto invalid; } else { ; /* anything goes, for now */ } + /* - * RHS - * - missing is allowed, but LHS then must be a - * valid looking ref. - * - empty is not allowed. - * - otherwise it must be a valid looking ref. - */ + * RHS + * - missing is allowed, but LHS then must be a + * valid looking ref. + * - empty is not allowed. + * - otherwise it must be a valid looking ref. + */ if (!refspec->dst) { - if (!git_reference__is_valid_name(refspec->src, flags)) + if (git_reference__name_is_valid(&valid, refspec->src, flags) < 0) + goto on_error; + else if (!valid) goto invalid; } else if (!*refspec->dst) { goto invalid; } else { - if (!git_reference__is_valid_name(refspec->dst, flags)) + if (git_reference__name_is_valid(&valid, refspec->dst, flags) < 0) + goto on_error; + else if (!valid) goto invalid; } @@ -141,10 +154,12 @@ int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch) return 0; - invalid: +invalid: git_error_set( GIT_ERROR_INVALID, "'%s' is not a valid refspec.", input); + +on_error: git_refspec__dispose(refspec); return -1; } From 29715d4082ef97d54ce2bf24943425f558335796 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 11 Oct 2020 12:50:52 +0100 Subject: [PATCH 0041/1616] refs: introduce git_reference_name_is_valid Provide a function that can check reference name validity but can also signal when an error occurs. Use the name "name_is_valid", which is more suggestive of checking a given name, rather than "is_valid_name", which suggests that the function checks the validity of the current reference's name. --- include/git2/refs.h | 17 +++++++++++++++++ src/fetch.c | 7 +++++-- src/refs.c | 7 +++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/git2/refs.h b/include/git2/refs.h index c9cce221248..6145811bb23 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -732,6 +732,23 @@ GIT_EXTERN(int) git_reference_peel( const git_reference *ref, git_object_t type); +/** + * Ensure the reference name is well-formed. + * + * Valid reference names must follow one of two patterns: + * + * 1. Top-level names must contain only capital letters and underscores, + * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). + * 2. Names prefixed with "refs/" can be almost anything. You must avoid + * the characters '~', '^', ':', '\\', '?', '[', and '*', and the + * sequences ".." and "@{" which have special meaning to revparse. + * + * @param valid output pointer to set with validity of given reference name + * @param refname name to be checked. + * @return 0 on success or an error code + */ +GIT_EXTERN(int) git_reference_name_is_valid(int *valid, const char *refname); + /** * Ensure the reference name is well-formed. * diff --git a/src/fetch.c b/src/fetch.c index f4a4c9f8170..dedbb54fa54 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -21,9 +21,12 @@ static int maybe_want(git_remote *remote, git_remote_head *head, git_odb *odb, git_refspec *tagspec, git_remote_autotag_option_t tagopt) { - int match = 0; + int match = 0, valid; - if (!git_reference_is_valid_name(head->name)) + if (git_reference_name_is_valid(&valid, head->name) < 0) + return -1; + + if (!valid) return 0; if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_ALL) { diff --git a/src/refs.c b/src/refs.c index bb83d9b3c72..da12d02f242 100644 --- a/src/refs.c +++ b/src/refs.c @@ -1294,6 +1294,8 @@ int git_reference__name_is_valid( { int error; + GIT_ASSERT(valid && refname); + *valid = 0; error = git_reference__normalize_name(NULL, refname, flags); @@ -1306,6 +1308,11 @@ int git_reference__name_is_valid( return error; } +int git_reference_name_is_valid(int *valid, const char *refname) +{ + return git_reference__name_is_valid(valid, refname, GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL); +} + int git_reference_is_valid_name(const char *refname) { int valid = 0; From b52bb4d4b2548d0c7f00de0eab5073cc8fe9e899 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 11 Oct 2020 13:20:52 +0100 Subject: [PATCH 0042/1616] refs: use git_reference_name_is_valid --- src/refs.c | 7 +++--- src/remote.c | 13 +++++++--- src/repository.c | 7 +++--- tests/online/push_util.c | 4 +++- tests/refs/isvalidname.c | 51 +++++++++++++++++++++++----------------- 5 files changed, 50 insertions(+), 32 deletions(-) diff --git a/src/refs.c b/src/refs.c index da12d02f242..90b9b06ffc5 100644 --- a/src/refs.c +++ b/src/refs.c @@ -239,7 +239,7 @@ int git_reference_lookup_resolved( int git_reference_dwim(git_reference **out, git_repository *repo, const char *refname) { - int error = 0, i; + int error = 0, i, valid; bool fallbackmode = true, foundvalid = false; git_reference *ref; git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT; @@ -265,10 +265,11 @@ int git_reference_dwim(git_reference **out, git_repository *repo, const char *re git_buf_clear(&refnamebuf); - if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0) + if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0 || + (error = git_reference_name_is_valid(&valid, git_buf_cstr(&refnamebuf))) < 0) goto cleanup; - if (!git_reference_is_valid_name(git_buf_cstr(&refnamebuf))) { + if (!valid) { error = GIT_EINVALIDSPEC; continue; } diff --git a/src/remote.c b/src/remote.c index 51e99dc949b..b69526c4232 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1362,7 +1362,7 @@ static int update_tips_for_spec( git_vector *refs, const char *log_message) { - int error = 0, autotag; + int error = 0, autotag, valid; unsigned int i = 0; git_buf refname = GIT_BUF_INIT; git_oid old; @@ -1390,7 +1390,10 @@ static int update_tips_for_spec( git_buf_clear(&refname); /* Ignore malformed ref names (which also saves us from tag^{} */ - if (!git_reference_is_valid_name(head->name)) + if (git_reference_name_is_valid(&valid, head->name) < 0) + goto on_error; + + if (!valid) continue; /* If we have a tag, see if the auto-follow rules say to update it */ @@ -1499,6 +1502,7 @@ static int next_head(const git_remote *remote, git_vector *refs, git_remote_head *head; git_refspec *spec, *passive_spec; size_t i, j, k; + int valid; active = &remote->active_refspecs; passive = &remote->passive_refspecs; @@ -1510,7 +1514,10 @@ static int next_head(const git_remote *remote, git_vector *refs, for (; i < refs->length; i++) { head = git_vector_get(refs, i); - if (!git_reference_is_valid_name(head->name)) + if (git_reference_name_is_valid(&valid, head->name) < 0) + return -1; + + if (!valid) continue; for (; j < active->length; j++) { diff --git a/src/repository.c b/src/repository.c index 513dbd61f83..f0d4b06aac1 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2359,7 +2359,7 @@ int git_repository_initialbranch(git_buf *out, git_repository *repo) git_config *config; git_config_entry *entry = NULL; const char *branch; - int error; + int valid, error; if ((error = git_repository_config__weakptr(&config, repo)) < 0) return error; @@ -2375,10 +2375,11 @@ int git_repository_initialbranch(git_buf *out, git_repository *repo) } if ((error = git_buf_puts(out, GIT_REFS_HEADS_DIR)) < 0 || - (error = git_buf_puts(out, branch)) < 0) + (error = git_buf_puts(out, branch)) < 0 || + (error = git_reference_name_is_valid(&valid, out->ptr)) < 0) goto done; - if (!git_reference_is_valid_name(out->ptr)) { + if (!valid) { git_error_set(GIT_ERROR_INVALID, "the value of init.defaultBranch is not a valid reference name"); error = -1; } diff --git a/tests/online/push_util.c b/tests/online/push_util.c index fe9af2c4369..b39f7811421 100644 --- a/tests/online/push_util.c +++ b/tests/online/push_util.c @@ -58,12 +58,14 @@ int record_update_tips_cb(const char *refname, const git_oid *a, const git_oid * int create_deletion_refspecs(git_vector *out, const git_remote_head **heads, size_t heads_len) { git_buf del_spec = GIT_BUF_INIT; + int valid; size_t i; for (i = 0; i < heads_len; i++) { const git_remote_head *head = heads[i]; /* Ignore malformed ref names (which also saves us from tag^{} */ - if (!git_reference_is_valid_name(head->name)) + cl_git_pass(git_reference_name_is_valid(&valid, head->name)); + if (!valid) return 0; /* Create a refspec that deletes a branch in the remote */ diff --git a/tests/refs/isvalidname.c b/tests/refs/isvalidname.c index 65c70ba4d88..063f0f798f9 100644 --- a/tests/refs/isvalidname.c +++ b/tests/refs/isvalidname.c @@ -1,31 +1,38 @@ #include "clar_libgit2.h" +static bool is_valid_name(const char *name) +{ + int valid; + cl_git_pass(git_reference_name_is_valid(&valid, name)); + return valid; +} + void test_refs_isvalidname__can_detect_invalid_formats(void) { - cl_assert_equal_i(false, git_reference_is_valid_name("refs/tags/0.17.0^{}")); - cl_assert_equal_i(false, git_reference_is_valid_name("TWO/LEVELS")); - cl_assert_equal_i(false, git_reference_is_valid_name("ONE.LEVEL")); - cl_assert_equal_i(false, git_reference_is_valid_name("HEAD/")); - cl_assert_equal_i(false, git_reference_is_valid_name("NO_TRAILING_UNDERSCORE_")); - cl_assert_equal_i(false, git_reference_is_valid_name("_NO_LEADING_UNDERSCORE")); - cl_assert_equal_i(false, git_reference_is_valid_name("HEAD/aa")); - cl_assert_equal_i(false, git_reference_is_valid_name("lower_case")); - cl_assert_equal_i(false, git_reference_is_valid_name("/stupid/name/master")); - cl_assert_equal_i(false, git_reference_is_valid_name("/")); - cl_assert_equal_i(false, git_reference_is_valid_name("//")); - cl_assert_equal_i(false, git_reference_is_valid_name("")); - cl_assert_equal_i(false, git_reference_is_valid_name("refs/heads/sub.lock/webmatrix")); + cl_assert_equal_i(false, is_valid_name("refs/tags/0.17.0^{}")); + cl_assert_equal_i(false, is_valid_name("TWO/LEVELS")); + cl_assert_equal_i(false, is_valid_name("ONE.LEVEL")); + cl_assert_equal_i(false, is_valid_name("HEAD/")); + cl_assert_equal_i(false, is_valid_name("NO_TRAILING_UNDERSCORE_")); + cl_assert_equal_i(false, is_valid_name("_NO_LEADING_UNDERSCORE")); + cl_assert_equal_i(false, is_valid_name("HEAD/aa")); + cl_assert_equal_i(false, is_valid_name("lower_case")); + cl_assert_equal_i(false, is_valid_name("/stupid/name/master")); + cl_assert_equal_i(false, is_valid_name("/")); + cl_assert_equal_i(false, is_valid_name("//")); + cl_assert_equal_i(false, is_valid_name("")); + cl_assert_equal_i(false, is_valid_name("refs/heads/sub.lock/webmatrix")); } void test_refs_isvalidname__wont_hopefully_choke_on_valid_formats(void) { - cl_assert_equal_i(true, git_reference_is_valid_name("refs/tags/0.17.0")); - cl_assert_equal_i(true, git_reference_is_valid_name("refs/LEVELS")); - cl_assert_equal_i(true, git_reference_is_valid_name("HEAD")); - cl_assert_equal_i(true, git_reference_is_valid_name("ONE_LEVEL")); - cl_assert_equal_i(true, git_reference_is_valid_name("refs/stash")); - cl_assert_equal_i(true, git_reference_is_valid_name("refs/remotes/origin/bim_with_3d@11296")); - cl_assert_equal_i(true, git_reference_is_valid_name("refs/master{yesterday")); - cl_assert_equal_i(true, git_reference_is_valid_name("refs/master}yesterday")); - cl_assert_equal_i(true, git_reference_is_valid_name("refs/master{yesterday}")); + cl_assert_equal_i(true, is_valid_name("refs/tags/0.17.0")); + cl_assert_equal_i(true, is_valid_name("refs/LEVELS")); + cl_assert_equal_i(true, is_valid_name("HEAD")); + cl_assert_equal_i(true, is_valid_name("ONE_LEVEL")); + cl_assert_equal_i(true, is_valid_name("refs/stash")); + cl_assert_equal_i(true, is_valid_name("refs/remotes/origin/bim_with_3d@11296")); + cl_assert_equal_i(true, is_valid_name("refs/master{yesterday")); + cl_assert_equal_i(true, is_valid_name("refs/master}yesterday")); + cl_assert_equal_i(true, is_valid_name("refs/master{yesterday}")); } From 63460fe4b5616cce01e4b67f0994e2e75415324d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 11 Oct 2020 13:21:13 +0100 Subject: [PATCH 0043/1616] refs: deprecate git_reference_is_valid_name --- include/git2/deprecated.h | 24 +++++++++++++++++++++--- include/git2/refs.h | 16 ---------------- src/refs.c | 24 +++++++++++++++--------- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index 3f285018d26..e24d057f4c6 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -340,10 +340,11 @@ GIT_EXTERN(size_t) git_object__size(git_object_t type); /**@}*/ -/** @name Deprecated Reference Constants +/** @name Deprecated Reference Functions and Constants * - * These enumeration values are retained for backward compatibility. The - * newer versions of these values should be preferred in all new code. + * These functions and enumeration values are retained for backward + * compatibility. The newer versions of these values should be + * preferred in all new code. * * There is no plan to remove these backward compatibility values at * this time. @@ -364,6 +365,23 @@ GIT_EXTERN(size_t) git_object__size(git_object_t type); #define GIT_REF_FORMAT_REFSPEC_PATTERN GIT_REFERENCE_FORMAT_REFSPEC_PATTERN #define GIT_REF_FORMAT_REFSPEC_SHORTHAND GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND +/** + * Ensure the reference name is well-formed. + * + * Valid reference names must follow one of two patterns: + * + * 1. Top-level names must contain only capital letters and underscores, + * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). + * 2. Names prefixed with "refs/" can be almost anything. You must avoid + * the characters '~', '^', ':', '\\', '?', '[', and '*', and the + * sequences ".." and "@{" which have special meaning to revparse. + * + * @deprecated Use git_reference_name_is_valid + * @param refname name to be checked. + * @return 1 if the reference name is acceptable; 0 if it isn't + */ +GIT_EXTERN(int) git_reference_is_valid_name(const char *refname); + GIT_EXTERN(int) git_tag_create_frombuffer( git_oid *oid, git_repository *repo, diff --git a/include/git2/refs.h b/include/git2/refs.h index 6145811bb23..a20a1265bf6 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -749,22 +749,6 @@ GIT_EXTERN(int) git_reference_peel( */ GIT_EXTERN(int) git_reference_name_is_valid(int *valid, const char *refname); -/** - * Ensure the reference name is well-formed. - * - * Valid reference names must follow one of two patterns: - * - * 1. Top-level names must contain only capital letters and underscores, - * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). - * 2. Names prefixed with "refs/" can be almost anything. You must avoid - * the characters '~', '^', ':', '\\', '?', '[', and '*', and the - * sequences ".." and "@{" which have special meaning to revparse. - * - * @param refname name to be checked. - * @return 1 if the reference name is acceptable; 0 if it isn't - */ -GIT_EXTERN(int) git_reference_is_valid_name(const char *refname); - /** * Get the reference's short name * diff --git a/src/refs.c b/src/refs.c index 90b9b06ffc5..497b066d2be 100644 --- a/src/refs.c +++ b/src/refs.c @@ -1314,15 +1314,6 @@ int git_reference_name_is_valid(int *valid, const char *refname) return git_reference__name_is_valid(valid, refname, GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL); } -int git_reference_is_valid_name(const char *refname) -{ - int valid = 0; - - git_reference__name_is_valid(&valid, refname, GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL); - - return valid; -} - const char *git_reference__shorthand(const char *name) { if (!git__prefixcmp(name, GIT_REFS_HEADS_DIR)) @@ -1366,3 +1357,18 @@ int git_reference__is_unborn_head(bool *unborn, const git_reference *ref, git_re return 0; } + +/* Deprecated functions */ + +#ifndef GIT_DEPRECATE_HARD + +int git_reference_is_valid_name(const char *refname) +{ + int valid = 0; + + git_reference__name_is_valid(&valid, refname, GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL); + + return valid; +} + +#endif From 68e35588ad5b55c9f0357e0a33f7282c0a454a0c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 11 Oct 2020 13:35:35 +0100 Subject: [PATCH 0044/1616] refspec: return GIT_EINVALIDSPEC for invalid specs Disambiguate invalid specifications in `git_refspec__parse` so that callers can determine the difference between invalid specifications and actual errors. No call sites wil propagagte this new error message to an end-user, so there is no user-facing API change. --- src/refspec.c | 9 +++++---- src/remote.c | 6 +----- tests/network/refspecs.c | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/refspec.c b/src/refspec.c index 95b2830f831..4245cbbdad7 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -155,12 +155,13 @@ int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch) return 0; invalid: - git_error_set( - GIT_ERROR_INVALID, - "'%s' is not a valid refspec.", input); + git_error_set(GIT_ERROR_INVALID, + "'%s' is not a valid refspec.", input); + git_refspec__dispose(refspec); + return GIT_EINVALIDSPEC; on_error: - git_refspec__dispose(refspec); + git_refspec__dispose(refspec); return -1; } diff --git a/src/remote.c b/src/remote.c index b69526c4232..9c795ee84de 100644 --- a/src/remote.c +++ b/src/remote.c @@ -110,12 +110,8 @@ static int write_add_refspec(git_repository *repo, const char *name, const char if ((error = ensure_remote_name_is_valid(name)) < 0) return error; - if ((error = git_refspec__parse(&spec, refspec, fetch)) < 0) { - if (git_error_last()->klass != GIT_ERROR_NOMEMORY) - error = GIT_EINVALIDSPEC; - + if ((error = git_refspec__parse(&spec, refspec, fetch)) < 0) return error; - } git_refspec__dispose(&spec); diff --git a/tests/network/refspecs.c b/tests/network/refspecs.c index 5c8eb1502e6..d9e0d9e8dd7 100644 --- a/tests/network/refspecs.c +++ b/tests/network/refspecs.c @@ -13,7 +13,7 @@ static void assert_refspec(unsigned int direction, const char *input, bool is_ex if (is_expected_to_be_valid) cl_assert_equal_i(0, error); else - cl_assert_equal_i(GIT_ERROR, error); + cl_assert_equal_i(GIT_EINVALIDSPEC, error); } void test_network_refspecs__parsing(void) From 023ebb9a8ebdb5963000253cd127d4bf18312b50 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 11 Oct 2020 13:48:07 +0100 Subject: [PATCH 0045/1616] refs: introduce git_remote_name_is_valid Provide a function that can check remote name validity but can also signal when an error occurs. Use the name "name_is_valid", which is more suggestive of checking a given name, rather than "is_valid_name", which suggests that the function checks the validity of the current remote's name. --- include/git2/remote.h | 9 +++++++++ src/remote.c | 32 +++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/include/git2/remote.h b/include/git2/remote.h index 51d9c723596..fa0345eb5ba 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -912,6 +912,15 @@ GIT_EXTERN(int) git_remote_rename( const char *name, const char *new_name); +/** + * Ensure the remote name is well-formed. + * + * @param valid output pointer to set with validity of given remote name + * @param remote_name name to be checked. + * @return 0 on success or an error code + */ +int git_remote_name_is_valid(int *valid, const char *remote_name); + /** * Ensure the remote name is well-formed. * diff --git a/src/remote.c b/src/remote.c index 9c795ee84de..d471c4c5045 100644 --- a/src/remote.c +++ b/src/remote.c @@ -2092,24 +2092,42 @@ int git_remote_rename(git_strarray *out, git_repository *repo, const char *name, return error; } -int git_remote_is_valid_name( - const char *remote_name) +int git_remote_name_is_valid(int *valid, const char *remote_name) { git_buf buf = GIT_BUF_INIT; - git_refspec refspec; - int error = -1; + git_refspec refspec = {0}; + int error; + + GIT_ASSERT(valid); + + *valid = 0; if (!remote_name || *remote_name == '\0') return 0; - git_buf_printf(&buf, "refs/heads/test:refs/remotes/%s/test", remote_name); + if ((error = git_buf_printf(&buf, "refs/heads/test:refs/remotes/%s/test", remote_name)) < 0) + goto done; + error = git_refspec__parse(&refspec, git_buf_cstr(&buf), true); + if (!error) + *valid = 1; + else if (error == GIT_EINVALIDSPEC) + error = 0; + +done: git_buf_dispose(&buf); git_refspec__dispose(&refspec); - git_error_clear(); - return error == 0; + return error; +} + +int git_remote_is_valid_name(const char *remote_name) +{ + int valid = 0; + + git_remote_name_is_valid(&valid, remote_name); + return valid; } git_refspec *git_remote__matching_refspec(git_remote *remote, const char *refname) From 55a7117d293c04f40fd943aeb141d856272070f6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 11 Oct 2020 13:55:44 +0100 Subject: [PATCH 0046/1616] remote: use git_remote_name_is_valid --- src/remote.c | 6 ++++-- tests/network/remote/isvalidname.c | 23 +++++++++++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/remote.c b/src/remote.c index d471c4c5045..6ebdaf80528 100644 --- a/src/remote.c +++ b/src/remote.c @@ -82,9 +82,11 @@ static int download_tags_value(git_remote *remote, git_config *cfg) static int ensure_remote_name_is_valid(const char *name) { - int error = 0; + int valid, error; + + error = git_remote_name_is_valid(&valid, name); - if (!git_remote_is_valid_name(name)) { + if (!error && !valid) { git_error_set( GIT_ERROR_CONFIG, "'%s' is not a valid remote name.", name ? name : "(null)"); diff --git a/tests/network/remote/isvalidname.c b/tests/network/remote/isvalidname.c index c26fbd0a5b9..a3080f67c03 100644 --- a/tests/network/remote/isvalidname.c +++ b/tests/network/remote/isvalidname.c @@ -1,17 +1,24 @@ #include "clar_libgit2.h" +static int is_valid_name(const char *name) +{ + int valid = 0; + cl_git_pass(git_remote_name_is_valid(&valid, name)); + return valid; +} + void test_network_remote_isvalidname__can_detect_invalid_formats(void) { - cl_assert_equal_i(false, git_remote_is_valid_name("/")); - cl_assert_equal_i(false, git_remote_is_valid_name("//")); - cl_assert_equal_i(false, git_remote_is_valid_name(".lock")); - cl_assert_equal_i(false, git_remote_is_valid_name("a.lock")); - cl_assert_equal_i(false, git_remote_is_valid_name("/no/leading/slash")); - cl_assert_equal_i(false, git_remote_is_valid_name("no/trailing/slash/")); + cl_assert_equal_i(false, is_valid_name("/")); + cl_assert_equal_i(false, is_valid_name("//")); + cl_assert_equal_i(false, is_valid_name(".lock")); + cl_assert_equal_i(false, is_valid_name("a.lock")); + cl_assert_equal_i(false, is_valid_name("/no/leading/slash")); + cl_assert_equal_i(false, is_valid_name("no/trailing/slash/")); } void test_network_remote_isvalidname__wont_hopefully_choke_on_valid_formats(void) { - cl_assert_equal_i(true, git_remote_is_valid_name("webmatrix")); - cl_assert_equal_i(true, git_remote_is_valid_name("yishaigalatzer/rules")); + cl_assert_equal_i(true, is_valid_name("webmatrix")); + cl_assert_equal_i(true, is_valid_name("yishaigalatzer/rules")); } From c7143d7ce4f4386ca5b024876177f915c39ff86e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 11 Oct 2020 13:56:16 +0100 Subject: [PATCH 0047/1616] remote: deprecate git_remote_is_valid_name --- include/git2/deprecated.h | 21 +++++++++++++++++++++ include/git2/remote.h | 8 -------- src/remote.c | 22 ++++++++++++++-------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index e24d057f4c6..4e43c453658 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -340,6 +340,27 @@ GIT_EXTERN(size_t) git_object__size(git_object_t type); /**@}*/ +/** @name Deprecated Remote Functions + * + * These functions are retained for backward compatibility. The newer + * versions of these functions should be preferred in all new code. + * + * There is no plan to remove these backward compatibility functions at + * this time. + */ +/**@{*/ + +/** + * Ensure the remote name is well-formed. + * + * @deprecated Use git_remote_name_is_valid + * @param remote_name name to be checked. + * @return 1 if the reference name is acceptable; 0 if it isn't + */ +GIT_EXTERN(int) git_remote_is_valid_name(const char *remote_name); + +/**@}*/ + /** @name Deprecated Reference Functions and Constants * * These functions and enumeration values are retained for backward diff --git a/include/git2/remote.h b/include/git2/remote.h index fa0345eb5ba..b82bd250b43 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -921,14 +921,6 @@ GIT_EXTERN(int) git_remote_rename( */ int git_remote_name_is_valid(int *valid, const char *remote_name); -/** - * Ensure the remote name is well-formed. - * - * @param remote_name name to be checked. - * @return 1 if the reference name is acceptable; 0 if it isn't - */ -GIT_EXTERN(int) git_remote_is_valid_name(const char *remote_name); - /** * Delete an existing persisted remote. * diff --git a/src/remote.c b/src/remote.c index 6ebdaf80528..f6382486174 100644 --- a/src/remote.c +++ b/src/remote.c @@ -2124,14 +2124,6 @@ int git_remote_name_is_valid(int *valid, const char *remote_name) return error; } -int git_remote_is_valid_name(const char *remote_name) -{ - int valid = 0; - - git_remote_name_is_valid(&valid, remote_name); - return valid; -} - git_refspec *git_remote__matching_refspec(git_remote *remote, const char *refname) { git_refspec *spec; @@ -2628,3 +2620,17 @@ char *apply_insteadof(git_config *config, const char *url, int direction) return result.ptr; } + +/* Deprecated functions */ + +#ifndef GIT_DEPRECATE_HARD + +int git_remote_is_valid_name(const char *remote_name) +{ + int valid = 0; + + git_remote_name_is_valid(&valid, remote_name); + return valid; +} + +#endif From fe11160c724853fe8469a9788c5992420e4638de Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Tue, 8 Sep 2020 21:05:18 +0200 Subject: [PATCH 0048/1616] Add git_branch_name_is_valid Signed-off-by: Sven Strickroth --- include/git2/branch.h | 12 ++++++++++++ src/branch.c | 29 +++++++++++++++++++++++++++++ tests/refs/branches/name.c | 17 +++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/include/git2/branch.h b/include/git2/branch.h index ba6235900d7..0c0cc7ff78b 100644 --- a/include/git2/branch.h +++ b/include/git2/branch.h @@ -304,6 +304,18 @@ GIT_EXTERN(int) git_branch_remote_name( */ GIT_EXTERN(int) git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname); +/** + * Determine whether a branch name is valid, meaning that (when prefixed + * with `refs/heads/`) that it is a valid reference name, and that any + * additional branch name restrictions are imposed (eg, it cannot start + * with a `-`). + * + * @param valid output pointer to set with validity of given branch name + * @param name a branch name to test + * @return 0 on success or an error code + */ +GIT_EXTERN(int) git_branch_name_is_valid(int *valid, const char *name); + /** @} */ GIT_END_DECL #endif diff --git a/src/branch.c b/src/branch.c index 715f6cf99c7..000a63ad888 100644 --- a/src/branch.c +++ b/src/branch.c @@ -723,3 +723,32 @@ int git_branch_is_head( return is_same; } + +int git_branch_name_is_valid(int *valid, const char *name) +{ + git_buf ref_name = GIT_BUF_INIT; + int error = 0; + + GIT_ASSERT(valid); + + *valid = 0; + + /* + * Discourage branch name starting with dash, + * https://github.com/git/git/commit/6348624010888b + * and discourage HEAD as branch name, + * https://github.com/git/git/commit/a625b092cc5994 + */ + if (!name || name[0] == '-' || !git__strcmp(name, "HEAD")) + goto done; + + if ((error = git_buf_puts(&ref_name, GIT_REFS_HEADS_DIR)) < 0 || + (error = git_buf_puts(&ref_name, name)) < 0) + goto done; + + error = git_reference_name_is_valid(valid, ref_name.ptr); + +done: + git_buf_dispose(&ref_name); + return error; +} diff --git a/tests/refs/branches/name.c b/tests/refs/branches/name.c index 176f836a426..290916eecd0 100644 --- a/tests/refs/branches/name.c +++ b/tests/refs/branches/name.c @@ -43,3 +43,20 @@ void test_refs_branches_name__error_when_ref_is_no_branch(void) cl_git_pass(git_reference_lookup(&ref,repo,"refs/notes/fanout")); cl_git_fail(git_branch_name(&name,ref)); } + +static int name_is_valid(const char *name) +{ + int valid; + cl_git_pass(git_branch_name_is_valid(&valid, name)); + return valid; +} + +void test_refs_branches_is_name_valid(void) +{ + cl_assert_equal_i(true, name_is_valid("master")); + cl_assert_equal_i(true, name_is_valid("test/master")); + + cl_assert_equal_i(false, name_is_valid("")); + cl_assert_equal_i(false, name_is_valid("HEAD")); + cl_assert_equal_i(false, name_is_valid("-dash")); +} From 0caa4655ebdb7bf028df970d0651378d121fab3e Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Wed, 9 Sep 2020 10:48:00 +0200 Subject: [PATCH 0049/1616] Add git_tag_name_is_valid Signed-off-by: Sven Strickroth --- include/git2/tag.h | 12 ++++++++++++ src/tag.c | 25 +++++++++++++++++++++++++ tests/refs/tags/name.c | 17 +++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 tests/refs/tags/name.c diff --git a/include/git2/tag.h b/include/git2/tag.h index 4e5fe1db1a7..a3921369dad 100644 --- a/include/git2/tag.h +++ b/include/git2/tag.h @@ -365,6 +365,18 @@ GIT_EXTERN(int) git_tag_peel( */ GIT_EXTERN(int) git_tag_dup(git_tag **out, git_tag *source); +/** + * Determine whether a tag name is valid, meaning that (when prefixed + * with `refs/tags/`) that it is a valid reference name, and that any + * additional tag name restrictions are imposed (eg, it cannot start + * with a `-`). + * + * @param valid output pointer to set with validity of given tag name + * @param name a tag name to test + * @return 0 on success or an error code + */ +GIT_EXTERN(int) git_tag_name_is_valid(int *valid, const char *name); + /** @} */ GIT_END_DECL #endif diff --git a/src/tag.c b/src/tag.c index 037dc666474..8a4d6eec887 100644 --- a/src/tag.c +++ b/src/tag.c @@ -522,6 +522,31 @@ int git_tag_peel(git_object **tag_target, const git_tag *tag) return git_object_peel(tag_target, (const git_object *)tag, GIT_OBJECT_ANY); } +int git_tag_name_is_valid(int *valid, const char *name) +{ + git_buf ref_name = GIT_BUF_INIT; + int error = 0; + + GIT_ASSERT(valid); + + /* + * Discourage tag name starting with dash, + * https://github.com/git/git/commit/4f0accd638b8d2 + */ + if (!name || name[0] == '-') + goto done; + + if ((error = git_buf_puts(&ref_name, GIT_REFS_TAGS_DIR)) < 0 || + (error = git_buf_puts(&ref_name, name)) < 0) + goto done; + + error = git_reference_name_is_valid(valid, ref_name.ptr); + +done: + git_buf_dispose(&ref_name); + return error; +} + /* Deprecated Functions */ #ifndef GIT_DEPRECATE_HARD diff --git a/tests/refs/tags/name.c b/tests/refs/tags/name.c new file mode 100644 index 00000000000..0ca5df7d641 --- /dev/null +++ b/tests/refs/tags/name.c @@ -0,0 +1,17 @@ +#include "clar_libgit2.h" + +static int name_is_valid(const char *name) +{ + int valid; + cl_git_pass(git_tag_name_is_valid(&valid, name)); + return valid; +} + +void test_refs_tags_is_name_valid(void) +{ + cl_assert_equal_i(true, name_is_valid("sometag")); + cl_assert_equal_i(true, name_is_valid("test/sometag")); + + cl_assert_equal_i(false, name_is_valid("")); + cl_assert_equal_i(false, name_is_valid("-dash")); +} From 8b0c7d7cdf4fd5ad30efa66251733d85b9c8b641 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 25 Oct 2020 16:38:45 +0000 Subject: [PATCH 0050/1616] changelog: include new reference validity functions --- docs/changelog.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 288ef2d115b..98bde2f6c46 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,3 +1,18 @@ +vNext +----- + +### Changes or improvements + +* Branch and tag name validation functions have been introduced: + `git_branch_name_is_valid` will check if a branch name is valid, + and `git_tag_name_is_valid` will check if a tag name is valid. + +* Some remote and reference validity checking functions have been + introduced with error reporting semantics. `git_remote_name_is_valid` + replaces `git_remote_is_valid_name`. `git_reference_name_is_valid` + replaces `git_reference_is_valid_name`. Tthe former functions are + deprecated. + v1.1 ---- From aa532e298937c7eb863b83c766cdabbf8be4fec9 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sat, 31 Oct 2020 07:51:03 -0700 Subject: [PATCH 0051/1616] Fix the `-DTHREADSAFE=OFF` build This change avoids using the `(void)0` construct for some of the mutex `#define`s, since that makes the "return type" of those "functions" to be `void` instead of `int`. --- src/runtime.c | 4 ++-- src/thread-utils.h | 41 +++++++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/runtime.c b/src/runtime.c index 56110c49a3b..f8e3e3b274f 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -103,8 +103,8 @@ GIT_INLINE(int) init_unlock(void) # error unknown threading model #else -# define mutex_lock() 0 -# define mutex_unlock() 0 +# define init_lock() git___noop() +# define init_unlock() git___noop() #endif diff --git a/src/thread-utils.h b/src/thread-utils.h index b4e44b468ed..e577a9b0b78 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -235,37 +235,38 @@ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a) #else -GIT_INLINE(int) git_threads_global_init(void) { return 0; } +GIT_INLINE(int) git___noop(void) { return 0; } + +#define git_threads_global_init git___noop #define git_thread unsigned int -#define git_thread_create(thread, start_routine, arg) 0 -#define git_thread_join(id, status) (void)0 +#define git_thread_create(thread, start_routine, arg) git___noop() +#define git_thread_join(id, status) git___noop() /* Pthreads Mutex */ #define git_mutex unsigned int -GIT_INLINE(int) git_mutex_init(git_mutex *mutex) \ - { GIT_UNUSED(mutex); return 0; } -GIT_INLINE(int) git_mutex_lock(git_mutex *mutex) \ - { GIT_UNUSED(mutex); return 0; } -#define git_mutex_unlock(a) (void)0 -#define git_mutex_free(a) (void)0 +#define git_mutex_init(a) git___noop() +#define git_mutex_init(a) git___noop() +#define git_mutex_lock(a) git___noop() +#define git_mutex_unlock(a) git___noop() +#define git_mutex_free(a) git___noop() /* Pthreads condition vars */ #define git_cond unsigned int -#define git_cond_init(c, a) (void)0 -#define git_cond_free(c) (void)0 -#define git_cond_wait(c, l) (void)0 -#define git_cond_signal(c) (void)0 -#define git_cond_broadcast(c) (void)0 +#define git_cond_init(c) git___noop() +#define git_cond_free(c) git___noop() +#define git_cond_wait(c, l) git___noop() +#define git_cond_signal(c) git___noop() +#define git_cond_broadcast(c) git___noop() /* Pthreads rwlock */ #define git_rwlock unsigned int -#define git_rwlock_init(a) 0 -#define git_rwlock_rdlock(a) 0 -#define git_rwlock_rdunlock(a) (void)0 -#define git_rwlock_wrlock(a) 0 -#define git_rwlock_wrunlock(a) (void)0 -#define git_rwlock_free(a) (void)0 +#define git_rwlock_init(a) git___noop() +#define git_rwlock_rdlock(a) git___noop() +#define git_rwlock_rdunlock(a) git___noop() +#define git_rwlock_wrlock(a) git___noop() +#define git_rwlock_wrunlock(a) git___noop() +#define git_rwlock_free(a) git___noop() #define GIT_RWLOCK_STATIC_INIT 0 From 848c7793d41a594e7b503fe0bc956b79c95295d6 Mon Sep 17 00:00:00 2001 From: Reginald McLean Date: Fri, 6 Nov 2020 11:32:13 -0500 Subject: [PATCH 0052/1616] worktree: Demonstrate missing worktree check worktree_dir isn't validated when it should be --- tests/worktree/worktree.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index cd20bed82fa..c3abf0030d6 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -610,3 +610,17 @@ void test_worktree_worktree__foreach_worktree_lists_all_worktrees(void) int counter = 0; cl_git_pass(git_repository_foreach_worktree(fixture.repo, foreach_worktree_cb, &counter)); } + +void test_worktree_worktree__validate_invalid_worktreedir(void) +{ + git_worktree *wt; + + cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); + git__free(wt->worktree_path); + wt->worktree_path = "/path/to/invalid/worktreedir"; + + cl_git_fail(git_worktree_validate(wt)); + + wt->worktree_path = NULL; + git_worktree_free(wt); +} From 6405ce29753000e84d485d18d6b0fde893a38f84 Mon Sep 17 00:00:00 2001 From: Reginald McLean Date: Fri, 6 Nov 2020 11:36:25 -0500 Subject: [PATCH 0053/1616] worktree: Added worktree_dir check Fixes #5280 --- src/worktree.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/worktree.c b/src/worktree.c index fda9b0b71ab..ea5a403c0ea 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -259,7 +259,14 @@ int git_worktree_validate(const git_worktree *wt) wt->commondir_path); return GIT_ERROR; } - + + if (!git_path_exists(wt->worktree_path)) { + git_error_set(GIT_ERROR_WORKTREE, + "worktree directory ('%s') does not exist ", + wt->worktree_path); + return GIT_ERROR; + } + return 0; } From 303b4c689477c3a3da1de6351c02db0368fe6625 Mon Sep 17 00:00:00 2001 From: Reginald McLean Date: Sat, 7 Nov 2020 16:30:44 -0500 Subject: [PATCH 0054/1616] worktree: change test to invalidate worktree via filesystem --- tests/worktree/worktree.c | 5 +---- tests/worktree/worktree_helpers.c | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index c3abf0030d6..88bcaa97e6d 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -616,11 +616,8 @@ void test_worktree_worktree__validate_invalid_worktreedir(void) git_worktree *wt; cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); - git__free(wt->worktree_path); - wt->worktree_path = "/path/to/invalid/worktreedir"; - + p_rename("testrepo-worktree", "testrepo-worktree-tmp"); cl_git_fail(git_worktree_validate(wt)); - wt->worktree_path = NULL; git_worktree_free(wt); } diff --git a/tests/worktree/worktree_helpers.c b/tests/worktree/worktree_helpers.c index 6d4cdbaebab..8d78e16925b 100644 --- a/tests/worktree/worktree_helpers.c +++ b/tests/worktree/worktree_helpers.c @@ -19,6 +19,7 @@ void cleanup_fixture_worktree(worktree_fixture *fixture) cl_fixture_cleanup(fixture->reponame); if (fixture->worktreename) cl_fixture_cleanup(fixture->worktreename); + p_rename("testrepo-worktree-tmp", "testrepo-worktree"); } void setup_fixture_worktree(worktree_fixture *fixture) From 3d6b90359d1307736c9fd4488b1703d934a69a1a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 18 Nov 2020 18:08:23 +0000 Subject: [PATCH 0055/1616] ci: stop using deprecated set-env in GitHub Actions (And move the ci scripts into the `ci` directory.) --- .github/workflows/main.yml | 14 +++++++------- azure-pipelines/bash.yml | 4 ++-- azure-pipelines/coverity.yml | 4 ++-- azure-pipelines/docker.yml | 6 +++--- azure-pipelines/nightly.yml | 6 +++--- {azure-pipelines => ci}/build.sh | 0 {azure-pipelines => ci}/coverity.sh | 0 {azure-pipelines => ci}/docker/bionic | 0 {azure-pipelines => ci}/docker/docurium | 0 {azure-pipelines => ci}/docker/entrypoint.sh | 0 {azure-pipelines => ci}/docker/focal | 0 {azure-pipelines => ci}/docker/xenial | 0 {azure-pipelines => ci}/getcontainer.sh | 14 +++++++------- {azure-pipelines => ci}/setup-mingw.sh | 0 {azure-pipelines => ci}/setup-osx.sh | 0 {azure-pipelines => ci}/test.sh | 0 16 files changed, 24 insertions(+), 24 deletions(-) rename {azure-pipelines => ci}/build.sh (100%) rename {azure-pipelines => ci}/coverity.sh (100%) rename {azure-pipelines => ci}/docker/bionic (100%) rename {azure-pipelines => ci}/docker/docurium (100%) rename {azure-pipelines => ci}/docker/entrypoint.sh (100%) rename {azure-pipelines => ci}/docker/focal (100%) rename {azure-pipelines => ci}/docker/xenial (100%) rename {azure-pipelines => ci}/getcontainer.sh (67%) rename {azure-pipelines => ci}/setup-mingw.sh (100%) rename {azure-pipelines => ci}/setup-osx.sh (100%) rename {azure-pipelines => ci}/test.sh (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 29507c8f03a..a36a0a0efc1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,7 +10,7 @@ on: env: docker-registry: docker.pkg.github.com - docker-config-path: azure-pipelines/docker + docker-config-path: ci/docker jobs: # Build the docker container images that we will use for our Linux @@ -38,7 +38,7 @@ jobs: fetch-depth: 0 if: github.event_name == 'push' - name: Download existing container - run: azure-pipelines/getcontainer.sh ${{ env.docker-config-path }}/${{ matrix.container }} + run: ci/getcontainer.sh ${{ env.docker-config-path }}/${{ matrix.container }} env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} @@ -166,11 +166,11 @@ jobs: with: fetch-depth: 0 - name: Set up build environment - run: azure-pipelines/setup-${{ matrix.platform.setup-script }}.sh + run: ci/setup-${{ matrix.platform.setup-script }}.sh shell: bash if: matrix.platform.setup-script != '' - name: Download container - run: azure-pipelines/getcontainer.sh ${{ env.docker-config-path }}/${{ matrix.platform.image }} + run: ci/getcontainer.sh ${{ env.docker-config-path }}/${{ matrix.platform.image }} env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} @@ -198,11 +198,11 @@ jobs: -e SKIP_NEGOTIATE_TESTS \ -e SKIP_SSH_TESTS \ ${{ env.docker-registry-container-sha }} \ - /bin/bash -c "mkdir build && cd build && ../azure-pipelines/build.sh && ../azure-pipelines/test.sh" + /bin/bash -c "mkdir build && cd build && ../ci/build.sh && ../ci/test.sh" else mkdir build && cd build - ../azure-pipelines/build.sh - ../azure-pipelines/test.sh + ../ci/build.sh + ../ci/test.sh fi shell: bash diff --git a/azure-pipelines/bash.yml b/azure-pipelines/bash.yml index 33a442b5751..d776a364996 100644 --- a/azure-pipelines/bash.yml +++ b/azure-pipelines/bash.yml @@ -1,10 +1,10 @@ # These are the steps used for building on machines with bash. steps: -- bash: . '$(Build.SourcesDirectory)/azure-pipelines/build.sh' +- bash: . '$(Build.SourcesDirectory)/ci/build.sh' displayName: Build workingDirectory: '$(Build.BinariesDirectory)' env: ${{ parameters.environmentVariables }} -- bash: . '$(Build.SourcesDirectory)/azure-pipelines/test.sh' +- bash: . '$(Build.SourcesDirectory)/ci/test.sh' displayName: Test workingDirectory: '$(Build.BinariesDirectory)' env: ${{ parameters.environmentVariables }} diff --git a/azure-pipelines/coverity.yml b/azure-pipelines/coverity.yml index a8747db7358..466f43693fa 100644 --- a/azure-pipelines/coverity.yml +++ b/azure-pipelines/coverity.yml @@ -8,7 +8,7 @@ jobs: vmImage: 'ubuntu-18.04' steps: - script: | - cd $(Build.SourcesDirectory)/azure-pipelines/docker + cd $(Build.SourcesDirectory)/ci/docker docker build -t libgit2/xenial --build-arg BASE=ubuntu:xenial -f xenial . displayName: 'Build Docker image' - task: Docker@0 @@ -22,5 +22,5 @@ jobs: envVars: | COVERITY_TOKEN=$(COVERITY_TOKEN) workDir: '/home/libgit2/build' - containerCommand: '/home/libgit2/source/azure-pipelines/coverity.sh' + containerCommand: '/home/libgit2/source/ci/coverity.sh' detached: false diff --git a/azure-pipelines/docker.yml b/azure-pipelines/docker.yml index 0f0885770d8..5bb58ee75f9 100644 --- a/azure-pipelines/docker.yml +++ b/azure-pipelines/docker.yml @@ -13,7 +13,7 @@ steps: if [ -f /tmp/dockercache/${{parameters.docker.image}}.tar ]; then docker load < /tmp/dockercache/${{parameters.docker.image}}.tar; fi displayName: 'Load Docker cache' - script: | - cd $(Build.SourcesDirectory)/azure-pipelines/docker && + cd $(Build.SourcesDirectory)/ci/docker && docker build -t libgit2/${{parameters.docker.image}} --build-arg BASE=${{parameters.docker.base}} -f ${{parameters.docker.image}} . && if [ ! -d /tmp/dockercache ]; then mkdir /tmp/dockercache; fi && docker save libgit2/${{parameters.docker.image}} $(docker history -q libgit2/${{parameters.docker.image}} | grep -v '') > /tmp/dockercache/${{parameters.docker.image}}.tar @@ -28,7 +28,7 @@ steps: $(Build.BinariesDirectory):/home/libgit2/build envVars: ${{ parameters.environmentVariables }} workDir: '/home/libgit2/build' - containerCommand: '/home/libgit2/source/azure-pipelines/build.sh' + containerCommand: '/home/libgit2/source/ci/build.sh' detached: false - task: docker@0 displayName: Test @@ -40,7 +40,7 @@ steps: $(Build.BinariesDirectory):/home/libgit2/build envVars: ${{ parameters.environmentVariables }} workDir: '/home/libgit2/build' - containerCommand: '/home/libgit2/source/azure-pipelines/test.sh' + containerCommand: '/home/libgit2/source/ci/test.sh' detached: false - task: publishtestresults@2 displayName: Publish Test Results diff --git a/azure-pipelines/nightly.yml b/azure-pipelines/nightly.yml index a75a9cc249d..97b44799553 100644 --- a/azure-pipelines/nightly.yml +++ b/azure-pipelines/nightly.yml @@ -71,7 +71,7 @@ jobs: pool: vmImage: 'macOS-10.15' steps: - - bash: . '$(Build.SourcesDirectory)/azure-pipelines/setup-osx.sh' + - bash: . '$(Build.SourcesDirectory)/ci/setup-osx.sh' displayName: Setup - template: bash.yml parameters: @@ -114,7 +114,7 @@ jobs: pool: vmImage: 'vs2017-win2016' steps: - - bash: . '$(Build.SourcesDirectory)\azure-pipelines\setup-mingw.sh' + - bash: . '$(Build.SourcesDirectory)\ci\setup-mingw.sh' displayName: Setup env: TEMP: $(Agent.TempDirectory) @@ -133,7 +133,7 @@ jobs: pool: vmImage: 'vs2017-win2016' steps: - - bash: . '$(Build.SourcesDirectory)\azure-pipelines\setup-mingw.sh' + - bash: . '$(Build.SourcesDirectory)\ci\setup-mingw.sh' displayName: Setup workingDirectory: '$(Build.BinariesDirectory)' env: diff --git a/azure-pipelines/build.sh b/ci/build.sh similarity index 100% rename from azure-pipelines/build.sh rename to ci/build.sh diff --git a/azure-pipelines/coverity.sh b/ci/coverity.sh similarity index 100% rename from azure-pipelines/coverity.sh rename to ci/coverity.sh diff --git a/azure-pipelines/docker/bionic b/ci/docker/bionic similarity index 100% rename from azure-pipelines/docker/bionic rename to ci/docker/bionic diff --git a/azure-pipelines/docker/docurium b/ci/docker/docurium similarity index 100% rename from azure-pipelines/docker/docurium rename to ci/docker/docurium diff --git a/azure-pipelines/docker/entrypoint.sh b/ci/docker/entrypoint.sh similarity index 100% rename from azure-pipelines/docker/entrypoint.sh rename to ci/docker/entrypoint.sh diff --git a/azure-pipelines/docker/focal b/ci/docker/focal similarity index 100% rename from azure-pipelines/docker/focal rename to ci/docker/focal diff --git a/azure-pipelines/docker/xenial b/ci/docker/xenial similarity index 100% rename from azure-pipelines/docker/xenial rename to ci/docker/xenial diff --git a/azure-pipelines/getcontainer.sh b/ci/getcontainer.sh similarity index 67% rename from azure-pipelines/getcontainer.sh rename to ci/getcontainer.sh index bc93f4919dc..b259260f4c8 100755 --- a/azure-pipelines/getcontainer.sh +++ b/ci/getcontainer.sh @@ -18,18 +18,18 @@ fi DOCKER_CONTAINER="${GITHUB_REPOSITORY}/$(basename ${DOCKERFILE_PATH})" DOCKER_REGISTRY_CONTAINER="${DOCKER_REGISTRY}/${DOCKER_CONTAINER}" -echo "::set-env name=docker-container::${DOCKER_CONTAINER}" -echo "::set-env name=docker-registry-container::${DOCKER_REGISTRY_CONTAINER}" +echo "docker-container=${DOCKER_CONTAINER}" >> $GITHUB_ENV +echo "docker-registry-container=${DOCKER_REGISTRY_CONTAINER}" >> $GITHUB_ENV # Identify the last git commit that touched the Dockerfiles # Use this as a hash to identify the resulting docker containers DOCKER_SHA=$(git log -1 --pretty=format:"%h" -- "${DOCKERFILE_PATH}") -echo "::set-env name=docker-sha::${DOCKER_SHA}" +echo "docker-sha=${DOCKER_SHA}" >> $GITHUB_ENV DOCKER_REGISTRY_CONTAINER_SHA="${DOCKER_REGISTRY_CONTAINER}:${DOCKER_SHA}" -echo "::set-env name=docker-registry-container-sha::${DOCKER_REGISTRY_CONTAINER_SHA}" -echo "::set-env name=docker-registry-container-latest::${DOCKER_REGISTRY_CONTAINER}:latest" +echo "docker-registry-container-sha=${DOCKER_REGISTRY_CONTAINER_SHA}" >> $GITHUB_ENV +echo "docker-registry-container-latest=${DOCKER_REGISTRY_CONTAINER}:latest" >> $GITHUB_ENV exists="true" docker login https://${DOCKER_REGISTRY} -u ${GITHUB_ACTOR} -p ${GITHUB_TOKEN} || exists="false" @@ -39,7 +39,7 @@ if [ "${exists}" != "false" ]; then fi if [ "${exists}" = "true" ]; then - echo "::set-env name=docker-container-exists::true" + echo "docker-container-exists=true" >> $GITHUB_ENV else - echo "::set-env name=docker-container-exists::false" + echo "docker-container-exists=false" >> $GITHUB_ENV fi diff --git a/azure-pipelines/setup-mingw.sh b/ci/setup-mingw.sh similarity index 100% rename from azure-pipelines/setup-mingw.sh rename to ci/setup-mingw.sh diff --git a/azure-pipelines/setup-osx.sh b/ci/setup-osx.sh similarity index 100% rename from azure-pipelines/setup-osx.sh rename to ci/setup-osx.sh diff --git a/azure-pipelines/test.sh b/ci/test.sh similarity index 100% rename from azure-pipelines/test.sh rename to ci/test.sh From 11deb143f7b466d932dde3abc49c17c0481ba3f4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 18 Nov 2020 19:10:00 +0000 Subject: [PATCH 0056/1616] ci: use GitHub Actions for nightly builds --- .github/workflows/nightly.yml | 163 ++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 .github/workflows/nightly.yml diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 00000000000..c0e15539ada --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,163 @@ +# Nightly build for the master branch across multiple targets. +name: Nightly Build + +on: + schedule: + - cron: '15 1 * * *' + +env: + docker-registry: docker.pkg.github.com + docker-config-path: ci/docker + +jobs: + build: + name: Build + strategy: + matrix: + platform: + - # Xenial, GCC, OpenSSL + image: xenial + env: + CC: gcc + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + os: ubuntu-latest + - # Xenial, GCC, mbedTLS + image: xenial + env: + CC: gcc + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + os: ubuntu-latest + - # Xenial, Clang, OpenSSL + image: xenial + env: + CC: clang + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + os: ubuntu-latest + - # Xenial, Clang, mbedTLS + image: xenial + env: + CC: clang + CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_GENERATOR: Ninja + os: ubuntu-latest + - # Focal, Clang 10, mbedTLS, MemorySanitizer + image: focal + env: + CC: clang-10 + CFLAGS: -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local/msan -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON + CMAKE_GENERATOR: Ninja + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 + os: ubuntu-latest + - # Focal, Clang 10, OpenSSL, UndefinedBehaviorSanitizer + image: focal + env: + CC: clang-10 + CFLAGS: -fsanitize=undefined,nullability -fno-sanitize-recover=undefined,nullability -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON + CMAKE_GENERATOR: Ninja + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 + os: ubuntu-latest + - # macOS + os: macos-10.15 + env: + CC: clang + CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON + CMAKE_GENERATOR: Ninja + PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + setup-script: osx + - # Windows amd64 Visual Studio + os: windows-2019 + env: + ARCH: amd64 + CMAKE_GENERATOR: Visual Studio 16 2019 + CMAKE_OPTIONS: -A x64 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + - # Windows x86 Visual Studio + os: windows-2019 + env: + ARCH: x86 + CMAKE_GENERATOR: Visual Studio 16 2019 + CMAKE_OPTIONS: -A Win32 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + - # Windows amd64 mingw + os: windows-2019 + setup-script: mingw + env: + ARCH: amd64 + CMAKE_GENERATOR: MinGW Makefiles + CMAKE_OPTIONS: -DDEPRECATE_HARD=ON + BUILD_TEMP: D:\Temp + BUILD_PATH: D:\Temp\mingw64\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + - # Windows x86 mingw + os: windows-2019 + setup-script: mingw + env: + ARCH: x86 + CMAKE_GENERATOR: MinGW Makefiles + CMAKE_OPTIONS: -DDEPRECATE_HARD=ON + BUILD_TEMP: D:\Temp + BUILD_PATH: D:\Temp\mingw32\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + fail-fast: false + env: ${{ matrix.platform.env }} + runs-on: ${{ matrix.platform.os }} + steps: + - name: Check out repository + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set up build environment + run: ci/setup-${{ matrix.platform.setup-script }}.sh + shell: bash + if: matrix.platform.setup-script != '' + - name: Download container + run: ci/getcontainer.sh ${{ env.docker-config-path }}/${{ matrix.platform.image }} + env: + DOCKER_REGISTRY: ${{ env.docker-registry }} + GITHUB_TOKEN: ${{ secrets.github_token }} + if: matrix.platform.image != '' + - name: Create container + run: docker build -t ${{ env.docker-registry-container-sha }} -f ${{ matrix.platform.image }} . + working-directory: ${{ env.docker-config-path }} + if: matrix.platform.image != '' && env.docker-container-exists != 'true' + - name: Build and test + run: | + export GITTEST_NEGOTIATE_PASSWORD="${{ secrets.GITTEST_NEGOTIATE_PASSWORD }}" + + if [ -n "${{ matrix.platform.image }}" ]; then + docker run \ + --rm \ + -v "$(pwd):/home/libgit2/source" \ + -w /home/libgit2/source \ + -e ASAN_SYMBOLIZER_PATH \ + -e CC \ + -e CFLAGS \ + -e CMAKE_GENERATOR \ + -e CMAKE_OPTIONS \ + -e GITTEST_NEGOTIATE_PASSWORD \ + -e PKG_CONFIG_PATH \ + -e SKIP_NEGOTIATE_TESTS \ + -e SKIP_SSH_TESTS \ + ${{ env.docker-registry-container-sha }} \ + /bin/bash -c "mkdir build && cd build && ../ci/build.sh && ../ci/test.sh" + else + mkdir build && cd build + ../ci/build.sh + ../ci/test.sh + fi + shell: bash From 3dc238c393ca12d106803d6be8f5691606636f81 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 18 Nov 2020 19:30:13 +0000 Subject: [PATCH 0057/1616] coverity --- .github/workflows/coverity.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/coverity.yml diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml new file mode 100644 index 00000000000..99a4b151b87 --- /dev/null +++ b/.github/workflows/coverity.yml @@ -0,0 +1,30 @@ +# Nightly build for the master branch running coverity. +name: Coverity Build + +on: + workflow_dispatch: + schedule: + - cron: '15 2 * * *' + +env: + docker-registry: docker.pkg.github.com + docker-config-path: ci/docker + +jobs: + build: + name: Coverity + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Download container + run: ci/getcontainer.sh ci/docker/xenial + env: + DOCKER_REGISTRY: ${{ env.docker-registry }} + GITHUB_TOKEN: ${{ secrets.github_token }} + - name: Run Coverity + run: ci/coverity.sh + env: + COVERITY_TOKEN: ${{ secrets.coverity_token }} From 938cf143116a4eef21e19424b098e277226fe9e1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 20 Nov 2020 22:32:12 +0000 Subject: [PATCH 0058/1616] ci: GitHub Actions for arm64 --- .github/workflows/nightly.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index c0e15539ada..c5daeeab1c6 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -2,6 +2,7 @@ name: Nightly Build on: + workflow_dispatch: schedule: - cron: '15 1 * * *' @@ -65,6 +66,10 @@ jobs: SKIP_NEGOTIATE_TESTS: true ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 os: ubuntu-latest + - # linux arm64 + os: [ linux, arm64, self-hosted ] + env: + CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON - # macOS os: macos-10.15 env: From cd6acb1d75cda075e82f1ee36783de9bd065a333 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 20 Nov 2020 22:48:41 +0000 Subject: [PATCH 0059/1616] ci: supply a token for self-hosted runners --- .github/workflows/nightly.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index c5daeeab1c6..0a28f362d8f 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -67,9 +67,11 @@ jobs: ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 os: ubuntu-latest - # linux arm64 - os: [ linux, arm64, self-hosted ] + os: [ focal, arm64, self-hosted ] env: + CC: gcc CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + ACTIONS_RUNNER_TOKEN: ${{ secrets.ACTIONS_RUNNER_TOKEN }} - # macOS os: macos-10.15 env: From 823137dcc6e4c3d46497ad59c8c0501863b6378f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 20 Nov 2020 23:14:18 +0000 Subject: [PATCH 0060/1616] ci: supply a token for self-hosted runners --- .github/workflows/nightly.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 0a28f362d8f..70edd965904 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -71,7 +71,6 @@ jobs: env: CC: gcc CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON - ACTIONS_RUNNER_TOKEN: ${{ secrets.ACTIONS_RUNNER_TOKEN }} - # macOS os: macos-10.15 env: @@ -121,7 +120,8 @@ jobs: SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true fail-fast: false - env: ${{ matrix.platform.env }} + env: + ACTIONS_RUNNER_TOKEN: ${{ secrets.ACTIONS_RUNNER_TOKEN }} runs-on: ${{ matrix.platform.os }} steps: - name: Check out repository @@ -167,4 +167,5 @@ jobs: ../ci/build.sh ../ci/test.sh fi + env: ${{ matrix.platform.env }} shell: bash From 2193f32a7673618312cc8223fdee896835044d6c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 20 Nov 2020 23:24:44 +0000 Subject: [PATCH 0061/1616] ci: propagate environment variables --- .github/workflows/nightly.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 70edd965904..aae6c4c346c 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -131,6 +131,7 @@ jobs: - name: Set up build environment run: ci/setup-${{ matrix.platform.setup-script }}.sh shell: bash + env: ${{ matrix.platform.env }} if: matrix.platform.setup-script != '' - name: Download container run: ci/getcontainer.sh ${{ env.docker-config-path }}/${{ matrix.platform.image }} From cb4b3bdf923c9ebc66f500d7cc484e6f453ebf0a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 12 Jul 2020 17:49:42 +0100 Subject: [PATCH 0062/1616] win32: "crtdbg" is now "leakcheck" msvc crtdbg is a mouthfull that is not particularly indicative of what it does. Let's rename it to "win32 leakcheck". --- src/alloc.c | 11 +- src/allocators/win32_crtdbg.c | 11 +- src/libgit2.c | 1 - src/win32/w32_crtdbg_stacktrace.h | 127 --------- ...32_crtdbg_stacktrace.c => w32_leakcheck.c} | 240 ++++++++++++++-- src/win32/w32_leakcheck.h | 256 ++++++++++++++++++ src/win32/w32_stack.c | 188 ------------- src/win32/w32_stack.h | 140 ---------- tests/trace/windows/stacktrace.c | 75 +++-- 9 files changed, 513 insertions(+), 536 deletions(-) delete mode 100644 src/win32/w32_crtdbg_stacktrace.h rename src/win32/{w32_crtdbg_stacktrace.c => w32_leakcheck.c} (56%) create mode 100644 src/win32/w32_leakcheck.h delete mode 100644 src/win32/w32_stack.c delete mode 100644 src/win32/w32_stack.h diff --git a/src/alloc.c b/src/alloc.c index 6972e7b5986..eedf85aa7a9 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -12,8 +12,7 @@ #include "allocators/win32_crtdbg.h" #if defined(GIT_MSVC_CRTDBG) -# include "win32/w32_stack.h" -# include "win32/w32_crtdbg_stacktrace.h" +# include "win32/w32_leakcheck.h" #endif git_allocator git__allocator; @@ -30,16 +29,16 @@ static int setup_default_allocator(void) #if defined(GIT_MSVC_CRTDBG) static void allocator_global_shutdown(void) { - git_win32__crtdbg_stacktrace_cleanup(); - git_win32__stack_cleanup(); + git_win32_leakcheck_stacktrace_cleanup(); + git_win32_leakcheck_stack_cleanup(); } #endif int git_allocator_global_init(void) { #if defined(GIT_MSVC_CRTDBG) - git_win32__crtdbg_stacktrace_init(); - git_win32__stack_init(); + git_win32_leakcheck_stacktrace_init(); + git_win32_leakcheck_stack_init(); if (git_runtime_shutdown_register(allocator_global_shutdown) < 0) return -1; diff --git a/src/allocators/win32_crtdbg.c b/src/allocators/win32_crtdbg.c index c726268a840..c542b0c5441 100644 --- a/src/allocators/win32_crtdbg.c +++ b/src/allocators/win32_crtdbg.c @@ -9,26 +9,25 @@ #if defined(GIT_MSVC_CRTDBG) -#include "win32/w32_stack.h" -#include "win32/w32_crtdbg_stacktrace.h" +#include "win32/w32_leakcheck.h" static void *crtdbg__malloc(size_t len, const char *file, int line) { - void *ptr = _malloc_dbg(len, _NORMAL_BLOCK, git_win32__crtdbg_stacktrace(1,file), line); + void *ptr = _malloc_dbg(len, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); if (!ptr) git_error_set_oom(); return ptr; } static void *crtdbg__calloc(size_t nelem, size_t elsize, const char *file, int line) { - void *ptr = _calloc_dbg(nelem, elsize, _NORMAL_BLOCK, git_win32__crtdbg_stacktrace(1,file), line); + void *ptr = _calloc_dbg(nelem, elsize, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); if (!ptr) git_error_set_oom(); return ptr; } static char *crtdbg__strdup(const char *str, const char *file, int line) { - char *ptr = _strdup_dbg(str, _NORMAL_BLOCK, git_win32__crtdbg_stacktrace(1,file), line); + char *ptr = _strdup_dbg(str, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); if (!ptr) git_error_set_oom(); return ptr; } @@ -68,7 +67,7 @@ static char *crtdbg__substrdup(const char *start, size_t n, const char *file, in static void *crtdbg__realloc(void *ptr, size_t size, const char *file, int line) { - void *new_ptr = _realloc_dbg(ptr, size, _NORMAL_BLOCK, git_win32__crtdbg_stacktrace(1,file), line); + void *new_ptr = _realloc_dbg(ptr, size, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); if (!new_ptr) git_error_set_oom(); return new_ptr; } diff --git a/src/libgit2.c b/src/libgit2.c index 316d8936527..2e9cb851036 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -31,7 +31,6 @@ #include "transports/smart.h" #include "transports/http.h" #include "transports/ssh.h" -#include "win32/w32_stack.h" #ifdef GIT_OPENSSL # include diff --git a/src/win32/w32_crtdbg_stacktrace.h b/src/win32/w32_crtdbg_stacktrace.h deleted file mode 100644 index d65154babe1..00000000000 --- a/src/win32/w32_crtdbg_stacktrace.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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_win32_w32_crtdbg_stacktrace_h__ -#define INCLUDE_win32_w32_crtdbg_stacktrace_h__ - -#include "common.h" - -#if defined(GIT_MSVC_CRTDBG) - -#include -#include - -#include "git2/errors.h" -#include "strnlen.h" - -/* MSVC CRTDBG memory leak reporting. - * - * We DO NOT use the "_CRTDBG_MAP_ALLOC" macro described in the MSVC - * documentation because all allocs/frees in libgit2 already go through - * the "git__" routines defined in this file. Simply using the normal - * reporting mechanism causes all leaks to be attributed to a routine - * here in util.h (ie, the actual call to calloc()) rather than the - * caller of git__calloc(). - * - * Therefore, we declare a set of "git__crtdbg__" routines to replace - * the corresponding "git__" routines and re-define the "git__" symbols - * as macros. This allows us to get and report the file:line info of - * the real caller. - * - * We DO NOT replace the "git__free" routine because it needs to remain - * a function pointer because it is used as a function argument when - * setting up various structure "destructors". - * - * We also DO NOT use the "_CRTDBG_MAP_ALLOC" macro because it causes - * "free" to be remapped to "_free_dbg" and this causes problems for - * structures which define a field named "free". - * - * Finally, CRTDBG must be explicitly enabled and configured at program - * startup. See tests/main.c for an example. - */ - -/** - * Initialize our memory leak tracking and de-dup data structures. - * This should ONLY be called by git_libgit2_init(). - */ -void git_win32__crtdbg_stacktrace_init(void); - -/** - * Shutdown our memory leak tracking and dump summary data. - * This should ONLY be called by git_libgit2_shutdown(). - * - * We explicitly call _CrtDumpMemoryLeaks() during here so - * that we can compute summary data for the leaks. We print - * the stacktrace of each unique leak. - * - * This cleanup does not happen if the app calls exit() - * without calling the libgit2 shutdown code. - * - * This info we print here is independent of any automatic - * reporting during exit() caused by _CRTDBG_LEAK_CHECK_DF. - * Set it in your app if you also want traditional reporting. - */ -void git_win32__crtdbg_stacktrace_cleanup(void); - -/** - * Checkpoint options. - */ -typedef enum git_win32__crtdbg_stacktrace_options { - /** - * Set checkpoint marker. - */ - GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK = (1 << 0), - - /** - * Dump leaks since last checkpoint marker. - * May not be combined with __LEAKS_TOTAL. - * - * Note that this may generate false positives for global TLS - * error state and other global caches that aren't cleaned up - * until the thread/process terminates. So when using this - * around a region of interest, also check the final (at exit) - * dump before digging into leaks reported here. - */ - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK = (1 << 1), - - /** - * Dump leaks since init. May not be combined - * with __LEAKS_SINCE_MARK. - */ - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_TOTAL = (1 << 2), - - /** - * Suppress printing during dumps. - * Just return leak count. - */ - GIT_WIN32__CRTDBG_STACKTRACE__QUIET = (1 << 3), - -} git_win32__crtdbg_stacktrace_options; - -/** - * Checkpoint memory state and/or dump unique stack traces of - * current memory leaks. - * - * @return number of unique leaks (relative to requested starting - * point) or error. - */ -GIT_EXTERN(int) git_win32__crtdbg_stacktrace__dump( - git_win32__crtdbg_stacktrace_options opt, - const char *label); - -/** - * Construct stacktrace and append it to the global buffer. - * Return pointer to start of this string. On any error or - * lack of buffer space, just return the given file buffer - * so it will behave as usual. - * - * This should ONLY be called by our internal memory allocations - * routines. - */ -const char *git_win32__crtdbg_stacktrace(int skip, const char *file); - -#endif -#endif diff --git a/src/win32/w32_crtdbg_stacktrace.c b/src/win32/w32_leakcheck.c similarity index 56% rename from src/win32/w32_crtdbg_stacktrace.c rename to src/win32/w32_leakcheck.c index 22a353d589f..4fc3ec489b5 100644 --- a/src/win32/w32_crtdbg_stacktrace.c +++ b/src/win32/w32_leakcheck.c @@ -5,12 +5,192 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "w32_crtdbg_stacktrace.h" +#include "w32_leakcheck.h" #if defined(GIT_MSVC_CRTDBG) -#include "w32_stack.h" -#define CRTDBG_STACKTRACE__UID_LEN (15) +#include "Windows.h" +#include "Dbghelp.h" +#include "win32/posix.h" +#include "hash.h" + +/* Stack frames (for stack tracing, below) */ + +static bool g_win32_stack_initialized = false; +static HANDLE g_win32_stack_process = INVALID_HANDLE_VALUE; +static git_win32_leakcheck_stack_aux_cb_alloc g_aux_cb_alloc = NULL; +static git_win32_leakcheck_stack_aux_cb_lookup g_aux_cb_lookup = NULL; + +int git_win32_leakcheck_stack_set_aux_cb( + git_win32_leakcheck_stack_aux_cb_alloc cb_alloc, + git_win32_leakcheck_stack_aux_cb_lookup cb_lookup) +{ + g_aux_cb_alloc = cb_alloc; + g_aux_cb_lookup = cb_lookup; + + return 0; +} + +void git_win32_leakcheck_stack_init(void) +{ + if (!g_win32_stack_initialized) { + g_win32_stack_process = GetCurrentProcess(); + SymSetOptions(SYMOPT_LOAD_LINES); + SymInitialize(g_win32_stack_process, NULL, TRUE); + g_win32_stack_initialized = true; + } +} + +void git_win32_leakcheck_stack_cleanup(void) +{ + if (g_win32_stack_initialized) { + SymCleanup(g_win32_stack_process); + g_win32_stack_process = INVALID_HANDLE_VALUE; + g_win32_stack_initialized = false; + } +} + +int git_win32_leakcheck_stack_capture(git_win32_leakcheck_stack_raw_data *pdata, int skip) +{ + if (!g_win32_stack_initialized) { + git_error_set(GIT_ERROR_INVALID, "git_win32_stack not initialized."); + return GIT_ERROR; + } + + memset(pdata, 0, sizeof(*pdata)); + pdata->nr_frames = RtlCaptureStackBackTrace( + skip+1, GIT_WIN32_LEAKCHECK_STACK_MAX_FRAMES, pdata->frames, NULL); + + /* If an "aux" data provider was registered, ask it to capture + * whatever data it needs and give us an "aux_id" to it so that + * we can refer to it later when reporting. + */ + if (g_aux_cb_alloc) + (g_aux_cb_alloc)(&pdata->aux_id); + + return 0; +} + +int git_win32_leakcheck_stack_compare( + git_win32_leakcheck_stack_raw_data *d1, + git_win32_leakcheck_stack_raw_data *d2) +{ + return memcmp(d1, d2, sizeof(*d1)); +} + +int git_win32_leakcheck_stack_format( + char *pbuf, size_t buf_len, + const git_win32_leakcheck_stack_raw_data *pdata, + const char *prefix, const char *suffix) +{ +#define MY_MAX_FILENAME 255 + + /* SYMBOL_INFO has char FileName[1] at the end. The docs say to + * to malloc it with extra space for your desired max filename. + */ + struct { + SYMBOL_INFO symbol; + char extra[MY_MAX_FILENAME + 1]; + } s; + + IMAGEHLP_LINE64 line; + size_t buf_used = 0; + unsigned int k; + char detail[MY_MAX_FILENAME * 2]; /* filename plus space for function name and formatting */ + size_t detail_len; + + if (!g_win32_stack_initialized) { + git_error_set(GIT_ERROR_INVALID, "git_win32_stack not initialized."); + return GIT_ERROR; + } + + if (!prefix) + prefix = "\t"; + if (!suffix) + suffix = "\n"; + + memset(pbuf, 0, buf_len); + + memset(&s, 0, sizeof(s)); + s.symbol.MaxNameLen = MY_MAX_FILENAME; + s.symbol.SizeOfStruct = sizeof(SYMBOL_INFO); + + memset(&line, 0, sizeof(line)); + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + for (k=0; k < pdata->nr_frames; k++) { + DWORD64 frame_k = (DWORD64)pdata->frames[k]; + DWORD dwUnused; + + if (SymFromAddr(g_win32_stack_process, frame_k, 0, &s.symbol) && + SymGetLineFromAddr64(g_win32_stack_process, frame_k, &dwUnused, &line)) { + const char *pslash; + const char *pfile; + + pslash = strrchr(line.FileName, '\\'); + pfile = ((pslash) ? (pslash+1) : line.FileName); + p_snprintf(detail, sizeof(detail), "%s%s:%d> %s%s", + prefix, pfile, line.LineNumber, s.symbol.Name, suffix); + } else { + /* This happens when we cross into another module. + * For example, in CLAR tests, this is typically + * the CRT startup code. Just print an unknown + * frame and continue. + */ + p_snprintf(detail, sizeof(detail), "%s??%s", prefix, suffix); + } + detail_len = strlen(detail); + + if (buf_len < (buf_used + detail_len + 1)) { + /* we don't have room for this frame in the buffer, so just stop. */ + break; + } + + memcpy(&pbuf[buf_used], detail, detail_len); + buf_used += detail_len; + } + + /* "aux_id" 0 is reserved to mean no aux data. This is needed to handle + * allocs that occur before the aux callbacks were registered. + */ + if (pdata->aux_id > 0) { + p_snprintf(detail, sizeof(detail), "%saux_id: %d%s", + prefix, pdata->aux_id, suffix); + detail_len = strlen(detail); + if ((buf_used + detail_len + 1) < buf_len) { + memcpy(&pbuf[buf_used], detail, detail_len); + buf_used += detail_len; + } + + /* If an "aux" data provider is still registered, ask it to append its detailed + * data to the end of ours using the "aux_id" it gave us when this de-duped + * item was created. + */ + if (g_aux_cb_lookup) + (g_aux_cb_lookup)(pdata->aux_id, &pbuf[buf_used], (buf_len - buf_used - 1)); + } + + return GIT_OK; +} + +int git_win32_leakcheck_stack( + char * pbuf, size_t buf_len, + int skip, + const char *prefix, const char *suffix) +{ + git_win32_leakcheck_stack_raw_data data; + int error; + + if ((error = git_win32_leakcheck_stack_capture(&data, skip)) < 0) + return error; + if ((error = git_win32_leakcheck_stack_format(pbuf, buf_len, &data, prefix, suffix)) < 0) + return error; + return 0; +} + +/* Strack tracing */ + +#define STACKTRACE_UID_LEN (15) /** * The stacktrace of an allocation can be distilled @@ -20,20 +200,20 @@ * give to the CRT malloc routines. */ typedef struct { - char uid[CRTDBG_STACKTRACE__UID_LEN + 1]; -} git_win32__crtdbg_stacktrace__uid; + char uid[STACKTRACE_UID_LEN + 1]; +} git_win32_leakcheck_stacktrace_uid; /** * All mallocs with the same stacktrace will be de-duped * and aggregated into this row. */ typedef struct { - git_win32__crtdbg_stacktrace__uid uid; /* must be first */ - git_win32__stack__raw_data raw_data; + git_win32_leakcheck_stacktrace_uid uid; /* must be first */ + git_win32_leakcheck_stack_raw_data raw_data; unsigned int count_allocs; /* times this alloc signature seen since init */ unsigned int count_allocs_at_last_checkpoint; /* times since last mark */ unsigned int transient_count_leaks; /* sum of leaks */ -} git_win32__crtdbg_stacktrace__row; +} git_win32_leakcheck_stacktrace_row; static CRITICAL_SECTION g_crtdbg_stacktrace_cs; @@ -58,8 +238,8 @@ static CRITICAL_SECTION g_crtdbg_stacktrace_cs; */ #define MY_ROW_LIMIT (2 * 1024 * 1024) -static git_win32__crtdbg_stacktrace__row g_cs_rows[MY_ROW_LIMIT]; -static git_win32__crtdbg_stacktrace__row *g_cs_index[MY_ROW_LIMIT]; +static git_win32_leakcheck_stacktrace_row g_cs_rows[MY_ROW_LIMIT]; +static git_win32_leakcheck_stacktrace_row *g_cs_index[MY_ROW_LIMIT]; static unsigned int g_cs_end = MY_ROW_LIMIT; static unsigned int g_cs_ins = 0; /* insertion point == unique allocs seen */ @@ -76,18 +256,18 @@ static bool g_transient_leaks_since_mark = false; /* payload for hook */ */ static int row_cmp(const void *v1, const void *v2) { - git_win32__stack__raw_data *d1 = (git_win32__stack__raw_data*)v1; - git_win32__crtdbg_stacktrace__row *r2 = (git_win32__crtdbg_stacktrace__row *)v2; + git_win32_leakcheck_stack_raw_data *d1 = (git_win32_leakcheck_stack_raw_data*)v1; + git_win32_leakcheck_stacktrace_row *r2 = (git_win32_leakcheck_stacktrace_row *)v2; - return (git_win32__stack_compare(d1, &r2->raw_data)); + return (git_win32_leakcheck_stack_compare(d1, &r2->raw_data)); } /** * Unique insert the new data into the row and index tables. * We have to sort by the stackframe data itself, not the uid. */ -static git_win32__crtdbg_stacktrace__row * insert_unique( - const git_win32__stack__raw_data *pdata) +static git_win32_leakcheck_stacktrace_row * insert_unique( + const git_win32_leakcheck_stack_raw_data *pdata) { size_t pos; if (git__bsearch(g_cs_index, g_cs_ins, pdata, row_cmp, &pos) < 0) { @@ -206,7 +386,7 @@ static void dump_summary(const char *label) g_cs_rows[k].count_allocs); my_output(buf); - if (git_win32__stack_format( + if (git_win32_leakcheck_stack_format( buf, sizeof(buf), &g_cs_rows[k].raw_data, NULL, NULL) >= 0) { my_output(buf); @@ -219,7 +399,7 @@ static void dump_summary(const char *label) fflush(stderr); } -void git_win32__crtdbg_stacktrace_init(void) +void git_win32_leakcheck_stacktrace_init(void) { InitializeCriticalSection(&g_crtdbg_stacktrace_cs); @@ -238,8 +418,8 @@ void git_win32__crtdbg_stacktrace_init(void) LeaveCriticalSection(&g_crtdbg_stacktrace_cs); } -int git_win32__crtdbg_stacktrace__dump( - git_win32__crtdbg_stacktrace_options opt, +int git_win32_leakcheck_stacktrace_dump( + git_win32_leakcheck_stacktrace_options opt, const char *label) { _CRT_REPORT_HOOK old; @@ -248,10 +428,10 @@ int git_win32__crtdbg_stacktrace__dump( #define IS_BIT_SET(o,b) (((o) & (b)) != 0) - bool b_set_mark = IS_BIT_SET(opt, GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK); - bool b_leaks_since_mark = IS_BIT_SET(opt, GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK); - bool b_leaks_total = IS_BIT_SET(opt, GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_TOTAL); - bool b_quiet = IS_BIT_SET(opt, GIT_WIN32__CRTDBG_STACKTRACE__QUIET); + bool b_set_mark = IS_BIT_SET(opt, GIT_WIN32_LEAKCHECK_STACKTRACE_SET_MARK); + bool b_leaks_since_mark = IS_BIT_SET(opt, GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK); + bool b_leaks_total = IS_BIT_SET(opt, GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_TOTAL); + bool b_quiet = IS_BIT_SET(opt, GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET); if (b_leaks_since_mark && b_leaks_total) { git_error_set(GIT_ERROR_INVALID, "cannot combine LEAKS_SINCE_MARK and LEAKS_TOTAL."); @@ -301,7 +481,7 @@ int git_win32__crtdbg_stacktrace__dump( return r; } -void git_win32__crtdbg_stacktrace_cleanup(void) +void git_win32_leakcheck_stacktrace_cleanup(void) { /* At shutdown/cleanup, dump cummulative leak info * with everything since startup. This might generate @@ -310,20 +490,20 @@ void git_win32__crtdbg_stacktrace_cleanup(void) * positives for resources previously reported during * checkpoints. */ - git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_TOTAL, + git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_TOTAL, "CLEANUP"); DeleteCriticalSection(&g_crtdbg_stacktrace_cs); } -const char *git_win32__crtdbg_stacktrace(int skip, const char *file) +const char *git_win32_leakcheck_stacktrace(int skip, const char *file) { - git_win32__stack__raw_data new_data; - git_win32__crtdbg_stacktrace__row *row; + git_win32_leakcheck_stack_raw_data new_data; + git_win32_leakcheck_stacktrace_row *row; const char * result = file; - if (git_win32__stack_capture(&new_data, skip+1) < 0) + if (git_win32_leakcheck_stack_capture(&new_data, skip+1) < 0) return result; EnterCriticalSection(&g_crtdbg_stacktrace_cs); diff --git a/src/win32/w32_leakcheck.h b/src/win32/w32_leakcheck.h new file mode 100644 index 00000000000..518f5ad7dbb --- /dev/null +++ b/src/win32/w32_leakcheck.h @@ -0,0 +1,256 @@ +/* + * 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_win32_leakcheck_h__ +#define INCLUDE_win32_leakcheck_h__ + +#include "common.h" + +#if defined(GIT_MSVC_CRTDBG) + +#include +#include + +#include "git2/errors.h" +#include "strnlen.h" + +/* Stack frames (for stack tracing, below) */ + +/** + * This type defines a callback to be used to augment a C stacktrace + * with "aux" data. This can be used, for example, to allow LibGit2Sharp + * (or other interpreted consumer libraries) to give us C# stacktrace + * data for the PInvoke. + * + * This callback will be called during crtdbg-instrumented allocs. + * + * @param aux_id [out] A returned "aux_id" representing a unique + * (de-duped at the C# layer) stacktrace. "aux_id" 0 is reserved + * to mean no aux stacktrace data. + */ +typedef void (*git_win32_leakcheck_stack_aux_cb_alloc)(unsigned int *aux_id); + +/** + * This type defines a callback to be used to augment the output of + * a stacktrace. This will be used to request the C# layer format + * the C# stacktrace associated with "aux_id" into the provided + * buffer. + * + * This callback will be called during leak reporting. + * + * @param aux_id The "aux_id" key associated with a stacktrace. + * @param aux_msg A buffer where a formatted message should be written. + * @param aux_msg_len The size of the buffer. + */ +typedef void (*git_win32_leakcheck_stack_aux_cb_lookup)(unsigned int aux_id, char *aux_msg, size_t aux_msg_len); + +/** + * Register an "aux" data provider to augment our C stacktrace data. + * + * This can be used, for example, to allow LibGit2Sharp (or other + * interpreted consumer libraries) to give us the C# stacktrace of + * the PInvoke. + * + * If you choose to use this feature, it should be registered during + * initialization and not changed for the duration of the process. + */ +int git_win32_leakcheck_stack_set_aux_cb( + git_win32_leakcheck_stack_aux_cb_alloc cb_alloc, + git_win32_leakcheck_stack_aux_cb_lookup cb_lookup); + +/** + * Maximum number of stackframes to record for a + * single stacktrace. + */ +#define GIT_WIN32_LEAKCHECK_STACK_MAX_FRAMES 30 + +/** + * Wrapper containing the raw unprocessed stackframe + * data for a single stacktrace and any "aux_id". + * + * I put the aux_id first so leaks will be sorted by it. + * So, for example, if a specific callstack in C# leaks + * a repo handle, all of the pointers within the associated + * repo pointer will be grouped together. + */ +typedef struct { + unsigned int aux_id; + unsigned int nr_frames; + void *frames[GIT_WIN32_LEAKCHECK_STACK_MAX_FRAMES]; +} git_win32_leakcheck_stack_raw_data; + + +/** + * Load symbol table data. This should be done in the primary + * thread at startup (under a lock if there are other threads + * active). + */ +void git_win32_leakcheck_stack_init(void); + +/** + * Cleanup symbol table data. This should be done in the + * primary thead at shutdown (under a lock if there are other + * threads active). + */ +void git_win32_leakcheck_stack_cleanup(void); + + +/** + * Capture raw stack trace data for the current process/thread. + * + * @param skip Number of initial frames to skip. Pass 0 to + * begin with the caller of this routine. Pass 1 to begin + * with its caller. And so on. + */ +int git_win32_leakcheck_stack_capture(git_win32_leakcheck_stack_raw_data *pdata, int skip); + +/** + * Compare 2 raw stacktraces with the usual -1,0,+1 result. + * This includes any "aux_id" values in the comparison, so that + * our de-dup is also "aux" context relative. + */ +int git_win32_leakcheck_stack_compare( + git_win32_leakcheck_stack_raw_data *d1, + git_win32_leakcheck_stack_raw_data *d2); + +/** + * Format raw stacktrace data into buffer WITHOUT using any mallocs. + * + * @param prefix String written before each frame; defaults to "\t". + * @param suffix String written after each frame; defaults to "\n". + */ +int git_win32_leakcheck_stack_format( + char *pbuf, size_t buf_len, + const git_win32_leakcheck_stack_raw_data *pdata, + const char *prefix, const char *suffix); + +/** + * Convenience routine to capture and format stacktrace into + * a buffer WITHOUT using any mallocs. This is primarily a + * wrapper for testing. + * + * @param skip Number of initial frames to skip. Pass 0 to + * begin with the caller of this routine. Pass 1 to begin + * with its caller. And so on. + * @param prefix String written before each frame; defaults to "\t". + * @param suffix String written after each frame; defaults to "\n". + */ +int git_win32_leakcheck_stack( + char * pbuf, size_t buf_len, + int skip, + const char *prefix, const char *suffix); + +/* Stack tracing */ + +/* MSVC CRTDBG memory leak reporting. + * + * We DO NOT use the "_CRTDBG_MAP_ALLOC" macro described in the MSVC + * documentation because all allocs/frees in libgit2 already go through + * the "git__" routines defined in this file. Simply using the normal + * reporting mechanism causes all leaks to be attributed to a routine + * here in util.h (ie, the actual call to calloc()) rather than the + * caller of git__calloc(). + * + * Therefore, we declare a set of "git__crtdbg__" routines to replace + * the corresponding "git__" routines and re-define the "git__" symbols + * as macros. This allows us to get and report the file:line info of + * the real caller. + * + * We DO NOT replace the "git__free" routine because it needs to remain + * a function pointer because it is used as a function argument when + * setting up various structure "destructors". + * + * We also DO NOT use the "_CRTDBG_MAP_ALLOC" macro because it causes + * "free" to be remapped to "_free_dbg" and this causes problems for + * structures which define a field named "free". + * + * Finally, CRTDBG must be explicitly enabled and configured at program + * startup. See tests/main.c for an example. + */ + +/** + * Initialize our memory leak tracking and de-dup data structures. + * This should ONLY be called by git_libgit2_init(). + */ +void git_win32_leakcheck_stacktrace_init(void); + +/** + * Shutdown our memory leak tracking and dump summary data. + * This should ONLY be called by git_libgit2_shutdown(). + * + * We explicitly call _CrtDumpMemoryLeaks() during here so + * that we can compute summary data for the leaks. We print + * the stacktrace of each unique leak. + * + * This cleanup does not happen if the app calls exit() + * without calling the libgit2 shutdown code. + * + * This info we print here is independent of any automatic + * reporting during exit() caused by _CRTDBG_LEAK_CHECK_DF. + * Set it in your app if you also want traditional reporting. + */ +void git_win32_leakcheck_stacktrace_cleanup(void); + +/** + * Checkpoint options. + */ +typedef enum git_win32_leakcheck_stacktrace_options { + /** + * Set checkpoint marker. + */ + GIT_WIN32_LEAKCHECK_STACKTRACE_SET_MARK = (1 << 0), + + /** + * Dump leaks since last checkpoint marker. + * May not be combined with _LEAKS_TOTAL. + * + * Note that this may generate false positives for global TLS + * error state and other global caches that aren't cleaned up + * until the thread/process terminates. So when using this + * around a region of interest, also check the final (at exit) + * dump before digging into leaks reported here. + */ + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK = (1 << 1), + + /** + * Dump leaks since init. May not be combined + * with _LEAKS_SINCE_MARK. + */ + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_TOTAL = (1 << 2), + + /** + * Suppress printing during dumps. + * Just return leak count. + */ + GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET = (1 << 3), + +} git_win32_leakcheck_stacktrace_options; + +/** + * Checkpoint memory state and/or dump unique stack traces of + * current memory leaks. + * + * @return number of unique leaks (relative to requested starting + * point) or error. + */ +int git_win32_leakcheck_stacktrace_dump( + git_win32_leakcheck_stacktrace_options opt, + const char *label); + +/** + * Construct stacktrace and append it to the global buffer. + * Return pointer to start of this string. On any error or + * lack of buffer space, just return the given file buffer + * so it will behave as usual. + * + * This should ONLY be called by our internal memory allocations + * routines. + */ +const char *git_win32_leakcheck_stacktrace(int skip, const char *file); + +#endif +#endif diff --git a/src/win32/w32_stack.c b/src/win32/w32_stack.c deleted file mode 100644 index 78c78dbbdeb..00000000000 --- a/src/win32/w32_stack.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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 "w32_stack.h" - -#if defined(GIT_MSVC_CRTDBG) -#include "Windows.h" -#include "Dbghelp.h" -#include "win32/posix.h" -#include "hash.h" - -static bool g_win32_stack_initialized = false; -static HANDLE g_win32_stack_process = INVALID_HANDLE_VALUE; -static git_win32__stack__aux_cb_alloc g_aux_cb_alloc = NULL; -static git_win32__stack__aux_cb_lookup g_aux_cb_lookup = NULL; - -int git_win32__stack__set_aux_cb( - git_win32__stack__aux_cb_alloc cb_alloc, - git_win32__stack__aux_cb_lookup cb_lookup) -{ - g_aux_cb_alloc = cb_alloc; - g_aux_cb_lookup = cb_lookup; - - return 0; -} - -void git_win32__stack_init(void) -{ - if (!g_win32_stack_initialized) { - g_win32_stack_process = GetCurrentProcess(); - SymSetOptions(SYMOPT_LOAD_LINES); - SymInitialize(g_win32_stack_process, NULL, TRUE); - g_win32_stack_initialized = true; - } -} - -void git_win32__stack_cleanup(void) -{ - if (g_win32_stack_initialized) { - SymCleanup(g_win32_stack_process); - g_win32_stack_process = INVALID_HANDLE_VALUE; - g_win32_stack_initialized = false; - } -} - -int git_win32__stack_capture(git_win32__stack__raw_data *pdata, int skip) -{ - if (!g_win32_stack_initialized) { - git_error_set(GIT_ERROR_INVALID, "git_win32_stack not initialized."); - return GIT_ERROR; - } - - memset(pdata, 0, sizeof(*pdata)); - pdata->nr_frames = RtlCaptureStackBackTrace( - skip+1, GIT_WIN32__STACK__MAX_FRAMES, pdata->frames, NULL); - - /* If an "aux" data provider was registered, ask it to capture - * whatever data it needs and give us an "aux_id" to it so that - * we can refer to it later when reporting. - */ - if (g_aux_cb_alloc) - (g_aux_cb_alloc)(&pdata->aux_id); - - return 0; -} - -int git_win32__stack_compare( - git_win32__stack__raw_data *d1, - git_win32__stack__raw_data *d2) -{ - return memcmp(d1, d2, sizeof(*d1)); -} - -int git_win32__stack_format( - char *pbuf, size_t buf_len, - const git_win32__stack__raw_data *pdata, - const char *prefix, const char *suffix) -{ -#define MY_MAX_FILENAME 255 - - /* SYMBOL_INFO has char FileName[1] at the end. The docs say to - * to malloc it with extra space for your desired max filename. - */ - struct { - SYMBOL_INFO symbol; - char extra[MY_MAX_FILENAME + 1]; - } s; - - IMAGEHLP_LINE64 line; - size_t buf_used = 0; - unsigned int k; - char detail[MY_MAX_FILENAME * 2]; /* filename plus space for function name and formatting */ - size_t detail_len; - - if (!g_win32_stack_initialized) { - git_error_set(GIT_ERROR_INVALID, "git_win32_stack not initialized."); - return GIT_ERROR; - } - - if (!prefix) - prefix = "\t"; - if (!suffix) - suffix = "\n"; - - memset(pbuf, 0, buf_len); - - memset(&s, 0, sizeof(s)); - s.symbol.MaxNameLen = MY_MAX_FILENAME; - s.symbol.SizeOfStruct = sizeof(SYMBOL_INFO); - - memset(&line, 0, sizeof(line)); - line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - - for (k=0; k < pdata->nr_frames; k++) { - DWORD64 frame_k = (DWORD64)pdata->frames[k]; - DWORD dwUnused; - - if (SymFromAddr(g_win32_stack_process, frame_k, 0, &s.symbol) && - SymGetLineFromAddr64(g_win32_stack_process, frame_k, &dwUnused, &line)) { - const char *pslash; - const char *pfile; - - pslash = strrchr(line.FileName, '\\'); - pfile = ((pslash) ? (pslash+1) : line.FileName); - p_snprintf(detail, sizeof(detail), "%s%s:%d> %s%s", - prefix, pfile, line.LineNumber, s.symbol.Name, suffix); - } else { - /* This happens when we cross into another module. - * For example, in CLAR tests, this is typically - * the CRT startup code. Just print an unknown - * frame and continue. - */ - p_snprintf(detail, sizeof(detail), "%s??%s", prefix, suffix); - } - detail_len = strlen(detail); - - if (buf_len < (buf_used + detail_len + 1)) { - /* we don't have room for this frame in the buffer, so just stop. */ - break; - } - - memcpy(&pbuf[buf_used], detail, detail_len); - buf_used += detail_len; - } - - /* "aux_id" 0 is reserved to mean no aux data. This is needed to handle - * allocs that occur before the aux callbacks were registered. - */ - if (pdata->aux_id > 0) { - p_snprintf(detail, sizeof(detail), "%saux_id: %d%s", - prefix, pdata->aux_id, suffix); - detail_len = strlen(detail); - if ((buf_used + detail_len + 1) < buf_len) { - memcpy(&pbuf[buf_used], detail, detail_len); - buf_used += detail_len; - } - - /* If an "aux" data provider is still registered, ask it to append its detailed - * data to the end of ours using the "aux_id" it gave us when this de-duped - * item was created. - */ - if (g_aux_cb_lookup) - (g_aux_cb_lookup)(pdata->aux_id, &pbuf[buf_used], (buf_len - buf_used - 1)); - } - - return GIT_OK; -} - -int git_win32__stack( - char * pbuf, size_t buf_len, - int skip, - const char *prefix, const char *suffix) -{ - git_win32__stack__raw_data data; - int error; - - if ((error = git_win32__stack_capture(&data, skip)) < 0) - return error; - if ((error = git_win32__stack_format(pbuf, buf_len, &data, prefix, suffix)) < 0) - return error; - return 0; -} - -#endif diff --git a/src/win32/w32_stack.h b/src/win32/w32_stack.h deleted file mode 100644 index c2565c228d6..00000000000 --- a/src/win32/w32_stack.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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_win32_w32_stack_h__ -#define INCLUDE_win32_w32_stack_h__ - -#include "common.h" - -#if defined(GIT_MSVC_CRTDBG) - -/** - * This type defines a callback to be used to augment a C stacktrace - * with "aux" data. This can be used, for example, to allow LibGit2Sharp - * (or other interpreted consumer libraries) to give us C# stacktrace - * data for the PInvoke. - * - * This callback will be called during crtdbg-instrumented allocs. - * - * @param aux_id [out] A returned "aux_id" representing a unique - * (de-duped at the C# layer) stacktrace. "aux_id" 0 is reserved - * to mean no aux stacktrace data. - */ -typedef void (*git_win32__stack__aux_cb_alloc)(unsigned int *aux_id); - -/** - * This type defines a callback to be used to augment the output of - * a stacktrace. This will be used to request the C# layer format - * the C# stacktrace associated with "aux_id" into the provided - * buffer. - * - * This callback will be called during leak reporting. - * - * @param aux_id The "aux_id" key associated with a stacktrace. - * @param aux_msg A buffer where a formatted message should be written. - * @param aux_msg_len The size of the buffer. - */ -typedef void (*git_win32__stack__aux_cb_lookup)(unsigned int aux_id, char *aux_msg, size_t aux_msg_len); - -/** - * Register an "aux" data provider to augment our C stacktrace data. - * - * This can be used, for example, to allow LibGit2Sharp (or other - * interpreted consumer libraries) to give us the C# stacktrace of - * the PInvoke. - * - * If you choose to use this feature, it should be registered during - * initialization and not changed for the duration of the process. - */ -GIT_EXTERN(int) git_win32__stack__set_aux_cb( - git_win32__stack__aux_cb_alloc cb_alloc, - git_win32__stack__aux_cb_lookup cb_lookup); - -/** - * Maximum number of stackframes to record for a - * single stacktrace. - */ -#define GIT_WIN32__STACK__MAX_FRAMES 30 - -/** - * Wrapper containing the raw unprocessed stackframe - * data for a single stacktrace and any "aux_id". - * - * I put the aux_id first so leaks will be sorted by it. - * So, for example, if a specific callstack in C# leaks - * a repo handle, all of the pointers within the associated - * repo pointer will be grouped together. - */ -typedef struct { - unsigned int aux_id; - unsigned int nr_frames; - void *frames[GIT_WIN32__STACK__MAX_FRAMES]; -} git_win32__stack__raw_data; - - -/** - * Load symbol table data. This should be done in the primary - * thread at startup (under a lock if there are other threads - * active). - */ -void git_win32__stack_init(void); - -/** - * Cleanup symbol table data. This should be done in the - * primary thead at shutdown (under a lock if there are other - * threads active). - */ -void git_win32__stack_cleanup(void); - - -/** - * Capture raw stack trace data for the current process/thread. - * - * @param skip Number of initial frames to skip. Pass 0 to - * begin with the caller of this routine. Pass 1 to begin - * with its caller. And so on. - */ -int git_win32__stack_capture(git_win32__stack__raw_data *pdata, int skip); - -/** - * Compare 2 raw stacktraces with the usual -1,0,+1 result. - * This includes any "aux_id" values in the comparison, so that - * our de-dup is also "aux" context relative. - */ -int git_win32__stack_compare( - git_win32__stack__raw_data *d1, - git_win32__stack__raw_data *d2); - -/** - * Format raw stacktrace data into buffer WITHOUT using any mallocs. - * - * @param prefix String written before each frame; defaults to "\t". - * @param suffix String written after each frame; defaults to "\n". - */ -int git_win32__stack_format( - char *pbuf, size_t buf_len, - const git_win32__stack__raw_data *pdata, - const char *prefix, const char *suffix); - -/** - * Convenience routine to capture and format stacktrace into - * a buffer WITHOUT using any mallocs. This is primarily a - * wrapper for testing. - * - * @param skip Number of initial frames to skip. Pass 0 to - * begin with the caller of this routine. Pass 1 to begin - * with its caller. And so on. - * @param prefix String written before each frame; defaults to "\t". - * @param suffix String written after each frame; defaults to "\n". - */ -int git_win32__stack( - char * pbuf, size_t buf_len, - int skip, - const char *prefix, const char *suffix); - -#endif /* GIT_MSVC_CRTDBG */ -#endif diff --git a/tests/trace/windows/stacktrace.c b/tests/trace/windows/stacktrace.c index 34fcbcb894b..15604a575bf 100644 --- a/tests/trace/windows/stacktrace.c +++ b/tests/trace/windows/stacktrace.c @@ -1,13 +1,12 @@ #include "clar_libgit2.h" -#include "win32/w32_stack.h" -#include "win32/w32_crtdbg_stacktrace.h" +#include "win32/w32_leakcheck.h" #if defined(GIT_MSVC_CRTDBG) static void a(void) { char buf[10000]; - cl_assert(git_win32__stack(buf, sizeof(buf), 0, NULL, NULL) == 0); + cl_assert(git_win32_leakcheck_stack(buf, sizeof(buf), 0, NULL, NULL) == 0); #if 0 fprintf(stderr, "Stacktrace from [%s:%d]:\n%s\n", __FILE__, __LINE__, buf); @@ -47,79 +46,79 @@ void test_trace_windows_stacktrace__leaks(void) /* remember outstanding leaks due to set setup * and set mark/checkpoint. */ - before = git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__QUIET | - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_TOTAL | - GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK, + before = git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET | + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_TOTAL | + GIT_WIN32_LEAKCHECK_STACKTRACE_SET_MARK, NULL); p1 = git__malloc(5); - leaks = git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__QUIET | - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, + leaks = git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET | + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK, "p1"); cl_assert_equal_i(1, leaks); p2 = git__malloc(5); - leaks = git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__QUIET | - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, + leaks = git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET | + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK, "p1,p2"); cl_assert_equal_i(2, leaks); p3 = git__malloc(5); - leaks = git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__QUIET | - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, + leaks = git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET | + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK, "p1,p2,p3"); cl_assert_equal_i(3, leaks); git__free(p2); - leaks = git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__QUIET | - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, + leaks = git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET | + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK, "p1,p3"); cl_assert_equal_i(2, leaks); /* move the mark. only new leaks should appear afterwards */ - error = git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK, + error = git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_SET_MARK, NULL); /* cannot use cl_git_pass() since that may allocate memory. */ cl_assert_equal_i(0, error); - leaks = git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__QUIET | - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, + leaks = git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET | + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK, "not_p1,not_p3"); cl_assert_equal_i(0, leaks); p4 = git__malloc(5); - leaks = git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__QUIET | - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, + leaks = git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET | + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK, "p4,not_p1,not_p3"); cl_assert_equal_i(1, leaks); git__free(p1); git__free(p3); - leaks = git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__QUIET | - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, + leaks = git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET | + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK, "p4"); cl_assert_equal_i(1, leaks); git__free(p4); - leaks = git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__QUIET | - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK, + leaks = git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET | + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK, "end"); cl_assert_equal_i(0, leaks); /* confirm current absolute leaks count matches beginning value. */ - after = git_win32__crtdbg_stacktrace__dump( - GIT_WIN32__CRTDBG_STACKTRACE__QUIET | - GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_TOTAL, + after = git_win32_leakcheck_stacktrace_dump( + GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET | + GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_TOTAL, "total"); cl_assert_equal_i(before, after); #endif @@ -143,11 +142,11 @@ static void aux_cb_lookup__1(unsigned int aux_id, char *aux_msg, size_t aux_msg_ void test_trace_windows_stacktrace__aux1(void) { #if defined(GIT_MSVC_CRTDBG) - git_win32__stack__set_aux_cb(aux_cb_alloc__1, aux_cb_lookup__1); + git_win32_leakcheck_stack_set_aux_cb(aux_cb_alloc__1, aux_cb_lookup__1); c(); c(); c(); c(); - git_win32__stack__set_aux_cb(NULL, NULL); + git_win32_leakcheck_stack_set_aux_cb(NULL, NULL); #endif } From 31654a34c9e6a457ef581892ba8775e3f5235f62 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 12 Jul 2020 18:07:10 +0100 Subject: [PATCH 0063/1616] win32: consolidate leak checking initialization Move leak check initialization into git_win32_leakcheck_global_init, and call it on library initialization. --- src/alloc.c | 20 --------------- src/libgit2.c | 7 ++++++ src/win32/w32_leakcheck.c | 51 +++++++++++++++++++++++++++++++++++++++ src/win32/w32_leakcheck.h | 42 +++----------------------------- 4 files changed, 61 insertions(+), 59 deletions(-) diff --git a/src/alloc.c b/src/alloc.c index eedf85aa7a9..a5674c9b47a 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -11,10 +11,6 @@ #include "allocators/stdalloc.h" #include "allocators/win32_crtdbg.h" -#if defined(GIT_MSVC_CRTDBG) -# include "win32/w32_leakcheck.h" -#endif - git_allocator git__allocator; static int setup_default_allocator(void) @@ -26,24 +22,8 @@ static int setup_default_allocator(void) #endif } -#if defined(GIT_MSVC_CRTDBG) -static void allocator_global_shutdown(void) -{ - git_win32_leakcheck_stacktrace_cleanup(); - git_win32_leakcheck_stack_cleanup(); -} -#endif - int git_allocator_global_init(void) { -#if defined(GIT_MSVC_CRTDBG) - git_win32_leakcheck_stacktrace_init(); - git_win32_leakcheck_stack_init(); - - if (git_runtime_shutdown_register(allocator_global_shutdown) < 0) - return -1; -#endif - /* * We don't want to overwrite any allocator which has been set before * the init function is called. diff --git a/src/libgit2.c b/src/libgit2.c index 2e9cb851036..07414bec826 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -32,6 +32,10 @@ #include "transports/http.h" #include "transports/ssh.h" +#ifdef GIT_WIN32 +# include "win32/w32_leakcheck.h" +#endif + #ifdef GIT_OPENSSL # include #endif @@ -64,6 +68,9 @@ static int git_libgit2_settings_global_init(void) int git_libgit2_init(void) { static git_runtime_init_fn init_fns[] = { +#ifdef GIT_WIN32 + git_win32_leakcheck_global_init, +#endif git_allocator_global_init, git_threadstate_global_init, git_threads_global_init, diff --git a/src/win32/w32_leakcheck.c b/src/win32/w32_leakcheck.c index 4fc3ec489b5..31803d5974e 100644 --- a/src/win32/w32_leakcheck.c +++ b/src/win32/w32_leakcheck.c @@ -13,6 +13,7 @@ #include "Dbghelp.h" #include "win32/posix.h" #include "hash.h" +#include "runtime.h" /* Stack frames (for stack tracing, below) */ @@ -31,6 +32,11 @@ int git_win32_leakcheck_stack_set_aux_cb( return 0; } +/** + * Load symbol table data. This should be done in the primary + * thread at startup (under a lock if there are other threads + * active). + */ void git_win32_leakcheck_stack_init(void) { if (!g_win32_stack_initialized) { @@ -41,6 +47,11 @@ void git_win32_leakcheck_stack_init(void) } } +/** + * Cleanup symbol table data. This should be done in the + * primary thead at shutdown (under a lock if there are other + * threads active). + */ void git_win32_leakcheck_stack_cleanup(void) { if (g_win32_stack_initialized) { @@ -399,6 +410,10 @@ static void dump_summary(const char *label) fflush(stderr); } +/** + * Initialize our memory leak tracking and de-dup data structures. + * This should ONLY be called by git_libgit2_init(). + */ void git_win32_leakcheck_stacktrace_init(void) { InitializeCriticalSection(&g_crtdbg_stacktrace_cs); @@ -481,6 +496,21 @@ int git_win32_leakcheck_stacktrace_dump( return r; } +/** + * Shutdown our memory leak tracking and dump summary data. + * This should ONLY be called by git_libgit2_shutdown(). + * + * We explicitly call _CrtDumpMemoryLeaks() during here so + * that we can compute summary data for the leaks. We print + * the stacktrace of each unique leak. + * + * This cleanup does not happen if the app calls exit() + * without calling the libgit2 shutdown code. + * + * This info we print here is independent of any automatic + * reporting during exit() caused by _CRTDBG_LEAK_CHECK_DF. + * Set it in your app if you also want traditional reporting. + */ void git_win32_leakcheck_stacktrace_cleanup(void) { /* At shutdown/cleanup, dump cummulative leak info @@ -522,4 +552,25 @@ const char *git_win32_leakcheck_stacktrace(int skip, const char *file) return result; } +static void git_win32_leakcheck_global_shutdown(void) +{ + git_win32_leakcheck_stacktrace_cleanup(); + git_win32_leakcheck_stack_cleanup(); +} + +int git_win32_leakcheck_global_init(void) +{ + git_win32_leakcheck_stacktrace_init(); + git_win32_leakcheck_stack_init(); + + return git_runtime_shutdown_register(git_win32_leakcheck_global_shutdown); +} + +#else + +int git_win32_leakcheck_global_init(void) +{ + return 0; +} + #endif diff --git a/src/win32/w32_leakcheck.h b/src/win32/w32_leakcheck.h index 518f5ad7dbb..29bce4e89bd 100644 --- a/src/win32/w32_leakcheck.h +++ b/src/win32/w32_leakcheck.h @@ -10,6 +10,9 @@ #include "common.h" +/* Initialize the win32 leak checking system. */ +int git_win32_leakcheck_global_init(void); + #if defined(GIT_MSVC_CRTDBG) #include @@ -83,22 +86,6 @@ typedef struct { void *frames[GIT_WIN32_LEAKCHECK_STACK_MAX_FRAMES]; } git_win32_leakcheck_stack_raw_data; - -/** - * Load symbol table data. This should be done in the primary - * thread at startup (under a lock if there are other threads - * active). - */ -void git_win32_leakcheck_stack_init(void); - -/** - * Cleanup symbol table data. This should be done in the - * primary thead at shutdown (under a lock if there are other - * threads active). - */ -void git_win32_leakcheck_stack_cleanup(void); - - /** * Capture raw stack trace data for the current process/thread. * @@ -172,29 +159,6 @@ int git_win32_leakcheck_stack( * startup. See tests/main.c for an example. */ -/** - * Initialize our memory leak tracking and de-dup data structures. - * This should ONLY be called by git_libgit2_init(). - */ -void git_win32_leakcheck_stacktrace_init(void); - -/** - * Shutdown our memory leak tracking and dump summary data. - * This should ONLY be called by git_libgit2_shutdown(). - * - * We explicitly call _CrtDumpMemoryLeaks() during here so - * that we can compute summary data for the leaks. We print - * the stacktrace of each unique leak. - * - * This cleanup does not happen if the app calls exit() - * without calling the libgit2 shutdown code. - * - * This info we print here is independent of any automatic - * reporting during exit() caused by _CRTDBG_LEAK_CHECK_DF. - * Set it in your app if you also want traditional reporting. - */ -void git_win32_leakcheck_stacktrace_cleanup(void); - /** * Checkpoint options. */ From 51825c4f39af069d413fdb6cc661e53c4b63ad47 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 12 Jul 2020 18:18:12 +0100 Subject: [PATCH 0064/1616] alloc: rename the win32 leakcheck allocator The win32 leakchecking system is now named win32_leakcheck. Update the allocator to match. --- src/alloc.c | 4 +- src/allocators/win32_crtdbg.c | 118 ------------------ src/allocators/win32_leakcheck.c | 118 ++++++++++++++++++ .../{win32_crtdbg.h => win32_leakcheck.h} | 6 +- 4 files changed, 123 insertions(+), 123 deletions(-) delete mode 100644 src/allocators/win32_crtdbg.c create mode 100644 src/allocators/win32_leakcheck.c rename src/allocators/{win32_crtdbg.h => win32_leakcheck.h} (63%) diff --git a/src/alloc.c b/src/alloc.c index a5674c9b47a..291511d6284 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -9,14 +9,14 @@ #include "runtime.h" #include "allocators/stdalloc.h" -#include "allocators/win32_crtdbg.h" +#include "allocators/win32_leakcheck.h" git_allocator git__allocator; static int setup_default_allocator(void) { #if defined(GIT_MSVC_CRTDBG) - return git_win32_crtdbg_init_allocator(&git__allocator); + return git_win32_leakcheck_init_allocator(&git__allocator); #else return git_stdalloc_init_allocator(&git__allocator); #endif diff --git a/src/allocators/win32_crtdbg.c b/src/allocators/win32_crtdbg.c deleted file mode 100644 index c542b0c5441..00000000000 --- a/src/allocators/win32_crtdbg.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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 "win32_crtdbg.h" - -#if defined(GIT_MSVC_CRTDBG) - -#include "win32/w32_leakcheck.h" - -static void *crtdbg__malloc(size_t len, const char *file, int line) -{ - void *ptr = _malloc_dbg(len, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); - if (!ptr) git_error_set_oom(); - return ptr; -} - -static void *crtdbg__calloc(size_t nelem, size_t elsize, const char *file, int line) -{ - void *ptr = _calloc_dbg(nelem, elsize, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); - if (!ptr) git_error_set_oom(); - return ptr; -} - -static char *crtdbg__strdup(const char *str, const char *file, int line) -{ - char *ptr = _strdup_dbg(str, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); - if (!ptr) git_error_set_oom(); - return ptr; -} - -static char *crtdbg__strndup(const char *str, size_t n, const char *file, int line) -{ - size_t length = 0, alloclength; - char *ptr; - - length = p_strnlen(str, n); - - if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) || - !(ptr = crtdbg__malloc(alloclength, file, line))) - return NULL; - - if (length) - memcpy(ptr, str, length); - - ptr[length] = '\0'; - - return ptr; -} - -static char *crtdbg__substrdup(const char *start, size_t n, const char *file, int line) -{ - char *ptr; - size_t alloclen; - - if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) || - !(ptr = crtdbg__malloc(alloclen, file, line))) - return NULL; - - memcpy(ptr, start, n); - ptr[n] = '\0'; - return ptr; -} - -static void *crtdbg__realloc(void *ptr, size_t size, const char *file, int line) -{ - void *new_ptr = _realloc_dbg(ptr, size, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); - if (!new_ptr) git_error_set_oom(); - return new_ptr; -} - -static void *crtdbg__reallocarray(void *ptr, size_t nelem, size_t elsize, const char *file, int line) -{ - size_t newsize; - - if (GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize)) - return NULL; - - return crtdbg__realloc(ptr, newsize, file, line); -} - -static void *crtdbg__mallocarray(size_t nelem, size_t elsize, const char *file, int line) -{ - return crtdbg__reallocarray(NULL, nelem, elsize, file, line); -} - -static void crtdbg__free(void *ptr) -{ - free(ptr); -} - -int git_win32_crtdbg_init_allocator(git_allocator *allocator) -{ - allocator->gmalloc = crtdbg__malloc; - allocator->gcalloc = crtdbg__calloc; - allocator->gstrdup = crtdbg__strdup; - allocator->gstrndup = crtdbg__strndup; - allocator->gsubstrdup = crtdbg__substrdup; - allocator->grealloc = crtdbg__realloc; - allocator->greallocarray = crtdbg__reallocarray; - allocator->gmallocarray = crtdbg__mallocarray; - allocator->gfree = crtdbg__free; - return 0; -} - -#else - -int git_win32_crtdbg_init_allocator(git_allocator *allocator) -{ - GIT_UNUSED(allocator); - git_error_set(GIT_EINVALID, "crtdbg memory allocator not available"); - return -1; -} - -#endif diff --git a/src/allocators/win32_leakcheck.c b/src/allocators/win32_leakcheck.c new file mode 100644 index 00000000000..3be45cae60f --- /dev/null +++ b/src/allocators/win32_leakcheck.c @@ -0,0 +1,118 @@ +/* + * 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 "win32_leakcheck.h" + +#if defined(GIT_MSVC_CRTDBG) + +#include "win32/w32_leakcheck.h" + +static void *leakcheck_malloc(size_t len, const char *file, int line) +{ + void *ptr = _malloc_dbg(len, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); + if (!ptr) git_error_set_oom(); + return ptr; +} + +static void *leakcheck_calloc(size_t nelem, size_t elsize, const char *file, int line) +{ + void *ptr = _calloc_dbg(nelem, elsize, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); + if (!ptr) git_error_set_oom(); + return ptr; +} + +static char *leakcheck_strdup(const char *str, const char *file, int line) +{ + char *ptr = _strdup_dbg(str, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); + if (!ptr) git_error_set_oom(); + return ptr; +} + +static char *leakcheck_strndup(const char *str, size_t n, const char *file, int line) +{ + size_t length = 0, alloclength; + char *ptr; + + length = p_strnlen(str, n); + + if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) || + !(ptr = leakcheck_malloc(alloclength, file, line))) + return NULL; + + if (length) + memcpy(ptr, str, length); + + ptr[length] = '\0'; + + return ptr; +} + +static char *leakcheck_substrdup(const char *start, size_t n, const char *file, int line) +{ + char *ptr; + size_t alloclen; + + if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) || + !(ptr = leakcheck_malloc(alloclen, file, line))) + return NULL; + + memcpy(ptr, start, n); + ptr[n] = '\0'; + return ptr; +} + +static void *leakcheck_realloc(void *ptr, size_t size, const char *file, int line) +{ + void *new_ptr = _realloc_dbg(ptr, size, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line); + if (!new_ptr) git_error_set_oom(); + return new_ptr; +} + +static void *leakcheck_reallocarray(void *ptr, size_t nelem, size_t elsize, const char *file, int line) +{ + size_t newsize; + + if (GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize)) + return NULL; + + return leakcheck_realloc(ptr, newsize, file, line); +} + +static void *leakcheck_mallocarray(size_t nelem, size_t elsize, const char *file, int line) +{ + return leakcheck_reallocarray(NULL, nelem, elsize, file, line); +} + +static void leakcheck_free(void *ptr) +{ + free(ptr); +} + +int git_win32_leakcheck_init_allocator(git_allocator *allocator) +{ + allocator->gmalloc = leakcheck_malloc; + allocator->gcalloc = leakcheck_calloc; + allocator->gstrdup = leakcheck_strdup; + allocator->gstrndup = leakcheck_strndup; + allocator->gsubstrdup = leakcheck_substrdup; + allocator->grealloc = leakcheck_realloc; + allocator->greallocarray = leakcheck_reallocarray; + allocator->gmallocarray = leakcheck_mallocarray; + allocator->gfree = leakcheck_free; + return 0; +} + +#else + +int git_win32_leakcheck_init_allocator(git_allocator *allocator) +{ + GIT_UNUSED(allocator); + git_error_set(GIT_EINVALID, "leakcheck memory allocator not available"); + return -1; +} + +#endif diff --git a/src/allocators/win32_crtdbg.h b/src/allocators/win32_leakcheck.h similarity index 63% rename from src/allocators/win32_crtdbg.h rename to src/allocators/win32_leakcheck.h index 754c6b6fb5e..089690f90a2 100644 --- a/src/allocators/win32_crtdbg.h +++ b/src/allocators/win32_leakcheck.h @@ -5,13 +5,13 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#ifndef INCLUDE_allocators_crtdbg_h -#define INCLUDE_allocators_crtdbg_h +#ifndef INCLUDE_allocators_win32_leakcheck_h +#define INCLUDE_allocators_win32_leakcheck_h #include "common.h" #include "alloc.h" -int git_win32_crtdbg_init_allocator(git_allocator *allocator); +int git_win32_leakcheck_init_allocator(git_allocator *allocator); #endif From 8aed4629b13a5335c0d84792a61c303274f1e09c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 12 Jul 2020 18:43:22 +0100 Subject: [PATCH 0065/1616] cmake: rename MSVC_CRTDBG to WIN32_LEAKCHECK --- CMakeLists.txt | 8 ++++---- docs/changelog.md | 4 ++++ src/alloc.c | 2 +- src/allocators/win32_leakcheck.c | 2 +- src/features.h.in | 2 +- src/win32/w32_leakcheck.c | 2 +- src/win32/w32_leakcheck.h | 2 +- tests/clar_libgit2_trace.c | 4 ++-- tests/trace/windows/stacktrace.c | 10 +++++----- 9 files changed, 20 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b6f23cf6bf1..05ad1baec7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,8 +89,8 @@ IF(WIN32) ENDIF() IF(MSVC) - # Enable MSVC CRTDBG memory leak reporting when in debug mode. - OPTION(MSVC_CRTDBG "Enable CRTDBG memory leak reporting" OFF) + # Enable leak checking using the debugging C runtime. + OPTION(WIN32_LEAKCHECK "Enable leak reporting via crtdbg" OFF) ENDIF() IF (DEPRECATE_HARD) @@ -129,8 +129,8 @@ IF (MSVC) SET(CRT_FLAG_RELEASE "/MD") ENDIF() - IF (MSVC_CRTDBG) - SET(GIT_MSVC_CRTDBG 1) + IF (WIN32_LEAKCHECK) + SET(GIT_WIN32_LEAKCHECK 1) SET(CRT_FLAG_DEBUG "${CRT_FLAG_DEBUG}") SET(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} Dbghelp.lib") ENDIF() diff --git a/docs/changelog.md b/docs/changelog.md index 98bde2f6c46..edd2c3f42dc 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -13,6 +13,10 @@ vNext replaces `git_reference_is_valid_name`. Tthe former functions are deprecated. +### Breaking CMake configuration changes + +The `MVSC_CRTDBG` configuration option is now `WIN32_LEAKCHECK`. + v1.1 ---- diff --git a/src/alloc.c b/src/alloc.c index 291511d6284..6efa104cafe 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -15,7 +15,7 @@ git_allocator git__allocator; static int setup_default_allocator(void) { -#if defined(GIT_MSVC_CRTDBG) +#if defined(GIT_WIN32_LEAKCHECK) return git_win32_leakcheck_init_allocator(&git__allocator); #else return git_stdalloc_init_allocator(&git__allocator); diff --git a/src/allocators/win32_leakcheck.c b/src/allocators/win32_leakcheck.c index 3be45cae60f..fe06a14af73 100644 --- a/src/allocators/win32_leakcheck.c +++ b/src/allocators/win32_leakcheck.c @@ -7,7 +7,7 @@ #include "win32_leakcheck.h" -#if defined(GIT_MSVC_CRTDBG) +#if defined(GIT_WIN32_LEAKCHECK) #include "win32/w32_leakcheck.h" diff --git a/src/features.h.in b/src/features.h.in index e000de5e0c6..c8d01804f00 100644 --- a/src/features.h.in +++ b/src/features.h.in @@ -4,7 +4,7 @@ #cmakedefine GIT_DEBUG_POOL 1 #cmakedefine GIT_TRACE 1 #cmakedefine GIT_THREADS 1 -#cmakedefine GIT_MSVC_CRTDBG 1 +#cmakedefine GIT_WIN32_LEAKCHECK 1 #cmakedefine GIT_ARCH_64 1 #cmakedefine GIT_ARCH_32 1 diff --git a/src/win32/w32_leakcheck.c b/src/win32/w32_leakcheck.c index 31803d5974e..95187a570b6 100644 --- a/src/win32/w32_leakcheck.c +++ b/src/win32/w32_leakcheck.c @@ -7,7 +7,7 @@ #include "w32_leakcheck.h" -#if defined(GIT_MSVC_CRTDBG) +#if defined(GIT_WIN32_LEAKCHECK) #include "Windows.h" #include "Dbghelp.h" diff --git a/src/win32/w32_leakcheck.h b/src/win32/w32_leakcheck.h index 29bce4e89bd..7da03ab0ec2 100644 --- a/src/win32/w32_leakcheck.h +++ b/src/win32/w32_leakcheck.h @@ -13,7 +13,7 @@ /* Initialize the win32 leak checking system. */ int git_win32_leakcheck_global_init(void); -#if defined(GIT_MSVC_CRTDBG) +#if defined(GIT_WIN32_LEAKCHECK) #include #include diff --git a/tests/clar_libgit2_trace.c b/tests/clar_libgit2_trace.c index d4d8d2c37be..8eb6d4e8dd9 100644 --- a/tests/clar_libgit2_trace.c +++ b/tests/clar_libgit2_trace.c @@ -164,7 +164,7 @@ void _cl_trace_cb__event_handler( switch (ev) { case CL_TRACE__SUITE_BEGIN: git_trace(GIT_TRACE_TRACE, "\n\n%s\n%s: Begin Suite", HR, suite_name); -#if 0 && defined(GIT_MSVC_CRTDBG) +#if 0 && defined(GIT_WIN32_LEAKCHECK) git_win32__crtdbg_stacktrace__dump( GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK, suite_name); @@ -172,7 +172,7 @@ void _cl_trace_cb__event_handler( break; case CL_TRACE__SUITE_END: -#if 0 && defined(GIT_MSVC_CRTDBG) +#if 0 && defined(GIT_WIN32_LEAKCHECK) /* As an example of checkpointing, dump leaks within this suite. * This may generate false positives for things like the global * TLS error state and maybe the odb cache since they aren't diff --git a/tests/trace/windows/stacktrace.c b/tests/trace/windows/stacktrace.c index 15604a575bf..0a77ef99d21 100644 --- a/tests/trace/windows/stacktrace.c +++ b/tests/trace/windows/stacktrace.c @@ -1,7 +1,7 @@ #include "clar_libgit2.h" #include "win32/w32_leakcheck.h" -#if defined(GIT_MSVC_CRTDBG) +#if defined(GIT_WIN32_LEAKCHECK) static void a(void) { char buf[10000]; @@ -26,7 +26,7 @@ static void c(void) void test_trace_windows_stacktrace__basic(void) { -#if defined(GIT_MSVC_CRTDBG) +#if defined(GIT_WIN32_LEAKCHECK) c(); #endif } @@ -34,7 +34,7 @@ void test_trace_windows_stacktrace__basic(void) void test_trace_windows_stacktrace__leaks(void) { -#if defined(GIT_MSVC_CRTDBG) +#if defined(GIT_WIN32_LEAKCHECK) void * p1; void * p2; void * p3; @@ -124,7 +124,7 @@ void test_trace_windows_stacktrace__leaks(void) #endif } -#if defined(GIT_MSVC_CRTDBG) +#if defined(GIT_WIN32_LEAKCHECK) static void aux_cb_alloc__1(unsigned int *aux_id) { static unsigned int aux_counter = 0; @@ -141,7 +141,7 @@ static void aux_cb_lookup__1(unsigned int aux_id, char *aux_msg, size_t aux_msg_ void test_trace_windows_stacktrace__aux1(void) { -#if defined(GIT_MSVC_CRTDBG) +#if defined(GIT_WIN32_LEAKCHECK) git_win32_leakcheck_stack_set_aux_cb(aux_cb_alloc__1, aux_cb_lookup__1); c(); c(); From 6d44c87a3d00283751a7fcc68c62da9c69a5e1c6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 12 Jul 2020 18:44:50 +0100 Subject: [PATCH 0066/1616] ci: set WIN32_LEAKCHECK instead of MSVC_CRTDBG --- .github/workflows/main.yml | 4 ++-- azure-pipelines.yml | 4 ++-- azure-pipelines/nightly.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a36a0a0efc1..a76d39835a4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -124,7 +124,7 @@ jobs: env: ARCH: amd64 CMAKE_GENERATOR: Visual Studio 16 2019 - CMAKE_OPTIONS: -A x64 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON + CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - # Windows x86 Visual Studio @@ -132,7 +132,7 @@ jobs: env: ARCH: x86 CMAKE_GENERATOR: Visual Studio 16 2019 - CMAKE_OPTIONS: -A Win32 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON + CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - # Windows amd64 mingw diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f3690b8ecb2..d999bf5f9f0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -96,7 +96,7 @@ jobs: parameters: environmentVariables: CMAKE_GENERATOR: Visual Studio 15 2017 - CMAKE_OPTIONS: -A x64 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON + CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true @@ -109,7 +109,7 @@ jobs: parameters: environmentVariables: CMAKE_GENERATOR: Visual Studio 15 2017 - CMAKE_OPTIONS: -A Win32 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON + CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true diff --git a/azure-pipelines/nightly.yml b/azure-pipelines/nightly.yml index 97b44799553..9c148fe609d 100644 --- a/azure-pipelines/nightly.yml +++ b/azure-pipelines/nightly.yml @@ -92,7 +92,7 @@ jobs: parameters: environmentVariables: CMAKE_GENERATOR: Visual Studio 15 2017 - CMAKE_OPTIONS: -A x64 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON + CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON RUN_INVASIVE_TESTS: true SKIP_SSH_TESTS: true @@ -105,7 +105,7 @@ jobs: parameters: environmentVariables: CMAKE_GENERATOR: Visual Studio 15 2017 - CMAKE_OPTIONS: -A Win32 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS + CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS RUN_INVASIVE_TESTS: true SKIP_SSH_TESTS: true From c8fe4da3c575568c30665ecbd9dcbf33deadd88b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 21 Nov 2020 22:06:03 +0000 Subject: [PATCH 0067/1616] Apply suggestions from code review --- src/worktree.c | 2 +- tests/worktree/worktree.c | 1 + tests/worktree/worktree_helpers.c | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/worktree.c b/src/worktree.c index ea5a403c0ea..5b1e2794b94 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -262,7 +262,7 @@ int git_worktree_validate(const git_worktree *wt) if (!git_path_exists(wt->worktree_path)) { git_error_set(GIT_ERROR_WORKTREE, - "worktree directory ('%s') does not exist ", + "worktree directory '%s' does not exist", wt->worktree_path); return GIT_ERROR; } diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index 88bcaa97e6d..f2078a3f925 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -618,6 +618,7 @@ void test_worktree_worktree__validate_invalid_worktreedir(void) cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); p_rename("testrepo-worktree", "testrepo-worktree-tmp"); cl_git_fail(git_worktree_validate(wt)); + p_rename("testrepo-worktree-tmp", "testrepo-worktree"); git_worktree_free(wt); } diff --git a/tests/worktree/worktree_helpers.c b/tests/worktree/worktree_helpers.c index 8d78e16925b..6d4cdbaebab 100644 --- a/tests/worktree/worktree_helpers.c +++ b/tests/worktree/worktree_helpers.c @@ -19,7 +19,6 @@ void cleanup_fixture_worktree(worktree_fixture *fixture) cl_fixture_cleanup(fixture->reponame); if (fixture->worktreename) cl_fixture_cleanup(fixture->worktreename); - p_rename("testrepo-worktree-tmp", "testrepo-worktree"); } void setup_fixture_worktree(worktree_fixture *fixture) From 9f8802d3eaa9dc915c6dc77c517952a49d566100 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 23 Nov 2020 17:27:09 +0000 Subject: [PATCH 0068/1616] ci: add krb5 to bionic container --- ci/docker/bionic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/docker/bionic b/ci/docker/bionic index 5918584dc31..9ecb5da60b7 100644 --- a/ci/docker/bionic +++ b/ci/docker/bionic @@ -6,7 +6,9 @@ RUN apt-get update && \ curl \ gcc \ git \ + krb5-user \ libcurl4-openssl-dev \ + libkrb5-dev \ libpcre3-dev \ libssh2-1-dev \ libssl-dev \ From 5a9d16dceb213af734697e7f552a5b79b6e46893 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 23 Nov 2020 14:28:26 +0000 Subject: [PATCH 0069/1616] ci: support multi-arch docker builds Provide the base to our docker images and run with the QEMU docker support optionally. --- .github/workflows/coverity.yml | 2 +- .github/workflows/main.yml | 77 +++++++++++++++++++++++++--------- ci/docker/bionic | 3 +- ci/docker/docurium | 3 +- ci/docker/focal | 3 +- ci/docker/xenial | 3 +- ci/getcontainer.sh | 14 +++++-- 7 files changed, 77 insertions(+), 28 deletions(-) diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 99a4b151b87..a29030cbc10 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -20,7 +20,7 @@ jobs: with: fetch-depth: 0 - name: Download container - run: ci/getcontainer.sh ci/docker/xenial + run: ci/getcontainer.sh xenial env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 90fe4e0bb3a..091f51844fb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,10 +26,22 @@ jobs: strategy: matrix: container: - - xenial - - bionic - - focal - - docurium + - name: xenial + - name: bionic + - name: focal + - name: docurium + - name: bionic-x86 + dockerfile: bionic + base: multiarch/ubuntu-core:x86-bionic + qemu: true + - name: bionic-arm32 + dockerfile: bionic + base: multiarch/ubuntu-core:armhf-bionic + qemu: true + - name: bionic-arm64 + dockerfile: bionic + base: multiarch/ubuntu-core:arm64-bionic + qemu: true runs-on: ubuntu-latest steps: - name: Check out repository @@ -37,15 +49,23 @@ jobs: with: fetch-depth: 0 if: github.event_name == 'push' + - name: Setup QEMU + run: docker run --rm --privileged multiarch/qemu-user-static:register --reset + if: matrix.container.qemu == true - name: Download existing container - run: ci/getcontainer.sh ${{ env.docker-config-path }}/${{ matrix.container }} + run: | + "${{ github.workspace }}/ci/getcontainer.sh" "${{ matrix.container.name }}" "${{ matrix.container.dockerfile }}" env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} + working-directory: ${{ env.docker-config-path }} if: github.event_name == 'push' - name: Build and publish image run: | - docker build -t ${{ env.docker-registry-container-sha }} --build-arg BASE=${{ matrix.container.base }} -f ${{ matrix.container }} . + if [ "${{ matrix.container.base }}" != "" ]; then + BASE_ARG="--build-arg BASE=${{ matrix.container.base }}" + fi + docker build -t ${{ env.docker-registry-container-sha }} ${BASE_ARG} -f ${{ env.dockerfile }} . docker push ${{ env.docker-registry-container-sha }} working-directory: ${{ env.docker-config-path }} if: github.event_name == 'push' && env.docker-container-exists != 'true' @@ -55,40 +75,45 @@ jobs: # or on the actual hosts (macOS, Windows). build: name: Build - needs: [build_containers] + needs: [ build_containers ] strategy: matrix: platform: - # Xenial, GCC, OpenSSL - image: xenial + container: + name: xenial env: CC: gcc CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON os: ubuntu-latest - # Xenial, GCC, mbedTLS - image: xenial + container: + name: xenial env: CC: gcc CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON os: ubuntu-latest - # Xenial, Clang, OpenSSL - image: xenial + container: + name: xenial env: CC: clang CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON os: ubuntu-latest - # Xenial, Clang, mbedTLS - image: xenial + container: + name: xenial env: CC: clang CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest - # Focal, Clang 10, mbedTLS, MemorySanitizer - image: focal + container: + name: focal env: CC: clang-10 CFLAGS: -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer @@ -99,7 +124,8 @@ jobs: ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 os: ubuntu-latest - # Focal, Clang 10, OpenSSL, UndefinedBehaviorSanitizer - image: focal + container: + name: focal env: CC: clang-10 CFLAGS: -fsanitize=undefined,nullability -fno-sanitize-recover=undefined,nullability -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer @@ -110,7 +136,8 @@ jobs: ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 os: ubuntu-latest - # Focal, Clang 10, OpenSSL, ThreadSanitizer - image: focal + container: + name: focal env: CC: clang-10 CFLAGS: -fsanitize=thread -fno-optimize-sibling-calls -fno-omit-frame-pointer @@ -181,21 +208,26 @@ jobs: run: ci/setup-${{ matrix.platform.setup-script }}.sh shell: bash if: matrix.platform.setup-script != '' + - name: Setup QEMU + run: docker run --rm --privileged multiarch/qemu-user-static:register --reset + if: matrix.platform.container.qemu == true - name: Download container - run: ci/getcontainer.sh ${{ env.docker-config-path }}/${{ matrix.platform.image }} + run: | + "${{ github.workspace }}/ci/getcontainer.sh" "${{ matrix.platform.container.name }}" "${{ matrix.platform.container.dockerfile }}" env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} - if: matrix.platform.image != '' + working-directory: ${{ env.docker-config-path }} + if: matrix.platform.container.name != '' - name: Create container - run: docker build -t ${{ env.docker-registry-container-sha }} -f ${{ matrix.platform.image }} . + run: docker build -t ${{ env.docker-registry-container-sha }} -f ${{ env.dockerfile }} . working-directory: ${{ env.docker-config-path }} - if: matrix.platform.image != '' && env.docker-container-exists != 'true' + if: matrix.platform.container.name != '' && env.docker-container-exists != 'true' - name: Build and test run: | export GITTEST_NEGOTIATE_PASSWORD="${{ secrets.GITTEST_NEGOTIATE_PASSWORD }}" - if [ -n "${{ matrix.platform.image }}" ]; then + if [ -n "${{ matrix.platform.container.name }}" ]; then docker run \ --rm \ -v "$(pwd):/home/libgit2/source" \ @@ -229,6 +261,13 @@ jobs: needs: [build_containers] runs-on: ubuntu-latest steps: + - name: Setup defaults + run: | + if [ "${{ matrix.container.dockerfile }}" = "" ]; then + echo "dockerfile=${{ matrix.container.dockerfile }}" >> $GITHUB_ENV + else + echo "dockerfile=${{ matrix.container.dockerfile }}" >> $GITHUB_ENV + fi - name: Check out repository uses: actions/checkout@v2 with: diff --git a/ci/docker/bionic b/ci/docker/bionic index 9ecb5da60b7..85bb6ecae2a 100644 --- a/ci/docker/bionic +++ b/ci/docker/bionic @@ -1,4 +1,5 @@ -FROM ubuntu:bionic AS apt +ARG BASE=ubuntu:bionic +FROM ${BASE} AS apt RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ clang \ diff --git a/ci/docker/docurium b/ci/docker/docurium index 54a4202b6ba..7aa24753274 100644 --- a/ci/docker/docurium +++ b/ci/docker/docurium @@ -1,3 +1,4 @@ -FROM ubuntu:bionic +ARG BASE=ubuntu:bionic +FROM ${BASE} RUN apt update && apt install -y cmake pkg-config ruby ruby-dev llvm libclang-dev libssl-dev python-pygments RUN gem install docurium diff --git a/ci/docker/focal b/ci/docker/focal index c75e85a4cfe..c6fefc7870d 100644 --- a/ci/docker/focal +++ b/ci/docker/focal @@ -1,4 +1,5 @@ -FROM ubuntu:focal AS apt +ARG BASE=ubuntu:focal +FROM ${BASE} AS apt RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ bzip2 \ diff --git a/ci/docker/xenial b/ci/docker/xenial index 67867edc63e..1c8e585d26b 100644 --- a/ci/docker/xenial +++ b/ci/docker/xenial @@ -1,4 +1,5 @@ -FROM ubuntu:xenial AS apt +ARG BASE=ubuntu:xenial +FROM ${BASE} AS apt RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ bzip2 \ diff --git a/ci/getcontainer.sh b/ci/getcontainer.sh index b259260f4c8..07ef7b8ea7d 100755 --- a/ci/getcontainer.sh +++ b/ci/getcontainer.sh @@ -2,22 +2,28 @@ set -e -DOCKERFILE_PATH=$1 +IMAGE_NAME=$1 +DOCKERFILE_PATH=$2 -if [ "${DOCKERFILE_PATH}" = "" ]; then - echo "usage: $0 dockerfile" +if [ "${IMAGE_NAME}" = "" ]; then + echo "usage: $0 image_name [dockerfile]" exit 1 fi +if [ "${DOCKERFILE_PATH}" = "" ]; then + DOCKERFILE_PATH="${IMAGE_NAME}" +fi + if [ "${DOCKER_REGISTRY}" = "" ]; then echo "DOCKER_REGISTRY environment variable is unset." echo "Not running inside GitHub Actions or misconfigured?" exit 1 fi -DOCKER_CONTAINER="${GITHUB_REPOSITORY}/$(basename ${DOCKERFILE_PATH})" +DOCKER_CONTAINER="${GITHUB_REPOSITORY}/${IMAGE_NAME}" DOCKER_REGISTRY_CONTAINER="${DOCKER_REGISTRY}/${DOCKER_CONTAINER}" +echo "dockerfile=${DOCKERFILE_PATH}" >> $GITHUB_ENV echo "docker-container=${DOCKER_CONTAINER}" >> $GITHUB_ENV echo "docker-registry-container=${DOCKER_REGISTRY_CONTAINER}" >> $GITHUB_ENV From 508d9359d3f530f5acbe6889798dbabbb522a8a9 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 23 Nov 2020 21:53:20 +0000 Subject: [PATCH 0070/1616] ci: introduce arm nightly builds for GitHub Actions --- .github/workflows/nightly.yml | 107 +++++++++++++++++++++++++++------- 1 file changed, 86 insertions(+), 21 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index aae6c4c346c..7bafaa606c7 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -11,41 +11,49 @@ env: docker-config-path: ci/docker jobs: + # Run our nightly builds. We build a matrix with the various build + # targets and their details. Then we build either in a docker container + # (Linux) or on the actual hosts (macOS, Windows). build: name: Build strategy: matrix: platform: - # Xenial, GCC, OpenSSL - image: xenial + container: + name: xenial env: CC: gcc CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON os: ubuntu-latest - # Xenial, GCC, mbedTLS - image: xenial + container: + name: xenial env: CC: gcc CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON os: ubuntu-latest - # Xenial, Clang, OpenSSL - image: xenial + container: + name: xenial env: CC: clang CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON os: ubuntu-latest - # Xenial, Clang, mbedTLS - image: xenial + container: + name: xenial env: CC: clang CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest - # Focal, Clang 10, mbedTLS, MemorySanitizer - image: focal + container: + name: focal env: CC: clang-10 CFLAGS: -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer @@ -56,7 +64,8 @@ jobs: ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 os: ubuntu-latest - # Focal, Clang 10, OpenSSL, UndefinedBehaviorSanitizer - image: focal + container: + name: focal env: CC: clang-10 CFLAGS: -fsanitize=undefined,nullability -fno-sanitize-recover=undefined,nullability -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer @@ -66,11 +75,19 @@ jobs: SKIP_NEGOTIATE_TESTS: true ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 os: ubuntu-latest - - # linux arm64 - os: [ focal, arm64, self-hosted ] + - # Focal, Clang 10, OpenSSL, ThreadSanitizer + container: + name: focal env: - CC: gcc - CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CC: clang-10 + CFLAGS: -fsanitize=thread -fno-optimize-sibling-calls -fno-omit-frame-pointer + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON + CMAKE_GENERATOR: Ninja + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 + TSAN_OPTIONS: suppressions=/home/libgit2/source/script/thread-sanitizer.supp second_deadlock_stack=1 + os: ubuntu-latest - # macOS os: macos-10.15 env: @@ -86,7 +103,7 @@ jobs: env: ARCH: amd64 CMAKE_GENERATOR: Visual Studio 16 2019 - CMAKE_OPTIONS: -A x64 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON + CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - # Windows x86 Visual Studio @@ -94,7 +111,7 @@ jobs: env: ARCH: x86 CMAKE_GENERATOR: Visual Studio 16 2019 - CMAKE_OPTIONS: -A Win32 -DMSVC_CRTDBG=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON + CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - # Windows amd64 mingw @@ -119,9 +136,53 @@ jobs: BUILD_PATH: D:\Temp\mingw32\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true + - # Bionic, x86, Clang, OpenSSL + container: + name: bionic-x86 + dockerfile: bionic + qemu: true + env: + CC: clang + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + RUN_INVASIVE_TESTS: true + os: ubuntu-latest + - # Bionic, x86, GCC, OpenSSL + container: + name: bionic-x86 + dockerfile: bionic + env: + CC: gcc + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + RUN_INVASIVE_TESTS: true + os: ubuntu-latest + - # Bionic, arm32, GCC, OpenSSL + container: + name: bionic-arm32 + dockerfile: bionic + qemu: true + env: + CC: gcc + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_GSSAPI=ON + RUN_INVASIVE_TESTS: true + SKIP_PROXY_TESTS: true + os: ubuntu-latest + - # Bionic, arm64, GCC, OpenSSL + container: + name: bionic-arm64 + dockerfile: bionic + qemu: true + env: + CC: gcc + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_GSSAPI=ON + RUN_INVASIVE_TESTS: true + SKIP_PROXY_TESTS: true + os: ubuntu-latest fail-fast: false - env: - ACTIONS_RUNNER_TOKEN: ${{ secrets.ACTIONS_RUNNER_TOKEN }} + env: ${{ matrix.platform.env }} runs-on: ${{ matrix.platform.os }} steps: - name: Check out repository @@ -131,23 +192,27 @@ jobs: - name: Set up build environment run: ci/setup-${{ matrix.platform.setup-script }}.sh shell: bash - env: ${{ matrix.platform.env }} if: matrix.platform.setup-script != '' + - name: Setup QEMU + run: docker run --rm --privileged multiarch/qemu-user-static:register --reset + if: matrix.platform.container.qemu == true - name: Download container - run: ci/getcontainer.sh ${{ env.docker-config-path }}/${{ matrix.platform.image }} + run: | + "${{ github.workspace }}/ci/getcontainer.sh" "${{ matrix.platform.container.name }}" "${{ matrix.platform.container.dockerfile }}" env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} - if: matrix.platform.image != '' + working-directory: ${{ env.docker-config-path }} + if: matrix.platform.container.name != '' - name: Create container - run: docker build -t ${{ env.docker-registry-container-sha }} -f ${{ matrix.platform.image }} . + run: docker build -t ${{ env.docker-registry-container-sha }} -f ${{ env.dockerfile }} . working-directory: ${{ env.docker-config-path }} - if: matrix.platform.image != '' && env.docker-container-exists != 'true' + if: matrix.platform.container.name != '' && env.docker-container-exists != 'true' - name: Build and test run: | export GITTEST_NEGOTIATE_PASSWORD="${{ secrets.GITTEST_NEGOTIATE_PASSWORD }}" - if [ -n "${{ matrix.platform.image }}" ]; then + if [ -n "${{ matrix.platform.container.name }}" ]; then docker run \ --rm \ -v "$(pwd):/home/libgit2/source" \ @@ -161,6 +226,7 @@ jobs: -e PKG_CONFIG_PATH \ -e SKIP_NEGOTIATE_TESTS \ -e SKIP_SSH_TESTS \ + -e TSAN_OPTIONS \ ${{ env.docker-registry-container-sha }} \ /bin/bash -c "mkdir build && cd build && ../ci/build.sh && ../ci/test.sh" else @@ -168,5 +234,4 @@ jobs: ../ci/build.sh ../ci/test.sh fi - env: ${{ matrix.platform.env }} shell: bash From b6a39e39abfff6f4444f2b9f7b67f251ca8fe276 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 23 Nov 2020 23:10:39 +0000 Subject: [PATCH 0071/1616] ci: remove Azure Pipelines GitHub Actions is the present and the future. --- azure-pipelines.yml | 153 ------------------------ azure-pipelines/bash.yml | 17 --- azure-pipelines/coverity.yml | 26 ----- azure-pipelines/docker.yml | 51 -------- azure-pipelines/nightly.yml | 219 ----------------------------------- 5 files changed, 466 deletions(-) delete mode 100644 azure-pipelines.yml delete mode 100644 azure-pipelines/bash.yml delete mode 100644 azure-pipelines/coverity.yml delete mode 100644 azure-pipelines/docker.yml delete mode 100644 azure-pipelines/nightly.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index d999bf5f9f0..00000000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,153 +0,0 @@ -resources: -- repo: self - -trigger: -- master -- maint/* - -jobs: -- job: linux_amd64_xenial_gcc_openssl - displayName: 'Linux (amd64; Xenial; GCC; OpenSSL)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: azure-pipelines/docker.yml - parameters: - docker: - image: xenial - base: ubuntu:xenial - environmentVariables: | - CC=gcc - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON - GITTEST_NEGOTIATE_PASSWORD=${{ variables.GITTEST_NEGOTIATE_PASSWORD }} - -- job: linux_amd64_xenial_gcc_mbedtls - displayName: 'Linux (amd64; Xenial; GCC; mbedTLS)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: azure-pipelines/docker.yml - parameters: - docker: - image: xenial - base: ubuntu:xenial - environmentVariables: | - CC=gcc - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON - GITTEST_NEGOTIATE_PASSWORD=${{ variables.GITTEST_NEGOTIATE_PASSWORD }} - -- job: linux_amd64_xenial_clang_openssl - displayName: 'Linux (amd64; Xenial; Clang; OpenSSL)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: azure-pipelines/docker.yml - parameters: - docker: - image: xenial - base: ubuntu:xenial - environmentVariables: | - CC=clang - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON - GITTEST_NEGOTIATE_PASSWORD=${{ variables.GITTEST_NEGOTIATE_PASSWORD }} - -- job: linux_amd64_xenial_clang_mbedtls - displayName: 'Linux (amd64; Xenial; Clang; mbedTLS)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: azure-pipelines/docker.yml - parameters: - docker: - image: xenial - base: ubuntu:xenial - environmentVariables: | - CC=clang - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON - GITTEST_NEGOTIATE_PASSWORD=${{ variables.GITTEST_NEGOTIATE_PASSWORD }} - -- job: macos - displayName: 'macOS (amd64; 10.15)' - pool: - vmImage: 'macOS-10.15' - steps: - - bash: . '$(Build.SourcesDirectory)/azure-pipelines/setup-osx.sh' - displayName: Setup - - template: azure-pipelines/bash.yml - parameters: - environmentVariables: - TMPDIR: $(Agent.TempDirectory) - PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig - CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON - SKIP_SSH_TESTS: true - GITTEST_NEGOTIATE_PASSWORD: ${{ variables.GITTEST_NEGOTIATE_PASSWORD }} - -- job: windows_vs_amd64 - displayName: 'Windows (amd64; Visual Studio)' - pool: - vmImage: 'vs2017-win2016' - steps: - - template: azure-pipelines/bash.yml - parameters: - environmentVariables: - CMAKE_GENERATOR: Visual Studio 15 2017 - CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON - SKIP_SSH_TESTS: true - SKIP_NEGOTIATE_TESTS: true - -- job: windows_vs_x86 - displayName: 'Windows (x86; Visual Studio)' - pool: - vmImage: 'vs2017-win2016' - steps: - - template: azure-pipelines/bash.yml - parameters: - environmentVariables: - CMAKE_GENERATOR: Visual Studio 15 2017 - CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON - SKIP_SSH_TESTS: true - SKIP_NEGOTIATE_TESTS: true - -- job: windows_mingw_amd64 - displayName: 'Windows (amd64; MinGW)' - pool: - vmImage: 'vs2017-win2016' - steps: - - bash: . '$(Build.SourcesDirectory)\azure-pipelines\setup-mingw.sh' - displayName: Setup - env: - TEMP: $(Agent.TempDirectory) - ARCH: amd64 - - template: azure-pipelines/bash.yml - parameters: - environmentVariables: - BUILD_PATH: $(Agent.TempDirectory)\mingw64\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin - CMAKE_GENERATOR: MinGW Makefiles - CMAKE_OPTIONS: -DDEPRECATE_HARD=ON - SKIP_SSH_TESTS: true - SKIP_NEGOTIATE_TESTS: true - -- job: windows_mingw_x86 - displayName: 'Windows (x86; MinGW)' - pool: - vmImage: 'vs2017-win2016' - steps: - - bash: . '$(Build.SourcesDirectory)\azure-pipelines\setup-mingw.sh' - displayName: Setup - workingDirectory: '$(Build.BinariesDirectory)' - env: - TEMP: $(Agent.TempDirectory) - ARCH: x86 - - template: azure-pipelines/bash.yml - parameters: - environmentVariables: - BUILD_PATH: $(Agent.TempDirectory)\mingw32\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin - CMAKE_GENERATOR: MinGW Makefiles - CMAKE_OPTIONS: -DDEPRECATE_HARD=ON - SKIP_SSH_TESTS: true - SKIP_NEGOTIATE_TESTS: true diff --git a/azure-pipelines/bash.yml b/azure-pipelines/bash.yml deleted file mode 100644 index d776a364996..00000000000 --- a/azure-pipelines/bash.yml +++ /dev/null @@ -1,17 +0,0 @@ -# These are the steps used for building on machines with bash. -steps: -- bash: . '$(Build.SourcesDirectory)/ci/build.sh' - displayName: Build - workingDirectory: '$(Build.BinariesDirectory)' - env: ${{ parameters.environmentVariables }} -- bash: . '$(Build.SourcesDirectory)/ci/test.sh' - displayName: Test - workingDirectory: '$(Build.BinariesDirectory)' - env: ${{ parameters.environmentVariables }} -- task: PublishTestResults@2 - displayName: Publish Test Results - condition: succeededOrFailed() - inputs: - testResultsFiles: 'results_*.xml' - searchFolder: '$(Build.BinariesDirectory)' - mergeTestResults: true diff --git a/azure-pipelines/coverity.yml b/azure-pipelines/coverity.yml deleted file mode 100644 index 466f43693fa..00000000000 --- a/azure-pipelines/coverity.yml +++ /dev/null @@ -1,26 +0,0 @@ -resources: -- repo: self - -jobs: -- job: coverity - displayName: 'Coverity' - pool: - vmImage: 'ubuntu-18.04' - steps: - - script: | - cd $(Build.SourcesDirectory)/ci/docker - docker build -t libgit2/xenial --build-arg BASE=ubuntu:xenial -f xenial . - displayName: 'Build Docker image' - - task: Docker@0 - displayName: Analyze - inputs: - action: 'Run an image' - imageName: libgit2/xenial - volumes: | - $(Build.SourcesDirectory):/home/libgit2/source - $(Build.BinariesDirectory):/home/libgit2/build - envVars: | - COVERITY_TOKEN=$(COVERITY_TOKEN) - workDir: '/home/libgit2/build' - containerCommand: '/home/libgit2/source/ci/coverity.sh' - detached: false diff --git a/azure-pipelines/docker.yml b/azure-pipelines/docker.yml deleted file mode 100644 index 5bb58ee75f9..00000000000 --- a/azure-pipelines/docker.yml +++ /dev/null @@ -1,51 +0,0 @@ -# These are the steps used in a container-based build in VSTS. -steps: -- ${{ if eq(parameters.qemu, 'true') }}: - - script: docker run --rm --privileged multiarch/qemu-user-static:register --reset - displayName: 'Register Docker QEMU' - -- task: cache@2 - displayName: Cache Docker layers - inputs: - key: docker - path: /tmp/dockercache -- script: | - if [ -f /tmp/dockercache/${{parameters.docker.image}}.tar ]; then docker load < /tmp/dockercache/${{parameters.docker.image}}.tar; fi - displayName: 'Load Docker cache' -- script: | - cd $(Build.SourcesDirectory)/ci/docker && - docker build -t libgit2/${{parameters.docker.image}} --build-arg BASE=${{parameters.docker.base}} -f ${{parameters.docker.image}} . && - if [ ! -d /tmp/dockercache ]; then mkdir /tmp/dockercache; fi && - docker save libgit2/${{parameters.docker.image}} $(docker history -q libgit2/${{parameters.docker.image}} | grep -v '') > /tmp/dockercache/${{parameters.docker.image}}.tar - displayName: 'Build Docker image' -- task: docker@0 - displayName: Build - inputs: - action: 'Run an image' - imageName: libgit2/${{ parameters.docker.image }} - volumes: | - $(Build.SourcesDirectory):/home/libgit2/source - $(Build.BinariesDirectory):/home/libgit2/build - envVars: ${{ parameters.environmentVariables }} - workDir: '/home/libgit2/build' - containerCommand: '/home/libgit2/source/ci/build.sh' - detached: false -- task: docker@0 - displayName: Test - inputs: - action: 'Run an image' - imageName: libgit2/${{ parameters.docker.image }} - volumes: | - $(Build.SourcesDirectory):/home/libgit2/source - $(Build.BinariesDirectory):/home/libgit2/build - envVars: ${{ parameters.environmentVariables }} - workDir: '/home/libgit2/build' - containerCommand: '/home/libgit2/source/ci/test.sh' - detached: false -- task: publishtestresults@2 - displayName: Publish Test Results - condition: succeededOrFailed() - inputs: - testResultsFiles: 'results_*.xml' - searchFolder: '$(Build.BinariesDirectory)' - mergeTestResults: true diff --git a/azure-pipelines/nightly.yml b/azure-pipelines/nightly.yml deleted file mode 100644 index 9c148fe609d..00000000000 --- a/azure-pipelines/nightly.yml +++ /dev/null @@ -1,219 +0,0 @@ -resources: -- repo: self - -jobs: -- job: linux_amd64_xenial_gcc_openssl - displayName: 'Linux (amd64; Xenial; GCC; OpenSSL)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: docker.yml - parameters: - docker: - image: xenial - base: ubuntu:xenial - environmentVariables: | - CC=gcc - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind - RUN_INVASIVE_TESTS=true - -- job: linux_amd64_xenial_gcc_mbedtls - displayName: 'Linux (amd64; Xenial; GCC; mbedTLS)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: docker.yml - parameters: - docker: - image: xenial - base: ubuntu:xenial - environmentVariables: | - CC=gcc - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind - RUN_INVASIVE_TESTS=true - -- job: linux_amd64_xenial_clang_openssl - displayName: 'Linux (amd64; Xenial; Clang; OpenSSL)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: docker.yml - parameters: - docker: - image: xenial - base: ubuntu:xenial - environmentVariables: | - CC=clang - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind - RUN_INVASIVE_TESTS=true - -- job: linux_amd64_xenial_clang_mbedtls - displayName: 'Linux (amd64; Xenial; Clang; mbedTLS)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: docker.yml - parameters: - docker: - image: xenial - base: ubuntu:xenial - environmentVariables: | - CC=clang - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind - RUN_INVASIVE_TESTS=true - -- job: macos - displayName: 'macOS (amd64; 10.15)' - pool: - vmImage: 'macOS-10.15' - steps: - - bash: . '$(Build.SourcesDirectory)/ci/setup-osx.sh' - displayName: Setup - - template: bash.yml - parameters: - environmentVariables: - TMPDIR: $(Agent.TempDirectory) - PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig - CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON - RUN_INVASIVE_TESTS: true - SKIP_SSH_TESTS: true - -- job: windows_vs_amd64 - displayName: 'Windows (amd64; Visual Studio)' - pool: - vmImage: 'vs2017-win2016' - steps: - - template: bash.yml - parameters: - environmentVariables: - CMAKE_GENERATOR: Visual Studio 15 2017 - CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON - RUN_INVASIVE_TESTS: true - SKIP_SSH_TESTS: true - -- job: windows_vs_x86 - displayName: 'Windows (x86; Visual Studio)' - pool: - vmImage: 'vs2017-win2016' - steps: - - template: bash.yml - parameters: - environmentVariables: - CMAKE_GENERATOR: Visual Studio 15 2017 - CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS - RUN_INVASIVE_TESTS: true - SKIP_SSH_TESTS: true - -- job: windows_mingw_amd64 - displayName: 'Windows (amd64; MinGW)' - pool: - vmImage: 'vs2017-win2016' - steps: - - bash: . '$(Build.SourcesDirectory)\ci\setup-mingw.sh' - displayName: Setup - env: - TEMP: $(Agent.TempDirectory) - ARCH: amd64 - - template: bash.yml - parameters: - environmentVariables: - BUILD_PATH: $(Agent.TempDirectory)\mingw64\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin - CMAKE_GENERATOR: MinGW Makefiles - CMAKE_OPTIONS: -DDEPRECATE_HARD=ON - RUN_INVASIVE_TESTS: true - SKIP_SSH_TESTS: true - -- job: windows_mingw_x86 - displayName: 'Windows (x86; MinGW)' - pool: - vmImage: 'vs2017-win2016' - steps: - - bash: . '$(Build.SourcesDirectory)\ci\setup-mingw.sh' - displayName: Setup - workingDirectory: '$(Build.BinariesDirectory)' - env: - TEMP: $(Agent.TempDirectory) - ARCH: x86 - - template: bash.yml - parameters: - environmentVariables: - BUILD_PATH: $(Agent.TempDirectory)\mingw32\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin - CMAKE_GENERATOR: MinGW Makefiles - CMAKE_OPTIONS: -DDEPRECATE_HARD=ON - RUN_INVASIVE_TESTS: true - SKIP_SSH_TESTS: true - -- job: linux_x86_bionic_gcc_openssl - displayName: 'Linux (x86; Bionic; GCC; OpenSSL)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: docker.yml - parameters: - qemu: 'true' - docker: - image: bionic - base: multiarch/ubuntu-core:x86-bionic - environmentVariables: | - CC=gcc - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind - RUN_INVASIVE_TESTS=true - -- job: linux_x86_bionic_clang_openssl - displayName: 'Linux (x86; Bionic; Clang; OpenSSL)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: docker.yml - parameters: - qemu: 'true' - docker: - image: bionic - base: multiarch/ubuntu-core:x86-bionic - environmentVariables: | - CC=clang - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind - RUN_INVASIVE_TESTS=true - -- job: linux_arm32_bionic_gcc_openssl - displayName: 'Linux (arm32; Bionic; GCC; OpenSSL)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: docker.yml - parameters: - qemu: 'true' - docker: - image: bionic - base: multiarch/ubuntu-core:armhf-bionic - environmentVariables: | - CC=gcc - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON - RUN_INVASIVE_TESTS=true - SKIP_PROXY_TESTS=true - -- job: linux_arm64_bionic_gcc_openssl - displayName: 'Linux (arm64; Bionic; GCC; OpenSSL)' - pool: - vmImage: 'ubuntu-18.04' - steps: - - template: docker.yml - parameters: - qemu: 'true' - docker: - image: bionic - base: multiarch/ubuntu-core:arm64-bionic - environmentVariables: | - CC=gcc - CMAKE_GENERATOR=Ninja - CMAKE_OPTIONS=-DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON - RUN_INVASIVE_TESTS=true - SKIP_PROXY_TESTS=true From d9e62bdd85c25a671f6a2954c06bb372b492e374 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 23 Nov 2020 23:40:46 +0000 Subject: [PATCH 0072/1616] ci: move coverity into nightly builds --- .github/workflows/coverity.yml | 30 ------------------------------ .github/workflows/nightly.yml | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 30 deletions(-) delete mode 100644 .github/workflows/coverity.yml diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml deleted file mode 100644 index a29030cbc10..00000000000 --- a/.github/workflows/coverity.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Nightly build for the master branch running coverity. -name: Coverity Build - -on: - workflow_dispatch: - schedule: - - cron: '15 2 * * *' - -env: - docker-registry: docker.pkg.github.com - docker-config-path: ci/docker - -jobs: - build: - name: Coverity - runs-on: ubuntu-latest - steps: - - name: Check out repository - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Download container - run: ci/getcontainer.sh xenial - env: - DOCKER_REGISTRY: ${{ env.docker-registry }} - GITHUB_TOKEN: ${{ secrets.github_token }} - - name: Run Coverity - run: ci/coverity.sh - env: - COVERITY_TOKEN: ${{ secrets.coverity_token }} diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 7bafaa606c7..58ea98d927a 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -235,3 +235,21 @@ jobs: ../ci/test.sh fi shell: bash + + coverity: + name: Coverity + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Download container + run: ci/getcontainer.sh ci/docker/xenial + env: + DOCKER_REGISTRY: ${{ env.docker-registry }} + GITHUB_TOKEN: ${{ secrets.github_token }} + - name: Run Coverity + run: ci/coverity.sh + env: + COVERITY_TOKEN: ${{ secrets.coverity_token }} From f811cec9d436d91bd94216b0109da6905478a473 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 23 Nov 2020 23:38:50 +0000 Subject: [PATCH 0073/1616] docs: update README with updated build links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a91f16067cc..e00a543b5dd 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,10 @@ libgit2 - the Git linkable library | Build Status | | | ------------ | - | -| **master** branch CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=master)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=master) | +| **master** branch CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22) | | **v1.0 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v1.0)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v1.0) | | **v0.28 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v0.28)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v0.28) | -| **Nightly** builds | [![Azure Pipelines Build Status](https://libgit2.visualstudio.com/libgit2/_apis/build/status/nightly?branchName=master&label=Full+Build)](https://libgit2.visualstudio.com/libgit2/_build/latest?definitionId=9&branchName=master) [![Coverity Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/coverity?branchName=master&label=Coverity+Build)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=21?branchName=master) [![Coverity Scan Build Status](https://scan.coverity.com/projects/639/badge.svg)](https://scan.coverity.com/projects/639) | +| **Nightly** builds | [![Nightly Build](https://github.com/libgit2/libgit2/workflows/Nightly%20Build/badge.svg)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22Nightly+Build%22) [![Coverity Scan Status](https://scan.coverity.com/projects/639/badge.svg)](https://scan.coverity.com/projects/639) | `libgit2` is a portable, pure C implementation of the Git core methods provided as a linkable library with a solid API, allowing to build Git From 8b29f66b447390fa11a8bfaac5a8231cd3085ddb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Nov 2020 00:01:32 +0000 Subject: [PATCH 0074/1616] ci: only report main branch in README status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e00a543b5dd..b66d190d72c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ libgit2 - the Git linkable library | Build Status | | | ------------ | - | -| **master** branch CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22) | +| **master** branch CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush) | | **v1.0 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v1.0)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v1.0) | | **v0.28 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v0.28)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v0.28) | | **Nightly** builds | [![Nightly Build](https://github.com/libgit2/libgit2/workflows/Nightly%20Build/badge.svg)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22Nightly+Build%22) [![Coverity Scan Status](https://scan.coverity.com/projects/639/badge.svg)](https://scan.coverity.com/projects/639) | From 78436df033be18b564629230d2398f7bab08437e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Nov 2020 00:26:15 +0000 Subject: [PATCH 0075/1616] ci: correct container usage for coverity --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 58ea98d927a..68c7fdb58c4 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -245,7 +245,7 @@ jobs: with: fetch-depth: 0 - name: Download container - run: ci/getcontainer.sh ci/docker/xenial + run: ci/getcontainer.sh xenial env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} From 05536454489a3d4a85b07d6cef71841b8f4ab4a8 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Nov 2020 00:54:39 +0000 Subject: [PATCH 0076/1616] ci: really correct container usage for coverity --- .github/workflows/nightly.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 68c7fdb58c4..65ab8be8ced 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -249,6 +249,7 @@ jobs: env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} + working-directory: ${{ env.docker-config-path }} - name: Run Coverity run: ci/coverity.sh env: From bcf11f6a947c9922b533d41f699c05474dc21bf2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Nov 2020 08:49:38 +0000 Subject: [PATCH 0077/1616] ci: really, really correct usage for coverity --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 65ab8be8ced..f60d6ab5b0a 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -245,7 +245,7 @@ jobs: with: fetch-depth: 0 - name: Download container - run: ci/getcontainer.sh xenial + run: ${{ github.workspace }}/ci/getcontainer.sh" xenial env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} From ab3c7ba540cef001d4aaaf81599e807f10c92791 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Nov 2020 09:20:53 +0000 Subject: [PATCH 0078/1616] ci: really truly run coverity --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index f60d6ab5b0a..ef747c54811 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -245,7 +245,7 @@ jobs: with: fetch-depth: 0 - name: Download container - run: ${{ github.workspace }}/ci/getcontainer.sh" xenial + run: "${{ github.workspace }}/ci/getcontainer.sh" xenial env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} From b8cdc9c9c59c61fc699550af5245c57744c1bcbd Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Nov 2020 09:27:41 +0000 Subject: [PATCH 0079/1616] ci: truly really absolutely run coverity --- .github/workflows/nightly.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index ef747c54811..11b184ee21c 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -245,7 +245,8 @@ jobs: with: fetch-depth: 0 - name: Download container - run: "${{ github.workspace }}/ci/getcontainer.sh" xenial + run: | + "${{ github.workspace }}/ci/getcontainer.sh" xenial env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} From f60ebfcb6b66b317ced1acca463e729cc182b83d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 4 Apr 2020 23:31:05 +0100 Subject: [PATCH 0080/1616] annotated_commit: use GIT_ASSERT --- src/annotated_commit.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/annotated_commit.c b/src/annotated_commit.c index 5d4f3708206..e489476796f 100644 --- a/src/annotated_commit.c +++ b/src/annotated_commit.c @@ -26,7 +26,8 @@ static int annotated_commit_init( git_annotated_commit *annotated_commit; int error = 0; - assert(out && commit); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(commit); *out = NULL; @@ -63,7 +64,9 @@ static int annotated_commit_init_from_id( git_commit *commit = NULL; int error = 0; - assert(out && repo && id); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(id); *out = NULL; @@ -100,7 +103,9 @@ int git_annotated_commit_from_revspec( git_object *obj, *commit; int error; - assert(out && repo && revspec); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(revspec); if ((error = git_revparse_single(&obj, repo, revspec)) < 0) return error; @@ -126,7 +131,9 @@ int git_annotated_commit_from_ref( git_object *peeled; int error = 0; - assert(out && repo && ref); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(ref); *out = NULL; @@ -154,11 +161,12 @@ int git_annotated_commit_from_head( git_reference *head; int error; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); *out = NULL; - if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0) + if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0) return -1; error = git_annotated_commit_from_ref(out, repo, head); @@ -174,7 +182,11 @@ int git_annotated_commit_from_fetchhead( const char *remote_url, const git_oid *id) { - assert(repo && id && branch_name && remote_url); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(branch_name); + GIT_ASSERT_ARG(remote_url); + GIT_ASSERT_ARG(id); if (annotated_commit_init_from_id(out, repo, id, branch_name) < 0) return -1; @@ -192,14 +204,14 @@ int git_annotated_commit_from_fetchhead( const git_oid *git_annotated_commit_id( const git_annotated_commit *annotated_commit) { - assert(annotated_commit); + GIT_ASSERT_ARG_WITH_RETVAL(annotated_commit, NULL); return git_commit_id(annotated_commit->commit); } const char *git_annotated_commit_ref( const git_annotated_commit *annotated_commit) { - assert(annotated_commit); + GIT_ASSERT_ARG_WITH_RETVAL(annotated_commit, NULL); return annotated_commit->ref_name; } From c6e84bce059a72b9a4922ec9777c3a35164a360c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 09:49:28 +0100 Subject: [PATCH 0081/1616] apply: use GIT_ASSERT --- src/apply.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/apply.c b/src/apply.c index b0be2d8e663..7c65cd79db6 100644 --- a/src/apply.c +++ b/src/apply.c @@ -5,8 +5,6 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "apply.h" - #include "git2/apply.h" #include "git2/patch.h" #include "git2/filter.h" @@ -21,6 +19,7 @@ #include "zstream.h" #include "reader.h" #include "index.h" +#include "apply.h" typedef struct { /* The lines that we allocate ourself are allocated out of the pool. @@ -399,7 +398,11 @@ int git_apply__patch( unsigned int mode = 0; int error = 0; - assert(contents_out && filename_out && mode_out && (source || !source_len) && patch); + GIT_ASSERT_ARG(contents_out); + GIT_ASSERT_ARG(filename_out); + GIT_ASSERT_ARG(mode_out); + GIT_ASSERT_ARG(source || !source_len); + GIT_ASSERT_ARG(patch); if (given_opts) memcpy(&ctx.opts, given_opts, sizeof(git_apply_options)); @@ -624,7 +627,10 @@ int git_apply_to_tree( size_t i; int error = 0; - assert(out && repo && preimage && diff); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(preimage); + GIT_ASSERT_ARG(diff); *out = NULL; @@ -772,6 +778,8 @@ static int git_apply__to_index( int git_apply_options_init(git_apply_options *opts, unsigned int version) { + GIT_ASSERT_ARG(opts); + GIT_INIT_STRUCTURE_FROM_TEMPLATE( opts, version, git_apply_options, GIT_APPLY_OPTIONS_INIT); return 0; @@ -805,7 +813,8 @@ int git_apply( git_apply_options opts = GIT_APPLY_OPTIONS_INIT; int error = GIT_EINVALID; - assert(repo && diff); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(diff); GIT_ERROR_CHECK_VERSION( given_opts, GIT_APPLY_OPTIONS_VERSION, "git_apply_options"); @@ -829,7 +838,7 @@ int git_apply( error = git_reader_for_workdir(&pre_reader, repo, false); break; default: - assert(false); + GIT_ASSERT(false); } if (error < 0) @@ -869,7 +878,7 @@ int git_apply( error = git_apply__to_workdir(repo, diff, preimage, postimage, location, &opts); break; default: - assert(false); + GIT_ASSERT(false); } if (error < 0) From 7b2f94bf9452bd11e9f5eb395905479f3f6de0d4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 10:04:52 +0100 Subject: [PATCH 0082/1616] attr: use GIT_ASSERT --- src/attr.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/attr.c b/src/attr.c index bd517cde3ae..e85e2716295 100644 --- a/src/attr.c +++ b/src/attr.c @@ -58,7 +58,9 @@ int git_attr_get( git_attr_rule *rule; git_dir_flag dir_flag = GIT_DIR_FLAG_UNKNOWN; - assert(value && repo && name); + GIT_ASSERT_ARG(value); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); *value = NULL; @@ -123,7 +125,10 @@ int git_attr_get_many_with_session( if (!num_attr) return 0; - assert(values && repo && names); + GIT_ASSERT_ARG(values); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(pathname); + GIT_ASSERT_ARG(names); if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; @@ -206,7 +211,8 @@ int git_attr_foreach( git_strmap *seen = NULL; git_dir_flag dir_flag = GIT_DIR_FLAG_UNKNOWN; - assert(repo && callback); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(callback); if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; @@ -378,6 +384,9 @@ int git_attr_add_macro( git_attr_rule *macro = NULL; git_pool *pool; + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); + if ((error = git_attr_cache__init(repo)) < 0) return error; From b44b262bef2c284608c4043450e4d7c270d76778 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 10:07:09 +0100 Subject: [PATCH 0083/1616] attr_file: use GIT_ASSERT --- src/attr_file.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/attr_file.c b/src/attr_file.c index 3f69b5ffcb3..0781c1d61c1 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -351,7 +351,9 @@ uint32_t git_attr_file__name_hash(const char *name) { uint32_t h = 5381; int c; - assert(name); + + GIT_ASSERT_ARG(name); + while ((c = (int)*name++) != 0) h = ((h << 5) + h) + c; return h; @@ -660,7 +662,8 @@ int git_attr_fnmatch__parse( int slash_count, allow_space; bool escaped; - assert(spec && base && *base); + GIT_ASSERT_ARG(spec); + GIT_ASSERT_ARG(base && *base); if (parse_optimized_patterns(spec, pool, *base)) return 0; @@ -828,7 +831,7 @@ int git_attr_assignment__parse( const char *scan = *base; git_attr_assignment *assign = NULL; - assert(assigns && !assigns->length); + GIT_ASSERT_ARG(assigns && !assigns->length); git_vector_set_cmp(assigns, sort_by_hash_and_name); @@ -954,7 +957,7 @@ void git_attr_rule__free(git_attr_rule *rule) int git_attr_session__init(git_attr_session *session, git_repository *repo) { - assert(repo); + GIT_ASSERT_ARG(repo); memset(session, 0, sizeof(*session)); session->key = git_atomic_inc(&repo->attr_session_key); From efab78cdabcec2c8c72d498ef75e1367d0074601 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 10:09:11 +0100 Subject: [PATCH 0084/1616] blame: use GIT_ASSERT --- src/blame.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/blame.c b/src/blame.c index 1046dab55e2..651b7a0035d 100644 --- a/src/blame.c +++ b/src/blame.c @@ -171,20 +171,21 @@ void git_blame_free(git_blame *blame) uint32_t git_blame_get_hunk_count(git_blame *blame) { - assert(blame); + GIT_ASSERT_ARG(blame); return (uint32_t)blame->hunks.length; } const git_blame_hunk *git_blame_get_hunk_byindex(git_blame *blame, uint32_t index) { - assert(blame); + GIT_ASSERT_ARG_WITH_RETVAL(blame, NULL); return (git_blame_hunk*)git_vector_get(&blame->hunks, index); } const git_blame_hunk *git_blame_get_hunk_byline(git_blame *blame, size_t lineno) { size_t i, new_lineno = lineno; - assert(blame); + + GIT_ASSERT_ARG_WITH_RETVAL(blame, NULL); if (!git_vector_bsearch2(&i, &blame->hunks, hunk_byfinalline_search_cmp, &new_lineno)) { return git_blame_get_hunk_byindex(blame, (uint32_t)i); @@ -388,7 +389,10 @@ int git_blame_file( git_blame_options normOptions = GIT_BLAME_OPTIONS_INIT; git_blame *blame = NULL; - assert(out && repo && path); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(path); + if ((error = normalize_options(&normOptions, options, repo)) < 0) goto on_error; @@ -509,7 +513,9 @@ int git_blame_buffer( diffopts.context_lines = 0; - assert(out && reference && buffer && buffer_len); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(reference); + GIT_ASSERT_ARG(buffer && buffer_len); blame = git_blame__alloc(reference->repository, reference->options, reference->path); GIT_ERROR_CHECK_ALLOC(blame); From abb7a7e44add2a6837a5d84182618fcfcaee8fb7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 10:11:34 +0100 Subject: [PATCH 0085/1616] blob: use GIT_ASSERT --- include/git2/blob.h | 2 +- src/blob.c | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/include/git2/blob.h b/include/git2/blob.h index 7e2a745d1cf..8e977267dd5 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -84,7 +84,7 @@ GIT_EXTERN(git_repository *) git_blob_owner(const git_blob *blob); * time. * * @param blob pointer to the blob - * @return the pointer + * @return the pointer, or NULL on error */ GIT_EXTERN(const void *) git_blob_rawcontent(const git_blob *blob); diff --git a/src/blob.c b/src/blob.c index da4e6ffa544..392a1fe07c7 100644 --- a/src/blob.c +++ b/src/blob.c @@ -18,7 +18,8 @@ const void *git_blob_rawcontent(const git_blob *blob) { - assert(blob); + GIT_ASSERT_ARG_WITH_RETVAL(blob, NULL); + if (blob->raw) return blob->data.raw.data; else @@ -27,7 +28,8 @@ const void *git_blob_rawcontent(const git_blob *blob) git_object_size_t git_blob_rawsize(const git_blob *blob) { - assert(blob); + GIT_ASSERT_ARG(blob); + if (blob->raw) return blob->data.raw.size; else @@ -53,7 +55,9 @@ void git_blob__free(void *_blob) int git_blob__parse_raw(void *_blob, const char *data, size_t size) { git_blob *blob = (git_blob *) _blob; - assert(blob); + + GIT_ASSERT_ARG(blob); + blob->raw = 1; blob->data.raw.data = data; blob->data.raw.size = size; @@ -63,7 +67,9 @@ int git_blob__parse_raw(void *_blob, const char *data, size_t size) int git_blob__parse(void *_blob, git_odb_object *odb_obj) { git_blob *blob = (git_blob *) _blob; - assert(blob); + + GIT_ASSERT_ARG(blob); + git_cached_obj_incref((git_cached_obj *)odb_obj); blob->raw = 0; blob->data.odb = odb_obj; @@ -77,7 +83,8 @@ int git_blob_create_from_buffer( git_odb *odb; git_odb_stream *stream; - assert(id && repo); + GIT_ASSERT_ARG(id); + GIT_ASSERT_ARG(repo); if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 || (error = git_odb_open_wstream(&stream, odb, len, GIT_OBJECT_BLOB)) < 0) @@ -188,7 +195,7 @@ int git_blob__create_from_paths( mode_t mode; git_buf path = GIT_BUF_INIT; - assert(hint_path || !try_load_filters); + GIT_ASSERT_ARG(hint_path || !try_load_filters); if (!content_path) { if (git_repository__ensure_not_bare(repo, "create blob from file") < 0) @@ -331,7 +338,8 @@ int git_blob_create_from_stream(git_writestream **out, git_repository *repo, con git_buf path = GIT_BUF_INIT; blob_writestream *stream; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); stream = git__calloc(1, sizeof(blob_writestream)); GIT_ERROR_CHECK_ALLOC(stream); @@ -391,7 +399,7 @@ int git_blob_is_binary(const git_blob *blob) git_buf content = GIT_BUF_INIT; git_object_size_t size; - assert(blob); + GIT_ASSERT_ARG(blob); size = git_blob_rawsize(blob); @@ -411,7 +419,9 @@ int git_blob_filter( git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT; git_filter_flag_t flags = GIT_FILTER_DEFAULT; - assert(blob && path && out); + GIT_ASSERT_ARG(blob); + GIT_ASSERT_ARG(path); + GIT_ASSERT_ARG(out); git_buf_sanitize(out); From 7d24070d7a8b5e6d0a37b6b874d9000cd4e388bc Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 10:14:28 +0100 Subject: [PATCH 0086/1616] branch: use GIT_ASSERT --- src/branch.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/branch.c b/src/branch.c index 000a63ad888..08fd95d5851 100644 --- a/src/branch.c +++ b/src/branch.c @@ -67,8 +67,10 @@ static int create_branch( int error = -1; int bare = git_repository_is_bare(repository); - assert(branch_name && commit && ref_out); - assert(git_object_owner((const git_object *)commit) == repository); + GIT_ASSERT_ARG(branch_name); + GIT_ASSERT_ARG(commit); + GIT_ASSERT_ARG(ref_out); + GIT_ASSERT_ARG(git_commit_owner(commit) == repository); if (!git__strcmp(branch_name, "HEAD")) { git_error_set(GIT_ERROR_REFERENCE, "'HEAD' is not a valid branch name"); @@ -161,6 +163,8 @@ static int branch_is_checked_out(git_repository *worktree, void *payload) int git_branch_is_checked_out(const git_reference *branch) { + GIT_ASSERT_ARG(branch); + if (!git_reference_is_branch(branch)) return 0; return git_repository_foreach_worktree(git_reference_owner(branch), @@ -173,7 +177,7 @@ int git_branch_delete(git_reference *branch) git_buf config_section = GIT_BUF_INIT; int error = -1; - assert(branch); + GIT_ASSERT_ARG(branch); if (!git_reference_is_branch(branch) && !git_reference_is_remote(branch)) { git_error_set(GIT_ERROR_INVALID, "reference '%s' is not a valid branch.", @@ -288,7 +292,8 @@ int git_branch_move( log_message = GIT_BUF_INIT; int error; - assert(branch && new_branch_name); + GIT_ASSERT_ARG(branch); + GIT_ASSERT_ARG(new_branch_name); if (!git_reference_is_branch(branch)) return not_a_local_branch(git_reference_name(branch)); @@ -333,7 +338,10 @@ int git_branch_lookup( git_branch_t branch_type) { int error = -1; - assert(ref_out && repo && branch_name); + + GIT_ASSERT_ARG(ref_out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(branch_name); switch (branch_type) { case GIT_BRANCH_LOCAL: @@ -346,7 +354,7 @@ int git_branch_lookup( error = retrieve_branch_reference(ref_out, repo, branch_name, true); break; default: - assert(false); + GIT_ASSERT(false); } return error; } @@ -357,7 +365,8 @@ int git_branch_name( { const char *branch_name; - assert(out && ref); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(ref); branch_name = ref->name; @@ -405,7 +414,8 @@ int git_branch_upstream_name( const git_refspec *refspec; git_config *config; - assert(out && refname); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(refname); git_buf_sanitize(out); @@ -491,7 +501,9 @@ int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refna int error = 0; char *remote_name = NULL; - assert(buf && repo && refname); + GIT_ASSERT_ARG(buf); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(refname); git_buf_sanitize(buf); @@ -702,7 +714,7 @@ int git_branch_is_head( bool is_same = false; int error; - assert(branch); + GIT_ASSERT_ARG(branch); if (!git_reference_is_branch(branch)) return false; From a6dd58659d16207ec92a1f4d87ec620236ce4a23 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 10:23:20 +0100 Subject: [PATCH 0087/1616] buffer: use GIT_ASSERT --- src/buf_text.c | 4 ++-- src/buffer.c | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/buf_text.c b/src/buf_text.c index 88fcb87dd8f..0fd22319f0b 100644 --- a/src/buf_text.c +++ b/src/buf_text.c @@ -69,7 +69,7 @@ int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src) size_t new_size; char *out; - assert(tgt != src); + GIT_ASSERT(tgt != src); if (!next) return git_buf_set(tgt, src->ptr, src->size); @@ -116,7 +116,7 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src) const char *next = memchr(scan, '\n', src->size); size_t alloclen; - assert(tgt != src); + GIT_ASSERT(tgt != src); if (!next) return git_buf_set(tgt, src->ptr, src->size); diff --git a/src/buffer.c b/src/buffer.c index c203650c752..f395a77cc02 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -225,7 +225,7 @@ int git_buf_put(git_buf *buf, const char *data, size_t len) if (len) { size_t new_size; - assert(data); + GIT_ASSERT_ARG(data); GIT_ERROR_CHECK_ALLOC_ADD(&new_size, buf->size, len); GIT_ERROR_CHECK_ALLOC_ADD(&new_size, new_size, 1); @@ -239,7 +239,8 @@ int git_buf_put(git_buf *buf, const char *data, size_t len) int git_buf_puts(git_buf *buf, const char *string) { - assert(string); + GIT_ASSERT_ARG(string); + return git_buf_put(buf, string, strlen(string)); } @@ -319,7 +320,7 @@ int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len) return -1; } - assert(len % 4 == 0); + GIT_ASSERT_ARG(len % 4 == 0); GIT_ERROR_CHECK_ALLOC_ADD(&new_size, (len / 4 * 3), buf->size); GIT_ERROR_CHECK_ALLOC_ADD(&new_size, new_size, 1); ENSURE_SIZE(buf, new_size); @@ -760,7 +761,7 @@ int git_buf_join( /* not safe to have str_b point internally to the buffer */ if (buf->size) - assert(str_b < buf->ptr || str_b >= buf->ptr + buf->size); + GIT_ASSERT_ARG(str_b < buf->ptr || str_b >= buf->ptr + buf->size); /* figure out if we need to insert a separator */ if (separator && strlen_a) { @@ -810,9 +811,9 @@ int git_buf_join3( char *tgt; /* for this function, disallow pointers into the existing buffer */ - assert(str_a < buf->ptr || str_a >= buf->ptr + buf->size); - assert(str_b < buf->ptr || str_b >= buf->ptr + buf->size); - assert(str_c < buf->ptr || str_c >= buf->ptr + buf->size); + GIT_ASSERT(str_a < buf->ptr || str_a >= buf->ptr + buf->size); + GIT_ASSERT(str_b < buf->ptr || str_b >= buf->ptr + buf->size); + GIT_ASSERT(str_c < buf->ptr || str_c >= buf->ptr + buf->size); if (separator) { if (len_a > 0) { @@ -885,7 +886,9 @@ int git_buf_splice( char *splice_loc; size_t new_size, alloc_size; - assert(buf && where <= buf->size && nb_to_remove <= buf->size - where); + GIT_ASSERT(buf); + GIT_ASSERT(where <= buf->size); + GIT_ASSERT(nb_to_remove <= buf->size - where); splice_loc = buf->ptr + where; From cb4bfbc99dffa7679f42cf8500931fa250bb7db3 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 11:07:54 +0100 Subject: [PATCH 0088/1616] buffer: git_buf_sanitize should return a value `git_buf_sanitize` is called with user-input, and wants to sanity-check that input. Allow it to return a value if the input was malformed in a way that we cannot cope. --- src/blob.c | 5 +++-- src/branch.c | 11 +++++----- src/buffer.c | 10 ++++++--- src/buffer.h | 2 +- src/config.c | 30 +++++++++++++++++++++------ src/describe.c | 3 ++- src/diff_print.c | 13 ++++++++++-- src/filter.c | 12 +++++++---- src/libgit2.c | 51 ++++++++++++++++++++++++++-------------------- src/message.c | 4 +++- src/notes.c | 5 ++--- src/object.c | 4 +++- src/pack-objects.c | 7 ++++++- src/refspec.c | 17 +++++++++++++--- src/remote.c | 10 ++++++--- src/repository.c | 7 +++++-- src/submodule.c | 3 ++- 17 files changed, 133 insertions(+), 61 deletions(-) diff --git a/src/blob.c b/src/blob.c index 392a1fe07c7..97069645c8b 100644 --- a/src/blob.c +++ b/src/blob.c @@ -423,11 +423,12 @@ int git_blob_filter( GIT_ASSERT_ARG(path); GIT_ASSERT_ARG(out); - git_buf_sanitize(out); - GIT_ERROR_CHECK_VERSION( given_opts, GIT_BLOB_FILTER_OPTIONS_VERSION, "git_blob_filter_options"); + if (git_buf_sanitize(out) < 0) + return -1; + if (given_opts != NULL) memcpy(&opts, given_opts, sizeof(git_blob_filter_options)); diff --git a/src/branch.c b/src/branch.c index 08fd95d5851..29ff0b9d99d 100644 --- a/src/branch.c +++ b/src/branch.c @@ -417,7 +417,8 @@ int git_branch_upstream_name( GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(refname); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; if (!git_reference__is_branch(refname)) return not_a_local_branch(refname); @@ -478,9 +479,8 @@ int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *r if ((error = git_repository_config__weakptr(&cfg, repo)) < 0) return error; - git_buf_sanitize(buf); - - if ((error = retrieve_upstream_configuration(buf, cfg, refname, "branch.%s.remote")) < 0) + if ((error = git_buf_sanitize(buf)) < 0 || + (error = retrieve_upstream_configuration(buf, cfg, refname, "branch.%s.remote")) < 0) return error; if (git_buf_len(buf) == 0) { @@ -505,7 +505,8 @@ int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refna GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(refname); - git_buf_sanitize(buf); + if ((error = git_buf_sanitize(buf)) < 0) + return error; /* Verify that this is a remote branch */ if (!git_reference__is_remote(refname)) { diff --git a/src/buffer.c b/src/buffer.c index f395a77cc02..2928b17674d 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -140,13 +140,17 @@ void git_buf_free(git_buf *buf) } #endif -void git_buf_sanitize(git_buf *buf) +int git_buf_sanitize(git_buf *buf) { if (buf->ptr == NULL) { - assert(buf->size == 0 && buf->asize == 0); + GIT_ASSERT_ARG(buf->size == 0 && buf->asize == 0); + buf->ptr = git_buf__initbuf; - } else if (buf->asize > buf->size) + } else if (buf->asize > buf->size) { buf->ptr[buf->size] = '\0'; + } + + return 0; } void git_buf_clear(git_buf *buf) diff --git a/src/buffer.h b/src/buffer.h index 6b717d2e90c..6257b435b25 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -69,7 +69,7 @@ extern int git_buf_try_grow( * git_buf__initbuf. If a buffer with a non-NULL ptr is passed in, this method * assures that the buffer is '\0'-terminated. */ -extern void git_buf_sanitize(git_buf *buf); +extern int git_buf_sanitize(git_buf *buf); extern void git_buf_swap(git_buf *buf_a, git_buf *buf_b); extern char *git_buf_detach(git_buf *buf); diff --git a/src/config.c b/src/config.c index 42f46e6cf12..b3e7324a1ce 100644 --- a/src/config.c +++ b/src/config.c @@ -886,7 +886,8 @@ int git_config_get_string_buf( int ret; const char *str; - git_buf_sanitize(out); + if ((ret = git_buf_sanitize(out)) < 0) + return ret; ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS); str = !ret ? (entry->value ? entry->value : "") : NULL; @@ -1084,19 +1085,31 @@ void git_config_iterator_free(git_config_iterator *iter) int git_config_find_global(git_buf *path) { - git_buf_sanitize(path); + int error; + + if ((error = git_buf_sanitize(path)) < 0) + return error; + return git_sysdir_find_global_file(path, GIT_CONFIG_FILENAME_GLOBAL); } int git_config_find_xdg(git_buf *path) { - git_buf_sanitize(path); + int error; + + if ((error = git_buf_sanitize(path)) < 0) + return error; + return git_sysdir_find_xdg_file(path, GIT_CONFIG_FILENAME_XDG); } int git_config_find_system(git_buf *path) { - git_buf_sanitize(path); + int error; + + if ((error = git_buf_sanitize(path)) < 0) + return error; + return git_sysdir_find_system_file(path, GIT_CONFIG_FILENAME_SYSTEM); } @@ -1104,7 +1117,9 @@ int git_config_find_programdata(git_buf *path) { int ret; - git_buf_sanitize(path); + if ((ret = git_buf_sanitize(path)) < 0) + return ret; + ret = git_sysdir_find_programdata_file(path, GIT_CONFIG_FILENAME_PROGRAMDATA); if (ret != GIT_OK) @@ -1360,9 +1375,12 @@ int git_config_parse_int32(int32_t *out, const char *value) int git_config_parse_path(git_buf *out, const char *value) { + int error; + assert(out && value); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; if (value[0] == '~') { if (value[1] != '\0' && value[1] != '/') { diff --git a/src/describe.c b/src/describe.c index 8beffdebaa6..ebf70b062eb 100644 --- a/src/describe.c +++ b/src/describe.c @@ -780,7 +780,8 @@ int git_describe_format(git_buf *out, const git_describe_result *result, const g GIT_ERROR_CHECK_VERSION(given, GIT_DESCRIBE_FORMAT_OPTIONS_VERSION, "git_describe_format_options"); normalize_format_options(&opts, given); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; if (opts.always_use_long_format && opts.abbreviated_size == 0) { diff --git a/src/diff_print.c b/src/diff_print.c index 9ce04d70e35..0e93fe8933f 100644 --- a/src/diff_print.c +++ b/src/diff_print.c @@ -764,8 +764,12 @@ int git_diff_print_callback__to_file_handle( /* print a git_diff to a git_buf */ int git_diff_to_buf(git_buf *out, git_diff *diff, git_diff_format_t format) { + int error; + assert(out && diff); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; + return git_diff_print(diff, format, git_diff_print_callback__to_buf, out); } @@ -799,7 +803,12 @@ int git_patch_print( /* print a git_patch to a git_buf */ int git_patch_to_buf(git_buf *out, git_patch *patch) { + int error; + assert(out && patch); - git_buf_sanitize(out); + + if ((error = git_buf_sanitize(out)) < 0) + return error; + return git_patch_print(patch, git_diff_print_callback__to_buf, out); } diff --git a/src/filter.c b/src/filter.c index 86db5a5e370..ae9220c9b79 100644 --- a/src/filter.c +++ b/src/filter.c @@ -725,8 +725,9 @@ int git_filter_list_apply_to_data( struct buf_stream writer; int error; - git_buf_sanitize(tgt); - git_buf_sanitize(src); + if ((error = git_buf_sanitize(tgt)) < 0 || + (error = git_buf_sanitize(src)) < 0) + return error; if (!filters) { git_buf_attach_notowned(tgt, src->ptr, src->size); @@ -832,7 +833,9 @@ static int proxy_stream_close(git_writestream *s) if (error == GIT_PASSTHROUGH) { writebuf = &proxy_stream->input; } else if (error == 0) { - git_buf_sanitize(proxy_stream->output); + if ((error = git_buf_sanitize(proxy_stream->output)) < 0) + return error; + writebuf = proxy_stream->output; } else { /* close stream before erroring out taking care @@ -1004,7 +1007,8 @@ int git_filter_list_stream_data( git_writestream *stream_start; int error, initialized = 0; - git_buf_sanitize(data); + if ((error = git_buf_sanitize(data)) < 0) + return error; if ((error = stream_list_init(&stream_start, &filter_streams, filters, target)) < 0) goto out; diff --git a/src/libgit2.c b/src/libgit2.c index 07414bec826..9e5112dbf2a 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -122,29 +122,28 @@ int git_libgit2_features(void) ; } -static int config_level_to_sysdir(int config_level) +static int config_level_to_sysdir(int *out, int config_level) { - int val = -1; - switch (config_level) { case GIT_CONFIG_LEVEL_SYSTEM: - val = GIT_SYSDIR_SYSTEM; - break; + *out = GIT_SYSDIR_SYSTEM; + return 0; case GIT_CONFIG_LEVEL_XDG: - val = GIT_SYSDIR_XDG; - break; + *out = GIT_SYSDIR_XDG; + return 0; case GIT_CONFIG_LEVEL_GLOBAL: - val = GIT_SYSDIR_GLOBAL; - break; + *out = GIT_SYSDIR_GLOBAL; + return 0; case GIT_CONFIG_LEVEL_PROGRAMDATA: - val = GIT_SYSDIR_PROGRAMDATA; - break; + *out = GIT_SYSDIR_PROGRAMDATA; + return 0; default: - git_error_set( - GIT_ERROR_INVALID, "invalid config path selector %d", config_level); + break; } - return val; + git_error_set( + GIT_ERROR_INVALID, "invalid config path selector %d", config_level); + return -1; } const char *git_libgit2__user_agent(void) @@ -190,12 +189,15 @@ int git_libgit2_opts(int key, ...) break; case GIT_OPT_GET_SEARCH_PATH: - if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0) { + { + int sysdir = va_arg(ap, int); git_buf *out = va_arg(ap, git_buf *); const git_buf *tmp; + int level; - git_buf_sanitize(out); - if ((error = git_sysdir_get(&tmp, error)) < 0) + if ((error = config_level_to_sysdir(&level, sysdir)) < 0 || + (error = git_buf_sanitize(out)) < 0 || + (error = git_sysdir_get(&tmp, level)) < 0) break; error = git_buf_sets(out, tmp->ptr); @@ -203,8 +205,12 @@ int git_libgit2_opts(int key, ...) break; case GIT_OPT_SET_SEARCH_PATH: - if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0) - error = git_sysdir_set(error, va_arg(ap, const char *)); + { + int level; + + if ((error = config_level_to_sysdir(&level, va_arg(ap, int))) >= 0) + error = git_sysdir_set(level, va_arg(ap, const char *)); + } break; case GIT_OPT_SET_CACHE_OBJECT_LIMIT: @@ -233,8 +239,8 @@ int git_libgit2_opts(int key, ...) git_buf *out = va_arg(ap, git_buf *); const git_buf *tmp; - git_buf_sanitize(out); - if ((error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0) + if ((error = git_buf_sanitize(out)) < 0 || + (error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0) break; error = git_buf_sets(out, tmp->ptr); @@ -303,7 +309,8 @@ int git_libgit2_opts(int key, ...) case GIT_OPT_GET_USER_AGENT: { git_buf *out = va_arg(ap, git_buf *); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + break; error = git_buf_sets(out, git__user_agent); } break; diff --git a/src/message.c b/src/message.c index 6c5a2379fc8..327b984fc7c 100644 --- a/src/message.c +++ b/src/message.c @@ -28,8 +28,10 @@ int git_message_prettify(git_buf *message_out, const char *message, int strip_co int consecutive_empty_lines = 0; size_t i, line_length, rtrimmed_line_length; char *next_newline; + int error; - git_buf_sanitize(message_out); + if ((error = git_buf_sanitize(message_out)) < 0) + return error; for (i = 0; i < strlen(message); i += line_length) { next_newline = memchr(message + i, '\n', message_len - i); diff --git a/src/notes.c b/src/notes.c index 68d2ae9ec62..a3c4b7c4fea 100644 --- a/src/notes.c +++ b/src/notes.c @@ -629,9 +629,8 @@ int git_note_default_ref(git_buf *out, git_repository *repo) assert(out && repo); - git_buf_sanitize(out); - - if ((error = note_get_default_ref(&default_ref, repo)) < 0) + if ((error = git_buf_sanitize(out)) < 0 || + (error = note_get_default_ref(&default_ref, repo)) < 0) return error; git_buf_attach(out, default_ref, strlen(default_ref)); diff --git a/src/object.c b/src/object.c index 749b0caf242..fa975347e11 100644 --- a/src/object.c +++ b/src/object.c @@ -495,7 +495,9 @@ int git_object_short_id(git_buf *out, const git_object *obj) assert(out && obj); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; + repo = git_object_owner(obj); if ((error = git_repository__configmap_lookup(&len, repo, GIT_CONFIGMAP_ABBREV)) < 0) diff --git a/src/pack-objects.c b/src/pack-objects.c index cf10e6cb5a6..9679e8e23f9 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -1363,8 +1363,13 @@ int git_packbuilder_foreach(git_packbuilder *pb, int (*cb)(void *buf, size_t siz int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb) { + int error; + + if ((error = git_buf_sanitize(buf)) < 0) + return error; + PREPARE_PACK; - git_buf_sanitize(buf); + return write_pack(pb, &write_pack_buf, buf); } diff --git a/src/refspec.c b/src/refspec.c index 4245cbbdad7..a778f62b465 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -245,8 +245,11 @@ static int refspec_transform( { const char *from_star, *to_star; size_t replacement_len, star_offset; + int error; + + if ((error = git_buf_sanitize(out)) < 0) + return error; - git_buf_sanitize(out); git_buf_clear(out); /* @@ -278,8 +281,12 @@ static int refspec_transform( int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name) { + int error; + assert(out && spec && name); - git_buf_sanitize(out); + + if ((error = git_buf_sanitize(out)) < 0) + return error; if (!git_refspec_src_matches(spec, name)) { git_error_set(GIT_ERROR_INVALID, "ref '%s' doesn't match the source", name); @@ -294,8 +301,12 @@ int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *nam int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name) { + int error; + assert(out && spec && name); - git_buf_sanitize(out); + + if ((error = git_buf_sanitize(out)) < 0) + return error; if (!git_refspec_dst_matches(spec, name)) { git_error_set(GIT_ERROR_INVALID, "ref '%s' doesn't match the destination", name); diff --git a/src/remote.c b/src/remote.c index f6382486174..a12fa00ba96 100644 --- a/src/remote.c +++ b/src/remote.c @@ -648,14 +648,17 @@ int git_remote_set_pushurl(git_repository *repo, const char *remote, const char* static int resolve_url(git_buf *resolved_url, const char *url, int direction, const git_remote_callbacks *callbacks) { - int status; + int status, error; if (callbacks && callbacks->resolve_url) { git_buf_clear(resolved_url); status = callbacks->resolve_url(resolved_url, url, direction, callbacks->payload); if (status != GIT_PASSTHROUGH) { git_error_set_after_callback_function(status, "git_resolve_url_cb"); - git_buf_sanitize(resolved_url); + + if ((error = git_buf_sanitize(resolved_url)) < 0) + return error; + return status; } } @@ -2403,7 +2406,8 @@ int git_remote_default_branch(git_buf *out, git_remote *remote) goto done; } - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; /* the first one must be HEAD so if that has the symref info, we're done */ if (heads[0]->symref_target) { diff --git a/src/repository.c b/src/repository.c index f0d4b06aac1..28cbf3c6c4d 100644 --- a/src/repository.c +++ b/src/repository.c @@ -945,10 +945,12 @@ int git_repository_discover( const char *ceiling_dirs) { uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0; + int error; assert(start_path); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; return find_repo(out, NULL, NULL, NULL, start_path, flags, ceiling_dirs); } @@ -2609,7 +2611,8 @@ int git_repository_message(git_buf *out, git_repository *repo) struct stat st; int error; - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0) return -1; diff --git a/src/submodule.c b/src/submodule.c index c32b9770a9a..8fb3bdb73d9 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -998,7 +998,8 @@ int git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *ur assert(out && repo && url); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; /* We do this in all platforms in case someone on Windows created the .gitmodules */ if (strchr(url, '\\')) { From e0f3c33d5a505f5341300351c2fcc493929a932f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 11:22:19 +0100 Subject: [PATCH 0089/1616] buffer: git_buf_copy_cstr should return a value `git_buf_copy_cstr` is called with user-input, and wants to sanity-check that input. Allow it to return a value if the input was malformed in a way that we cannot cope. --- src/buffer.c | 10 +++++++--- src/buffer.h | 2 +- src/refs.c | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index 2928b17674d..f6ecc6e4147 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -556,22 +556,26 @@ int git_buf_printf(git_buf *buf, const char *format, ...) return r; } -void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf) +int git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf) { size_t copylen; - assert(data && datasize && buf); + GIT_ASSERT_ARG(data); + GIT_ASSERT_ARG(datasize); + GIT_ASSERT_ARG(buf); data[0] = '\0'; if (buf->size == 0 || buf->asize <= 0) - return; + return 0; copylen = buf->size; if (copylen > datasize - 1) copylen = datasize - 1; memmove(data, buf->ptr, copylen); data[copylen] = '\0'; + + return 0; } void git_buf_consume_bytes(git_buf *buf, size_t len) diff --git a/src/buffer.h b/src/buffer.h index 6257b435b25..8c2096bcee9 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -145,7 +145,7 @@ GIT_INLINE(size_t) git_buf_len(const git_buf *buf) return buf->size; } -void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf); +int git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf); #define git_buf_PUTS(buf, str) git_buf_put(buf, str, sizeof(str) - 1) diff --git a/src/refs.c b/src/refs.c index 497b066d2be..71594d73b3b 100644 --- a/src/refs.c +++ b/src/refs.c @@ -1024,7 +1024,8 @@ int git_reference_normalize_name( goto cleanup; } - git_buf_copy_cstr(buffer_out, buffer_size, &buf); + if ((error = git_buf_copy_cstr(buffer_out, buffer_size, &buf)) < 0) + goto cleanup; error = 0; From 266f26ed92f2970d9efcfa0006d01f06c3403fcb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 14:35:23 +0100 Subject: [PATCH 0090/1616] checkout: use GIT_ASSERT --- src/checkout.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/checkout.c b/src/checkout.c index 94a2cb9fac0..65487993b74 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -1243,7 +1243,7 @@ static int checkout_conflict_append_remove( checkout_data *data = payload; const char *name; - assert(ancestor || ours || theirs); + GIT_ASSERT_ARG(ancestor || ours || theirs); if (ancestor) name = git__strdup(ancestor->path); @@ -1487,7 +1487,9 @@ static int checkout_stream_write( static int checkout_stream_close(git_writestream *s) { struct checkout_stream *stream = (struct checkout_stream *)s; - assert(stream && stream->open); + + GIT_ASSERT_ARG(stream); + GIT_ASSERT_ARG(stream->open); stream->open = 0; return p_close(stream->fd); @@ -1554,7 +1556,7 @@ static int blob_content_to_file( error = git_filter_list_stream_blob(fl, blob, &writer.base); - assert(writer.open == 0); + GIT_ASSERT(writer.open == 0); git_filter_list_free(fl); @@ -1976,7 +1978,7 @@ static int checkout_write_entry( struct stat st; int error; - assert (side == conflict->ours || side == conflict->theirs); + GIT_ASSERT(side == conflict->ours || side == conflict->theirs); if (checkout_target_fullpath(&fullpath, data, side->path) < 0) return -1; @@ -2588,7 +2590,7 @@ int git_checkout_iterator( } /* Should not have case insensitivity mismatch */ - assert(git_iterator_ignore_case(workdir) == git_iterator_ignore_case(baseline)); + GIT_ASSERT(git_iterator_ignore_case(workdir) == git_iterator_ignore_case(baseline)); /* Generate baseline-to-target diff which will include an entry for * every possible update that might need to be made. @@ -2639,7 +2641,7 @@ int git_checkout_iterator( (error = checkout_extensions_update_index(&data)) < 0) goto cleanup; - assert(data.completed_steps == data.total_steps); + GIT_ASSERT(data.completed_steps == data.total_steps); if (data.opts.perfdata_cb) data.opts.perfdata_cb(&data.perfdata, data.opts.perfdata_payload); @@ -2767,7 +2769,8 @@ int git_checkout_head( git_repository *repo, const git_checkout_options *opts) { - assert(repo); + GIT_ASSERT_ARG(repo); + return git_checkout_tree(repo, NULL, opts); } From 5d8b75fa9bcdc66de1a4fa6689479078eccd2bb8 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 14:37:22 +0100 Subject: [PATCH 0091/1616] cherrypick: use GIT_ASSERT --- src/cherrypick.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cherrypick.c b/src/cherrypick.c index 103897aaeb4..4287956c9c3 100644 --- a/src/cherrypick.c +++ b/src/cherrypick.c @@ -126,7 +126,10 @@ int git_cherrypick_commit( git_tree *parent_tree = NULL, *our_tree = NULL, *cherrypick_tree = NULL; int parent = 0, error = 0; - assert(out && repo && cherrypick_commit && our_commit); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(cherrypick_commit); + GIT_ASSERT_ARG(our_commit); if (git_commit_parentcount(cherrypick_commit) > 1) { if (!mainline) @@ -177,7 +180,8 @@ int git_cherrypick( git_indexwriter indexwriter = GIT_INDEXWRITER_INIT; int error = 0; - assert(repo && commit); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(commit); GIT_ERROR_CHECK_VERSION(given_opts, GIT_CHERRYPICK_OPTIONS_VERSION, "git_cherrypick_options"); From d4384977c32ffbd55541fd7888ffd4dfe8990bce Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 14:38:20 +0100 Subject: [PATCH 0092/1616] clone: use GIT_ASSERT --- src/clone.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/clone.c b/src/clone.c index a93ec475f42..7ae90b09ea3 100644 --- a/src/clone.c +++ b/src/clone.c @@ -231,7 +231,7 @@ static int update_head_to_remote( /* We know we have HEAD, let's see where it points */ remote_head = refs[0]; - assert(remote_head); + GIT_ASSERT(remote_head); remote_head_id = &remote_head->oid; @@ -267,7 +267,8 @@ static int update_head_to_branch( git_buf remote_branch_name = GIT_BUF_INIT; git_reference* remote_ref = NULL; - assert(remote_name && branch); + GIT_ASSERT_ARG(remote_name); + GIT_ASSERT_ARG(branch); if ((retcode = git_buf_printf(&remote_branch_name, GIT_REFS_REMOTES_DIR "%s/%s", remote_name, branch)) < 0 ) @@ -385,7 +386,8 @@ static int clone_into(git_repository *repo, git_remote *_remote, const git_fetch git_fetch_options fetch_opts; git_remote *remote; - assert(repo && _remote); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(_remote); if (!git_repository_is_empty(repo)) { git_error_set(GIT_ERROR_INVALID, "the repository is not empty"); @@ -452,7 +454,9 @@ static int git__clone( uint32_t rmdir_flags = GIT_RMDIR_REMOVE_FILES; git_repository_create_cb repository_cb; - assert(out && url && local_path); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(url); + GIT_ASSERT_ARG(local_path); if (_options) memcpy(&options, _options, sizeof(git_clone_options)); @@ -575,7 +579,8 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_ git_buf src_odb = GIT_BUF_INIT, dst_odb = GIT_BUF_INIT, src_path = GIT_BUF_INIT; git_buf reflog_message = GIT_BUF_INIT; - assert(repo && remote); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(remote); if (!git_repository_is_empty(repo)) { git_error_set(GIT_ERROR_INVALID, "the repository is not empty"); From 3b2153feb111409d820ed41a5cf8c72343866dfb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 14:42:44 +0100 Subject: [PATCH 0093/1616] commit: use GIT_ASSERT --- src/commit.c | 69 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/src/commit.c b/src/commit.c index cf9902d022b..96259d5bb14 100644 --- a/src/commit.c +++ b/src/commit.c @@ -53,7 +53,8 @@ static int git_commit__create_buffer_internal( size_t i = 0; const git_oid *parent; - assert(out && tree); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(tree); git_oid__writebuf(out, "tree ", tree); @@ -229,7 +230,8 @@ int git_commit_create_v( int error = 0; commit_parent_varargs data; - assert(tree && git_tree_owner(tree) == repo); + GIT_ASSERT_ARG(tree); + GIT_ASSERT_ARG(git_tree_owner(tree) == repo); data.total = parent_count; va_start(data.args, parent_count); @@ -306,7 +308,8 @@ int git_commit_create( { commit_parent_data data = { parent_count, parents, repo }; - assert(tree && git_tree_owner(tree) == repo); + GIT_ASSERT_ARG(tree); + GIT_ASSERT_ARG(git_tree_owner(tree) == repo); return git_commit__create_internal( id, repo, update_ref, author, committer, @@ -337,7 +340,8 @@ int git_commit_amend( git_reference *ref; int error; - assert(id && commit_to_amend); + GIT_ASSERT_ARG(id); + GIT_ASSERT_ARG(commit_to_amend); repo = git_commit_owner(commit_to_amend); @@ -356,7 +360,7 @@ int git_commit_amend( git_oid_cpy(&tree_id, git_tree_id(old_tree)); git_tree_free(old_tree); } else { - assert(git_tree_owner(tree) == repo); + GIT_ASSERT_ARG(git_tree_owner(tree) == repo); git_oid_cpy(&tree_id, git_tree_id(tree)); } @@ -392,7 +396,8 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig size_t header_len; git_signature dummy_sig; - assert(commit && data); + GIT_ASSERT_ARG(commit); + GIT_ASSERT_ARG(data); buffer = buffer_start; @@ -506,28 +511,28 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj) return git_commit__parse_ext(_commit, odb_obj, 0); } -#define GIT_COMMIT_GETTER(_rvalue, _name, _return) \ +#define GIT_COMMIT_GETTER(_rvalue, _name, _return, _invalid) \ _rvalue git_commit_##_name(const git_commit *commit) \ {\ - assert(commit); \ + GIT_ASSERT_ARG_WITH_RETVAL(commit, _invalid); \ return _return; \ } -GIT_COMMIT_GETTER(const git_signature *, author, commit->author) -GIT_COMMIT_GETTER(const git_signature *, committer, commit->committer) -GIT_COMMIT_GETTER(const char *, message_raw, commit->raw_message) -GIT_COMMIT_GETTER(const char *, message_encoding, commit->message_encoding) -GIT_COMMIT_GETTER(const char *, raw_header, commit->raw_header) -GIT_COMMIT_GETTER(git_time_t, time, commit->committer->when.time) -GIT_COMMIT_GETTER(int, time_offset, commit->committer->when.offset) -GIT_COMMIT_GETTER(unsigned int, parentcount, (unsigned int)git_array_size(commit->parent_ids)) -GIT_COMMIT_GETTER(const git_oid *, tree_id, &commit->tree_id) +GIT_COMMIT_GETTER(const git_signature *, author, commit->author, NULL) +GIT_COMMIT_GETTER(const git_signature *, committer, commit->committer, NULL) +GIT_COMMIT_GETTER(const char *, message_raw, commit->raw_message, NULL) +GIT_COMMIT_GETTER(const char *, message_encoding, commit->message_encoding, NULL) +GIT_COMMIT_GETTER(const char *, raw_header, commit->raw_header, NULL) +GIT_COMMIT_GETTER(git_time_t, time, commit->committer->when.time, INT64_MIN) +GIT_COMMIT_GETTER(int, time_offset, commit->committer->when.offset, -1) +GIT_COMMIT_GETTER(unsigned int, parentcount, (unsigned int)git_array_size(commit->parent_ids), 0) +GIT_COMMIT_GETTER(const git_oid *, tree_id, &commit->tree_id, NULL) const char *git_commit_message(const git_commit *commit) { const char *message; - assert(commit); + GIT_ASSERT_ARG_WITH_RETVAL(commit, NULL); message = commit->raw_message; @@ -544,7 +549,7 @@ const char *git_commit_summary(git_commit *commit) const char *msg, *space; bool space_contains_newline = false; - assert(commit); + GIT_ASSERT_ARG_WITH_RETVAL(commit, NULL); if (!commit->summary) { for (msg = git_commit_message(commit), space = NULL; *msg; ++msg) { @@ -587,7 +592,7 @@ const char *git_commit_body(git_commit *commit) { const char *msg, *end; - assert(commit); + GIT_ASSERT_ARG_WITH_RETVAL(commit, NULL); if (!commit->body) { /* search for end of summary */ @@ -612,14 +617,14 @@ const char *git_commit_body(git_commit *commit) int git_commit_tree(git_tree **tree_out, const git_commit *commit) { - assert(commit); + GIT_ASSERT_ARG(commit); return git_tree_lookup(tree_out, commit->object.repo, &commit->tree_id); } const git_oid *git_commit_parent_id( const git_commit *commit, unsigned int n) { - assert(commit); + GIT_ASSERT_ARG_WITH_RETVAL(commit, NULL); return git_array_get(commit->parent_ids, n); } @@ -628,7 +633,7 @@ int git_commit_parent( git_commit **parent, const git_commit *commit, unsigned int n) { const git_oid *parent_id; - assert(commit); + GIT_ASSERT_ARG(commit); parent_id = git_commit_parent_id(commit, n); if (parent_id == NULL) { @@ -647,7 +652,8 @@ int git_commit_nth_gen_ancestor( git_commit *current, *parent = NULL; int error; - assert(ancestor && commit); + GIT_ASSERT_ARG(ancestor); + GIT_ASSERT_ARG(commit); if (git_commit_dup(¤t, (git_commit *)commit) < 0) return -1; @@ -840,7 +846,8 @@ int git_commit_create_buffer(git_buf *out, git_array_oid_t parents_arr = GIT_ARRAY_INIT; const git_oid *tree_id; - assert(tree && git_tree_owner(tree) == repo); + GIT_ASSERT_ARG(tree); + GIT_ASSERT_ARG(git_tree_owner(tree) == repo); tree_id = git_tree_id(tree); @@ -859,11 +866,13 @@ int git_commit_create_buffer(git_buf *out, /** * Append to 'out' properly marking continuations when there's a newline in 'content' */ -static void format_header_field(git_buf *out, const char *field, const char *content) +static int format_header_field(git_buf *out, const char *field, const char *content) { const char *lf; - assert(out && field && content); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(field); + GIT_ASSERT_ARG(content); git_buf_puts(out, field); git_buf_putc(out, ' '); @@ -876,6 +885,8 @@ static void format_header_field(git_buf *out, const char *field, const char *con git_buf_puts(out, content); git_buf_putc(out, '\n'); + + return git_buf_oom(out) ? -1 : 0; } static const git_oid *commit_parent_from_commit(size_t n, void *payload) @@ -926,7 +937,9 @@ int git_commit_create_with_signature( if (signature != NULL) { field = signature_field ? signature_field : "gpgsig"; - format_header_field(&commit, field, signature); + + if ((error = format_header_field(&commit, field, signature)) < 0) + goto cleanup; } git_buf_puts(&commit, header_end); From e7604da800f19b16d7b6b8281068313a993a90b9 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 14:51:56 +0100 Subject: [PATCH 0094/1616] config: use GIT_ASSERT --- src/config.c | 19 ++++++++++++------- src/config_file.c | 4 ++-- src/config_parse.c | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/config.c b/src/config.c index b3e7324a1ce..a6a8cb246a1 100644 --- a/src/config.c +++ b/src/config.c @@ -108,7 +108,8 @@ int git_config_add_file_ondisk( struct stat st; int res; - assert(cfg && path); + GIT_ASSERT_ARG(cfg); + GIT_ASSERT_ARG(path); res = p_stat(path, &st); if (res < 0 && errno != ENOENT && errno != ENOTDIR) { @@ -316,7 +317,8 @@ int git_config_add_backend( backend_internal *internal; int result; - assert(cfg && backend); + GIT_ASSERT_ARG(cfg); + GIT_ASSERT_ARG(backend); GIT_ERROR_CHECK_VERSION(backend, GIT_CONFIG_BACKEND_VERSION, "git_config_backend"); @@ -514,7 +516,8 @@ int git_config_backend_foreach_match( git_regexp regex; int error = 0; - assert(backend && cb); + GIT_ASSERT_ARG(backend); + GIT_ASSERT_ARG(cb); if (regexp && git_regexp_compile(®ex, regexp, 0) < 0) return -1; @@ -1197,7 +1200,7 @@ int git_config_lock(git_transaction **out, git_config *cfg) git_config_backend *backend; backend_internal *internal; - assert(cfg); + GIT_ASSERT_ARG(cfg); internal = git_vector_get(&cfg->backends, 0); if (!internal || !internal->backend) { @@ -1217,7 +1220,7 @@ int git_config_unlock(git_config *cfg, int commit) git_config_backend *backend; backend_internal *internal; - assert(cfg); + GIT_ASSERT_ARG(cfg); internal = git_vector_get(&cfg->backends, 0); if (!internal || !internal->backend) { @@ -1377,7 +1380,8 @@ int git_config_parse_path(git_buf *out, const char *value) { int error; - assert(out && value); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(value); if ((error = git_buf_sanitize(out)) < 0) return error; @@ -1423,7 +1427,8 @@ int git_config__normalize_name(const char *in, char **out) { char *name, *fdot, *ldot; - assert(in && out); + GIT_ASSERT_ARG(in); + GIT_ASSERT_ARG(out); name = git__strdup(in); GIT_ERROR_CHECK_ALLOC(name); diff --git a/src/config_file.c b/src/config_file.c index b1e0028369a..7fba71a98ba 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -365,7 +365,7 @@ static int config_file_set_multivar( int result; char *key; - assert(regexp); + GIT_ASSERT_ARG(regexp); if ((result = git_config__normalize_name(name, &key)) < 0) return result; @@ -531,7 +531,7 @@ static char *escape_value(const char *ptr) size_t len; const char *esc; - assert(ptr); + GIT_ASSERT_ARG_WITH_RETVAL(ptr, NULL); len = strlen(ptr); if (!len) diff --git a/src/config_parse.c b/src/config_parse.c index ed2c87f6bcf..7da92d3e72d 100644 --- a/src/config_parse.c +++ b/src/config_parse.c @@ -187,7 +187,7 @@ static int parse_section_header(git_config_parser *reader, char **section_out) /* Make sure we were given a section header */ c = line[pos++]; - assert(c == '['); + GIT_ASSERT(c == '['); c = line[pos++]; From 00974bcaa3340380a77c262950105b328d2f6ff6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 14:52:48 +0100 Subject: [PATCH 0095/1616] date: use GIT_ASSERT --- src/date.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/date.c b/src/date.c index 0e1b31aeed3..f8594ed4e53 100644 --- a/src/date.c +++ b/src/date.c @@ -881,7 +881,8 @@ int git__date_rfc2822_fmt(char *out, size_t len, const git_time *date) struct tm gmt; time_t t; - assert(out && date); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(date); t = (time_t) (date->time + date->offset * 60); From 65c23e9cde48e7448569587ffcfed81a1e1698da Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 14:53:08 +0100 Subject: [PATCH 0096/1616] delta: use GIT_ASSERT --- src/delta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/delta.c b/src/delta.c index 1ff7752c7d8..2d2c5fa85bb 100644 --- a/src/delta.c +++ b/src/delta.c @@ -256,7 +256,7 @@ void git_delta_index_free(git_delta_index *index) size_t git_delta_index_size(git_delta_index *index) { - assert(index); + GIT_ASSERT_ARG(index); return index->memsize; } From 81609902461217e8ac0781ca6f2a036adc12c278 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 14:53:50 +0100 Subject: [PATCH 0097/1616] describe: use GIT_ASSERT --- src/describe.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/describe.c b/src/describe.c index ebf70b062eb..3648ccef632 100644 --- a/src/describe.c +++ b/src/describe.c @@ -655,7 +655,8 @@ int git_describe_commit( int error = -1; git_describe_options normalized; - assert(committish); + GIT_ASSERT_ARG(result); + GIT_ASSERT_ARG(committish); data.result = git__calloc(1, sizeof(git_describe_result)); GIT_ERROR_CHECK_ALLOC(data.result); @@ -775,7 +776,8 @@ int git_describe_format(git_buf *out, const git_describe_result *result, const g struct commit_name *name; git_describe_format_options opts; - assert(out && result); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(result); GIT_ERROR_CHECK_VERSION(given, GIT_DESCRIBE_FORMAT_OPTIONS_VERSION, "git_describe_format_options"); normalize_format_options(&opts, given); From 5d6c2f26c0edd72cdb582ec23816f4fb70b57982 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 14:59:54 +0100 Subject: [PATCH 0098/1616] diff: use GIT_ASSERT --- src/diff.c | 19 +++++++++++-------- src/diff_driver.c | 2 +- src/diff_generate.c | 29 +++++++++++++++++++---------- src/diff_print.c | 12 ++++++++---- src/diff_stats.c | 12 +++++++----- src/diff_tform.c | 13 +++++++------ 6 files changed, 53 insertions(+), 34 deletions(-) diff --git a/src/diff.c b/src/diff.c index 3e52e3f18df..4085c5f78fd 100644 --- a/src/diff.c +++ b/src/diff.c @@ -77,7 +77,7 @@ void git_diff_addref(git_diff *diff) size_t git_diff_num_deltas(const git_diff *diff) { - assert(diff); + GIT_ASSERT_ARG(diff); return diff->deltas.length; } @@ -86,7 +86,7 @@ size_t git_diff_num_deltas_of_type(const git_diff *diff, git_delta_t type) size_t i, count = 0; const git_diff_delta *delta; - assert(diff); + GIT_ASSERT_ARG(diff); git_vector_foreach(&diff->deltas, i, delta) { count += (delta->status == type); @@ -97,7 +97,7 @@ size_t git_diff_num_deltas_of_type(const git_diff *diff, git_delta_t type) const git_diff_delta *git_diff_get_delta(const git_diff *diff, size_t idx) { - assert(diff); + GIT_ASSERT_ARG_WITH_RETVAL(diff, NULL); return git_vector_get(&diff->deltas, idx); } @@ -108,7 +108,7 @@ int git_diff_is_sorted_icase(const git_diff *diff) int git_diff_get_perfdata(git_diff_perfdata *out, const git_diff *diff) { - assert(out); + GIT_ASSERT_ARG(out); GIT_ERROR_CHECK_VERSION(out, GIT_DIFF_PERFDATA_VERSION, "git_diff_perfdata"); out->stat_calls = diff->perf.stat_calls; out->oid_calculations = diff->perf.oid_calculations; @@ -127,7 +127,7 @@ int git_diff_foreach( git_diff_delta *delta; size_t idx; - assert(diff); + GIT_ASSERT_ARG(diff); git_vector_foreach(&diff->deltas, idx, delta) { git_patch *patch; @@ -243,8 +243,9 @@ int git_diff_format_email( size_t allocsize; int error; - assert(out && diff && opts); - assert(opts->summary && opts->id && opts->author); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(diff); + GIT_ASSERT_ARG(opts && opts->summary && opts->id && opts->author); GIT_ERROR_CHECK_VERSION(opts, GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, @@ -326,7 +327,9 @@ int git_diff_commit_as_email( GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; int error; - assert (out && repo && commit); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(commit); opts.flags = flags; opts.patch_no = patch_no; diff --git a/src/diff_driver.c b/src/diff_driver.c index 831d3262dce..606c391e4ac 100644 --- a/src/diff_driver.c +++ b/src/diff_driver.c @@ -358,7 +358,7 @@ int git_diff_driver_lookup( int error = 0; const char *values[1], *attrs[] = { "diff" }; - assert(out); + GIT_ASSERT_ARG(out); *out = NULL; if (!repo || !path || !strlen(path)) diff --git a/src/diff_generate.c b/src/diff_generate.c index e7bfd6223fa..f021a2667c5 100644 --- a/src/diff_generate.c +++ b/src/diff_generate.c @@ -128,7 +128,7 @@ static int diff_delta__from_one( git_diff_delta *delta; const char *matched_pathspec; - assert((oitem != NULL) ^ (nitem != NULL)); + GIT_ASSERT_ARG((oitem != NULL) ^ (nitem != NULL)); if (oitem) { entry = oitem; @@ -160,7 +160,7 @@ static int diff_delta__from_one( GIT_ERROR_CHECK_ALLOC(delta); /* This fn is just for single-sided diffs */ - assert(status != GIT_DELTA_MODIFIED); + GIT_ASSERT(status != GIT_DELTA_MODIFIED); delta->nfiles = 1; if (has_old) { @@ -408,7 +408,9 @@ static git_diff_generated *diff_generated_alloc( git_diff_generated *diff; git_diff_options dflt = GIT_DIFF_OPTIONS_INIT; - assert(repo && old_iter && new_iter); + GIT_ASSERT_ARG_WITH_RETVAL(repo, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(old_iter, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(new_iter, NULL); if ((diff = git__calloc(1, sizeof(git_diff_generated))) == NULL) return NULL; @@ -589,7 +591,7 @@ int git_diff__oid_for_entry( git_filter_list *fl = NULL; int error = 0; - assert(d->type == GIT_DIFF_TYPE_GENERATED); + GIT_ASSERT(d->type == GIT_DIFF_TYPE_GENERATED); diff = (git_diff_generated *)d; memset(out, 0, sizeof(*out)); @@ -1302,7 +1304,8 @@ int git_diff_tree_to_tree( char *prefix = NULL; int error = 0; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); *out = NULL; @@ -1358,7 +1361,8 @@ int git_diff_tree_to_index( bool index_ignore_case = false; int error = 0; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); *out = NULL; @@ -1401,7 +1405,8 @@ int git_diff_index_to_workdir( char *prefix = NULL; int error = 0; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); *out = NULL; @@ -1444,7 +1449,8 @@ int git_diff_tree_to_workdir( git_index *index; int error; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); *out = NULL; @@ -1477,7 +1483,8 @@ int git_diff_tree_to_workdir_with_index( git_index *index = NULL; int error = 0; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); *out = NULL; @@ -1513,7 +1520,9 @@ int git_diff_index_to_index( char *prefix = NULL; int error; - assert(out && old_index && new_index); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(old_index); + GIT_ASSERT_ARG(new_index); *out = NULL; diff --git a/src/diff_print.c b/src/diff_print.c index 0e93fe8933f..062e267b00c 100644 --- a/src/diff_print.c +++ b/src/diff_print.c @@ -95,7 +95,7 @@ static int diff_print_info_init_frompatch( git_diff_line_cb cb, void *payload) { - assert(patch); + GIT_ASSERT_ARG(patch); memset(pi, 0, sizeof(diff_print_info)); @@ -766,7 +766,9 @@ int git_diff_to_buf(git_buf *out, git_diff *diff, git_diff_format_t format) { int error; - assert(out && diff); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(diff); + if ((error = git_buf_sanitize(out)) < 0) return error; @@ -783,7 +785,8 @@ int git_patch_print( diff_print_info pi; int error; - assert(patch && print_cb); + GIT_ASSERT_ARG(patch); + GIT_ASSERT_ARG(print_cb); if ((error = diff_print_info_init_frompatch(&pi, &temp, patch, GIT_DIFF_FORMAT_PATCH, print_cb, payload)) < 0) @@ -805,7 +808,8 @@ int git_patch_to_buf(git_buf *out, git_patch *patch) { int error; - assert(out && patch); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(patch); if ((error = git_buf_sanitize(out)) < 0) return error; diff --git a/src/diff_stats.c b/src/diff_stats.c index f5fda792531..41a25bf8aca 100644 --- a/src/diff_stats.c +++ b/src/diff_stats.c @@ -183,7 +183,8 @@ int git_diff_get_stats( git_diff_stats *stats = NULL; int error = 0; - assert(out && diff); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(diff); stats = git__calloc(1, sizeof(git_diff_stats)); GIT_ERROR_CHECK_ALLOC(stats); @@ -251,7 +252,7 @@ int git_diff_get_stats( size_t git_diff_stats_files_changed( const git_diff_stats *stats) { - assert(stats); + GIT_ASSERT_ARG(stats); return stats->files_changed; } @@ -259,7 +260,7 @@ size_t git_diff_stats_files_changed( size_t git_diff_stats_insertions( const git_diff_stats *stats) { - assert(stats); + GIT_ASSERT_ARG(stats); return stats->insertions; } @@ -267,7 +268,7 @@ size_t git_diff_stats_insertions( size_t git_diff_stats_deletions( const git_diff_stats *stats) { - assert(stats); + GIT_ASSERT_ARG(stats); return stats->deletions; } @@ -282,7 +283,8 @@ int git_diff_stats_to_buf( size_t i; const git_diff_delta *delta; - assert(out && stats); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(stats); if (format & GIT_DIFF_STATS_NUMBER) { for (i = 0; i < stats->files_changed; ++i) { diff --git a/src/diff_tform.c b/src/diff_tform.c index 7de88bd0d81..03fc2b0a647 100644 --- a/src/diff_tform.c +++ b/src/diff_tform.c @@ -87,7 +87,7 @@ git_diff_delta *git_diff__merge_like_cgit( a->status == GIT_DELTA_UNREADABLE) return dup; - assert(b->status != GIT_DELTA_UNMODIFIED); + GIT_ASSERT_WITH_RETVAL(b->status != GIT_DELTA_UNMODIFIED, NULL); /* A cgit exception is that the diff of a file that is only in the * index (i.e. not in HEAD nor workdir) is given as empty. @@ -121,7 +121,8 @@ int git_diff__merge( bool ignore_case, reversed; unsigned int i, j; - assert(onto && from); + GIT_ASSERT_ARG(onto); + GIT_ASSERT_ARG(from); if (!from->deltas.length) return 0; @@ -815,7 +816,7 @@ int git_diff_find_similar( diff_find_match *best_match; git_diff_file swap; - assert(diff); + GIT_ASSERT_ARG(diff); if ((error = normalize_find_opts(diff, &opts, given_opts)) < 0) return error; @@ -978,7 +979,7 @@ int git_diff_find_similar( src->flags |= GIT_DIFF_FLAG__TO_DELETE; num_rewrites++; } else { - assert(delta_is_split(tgt)); + GIT_ASSERT(delta_is_split(tgt)); if (best_match->similarity < opts.rename_from_rewrite_threshold) continue; @@ -988,7 +989,7 @@ int git_diff_find_similar( delta_make_rename(tgt, src, best_match->similarity); num_rewrites--; - assert(src->status == GIT_DELTA_DELETED); + GIT_ASSERT(src->status == GIT_DELTA_DELETED); memcpy(&src->old_file, &swap, sizeof(src->old_file)); memset(&src->new_file, 0, sizeof(src->new_file)); src->new_file.path = src->old_file.path; @@ -1024,7 +1025,7 @@ int git_diff_find_similar( num_updates++; } else { - assert(delta_is_split(src)); + GIT_ASSERT(delta_is_split(src)); if (best_match->similarity < opts.rename_from_rewrite_threshold) continue; From 59565a0581cafd7cb8acbba7028877f2bd6faca9 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 16:23:40 +0100 Subject: [PATCH 0099/1616] errors: use GIT_ASSERT --- src/errors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/errors.c b/src/errors.c index d4da50da8d9..5b68dd9cbf0 100644 --- a/src/errors.c +++ b/src/errors.c @@ -99,7 +99,7 @@ int git_error_set_str(int error_class, const char *string) { git_buf *buf = &GIT_THREADSTATE->error_buf; - assert(string); + GIT_ASSERT_ARG(string); if (!string) { git_error_set(GIT_ERROR_INVALID, "unspecified caller error"); From a08bd547b88fbd56efba6b9735cec612c610a52f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 16:24:26 +0100 Subject: [PATCH 0100/1616] fetchhead: use GIT_ASSERT --- src/fetchhead.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/fetchhead.c b/src/fetchhead.c index ea610f39a8f..88c567e4847 100644 --- a/src/fetchhead.c +++ b/src/fetchhead.c @@ -73,7 +73,8 @@ int git_fetchhead_ref_create( { git_fetchhead_ref *fetchhead_ref; - assert(out && oid); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(oid); *out = NULL; @@ -108,7 +109,8 @@ static int fetchhead_ref_write( const char *type, *name; int head = 0; - assert(file && fetchhead_ref); + GIT_ASSERT_ARG(file); + GIT_ASSERT_ARG(fetchhead_ref); git_oid_fmt(oid, &fetchhead_ref->oid); oid[GIT_OID_HEXSZ] = '\0'; @@ -145,7 +147,8 @@ int git_fetchhead_write(git_repository *repo, git_vector *fetchhead_refs) unsigned int i; git_fetchhead_ref *fetchhead_ref; - assert(repo && fetchhead_refs); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(fetchhead_refs); if (git_buf_joinpath(&path, repo->gitdir, GIT_FETCH_HEAD_FILE) < 0) return -1; @@ -279,7 +282,8 @@ int git_repository_fetchhead_foreach(git_repository *repo, size_t line_num = 0; int error = 0; - assert(repo && cb); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(cb); if (git_buf_joinpath(&path, repo->gitdir, GIT_FETCH_HEAD_FILE) < 0) return -1; From 33c5c51388d04c4a0a38b40e3a8525a067c7cfc5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 16:30:00 +0100 Subject: [PATCH 0101/1616] filebuf: use GIT_ASSERT --- src/filebuf.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/filebuf.c b/src/filebuf.c index e12a9eabfea..a3f6b14839a 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -184,7 +184,7 @@ static int write_deflate(git_filebuf *file, void *source, size_t len) } while (zs->avail_out == 0); - assert(zs->avail_in == 0); + GIT_ASSERT(zs->avail_in == 0); if (file->compute_digest) git_hash_update(&file->digest, source, len); @@ -278,10 +278,9 @@ int git_filebuf_open_withsize(git_filebuf *file, const char *path, int flags, mo int compression, error = -1; size_t path_len, alloc_len; - /* opening an already open buffer is a programming error; - * assert that this never happens instead of returning - * an error code */ - assert(file && path && file->buffer == NULL); + GIT_ASSERT_ARG(file); + GIT_ASSERT_ARG(path); + GIT_ASSERT(file->buffer == NULL); memset(file, 0x0, sizeof(git_filebuf)); @@ -389,7 +388,9 @@ int git_filebuf_open_withsize(git_filebuf *file, const char *path, int flags, mo int git_filebuf_hash(git_oid *oid, git_filebuf *file) { - assert(oid && file && file->compute_digest); + GIT_ASSERT_ARG(oid); + GIT_ASSERT_ARG(file); + GIT_ASSERT_ARG(file->compute_digest); flush_buffer(file); @@ -415,7 +416,8 @@ int git_filebuf_commit_at(git_filebuf *file, const char *path) int git_filebuf_commit(git_filebuf *file) { /* temporary files cannot be committed */ - assert(file && file->path_original); + GIT_ASSERT_ARG(file); + GIT_ASSERT(file->path_original); file->flush_mode = Z_FINISH; flush_buffer(file); From bc54898f01745fcae87c0418c4b222d6a4588e75 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 16:27:30 +0100 Subject: [PATCH 0102/1616] filter: use GIT_ASSERT --- src/filter.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/filter.c b/src/filter.c index ae9220c9b79..ccabdcdc8b2 100644 --- a/src/filter.c +++ b/src/filter.c @@ -266,7 +266,8 @@ int git_filter_register( { int error; - assert(name && filter); + GIT_ASSERT_ARG(name); + GIT_ASSERT_ARG(filter); if (git_rwlock_wrlock(&filter_registry.lock) < 0) { git_error_set(GIT_ERROR_OS, "failed to lock filter registry"); @@ -293,7 +294,7 @@ int git_filter_unregister(const char *name) git_filter_def *fdef; int error = 0; - assert(name); + GIT_ASSERT_ARG(name); /* cannot unregister default filters */ if (!strcmp(GIT_FILTER_CRLF, name) || !strcmp(GIT_FILTER_IDENT, name)) { @@ -618,7 +619,7 @@ int git_filter_list_contains( { size_t i; - assert(name); + GIT_ASSERT_ARG(name); if (!fl) return 0; @@ -639,7 +640,8 @@ int git_filter_list_push( git_filter_def *fdef = NULL; git_filter_entry *fe; - assert(fl && filter); + GIT_ASSERT_ARG(fl); + GIT_ASSERT_ARG(filter); if (git_rwlock_rdlock(&filter_registry.lock) < 0) { git_error_set(GIT_ERROR_OS, "failed to lock filter registry"); @@ -684,9 +686,8 @@ static int buf_stream_write( git_writestream *s, const char *buffer, size_t len) { struct buf_stream *buf_stream = (struct buf_stream *)s; - assert(buf_stream); - - assert(buf_stream->complete == 0); + GIT_ASSERT_ARG(buf_stream); + GIT_ASSERT(buf_stream->complete == 0); return git_buf_put(buf_stream->target, buffer, len); } @@ -694,9 +695,9 @@ static int buf_stream_write( static int buf_stream_close(git_writestream *s) { struct buf_stream *buf_stream = (struct buf_stream *)s; - assert(buf_stream); + GIT_ASSERT_ARG(buf_stream); - assert(buf_stream->complete == 0); + GIT_ASSERT(buf_stream->complete == 0); buf_stream->complete = 1; return 0; @@ -740,7 +741,7 @@ int git_filter_list_apply_to_data( &writer.parent)) < 0) return error; - assert(writer.complete); + GIT_ASSERT(writer.complete); return error; } @@ -759,7 +760,7 @@ int git_filter_list_apply_to_file( filters, repo, path, &writer.parent)) < 0) return error; - assert(writer.complete); + GIT_ASSERT(writer.complete); return error; } @@ -790,7 +791,7 @@ int git_filter_list_apply_to_blob( filters, blob, &writer.parent)) < 0) return error; - assert(writer.complete); + GIT_ASSERT(writer.complete); return error; } @@ -809,7 +810,7 @@ static int proxy_stream_write( git_writestream *s, const char *buffer, size_t len) { struct proxy_stream *proxy_stream = (struct proxy_stream *)s; - assert(proxy_stream); + GIT_ASSERT_ARG(proxy_stream); return git_buf_put(&proxy_stream->input, buffer, len); } @@ -821,7 +822,7 @@ static int proxy_stream_close(git_writestream *s) git_error_state error_state = {0}; int error; - assert(proxy_stream); + GIT_ASSERT_ARG(proxy_stream); error = proxy_stream->filter->apply( proxy_stream->filter, @@ -856,11 +857,12 @@ static int proxy_stream_close(git_writestream *s) static void proxy_stream_free(git_writestream *s) { struct proxy_stream *proxy_stream = (struct proxy_stream *)s; - assert(proxy_stream); - git_buf_dispose(&proxy_stream->input); - git_buf_dispose(&proxy_stream->temp_buf); - git__free(proxy_stream); + if (proxy_stream) { + git_buf_dispose(&proxy_stream->input); + git_buf_dispose(&proxy_stream->temp_buf); + git__free(proxy_stream); + } } static int proxy_stream_init( @@ -914,7 +916,7 @@ static int stream_list_init( git_filter_entry *fe = git_array_get(filters->filters, filter_idx); git_writestream *filter_stream; - assert(fe->filter->stream || fe->filter->apply); + GIT_ASSERT(fe->filter->stream || fe->filter->apply); /* If necessary, create a stream that proxies the traditional * application. From 03623b47939696c2d75ed3872aa19e8ea7ac1a86 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 16:28:03 +0100 Subject: [PATCH 0103/1616] futils: use GIT_ASSERT --- src/futils.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/futils.c b/src/futils.c index 2ad8a1b806a..a44820875b1 100644 --- a/src/futils.c +++ b/src/futils.c @@ -185,7 +185,8 @@ int git_futils_readbuffer_updated( git_buf buf = GIT_BUF_INIT; git_oid checksum_new; - assert(out && path && *path); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(path && *path); if (updated != NULL) *updated = 0; @@ -493,7 +494,7 @@ int git_futils_mkdir( goto done; } - assert(len); + GIT_ASSERT(len); /* * We've walked all the given path's parents and it's either relative @@ -1128,8 +1129,6 @@ int git_futils_filestamp_check( void git_futils_filestamp_set( git_futils_filestamp *target, const git_futils_filestamp *source) { - assert(target); - if (source) memcpy(target, source, sizeof(*target)); else From 253a873b5e4c142cd58a99274d9b58d200ebfd87 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 16:33:54 +0100 Subject: [PATCH 0104/1616] hash: use GIT_ASSERT --- src/hash.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/hash.c b/src/hash.c index 405c46a9acb..963c281377c 100644 --- a/src/hash.c +++ b/src/hash.c @@ -31,7 +31,7 @@ void git_hash_ctx_cleanup(git_hash_ctx *ctx) git_hash_sha1_ctx_cleanup(&ctx->sha1); return; default: - assert(0); + /* unreachable */ ; } } @@ -41,8 +41,7 @@ int git_hash_init(git_hash_ctx *ctx) case GIT_HASH_ALGO_SHA1: return git_hash_sha1_init(&ctx->sha1); default: - assert(0); - return -1; + GIT_ASSERT(0); } } @@ -52,8 +51,7 @@ int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) case GIT_HASH_ALGO_SHA1: return git_hash_sha1_update(&ctx->sha1, data, len); default: - assert(0); - return -1; + GIT_ASSERT(0); } } @@ -63,8 +61,7 @@ int git_hash_final(git_oid *out, git_hash_ctx *ctx) case GIT_HASH_ALGO_SHA1: return git_hash_sha1_final(out, &ctx->sha1); default: - assert(0); - return -1; + GIT_ASSERT(0); } } @@ -80,7 +77,7 @@ int git_hash_buf(git_oid *out, const void *data, size_t len) error = git_hash_final(out, &ctx); git_hash_ctx_cleanup(&ctx); - + return error; } From 01c649454ed2e9f0e9c0d4524628ccd5cb1eba03 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 16:43:55 +0100 Subject: [PATCH 0105/1616] hashsig: use GIT_ASSERT --- src/hashsig.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/hashsig.c b/src/hashsig.c index 14ec34b2f01..a5fbeee1012 100644 --- a/src/hashsig.c +++ b/src/hashsig.c @@ -133,13 +133,13 @@ typedef struct { uint8_t ignore_ch[256]; } hashsig_in_progress; -static void hashsig_in_progress_init( +static int hashsig_in_progress_init( hashsig_in_progress *prog, git_hashsig *sig) { int i; /* no more than one can be set */ - assert(!(sig->opt & GIT_HASHSIG_IGNORE_WHITESPACE) || + GIT_ASSERT(!(sig->opt & GIT_HASHSIG_IGNORE_WHITESPACE) || !(sig->opt & GIT_HASHSIG_SMART_WHITESPACE)); if (sig->opt & GIT_HASHSIG_IGNORE_WHITESPACE) { @@ -153,6 +153,8 @@ static void hashsig_in_progress_init( } else { memset(prog, 0, sizeof(*prog)); } + + return 0; } static int hashsig_add_hashes( @@ -251,7 +253,8 @@ int git_hashsig_create( git_hashsig *sig = hashsig_alloc(opts); GIT_ERROR_CHECK_ALLOC(sig); - hashsig_in_progress_init(&prog, sig); + if ((error = hashsig_in_progress_init(&prog, sig)) < 0) + return error; error = hashsig_add_hashes(sig, (const uint8_t *)buf, buflen, &prog); @@ -283,7 +286,8 @@ int git_hashsig_create_fromfile( return fd; } - hashsig_in_progress_init(&prog, sig); + if ((error = hashsig_in_progress_init(&prog, sig)) < 0) + return error; while (!error) { if ((buflen = p_read(fd, buf, sizeof(buf))) <= 0) { @@ -318,7 +322,7 @@ static int hashsig_heap_compare(const hashsig_heap *a, const hashsig_heap *b) { int matches = 0, i, j, cmp; - assert(a->cmp == b->cmp); + GIT_ASSERT_WITH_RETVAL(a->cmp == b->cmp, 0); /* hash heaps are sorted - just look for overlap vs total */ @@ -354,9 +358,16 @@ int git_hashsig_compare(const git_hashsig *a, const git_hashsig *b) /* if we have fewer than the maximum number of elements, then just use * one array since the two arrays will be the same */ - if (a->mins.size < HASHSIG_HEAP_SIZE) + if (a->mins.size < HASHSIG_HEAP_SIZE) { return hashsig_heap_compare(&a->mins, &b->mins); - else - return (hashsig_heap_compare(&a->mins, &b->mins) + - hashsig_heap_compare(&a->maxs, &b->maxs)) / 2; + } else { + int mins, maxs; + + if ((mins = hashsig_heap_compare(&a->mins, &b->mins)) < 0) + return mins; + if ((maxs = hashsig_heap_compare(&a->maxs, &b->maxs)) < 0) + return maxs; + + return (mins + maxs) / 2; + } } From 3a6d04a344f1ad851a79a9a10d4bad1cadc018b4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 16:44:42 +0100 Subject: [PATCH 0106/1616] ignore: use GIT_ASSERT --- src/ignore.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ignore.c b/src/ignore.c index f5fb507e68f..27a650b1b74 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -287,7 +287,9 @@ int git_ignore__for_path( const char *workdir = git_repository_workdir(repo); git_buf infopath = GIT_BUF_INIT; - assert(repo && ignores && path); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(ignores); + GIT_ASSERT_ARG(path); memset(ignores, 0, sizeof(*ignores)); ignores->repo = repo; @@ -521,7 +523,9 @@ int git_ignore_path_is_ignored( git_attr_file *file; git_dir_flag dir_flag = GIT_DIR_FLAG_UNKNOWN; - assert(repo && ignored && pathname); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(ignored); + GIT_ASSERT_ARG(pathname); workdir = git_repository_workdir(repo); From 1fa339be78ad0e07a9220ff091d3f7aaa21502c1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 16:50:13 +0100 Subject: [PATCH 0107/1616] index: use GIT_ASSERT --- src/index.c | 154 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 95 insertions(+), 59 deletions(-) diff --git a/src/index.c b/src/index.c index d5afc9bb695..d9116c412bb 100644 --- a/src/index.c +++ b/src/index.c @@ -406,7 +406,7 @@ int git_index_open(git_index **index_out, const char *index_path) git_index *index; int error = -1; - assert(index_out); + GIT_ASSERT_ARG(index_out); index = git__calloc(1, sizeof(git_index)); GIT_ERROR_CHECK_ALLOC(index); @@ -461,7 +461,8 @@ static void index_free(git_index *index) /* index iterators increment the refcount of the index, so if we * get here then there should be no outstanding iterators. */ - assert(!git_atomic_get(&index->readers)); + if (git_atomic_get(&index->readers)) + return; git_index_clear(index); git_idxmap_free(index->entries_map); @@ -531,7 +532,7 @@ int git_index_clear(git_index *index) { int error = 0; - assert(index); + GIT_ASSERT_ARG(index); index->dirty = 1; index->tree = NULL; @@ -566,7 +567,7 @@ int git_index_set_caps(git_index *index, int caps) { unsigned int old_ignore_case; - assert(index); + GIT_ASSERT_ARG(index); old_ignore_case = index->ignore_case; @@ -778,14 +779,14 @@ static int truncate_racily_clean(git_index *index) unsigned git_index_version(git_index *index) { - assert(index); + GIT_ASSERT_ARG(index); return index->version; } int git_index_set_version(git_index *index, unsigned int version) { - assert(index); + GIT_ASSERT_ARG(index); if (version < INDEX_VERSION_NUMBER_LB || version > INDEX_VERSION_NUMBER_UB) { @@ -814,9 +815,9 @@ int git_index_write(git_index *index) return error; } -const char * git_index_path(const git_index *index) +const char *git_index_path(const git_index *index) { - assert(index); + GIT_ASSERT_ARG_WITH_RETVAL(index, NULL); return index->index_file_path; } @@ -824,7 +825,8 @@ int git_index_write_tree(git_oid *oid, git_index *index) { git_repository *repo; - assert(oid && index); + GIT_ASSERT_ARG(oid); + GIT_ASSERT_ARG(index); repo = INDEX_OWNER(index); @@ -838,20 +840,25 @@ int git_index_write_tree(git_oid *oid, git_index *index) int git_index_write_tree_to( git_oid *oid, git_index *index, git_repository *repo) { - assert(oid && index && repo); + GIT_ASSERT_ARG(oid); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(repo); + return git_tree__write_index(oid, index, repo); } size_t git_index_entrycount(const git_index *index) { - assert(index); + GIT_ASSERT_ARG(index); + return index->entries.length; } const git_index_entry *git_index_get_byindex( git_index *index, size_t n) { - assert(index); + GIT_ASSERT_ARG_WITH_RETVAL(index, NULL); + git_vector_sort(&index->entries); return git_vector_get(&index->entries, n); } @@ -862,7 +869,7 @@ const git_index_entry *git_index_get_bypath( git_index_entry key = {{ 0 }}; git_index_entry *value; - assert(index); + GIT_ASSERT_ARG_WITH_RETVAL(index, NULL); key.path = path; GIT_INDEX_ENTRY_STAGE_SET(&key, stage); @@ -1039,23 +1046,24 @@ static int index_entry_reuc_init(git_index_reuc_entry **reuc_out, { git_index_reuc_entry *reuc = NULL; - assert(reuc_out && path); + GIT_ASSERT_ARG(reuc_out); + GIT_ASSERT_ARG(path); *reuc_out = reuc = reuc_entry_alloc(path); GIT_ERROR_CHECK_ALLOC(reuc); if ((reuc->mode[0] = ancestor_mode) > 0) { - assert(ancestor_oid); + GIT_ASSERT(ancestor_oid); git_oid_cpy(&reuc->oid[0], ancestor_oid); } if ((reuc->mode[1] = our_mode) > 0) { - assert(our_oid); + GIT_ASSERT(our_oid); git_oid_cpy(&reuc->oid[1], our_oid); } if ((reuc->mode[2] = their_mode) > 0) { - assert(their_oid); + GIT_ASSERT(their_oid); git_oid_cpy(&reuc->oid[2], their_oid); } @@ -1347,7 +1355,8 @@ static int index_insert( size_t path_length, position; int error; - assert(index && entry_ptr); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(entry_ptr); entry = *entry_ptr; @@ -1472,7 +1481,8 @@ int git_index_add_from_buffer( int error = 0; git_oid id; - assert(index && source_entry->path); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(source_entry && source_entry->path); if (INDEX_OWNER(index) == NULL) return create_index_error(-1, @@ -1557,7 +1567,8 @@ int git_index_add_bypath(git_index *index, const char *path) git_index_entry *entry = NULL; int ret; - assert(index && path); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(path); if ((ret = index_entry_init(&entry, index, path)) == 0) ret = index_insert(index, &entry, 1, false, false, true); @@ -1609,7 +1620,8 @@ int git_index_remove_bypath(git_index *index, const char *path) { int ret; - assert(index && path); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(path); if (((ret = git_index_remove(index, path, 0)) < 0 && ret != GIT_ENOTFOUND) || @@ -1629,7 +1641,7 @@ int git_index__fill(git_index *index, const git_vector *source_entries) int error = 0; size_t i; - assert(index); + GIT_ASSERT_ARG(index); if (!source_entries->length) return 0; @@ -1670,7 +1682,8 @@ int git_index_add(git_index *index, const git_index_entry *source_entry) git_index_entry *entry = NULL; int ret; - assert(index && source_entry && source_entry->path); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(source_entry && source_entry->path); if (!valid_filemode(source_entry->mode)) { git_error_set(GIT_ERROR_INDEX, "invalid entry mode"); @@ -1758,7 +1771,8 @@ int git_index_find_prefix(size_t *at_pos, git_index *index, const char *prefix) int git_index__find_pos( size_t *out, git_index *index, const char *path, size_t path_len, int stage) { - assert(index && path); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(path); return index_find(out, index, path, path_len, stage); } @@ -1766,7 +1780,8 @@ int git_index_find(size_t *at_pos, git_index *index, const char *path) { size_t pos; - assert(index && path); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(path); if (git_vector_bsearch2( &pos, &index->entries, index->entries_search_path, path) < 0) { @@ -1799,7 +1814,7 @@ int git_index_conflict_add(git_index *index, unsigned short i; int ret = 0; - assert (index); + GIT_ASSERT_ARG(index); if ((ancestor_entry && (ret = index_entry_dup(&entries[0], index, ancestor_entry)) < 0) || @@ -1870,7 +1885,10 @@ static int index_conflict__get_byindex( size_t count; int stage, len = 0; - assert(ancestor_out && our_out && their_out && index); + GIT_ASSERT_ARG(ancestor_out); + GIT_ASSERT_ARG(our_out); + GIT_ASSERT_ARG(their_out); + GIT_ASSERT_ARG(index); *ancestor_out = NULL; *our_out = NULL; @@ -1916,7 +1934,11 @@ int git_index_conflict_get( size_t pos; int len = 0; - assert(ancestor_out && our_out && their_out && index && path); + GIT_ASSERT_ARG(ancestor_out); + GIT_ASSERT_ARG(our_out); + GIT_ASSERT_ARG(their_out); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(path); *ancestor_out = NULL; *our_out = NULL; @@ -1963,13 +1985,14 @@ static int index_conflict_remove(git_index *index, const char *path) int git_index_conflict_remove(git_index *index, const char *path) { - assert(index && path); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(path); return index_conflict_remove(index, path); } int git_index_conflict_cleanup(git_index *index) { - assert(index); + GIT_ASSERT_ARG(index); return index_conflict_remove(index, NULL); } @@ -1978,7 +2001,7 @@ int git_index_has_conflicts(const git_index *index) size_t i; git_index_entry *entry; - assert(index); + GIT_ASSERT_ARG(index); git_vector_foreach(&index->entries, i, entry) { if (GIT_INDEX_ENTRY_STAGE(entry) > 0) @@ -1995,7 +2018,8 @@ int git_index_iterator_new( git_index_iterator *it; int error; - assert(iterator_out && index); + GIT_ASSERT_ARG(iterator_out); + GIT_ASSERT_ARG(index); it = git__calloc(1, sizeof(git_index_iterator)); GIT_ERROR_CHECK_ALLOC(it); @@ -2015,7 +2039,8 @@ int git_index_iterator_next( const git_index_entry **out, git_index_iterator *it) { - assert(out && it); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(it); if (it->cur >= git_vector_length(&it->snap)) return GIT_ITEROVER; @@ -2039,7 +2064,8 @@ int git_index_conflict_iterator_new( { git_index_conflict_iterator *it = NULL; - assert(iterator_out && index); + GIT_ASSERT_ARG(iterator_out); + GIT_ASSERT_ARG(index); it = git__calloc(1, sizeof(git_index_conflict_iterator)); GIT_ERROR_CHECK_ALLOC(it); @@ -2059,7 +2085,10 @@ int git_index_conflict_next( const git_index_entry *entry; int len; - assert(ancestor_out && our_out && their_out && iterator); + GIT_ASSERT_ARG(ancestor_out); + GIT_ASSERT_ARG(our_out); + GIT_ASSERT_ARG(their_out); + GIT_ASSERT_ARG(iterator); *ancestor_out = NULL; *our_out = NULL; @@ -2097,14 +2126,14 @@ void git_index_conflict_iterator_free(git_index_conflict_iterator *iterator) size_t git_index_name_entrycount(git_index *index) { - assert(index); + GIT_ASSERT_ARG(index); return index->names.length; } const git_index_name_entry *git_index_name_get_byindex( git_index *index, size_t n) { - assert(index); + GIT_ASSERT_ARG_WITH_RETVAL(index, NULL); git_vector_sort(&index->names); return git_vector_get(&index->names, n); @@ -2125,7 +2154,7 @@ int git_index_name_add(git_index *index, { git_index_name_entry *conflict_name; - assert((ancestor && ours) || (ancestor && theirs) || (ours && theirs)); + GIT_ASSERT_ARG((ancestor && ours) || (ancestor && theirs) || (ours && theirs)); conflict_name = git__calloc(1, sizeof(git_index_name_entry)); GIT_ERROR_CHECK_ALLOC(conflict_name); @@ -2148,7 +2177,7 @@ int git_index_name_clear(git_index *index) size_t i; git_index_name_entry *conflict_name; - assert(index); + GIT_ASSERT_ARG(index); git_vector_foreach(&index->names, i, conflict_name) index_name_entry_free(conflict_name); @@ -2162,7 +2191,7 @@ int git_index_name_clear(git_index *index) size_t git_index_reuc_entrycount(git_index *index) { - assert(index); + GIT_ASSERT_ARG(index); return index->reuc.length; } @@ -2179,8 +2208,9 @@ static int index_reuc_insert( { int res; - assert(index && reuc && reuc->path != NULL); - assert(git_vector_is_sorted(&index->reuc)); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(reuc && reuc->path != NULL); + GIT_ASSERT(git_vector_is_sorted(&index->reuc)); res = git_vector_insert_sorted(&index->reuc, reuc, &index_reuc_on_dup); index->dirty = 1; @@ -2196,7 +2226,8 @@ int git_index_reuc_add(git_index *index, const char *path, git_index_reuc_entry *reuc = NULL; int error = 0; - assert(index && path); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(path); if ((error = index_entry_reuc_init(&reuc, path, ancestor_mode, ancestor_oid, our_mode, our_oid, their_mode, their_oid)) < 0 || @@ -2215,12 +2246,14 @@ const git_index_reuc_entry *git_index_reuc_get_bypath( git_index *index, const char *path) { size_t pos; - assert(index && path); + + GIT_ASSERT_ARG_WITH_RETVAL(index, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(path, NULL); if (!index->reuc.length) return NULL; - assert(git_vector_is_sorted(&index->reuc)); + GIT_ASSERT_WITH_RETVAL(git_vector_is_sorted(&index->reuc), NULL); if (git_index_reuc_find(&pos, index, path) < 0) return NULL; @@ -2231,8 +2264,8 @@ const git_index_reuc_entry *git_index_reuc_get_bypath( const git_index_reuc_entry *git_index_reuc_get_byindex( git_index *index, size_t n) { - assert(index); - assert(git_vector_is_sorted(&index->reuc)); + GIT_ASSERT_ARG_WITH_RETVAL(index, NULL); + GIT_ASSERT_WITH_RETVAL(git_vector_is_sorted(&index->reuc), NULL); return git_vector_get(&index->reuc, n); } @@ -2242,7 +2275,8 @@ int git_index_reuc_remove(git_index *index, size_t position) int error; git_index_reuc_entry *reuc; - assert(git_vector_is_sorted(&index->reuc)); + GIT_ASSERT_ARG(index); + GIT_ASSERT(git_vector_is_sorted(&index->reuc)); reuc = git_vector_get(&index->reuc, position); error = git_vector_remove(&index->reuc, position); @@ -2258,7 +2292,7 @@ int git_index_reuc_clear(git_index *index) { size_t i; - assert(index); + GIT_ASSERT_ARG(index); for (i = 0; i < index->reuc.length; ++i) index_entry_reuc_free(git__swap(index->reuc.contents[i], NULL)); @@ -2626,7 +2660,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) seek_forward(INDEX_HEADER_SIZE); - assert(!index->entries.length); + GIT_ASSERT(!index->entries.length); if ((error = index_map_resize(index->entries_map, header.entry_count, index->ignore_case)) < 0) return error; @@ -2799,7 +2833,8 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha if (last) { varint_len = git_encode_varint((unsigned char *) path, disk_size, strlen(last) - same_len); - assert(varint_len > 0); + GIT_ASSERT(varint_len > 0); + path += varint_len; disk_size -= varint_len; @@ -2807,14 +2842,14 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha * If using path compression, we are not allowed * to have additional trailing NULs. */ - assert(disk_size == path_len + 1); + GIT_ASSERT(disk_size == path_len + 1); } else { /* * If no path compression is used, we do have * NULs as padding. As such, simply assert that * we have enough space left to write the path. */ - assert(disk_size > path_len); + GIT_ASSERT(disk_size > path_len); } memcpy(path, path_start, path_len + 1); @@ -3010,7 +3045,8 @@ static int write_index(git_oid *checksum, git_index *index, git_filebuf *file) bool is_extended; uint32_t index_version_number; - assert(index && file); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(file); if (index->version <= INDEX_VERSION_NUMBER_EXT) { is_extended = is_index_extended(index); @@ -3192,7 +3228,7 @@ static int git_index_read_iterator( size_t i; int error; - assert((new_iterator->flags & GIT_ITERATOR_DONT_IGNORE_CASE)); + GIT_ASSERT((new_iterator->flags & GIT_ITERATOR_DONT_IGNORE_CASE)); if ((error = git_vector_init(&new_entries, new_length_hint, index->entries._cmp)) < 0 || (error = git_vector_init(&remove_entries, index->entries.length, NULL)) < 0 || @@ -3364,7 +3400,7 @@ int git_index_add_all( git_pathspec ps; bool no_fnmatch = (flags & GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH) != 0; - assert(index); + GIT_ASSERT_ARG(index); repo = INDEX_OWNER(index); if ((error = git_repository__ensure_not_bare(repo, "index add all")) < 0) @@ -3450,8 +3486,8 @@ static int index_apply_to_wd_diff(git_index *index, int action, const git_strarr payload, }; - assert(index); - assert(action == INDEX_ACTION_UPDATE || action == INDEX_ACTION_ADDALL); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(action == INDEX_ACTION_UPDATE || action == INDEX_ACTION_ADDALL); repo = INDEX_OWNER(index); @@ -3505,7 +3541,7 @@ static int index_apply_to_all( const char *match; git_buf path = GIT_BUF_INIT; - assert(index); + GIT_ASSERT_ARG(index); if ((error = git_pathspec__init(&ps, paths)) < 0) return error; From cd2fe662a6da39fcb7bdef666716e7c35fd66ab6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 16:56:55 +0100 Subject: [PATCH 0108/1616] indexer: use GIT_ASSERT --- src/indexer.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/indexer.c b/src/indexer.c index 8c74f0e72cf..1068a509ac3 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -239,7 +239,8 @@ static int hash_object_stream(git_indexer*idx, git_packfile_stream *stream) { ssize_t read; - assert(idx && stream); + GIT_ASSERT_ARG(idx); + GIT_ASSERT_ARG(stream); do { if ((read = git_packfile_stream_read(stream, idx->objbuf, sizeof(idx->objbuf))) < 0) @@ -262,7 +263,7 @@ static int advance_delta_offset(git_indexer *idx, git_object_t type) { git_mwindow *w = NULL; - assert(type == GIT_OBJECT_REF_DELTA || type == GIT_OBJECT_OFS_DELTA); + GIT_ASSERT_ARG(type == GIT_OBJECT_REF_DELTA || type == GIT_OBJECT_OFS_DELTA); if (type == GIT_OBJECT_REF_DELTA) { idx->off += GIT_OID_RAWSZ; @@ -282,7 +283,7 @@ static int read_object_stream(git_indexer *idx, git_packfile_stream *stream) { ssize_t read; - assert(stream); + GIT_ASSERT_ARG(stream); do { read = git_packfile_stream_read(stream, idx->objbuf, sizeof(idx->objbuf)); @@ -612,7 +613,8 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s git_map map; int error; - assert(data && size); + GIT_ASSERT_ARG(data); + GIT_ASSERT_ARG(size); if ((error = git__mmap_alignment(&mmap_alignment)) < 0) return error; @@ -759,7 +761,9 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_inde struct git_pack_header *hdr = &idx->hdr; git_mwindow_file *mwf = &idx->pack->mwf; - assert(idx && data && stats); + GIT_ASSERT_ARG(idx); + GIT_ASSERT_ARG(data); + GIT_ASSERT_ARG(stats); if ((error = append_to_pack(idx, data, size)) < 0) return error; @@ -950,7 +954,7 @@ static int fix_thin_pack(git_indexer *idx, git_indexer_progress *stats) unsigned int left = 0; git_oid base; - assert(git_vector_length(&idx->deltas) > 0); + GIT_ASSERT(git_vector_length(&idx->deltas) > 0); if (idx->odb == NULL) { git_error_set(GIT_ERROR_INDEXER, "cannot fix a thin pack without an ODB"); From 79b0c8c84a717614dbcf2b99a7dee59c94431e76 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 21 Nov 2020 23:29:29 +0000 Subject: [PATCH 0109/1616] iterator: use GIT_ASSERT --- src/diff_generate.c | 5 +++-- src/iterator.c | 48 ++++++++++++++++++++++++++------------------- src/iterator.h | 2 +- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/diff_generate.c b/src/diff_generate.c index f021a2667c5..745e5ae1bd8 100644 --- a/src/diff_generate.c +++ b/src/diff_generate.c @@ -1206,8 +1206,9 @@ int git_diff__from_iterators( /* make iterators have matching icase behavior */ if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE)) { - git_iterator_set_ignore_case(old_iter, true); - git_iterator_set_ignore_case(new_iter, true); + if ((error = git_iterator_set_ignore_case(old_iter, true)) < 0 || + (error = git_iterator_set_ignore_case(new_iter, true)) < 0) + goto cleanup; } /* finish initialization */ diff --git a/src/iterator.c b/src/iterator.c index a393187c07e..073459501ac 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -330,7 +330,7 @@ static iterator_pathlist_search_t iterator_pathlist_search( break; /* an exact match would have been matched by the bsearch above */ - assert(p[path_len]); + GIT_ASSERT_WITH_RETVAL(p[path_len], ITERATOR_PATHLIST_NONE); /* is this a literal directory entry (eg `foo/`) or a file beneath */ if (p[path_len] == '/') { @@ -678,14 +678,14 @@ GIT_INLINE(int) tree_iterator_frame_push( return error; } -static void tree_iterator_frame_pop(tree_iterator *iter) +static int tree_iterator_frame_pop(tree_iterator *iter) { tree_iterator_frame *frame; git_buf *buf = NULL; git_tree *tree; size_t i; - assert(iter->frames.size); + GIT_ASSERT(iter->frames.size); frame = git_array_pop(iter->frames); @@ -705,6 +705,8 @@ static void tree_iterator_frame_pop(tree_iterator *iter) git_vector_free(&frame->similar_trees); git_buf_dispose(&frame->path); + + return 0; } static int tree_iterator_current( @@ -760,7 +762,9 @@ static int tree_iterator_advance(const git_index_entry **out, git_iterator *i) /* no more entries in this frame. pop the frame out */ if (frame->next_idx == frame->entries.length) { - tree_iterator_frame_pop(iter); + if ((error = tree_iterator_frame_pop(iter)) < 0) + break; + continue; } @@ -838,7 +842,7 @@ static int tree_iterator_advance_into( const git_index_entry **out, git_iterator *i) { tree_iterator *iter = (tree_iterator *)i; - tree_iterator_frame *frame; + tree_iterator_frame *frame; tree_iterator_entry *prev_entry; int error; @@ -855,7 +859,7 @@ static int tree_iterator_advance_into( * we will have pushed a new (empty) frame on to the stack for this * new directory. since it's empty, its current_entry should be null. */ - assert(iterator__do_autoexpand(i) ^ (prev_entry != NULL)); + GIT_ASSERT(iterator__do_autoexpand(i) ^ (prev_entry != NULL)); if (prev_entry) { if (!git_tree_entry__is_tree(prev_entry->tree_entry)) @@ -973,7 +977,7 @@ int git_iterator_current_tree_entry( tree_iterator_frame *frame; tree_iterator_entry *entry; - assert(i->type == GIT_ITERATOR_TREE); + GIT_ASSERT(i->type == GIT_ITERATOR_TREE); iter = (tree_iterator *)i; @@ -990,11 +994,11 @@ int git_iterator_current_parent_tree( tree_iterator *iter; tree_iterator_frame *frame; - assert(i->type == GIT_ITERATOR_TREE); + GIT_ASSERT(i->type == GIT_ITERATOR_TREE); iter = (tree_iterator *)i; - assert(depth < iter->frames.size); + GIT_ASSERT(depth < iter->frames.size); frame = &iter->frames.ptr[iter->frames.size-depth-1]; *parent_tree = frame->tree; @@ -1388,7 +1392,7 @@ static int filesystem_iterator_frame_push( if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0) goto done; - assert(path_len > iter->root_len); + GIT_ASSERT(path_len > iter->root_len); /* remove the prefix if requested */ path += iter->root_len; @@ -1469,17 +1473,19 @@ static int filesystem_iterator_frame_push( return error; } -GIT_INLINE(void) filesystem_iterator_frame_pop(filesystem_iterator *iter) +GIT_INLINE(int) filesystem_iterator_frame_pop(filesystem_iterator *iter) { filesystem_iterator_frame *frame; - assert(iter->frames.size); + GIT_ASSERT(iter->frames.size); frame = git_array_pop(iter->frames); filesystem_iterator_frame_pop_ignores(iter); git_pool_clear(&frame->entry_pool); git_vector_free(&frame->entries); + + return 0; } static void filesystem_iterator_set_current( @@ -1646,7 +1652,7 @@ static int filesystem_iterator_advance_into( * we will have pushed a new (empty) frame on to the stack for this * new directory. since it's empty, its current_entry should be null. */ - assert(iterator__do_autoexpand(i) ^ (prev_entry != NULL)); + GIT_ASSERT(iterator__do_autoexpand(i) ^ (prev_entry != NULL)); if (prev_entry) { if (prev_entry->st.st_mode != GIT_FILEMODE_COMMIT && @@ -1762,12 +1768,13 @@ static int filesystem_iterator_advance_over( *out = NULL; *status = GIT_ITERATOR_STATUS_NORMAL; - assert(iterator__has_been_accessed(i)); + GIT_ASSERT(iterator__has_been_accessed(i)); current_frame = filesystem_iterator_current_frame(iter); - assert(current_frame); + GIT_ASSERT(current_frame); + current_entry = filesystem_iterator_current_entry(current_frame); - assert(current_entry); + GIT_ASSERT(current_entry); if ((error = git_iterator_current(&entry, i)) < 0) return error; @@ -2065,8 +2072,8 @@ static bool index_iterator_create_pseudotree( static int index_iterator_skip_pseudotree(index_iterator *iter) { - assert(iterator__has_been_accessed(&iter->base)); - assert(S_ISDIR(iter->entry->mode)); + GIT_ASSERT(iterator__has_been_accessed(&iter->base)); + GIT_ASSERT(S_ISDIR(iter->entry->mode)); while (true) { const git_index_entry *next_entry = NULL; @@ -2280,10 +2287,11 @@ int git_iterator_reset_range( return i->cb->reset(i); } -void git_iterator_set_ignore_case(git_iterator *i, bool ignore_case) +int git_iterator_set_ignore_case(git_iterator *i, bool ignore_case) { - assert(!iterator__has_been_accessed(i)); + GIT_ASSERT(!iterator__has_been_accessed(i)); iterator_set_ignore_case(i, ignore_case); + return 0; } void git_iterator_free(git_iterator *iter) diff --git a/src/iterator.h b/src/iterator.h index ebd69362bcc..30465df2f03 100644 --- a/src/iterator.h +++ b/src/iterator.h @@ -263,7 +263,7 @@ GIT_INLINE(bool) git_iterator_ignore_case(git_iterator *iter) return ((iter->flags & GIT_ITERATOR_IGNORE_CASE) != 0); } -extern void git_iterator_set_ignore_case( +extern int git_iterator_set_ignore_case( git_iterator *iter, bool ignore_case); extern int git_iterator_current_tree_entry( From 23e38fd378f747c6c9ff4ce54123857812e6dfcd Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:02:17 +0100 Subject: [PATCH 0110/1616] mailmap: use GIT_ASSERT --- src/mailmap.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/mailmap.c b/src/mailmap.c index 409cdbd3c22..347b4339142 100644 --- a/src/mailmap.c +++ b/src/mailmap.c @@ -43,7 +43,8 @@ static int mailmap_entry_cmp(const void *a_raw, const void *b_raw) const git_mailmap_entry *b = (const git_mailmap_entry *)b_raw; int cmp; - assert(a && b && a->replace_email && b->replace_email); + GIT_ASSERT_ARG(a && a->replace_email); + GIT_ASSERT_ARG(b && b->replace_email); cmp = git__strcmp(a->replace_email, b->replace_email); if (cmp) @@ -185,7 +186,8 @@ static int mailmap_add_entry_unterminated( git_mailmap_entry *entry = git__calloc(1, sizeof(git_mailmap_entry)); GIT_ERROR_CHECK_ALLOC(entry); - assert(mm && replace_email && *replace_email); + GIT_ASSERT_ARG(mm); + GIT_ASSERT_ARG(replace_email && *replace_email); if (real_name_size > 0) { entry->real_name = git__substrdup(real_name, real_name_size); @@ -290,7 +292,8 @@ static int mailmap_add_blob( git_buf content = GIT_BUF_INIT; int error; - assert(mm && repo); + GIT_ASSERT_ARG(mm); + GIT_ASSERT_ARG(repo); error = git_revparse_single(&object, repo, rev); if (error < 0) @@ -350,8 +353,6 @@ static void mailmap_add_from_repository(git_mailmap *mm, git_repository *repo) const char *rev = NULL; const char *path = NULL; - assert(mm && repo); - /* If we're in a bare repo, default blob to 'HEAD:.mailmap' */ if (repo->is_bare) rev = MM_BLOB_DEFAULT; @@ -389,9 +390,14 @@ static void mailmap_add_from_repository(git_mailmap *mm, git_repository *repo) int git_mailmap_from_repository(git_mailmap **out, git_repository *repo) { - int error = git_mailmap_new(out); - if (error < 0) + int error; + + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + + if ((error = git_mailmap_new(out)) < 0) return error; + mailmap_add_from_repository(*out, repo); return 0; } @@ -408,7 +414,7 @@ const git_mailmap_entry *git_mailmap_entry_lookup( git_mailmap_entry needle = { NULL }; needle.replace_email = (char *)email; - assert(email); + GIT_ASSERT_ARG_WITH_RETVAL(email, NULL); if (!mm) return NULL; @@ -431,7 +437,8 @@ const git_mailmap_entry *git_mailmap_entry_lookup( if (git__strcmp(entry->replace_email, email)) break; /* it's a different email, so we're done looking */ - assert(entry->replace_name); /* should be specific */ + /* should be specific */ + GIT_ASSERT_WITH_RETVAL(entry->replace_name, NULL); if (!name || !git__strcmp(entry->replace_name, name)) return entry; } @@ -447,7 +454,9 @@ int git_mailmap_resolve( const char *name, const char *email) { const git_mailmap_entry *entry = NULL; - assert(name && email); + + GIT_ASSERT(name); + GIT_ASSERT(email); *real_name = name; *real_email = email; From 237657f43ef8b95cd22682914aeb4a4285ed6207 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:03:41 +0100 Subject: [PATCH 0111/1616] map: use GIT_ASSERT --- src/map.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/map.h b/src/map.h index 6328d8cf45e..01931d199c0 100644 --- a/src/map.h +++ b/src/map.h @@ -36,9 +36,9 @@ typedef struct { /* memory mapped buffer */ } git_map; #define GIT_MMAP_VALIDATE(out, len, prot, flags) do { \ - assert(out != NULL && len > 0); \ - assert((prot & GIT_PROT_WRITE) || (prot & GIT_PROT_READ)); \ - assert((flags & GIT_MAP_FIXED) == 0); } while (0) + GIT_ASSERT(out != NULL && len > 0); \ + GIT_ASSERT((prot & GIT_PROT_WRITE) || (prot & GIT_PROT_READ)); \ + GIT_ASSERT((flags & GIT_MAP_FIXED) == 0); } while (0) extern int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset); extern int p_munmap(git_map *map); From c59fbafdb8e0d9c62ac8c854e7c3e39abd65e9a0 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:06:37 +0100 Subject: [PATCH 0112/1616] merge: use GIT_ASSERT --- src/merge.c | 67 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/src/merge.c b/src/merge.c index 2f6bf6fe79b..e02ea9169d3 100644 --- a/src/merge.c +++ b/src/merge.c @@ -139,7 +139,9 @@ int git_merge_base_many(git_oid *out, git_repository *repo, size_t length, const git_commit_list *result = NULL; int error = 0; - assert(out && repo && input_array); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(input_array); if ((error = merge_bases_many(&result, &walk, repo, length, input_array)) < 0) return error; @@ -159,7 +161,9 @@ int git_merge_bases_many(git_oidarray *out, git_repository *repo, size_t length, int error = 0; git_array_oid_t array; - assert(out && repo && input_array); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(input_array); if ((error = merge_bases_many(&result, &walk, repo, length, input_array)) < 0) return error; @@ -193,7 +197,9 @@ int git_merge_base_octopus(git_oid *out, git_repository *repo, size_t length, co unsigned int i; int error = -1; - assert(out && repo && input_array); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(input_array); if (length < 2) { git_error_set(GIT_ERROR_INVALID, "at least two commits are required to find an ancestor"); @@ -581,7 +587,8 @@ int git_repository_mergehead_foreach( git_oid oid; int error = 0; - assert(repo && cb); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(cb); if ((error = git_buf_joinpath(&merge_head_path, repo->gitdir, GIT_MERGE_HEAD_FILE)) < 0) @@ -650,7 +657,9 @@ static int merge_conflict_resolve_trivial( git_index_entry const *result = NULL; int error = 0; - assert(resolved && diff_list && conflict); + GIT_ASSERT_ARG(resolved); + GIT_ASSERT_ARG(diff_list); + GIT_ASSERT_ARG(conflict); *resolved = 0; @@ -733,7 +742,9 @@ static int merge_conflict_resolve_one_removed( int ours_changed, theirs_changed; int error = 0; - assert(resolved && diff_list && conflict); + GIT_ASSERT_ARG(resolved); + GIT_ASSERT_ARG(diff_list); + GIT_ASSERT_ARG(conflict); *resolved = 0; @@ -773,7 +784,9 @@ static int merge_conflict_resolve_one_renamed( git_index_entry *merged; int error = 0; - assert(resolved && diff_list && conflict); + GIT_ASSERT_ARG(resolved); + GIT_ASSERT_ARG(diff_list); + GIT_ASSERT_ARG(conflict); *resolved = 0; @@ -917,7 +930,9 @@ static int merge_conflict_resolve_contents( bool fallback = false; int error; - assert(resolved && diff_list && conflict); + GIT_ASSERT_ARG(resolved); + GIT_ASSERT_ARG(diff_list); + GIT_ASSERT_ARG(conflict); *resolved = 0; @@ -1517,7 +1532,8 @@ int git_merge_diff_list__find_renames( size_t src_count, tgt_count, i; int error = 0; - assert(diff_list && opts); + GIT_ASSERT_ARG(diff_list); + GIT_ASSERT_ARG(opts); if ((opts->flags & GIT_MERGE_FIND_RENAMES) == 0) return 0; @@ -1843,7 +1859,8 @@ static int merge_normalize_opts( git_config_entry *entry = NULL; int error = 0; - assert(repo && opts); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(opts); if ((error = git_repository_config__weakptr(&cfg, repo)) < 0) return error; @@ -2070,7 +2087,8 @@ int git_merge__iterators( size_t i; int error = 0; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); *out = NULL; @@ -2154,7 +2172,8 @@ int git_merge_trees( git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT; int error; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); /* if one side is treesame to the ancestor, take the other side */ if (ancestor_tree && merge_opts && (merge_opts->flags & GIT_MERGE_SKIP_REUC)) { @@ -2441,7 +2460,8 @@ static int write_merge_head( size_t i; int error = 0; - assert(repo && heads); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(heads); if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_HEAD_FILE)) < 0 || (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0) @@ -2469,7 +2489,7 @@ static int write_merge_mode(git_repository *repo) git_buf file_path = GIT_BUF_INIT; int error = 0; - assert(repo); + GIT_ASSERT_ARG(repo); if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MODE_FILE)) < 0 || (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0) @@ -2689,7 +2709,8 @@ static int write_merge_msg( char sep = 0; int error = 0; - assert(repo && heads); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(heads); entries = git__calloc(heads_len, sizeof(struct merge_msg_entry)); GIT_ERROR_CHECK_ALLOC(entries); @@ -2800,7 +2821,9 @@ int git_merge__setup( { int error = 0; - assert (repo && our_head && heads); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(our_head); + GIT_ASSERT_ARG(heads); if ((error = git_repository__set_orig_head(repo, git_annotated_commit_id(our_head))) == 0 && (error = write_merge_head(repo, heads, heads_len)) == 0 && @@ -2824,7 +2847,9 @@ static int merge_ancestor_head( size_t i, alloc_len; int error = 0; - assert(repo && our_head && their_heads); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(our_head); + GIT_ASSERT_ARG(their_heads); GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, their_heads_len, 1); oids = git__calloc(alloc_len, sizeof(git_oid)); @@ -3202,7 +3227,10 @@ int git_merge_analysis_for_ref( int error = 0; bool unborn; - assert(analysis_out && preference_out && repo && their_heads && their_heads_len > 0); + GIT_ASSERT_ARG(analysis_out); + GIT_ASSERT_ARG(preference_out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(their_heads && their_heads_len > 0); if (their_heads_len != 1) { git_error_set(GIT_ERROR_MERGE, "can only merge a single branch"); @@ -3284,7 +3312,8 @@ int git_merge( unsigned int checkout_strategy; int error = 0; - assert(repo && their_heads && their_heads_len > 0); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(their_heads && their_heads_len > 0); if (their_heads_len != 1) { git_error_set(GIT_ERROR_MERGE, "can only merge a single branch"); From 61f33f3e8ab90ce65a69a70a98675ca6b20c7630 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:08:42 +0100 Subject: [PATCH 0113/1616] merge_driver: use GIT_ASSERT --- src/merge_driver.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/merge_driver.c b/src/merge_driver.c index b1f574801d9..17c386a143c 100644 --- a/src/merge_driver.c +++ b/src/merge_driver.c @@ -32,33 +32,38 @@ static struct merge_driver_registry merge_driver_registry; static void git_merge_driver_global_shutdown(void); -git_repository* git_merge_driver_source_repo(const git_merge_driver_source *src) +git_repository *git_merge_driver_source_repo( + const git_merge_driver_source *src) { - assert(src); + GIT_ASSERT_ARG_WITH_RETVAL(src, NULL); return src->repo; } -const git_index_entry* git_merge_driver_source_ancestor(const git_merge_driver_source *src) +const git_index_entry *git_merge_driver_source_ancestor( + const git_merge_driver_source *src) { - assert(src); + GIT_ASSERT_ARG_WITH_RETVAL(src, NULL); return src->ancestor; } -const git_index_entry* git_merge_driver_source_ours(const git_merge_driver_source *src) +const git_index_entry *git_merge_driver_source_ours( + const git_merge_driver_source *src) { - assert(src); + GIT_ASSERT_ARG_WITH_RETVAL(src, NULL); return src->ours; } -const git_index_entry* git_merge_driver_source_theirs(const git_merge_driver_source *src) +const git_index_entry *git_merge_driver_source_theirs( + const git_merge_driver_source *src) { - assert(src); + GIT_ASSERT_ARG_WITH_RETVAL(src, NULL); return src->theirs; } -const git_merge_file_options* git_merge_driver_source_file_options(const git_merge_driver_source *src) +const git_merge_file_options *git_merge_driver_source_file_options( + const git_merge_driver_source *src) { - assert(src); + GIT_ASSERT_ARG_WITH_RETVAL(src, NULL); return src->file_opts; } @@ -262,7 +267,8 @@ int git_merge_driver_register(const char *name, git_merge_driver *driver) { int error; - assert(name && driver); + GIT_ASSERT_ARG(name); + GIT_ASSERT_ARG(driver); if (git_rwlock_wrlock(&merge_driver_registry.lock) < 0) { git_error_set(GIT_ERROR_OS, "failed to lock merge driver registry"); From f16f2927879c9a2193d575f655ecd110508313df Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:09:59 +0100 Subject: [PATCH 0114/1616] merge_file: use GIT_ASSERT --- src/merge_file.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/merge_file.c b/src/merge_file.c index 755340fa984..bfa3ec52e48 100644 --- a/src/merge_file.c +++ b/src/merge_file.c @@ -36,7 +36,10 @@ static int merge_file_input_from_index( { int error = 0; - assert(input_out && odb_object_out && odb && entry); + GIT_ASSERT_ARG(input_out); + GIT_ASSERT_ARG(odb_object_out); + GIT_ASSERT_ARG(odb); + GIT_ASSERT_ARG(entry); if ((error = git_odb_read(odb_object_out, odb, &entry->id)) < 0) goto done; @@ -241,7 +244,9 @@ int git_merge_file( { git_merge_file_input inputs[3] = { {0} }; - assert(out && ours && theirs); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(ours); + GIT_ASSERT_ARG(theirs); memset(out, 0x0, sizeof(git_merge_file_result)); @@ -268,7 +273,10 @@ int git_merge_file_from_index( git_odb_object *odb_object[3] = { 0 }; int error = 0; - assert(out && repo && ours && theirs); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(ours); + GIT_ASSERT_ARG(theirs); memset(out, 0x0, sizeof(git_merge_file_result)); From 69fb897915fc56ba14c2a5e35fb55000732817b7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 21 Nov 2020 22:54:26 +0000 Subject: [PATCH 0115/1616] midx: use GIT_ASSERT --- src/midx.c | 11 +++++++---- src/midx.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/midx.c b/src/midx.c index 21cfff497cf..00d73153da2 100644 --- a/src/midx.c +++ b/src/midx.c @@ -181,7 +181,7 @@ int git_midx_parse( chunk_object_offsets = {0}, chunk_object_large_offsets = {0}; - assert(idx); + GIT_ASSERT_ARG(idx); if (size < sizeof(struct git_midx_header) + 20) return midx_error("multi-pack index is too short"); @@ -338,7 +338,7 @@ int git_midx_entry_find( const unsigned char *object_offset; off64_t offset; - assert(idx); + GIT_ASSERT_ARG(idx); hi = ntohl(idx->oid_fanout[(int)short_oid->id[0]]); lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(idx->oid_fanout[(int)short_oid->id[0] - 1])); @@ -399,13 +399,16 @@ int git_midx_entry_find( return 0; } -void git_midx_close(git_midx_file *idx) +int git_midx_close(git_midx_file *idx) { - assert(idx); + GIT_ASSERT_ARG(idx); if (idx->index_map.data) git_futils_mmap_free(&idx->index_map); + git_vector_free(&idx->packfile_names); + + return 0; } void git_midx_free(git_midx_file *idx) diff --git a/src/midx.h b/src/midx.h index e6a64cd8158..3b802952c72 100644 --- a/src/midx.h +++ b/src/midx.h @@ -71,7 +71,7 @@ int git_midx_entry_find( git_midx_file *idx, const git_oid *short_oid, size_t len); -void git_midx_close(git_midx_file *idx); +int git_midx_close(git_midx_file *idx); void git_midx_free(git_midx_file *idx); /* This is exposed for use in the fuzzers. */ From a3e8b7cd3e49bdcffc9d9d5bda1d134a448932e2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:18:20 +0100 Subject: [PATCH 0116/1616] mwindow: use GIT_ASSERT --- src/indexer.c | 26 ++++++++++++++++---------- src/mwindow.c | 36 +++++++++++++++++++++--------------- src/mwindow.h | 6 +++--- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/indexer.c b/src/indexer.c index 1068a509ac3..b6a2ee45efa 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -817,7 +817,8 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_inde /* Now that we have data in the pack, let's try to parse it */ /* As the file grows any windows we try to use will be out of date */ - git_mwindow_free_all(mwf); + if ((error = git_mwindow_free_all(mwf)) < 0) + goto on_error; while (stats->indexed_objects < idx->nr_objects) { if ((error = read_stream_object(idx, stats)) != 0) { @@ -861,16 +862,16 @@ static int index_path(git_buf *path, git_indexer *idx, const char *suffix) * Rewind the packfile by the trailer, as we might need to fix the * packfile by injecting objects at the tail and must overwrite it. */ -static void seek_back_trailer(git_indexer *idx) +static int seek_back_trailer(git_indexer *idx) { idx->pack->mwf.size -= GIT_OID_RAWSZ; - git_mwindow_free_all(&idx->pack->mwf); + return git_mwindow_free_all(&idx->pack->mwf); } static int inject_object(git_indexer *idx, git_oid *id) { - git_odb_object *obj; - struct entry *entry; + git_odb_object *obj = NULL; + struct entry *entry = NULL; struct git_pack_entry *pentry = NULL; git_oid foo = {{0}}; unsigned char hdr[64]; @@ -880,12 +881,14 @@ static int inject_object(git_indexer *idx, git_oid *id) size_t len, hdr_len; int error; - seek_back_trailer(idx); + if ((error = seek_back_trailer(idx)) < 0) + goto cleanup; + entry_start = idx->pack->mwf.size; - if (git_odb_read(&obj, idx->odb, id) < 0) { + if ((error = git_odb_read(&obj, idx->odb, id)) < 0) { git_error_set(GIT_ERROR_INDEXER, "missing delta bases"); - return -1; + goto cleanup; } data = git_odb_object_data(obj); @@ -1085,7 +1088,9 @@ static int update_header_and_rehash(git_indexer *idx, git_indexer_progress *stat * hash_partially() keep the existing trailer out of the * calculation. */ - git_mwindow_free_all(mwf); + if (git_mwindow_free_all(mwf) < 0) + return -1; + idx->inbuf_len = 0; while (hashed < mwf->size) { ptr = git_mwindow_open(mwf, &w, hashed, chunk, &left); @@ -1257,7 +1262,8 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) if (git_filebuf_commit_at(&index_file, filename.ptr) < 0) goto on_error; - git_mwindow_free_all(&idx->pack->mwf); + if (git_mwindow_free_all(&idx->pack->mwf) < 0) + goto on_error; /* Truncate file to undo rounding up to next page_size in append_to_pack */ if (p_ftruncate(idx->pack->mwf.fd, idx->pack->mwf.size) < 0) { diff --git a/src/mwindow.c b/src/mwindow.c index a852d6bf2f7..66fd2182394 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -52,7 +52,7 @@ int git_mwindow_global_init(void) { int error; - assert(!git__pack_cache); + GIT_ASSERT(!git__pack_cache); if ((error = git_mutex_init(&git__mwindow_mutex)) < 0 || (error = git_strmap_new(&git__pack_cache)) < 0) @@ -105,18 +105,18 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path) return 0; } -void git_mwindow_put_pack(struct git_pack_file *pack) +int git_mwindow_put_pack(struct git_pack_file *pack) { - int count; + int count, error; - if (git_mutex_lock(&git__mwindow_mutex) < 0) - return; + if ((error = git_mutex_lock(&git__mwindow_mutex)) < 0) + return error; /* put before get would be a corrupted state */ - assert(git__pack_cache); + GIT_ASSERT(git__pack_cache); /* if we cannot find it, the state is corrupted */ - assert(git_strmap_exists(git__pack_cache, pack->pack_name)); + GIT_ASSERT(git_strmap_exists(git__pack_cache, pack->pack_name)); count = git_atomic_dec(&pack->refcount); if (count == 0) { @@ -125,26 +125,30 @@ void git_mwindow_put_pack(struct git_pack_file *pack) } git_mutex_unlock(&git__mwindow_mutex); - return; + return 0; } -void git_mwindow_free_all(git_mwindow_file *mwf) +int git_mwindow_free_all(git_mwindow_file *mwf) { + int error; + if (git_mutex_lock(&git__mwindow_mutex)) { git_error_set(GIT_ERROR_THREAD, "unable to lock mwindow mutex"); - return; + return -1; } - git_mwindow_free_all_locked(mwf); + error = git_mwindow_free_all_locked(mwf); git_mutex_unlock(&git__mwindow_mutex); + + return error; } /* * Free all the windows in a sequence, typically because we're done * with the file */ -void git_mwindow_free_all_locked(git_mwindow_file *mwf) +int git_mwindow_free_all_locked(git_mwindow_file *mwf) { git_mwindow_ctl *ctl = &git_mwindow__mem_ctl; size_t i; @@ -166,7 +170,7 @@ void git_mwindow_free_all_locked(git_mwindow_file *mwf) while (mwf->windows) { git_mwindow *w = mwf->windows; - assert(w->inuse_cnt == 0); + GIT_ASSERT(w->inuse_cnt == 0); ctl->mapped -= w->window_map.len; ctl->open_windows--; @@ -176,6 +180,8 @@ void git_mwindow_free_all_locked(git_mwindow_file *mwf) mwf->windows = w->next; git__free(w); } + + return 0; } /* @@ -210,8 +216,8 @@ static bool git_mwindow_scan_recently_used( git_mwindow *lru_window = NULL, *lru_last = NULL; bool found = false; - assert(mwf); - assert(out_window); + GIT_ASSERT_ARG(mwf); + GIT_ASSERT_ARG(out_window); lru_window = *out_window; if (out_last) diff --git a/src/mwindow.h b/src/mwindow.h index 7519fc36d6b..b379fba2ddb 100644 --- a/src/mwindow.h +++ b/src/mwindow.h @@ -40,8 +40,8 @@ typedef struct git_mwindow_ctl { } git_mwindow_ctl; int git_mwindow_contains(git_mwindow *win, off64_t offset); -void git_mwindow_free_all(git_mwindow_file *mwf); /* locks */ -void git_mwindow_free_all_locked(git_mwindow_file *mwf); /* run under lock */ +int git_mwindow_free_all(git_mwindow_file *mwf); /* locks */ +int git_mwindow_free_all_locked(git_mwindow_file *mwf); /* run under lock */ unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, off64_t offset, size_t extra, unsigned int *left); int git_mwindow_file_register(git_mwindow_file *mwf); void git_mwindow_file_deregister(git_mwindow_file *mwf); @@ -51,6 +51,6 @@ extern int git_mwindow_global_init(void); struct git_pack_file; /* just declaration to avoid cyclical includes */ int git_mwindow_get_pack(struct git_pack_file **out, const char *path); -void git_mwindow_put_pack(struct git_pack_file *pack); +int git_mwindow_put_pack(struct git_pack_file *pack); #endif From ea7c807a373a15c69c710375d65e4ba3777c09af Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:18:46 +0100 Subject: [PATCH 0117/1616] net: use GIT_ASSERT --- src/net.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/net.c b/src/net.c index ac1bc429973..0705dd390cd 100644 --- a/src/net.c +++ b/src/net.c @@ -281,7 +281,8 @@ int git_net_url_apply_redirect( git_net_url tmp = GIT_NET_URL_INIT; int error = 0; - assert(url && redirect_location); + GIT_ASSERT(url); + GIT_ASSERT(redirect_location); if (redirect_location[0] == '/') { git__free(url->path); From 05816a98e95b0fb3897f1e8482494893c20673bb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:20:08 +0100 Subject: [PATCH 0118/1616] netops: use GIT_ASSERT --- src/netops.c | 8 +++++--- src/netops.h | 2 +- src/transports/smart_protocol.c | 11 ++++++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/netops.c b/src/netops.c index 1ef2302931a..a1ee2927cd9 100644 --- a/src/netops.c +++ b/src/netops.c @@ -61,18 +61,20 @@ void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data } /* Consume up to ptr and move the rest of the buffer to the beginning */ -void gitno_consume(gitno_buffer *buf, const char *ptr) +int gitno_consume(gitno_buffer *buf, const char *ptr) { size_t consumed; - assert(ptr - buf->data >= 0); - assert(ptr - buf->data <= (int) buf->len); + GIT_ASSERT(ptr - buf->data >= 0); + GIT_ASSERT(ptr - buf->data <= (int) buf->len); consumed = ptr - buf->data; memmove(buf->data, ptr, buf->offset - consumed); memset(buf->data + buf->offset, 0x0, buf->len - buf->offset); buf->offset -= consumed; + + return 0; } /* Consume const bytes and move the rest of the buffer to the beginning */ diff --git a/src/netops.h b/src/netops.h index 52f1cccb606..771c87b64b7 100644 --- a/src/netops.h +++ b/src/netops.h @@ -62,7 +62,7 @@ void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data void gitno_buffer_setup_callback(gitno_buffer *buf, char *data, size_t len, int (*recv)(gitno_buffer *buf), void *cb_data); int gitno_recv(gitno_buffer *buf); -void gitno_consume(gitno_buffer *buf, const char *ptr); +int gitno_consume(gitno_buffer *buf, const char *ptr); void gitno_consume_n(gitno_buffer *buf, size_t cons); #endif diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index c01656dc469..18dcaa879d6 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -64,7 +64,9 @@ int git_smart__store_refs(transport_smart *t, int flushes) continue; } - gitno_consume(buf, line_end); + if (gitno_consume(buf, line_end) < 0) + return -1; + if (pkt->type == GIT_PKT_ERR) { git_error_set(GIT_ERROR_NET, "remote error: %s", ((git_pkt_err *)pkt)->error); git__free(pkt); @@ -236,7 +238,9 @@ static int recv_pkt(git_pkt **out_pkt, git_pkt_type *out_type, gitno_buffer *buf } } while (error); - gitno_consume(buf, line_end); + if (gitno_consume(buf, line_end) < 0) + return -1; + if (out_type != NULL) *out_type = pkt->type; if (out_pkt != NULL) @@ -791,7 +795,8 @@ static int parse_report(transport_smart *transport, git_push *push) continue; } - gitno_consume(buf, line_end); + if (gitno_consume(buf, line_end) < 0) + return -1; error = 0; From 6718ad9fae65db3988b37e4893946c565f1806ca Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:20:46 +0100 Subject: [PATCH 0119/1616] notes: use GIT_ASSERT --- src/notes.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/notes.c b/src/notes.c index a3c4b7c4fea..b9e198599d9 100644 --- a/src/notes.c +++ b/src/notes.c @@ -627,7 +627,8 @@ int git_note_default_ref(git_buf *out, git_repository *repo) char *default_ref; int error; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); if ((error = git_buf_sanitize(out)) < 0 || (error = note_get_default_ref(&default_ref, repo)) < 0) @@ -639,25 +640,25 @@ int git_note_default_ref(git_buf *out, git_repository *repo) const git_signature *git_note_committer(const git_note *note) { - assert(note); + GIT_ASSERT_ARG_WITH_RETVAL(note, NULL); return note->committer; } const git_signature *git_note_author(const git_note *note) { - assert(note); + GIT_ASSERT_ARG_WITH_RETVAL(note, NULL); return note->author; } -const char * git_note_message(const git_note *note) +const char *git_note_message(const git_note *note) { - assert(note); + GIT_ASSERT_ARG_WITH_RETVAL(note, NULL); return note->message; } -const git_oid * git_note_id(const git_note *note) +const git_oid *git_note_id(const git_note *note) { - assert(note); + GIT_ASSERT_ARG_WITH_RETVAL(note, NULL); return ¬e->id; } From 4300aa4bfd5e690a414df231459d9e57dc8f5f5c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:24:32 +0100 Subject: [PATCH 0120/1616] object: use GIT_ASSERT --- src/object.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/object.c b/src/object.c index fa975347e11..42e1e46bcc5 100644 --- a/src/object.c +++ b/src/object.c @@ -67,7 +67,7 @@ int git_object__from_raw( size_t object_size; int error; - assert(object_out); + GIT_ASSERT_ARG(object_out); *object_out = NULL; /* Validate type match */ @@ -91,7 +91,7 @@ int git_object__from_raw( /* Parse raw object data */ def = &git_objects_table[type]; - assert(def->free && def->parse_raw); + GIT_ASSERT(def->free && def->parse_raw); if ((error = def->parse_raw(object, data, size)) < 0) { def->free(object); @@ -115,7 +115,7 @@ int git_object__from_odb_object( git_object_def *def; git_object *object = NULL; - assert(object_out); + GIT_ASSERT_ARG(object_out); *object_out = NULL; /* Validate type match */ @@ -141,7 +141,7 @@ int git_object__from_odb_object( /* Parse raw object data */ def = &git_objects_table[odb_obj->cached.type]; - assert(def->free && def->parse); + GIT_ASSERT(def->free && def->parse); if ((error = def->parse(object, odb_obj)) < 0) def->free(object); @@ -174,7 +174,9 @@ int git_object_lookup_prefix( git_odb_object *odb_obj = NULL; int error = 0; - assert(repo && object_out && id); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(object_out); + GIT_ASSERT_ARG(id); if (len < GIT_OID_MINPREFIXLEN) { git_error_set(GIT_ERROR_OBJECT, "ambiguous lookup - OID prefix is too short"); @@ -211,7 +213,7 @@ int git_object_lookup_prefix( } else if (cached->flags == GIT_CACHE_STORE_RAW) { odb_obj = (git_odb_object *)cached; } else { - assert(!"Wrong caching type in the global object cache"); + GIT_ASSERT(!"Wrong caching type in the global object cache"); } } else { /* Object was not found in the cache, let's explore the backends. @@ -263,19 +265,19 @@ void git_object_free(git_object *object) const git_oid *git_object_id(const git_object *obj) { - assert(obj); + GIT_ASSERT_ARG_WITH_RETVAL(obj, NULL); return &obj->cached.oid; } git_object_t git_object_type(const git_object *obj) { - assert(obj); + GIT_ASSERT_ARG_WITH_RETVAL(obj, GIT_OBJECT_INVALID); return obj->cached.type; } git_repository *git_object_owner(const git_object *obj) { - assert(obj); + GIT_ASSERT_ARG_WITH_RETVAL(obj, NULL); return obj->repo; } @@ -396,9 +398,10 @@ int git_object_peel( git_object *source, *deref = NULL; int error; - assert(object && peeled); + GIT_ASSERT_ARG(object); + GIT_ASSERT_ARG(peeled); - assert(target_type == GIT_OBJECT_TAG || + GIT_ASSERT_ARG(target_type == GIT_OBJECT_TAG || target_type == GIT_OBJECT_COMMIT || target_type == GIT_OBJECT_TREE || target_type == GIT_OBJECT_BLOB || @@ -461,7 +464,9 @@ int git_object_lookup_bypath( git_tree *tree = NULL; git_tree_entry *entry = NULL; - assert(out && treeish && path); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(treeish); + GIT_ASSERT_ARG(path); if ((error = git_object_peel((git_object**)&tree, treeish, GIT_OBJECT_TREE)) < 0 || (error = git_tree_entry_bypath(&entry, tree, path)) < 0) @@ -493,7 +498,8 @@ int git_object_short_id(git_buf *out, const git_object *obj) git_oid id = {{0}}; git_odb *odb; - assert(out && obj); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(obj); if ((error = git_buf_sanitize(out)) < 0) return error; From 931fd6b08a810f02fc046ef9501d0b7e6a8e2640 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:29:13 +0100 Subject: [PATCH 0121/1616] odb: use GIT_ASSERT --- src/odb.c | 61 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/src/odb.c b/src/odb.c index 129a63255dc..1e608f5d83a 100644 --- a/src/odb.c +++ b/src/odb.c @@ -114,7 +114,8 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj) size_t hdrlen; int error; - assert(id && obj); + GIT_ASSERT_ARG(id); + GIT_ASSERT_ARG(obj); if (!git_object_typeisloose(obj->type)) { git_error_set(GIT_ERROR_INVALID, "invalid object type"); @@ -346,7 +347,7 @@ int git_odb_hash(git_oid *id, const void *data, size_t len, git_object_t type) { git_rawobj raw; - assert(id); + GIT_ASSERT_ARG(id); raw.data = (void *)data; raw.len = len; @@ -376,7 +377,7 @@ static int fake_wstream__write(git_odb_stream *_stream, const char *data, size_t { fake_wstream *stream = (fake_wstream *)_stream; - assert(stream->written + len <= stream->size); + GIT_ASSERT(stream->written + len <= stream->size); memcpy(stream->buffer + stream->written, data, len); stream->written += len; @@ -470,12 +471,13 @@ static int add_backend_internal( { backend_internal *internal; - assert(odb && backend); + GIT_ASSERT_ARG(odb); + GIT_ASSERT_ARG(backend); GIT_ERROR_CHECK_VERSION(backend, GIT_ODB_BACKEND_VERSION, "git_odb_backend"); /* Check if the backend is already owned by another ODB */ - assert(!backend->odb || backend->odb == odb); + GIT_ASSERT(!backend->odb || backend->odb == odb); internal = git__malloc(sizeof(backend_internal)); GIT_ERROR_CHECK_ALLOC(internal); @@ -507,7 +509,7 @@ int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority) size_t git_odb_num_backends(git_odb *odb) { - assert(odb); + GIT_ASSERT_ARG(odb); return odb->backends.length; } @@ -523,7 +525,9 @@ int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos) { backend_internal *internal; - assert(out && odb); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(odb); + internal = git_vector_get(&odb->backends, pos); if (internal && internal->backend) { @@ -645,7 +649,8 @@ int git_odb_open(git_odb **out, const char *objects_dir) { git_odb *db; - assert(out && objects_dir); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(objects_dir); *out = NULL; @@ -755,7 +760,8 @@ static int odb_freshen_1( int git_odb__freshen(git_odb *db, const git_oid *id) { - assert(db && id); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(id); if (odb_freshen_1(db, id, false)) return 1; @@ -771,7 +777,8 @@ int git_odb_exists(git_odb *db, const git_oid *id) { git_odb_object *object; - assert(db && id); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(id); if (git_oid_is_zero(id)) return 0; @@ -839,7 +846,8 @@ int git_odb_exists_prefix( int error; git_oid key = {{0}}; - assert(db && short_id); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(short_id); if (len < GIT_OID_MINPREFIXLEN) return git_odb__error_ambiguous("prefix length too short"); @@ -875,7 +883,8 @@ int git_odb_expand_ids( { size_t i; - assert(db && ids); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(ids); for (i = 0; i < count; i++) { git_odb_expand_id *query = &ids[i]; @@ -997,7 +1006,11 @@ int git_odb__read_header_or_object( int error = GIT_ENOTFOUND; git_odb_object *object; - assert(db && id && out && len_p && type_p); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(id); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(len_p); + GIT_ASSERT_ARG(type_p); *out = NULL; @@ -1104,7 +1117,9 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id) { int error; - assert(out && db && id); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(id); if (git_oid_is_zero(id)) return error_null_oid(GIT_ENOTFOUND, "cannot read object"); @@ -1237,7 +1252,8 @@ int git_odb_read_prefix( git_oid key = {{0}}; int error; - assert(out && db); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(db); if (len < GIT_OID_MINPREFIXLEN) return git_odb__error_ambiguous("prefix length too short"); @@ -1286,7 +1302,8 @@ int git_odb_write( int error; git_odb_stream *stream; - assert(oid && db); + GIT_ASSERT_ARG(oid); + GIT_ASSERT_ARG(db); if ((error = git_odb_hash(oid, data, len, type)) < 0) return error; @@ -1346,7 +1363,8 @@ int git_odb_open_wstream( int error = GIT_ERROR; git_hash_ctx *ctx = NULL; - assert(stream && db); + GIT_ASSERT_ARG(stream); + GIT_ASSERT_ARG(db); for (i = 0; i < db->backends.length && error < 0; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); @@ -1456,7 +1474,8 @@ int git_odb_open_rstream( size_t i, reads = 0; int error = GIT_ERROR; - assert(stream && db); + GIT_ASSERT_ARG(stream); + GIT_ASSERT_ARG(db); for (i = 0; i < db->backends.length && error < 0; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); @@ -1481,7 +1500,8 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_ size_t i, writes = 0; int error = GIT_ERROR; - assert(out && db); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(db); for (i = 0; i < db->backends.length && error < 0; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); @@ -1527,7 +1547,8 @@ void git_odb_backend_data_free(git_odb_backend *backend, void *data) int git_odb_refresh(struct git_odb *db) { size_t i; - assert(db); + + GIT_ASSERT_ARG(db); for (i = 0; i < db->backends.length; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); From 9d1cfb2fd30fc57f28184ff587dcca0175d03709 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:32:52 +0100 Subject: [PATCH 0122/1616] odb_loose: use GIT_ASSERT --- src/odb_loose.c | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/odb_loose.c b/src/odb_loose.c index 68287795a54..b0abbbf4c27 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -309,7 +309,7 @@ static int read_loose_standard(git_rawobj *out, git_buf *obj) goto done; } - assert(decompressed >= head_len); + GIT_ASSERT(decompressed >= head_len); body_len = decompressed - head_len; if (body_len) @@ -344,7 +344,8 @@ static int read_loose(git_rawobj *out, git_buf *loc) int error; git_buf obj = GIT_BUF_INIT; - assert(out && loc); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(loc); if (git_buf_oom(loc)) return -1; @@ -411,7 +412,8 @@ static int read_header_loose(git_rawobj *out, git_buf *loc) ssize_t obj_len; int fd, error; - assert(out && loc); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(loc); if (git_buf_oom(loc)) return -1; @@ -585,7 +587,8 @@ static int loose_backend__read_header(size_t *len_p, git_object_t *type_p, git_o git_rawobj raw; int error; - assert(backend && oid); + GIT_ASSERT_ARG(backend); + GIT_ASSERT_ARG(oid); raw.len = 0; raw.type = GIT_OBJECT_INVALID; @@ -609,7 +612,8 @@ static int loose_backend__read(void **buffer_p, size_t *len_p, git_object_t *typ git_rawobj raw; int error = 0; - assert(backend && oid); + GIT_ASSERT_ARG(backend); + GIT_ASSERT_ARG(oid); if (locate_object(&object_path, (loose_backend *)backend, oid) < 0) { error = git_odb__error_notfound("no matching loose object", @@ -636,7 +640,7 @@ static int loose_backend__read_prefix( { int error = 0; - assert(len >= GIT_OID_MINPREFIXLEN && len <= GIT_OID_HEXSZ); + GIT_ASSERT_ARG(len >= GIT_OID_MINPREFIXLEN && len <= GIT_OID_HEXSZ); if (len == GIT_OID_HEXSZ) { /* We can fall back to regular read method */ @@ -647,7 +651,7 @@ static int loose_backend__read_prefix( git_buf object_path = GIT_BUF_INIT; git_rawobj raw; - assert(backend && short_oid); + GIT_ASSERT_ARG(backend && short_oid); if ((error = locate_object_short_oid(&object_path, out_oid, (loose_backend *)backend, short_oid, len)) == 0 && @@ -669,7 +673,8 @@ static int loose_backend__exists(git_odb_backend *backend, const git_oid *oid) git_buf object_path = GIT_BUF_INIT; int error; - assert(backend && oid); + GIT_ASSERT_ARG(backend); + GIT_ASSERT_ARG(oid); error = locate_object(&object_path, (loose_backend *)backend, oid); @@ -684,7 +689,10 @@ static int loose_backend__exists_prefix( git_buf object_path = GIT_BUF_INIT; int error; - assert(backend && out && short_id && len >= GIT_OID_MINPREFIXLEN); + GIT_ASSERT_ARG(backend); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(short_id); + GIT_ASSERT_ARG(len >= GIT_OID_MINPREFIXLEN); error = locate_object_short_oid( &object_path, out, (loose_backend *)backend, short_id, len); @@ -759,7 +767,8 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb struct foreach_state state; loose_backend *backend = (loose_backend *) _backend; - assert(backend && cb); + GIT_ASSERT_ARG(backend); + GIT_ASSERT_ARG(cb); objects_dir = backend->objects_dir; @@ -833,7 +842,7 @@ static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backe size_t hdrlen; int error; - assert(_backend); + GIT_ASSERT_ARG(_backend); backend = (loose_backend *)_backend; *stream_out = NULL; @@ -991,7 +1000,11 @@ static int loose_backend__readstream( obj_hdr hdr; int error = 0; - assert(stream_out && len_out && type_out && _backend && oid); + GIT_ASSERT_ARG(stream_out); + GIT_ASSERT_ARG(len_out); + GIT_ASSERT_ARG(type_out); + GIT_ASSERT_ARG(_backend); + GIT_ASSERT_ARG(oid); backend = (loose_backend *)_backend; *stream_out = NULL; @@ -1108,11 +1121,7 @@ static int loose_backend__freshen( static void loose_backend__free(git_odb_backend *_backend) { - loose_backend *backend; - assert(_backend); - backend = (loose_backend *)_backend; - - git__free(backend); + git__free(_backend); } int git_odb_backend_loose( @@ -1126,7 +1135,8 @@ int git_odb_backend_loose( loose_backend *backend; size_t objects_dirlen, alloclen; - assert(backend_out && objects_dir); + GIT_ASSERT_ARG(backend_out); + GIT_ASSERT_ARG(objects_dir); objects_dirlen = strlen(objects_dir); From 3bb9916c75782f5c548285f653f1ccbb2366d900 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:33:06 +0100 Subject: [PATCH 0123/1616] odb_mempack: use GIT_ASSERT --- src/odb_mempack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odb_mempack.c b/src/odb_mempack.c index 6d20b39baed..d08356a8d44 100644 --- a/src/odb_mempack.c +++ b/src/odb_mempack.c @@ -156,7 +156,7 @@ int git_mempack_new(git_odb_backend **out) { struct memory_packer_db *db; - assert(out); + GIT_ASSERT_ARG(out); db = git__calloc(1, sizeof(struct memory_packer_db)); GIT_ERROR_CHECK_ALLOC(db); From a072a025712d5ffcac6bd017318df8ad816318a1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:34:12 +0100 Subject: [PATCH 0124/1616] odb_pack: use GIT_ASSERT --- src/odb_pack.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/odb_pack.c b/src/odb_pack.c index 86c858df111..e4ad0f4b7d7 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -358,7 +358,10 @@ static int pack_backend__read_header( struct git_pack_entry e; int error; - assert(len_p && type_p && backend && oid); + GIT_ASSERT_ARG(len_p); + GIT_ASSERT_ARG(type_p); + GIT_ASSERT_ARG(backend); + GIT_ASSERT_ARG(oid); if ((error = pack_entry_find(&e, (struct pack_backend *)backend, oid)) < 0) return error; @@ -469,7 +472,9 @@ static int pack_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb c struct pack_backend *backend; unsigned int i; - assert(_backend && cb); + GIT_ASSERT_ARG(_backend); + GIT_ASSERT_ARG(cb); + backend = (struct pack_backend *)_backend; /* Make sure we know about the packfiles */ @@ -488,7 +493,7 @@ static int pack_backend__writepack_append(struct git_odb_writepack *_writepack, { struct pack_writepack *writepack = (struct pack_writepack *)_writepack; - assert(writepack); + GIT_ASSERT_ARG(writepack); return git_indexer_append(writepack->indexer, data, size, stats); } @@ -497,16 +502,19 @@ static int pack_backend__writepack_commit(struct git_odb_writepack *_writepack, { struct pack_writepack *writepack = (struct pack_writepack *)_writepack; - assert(writepack); + GIT_ASSERT_ARG(writepack); return git_indexer_commit(writepack->indexer, stats); } static void pack_backend__writepack_free(struct git_odb_writepack *_writepack) { - struct pack_writepack *writepack = (struct pack_writepack *)_writepack; + struct pack_writepack *writepack; + + if (!_writepack) + return; - assert(writepack); + writepack = (struct pack_writepack *)_writepack; git_indexer_free(writepack->indexer); git__free(writepack); @@ -522,7 +530,8 @@ static int pack_backend__writepack(struct git_odb_writepack **out, struct pack_backend *backend; struct pack_writepack *writepack; - assert(out && _backend); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(_backend); *out = NULL; @@ -555,7 +564,8 @@ static void pack_backend__free(git_odb_backend *_backend) struct pack_backend *backend; size_t i; - assert(_backend); + if (!_backend) + return; backend = (struct pack_backend *)_backend; From 87d378961cc05daeefefdb1023a738249b8c6cf6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 17:35:19 +0100 Subject: [PATCH 0125/1616] oid: use GIT_ASSERT --- src/oid.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/oid.c b/src/oid.c index a8ad3d2ee0d..893e2fc0fb0 100644 --- a/src/oid.c +++ b/src/oid.c @@ -26,7 +26,8 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length) size_t p; int v; - assert(out && str); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(str); if (!length) return oid_error_invalid("too short"); @@ -316,7 +317,7 @@ git_oid_shorten *git_oid_shorten_new(size_t min_length) { git_oid_shorten *os; - assert((size_t)((int)min_length) == min_length); + GIT_ASSERT_ARG_WITH_RETVAL((size_t)((int)min_length) == min_length, NULL); os = git__calloc(1, sizeof(git_oid_shorten)); if (os == NULL) From 7cd0bf65671a1a486242403aaa0237ed5dec9d2b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 18:26:52 +0100 Subject: [PATCH 0126/1616] pack: use GIT_ASSERT --- src/indexer.c | 4 ++-- src/pack-objects.c | 7 +++---- src/pack.c | 21 +++++++++++---------- src/pack.h | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/indexer.c b/src/indexer.c index b6a2ee45efa..7b3db310100 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -900,8 +900,8 @@ static int inject_object(git_indexer *idx, git_oid *id) entry->crc = crc32(0L, Z_NULL, 0); /* Write out the object header */ - hdr_len = git_packfile__object_header(hdr, len, git_odb_object_type(obj)); - if ((error = append_to_pack(idx, hdr, hdr_len)) < 0) + if ((error = git_packfile__object_header(&hdr_len, hdr, len, git_odb_object_type(obj))) < 0 || + (error = append_to_pack(idx, hdr, hdr_len)) < 0) goto cleanup; idx->pack->mwf.size += hdr_len; diff --git a/src/pack-objects.c b/src/pack-objects.c index 9679e8e23f9..abc636b5b6e 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -347,10 +347,9 @@ static int write_object( } /* Write header */ - hdr_len = git_packfile__object_header(hdr, data_len, type); - - if ((error = write_cb(hdr, hdr_len, cb_data)) < 0 || - (error = git_hash_update(&pb->ctx, hdr, hdr_len)) < 0) + if ((error = git_packfile__object_header(&hdr_len, hdr, data_len, type)) < 0 || + (error = write_cb(hdr, hdr_len, cb_data)) < 0 || + (error = git_hash_update(&pb->ctx, hdr, hdr_len)) < 0) goto done; if (type == GIT_OBJECT_REF_DELTA) { diff --git a/src/pack.c b/src/pack.c index 1b5cf670f8d..982ad1770a5 100644 --- a/src/pack.c +++ b/src/pack.c @@ -67,7 +67,6 @@ static void free_cache_object(void *o) git_pack_cache_entry *e = (git_pack_cache_entry *)o; if (e != NULL) { - assert(e->refcount.val == 0); git__free(e->raw.data); git__free(e); } @@ -311,8 +310,9 @@ static int pack_index_open(struct git_pack_file *p) if (p->index_version > -1) return 0; + /* checked by git_pack_file alloc */ name_len = strlen(p->pack_name); - assert(name_len > strlen(".pack")); /* checked by git_pack_file alloc */ + GIT_ASSERT(name_len > strlen(".pack")); if (git_buf_init(&idx_name, name_len) < 0) return -1; @@ -372,12 +372,12 @@ static unsigned char *pack_window_open( * - each byte afterwards: low seven bits are size continuation, * with the high bit being "size continues" */ -size_t git_packfile__object_header(unsigned char *hdr, size_t size, git_object_t type) +int git_packfile__object_header(size_t *out, unsigned char *hdr, size_t size, git_object_t type) { unsigned char *hdr_base; unsigned char c; - assert(type >= GIT_OBJECT_COMMIT && type <= GIT_OBJECT_REF_DELTA); + GIT_ASSERT_ARG(type >= GIT_OBJECT_COMMIT && type <= GIT_OBJECT_REF_DELTA); /* TODO: add support for chunked objects; see git.git 6c0d19b1 */ @@ -392,7 +392,8 @@ size_t git_packfile__object_header(unsigned char *hdr, size_t size, git_object_t } *hdr++ = c; - return (hdr - hdr_base); + *out = (hdr - hdr_base); + return 0; } @@ -899,7 +900,7 @@ int get_delta_base( off64_t base_offset; git_oid unused; - assert(delta_base_out); + GIT_ASSERT_ARG(delta_base_out); base_info = pack_window_open(p, w_curs, *curpos, &left); /* Assumption: the only reason this would fail is because the file is too small */ @@ -1211,8 +1212,7 @@ int git_pack_foreach_entry( if ((error = pack_index_open(p)) < 0) return error; - assert(p->index_map.data); - + GIT_ASSERT(p->index_map.data); index = p->index_map.data; } @@ -1299,7 +1299,8 @@ static int pack_entry_find_offset( if ((error = pack_index_open(p)) < 0) return error; - assert(p->index_map.data); + + GIT_ASSERT(p->index_map.data); } index = p->index_map.data; @@ -1388,7 +1389,7 @@ int git_pack_entry_find( git_oid found_oid; int error; - assert(p); + GIT_ASSERT_ARG(p); if (len == GIT_OID_HEXSZ && p->num_bad_objects) { unsigned i; diff --git a/src/pack.h b/src/pack.h index cebfcd1bd29..544a5d286ac 100644 --- a/src/pack.h +++ b/src/pack.h @@ -133,7 +133,7 @@ typedef struct git_packfile_stream { git_mwindow *mw; } git_packfile_stream; -size_t git_packfile__object_header(unsigned char *hdr, size_t size, git_object_t type); +int git_packfile__object_header(size_t *out, unsigned char *hdr, size_t size, git_object_t type); int git_packfile__name(char **out, const char *path); From 4dba9303359e45cb5a7cfe58740131140760b122 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 22 Nov 2020 10:42:41 +0000 Subject: [PATCH 0127/1616] pack-objects: use GIT_ASSERT --- src/pack-objects.c | 54 +++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/src/pack-objects.c b/src/pack-objects.c index abc636b5b6e..8ebb8cf430a 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -48,18 +48,10 @@ struct walk_object { }; #ifdef GIT_THREADS - -#define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) do { \ - int result = git_mutex_##op(&(pb)->mtx); \ - assert(!result); \ - GIT_UNUSED(result); \ - } while (0) - +# define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) git_mutex_##op(&(pb)->mtx) #else - -#define GIT_PACKBUILDER__MUTEX_OP(pb,mtx,op) GIT_UNUSED(pb) - -#endif /* GIT_THREADS */ +# define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) GIT_UNUSED(pb) +#endif #define git_packbuilder__cache_lock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, cache_mutex, lock) #define git_packbuilder__cache_unlock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, cache_mutex, unlock) @@ -177,13 +169,13 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo) unsigned int git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n) { - assert(pb); + GIT_ASSERT_ARG(pb); #ifdef GIT_THREADS pb->nr_threads = n; #else GIT_UNUSED(n); - assert(1 == pb->nr_threads); + GIT_ASSERT(pb->nr_threads == 1); #endif return pb->nr_threads; @@ -211,7 +203,8 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid, size_t newsize; int ret; - assert(pb && oid); + GIT_ASSERT_ARG(pb); + GIT_ASSERT_ARG(oid); /* If the object already exists in the hash table, then we don't * have any work to do */ @@ -851,10 +844,11 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg, } } - git_packbuilder__cache_lock(pb); + GIT_ASSERT(git_packbuilder__cache_lock(pb) == 0); + if (trg_object->delta_data) { git__free(trg_object->delta_data); - assert(pb->delta_cache_size >= trg_object->delta_size); + GIT_ASSERT(pb->delta_cache_size >= trg_object->delta_size); pb->delta_cache_size -= trg_object->delta_size; trg_object->delta_data = NULL; } @@ -862,7 +856,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg, bool overflow = git__add_sizet_overflow( &pb->delta_cache_size, pb->delta_cache_size, delta_size); - git_packbuilder__cache_unlock(pb); + GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0); if (overflow) { git__free(delta_buf); @@ -873,7 +867,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg, GIT_ERROR_CHECK_ALLOC(trg_object->delta_data); } else { /* create delta when writing the pack */ - git_packbuilder__cache_unlock(pb); + GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0); git__free(delta_buf); } @@ -961,9 +955,9 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list, struct unpacked *n = array + idx; size_t max_depth, j, best_base = SIZE_MAX; - git_packbuilder__progress_lock(pb); + GIT_ASSERT(git_packbuilder__progress_lock(pb) == 0); if (!*list_size) { - git_packbuilder__progress_unlock(pb); + GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0); break; } @@ -972,7 +966,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list, po = *list++; (*list_size)--; - git_packbuilder__progress_unlock(pb); + GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0); mem_usage -= free_unpacked(n); n->object = po; @@ -1047,10 +1041,10 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list, po->z_delta_size = zbuf.size; git_buf_clear(&zbuf); - git_packbuilder__cache_lock(pb); + GIT_ASSERT(git_packbuilder__cache_lock(pb) == 0); pb->delta_cache_size -= po->delta_size; pb->delta_cache_size += po->z_delta_size; - git_packbuilder__cache_unlock(pb); + GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0); } /* @@ -1128,10 +1122,10 @@ static void *threaded_find_deltas(void *arg) ; /* TODO */ } - git_packbuilder__progress_lock(me->pb); + GIT_ASSERT_WITH_RETVAL(git_packbuilder__progress_lock(me->pb) == 0, NULL); me->working = 0; git_cond_signal(&me->pb->progress_cond); - git_packbuilder__progress_unlock(me->pb); + GIT_ASSERT_WITH_RETVAL(git_packbuilder__progress_unlock(me->pb) == 0, NULL); if (git_mutex_lock(&me->mutex)) { git_error_set(GIT_ERROR_THREAD, "unable to lock packfile condition mutex"); @@ -1236,7 +1230,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list, * 'working' flag from 1 -> 0. This indicates that it is * ready to receive more work using our work-stealing * algorithm. */ - git_packbuilder__progress_lock(pb); + GIT_ASSERT(git_packbuilder__progress_lock(pb) == 0); for (;;) { for (i = 0; !target && i < pb->nr_threads; i++) if (!p[i].working) @@ -1279,7 +1273,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list, target->list_size = sub_size; target->remaining = sub_size; target->working = 1; - git_packbuilder__progress_unlock(pb); + GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0); if (git_mutex_lock(&target->mutex)) { git_error_set(GIT_ERROR_THREAD, "unable to lock packfile condition mutex"); @@ -1490,7 +1484,8 @@ int git_packbuilder_insert_recur(git_packbuilder *pb, const git_oid *id, const c git_object *obj; int error; - assert(pb && id); + GIT_ASSERT_ARG(pb); + GIT_ASSERT_ARG(id); if ((error = git_object_lookup(&obj, pb->repo, id, GIT_OBJECT_ANY)) < 0) return error; @@ -1731,7 +1726,8 @@ int git_packbuilder_insert_walk(git_packbuilder *pb, git_revwalk *walk) git_oid id; struct walk_object *obj; - assert(pb && walk); + GIT_ASSERT_ARG(pb); + GIT_ASSERT_ARG(walk); if ((error = mark_edges_uninteresting(pb, walk->user_input)) < 0) return error; From 1a724625e76d9127cf03fb780a924650345f7f60 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 18:27:51 +0100 Subject: [PATCH 0128/1616] patch: use GIT_ASSERT --- src/patch.c | 16 +++++++++------- src/patch_generate.c | 4 ++-- src/patch_parse.c | 3 ++- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/patch.c b/src/patch.c index 82181bb3d9e..8f8bd7a08e3 100644 --- a/src/patch.c +++ b/src/patch.c @@ -65,7 +65,7 @@ size_t git_patch_size( { size_t out; - assert(patch); + GIT_ASSERT_ARG(patch); out = patch->content_size; @@ -129,13 +129,13 @@ int git_patch_line_stats( const git_diff_delta *git_patch_get_delta(const git_patch *patch) { - assert(patch); + GIT_ASSERT_ARG_WITH_RETVAL(patch, NULL); return patch->delta; } size_t git_patch_num_hunks(const git_patch *patch) { - assert(patch); + GIT_ASSERT_ARG(patch); return git_array_size(patch->hunks); } @@ -152,7 +152,7 @@ int git_patch_get_hunk( size_t hunk_idx) { git_patch_hunk *hunk; - assert(patch); + GIT_ASSERT_ARG(patch); hunk = git_array_get(patch->hunks, hunk_idx); @@ -170,7 +170,7 @@ int git_patch_get_hunk( int git_patch_num_lines_in_hunk(const git_patch *patch, size_t hunk_idx) { git_patch_hunk *hunk; - assert(patch); + GIT_ASSERT_ARG(patch); if (!(hunk = git_array_get(patch->hunks, hunk_idx))) return patch_error_outofrange("hunk"); @@ -186,7 +186,7 @@ int git_patch_get_line_in_hunk( git_patch_hunk *hunk; git_diff_line *line; - assert(patch); + GIT_ASSERT_ARG(patch); if (!(hunk = git_array_get(patch->hunks, hunk_idx))) { if (out) *out = NULL; @@ -206,7 +206,9 @@ int git_patch_get_line_in_hunk( int git_patch_from_diff(git_patch **out, git_diff *diff, size_t idx) { - assert(out && diff && diff->patch_fn); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(diff); + GIT_ASSERT_ARG(diff->patch_fn); return diff->patch_fn(out, diff, idx); } diff --git a/src/patch_generate.c b/src/patch_generate.c index 6dd61c18f11..38cd714a980 100644 --- a/src/patch_generate.c +++ b/src/patch_generate.c @@ -561,7 +561,7 @@ static int patch_from_sources( patch_generated_with_delta *pd; git_xdiff_output xo; - assert(out); + GIT_ASSERT_ARG(out); *out = NULL; if ((error = patch_generated_with_delta_alloc( @@ -840,7 +840,7 @@ static int patch_generated_line_cb( GIT_UNUSED(hunk_); hunk = git_array_last(patch->base.hunks); - assert(hunk); /* programmer error if no hunk is available */ + GIT_ASSERT(hunk); /* programmer error if no hunk is available */ line = git_array_alloc(patch->base.lines); GIT_ERROR_CHECK_ALLOC(line); diff --git a/src/patch_parse.c b/src/patch_parse.c index 2bf94c2cb07..2cc5c599517 100644 --- a/src/patch_parse.c +++ b/src/patch_parse.c @@ -1168,7 +1168,8 @@ int git_patch_parse( size_t start, used; int error = 0; - assert(out && ctx); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(ctx); *out = NULL; From 2cfa31c4179ea6722bbf85043428068aa8a0e58f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 18:30:07 +0100 Subject: [PATCH 0129/1616] path: remove unused git_path_topdir --- src/path.c | 18 ------------------ src/path.h | 2 -- tests/core/path.c | 28 +--------------------------- 3 files changed, 1 insertion(+), 47 deletions(-) diff --git a/src/path.c b/src/path.c index f271c532cd0..a456fefc89f 100644 --- a/src/path.c +++ b/src/path.c @@ -274,24 +274,6 @@ size_t git_path_basename_offset(git_buf *buffer) return 0; } -const char *git_path_topdir(const char *path) -{ - size_t len; - ssize_t i; - - assert(path); - len = strlen(path); - - if (!len || path[len - 1] != '/') - return NULL; - - for (i = (ssize_t)len - 2; i >= 0; --i) - if (path[i] == '/') - break; - - return &path[i + 1]; -} - int git_path_root(const char *path) { int offset = 0, prefix_len; diff --git a/src/path.h b/src/path.h index ed6b93574f0..bfef1b8a819 100644 --- a/src/path.h +++ b/src/path.h @@ -67,8 +67,6 @@ extern int git_path_basename_r(git_buf *buffer, const char *path); */ extern size_t git_path_basename_offset(git_buf *buffer); -extern const char *git_path_topdir(const char *path); - /** * Find offset to root of path if path has one. * diff --git a/tests/core/path.c b/tests/core/path.c index 2e5a4ab24c8..eac3573fea7 100644 --- a/tests/core/path.c +++ b/tests/core/path.c @@ -31,15 +31,6 @@ check_basename(const char *A, const char *B) git__free(base2); } -static void -check_topdir(const char *A, const char *B) -{ - const char *dir; - - cl_assert((dir = git_path_topdir(A)) != NULL); - cl_assert_equal_s(B, dir); -} - static void check_joinpath(const char *path_a, const char *path_b, const char *expected_path) { @@ -119,23 +110,6 @@ void test_core_path__01_basename(void) check_basename(REP1024("/abc"), "abc"); } -/* get the latest component in a path */ -void test_core_path__02_topdir(void) -{ - check_topdir(".git/", ".git/"); - check_topdir("/.git/", ".git/"); - check_topdir("usr/local/.git/", ".git/"); - check_topdir("./.git/", ".git/"); - check_topdir("/usr/.git/", ".git/"); - check_topdir("/", "/"); - check_topdir("a/", "a/"); - - cl_assert(git_path_topdir("/usr/.git") == NULL); - cl_assert(git_path_topdir(".") == NULL); - cl_assert(git_path_topdir("") == NULL); - cl_assert(git_path_topdir("a") == NULL); -} - /* properly join path components */ void test_core_path__05_joins(void) { @@ -285,7 +259,7 @@ void test_core_path__08_self_join(void) cl_git_pass(git_buf_joinpath(&path, path.ptr + 4, "somethinglongenoughtorealloc")); cl_assert_equal_s(path.ptr, "/baz/somethinglongenoughtorealloc"); cl_assert(asize < path.asize); - + git_buf_dispose(&path); } From 16b1a7560b74c6d6f9eafe8860e7122ee0e0f5da Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 18:33:55 +0100 Subject: [PATCH 0130/1616] path: use GIT_ASSERT --- src/path.c | 67 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/src/path.c b/src/path.c index a456fefc89f..dde3efb6387 100644 --- a/src/path.c +++ b/src/path.c @@ -307,7 +307,9 @@ int git_path_root(const char *path) static void path_trim_slashes(git_buf *path) { int ceiling = git_path_root(path->ptr) + 1; - assert(ceiling >= 0); + + if (ceiling < 0) + return; while (path->size > (size_t)ceiling) { if (path->ptr[path->size-1] != '/') @@ -323,7 +325,8 @@ int git_path_join_unrooted( { ssize_t root; - assert(path && path_out); + GIT_ASSERT_ARG(path_out); + GIT_ASSERT_ARG(path); root = (ssize_t)git_path_root(path); @@ -371,7 +374,8 @@ int git_path_prettify(git_buf *path_out, const char *path, const char *base) { char buf[GIT_PATH_MAX]; - assert(path && path_out); + GIT_ASSERT_ARG(path_out); + GIT_ASSERT_ARG(path); /* construct path if needed */ if (base != NULL && git_path_root(path) < 0) { @@ -422,7 +426,9 @@ void git_path_string_to_dir(char* path, size_t size) int git__percent_decode(git_buf *decoded_out, const char *input) { int len, hi, lo, i; - assert(decoded_out && input); + + GIT_ASSERT_ARG(decoded_out); + GIT_ASSERT_ARG(input); len = (int)strlen(input); git_buf_clear(decoded_out); @@ -483,7 +489,8 @@ int git_path_fromurl(git_buf *local_path_out, const char *file_url) { int offset; - assert(local_path_out && file_url); + GIT_ASSERT_ARG(local_path_out); + GIT_ASSERT_ARG(file_url); if ((offset = local_file_url_prefixlen(file_url)) < 0 || file_url[offset] == '\0' || file_url[offset] == '/') @@ -508,7 +515,8 @@ int git_path_walk_up( ssize_t stop = 0, scan; char oldc = '\0'; - assert(path && cb); + GIT_ASSERT_ARG(path); + GIT_ASSERT_ARG(cb); if (ceiling != NULL) { if (git__prefixcmp(path->ptr, ceiling) == 0) @@ -563,7 +571,7 @@ int git_path_walk_up( bool git_path_exists(const char *path) { - assert(path); + GIT_ASSERT_ARG_WITH_RETVAL(path, false); return p_access(path, F_OK) == 0; } @@ -580,7 +588,7 @@ bool git_path_isfile(const char *path) { struct stat st; - assert(path); + GIT_ASSERT_ARG_WITH_RETVAL(path, false); if (p_stat(path, &st) < 0) return false; @@ -591,7 +599,7 @@ bool git_path_islink(const char *path) { struct stat st; - assert(path); + GIT_ASSERT_ARG_WITH_RETVAL(path, false); if (p_lstat(path, &st) < 0) return false; @@ -1193,7 +1201,8 @@ int git_path_diriter_init( if (is_win7_or_later < 0) is_win7_or_later = git_has_win32_version(6, 1, 0); - assert(diriter && path); + GIT_ASSERT_ARG(diriter); + GIT_ASSERT_ARG(path); memset(diriter, 0, sizeof(git_path_diriter)); diriter->handle = INVALID_HANDLE_VALUE; @@ -1293,9 +1302,10 @@ int git_path_diriter_filename( size_t *out_len, git_path_diriter *diriter) { - assert(out && out_len && diriter); - - assert(diriter->path_utf8.size > diriter->parent_utf8_len); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); + GIT_ASSERT(diriter->path_utf8.size > diriter->parent_utf8_len); *out = &diriter->path_utf8.ptr[diriter->parent_utf8_len+1]; *out_len = diriter->path_utf8.size - diriter->parent_utf8_len - 1; @@ -1307,7 +1317,9 @@ int git_path_diriter_fullpath( size_t *out_len, git_path_diriter *diriter) { - assert(out && out_len && diriter); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); *out = diriter->path_utf8.ptr; *out_len = diriter->path_utf8.size; @@ -1316,7 +1328,8 @@ int git_path_diriter_fullpath( int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter) { - assert(out && diriter); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(diriter); return git_win32__file_attribute_to_stat(out, (WIN32_FILE_ATTRIBUTE_DATA *)&diriter->current, @@ -1343,7 +1356,8 @@ int git_path_diriter_init( const char *path, unsigned int flags) { - assert(diriter && path); + GIT_ASSERT_ARG(diriter); + GIT_ASSERT_ARG(path); memset(diriter, 0, sizeof(git_path_diriter)); @@ -1383,7 +1397,7 @@ int git_path_diriter_next(git_path_diriter *diriter) bool skip_dot = !(diriter->flags & GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT); int error = 0; - assert(diriter); + GIT_ASSERT_ARG(diriter); errno = 0; @@ -1426,9 +1440,10 @@ int git_path_diriter_filename( size_t *out_len, git_path_diriter *diriter) { - assert(out && out_len && diriter); - - assert(diriter->path.size > diriter->parent_len); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); + GIT_ASSERT(diriter->path.size > diriter->parent_len); *out = &diriter->path.ptr[diriter->parent_len+1]; *out_len = diriter->path.size - diriter->parent_len - 1; @@ -1440,7 +1455,9 @@ int git_path_diriter_fullpath( size_t *out_len, git_path_diriter *diriter) { - assert(out && out_len && diriter); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); *out = diriter->path.ptr; *out_len = diriter->path.size; @@ -1449,7 +1466,8 @@ int git_path_diriter_fullpath( int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter) { - assert(out && diriter); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(diriter); return git_path_lstat(diriter->path.ptr, out); } @@ -1485,7 +1503,8 @@ int git_path_dirload( char *dup; int error; - assert(contents && path); + GIT_ASSERT_ARG(contents); + GIT_ASSERT_ARG(path); if ((error = git_path_diriter_init(&iter, path, flags)) < 0) return error; @@ -1494,7 +1513,7 @@ int git_path_dirload( if ((error = git_path_diriter_fullpath(&name, &name_len, &iter)) < 0) break; - assert(name_len > prefix_len); + GIT_ASSERT(name_len > prefix_len); dup = git__strndup(name + prefix_len, name_len - prefix_len); GIT_ERROR_CHECK_ALLOC(dup); From 4b093e75f280eda8cd4faa9c628bd0d74ebb6d6f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 18:36:23 +0100 Subject: [PATCH 0131/1616] pathspec: use GIT_ASSERT --- src/pathspec.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/pathspec.c b/src/pathspec.c index 83f776c91db..8b17a6e2774 100644 --- a/src/pathspec.c +++ b/src/pathspec.c @@ -289,7 +289,8 @@ int git_pathspec_matches_path( bool no_fnmatch = (flags & GIT_PATHSPEC_NO_GLOB) != 0; bool casefold = (flags & GIT_PATHSPEC_IGNORE_CASE) != 0; - assert(ps && path); + GIT_ASSERT_ARG(ps); + GIT_ASSERT_ARG(path); return (0 != git_pathspec__match( &ps->pathspec, path, no_fnmatch, casefold, NULL, NULL)); @@ -526,7 +527,7 @@ int git_pathspec_match_workdir( git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT; int error = 0; - assert(repo); + GIT_ASSERT_ARG(repo); iter_opts.flags = pathspec_match_iter_flags(flags); @@ -548,7 +549,7 @@ int git_pathspec_match_index( git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT; int error = 0; - assert(index); + GIT_ASSERT_ARG(index); iter_opts.flags = pathspec_match_iter_flags(flags); @@ -570,7 +571,7 @@ int git_pathspec_match_tree( git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT; int error = 0; - assert(tree); + GIT_ASSERT_ARG(tree); iter_opts.flags = pathspec_match_iter_flags(flags); @@ -598,7 +599,7 @@ int git_pathspec_match_diff( const git_diff_delta *delta, **match; git_bitvec used_patterns; - assert(diff); + GIT_ASSERT_ARG(diff); if (git_bitvec_init(&used_patterns, patterns->length) < 0) return -1; From 9502f8e9fe69635a3e8636b0413ab23c9a6cf07d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 19:13:07 +0100 Subject: [PATCH 0132/1616] pool: use GIT_ASSERT --- src/pool.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/pool.c b/src/pool.c index 0c423dd3a6c..16ffa398d65 100644 --- a/src/pool.c +++ b/src/pool.c @@ -36,8 +36,8 @@ int git_pool_global_init(void) int git_pool_init(git_pool *pool, size_t item_size) { - assert(pool); - assert(item_size >= 1); + GIT_ASSERT_ARG(pool); + GIT_ASSERT_ARG(item_size >= 1); memset(pool, 0, sizeof(git_pool)); pool->item_size = item_size; @@ -131,8 +131,8 @@ static int git_pool__ptr_cmp(const void * a, const void * b) int git_pool_init(git_pool *pool, size_t item_size) { - assert(pool); - assert(item_size >= 1); + GIT_ASSERT_ARG(pool); + GIT_ASSERT_ARG(item_size >= 1); memset(pool, 0, sizeof(git_pool)); pool->item_size = item_size; @@ -205,7 +205,9 @@ char *git_pool_strndup(git_pool *pool, const char *str, size_t n) { char *ptr = NULL; - assert(pool && str && pool->item_size == sizeof(char)); + GIT_ASSERT_ARG_WITH_RETVAL(pool, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(str, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(pool->item_size == sizeof(char), NULL); if (n == SIZE_MAX) return NULL; @@ -220,7 +222,10 @@ char *git_pool_strndup(git_pool *pool, const char *str, size_t n) char *git_pool_strdup(git_pool *pool, const char *str) { - assert(pool && str && pool->item_size == sizeof(char)); + GIT_ASSERT_ARG_WITH_RETVAL(pool, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(str, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(pool->item_size == sizeof(char), NULL); + return git_pool_strndup(pool, str, strlen(str)); } @@ -234,7 +239,8 @@ char *git_pool_strcat(git_pool *pool, const char *a, const char *b) void *ptr; size_t len_a, len_b, total; - assert(pool && pool->item_size == sizeof(char)); + GIT_ASSERT_ARG_WITH_RETVAL(pool, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(pool->item_size == sizeof(char), NULL); len_a = a ? strlen(a) : 0; len_b = b ? strlen(b) : 0; From 9cd6481e5ded04dba277925e6084f0d84ad537a8 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 19:14:35 +0100 Subject: [PATCH 0133/1616] posix: use GIT_ASSERT --- src/posix.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/posix.c b/src/posix.c index fbaa7c3caab..9cd96d2c832 100644 --- a/src/posix.c +++ b/src/posix.c @@ -129,7 +129,8 @@ int p_getcwd(char *buffer_out, size_t size) { char *cwd_buffer; - assert(buffer_out && size > 0); + GIT_ASSERT_ARG(buffer_out); + GIT_ASSERT_ARG(size > 0); cwd_buffer = getcwd(buffer_out, size); @@ -196,7 +197,7 @@ int p_write(git_file fd, const void *buf, size_t cnt) while (cnt) { ssize_t r; #ifdef GIT_WIN32 - assert((size_t)((unsigned int)cnt) == cnt); + GIT_ASSERT((size_t)((unsigned int)cnt) == cnt); r = write(fd, b, (unsigned int)cnt); #else r = write(fd, b, cnt); @@ -263,7 +264,7 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset int p_munmap(git_map *map) { - assert(map != NULL); + GIT_ASSERT_ARG(map); git__free(map->data); return 0; From 00e57f646d9afb3c434b3ee1d4b9c5462e7ab617 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 19:15:11 +0100 Subject: [PATCH 0134/1616] reader: use GIT_ASSERT --- src/reader.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/reader.c b/src/reader.c index 90f700a0011..9672473e852 100644 --- a/src/reader.c +++ b/src/reader.c @@ -61,7 +61,8 @@ int git_reader_for_tree(git_reader **out, git_tree *tree) { tree_reader *reader; - assert(out && tree); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(tree); reader = git__calloc(1, sizeof(tree_reader)); GIT_ERROR_CHECK_ALLOC(reader); @@ -158,7 +159,8 @@ int git_reader_for_workdir( workdir_reader *reader; int error; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); reader = git__calloc(1, sizeof(workdir_reader)); GIT_ERROR_CHECK_ALLOC(reader); @@ -223,7 +225,8 @@ int git_reader_for_index( index_reader *reader; int error; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); reader = git__calloc(1, sizeof(index_reader)); GIT_ERROR_CHECK_ALLOC(reader); @@ -251,7 +254,9 @@ int git_reader_read( git_reader *reader, const char *filename) { - assert(out && reader && filename); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(reader); + GIT_ASSERT_ARG(filename); return reader->read(out, out_id, out_filemode, reader, filename); } From 690ff9cd8d3d4ecf564693a10b150a8684ad06e6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 19:17:58 +0100 Subject: [PATCH 0135/1616] rebase: use GIT_ASSERT --- src/rebase.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/rebase.c b/src/rebase.c index 7c656119563..bf6581a1b18 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -186,8 +186,8 @@ static git_rebase_operation *rebase_operation_alloc( { git_rebase_operation *operation; - assert((type == GIT_REBASE_OPERATION_EXEC) == !id); - assert((type == GIT_REBASE_OPERATION_EXEC) == !!exec); + GIT_ASSERT_WITH_RETVAL((type == GIT_REBASE_OPERATION_EXEC) == !id, NULL); + GIT_ASSERT_WITH_RETVAL((type == GIT_REBASE_OPERATION_EXEC) == !!exec, NULL); if ((operation = git_array_alloc(rebase->operations)) == NULL) return NULL; @@ -301,7 +301,7 @@ int git_rebase_open( size_t state_path_len; int error; - assert(repo); + GIT_ASSERT_ARG(repo); if ((error = rebase_check_versions(given_opts)) < 0) return error; @@ -701,7 +701,8 @@ int git_rebase_init( bool inmemory = (given_opts && given_opts->inmemory); int error; - assert(repo && (upstream || onto)); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(upstream || onto); *out = NULL; @@ -912,7 +913,8 @@ int git_rebase_next( { int error; - assert(out && rebase); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(rebase); if ((error = rebase_movenext(rebase)) < 0) return error; @@ -931,7 +933,9 @@ int git_rebase_inmemory_index( git_index **out, git_rebase *rebase) { - assert(out && rebase && rebase->index); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(rebase); + GIT_ASSERT_ARG(rebase->index); GIT_REFCOUNT_INC(rebase->index); *out = rebase->index; @@ -1006,12 +1010,12 @@ static int rebase_commit__create( } if (git_buf_is_allocated(&commit_signature)) { - assert(git_buf_contains_nul(&commit_signature)); + GIT_ASSERT(git_buf_contains_nul(&commit_signature)); commit_signature_string = git_buf_cstr(&commit_signature); } if (git_buf_is_allocated(&signature_field)) { - assert(git_buf_contains_nul(&signature_field)); + GIT_ASSERT(git_buf_contains_nul(&signature_field)); signature_field_string = git_buf_cstr(&signature_field); } @@ -1055,7 +1059,7 @@ static int rebase_commit_merge( int error; operation = git_array_get(rebase->operations, rebase->current); - assert(operation); + GIT_ASSERT(operation); if ((error = rebase_ensure_not_dirty(rebase->repo, false, true, GIT_EUNMERGED)) < 0 || (error = git_repository_head(&head, rebase->repo)) < 0 || @@ -1095,9 +1099,9 @@ static int rebase_commit_inmemory( git_commit *commit = NULL; int error = 0; - assert(rebase->index); - assert(rebase->last_commit); - assert(rebase->current < rebase->operations.size); + GIT_ASSERT_ARG(rebase->index); + GIT_ASSERT_ARG(rebase->last_commit); + GIT_ASSERT_ARG(rebase->current < rebase->operations.size); if ((error = rebase_commit__create(&commit, rebase, rebase->index, rebase->last_commit, author, committer, message_encoding, message)) < 0) @@ -1125,7 +1129,8 @@ int git_rebase_commit( { int error; - assert(rebase && committer); + GIT_ASSERT_ARG(rebase); + GIT_ASSERT_ARG(committer); if (rebase->inmemory) error = rebase_commit_inmemory( @@ -1145,7 +1150,7 @@ int git_rebase_abort(git_rebase *rebase) git_commit *orig_head_commit = NULL; int error; - assert(rebase); + GIT_ASSERT_ARG(rebase); if (rebase->inmemory) return 0; @@ -1358,7 +1363,7 @@ int git_rebase_finish( { int error = 0; - assert(rebase); + GIT_ASSERT_ARG(rebase); if (rebase->inmemory) return 0; @@ -1373,14 +1378,17 @@ int git_rebase_finish( } const char *git_rebase_orig_head_name(git_rebase *rebase) { + GIT_ASSERT_ARG_WITH_RETVAL(rebase, NULL); return rebase->orig_head_name; } const git_oid *git_rebase_orig_head_id(git_rebase *rebase) { + GIT_ASSERT_ARG_WITH_RETVAL(rebase, NULL); return &rebase->orig_head_id; } const char *git_rebase_onto_name(git_rebase *rebase) { + GIT_ASSERT_ARG_WITH_RETVAL(rebase, NULL); return rebase->onto_name; } @@ -1390,21 +1398,21 @@ const git_oid *git_rebase_onto_id(git_rebase *rebase) { size_t git_rebase_operation_entrycount(git_rebase *rebase) { - assert(rebase); + GIT_ASSERT_ARG_WITH_RETVAL(rebase, 0); return git_array_size(rebase->operations); } size_t git_rebase_operation_current(git_rebase *rebase) { - assert(rebase); + GIT_ASSERT_ARG_WITH_RETVAL(rebase, 0); return rebase->started ? rebase->current : GIT_REBASE_NO_OPERATION; } git_rebase_operation *git_rebase_operation_byindex(git_rebase *rebase, size_t idx) { - assert(rebase); + GIT_ASSERT_ARG_WITH_RETVAL(rebase, NULL); return git_array_get(rebase->operations, idx); } From 8d66d57fd342f7603a2bf110db1009914a022fac Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 19:20:01 +0100 Subject: [PATCH 0136/1616] refdb: use GIT_ASSERT --- src/refdb.c | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/refdb.c b/src/refdb.c index fb86d5ccbad..ed33de92bf2 100644 --- a/src/refdb.c +++ b/src/refdb.c @@ -24,7 +24,8 @@ int git_refdb_new(git_refdb **out, git_repository *repo) { git_refdb *db; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); db = git__calloc(1, sizeof(*db)); GIT_ERROR_CHECK_ALLOC(db); @@ -41,7 +42,8 @@ int git_refdb_open(git_refdb **out, git_repository *repo) git_refdb *db; git_refdb_backend *dir; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); *out = NULL; @@ -89,7 +91,7 @@ int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend) int git_refdb_compress(git_refdb *db) { - assert(db); + GIT_ASSERT_ARG(db); if (db->backend->compress) return db->backend->compress(db->backend); @@ -114,7 +116,9 @@ void git_refdb_free(git_refdb *db) int git_refdb_exists(int *exists, git_refdb *refdb, const char *ref_name) { - assert(exists && refdb && refdb->backend); + GIT_ASSERT_ARG(exists); + GIT_ASSERT_ARG(refdb); + GIT_ASSERT_ARG(refdb->backend); return refdb->backend->exists(exists, refdb->backend, ref_name); } @@ -124,7 +128,10 @@ int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name) git_reference *ref; int error; - assert(db && db->backend && out && ref_name); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(db->backend); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(ref_name); error = db->backend->lookup(&ref, db->backend, ref_name); if (error < 0) @@ -234,7 +241,8 @@ void git_refdb_iterator_free(git_reference_iterator *iter) int git_refdb_write(git_refdb *db, git_reference *ref, int force, const git_signature *who, const char *message, const git_oid *old_id, const char *old_target) { - assert(db && db->backend); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(db->backend); GIT_REFCOUNT_INC(db); ref->db = db; @@ -253,7 +261,9 @@ int git_refdb_rename( { int error; - assert(db && db->backend); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(db->backend); + error = db->backend->rename(out, db->backend, old_name, new_name, force, who, message); if (error < 0) return error; @@ -268,7 +278,9 @@ int git_refdb_rename( int git_refdb_delete(struct git_refdb *db, const char *ref_name, const git_oid *old_id, const char *old_target) { - assert(db && db->backend); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(db->backend); + return db->backend->del(db->backend, ref_name, old_id, old_target); } @@ -276,7 +288,8 @@ int git_refdb_reflog_read(git_reflog **out, git_refdb *db, const char *name) { int error; - assert(db && db->backend); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(db->backend); if ((error = db->backend->reflog_read(out, db->backend, name)) < 0) return error; @@ -368,14 +381,16 @@ int git_refdb_should_write_head_reflog(int *out, git_refdb *db, const git_refere int git_refdb_has_log(git_refdb *db, const char *refname) { - assert(db && refname); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(refname); return db->backend->has_log(db->backend, refname); } int git_refdb_ensure_log(git_refdb *db, const char *refname) { - assert(db && refname); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(refname); return db->backend->ensure_log(db->backend, refname); } @@ -389,7 +404,9 @@ int git_refdb_init_backend(git_refdb_backend *backend, unsigned int version) int git_refdb_lock(void **payload, git_refdb *db, const char *refname) { - assert(payload && db && refname); + GIT_ASSERT_ARG(payload); + GIT_ASSERT_ARG(db); + GIT_ASSERT_ARG(refname); if (!db->backend->lock) { git_error_set(GIT_ERROR_REFERENCE, "backend does not support locking"); @@ -401,7 +418,7 @@ int git_refdb_lock(void **payload, git_refdb *db, const char *refname) int git_refdb_unlock(git_refdb *db, void *payload, int success, int update_reflog, const git_reference *ref, const git_signature *sig, const char *message) { - assert(db); + GIT_ASSERT_ARG(db); return db->backend->unlock(db->backend, payload, success, update_reflog, ref, sig, message); } From 98a4f2789f68135d755ac2d75d147798fccdf324 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 21:38:42 +0100 Subject: [PATCH 0137/1616] refdb_fs: use GIT_ASSERT --- src/refdb_fs.c | 86 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 31 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 7e0481909db..aef5ab237ca 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -331,7 +331,7 @@ static int refdb_fs_backend__exists( git_buf ref_path = GIT_BUF_INIT; int error; - assert(backend); + GIT_ASSERT_ARG(backend); *exists = 0; @@ -472,7 +472,7 @@ static int refdb_fs_backend__lookup( refdb_fs_backend *backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); int error; - assert(backend); + GIT_ASSERT_ARG(backend); if (!(error = loose_lookup(out, backend, ref_name))) return 0; @@ -678,7 +678,7 @@ static int refdb_fs_backend__iterator( refdb_fs_iter *iter = NULL; int error; - assert(backend); + GIT_ASSERT_ARG(backend); iter = git__calloc(1, sizeof(refdb_fs_iter)); GIT_ERROR_CHECK_ALLOC(iter); @@ -783,7 +783,9 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char * git_buf ref_path = GIT_BUF_INIT; const char *basedir; - assert(file && backend && name); + GIT_ASSERT_ARG(file); + GIT_ASSERT_ARG(backend); + GIT_ASSERT_ARG(name); if (!git_path_isvalid(backend->repo, name, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) { git_error_set(GIT_ERROR_INVALID, "invalid reference name '%s'", name); @@ -819,7 +821,8 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char * static int loose_commit(git_filebuf *file, const git_reference *ref) { - assert(file && ref); + GIT_ASSERT_ARG(file); + GIT_ASSERT_ARG(ref); if (ref->type == GIT_REFERENCE_DIRECT) { char oid[GIT_OID_HEXSZ + 1]; @@ -829,7 +832,7 @@ static int loose_commit(git_filebuf *file, const git_reference *ref) } else if (ref->type == GIT_REFERENCE_SYMBOLIC) { git_filebuf_printf(file, GIT_SYMREF "%s\n", ref->target.symbolic); } else { - assert(0); /* don't let this happen */ + GIT_ASSERT(0); } return git_filebuf_commit(file); @@ -1066,7 +1069,7 @@ static int packed_write(refdb_fs_backend *backend) for (i = 0; i < git_sortedcache_entrycount(refcache); ++i) { struct packref *ref = git_sortedcache_entry(refcache, i); - assert(ref); + GIT_ASSERT(ref); if ((error = packed_find_peel(backend, ref)) < 0) goto fail; @@ -1219,7 +1222,7 @@ static int refdb_fs_backend__write( git_filebuf file = GIT_FILEBUF_INIT; int error = 0; - assert(backend); + GIT_ASSERT_ARG(backend); if ((error = reference_path_available(backend, ref->name, NULL, force)) < 0) return error; @@ -1292,7 +1295,7 @@ static int refdb_fs_backend__write_tail( return error; } -static void refdb_fs_backend__prune_refs( +static int refdb_fs_backend__prune_refs( refdb_fs_backend *backend, const char *ref_name, const char *prefix) @@ -1300,10 +1303,12 @@ static void refdb_fs_backend__prune_refs( git_buf relative_path = GIT_BUF_INIT; git_buf base_path = GIT_BUF_INIT; size_t commonlen; + int error; - assert(backend && ref_name); + GIT_ASSERT_ARG(backend); + GIT_ASSERT_ARG(ref_name); - if (git_buf_sets(&relative_path, ref_name) < 0) + if ((error = git_buf_sets(&relative_path, ref_name)) < 0) goto cleanup; git_path_squash_slashes(&relative_path); @@ -1313,20 +1318,30 @@ static void refdb_fs_backend__prune_refs( git_buf_truncate(&relative_path, commonlen); - if (prefix) { - if (git_buf_join3(&base_path, '/', backend->commonpath, prefix, git_buf_cstr(&relative_path)) < 0) - goto cleanup; - } else { - if (git_buf_joinpath(&base_path, backend->commonpath, git_buf_cstr(&relative_path)) < 0) - goto cleanup; - } + if (prefix) + error = git_buf_join3(&base_path, '/', + backend->commonpath, prefix, + git_buf_cstr(&relative_path)); + else + error = git_buf_joinpath(&base_path, + backend->commonpath, + git_buf_cstr(&relative_path)); + + if (error < 0) + goto cleanup; + + error = git_futils_rmdir_r(ref_name + commonlen, + git_buf_cstr(&base_path), + GIT_RMDIR_EMPTY_PARENTS | GIT_RMDIR_SKIP_ROOT); - git_futils_rmdir_r(ref_name + commonlen, git_buf_cstr(&base_path), GIT_RMDIR_EMPTY_PARENTS | GIT_RMDIR_SKIP_ROOT); + if (error == GIT_ENOTFOUND) + error = 0; } cleanup: git_buf_dispose(&relative_path); git_buf_dispose(&base_path); + return error; } static int refdb_fs_backend__delete( @@ -1338,7 +1353,8 @@ static int refdb_fs_backend__delete( git_filebuf file = GIT_FILEBUF_INIT; int error = 0; - assert(backend && ref_name); + GIT_ASSERT_ARG(backend); + GIT_ASSERT_ARG(ref_name); if ((error = loose_lock(&file, backend, ref_name)) < 0) return error; @@ -1424,7 +1440,7 @@ static int refdb_fs_backend__delete_tail( cleanup: git_filebuf_cleanup(file); if (error == 0) - refdb_fs_backend__prune_refs(backend, ref_name, ""); + error = refdb_fs_backend__prune_refs(backend, ref_name, ""); return error; } @@ -1444,7 +1460,7 @@ static int refdb_fs_backend__rename( git_filebuf file = GIT_FILEBUF_INIT; int error; - assert(backend); + GIT_ASSERT_ARG(backend); if ((error = reference_path_available( backend, new_name, old_name, force)) < 0 || @@ -1497,7 +1513,7 @@ static int refdb_fs_backend__compress(git_refdb_backend *_backend) int error; refdb_fs_backend *backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); - assert(backend); + GIT_ASSERT_ARG(backend); if ((error = packed_reload(backend)) < 0 || /* load the existing packfile */ (error = packed_loadloose(backend)) < 0 || /* add all the loose refs */ @@ -1511,7 +1527,8 @@ static void refdb_fs_backend__free(git_refdb_backend *_backend) { refdb_fs_backend *backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); - assert(backend); + if (!backend) + return; git_sortedcache_free(backend->refcache); git__free(backend->gitpath); @@ -1672,7 +1689,7 @@ static int refdb_reflog_fs__ensure_log(git_refdb_backend *_backend, const char * git_buf path = GIT_BUF_INIT; int error; - assert(_backend && name); + GIT_ASSERT_ARG(_backend && name); backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); repo = backend->repo; @@ -1705,7 +1722,8 @@ static int refdb_reflog_fs__has_log(git_refdb_backend *_backend, const char *nam { refdb_fs_backend *backend; - assert(_backend && name); + GIT_ASSERT_ARG(_backend); + GIT_ASSERT_ARG(name); backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); @@ -1721,7 +1739,9 @@ static int refdb_reflog_fs__read(git_reflog **out, git_refdb_backend *_backend, git_repository *repo; refdb_fs_backend *backend; - assert(out && _backend && name); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(_backend); + GIT_ASSERT_ARG(name); backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); repo = backend->repo; @@ -1838,7 +1858,8 @@ static int refdb_reflog_fs__write(git_refdb_backend *_backend, git_reflog *reflo git_buf log = GIT_BUF_INIT; git_filebuf fbuf = GIT_FILEBUF_INIT; - assert(_backend && reflog); + GIT_ASSERT_ARG(_backend); + GIT_ASSERT_ARG(reflog); backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); @@ -1960,7 +1981,9 @@ static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_ git_repository *repo; refdb_fs_backend *backend; - assert(_backend && old_name && new_name); + GIT_ASSERT_ARG(_backend); + GIT_ASSERT_ARG(old_name); + GIT_ASSERT_ARG(new_name); backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); repo = backend->repo; @@ -2037,7 +2060,8 @@ static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name git_buf path = GIT_BUF_INIT; int error; - assert(_backend && name); + GIT_ASSERT_ARG(_backend); + GIT_ASSERT_ARG(name); if ((error = retrieve_reflog_path(&path, backend->repo, name)) < 0) goto out; @@ -2048,7 +2072,7 @@ static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name if ((error = p_unlink(path.ptr)) < 0) goto out; - refdb_fs_backend__prune_refs(backend, name, GIT_REFLOG_DIR); + error = refdb_fs_backend__prune_refs(backend, name, GIT_REFLOG_DIR); out: git_buf_dispose(&path); From 7d75e1c7271a7bd07300465ee9ff63722c8dbb40 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 19:28:13 +0100 Subject: [PATCH 0138/1616] reflog: use GIT_ASSERT --- src/reflog.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/reflog.c b/src/reflog.c index 34537aa1f83..1e9c0d4f12b 100644 --- a/src/reflog.c +++ b/src/reflog.c @@ -50,7 +50,9 @@ int git_reflog_read(git_reflog **reflog, git_repository *repo, const char *name git_refdb *refdb; int error; - assert(reflog && repo && name); + GIT_ASSERT_ARG(reflog); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) return error; @@ -62,7 +64,8 @@ int git_reflog_write(git_reflog *reflog) { git_refdb *db; - assert(reflog && reflog->db); + GIT_ASSERT_ARG(reflog); + GIT_ASSERT_ARG(reflog->db); db = reflog->db; return db->backend->reflog_write(db->backend, reflog); @@ -73,7 +76,9 @@ int git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_sign const git_reflog_entry *previous; git_reflog_entry *entry; - assert(reflog && new_oid && committer); + GIT_ASSERT_ARG(reflog); + GIT_ASSERT_ARG(new_oid); + GIT_ASSERT_ARG(committer); entry = git__calloc(1, sizeof(git_reflog_entry)); GIT_ERROR_CHECK_ALLOC(entry); @@ -139,13 +144,13 @@ int git_reflog_delete(git_repository *repo, const char *name) size_t git_reflog_entrycount(git_reflog *reflog) { - assert(reflog); + GIT_ASSERT_ARG_WITH_RETVAL(reflog, 0); return reflog->entries.length; } -const git_reflog_entry * git_reflog_entry_byindex(const git_reflog *reflog, size_t idx) +const git_reflog_entry *git_reflog_entry_byindex(const git_reflog *reflog, size_t idx) { - assert(reflog); + GIT_ASSERT_ARG_WITH_RETVAL(reflog, NULL); if (idx >= reflog->entries.length) return NULL; @@ -154,27 +159,27 @@ const git_reflog_entry * git_reflog_entry_byindex(const git_reflog *reflog, size &reflog->entries, reflog_inverse_index(idx, reflog->entries.length)); } -const git_oid * git_reflog_entry_id_old(const git_reflog_entry *entry) +const git_oid *git_reflog_entry_id_old(const git_reflog_entry *entry) { - assert(entry); + GIT_ASSERT_ARG_WITH_RETVAL(entry, NULL); return &entry->oid_old; } -const git_oid * git_reflog_entry_id_new(const git_reflog_entry *entry) +const git_oid *git_reflog_entry_id_new(const git_reflog_entry *entry) { - assert(entry); + GIT_ASSERT_ARG_WITH_RETVAL(entry, NULL); return &entry->oid_cur; } -const git_signature * git_reflog_entry_committer(const git_reflog_entry *entry) +const git_signature *git_reflog_entry_committer(const git_reflog_entry *entry) { - assert(entry); + GIT_ASSERT_ARG_WITH_RETVAL(entry, NULL); return entry->committer; } -const char * git_reflog_entry_message(const git_reflog_entry *entry) +const char *git_reflog_entry_message(const git_reflog_entry *entry) { - assert(entry); + GIT_ASSERT_ARG_WITH_RETVAL(entry, NULL); return entry->msg; } From 7f0cabd1d83d9b948a943cad51a44043237baf83 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 19:33:22 +0100 Subject: [PATCH 0139/1616] refs: use GIT_ASSERT --- src/refs.c | 80 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/src/refs.c b/src/refs.c index 71594d73b3b..a954b835949 100644 --- a/src/refs.c +++ b/src/refs.c @@ -50,7 +50,8 @@ git_reference *git_reference__alloc_symbolic( { git_reference *ref; - assert(name && target); + GIT_ASSERT_ARG_WITH_RETVAL(name, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(target, NULL); ref = alloc_ref(name); if (!ref) @@ -73,7 +74,8 @@ git_reference *git_reference__alloc( { git_reference *ref; - assert(name && oid); + GIT_ASSERT_ARG_WITH_RETVAL(name, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(oid, NULL); ref = alloc_ref(name); if (!ref) @@ -94,7 +96,8 @@ git_reference *git_reference__realloc( size_t namelen, reflen; git_reference *rewrite = NULL; - assert(ptr_to_ref && name); + GIT_ASSERT_ARG_WITH_RETVAL(ptr_to_ref, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(name, NULL); namelen = strlen(name); @@ -215,7 +218,9 @@ int git_reference_lookup_resolved( git_refdb *refdb; int error = 0; - assert(ref_out && repo && name); + GIT_ASSERT_ARG(ref_out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); if ((error = reference_normalize_for_repo(normalized, repo, name, true)) < 0 || (error = git_repository_refdb__weakptr(&refdb, repo)) < 0 || @@ -307,25 +312,25 @@ int git_reference_dwim(git_reference **out, git_repository *repo, const char *re */ git_reference_t git_reference_type(const git_reference *ref) { - assert(ref); + GIT_ASSERT_ARG(ref); return ref->type; } const char *git_reference_name(const git_reference *ref) { - assert(ref); + GIT_ASSERT_ARG_WITH_RETVAL(ref, NULL); return ref->name; } git_repository *git_reference_owner(const git_reference *ref) { - assert(ref); + GIT_ASSERT_ARG_WITH_RETVAL(ref, NULL); return ref->db->repo; } const git_oid *git_reference_target(const git_reference *ref) { - assert(ref); + GIT_ASSERT_ARG_WITH_RETVAL(ref, NULL); if (ref->type != GIT_REFERENCE_DIRECT) return NULL; @@ -335,7 +340,7 @@ const git_oid *git_reference_target(const git_reference *ref) const git_oid *git_reference_target_peel(const git_reference *ref) { - assert(ref); + GIT_ASSERT_ARG_WITH_RETVAL(ref, NULL); if (ref->type != GIT_REFERENCE_DIRECT || git_oid_is_zero(&ref->peel)) return NULL; @@ -345,7 +350,7 @@ const git_oid *git_reference_target_peel(const git_reference *ref) const char *git_reference_symbolic_target(const git_reference *ref) { - assert(ref); + GIT_ASSERT_ARG_WITH_RETVAL(ref, NULL); if (ref->type != GIT_REFERENCE_SYMBOLIC) return NULL; @@ -370,8 +375,9 @@ static int reference__create( git_reference *ref = NULL; int error = 0; - assert(repo && name); - assert(symbolic || signature); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); + GIT_ASSERT_ARG(symbolic || signature); if (ref_out) *ref_out = NULL; @@ -385,7 +391,7 @@ static int reference__create( return error; if (oid != NULL) { - assert(symbolic == NULL); + GIT_ASSERT(symbolic == NULL); if (!git_object__is_valid(repo, oid, GIT_OBJECT_ANY)) { git_error_set(GIT_ERROR_REFERENCE, @@ -457,7 +463,7 @@ int git_reference_create_matching( int error; git_signature *who = NULL; - assert(id); + GIT_ASSERT_ARG(id); if ((error = git_reference__log_signature(&who, repo)) < 0) return error; @@ -492,7 +498,7 @@ int git_reference_symbolic_create_matching( int error; git_signature *who = NULL; - assert(target); + GIT_ASSERT_ARG(target); if ((error = git_reference__log_signature(&who, repo)) < 0) return error; @@ -533,7 +539,9 @@ int git_reference_set_target( int error; git_repository *repo; - assert(out && ref && id); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(ref); + GIT_ASSERT_ARG(id); repo = ref->db->repo; @@ -560,7 +568,9 @@ int git_reference_symbolic_set_target( { int error; - assert(out && ref && target); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(ref); + GIT_ASSERT_ARG(target); if ((error = ensure_is_an_updatable_symbolic_reference(ref)) < 0) return error; @@ -611,7 +621,8 @@ int git_reference_rename( git_repository *repo; int error; - assert(out && ref); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(ref); repo = git_reference_owner(ref); @@ -777,7 +788,8 @@ int git_reference_list( { git_vector ref_list; - assert(array && repo); + GIT_ASSERT_ARG(array); + GIT_ASSERT_ARG(repo); array->strings = NULL; array->count = 0; @@ -861,7 +873,8 @@ static bool is_all_caps_and_underscore(const char *name, size_t len) size_t i; char c; - assert(name && len > 0); + GIT_ASSERT_ARG(name); + GIT_ASSERT_ARG(len > 0); for (i = 0; i < len; i++) { @@ -892,7 +905,7 @@ int git_reference__normalize_name( git_path_iconv_t ic = GIT_PATH_ICONV_INIT; #endif - assert(name); + GIT_ASSERT_ARG(name); process_flags = flags; current = (char *)name; @@ -1041,7 +1054,9 @@ int git_reference_cmp( const git_reference *ref2) { git_reference_t type1, type2; - assert(ref1 && ref2); + + GIT_ASSERT_ARG(ref1); + GIT_ASSERT_ARG(ref2); type1 = git_reference_type(ref1); type2 = git_reference_type(ref2); @@ -1164,7 +1179,8 @@ int git_reference_has_log(git_repository *repo, const char *refname) int error; git_refdb *refdb; - assert(repo && refname); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(refname); if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) return error; @@ -1177,7 +1193,8 @@ int git_reference_ensure_log(git_repository *repo, const char *refname) int error; git_refdb *refdb; - assert(repo && refname); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(refname); if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) return error; @@ -1192,7 +1209,7 @@ int git_reference__is_branch(const char *ref_name) int git_reference_is_branch(const git_reference *ref) { - assert(ref); + GIT_ASSERT_ARG(ref); return git_reference__is_branch(ref->name); } @@ -1203,7 +1220,7 @@ int git_reference__is_remote(const char *ref_name) int git_reference_is_remote(const git_reference *ref) { - assert(ref); + GIT_ASSERT_ARG(ref); return git_reference__is_remote(ref->name); } @@ -1214,7 +1231,7 @@ int git_reference__is_tag(const char *ref_name) int git_reference_is_tag(const git_reference *ref) { - assert(ref); + GIT_ASSERT_ARG(ref); return git_reference__is_tag(ref->name); } @@ -1225,7 +1242,7 @@ int git_reference__is_note(const char *ref_name) int git_reference_is_note(const git_reference *ref) { - assert(ref); + GIT_ASSERT_ARG(ref); return git_reference__is_note(ref->name); } @@ -1247,7 +1264,7 @@ int git_reference_peel( git_object *target = NULL; int error; - assert(ref); + GIT_ASSERT_ARG(ref); if (ref->type == GIT_REFERENCE_DIRECT) { resolved = ref; @@ -1339,7 +1356,10 @@ int git_reference__is_unborn_head(bool *unborn, const git_reference *ref, git_re { int error; git_reference *tmp_ref; - assert(unborn && ref && repo); + + GIT_ASSERT_ARG(unborn); + GIT_ASSERT_ARG(ref); + GIT_ASSERT_ARG(repo); if (ref->type == GIT_REFERENCE_DIRECT) { *unborn = 0; From 89ee31a80ca26bae727a3762265e1e65ff0cb69b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 19:35:19 +0100 Subject: [PATCH 0140/1616] refspec: use GIT_ASSERT --- src/refspec.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/refspec.c b/src/refspec.c index a778f62b465..d0be29bf691 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -24,7 +24,8 @@ int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch) int valid = 0; unsigned int flags; - assert(refspec && input); + GIT_ASSERT_ARG(refspec); + GIT_ASSERT_ARG(input); memset(refspec, 0x0, sizeof(git_refspec)); refspec->push = !is_fetch; @@ -180,7 +181,8 @@ void git_refspec__dispose(git_refspec *refspec) int git_refspec_parse(git_refspec **out_refspec, const char *input, int is_fetch) { git_refspec *refspec; - assert(out_refspec && input); + GIT_ASSERT_ARG(out_refspec); + GIT_ASSERT_ARG(input); *out_refspec = NULL; @@ -219,7 +221,7 @@ const char *git_refspec_string(const git_refspec *refspec) int git_refspec_force(const git_refspec *refspec) { - assert(refspec); + GIT_ASSERT_ARG(refspec); return refspec->force; } @@ -261,7 +263,7 @@ static int refspec_transform( from_star = strchr(from, '*'); to_star = strchr(to, '*'); - assert(from_star && to_star); + GIT_ASSERT(from_star && to_star); /* star offset, both in 'from' and in 'name' */ star_offset = from_star - from; @@ -283,7 +285,9 @@ int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *nam { int error; - assert(out && spec && name); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(spec); + GIT_ASSERT_ARG(name); if ((error = git_buf_sanitize(out)) < 0) return error; @@ -303,7 +307,9 @@ int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *na { int error; - assert(out && spec && name); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(spec); + GIT_ASSERT_ARG(name); if ((error = git_buf_sanitize(out)) < 0) return error; @@ -333,14 +339,15 @@ int git_refspec__serialize(git_buf *out, const git_refspec *refspec) int git_refspec_is_wildcard(const git_refspec *spec) { - assert(spec && spec->src); + GIT_ASSERT_ARG(spec); + GIT_ASSERT_ARG(spec->src); return (spec->src[strlen(spec->src) - 1] == '*'); } git_direction git_refspec_direction(const git_refspec *spec) { - assert(spec); + GIT_ASSERT_ARG(spec); return spec->push; } @@ -359,7 +366,9 @@ int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs) NULL }; - assert(out && spec && refs); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(spec); + GIT_ASSERT_ARG(refs); cur = git__calloc(1, sizeof(git_refspec)); GIT_ERROR_CHECK_ALLOC(cur); From d4196c06be19ff2827593c9794cd0d82b128838e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 19:42:16 +0100 Subject: [PATCH 0141/1616] remote: use GIT_ASSERT --- src/remote.c | 81 +++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/src/remote.c b/src/remote.c index a12fa00ba96..29e15bbdf0a 100644 --- a/src/remote.c +++ b/src/remote.c @@ -210,7 +210,8 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem const git_remote_create_options dummy_opts = GIT_REMOTE_CREATE_OPTIONS_INIT; int error = -1; - assert(out && url); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(url); if (!opts) { opts = &dummy_opts; @@ -459,7 +460,9 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) struct refspec_cb_data data = { NULL }; bool optional_setting_found = false, found; - assert(out && repo && name); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); if ((error = ensure_remote_name_is_valid(name)) < 0) return error; @@ -581,19 +584,19 @@ static int lookup_remote_prune_config(git_remote *remote, git_config *config, co const char *git_remote_name(const git_remote *remote) { - assert(remote); + GIT_ASSERT_ARG_WITH_RETVAL(remote, NULL); return remote->name; } git_repository *git_remote_owner(const git_remote *remote) { - assert(remote); + GIT_ASSERT_ARG_WITH_RETVAL(remote, NULL); return remote->repo; } const char *git_remote_url(const git_remote *remote) { - assert(remote); + GIT_ASSERT_ARG_WITH_RETVAL(remote, NULL); return remote->url; } @@ -603,7 +606,8 @@ static int set_url(git_repository *repo, const char *remote, const char *pattern git_buf buf = GIT_BUF_INIT, canonical_url = GIT_BUF_INIT; int error; - assert(repo && remote); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(remote); if ((error = ensure_remote_name_is_valid(remote)) < 0) return error; @@ -637,7 +641,7 @@ int git_remote_set_url(git_repository *repo, const char *remote, const char *url const char *git_remote_pushurl(const git_remote *remote) { - assert(remote); + GIT_ASSERT_ARG_WITH_RETVAL(remote, NULL); return remote->pushurl; } @@ -670,8 +674,8 @@ int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int { const char *url = NULL; - assert(remote); - assert(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH); + GIT_ASSERT_ARG(remote); + GIT_ASSERT_ARG(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH); if (direction == GIT_DIRECTION_FETCH) { url = remote->url; @@ -716,7 +720,7 @@ int git_remote__connect(git_remote *remote, git_direction direction, const git_r git_credential_acquire_cb credentials = NULL; git_transport_cb transport = NULL; - assert(remote); + GIT_ASSERT_ARG(remote); if (callbacks) { GIT_ERROR_CHECK_VERSION(callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); @@ -781,7 +785,7 @@ int git_remote_connect(git_remote *remote, git_direction direction, const git_re int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote) { - assert(remote); + GIT_ASSERT_ARG(remote); if (!remote->transport) { git_error_set(GIT_ERROR_NET, "this remote has never connected"); @@ -798,7 +802,7 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur git_buf val = GIT_BUF_INIT; int error; - assert(remote); + GIT_ASSERT_ARG(remote); if (!proxy_url || !remote->repo) return -1; @@ -927,7 +931,7 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const const git_strarray *custom_headers = NULL; const git_proxy_options *proxy = NULL; - assert(remote); + GIT_ASSERT_ARG(remote); if (!remote->repo) { git_error_set(GIT_ERROR_INVALID, "cannot download detached remote"); @@ -1066,7 +1070,8 @@ static int remote_head_for_fetchspec_src(git_remote_head **out, git_vector *upda unsigned int i; git_remote_head *remote_ref; - assert(update_heads && fetchspec_src); + GIT_ASSERT_ARG(update_heads); + GIT_ASSERT_ARG(fetchspec_src); *out = NULL; @@ -1120,7 +1125,9 @@ static int remote_head_for_ref(git_remote_head **out, git_remote *remote, git_re const char *ref_name; int error = 0, update; - assert(out && spec && ref); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(spec); + GIT_ASSERT_ARG(ref); *out = NULL; @@ -1157,7 +1164,7 @@ static int git_remote_write_fetchhead(git_remote *remote, git_refspec *spec, git unsigned int i = 0; int error = 0; - assert(remote); + GIT_ASSERT_ARG(remote); /* no heads, nothing to do */ if (update_heads->length == 0) @@ -1373,7 +1380,7 @@ static int update_tips_for_spec( git_refspec tagspec; git_vector update_heads; - assert(remote); + GIT_ASSERT_ARG(remote); if (git_repository_odb__weakptr(&odb, remote->repo) < 0) return -1; @@ -1677,7 +1684,7 @@ int git_remote_update_tips( int git_remote_connected(const git_remote *remote) { - assert(remote); + GIT_ASSERT_ARG(remote); if (!remote->transport || !remote->transport->is_connected) return 0; @@ -1688,7 +1695,7 @@ int git_remote_connected(const git_remote *remote) int git_remote_stop(git_remote *remote) { - assert(remote); + GIT_ASSERT_ARG(remote); if (remote->transport && remote->transport->cancel) remote->transport->cancel(remote->transport); @@ -1698,7 +1705,7 @@ int git_remote_stop(git_remote *remote) int git_remote_disconnect(git_remote *remote) { - assert(remote); + GIT_ASSERT_ARG(remote); if (git_remote_connected(remote)) remote->transport->close(remote->transport); @@ -1784,7 +1791,7 @@ int git_remote_list(git_strarray *remotes_list, git_repository *repo) const git_indexer_progress *git_remote_stats(git_remote *remote) { - assert(remote); + GIT_ASSERT_ARG_WITH_RETVAL(remote, NULL); return &remote->stats; } @@ -1799,7 +1806,7 @@ int git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_ git_config *config; int error; - assert(repo && remote); + GIT_ASSERT_ARG(repo && remote); if ((error = ensure_remote_name_is_valid(remote)) < 0) return error; @@ -2063,7 +2070,7 @@ int git_remote_rename(git_strarray *out, git_repository *repo, const char *name, git_vector problem_refspecs = GIT_VECTOR_INIT; git_remote *remote = NULL; - assert(out && repo && name && new_name); + GIT_ASSERT_ARG(out && repo && name && new_name); if ((error = git_remote_lookup(&remote, repo, name)) < 0) return error; @@ -2239,7 +2246,7 @@ static const char *name_offset(size_t *len_out, const char *name) prefix_len = strlen("remote."); dot = strchr(name + prefix_len, '.'); - assert(dot); + GIT_ASSERT_ARG_WITH_RETVAL(dot, NULL); *len_out = dot - name - prefix_len; return name + prefix_len; @@ -2269,10 +2276,13 @@ static int remove_branch_config_related_entries( if (strcmp(remote_name, entry->value)) continue; - branch = name_offset(&branch_len, entry->name); + if ((branch = name_offset(&branch_len, entry->name)) == NULL) { + error = -1; + break; + } git_buf_clear(&buf); - if (git_buf_printf(&buf, "branch.%.*s.merge", (int)branch_len, branch) < 0) + if ((error = git_buf_printf(&buf, "branch.%.*s.merge", (int)branch_len, branch)) < 0) break; if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0) { @@ -2282,7 +2292,7 @@ static int remove_branch_config_related_entries( } git_buf_clear(&buf); - if (git_buf_printf(&buf, "branch.%.*s.remote", (int)branch_len, branch) < 0) + if ((error = git_buf_printf(&buf, "branch.%.*s.remote", (int)branch_len, branch)) < 0) break; if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0) { @@ -2377,7 +2387,8 @@ int git_remote_delete(git_repository *repo, const char *name) { int error; - assert(repo && name); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); if ((error = remove_branch_config_related_entries(repo, name)) < 0 || (error = remove_remote_tracking(repo, name)) < 0 || @@ -2396,7 +2407,7 @@ int git_remote_default_branch(git_buf *out, git_remote *remote) git_buf local_default = GIT_BUF_INIT; int error; - assert(out); + GIT_ASSERT_ARG(out); if ((error = git_remote_ls(&heads, &heads_len, remote)) < 0) goto done; @@ -2465,7 +2476,7 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi const git_remote_callbacks *cbs = NULL; git_remote_connection_opts conn = GIT_REMOTE_CONNECTION_OPTIONS_INIT; - assert(remote); + GIT_ASSERT_ARG(remote); if (!remote->repo) { git_error_set(GIT_ERROR_INVALID, "cannot download detached remote"); @@ -2531,7 +2542,7 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_ const git_strarray *custom_headers = NULL; const git_proxy_options *proxy = NULL; - assert(remote); + GIT_ASSERT_ARG(remote); if (!remote->repo) { git_error_set(GIT_ERROR_INVALID, "cannot download detached remote"); @@ -2546,8 +2557,6 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_ proxy = &opts->proxy_opts; } - assert(remote); - if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs, proxy, custom_headers)) < 0) return error; @@ -2574,9 +2583,9 @@ char *apply_insteadof(git_config *config, const char *url, int direction) git_config_entry *entry; git_config_iterator *iter; - assert(config); - assert(url); - assert(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH); + GIT_ASSERT_ARG_WITH_RETVAL(config, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(url, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH, NULL); /* Add 1 to prefix/suffix length due to the additional escaped dot */ prefix_length = strlen(PREFIX) + 1; From 36adde5690f053fbbfaf8f45f96961a8307a0fa6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 21:17:42 +0100 Subject: [PATCH 0142/1616] repository: use GIT_ASSERT --- src/repository.c | 91 ++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/src/repository.c b/src/repository.c index 28cbf3c6c4d..697d6dfe927 100644 --- a/src/repository.c +++ b/src/repository.c @@ -142,7 +142,7 @@ static void set_index(git_repository *repo, git_index *index) int git_repository__cleanup(git_repository *repo) { - assert(repo); + GIT_ASSERT_ARG(repo); git_repository_submodule_cache_clear(repo); git_cache_clear(&repo->objects); @@ -368,7 +368,7 @@ static size_t find_ceiling_dir_offset( const char *ceil, *sep; size_t len, max_len = 0, min_len; - assert(path); + GIT_ASSERT_ARG(path); min_len = (size_t)(git_path_root(path) + 1); @@ -414,7 +414,8 @@ static int read_gitfile(git_buf *path_out, const char *file_path) git_buf file = GIT_BUF_INIT; size_t prefix_len = strlen(GIT_FILE_CONTENT_PREFIX); - assert(path_out && file_path); + GIT_ASSERT_ARG(path_out); + GIT_ASSERT_ARG(file_path); if (git_futils_readbuffer(&file, file_path) < 0) return -1; @@ -901,7 +902,8 @@ int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *w size_t len; int err; - assert(repo_out && wt); + GIT_ASSERT_ARG(repo_out); + GIT_ASSERT_ARG(wt); *repo_out = NULL; len = strlen(wt->gitlink_path); @@ -947,7 +949,7 @@ int git_repository_discover( uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0; int error; - assert(start_path); + GIT_ASSERT_ARG(start_path); if ((error = git_buf_sanitize(out)) < 0) return error; @@ -967,7 +969,7 @@ static int load_config( git_buf config_path = GIT_BUF_INIT; git_config *cfg = NULL; - assert(out); + GIT_ASSERT_ARG(out); if ((error = git_config_new(&cfg)) < 0) return error; @@ -1091,7 +1093,9 @@ int git_repository_config_snapshot(git_config **out, git_repository *repo) int git_repository_set_config(git_repository *repo, git_config *config) { - assert(repo && config); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(config); + set_config(repo, config); return 0; } @@ -1100,7 +1104,8 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo) { int error = 0; - assert(repo && out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(out); if (repo->_odb == NULL) { git_buf odb_path = GIT_BUF_INIT; @@ -1143,7 +1148,9 @@ int git_repository_odb(git_odb **out, git_repository *repo) int git_repository_set_odb(git_repository *repo, git_odb *odb) { - assert(repo && odb); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(odb); + set_odb(repo, odb); return 0; } @@ -1152,7 +1159,8 @@ int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo) { int error = 0; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); if (repo->_refdb == NULL) { git_refdb *refdb; @@ -1184,7 +1192,9 @@ int git_repository_refdb(git_refdb **out, git_repository *repo) int git_repository_set_refdb(git_repository *repo, git_refdb *refdb) { - assert(repo && refdb); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(refdb); + set_refdb(repo, refdb); return 0; } @@ -1193,7 +1203,8 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo) { int error = 0; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); if (repo->_index == NULL) { git_buf index_path = GIT_BUF_INIT; @@ -1234,7 +1245,7 @@ int git_repository_index(git_index **out, git_repository *repo) int git_repository_set_index(git_repository *repo, git_index *index) { - assert(repo); + GIT_ASSERT_ARG(repo); set_index(repo, index); return 0; } @@ -2132,7 +2143,9 @@ int git_repository_init_ext( bool is_valid; int error; - assert(out && given_repo && opts); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(given_repo); + GIT_ASSERT_ARG(opts); GIT_ERROR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options"); @@ -2208,7 +2221,8 @@ int git_repository_head_detached_for_worktree(git_repository *repo, const char * git_reference *ref = NULL; int error; - assert(repo && name); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); if ((error = git_repository_head_for_worktree(&ref, repo, name)) < 0) goto out; @@ -2225,7 +2239,7 @@ int git_repository_head(git_reference **head_out, git_repository *repo) git_reference *head; int error; - assert(head_out); + GIT_ASSERT_ARG(head_out); if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0) return error; @@ -2248,7 +2262,9 @@ int git_repository_head_for_worktree(git_reference **out, git_repository *repo, git_reference *head = NULL; int error; - assert(out && repo && name); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); *out = NULL; @@ -2462,13 +2478,13 @@ int git_repository_item_path(git_buf *out, const git_repository *repo, git_repos const char *git_repository_path(const git_repository *repo) { - assert(repo); + GIT_ASSERT_ARG_WITH_RETVAL(repo, NULL); return repo->gitdir; } const char *git_repository_workdir(const git_repository *repo) { - assert(repo); + GIT_ASSERT_ARG_WITH_RETVAL(repo, NULL); if (repo->is_bare) return NULL; @@ -2478,7 +2494,7 @@ const char *git_repository_workdir(const git_repository *repo) const char *git_repository_commondir(const git_repository *repo) { - assert(repo); + GIT_ASSERT_ARG_WITH_RETVAL(repo, NULL); return repo->commondir; } @@ -2488,7 +2504,8 @@ int git_repository_set_workdir( int error = 0; git_buf path = GIT_BUF_INIT; - assert(repo && workdir); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(workdir); if (git_path_prettify_dir(&path, workdir, NULL) < 0) return -1; @@ -2528,13 +2545,13 @@ int git_repository_set_workdir( int git_repository_is_bare(const git_repository *repo) { - assert(repo); + GIT_ASSERT_ARG(repo); return repo->is_bare; } int git_repository_is_worktree(const git_repository *repo) { - assert(repo); + GIT_ASSERT_ARG(repo); return repo->is_worktree; } @@ -2543,7 +2560,7 @@ int git_repository_set_bare(git_repository *repo) int error; git_config *config; - assert(repo); + GIT_ASSERT_ARG(repo); if (repo->is_bare) return 0; @@ -2657,7 +2674,10 @@ int git_repository_hashfile( uint64_t len; git_buf full_path = GIT_BUF_INIT; - assert(out && path && repo); /* as_path can be NULL */ + /* as_path can be NULL */ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(path); + GIT_ASSERT_ARG(repo); /* At some point, it would be nice if repo could be NULL to just * apply filter rules defined in system and global files, but for @@ -2742,7 +2762,8 @@ static int detach(git_repository *repo, const git_oid *id, const char *new) git_object *object = NULL, *peeled = NULL; git_reference *new_head = NULL, *current = NULL; - assert(repo && id); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(id); if ((error = git_reference_lookup(¤t, repo, GIT_HEAD_FILE)) < 0) return error; @@ -2778,7 +2799,8 @@ int git_repository_set_head( git_buf log_message = GIT_BUF_INIT; int error; - assert(repo && refname); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(refname); if ((error = git_reference_lookup(¤t, repo, GIT_HEAD_FILE)) < 0) return error; @@ -2830,7 +2852,8 @@ int git_repository_set_head_detached_from_annotated( git_repository *repo, const git_annotated_commit *commitish) { - assert(repo && commitish); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(commitish); return detach(repo, git_annotated_commit_id(commitish), commitish->description); } @@ -2842,7 +2865,7 @@ int git_repository_detach_head(git_repository* repo) git_buf log_message = GIT_BUF_INIT; int error; - assert(repo); + GIT_ASSERT_ARG(repo); if ((error = git_reference_lookup(¤t, repo, GIT_HEAD_FILE)) < 0) return error; @@ -2877,7 +2900,7 @@ int git_repository_state(git_repository *repo) git_buf repo_path = GIT_BUF_INIT; int state = GIT_REPOSITORY_STATE_NONE; - assert(repo); + GIT_ASSERT_ARG(repo); if (git_buf_puts(&repo_path, repo->gitdir) < 0) return -1; @@ -2954,7 +2977,7 @@ static const char *state_files[] = { int git_repository_state_cleanup(git_repository *repo) { - assert(repo); + GIT_ASSERT_ARG(repo); return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files)); } @@ -3033,7 +3056,7 @@ int git_repository_submodule_cache_all(git_repository *repo) { int error; - assert(repo); + GIT_ASSERT_ARG(repo); if ((error = git_strmap_new(&repo->submodule_cache))) return error; @@ -3045,7 +3068,9 @@ int git_repository_submodule_cache_all(git_repository *repo) int git_repository_submodule_cache_clear(git_repository *repo) { git_submodule *sm; - assert(repo); + + GIT_ASSERT_ARG(repo); + if (repo->submodule_cache == NULL) { return 0; } From 59f46913c0b53f2bb45a0f9dc9d390de6a4d7697 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 21:55:13 +0100 Subject: [PATCH 0143/1616] reset: use GIT_ASSERT --- src/reset.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/reset.c b/src/reset.c index ca6a5bd73cf..dfae91d6fab 100644 --- a/src/reset.c +++ b/src/reset.c @@ -33,7 +33,7 @@ int git_reset_default( int error; git_index *index = NULL; - assert(pathspecs != NULL && pathspecs->count > 0); + GIT_ASSERT_ARG(pathspecs && pathspecs->count > 0); memset(&entry, 0, sizeof(git_index_entry)); @@ -62,10 +62,10 @@ int git_reset_default( for (i = 0, max_i = git_diff_num_deltas(diff); i < max_i; ++i) { const git_diff_delta *delta = git_diff_get_delta(diff, i); - assert(delta->status == GIT_DELTA_ADDED || - delta->status == GIT_DELTA_MODIFIED || - delta->status == GIT_DELTA_CONFLICTED || - delta->status == GIT_DELTA_DELETED); + GIT_ASSERT(delta->status == GIT_DELTA_ADDED || + delta->status == GIT_DELTA_MODIFIED || + delta->status == GIT_DELTA_CONFLICTED || + delta->status == GIT_DELTA_DELETED); error = git_index_conflict_remove(index, delta->old_file.path); if (error < 0) { @@ -113,7 +113,8 @@ static int reset( git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_buf log_message = GIT_BUF_INIT; - assert(repo && target); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(target); if (checkout_opts) opts = *checkout_opts; From 055fbf6d904a7799cb42293da588082b6dca84a4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 21:55:59 +0100 Subject: [PATCH 0144/1616] revert: use GIT_ASSERT --- src/revert.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/revert.c b/src/revert.c index b84bc7d79a0..683f0d70d8b 100644 --- a/src/revert.c +++ b/src/revert.c @@ -129,7 +129,10 @@ int git_revert_commit( git_tree *parent_tree = NULL, *our_tree = NULL, *revert_tree = NULL; int parent = 0, error = 0; - assert(out && repo && revert_commit && our_commit); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(revert_commit); + GIT_ASSERT_ARG(our_commit); if (git_commit_parentcount(revert_commit) > 1) { if (!mainline) @@ -180,7 +183,8 @@ int git_revert( git_indexwriter indexwriter = GIT_INDEXWRITER_INIT; int error; - assert(repo && commit); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(commit); GIT_ERROR_CHECK_VERSION(given_opts, GIT_REVERT_OPTIONS_VERSION, "git_revert_options"); From 5bd139e922e32e83403a23d575731b39a7e8ebf4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 21:57:22 +0100 Subject: [PATCH 0145/1616] revparse: use GIT_ASSERT --- src/revparse.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/revparse.c b/src/revparse.c index 1cc8b97f52b..4b919d32a63 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -317,7 +317,7 @@ static int handle_at_syntax(git_object **out, git_reference **ref, const char *s git_buf identifier = GIT_BUF_INIT; git_time_t timestamp; - assert(*out == NULL); + GIT_ASSERT(*out == NULL); if (git_buf_put(&identifier, spec, identifier_len) < 0) return -1; @@ -524,7 +524,7 @@ static int extract_curly_braces_content(git_buf *buf, const char *spec, size_t * { git_buf_clear(buf); - assert(spec[*pos] == '^' || spec[*pos] == '@'); + GIT_ASSERT_ARG(spec[*pos] == '^' || spec[*pos] == '@'); (*pos)++; @@ -550,7 +550,7 @@ static int extract_path(git_buf *buf, const char *spec, size_t *pos) { git_buf_clear(buf); - assert(spec[*pos] == ':'); + GIT_ASSERT_ARG(spec[*pos] == ':'); (*pos)++; @@ -568,7 +568,7 @@ static int extract_how_many(int *n, const char *spec, size_t *pos) int parsed, accumulated; char kind = spec[*pos]; - assert(spec[*pos] == '^' || spec[*pos] == '~'); + GIT_ASSERT_ARG(spec[*pos] == '^' || spec[*pos] == '~'); accumulated = 0; @@ -676,7 +676,10 @@ static int revparse( bool should_return_reference = true; - assert(object_out && reference_out && repo && spec); + GIT_ASSERT_ARG(object_out); + GIT_ASSERT_ARG(reference_out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(spec); *object_out = NULL; *reference_out = NULL; @@ -882,7 +885,9 @@ int git_revparse( const char *dotdot; int error = 0; - assert(revspec && repo && spec); + GIT_ASSERT_ARG(revspec); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(spec); memset(revspec, 0x0, sizeof(*revspec)); From ef6b12b0c5748c3f323c04473ea44db180af873e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 21:58:40 +0100 Subject: [PATCH 0146/1616] revwalk: use GIT_ASSERT --- src/revwalk.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/src/revwalk.c b/src/revwalk.c index 1efb938bd3e..249cb16bf96 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -99,7 +99,8 @@ int git_revwalk_push(git_revwalk *walk, const git_oid *oid) { git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT; - assert(walk && oid); + GIT_ASSERT_ARG(walk); + GIT_ASSERT_ARG(oid); return git_revwalk__push_commit(walk, oid, &opts); } @@ -108,7 +109,9 @@ int git_revwalk_push(git_revwalk *walk, const git_oid *oid) int git_revwalk_hide(git_revwalk *walk, const git_oid *oid) { git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT; - assert(walk && oid); + + GIT_ASSERT_ARG(walk); + GIT_ASSERT_ARG(oid); opts.uninteresting = 1; return git_revwalk__push_commit(walk, oid, &opts); @@ -133,7 +136,8 @@ int git_revwalk__push_glob(git_revwalk *walk, const char *glob, const git_revwal git_reference_iterator *iter; size_t wildcard; - assert(walk && glob); + GIT_ASSERT_ARG(walk); + GIT_ASSERT_ARG(glob); if (given_opts) memcpy(&opts, given_opts, sizeof(opts)); @@ -172,7 +176,9 @@ int git_revwalk__push_glob(git_revwalk *walk, const char *glob, const git_revwal int git_revwalk_push_glob(git_revwalk *walk, const char *glob) { git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT; - assert(walk && glob); + + GIT_ASSERT_ARG(walk); + GIT_ASSERT_ARG(glob); return git_revwalk__push_glob(walk, glob, &opts); } @@ -180,7 +186,9 @@ int git_revwalk_push_glob(git_revwalk *walk, const char *glob) int git_revwalk_hide_glob(git_revwalk *walk, const char *glob) { git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT; - assert(walk && glob); + + GIT_ASSERT_ARG(walk); + GIT_ASSERT_ARG(glob); opts.uninteresting = 1; return git_revwalk__push_glob(walk, glob, &opts); @@ -189,7 +197,8 @@ int git_revwalk_hide_glob(git_revwalk *walk, const char *glob) int git_revwalk_push_head(git_revwalk *walk) { git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT; - assert(walk); + + GIT_ASSERT_ARG(walk); return git_revwalk__push_ref(walk, GIT_HEAD_FILE, &opts); } @@ -197,7 +206,8 @@ int git_revwalk_push_head(git_revwalk *walk) int git_revwalk_hide_head(git_revwalk *walk) { git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT; - assert(walk); + + GIT_ASSERT_ARG(walk); opts.uninteresting = 1; return git_revwalk__push_ref(walk, GIT_HEAD_FILE, &opts); @@ -206,7 +216,9 @@ int git_revwalk_hide_head(git_revwalk *walk) int git_revwalk_push_ref(git_revwalk *walk, const char *refname) { git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT; - assert(walk && refname); + + GIT_ASSERT_ARG(walk); + GIT_ASSERT_ARG(refname); return git_revwalk__push_ref(walk, refname, &opts); } @@ -249,7 +261,10 @@ int git_revwalk_push_range(git_revwalk *walk, const char *range) int git_revwalk_hide_ref(git_revwalk *walk, const char *refname) { git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT; - assert(walk && refname); + + GIT_ASSERT_ARG(walk); + GIT_ASSERT_ARG(refname); + opts.uninteresting = 1; return git_revwalk__push_ref(walk, refname, &opts); } @@ -694,13 +709,14 @@ void git_revwalk_free(git_revwalk *walk) git_repository *git_revwalk_repository(git_revwalk *walk) { - assert(walk); + GIT_ASSERT_ARG_WITH_RETVAL(walk, NULL); + return walk->repo; } int git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode) { - assert(walk); + GIT_ASSERT_ARG(walk); if (walk->walking) git_revwalk_reset(walk); @@ -732,7 +748,8 @@ int git_revwalk_next(git_oid *oid, git_revwalk *walk) int error; git_commit_list_node *next; - assert(walk && oid); + GIT_ASSERT_ARG(walk); + GIT_ASSERT_ARG(oid); if (!walk->walking) { if ((error = prepare_walk(walk)) < 0) @@ -757,7 +774,7 @@ int git_revwalk_reset(git_revwalk *walk) { git_commit_list_node *commit; - assert(walk); + GIT_ASSERT_ARG(walk); git_oidmap_foreach_value(walk->commits, commit, { commit->seen = 0; @@ -787,7 +804,7 @@ int git_revwalk_add_hide_cb( git_revwalk_hide_cb hide_cb, void *payload) { - assert(walk); + GIT_ASSERT_ARG(walk); if (walk->walking) git_revwalk_reset(walk); From 42594f3ffa2090697d229c6766e4e871e1c28386 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:00:36 +0100 Subject: [PATCH 0147/1616] signature: use GIT_ASSERT --- src/signature.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/signature.c b/src/signature.c index f4c8a104aba..0fbd3d5ff4b 100644 --- a/src/signature.c +++ b/src/signature.c @@ -65,7 +65,8 @@ int git_signature_new(git_signature **sig_out, const char *name, const char *ema { git_signature *p = NULL; - assert(name && email); + GIT_ASSERT_ARG(name); + GIT_ASSERT_ARG(email); *sig_out = NULL; @@ -279,7 +280,8 @@ int git_signature_from_buffer(git_signature **out, const char *buf) const char *buf_end; int error; - assert(out && buf); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(buf); *out = NULL; @@ -302,7 +304,8 @@ void git_signature__writebuf(git_buf *buf, const char *header, const git_signatu int offset, hours, mins; char sign; - assert(buf && sig); + GIT_ASSERT_ARG(buf); + GIT_ASSERT_ARG(sig); offset = sig->when.offset; sign = (sig->when.offset < 0 || sig->when.sign == '-') ? '-' : '+'; @@ -320,7 +323,8 @@ void git_signature__writebuf(git_buf *buf, const char *header, const git_signatu bool git_signature__equal(const git_signature *one, const git_signature *two) { - assert(one && two); + GIT_ASSERT_ARG(one); + GIT_ASSERT_ARG(two); return git__strcmp(one->name, two->name) == 0 && From 9cf2c9dc1e08f77bb74bfc1bc8feaabcde91d20e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:05:40 +0100 Subject: [PATCH 0148/1616] signature: use GIT_ASSERT --- src/signature.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/signature.c b/src/signature.c index 0fbd3d5ff4b..1efda212a0a 100644 --- a/src/signature.c +++ b/src/signature.c @@ -304,9 +304,6 @@ void git_signature__writebuf(git_buf *buf, const char *header, const git_signatu int offset, hours, mins; char sign; - GIT_ASSERT_ARG(buf); - GIT_ASSERT_ARG(sig); - offset = sig->when.offset; sign = (sig->when.offset < 0 || sig->when.sign == '-') ? '-' : '+'; From 9522de900f38119c005cb53a77fe61fd0139857e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:06:25 +0100 Subject: [PATCH 0149/1616] stash: use GIT_ASSERT --- src/stash.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stash.c b/src/stash.c index 0d5dc4351a4..8ee12732295 100644 --- a/src/stash.c +++ b/src/stash.c @@ -546,7 +546,9 @@ int git_stash_save( git_buf msg = GIT_BUF_INIT; int error; - assert(out && repo && stasher); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(stasher); if ((error = git_repository__ensure_not_bare(repo, "stash save")) < 0) return error; From 1e3c2d9ca6432ff9d3f5e6a77d82868f972dc907 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:07:11 +0100 Subject: [PATCH 0150/1616] status: use GIT_ASSERT --- src/status.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/status.c b/src/status.c index eca1f49120f..c98564643fc 100644 --- a/src/status.c +++ b/src/status.c @@ -391,14 +391,14 @@ int git_status_list_new( size_t git_status_list_entrycount(git_status_list *status) { - assert(status); + GIT_ASSERT_ARG_WITH_RETVAL(status, 0); return status->paired.length; } const git_status_entry *git_status_byindex(git_status_list *status, size_t i) { - assert(status); + GIT_ASSERT_ARG_WITH_RETVAL(status, NULL); return git_vector_get(&status->paired, i); } @@ -492,7 +492,9 @@ int git_status_file( struct status_file_info sfi = {0}; git_index *index; - assert(status_flags && repo && path); + GIT_ASSERT_ARG(status_flags); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(path); if ((error = git_repository_index__weakptr(&index, repo)) < 0) return error; @@ -558,7 +560,8 @@ int git_status_init_options(git_status_options *opts, unsigned int version) int git_status_list_get_perfdata( git_diff_perfdata *out, const git_status_list *status) { - assert(out); + GIT_ASSERT_ARG(out); + GIT_ERROR_CHECK_VERSION(out, GIT_DIFF_PERFDATA_VERSION, "git_diff_perfdata"); out->stat_calls = 0; From 203832c3ff784728c527179eaffb14bc0e31f3bd Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 21 Nov 2020 23:04:04 +0000 Subject: [PATCH 0151/1616] strarray: use GIT_ASSERT --- src/strarray.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/strarray.c b/src/strarray.c index 54fe9fbfba4..2f9b77cc280 100644 --- a/src/strarray.c +++ b/src/strarray.c @@ -13,7 +13,8 @@ int git_strarray_copy(git_strarray *tgt, const git_strarray *src) { size_t i; - assert(tgt && src); + GIT_ASSERT_ARG(tgt); + GIT_ASSERT_ARG(src); memset(tgt, 0, sizeof(*tgt)); From c06e7987c9c69f945ee1ab162d5efe4299871288 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:12:20 +0100 Subject: [PATCH 0152/1616] submodule: use GIT_ASSERT --- src/submodule.c | 78 ++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/src/submodule.c b/src/submodule.c index 8fb3bdb73d9..0c901fa6fd8 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -258,7 +258,8 @@ int git_submodule_lookup( unsigned int location; git_submodule *sm; - assert(repo && name); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); if (repo->is_bare) { git_error_set(GIT_ERROR_SUBMODULE, "cannot get submodules without a working tree"); @@ -520,7 +521,8 @@ int git_submodule__map(git_repository *repo, git_strmap *map) git_submodule *sm; git_config *mods = NULL; - assert(repo && map); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(map); /* get sources that we will need to check */ if (git_repository_index(&idx, repo) < 0) @@ -698,7 +700,9 @@ int git_submodule_add_setup( git_repository *subrepo = NULL; bool path_occupied; - assert(repo && url && path); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(url); + GIT_ASSERT_ARG(path); /* see if there is already an entry for this submodule */ @@ -799,7 +803,8 @@ int git_submodule_repo_init( git_config *cfg = NULL; git_buf buf = GIT_BUF_INIT; - assert(out && sm); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(sm); /* get the configured remote url of the submodule */ if ((error = git_buf_printf(&buf, "submodule.%s.url", sm->name)) < 0 || @@ -840,7 +845,7 @@ int git_submodule_clone(git_repository **out, git_submodule *submodule, const gi git_submodule_update_options sub_opts = GIT_SUBMODULE_UPDATE_OPTIONS_INIT; git_clone_options opts = GIT_CLONE_OPTIONS_INIT; - assert(submodule); + GIT_ASSERT_ARG(submodule); if (given_opts) memcpy(&sub_opts, given_opts, sizeof(sub_opts)); @@ -879,7 +884,7 @@ int git_submodule_add_finalize(git_submodule *sm) int error; git_index *index; - assert(sm); + GIT_ASSERT_ARG(sm); if ((error = git_repository_index__weakptr(&index, sm->repo)) < 0 || (error = git_index_add_bypath(index, GIT_MODULES_FILE)) < 0) @@ -898,7 +903,7 @@ int git_submodule_add_to_index(git_submodule *sm, int write_index) git_index_entry entry; struct stat st; - assert(sm); + GIT_ASSERT_ARG(sm); /* force reload of wd OID by git_submodule_open */ sm->flags = sm->flags & ~GIT_SUBMODULE_STATUS__WD_OID_VALID; @@ -969,25 +974,25 @@ static const char *submodule_update_to_str(git_submodule_update_t update) git_repository *git_submodule_owner(git_submodule *submodule) { - assert(submodule); + GIT_ASSERT_ARG_WITH_RETVAL(submodule, NULL); return submodule->repo; } const char *git_submodule_name(git_submodule *submodule) { - assert(submodule); + GIT_ASSERT_ARG_WITH_RETVAL(submodule, NULL); return submodule->name; } const char *git_submodule_path(git_submodule *submodule) { - assert(submodule); + GIT_ASSERT_ARG_WITH_RETVAL(submodule, NULL); return submodule->path; } const char *git_submodule_url(git_submodule *submodule) { - assert(submodule); + GIT_ASSERT_ARG_WITH_RETVAL(submodule, NULL); return submodule->url; } @@ -996,7 +1001,9 @@ int git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *ur int error = 0; git_buf normalized = GIT_BUF_INIT; - assert(out && repo && url); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(url); if ((error = git_buf_sanitize(out)) < 0) return error; @@ -1067,28 +1074,30 @@ static int write_mapped_var(git_repository *repo, const char *name, git_configma const char *git_submodule_branch(git_submodule *submodule) { - assert(submodule); + GIT_ASSERT_ARG_WITH_RETVAL(submodule, NULL); return submodule->branch; } int git_submodule_set_branch(git_repository *repo, const char *name, const char *branch) { - - assert(repo && name); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); return write_var(repo, name, "branch", branch); } int git_submodule_set_url(git_repository *repo, const char *name, const char *url) { - assert(repo && name && url); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); + GIT_ASSERT_ARG(url); return write_var(repo, name, "url", url); } const git_oid *git_submodule_index_id(git_submodule *submodule) { - assert(submodule); + GIT_ASSERT_ARG_WITH_RETVAL(submodule, NULL); if (submodule->flags & GIT_SUBMODULE_STATUS__INDEX_OID_VALID) return &submodule->index_oid; @@ -1098,7 +1107,7 @@ const git_oid *git_submodule_index_id(git_submodule *submodule) const git_oid *git_submodule_head_id(git_submodule *submodule) { - assert(submodule); + GIT_ASSERT_ARG_WITH_RETVAL(submodule, NULL); if (submodule->flags & GIT_SUBMODULE_STATUS__HEAD_OID_VALID) return &submodule->head_oid; @@ -1108,7 +1117,7 @@ const git_oid *git_submodule_head_id(git_submodule *submodule) const git_oid *git_submodule_wd_id(git_submodule *submodule) { - assert(submodule); + GIT_ASSERT_ARG_WITH_RETVAL(submodule, NULL); /* load unless we think we have a valid oid */ if (!(submodule->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID)) { @@ -1129,28 +1138,32 @@ const git_oid *git_submodule_wd_id(git_submodule *submodule) git_submodule_ignore_t git_submodule_ignore(git_submodule *submodule) { - assert(submodule); + GIT_ASSERT_ARG_WITH_RETVAL(submodule, GIT_SUBMODULE_IGNORE_UNSPECIFIED); + return (submodule->ignore < GIT_SUBMODULE_IGNORE_NONE) ? GIT_SUBMODULE_IGNORE_NONE : submodule->ignore; } int git_submodule_set_ignore(git_repository *repo, const char *name, git_submodule_ignore_t ignore) { - assert(repo && name); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); return write_mapped_var(repo, name, _sm_ignore_map, ARRAY_SIZE(_sm_ignore_map), "ignore", ignore); } git_submodule_update_t git_submodule_update_strategy(git_submodule *submodule) { - assert(submodule); + GIT_ASSERT_ARG_WITH_RETVAL(submodule, GIT_SUBMODULE_UPDATE_NONE); + return (submodule->update < GIT_SUBMODULE_UPDATE_CHECKOUT) ? GIT_SUBMODULE_UPDATE_CHECKOUT : submodule->update; } int git_submodule_set_update(git_repository *repo, const char *name, git_submodule_update_t update) { - assert(repo && name); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); return write_mapped_var(repo, name, _sm_update_map, ARRAY_SIZE(_sm_update_map), "update", update); } @@ -1158,13 +1171,14 @@ int git_submodule_set_update(git_repository *repo, const char *name, git_submodu git_submodule_recurse_t git_submodule_fetch_recurse_submodules( git_submodule *submodule) { - assert(submodule); + GIT_ASSERT_ARG_WITH_RETVAL(submodule, GIT_SUBMODULE_RECURSE_NO); return submodule->fetch_recurse; } int git_submodule_set_fetch_recurse_submodules(git_repository *repo, const char *name, git_submodule_recurse_t recurse) { - assert(repo && name); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); return write_mapped_var(repo, name, _sm_recurse_map, ARRAY_SIZE(_sm_recurse_map), "fetchRecurseSubmodules", recurse); } @@ -1261,7 +1275,7 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT; git_clone_options clone_options = GIT_CLONE_OPTIONS_INIT; - assert(sm); + GIT_ASSERT_ARG(sm); if (_update_options) memcpy(&update_options, _update_options, sizeof(git_submodule_update_options)); @@ -1474,7 +1488,8 @@ static int git_submodule__open( unsigned int flags = GIT_REPOSITORY_OPEN_NO_SEARCH; const char *wd; - assert(sm && subrepo); + GIT_ASSERT_ARG(sm); + GIT_ASSERT_ARG(subrepo); if (git_repository__ensure_not_bare( sm->repo, "open submodule repository") < 0) @@ -1610,7 +1625,7 @@ int git_submodule_reload(git_submodule *sm, int force) GIT_UNUSED(force); - assert(sm); + GIT_ASSERT_ARG(sm); if ((error = git_submodule_name_is_valid(sm->repo, sm->name, 0)) <= 0) /* This should come with a warning, but we've no API for that */ @@ -1727,7 +1742,9 @@ int git_submodule_status(unsigned int *status, git_repository *repo, const char git_submodule *sm; int error; - assert(status && repo && name); + GIT_ASSERT_ARG(status); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); if ((error = git_submodule_lookup(&sm, repo, name)) < 0) return error; @@ -1740,7 +1757,8 @@ int git_submodule_status(unsigned int *status, git_repository *repo, const char int git_submodule_location(unsigned int *location, git_submodule *sm) { - assert(location && sm); + GIT_ASSERT_ARG(location); + GIT_ASSERT_ARG(sm); return git_submodule__status( location, NULL, NULL, NULL, sm, GIT_SUBMODULE_IGNORE_ALL); From fc98354291bf7478c15fdfa0ac704361c4ece257 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:12:57 +0100 Subject: [PATCH 0153/1616] sysdir: use GIT_ASSERT --- src/sysdir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sysdir.c b/src/sysdir.c index 401b4a55e92..dcbd48bc394 100644 --- a/src/sysdir.c +++ b/src/sysdir.c @@ -45,7 +45,7 @@ static int get_passwd_home(git_buf *out, uid_t uid) long buflen; int error; - assert(out); + GIT_ASSERT_ARG(out); if ((buflen = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1) buflen = 1024; @@ -204,7 +204,7 @@ static int git_sysdir_check_selector(git_sysdir_t which) int git_sysdir_get(const git_buf **out, git_sysdir_t which) { - assert(out); + GIT_ASSERT_ARG(out); *out = NULL; From e1af2e5595d5dd3896dff49674aaa1d711b30ea4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:15:06 +0100 Subject: [PATCH 0154/1616] tag: use GIT_ASSERT --- src/tag.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/tag.c b/src/tag.c index 8a4d6eec887..ee91e509162 100644 --- a/src/tag.c +++ b/src/tag.c @@ -27,25 +27,25 @@ void git_tag__free(void *_tag) int git_tag_target(git_object **target, const git_tag *t) { - assert(t); + GIT_ASSERT_ARG(t); return git_object_lookup(target, t->object.repo, &t->target, t->type); } const git_oid *git_tag_target_id(const git_tag *t) { - assert(t); + GIT_ASSERT_ARG_WITH_RETVAL(t, NULL); return &t->target; } git_object_t git_tag_target_type(const git_tag *t) { - assert(t); + GIT_ASSERT_ARG_WITH_RETVAL(t, GIT_OBJECT_INVALID); return t->type; } const char *git_tag_name(const git_tag *t) { - assert(t); + GIT_ASSERT_ARG_WITH_RETVAL(t, NULL); return t->tag_name; } @@ -56,7 +56,7 @@ const git_signature *git_tag_tagger(const git_tag *t) const char *git_tag_message(const git_tag *t) { - assert(t); + GIT_ASSERT_ARG_WITH_RETVAL(t, NULL); return t->message; } @@ -259,8 +259,10 @@ static int git_tag_create__internal( int error; - assert(repo && tag_name && target); - assert(!create_tag_annotation || (tagger && message)); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(tag_name); + GIT_ASSERT_ARG(target); + GIT_ASSERT_ARG(!create_tag_annotation || (tagger && message)); if (git_object_owner(target) != repo) { git_error_set(GIT_ERROR_INVALID, "the given target does not belong to this repository"); @@ -313,7 +315,12 @@ int git_tag_annotation_create( const git_signature *tagger, const char *message) { - assert(oid && repo && tag_name && target && tagger && message); + GIT_ASSERT_ARG(oid); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(tag_name); + GIT_ASSERT_ARG(target); + GIT_ASSERT_ARG(tagger); + GIT_ASSERT_ARG(message); return write_tag_annotation(oid, repo, tag_name, target, tagger, message); } @@ -339,7 +346,8 @@ int git_tag_create_from_buffer(git_oid *oid, git_repository *repo, const char *b git_reference *new_ref = NULL; git_buf ref_name = GIT_BUF_INIT; - assert(oid && buffer); + GIT_ASSERT_ARG(oid); + GIT_ASSERT_ARG(buffer); memset(&tag, 0, sizeof(tag)); @@ -454,7 +462,8 @@ int git_tag_foreach(git_repository *repo, git_tag_foreach_cb cb, void *cb_data) { tag_cb_data data; - assert(repo && cb); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(cb); data.cb = cb; data.cb_data = cb_data; @@ -493,7 +502,9 @@ int git_tag_list_match(git_strarray *tag_names, const char *pattern, git_reposit tag_filter_data filter; git_vector taglist; - assert(tag_names && repo && pattern); + GIT_ASSERT_ARG(tag_names); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(pattern); if ((error = git_vector_init(&taglist, 8, NULL)) < 0) return error; From 9083a0e62834123aa5172d11ee27022850ec37a9 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:15:21 +0100 Subject: [PATCH 0155/1616] trace: use GIT_ASSERT --- src/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trace.c b/src/trace.c index 3acb64398d1..efc7b01a2d8 100644 --- a/src/trace.c +++ b/src/trace.c @@ -20,7 +20,7 @@ struct git_trace_data git_trace__data = {0}; int git_trace_set(git_trace_level_t level, git_trace_cb callback) { #ifdef GIT_TRACE - assert(level == 0 || callback != NULL); + GIT_ASSERT_ARG(level == 0 || callback != NULL); git_trace__data.level = level; git_trace__data.callback = callback; From d42e4d5fee93a7bf35f4acca0cc3a1bea94347ea Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:16:57 +0100 Subject: [PATCH 0156/1616] transaction: use GIT_ASSERT --- src/transaction.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/transaction.c b/src/transaction.c index 81af8d83153..98fa1ba900c 100644 --- a/src/transaction.c +++ b/src/transaction.c @@ -57,7 +57,9 @@ struct git_transaction { int git_transaction_config_new(git_transaction **out, git_config *cfg) { git_transaction *tx; - assert(out && cfg); + + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(cfg); tx = git__calloc(1, sizeof(git_transaction)); GIT_ERROR_CHECK_ALLOC(tx); @@ -74,7 +76,8 @@ int git_transaction_new(git_transaction **out, git_repository *repo) git_pool pool; git_transaction *tx = NULL; - assert(out && repo); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); if ((error = git_pool_init(&pool, 1)) < 0) goto on_error; @@ -109,7 +112,8 @@ int git_transaction_lock_ref(git_transaction *tx, const char *refname) int error; transaction_node *node; - assert(tx && refname); + GIT_ASSERT_ARG(tx); + GIT_ASSERT_ARG(refname); node = git_pool_mallocz(&tx->pool, sizeof(transaction_node)); GIT_ERROR_CHECK_ALLOC(node); @@ -176,7 +180,9 @@ int git_transaction_set_target(git_transaction *tx, const char *refname, const g int error; transaction_node *node; - assert(tx && refname && target); + GIT_ASSERT_ARG(tx); + GIT_ASSERT_ARG(refname); + GIT_ASSERT_ARG(target); if ((error = find_locked(&node, tx, refname)) < 0) return error; @@ -195,7 +201,9 @@ int git_transaction_set_symbolic_target(git_transaction *tx, const char *refname int error; transaction_node *node; - assert(tx && refname && target); + GIT_ASSERT_ARG(tx); + GIT_ASSERT_ARG(refname); + GIT_ASSERT_ARG(target); if ((error = find_locked(&node, tx, refname)) < 0) return error; @@ -272,7 +280,9 @@ int git_transaction_set_reflog(git_transaction *tx, const char *refname, const g int error; transaction_node *node; - assert(tx && refname && reflog); + GIT_ASSERT_ARG(tx); + GIT_ASSERT_ARG(refname); + GIT_ASSERT_ARG(reflog); if ((error = find_locked(&node, tx, refname)) < 0) return error; @@ -320,7 +330,7 @@ int git_transaction_commit(git_transaction *tx) transaction_node *node; int error = 0; - assert(tx); + GIT_ASSERT_ARG(tx); if (tx->type == TRANSACTION_CONFIG) { error = git_config_unlock(tx->cfg, true); @@ -355,7 +365,8 @@ void git_transaction_free(git_transaction *tx) transaction_node *node; git_pool pool; - assert(tx); + if (!tx) + return; if (tx->type == TRANSACTION_CONFIG) { if (tx->cfg) { From 2ab26a98abf9aa410bc0392eb4a121afdf2299bd Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:17:41 +0100 Subject: [PATCH 0157/1616] transport: use GIT_ASSERT --- src/transport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transport.c b/src/transport.c index 227ee7dee3a..e128aa6c724 100644 --- a/src/transport.c +++ b/src/transport.c @@ -148,8 +148,8 @@ int git_transport_register( size_t i; int error = 0; - assert(scheme); - assert(cb); + GIT_ASSERT_ARG(scheme); + GIT_ASSERT_ARG(cb); if ((error = git_buf_printf(&prefix, "%s://", scheme)) < 0) goto on_error; @@ -186,7 +186,7 @@ int git_transport_unregister(const char *scheme) size_t i; int error = 0; - assert(scheme); + GIT_ASSERT_ARG(scheme); if ((error = git_buf_printf(&prefix, "%s://", scheme)) < 0) goto done; From 8613133b1f6bcbfef8b469ed2235fa9dc84a8412 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:21:30 +0100 Subject: [PATCH 0158/1616] tree: use GIT_ASSERT --- src/tree.c | 51 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/tree.c b/src/tree.c index 48468dff6a0..ba6383ef8da 100644 --- a/src/tree.c +++ b/src/tree.c @@ -228,7 +228,7 @@ int git_tree_entry_dup(git_tree_entry **dest, const git_tree_entry *source) { git_tree_entry *cpy; - assert(source); + GIT_ASSERT_ARG(source); cpy = alloc_entry(source->filename, source->filename_len, source->oid); if (cpy == NULL) @@ -261,19 +261,19 @@ git_filemode_t git_tree_entry_filemode_raw(const git_tree_entry *entry) const char *git_tree_entry_name(const git_tree_entry *entry) { - assert(entry); + GIT_ASSERT_ARG_WITH_RETVAL(entry, NULL); return entry->filename; } const git_oid *git_tree_entry_id(const git_tree_entry *entry) { - assert(entry); + GIT_ASSERT_ARG_WITH_RETVAL(entry, NULL); return entry->oid; } git_object_t git_tree_entry_type(const git_tree_entry *entry) { - assert(entry); + GIT_ASSERT_ARG_WITH_RETVAL(entry, GIT_OBJECT_INVALID); if (S_ISGITLINK(entry->attr)) return GIT_OBJECT_COMMIT; @@ -288,7 +288,9 @@ int git_tree_entry_to_object( git_repository *repo, const git_tree_entry *entry) { - assert(entry && object_out); + GIT_ASSERT_ARG(entry); + GIT_ASSERT_ARG(object_out); + return git_object_lookup(object_out, repo, entry->oid, GIT_OBJECT_ANY); } @@ -306,7 +308,8 @@ static const git_tree_entry *entry_fromname( const git_tree_entry *git_tree_entry_byname( const git_tree *tree, const char *filename) { - assert(tree && filename); + GIT_ASSERT_ARG_WITH_RETVAL(tree, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(filename, NULL); return entry_fromname(tree, filename, strlen(filename)); } @@ -314,7 +317,7 @@ const git_tree_entry *git_tree_entry_byname( const git_tree_entry *git_tree_entry_byindex( const git_tree *tree, size_t idx) { - assert(tree); + GIT_ASSERT_ARG_WITH_RETVAL(tree, NULL); return git_array_get(tree->entries, idx); } @@ -324,7 +327,7 @@ const git_tree_entry *git_tree_entry_byid( size_t i; const git_tree_entry *e; - assert(tree); + GIT_ASSERT_ARG_WITH_RETVAL(tree, NULL); git_array_foreach(tree->entries, i, e) { if (memcmp(&e->oid->id, &id->id, sizeof(id->id)) == 0) @@ -336,13 +339,13 @@ const git_tree_entry *git_tree_entry_byid( size_t git_tree_entrycount(const git_tree *tree) { - assert(tree); + GIT_ASSERT_ARG_WITH_RETVAL(tree, 0); return tree->entries.size; } size_t git_treebuilder_entrycount(git_treebuilder *bld) { - assert(bld); + GIT_ASSERT_ARG_WITH_RETVAL(bld, 0); return git_strmap_size(bld->map); } @@ -626,7 +629,9 @@ int git_tree__write_index( git_buf shared_buf = GIT_BUF_INIT; bool old_ignore_case = false; - assert(oid && index && repo); + GIT_ASSERT_ARG(oid); + GIT_ASSERT_ARG(index); + GIT_ASSERT_ARG(repo); if (git_index_has_conflicts(index)) { git_error_set(GIT_ERROR_INDEX, @@ -680,7 +685,8 @@ int git_treebuilder_new( git_treebuilder *bld; size_t i; - assert(builder_p && repo); + GIT_ASSERT_ARG(builder_p); + GIT_ASSERT_ARG(repo); bld = git__calloc(1, sizeof(git_treebuilder)); GIT_ERROR_CHECK_ALLOC(bld); @@ -723,7 +729,9 @@ int git_treebuilder_insert( git_tree_entry *entry; int error; - assert(bld && id && filename); + GIT_ASSERT_ARG(bld); + GIT_ASSERT_ARG(id); + GIT_ASSERT_ARG(filename); if ((error = check_entry(bld->repo, filename, id, filemode)) < 0) return error; @@ -751,7 +759,9 @@ int git_treebuilder_insert( static git_tree_entry *treebuilder_get(git_treebuilder *bld, const char *filename) { - assert(bld && filename); + GIT_ASSERT_ARG_WITH_RETVAL(bld, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(filename, NULL); + return git_strmap_get(bld->map, filename); } @@ -792,8 +802,8 @@ int git_treebuilder_write_with_buffer(git_oid *oid, git_treebuilder *bld, git_bu git_tree_entry *entry; git_vector entries = GIT_VECTOR_INIT; - assert(bld); - assert(tree); + GIT_ASSERT_ARG(bld); + GIT_ASSERT_ARG(tree); git_buf_clear(tree); @@ -842,7 +852,8 @@ int git_treebuilder_filter( const char *filename; git_tree_entry *entry; - assert(bld && filter); + GIT_ASSERT_ARG(bld); + GIT_ASSERT_ARG(filter); git_strmap_foreach(bld->map, filename, entry, { if (filter(entry, payload)) { @@ -858,7 +869,7 @@ int git_treebuilder_clear(git_treebuilder *bld) { git_tree_entry *e; - assert(bld); + GIT_ASSERT_ARG(bld); git_strmap_foreach_value(bld->map, e, git_tree_entry_free(e)); git_strmap_clear(bld->map); @@ -1174,10 +1185,10 @@ int git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseli for (j = 0; j < steps_up; j++) { tree_stack_entry *current, *popped = git_array_pop(stack); - assert(popped); + GIT_ASSERT(popped); current = git_array_last(stack); - assert(current); + GIT_ASSERT(current); if ((error = create_popped_tree(current, popped, &component)) < 0) goto cleanup; From 63baed3762b017e26152eaac38d74f12c9e49cff Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:23:54 +0100 Subject: [PATCH 0159/1616] tsort: remove assertion --- src/tsort.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tsort.c b/src/tsort.c index 8d1ed9787c0..045efad23f6 100644 --- a/src/tsort.c +++ b/src/tsort.c @@ -29,8 +29,6 @@ static int binsearch( int l, c, r; void *lx, *cx; - assert(size > 0); - l = 0; r = (int)size - 1; c = r >> 1; From 64e2b6ef022607e5ceca39e9ea9b6f3a8cc00f8e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:28:19 +0100 Subject: [PATCH 0160/1616] vector: use GIT_ASSERT --- src/vector.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/vector.c b/src/vector.c index b51e7644b56..4a4bc8c0e44 100644 --- a/src/vector.c +++ b/src/vector.c @@ -53,7 +53,8 @@ int git_vector_size_hint(git_vector *v, size_t size_hint) int git_vector_dup(git_vector *v, const git_vector *src, git_vector_cmp cmp) { - assert(v && src); + GIT_ASSERT_ARG(v); + GIT_ASSERT_ARG(src); v->_alloc_size = 0; v->contents = NULL; @@ -77,7 +78,8 @@ int git_vector_dup(git_vector *v, const git_vector *src, git_vector_cmp cmp) void git_vector_free(git_vector *v) { - assert(v); + if (!v) + return; git__free(v->contents); v->contents = NULL; @@ -90,7 +92,8 @@ void git_vector_free_deep(git_vector *v) { size_t i; - assert(v); + if (!v) + return; for (i = 0; i < v->length; ++i) { git__free(v->contents[i]); @@ -102,7 +105,7 @@ void git_vector_free_deep(git_vector *v) int git_vector_init(git_vector *v, size_t initial_size, git_vector_cmp cmp) { - assert(v); + GIT_ASSERT_ARG(v); v->_alloc_size = 0; v->_cmp = cmp; @@ -131,7 +134,7 @@ void **git_vector_detach(size_t *size, size_t *asize, git_vector *v) int git_vector_insert(git_vector *v, void *element) { - assert(v); + GIT_ASSERT_ARG(v); if (v->length >= v->_alloc_size && resize_vector(v, compute_new_size(v)) < 0) @@ -150,7 +153,8 @@ int git_vector_insert_sorted( int result; size_t pos; - assert(v && v->_cmp); + GIT_ASSERT_ARG(v); + GIT_ASSERT(v->_cmp); if (!git_vector_is_sorted(v)) git_vector_sort(v); @@ -180,8 +184,6 @@ int git_vector_insert_sorted( void git_vector_sort(git_vector *v) { - assert(v); - if (git_vector_is_sorted(v) || !v->_cmp) return; @@ -196,7 +198,9 @@ int git_vector_bsearch2( git_vector_cmp key_lookup, const void *key) { - assert(v && key && key_lookup); + GIT_ASSERT_ARG(v); + GIT_ASSERT_ARG(key); + GIT_ASSERT(key_lookup); /* need comparison function to sort the vector */ if (!v->_cmp) @@ -212,7 +216,9 @@ int git_vector_search2( { size_t i; - assert(v && key && key_lookup); + GIT_ASSERT_ARG(v); + GIT_ASSERT_ARG(key); + GIT_ASSERT(key_lookup); for (i = 0; i < v->length; ++i) { if (key_lookup(key, v->contents[i]) == 0) { @@ -240,7 +246,7 @@ int git_vector_remove(git_vector *v, size_t idx) { size_t shift_count; - assert(v); + GIT_ASSERT_ARG(v); if (idx >= v->length) return GIT_ENOTFOUND; @@ -303,7 +309,6 @@ void git_vector_remove_matching( void git_vector_clear(git_vector *v) { - assert(v); v->length = 0; git_vector_set_sorted(v, 1); } @@ -312,8 +317,6 @@ void git_vector_swap(git_vector *a, git_vector *b) { git_vector t; - assert(a && b); - if (a != b) { memcpy(&t, a, sizeof(t)); memcpy(a, b, sizeof(t)); @@ -340,7 +343,8 @@ int git_vector_insert_null(git_vector *v, size_t idx, size_t insert_len) { size_t new_length; - assert(insert_len > 0 && idx <= v->length); + GIT_ASSERT_ARG(insert_len > 0); + GIT_ASSERT_ARG(idx <= v->length); GIT_ERROR_CHECK_ALLOC_ADD(&new_length, v->length, insert_len); @@ -359,13 +363,13 @@ int git_vector_remove_range(git_vector *v, size_t idx, size_t remove_len) { size_t new_length = v->length - remove_len; size_t end_idx = 0; - - assert(remove_len > 0); + + GIT_ASSERT_ARG(remove_len > 0); if (git__add_sizet_overflow(&end_idx, idx, remove_len)) - assert(0); + GIT_ASSERT(0); - assert(end_idx <= v->length); + GIT_ASSERT(end_idx <= v->length); if (end_idx < v->length) memmove(&v->contents[idx], &v->contents[end_idx], From 0165e885bcb04cb3134df0dbe32f27b8deeabc65 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:29:56 +0100 Subject: [PATCH 0161/1616] worktree: use GIT_ASSERT --- src/worktree.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/worktree.c b/src/worktree.c index 5b1e2794b94..7d447e896d8 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -37,7 +37,8 @@ int git_worktree_list(git_strarray *wts, git_repository *repo) size_t i, len; int error; - assert(wts && repo); + GIT_ASSERT_ARG(wts); + GIT_ASSERT_ARG(repo); wts->count = 0; wts->strings = NULL; @@ -73,7 +74,8 @@ char *git_worktree__read_link(const char *base, const char *file) { git_buf path = GIT_BUF_INIT, buf = GIT_BUF_INIT; - assert(base && file); + GIT_ASSERT_ARG_WITH_RETVAL(base, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(file, NULL); if (git_buf_joinpath(&path, base, file) < 0) goto err; @@ -106,7 +108,9 @@ static int write_wtfile(const char *base, const char *file, const git_buf *buf) git_buf path = GIT_BUF_INIT; int err; - assert(base && file && buf); + GIT_ASSERT_ARG(base); + GIT_ASSERT_ARG(file); + GIT_ASSERT_ARG(buf); if ((err = git_buf_joinpath(&path, base, file)) < 0) goto out; @@ -170,7 +174,8 @@ int git_worktree_lookup(git_worktree **out, git_repository *repo, const char *na git_worktree *wt = NULL; int error; - assert(repo && name); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); *out = NULL; @@ -237,7 +242,7 @@ void git_worktree_free(git_worktree *wt) int git_worktree_validate(const git_worktree *wt) { - assert(wt); + GIT_ASSERT_ARG(wt); if (!is_worktree_dir(wt->gitdir_path)) { git_error_set(GIT_ERROR_WORKTREE, @@ -304,7 +309,10 @@ int git_worktree_add(git_worktree **out, git_repository *repo, if (opts) memcpy(&wtopts, opts, sizeof(wtopts)); - assert(out && repo && name && worktree); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(name); + GIT_ASSERT_ARG(worktree); *out = NULL; @@ -417,7 +425,7 @@ int git_worktree_lock(git_worktree *wt, const char *reason) git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT; int error; - assert(wt); + GIT_ASSERT_ARG(wt); if ((error = git_worktree_is_locked(NULL, wt)) < 0) goto out; @@ -448,7 +456,7 @@ int git_worktree_unlock(git_worktree *wt) git_buf path = GIT_BUF_INIT; int error; - assert(wt); + GIT_ASSERT_ARG(wt); if ((error = git_worktree_is_locked(NULL, wt)) < 0) return error; @@ -475,7 +483,7 @@ int git_worktree_is_locked(git_buf *reason, const git_worktree *wt) git_buf path = GIT_BUF_INIT; int error, locked; - assert(wt); + GIT_ASSERT_ARG(wt); if (reason) git_buf_clear(reason); @@ -496,13 +504,13 @@ int git_worktree_is_locked(git_buf *reason, const git_worktree *wt) const char *git_worktree_name(const git_worktree *wt) { - assert(wt); + GIT_ASSERT_ARG_WITH_RETVAL(wt, NULL); return wt->name; } const char *git_worktree_path(const git_worktree *wt) { - assert(wt); + GIT_ASSERT_ARG_WITH_RETVAL(wt, NULL); return wt->worktree_path; } From cac36006ac512db953544e0daff963657589ae9e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Apr 2020 22:30:20 +0100 Subject: [PATCH 0162/1616] zstream: use GIT_ASSERT --- src/zstream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zstream.c b/src/zstream.c index 975ead2f6fb..a5675676e90 100644 --- a/src/zstream.c +++ b/src/zstream.c @@ -156,7 +156,7 @@ int git_zstream_get_output(void *out, size_t *out_len, git_zstream *zstream) } /* either we finished the input or we did not flush the data */ - assert(zstream->in_len > 0 || zstream->flush == Z_FINISH); + GIT_ASSERT(zstream->in_len > 0 || zstream->flush == Z_FINISH); /* set out_size to number of bytes actually written to output */ *out_len = *out_len - out_remain; From 3ff56dae29a213110255a30f5085ad290c98d717 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 21 Nov 2020 23:35:09 +0000 Subject: [PATCH 0163/1616] hash: use GIT_ASSERT --- src/hash/sha1/collisiondetect.c | 6 +++--- src/hash/sha1/common_crypto.c | 6 +++--- src/hash/sha1/mbedtls.c | 24 ++++++++++++------------ src/hash/sha1/openssl.c | 6 +++--- src/hash/sha1/win32.c | 21 ++++++++++++--------- 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/hash/sha1/collisiondetect.c b/src/hash/sha1/collisiondetect.c index e6a126780a1..722ebf36f38 100644 --- a/src/hash/sha1/collisiondetect.c +++ b/src/hash/sha1/collisiondetect.c @@ -24,21 +24,21 @@ void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx) int git_hash_sha1_init(git_hash_sha1_ctx *ctx) { - assert(ctx); + GIT_ASSERT_ARG(ctx); SHA1DCInit(&ctx->c); return 0; } int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) { - assert(ctx); + GIT_ASSERT_ARG(ctx); SHA1DCUpdate(&ctx->c, data, len); return 0; } int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) { - assert(ctx); + GIT_ASSERT_ARG(ctx); if (SHA1DCFinal(out->id, &ctx->c)) { git_error_set(GIT_ERROR_SHA1, "SHA1 collision attack detected"); return -1; diff --git a/src/hash/sha1/common_crypto.c b/src/hash/sha1/common_crypto.c index 0449a3c9dff..4250e0b614f 100644 --- a/src/hash/sha1/common_crypto.c +++ b/src/hash/sha1/common_crypto.c @@ -26,7 +26,7 @@ void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx) int git_hash_sha1_init(git_hash_sha1_ctx *ctx) { - assert(ctx); + GIT_ASSERT_ARG(ctx); CC_SHA1_Init(&ctx->c); return 0; } @@ -35,7 +35,7 @@ int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *_data, size_t len) { const unsigned char *data = _data; - assert(ctx); + GIT_ASSERT_ARG(ctx); while (len > 0) { CC_LONG chunk = (len > CC_LONG_MAX) ? CC_LONG_MAX : (CC_LONG)len; @@ -51,7 +51,7 @@ int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *_data, size_t len) int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) { - assert(ctx); + GIT_ASSERT_ARG(ctx); CC_SHA1_Final(out->id, &ctx->c); return 0; } diff --git a/src/hash/sha1/mbedtls.c b/src/hash/sha1/mbedtls.c index e44343fcf3c..04e7da5facb 100644 --- a/src/hash/sha1/mbedtls.c +++ b/src/hash/sha1/mbedtls.c @@ -19,28 +19,28 @@ int git_hash_sha1_ctx_init(git_hash_sha1_ctx *ctx) void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx) { - assert(ctx); - mbedtls_sha1_free(&ctx->c); + if (ctx) + mbedtls_sha1_free(&ctx->c); } int git_hash_sha1_init(git_hash_sha1_ctx *ctx) { - assert(ctx); - mbedtls_sha1_init(&ctx->c); - mbedtls_sha1_starts(&ctx->c); - return 0; + GIT_ASSERT_ARG(ctx); + mbedtls_sha1_init(&ctx->c); + mbedtls_sha1_starts(&ctx->c); + return 0; } int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) { - assert(ctx); - mbedtls_sha1_update(&ctx->c, data, len); - return 0; + GIT_ASSERT_ARG(ctx); + mbedtls_sha1_update(&ctx->c, data, len); + return 0; } int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) { - assert(ctx); - mbedtls_sha1_finish(&ctx->c, out->id); - return 0; + GIT_ASSERT_ARG(ctx); + mbedtls_sha1_finish(&ctx->c, out->id); + return 0; } diff --git a/src/hash/sha1/openssl.c b/src/hash/sha1/openssl.c index ba3212ff283..68d9611d4ad 100644 --- a/src/hash/sha1/openssl.c +++ b/src/hash/sha1/openssl.c @@ -24,7 +24,7 @@ void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx) int git_hash_sha1_init(git_hash_sha1_ctx *ctx) { - assert(ctx); + GIT_ASSERT_ARG(ctx); if (SHA1_Init(&ctx->c) != 1) { git_error_set(GIT_ERROR_SHA1, "hash_openssl: failed to initialize hash context"); @@ -36,7 +36,7 @@ int git_hash_sha1_init(git_hash_sha1_ctx *ctx) int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) { - assert(ctx); + GIT_ASSERT_ARG(ctx); if (SHA1_Update(&ctx->c, data, len) != 1) { git_error_set(GIT_ERROR_SHA1, "hash_openssl: failed to update hash"); @@ -48,7 +48,7 @@ int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) { - assert(ctx); + GIT_ASSERT_ARG(ctx); if (SHA1_Final(out->id, &ctx->c) != 1) { git_error_set(GIT_ERROR_SHA1, "hash_openssl: failed to finalize hash"); diff --git a/src/hash/sha1/win32.c b/src/hash/sha1/win32.c index b1266cca020..a6e7061c6ac 100644 --- a/src/hash/sha1/win32.c +++ b/src/hash/sha1/win32.c @@ -164,7 +164,7 @@ GIT_INLINE(int) hash_cryptoapi_update(git_hash_sha1_ctx *ctx, const void *_data, { const BYTE *data = (BYTE *)_data; - assert(ctx->ctx.cryptoapi.valid); + GIT_ASSERT(ctx->ctx.cryptoapi.valid); while (len > 0) { DWORD chunk = (len > MAXDWORD) ? MAXDWORD : (DWORD)len; @@ -186,7 +186,7 @@ GIT_INLINE(int) hash_cryptoapi_final(git_oid *out, git_hash_sha1_ctx *ctx) DWORD len = 20; int error = 0; - assert(ctx->ctx.cryptoapi.valid); + GIT_ASSERT(ctx->ctx.cryptoapi.valid); if (!CryptGetHashParam(ctx->ctx.cryptoapi.hash_handle, HP_HASHVAL, out->id, &len, 0)) { git_error_set(GIT_ERROR_OS, "legacy hash data could not be finished"); @@ -286,7 +286,7 @@ int git_hash_sha1_ctx_init(git_hash_sha1_ctx *ctx) { int error = 0; - assert(ctx); + GIT_ASSERT_ARG(ctx); /* * When compiled with GIT_THREADS, the global hash_prov data is @@ -303,27 +303,30 @@ int git_hash_sha1_ctx_init(git_hash_sha1_ctx *ctx) int git_hash_sha1_init(git_hash_sha1_ctx *ctx) { - assert(ctx && ctx->type); + GIT_ASSERT_ARG(ctx); + GIT_ASSERT_ARG(ctx->type); return (ctx->type == CNG) ? hash_cng_init(ctx) : hash_cryptoapi_init(ctx); } int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) { - assert(ctx && ctx->type); + GIT_ASSERT_ARG(ctx); + GIT_ASSERT_ARG(ctx->type); return (ctx->type == CNG) ? hash_cng_update(ctx, data, len) : hash_cryptoapi_update(ctx, data, len); } int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) { - assert(ctx && ctx->type); + GIT_ASSERT_ARG(ctx); + GIT_ASSERT_ARG(ctx->type); return (ctx->type == CNG) ? hash_cng_final(out, ctx) : hash_cryptoapi_final(out, ctx); } void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx) { - assert(ctx); - - if (ctx->type == CNG) + if (!ctx) + return; + else if (ctx->type == CNG) hash_ctx_cng_cleanup(ctx); else if(ctx->type == CRYPTOAPI) hash_ctx_cryptoapi_cleanup(ctx); From 07a3c9928aa36cfd6f02d500222ed6cb22eeeed1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 21 Nov 2020 23:52:39 +0000 Subject: [PATCH 0164/1616] streams: use GIT_ASSERT --- src/streams/mbedtls.c | 10 ++++++---- src/streams/openssl.c | 12 ++++++++---- src/streams/registry.c | 6 +++--- src/streams/socket.c | 8 ++++++-- src/streams/stransport.c | 9 ++++++--- src/streams/tls.c | 7 +++++-- 6 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/streams/mbedtls.c b/src/streams/mbedtls.c index 00daa55215a..22b9f47df55 100644 --- a/src/streams/mbedtls.c +++ b/src/streams/mbedtls.c @@ -181,8 +181,8 @@ static int ssl_set_error(mbedtls_ssl_context *ssl, int error) char errbuf[512]; int ret = -1; - assert(error != MBEDTLS_ERR_SSL_WANT_READ); - assert(error != MBEDTLS_ERR_SSL_WANT_WRITE); + GIT_ASSERT(error != MBEDTLS_ERR_SSL_WANT_READ); + GIT_ASSERT(error != MBEDTLS_ERR_SSL_WANT_WRITE); if (error != 0) mbedtls_strerror( error, errbuf, 512 ); @@ -423,7 +423,9 @@ int git_mbedtls_stream_new( git_stream *stream; int error; - assert(out && host && port); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(host); + GIT_ASSERT_ARG(port); if ((error = git_socket_stream_new(&stream, host, port)) < 0) return error; @@ -442,7 +444,7 @@ int git_mbedtls__set_cert_location(const char *path, int is_dir) char errbuf[512]; mbedtls_x509_crt *cacert; - assert(path != NULL); + GIT_ASSERT_ARG(path); cacert = git__malloc(sizeof(mbedtls_x509_crt)); GIT_ERROR_CHECK_ALLOC(cacert); diff --git a/src/streams/openssl.c b/src/streams/openssl.c index 0a0c2c5e5bb..d866832c618 100644 --- a/src/streams/openssl.c +++ b/src/streams/openssl.c @@ -414,8 +414,8 @@ static int ssl_set_error(SSL *ssl, int error) err = SSL_get_error(ssl, error); - assert(err != SSL_ERROR_WANT_READ); - assert(err != SSL_ERROR_WANT_WRITE); + GIT_ASSERT(err != SSL_ERROR_WANT_READ); + GIT_ASSERT(err != SSL_ERROR_WANT_WRITE); switch (err) { case SSL_ERROR_WANT_CONNECT: @@ -757,7 +757,9 @@ static int openssl_stream_wrap( { openssl_stream *st; - assert(out && in && host); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(in); + GIT_ASSERT_ARG(host); st = git__calloc(1, sizeof(openssl_stream)); GIT_ERROR_CHECK_ALLOC(st); @@ -800,7 +802,9 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port) git_stream *stream = NULL; int error; - assert(out && host && port); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(host); + GIT_ASSERT_ARG(port); if ((error = git_socket_stream_new(&stream, host, port)) < 0) return error; diff --git a/src/streams/registry.c b/src/streams/registry.c index b3bf17a4e9b..e60e1cd63e8 100644 --- a/src/streams/registry.c +++ b/src/streams/registry.c @@ -51,7 +51,7 @@ int git_stream_registry_lookup(git_stream_registration *out, git_stream_t type) git_stream_registration *target; int error = GIT_ENOTFOUND; - assert(out); + GIT_ASSERT_ARG(out); switch(type) { case GIT_STREAM_STANDARD: @@ -61,7 +61,7 @@ int git_stream_registry_lookup(git_stream_registration *out, git_stream_t type) target = &stream_registry.tls_callbacks; break; default: - assert(0); + git_error_set(GIT_ERROR_INVALID, "invalid stream type"); return -1; } @@ -81,7 +81,7 @@ int git_stream_registry_lookup(git_stream_registration *out, git_stream_t type) int git_stream_register(git_stream_t type, git_stream_registration *registration) { - assert(!registration || registration->init); + GIT_ASSERT(!registration || registration->init); GIT_ERROR_CHECK_VERSION(registration, GIT_STREAM_VERSION, "stream_registration"); diff --git a/src/streams/socket.c b/src/streams/socket.c index 33f7883cd9c..9415fe89237 100644 --- a/src/streams/socket.c +++ b/src/streams/socket.c @@ -183,7 +183,9 @@ static int default_socket_stream_new( { git_socket_stream *st; - assert(out && host && port); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(host); + GIT_ASSERT_ARG(port); st = git__calloc(1, sizeof(git_socket_stream)); GIT_ERROR_CHECK_ALLOC(st); @@ -217,7 +219,9 @@ int git_socket_stream_new( git_stream_registration custom = {0}; int error; - assert(out && host && port); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(host); + GIT_ASSERT_ARG(port); if ((error = git_stream_registry_lookup(&custom, GIT_STREAM_STANDARD)) == 0) init = custom.init; diff --git a/src/streams/stransport.c b/src/streams/stransport.c index a79d3cbf0d7..3f31d2541c7 100644 --- a/src/streams/stransport.c +++ b/src/streams/stransport.c @@ -167,7 +167,7 @@ static ssize_t stransport_write(git_stream *stream, const char *data, size_t len if ((ret = SSLWrite(st->ctx, data, data_len, &processed)) != noErr) return stransport_error(ret); - assert(processed < SSIZE_MAX); + GIT_ASSERT(processed < SSIZE_MAX); return (ssize_t)processed; } @@ -251,7 +251,9 @@ static int stransport_wrap( stransport_stream *st; OSStatus ret; - assert(out && in && host); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(in); + GIT_ASSERT_ARG(host); st = git__calloc(1, sizeof(stransport_stream)); GIT_ERROR_CHECK_ALLOC(st); @@ -305,7 +307,8 @@ int git_stransport_stream_new(git_stream **out, const char *host, const char *po git_stream *stream = NULL; int error; - assert(out && host); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(host); error = git_socket_stream_new(&stream, host, port); diff --git a/src/streams/tls.c b/src/streams/tls.c index 255a4a0f630..e063a33f99a 100644 --- a/src/streams/tls.c +++ b/src/streams/tls.c @@ -20,7 +20,9 @@ int git_tls_stream_new(git_stream **out, const char *host, const char *port) git_stream_registration custom = {0}; int error; - assert(out && host && port); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(host); + GIT_ASSERT_ARG(port); if ((error = git_stream_registry_lookup(&custom, GIT_STREAM_TLS)) == 0) { init = custom.init; @@ -49,7 +51,8 @@ int git_tls_stream_wrap(git_stream **out, git_stream *in, const char *host) int (*wrap)(git_stream **, git_stream *, const char *) = NULL; git_stream_registration custom = {0}; - assert(out && in); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(in); if (git_stream_registry_lookup(&custom, GIT_STREAM_TLS) == 0) { wrap = custom.wrap; From 4f5f112793c520eaf3f517b295c0128e0efea73e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 22 Nov 2020 00:01:09 +0000 Subject: [PATCH 0165/1616] transports: use GIT_ASSERT --- src/transports/auth_negotiate.c | 13 +++++++++--- src/transports/auth_ntlm.c | 12 +++++++---- src/transports/credential.c | 22 +++++++++++++------- src/transports/git.c | 4 +--- src/transports/http.c | 11 +++++----- src/transports/httpclient.c | 36 ++++++++++++++++++++------------- src/transports/local.c | 2 +- src/transports/smart.c | 13 +++++++----- src/transports/ssh.c | 18 ++++++++--------- src/transports/winhttp.c | 14 ++++++------- 10 files changed, 86 insertions(+), 59 deletions(-) diff --git a/src/transports/auth_negotiate.c b/src/transports/auth_negotiate.c index 8a614b81a3a..c538dbbca9d 100644 --- a/src/transports/auth_negotiate.c +++ b/src/transports/auth_negotiate.c @@ -65,7 +65,9 @@ static int negotiate_set_challenge( { http_auth_negotiate_context *ctx = (http_auth_negotiate_context *)c; - assert(ctx && ctx->configured && challenge); + GIT_ASSERT_ARG(ctx); + GIT_ASSERT_ARG(challenge); + GIT_ASSERT(ctx->configured); git__free(ctx->challenge); @@ -108,7 +110,12 @@ static int negotiate_next_token( size_t challenge_len; int error = 0; - assert(buf && ctx && ctx->configured && cred && cred->credtype == GIT_CREDENTIAL_DEFAULT); + GIT_ASSERT_ARG(buf); + GIT_ASSERT_ARG(ctx); + GIT_ASSERT_ARG(cred); + + GIT_ASSERT(ctx->configured); + GIT_ASSERT(cred->credtype == GIT_CREDENTIAL_DEFAULT); if (ctx->complete) return 0; @@ -202,7 +209,7 @@ static int negotiate_is_complete(git_http_auth_context *c) { http_auth_negotiate_context *ctx = (http_auth_negotiate_context *)c; - assert(ctx); + GIT_ASSERT_ARG(ctx); return (ctx->complete == 1); } diff --git a/src/transports/auth_ntlm.c b/src/transports/auth_ntlm.c index d134a3db666..e0960bf9d3b 100644 --- a/src/transports/auth_ntlm.c +++ b/src/transports/auth_ntlm.c @@ -29,7 +29,8 @@ static int ntlm_set_challenge( { http_auth_ntlm_context *ctx = (http_auth_ntlm_context *)c; - assert(ctx && challenge); + GIT_ASSERT_ARG(ctx); + GIT_ASSERT_ARG(challenge); git__free(ctx->challenge); @@ -46,7 +47,7 @@ static int ntlm_set_credentials(http_auth_ntlm_context *ctx, git_credential *_cr char *domain = NULL, *domainuser = NULL; int error = 0; - assert(_cred->credtype == GIT_CREDENTIAL_USERPASS_PLAINTEXT); + GIT_ASSERT(_cred->credtype == GIT_CREDENTIAL_USERPASS_PLAINTEXT); cred = (git_credential_userpass_plaintext *)_cred; if ((sep = strchr(cred->username, '\\')) != NULL) { @@ -86,7 +87,10 @@ static int ntlm_next_token( size_t challenge_len, msg_len; int error = -1; - assert(buf && ctx && ctx->ntlm); + GIT_ASSERT_ARG(buf); + GIT_ASSERT_ARG(ctx); + + GIT_ASSERT(ctx->ntlm); challenge_len = ctx->challenge ? strlen(ctx->challenge) : 0; @@ -162,7 +166,7 @@ static int ntlm_is_complete(git_http_auth_context *c) { http_auth_ntlm_context *ctx = (http_auth_ntlm_context *)c; - assert(ctx); + GIT_ASSERT_ARG(ctx); return (ctx->complete == true); } diff --git a/src/transports/credential.c b/src/transports/credential.c index 7b2836445bc..6e00b028243 100644 --- a/src/transports/credential.c +++ b/src/transports/credential.c @@ -85,7 +85,9 @@ int git_credential_userpass_plaintext_new( { git_credential_userpass_plaintext *c; - assert(cred && username && password); + GIT_ASSERT_ARG(cred); + GIT_ASSERT_ARG(username); + GIT_ASSERT_ARG(password); c = git__malloc(sizeof(git_credential_userpass_plaintext)); GIT_ERROR_CHECK_ALLOC(c); @@ -233,7 +235,9 @@ static int git_credential_ssh_key_type_new( { git_credential_ssh_key *c; - assert(username && cred && privatekey); + GIT_ASSERT_ARG(username); + GIT_ASSERT_ARG(cred); + GIT_ASSERT_ARG(privatekey); c = git__calloc(1, sizeof(git_credential_ssh_key)); GIT_ERROR_CHECK_ALLOC(c); @@ -269,7 +273,9 @@ int git_credential_ssh_interactive_new( { git_credential_ssh_interactive *c; - assert(out && username && prompt_callback); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(username); + GIT_ASSERT_ARG(prompt_callback); c = git__calloc(1, sizeof(git_credential_ssh_interactive)); GIT_ERROR_CHECK_ALLOC(c); @@ -290,7 +296,8 @@ int git_credential_ssh_interactive_new( int git_credential_ssh_key_from_agent(git_credential **cred, const char *username) { git_credential_ssh_key *c; - assert(username && cred); + GIT_ASSERT_ARG(username); + GIT_ASSERT_ARG(cred); c = git__calloc(1, sizeof(git_credential_ssh_key)); GIT_ERROR_CHECK_ALLOC(c); @@ -317,7 +324,8 @@ int git_credential_ssh_custom_new( { git_credential_ssh_custom *c; - assert(username && cred); + GIT_ASSERT_ARG(username); + GIT_ASSERT_ARG(cred); c = git__calloc(1, sizeof(git_credential_ssh_custom)); GIT_ERROR_CHECK_ALLOC(c); @@ -347,7 +355,7 @@ int git_credential_default_new(git_credential **cred) { git_credential_default *c; - assert(cred); + GIT_ASSERT_ARG(cred); c = git__calloc(1, sizeof(git_credential_default)); GIT_ERROR_CHECK_ALLOC(c); @@ -364,7 +372,7 @@ int git_credential_username_new(git_credential **cred, const char *username) git_credential_username *c; size_t len, allocsize; - assert(cred); + GIT_ASSERT_ARG(cred); len = strlen(username); diff --git a/src/transports/git.c b/src/transports/git.c index e48b7f961cc..7c93155a8bf 100644 --- a/src/transports/git.c +++ b/src/transports/git.c @@ -327,7 +327,7 @@ static int _git_close(git_smart_subtransport *subtransport) { git_subtransport *t = (git_subtransport *) subtransport; - assert(!t->current_stream); + GIT_ASSERT(!t->current_stream); GIT_UNUSED(t); @@ -338,8 +338,6 @@ static void _git_free(git_smart_subtransport *subtransport) { git_subtransport *t = (git_subtransport *) subtransport; - assert(!t->current_stream); - git__free(t); } diff --git a/src/transports/http.c b/src/transports/http.c index fb1740c33c7..4538dd143e4 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -416,7 +416,7 @@ static int http_stream_read( goto done; } - assert (stream->state == HTTP_STATE_RECEIVING_RESPONSE); + GIT_ASSERT(stream->state == HTTP_STATE_RECEIVING_RESPONSE); error = git_http_client_read_body(transport->http_client, buffer, buffer_size); @@ -554,7 +554,7 @@ static int http_stream_write( goto done; } - assert(stream->state == HTTP_STATE_SENDING_REQUEST); + GIT_ASSERT(stream->state == HTTP_STATE_SENDING_REQUEST); error = git_http_client_send_body(transport->http_client, buffer, len); @@ -588,7 +588,7 @@ static int http_stream_read_response( (error = handle_response(&complete, stream, &response, false)) < 0) goto done; - assert(complete); + GIT_ASSERT(complete); stream->state = HTTP_STATE_RECEIVING_RESPONSE; } @@ -637,7 +637,8 @@ static int http_action( const http_service *service; int error; - assert(out && t); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(t); *out = NULL; @@ -720,7 +721,7 @@ int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *own GIT_UNUSED(param); - assert(out); + GIT_ASSERT_ARG(out); transport = git__calloc(sizeof(http_subtransport), 1); GIT_ERROR_CHECK_ALLOC(transport); diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index 6ec22f83768..d9cbf1783f8 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -145,7 +145,8 @@ bool git_http_response_is_redirect(git_http_response *response) void git_http_response_dispose(git_http_response *response) { - assert(response); + if (!response) + return; git__free(response->content_type); git__free(response->location); @@ -399,7 +400,7 @@ static int on_body(http_parser *parser, const char *buf, size_t len) return 0; } - assert(ctx->output_size >= ctx->output_written); + GIT_ASSERT(ctx->output_size >= ctx->output_written); max_len = min(ctx->output_size - ctx->output_written, len); max_len = min(max_len, INT_MAX); @@ -665,7 +666,8 @@ static int generate_request( size_t i; int error; - assert(client && request); + GIT_ASSERT_ARG(client); + GIT_ASSERT_ARG(request); git_buf_clear(&client->request_msg); buf = &client->request_msg; @@ -842,7 +844,10 @@ static int setup_hosts( { int ret, diff = 0; - assert(client && request && request->url); + GIT_ASSERT_ARG(client); + GIT_ASSERT_ARG(request); + + GIT_ASSERT(request->url); if ((ret = server_setup_from_url(&client->server, request->url)) < 0) return ret; @@ -922,7 +927,7 @@ static int proxy_connect( (error = git_http_client_skip_body(client)) < 0) goto done; - assert(client->state == DONE); + GIT_ASSERT(client->state == DONE); if (response.status == GIT_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED) { save_early_response(client, &response); @@ -1137,7 +1142,7 @@ GIT_INLINE(int) client_read_and_parse(git_http_client *client) * final byte when paused in a callback. Consume that byte. * https://github.com/nodejs/http-parser/issues/97 */ - assert(client->read_buf.size > parsed_len); + GIT_ASSERT(client->read_buf.size > parsed_len); http_parser_pause(parser, 0); @@ -1215,7 +1220,8 @@ int git_http_client_send_request( git_http_response response = {0}; int error = -1; - assert(client && request); + GIT_ASSERT_ARG(client); + GIT_ASSERT_ARG(request); /* If the client did not finish reading, clean up the stream. */ if (client->state == READING_BODY) @@ -1286,7 +1292,7 @@ int git_http_client_send_body( git_buf hdr = GIT_BUF_INIT; int error; - assert(client); + GIT_ASSERT_ARG(client); /* If we're waiting for proxy auth, don't sending more requests. */ if (client->state == HAS_EARLY_RESPONSE) @@ -1303,7 +1309,7 @@ int git_http_client_send_body( server = &client->server; if (client->request_body_len) { - assert(buffer_len <= client->request_body_remain); + GIT_ASSERT(buffer_len <= client->request_body_remain); if ((error = stream_write(server, buffer, buffer_len)) < 0) goto done; @@ -1326,7 +1332,8 @@ static int complete_request(git_http_client *client) { int error = 0; - assert(client && client->state == SENDING_BODY); + GIT_ASSERT_ARG(client); + GIT_ASSERT(client->state == SENDING_BODY); if (client->request_body_len && client->request_body_remain) { git_error_set(GIT_ERROR_HTTP, "truncated write"); @@ -1346,7 +1353,8 @@ int git_http_client_read_response( http_parser_context parser_context = {0}; int error; - assert(response && client); + GIT_ASSERT_ARG(response); + GIT_ASSERT_ARG(client); if (client->state == SENDING_BODY) { if ((error = complete_request(client)) < 0) @@ -1386,7 +1394,7 @@ int git_http_client_read_response( goto done; } - assert(client->state == READING_BODY || client->state == DONE); + GIT_ASSERT(client->state == READING_BODY || client->state == DONE); done: git_buf_dispose(&parser_context.parse_header_name); @@ -1439,7 +1447,7 @@ int git_http_client_read_body( break; } - assert(parser_context.output_written <= INT_MAX); + GIT_ASSERT(parser_context.output_written <= INT_MAX); error = (int)parser_context.output_written; done: @@ -1493,7 +1501,7 @@ int git_http_client_new( { git_http_client *client; - assert(out); + GIT_ASSERT_ARG(out); client = git__calloc(1, sizeof(git_http_client)); GIT_ERROR_CHECK_ALLOC(client); diff --git a/src/transports/local.c b/src/transports/local.c index 210de9f742e..4af85db817d 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -158,7 +158,7 @@ static int store_refs(transport_local *t) git_remote_head *head; git_strarray ref_names = {0}; - assert(t); + GIT_ASSERT_ARG(t); if (git_reference_list(&ref_names, t->repo) < 0) goto on_error; diff --git a/src/transports/smart.c b/src/transports/smart.c index 5f5919407d7..3b8a14a4c28 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -18,7 +18,7 @@ static int git_smart__recv_cb(gitno_buffer *buf) size_t old_len, bytes_read; int error; - assert(t->current_stream); + GIT_ASSERT(t->current_stream); old_len = buf->offset; @@ -346,7 +346,7 @@ int git_smart__negotiation_step(git_transport *transport, void *data, size_t len return error; /* If this is a stateful implementation, the stream we get back should be the same */ - assert(t->rpc || t->current_stream == stream); + GIT_ASSERT(t->rpc || t->current_stream == stream); /* Save off the current stream (i.e. socket) that we are working with */ t->current_stream = stream; @@ -375,7 +375,7 @@ int git_smart__get_push_stream(transport_smart *t, git_smart_subtransport_stream return error; /* If this is a stateful implementation, the stream we get back should be the same */ - assert(t->rpc || t->current_stream == *stream); + GIT_ASSERT(t->rpc || t->current_stream == *stream); /* Save off the current stream (i.e. socket) that we are working with */ t->current_stream = *stream; @@ -481,7 +481,9 @@ int git_transport_smart_certificate_check(git_transport *transport, git_cert *ce { transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); - assert(transport && cert && hostname); + GIT_ASSERT_ARG(transport); + GIT_ASSERT_ARG(cert); + GIT_ASSERT_ARG(hostname); if (!t->certificate_check_cb) return GIT_PASSTHROUGH; @@ -493,7 +495,8 @@ int git_transport_smart_credentials(git_credential **out, git_transport *transpo { transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); - assert(out && transport); + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(transport); if (!t->cred_acquire_cb) return GIT_PASSTHROUGH; diff --git a/src/transports/ssh.c b/src/transports/ssh.c index f4ed05bb160..b7efd5ceb16 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -238,7 +238,7 @@ static int ssh_stream_alloc( { ssh_stream *s; - assert(stream); + GIT_ASSERT_ARG(stream); s = git__calloc(sizeof(ssh_stream), 1); GIT_ERROR_CHECK_ALLOC(s); @@ -404,8 +404,8 @@ static int _git_ssh_authenticate_session( case GIT_CREDENTIAL_SSH_MEMORY: { git_credential_ssh_key *c = (git_credential_ssh_key *)cred; - assert(c->username); - assert(c->privatekey); + GIT_ASSERT(c->username); + GIT_ASSERT(c->privatekey); rc = libssh2_userauth_publickey_frommemory( session, @@ -483,7 +483,7 @@ static int _git_ssh_session_create( LIBSSH2_SESSION* s; git_socket_stream *socket = GIT_CONTAINER_OF(io, git_socket_stream, parent); - assert(session); + GIT_ASSERT_ARG(session); s = libssh2_session_init(); if (!s) { @@ -772,7 +772,7 @@ static int _ssh_close(git_smart_subtransport *subtransport) { ssh_subtransport *t = GIT_CONTAINER_OF(subtransport, ssh_subtransport, parent); - assert(!t->current_stream); + GIT_ASSERT(!t->current_stream); GIT_UNUSED(t); @@ -783,8 +783,6 @@ static void _ssh_free(git_smart_subtransport *subtransport) { ssh_subtransport *t = GIT_CONTAINER_OF(subtransport, ssh_subtransport, parent); - assert(!t->current_stream); - git__free(t->cmd_uploadpack); git__free(t->cmd_receivepack); git__free(t); @@ -849,7 +847,7 @@ int git_smart_subtransport_ssh( #ifdef GIT_SSH ssh_subtransport *t; - assert(out); + GIT_ASSERT_ARG(out); GIT_UNUSED(param); @@ -867,7 +865,7 @@ int git_smart_subtransport_ssh( GIT_UNUSED(owner); GIT_UNUSED(param); - assert(out); + GIT_ASSERT_ARG(out); *out = NULL; git_error_set(GIT_ERROR_INVALID, "cannot create SSH transport. Library was built without SSH support"); @@ -911,7 +909,7 @@ int git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *p GIT_UNUSED(owner); GIT_UNUSED(payload); - assert(out); + GIT_ASSERT_ARG(out); *out = NULL; git_error_set(GIT_ERROR_INVALID, "cannot create SSH transport. Library was built without SSH support"); diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index 2a1f6f26f71..2b77ec9a70e 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -1003,7 +1003,7 @@ static int winhttp_stream_read( } if (s->chunked) { - assert(s->verb == post_verb); + GIT_ASSERT(s->verb == post_verb); /* Flush, if necessary */ if (s->chunk_buffer_len > 0 && @@ -1054,7 +1054,7 @@ static int winhttp_stream_read( } len -= bytes_read; - assert(bytes_read == bytes_written); + GIT_ASSERT(bytes_read == bytes_written); } git__free(buffer); @@ -1166,7 +1166,7 @@ static int winhttp_stream_read( if (error < 0) { return error; } else if (!error) { - assert(t->server.cred); + GIT_ASSERT(t->server.cred); winhttp_stream_close(s); goto replay; } @@ -1180,7 +1180,7 @@ static int winhttp_stream_read( if (error < 0) { return error; } else if (!error) { - assert(t->proxy.cred); + GIT_ASSERT(t->proxy.cred); winhttp_stream_close(s); goto replay; } @@ -1266,7 +1266,7 @@ static int winhttp_stream_write_single( return -1; } - assert((DWORD)len == bytes_written); + GIT_ASSERT((DWORD)len == bytes_written); return 0; } @@ -1365,7 +1365,7 @@ static int winhttp_stream_write_buffered( return -1; } - assert((DWORD)len == bytes_written); + GIT_ASSERT((DWORD)len == bytes_written); s->post_body_len += bytes_written; @@ -1572,7 +1572,7 @@ static int winhttp_action( break; default: - assert(0); + GIT_ASSERT(0); } if (!ret) From c6ebdb296bc44b50fa76e492f57f086bf6c9ec08 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 22 Nov 2020 09:43:06 +0000 Subject: [PATCH 0166/1616] win32: use GIT_ASSERT --- src/unix/map.c | 2 +- src/win32/findfile.c | 6 ++++-- src/win32/map.c | 2 +- src/win32/path_w32.c | 14 ++++++-------- src/win32/precompiled.h | 1 - src/win32/thread.c | 13 +++++-------- src/win32/w32_buffer.c | 6 +++--- 7 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/unix/map.c b/src/unix/map.c index 7f9076e19cf..62c52578b23 100644 --- a/src/unix/map.c +++ b/src/unix/map.c @@ -66,7 +66,7 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset int p_munmap(git_map *map) { - assert(map != NULL); + GIT_ASSERT_ARG(map); munmap(map->data, map->len); return 0; diff --git a/src/win32/findfile.c b/src/win32/findfile.c index 7f077e154ff..f541a03d4bc 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -53,7 +53,9 @@ static wchar_t* win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen) { wchar_t term, *base = path; - assert(path && buf && buflen); + GIT_ASSERT_ARG_WITH_RETVAL(path, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(buf, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(buflen, NULL); term = (*path == L'"') ? *path++ : L';'; @@ -109,7 +111,7 @@ static int win32_find_git_in_registry( HKEY hKey; int error = GIT_ENOTFOUND; - assert(buf); + GIT_ASSERT_ARG(buf); if (!RegOpenKeyExW(hive, key, 0, KEY_READ, &hKey)) { DWORD dwType, cbData; diff --git a/src/win32/map.c b/src/win32/map.c index e2ce737debd..2aabc9b153d 100644 --- a/src/win32/map.c +++ b/src/win32/map.c @@ -117,7 +117,7 @@ int p_munmap(git_map *map) { int error = 0; - assert(map != NULL); + GIT_ASSERT_ARG(map); if (map->data) { if (!UnmapViewOfFile(map->data)) { diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c index 9faddcf3bfe..23efd926903 100644 --- a/src/win32/path_w32.c +++ b/src/win32/path_w32.c @@ -492,14 +492,12 @@ size_t git_win32_path_remove_namespace(wchar_t *str, size_t len) prefix_len = CONST_STRLEN(unc_prefix); } - if (remainder) { - /* - * Sanity check that the new string isn't longer than the old one. - * (This could only happen due to programmer error introducing a - * prefix longer than the namespace it replaces.) - */ - assert(len >= remainder_len + prefix_len); - + /* + * Sanity check that the new string isn't longer than the old one. + * (This could only happen due to programmer error introducing a + * prefix longer than the namespace it replaces.) + */ + if (remainder && len >= remainder_len + prefix_len) { if (prefix) memmove(str, prefix, prefix_len * sizeof(wchar_t)); diff --git a/src/win32/precompiled.h b/src/win32/precompiled.h index 314383d31b3..806b1698a09 100644 --- a/src/win32/precompiled.h +++ b/src/win32/precompiled.h @@ -1,6 +1,5 @@ #include "common.h" -#include #include #include #include diff --git a/src/win32/thread.c b/src/win32/thread.c index 51b005bc887..f5cacd320d8 100644 --- a/src/win32/thread.c +++ b/src/win32/thread.c @@ -94,10 +94,7 @@ int git_thread_join( /* Check for the thread having exited uncleanly. If exit was unclean, * then we don't have a return value to give back to the caller. */ - if (exit != CLEAN_THREAD_EXIT) { - assert(false); - thread->result = NULL; - } + GIT_ASSERT(exit == CLEAN_THREAD_EXIT); if (value_ptr) *value_ptr = thread->result; @@ -149,7 +146,7 @@ int git_cond_init(git_cond *cond) { /* This is an auto-reset event. */ *cond = CreateEventW(NULL, FALSE, FALSE, NULL); - assert(*cond); + GIT_ASSERT(*cond); /* If we can't create the event, claim that the reason was out-of-memory. * The actual reason can be fetched with GetLastError(). */ @@ -164,7 +161,7 @@ int git_cond_free(git_cond *cond) return EINVAL; closed = CloseHandle(*cond); - assert(closed); + GIT_ASSERT(closed); GIT_UNUSED(closed); *cond = NULL; @@ -186,7 +183,7 @@ int git_cond_wait(git_cond *cond, git_mutex *mutex) return error; wait_result = WaitForSingleObject(*cond, INFINITE); - assert(WAIT_OBJECT_0 == wait_result); + GIT_ASSERT(WAIT_OBJECT_0 == wait_result); GIT_UNUSED(wait_result); return git_mutex_lock(mutex); @@ -200,7 +197,7 @@ int git_cond_signal(git_cond *cond) return EINVAL; signaled = SetEvent(*cond); - assert(signaled); + GIT_ASSERT(signaled); GIT_UNUSED(signaled); return 0; diff --git a/src/win32/w32_buffer.c b/src/win32/w32_buffer.c index b78a7e6f39c..f270a1e6ac9 100644 --- a/src/win32/w32_buffer.c +++ b/src/win32/w32_buffer.c @@ -32,13 +32,13 @@ int git_buf_put_w(git_buf *buf, const wchar_t *string_w, size_t len_w) return -1; } - assert(string_w); + GIT_ASSERT(string_w); /* Measure the string necessary for conversion */ if ((utf8_len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, string_w, (int)len_w, NULL, 0, NULL, NULL)) == 0) return 0; - assert(utf8_len > 0); + GIT_ASSERT(utf8_len > 0); GIT_ERROR_CHECK_ALLOC_ADD(&new_size, buf->size, (size_t)utf8_len); GIT_ERROR_CHECK_ALLOC_ADD(&new_size, new_size, 1); @@ -50,7 +50,7 @@ int git_buf_put_w(git_buf *buf, const wchar_t *string_w, size_t len_w) CP_UTF8, WC_ERR_INVALID_CHARS, string_w, (int)len_w, &buf->ptr[buf->size], utf8_len, NULL, NULL)) == 0) return handle_wc_error(); - assert(utf8_write_len == utf8_len); + GIT_ASSERT(utf8_write_len == utf8_len); buf->size += utf8_write_len; buf->ptr[buf->size] = '\0'; From f847fa7b34abdc7850b8739747e1d25eefafa5f2 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sun, 16 Feb 2020 02:00:56 +0000 Subject: [PATCH 0167/1616] midx: Support multi-pack-index files in odb_pack.c This change adds support for reading multi-pack-index files from the packfile odb backend. This also makes git_pack_file objects open their backing failes lazily in more scenarios, since the multi-pack-index can avoid having to open them in some cases (yay!). This change also refreshes the documentation found in src/odb_pack.c to match the updated code. Part of: #5399 --- src/midx.c | 73 ++++++++- src/midx.h | 11 ++ src/odb_pack.c | 405 ++++++++++++++++++++++++++++++++++------------ src/pack.c | 6 + tests/pack/midx.c | 16 ++ 5 files changed, 399 insertions(+), 112 deletions(-) diff --git a/src/midx.c b/src/midx.c index 00d73153da2..ee93b03c117 100644 --- a/src/midx.c +++ b/src/midx.c @@ -13,8 +13,6 @@ #include "odb.h" #include "pack.h" -#define GIT_MIDX_FILE_MODE 0444 - #define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */ #define MIDX_VERSION 1 #define MIDX_OBJECT_ID_VERSION 1 @@ -116,7 +114,7 @@ static int midx_parse_oid_lookup( return midx_error("missing OID Lookup chunk"); if (chunk_oid_lookup->length == 0) return midx_error("empty OID Lookup chunk"); - if (chunk_oid_lookup->length != idx->num_objects * 20) + if (chunk_oid_lookup->length != idx->num_objects * GIT_OID_RAWSZ) return midx_error("OID Lookup chunk has wrong length"); idx->oid_lookup = oid = (git_oid *)(data + chunk_oid_lookup->offset); @@ -183,7 +181,7 @@ int git_midx_parse( GIT_ASSERT_ARG(idx); - if (size < sizeof(struct git_midx_header) + 20) + if (size < sizeof(struct git_midx_header) + GIT_OID_RAWSZ) return midx_error("multi-pack index is too short"); hdr = ((struct git_midx_header *)data); @@ -203,7 +201,7 @@ int git_midx_parse( last_chunk_offset = sizeof(struct git_midx_header) + (1 + hdr->chunks) * 12; - trailer_offset = size - 20; + trailer_offset = size - GIT_OID_RAWSZ; if (trailer_offset < last_chunk_offset) return midx_error("wrong index size"); git_oid_cpy(&idx->checksum, (git_oid *)(data + trailer_offset)); @@ -309,6 +307,10 @@ int git_midx_open( idx = git__calloc(1, sizeof(git_midx_file)); GIT_ERROR_CHECK_ALLOC(idx); + error = git_buf_sets(&idx->filename, path); + if (error < 0) + return error; + error = git_futils_mmap_ro(&idx->index_map, fd, 0, idx_size); p_close(fd); if (error < 0) { @@ -325,6 +327,46 @@ int git_midx_open( return 0; } +bool git_midx_needs_refresh( + const git_midx_file *idx, + const char *path) +{ + git_file fd = -1; + struct stat st; + ssize_t bytes_read; + git_oid idx_checksum = {{0}}; + + /* TODO: properly open the file without access time using O_NOATIME */ + fd = git_futils_open_ro(path); + if (fd < 0) + return true; + + if (p_fstat(fd, &st) < 0) { + p_close(fd); + return true; + } + + if (!S_ISREG(st.st_mode) || + !git__is_sizet(st.st_size) || + (size_t)st.st_size != idx->index_map.len) { + p_close(fd); + return true; + } + + if (p_lseek(fd, -GIT_OID_RAWSZ, SEEK_END) < 0) { + p_close(fd); + return true; + } + + bytes_read = p_read(fd, &idx_checksum, GIT_OID_RAWSZ); + p_close(fd); + + if (bytes_read != GIT_OID_RAWSZ) + return true; + + return git_oid_cmp(&idx_checksum, &idx->checksum) == 0; +} + int git_midx_entry_find( git_midx_entry *e, git_midx_file *idx, @@ -343,7 +385,7 @@ int git_midx_entry_find( hi = ntohl(idx->oid_fanout[(int)short_oid->id[0]]); lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(idx->oid_fanout[(int)short_oid->id[0] - 1])); - pos = git_pack__lookup_sha1(idx->oid_lookup, 20, lo, hi, short_oid->id); + pos = git_pack__lookup_sha1(idx->oid_lookup, GIT_OID_RAWSZ, lo, hi, short_oid->id); if (pos >= 0) { /* An object matching exactly the oid was found */ @@ -399,6 +441,24 @@ int git_midx_entry_find( return 0; } +int git_midx_foreach_entry( + git_midx_file *idx, + git_odb_foreach_cb cb, + void *data) +{ + size_t i; + int error; + + GIT_ASSERT_ARG(idx); + + for (i = 0; i < idx->num_objects; ++i) { + if ((error = cb(&idx->oid_lookup[i], data)) != 0) + return git_error_set_after_callback(error); + } + + return error; +} + int git_midx_close(git_midx_file *idx) { GIT_ASSERT_ARG(idx); @@ -416,6 +476,7 @@ void git_midx_free(git_midx_file *idx) if (!idx) return; + git_buf_dispose(&idx->filename); git_midx_close(idx); git__free(idx); } diff --git a/src/midx.h b/src/midx.h index 3b802952c72..543ff2178df 100644 --- a/src/midx.h +++ b/src/midx.h @@ -14,6 +14,7 @@ #include "map.h" #include "mwindow.h" +#include "odb.h" /* * A multi-pack-index file. @@ -49,6 +50,9 @@ typedef struct git_midx_file { /* The trailer of the file. Contains the SHA1-checksum of the whole file. */ git_oid checksum; + + /* something like ".git/objects/pack/multi-pack-index". */ + git_buf filename; } git_midx_file; /* @@ -66,11 +70,18 @@ typedef struct git_midx_entry { int git_midx_open( git_midx_file **idx_out, const char *path); +bool git_midx_needs_refresh( + const git_midx_file *idx, + const char *path); int git_midx_entry_find( git_midx_entry *e, git_midx_file *idx, const git_oid *short_oid, size_t len); +int git_midx_foreach_entry( + git_midx_file *idx, + git_odb_foreach_cb cb, + void *data); int git_midx_close(git_midx_file *idx); void git_midx_free(git_midx_file *idx); diff --git a/src/odb_pack.c b/src/odb_pack.c index e4ad0f4b7d7..3df8a426743 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -11,11 +11,12 @@ #include "git2/repository.h" #include "git2/indexer.h" #include "git2/sys/odb_backend.h" +#include "delta.h" #include "futils.h" #include "hash.h" -#include "odb.h" -#include "delta.h" +#include "midx.h" #include "mwindow.h" +#include "odb.h" #include "pack.h" #include "git2/odb_backend.h" @@ -25,6 +26,8 @@ struct pack_backend { git_odb_backend parent; + git_midx_file *midx; + git_vector midx_packs; git_vector packs; struct git_pack_file *last_found; char *pack_folder; @@ -47,36 +50,43 @@ struct pack_writepack { * Initialization of the Pack Backend * -------------------------------------------------- * - * # git_odb_backend_pack - * | Creates the pack backend structure, initializes the - * | callback pointers to our default read() and exist() methods, - * | and tries to preload all the known packfiles in the ODB. + * # git_odb_backend_pack + * | Creates the pack backend structure, initializes the + * | callback pointers to our default read() and exist() methods, + * | and tries to find the `pack` folder, if it exists. ODBs without a `pack` + * | folder are ignored altogether. If there is a `pack` folder, it tries to + * | preload all the known packfiles in the ODB. * | - * |-# packfile_load_all - * | Tries to find the `pack` folder, if it exists. ODBs without - * | a pack folder are ignored altogether. If there's a `pack` folder - * | we run a `dirent` callback through every file in the pack folder - * | to find our packfiles. The packfiles are then sorted according - * | to a sorting callback. - * | - * |-# packfile_load__cb - * | | This callback is called from `dirent` with every single file - * | | inside the pack folder. We find the packs by actually locating - * | | their index (ends in ".idx"). From that index, we verify that - * | | the corresponding packfile exists and is valid, and if so, we - * | | add it to the pack list. - * | | - * | |-# packfile_check - * | Make sure that there's a packfile to back this index, and store - * | some very basic information regarding the packfile itself, - * | such as the full path, the size, and the modification time. - * | We don't actually open the packfile to check for internal consistency. - * | - * |-# packfile_sort__cb - * Sort all the preloaded packs according to some specific criteria: - * we prioritize the "newer" packs because it's more likely they - * contain the objects we are looking for, and we prioritize local - * packs over remote ones. + * |-# pack_backend__refresh + * | The `multi-pack-index` is loaded if it exists and is valid. + * | Then we run a `dirent` callback through every file in the pack folder, + * | even those present in `multi-pack-index`. The unindexed packfiles are + * | then sorted according to a sorting callback. + * | + * |-# refresh_multi_pack_index + * | Detect the presence of the `multi-pack-index` file. If it needs to be + * | refreshed, frees the old copy and tries to load the new one, together + * | with all the packfiles it indexes. If the process fails, fall back to + * | the old behavior, as if the `multi-pack-index` file was not there. + * | + * |-# packfile_load__cb + * | | This callback is called from `dirent` with every single file + * | | inside the pack folder. We find the packs by actually locating + * | | their index (ends in ".idx"). From that index, we verify that + * | | the corresponding packfile exists and is valid, and if so, we + * | | add it to the pack list. + * | | + * | # git_mwindow_get_pack + * | Make sure that there's a packfile to back this index, and store + * | some very basic information regarding the packfile itself, + * | such as the full path, the size, and the modification time. + * | We don't actually open the packfile to check for internal consistency. + * | + * |-# packfile_sort__cb + * Sort all the preloaded packs according to some specific criteria: + * we prioritize the "newer" packs because it's more likely they + * contain the objects we are looking for, and we prioritize local + * packs over remote ones. * * * @@ -84,48 +94,66 @@ struct pack_writepack { * A standard packed `exist` query for an OID * -------------------------------------------------- * - * # pack_backend__exists - * | Check if the given SHA1 oid exists in any of the packs - * | that have been loaded for our ODB. + * # pack_backend__exists / pack_backend__exists_prefix + * | Check if the given SHA1 oid (or a SHA1 oid prefix) exists in any of the + * | packs that have been loaded for our ODB. * | - * |-# pack_entry_find - * | Iterate through all the packs that have been preloaded - * | (starting by the pack where the latest object was found) - * | to try to find the OID in one of them. - * | - * |-# pack_entry_find1 - * | Check the index of an individual pack to see if the SHA1 - * | OID can be found. If we can find the offset to that SHA1 - * | inside of the index, that means the object is contained - * | inside of the packfile and we can stop searching. - * | Before returning, we verify that the packfile behing the - * | index we are searching still exists on disk. - * | - * |-# pack_entry_find_offset - * | | Mmap the actual index file to disk if it hasn't been opened - * | | yet, and run a binary search through it to find the OID. - * | | See for specifics - * | | on the Packfile Index format and how do we find entries in it. - * | | - * | |-# pack_index_open - * | | Guess the name of the index based on the full path to the - * | | packfile, open it and verify its contents. Only if the index - * | | has not been opened already. - * | | - * | |-# pack_index_check - * | Mmap the index file and do a quick run through the header - * | to guess the index version (right now we support v1 and v2), - * | and to verify that the size of the index makes sense. - * | - * |-# packfile_open - * See `packfile_open` in Chapter 3 + * |-# pack_entry_find / pack_entry_find_prefix + * | If there is a multi-pack-index present, search the SHA1 oid in that + * | index first. If it is not found there, iterate through all the unindexed + * | packs that have been preloaded (starting by the pack where the latest + * | object was found) to try to find the OID in one of them. + * | + * |-# git_midx_entry_find + * | Search for the SHA1 oid in the multi-pack-index. See + * | + * | for specifics on the multi-pack-index format and how do we find + * | entries in it. + * | + * |-# git_pack_entry_find + * | Check the index of an individual unindexed pack to see if the SHA1 + * | OID can be found. If we can find the offset to that SHA1 inside of the + * | index, that means the object is contained inside of the packfile and + * | we can stop searching. Before returning, we verify that the + * | packfile behing the index we are searching still exists on disk. + * | + * |-# pack_entry_find_offset + * | Mmap the actual index file to disk if it hasn't been opened + * | yet, and run a binary search through it to find the OID. + * | See + * | for specifics on the Packfile Index format and how do we find + * | entries in it. + * | + * |-# pack_index_open + * | Guess the name of the index based on the full path to the + * | packfile, open it and verify its contents. Only if the index + * | has not been opened already. + * | + * |-# pack_index_check + * Mmap the index file and do a quick run through the header + * to guess the index version (right now we support v1 and v2), + * and to verify that the size of the index makes sense. * * * * Chapter 3: The neverending story... * A standard packed `lookup` query for an OID * -------------------------------------------------- - * TODO + * + * # pack_backend__read / pack_backend__read_prefix + * | Check if the given SHA1 oid (or a SHA1 oid prefix) exists in any of the + * | packs that have been loaded for our ODB. If it does, open the packfile and + * | read from it. + * | + * |-# git_packfile_unpack + * Armed with a packfile and the offset within it, we can finally unpack + * the object pointed at by the SHA1 oid. This involves mmapping part of + * the `.pack` file, and uncompressing the object within it (if it is + * stored in the undelfitied representation), or finding a base object and + * applying some deltas to its uncompressed representation (if it is stored + * in the deltified representation). See + * + * for specifics on the Packfile format and how do we read from it. * */ @@ -140,6 +168,8 @@ static int packfile_sort__cb(const void *a_, const void *b_); static int packfile_load__cb(void *_data, git_buf *path); +static int packfile_byname_search_cmp(const void *path, const void *pack_entry); + static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid); @@ -163,6 +193,14 @@ static int pack_entry_find_prefix( * ***********************************************************/ +static int packfile_byname_search_cmp(const void *path_, const void *p_) +{ + const git_buf *path = (const git_buf *)path_; + const struct git_pack_file *p = (const struct git_pack_file *)p_; + + return strncmp(p->pack_name, git_buf_cstr(path), git_buf_len(path)); +} + static int packfile_sort__cb(const void *a_, const void *b_) { const struct git_pack_file *a = a_; @@ -198,20 +236,20 @@ static int packfile_load__cb(void *data, git_buf *path) struct pack_backend *backend = data; struct git_pack_file *pack; const char *path_str = git_buf_cstr(path); - size_t i, cmp_len = git_buf_len(path); + git_buf index_prefix = GIT_BUF_INIT; + size_t cmp_len = git_buf_len(path); int error; if (cmp_len <= strlen(".idx") || git__suffixcmp(path_str, ".idx") != 0) return 0; /* not an index */ cmp_len -= strlen(".idx"); + git_buf_attach_notowned(&index_prefix, path_str, cmp_len); - for (i = 0; i < backend->packs.length; ++i) { - struct git_pack_file *p = git_vector_get(&backend->packs, i); - - if (strncmp(p->pack_name, path_str, cmp_len) == 0) - return 0; - } + if (git_vector_search2(NULL, &backend->midx_packs, packfile_byname_search_cmp, &index_prefix) == 0) + return 0; + if (git_vector_search2(NULL, &backend->packs, packfile_byname_search_cmp, &index_prefix) == 0) + return 0; error = git_mwindow_get_pack(&pack, path->ptr); @@ -228,22 +266,26 @@ static int packfile_load__cb(void *data, git_buf *path) } -static int pack_entry_find_inner( - struct git_pack_entry *e, - struct pack_backend *backend, - const git_oid *oid, - struct git_pack_file *last_found) +static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid) { + struct git_pack_file *last_found = backend->last_found, *p; + git_midx_entry midx_entry; size_t i; + if (backend->midx && + git_midx_entry_find(&midx_entry, backend->midx, oid, GIT_OID_HEXSZ) == 0 && + midx_entry.pack_index < git_vector_length(&backend->midx_packs)) { + e->offset = midx_entry.offset; + git_oid_cpy(&e->sha1, &midx_entry.sha1); + e->p = git_vector_get(&backend->midx_packs, midx_entry.pack_index); + return 0; + } + if (last_found && git_pack_entry_find(e, last_found, oid, GIT_OID_HEXSZ) == 0) return 0; - for (i = 0; i < backend->packs.length; ++i) { - struct git_pack_file *p; - - p = git_vector_get(&backend->packs, i); + git_vector_foreach(&backend->packs, i, p) { if (p == last_found) continue; @@ -253,20 +295,6 @@ static int pack_entry_find_inner( } } - return -1; -} - -static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid) -{ - struct git_pack_file *last_found = backend->last_found; - - if (backend->last_found && - git_pack_entry_find(e, backend->last_found, oid, GIT_OID_HEXSZ) == 0) - return 0; - - if (!pack_entry_find_inner(e, backend, oid, last_found)) - return 0; - return git_odb__error_notfound( "failed to find pack entry", oid, GIT_OID_HEXSZ); } @@ -281,22 +309,35 @@ static int pack_entry_find_prefix( size_t i; git_oid found_full_oid = {{0}}; bool found = false; - struct git_pack_file *last_found = backend->last_found; + struct git_pack_file *last_found = backend->last_found, *p; + git_midx_entry midx_entry; + + if (backend->midx) { + error = git_midx_entry_find(&midx_entry, backend->midx, short_oid, len); + if (error == GIT_EAMBIGUOUS) + return error; + if (!error && midx_entry.pack_index < git_vector_length(&backend->midx_packs)) { + e->offset = midx_entry.offset; + git_oid_cpy(&e->sha1, &midx_entry.sha1); + e->p = git_vector_get(&backend->midx_packs, midx_entry.pack_index); + git_oid_cpy(&found_full_oid, &e->sha1); + found = true; + } + } if (last_found) { error = git_pack_entry_find(e, last_found, short_oid, len); if (error == GIT_EAMBIGUOUS) return error; if (!error) { + if (found && git_oid_cmp(&e->sha1, &found_full_oid)) + return git_odb__error_ambiguous("found multiple pack entries"); git_oid_cpy(&found_full_oid, &e->sha1); found = true; } } - for (i = 0; i < backend->packs.length; ++i) { - struct git_pack_file *p; - - p = git_vector_get(&backend->packs, i); + git_vector_foreach(&backend->packs, i, p) { if (p == last_found) continue; @@ -319,6 +360,141 @@ static int pack_entry_find_prefix( return 0; } +/*********************************************************** + * + * MULTI-PACK-INDEX SUPPORT + * + * Functions needed to support the multi-pack-index. + * + ***********************************************************/ + +/* + * Remove the multi-pack-index, and move all midx_packs to packs. + */ +static int remove_multi_pack_index(struct pack_backend *backend) +{ + size_t i, j = git_vector_length(&backend->packs); + struct pack_backend *p; + int error = git_vector_size_hint( + &backend->packs, + j + git_vector_length(&backend->midx_packs)); + if (error < 0) + return error; + + git_vector_foreach(&backend->midx_packs, i, p) + git_vector_set(NULL, &backend->packs, j++, p); + git_vector_clear(&backend->midx_packs); + + git_midx_free(backend->midx); + backend->midx = NULL; + + return 0; +} + +/* + * Loads a single .pack file referred to by the multi-pack-index. These must + * match the order in which they are declared in the multi-pack-index file, + * since these files are referred to by their index. + */ +static int process_multi_pack_index_pack( + struct pack_backend *backend, + size_t i, + const char *packfile_name) +{ + int error; + size_t cmp_len = strlen(packfile_name); + struct git_pack_file *pack; + size_t found_position; + git_buf pack_path = GIT_BUF_INIT, index_prefix = GIT_BUF_INIT; + + error = git_buf_joinpath(&pack_path, backend->pack_folder, packfile_name); + if (error < 0) + return error; + + /* This is ensured by midx__parse_packfile_name() */ + if (cmp_len <= strlen(".idx") || git__suffixcmp(git_buf_cstr(&pack_path), ".idx") != 0) + return git_odb__error_notfound("midx file contained a non-index", NULL, 0); + + cmp_len -= strlen(".idx"); + git_buf_attach_notowned(&index_prefix, git_buf_cstr(&pack_path), cmp_len); + + if (git_vector_search2(&found_position, &backend->packs, packfile_byname_search_cmp, &index_prefix) == 0) { + /* Pack was found in the packs list. Moving it to the midx_packs list. */ + git_buf_dispose(&pack_path); + git_vector_set(NULL, &backend->midx_packs, i, git_vector_get(&backend->packs, found_position)); + git_vector_remove(&backend->packs, found_position); + return 0; + } + + /* Pack was not found. Allocate a new one. */ + error = git_mwindow_get_pack(&pack, git_buf_cstr(&pack_path)); + git_buf_dispose(&pack_path); + if (error < 0) + return error; + + git_vector_set(NULL, &backend->midx_packs, i, pack); + return 0; +} + +/* + * Reads the multi-pack-index. If this fails for whatever reason, the + * multi-pack-index object is freed, and all the packfiles that are related to + * it are moved to the unindexed packfiles vector. + */ +static int refresh_multi_pack_index(struct pack_backend *backend) +{ + int error; + git_buf midx_path = GIT_BUF_INIT; + const char *packfile_name; + size_t i; + + error = git_buf_joinpath(&midx_path, backend->pack_folder, "multi-pack-index"); + if (error < 0) + return error; + + /* + * Check whether the multi-pack-index has changed. If it has, close any + * old multi-pack-index and move all the packfiles to the unindexed + * packs. This is done to prevent losing any open packfiles in case + * refreshing the new multi-pack-index fails, or the file is deleted. + */ + if (backend->midx) { + if (!git_midx_needs_refresh(backend->midx, git_buf_cstr(&midx_path))) { + git_buf_dispose(&midx_path); + return 0; + } + error = remove_multi_pack_index(backend); + if (error < 0) { + git_buf_dispose(&midx_path); + return error; + } + } + + error = git_midx_open(&backend->midx, git_buf_cstr(&midx_path)); + git_buf_dispose(&midx_path); + if (error < 0) + return error; + + git_vector_resize_to(&backend->midx_packs, git_vector_length(&backend->midx->packfile_names)); + + git_vector_foreach(&backend->midx->packfile_names, i, packfile_name) { + error = process_multi_pack_index_pack(backend, i, packfile_name); + if (error < 0) { + /* + * Something failed during reading multi-pack-index. + * Restore the state of backend as if the + * multi-pack-index was never there, and move all + * packfiles that have been processed so far to the + * unindexed packs. + */ + git_vector_resize_to(&backend->midx_packs, i); + remove_multi_pack_index(backend); + return error; + } + } + + return 0; +} /*********************************************************** * @@ -340,9 +516,16 @@ static int pack_backend__refresh(git_odb_backend *backend_) if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode)) return git_odb__error_notfound("failed to refresh packfiles", NULL, 0); - git_buf_sets(&path, backend->pack_folder); + if (refresh_multi_pack_index(backend) < 0) { + /* + * It is okay if this fails. We will just not use the + * multi-pack-index in this case. + */ + git_error_clear(); + } /* reload all packs */ + git_buf_sets(&path, backend->pack_folder); error = git_path_direach(&path, 0, packfile_load__cb, backend); git_buf_dispose(&path); @@ -478,9 +661,11 @@ static int pack_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb c backend = (struct pack_backend *)_backend; /* Make sure we know about the packfiles */ - if ((error = pack_backend__refresh(_backend)) < 0) + if ((error = pack_backend__refresh(_backend)) != 0) return error; + if (backend->midx && (error = git_midx_foreach_entry(backend->midx, cb, data)) != 0) + return error; git_vector_foreach(&backend->packs, i, p) { if ((error = git_pack_foreach_entry(p, cb, data)) != 0) return error; @@ -562,6 +747,7 @@ static int pack_backend__writepack(struct git_odb_writepack **out, static void pack_backend__free(git_odb_backend *_backend) { struct pack_backend *backend; + struct git_pack_file *p; size_t i; if (!_backend) @@ -569,11 +755,13 @@ static void pack_backend__free(git_odb_backend *_backend) backend = (struct pack_backend *)_backend; - for (i = 0; i < backend->packs.length; ++i) { - struct git_pack_file *p = git_vector_get(&backend->packs, i); + git_vector_foreach(&backend->midx_packs, i, p) + git_mwindow_put_pack(p); + git_vector_foreach(&backend->packs, i, p) git_mwindow_put_pack(p); - } + git_midx_free(backend->midx); + git_vector_free(&backend->midx_packs); git_vector_free(&backend->packs); git__free(backend->pack_folder); git__free(backend); @@ -584,7 +772,12 @@ static int pack_backend__alloc(struct pack_backend **out, size_t initial_size) struct pack_backend *backend = git__calloc(1, sizeof(struct pack_backend)); GIT_ERROR_CHECK_ALLOC(backend); + if (git_vector_init(&backend->midx_packs, 0, NULL) < 0) { + git__free(backend); + return -1; + } if (git_vector_init(&backend->packs, initial_size, packfile_sort__cb) < 0) { + git_vector_free(&backend->midx_packs); git__free(backend); return -1; } diff --git a/src/pack.c b/src/pack.c index 982ad1770a5..f81bc91f2cd 100644 --- a/src/pack.c +++ b/src/pack.c @@ -481,6 +481,9 @@ int git_packfile_resolve_header( off64_t base_offset; int error; + if (p->mwf.fd == -1 && (error = packfile_open(p)) < 0) + return error; + error = git_packfile_unpack_header(&size, &type, &p->mwf, &w_curs, &curpos); if (error < 0) return error; @@ -631,6 +634,9 @@ int git_packfile_unpack( size_t stack_size = 0, elem_pos, alloclen; git_object_t base_type; + if (p->mwf.fd == -1 && (error = packfile_open(p)) < 0) + return error; + /* * TODO: optionally check the CRC on the packfile */ diff --git a/tests/pack/midx.c b/tests/pack/midx.c index 1f47d9502b8..92d9ae24c39 100644 --- a/tests/pack/midx.c +++ b/tests/pack/midx.c @@ -27,3 +27,19 @@ void test_pack_midx__parse(void) git_repository_free(repo); git_buf_dispose(&midx_path); } + +void test_pack_midx__lookup(void) +{ + git_repository *repo; + git_commit *commit; + git_oid id; + + cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); + + cl_git_pass(git_oid_fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5")); + cl_git_pass(git_commit_lookup_prefix(&commit, repo, &id, GIT_OID_HEXSZ)); + cl_assert_equal_s(git_commit_message(commit), "packed commit one\n"); + + git_commit_free(commit); + git_repository_free(repo); +} From 29fe5f61ac2d5f7039ecf7dad834918fc683c98e Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sun, 22 Nov 2020 18:25:00 -0800 Subject: [PATCH 0168/1616] Also add the raw hostkey to `git_cert_hostkey` `git_cert_x509` has the raw encoded certificate. Let's do the same for the SSH certificate for symmetry. --- include/git2/cert.h | 38 +++++++++++++++++++++++++++++++++----- src/transports/ssh.c | 19 +++++++++++++++++++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/include/git2/cert.h b/include/git2/cert.h index e8cd2d18083..07ae8c9f938 100644 --- a/include/git2/cert.h +++ b/include/git2/cert.h @@ -80,8 +80,19 @@ typedef enum { GIT_CERT_SSH_SHA1 = (1 << 1), /** SHA-256 is available */ GIT_CERT_SSH_SHA256 = (1 << 2), + /** Raw hostkey is available */ + GIT_CERT_SSH_RAW = (1 << 3), } git_cert_ssh_t; +typedef enum { + /** The raw key is of an unknown type. */ + GIT_CERT_SSH_RAW_TYPE_UNKNOWN = 0, + /** The raw key is an RSA key. */ + GIT_CERT_SSH_RAW_TYPE_RSA = 1, + /** The raw key is a DSS key. */ + GIT_CERT_SSH_RAW_TYPE_DSS = 2, +} git_cert_ssh_raw_type_t; + /** * Hostkey information taken from libssh2 */ @@ -89,28 +100,45 @@ typedef struct { git_cert parent; /**< The parent cert */ /** - * A hostkey type from libssh2, either - * `GIT_CERT_SSH_MD5` or `GIT_CERT_SSH_SHA1` + * A bitmask containing the available fields. */ git_cert_ssh_t type; /** - * Hostkey hash. If type has `GIT_CERT_SSH_MD5` set, this will + * Hostkey hash. If `type` has `GIT_CERT_SSH_MD5` set, this will * have the MD5 hash of the hostkey. */ unsigned char hash_md5[16]; /** - * Hostkey hash. If type has `GIT_CERT_SSH_SHA1` set, this will + * Hostkey hash. If `type` has `GIT_CERT_SSH_SHA1` set, this will * have the SHA-1 hash of the hostkey. */ unsigned char hash_sha1[20]; /** - * Hostkey hash. If type has `GIT_CERT_SSH_SHA256` set, this will + * Hostkey hash. If `type` has `GIT_CERT_SSH_SHA256` set, this will * have the SHA-256 hash of the hostkey. */ unsigned char hash_sha256[32]; + + /** + * Raw hostkey type. If `type` has `GIT_CERT_SSH_RAW` set, this will + * have the type of the raw hostkey. + */ + git_cert_ssh_raw_type_t raw_type; + + /** + * Pointer to the raw hostkey. If `type` has `GIT_CERT_SSH_RAW` set, + * this will have the raw contents of the hostkey. + */ + const char *hostkey; + + /** + * Raw hostkey length. If `type` has `GIT_CERT_SSH_RAW` set, this will + * have the length of the raw contents of the hostkey. + */ + size_t hostkey_len; } git_cert_hostkey; /** diff --git a/src/transports/ssh.c b/src/transports/ssh.c index b7efd5ceb16..c33c08af1bb 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -563,9 +563,28 @@ static int _git_ssh_setup_conn( if (t->owner->certificate_check_cb != NULL) { git_cert_hostkey cert = {{ 0 }}, *cert_ptr; const char *key; + size_t cert_len; + int cert_type; cert.parent.cert_type = GIT_CERT_HOSTKEY_LIBSSH2; + key = libssh2_session_hostkey(session, &cert_len, &cert_type); + if (key != NULL) { + cert.type |= GIT_CERT_SSH_RAW; + cert.hostkey = key; + cert.hostkey_len = cert_len; + switch (cert_type) { + case LIBSSH2_HOSTKEY_TYPE_RSA: + cert.raw_type = GIT_CERT_SSH_RAW_TYPE_RSA; + break; + case LIBSSH2_HOSTKEY_TYPE_DSS: + cert.raw_type = GIT_CERT_SSH_RAW_TYPE_DSS; + break; + default: + cert.raw_type = GIT_CERT_SSH_RAW_TYPE_UNKNOWN; + } + } + #ifdef LIBSSH2_HOSTKEY_HASH_SHA256 key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA256); if (key != NULL) { From 5db304f07520181da04f31a94c9479ac345cc12a Mon Sep 17 00:00:00 2001 From: lhchavez Date: Fri, 27 Nov 2020 06:17:57 -0800 Subject: [PATCH 0169/1616] Fix the non-debug build in Groovy Gorilla (gcc 10.2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The release build has been failing with the following error: ```shell FAILED: src/CMakeFiles/git2internal.dir/hash.c.o /usr/bin/cc -DHAVE_QSORT_R_GNU -DSHA1DC_CUSTOM_INCLUDE_SHA1_C=\"common.h\" -DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"common.h\" -DSHA1DC_NO_STANDARD_INCLUDES=1 -D_FILE_OFFSET_BITS=64 -Isrc -I../src -I../include -I../deps/pcre -I../deps/http-parser -D_GNU_SOURCE -fsanitize=thread -fno-optimize-sibling-calls -fno-omit-frame-pointer -Werror -Wall -Wextra -fvisibility= hidden -fPIC -Wno-documentation-deprecated-sync -Wno-missing-field-initializers -Wstrict-aliasing -Wstrict-prototypes -Wdeclaration-after-statement -Wshift-count-overflow -Wunused-const-variable -Wunused-function -Wint-conversion -Wformat -Wformat-security -Wmissing-declarations -g -D_DEBUG -O0 -std=gnu90 -MD -MT src/CMakeFiles/git2internal.dir/hash.c.o -MF s rc/CMakeFiles/git2internal.dir/hash.c.o.d -o src/CMakeFiles/git2internal.dir/hash.c.o -c ../src/hash.c ../src/hash.c: In function ‘git_hash_init’: ../src/hash.c:47:1: error: control reaches end of non-void function [-Werror=return-type] 47 | } | ^ ../src/hash.c: In function ‘git_hash_update’: ../src/hash.c:58:1: error: control reaches end of non-void function [-Werror=return-type] 58 | } | ^ ../src/hash.c: In function ‘git_hash_final’: ../src/hash.c:68:1: error: control reaches end of non-void function [-Werror=return-type] 68 | } | ^ ../src/hash.c: At top level: cc1: note: unrecognized command-line option ‘-Wno-documentation-deprecated-sync’ may have been intended to silence earlier diagnostics cc1: all warnings being treated as errors [11/533] Building C object src/CMakeFiles/git2internal.dir/odb_pack.c.o ninja: build stopped: subcommand failed. ``` The compiler _should_ be able to figure out that there is no way to reach the end of the non-void function since `GIT_ASSERT(0)` expands to either `assert()` or an unconditional `return -1;` (after doing constant folding and stuff, depending on the debug level). But it's not doing so at the moment, so let's help it. --- src/hash.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/hash.c b/src/hash.c index 963c281377c..d334236609a 100644 --- a/src/hash.c +++ b/src/hash.c @@ -41,8 +41,10 @@ int git_hash_init(git_hash_ctx *ctx) case GIT_HASH_ALGO_SHA1: return git_hash_sha1_init(&ctx->sha1); default: - GIT_ASSERT(0); + /* unreachable */ ; } + GIT_ASSERT(0); + return -1; } int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) @@ -51,8 +53,10 @@ int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) case GIT_HASH_ALGO_SHA1: return git_hash_sha1_update(&ctx->sha1, data, len); default: - GIT_ASSERT(0); + /* unreachable */ ; } + GIT_ASSERT(0); + return -1; } int git_hash_final(git_oid *out, git_hash_ctx *ctx) @@ -61,8 +65,10 @@ int git_hash_final(git_oid *out, git_hash_ctx *ctx) case GIT_HASH_ALGO_SHA1: return git_hash_sha1_final(out, &ctx->sha1); default: - GIT_ASSERT(0); + /* unreachable */ ; } + GIT_ASSERT(0); + return -1; } int git_hash_buf(git_oid *out, const void *data, size_t len) From 4ae41f9c639d246d34dac89c3f1d9451c9cfa8d3 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sun, 2 Aug 2020 16:26:25 -0700 Subject: [PATCH 0170/1616] Make the odb race-free This change adds all the necessary locking to the odb to avoid races in the backends. Part of: #5592 --- script/thread-sanitizer.supp | 7 +- src/config_cache.c | 5 +- src/odb.c | 170 +++++++++++++++++++++++++++++++---- src/odb.h | 1 + src/pack.c | 114 ++++++++++++++--------- src/repository.c | 5 +- 6 files changed, 235 insertions(+), 67 deletions(-) diff --git a/script/thread-sanitizer.supp b/script/thread-sanitizer.supp index 757a0e79cd7..359a9b35e59 100644 --- a/script/thread-sanitizer.supp +++ b/script/thread-sanitizer.supp @@ -8,11 +8,6 @@ deadlock:attr_cache_lock # data races. called_from_lib:libc.so.6 -# TODO(#5595): Remove these once the fixes land. -race:src/odb.c -race:git_repository_odb__weakptr -race:cache_store - -# TODO(#5595): Investigate and fix this. It can be triggered by the `thread` +# TODO(#5592): Investigate and fix this. It can be triggered by the `thread` # test suite. race:git_filter_list__load_ext diff --git a/src/config_cache.c b/src/config_cache.c index e4e071b5405..1a28ba96c96 100644 --- a/src/config_cache.c +++ b/src/config_cache.c @@ -111,17 +111,18 @@ int git_config__configmap_lookup(int *out, git_config *config, git_configmap_ite int git_repository__configmap_lookup(int *out, git_repository *repo, git_configmap_item item) { - *out = repo->configmap_cache[(int)item]; + *out = (int)(intptr_t)git__load(repo->configmap_cache[(int)item]); if (*out == GIT_CONFIGMAP_NOT_CACHED) { int error; + int oldval = GIT_CONFIGMAP_NOT_CACHED; git_config *config; if ((error = git_repository_config__weakptr(&config, repo)) < 0 || (error = git_config__configmap_lookup(out, config, item)) < 0) return error; - repo->configmap_cache[(int)item] = *out; + git__compare_and_swap(&repo->configmap_cache[(int)item], &oldval, out); } return 0; diff --git a/src/odb.c b/src/odb.c index 1e608f5d83a..b2988c42903 100644 --- a/src/odb.c +++ b/src/odb.c @@ -450,12 +450,18 @@ int git_odb_new(git_odb **out) git_odb *db = git__calloc(1, sizeof(*db)); GIT_ERROR_CHECK_ALLOC(db); + if (git_mutex_init(&db->lock) < 0) { + git__free(db); + return -1; + } if (git_cache_init(&db->own_cache) < 0) { + git_mutex_free(&db->lock); git__free(db); return -1; } if (git_vector_init(&db->backends, 4, backend_sort_cmp) < 0) { git_cache_dispose(&db->own_cache); + git_mutex_free(&db->lock); git__free(db); return -1; } @@ -487,13 +493,18 @@ static int add_backend_internal( internal->is_alternate = is_alternate; internal->disk_inode = disk_inode; + if (git_mutex_lock(&odb->lock) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return -1; + } if (git_vector_insert(&odb->backends, internal) < 0) { + git_mutex_unlock(&odb->lock); git__free(internal); return -1; } - git_vector_sort(&odb->backends); internal->backend->odb = odb; + git_mutex_unlock(&odb->lock); return 0; } @@ -509,8 +520,19 @@ int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority) size_t git_odb_num_backends(git_odb *odb) { + size_t length; + bool locked = true; + GIT_ASSERT_ARG(odb); - return odb->backends.length; + + if (git_mutex_lock(&odb->lock) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + locked = false; + } + length = odb->backends.length; + if (locked) + git_mutex_unlock(&odb->lock); + return length; } static int git_odb__error_unsupported_in_backend(const char *action) @@ -524,19 +546,28 @@ static int git_odb__error_unsupported_in_backend(const char *action) int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos) { backend_internal *internal; + int error; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(odb); + + if ((error = git_mutex_lock(&odb->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } internal = git_vector_get(&odb->backends, pos); - if (internal && internal->backend) { - *out = internal->backend; - return 0; + if (!internal || !internal->backend) { + git_mutex_unlock(&odb->lock); + + git_error_set(GIT_ERROR_ODB, "no ODB backend loaded at index %" PRIuZ, pos); + return GIT_ENOTFOUND; } + *out = internal->backend; + git_mutex_unlock(&odb->lock); - git_error_set(GIT_ERROR_ODB, "no ODB backend loaded at index %" PRIuZ, pos); - return GIT_ENOTFOUND; + return 0; } int git_odb__add_default_backends( @@ -567,11 +598,18 @@ int git_odb__add_default_backends( inode = st.st_ino; + if (git_mutex_lock(&db->lock) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return -1; + } for (i = 0; i < db->backends.length; ++i) { backend_internal *backend = git_vector_get(&db->backends, i); - if (backend->disk_inode == inode) + if (backend->disk_inode == inode) { + git_mutex_unlock(&db->lock); return 0; + } } + git_mutex_unlock(&db->lock); #endif /* add the loose object backend */ @@ -687,7 +725,12 @@ int git_odb__set_caps(git_odb *odb, int caps) static void odb_free(git_odb *db) { size_t i; + bool locked = true; + if (git_mutex_lock(&db->lock) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + locked = false; + } for (i = 0; i < db->backends.length; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *backend = internal->backend; @@ -696,9 +739,12 @@ static void odb_free(git_odb *db) git__free(internal); } + if (locked) + git_mutex_unlock(&db->lock); git_vector_free(&db->backends); git_cache_dispose(&db->own_cache); + git_mutex_free(&db->lock); git__memzero(db, sizeof(*db)); git__free(db); @@ -719,7 +765,12 @@ static int odb_exists_1( { size_t i; bool found = false; + int error; + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } for (i = 0; i < db->backends.length && !found; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; @@ -730,6 +781,7 @@ static int odb_exists_1( if (b->exists != NULL) found = (bool)b->exists(b, id); } + git_mutex_unlock(&db->lock); return (int)found; } @@ -741,7 +793,12 @@ static int odb_freshen_1( { size_t i; bool found = false; + int error; + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } for (i = 0; i < db->backends.length && !found; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; @@ -754,6 +811,7 @@ static int odb_freshen_1( else if (b->exists != NULL) found = b->exists(b, id); } + git_mutex_unlock(&db->lock); return (int)found; } @@ -805,6 +863,11 @@ static int odb_exists_prefix_1(git_oid *out, git_odb *db, int error = GIT_ENOTFOUND, num_found = 0; git_oid last_found = {{0}}, found; + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } + error = GIT_ENOTFOUND; for (i = 0; i < db->backends.length; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; @@ -818,18 +881,23 @@ static int odb_exists_prefix_1(git_oid *out, git_odb *db, error = b->exists_prefix(&found, b, key, len); if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH) continue; - if (error) + if (error) { + git_mutex_unlock(&db->lock); return error; + } /* make sure found item doesn't introduce ambiguity */ if (num_found) { - if (git_oid__cmp(&last_found, &found)) + if (git_oid__cmp(&last_found, &found)) { + git_mutex_unlock(&db->lock); return git_odb__error_ambiguous("multiple matches for prefix"); + } } else { git_oid_cpy(&last_found, &found); num_found++; } } + git_mutex_unlock(&db->lock); if (!num_found) return GIT_ENOTFOUND; @@ -971,6 +1039,10 @@ static int odb_read_header_1( return 0; } + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } for (i = 0; i < db->backends.length; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; @@ -992,9 +1064,11 @@ static int odb_read_header_1( case GIT_ENOTFOUND: break; default: + git_mutex_unlock(&db->lock); return error; } } + git_mutex_unlock(&db->lock); return passthrough ? GIT_PASSTHROUGH : GIT_ENOTFOUND; } @@ -1067,6 +1141,10 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id, return error; } + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } for (i = 0; i < db->backends.length && !found; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; @@ -1079,12 +1157,15 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id, if (error == GIT_PASSTHROUGH || error == GIT_ENOTFOUND) continue; - if (error < 0) + if (error < 0) { + git_mutex_unlock(&db->lock); return error; + } found = true; } } + git_mutex_unlock(&db->lock); if (!found) return GIT_ENOTFOUND; @@ -1177,6 +1258,10 @@ static int read_prefix_1(git_odb_object **out, git_odb *db, bool found = false; git_odb_object *object; + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } for (i = 0; i < db->backends.length; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; @@ -1193,8 +1278,10 @@ static int read_prefix_1(git_odb_object **out, git_odb *db, continue; } - if (error) + if (error) { + git_mutex_unlock(&db->lock); goto out; + } git__free(data); data = raw.data; @@ -1209,6 +1296,7 @@ static int read_prefix_1(git_odb_object **out, git_odb *db, error = git_odb__error_ambiguous(buf.ptr); git_buf_dispose(&buf); + git_mutex_unlock(&db->lock); goto out; } @@ -1216,6 +1304,7 @@ static int read_prefix_1(git_odb_object **out, git_odb *db, found = true; } } + git_mutex_unlock(&db->lock); if (!found) return GIT_ENOTFOUND; @@ -1283,16 +1372,32 @@ int git_odb_read_prefix( int git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload) { unsigned int i; + git_vector backends = GIT_VECTOR_INIT; backend_internal *internal; + int error = 0; - git_vector_foreach(&db->backends, i, internal) { + /* Make a copy of the backends vector to invoke the callback without holding the lock. */ + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + goto cleanup; + } + error = git_vector_dup(&backends, &db->backends, NULL); + git_mutex_unlock(&db->lock); + + if (error < 0) + goto cleanup; + + git_vector_foreach(&backends, i, internal) { git_odb_backend *b = internal->backend; - int error = b->foreach(b, cb, payload); + error = b->foreach(b, cb, payload); if (error != 0) - return error; + goto cleanup; } - return 0; +cleanup: + git_vector_free(&backends); + + return error; } int git_odb_write( @@ -1314,6 +1419,10 @@ int git_odb_write( if (git_odb__freshen(db, oid)) return 0; + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } for (i = 0, error = GIT_ERROR; i < db->backends.length && error < 0; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; @@ -1325,6 +1434,7 @@ int git_odb_write( if (b->write != NULL) error = b->write(b, oid, data, len, type); } + git_mutex_unlock(&db->lock); if (!error || error == GIT_PASSTHROUGH) return 0; @@ -1366,6 +1476,11 @@ int git_odb_open_wstream( GIT_ASSERT_ARG(stream); GIT_ASSERT_ARG(db); + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } + error = GIT_ERROR; for (i = 0; i < db->backends.length && error < 0; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; @@ -1382,6 +1497,7 @@ int git_odb_open_wstream( error = init_fake_wstream(stream, b, size, type); } } + git_mutex_unlock(&db->lock); if (error < 0) { if (error == GIT_PASSTHROUGH) @@ -1477,6 +1593,11 @@ int git_odb_open_rstream( GIT_ASSERT_ARG(stream); GIT_ASSERT_ARG(db); + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } + error = GIT_ERROR; for (i = 0; i < db->backends.length && error < 0; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; @@ -1486,6 +1607,7 @@ int git_odb_open_rstream( error = b->readstream(stream, len, type, b, oid); } } + git_mutex_unlock(&db->lock); if (error == GIT_PASSTHROUGH) error = 0; @@ -1503,6 +1625,11 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_ GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(db); + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } + error = GIT_ERROR; for (i = 0; i < db->backends.length && error < 0; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; @@ -1516,6 +1643,7 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_ error = b->writepack(out, b, db, progress_cb, progress_payload); } } + git_mutex_unlock(&db->lock); if (error == GIT_PASSTHROUGH) error = 0; @@ -1547,19 +1675,27 @@ void git_odb_backend_data_free(git_odb_backend *backend, void *data) int git_odb_refresh(struct git_odb *db) { size_t i; + int error; GIT_ASSERT_ARG(db); + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return error; + } for (i = 0; i < db->backends.length; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; if (b->refresh != NULL) { int error = b->refresh(b); - if (error < 0) + if (error < 0) { + git_mutex_unlock(&db->lock); return error; + } } } + git_mutex_unlock(&db->lock); return 0; } diff --git a/src/odb.h b/src/odb.h index 8dd4efd64f3..d71985668ff 100644 --- a/src/odb.h +++ b/src/odb.h @@ -40,6 +40,7 @@ struct git_odb_object { /* EXPORT */ struct git_odb { git_refcount rc; + git_mutex lock; /* protects backends */ git_vector backends; git_cache own_cache; unsigned int do_fsync :1; diff --git a/src/pack.c b/src/pack.c index f81bc91f2cd..5a96ac5b595 100644 --- a/src/pack.c +++ b/src/pack.c @@ -12,6 +12,7 @@ #include "mwindow.h" #include "odb.h" #include "oid.h" +#include "oidarray.h" /* Option to bypass checking existence of '.keep' files */ bool git_disable_pack_keep_file_checks = false; @@ -195,7 +196,8 @@ static void pack_index_free(struct git_pack_file *p) } } -static int pack_index_check(const char *path, struct git_pack_file *p) +/* Run with the packfile lock held */ +static int pack_index_check_locked(const char *path, struct git_pack_file *p) { struct git_pack_idx_header *hdr; uint32_t version, nr, i, *index; @@ -301,7 +303,8 @@ static int pack_index_check(const char *path, struct git_pack_file *p) return 0; } -static int pack_index_open(struct git_pack_file *p) +/* Run with the packfile lock held */ +static int pack_index_open_locked(struct git_pack_file *p) { int error = 0; size_t name_len; @@ -324,18 +327,11 @@ static int pack_index_open(struct git_pack_file *p) return -1; } - if ((error = git_mutex_lock(&p->lock)) < 0) { - git_buf_dispose(&idx_name); - return error; - } - if (p->index_version == -1) - error = pack_index_check(idx_name.ptr, p); + error = pack_index_check_locked(idx_name.ptr, p); git_buf_dispose(&idx_name); - git_mutex_unlock(&p->lock); - return error; } @@ -1015,13 +1011,14 @@ static int packfile_open(struct git_pack_file *p) git_oid sha1; unsigned char *idx_sha1; - if (p->index_version == -1 && pack_index_open(p) < 0) - return git_odb__error_notfound("failed to open packfile", NULL, 0); - - /* if mwf opened by another thread, return now */ if (git_mutex_lock(&p->lock) < 0) return packfile_error("failed to get lock for open"); + if (pack_index_open_locked(p) < 0) { + git_mutex_unlock(&p->lock); + return git_odb__error_notfound("failed to open packfile", NULL, 0); + } + if (p->mwf.fd >= 0) { git_mutex_unlock(&p->lock); return 0; @@ -1210,32 +1207,40 @@ int git_pack_foreach_entry( git_odb_foreach_cb cb, void *data) { - const unsigned char *index = p->index_map.data, *current; + const unsigned char *index, *current; uint32_t i; int error = 0; + git_array_oid_t oids = GIT_ARRAY_INIT; + git_oid *oid; - if (index == NULL) { - if ((error = pack_index_open(p)) < 0) - return error; + if (git_mutex_lock(&p->lock) < 0) + return packfile_error("failed to get lock for git_pack_foreach_entry"); - GIT_ASSERT(p->index_map.data); - index = p->index_map.data; + if ((error = pack_index_open_locked(p)) < 0) { + git_mutex_unlock(&p->lock); + return error; } - if (p->index_version > 1) { + GIT_ASSERT(p->index_map.data); + index = p->index_map.data; + + if (p->index_version > 1) index += 8; - } index += 4 * 256; if (p->oids == NULL) { git_vector offsets, oids; - if ((error = git_vector_init(&oids, p->num_objects, NULL))) + if ((error = git_vector_init(&oids, p->num_objects, NULL))) { + git_mutex_unlock(&p->lock); return error; + } - if ((error = git_vector_init(&offsets, p->num_objects, git__memcmp4))) + if ((error = git_vector_init(&offsets, p->num_objects, git__memcmp4))) { + git_mutex_unlock(&p->lock); return error; + } if (p->index_version > 1) { const unsigned char *off = index + 24 * p->num_objects; @@ -1256,10 +1261,33 @@ int git_pack_foreach_entry( p->oids = (git_oid **)git_vector_detach(NULL, NULL, &oids); } - for (i = 0; i < p->num_objects; i++) - if ((error = cb(p->oids[i], data)) != 0) - return git_error_set_after_callback(error); + /* We need to copy the OIDs to another array before we relinquish the lock to avoid races. */ + git_array_init_to_size(oids, p->num_objects); + if (!oids.ptr) { + git_mutex_unlock(&p->lock); + git_array_clear(oids); + GIT_ERROR_CHECK_ARRAY(oids); + } + for (i = 0; i < p->num_objects; i++) { + oid = git_array_alloc(oids); + if (!oid) { + git_mutex_unlock(&p->lock); + git_array_clear(oids); + GIT_ERROR_CHECK_ALLOC(oid); + } + git_oid_cpy(oid, p->oids[i]); + } + + git_mutex_unlock(&p->lock); + + git_array_foreach(oids, i, oid) { + if ((error = cb(oid, data)) != 0) { + git_error_set_after_callback(error); + break; + } + } + git_array_clear(oids); return error; } @@ -1297,18 +1325,17 @@ static int pack_entry_find_offset( int pos, found = 0; off64_t offset; const unsigned char *current = 0; + int error = 0; *offset_out = 0; - if (p->index_version == -1) { - int error; - - if ((error = pack_index_open(p)) < 0) - return error; + if (git_mutex_lock(&p->lock) < 0) + return packfile_error("failed to get lock for pack_entry_find_offset"); - GIT_ASSERT(p->index_map.data); - } + if ((error = pack_index_open_locked(p)) < 0) + goto cleanup; + GIT_ASSERT(p->index_map.data); index = p->index_map.data; level1_ofs = p->index_map.data; @@ -1360,14 +1387,19 @@ static int pack_entry_find_offset( } } - if (!found) - return git_odb__error_notfound("failed to find offset for pack entry", short_oid, len); - if (found > 1) - return git_odb__error_ambiguous("found multiple offsets for pack entry"); + if (!found) { + error = git_odb__error_notfound("failed to find offset for pack entry", short_oid, len); + goto cleanup; + } + if (found > 1) { + error = git_odb__error_ambiguous("found multiple offsets for pack entry"); + goto cleanup; + } if ((offset = nth_packed_object_offset(p, pos)) < 0) { git_error_set(GIT_ERROR_ODB, "packfile index is corrupt"); - return -1; + error = -1; + goto cleanup; } *offset_out = offset; @@ -1382,7 +1414,9 @@ static int pack_entry_find_offset( } #endif - return 0; +cleanup: + git_mutex_unlock(&p->lock); + return error; } int git_pack_entry_find( diff --git a/src/repository.c b/src/repository.c index 697d6dfe927..bef84caafad 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1107,7 +1107,8 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo) GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(out); - if (repo->_odb == NULL) { + *out = git__load(repo->_odb); + if (*out == NULL) { git_buf odb_path = GIT_BUF_INIT; git_odb *odb; @@ -1131,9 +1132,9 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo) } git_buf_dispose(&odb_path); + *out = git__load(repo->_odb); } - *out = repo->_odb; return error; } From 322c15ee858622f2e3def514d3e7e1b47023950e Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sat, 1 Aug 2020 18:24:41 -0700 Subject: [PATCH 0171/1616] Make the pack and mwindow implementations data-race-free This change fixes a packfile heap corruption that can happen when interacting with multiple packfiles concurrently across multiple threads. This is exacerbated by setting a lower mwindow open file limit. This change: * Renames most of the internal methods in pack.c to clearly indicate that they expect to be called with a certain lock held, making reasoning about the state of locks a bit easier. * Splits the `git_pack_file` lock in two: the one in `git_pack_file` only protects the `index_map`. The protection to `git_mwindow_file` is now in that struct. * Explicitly checks for freshness of the `git_pack_file` in `git_packfile_unpack_header`: this allows the mwindow implementation to close files whenever there is enough cache pressure, and `git_packfile_unpack_header` will reopen the packfile if needed. * After a call to `p_munmap()`, the `data` and `len` fields are poisoned with `NULL` to make use-after-frees more evident and crash rather than being open to the possibility of heap corruption. * Adds a test case to prevent this from regressing in the future. Fixes: #5591 --- script/thread-sanitizer.supp | 13 ++ src/indexer.c | 14 +- src/mwindow.c | 120 ++++++++++------- src/mwindow.h | 4 +- src/pack.c | 241 ++++++++++++++++++++++++----------- src/pack.h | 7 +- src/unix/map.c | 2 + tests/pack/filelimit.c | 1 + tests/pack/threadsafety.c | 60 +++++++++ 9 files changed, 322 insertions(+), 140 deletions(-) create mode 100644 tests/pack/threadsafety.c diff --git a/script/thread-sanitizer.supp b/script/thread-sanitizer.supp index 359a9b35e59..97d23046ff2 100644 --- a/script/thread-sanitizer.supp +++ b/script/thread-sanitizer.supp @@ -3,6 +3,19 @@ # consistent lock hierarchy that is easy to understand. deadlock:attr_cache_lock +# git_mwindow_file_register has the possibility of evicting some files from the +# global cache. In order to avoid races and closing files that are currently +# being accessed, before evicting any file it will attempt to acquire that +# file's lock. Finally, git_mwindow_file_register is typically called with a +# file lock held, because the caller will use the fd in the mwf immediately +# after registering it. This causes ThreadSanitizer to observe different orders +# of acquisition of the mutex (which implies a possibility of a deadlock), +# _but_ since the files are added to the cache after other files have been +# evicted, there cannot be a case where mwf A is trying to be registered while +# evicting mwf B concurrently and viceversa: at most one of them can be present +# in the cache. +deadlock:git_mwindow_file_register + # When invoking the time/timezone functions from git_signature_now(), they # access libc methods that need to be instrumented to correctly analyze the # data races. diff --git a/src/indexer.c b/src/indexer.c index 7b3db310100..453bb3df7fa 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -24,8 +24,6 @@ #include "zstream.h" #include "object.h" -extern git_mutex git__mwindow_mutex; - size_t git_indexer__max_objects = UINT32_MAX; #define UINT31_MAX (0x7FFFFFFF) @@ -679,7 +677,7 @@ static int read_stream_object(git_indexer *idx, git_indexer_progress *stats) return GIT_EBUFS; if (!idx->have_stream) { - error = git_packfile_unpack_header(&entry_size, &type, &idx->pack->mwf, &w, &idx->off); + error = git_packfile_unpack_header(&entry_size, &type, idx->pack, &w, &idx->off); if (error == GIT_EBUFS) { idx->off = entry_start; return error; @@ -970,7 +968,7 @@ static int fix_thin_pack(git_indexer *idx, git_indexer_progress *stats) continue; curpos = delta->delta_off; - error = git_packfile_unpack_header(&size, &type, &idx->pack->mwf, &w, &curpos); + error = git_packfile_unpack_header(&size, &type, idx->pack, &w, &curpos); if (error < 0) return error; @@ -1333,13 +1331,7 @@ void git_indexer_free(git_indexer *idx) git_vector_free_deep(&idx->deltas); - if (!git_mutex_lock(&git__mwindow_mutex)) { - if (!idx->pack_committed) - git_packfile_close(idx->pack, true); - - git_packfile_free(idx->pack); - git_mutex_unlock(&git__mwindow_mutex); - } + git_packfile_free(idx->pack, !idx->pack_committed); iter = 0; while (git_oidmap_iterate((void **) &value, idx->expected_oids, &iter, &key) == 0) diff --git a/src/mwindow.c b/src/mwindow.c index 66fd2182394..4f105e65927 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -29,10 +29,10 @@ size_t git_mwindow__window_size = DEFAULT_WINDOW_SIZE; size_t git_mwindow__mapped_limit = DEFAULT_MAPPED_LIMIT; size_t git_mwindow__file_limit = DEFAULT_FILE_LIMIT; -/* Mutex to control access */ +/* Mutex to control access to `git_mwindow__mem_ctl` and `git__pack_cache`. */ git_mutex git__mwindow_mutex; -/* Whenever you want to read or modify this, grab git__mwindow_mutex */ +/* Whenever you want to read or modify this, grab `git__mwindow_mutex` */ git_mwindow_ctl git_mwindow__mem_ctl; /* Global list of mwindow files, to open packs once across repos */ @@ -95,10 +95,9 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path) error = git_strmap_set(git__pack_cache, pack->pack_name, pack); git_mutex_unlock(&git__mwindow_mutex); - if (error < 0) { - git_packfile_free(pack); - return -1; + git_packfile_free(pack, false); + return error; } *out = pack; @@ -108,6 +107,7 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path) int git_mwindow_put_pack(struct git_pack_file *pack) { int count, error; + struct git_pack_file *pack_to_delete = NULL; if ((error = git_mutex_lock(&git__mwindow_mutex)) < 0) return error; @@ -121,34 +121,19 @@ int git_mwindow_put_pack(struct git_pack_file *pack) count = git_atomic_dec(&pack->refcount); if (count == 0) { git_strmap_delete(git__pack_cache, pack->pack_name); - git_packfile_free(pack); + pack_to_delete = pack; } - git_mutex_unlock(&git__mwindow_mutex); - return 0; -} + git_packfile_free(pack_to_delete, false); -int git_mwindow_free_all(git_mwindow_file *mwf) -{ - int error; - - if (git_mutex_lock(&git__mwindow_mutex)) { - git_error_set(GIT_ERROR_THREAD, "unable to lock mwindow mutex"); - return -1; - } - - error = git_mwindow_free_all_locked(mwf); - - git_mutex_unlock(&git__mwindow_mutex); - - return error; + return 0; } /* * Free all the windows in a sequence, typically because we're done - * with the file + * with the file. Needs to hold the git__mwindow_mutex. */ -int git_mwindow_free_all_locked(git_mwindow_file *mwf) +static int git_mwindow_free_all_locked(git_mwindow_file *mwf) { git_mwindow_ctl *ctl = &git_mwindow__mem_ctl; size_t i; @@ -184,6 +169,22 @@ int git_mwindow_free_all_locked(git_mwindow_file *mwf) return 0; } +int git_mwindow_free_all(git_mwindow_file *mwf) +{ + int error; + + if (git_mutex_lock(&git__mwindow_mutex)) { + git_error_set(GIT_ERROR_THREAD, "unable to lock mwindow mutex"); + return -1; + } + + error = git_mwindow_free_all_locked(mwf); + + git_mutex_unlock(&git__mwindow_mutex); + + return error; +} + /* * Check if a window 'win' contains the address 'offset' */ @@ -256,9 +257,9 @@ static bool git_mwindow_scan_recently_used( /* * Close the least recently used window (that is currently not being used) out - * of all the files. Called under lock from new_window. + * of all the files. Called under lock from new_window_locked. */ -static int git_mwindow_close_lru_window(void) +static int git_mwindow_close_lru_window_locked(void) { git_mwindow_ctl *ctl = &git_mwindow__mem_ctl; git_mwindow_file *cur; @@ -292,13 +293,13 @@ static int git_mwindow_close_lru_window(void) } /* - * Close the file that does not have any open windows AND whose + * Finds the file that does not have any open windows AND whose * most-recently-used window is the least-recently used one across all * currently open files. * - * Called under lock from new_window. + * Called under lock from new_window_locked. */ -static int git_mwindow_close_lru_file(void) +static int git_mwindow_find_lru_file_locked(git_mwindow_file **out) { git_mwindow_ctl *ctl = &git_mwindow__mem_ctl; git_mwindow_file *lru_file = NULL, *current_file = NULL; @@ -320,15 +321,12 @@ static int git_mwindow_close_lru_file(void) return -1; } - git_mwindow_free_all_locked(lru_file); - p_close(lru_file->fd); - lru_file->fd = -1; - + *out = lru_file; return 0; } /* This gets called under lock from git_mwindow_open */ -static git_mwindow *new_window( +static git_mwindow *new_window_locked( git_file fd, off64_t size, off64_t offset) @@ -338,12 +336,11 @@ static git_mwindow *new_window( off64_t len; git_mwindow *w; - w = git__malloc(sizeof(*w)); + w = git__calloc(1, sizeof(*w)); if (w == NULL) return NULL; - memset(w, 0x0, sizeof(*w)); w->offset = (offset / walign) * walign; len = size - w->offset; @@ -353,7 +350,7 @@ static git_mwindow *new_window( ctl->mapped += (size_t)len; while (git_mwindow__mapped_limit < ctl->mapped && - git_mwindow_close_lru_window() == 0) /* nop */; + git_mwindow_close_lru_window_locked() == 0) /* nop */; /* * We treat `mapped_limit` as a soft limit. If we can't find a @@ -367,7 +364,7 @@ static git_mwindow *new_window( * we're below our soft limits, so free up what we can and try again. */ - while (git_mwindow_close_lru_window() == 0) + while (git_mwindow_close_lru_window_locked() == 0) /* nop */; if (git_futils_mmap_ro(&w->window_map, fd, w->offset, (size_t)len) < 0) { @@ -423,7 +420,7 @@ unsigned char *git_mwindow_open( * one. */ if (!w) { - w = new_window(mwf->fd, mwf->size, offset); + w = new_window_locked(mwf->fd, mwf->size, offset); if (w == NULL) { git_mutex_unlock(&git__mwindow_mutex); return NULL; @@ -451,8 +448,11 @@ unsigned char *git_mwindow_open( int git_mwindow_file_register(git_mwindow_file *mwf) { + git_vector closed_files = GIT_VECTOR_INIT; git_mwindow_ctl *ctl = &git_mwindow__mem_ctl; - int ret; + int error; + size_t i; + git_mwindow_file *closed_file = NULL; if (git_mutex_lock(&git__mwindow_mutex)) { git_error_set(GIT_ERROR_THREAD, "unable to lock mwindow mutex"); @@ -460,20 +460,48 @@ int git_mwindow_file_register(git_mwindow_file *mwf) } if (ctl->windowfiles.length == 0 && - git_vector_init(&ctl->windowfiles, 8, NULL) < 0) { + (error = git_vector_init(&ctl->windowfiles, 8, NULL)) < 0) { git_mutex_unlock(&git__mwindow_mutex); - return -1; + goto cleanup; } if (git_mwindow__file_limit) { + git_mwindow_file *lru_file; while (git_mwindow__file_limit <= ctl->windowfiles.length && - git_mwindow_close_lru_file() == 0) /* nop */; + git_mwindow_find_lru_file_locked(&lru_file) == 0) { + if ((error = git_vector_insert(&closed_files, lru_file)) < 0) { + /* + * Exceeding the file limit seems preferrable to being open to + * data races that can end up corrupting the heap. + */ + break; + } + git_mwindow_free_all_locked(lru_file); + } } - ret = git_vector_insert(&ctl->windowfiles, mwf); + error = git_vector_insert(&ctl->windowfiles, mwf); git_mutex_unlock(&git__mwindow_mutex); + if (error < 0) + goto cleanup; - return ret; + /* + * Once we have released the global windowfiles lock, we can close each + * individual file. Before doing so, acquire that file's lock to avoid + * closing a file that is currently being used. + */ + git_vector_foreach(&closed_files, i, closed_file) { + error = git_mutex_lock(&closed_file->lock); + if (error < 0) + continue; + p_close(closed_file->fd); + closed_file->fd = -1; + git_mutex_unlock(&closed_file->lock); + } + +cleanup: + git_vector_free(&closed_files); + return error; } void git_mwindow_file_deregister(git_mwindow_file *mwf) diff --git a/src/mwindow.h b/src/mwindow.h index b379fba2ddb..e3a03f019bd 100644 --- a/src/mwindow.h +++ b/src/mwindow.h @@ -13,8 +13,6 @@ #include "map.h" #include "vector.h" -extern git_mutex git__mwindow_mutex; - typedef struct git_mwindow { struct git_mwindow *next; git_map window_map; @@ -24,6 +22,7 @@ typedef struct git_mwindow { } git_mwindow; typedef struct git_mwindow_file { + git_mutex lock; /* protects updates to fd */ git_mwindow *windows; int fd; off64_t size; @@ -41,7 +40,6 @@ typedef struct git_mwindow_ctl { int git_mwindow_contains(git_mwindow *win, off64_t offset); int git_mwindow_free_all(git_mwindow_file *mwf); /* locks */ -int git_mwindow_free_all_locked(git_mwindow_file *mwf); /* run under lock */ unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, off64_t offset, size_t extra, unsigned int *left); int git_mwindow_file_register(git_mwindow_file *mwf); void git_mwindow_file_deregister(git_mwindow_file *mwf); diff --git a/src/pack.c b/src/pack.c index 5a96ac5b595..b88c52acf96 100644 --- a/src/pack.c +++ b/src/pack.c @@ -17,8 +17,8 @@ /* Option to bypass checking existence of '.keep' files */ bool git_disable_pack_keep_file_checks = false; -static int packfile_open(struct git_pack_file *p); -static off64_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n); +static int packfile_open_locked(struct git_pack_file *p); +static off64_t nth_packed_object_offset_locked(struct git_pack_file *p, uint32_t n); static int packfile_unpack_compressed( git_rawobj *obj, struct git_pack_file *p, @@ -129,7 +129,7 @@ static void free_lowest_entry(git_pack_cache *cache) git_pack_cache_entry *entry; git_offmap_foreach(cache->entries, offset, entry, { - if (entry && entry->refcount.val == 0) { + if (entry && git_atomic_get(&entry->refcount) == 0) { cache->memory_used -= entry->raw.len; git_offmap_delete(cache->entries, offset); free_cache_object(entry); @@ -308,28 +308,29 @@ static int pack_index_open_locked(struct git_pack_file *p) { int error = 0; size_t name_len; - git_buf idx_name; + git_buf idx_name = GIT_BUF_INIT; if (p->index_version > -1) - return 0; + goto cleanup; /* checked by git_pack_file alloc */ name_len = strlen(p->pack_name); GIT_ASSERT(name_len > strlen(".pack")); - if (git_buf_init(&idx_name, name_len) < 0) - return -1; + if ((error = git_buf_init(&idx_name, name_len)) < 0) + goto cleanup; git_buf_put(&idx_name, p->pack_name, name_len - strlen(".pack")); git_buf_puts(&idx_name, ".idx"); if (git_buf_oom(&idx_name)) { - git_buf_dispose(&idx_name); - return -1; + error = -1; + goto cleanup; } if (p->index_version == -1) error = pack_index_check_locked(idx_name.ptr, p); +cleanup: git_buf_dispose(&idx_name); return error; @@ -341,8 +342,20 @@ static unsigned char *pack_window_open( off64_t offset, unsigned int *left) { - if (p->mwf.fd == -1 && packfile_open(p) < 0) + unsigned char *pack_data = NULL; + + if (git_mutex_lock(&p->lock) < 0) { + git_error_set(GIT_ERROR_THREAD, "unable to lock packfile"); return NULL; + } + if (git_mutex_lock(&p->mwf.lock) < 0) { + git_mutex_unlock(&p->lock); + git_error_set(GIT_ERROR_THREAD, "unable to lock packfile"); + return NULL; + } + + if (p->mwf.fd == -1 && packfile_open_locked(p) < 0) + goto cleanup; /* Since packfiles end in a hash of their content and it's * pointless to ask for an offset into the middle of that @@ -353,11 +366,16 @@ static unsigned char *pack_window_open( * around. */ if (offset > (p->mwf.size - 20)) - return NULL; + goto cleanup; if (offset < 0) - return NULL; + goto cleanup; + + pack_data = git_mwindow_open(&p->mwf, w_cursor, offset, 20, left); - return git_mwindow_open(&p->mwf, w_cursor, offset, 20, left); +cleanup: + git_mutex_unlock(&p->mwf.lock); + git_mutex_unlock(&p->lock); + return pack_data; } /* @@ -433,14 +451,27 @@ static int packfile_unpack_header1( int git_packfile_unpack_header( size_t *size_p, git_object_t *type_p, - git_mwindow_file *mwf, + struct git_pack_file *p, git_mwindow **w_curs, off64_t *curpos) { unsigned char *base; unsigned int left; unsigned long used; - int ret; + int error; + + if ((error = git_mutex_lock(&p->lock)) < 0) + return error; + if ((error = git_mutex_lock(&p->mwf.lock)) < 0) { + git_mutex_unlock(&p->lock); + return error; + } + + if (p->mwf.fd == -1 && (error = packfile_open_locked(p)) < 0) { + git_mutex_unlock(&p->lock); + git_mutex_unlock(&p->mwf.lock); + return error; + } /* pack_window_open() assures us we have [base, base + 20) available * as a range that we can look at at. (Its actually the hash @@ -448,16 +479,17 @@ int git_packfile_unpack_header( * the maximum deflated object size is 2^137, which is just * insane, so we know won't exceed what we have been given. */ -/* base = pack_window_open(p, w_curs, *curpos, &left); */ - base = git_mwindow_open(mwf, w_curs, *curpos, 20, &left); + base = git_mwindow_open(&p->mwf, w_curs, *curpos, 20, &left); + git_mutex_unlock(&p->lock); + git_mutex_unlock(&p->mwf.lock); if (base == NULL) return GIT_EBUFS; - ret = packfile_unpack_header1(&used, size_p, type_p, base, left); + error = packfile_unpack_header1(&used, size_p, type_p, base, left); git_mwindow_close(w_curs); - if (ret == GIT_EBUFS) - return ret; - else if (ret < 0) + if (error == GIT_EBUFS) + return error; + else if (error < 0) return packfile_error("header length is zero"); *curpos += used; @@ -477,10 +509,27 @@ int git_packfile_resolve_header( off64_t base_offset; int error; - if (p->mwf.fd == -1 && (error = packfile_open(p)) < 0) + error = git_mutex_lock(&p->lock); + if (error < 0) { + git_error_set(GIT_ERROR_OS, "failed to lock packfile reader"); + return error; + } + error = git_mutex_lock(&p->mwf.lock); + if (error < 0) { + git_error_set(GIT_ERROR_OS, "failed to lock packfile reader"); + git_mutex_unlock(&p->lock); + return error; + } + + if (p->mwf.fd == -1 && (error = packfile_open_locked(p)) < 0) { + git_mutex_unlock(&p->mwf.lock); + git_mutex_unlock(&p->lock); return error; + } + git_mutex_unlock(&p->mwf.lock); + git_mutex_unlock(&p->lock); - error = git_packfile_unpack_header(&size, &type, &p->mwf, &w_curs, &curpos); + error = git_packfile_unpack_header(&size, &type, p, &w_curs, &curpos); if (error < 0) return error; @@ -507,7 +556,7 @@ int git_packfile_resolve_header( while (type == GIT_OBJECT_OFS_DELTA || type == GIT_OBJECT_REF_DELTA) { curpos = base_offset; - error = git_packfile_unpack_header(&size, &type, &p->mwf, &w_curs, &curpos); + error = git_packfile_unpack_header(&size, &type, p, &w_curs, &curpos); if (error < 0) return error; if (type != GIT_OBJECT_OFS_DELTA && type != GIT_OBJECT_REF_DELTA) @@ -578,8 +627,7 @@ static int pack_dependency_chain(git_dependency_chain *chain_out, elem->base_key = obj_offset; - error = git_packfile_unpack_header(&size, &type, &p->mwf, &w_curs, &curpos); - + error = git_packfile_unpack_header(&size, &type, p, &w_curs, &curpos); if (error < 0) goto on_error; @@ -630,7 +678,23 @@ int git_packfile_unpack( size_t stack_size = 0, elem_pos, alloclen; git_object_t base_type; - if (p->mwf.fd == -1 && (error = packfile_open(p)) < 0) + error = git_mutex_lock(&p->lock); + if (error < 0) { + git_error_set(GIT_ERROR_OS, "failed to lock packfile reader"); + return error; + } + error = git_mutex_lock(&p->mwf.lock); + if (error < 0) { + git_error_set(GIT_ERROR_OS, "failed to lock packfile reader"); + git_mutex_unlock(&p->lock); + return error; + } + + if (p->mwf.fd == -1) + error = packfile_open_locked(p); + git_mutex_unlock(&p->mwf.lock); + git_mutex_unlock(&p->lock); + if (error < 0) return error; /* @@ -974,64 +1038,63 @@ int get_delta_base( * ***********************************************************/ -void git_packfile_close(struct git_pack_file *p, bool unlink_packfile) +void git_packfile_free(struct git_pack_file *p, bool unlink_packfile) { + bool locked = true; + + if (!p) + return; + + cache_free(&p->bases); + + if (git_mutex_lock(&p->lock) < 0) { + git_error_set(GIT_ERROR_OS, "failed to lock packfile"); + locked = false; + } if (p->mwf.fd >= 0) { - git_mwindow_free_all_locked(&p->mwf); + git_mwindow_free_all(&p->mwf); p_close(p->mwf.fd); p->mwf.fd = -1; } + if (locked) + git_mutex_unlock(&p->lock); if (unlink_packfile) p_unlink(p->pack_name); -} - -void git_packfile_free(struct git_pack_file *p) -{ - if (!p) - return; - - cache_free(&p->bases); - - git_packfile_close(p, false); pack_index_free(p); git__free(p->bad_object_sha1); - git_mutex_free(&p->lock); git_mutex_free(&p->bases.lock); + git_mutex_free(&p->mwf.lock); + git_mutex_free(&p->lock); git__free(p); } -static int packfile_open(struct git_pack_file *p) +/* Run with the packfile and mwf locks held */ +static int packfile_open_locked(struct git_pack_file *p) { struct stat st; struct git_pack_header hdr; git_oid sha1; unsigned char *idx_sha1; - if (git_mutex_lock(&p->lock) < 0) - return packfile_error("failed to get lock for open"); - - if (pack_index_open_locked(p) < 0) { - git_mutex_unlock(&p->lock); + if (pack_index_open_locked(p) < 0) return git_odb__error_notfound("failed to open packfile", NULL, 0); - } - if (p->mwf.fd >= 0) { - git_mutex_unlock(&p->lock); + if (p->mwf.fd >= 0) return 0; - } /* TODO: open with noatime */ p->mwf.fd = git_futils_open_ro(p->pack_name); if (p->mwf.fd < 0) goto cleanup; - if (p_fstat(p->mwf.fd, &st) < 0 || - git_mwindow_file_register(&p->mwf) < 0) + if (p_fstat(p->mwf.fd, &st) < 0) { + git_error_set(GIT_ERROR_OS, "could not stat packfile"); goto cleanup; + } /* If we created the struct before we had the pack we lack size. */ if (!p->mwf.size) { @@ -1071,7 +1134,9 @@ static int packfile_open(struct git_pack_file *p) if (git_oid__cmp(&sha1, (git_oid *)idx_sha1) != 0) goto cleanup; - git_mutex_unlock(&p->lock); + if (git_mwindow_file_register(&p->mwf) < 0) + goto cleanup; + return 0; cleanup: @@ -1081,8 +1146,6 @@ static int packfile_open(struct git_pack_file *p) p_close(p->mwf.fd); p->mwf.fd = -1; - git_mutex_unlock(&p->lock); - return -1; } @@ -1152,13 +1215,22 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path) p->mtime = (git_time_t)st.st_mtime; p->index_version = -1; - if (git_mutex_init(&p->lock)) { + if (git_mutex_init(&p->lock) < 0) { git_error_set(GIT_ERROR_OS, "failed to initialize packfile mutex"); git__free(p); return -1; } + if (git_mutex_init(&p->mwf.lock) < 0) { + git_error_set(GIT_ERROR_OS, "failed to initialize packfile window mutex"); + git_mutex_free(&p->lock); + git__free(p); + return -1; + } + if (cache_init(&p->bases) < 0) { + git_mutex_free(&p->mwf.lock); + git_mutex_free(&p->lock); git__free(p); return -1; } @@ -1174,28 +1246,29 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path) * ***********************************************************/ -static off64_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n) +static off64_t nth_packed_object_offset_locked(struct git_pack_file *p, uint32_t n) { - const unsigned char *index = p->index_map.data; - const unsigned char *end = index + p->index_map.len; + const unsigned char *index, *end; + uint32_t off32; + + index = p->index_map.data; + end = index + p->index_map.len; index += 4 * 256; - if (p->index_version == 1) { + if (p->index_version == 1) return ntohl(*((uint32_t *)(index + 24 * n))); - } else { - uint32_t off; - index += 8 + p->num_objects * (20 + 4); - off = ntohl(*((uint32_t *)(index + 4 * n))); - if (!(off & 0x80000000)) - return off; - index += p->num_objects * 4 + (off & 0x7fffffff) * 8; - - /* Make sure we're not being sent out of bounds */ - if (index >= end - 8) - return -1; - return (((uint64_t)ntohl(*((uint32_t *)(index + 0)))) << 32) | - ntohl(*((uint32_t *)(index + 4))); - } + index += 8 + p->num_objects * (20 + 4); + off32 = ntohl(*((uint32_t *)(index + 4 * n))); + if (!(off32 & 0x80000000)) + return off32; + index += p->num_objects * 4 + (off32 & 0x7fffffff) * 8; + + /* Make sure we're not being sent out of bounds */ + if (index >= end - 8) + return -1; + + return (((uint64_t)ntohl(*((uint32_t *)(index + 0)))) << 32) | + ntohl(*((uint32_t *)(index + 4))); } static int git__memcmp4(const void *a, const void *b) { @@ -1396,7 +1469,7 @@ static int pack_entry_find_offset( goto cleanup; } - if ((offset = nth_packed_object_offset(p, pos)) < 0) { + if ((offset = nth_packed_object_offset_locked(p, pos)) < 0) { git_error_set(GIT_ERROR_ODB, "packfile index is corrupt"); error = -1; goto cleanup; @@ -1442,10 +1515,26 @@ int git_pack_entry_find( if (error < 0) return error; + error = git_mutex_lock(&p->lock); + if (error < 0) { + git_error_set(GIT_ERROR_OS, "failed to lock packfile reader"); + return error; + } + error = git_mutex_lock(&p->mwf.lock); + if (error < 0) { + git_mutex_unlock(&p->lock); + git_error_set(GIT_ERROR_OS, "failed to lock packfile reader"); + return error; + } + /* we found a unique entry in the index; * make sure the packfile backing the index * still exists on disk */ - if (p->mwf.fd == -1 && (error = packfile_open(p)) < 0) + if (p->mwf.fd == -1) + error = packfile_open_locked(p); + git_mutex_unlock(&p->mwf.lock); + git_mutex_unlock(&p->lock); + if (error < 0) return error; e->offset = offset; diff --git a/src/pack.h b/src/pack.h index 544a5d286ac..7c3be079ede 100644 --- a/src/pack.h +++ b/src/pack.h @@ -85,7 +85,7 @@ typedef struct { struct git_pack_file { git_mwindow_file mwf; git_map index_map; - git_mutex lock; /* protect updates to mwf and index_map */ + git_mutex lock; /* protect updates to index_map */ git_atomic refcount; uint32_t num_objects; @@ -140,7 +140,7 @@ int git_packfile__name(char **out, const char *path); int git_packfile_unpack_header( size_t *size_p, git_object_t *type_p, - git_mwindow_file *mwf, + struct git_pack_file *p, git_mwindow **w_curs, off64_t *curpos); @@ -164,8 +164,7 @@ int get_delta_base( git_object_t type, off64_t delta_obj_offset); -void git_packfile_close(struct git_pack_file *p, bool unlink_packfile); -void git_packfile_free(struct git_pack_file *p); +void git_packfile_free(struct git_pack_file *p, bool unlink_packfile); int git_packfile_alloc(struct git_pack_file **pack_out, const char *path); int git_pack_entry_find( diff --git a/src/unix/map.c b/src/unix/map.c index 62c52578b23..88f283ce815 100644 --- a/src/unix/map.c +++ b/src/unix/map.c @@ -68,6 +68,8 @@ int p_munmap(git_map *map) { GIT_ASSERT_ARG(map); munmap(map->data, map->len); + map->data = NULL; + map->len = 0; return 0; } diff --git a/tests/pack/filelimit.c b/tests/pack/filelimit.c index b39ab732758..5e0b77e9bd2 100644 --- a/tests/pack/filelimit.c +++ b/tests/pack/filelimit.c @@ -8,6 +8,7 @@ static size_t expected_open_mwindow_files = 0; static size_t original_mwindow_file_limit = 0; +extern git_mutex git__mwindow_mutex; extern git_mwindow_ctl git_mwindow__mem_ctl; void test_pack_filelimit__initialize_tiny(void) diff --git a/tests/pack/threadsafety.c b/tests/pack/threadsafety.c new file mode 100644 index 00000000000..0b479788f01 --- /dev/null +++ b/tests/pack/threadsafety.c @@ -0,0 +1,60 @@ +#include "clar_libgit2.h" +#include "pool.h" + +#include +#include "git2/sys/commit.h" +#include "git2/sys/mempack.h" + +static size_t original_mwindow_file_limit = 0; + +void test_pack_threadsafety__initialize(void) +{ + size_t open_mwindow_files = 1; + + cl_git_pass(git_libgit2_opts(GIT_OPT_GET_MWINDOW_FILE_LIMIT, &original_mwindow_file_limit)); + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT, open_mwindow_files)); +} + +void test_pack_threadsafety__cleanup(void) +{ + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT, original_mwindow_file_limit)); +} + +static void *get_status(void *arg) +{ + const char *repo_path = (const char *)arg; + git_repository *repo; + git_status_list *status; + + cl_git_pass(git_repository_open(&repo, repo_path)); + cl_git_pass(git_status_list_new(&status, repo, NULL)); + git_status_list_free(status); + git_repository_free(repo); + + return NULL; +} + +void test_pack_threadsafety__open_repo_in_multiple_threads(void) +{ +#ifdef GIT_THREADS + const char *repo_path = cl_fixture("../.."); + git_repository *repo; + git_thread threads[8]; + size_t i; + + /* If we can't open the libgit2 repo or if it isn't a full repo + * with proper history, just skip this test */ + if (git_repository_open(&repo, repo_path) < 0) + cl_skip(); + if (git_repository_is_shallow(repo)) + cl_skip(); + git_repository_free(repo); + + for (i = 0; i < ARRAY_SIZE(threads); i++) + git_thread_create(&threads[i], get_status, (void *)repo_path); + for (i = 0; i < ARRAY_SIZE(threads); i++) + git_thread_join(&threads[i], NULL); +#else + cl_skip(); +#endif +} From 8413c0f9b357a513943e496b01c68aa27e1d95b4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Dec 2020 21:32:48 +0000 Subject: [PATCH 0172/1616] util: move git__noop into the util header The git__noop function is more largely useful; move it into the util header. (And reduce the number of underscores.) --- src/runtime.c | 4 ++-- src/thread-utils.h | 40 +++++++++++++++++++--------------------- src/util.h | 2 ++ 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/runtime.c b/src/runtime.c index f8e3e3b274f..a214b435e67 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -103,8 +103,8 @@ GIT_INLINE(int) init_unlock(void) # error unknown threading model #else -# define init_lock() git___noop() -# define init_unlock() git___noop() +# define init_lock() git__noop() +# define init_unlock() git__noop() #endif diff --git a/src/thread-utils.h b/src/thread-utils.h index e577a9b0b78..d71fabe100c 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -235,38 +235,36 @@ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a) #else -GIT_INLINE(int) git___noop(void) { return 0; } - -#define git_threads_global_init git___noop +#define git_threads_global_init git__noop #define git_thread unsigned int -#define git_thread_create(thread, start_routine, arg) git___noop() -#define git_thread_join(id, status) git___noop() +#define git_thread_create(thread, start_routine, arg) git__noop() +#define git_thread_join(id, status) git__noop() /* Pthreads Mutex */ #define git_mutex unsigned int -#define git_mutex_init(a) git___noop() -#define git_mutex_init(a) git___noop() -#define git_mutex_lock(a) git___noop() -#define git_mutex_unlock(a) git___noop() -#define git_mutex_free(a) git___noop() +#define git_mutex_init(a) git__noop() +#define git_mutex_init(a) git__noop() +#define git_mutex_lock(a) git__noop() +#define git_mutex_unlock(a) git__noop() +#define git_mutex_free(a) git__noop() /* Pthreads condition vars */ #define git_cond unsigned int -#define git_cond_init(c) git___noop() -#define git_cond_free(c) git___noop() -#define git_cond_wait(c, l) git___noop() -#define git_cond_signal(c) git___noop() -#define git_cond_broadcast(c) git___noop() +#define git_cond_init(c) git__noop() +#define git_cond_free(c) git__noop() +#define git_cond_wait(c, l) git__noop() +#define git_cond_signal(c) git__noop() +#define git_cond_broadcast(c) git__noop() /* Pthreads rwlock */ #define git_rwlock unsigned int -#define git_rwlock_init(a) git___noop() -#define git_rwlock_rdlock(a) git___noop() -#define git_rwlock_rdunlock(a) git___noop() -#define git_rwlock_wrlock(a) git___noop() -#define git_rwlock_wrunlock(a) git___noop() -#define git_rwlock_free(a) git___noop() +#define git_rwlock_init(a) git__noop() +#define git_rwlock_rdlock(a) git__noop() +#define git_rwlock_rdunlock(a) git__noop() +#define git_rwlock_wrlock(a) git__noop() +#define git_rwlock_wrunlock(a) git__noop() +#define git_rwlock_free(a) git__noop() #define GIT_RWLOCK_STATIC_INIT 0 diff --git a/src/util.h b/src/util.h index f49989f7ed2..185a1b129fe 100644 --- a/src/util.h +++ b/src/util.h @@ -414,6 +414,8 @@ GIT_INLINE(double) git__timer(void) extern int git__getenv(git_buf *out, const char *name); +GIT_INLINE(int) git__noop(void) { return 0; } + #include "alloc.h" #endif From fe07ef8a1b4eae52421d81b28b327d0f55c338cf Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Dec 2020 21:38:29 +0000 Subject: [PATCH 0173/1616] packbuilder: use git__noop on non-threaded systems Our git_packbuilder__cache_lock function returns a value; use git__noop. --- src/pack-objects.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pack-objects.c b/src/pack-objects.c index 8ebb8cf430a..03d05b7e7f7 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -50,7 +50,7 @@ struct walk_object { #ifdef GIT_THREADS # define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) git_mutex_##op(&(pb)->mtx) #else -# define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) GIT_UNUSED(pb) +# define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) git__noop() #endif #define git_packbuilder__cache_lock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, cache_mutex, lock) From 0450e3134b543e047eb391e0a26bce760c62ebb1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Dec 2020 22:03:59 +0000 Subject: [PATCH 0174/1616] tests: ifdef out unused function in no-thread builds --- tests/pack/threadsafety.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/pack/threadsafety.c b/tests/pack/threadsafety.c index 0b479788f01..fd6a61fbd19 100644 --- a/tests/pack/threadsafety.c +++ b/tests/pack/threadsafety.c @@ -20,6 +20,7 @@ void test_pack_threadsafety__cleanup(void) cl_git_pass(git_libgit2_opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT, original_mwindow_file_limit)); } +#ifdef GIT_THREADS static void *get_status(void *arg) { const char *repo_path = (const char *)arg; @@ -33,6 +34,7 @@ static void *get_status(void *arg) return NULL; } +#endif void test_pack_threadsafety__open_repo_in_multiple_threads(void) { From 8f3053269e6d518ccf06549aed82dddbfe0c4823 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Dec 2020 21:41:39 +0000 Subject: [PATCH 0175/1616] ci: run a threadsafe build in nightly --- .github/workflows/nightly.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 11b184ee21c..8e35726d7ad 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -51,6 +51,14 @@ jobs: CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest + - # Xenial, GCC, thread-free + container: + name: xenial + env: + CC: gcc + CMAKE_OPTIONS: -DTHREADSAFE=OFF -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_GENERATOR: Ninja + os: ubuntu-latest - # Focal, Clang 10, mbedTLS, MemorySanitizer container: name: focal From 9800728a746b872fdd22db9e68bc85ef0c851f27 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Dec 2020 16:08:34 +0000 Subject: [PATCH 0176/1616] util: move git_online_cpus into util The number of CPUs is useful information for creating a thread pool or a number of workers, but it's not really about threading directly. Evict it from the thread file --- src/pack-objects.c | 2 +- src/thread-utils.c | 58 ---------------------------------------------- src/thread-utils.h | 2 -- src/util.c | 49 +++++++++++++++++++++++++++++++++++++++ src/util.h | 2 ++ 5 files changed, 52 insertions(+), 61 deletions(-) delete mode 100644 src/thread-utils.c diff --git a/src/pack-objects.c b/src/pack-objects.c index 03d05b7e7f7..81678537d0d 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -1158,7 +1158,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list, int ret, active_threads = 0; if (!pb->nr_threads) - pb->nr_threads = git_online_cpus(); + pb->nr_threads = git__online_cpus(); if (pb->nr_threads <= 1) { find_deltas(pb, list, &list_size, window, depth); diff --git a/src/thread-utils.c b/src/thread-utils.c deleted file mode 100644 index e5ec6a843f8..00000000000 --- a/src/thread-utils.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ - -#include "common.h" -#include "thread-utils.h" - -#ifdef _WIN32 -#ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif -# include -#elif defined(hpux) || defined(__hpux) || defined(_hpux) -# include -#endif - -/* - * By doing this in two steps we can at least get - * the function to be somewhat coherent, even - * with this disgusting nest of #ifdefs. - */ -#ifndef _SC_NPROCESSORS_ONLN -# ifdef _SC_NPROC_ONLN -# define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN -# elif defined _SC_CRAY_NCPU -# define _SC_NPROCESSORS_ONLN _SC_CRAY_NCPU -# endif -#endif - -int git_online_cpus(void) -{ -#ifdef _SC_NPROCESSORS_ONLN - long ncpus; -#endif - -#ifdef _WIN32 - SYSTEM_INFO info; - GetSystemInfo(&info); - - if ((int)info.dwNumberOfProcessors > 0) - return (int)info.dwNumberOfProcessors; -#elif defined(hpux) || defined(__hpux) || defined(_hpux) - struct pst_dynamic psd; - - if (!pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0)) - return (int)psd.psd_proc_cnt; -#endif - -#ifdef _SC_NPROCESSORS_ONLN - if ((ncpus = (long)sysconf(_SC_NPROCESSORS_ONLN)) > 0) - return (int)ncpus; -#endif - - return 1; -} diff --git a/src/thread-utils.h b/src/thread-utils.h index d71fabe100c..10143475afd 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -349,8 +349,6 @@ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a) #define git__load(ptr) (void *)git___load((void * volatile *)&ptr) -extern int git_online_cpus(void); - #if defined(GIT_THREADS) # if defined(GIT_WIN32) diff --git a/src/util.c b/src/util.c index 2efb212bc79..18a02a265c2 100644 --- a/src/util.c +++ b/src/util.c @@ -13,6 +13,11 @@ # include "win32/utf-conv.h" # include "win32/w32_buffer.h" +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include + # ifdef HAVE_QSORT_S # include # endif @@ -22,6 +27,10 @@ # include #endif +#if defined(hpux) || defined(__hpux) || defined(_hpux) +# include +#endif + int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const char **endptr, int base) { const char *p; @@ -893,3 +902,43 @@ int git__getenv(git_buf *out, const char *name) return git_buf_puts(out, val); } #endif + +/* + * By doing this in two steps we can at least get + * the function to be somewhat coherent, even + * with this disgusting nest of #ifdefs. + */ +#ifndef _SC_NPROCESSORS_ONLN +# ifdef _SC_NPROC_ONLN +# define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN +# elif defined _SC_CRAY_NCPU +# define _SC_NPROCESSORS_ONLN _SC_CRAY_NCPU +# endif +#endif + +int git__online_cpus(void) +{ +#ifdef _SC_NPROCESSORS_ONLN + long ncpus; +#endif + +#ifdef _WIN32 + SYSTEM_INFO info; + GetSystemInfo(&info); + + if ((int)info.dwNumberOfProcessors > 0) + return (int)info.dwNumberOfProcessors; +#elif defined(hpux) || defined(__hpux) || defined(_hpux) + struct pst_dynamic psd; + + if (!pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0)) + return (int)psd.psd_proc_cnt; +#endif + +#ifdef _SC_NPROCESSORS_ONLN + if ((ncpus = (long)sysconf(_SC_NPROCESSORS_ONLN)) > 0) + return (int)ncpus; +#endif + + return 1; +} diff --git a/src/util.h b/src/util.h index 185a1b129fe..ef5e4eb125b 100644 --- a/src/util.h +++ b/src/util.h @@ -414,6 +414,8 @@ GIT_INLINE(double) git__timer(void) extern int git__getenv(git_buf *out, const char *name); +extern int git__online_cpus(void); + GIT_INLINE(int) git__noop(void) { return 0; } #include "alloc.h" From 37763d38fbf5db932be8d6a0070255839e7719ca Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Dec 2020 15:26:59 +0000 Subject: [PATCH 0177/1616] threads: rename git_atomic to git_atomic32 Clarify the `git_atomic` type and functions now that we have a 64 bit version as well (`git_atomic64`). --- src/attr_file.c | 2 +- src/cache.c | 2 +- src/cache.h | 12 ++++++------ src/index.c | 10 +++++----- src/index.h | 2 +- src/mwindow.c | 6 +++--- src/pack.c | 12 ++++++------ src/pack.h | 4 ++-- src/repository.h | 2 +- src/runtime.c | 16 ++++++++-------- src/thread-utils.h | 30 +++++++++++++++--------------- src/transports/local.c | 4 ++-- src/transports/smart.c | 4 ++-- src/transports/smart.h | 2 +- src/transports/smart_protocol.c | 2 +- src/util.h | 8 ++++---- tests/threads/diff.c | 18 +++++++++--------- 17 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/attr_file.c b/src/attr_file.c index 0781c1d61c1..adc56d53ea8 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -960,7 +960,7 @@ int git_attr_session__init(git_attr_session *session, git_repository *repo) GIT_ASSERT_ARG(repo); memset(session, 0, sizeof(*session)); - session->key = git_atomic_inc(&repo->attr_session_key); + session->key = git_atomic32_inc(&repo->attr_session_key); return 0; } diff --git a/src/cache.c b/src/cache.c index a76da50d7a1..dbd4c319a3a 100644 --- a/src/cache.c +++ b/src/cache.c @@ -235,7 +235,7 @@ void git_cached_obj_decref(void *_obj) { git_cached_obj *obj = _obj; - if (git_atomic_dec(&obj->refcount) == 0) { + if (git_atomic32_dec(&obj->refcount) == 0) { switch (obj->flags) { case GIT_CACHE_STORE_RAW: git_odb_object__free(_obj); diff --git a/src/cache.h b/src/cache.h index 1e617923664..c43422d6fe7 100644 --- a/src/cache.h +++ b/src/cache.h @@ -23,11 +23,11 @@ enum { }; typedef struct { - git_oid oid; - int16_t type; /* git_object_t value */ - uint16_t flags; /* GIT_CACHE_STORE value */ - size_t size; - git_atomic refcount; + git_oid oid; + int16_t type; /* git_object_t value */ + uint16_t flags; /* GIT_CACHE_STORE value */ + size_t size; + git_atomic32 refcount; } git_cached_obj; typedef struct { @@ -61,7 +61,7 @@ GIT_INLINE(size_t) git_cache_size(git_cache *cache) GIT_INLINE(void) git_cached_obj_incref(void *_obj) { git_cached_obj *obj = _obj; - git_atomic_inc(&obj->refcount); + git_atomic32_inc(&obj->refcount); } void git_cached_obj_decref(void *_obj); diff --git a/src/index.c b/src/index.c index d9116c412bb..942fcca26e2 100644 --- a/src/index.c +++ b/src/index.c @@ -461,7 +461,7 @@ static void index_free(git_index *index) /* index iterators increment the refcount of the index, so if we * get here then there should be no outstanding iterators. */ - if (git_atomic_get(&index->readers)) + if (git_atomic32_get(&index->readers)) return; git_index_clear(index); @@ -488,7 +488,7 @@ void git_index_free(git_index *index) /* call with locked index */ static void index_free_deleted(git_index *index) { - int readers = (int)git_atomic_get(&index->readers); + int readers = (int)git_atomic32_get(&index->readers); size_t i; if (readers > 0 || !index->deleted.length) @@ -516,7 +516,7 @@ static int index_remove_entry(git_index *index, size_t pos) error = git_vector_remove(&index->entries, pos); if (!error) { - if (git_atomic_get(&index->readers) > 0) { + if (git_atomic32_get(&index->readers) > 0) { error = git_vector_insert(&index->deleted, entry); } else { index_entry_free(entry); @@ -3637,7 +3637,7 @@ int git_index_snapshot_new(git_vector *snap, git_index *index) GIT_REFCOUNT_INC(index); - git_atomic_inc(&index->readers); + git_atomic32_inc(&index->readers); git_vector_sort(&index->entries); error = git_vector_dup(snap, &index->entries, index->entries._cmp); @@ -3652,7 +3652,7 @@ void git_index_snapshot_release(git_vector *snap, git_index *index) { git_vector_free(snap); - git_atomic_dec(&index->readers); + git_atomic32_dec(&index->readers); git_index_free(index); } diff --git a/src/index.h b/src/index.h index 54402f5634b..a365867d0bf 100644 --- a/src/index.h +++ b/src/index.h @@ -33,7 +33,7 @@ struct git_index { git_idxmap *entries_map; git_vector deleted; /* deleted entries if readers > 0 */ - git_atomic readers; /* number of active iterators */ + git_atomic32 readers; /* number of active iterators */ unsigned int on_disk:1; unsigned int ignore_case:1; diff --git a/src/mwindow.c b/src/mwindow.c index 4f105e65927..7832d9c8baf 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -79,7 +79,7 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path) git__free(packname); if (pack != NULL) { - git_atomic_inc(&pack->refcount); + git_atomic32_inc(&pack->refcount); git_mutex_unlock(&git__mwindow_mutex); *out = pack; return 0; @@ -91,7 +91,7 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path) return error; } - git_atomic_inc(&pack->refcount); + git_atomic32_inc(&pack->refcount); error = git_strmap_set(git__pack_cache, pack->pack_name, pack); git_mutex_unlock(&git__mwindow_mutex); @@ -118,7 +118,7 @@ int git_mwindow_put_pack(struct git_pack_file *pack) /* if we cannot find it, the state is corrupted */ GIT_ASSERT(git_strmap_exists(git__pack_cache, pack->pack_name)); - count = git_atomic_dec(&pack->refcount); + count = git_atomic32_dec(&pack->refcount); if (count == 0) { git_strmap_delete(git__pack_cache, pack->pack_name); pack_to_delete = pack; diff --git a/src/pack.c b/src/pack.c index b88c52acf96..a9140c63dd1 100644 --- a/src/pack.c +++ b/src/pack.c @@ -57,7 +57,7 @@ static git_pack_cache_entry *new_cache_object(git_rawobj *source) if (!e) return NULL; - git_atomic_inc(&e->refcount); + git_atomic32_inc(&e->refcount); memcpy(&e->raw, source, sizeof(git_rawobj)); return e; @@ -114,7 +114,7 @@ static git_pack_cache_entry *cache_get(git_pack_cache *cache, off64_t offset) return NULL; if ((entry = git_offmap_get(cache->entries, offset)) != NULL) { - git_atomic_inc(&entry->refcount); + git_atomic32_inc(&entry->refcount); entry->last_usage = cache->use_ctr++; } git_mutex_unlock(&cache->lock); @@ -129,7 +129,7 @@ static void free_lowest_entry(git_pack_cache *cache) git_pack_cache_entry *entry; git_offmap_foreach(cache->entries, offset, entry, { - if (entry && git_atomic_get(&entry->refcount) == 0) { + if (entry && git_atomic32_get(&entry->refcount) == 0) { cache->memory_used -= entry->raw.len; git_offmap_delete(cache->entries, offset); free_cache_object(entry); @@ -759,7 +759,7 @@ int git_packfile_unpack( GIT_ERROR_CHECK_ALLOC(obj->data); memcpy(obj->data, data, obj->len + 1); - git_atomic_dec(&cached->refcount); + git_atomic32_dec(&cached->refcount); goto cleanup; } @@ -807,7 +807,7 @@ int git_packfile_unpack( } if (cached) { - git_atomic_dec(&cached->refcount); + git_atomic32_dec(&cached->refcount); cached = NULL; } @@ -821,7 +821,7 @@ int git_packfile_unpack( if (error < 0) { git__free(obj->data); if (cached) - git_atomic_dec(&cached->refcount); + git_atomic32_dec(&cached->refcount); } if (elem) diff --git a/src/pack.h b/src/pack.h index 7c3be079ede..1d077240d01 100644 --- a/src/pack.h +++ b/src/pack.h @@ -58,7 +58,7 @@ struct git_pack_idx_header { typedef struct git_pack_cache_entry { size_t last_usage; /* enough? */ - git_atomic refcount; + git_atomic32 refcount; git_rawobj raw; } git_pack_cache_entry; @@ -86,7 +86,7 @@ struct git_pack_file { git_mwindow_file mwf; git_map index_map; git_mutex lock; /* protect updates to index_map */ - git_atomic refcount; + git_atomic32 refcount; uint32_t num_objects; uint32_t num_bad_objects; diff --git a/src/repository.h b/src/repository.h index de009ba5e8b..4b1222e3a03 100644 --- a/src/repository.h +++ b/src/repository.h @@ -152,7 +152,7 @@ struct git_repository { unsigned int lru_counter; - git_atomic attr_session_key; + git_atomic32 attr_session_key; git_configmap_value configmap_cache[GIT_CONFIGMAP_CACHE_MAX]; git_strmap *submodule_cache; diff --git a/src/runtime.c b/src/runtime.c index a214b435e67..3fd064982ee 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -9,9 +9,9 @@ #include "runtime.h" static git_runtime_shutdown_fn shutdown_callback[32]; -static git_atomic shutdown_callback_count; +static git_atomic32 shutdown_callback_count; -static git_atomic init_count; +static git_atomic32 init_count; static int init_common(git_runtime_init_fn init_fns[], size_t cnt) { @@ -34,9 +34,9 @@ static void shutdown_common(void) git_runtime_shutdown_fn cb; int pos; - for (pos = git_atomic_get(&shutdown_callback_count); + for (pos = git_atomic32_get(&shutdown_callback_count); pos > 0; - pos = git_atomic_dec(&shutdown_callback_count)) { + pos = git_atomic32_dec(&shutdown_callback_count)) { cb = git__swap(shutdown_callback[pos - 1], NULL); if (cb != NULL) @@ -46,12 +46,12 @@ static void shutdown_common(void) int git_runtime_shutdown_register(git_runtime_shutdown_fn callback) { - int count = git_atomic_inc(&shutdown_callback_count); + int count = git_atomic32_inc(&shutdown_callback_count); if (count > (int)ARRAY_SIZE(shutdown_callback) || count == 0) { git_error_set(GIT_ERROR_INVALID, "too many shutdown callbacks registered"); - git_atomic_dec(&shutdown_callback_count); + git_atomic32_dec(&shutdown_callback_count); return -1; } @@ -116,7 +116,7 @@ int git_runtime_init(git_runtime_init_fn init_fns[], size_t cnt) return -1; /* Only do work on a 0 -> 1 transition of the refcount */ - if ((ret = git_atomic_inc(&init_count)) == 1) { + if ((ret = git_atomic32_inc(&init_count)) == 1) { if (init_common(init_fns, cnt) < 0) ret = -1; } @@ -136,7 +136,7 @@ int git_runtime_shutdown(void) return -1; /* Only do work on a 1 -> 0 transition of the refcount */ - if ((ret = git_atomic_dec(&init_count)) == 0) + if ((ret = git_atomic32_dec(&init_count)) == 0) shutdown_common(); /* Exit the lock */ diff --git a/src/thread-utils.h b/src/thread-utils.h index 10143475afd..31a4c09e324 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -38,7 +38,7 @@ typedef struct { #else volatile int val; #endif -} git_atomic; +} git_atomic32; #ifdef GIT_ARCH_64 @@ -58,11 +58,11 @@ typedef git_atomic64 git_atomic_ssize; #else -typedef git_atomic git_atomic_ssize; +typedef git_atomic32 git_atomic_ssize; -#define git_atomic_ssize_set git_atomic_set -#define git_atomic_ssize_add git_atomic_add -#define git_atomic_ssize_get git_atomic_get +#define git_atomic_ssize_set git_atomic32_set +#define git_atomic_ssize_add git_atomic32_add +#define git_atomic_ssize_get git_atomic32_get #endif @@ -74,7 +74,7 @@ typedef git_atomic git_atomic_ssize; # include "unix/pthread.h" #endif -GIT_INLINE(void) git_atomic_set(git_atomic *a, int val) +GIT_INLINE(void) git_atomic32_set(git_atomic32 *a, int val) { #if defined(GIT_WIN32) InterlockedExchange(&a->val, (LONG)val); @@ -87,7 +87,7 @@ GIT_INLINE(void) git_atomic_set(git_atomic *a, int val) #endif } -GIT_INLINE(int) git_atomic_inc(git_atomic *a) +GIT_INLINE(int) git_atomic32_inc(git_atomic32 *a) { #if defined(GIT_WIN32) return InterlockedIncrement(&a->val); @@ -100,7 +100,7 @@ GIT_INLINE(int) git_atomic_inc(git_atomic *a) #endif } -GIT_INLINE(int) git_atomic_add(git_atomic *a, int32_t addend) +GIT_INLINE(int) git_atomic32_add(git_atomic32 *a, int32_t addend) { #if defined(GIT_WIN32) return InterlockedExchangeAdd(&a->val, addend); @@ -113,7 +113,7 @@ GIT_INLINE(int) git_atomic_add(git_atomic *a, int32_t addend) #endif } -GIT_INLINE(int) git_atomic_dec(git_atomic *a) +GIT_INLINE(int) git_atomic32_dec(git_atomic32 *a) { #if defined(GIT_WIN32) return InterlockedDecrement(&a->val); @@ -126,7 +126,7 @@ GIT_INLINE(int) git_atomic_dec(git_atomic *a) #endif } -GIT_INLINE(int) git_atomic_get(git_atomic *a) +GIT_INLINE(int) git_atomic32_get(git_atomic32 *a) { #if defined(GIT_WIN32) return (int)InterlockedCompareExchange(&a->val, 0, 0); @@ -268,28 +268,28 @@ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a) #define GIT_RWLOCK_STATIC_INIT 0 -GIT_INLINE(void) git_atomic_set(git_atomic *a, int val) +GIT_INLINE(void) git_atomic32_set(git_atomic32 *a, int val) { a->val = val; } -GIT_INLINE(int) git_atomic_inc(git_atomic *a) +GIT_INLINE(int) git_atomic32_inc(git_atomic32 *a) { return ++a->val; } -GIT_INLINE(int) git_atomic_add(git_atomic *a, int32_t addend) +GIT_INLINE(int) git_atomic32_add(git_atomic32 *a, int32_t addend) { a->val += addend; return a->val; } -GIT_INLINE(int) git_atomic_dec(git_atomic *a) +GIT_INLINE(int) git_atomic32_dec(git_atomic32 *a) { return --a->val; } -GIT_INLINE(int) git_atomic_get(git_atomic *a) +GIT_INLINE(int) git_atomic32_get(git_atomic32 *a) { return (int)a->val; } diff --git a/src/transports/local.c b/src/transports/local.c index 4af85db817d..bb31b134580 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -36,7 +36,7 @@ typedef struct { char *url; int direction; int flags; - git_atomic cancelled; + git_atomic32 cancelled; git_repository *repo; git_transport_message_cb progress_cb; git_transport_message_cb error_cb; @@ -671,7 +671,7 @@ static void local_cancel(git_transport *transport) { transport_local *t = (transport_local *)transport; - git_atomic_set(&t->cancelled, 1); + git_atomic32_set(&t->cancelled, 1); } static int local_close(git_transport *transport) diff --git a/src/transports/smart.c b/src/transports/smart.c index 3b8a14a4c28..da8fe8e221d 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -30,7 +30,7 @@ static int git_smart__recv_cb(gitno_buffer *buf) if (t->packetsize_cb && !t->cancelled.val) { error = t->packetsize_cb(bytes_read, t->packetsize_payload); if (error) { - git_atomic_set(&t->cancelled, 1); + git_atomic32_set(&t->cancelled, 1); return GIT_EUSER; } } @@ -389,7 +389,7 @@ static void git_smart__cancel(git_transport *transport) { transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); - git_atomic_set(&t->cancelled, 1); + git_atomic32_set(&t->cancelled, 1); } static int git_smart__is_connected(git_transport *transport) diff --git a/src/transports/smart.h b/src/transports/smart.h index 18e0b7e9fba..a05d4c9e3a2 100644 --- a/src/transports/smart.h +++ b/src/transports/smart.h @@ -153,7 +153,7 @@ typedef struct { git_vector refs; git_vector heads; git_vector common; - git_atomic cancelled; + git_atomic32 cancelled; packetsize_cb packetsize_cb; void *packetsize_payload; unsigned rpc : 1, diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 18dcaa879d6..9482915d886 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -535,7 +535,7 @@ int git_smart__download_pack( /* We might have something in the buffer already from negotiate_fetch */ if (t->buffer.offset > 0 && !t->cancelled.val) if (t->packetsize_cb(t->buffer.offset, t->packetsize_payload)) - git_atomic_set(&t->cancelled, 1); + git_atomic32_set(&t->cancelled, 1); } if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 || diff --git a/src/util.h b/src/util.h index ef5e4eb125b..6c7c4c28413 100644 --- a/src/util.h +++ b/src/util.h @@ -169,19 +169,19 @@ extern int git__strncasecmp(const char *a, const char *b, size_t sz); extern int git__strcasesort_cmp(const char *a, const char *b); typedef struct { - git_atomic refcount; + git_atomic32 refcount; void *owner; } git_refcount; typedef void (*git_refcount_freeptr)(void *r); #define GIT_REFCOUNT_INC(r) { \ - git_atomic_inc(&(r)->rc.refcount); \ + git_atomic32_inc(&(r)->rc.refcount); \ } #define GIT_REFCOUNT_DEC(_r, do_free) { \ git_refcount *r = &(_r)->rc; \ - int val = git_atomic_dec(&r->refcount); \ + int val = git_atomic32_dec(&r->refcount); \ if (val <= 0 && r->owner == NULL) { do_free(_r); } \ } @@ -191,7 +191,7 @@ typedef void (*git_refcount_freeptr)(void *r); #define GIT_REFCOUNT_OWNER(r) git__load((r)->rc.owner) -#define GIT_REFCOUNT_VAL(r) git_atomic_get((r)->rc.refcount) +#define GIT_REFCOUNT_VAL(r) git_atomic32_get((r)->rc.refcount) static signed char from_hex[] = { diff --git a/tests/threads/diff.c b/tests/threads/diff.c index 69964279001..04c8cb97fd3 100644 --- a/tests/threads/diff.c +++ b/tests/threads/diff.c @@ -17,7 +17,7 @@ static git_repository *_repo; static git_tree *_a, *_b; -static git_atomic _counts[4]; +static git_atomic32 _counts[4]; static int _check_counts; #ifdef GIT_WIN32 static int _retries; @@ -66,10 +66,10 @@ static void free_trees(void) git_tree_free(_b); _b = NULL; if (_check_counts) { - cl_assert_equal_i(288, git_atomic_get(&_counts[0])); - cl_assert_equal_i(112, git_atomic_get(&_counts[1])); - cl_assert_equal_i( 80, git_atomic_get(&_counts[2])); - cl_assert_equal_i( 96, git_atomic_get(&_counts[3])); + cl_assert_equal_i(288, git_atomic32_get(&_counts[0])); + cl_assert_equal_i(112, git_atomic32_get(&_counts[1])); + cl_assert_equal_i( 80, git_atomic32_get(&_counts[2])); + cl_assert_equal_i( 96, git_atomic32_get(&_counts[3])); } } @@ -107,14 +107,14 @@ static void *run_index_diffs(void *arg) /* keep some diff stats to make sure results are as expected */ i = git_diff_num_deltas(diff); - git_atomic_add(&_counts[0], (int32_t)i); + git_atomic32_add(&_counts[0], (int32_t)i); exp[0] = (int)i; while (i > 0) { switch (git_diff_get_delta(diff, --i)->status) { - case GIT_DELTA_MODIFIED: exp[1]++; git_atomic_inc(&_counts[1]); break; - case GIT_DELTA_ADDED: exp[2]++; git_atomic_inc(&_counts[2]); break; - case GIT_DELTA_DELETED: exp[3]++; git_atomic_inc(&_counts[3]); break; + case GIT_DELTA_MODIFIED: exp[1]++; git_atomic32_inc(&_counts[1]); break; + case GIT_DELTA_ADDED: exp[2]++; git_atomic32_inc(&_counts[2]); break; + case GIT_DELTA_DELETED: exp[3]++; git_atomic32_inc(&_counts[3]); break; default: break; } } From ab7729747c4b55a93b8973e94429c747fe274529 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Dec 2020 15:49:30 +0000 Subject: [PATCH 0178/1616] threads: give atomic functions the git_atomic prefix --- src/attrcache.c | 10 +++++----- src/config_cache.c | 4 ++-- src/diff_driver.c | 2 +- src/index.c | 8 ++++---- src/repository.c | 24 ++++++++++++------------ src/runtime.c | 2 +- src/thread-utils.h | 22 ++++++++++++---------- src/util.h | 4 ++-- 8 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/attrcache.c b/src/attrcache.c index 47fb675e057..2485b05996c 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -108,7 +108,7 @@ static int attr_cache_upsert(git_attr_cache *cache, git_attr_file *file) * Replace the existing value if another thread has * created it in the meantime. */ - old = git__swap(entry->file[file->source], file); + old = git_atomic_swap(entry->file[file->source], file); if (old) { GIT_REFCOUNT_OWN(old, NULL); @@ -132,7 +132,7 @@ static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file) return error; if ((entry = attr_cache_lookup_entry(cache, file->entry->path)) != NULL) - old = git__compare_and_swap(&entry->file[file->source], file, NULL); + old = git_atomic_compare_and_swap(&entry->file[file->source], file, NULL); attr_cache_unlock(cache); @@ -321,7 +321,7 @@ static void attr_cache__free(git_attr_cache *cache) git_strmap_foreach_value(cache->files, entry, { for (i = 0; i < GIT_ATTR_FILE_NUM_SOURCES; ++i) { - if ((file = git__swap(entry->file[i], NULL)) != NULL) { + if ((file = git_atomic_swap(entry->file[i], NULL)) != NULL) { GIT_REFCOUNT_OWN(file, NULL); git_attr_file__free(file); } @@ -395,7 +395,7 @@ int git_attr_cache__init(git_repository *repo) (ret = git_pool_init(&cache->pool, 1)) < 0) goto cancel; - cache = git__compare_and_swap(&repo->attrcache, NULL, cache); + cache = git_atomic_compare_and_swap(&repo->attrcache, NULL, cache); if (cache) goto cancel; /* raced with another thread, free this but no error */ @@ -417,7 +417,7 @@ int git_attr_cache_flush(git_repository *repo) /* this could be done less expensively, but for now, we'll just free * the entire attrcache and let the next use reinitialize it... */ - if (repo && (cache = git__swap(repo->attrcache, NULL)) != NULL) + if (repo && (cache = git_atomic_swap(repo->attrcache, NULL)) != NULL) attr_cache__free(cache); return 0; diff --git a/src/config_cache.c b/src/config_cache.c index 1a28ba96c96..2f0455af9c7 100644 --- a/src/config_cache.c +++ b/src/config_cache.c @@ -111,7 +111,7 @@ int git_config__configmap_lookup(int *out, git_config *config, git_configmap_ite int git_repository__configmap_lookup(int *out, git_repository *repo, git_configmap_item item) { - *out = (int)(intptr_t)git__load(repo->configmap_cache[(int)item]); + *out = (int)(intptr_t)git_atomic_load(repo->configmap_cache[(int)item]); if (*out == GIT_CONFIGMAP_NOT_CACHED) { int error; @@ -122,7 +122,7 @@ int git_repository__configmap_lookup(int *out, git_repository *repo, git_configm (error = git_config__configmap_lookup(out, config, item)) < 0) return error; - git__compare_and_swap(&repo->configmap_cache[(int)item], &oldval, out); + git_atomic_compare_and_swap(&repo->configmap_cache[(int)item], &oldval, out); } return 0; diff --git a/src/diff_driver.c b/src/diff_driver.c index 606c391e4ac..6b19012c771 100644 --- a/src/diff_driver.c +++ b/src/diff_driver.c @@ -144,7 +144,7 @@ static git_diff_driver_registry *git_repository_driver_registry( { if (!repo->diff_drivers) { git_diff_driver_registry *reg = git_diff_driver_registry_new(); - reg = git__compare_and_swap(&repo->diff_drivers, NULL, reg); + reg = git_atomic_compare_and_swap(&repo->diff_drivers, NULL, reg); if (reg != NULL) /* if we race, free losing allocation */ git_diff_driver_registry_free(reg); diff --git a/src/index.c b/src/index.c index 942fcca26e2..7ebe0758239 100644 --- a/src/index.c +++ b/src/index.c @@ -495,7 +495,7 @@ static void index_free_deleted(git_index *index) return; for (i = 0; i < index->deleted.length; ++i) { - git_index_entry *ie = git__swap(index->deleted.contents[i], NULL); + git_index_entry *ie = git_atomic_swap(index->deleted.contents[i], NULL); index_entry_free(ie); } @@ -2295,7 +2295,7 @@ int git_index_reuc_clear(git_index *index) GIT_ASSERT_ARG(index); for (i = 0; i < index->reuc.length; ++i) - index_entry_reuc_free(git__swap(index->reuc.contents[i], NULL)); + index_entry_reuc_free(git_atomic_swap(index->reuc.contents[i], NULL)); git_vector_clear(&index->reuc); @@ -3197,7 +3197,7 @@ int git_index_read_tree(git_index *index, const git_tree *tree) /* well, this isn't good */; } else { git_vector_swap(&entries, &index->entries); - entries_map = git__swap(index->entries_map, entries_map); + entries_map = git_atomic_swap(index->entries_map, entries_map); } index->dirty = 1; @@ -3331,7 +3331,7 @@ static int git_index_read_iterator( goto done; git_vector_swap(&new_entries, &index->entries); - new_entries_map = git__swap(index->entries_map, new_entries_map); + new_entries_map = git_atomic_swap(index->entries_map, new_entries_map); git_vector_foreach(&remove_entries, i, entry) { if (index->tree) diff --git a/src/repository.c b/src/repository.c index bef84caafad..3b6bcbe866f 100644 --- a/src/repository.c +++ b/src/repository.c @@ -93,7 +93,7 @@ static void set_odb(git_repository *repo, git_odb *odb) GIT_REFCOUNT_INC(odb); } - if ((odb = git__swap(repo->_odb, odb)) != NULL) { + if ((odb = git_atomic_swap(repo->_odb, odb)) != NULL) { GIT_REFCOUNT_OWN(odb, NULL); git_odb_free(odb); } @@ -106,7 +106,7 @@ static void set_refdb(git_repository *repo, git_refdb *refdb) GIT_REFCOUNT_INC(refdb); } - if ((refdb = git__swap(repo->_refdb, refdb)) != NULL) { + if ((refdb = git_atomic_swap(repo->_refdb, refdb)) != NULL) { GIT_REFCOUNT_OWN(refdb, NULL); git_refdb_free(refdb); } @@ -119,7 +119,7 @@ static void set_config(git_repository *repo, git_config *config) GIT_REFCOUNT_INC(config); } - if ((config = git__swap(repo->_config, config)) != NULL) { + if ((config = git_atomic_swap(repo->_config, config)) != NULL) { GIT_REFCOUNT_OWN(config, NULL); git_config_free(config); } @@ -134,7 +134,7 @@ static void set_index(git_repository *repo, git_index *index) GIT_REFCOUNT_INC(index); } - if ((index = git__swap(repo->_index, index)) != NULL) { + if ((index = git_atomic_swap(repo->_index, index)) != NULL) { GIT_REFCOUNT_OWN(index, NULL); git_index_free(index); } @@ -1054,7 +1054,7 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo) if (!error) { GIT_REFCOUNT_OWN(config, repo); - config = git__compare_and_swap(&repo->_config, NULL, config); + config = git_atomic_compare_and_swap(&repo->_config, NULL, config); if (config != NULL) { GIT_REFCOUNT_OWN(config, NULL); git_config_free(config); @@ -1107,7 +1107,7 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo) GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(out); - *out = git__load(repo->_odb); + *out = git_atomic_load(repo->_odb); if (*out == NULL) { git_buf odb_path = GIT_BUF_INIT; git_odb *odb; @@ -1125,14 +1125,14 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo) return error; } - odb = git__compare_and_swap(&repo->_odb, NULL, odb); + odb = git_atomic_compare_and_swap(&repo->_odb, NULL, odb); if (odb != NULL) { GIT_REFCOUNT_OWN(odb, NULL); git_odb_free(odb); } git_buf_dispose(&odb_path); - *out = git__load(repo->_odb); + *out = git_atomic_load(repo->_odb); } return error; @@ -1170,7 +1170,7 @@ int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo) if (!error) { GIT_REFCOUNT_OWN(refdb, repo); - refdb = git__compare_and_swap(&repo->_refdb, NULL, refdb); + refdb = git_atomic_compare_and_swap(&repo->_refdb, NULL, refdb); if (refdb != NULL) { GIT_REFCOUNT_OWN(refdb, NULL); git_refdb_free(refdb); @@ -1218,7 +1218,7 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo) if (!error) { GIT_REFCOUNT_OWN(index, repo); - index = git__compare_and_swap(&repo->_index, NULL, index); + index = git_atomic_compare_and_swap(&repo->_index, NULL, index); if (index != NULL) { GIT_REFCOUNT_OWN(index, NULL); git_index_free(index); @@ -3044,8 +3044,8 @@ int git_repository_set_ident(git_repository *repo, const char *name, const char GIT_ERROR_CHECK_ALLOC(tmp_email); } - tmp_name = git__swap(repo->ident_name, tmp_name); - tmp_email = git__swap(repo->ident_email, tmp_email); + tmp_name = git_atomic_swap(repo->ident_name, tmp_name); + tmp_email = git_atomic_swap(repo->ident_email, tmp_email); git__free(tmp_name); git__free(tmp_email); diff --git a/src/runtime.c b/src/runtime.c index 3fd064982ee..b61c3c4ba3d 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -37,7 +37,7 @@ static void shutdown_common(void) for (pos = git_atomic32_get(&shutdown_callback_count); pos > 0; pos = git_atomic32_dec(&shutdown_callback_count)) { - cb = git__swap(shutdown_callback[pos - 1], NULL); + cb = git_atomic_swap(shutdown_callback[pos - 1], NULL); if (cb != NULL) cb(); diff --git a/src/thread-utils.h b/src/thread-utils.h index 31a4c09e324..9b511b650e0 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -139,7 +139,7 @@ GIT_INLINE(int) git_atomic32_get(git_atomic32 *a) #endif } -GIT_INLINE(void *) git___compare_and_swap( +GIT_INLINE(void *) git_atomic__compare_and_swap( void * volatile *ptr, void *oldval, void *newval) { #if defined(GIT_WIN32) @@ -158,7 +158,7 @@ GIT_INLINE(void *) git___compare_and_swap( #endif } -GIT_INLINE(volatile void *) git___swap( +GIT_INLINE(volatile void *) git_atomic__swap( void * volatile *ptr, void *newval) { #if defined(GIT_WIN32) @@ -174,7 +174,7 @@ GIT_INLINE(volatile void *) git___swap( #endif } -GIT_INLINE(volatile void *) git___load(void * volatile *ptr) +GIT_INLINE(volatile void *) git_atomic__load(void * volatile *ptr) { #if defined(GIT_WIN32) void *newval = NULL, *oldval = NULL; @@ -294,7 +294,7 @@ GIT_INLINE(int) git_atomic32_get(git_atomic32 *a) return (int)a->val; } -GIT_INLINE(void *) git___compare_and_swap( +GIT_INLINE(void *) git_atomic__compare_and_swap( void * volatile *ptr, void *oldval, void *newval) { if (*ptr == oldval) @@ -304,7 +304,7 @@ GIT_INLINE(void *) git___compare_and_swap( return oldval; } -GIT_INLINE(volatile void *) git___swap( +GIT_INLINE(volatile void *) git_atomic__swap( void * volatile *ptr, void *newval) { volatile void *old = *ptr; @@ -312,7 +312,7 @@ GIT_INLINE(volatile void *) git___swap( return old; } -GIT_INLINE(volatile void *) git___load(void * volatile *ptr) +GIT_INLINE(volatile void *) git_atomic__load(void * volatile *ptr) { return *ptr; } @@ -342,12 +342,14 @@ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a) /* Atomically replace oldval with newval * @return oldval if it was replaced or newval if it was not */ -#define git__compare_and_swap(P,O,N) \ - git___compare_and_swap((void * volatile *)P, O, N) +#define git_atomic_compare_and_swap(P,O,N) \ + git_atomic__compare_and_swap((void * volatile *)P, O, N) -#define git__swap(ptr, val) (void *)git___swap((void * volatile *)&ptr, val) +#define git_atomic_swap(ptr, val) \ + (void *)git_atomic__swap((void * volatile *)&ptr, val) -#define git__load(ptr) (void *)git___load((void * volatile *)&ptr) +#define git_atomic_load(ptr) \ + (void *)git_atomic__load((void * volatile *)&ptr) #if defined(GIT_THREADS) diff --git a/src/util.h b/src/util.h index 6c7c4c28413..b8ea68c5b62 100644 --- a/src/util.h +++ b/src/util.h @@ -186,10 +186,10 @@ typedef void (*git_refcount_freeptr)(void *r); } #define GIT_REFCOUNT_OWN(r, o) { \ - (void)git__swap((r)->rc.owner, o); \ + (void)git_atomic_swap((r)->rc.owner, o); \ } -#define GIT_REFCOUNT_OWNER(r) git__load((r)->rc.owner) +#define GIT_REFCOUNT_OWNER(r) git_atomic_load((r)->rc.owner) #define GIT_REFCOUNT_VAL(r) git_atomic32_get((r)->rc.refcount) From 404dd02443aebed284033e02ace8b791151aa7a9 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Dec 2020 15:57:48 +0000 Subject: [PATCH 0179/1616] threads: rename thread files to thread.[ch] --- src/cache.c | 2 +- src/cache.h | 2 +- src/common.h | 2 +- src/libgit2.c | 2 +- src/pack-objects.c | 2 +- src/sortedcache.h | 2 +- src/{thread-utils.h => thread.h} | 4 ++-- src/util.h | 2 +- tests/threads/thread_helpers.h | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) rename src/{thread-utils.h => thread.h} (99%) diff --git a/src/cache.c b/src/cache.c index dbd4c319a3a..2f68e357cbd 100644 --- a/src/cache.c +++ b/src/cache.c @@ -9,7 +9,7 @@ #include "repository.h" #include "commit.h" -#include "thread-utils.h" +#include "thread.h" #include "util.h" #include "odb.h" #include "object.h" diff --git a/src/cache.h b/src/cache.h index c43422d6fe7..42c4fa80d7f 100644 --- a/src/cache.h +++ b/src/cache.h @@ -13,7 +13,7 @@ #include "git2/oid.h" #include "git2/odb.h" -#include "thread-utils.h" +#include "thread.h" #include "oidmap.h" enum { diff --git a/src/common.h b/src/common.h index 2b1a4a4569c..a4ddcf90b3e 100644 --- a/src/common.h +++ b/src/common.h @@ -78,7 +78,7 @@ #include "git2/types.h" #include "git2/errors.h" #include "errors.h" -#include "thread-utils.h" +#include "thread.h" #include "integer.h" #include "assert_safe.h" diff --git a/src/libgit2.c b/src/libgit2.c index 9e5112dbf2a..e41988c8eb7 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -22,7 +22,7 @@ #include "refs.h" #include "runtime.h" #include "sysdir.h" -#include "thread-utils.h" +#include "thread.h" #include "threadstate.h" #include "git2/global.h" #include "streams/registry.h" diff --git a/src/pack-objects.c b/src/pack-objects.c index 81678537d0d..f9d8bfd35b0 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -12,7 +12,7 @@ #include "iterator.h" #include "netops.h" #include "pack.h" -#include "thread-utils.h" +#include "thread.h" #include "tree.h" #include "util.h" #include "revwalk.h" diff --git a/src/sortedcache.h b/src/sortedcache.h index e553d01dd6d..ca8b106743a 100644 --- a/src/sortedcache.h +++ b/src/sortedcache.h @@ -12,7 +12,7 @@ #include "util.h" #include "futils.h" #include "vector.h" -#include "thread-utils.h" +#include "thread.h" #include "pool.h" #include "strmap.h" diff --git a/src/thread-utils.h b/src/thread.h similarity index 99% rename from src/thread-utils.h rename to src/thread.h index 9b511b650e0..561e6ecc804 100644 --- a/src/thread-utils.h +++ b/src/thread.h @@ -4,8 +4,8 @@ * 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_thread_utils_h__ -#define INCLUDE_thread_utils_h__ +#ifndef INCLUDE_thread_h__ +#define INCLUDE_thread_h__ #if defined(GIT_THREADS) diff --git a/src/util.h b/src/util.h index b8ea68c5b62..5076df28201 100644 --- a/src/util.h +++ b/src/util.h @@ -18,7 +18,7 @@ #include "buffer.h" #include "common.h" #include "strnlen.h" -#include "thread-utils.h" +#include "thread.h" #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) #define bitsizeof(x) (CHAR_BIT * sizeof(x)) diff --git a/tests/threads/thread_helpers.h b/tests/threads/thread_helpers.h index 3c13cfb6bb4..0f23a4ce06d 100644 --- a/tests/threads/thread_helpers.h +++ b/tests/threads/thread_helpers.h @@ -1,4 +1,4 @@ -#include "thread-utils.h" +#include "thread.h" void run_in_parallel( int repeats, From 971b7187faa1260aab75c531d9c78b29cdba6cc4 Mon Sep 17 00:00:00 2001 From: Tyler Ang-Wanek Date: Thu, 6 Aug 2020 16:24:18 -0700 Subject: [PATCH 0180/1616] Implement generic TLS interface This adds a generic TLS interface for anyone to store TLS data. It is designed to work regardless of whether threading support is built into the library or not. Nobody in the library should directly interface with the data on the TLS struct, so it's been built to be opaque even in the library. Requires the allocator to be initialized before use. --- src/thread.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/thread.h | 48 ++++++++++++ 2 files changed, 261 insertions(+) create mode 100644 src/thread.c diff --git a/src/thread.c b/src/thread.c new file mode 100644 index 00000000000..d9ca374e911 --- /dev/null +++ b/src/thread.c @@ -0,0 +1,213 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "common.h" + +#ifndef GIT_THREADS + +struct git_tls_data { + void GIT_CALLBACK(free_fn)(void *payload); + void *storage; +}; + +int git_tls_data__init(git_tls_data **out, + void GIT_CALLBACK(free_fn)(void *storage)) +{ + struct git_tls_data *tls = git__malloc(sizeof(struct git_tls_data)); + GIT_ERROR_CHECK_ALLOC(tls); + + tls->storage = NULL; + tls->free_fn = free_fn; + *out = tls; + + return 0; +} + +int git_tls_data__set(git_tls_data *tls, void *payload) +{ + tls->storage = payload; + return 0; +} + +void *git_tls_data__get(git_tls_data *tls) +{ + return tls->storage; +} + +void git_tls_data__free(git_tls_data *tls) +{ + tls->free_fn(tls->storage); + git__free(tls); +} + +#elif defined(GIT_WIN32) + +struct git_tls_data { + void GIT_CALLBACK(free_fn)(void *payload); + DWORD fls_index; +}; + +struct git_tls_cell { + void GIT_CALLBACK(free_fn)(void *storage); + void *storage; +}; + +static void WINAPI git_tls_cell__free(void *sc) +{ + struct git_tls_cell *storage_cell = sc; + if (storage_cell == NULL) { + return; + } + + storage_cell->free_fn(storage_cell->storage); + git__free(storage_cell); +} + +int git_tls_data__init(git_tls_data **out, + void GIT_CALLBACK(free_fn)(void *payload)) +{ + struct git_tls_data *tls = git__malloc(sizeof(struct git_tls_data)); + GIT_ERROR_CHECK_ALLOC(tls); + + if ((tls->fls_index = FlsAlloc(git_tls_cell__free)) == FLS_OUT_OF_INDEXES) { + git__free(tls); + return -1; + } + + tls->free_fn = free_fn; + *out = tls; + + return 0; +} + +int git_tls_data__set(git_tls_data *tls, void *payload) +{ + struct git_tls_cell *storage_cell; + + if (payload == NULL) { + if ((storage_cell = FlsGetValue(tls->fls_index)) != NULL) + git_tls_cell__free(storage_cell); + + if (FlsSetValue(tls->fls_index, NULL) == 0) + return -1; + + return 0; + } + + storage_cell = git__malloc(sizeof(struct git_tls_cell)); + GIT_ERROR_CHECK_ALLOC(storage_cell); + + storage_cell->free_fn = tls->free_fn; + storage_cell->storage = payload; + + if (FlsSetValue(tls->fls_index, storage_cell) == 0) { + git__free(storage_cell); + return -1; + } + + return 0; +} + +void *git_tls_data__get(git_tls_data *tls) +{ + struct git_tls_cell *storage_cell = FlsGetValue(tls->fls_index); + if (storage_cell == NULL) + return NULL; + + return storage_cell->storage; +} + +void git_tls_data__free(git_tls_data *tls) +{ + FlsFree(tls->fls_index); + tls->free_fn = NULL; + git__free(tls); +} + +#elif defined(_POSIX_THREADS) + +struct git_tls_data { + void GIT_CALLBACK(free_fn)(void *payload); + pthread_key_t tls_key; +}; + +struct git_tls_cell { + void GIT_CALLBACK(free_fn)(void *storage); + void *storage; +}; + +static void git_tls_cell__free(void *sc) +{ + struct git_tls_cell *storage_cell = sc; + storage_cell->free_fn(storage_cell->storage); + git__free(storage_cell); +} + +int git_tls_data__init(git_tls_data **out, + void GIT_CALLBACK(free_fn)(void *payload)) +{ + struct git_tls_data *tls = git__malloc(sizeof(struct git_tls_data)); + GIT_ERROR_CHECK_ALLOC(tls); + + if (pthread_key_create(&tls->tls_key, git_tls_cell__free) != 0) { + git__free(tls); + return -1; + } + + tls->free_fn = free_fn; + *out = tls; + + return 0; +} + +int git_tls_data__set(git_tls_data *tls, void *payload) +{ + struct git_tls_cell *storage_cell; + + if (payload == NULL) { + if ((storage_cell = pthread_getspecific(tls->tls_key)) != NULL) + git_tls_cell__free(storage_cell); + + if (pthread_setspecific(tls->tls_key, NULL) != 0) + return -1; + + return 0; + } + + storage_cell = git__malloc(sizeof(struct git_tls_cell)); + GIT_ERROR_CHECK_ALLOC(storage_cell); + + storage_cell->free_fn = tls->free_fn; + storage_cell->storage = payload; + + if (pthread_setspecific(tls->tls_key, storage_cell) != 0) { + git__free(storage_cell); + return -1; + } + + return 0; +} + +void *git_tls_data__get(git_tls_data *tls) +{ + struct git_tls_cell *storage_cell = pthread_getspecific(tls->tls_key); + if (storage_cell == NULL) + return NULL; + + return storage_cell->storage; +} + +void git_tls_data__free(git_tls_data *tls) +{ + git_tls_data__set(tls, NULL); + pthread_key_delete(tls->tls_key); + git__free(tls); +} + +#else +# error unknown threading model +#endif diff --git a/src/thread.h b/src/thread.h index 561e6ecc804..6cdf7382b34 100644 --- a/src/thread.h +++ b/src/thread.h @@ -367,4 +367,52 @@ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a) #endif +/** + * An opaque structure for managing TLS in the library + */ +typedef struct git_tls_data git_tls_data; + +/** + * Initializes a thread local storage container. + * This has an implementation even without GIT_THREADS + * which just serves to encourage use of this where TLS + * is necessary. + * + * Do not call this before the allocator has been initialized. + * + * @param out a pointer to store the TLS container in + * @param free_fn the method that should be called when + * deleting something in the TLS. Will be + * registered as the clean up callback for + * the OS specific TLS construct. + * @return 0 on success, non-zero on failure + */ +int git_tls_data__init(git_tls_data **out, + void GIT_CALLBACK(free_fn)(void *payload)); + +/** + * Will set a thread specific value on the TLS. Passing NULL will free the + * currently held thread specific value. + * + * @param tls the TLS instance to store data on + * @param payload the pointer to store + * @return 0 on success, non-zero on failure + */ +int git_tls_data__set(git_tls_data *tls, void *payload); + +/** + * Will get the thread specific value stored in TLS. + * + * @param tls the TLS instance to retrieve data from + */ +void *git_tls_data__get(git_tls_data *tls); + +/** + * Must call this to clean up the TLS when no longer in use. + * The TLS pointer is unusable after a call to this. + * + * @param tls the TLS to free + */ +void git_tls_data__free(git_tls_data *tls); + #endif From 42d5f11084c67f8c96693bd42b424b0262be3f84 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 8 Dec 2020 14:33:31 +0000 Subject: [PATCH 0181/1616] win32: provide macros for calling conventions Provide more clarity for Win32 calling conventions - now that we always compile to __cdecl on Win32, we'll define that as the the libgit2 calling convention. Also offer NTAPI (__stdcall) calling conventions for things that need callbacks from NTAPI code (eg fiber-local storage). --- src/common.h | 4 +++- src/util.c | 2 +- src/win32/msvc-compat.h | 10 +++++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/common.h b/src/common.h index a4ddcf90b3e..bda3edbc17e 100644 --- a/src/common.h +++ b/src/common.h @@ -63,7 +63,9 @@ # include # include # endif -#define GIT_STDLIB_CALL + +#define GIT_LIBGIT2_CALL +#define GIT_SYSTEM_CALL #ifdef GIT_USE_STAT_ATIMESPEC # define st_atim st_atimespec diff --git a/src/util.c b/src/util.c index 18a02a265c2..87ccf32afdf 100644 --- a/src/util.c +++ b/src/util.c @@ -687,7 +687,7 @@ typedef struct { void *payload; } git__qsort_r_glue; -static int GIT_STDLIB_CALL git__qsort_r_glue_cmp( +static int GIT_LIBGIT2_CALL git__qsort_r_glue_cmp( void *payload, const void *a, const void *b) { git__qsort_r_glue *glue = payload; diff --git a/src/win32/msvc-compat.h b/src/win32/msvc-compat.h index 4cf471f1d3c..03f9f36dc92 100644 --- a/src/win32/msvc-compat.h +++ b/src/win32/msvc-compat.h @@ -23,6 +23,14 @@ typedef SSIZE_T ssize_t; #endif -#define GIT_STDLIB_CALL __cdecl +/* + * Offer GIT_LIBGIT2_CALL for our calling conventions (__cdecl, always). + * This is useful for providing callbacks to userspace code. + * + * Offer GIT_SYSTEM_CALL for the system calling conventions (__stdcall on + * Win32). Useful for providing callbacks to system libraries. + */ +#define GIT_LIBGIT2_CALL __cdecl +#define GIT_SYSTEM_CALL NTAPI #endif From fd2d4759ff7fb6ae038daef146fb7f5ba40c5e64 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Dec 2020 22:22:38 +0000 Subject: [PATCH 0182/1616] threads: git_tls_data to git_tlsdata Use a no-allocation approach to the TLS data abstraction. --- src/thread.c | 207 +++++++++++++--------------------------- src/thread.h | 60 ++++++------ tests/threads/tlsdata.c | 65 +++++++++++++ 3 files changed, 164 insertions(+), 168 deletions(-) create mode 100644 tests/threads/tlsdata.c diff --git a/src/thread.c b/src/thread.c index d9ca374e911..3171771d7f3 100644 --- a/src/thread.c +++ b/src/thread.c @@ -7,207 +7,134 @@ #include "common.h" -#ifndef GIT_THREADS +#if !defined(GIT_THREADS) -struct git_tls_data { - void GIT_CALLBACK(free_fn)(void *payload); - void *storage; -}; +#define TLSDATA_MAX 16 -int git_tls_data__init(git_tls_data **out, - void GIT_CALLBACK(free_fn)(void *storage)) +typedef struct { + void *value; + void (GIT_SYSTEM_CALL *destroy_fn)(void *); +} tlsdata_value; + +static tlsdata_value tlsdata_values[TLSDATA_MAX]; +static int tlsdata_cnt = 0; + +int git_tlsdata_init(git_tlsdata_key *key, void (GIT_SYSTEM_CALL *destroy_fn)(void *)) { - struct git_tls_data *tls = git__malloc(sizeof(struct git_tls_data)); - GIT_ERROR_CHECK_ALLOC(tls); + if (tlsdata_cnt >= TLSDATA_MAX) + return -1; - tls->storage = NULL; - tls->free_fn = free_fn; - *out = tls; + tlsdata_values[tlsdata_cnt].value = NULL; + tlsdata_values[tlsdata_cnt].destroy_fn = destroy_fn; + + *key = tlsdata_cnt; + tlsdata_cnt++; return 0; } -int git_tls_data__set(git_tls_data *tls, void *payload) +int git_tlsdata_set(git_tlsdata_key key, void *value) { - tls->storage = payload; + if (key < 0 || key > tlsdata_cnt) + return -1; + + tlsdata_values[key].value = value; return 0; } -void *git_tls_data__get(git_tls_data *tls) +void *git_tlsdata_get(git_tlsdata_key key) { - return tls->storage; + if (key < 0 || key > tlsdata_cnt) + return NULL; + + return tlsdata_values[key].value; } -void git_tls_data__free(git_tls_data *tls) +int git_tlsdata_dispose(git_tlsdata_key key) { - tls->free_fn(tls->storage); - git__free(tls); -} + void *value; + void (*destroy_fn)(void *) = NULL; -#elif defined(GIT_WIN32) + if (key < 0 || key > tlsdata_cnt) + return -1; -struct git_tls_data { - void GIT_CALLBACK(free_fn)(void *payload); - DWORD fls_index; -}; + value = tlsdata_values[key].value; + destroy_fn = tlsdata_values[key].destroy_fn; -struct git_tls_cell { - void GIT_CALLBACK(free_fn)(void *storage); - void *storage; -}; + tlsdata_values[key].value = NULL; + tlsdata_values[key].destroy_fn = NULL; -static void WINAPI git_tls_cell__free(void *sc) -{ - struct git_tls_cell *storage_cell = sc; - if (storage_cell == NULL) { - return; - } + if (value && destroy_fn) + destroy_fn(value); - storage_cell->free_fn(storage_cell->storage); - git__free(storage_cell); + return 0; } -int git_tls_data__init(git_tls_data **out, - void GIT_CALLBACK(free_fn)(void *payload)) +#elif defined(GIT_WIN32) + +int git_tlsdata_init(git_tlsdata_key *key, void (GIT_SYSTEM_CALL *destroy_fn)(void *)) { - struct git_tls_data *tls = git__malloc(sizeof(struct git_tls_data)); - GIT_ERROR_CHECK_ALLOC(tls); + DWORD fls_index = FlsAlloc(destroy_fn); - if ((tls->fls_index = FlsAlloc(git_tls_cell__free)) == FLS_OUT_OF_INDEXES) { - git__free(tls); + if (fls_index == FLS_OUT_OF_INDEXES) return -1; - } - - tls->free_fn = free_fn; - *out = tls; + *key = fls_index; return 0; } -int git_tls_data__set(git_tls_data *tls, void *payload) +int git_tlsdata_set(git_tlsdata_key key, void *value) { - struct git_tls_cell *storage_cell; - - if (payload == NULL) { - if ((storage_cell = FlsGetValue(tls->fls_index)) != NULL) - git_tls_cell__free(storage_cell); - - if (FlsSetValue(tls->fls_index, NULL) == 0) - return -1; - - return 0; - } - - storage_cell = git__malloc(sizeof(struct git_tls_cell)); - GIT_ERROR_CHECK_ALLOC(storage_cell); - - storage_cell->free_fn = tls->free_fn; - storage_cell->storage = payload; - - if (FlsSetValue(tls->fls_index, storage_cell) == 0) { - git__free(storage_cell); + if (!FlsSetValue(key, value)) return -1; - } return 0; } -void *git_tls_data__get(git_tls_data *tls) +void *git_tlsdata_get(git_tlsdata_key key) { - struct git_tls_cell *storage_cell = FlsGetValue(tls->fls_index); - if (storage_cell == NULL) - return NULL; - - return storage_cell->storage; + return FlsGetValue(key); } -void git_tls_data__free(git_tls_data *tls) +int git_tlsdata_dispose(git_tlsdata_key key) { - FlsFree(tls->fls_index); - tls->free_fn = NULL; - git__free(tls); + if (!FlsFree(key)) + return -1; + + return 0; } #elif defined(_POSIX_THREADS) -struct git_tls_data { - void GIT_CALLBACK(free_fn)(void *payload); - pthread_key_t tls_key; -}; - -struct git_tls_cell { - void GIT_CALLBACK(free_fn)(void *storage); - void *storage; -}; - -static void git_tls_cell__free(void *sc) +int git_tlsdata_init(git_tlsdata_key *key, void (GIT_SYSTEM_CALL *destroy_fn)(void *)) { - struct git_tls_cell *storage_cell = sc; - storage_cell->free_fn(storage_cell->storage); - git__free(storage_cell); -} - -int git_tls_data__init(git_tls_data **out, - void GIT_CALLBACK(free_fn)(void *payload)) -{ - struct git_tls_data *tls = git__malloc(sizeof(struct git_tls_data)); - GIT_ERROR_CHECK_ALLOC(tls); - - if (pthread_key_create(&tls->tls_key, git_tls_cell__free) != 0) { - git__free(tls); + if (pthread_key_create(key, destroy_fn) != 0) return -1; - } - - tls->free_fn = free_fn; - *out = tls; return 0; } -int git_tls_data__set(git_tls_data *tls, void *payload) +int git_tlsdata_set(git_tlsdata_key key, void *value) { - struct git_tls_cell *storage_cell; - - if (payload == NULL) { - if ((storage_cell = pthread_getspecific(tls->tls_key)) != NULL) - git_tls_cell__free(storage_cell); - - if (pthread_setspecific(tls->tls_key, NULL) != 0) - return -1; - - return 0; - } - - storage_cell = git__malloc(sizeof(struct git_tls_cell)); - GIT_ERROR_CHECK_ALLOC(storage_cell); - - storage_cell->free_fn = tls->free_fn; - storage_cell->storage = payload; - - if (pthread_setspecific(tls->tls_key, storage_cell) != 0) { - git__free(storage_cell); + if (pthread_setspecific(key, value) != 0) return -1; - } return 0; } -void *git_tls_data__get(git_tls_data *tls) +void *git_tlsdata_get(git_tlsdata_key key) { - struct git_tls_cell *storage_cell = pthread_getspecific(tls->tls_key); - if (storage_cell == NULL) - return NULL; - - return storage_cell->storage; + return pthread_getspecific(key); } -void git_tls_data__free(git_tls_data *tls) +int git_tlsdata_dispose(git_tlsdata_key key) { - git_tls_data__set(tls, NULL); - pthread_key_delete(tls->tls_key); - git__free(tls); + if (pthread_key_delete(key) != 0) + return -1; + + return 0; } #else -# error unknown threading model +# error unknown threading model #endif diff --git a/src/thread.h b/src/thread.h index 6cdf7382b34..b4f869243e9 100644 --- a/src/thread.h +++ b/src/thread.h @@ -367,52 +367,56 @@ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a) #endif -/** - * An opaque structure for managing TLS in the library - */ -typedef struct git_tls_data git_tls_data; +/* Thread-local data */ + +#if !defined(GIT_THREADS) +# define git_tlsdata_key int +#elif defined(GIT_WIN32) +# define git_tlsdata_key DWORD +#elif defined(_POSIX_THREADS) +# define git_tlsdata_key pthread_key_t +#else +# error unknown threading model +#endif /** - * Initializes a thread local storage container. - * This has an implementation even without GIT_THREADS - * which just serves to encourage use of this where TLS - * is necessary. + * Create a thread-local data key. The destroy function will be + * called upon thread exit. On some platforms, it may be called + * when all threads have deleted their keys. * - * Do not call this before the allocator has been initialized. + * Note that the tlsdata functions do not set an error message on + * failure; this is because the error handling in libgit2 is itself + * handled by thread-local data storage. * - * @param out a pointer to store the TLS container in - * @param free_fn the method that should be called when - * deleting something in the TLS. Will be - * registered as the clean up callback for - * the OS specific TLS construct. + * @param key the tlsdata key + * @param destroy_fn function pointer called upon thread exit * @return 0 on success, non-zero on failure */ -int git_tls_data__init(git_tls_data **out, - void GIT_CALLBACK(free_fn)(void *payload)); +int git_tlsdata_init(git_tlsdata_key *key, void (GIT_SYSTEM_CALL *destroy_fn)(void *)); /** - * Will set a thread specific value on the TLS. Passing NULL will free the - * currently held thread specific value. + * Set a the thread-local value for the given key. * - * @param tls the TLS instance to store data on - * @param payload the pointer to store + * @param key the tlsdata key to store data on + * @param value the pointer to store * @return 0 on success, non-zero on failure */ -int git_tls_data__set(git_tls_data *tls, void *payload); +int git_tlsdata_set(git_tlsdata_key key, void *value); /** - * Will get the thread specific value stored in TLS. + * Get the thread-local value for the given key. * - * @param tls the TLS instance to retrieve data from + * @param key the tlsdata key to retrieve the value of + * @return the pointer stored with git_tlsdata_set */ -void *git_tls_data__get(git_tls_data *tls); +void *git_tlsdata_get(git_tlsdata_key key); /** - * Must call this to clean up the TLS when no longer in use. - * The TLS pointer is unusable after a call to this. + * Delete the given thread-local key. * - * @param tls the TLS to free + * @param key the tlsdata key to dispose + * @return 0 on success, non-zero on failure */ -void git_tls_data__free(git_tls_data *tls); +int git_tlsdata_dispose(git_tlsdata_key key); #endif diff --git a/tests/threads/tlsdata.c b/tests/threads/tlsdata.c new file mode 100644 index 00000000000..7c69b444427 --- /dev/null +++ b/tests/threads/tlsdata.c @@ -0,0 +1,65 @@ +#include "clar_libgit2.h" + +#include "thread_helpers.h" + +void test_threads_tlsdata__can_set_and_get(void) +{ + git_tlsdata_key key_one, key_two, key_three; + + cl_git_pass(git_tlsdata_init(&key_one, NULL)); + cl_git_pass(git_tlsdata_init(&key_two, NULL)); + cl_git_pass(git_tlsdata_init(&key_three, NULL)); + + cl_git_pass(git_tlsdata_set(key_one, (void *)(size_t)42424242)); + cl_git_pass(git_tlsdata_set(key_two, (void *)(size_t)0xdeadbeef)); + cl_git_pass(git_tlsdata_set(key_three, (void *)(size_t)98761234)); + + cl_assert_equal_sz((size_t)42424242, git_tlsdata_get(key_one)); + cl_assert_equal_sz((size_t)0xdeadbeef, git_tlsdata_get(key_two)); + cl_assert_equal_sz((size_t)98761234, git_tlsdata_get(key_three)); + + cl_git_pass(git_tlsdata_dispose(key_one)); + cl_git_pass(git_tlsdata_dispose(key_two)); + cl_git_pass(git_tlsdata_dispose(key_three)); +} + +#ifdef GIT_THREADS + +static void *set_and_get(void *param) +{ + git_tlsdata_key *tlsdata_key = (git_tlsdata_key *)param; + int val; + + if (git_tlsdata_set(*tlsdata_key, &val) != 0 || + git_tlsdata_get(*tlsdata_key) != &val) + return (void *)0; + + return (void *)1; +} + +#endif + +#define THREAD_COUNT 10 + +void test_threads_tlsdata__threads(void) +{ +#ifdef GIT_THREADS + git_thread thread[THREAD_COUNT]; + git_tlsdata_key tlsdata; + int i; + + cl_git_pass(git_tlsdata_init(&tlsdata, NULL)); + + for (i = 0; i < THREAD_COUNT; i++) + cl_git_pass(git_thread_create(&thread[i], set_and_get, &tlsdata)); + + for (i = 0; i < THREAD_COUNT; i++) { + void *result; + + cl_git_pass(git_thread_join(&thread[i], &result)); + cl_assert_equal_sz(1, (size_t)result); + } + + cl_git_pass(git_tlsdata_dispose(tlsdata)); +#endif +} From 20ce17f06d27a92ada11fa5d15108532223e9884 Mon Sep 17 00:00:00 2001 From: Tyler Ang-Wanek Date: Thu, 6 Aug 2020 16:24:27 -0700 Subject: [PATCH 0183/1616] Replace global storage TLS with new interface --- src/threadstate.c | 102 +++++++--------------------------------------- 1 file changed, 15 insertions(+), 87 deletions(-) diff --git a/src/threadstate.c b/src/threadstate.c index 1c5ac60917f..6031e8280ff 100644 --- a/src/threadstate.c +++ b/src/threadstate.c @@ -8,8 +8,6 @@ #include "threadstate.h" #include "runtime.h" -static void threadstate_dispose(git_threadstate *threadstate); - /** * Handle the thread-local state * @@ -17,8 +15,7 @@ static void threadstate_dispose(git_threadstate *threadstate); * of `git_libgit2_init` (which itself must be called * before calling any other function in the library). * - * This function allocates a TLS index (using pthreads - * or fiber-local storage in Win32) to store the per- + * This function allocates a TLS index to store the per- * thread state. * * Any internal method that requires thread-local state @@ -30,77 +27,41 @@ static void threadstate_dispose(git_threadstate *threadstate); * (`git_threadstate_global_shutdown`) which will free the * TLS index. This shutdown handler will be called by * `git_libgit2_shutdown`. - * - * If libgit2 is built without threading support, the - * `git_threadstate_get()` call returns a pointer to a single, - * statically allocated global state. The `git_thread_` - * functions are not available in that case. */ -#if defined(GIT_THREADS) && defined(GIT_WIN32) +static git_tlsdata_key tls_key; -static DWORD fls_index; - -static void git_threadstate_global_shutdown(void) +static void threadstate_dispose(git_threadstate *threadstate) { - FlsFree(fls_index); + if (!threadstate) + return; + + git__free(threadstate->error_t.message); + threadstate->error_t.message = NULL; } -static void WINAPI fls_free(void *threadstate) +static void GIT_SYSTEM_CALL threadstate_free(void *threadstate) { threadstate_dispose(threadstate); git__free(threadstate); } -int git_threadstate_global_init(void) -{ - if ((fls_index = FlsAlloc(fls_free)) == FLS_OUT_OF_INDEXES) - return -1; - - return git_runtime_shutdown_register(git_threadstate_global_shutdown); -} - -git_threadstate *git_threadstate_get(void) -{ - git_threadstate *threadstate; - - if ((threadstate = FlsGetValue(fls_index)) != NULL) - return threadstate; - - if ((threadstate = git__calloc(1, sizeof(git_threadstate))) == NULL || - git_buf_init(&threadstate->error_buf, 0) < 0) - return NULL; - - FlsSetValue(fls_index, threadstate); - return threadstate; -} - -#elif defined(GIT_THREADS) && defined(_POSIX_THREADS) - -static pthread_key_t tls_key; - static void git_threadstate_global_shutdown(void) { git_threadstate *threadstate; - threadstate = pthread_getspecific(tls_key); - pthread_setspecific(tls_key, NULL); + threadstate = git_tlsdata_get(tls_key); + git_tlsdata_set(tls_key, NULL); threadstate_dispose(threadstate); git__free(threadstate); - pthread_key_delete(tls_key); -} - -static void tls_free(void *threadstate) -{ - threadstate_dispose(threadstate); - git__free(threadstate); + git_tlsdata_dispose(tls_key); } int git_threadstate_global_init(void) { - if (pthread_key_create(&tls_key, &tls_free) != 0) + if (git_tlsdata_init(&tls_key, &threadstate_free) != 0) return -1; return git_runtime_shutdown_register(git_threadstate_global_shutdown); @@ -110,46 +71,13 @@ git_threadstate *git_threadstate_get(void) { git_threadstate *threadstate; - if ((threadstate = pthread_getspecific(tls_key)) != NULL) + if ((threadstate = git_tlsdata_get(tls_key)) != NULL) return threadstate; if ((threadstate = git__calloc(1, sizeof(git_threadstate))) == NULL || git_buf_init(&threadstate->error_buf, 0) < 0) return NULL; - pthread_setspecific(tls_key, threadstate); + git_tlsdata_set(tls_key, threadstate); return threadstate; } - -#elif defined(GIT_THREADS) -# error unknown threading model -#else - -static git_threadstate threadstate; - -static void git_threadstate_global_shutdown(void) -{ - threadstate_dispose(&threadstate); - memset(&threadstate, 0, sizeof(git_threadstate)); -} - -int git_threadstate_global_init(void) -{ - return git_runtime_shutdown_register(git_threadstate_global_shutdown); -} - -git_threadstate *git_threadstate_get(void) -{ - return &threadstate; -} - -#endif - -static void threadstate_dispose(git_threadstate *threadstate) -{ - if (!threadstate) - return; - - git__free(threadstate->error_t.message); - threadstate->error_t.message = NULL; -} From 6c51014db6699b21a39641d4a5c01d76d1f1d8f5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 11 Jul 2020 14:24:17 +0100 Subject: [PATCH 0184/1616] libgit2: provide init_count of the library A function to provide the initialization count of the library; this is subject to race conditions but is useful for a naive determination as to whether the library has been initialized or not. --- src/libgit2.c | 5 +++++ src/libgit2.h | 2 ++ src/runtime.c | 15 +++++++++++++++ src/runtime.h | 9 +++++++++ 4 files changed, 31 insertions(+) diff --git a/src/libgit2.c b/src/libgit2.c index e41988c8eb7..f27c9997dce 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -90,6 +90,11 @@ int git_libgit2_init(void) return git_runtime_init(init_fns, ARRAY_SIZE(init_fns)); } +int git_libgit2_init_count(void) +{ + return git_runtime_init_count(); +} + int git_libgit2_shutdown(void) { return git_runtime_shutdown(); diff --git a/src/libgit2.h b/src/libgit2.h index 6f92a8318bd..a898367ae37 100644 --- a/src/libgit2.h +++ b/src/libgit2.h @@ -7,6 +7,8 @@ #ifndef INCLUDE_libgit2_h__ #define INCLUDE_libgit2_h__ +extern int git_libgit2_init_count(void); + extern const char *git_libgit2__user_agent(void); extern const char *git_libgit2__ssl_ciphers(void); diff --git a/src/runtime.c b/src/runtime.c index b61c3c4ba3d..c05dee8b96d 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -127,6 +127,21 @@ int git_runtime_init(git_runtime_init_fn init_fns[], size_t cnt) return ret; } +int git_runtime_init_count(void) +{ + int ret; + + if (init_lock() < 0) + return -1; + + ret = git_atomic32_get(&init_count); + + if (init_unlock() < 0) + return -1; + + return ret; +} + int git_runtime_shutdown(void) { int ret; diff --git a/src/runtime.h b/src/runtime.h index be2e37a6016..2cbcafe529d 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -28,6 +28,15 @@ typedef void (*git_runtime_shutdown_fn)(void); */ int git_runtime_init(git_runtime_init_fn init_fns[], size_t cnt); +/* + * Returns the number of initializations active (the number of calls to + * `git_runtime_init` minus the number of calls sto `git_runtime_shutdown`). + * If 0, the runtime is not currently initialized. + * + * @return The number of initializations performed or an error + */ +int git_runtime_init_count(void); + /** * Shut down the runtime. If this is the last shutdown call, * such that there are no remaining `init` calls, then any From 08f28ff50e3f6fabcc1469fdf4a53c3a3a33eff4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 10 Jul 2020 08:57:05 +0100 Subject: [PATCH 0185/1616] alloc: set up an allocator that fails before library init We require the library to be initialized with git_libgit2_init before it is functional. However, if a user tries to uses the library without doing so - as they might when getting started with the library for the first time - we will likely crash. This commit introduces some guard rails - now instead of having _no_ allocator by default, we'll have an allocator that always fails, and never tries to set an error message (since the thread-local state is set up by git_libgit2_init). We've modified the error retrieval function to (try to) ensure that the library has been initialized before getting the thread-local error message. (Unfortunately, we cannot determine if the thread local storage has actually been configured, this does require initialization by git_libgit2_init. But a naive attempt should be good enough for most cases.) --- src/alloc.c | 20 +++++++-- src/allocators/failalloc.c | 92 ++++++++++++++++++++++++++++++++++++++ src/allocators/failalloc.h | 23 ++++++++++ src/errors.c | 10 +++++ 4 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 src/allocators/failalloc.c create mode 100644 src/allocators/failalloc.h diff --git a/src/alloc.c b/src/alloc.c index 6efa104cafe..2820d84a219 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -8,10 +8,22 @@ #include "alloc.h" #include "runtime.h" +#include "allocators/failalloc.h" #include "allocators/stdalloc.h" #include "allocators/win32_leakcheck.h" -git_allocator git__allocator; +/* Fail any allocation until git_libgit2_init is called. */ +git_allocator git__allocator = { + git_failalloc_malloc, + git_failalloc_calloc, + git_failalloc_strdup, + git_failalloc_strndup, + git_failalloc_substrdup, + git_failalloc_realloc, + git_failalloc_reallocarray, + git_failalloc_mallocarray, + git_failalloc_free +}; static int setup_default_allocator(void) { @@ -25,10 +37,10 @@ static int setup_default_allocator(void) int git_allocator_global_init(void) { /* - * We don't want to overwrite any allocator which has been set before - * the init function is called. + * We don't want to overwrite any allocator which has been set + * before the init function is called. */ - if (git__allocator.gmalloc != NULL) + if (git__allocator.gmalloc != git_failalloc_malloc) return 0; return setup_default_allocator(); diff --git a/src/allocators/failalloc.c b/src/allocators/failalloc.c new file mode 100644 index 00000000000..5257d1dece0 --- /dev/null +++ b/src/allocators/failalloc.c @@ -0,0 +1,92 @@ +/* + * 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 "failalloc.h" + +void *git_failalloc_malloc(size_t len, const char *file, int line) +{ + GIT_UNUSED(len); + GIT_UNUSED(file); + GIT_UNUSED(line); + + return NULL; +} + +void *git_failalloc_calloc(size_t nelem, size_t elsize, const char *file, int line) +{ + GIT_UNUSED(nelem); + GIT_UNUSED(elsize); + GIT_UNUSED(file); + GIT_UNUSED(line); + + return NULL; +} + +char *git_failalloc_strdup(const char *str, const char *file, int line) +{ + GIT_UNUSED(str); + GIT_UNUSED(file); + GIT_UNUSED(line); + + return NULL; +} + +char *git_failalloc_strndup(const char *str, size_t n, const char *file, int line) +{ + GIT_UNUSED(str); + GIT_UNUSED(n); + GIT_UNUSED(file); + GIT_UNUSED(line); + + return NULL; +} + +char *git_failalloc_substrdup(const char *start, size_t n, const char *file, int line) +{ + GIT_UNUSED(start); + GIT_UNUSED(n); + GIT_UNUSED(file); + GIT_UNUSED(line); + + return NULL; +} + +void *git_failalloc_realloc(void *ptr, size_t size, const char *file, int line) +{ + GIT_UNUSED(ptr); + GIT_UNUSED(size); + GIT_UNUSED(file); + GIT_UNUSED(line); + + return NULL; +} + +void *git_failalloc_reallocarray(void *ptr, size_t nelem, size_t elsize, const char *file, int line) +{ + GIT_UNUSED(ptr); + GIT_UNUSED(nelem); + GIT_UNUSED(elsize); + GIT_UNUSED(file); + GIT_UNUSED(line); + + return NULL; +} + +void *git_failalloc_mallocarray(size_t nelem, size_t elsize, const char *file, int line) +{ + GIT_UNUSED(nelem); + GIT_UNUSED(elsize); + GIT_UNUSED(file); + GIT_UNUSED(line); + + return NULL; +} + +void git_failalloc_free(void *ptr) +{ + GIT_UNUSED(ptr); +} diff --git a/src/allocators/failalloc.h b/src/allocators/failalloc.h new file mode 100644 index 00000000000..6115e51e78f --- /dev/null +++ b/src/allocators/failalloc.h @@ -0,0 +1,23 @@ +/* + * 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_allocators_failalloc_h__ +#define INCLUDE_allocators_failalloc_h__ + +#include "common.h" + +extern void *git_failalloc_malloc(size_t len, const char *file, int line); +extern void *git_failalloc_calloc(size_t nelem, size_t elsize, const char *file, int line); +extern char *git_failalloc_strdup(const char *str, const char *file, int line); +extern char *git_failalloc_strndup(const char *str, size_t n, const char *file, int line); +extern char *git_failalloc_substrdup(const char *start, size_t n, const char *file, int line); +extern void *git_failalloc_realloc(void *ptr, size_t size, const char *file, int line); +extern void *git_failalloc_reallocarray(void *ptr, size_t nelem, size_t elsize, const char *file, int line); +extern void *git_failalloc_mallocarray(size_t nelem, size_t elsize, const char *file, int line); +extern void git_failalloc_free(void *ptr); + +#endif diff --git a/src/errors.c b/src/errors.c index 5b68dd9cbf0..3d1d1c9a116 100644 --- a/src/errors.c +++ b/src/errors.c @@ -10,6 +10,7 @@ #include "threadstate.h" #include "posix.h" #include "buffer.h" +#include "libgit2.h" /******************************************** * New error handling @@ -20,6 +21,11 @@ static git_error g_git_oom_error = { GIT_ERROR_NOMEMORY }; +static git_error g_git_uninitialized_error = { + "libgit2 has not been initialized; you must call git_libgit2_init", + GIT_ERROR_INVALID +}; + static void set_error_from_buffer(int error_class) { git_error *error = &GIT_THREADSTATE->error_t; @@ -131,6 +137,10 @@ void git_error_clear(void) const git_error *git_error_last(void) { + /* If the library is not initialized, return a static error. */ + if (!git_libgit2_init_count()) + return &g_git_uninitialized_error; + return GIT_THREADSTATE->last_error; } From 5bce48412437192945277a3aadda7c975fe737db Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Wed, 9 Dec 2020 21:47:42 +0100 Subject: [PATCH 0186/1616] git.git-authors: Replacing his/her with their --- git.git-authors | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git.git-authors b/git.git-authors index 905bdd24fa2..d9a911419a6 100644 --- a/git.git-authors +++ b/git.git-authors @@ -25,9 +25,9 @@ # contributed code (possibly with some exceptions) # "no" means the author does not consent # "ask" means that the contributor wants to give/withhold -# his/her consent on a patch-by-patch basis. +# their consent on a patch-by-patch basis. # "???" means the person is a prominent contributor who has -# not yet made his/her standpoint clear. +# not yet made their standpoint clear. # # Please try to keep the list alphabetically ordered. It will # help in case we get all 600-ish git.git authors on it. From 41da4e16eb01a7bb19c52bbc4251963be192ba69 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Thu, 10 Dec 2020 19:52:01 -0800 Subject: [PATCH 0187/1616] Cache the parsed submodule config when diffing This change makes that anything that calls `git_diff__from_iterators` (any of the `git_diff_xxx` functions) only need to parse the `.gitmodules` file once. This can be avoided by calling `git_repository_submodule_cache_all(...)`, but we can do that safely for the user with no change in semantics. Fixes: #5725 --- src/diff_generate.c | 37 ++++++++++++++++++++++++++++++++++--- src/submodule.c | 13 +++++++++++-- src/submodule.h | 6 +++--- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/diff_generate.c b/src/diff_generate.c index 745e5ae1bd8..bc7c2665868 100644 --- a/src/diff_generate.c +++ b/src/diff_generate.c @@ -680,6 +680,8 @@ typedef struct { git_iterator *new_iter; const git_index_entry *oitem; const git_index_entry *nitem; + git_strmap *submodule_cache; + bool submodule_cache_initialized; } diff_in_progress; #define MODE_BITS_MASK 0000777 @@ -694,6 +696,7 @@ static int maybe_modified_submodule( git_submodule *sub; unsigned int sm_status = 0; git_submodule_ignore_t ign = diff->base.opts.ignore_submodules; + git_strmap *submodule_cache = NULL; *status = GIT_DELTA_UNMODIFIED; @@ -701,8 +704,29 @@ static int maybe_modified_submodule( ign == GIT_SUBMODULE_IGNORE_ALL) return 0; - if ((error = git_submodule_lookup( - &sub, diff->base.repo, info->nitem->path)) < 0) { + if (diff->base.repo->submodule_cache != NULL) { + submodule_cache = diff->base.repo->submodule_cache; + } else { + if (!info->submodule_cache_initialized) { + info->submodule_cache_initialized = true; + /* Cache the submodule information to avoid having to parse it for every submodule. */ + if (git_strmap_new(&info->submodule_cache) == 0) { + if (git_submodule__map(diff->base.repo, info->submodule_cache) < 0) { + /* If the caching failed for whatever reason, bail out and clean up. */ + git_submodule *sm = NULL; + git_strmap_foreach_value(info->submodule_cache, sm, { + git_submodule_free(sm); + }); + git_strmap_free(info->submodule_cache); + info->submodule_cache = NULL; + } + } + } + submodule_cache = info->submodule_cache; + } + + if ((error = git_submodule__lookup_with_cache( + &sub, diff->base.repo, info->nitem->path, submodule_cache)) < 0) { /* GIT_EEXISTS means dir with .git in it was found - ignore it */ if (error == GIT_EEXISTS) { @@ -1192,7 +1216,7 @@ int git_diff__from_iterators( const git_diff_options *opts) { git_diff_generated *diff; - diff_in_progress info; + diff_in_progress info = {0}; int error = 0; *out = NULL; @@ -1260,6 +1284,13 @@ int git_diff__from_iterators( *out = &diff->base; else git_diff_free(&diff->base); + if (info.submodule_cache) { + git_submodule *sm = NULL; + git_strmap_foreach_value(info.submodule_cache, sm, { + git_submodule_free(sm); + }); + git_strmap_free(info.submodule_cache); + } return error; } diff --git a/src/submodule.c b/src/submodule.c index 0c901fa6fd8..3bbdeed2547 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -253,6 +253,15 @@ int git_submodule_lookup( git_submodule **out, /* NULL if user only wants to test existence */ git_repository *repo, const char *name) /* trailing slash is allowed */ +{ + return git_submodule__lookup_with_cache(out, repo, name, repo->submodule_cache); +} + +int git_submodule__lookup_with_cache( + git_submodule **out, /* NULL if user only wants to test existence */ + git_repository *repo, + const char *name, /* trailing slash is allowed */ + git_strmap *cache) { int error; unsigned int location; @@ -266,8 +275,8 @@ int git_submodule_lookup( return -1; } - if (repo->submodule_cache != NULL) { - if ((sm = git_strmap_get(repo->submodule_cache, name)) != NULL) { + if (cache != NULL) { + if ((sm = git_strmap_get(cache, name)) != NULL) { if (out) { *out = sm; GIT_REFCOUNT_INC(*out); diff --git a/src/submodule.h b/src/submodule.h index 57d95c3fc8d..f32f818ea4f 100644 --- a/src/submodule.h +++ b/src/submodule.h @@ -122,9 +122,9 @@ enum { #define GIT_SUBMODULE_STATUS__CLEAR_INTERNAL(S) \ ((S) & ~(0xFFFFFFFFu << 20)) -/* Internal lookup does not attempt to refresh cached data */ -extern int git_submodule__lookup( - git_submodule **out, git_repository *repo, const char *path); +/* Submodule lookup with an explicit cache */ +extern int git_submodule__lookup_with_cache( + git_submodule **out, git_repository *repo, const char *path, git_strmap *cache); /* Internal status fn returns status and optionally the various OIDs */ extern int git_submodule__status( From 6cd0c8534d81509a330b09f619fe3249f1d121d2 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Fri, 11 Dec 2020 05:08:45 -0800 Subject: [PATCH 0188/1616] Small refactor to make thing tidier Also repurposed an unused function and deleted another one. --- src/diff_generate.c | 27 ++++++++------------------- src/repository.c | 22 ++++------------------ src/submodule.c | 28 ++++++++++++++++++++++++++++ src/submodule.h | 12 ++++++------ 4 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/diff_generate.c b/src/diff_generate.c index bc7c2665868..f05ae37133b 100644 --- a/src/diff_generate.c +++ b/src/diff_generate.c @@ -709,18 +709,12 @@ static int maybe_modified_submodule( } else { if (!info->submodule_cache_initialized) { info->submodule_cache_initialized = true; - /* Cache the submodule information to avoid having to parse it for every submodule. */ - if (git_strmap_new(&info->submodule_cache) == 0) { - if (git_submodule__map(diff->base.repo, info->submodule_cache) < 0) { - /* If the caching failed for whatever reason, bail out and clean up. */ - git_submodule *sm = NULL; - git_strmap_foreach_value(info->submodule_cache, sm, { - git_submodule_free(sm); - }); - git_strmap_free(info->submodule_cache); - info->submodule_cache = NULL; - } - } + /* + * Try to cache the submodule information to avoid having to parse it for + * every submodule. It is okay if it fails, the cache will still be NULL + * and the submodules will be attempted to be looked up individually. + */ + git_submodule_cache_init(&info->submodule_cache, diff->base.repo); } submodule_cache = info->submodule_cache; } @@ -1284,13 +1278,8 @@ int git_diff__from_iterators( *out = &diff->base; else git_diff_free(&diff->base); - if (info.submodule_cache) { - git_submodule *sm = NULL; - git_strmap_foreach_value(info.submodule_cache, sm, { - git_submodule_free(sm); - }); - git_strmap_free(info.submodule_cache); - } + if (info.submodule_cache) + git_submodule_cache_free(info.submodule_cache); return error; } diff --git a/src/repository.c b/src/repository.c index 3b6bcbe866f..3a54f8c44a4 100644 --- a/src/repository.c +++ b/src/repository.c @@ -3055,30 +3055,16 @@ int git_repository_set_ident(git_repository *repo, const char *name, const char int git_repository_submodule_cache_all(git_repository *repo) { - int error; - GIT_ASSERT_ARG(repo); - - if ((error = git_strmap_new(&repo->submodule_cache))) - return error; - - error = git_submodule__map(repo, repo->submodule_cache); - return error; + return git_submodule_cache_init(&repo->submodule_cache, repo); } int git_repository_submodule_cache_clear(git_repository *repo) { - git_submodule *sm; - + int error = 0; GIT_ASSERT_ARG(repo); - if (repo->submodule_cache == NULL) { - return 0; - } - git_strmap_foreach_value(repo->submodule_cache, sm, { - git_submodule_free(sm); - }); - git_strmap_free(repo->submodule_cache); - repo->submodule_cache = 0; + error = git_submodule_cache_free(repo->submodule_cache); + repo->submodule_cache = NULL; return 0; } diff --git a/src/submodule.c b/src/submodule.c index 3bbdeed2547..50bde2c63e7 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -249,6 +249,34 @@ static int load_submodule_names(git_strmap **out, git_repository *repo, git_conf return error; } +int git_submodule_cache_init(git_strmap **out, git_repository *repo) +{ + int error = 0; + git_strmap *cache = NULL; + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + if ((error = git_strmap_new(&cache)) < 0) + return error; + if ((error = git_submodule__map(repo, cache)) < 0) { + git_submodule_cache_free(cache); + return error; + } + *out = cache; + return error; +} + +int git_submodule_cache_free(git_strmap *cache) +{ + git_submodule *sm = NULL; + if (cache == NULL) + return 0; + git_strmap_foreach_value(cache, sm, { + git_submodule_free(sm); + }); + git_strmap_free(cache); + return 0; +} + int git_submodule_lookup( git_submodule **out, /* NULL if user only wants to test existence */ git_repository *repo, diff --git a/src/submodule.h b/src/submodule.h index f32f818ea4f..b01ff68a203 100644 --- a/src/submodule.h +++ b/src/submodule.h @@ -101,12 +101,6 @@ struct git_submodule { git_oid wd_oid; }; -/* Force revalidation of submodule data cache (alloc as needed) */ -extern int git_submodule_cache_refresh(git_repository *repo); - -/* Release all submodules */ -extern void git_submodule_cache_free(git_repository *repo); - /* Additional flags on top of public GIT_SUBMODULE_STATUS values */ enum { GIT_SUBMODULE_STATUS__WD_SCANNED = (1u << 20), @@ -122,6 +116,12 @@ enum { #define GIT_SUBMODULE_STATUS__CLEAR_INTERNAL(S) \ ((S) & ~(0xFFFFFFFFu << 20)) +/* Initialize an external submodule cache for the provided repo. */ +extern int git_submodule_cache_init(git_strmap **out, git_repository *repo); + +/* Release the resources of the submodule cache. */ +extern int git_submodule_cache_free(git_strmap *cache); + /* Submodule lookup with an explicit cache */ extern int git_submodule__lookup_with_cache( git_submodule **out, git_repository *repo, const char *path, git_strmap *cache); From 58d757b1d36f5744e969852a54d34990a44c6389 Mon Sep 17 00:00:00 2001 From: Jason Haslam Date: Mon, 14 Nov 2016 16:52:33 -0700 Subject: [PATCH 0189/1616] patch: add owner accessor --- include/git2/patch.h | 8 ++++++++ src/patch.c | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/include/git2/patch.h b/include/git2/patch.h index b177798e6a5..fde9659e713 100644 --- a/include/git2/patch.h +++ b/include/git2/patch.h @@ -28,6 +28,14 @@ GIT_BEGIN_DECL */ typedef struct git_patch git_patch; +/** + * Get the repository associated with this patch. May be NULL. + * + * @param patch the patch + * @return a pointer to the repository + */ +GIT_EXTERN(git_repository *) git_patch_owner(const git_patch *patch); + /** * Return a patch for an entry in the diff list. * diff --git a/src/patch.c b/src/patch.c index 8f8bd7a08e3..f02c928de25 100644 --- a/src/patch.c +++ b/src/patch.c @@ -204,6 +204,11 @@ int git_patch_get_line_in_hunk( return 0; } +git_repository *git_patch_owner(const git_patch *patch) +{ + return patch->repo; +} + int git_patch_from_diff(git_patch **out, git_diff *diff, size_t idx) { GIT_ASSERT_ARG(out); From 1ab2f577bc070dd7d59cdce6d35b268f3a77fd0d Mon Sep 17 00:00:00 2001 From: lhchavez Date: Fri, 11 Dec 2020 05:13:16 -0800 Subject: [PATCH 0190/1616] Fix an oops --- src/repository.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/repository.c b/src/repository.c index 3a54f8c44a4..948413d17b2 100644 --- a/src/repository.c +++ b/src/repository.c @@ -3066,5 +3066,5 @@ int git_repository_submodule_cache_clear(git_repository *repo) error = git_submodule_cache_free(repo->submodule_cache); repo->submodule_cache = NULL; - return 0; + return error; } From e99e833f4808e027de8e984b9b99544ca41e28e2 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sat, 12 Dec 2020 16:51:15 -0800 Subject: [PATCH 0191/1616] Make git__strntol64() ~70%* faster This change uses compiler intrinsics to detect overflows instead of using divisions to detect potential overflow. This makes the code faster and makes it easier to read as a bonus side-effect! Some of the things this quickens: * Config parsing. * Tree parsing. * Smart protocol negotiation. \* Measured by running `libgit2_clar` with `-fno-optimize-sibling-calls -fno-omit-frame-pointer` under `perf(1)`: ```shell $ perf diff --symbols=git__strntol64 --compute=ratio \ --percentage=absolute baseline.data perf.data \# Event 'cycles' \# \# Baseline Ratio Shared Object \# ........ .............. ............. \# 0.25% 0.321836 libgit2_clar ``` --- src/integer.h | 31 +++++++++++++++++++++++++++++++ src/util.c | 14 +++----------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/integer.h b/src/integer.h index 067c0be1fcd..026a1fac0cc 100644 --- a/src/integer.h +++ b/src/integer.h @@ -77,6 +77,11 @@ GIT_INLINE(int) git__is_int(long long p) # define git__sub_int_overflow(out, one, two) \ __builtin_ssub_overflow(one, two, out) +# define git__add_int64_overflow(out, one, two) \ + __builtin_add_overflow(one, two, out) +# define git__multiply_int64_overflow(out, one, two) \ + __builtin_mul_overflow(one, two, out) + /* Use Microsoft's safe integer handling functions where available */ #elif defined(_MSC_VER) @@ -87,11 +92,17 @@ GIT_INLINE(int) git__is_int(long long p) (SizeTAdd(one, two, out) != S_OK) # define git__multiply_sizet_overflow(out, one, two) \ (SizeTMult(one, two, out) != S_OK) + #define git__add_int_overflow(out, one, two) \ (IntAdd(one, two, out) != S_OK) #define git__sub_int_overflow(out, one, two) \ (IntSub(one, two, out) != S_OK) +#define git__add_int64_overflow(out, one, two) \ + (LongLongAdd(one, two, out) != S_OK) +#define git__multiply_int64_overflow(out, one, two) \ + (LongLongMult(one, two, out) != S_OK) + #else /** @@ -136,6 +147,26 @@ GIT_INLINE(bool) git__sub_int_overflow(int *out, int one, int two) return false; } +GIT_INLINE(bool) git__add_int64_overflow(int64_t *out, int64_t one, int64_t two) +{ + if ((two > 0 && one > (INT64_MAX - two)) || + (two < 0 && one < (INT64_MIN - two))) + return true; + *out = one + two; + return false; +} + +GIT_INLINE(bool) git__multiply_int64_overflow(int64_t *out, int64_t one, int64_t two) +{ + if ((one == -1 && two == INT_MIN) || + (two == -1 && one == INT_MIN) || + (one && INT64_MAX / one < two) || + (one && INT64_MIN / one > two)) + return true; + *out = one * two; + return false; +} + #endif #endif diff --git a/src/util.c b/src/util.c index 87ccf32afdf..af825e4d252 100644 --- a/src/util.c +++ b/src/util.c @@ -34,8 +34,8 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const char **endptr, int base) { const char *p; - int64_t n, nn; - int c, ovfl, v, neg, ndig; + int64_t n, nn, v; + int c, ovfl, neg, ndig; p = nptr; neg = 0; @@ -110,19 +110,11 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha if (v >= base) break; v = neg ? -v : v; - if (n > INT64_MAX / base || n < INT64_MIN / base) { + if (git__multiply_int64_overflow(&nn, n, base) || git__add_int64_overflow(&n, nn, v)) { ovfl = 1; /* Keep on iterating until the end of this number */ continue; } - nn = n * base; - if ((v > 0 && nn > INT64_MAX - v) || - (v < 0 && nn < INT64_MIN - v)) { - ovfl = 1; - /* Keep on iterating until the end of this number */ - continue; - } - n = nn + v; } Return: From 21fe183e1c5a9d4b39af8d76a8825c3d2ab61fe6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 13 Dec 2020 13:21:11 +0000 Subject: [PATCH 0192/1616] README: show v1.1 build status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b66d190d72c..9bbdeaf3baf 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ libgit2 - the Git linkable library | Build Status | | | ------------ | - | | **master** branch CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush) | +| **v1.1 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.1&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.1) | | **v1.0 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v1.0)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v1.0) | -| **v0.28 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v0.28)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v0.28) | | **Nightly** builds | [![Nightly Build](https://github.com/libgit2/libgit2/workflows/Nightly%20Build/badge.svg)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22Nightly+Build%22) [![Coverity Scan Status](https://scan.coverity.com/projects/639/badge.svg)](https://scan.coverity.com/projects/639) | `libgit2` is a portable, pure C implementation of the Git core methods From 89ffa98eacde35b045b16586be196dc2ca89ab0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 18 Nov 2017 15:51:08 +0100 Subject: [PATCH 0193/1616] badssl: re-enable RC4 test This used to fail with an error indicating a mis-use of OpenSSL on platforms using it due to poor error handling. Re-enable it even if this isn't the right error code to use for now. --- tests/online/badssl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/online/badssl.c b/tests/online/badssl.c index 6524fcd8eee..ffd4ef12604 100644 --- a/tests/online/badssl.c +++ b/tests/online/badssl.c @@ -67,9 +67,6 @@ void test_online_badssl__old_cipher(void) git_clone_options opts = GIT_CLONE_OPTIONS_INIT; opts.fetch_opts.callbacks.certificate_check = cert_check_assert_invalid; - /* FIXME: we don't actually reject RC4 anywhere, figure out what to tweak */ - cl_skip(); - if (!g_has_ssl) cl_skip(); From 589b8129e065b0bcfdbb7c4eee815b6e149218bc Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 14 Dec 2020 10:43:07 +0000 Subject: [PATCH 0194/1616] badssl: RC4 should not fail with ECERTIFICATE Using RC4 is not a _certificate_ problem, it's a cipher problem. The SSL implementation should and will fail with an unrecoverable error (-1). There's no opportunity to accept/continue. --- tests/online/badssl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/online/badssl.c b/tests/online/badssl.c index ffd4ef12604..6735e9cdb31 100644 --- a/tests/online/badssl.c +++ b/tests/online/badssl.c @@ -70,8 +70,6 @@ void test_online_badssl__old_cipher(void) if (!g_has_ssl) cl_skip(); - cl_git_fail_with(GIT_ECERTIFICATE, - git_clone(&g_repo, "https://rc4.badssl.com/fake.git", "./fake", NULL)); - cl_git_fail_with(GIT_ECERTIFICATE, - git_clone(&g_repo, "https://rc4.badssl.com/fake.git", "./fake", &opts)); + cl_git_fail(git_clone(&g_repo, "https://rc4.badssl.com/fake.git", "./fake", NULL)); + cl_git_fail(git_clone(&g_repo, "https://rc4.badssl.com/fake.git", "./fake", &opts)); } From 93f61c5a9f638e76189cef2dbde7839a9af5ff54 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 15 Dec 2020 23:03:03 +0000 Subject: [PATCH 0195/1616] pack: continue zlib while we can make progress Continue the zlib stream as long as we can make progress; stop when we stop getting output _or_ when zlib stops taking input from us. --- src/pack.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/pack.c b/src/pack.c index a9140c63dd1..30b1464b6a3 100644 --- a/src/pack.c +++ b/src/pack.c @@ -908,7 +908,7 @@ static int packfile_unpack_compressed( do { size_t bytes = buffer_len - total; - unsigned int window_len; + unsigned int window_len, consumed; unsigned char *in; if ((in = pack_window_open(p, mwindow, *position, &window_len)) == NULL) { @@ -924,10 +924,15 @@ static int packfile_unpack_compressed( git_mwindow_close(mwindow); - if (!bytes) - break; + consumed = window_len - (unsigned int)zstream.in_len; + + if (!bytes && !consumed) { + git_error_set(GIT_ERROR_ZLIB, "error inflating zlib stream"); + error = -1; + goto out; + } - *position += window_len - zstream.in_len; + *position += consumed; total += bytes; } while (!git_zstream_eos(&zstream)); From 7d1c5d692703aae1a9acb18cf956c897da11ed59 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Nov 2020 00:30:05 +0000 Subject: [PATCH 0196/1616] ci: run codeql --- .github/workflows/codeql.yml | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000000..cd370957f79 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,39 @@ +name: "CodeQL" + +on: + push: + branches: [ master, maint/* ] + pull_request: + branches: [ master, maint/* ] + schedule: + - cron: '21 3 * * 1' + +env: + docker-registry: docker.pkg.github.com + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + steps: + - name: Check out repository + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: 'cpp' + + - name: Build + run: | + mkdir build + cd build + cmake .. -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON + cmake --build . + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 7f8ae01913e408bf219ab41036bd68265596c917 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Fri, 18 Dec 2020 07:03:21 -0800 Subject: [PATCH 0197/1616] Avoid using `__builtin_mul_overflow` with the clang+32-bit combo This causes clang to produce an undefined reference to `__mulodi4`. This could be fixed by statically linking some compiler-rt libraries to provide this symbol, but let's first stop the bleeding since doing the correct long-term fix requires some non-trivial CMake knowledge which I lack. --- src/integer.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/integer.h b/src/integer.h index 026a1fac0cc..28122a99f62 100644 --- a/src/integer.h +++ b/src/integer.h @@ -79,8 +79,12 @@ GIT_INLINE(int) git__is_int(long long p) # define git__add_int64_overflow(out, one, two) \ __builtin_add_overflow(one, two, out) -# define git__multiply_int64_overflow(out, one, two) \ - __builtin_mul_overflow(one, two, out) + +/* clang on 32-bit systems produces an undefined reference to `__mulodi4`. */ +# if !defined(__clang__) || !defined(GIT_ARCH_32) +# define git__multiply_int64_overflow(out, one, two) \ + __builtin_mul_overflow(one, two, out) +# endif /* Use Microsoft's safe integer handling functions where available */ #elif defined(_MSC_VER) @@ -156,6 +160,10 @@ GIT_INLINE(bool) git__add_int64_overflow(int64_t *out, int64_t one, int64_t two) return false; } +#endif + +/* If we could not provide an intrinsic implementation for this, provide a (slow) fallback. */ +#if !defined(git__multiply_int64_overflow) GIT_INLINE(bool) git__multiply_int64_overflow(int64_t *out, int64_t one, int64_t two) { if ((one == -1 && two == INT_MIN) || @@ -166,7 +174,6 @@ GIT_INLINE(bool) git__multiply_int64_overflow(int64_t *out, int64_t one, int64_t *out = one * two; return false; } - #endif #endif From be85c7e8e5510b5b4f7930e0f8b0b0238b297947 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 18 Dec 2020 15:11:12 +0000 Subject: [PATCH 0198/1616] ci: only run codeql nightly --- .github/workflows/codeql.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index cd370957f79..38b4a044a6f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,10 +1,7 @@ name: "CodeQL" on: - push: - branches: [ master, maint/* ] - pull_request: - branches: [ master, maint/* ] + workflow_dispatch: schedule: - cron: '21 3 * * 1' From e9b98cd53089077cb3c547b6f3870c51e3b128cc Mon Sep 17 00:00:00 2001 From: lhchavez Date: Fri, 18 Dec 2020 19:43:13 -0800 Subject: [PATCH 0199/1616] Third attempt to fix the 32-bit version of `git__multiply_int64_overflow` This change should now fix the issue for realsies. `./libgit2_clar -score::strtol` passes on a 32-bit Docker. --- src/integer.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/integer.h b/src/integer.h index 28122a99f62..724e076a0a4 100644 --- a/src/integer.h +++ b/src/integer.h @@ -166,11 +166,18 @@ GIT_INLINE(bool) git__add_int64_overflow(int64_t *out, int64_t one, int64_t two) #if !defined(git__multiply_int64_overflow) GIT_INLINE(bool) git__multiply_int64_overflow(int64_t *out, int64_t one, int64_t two) { - if ((one == -1 && two == INT_MIN) || - (two == -1 && one == INT_MIN) || - (one && INT64_MAX / one < two) || - (one && INT64_MIN / one > two)) + if ((one == -1 && two == INT64_MIN) || + (two == -1 && one == INT64_MIN)) return true; + if (one && two) { + if (one > 0 == two > 0) { + if (INT64_MAX / one < two) + return true; + } else { + if (INT64_MIN / one < two) + return true; + } + } *out = one * two; return false; } From 5ab0736bef1a2e9ed15d6f5edbc81393bb7b63cf Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sat, 19 Dec 2020 09:30:26 -0800 Subject: [PATCH 0200/1616] Add tests for `git__multiply_int64_overflow` As it turns out, the implementation of `git__multiply_int64_overflow` is full of edge cases and tricky arithmetic. That means that it should have unit tests. As a result, a bug in `git__strntol64` was found (and fixed!) in clang+32-bit. --- src/integer.h | 42 ++++++- tests/core/integer.c | 253 +++++++++++++++++++++++++++++++++++++++++++ tests/core/strtol.c | 2 + 3 files changed, 292 insertions(+), 5 deletions(-) create mode 100644 tests/core/integer.c diff --git a/src/integer.h b/src/integer.h index 724e076a0a4..a3a0f53ee11 100644 --- a/src/integer.h +++ b/src/integer.h @@ -166,15 +166,47 @@ GIT_INLINE(bool) git__add_int64_overflow(int64_t *out, int64_t one, int64_t two) #if !defined(git__multiply_int64_overflow) GIT_INLINE(bool) git__multiply_int64_overflow(int64_t *out, int64_t one, int64_t two) { - if ((one == -1 && two == INT64_MIN) || - (two == -1 && one == INT64_MIN)) - return true; + /* + * Detects whether `INT64_MAX < (one * two) || INT64_MIN > (one * two)`, + * without incurring in undefined behavior. That is done by performing the + * comparison with a division instead of a multiplication, which translates + * to `INT64_MAX / one < two || INT64_MIN / one > two`. Some caveats: + * + * - The comparison sign is inverted when both sides of the inequality are + * multiplied/divided by a negative number, so if `one < 0` the comparison + * needs to be flipped. + * - `INT64_MAX / -1` itself overflows (or traps), so that case should be + * avoided. + * - Since the overflow flag is defined as the discrepance between the result + * of performing the multiplication in a signed integer at twice the width + * of the operands, and the truncated+sign-extended version of that same + * result, there are four cases where the result is the opposite of what + * would be expected: + * * `INT64_MIN * -1` / `-1 * INT64_MIN` + * * `INT64_MIN * 1 / `1 * INT64_MIN` + */ if (one && two) { - if (one > 0 == two > 0) { + if (one > 0 && two > 0) { if (INT64_MAX / one < two) return true; + } else if (one < 0 && two < 0) { + if ((one == -1 && two == INT64_MIN) || + (two == -1 && one == INT64_MIN)) { + *out = INT64_MIN; + return false; + } + if (INT64_MAX / one > two) + return true; + } else if (one > 0 && two < 0) { + if ((one == 1 && two == INT64_MIN) || + (INT64_MIN / one > two)) + return true; + } else if (one == -1) { + if (INT64_MIN / two > one) + return true; } else { - if (INT64_MIN / one < two) + if ((one == INT64_MIN && two == 1) || + (INT64_MIN / one < two)) return true; } } diff --git a/tests/core/integer.c b/tests/core/integer.c new file mode 100644 index 00000000000..bd19651afe3 --- /dev/null +++ b/tests/core/integer.c @@ -0,0 +1,253 @@ +#include "clar_libgit2.h" + +void test_core_integer__multiply_int64_no_overflow(void) +{ +#if !defined(git__multiply_int64_overflow) + int64_t result = 0; + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x1ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x1ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x2ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x2ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x800000000000000ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x800000000000000ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x7fffffffffffffffll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x7fffffffffffffffll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x8000000000000000ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x1ll)); + cl_assert_equal_i(result, 0x1ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x1ll)); + cl_assert_equal_i(result, -0x1ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x2ll)); + cl_assert_equal_i(result, 0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x2ll)); + cl_assert_equal_i(result, -0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x7ffffffffffffffll)); + cl_assert_equal_i(result, -0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x800000000000000ll)); + cl_assert_equal_i(result, 0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x800000000000000ll)); + cl_assert_equal_i(result, -0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x7fffffffffffffffll)); + cl_assert_equal_i(result, 0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x7fffffffffffffffll)); + cl_assert_equal_i(result, -0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x1ll)); + cl_assert_equal_i(result, -0x1ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x1ll)); + cl_assert_equal_i(result, 0x1ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x2ll)); + cl_assert_equal_i(result, -0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x2ll)); + cl_assert_equal_i(result, 0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x7ffffffffffffffll)); + cl_assert_equal_i(result, -0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x800000000000000ll)); + cl_assert_equal_i(result, -0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x800000000000000ll)); + cl_assert_equal_i(result, 0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x7fffffffffffffffll)); + cl_assert_equal_i(result, -0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x7fffffffffffffffll)); + cl_assert_equal_i(result, 0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x1ll)); + cl_assert_equal_i(result, 0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x1ll)); + cl_assert_equal_i(result, -0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x2ll)); + cl_assert_equal_i(result, 0x4ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x2ll)); + cl_assert_equal_i(result, -0x4ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x7ffffffffffffffll)); + cl_assert_equal_i(result, -0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x800000000000000ll)); + cl_assert_equal_i(result, 0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x800000000000000ll)); + cl_assert_equal_i(result, -0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x1ll)); + cl_assert_equal_i(result, -0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x1ll)); + cl_assert_equal_i(result, 0x2ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x2ll)); + cl_assert_equal_i(result, -0x4ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x2ll)); + cl_assert_equal_i(result, 0x4ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x7ffffffffffffffll)); + cl_assert_equal_i(result, -0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x7ffffffffffffffll)); + cl_assert_equal_i(result, 0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x800000000000000ll)); + cl_assert_equal_i(result, -0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x800000000000000ll)); + cl_assert_equal_i(result, 0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x4000000000000000ll)); + cl_assert_equal_i(result, -0x8000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x1ll)); + cl_assert_equal_i(result, 0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x1ll)); + cl_assert_equal_i(result, -0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x2ll)); + cl_assert_equal_i(result, 0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x2ll)); + cl_assert_equal_i(result, -0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x1ll)); + cl_assert_equal_i(result, -0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x1ll)); + cl_assert_equal_i(result, 0x7ffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x2ll)); + cl_assert_equal_i(result, -0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x2ll)); + cl_assert_equal_i(result, 0xffffffffffffffell); + cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x1ll)); + cl_assert_equal_i(result, 0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x1ll)); + cl_assert_equal_i(result, -0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x2ll)); + cl_assert_equal_i(result, 0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x2ll)); + cl_assert_equal_i(result, -0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x1ll)); + cl_assert_equal_i(result, -0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x1ll)); + cl_assert_equal_i(result, 0x800000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x2ll)); + cl_assert_equal_i(result, -0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x2ll)); + cl_assert_equal_i(result, 0x1000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x1ll)); + cl_assert_equal_i(result, 0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x1ll)); + cl_assert_equal_i(result, -0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x4000000000000000ll, 0x2ll)); + cl_assert_equal_i(result, -0x8000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x1ll)); + cl_assert_equal_i(result, -0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x1ll)); + cl_assert_equal_i(result, 0x7fffffffffffffffll); + cl_assert(!git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x0ll)); + cl_assert_equal_i(result, 0x0ll); +#endif +} + +void test_core_integer__multiply_int64_overflow(void) +{ +#if !defined(git__multiply_int64_overflow) + int64_t result = 0; + cl_assert(git__multiply_int64_overflow(&result, 0x2ll, 0x4000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x2ll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x2ll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x2ll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x2ll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x2ll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x2ll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x4000000000000000ll, 0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x2ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x7ffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x800000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x7fffffffffffffffll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x8000000000000000ll)); +#endif +} + +void test_core_integer__multiply_int64_edge_cases(void) +{ +#if !defined(git__multiply_int64_overflow) + int64_t result = 0; + cl_assert(!git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x1ll)); + cl_assert_equal_i(result, -0x8000000000000000ll); + cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x8000000000000000ll)); + cl_assert_equal_i(result, -0x8000000000000000ll); + cl_assert(git__multiply_int64_overflow(&result, 0x1ll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x1ll)); +#endif +} diff --git a/tests/core/strtol.c b/tests/core/strtol.c index 25dbe467c1d..cac6ca56bb7 100644 --- a/tests/core/strtol.c +++ b/tests/core/strtol.c @@ -30,6 +30,7 @@ void test_core_strtol__int32(void) { assert_l32_parses("123", 123, 10); assert_l32_parses(" +123 ", 123, 10); + assert_l32_parses(" -123 ", -123, 10); assert_l32_parses(" +2147483647 ", 2147483647, 10); assert_l32_parses(" -2147483648 ", -2147483648LL, 10); assert_l32_parses("A", 10, 16); @@ -46,6 +47,7 @@ void test_core_strtol__int64(void) { assert_l64_parses("123", 123, 10); assert_l64_parses(" +123 ", 123, 10); + assert_l64_parses(" -123 ", -123, 10); assert_l64_parses(" +2147483647 ", 2147483647, 10); assert_l64_parses(" -2147483648 ", -2147483648LL, 10); assert_l64_parses(" 2147483657 ", 2147483657LL, 10); From f52f593eb6b2fdbca8e8ca216d9cecf64322c59d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 20 Dec 2020 16:33:42 +0000 Subject: [PATCH 0201/1616] repository: use intptr_t's in the config map cache Since we're using atomic primitives to read and write into the config map cache, we need to read/write something pointer-sized. Use an `intptr_t` for the config map cache. --- src/repository.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/repository.h b/src/repository.h index 4b1222e3a03..c0a28242aa8 100644 --- a/src/repository.h +++ b/src/repository.h @@ -154,7 +154,7 @@ struct git_repository { git_atomic32 attr_session_key; - git_configmap_value configmap_cache[GIT_CONFIGMAP_CACHE_MAX]; + intptr_t configmap_cache[GIT_CONFIGMAP_CACHE_MAX]; git_strmap *submodule_cache; }; From 1b70868324d63b84991f7d3a17a998d1731566fd Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 20 Dec 2020 20:42:40 +0000 Subject: [PATCH 0202/1616] config_cache: cleanup config map lookup --- src/config_cache.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/config_cache.c b/src/config_cache.c index 2f0455af9c7..37617af387b 100644 --- a/src/config_cache.c +++ b/src/config_cache.c @@ -111,18 +111,21 @@ int git_config__configmap_lookup(int *out, git_config *config, git_configmap_ite int git_repository__configmap_lookup(int *out, git_repository *repo, git_configmap_item item) { - *out = (int)(intptr_t)git_atomic_load(repo->configmap_cache[(int)item]); + intptr_t value = (intptr_t)git_atomic_load(repo->configmap_cache[(int)item]); - if (*out == GIT_CONFIGMAP_NOT_CACHED) { - int error; - int oldval = GIT_CONFIGMAP_NOT_CACHED; + *out = (int)value; + + if (value == GIT_CONFIGMAP_NOT_CACHED) { git_config *config; + intptr_t oldval = value; + int error; if ((error = git_repository_config__weakptr(&config, repo)) < 0 || (error = git_config__configmap_lookup(out, config, item)) < 0) return error; - git_atomic_compare_and_swap(&repo->configmap_cache[(int)item], &oldval, out); + value = *out; + git_atomic_compare_and_swap(&repo->configmap_cache[(int)item], (void *)oldval, (void *)value); } return 0; From 212ae9a70eddf3a77783d5cdffd3418273bfedd7 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Mon, 21 Dec 2020 06:48:48 -0800 Subject: [PATCH 0203/1616] Fix the `-DENABLE_WERROR=ON` build for gcc 10.2 This change makes it possible to build with newer versions of gcc without warnings. There were two warnings issued: * gcc 8 added [`-Wstringop-truncation`](https://developers.redhat.com/blog/2018/05/24/detecting-string-truncation-with-gcc-8/), which warns if a call to `strncpy(3)` is prone to accidentally truncating the destination string, since `strncpy(3)` does NOT add a terminating `NULL` if the destination buffer is not large enough to hold the input. This change uses the pattern suggested in https://us-cert.cisa.gov/bsi/articles/knowledge/coding-practices/strncpy-and-strncat to fix the locations flagged by gcc. * There was a potentially uninitialized access of `dest` in `fs_copy`. --- tests/clar/fs.h | 2 +- tests/clar/sandbox.h | 11 +++++++---- tests/clar_libgit2.c | 7 ++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/clar/fs.h b/tests/clar/fs.h index 31a53642787..d88f249c7c7 100644 --- a/tests/clar/fs.h +++ b/tests/clar/fs.h @@ -396,7 +396,7 @@ static void fs_copy(const char *source, const char *_dest) { char *dbuf = NULL; - const char *dest; + const char *dest = NULL; struct stat source_st, dest_st; cl_must_pass_(lstat(source, &source_st), "Failed to stat copy source"); diff --git a/tests/clar/sandbox.h b/tests/clar/sandbox.h index 2114819e4e7..0ba1479620a 100644 --- a/tests/clar/sandbox.h +++ b/tests/clar/sandbox.h @@ -2,7 +2,7 @@ #include #endif -static char _clar_path[4096]; +static char _clar_path[4096 + 1]; static int is_valid_tmp_path(const char *path) @@ -39,7 +39,8 @@ find_tmp_path(char *buffer, size_t length) if (length >= PATH_MAX && realpath(env, buffer) != NULL) return 0; #endif - strncpy(buffer, env, length); + strncpy(buffer, env, length - 1); + buffer[length - 1] = '\0'; return 0; } } @@ -50,7 +51,8 @@ find_tmp_path(char *buffer, size_t length) if (length >= PATH_MAX && realpath("/tmp", buffer) != NULL) return 0; #endif - strncpy(buffer, "/tmp", length); + strncpy(buffer, "/tmp", length - 1); + buffer[length - 1] = '\0'; return 0; } @@ -65,7 +67,8 @@ find_tmp_path(char *buffer, size_t length) /* This system doesn't like us, try to use the current directory */ if (is_valid_tmp_path(".")) { - strncpy(buffer, ".", length); + strncpy(buffer, ".", length - 1); + buffer[length - 1] = '\0'; return 0; } diff --git a/tests/clar_libgit2.c b/tests/clar_libgit2.c index 65b8923f5cd..c4550c32a8b 100644 --- a/tests/clar_libgit2.c +++ b/tests/clar_libgit2.c @@ -275,7 +275,7 @@ const char* cl_git_fixture_url(const char *fixturename) const char* cl_git_path_url(const char *path) { - static char url[4096]; + static char url[4096 + 1]; const char *in_buf; git_buf path_buf = GIT_BUF_INIT; @@ -311,9 +311,10 @@ const char* cl_git_path_url(const char *path) in_buf++; } - cl_assert(url_buf.size < 4096); + cl_assert(url_buf.size < sizeof(url) - 1); - strncpy(url, git_buf_cstr(&url_buf), 4096); + strncpy(url, git_buf_cstr(&url_buf), sizeof(url) - 1); + url[sizeof(url) - 1] = '\0'; git_buf_dispose(&url_buf); git_buf_dispose(&path_buf); return url; From ed7b20e72d0710f329fcfd05001c0c57d424aa09 Mon Sep 17 00:00:00 2001 From: Miguel Arroz <750683+arroz@users.noreply.github.com> Date: Mon, 21 Dec 2020 17:26:34 -0800 Subject: [PATCH 0204/1616] Add support for additional hostkey types. Specifically: ECDSA_256, ECDSA_384, ECDSA_521 and ED25519. --- include/git2/cert.h | 8 ++++++++ src/transports/ssh.c | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/git2/cert.h b/include/git2/cert.h index 07ae8c9f938..f111b136e30 100644 --- a/include/git2/cert.h +++ b/include/git2/cert.h @@ -91,6 +91,14 @@ typedef enum { GIT_CERT_SSH_RAW_TYPE_RSA = 1, /** The raw key is a DSS key. */ GIT_CERT_SSH_RAW_TYPE_DSS = 2, + /** The raw key is a ECDSA 256 key. */ + GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256 = 3, + /** The raw key is a ECDSA 384 key. */ + GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_384 = 4, + /** The raw key is a ECDSA 521 key. */ + GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521 = 5, + /** The raw key is a ED25519 key. */ + GIT_CERT_SSH_RAW_TYPE_KEY_ED25519 = 6 } git_cert_ssh_raw_type_t; /** diff --git a/src/transports/ssh.c b/src/transports/ssh.c index c33c08af1bb..38274240aef 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -580,6 +580,18 @@ static int _git_ssh_setup_conn( case LIBSSH2_HOSTKEY_TYPE_DSS: cert.raw_type = GIT_CERT_SSH_RAW_TYPE_DSS; break; + case LIBSSH2_HOSTKEY_TYPE_ECDSA_256: + cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256; + break; + case LIBSSH2_HOSTKEY_TYPE_ECDSA_384: + cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_384; + break; + case LIBSSH2_KNOWNHOST_KEY_ECDSA_521: + cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521; + break; + case LIBSSH2_HOSTKEY_TYPE_ED25519: + cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ED25519; + break; default: cert.raw_type = GIT_CERT_SSH_RAW_TYPE_UNKNOWN; } From 3433acd905647b496311986960f13a9998bd1ee5 Mon Sep 17 00:00:00 2001 From: Miguel Arroz <750683+arroz@users.noreply.github.com> Date: Mon, 21 Dec 2020 21:27:58 -0800 Subject: [PATCH 0205/1616] Wrap newer hostkeys in #ifdefs This allows the library to be built using a pre-1.9.0 version of libssh2. --- src/transports/ssh.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/transports/ssh.c b/src/transports/ssh.c index 38274240aef..71c37e758bd 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -580,6 +580,8 @@ static int _git_ssh_setup_conn( case LIBSSH2_HOSTKEY_TYPE_DSS: cert.raw_type = GIT_CERT_SSH_RAW_TYPE_DSS; break; + +#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256 case LIBSSH2_HOSTKEY_TYPE_ECDSA_256: cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256; break; @@ -589,9 +591,13 @@ static int _git_ssh_setup_conn( case LIBSSH2_KNOWNHOST_KEY_ECDSA_521: cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521; break; +#endif + +#ifdef LIBSSH2_HOSTKEY_TYPE_ED25519 case LIBSSH2_HOSTKEY_TYPE_ED25519: cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ED25519; break; +#endif default: cert.raw_type = GIT_CERT_SSH_RAW_TYPE_UNKNOWN; } From 8dc0ba75f0a49fac0af920630a867720b287ada3 Mon Sep 17 00:00:00 2001 From: Miguel Arroz <750683+arroz@users.noreply.github.com> Date: Mon, 21 Dec 2020 21:31:50 -0800 Subject: [PATCH 0206/1616] Change libssh2 version to 1.9.0 on focal --- ci/docker/focal | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/docker/focal b/ci/docker/focal index c6fefc7870d..ce972687702 100644 --- a/ci/docker/focal +++ b/ci/docker/focal @@ -48,9 +48,9 @@ RUN cd /tmp && \ FROM mbedtls AS libssh2 RUN cd /tmp && \ - curl --insecure --location --silent --show-error https://www.libssh2.org/download/libssh2-1.8.2.tar.gz | \ + curl --insecure --location --silent --show-error https://www.libssh2.org/download/libssh2-1.9.0.tar.gz | \ tar -xz && \ - cd libssh2-1.8.2 && \ + cd libssh2-1.9.0 && \ mkdir build build-msan && \ cd build && \ CC=clang-10 CFLAGS="-fPIC" cmake -G Ninja -DBUILD_SHARED_LIBS=ON -DCRYPTO_BACKEND=Libgcrypt -DCMAKE_PREFIX_PATH=/usr/local -DCMAKE_INSTALL_PREFIX=/usr/local .. && \ @@ -59,7 +59,7 @@ RUN cd /tmp && \ CC=clang-10 CFLAGS="-fPIC -fsanitize=memory -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer" LDFLAGS="-fsanitize=memory" cmake -G Ninja -DBUILD_SHARED_LIBS=ON -DCRYPTO_BACKEND=mbedTLS -DCMAKE_PREFIX_PATH=/usr/local/msan -DCMAKE_INSTALL_PREFIX=/usr/local/msan .. && \ ninja install && \ cd .. && \ - rm -rf libssh2-1.8.2 + rm -rf libssh2-1.9.0 FROM libssh2 AS valgrind RUN cd /tmp && \ From ab3e8565da67e3a1765780b717187314b47a83d6 Mon Sep 17 00:00:00 2001 From: "Paul Wolfgang (DC-AE/ESF1)" Date: Mon, 1 Jul 2019 19:59:01 +0200 Subject: [PATCH 0207/1616] urlparse: Add IPv4 and IPv6 based tests --- tests/network/urlparse.c | 510 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 510 insertions(+) diff --git a/tests/network/urlparse.c b/tests/network/urlparse.c index 15707885af0..d0aa214d80e 100644 --- a/tests/network/urlparse.c +++ b/tests/network/urlparse.c @@ -13,6 +13,10 @@ void test_network_urlparse__cleanup(void) git_net_url_dispose(&conndata); } +/* + * example.com based tests + */ + void test_network_urlparse__trivial(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com/resource")); @@ -166,3 +170,509 @@ void test_network_urlparse__user_pass_port(void) cl_assert_equal_s(conndata.password, "pass"); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } + +/* + * IPv4 based tests + */ + +void test_network_urlparse__trivial_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1/resource")); + cl_assert_equal_s(conndata.scheme, "http"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_urlparse__root_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1/")); + cl_assert_equal_s(conndata.scheme, "http"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_urlparse__implied_root_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1")); + cl_assert_equal_s(conndata.scheme, "http"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_urlparse__implied_root_custom_port_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:42")); + cl_assert_equal_s(conndata.scheme, "http"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "42"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_network_urlparse__implied_root_empty_port_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:")); + cl_assert_equal_s(conndata.scheme, "http"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_urlparse__encoded_password_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://user:pass%2fis%40bad@192.168.1.1:1234/")); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "1234"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_s(conndata.password, "pass/is@bad"); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_network_urlparse__user_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://user@192.168.1.1/resource")); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "443"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_urlparse__user_pass_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://user:pass@192.168.1.1/resource")); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "443"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_s(conndata.password, "pass"); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_urlparse__port_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://192.168.1.1:9191/resource")); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "9191"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_network_urlparse__empty_port_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:/resource")); + cl_assert_equal_s(conndata.scheme, "http"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_urlparse__user_port_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://user@192.168.1.1:9191/resource")); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "9191"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_network_urlparse__user_pass_port_ipv4(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://user:pass@192.168.1.1:9191/resource")); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "192.168.1.1"); + cl_assert_equal_s(conndata.port, "9191"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_s(conndata.password, "pass"); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +/* + * IPv6 based tests + */ + +void test_network_urlparse__trivial_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]/resource")); + cl_assert_equal_s(conndata.scheme, "http"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]/resource")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001/resource")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001/resource")); +#endif +} + +void test_network_urlparse__root_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]/")); + cl_assert_equal_s(conndata.scheme, "http"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]/")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001/")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001/")); +#endif +} + +void test_network_urlparse__implied_root_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]")); + cl_assert_equal_s(conndata.scheme, "http"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001")); +#endif +} + +void test_network_urlparse__implied_root_custom_port_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:42")); + cl_assert_equal_s(conndata.scheme, "http"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "42"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]:42")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001:42")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001:42")); +#endif +} + +void test_network_urlparse__implied_root_empty_port_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:")); + cl_assert_equal_s(conndata.scheme, "http"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]:")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001:")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001:")); +#endif +} + +void test_network_urlparse__encoded_password_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://user:pass%2fis%40bad@[fe80::dcad:beff:fe00:0001]:1234/")); + cl_assert_equal_s(conndata.scheme, "https"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "1234"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_s(conndata.password, "pass/is@bad"); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass%2fis%40bad@fe80::dcad:beff:fe00:0001]:1234/")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass%2fis%40bad@[fe80::dcad:beff:fe00:0001:1234/")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass%2fis%40bad@fe80::dcad:beff:fe00:0001:1234/")); +#endif +} + +void test_network_urlparse__user_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://user@[fe80::dcad:beff:fe00:0001]/resource")); + cl_assert_equal_s(conndata.scheme, "https"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "443"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@fe80::dcad:beff:fe00:0001]/resource")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@[fe80::dcad:beff:fe00:0001/resource")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@fe80::dcad:beff:fe00:0001/resource")); +#endif +} + +void test_network_urlparse__user_pass_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://user:pass@[fe80::dcad:beff:fe00:0001]/resource")); + cl_assert_equal_s(conndata.scheme, "https"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "443"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_s(conndata.password, "pass"); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass@fe80::dcad:beff:fe00:0001]/resource")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass@[fe80::dcad:beff:fe00:0001/resource")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass@fe80::dcad:beff:fe00:0001/resource")); +#endif +} + +void test_network_urlparse__port_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://[fe80::dcad:beff:fe00:0001]:9191/resource")); + cl_assert_equal_s(conndata.scheme, "https"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "9191"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://fe80::dcad:beff:fe00:0001]:9191/resource")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://[fe80::dcad:beff:fe00:0001:9191/resource")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://fe80::dcad:beff:fe00:0001:9191/resource")); +#endif +} + +void test_network_urlparse__empty_port_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:/resource")); + cl_assert_equal_s(conndata.scheme, "http"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "80"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]:/resource")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001:/resource")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001:/resource")); +#endif +} + +void test_network_urlparse__user_port_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://user@[fe80::dcad:beff:fe00:0001]:9191/resource")); + cl_assert_equal_s(conndata.scheme, "https"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "9191"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@fe80::dcad:beff:fe00:0001]:9191/resource")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@[fe80::dcad:beff:fe00:0001:9191/resource")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@fe80::dcad:beff:fe00:0001:9191/resource")); +#endif +} + +void test_network_urlparse__user_pass_port_ipv6(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://user:pass@[fe80::dcad:beff:fe00:0001]:9191/resource")); + cl_assert_equal_s(conndata.scheme, "https"); +#ifdef WIN32 + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); +#else + cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); +#endif + cl_assert_equal_s(conndata.port, "9191"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "user"); + cl_assert_equal_s(conndata.password, "pass"); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); + + /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass@fe80::dcad:beff:fe00:0001]:9191/resource")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass@[fe80::dcad:beff:fe00:0001:9191/resource")); +#ifdef WIN32 + /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass@fe80::dcad:beff:fe00:0001:9191/resource")); +#endif +} + +void test_network_urlparse__fails_ipv6(void) +{ + /* Invalid chracter inside address */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, "http://[fe8o::dcad:beff:fe00:0001]/resource")); +} From 780ad7a9aac4215570f1a7a93b71dd4cf2f74312 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 17 Dec 2020 14:09:45 +0000 Subject: [PATCH 0208/1616] urlparse: use consistent ipv6 address rules IPv6 addresses should be used identically internally; we should not denote them with brackets in one operating system and without them in another. --- tests/network/urlparse.c | 339 +++++++++++++-------------------------- 1 file changed, 109 insertions(+), 230 deletions(-) diff --git a/tests/network/urlparse.c b/tests/network/urlparse.c index d0aa214d80e..91c1a527cd9 100644 --- a/tests/network/urlparse.c +++ b/tests/network/urlparse.c @@ -13,11 +13,9 @@ void test_network_urlparse__cleanup(void) git_net_url_dispose(&conndata); } -/* - * example.com based tests - */ +/* Hostname */ -void test_network_urlparse__trivial(void) +void test_network_urlparse__hostname_trivial(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -29,7 +27,7 @@ void test_network_urlparse__trivial(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__root(void) +void test_network_urlparse__hostname_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com/")); cl_assert_equal_s(conndata.scheme, "http"); @@ -41,7 +39,7 @@ void test_network_urlparse__root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__implied_root(void) +void test_network_urlparse__hostname_implied_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com")); cl_assert_equal_s(conndata.scheme, "http"); @@ -53,7 +51,7 @@ void test_network_urlparse__implied_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__implied_root_custom_port(void) +void test_network_urlparse__hostname_implied_root_custom_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com:42")); cl_assert_equal_s(conndata.scheme, "http"); @@ -65,7 +63,7 @@ void test_network_urlparse__implied_root_custom_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__implied_root_empty_port(void) +void test_network_urlparse__hostname_implied_root_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com:")); cl_assert_equal_s(conndata.scheme, "http"); @@ -77,7 +75,7 @@ void test_network_urlparse__implied_root_empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__encoded_password(void) +void test_network_urlparse__hostname_encoded_password(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass%2fis%40bad@hostname.com:1234/")); @@ -90,7 +88,7 @@ void test_network_urlparse__encoded_password(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__user(void) +void test_network_urlparse__hostname_user(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@example.com/resource")); @@ -103,7 +101,7 @@ void test_network_urlparse__user(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__user_pass(void) +void test_network_urlparse__hostname_user_pass(void) { /* user:pass@hostname.tld/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -117,7 +115,7 @@ void test_network_urlparse__user_pass(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__port(void) +void test_network_urlparse__hostname_port(void) { /* hostname.tld:port/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -131,7 +129,7 @@ void test_network_urlparse__port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__empty_port(void) +void test_network_urlparse__hostname_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com:/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -143,7 +141,7 @@ void test_network_urlparse__empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__user_port(void) +void test_network_urlparse__hostname_user_port(void) { /* user@hostname.tld:port/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -157,7 +155,7 @@ void test_network_urlparse__user_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__user_pass_port(void) +void test_network_urlparse__hostname_user_pass_port(void) { /* user:pass@hostname.tld:port/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -171,11 +169,9 @@ void test_network_urlparse__user_pass_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -/* - * IPv4 based tests - */ +/* IPv4 addresses */ -void test_network_urlparse__trivial_ipv4(void) +void test_network_urlparse__ipv4_trivial(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -187,7 +183,7 @@ void test_network_urlparse__trivial_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__root_ipv4(void) +void test_network_urlparse__ipv4_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1/")); cl_assert_equal_s(conndata.scheme, "http"); @@ -199,7 +195,7 @@ void test_network_urlparse__root_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__implied_root_ipv4(void) +void test_network_urlparse__ipv4_implied_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1")); cl_assert_equal_s(conndata.scheme, "http"); @@ -211,7 +207,7 @@ void test_network_urlparse__implied_root_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__implied_root_custom_port_ipv4(void) +void test_network_urlparse__ipv4_implied_root_custom_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:42")); cl_assert_equal_s(conndata.scheme, "http"); @@ -223,7 +219,7 @@ void test_network_urlparse__implied_root_custom_port_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__implied_root_empty_port_ipv4(void) +void test_network_urlparse__ipv4_implied_root_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:")); cl_assert_equal_s(conndata.scheme, "http"); @@ -235,7 +231,7 @@ void test_network_urlparse__implied_root_empty_port_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__encoded_password_ipv4(void) +void test_network_urlparse__ipv4_encoded_password(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass%2fis%40bad@192.168.1.1:1234/")); @@ -248,7 +244,7 @@ void test_network_urlparse__encoded_password_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__user_ipv4(void) +void test_network_urlparse__ipv4_user(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@192.168.1.1/resource")); @@ -261,7 +257,7 @@ void test_network_urlparse__user_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__user_pass_ipv4(void) +void test_network_urlparse__ipv4_user_pass(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@192.168.1.1/resource")); @@ -274,7 +270,7 @@ void test_network_urlparse__user_pass_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__port_ipv4(void) +void test_network_urlparse__ipv4_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://192.168.1.1:9191/resource")); @@ -287,7 +283,7 @@ void test_network_urlparse__port_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__empty_port_ipv4(void) +void test_network_urlparse__ipv4_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -299,7 +295,7 @@ void test_network_urlparse__empty_port_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__user_port_ipv4(void) +void test_network_urlparse__ipv4_user_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@192.168.1.1:9191/resource")); @@ -312,7 +308,7 @@ void test_network_urlparse__user_port_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__user_pass_port_ipv4(void) +void test_network_urlparse__ipv4_user_pass_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@192.168.1.1:9191/resource")); @@ -325,354 +321,237 @@ void test_network_urlparse__user_pass_port_ipv4(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -/* - * IPv6 based tests - */ +/* IPv6 addresses */ -void test_network_urlparse__trivial_ipv6(void) +void test_network_urlparse__ipv6_trivial(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]/resource")); cl_assert_equal_s(conndata.scheme, "http"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "80"); cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); - - /* Opening bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001]/resource")); - /* Closing bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://[fe80::dcad:beff:fe00:0001/resource")); -#ifdef WIN32 - /* Both brackets missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001/resource")); -#endif } -void test_network_urlparse__root_ipv6(void) +void test_network_urlparse__ipv6_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]/")); cl_assert_equal_s(conndata.scheme, "http"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "80"); cl_assert_equal_s(conndata.path, "/"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); - - /* Opening bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001]/")); - /* Closing bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://[fe80::dcad:beff:fe00:0001/")); -#ifdef WIN32 - /* Both brackets missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001/")); -#endif } -void test_network_urlparse__implied_root_ipv6(void) +void test_network_urlparse__ipv6_implied_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]")); cl_assert_equal_s(conndata.scheme, "http"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "80"); cl_assert_equal_s(conndata.path, "/"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); - - /* Opening bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001]")); - /* Closing bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://[fe80::dcad:beff:fe00:0001")); -#ifdef WIN32 - /* Both brackets missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001")); -#endif } -void test_network_urlparse__implied_root_custom_port_ipv6(void) +void test_network_urlparse__ipv6_implied_root_custom_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:42")); cl_assert_equal_s(conndata.scheme, "http"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "42"); cl_assert_equal_s(conndata.path, "/"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); - - /* Opening bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001]:42")); - /* Closing bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://[fe80::dcad:beff:fe00:0001:42")); -#ifdef WIN32 - /* Both brackets missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001:42")); -#endif } -void test_network_urlparse__implied_root_empty_port_ipv6(void) +void test_network_urlparse__ipv6_implied_root_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:")); cl_assert_equal_s(conndata.scheme, "http"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "80"); cl_assert_equal_s(conndata.path, "/"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); - - /* Opening bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001]:")); - /* Closing bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://[fe80::dcad:beff:fe00:0001:")); -#ifdef WIN32 - /* Both brackets missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001:")); -#endif } -void test_network_urlparse__encoded_password_ipv6(void) +void test_network_urlparse__ipv6_encoded_password(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass%2fis%40bad@[fe80::dcad:beff:fe00:0001]:1234/")); cl_assert_equal_s(conndata.scheme, "https"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "1234"); cl_assert_equal_s(conndata.path, "/"); cl_assert_equal_s(conndata.username, "user"); cl_assert_equal_s(conndata.password, "pass/is@bad"); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); - - /* Opening bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user:pass%2fis%40bad@fe80::dcad:beff:fe00:0001]:1234/")); - /* Closing bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user:pass%2fis%40bad@[fe80::dcad:beff:fe00:0001:1234/")); -#ifdef WIN32 - /* Both brackets missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user:pass%2fis%40bad@fe80::dcad:beff:fe00:0001:1234/")); -#endif } -void test_network_urlparse__user_ipv6(void) +void test_network_urlparse__ipv6_user(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@[fe80::dcad:beff:fe00:0001]/resource")); cl_assert_equal_s(conndata.scheme, "https"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "443"); cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_s(conndata.username, "user"); cl_assert_equal_p(conndata.password, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); - - /* Opening bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user@fe80::dcad:beff:fe00:0001]/resource")); - /* Closing bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user@[fe80::dcad:beff:fe00:0001/resource")); -#ifdef WIN32 - /* Both brackets missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user@fe80::dcad:beff:fe00:0001/resource")); -#endif } -void test_network_urlparse__user_pass_ipv6(void) +void test_network_urlparse__ipv6_user_pass(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@[fe80::dcad:beff:fe00:0001]/resource")); cl_assert_equal_s(conndata.scheme, "https"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "443"); cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_s(conndata.username, "user"); cl_assert_equal_s(conndata.password, "pass"); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); - - /* Opening bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user:pass@fe80::dcad:beff:fe00:0001]/resource")); - /* Closing bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user:pass@[fe80::dcad:beff:fe00:0001/resource")); -#ifdef WIN32 - /* Both brackets missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user:pass@fe80::dcad:beff:fe00:0001/resource")); -#endif } -void test_network_urlparse__port_ipv6(void) +void test_network_urlparse__ipv6_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://[fe80::dcad:beff:fe00:0001]:9191/resource")); cl_assert_equal_s(conndata.scheme, "https"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "9191"); cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); - - /* Opening bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://fe80::dcad:beff:fe00:0001]:9191/resource")); - /* Closing bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://[fe80::dcad:beff:fe00:0001:9191/resource")); -#ifdef WIN32 - /* Both brackets missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://fe80::dcad:beff:fe00:0001:9191/resource")); -#endif } -void test_network_urlparse__empty_port_ipv6(void) +void test_network_urlparse__ipv6_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:/resource")); cl_assert_equal_s(conndata.scheme, "http"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "80"); cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_p(conndata.username, NULL); cl_assert_equal_p(conndata.password, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); - - /* Opening bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001]:/resource")); - /* Closing bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://[fe80::dcad:beff:fe00:0001:/resource")); -#ifdef WIN32 - /* Both brackets missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "http://fe80::dcad:beff:fe00:0001:/resource")); -#endif } -void test_network_urlparse__user_port_ipv6(void) +void test_network_urlparse__ipv6_user_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@[fe80::dcad:beff:fe00:0001]:9191/resource")); cl_assert_equal_s(conndata.scheme, "https"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "9191"); cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_s(conndata.username, "user"); cl_assert_equal_p(conndata.password, NULL); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); - - /* Opening bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user@fe80::dcad:beff:fe00:0001]:9191/resource")); - /* Closing bracket missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user@[fe80::dcad:beff:fe00:0001:9191/resource")); -#ifdef WIN32 - /* Both brackets missing */ - cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, - "https://user@fe80::dcad:beff:fe00:0001:9191/resource")); -#endif } -void test_network_urlparse__user_pass_port_ipv6(void) +void test_network_urlparse__ipv6_user_pass_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@[fe80::dcad:beff:fe00:0001]:9191/resource")); cl_assert_equal_s(conndata.scheme, "https"); -#ifdef WIN32 - cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); -#else cl_assert_equal_s(conndata.host, "fe80::dcad:beff:fe00:0001"); -#endif cl_assert_equal_s(conndata.port, "9191"); cl_assert_equal_s(conndata.path, "/resource"); cl_assert_equal_s(conndata.username, "user"); cl_assert_equal_s(conndata.password, "pass"); cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} +void test_network_urlparse__ipv6_invalid_addresses(void) +{ /* Opening bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]/")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]:42")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]:")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass%2fis%40bad@fe80::dcad:beff:fe00:0001]:1234/")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@fe80::dcad:beff:fe00:0001]/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass@fe80::dcad:beff:fe00:0001]/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://fe80::dcad:beff:fe00:0001]:9191/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001]:/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@fe80::dcad:beff:fe00:0001]:9191/resource")); cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, "https://user:pass@fe80::dcad:beff:fe00:0001]:9191/resource")); + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001/")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001:42")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001:")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass%2fis%40bad@[fe80::dcad:beff:fe00:0001:1234/")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@[fe80::dcad:beff:fe00:0001/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass@[fe80::dcad:beff:fe00:0001/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://[fe80::dcad:beff:fe00:0001:9191/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://[fe80::dcad:beff:fe00:0001:/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@[fe80::dcad:beff:fe00:0001:9191/resource")); cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, "https://user:pass@[fe80::dcad:beff:fe00:0001:9191/resource")); -#ifdef WIN32 /* Both brackets missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001/")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001:42")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001:")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass%2fis%40bad@fe80::dcad:beff:fe00:0001:1234/")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@fe80::dcad:beff:fe00:0001/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user:pass@fe80::dcad:beff:fe00:0001/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://fe80::dcad:beff:fe00:0001:9191/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "http://fe80::dcad:beff:fe00:0001:/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "https://user@fe80::dcad:beff:fe00:0001:9191/resource")); cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, "https://user:pass@fe80::dcad:beff:fe00:0001:9191/resource")); -#endif -} -void test_network_urlparse__fails_ipv6(void) -{ /* Invalid chracter inside address */ cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, "http://[fe8o::dcad:beff:fe00:0001]/resource")); } From 2807de5cc2768eaf0c0b6d7157c42c1c782bd730 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 17 Dec 2020 15:18:31 +0000 Subject: [PATCH 0209/1616] http: handle ipv6 addresses --- src/transports/httpclient.c | 40 +++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index d9cbf1783f8..d3975746b73 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -631,6 +631,26 @@ GIT_INLINE(int) apply_proxy_credentials( request->proxy_credentials); } +static int puts_host_and_port(git_buf *buf, git_net_url *url, bool force_port) +{ + bool ipv6 = git_net_url_is_ipv6(url); + + if (ipv6) + git_buf_putc(buf, '['); + + git_buf_puts(buf, url->host); + + if (ipv6) + git_buf_putc(buf, ']'); + + if (force_port || !git_net_url_is_default_port(url)) { + git_buf_putc(buf, ':'); + git_buf_puts(buf, url->port); + } + + return git_buf_oom(buf) ? -1 : 0; +} + static int generate_connect_request( git_http_client *client, git_http_request *request) @@ -641,14 +661,17 @@ static int generate_connect_request( git_buf_clear(&client->request_msg); buf = &client->request_msg; - git_buf_printf(buf, "CONNECT %s:%s HTTP/1.1\r\n", - client->server.url.host, client->server.url.port); + git_buf_puts(buf, "CONNECT "); + puts_host_and_port(buf, &client->server.url, true); + git_buf_puts(buf, " HTTP/1.1\r\n"); git_buf_puts(buf, "User-Agent: "); git_http__user_agent(buf); git_buf_puts(buf, "\r\n"); - git_buf_printf(buf, "Host: %s\r\n", client->proxy.url.host); + git_buf_puts(buf, "Host: "); + puts_host_and_port(buf, &client->proxy.url, false); + git_buf_puts(buf, "\r\n"); if ((error = apply_proxy_credentials(buf, client, request) < 0)) return -1; @@ -687,11 +710,8 @@ static int generate_request( git_http__user_agent(buf); git_buf_puts(buf, "\r\n"); - git_buf_printf(buf, "Host: %s", request->url->host); - - if (!git_net_url_is_default_port(request->url)) - git_buf_printf(buf, ":%s", request->url->port); - + git_buf_puts(buf, "Host: "); + puts_host_and_port(buf, request->url, false); git_buf_puts(buf, "\r\n"); if (request->accept) @@ -902,7 +922,7 @@ static int proxy_connect( int error; if (!client->proxy_connected || !client->keepalive) { - git_trace(GIT_TRACE_DEBUG, "Connecting to proxy %s:%s", + git_trace(GIT_TRACE_DEBUG, "Connecting to proxy %s port %s", client->proxy.url.host, client->proxy.url.port); if ((error = server_create_stream(&client->proxy)) < 0 || @@ -1023,7 +1043,7 @@ static int http_client_connect( goto on_error; } - git_trace(GIT_TRACE_DEBUG, "Connecting to remote %s:%s", + git_trace(GIT_TRACE_DEBUG, "Connecting to remote %s port %s", client->server.url.host, client->server.url.port); if ((error = server_connect(client)) < 0) From b7ffc63b1b0aee36d54733baec5412942e71f00c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 17 Dec 2020 18:38:01 +0000 Subject: [PATCH 0210/1616] winhttp: handle ipv6 addresses --- src/transports/winhttp.c | 42 ++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index c82c788aea3..54aacdba3a6 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -451,8 +451,14 @@ static int winhttp_stream_connect(winhttp_stream *s) git_buf_puts(&processed_url, t->proxy.url.scheme); git_buf_PUTS(&processed_url, "://"); + if (git_net_url_is_ipv6(&t->proxy.url)) + git_buf_putc(&processed_url, '['); + git_buf_puts(&processed_url, t->proxy.url.host); + if (git_net_url_is_ipv6(&t->proxy.url)) + git_buf_putc(&processed_url, ']'); + if (!git_net_url_is_default_port(&t->proxy.url)) git_buf_printf(&processed_url, ":%s", t->proxy.url.port); @@ -736,10 +742,11 @@ static void CALLBACK winhttp_status( static int winhttp_connect( winhttp_subtransport *t) { - wchar_t *wide_host; + wchar_t *wide_host = NULL; int32_t port; - wchar_t *wide_ua; - git_buf ua = GIT_BUF_INIT; + wchar_t *wide_ua = NULL; + git_buf ipv6 = GIT_BUF_INIT, ua = GIT_BUF_INIT; + const char *host; int error = -1; int default_timeout = TIMEOUT_INFINITE; int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT; @@ -755,29 +762,33 @@ static int winhttp_connect( /* Prepare port */ if (git__strntol32(&port, t->server.url.port, strlen(t->server.url.port), NULL, 10) < 0) - return -1; + goto on_error; + + /* IPv6? Add braces around the host. */ + if (git_net_url_is_ipv6(&t->server.url)) { + if (git_buf_printf(&ipv6, "[%s]", t->server.url.host) < 0) + goto on_error; + + host = ipv6.ptr; + } else { + host = t->server.url.host; + } /* Prepare host */ - if (git__utf8_to_16_alloc(&wide_host, t->server.url.host) < 0) { + if (git__utf8_to_16_alloc(&wide_host, host) < 0) { git_error_set(GIT_ERROR_OS, "unable to convert host to wide characters"); - return -1; + goto on_error; } - if ((error = git_http__user_agent(&ua)) < 0) { - git__free(wide_host); - return error; - } + if (git_http__user_agent(&ua) < 0) + goto on_error; if (git__utf8_to_16_alloc(&wide_ua, git_buf_cstr(&ua)) < 0) { git_error_set(GIT_ERROR_OS, "unable to convert host to wide characters"); - git__free(wide_host); - git_buf_dispose(&ua); - return -1; + goto on_error; } - git_buf_dispose(&ua); - /* Establish session */ t->session = WinHttpOpen( wide_ua, @@ -836,6 +847,7 @@ static int winhttp_connect( if (error < 0) winhttp_close_connection(t); + git_buf_dispose(&ipv6); git__free(wide_host); git__free(wide_ua); From 953dee20c6ccb5cb9b5e89ae571bfd356fe21a0e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 17 Dec 2020 20:51:37 +0000 Subject: [PATCH 0211/1616] net: is_default_port is a bool --- src/net.c | 2 +- src/net.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/net.c b/src/net.c index 0705dd390cd..d5662393a21 100644 --- a/src/net.c +++ b/src/net.c @@ -335,7 +335,7 @@ bool git_net_url_valid(git_net_url *url) return (url->host && url->port && url->path); } -int git_net_url_is_default_port(git_net_url *url) +bool git_net_url_is_default_port(git_net_url *url) { const char *default_port; diff --git a/src/net.h b/src/net.h index 7e72db13f33..0082dd6d71f 100644 --- a/src/net.h +++ b/src/net.h @@ -33,8 +33,8 @@ extern int git_net_url_joinpath( /** Ensures that a URL is minimally valid (contains a host, port and path) */ extern bool git_net_url_valid(git_net_url *url); -/** Returns nonzero if the URL is on the default port. */ -extern int git_net_url_is_default_port(git_net_url *url); +/** Returns true if the URL is on the default port. */ +extern bool git_net_url_is_default_port(git_net_url *url); /* Applies a redirect to the URL with a git-aware service suffix. */ extern int git_net_url_apply_redirect( From 27301cd02676e8e1247f36ff5bbd3ee9c2579ee1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 17 Dec 2020 20:53:11 +0000 Subject: [PATCH 0212/1616] net: function to identify ipv6 addresses in URLs --- src/net.c | 5 +++++ src/net.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/net.c b/src/net.c index d5662393a21..d4a9f8a6d6e 100644 --- a/src/net.c +++ b/src/net.c @@ -345,6 +345,11 @@ bool git_net_url_is_default_port(git_net_url *url) return false; } +bool git_net_url_is_ipv6(git_net_url *url) +{ + return (strchr(url->host, ':') != NULL); +} + void git_net_url_swap(git_net_url *a, git_net_url *b) { git_net_url tmp = GIT_NET_URL_INIT; diff --git a/src/net.h b/src/net.h index 0082dd6d71f..391b99a9fe0 100644 --- a/src/net.h +++ b/src/net.h @@ -36,6 +36,9 @@ extern bool git_net_url_valid(git_net_url *url); /** Returns true if the URL is on the default port. */ extern bool git_net_url_is_default_port(git_net_url *url); +/** Returns true if the host portion of the URL is an ipv6 address. */ +extern bool git_net_url_is_ipv6(git_net_url *url); + /* Applies a redirect to the URL with a git-aware service suffix. */ extern int git_net_url_apply_redirect( git_net_url *url, From 83265b3e2c6b10370c2fea304be33db78f653761 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Fri, 18 Dec 2020 06:50:22 -0800 Subject: [PATCH 0213/1616] zlib: Add support for building with Chromium's zlib implementation This change builds libgit2 using Chromium's zlib implementation by invoking cmake with `-DUSE_BUNDLED_ZLIB=ON -DUSE_CHROMIUM_ZLIB=ON`, which is ~10% faster than the bundled zlib for the core::zstream suite. This version of zlib has some optimizations: a) Decompression (Intel+ARM): inflate_fast, adler32, crc32, etc. b) Compression (Intel): fill_window, longest_match, hash function, etc. Due to the introduction of SIMD optimizations, and to get the maximum performance out of this fork of zlib, this requires an x86_64 processor with SSE4.2 and CLMUL (anything Westmere or later, ~2010). The Chromium zlib implementation also supports ARM with NEON, but it has not been enabled in this patch. Performance =========== TL;DR: Running just `./libgit2_clar -score::zstream` 100 times in a loop took 0:56.30 before and 0:50.67 after (~10% reduction!). The bundled and system zlib implementations on an Ubuntu Focal system perform relatively similar (the bundled one is marginally better due to the compiler being able to inline some functions), so only the bundled and Chromium zlibs were compared. For a more balanced comparison (to ensure that nothing regressed overall), `libgit2_clar` under `perf` was also run, and the zlib-related functions were compared. Bundled ------- ```shell cmake \ -DUSE_BUNDLED_ZLIB=ON \ -DUSE_CHROMIUM_ZLIB=OFF \ -DCMAKE_BUILD_TYPE="RelWithDebInfo" \ -DCMAKE_C_FLAGS="-fPIC -fno-omit-frame-pointer" \ -GNinja \ .. ninja perf record --call-graph=dwarf ./libgit2_clar perf report --children ``` ``` Samples: 87K of event 'cycles', Event count (approx.): 75923450603 Children Self Command Shared Objec Symbol + 4.14% 0.01% libgit2_clar libgit2_clar [.] git_zstream_get_output_chunk + 2.91% 0.00% libgit2_clar libgit2_clar [.] git_zstream_get_output + 0.69% 0.00% libgit2_clar libgit2_clar [.] git_zstream_get_output (inlined) 0.17% 0.00% libgit2_clar libgit2_clar [.] git_zstream_init 0.02% 0.00% libgit2_clar libgit2_clar [.] git_zstream_reset 0.00% 0.00% libgit2_clar libgit2_clar [.] git_zstream_eos 0.00% 0.00% libgit2_clar libgit2_clar [.] git_zstream_done 0.00% 0.00% libgit2_clar libgit2_clar [.] git_zstream_free (inlined) Samples: 87K of event 'cycles', Event count (approx.): 75923450603 Children Self Command Shared Objec Symbol + 3.12% 0.01% libgit2_clar libgit2_clar [.] deflate + 2.65% 1.48% libgit2_clar libgit2_clar [.] deflate_slow + 1.60% 0.55% libgit2_clar libgit2_clar [.] inflate + 0.53% 0.00% libgit2_clar libgit2_clar [.] write_deflate 0.49% 0.36% libgit2_clar libgit2_clar [.] inflate_fast 0.46% 0.02% libgit2_clar libgit2_clar [.] deflate_fast 0.19% 0.19% libgit2_clar libgit2_clar [.] inflate_table 0.16% 0.01% libgit2_clar libgit2_clar [.] inflateInit_ 0.15% 0.00% libgit2_clar libgit2_clar [.] inflateInit2_ (inlined) 0.10% 0.00% libgit2_clar libgit2_clar [.] deflateInit_ 0.10% 0.00% libgit2_clar libgit2_clar [.] deflateInit2_ 0.03% 0.00% libgit2_clar libgit2_clar [.] deflateReset (inlined) 0.02% 0.00% libgit2_clar libgit2_clar [.] deflateReset 0.02% 0.00% libgit2_clar libgit2_clar [.] inflateEnd 0.02% 0.00% libgit2_clar libgit2_clar [.] deflateEnd 0.01% 0.00% libgit2_clar libgit2_clar [.] deflateResetKeep 0.01% 0.01% libgit2_clar libgit2_clar [.] inflateReset2 0.01% 0.00% libgit2_clar libgit2_clar [.] deflateReset (inlined) 0.00% 0.00% libgit2_clar libgit2_clar [.] inflateStateCheck (inlined) 0.00% 0.00% libgit2_clar libgit2_clar [.] inflateReset (inlined) 0.00% 0.00% libgit2_clar libgit2_clar [.] inflateStateCheck (inlined) 0.00% 0.00% libgit2_clar libgit2_clar [.] deflateStateCheck (inlined) 0.00% 0.00% libgit2_clar libgit2_clar [.] inflateResetKeep (inlined) ``` Chromium -------- ```shell cmake \ -DUSE_BUNDLED_ZLIB=ON \ -DUSE_CHROMIUM_ZLIB=ON \ -DCMAKE_BUILD_TYPE="RelWithDebInfo" \ -DCMAKE_C_FLAGS="-fPIC -fno-omit-frame-pointer" \ -GNinja \ .. ninja perf record --call-graph=dwarf ./libgit2_clar perf report --children ``` ``` Samples: 97K of event 'cycles', Event count (approx.): 80862210917 Children Self Command Shared Objec Symbol + 3.31% 0.00% libgit2_clar libgit2_clar [.] git_zstream_get_output_chunk + 2.27% 0.01% libgit2_clar libgit2_clar [.] git_zstream_get_output + 0.55% 0.00% libgit2_clar libgit2_clar [.] git_zstream_get_output (inlined) 0.18% 0.00% libgit2_clar libgit2_clar [.] git_zstream_init 0.02% 0.00% libgit2_clar libgit2_clar [.] git_zstream_reset 0.00% 0.00% libgit2_clar libgit2_clar [.] git_zstream_free (inlined) 0.00% 0.00% libgit2_clar libgit2_clar [.] git_zstream_done 0.00% 0.00% libgit2_clar libgit2_clar [.] git_zstream_free Samples: 97K of event 'cycles', Event count (approx.): 80862210917 Children Self Command Shared Objec Symbol + 2.55% 0.01% libgit2_clar libgit2_clar [.] deflate + 2.25% 1.41% libgit2_clar libgit2_clar [.] deflate_slow + 1.10% 0.52% libgit2_clar libgit2_clar [.] inflate 0.36% 0.00% libgit2_clar libgit2_clar [.] write_deflate 0.30% 0.03% libgit2_clar libgit2_clar [.] deflate_fast 0.28% 0.15% libgit2_clar libgit2_clar [.] inflate_fast_chunk_ 0.19% 0.19% libgit2_clar libgit2_clar [.] inflate_table 0.17% 0.01% libgit2_clar libgit2_clar [.] inflateInit_ 0.16% 0.00% libgit2_clar libgit2_clar [.] inflateInit2_ (inlined) 0.15% 0.00% libgit2_clar libgit2_clar [.] deflateInit_ 0.15% 0.00% libgit2_clar libgit2_clar [.] deflateInit2_ 0.11% 0.01% libgit2_clar libgit2_clar [.] adler32_z 0.09% 0.09% libgit2_clar libgit2_clar [.] adler32_simd_ 0.05% 0.00% libgit2_clar libgit2_clar [.] deflateReset (inlined) 0.05% 0.00% libgit2_clar libgit2_clar [.] deflate_read_buf 0.03% 0.00% libgit2_clar libgit2_clar [.] inflateEnd 0.02% 0.00% libgit2_clar libgit2_clar [.] deflateReset 0.01% 0.00% libgit2_clar libgit2_clar [.] deflateEnd 0.01% 0.01% libgit2_clar libgit2_clar [.] inflateReset2 0.01% 0.00% libgit2_clar libgit2_clar [.] inflateReset (inlined) 0.00% 0.00% libgit2_clar libgit2_clar [.] adler32 0.00% 0.00% libgit2_clar libgit2_clar [.] inflateResetKeep (inlined) 0.00% 0.00% libgit2_clar libgit2_clar [.] deflateResetKeep 0.00% 0.00% libgit2_clar libgit2_clar [.] inflateStateCheck (inlined) 0.00% 0.00% libgit2_clar libgit2_clar [.] inflateStateCheck (inlined) 0.00% 0.00% libgit2_clar libgit2_clar [.] inflateStateCheck (inlined) 0.00% 0.00% libgit2_clar libgit2_clar [.] deflateStateCheck (inlined) ``` --- CMakeLists.txt | 1 + deps/chromium-zlib/CMakeLists.txt | 101 ++++++++++++++++++++++++++++++ src/CMakeLists.txt | 15 +++-- 3 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 deps/chromium-zlib/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 05ad1baec7b..a8f6b7537a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF) OPTION(DEBUG_POOL "Enable debug pool allocator" OFF) OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF) OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib" OFF) +OPTION(USE_CHROMIUM_ZLIB "If using the bundled version of zlib, use the Chromium flavor (x86_64 processor with SSE4.2 and CLMUL required)" OFF) SET(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.") OPTION(DEPRECATE_HARD "Do not include deprecated functions in the library" OFF) SET(REGEX_BACKEND "" CACHE STRING "Regular expression implementation. One of regcomp_l, pcre2, pcre, regcomp, or builtin.") diff --git a/deps/chromium-zlib/CMakeLists.txt b/deps/chromium-zlib/CMakeLists.txt new file mode 100644 index 00000000000..bbb35d4e6fc --- /dev/null +++ b/deps/chromium-zlib/CMakeLists.txt @@ -0,0 +1,101 @@ +# CMake build script for the bundled Chromium zlib implementation. So far, it +# is only supported for x86_64 processors with CLMUL, SSE3, SSE4.2. +# +# TODO: The Chromium build file (in deps/chromium-zlib/zlib/BUILD.gn) supports +# more platforms (like ARM with NEON), more can be enabled as needed. + +CMAKE_MINIMUM_REQUIRED(VERSION 3.11) + +include(FetchContent) +include(FindGit) + +# Ensure that the git binary is present to download the sources. +find_package(Git) +IF(NOT Git_FOUND) + message(FATAL_ERROR "git is required to download the Chromium zlib sources") +ENDIF() + +FetchContent_Populate(chromium_zlib_src + GIT_REPOSITORY https://chromium.googlesource.com/chromium/src/third_party/zlib.git + GIT_TAG 2c183c9f93a328bfb3121284da13cf89a0f7e64a + QUIET +) + +# The Chromium build globally disables some warnings. +disable_warnings(implicit-fallthrough) +disable_warnings(unused-function) +disable_warnings(unused-parameter) +disable_warnings(sign-compare) +disable_warnings(declaration-after-statement) +disable_warnings(missing-declarations) + +# -O3 is also set by the Chromium configuration and has been deemed safe enough +# for them. +SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -g -DNDEBUG") +SET(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") + +# Common definitions. +add_definitions( + -DSTDC + -DNO_GZIP + -DZLIB_IMPLEMENTATION +) +list(APPEND SRC_ZLIB + "${chromium_zlib_src_SOURCE_DIR}/adler32.c" + "${chromium_zlib_src_SOURCE_DIR}/chromeconf.h" + "${chromium_zlib_src_SOURCE_DIR}/compress.c" + "${chromium_zlib_src_SOURCE_DIR}/contrib/optimizations/insert_string.h" + "${chromium_zlib_src_SOURCE_DIR}/cpu_features.c" + "${chromium_zlib_src_SOURCE_DIR}/cpu_features.h" + "${chromium_zlib_src_SOURCE_DIR}/crc32.c" + "${chromium_zlib_src_SOURCE_DIR}/crc32.h" + "${chromium_zlib_src_SOURCE_DIR}/deflate.c" + "${chromium_zlib_src_SOURCE_DIR}/deflate.h" + "${chromium_zlib_src_SOURCE_DIR}/gzclose.c" + "${chromium_zlib_src_SOURCE_DIR}/gzguts.h" + "${chromium_zlib_src_SOURCE_DIR}/gzlib.c" + "${chromium_zlib_src_SOURCE_DIR}/gzread.c" + "${chromium_zlib_src_SOURCE_DIR}/gzwrite.c" + "${chromium_zlib_src_SOURCE_DIR}/infback.c" + "${chromium_zlib_src_SOURCE_DIR}/inffast.c" + "${chromium_zlib_src_SOURCE_DIR}/inffast.h" + "${chromium_zlib_src_SOURCE_DIR}/inffixed.h" + "${chromium_zlib_src_SOURCE_DIR}/inflate.h" + "${chromium_zlib_src_SOURCE_DIR}/inftrees.c" + "${chromium_zlib_src_SOURCE_DIR}/inftrees.h" + "${chromium_zlib_src_SOURCE_DIR}/trees.c" + "${chromium_zlib_src_SOURCE_DIR}/trees.h" + "${chromium_zlib_src_SOURCE_DIR}/uncompr.c" + "${chromium_zlib_src_SOURCE_DIR}/zconf.h" + "${chromium_zlib_src_SOURCE_DIR}/zlib.h" + "${chromium_zlib_src_SOURCE_DIR}/zutil.c" + "${chromium_zlib_src_SOURCE_DIR}/zutil.h" +) + +# x86_64-specific optimizations +string(APPEND CMAKE_C_FLAGS " -mssse3 -msse4.2 -mpclmul") +add_definitions( + -DCHROMIUM_ZLIB_NO_CHROMECONF + -DX86_NOT_WINDOWS + -DADLER32_SIMD_SSSE3 + -DCRC32_SIMD_SSE42_PCLMUL + -DDEFLATE_FILL_WINDOW_SSE2 + -DINFLATE_CHUNK_READ_64LE + -DINFLATE_CHUNK_SIMD_SSE2 +) +list(APPEND SRC_ZLIB + "${chromium_zlib_src_SOURCE_DIR}/adler32_simd.c" + "${chromium_zlib_src_SOURCE_DIR}/adler32_simd.h" + "${chromium_zlib_src_SOURCE_DIR}/contrib/optimizations/chunkcopy.h" + "${chromium_zlib_src_SOURCE_DIR}/contrib/optimizations/inffast_chunk.c" + "${chromium_zlib_src_SOURCE_DIR}/contrib/optimizations/inffast_chunk.h" + "${chromium_zlib_src_SOURCE_DIR}/contrib/optimizations/inflate.c" + "${chromium_zlib_src_SOURCE_DIR}/crc32_simd.c" + "${chromium_zlib_src_SOURCE_DIR}/crc32_simd.h" + "${chromium_zlib_src_SOURCE_DIR}/crc_folding.c" + "${chromium_zlib_src_SOURCE_DIR}/fill_window_sse.c" +) + +list(SORT SRC_ZLIB) +include_directories("${chromium_zlib_src_SOURCE_DIR}") +add_library(chromium_zlib OBJECT ${SRC_ZLIB}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d01cc6458e3..65a289b81f7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -202,10 +202,17 @@ IF(NOT USE_BUNDLED_ZLIB) ENDIF() ENDIF() IF(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND) - ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib") - LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib") - LIST(APPEND LIBGIT2_OBJECTS $) - ADD_FEATURE_INFO(zlib ON "using bundled zlib") + IF(USE_CHROMIUM_ZLIB) + ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/chromium-zlib" "${libgit2_BINARY_DIR}/deps/chromium-zlib") + LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/chromium-zlib") + LIST(APPEND LIBGIT2_OBJECTS $) + ADD_FEATURE_INFO(zlib ON "using (Chromium) bundled zlib") + ELSE() + ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib") + LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib") + LIST(APPEND LIBGIT2_OBJECTS $) + ADD_FEATURE_INFO(zlib ON "using bundled zlib") + ENDIF() ENDIF() # Optional external dependency: libssh2 From a9f57a8919f264fa184320d1f5c3ed7a35b7576a Mon Sep 17 00:00:00 2001 From: Dhruva Krishnamurthy Date: Mon, 23 Nov 2020 10:14:00 -0800 Subject: [PATCH 0214/1616] Remove broken support for write in emulated mmap * Emulated mmap based write without pagefault handling is not possible since IO happens outside of call to mmap and data is written to mapped memory * Potential emulation using userfaultfd() might be possible --- src/posix.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/posix.c b/src/posix.c index 9cd96d2c832..debd8d2c86b 100644 --- a/src/posix.c +++ b/src/posix.c @@ -240,14 +240,15 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset { GIT_MMAP_VALIDATE(out, len, prot, flags); - out->data = NULL; - out->len = 0; - - if ((prot & GIT_PROT_WRITE) && ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED)) { - git_error_set(GIT_ERROR_OS, "trying to map shared-writeable"); + /* writes cannot be emulated without handling pagefaults since write happens by + * writing to mapped memory */ + if (prot & GIT_PROT_WRITE) { + git_error_set(GIT_ERROR_OS, "trying to map %s-writeable", + ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED) ? "shared": "private"); return -1; } + out->len = 0; out->data = git__malloc(len); GIT_ERROR_CHECK_ALLOC(out->data); From 4ce8e01a7ada3c75f7407dc9fafd25b4ac38d037 Mon Sep 17 00:00:00 2001 From: Dhruva Krishnamurthy Date: Wed, 17 Jun 2020 14:31:11 -0700 Subject: [PATCH 0215/1616] Support build with NO_MMAP to disable use of system mmap * Use pread/pwrite to avoid updating position in file descriptor * Emulate missing pread/pwrite on win32 using overlapped file IO --- src/indexer.c | 18 +++++++++++ src/posix.c | 32 ++++++++++++++++---- src/posix.h | 9 ++++++ src/unix/posix.h | 3 ++ src/win32/posix_w32.c | 70 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 5 deletions(-) diff --git a/src/indexer.c b/src/indexer.c index 453bb3df7fa..ba82d716db8 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -603,6 +603,23 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size) static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t size) { +#ifdef NO_MMAP + size_t remaining_size = size; + const char *ptr = (const char *)data; + + /* Handle data size larger that ssize_t */ + while (remaining_size > 0) { + ssize_t nb; + HANDLE_EINTR(nb, p_pwrite(idx->pack->mwf.fd, (void *)ptr, + remaining_size, offset)); + if (nb <= 0) + return -1; + + ptr += nb; + offset += nb; + remaining_size -= nb; + } +#else git_file fd = idx->pack->mwf.fd; size_t mmap_alignment; size_t page_offset; @@ -627,6 +644,7 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s map_data = (unsigned char *)map.data; memcpy(map_data + page_offset, data, size); p_munmap(&map); +#endif return 0; } diff --git a/src/posix.c b/src/posix.c index debd8d2c86b..bf764ae6b67 100644 --- a/src/posix.c +++ b/src/posix.c @@ -238,6 +238,9 @@ int git__mmap_alignment(size_t *alignment) int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset) { + const char *ptr; + size_t remaining_len; + GIT_MMAP_VALIDATE(out, len, prot, flags); /* writes cannot be emulated without handling pagefaults since write happens by @@ -248,15 +251,30 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset return -1; } + if (!git__is_ssizet(len)) { + errno = EINVAL; + return -1; + } + out->len = 0; out->data = git__malloc(len); GIT_ERROR_CHECK_ALLOC(out->data); - if (!git__is_ssizet(len) || - (p_lseek(fd, offset, SEEK_SET) < 0) || - (p_read(fd, out->data, len) != (ssize_t)len)) { - git_error_set(GIT_ERROR_OS, "mmap emulation failed"); - return -1; + remaining_len = len; + ptr = (const char *)out->data; + while (remaining_len > 0) { + ssize_t nb; + HANDLE_EINTR(nb, p_pread(fd, (void *)ptr, remaining_len, offset)); + if (nb <= 0) { + git_error_set(GIT_ERROR_OS, "mmap emulation failed"); + git__free(out->data); + out->data = NULL; + return -1; + } + + ptr += nb; + offset += nb; + remaining_len -= nb; } out->len = len; @@ -268,6 +286,10 @@ int p_munmap(git_map *map) GIT_ASSERT_ARG(map); git__free(map->data); + /* Initializing will help debug use-after-free */ + map->len = 0; + map->data = NULL; + return 0; } diff --git a/src/posix.h b/src/posix.h index eef667762cf..d98bc82ca80 100644 --- a/src/posix.h +++ b/src/posix.h @@ -89,6 +89,12 @@ #define EAFNOSUPPORT (INT_MAX-1) #endif +/* Compiler independent macro to handle signal interrpted system calls */ +#define HANDLE_EINTR(result, x) do { \ + result = (x); \ + } while (result == -1 && errno == EINTR); + + /* Provide a 64-bit size for offsets. */ #if defined(_MSC_VER) @@ -119,6 +125,9 @@ typedef int git_file; extern ssize_t p_read(git_file fd, void *buf, size_t cnt); extern int p_write(git_file fd, const void *buf, size_t cnt); +extern ssize_t p_pread(int fd, void *data, size_t size, off64_t offset); +extern ssize_t p_pwrite(int fd, const void *data, size_t size, off64_t offset); + #define p_close(fd) close(fd) #define p_umask(m) umask(m) diff --git a/src/unix/posix.h b/src/unix/posix.h index b5527a4a84b..7b3325e7817 100644 --- a/src/unix/posix.h +++ b/src/unix/posix.h @@ -101,4 +101,7 @@ GIT_INLINE(int) p_futimes(int f, const struct p_timeval t[2]) # define p_futimes futimes #endif +#define p_pread(f, d, s, o) pread(f, d, s, o) +#define p_pwrite(f, d, s, o) pwrite(f, d, s, o) + #endif diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index 5a5e92158ea..0a8f2bee07f 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -981,3 +981,73 @@ int p_inet_pton(int af, const char *src, void *dst) errno = EINVAL; return -1; } + +ssize_t p_pread(int fd, void *data, size_t size, off64_t offset) +{ + HANDLE fh; + DWORD rsize = 0; + OVERLAPPED ov = {0}; + LARGE_INTEGER pos = {0}; + off64_t final_offset = 0; + + /* Fail if the final offset would have overflowed to match POSIX semantics. */ + if (!git__is_ssizet(size) || git__add_int64_overflow(&final_offset, offset, (int64_t)size)) { + errno = EINVAL; + return -1; + } + + /* + * Truncate large writes to the maximum allowable size: the caller + * needs to always call this in a loop anyways. + */ + if (size > INT32_MAX) { + size = INT32_MAX; + } + + pos.QuadPart = offset; + ov.Offset = pos.LowPart; + ov.OffsetHigh = pos.HighPart; + fh = (HANDLE)_get_osfhandle(fd); + + if (ReadFile(fh, data, (DWORD)size, &rsize, &ov)) { + return (ssize_t)rsize; + } + + set_errno(); + return -1; +} + +ssize_t p_pwrite(int fd, const void *data, size_t size, off64_t offset) +{ + HANDLE fh; + DWORD wsize = 0; + OVERLAPPED ov = {0}; + LARGE_INTEGER pos = {0}; + off64_t final_offset = 0; + + /* Fail if the final offset would have overflowed to match POSIX semantics. */ + if (!git__is_ssizet(size) || git__add_int64_overflow(&final_offset, offset, (int64_t)size)) { + errno = EINVAL; + return -1; + } + + /* + * Truncate large writes to the maximum allowable size: the caller + * needs to always call this in a loop anyways. + */ + if (size > INT32_MAX) { + size = INT32_MAX; + } + + pos.QuadPart = offset; + ov.Offset = pos.LowPart; + ov.OffsetHigh = pos.HighPart; + fh = (HANDLE)_get_osfhandle(fd); + + if (WriteFile(fh, data, (DWORD)size, &wsize, &ov)) { + return (ssize_t)wsize; + } + + set_errno(); + return -1; +} From 4fafe9f6a15ccf540d23c96d37ca1c3127a7ddac Mon Sep 17 00:00:00 2001 From: Dhruva Krishnamurthy Date: Sun, 22 Nov 2020 13:23:46 -0800 Subject: [PATCH 0216/1616] Add github action to build and test with mmap emulation --- .github/workflows/nightly.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 8e35726d7ad..fa83491ba39 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -96,6 +96,17 @@ jobs: ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 TSAN_OPTIONS: suppressions=/home/libgit2/source/script/thread-sanitizer.supp second_deadlock_stack=1 os: ubuntu-latest + - # Focal, Clang 10, mmap emulation (NO_MMAP) + container: + name: focal + env: + CC: clang-10 + CFLAGS: -DNO_MMAP + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local + CMAKE_GENERATOR: Ninja + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true + os: ubuntu-latest - # macOS os: macos-10.15 env: @@ -114,6 +125,15 @@ jobs: CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true + - # Windows amd64 Visual Studio (NO_MMAP) + os: windows-2019 + env: + ARCH: amd64 + CMAKE_GENERATOR: Visual Studio 16 2019 + CFLAGS: -DNO_MMAP + CMAKE_OPTIONS: -A x64 -DDEPRECATE_HARD=ON + SKIP_SSH_TESTS: true + SKIP_NEGOTIATE_TESTS: true - # Windows x86 Visual Studio os: windows-2019 env: From 0af0f7fdcf6e2fdc1139fef325ad01b77f3e86a3 Mon Sep 17 00:00:00 2001 From: Josh Stockin Date: Sun, 3 Jan 2021 20:39:45 -0600 Subject: [PATCH 0217/1616] Add documentation for git_blob_filter_options.version Resolves #5756 --- include/git2/blob.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/git2/blob.h b/include/git2/blob.h index 8e977267dd5..866b8bdd7a8 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -120,6 +120,7 @@ typedef enum { * The options used when applying filter options to a file. */ typedef struct { + /** The struct version; set to `GIT_BLOB_FILTER_OPTIONS_VERSION`. */ int version; /** Flags to control the filtering process, see `git_blob_filter_flag_t` above */ From 754fa5263e9551c6b862a8e17869e5948e99fb9f Mon Sep 17 00:00:00 2001 From: lhchavez Date: Mon, 4 Jan 2021 06:10:10 -0800 Subject: [PATCH 0218/1616] Use an option instead of a flag for USE_BUNDLED_ZLIB Now `USE_BUNDLED_ZLIB` can be set to the string `Chromium` to enable the Chromium implementation of zlib. --- CMakeLists.txt | 3 +-- src/CMakeLists.txt | 30 +++++++++++++++++------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a8f6b7537a5..65569797906 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,8 +50,7 @@ OPTION(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)" OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF) OPTION(DEBUG_POOL "Enable debug pool allocator" OFF) OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF) -OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib" OFF) -OPTION(USE_CHROMIUM_ZLIB "If using the bundled version of zlib, use the Chromium flavor (x86_64 processor with SSE4.2 and CLMUL required)" OFF) +OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib. Can be set to one of Bundled(ON)/Chromium. The Chromium option requires a x86_64 processor with SSE4.2 and CLMUL" OFF) SET(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.") OPTION(DEPRECATE_HARD "Do not include deprecated functions in the library" OFF) SET(REGEX_BACKEND "" CACHE STRING "Regular expression implementation. One of regcomp_l, pcre2, pcre, regcomp, or builtin.") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 65a289b81f7..4fde16d8a98 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ ENDIF() ADD_FEATURE_INFO(debugpool GIT_DEBUG_POOL "debug pool allocator") INCLUDE(PkgBuildConfig) +INCLUDE(SanitizeBool) # This variable will contain the libraries we need to put into # libgit2.pc's Requires.private. That is, what we're linking to or @@ -186,7 +187,12 @@ ELSE() ENDIF() # Optional external dependency: zlib -IF(NOT USE_BUNDLED_ZLIB) +SanitizeBool(USE_BUNDLED_ZLIB) +IF(USE_BUNDLED_ZLIB STREQUAL ON) + SET(USE_BUNDLED_ZLIB "Bundled") +ENDIF() + +IF(USE_BUNDLED_ZLIB STREQUAL "OFF") FIND_PACKAGE(ZLIB) IF(ZLIB_FOUND) LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${ZLIB_INCLUDE_DIRS}) @@ -201,18 +207,16 @@ IF(NOT USE_BUNDLED_ZLIB) MESSAGE(STATUS "zlib was not found; using bundled 3rd-party sources." ) ENDIF() ENDIF() -IF(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND) - IF(USE_CHROMIUM_ZLIB) - ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/chromium-zlib" "${libgit2_BINARY_DIR}/deps/chromium-zlib") - LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/chromium-zlib") - LIST(APPEND LIBGIT2_OBJECTS $) - ADD_FEATURE_INFO(zlib ON "using (Chromium) bundled zlib") - ELSE() - ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib") - LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib") - LIST(APPEND LIBGIT2_OBJECTS $) - ADD_FEATURE_INFO(zlib ON "using bundled zlib") - ENDIF() +IF(USE_BUNDLED_ZLIB STREQUAL "Chromium") + ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/chromium-zlib" "${libgit2_BINARY_DIR}/deps/chromium-zlib") + LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/chromium-zlib") + LIST(APPEND LIBGIT2_OBJECTS $) + ADD_FEATURE_INFO(zlib ON "using (Chromium) bundled zlib") +ELSEIF(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND) + ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib") + LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib") + LIST(APPEND LIBGIT2_OBJECTS $) + ADD_FEATURE_INFO(zlib ON "using bundled zlib") ENDIF() # Optional external dependency: libssh2 From 556e07473b80c8d4e763bda23ecf522136c7d06c Mon Sep 17 00:00:00 2001 From: Josh Stockin Date: Mon, 4 Jan 2021 10:56:01 -0600 Subject: [PATCH 0219/1616] Move doc comment about `GIT_BLOB_FILTER_OPTIONS_VERSION` Removes doc comment on `git_blob_filter_options.version`, moves information to `git_blob_filter_options` doc comment to remain consistent with other options structures' documentation. `git_blob_filter_options_init` still needed; should be added in another commit/PR (it's out of the scope of this PR, #5759), update this documentation again. --- include/git2/blob.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/git2/blob.h b/include/git2/blob.h index 866b8bdd7a8..29588ecf052 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -118,9 +118,11 @@ typedef enum { /** * The options used when applying filter options to a file. + * + * Initialize with `GIT_BLOB_FILTER_OPTIONS_VERSION`. + * */ typedef struct { - /** The struct version; set to `GIT_BLOB_FILTER_OPTIONS_VERSION`. */ int version; /** Flags to control the filtering process, see `git_blob_filter_flag_t` above */ From f1151fb31ef0069cad1520739dd54eae0eca2652 Mon Sep 17 00:00:00 2001 From: Josh Stockin Date: Mon, 4 Jan 2021 16:29:10 -0600 Subject: [PATCH 0220/1616] Fix documentation for git_blob_filter_options --- include/git2/blob.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/blob.h b/include/git2/blob.h index 29588ecf052..0c6372c64bd 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -119,7 +119,7 @@ typedef enum { /** * The options used when applying filter options to a file. * - * Initialize with `GIT_BLOB_FILTER_OPTIONS_VERSION`. + * Initialize with `GIT_BLOB_FILTER_OPTIONS_INIT`. * */ typedef struct { From d9c1538775ff77e08427d82872ac28b42f7f81ba Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 5 Jan 2021 14:29:58 +0000 Subject: [PATCH 0221/1616] blob: add git_blob_filter_options_init The `git_blob_filter_options_init` function should be included, to allow callers in FFI environments to let us initialize an options structure for them. --- include/git2/blob.h | 12 ++++++++++++ src/blob.c | 9 +++++++++ tests/core/structinit.c | 5 +++++ 3 files changed, 26 insertions(+) diff --git a/include/git2/blob.h b/include/git2/blob.h index 0c6372c64bd..c2a968c933f 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -132,6 +132,18 @@ typedef struct { #define GIT_BLOB_FILTER_OPTIONS_VERSION 1 #define GIT_BLOB_FILTER_OPTIONS_INIT {GIT_BLOB_FILTER_OPTIONS_VERSION, GIT_BLOB_FILTER_CHECK_FOR_BINARY} +/** + * Initialize git_blob_filter_options structure + * + * Initializes a `git_blob_filter_options` with default values. Equivalent + * to creating an instance with `GIT_BLOB_FILTER_OPTIONS_INIT`. + * + * @param opts The `git_blob_filter_options` struct to initialize. + * @param version The struct version; pass `GIT_BLOB_FILTER_OPTIONS_VERSION`. + * @return Zero on success; -1 on failure. + */ +GIT_EXTERN(int) git_blob_filter_options_init(git_blob_filter_options *opts, unsigned int version); + /** * Get a buffer with the filtered content of a blob. * diff --git a/src/blob.c b/src/blob.c index 97069645c8b..545c10eb8b0 100644 --- a/src/blob.c +++ b/src/blob.c @@ -408,6 +408,15 @@ int git_blob_is_binary(const git_blob *blob) return git_buf_text_is_binary(&content); } +int git_blob_filter_options_init( + git_blob_filter_options *opts, + unsigned int version) +{ + GIT_INIT_STRUCTURE_FROM_TEMPLATE(opts, version, + git_blob_filter_options, GIT_BLOB_FILTER_OPTIONS_INIT); + return 0; +} + int git_blob_filter( git_buf *out, git_blob *blob, diff --git a/tests/core/structinit.c b/tests/core/structinit.c index 192096be3f8..b6377bdde57 100644 --- a/tests/core/structinit.c +++ b/tests/core/structinit.c @@ -82,6 +82,11 @@ void test_core_structinit__compare(void) git_blame_options, GIT_BLAME_OPTIONS_VERSION, \ GIT_BLAME_OPTIONS_INIT, git_blame_options_init); + /* blob_filter_options */ + CHECK_MACRO_FUNC_INIT_EQUAL( \ + git_blob_filter_options, GIT_BLOB_FILTER_OPTIONS_VERSION, \ + GIT_BLOB_FILTER_OPTIONS_INIT, git_blob_filter_options_init); + /* checkout */ CHECK_MACRO_FUNC_INIT_EQUAL( \ git_checkout_options, GIT_CHECKOUT_OPTIONS_VERSION, \ From 855f2998acfa58ce6f4a7a1a1b3d5d48475b2330 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 5 Jan 2021 14:45:14 +0000 Subject: [PATCH 0222/1616] blob: fix name of `GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD` `GIT_BLOB_FILTER_ATTTRIBUTES_FROM_HEAD` is misspelled, it should be `GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD`, and it would be if it were not for the MacBook Pro keyboard and my inattentiveness. --- include/git2/blob.h | 2 +- include/git2/deprecated.h | 9 ++++++--- src/blob.c | 2 +- tests/filter/bare.c | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/include/git2/blob.h b/include/git2/blob.h index 8e977267dd5..91b2c1475bb 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -113,7 +113,7 @@ typedef enum { * When set, filters will be loaded from a `.gitattributes` file * in the HEAD commit. */ - GIT_BLOB_FILTER_ATTTRIBUTES_FROM_HEAD = (1 << 2), + GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD = (1 << 2), } git_blob_filter_flag_t; /** diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index 4e43c453658..79f637a7f33 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -80,16 +80,19 @@ typedef git_attr_value_t git_attr_t; /**@}*/ -/** @name Deprecated Blob Functions +/** @name Deprecated Blob Functions and Constants * - * These functions are retained for backward compatibility. The newer - * versions of these functions should be preferred in all new code. + * These functions and enumeration values are retained for backward + * compatibility. The newer versions of these functions and values + * should be preferred in all new code. * * There is no plan to remove these backward compatibility values at * this time. */ /**@{*/ +#define GIT_BLOB_FILTER_ATTTRIBUTES_FROM_HEAD GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD + GIT_EXTERN(int) git_blob_create_fromworkdir(git_oid *id, git_repository *repo, const char *relative_path); GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *id, git_repository *repo, const char *path); GIT_EXTERN(int) git_blob_create_fromstream( diff --git a/src/blob.c b/src/blob.c index 97069645c8b..b9739b69a0f 100644 --- a/src/blob.c +++ b/src/blob.c @@ -439,7 +439,7 @@ int git_blob_filter( if ((opts.flags & GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES) != 0) flags |= GIT_FILTER_NO_SYSTEM_ATTRIBUTES; - if ((opts.flags & GIT_BLOB_FILTER_ATTTRIBUTES_FROM_HEAD) != 0) + if ((opts.flags & GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD) != 0) flags |= GIT_FILTER_ATTRIBUTES_FROM_HEAD; if (!(error = git_filter_list_load( diff --git a/tests/filter/bare.c b/tests/filter/bare.c index 430931ee8db..7319b5203a3 100644 --- a/tests/filter/bare.c +++ b/tests/filter/bare.c @@ -10,7 +10,7 @@ void test_filter_bare__initialize(void) cl_git_pass(git_repository_open(&g_repo, "crlf.git")); filter_opts.flags |= GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES; - filter_opts.flags |= GIT_BLOB_FILTER_ATTTRIBUTES_FROM_HEAD; + filter_opts.flags |= GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD; } void test_filter_bare__cleanup(void) From ddafbafef54677c3466260e52b135d5dff832624 Mon Sep 17 00:00:00 2001 From: Josh Stockin Date: Tue, 5 Jan 2021 17:26:50 -0600 Subject: [PATCH 0223/1616] Update documentation for git_blob_filter_options Adds info about initializing options with git_blob_filter_options_init --- include/git2/blob.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/git2/blob.h b/include/git2/blob.h index c2a968c933f..741b28f4cba 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -119,7 +119,8 @@ typedef enum { /** * The options used when applying filter options to a file. * - * Initialize with `GIT_BLOB_FILTER_OPTIONS_INIT`. + * Initialize with `GIT_BLOB_FILTER_OPTIONS_INIT`. Alternatively, you can + * use `git_blob_filter_options_init`. * */ typedef struct { From c41871e542dce9cfb1b5cf1814e17c65c7e04ce4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 7 Jan 2021 12:22:08 +0000 Subject: [PATCH 0224/1616] fetch: test when HEAD points to nonexistent branch When HEAD points to a nonexistent or invalid branch - for example, to `refs/heads/` - the fetch should be permitted to continue, but we should not use it when creating the `for merge` option in the FETCH_HEAD file. (This emulates git's behavior.) --- tests/fetchhead/nonetwork.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c index 6cea6d166c9..02e7ecfdb1a 100644 --- a/tests/fetchhead/nonetwork.c +++ b/tests/fetchhead/nonetwork.c @@ -319,6 +319,16 @@ static int assert_master_for_merge(const char *ref, const char *url, const git_o return 0; } +static int assert_none_for_merge(const char *ref, const char *url, const git_oid *id, unsigned int is_merge, void *data) +{ + GIT_UNUSED(ref); + GIT_UNUSED(url); + GIT_UNUSED(id); + GIT_UNUSED(data); + + return is_merge ? -1 : 0; +} + void test_fetchhead_nonetwork__unborn_with_upstream(void) { git_repository *repo; @@ -366,6 +376,25 @@ void test_fetchhead_nonetwork__fetch_into_repo_with_symrefs(void) cl_git_sandbox_cleanup(); } +void test_fetchhead_nonetwork__fetch_into_repo_with_invalid_head(void) +{ + git_remote *remote; + char *strings[] = { "refs/heads/*:refs/remotes/origin/*" }; + git_strarray refspecs = { strings, 1 }; + + cl_set_cleanup(&cleanup_repository, "./test1"); + cl_git_pass(git_repository_init(&g_repo, "./test1", 0)); + + /* HEAD pointing to nonexistent branch */ + cl_git_rewritefile("./test1/.git/HEAD", "ref: refs/heads/\n"); + + cl_git_pass(git_remote_create_anonymous(&remote, g_repo, cl_fixture("testrepo.git"))); + cl_git_pass(git_remote_fetch(remote, &refspecs, NULL, NULL)); + cl_git_pass(git_repository_fetchhead_foreach(g_repo, assert_none_for_merge, NULL)); + + git_remote_free(remote); +} + void test_fetchhead_nonetwork__quote_in_branch_name(void) { cl_set_cleanup(&cleanup_repository, "./test1"); From 32350e89d8e3ca245def9ccee05aa21c92e10726 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 7 Jan 2021 14:01:30 +0000 Subject: [PATCH 0225/1616] remote: don't update invalid refs If a symbolic reference points to something invalid, then do not try to update it. --- src/remote.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/remote.c b/src/remote.c index 29e15bbdf0a..55effccfb91 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1141,6 +1141,16 @@ static int remote_head_for_ref(git_remote_head **out, git_remote *remote, git_re ref_name = git_reference_name(resolved_ref); } + /* + * The ref name may be unresolvable - perhaps it's pointing to + * something invalid. In this case, there is no remote head for + * this ref. + */ + if (!ref_name) { + error = 0; + goto cleanup; + } + if ((error = ref_to_update(&update, &remote_name, remote, spec, ref_name)) < 0) goto cleanup; From 3f4bc2132c933e1a1719555dde1207d4896f7a12 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 7 Jan 2021 14:05:02 +0000 Subject: [PATCH 0226/1616] repo: ignore empty init.defaultbranch The init.defaultbranch option may be set, but empty. In this case, we should ignore it instead of trying to set our default branch to `refs/heads/`. --- src/repository.c | 3 ++- tests/repo/init.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/repository.c b/src/repository.c index 948413d17b2..de1a895828a 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2092,7 +2092,8 @@ static int repo_init_head(const char *repo_dir, const char *given) if (given) { initial_head = given; } else if ((error = git_config_open_default(&cfg)) >= 0 && - (error = git_config_get_string_buf(&cfg_branch, cfg, "init.defaultbranch")) >= 0) { + (error = git_config_get_string_buf(&cfg_branch, cfg, "init.defaultbranch")) >= 0 && + *cfg_branch.ptr) { initial_head = cfg_branch.ptr; } diff --git a/tests/repo/init.c b/tests/repo/init.c index b86e09a58bc..01371ba786e 100644 --- a/tests/repo/init.c +++ b/tests/repo/init.c @@ -688,3 +688,19 @@ void test_repo_init__defaultbranch_config(void) git_reference_free(head); } + +void test_repo_init__defaultbranch_config_empty(void) +{ + git_reference *head; + + cl_set_cleanup(&cleanup_repository, "repo"); + + create_tmp_global_config("tmp_global_path", "init.defaultbranch", ""); + + cl_git_pass(git_repository_init(&g_repo, "repo", 0)); + cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); + + cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head)); + + git_reference_free(head); +} From 1ddffb0584231ffc3a36a009f96892ba083efccd Mon Sep 17 00:00:00 2001 From: lhchavez Date: Thu, 7 Jan 2021 06:11:01 -0800 Subject: [PATCH 0227/1616] github-actions: Also rename the main branch here This should fix the CI. --- .github/workflows/main.yml | 8 ++++---- .github/workflows/nightly.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 091f51844fb..f101eda65f3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,12 +1,12 @@ # Continuous integration and pull request validation builds for the -# master and maintenance branches. +# main and maintenance branches. name: CI Build on: push: - branches: [ master, maint/* ] + branches: [ main, maint/* ] pull_request: - branches: [ master, maint/* ] + branches: [ main, maint/* ] env: docker-registry: docker.pkg.github.com @@ -254,7 +254,7 @@ jobs: # Generate documentation using docurium. We'll upload the documentation # as a build artifact so that it can be reviewed as part of a pull # request or in a forked build. For CI builds in the main repository's - # master branch, we'll push the gh-pages branch back up so that it is + # main branch, we'll push the gh-pages branch back up so that it is # published to our documentation site. documentation: name: Generate documentation diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index fa83491ba39..2f56fdb7f21 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,4 +1,4 @@ -# Nightly build for the master branch across multiple targets. +# Nightly build for the main branch across multiple targets. name: Nightly Build on: From d50d3db64a7c3a80479954440b373237ee2d716f Mon Sep 17 00:00:00 2001 From: lhchavez Date: Thu, 7 Jan 2021 05:43:30 -0800 Subject: [PATCH 0228/1616] midx: Fix a bug in `git_midx_needs_refresh()` The very last check in the freshness check for the midx was wrong >< This was also because this function was not tested. --- src/midx.c | 2 +- tests/pack/midx.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/midx.c b/src/midx.c index ee93b03c117..60858716d06 100644 --- a/src/midx.c +++ b/src/midx.c @@ -364,7 +364,7 @@ bool git_midx_needs_refresh( if (bytes_read != GIT_OID_RAWSZ) return true; - return git_oid_cmp(&idx_checksum, &idx->checksum) == 0; + return !git_oid_equal(&idx_checksum, &idx->checksum); } int git_midx_entry_find( diff --git a/tests/pack/midx.c b/tests/pack/midx.c index 92d9ae24c39..0d7efbef10b 100644 --- a/tests/pack/midx.c +++ b/tests/pack/midx.c @@ -15,6 +15,7 @@ void test_pack_midx__parse(void) cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); cl_git_pass(git_buf_joinpath(&midx_path, git_repository_path(repo), "objects/pack/multi-pack-index")); cl_git_pass(git_midx_open(&idx, git_buf_cstr(&midx_path))); + cl_assert_equal_i(git_midx_needs_refresh(idx, git_buf_cstr(&midx_path)), 0); cl_git_pass(git_oid_fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5")); cl_git_pass(git_midx_entry_find(&e, idx, &id, GIT_OID_HEXSZ)); From ff6f675495083d9792b8d54457e40564f3d5bd51 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Thu, 7 Jan 2021 05:44:16 -0800 Subject: [PATCH 0229/1616] Use `p_pwrite`/`p_pread` consistently throughout the codebase This change stops using the seek+read/write combo to perform I/O with an offset, since this is faster by one system call (and also more atomic and therefore safer). --- src/indexer.c | 4 +--- src/midx.c | 7 +------ src/pack.c | 3 +-- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/indexer.c b/src/indexer.c index ba82d716db8..d546888ccd9 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -656,7 +656,6 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size) size_t page_offset; off64_t page_start; off64_t current_size = idx->pack->mwf.size; - int fd = idx->pack->mwf.fd; int error; if (!size) @@ -673,8 +672,7 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size) page_offset = new_size % mmap_alignment; page_start = new_size - page_offset; - if (p_lseek(fd, page_start + mmap_alignment - 1, SEEK_SET) < 0 || - p_write(idx->pack->mwf.fd, data, 1) < 0) { + if (p_pwrite(idx->pack->mwf.fd, data, 1, page_start + mmap_alignment - 1) < 0) { git_error_set(GIT_ERROR_OS, "cannot extend packfile '%s'", idx->pack->pack_name); return -1; } diff --git a/src/midx.c b/src/midx.c index ee93b03c117..0eff2e7144b 100644 --- a/src/midx.c +++ b/src/midx.c @@ -353,12 +353,7 @@ bool git_midx_needs_refresh( return true; } - if (p_lseek(fd, -GIT_OID_RAWSZ, SEEK_END) < 0) { - p_close(fd); - return true; - } - - bytes_read = p_read(fd, &idx_checksum, GIT_OID_RAWSZ); + bytes_read = p_pread(fd, &idx_checksum, GIT_OID_RAWSZ, st.st_size - GIT_OID_RAWSZ); p_close(fd); if (bytes_read != GIT_OID_RAWSZ) diff --git a/src/pack.c b/src/pack.c index 30b1464b6a3..5d284ca9e12 100644 --- a/src/pack.c +++ b/src/pack.c @@ -1130,8 +1130,7 @@ static int packfile_open_locked(struct git_pack_file *p) /* Verify the pack matches its index. */ if (p->num_objects != ntohl(hdr.hdr_entries) || - p_lseek(p->mwf.fd, p->mwf.size - GIT_OID_RAWSZ, SEEK_SET) == -1 || - p_read(p->mwf.fd, sha1.id, GIT_OID_RAWSZ) < 0) + p_pread(p->mwf.fd, sha1.id, GIT_OID_RAWSZ, p->mwf.size - GIT_OID_RAWSZ) < 0) goto cleanup; idx_sha1 = ((unsigned char *)p->index_map.data) + p->index_map.len - 40; From 4ac12634195e225893fd458c0aab3fc5a9bdaae5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 7 Jan 2021 15:08:37 +0000 Subject: [PATCH 0230/1616] README: instructions for using libgit2 without compiling --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index 9bbdeaf3baf..23c569e4c67 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Additionally, the example code has been released to the public domain (see the Table of Contents ================= +* [Using libgit2](#using-libgit2) * [Quick Start](#quick-start) * [Getting Help](#getting-help) * [What It Can Do](#what-it-can-do) @@ -52,6 +53,28 @@ Table of Contents * [How Can I Contribute?](#how-can-i-contribute) * [License](#license) +Using libgit2 +============= + +Most of these instructions assume that you're writing an application +in C and want to use libgit2 directly. If you're _not_ using C, +and you're writing in a different language or platform like .NET, +Node.js, or Ruby, then there is probably a +"[language binding](#language-bindings)" that you can use to take care +of the messy tasks of calling into native code. + +But if you _do_ want to use libgit2 directly - because you're building +an application in C - then you may be able use an existing binary. +There are packages for the +[vcpkg](https://github.com/Microsoft/vcpkg) and +[conan](https://conan.io/center/libgit2) +package managers. And libgit2 is available in +[Homebrew](https://formulae.brew.sh/formula/libgit2) and most Linux +distributions. + +However, these versions _may_ be outdated and we recommend using the +latest version if possible. Thankfully libgit2 is not hard to compile. + Quick Start =========== From 923c0f7b763bf3d20f9cd8f02ab9b1d400c733ab Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 7 Jan 2021 17:34:17 +0000 Subject: [PATCH 0231/1616] clone: set refs/remotes/origin/HEAD when branch is specified When a branch is specified to check out in clone, update the remote tracking `HEAD` to point to it. This mimics git's behavior, when `git clone -b ` is used. --- src/clone.c | 63 +++++++++++++++++++++++++++-------------- tests/clone/nonetwork.c | 8 ++++++ 2 files changed, 50 insertions(+), 21 deletions(-) diff --git a/src/clone.c b/src/clone.c index 7ae90b09ea3..6d5ebf6b059 100644 --- a/src/clone.c +++ b/src/clone.c @@ -162,6 +162,37 @@ static int update_head_to_default(git_repository *repo) return error; } +static int update_remote_head_byname( + git_repository *repo, + const char *remote_name, + const char *tracking_branch_name, + const char *reflog_message) +{ + git_buf tracking_head_name = GIT_BUF_INIT; + git_reference *remote_head = NULL; + int error; + + if ((error = git_buf_printf(&tracking_head_name, + "%s%s/%s", + GIT_REFS_REMOTES_DIR, + remote_name, + GIT_HEAD_FILE)) < 0) + goto cleanup; + + error = git_reference_symbolic_create( + &remote_head, + repo, + git_buf_cstr(&tracking_head_name), + tracking_branch_name, + true, + reflog_message); + +cleanup: + git_reference_free(remote_head); + git_buf_dispose(&tracking_head_name); + return error; +} + static int update_remote_head( git_repository *repo, git_remote *remote, @@ -169,9 +200,7 @@ static int update_remote_head( const char *reflog_message) { git_refspec *refspec; - git_reference *remote_head = NULL; - git_buf remote_head_name = GIT_BUF_INIT; - git_buf remote_branch_name = GIT_BUF_INIT; + git_buf tracking_branch_name = GIT_BUF_INIT; int error; /* Determine the remote tracking ref name from the local branch */ @@ -184,30 +213,19 @@ static int update_remote_head( } if ((error = git_refspec_transform( - &remote_branch_name, + &tracking_branch_name, refspec, git_buf_cstr(target))) < 0) goto cleanup; - if ((error = git_buf_printf(&remote_head_name, - "%s%s/%s", - GIT_REFS_REMOTES_DIR, - git_remote_name(remote), - GIT_HEAD_FILE)) < 0) - goto cleanup; - - error = git_reference_symbolic_create( - &remote_head, + error = update_remote_head_byname( repo, - git_buf_cstr(&remote_head_name), - git_buf_cstr(&remote_branch_name), - true, + git_remote_name(remote), + git_buf_cstr(&tracking_branch_name), reflog_message); cleanup: - git_reference_free(remote_head); - git_buf_dispose(&remote_branch_name); - git_buf_dispose(&remote_head_name); + git_buf_dispose(&tracking_branch_name); return error; } @@ -277,8 +295,11 @@ static int update_head_to_branch( if ((retcode = git_reference_lookup(&remote_ref, repo, git_buf_cstr(&remote_branch_name))) < 0) goto cleanup; - retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch, - reflog_message); + if ((retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch, + reflog_message)) < 0) + goto cleanup; + + retcode = update_remote_head_byname(repo, remote_name, remote_branch_name.ptr, reflog_message); cleanup: git_reference_free(remote_ref); diff --git a/tests/clone/nonetwork.c b/tests/clone/nonetwork.c index 7ca49085cfe..d4da3d3af32 100644 --- a/tests/clone/nonetwork.c +++ b/tests/clone/nonetwork.c @@ -158,6 +158,8 @@ void test_clone_nonetwork__can_prevent_the_checkout_of_a_standard_repo(void) void test_clone_nonetwork__can_checkout_given_branch(void) { + git_reference *remote_head; + g_options.checkout_branch = "test"; cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); @@ -167,6 +169,12 @@ void test_clone_nonetwork__can_checkout_given_branch(void) cl_assert_equal_s(git_reference_name(g_ref), "refs/heads/test"); cl_assert(git_path_exists("foo/readme.txt")); + + cl_git_pass(git_reference_lookup(&remote_head, g_repo, "refs/remotes/origin/HEAD")); + cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(remote_head)); + cl_assert_equal_s("refs/remotes/origin/test", git_reference_symbolic_target(remote_head)); + + git_reference_free(remote_head); } static int clone_cancel_fetch_transfer_progress_cb( From 3fd57a75e9dd0c4b0e40ee6e21568d40bd70d29b Mon Sep 17 00:00:00 2001 From: lhchavez Date: Mon, 4 Jan 2021 18:22:43 -0800 Subject: [PATCH 0232/1616] commit-graph: Introduce a parser for commit-graph files This change is the first in a series to add support for git's commit-graph. This should speed up commit graph traversals by avoiding object parsing and allowing some operations to terminate earlier. Part of: #5757 --- fuzzers/commit_graph_fuzzer.c | 75 +++++ .../005682ce1cb5b20c20fccf4be5dbd47ca399e53e | Bin 0 -> 1092 bytes .../00574fc29fd1323e93d18d625cde80d3ea20e8cc | Bin 0 -> 2428 bytes .../00916ec21ddbd3c622bde6e4dc824250176b9e88 | Bin 0 -> 223 bytes .../00b6dde4b8d5e68a5ec40d88c39134cf2f1f8bc3 | Bin 0 -> 82 bytes .../020f0e77e42d8b3810019050f4c5ceadd205b37c | Bin 0 -> 965 bytes .../02739c05abc1715fac1ce995b532e482abc8d4dc | Bin 0 -> 982 bytes .../02a276faa5dc8c7df5b82a57ab6cd195a13e4ae0 | Bin 0 -> 671 bytes .../02de15987d68a97db3d9fd964cfd785bcbd54d3a | Bin 0 -> 96 bytes .../02e106f97a91b1d3aef4dd2d31368ae5077bd42b | Bin 0 -> 146 bytes .../038555bcb4cc2daf764840f79ebce4023bdb7670 | Bin 0 -> 240 bytes .../04c159a04b0732e04ac4c59ed3356860af8dffce | Bin 0 -> 1385 bytes .../0560ec993882ffbd8d46dcab0ed430089c4f2aa1 | Bin 0 -> 86 bytes .../059b3aab3fde6b4c9404aff83fed638596f594bb | Bin 0 -> 90 bytes .../06168e726aa0260f520165be4ea0c88244831049 | Bin 0 -> 430 bytes .../066d1ec700a526b97009cedd0305b6a47242faba | Bin 0 -> 1980 bytes .../086a5f8cbfa9f058b5c938a6eb724c9e4c5f84f3 | Bin 0 -> 68 bytes .../089313c698f3e351433e9a45af2ace1d85b9673e | Bin 0 -> 86 bytes .../092eb973a771fa14cf0b567d65bd2c99130f543e | Bin 0 -> 32 bytes .../094b8cd1aa3e40b1f9ff83680892d52e246df0f8 | Bin 0 -> 155 bytes .../0ce990c9c2ec121b8c78ba2bdf84679e04c0bdae | Bin 0 -> 278 bytes .../0dd0770c34fcf6b1f13219450190616d344db021 | Bin 0 -> 264 bytes .../0e2b2e6a32733b8a625bc7e812e2ea508d69a5e4 | Bin 0 -> 2221 bytes .../0e8d0bd07c543d708aecaca377106492b7a74fa3 | Bin 0 -> 287 bytes .../0f0d16e1b8c8671dbe1074115c1d86aa9b359e7e | Bin 0 -> 551 bytes .../102ef78036de5a30927e7f751377b05441c41a08 | Bin 0 -> 1980 bytes .../10494e7cc9cb8dff289c431d7560bcee0d1b14ed | Bin 0 -> 157 bytes .../107b11d86381345f50aa19b8485477a870ff399f | Bin 0 -> 2908 bytes .../10bb37e18fb3c0897dabacf9c464b4d324007dc3 | Bin 0 -> 346 bytes .../10ee715f64b08549c3e8261204276694728eb841 | Bin 0 -> 174 bytes .../123e4eeb7a731f48d06e336b4d29af717f8b6550 | Bin 0 -> 123 bytes .../125a228afb923970e0a6d4412f7257ba998594a1 | Bin 0 -> 283 bytes .../130d96c16fba06dcbe7e2a661ab959a3274a4bd9 | Bin 0 -> 214 bytes .../131c5a2fec55cb0d63f7dc055d6fad5f3dc3c974 | Bin 0 -> 408 bytes .../13e562d61acb3aa36260a819a00b07ff16450335 | Bin 0 -> 3784 bytes .../1414e6e8ab6bad1b5c51fed807c514a9d6575e66 | Bin 0 -> 584 bytes .../1432d191846ae2d0e381813efcfacff2f1dba0e4 | Bin 0 -> 475 bytes .../14a84cdc6f8d432be4cd3d3eafce92ae385e472f | Bin 0 -> 472 bytes .../14e3e735dba88791f2cadd6e0dc5d662a104a6d7 | Bin 0 -> 214 bytes .../1574abb020203103ea629d677edd21c967fc0f4c | Bin 0 -> 96 bytes .../169cc492ba94948a6206765436881a1a0c601780 | Bin 0 -> 199 bytes .../16a2130c1d75129f3bae3bf8f2c2de41fb3533c0 | Bin 0 -> 351 bytes .../16ba602eadfc9a3f74c0845394eda0de42b61571 | Bin 0 -> 345 bytes .../17555fb2dfc444d171ba686667d72e388bd6c041 | Bin 0 -> 63 bytes .../1a10450d99c1e53d9b7f97b8014cb7fc01906ef2 | Bin 0 -> 956 bytes .../1af670b5515231fc04b2be9038ee30a7e066b09b | Bin 0 -> 650 bytes .../1b72cfa68259e3f3b3802906902a0a29368f86b5 | Bin 0 -> 227 bytes .../1c62ac5d632aa9e449a4335b675941107d8825ae | Bin 0 -> 497 bytes .../1d95b5db2f802011b33d10212a66fbe40827dfd4 | Bin 0 -> 284 bytes .../1e068537ce1211a325aab42ae1263a109131c9f9 | Bin 0 -> 81 bytes .../1e9c882c9d33304a5791ef6c98eee65e142bd7fd | Bin 0 -> 114 bytes .../1f54935df929403a29e77591c97f767d94871aea | Bin 0 -> 202 bytes .../206015659641771bb0d668728c2fdc4209e65dda | Bin 0 -> 152 bytes .../2096493a2bcc2d15b7ae5bf3112fe49c39976ad8 | Bin 0 -> 146 bytes .../209b74e08abe8c787b7c5ba81e51cb69c57ecded | Bin 0 -> 519 bytes .../21137876575fbca357fc0c96db1de73c6737e1ae | Bin 0 -> 32 bytes .../2143d9db9802f076c72a71184cd9d0cb4581e9e7 | Bin 0 -> 466 bytes .../21a52a5282145407d951ac73c2ff27876783899d | Bin 0 -> 408 bytes .../21d5c8c8ac3a09bcba5388c472df32795986a5cb | 1 + .../22170d1110a1c18009b7feb21a470681f55e85fb | Bin 0 -> 469 bytes .../22f55dff94785f24252d7a070f713840f59b0870 | Bin 0 -> 609 bytes .../23d10ee9694e1c66bedc7060990f19a2ac3eaee3 | Bin 0 -> 766 bytes .../2435430ca19502c3b0ec4987508d4a8fbdbc898c | Bin 0 -> 349 bytes .../244d2ea0c5c3117000b599cfab37680ba8f04513 | Bin 0 -> 216 bytes .../248bf94143d150da2459cfdca099c30c6daff00a | Bin 0 -> 1049 bytes .../25bc53498129bb3717671f00c355d2637a91c86a | Bin 0 -> 531 bytes .../2614f60da2d7e291501397238366d27513bff773 | Bin 0 -> 80 bytes .../2651b3d5a8b4616b1faa81dabe27ab2712a27561 | Bin 0 -> 787 bytes .../270257a2872b33dd13c4fd466cbc1ae67d613f9b | Bin 0 -> 600 bytes .../2830c6244c74656f6c5649c8226953905a582a38 | Bin 0 -> 353 bytes .../2889a85c07c20551ff0b97fc640e3c91b33aa4a1 | Bin 0 -> 1067 bytes .../295ce43fdd56def8948d1ba2bfa7fdf0c47b5318 | Bin 0 -> 2227 bytes .../296cbb94c4e68ab86972a174405308ee34d0c40f | Bin 0 -> 3003 bytes .../2975adf222cad108ec90d8225fd655e30e3bf253 | Bin 0 -> 407 bytes .../29f5d27760c9254ab4db661a6cd0323dd11c34ca | Bin 0 -> 282 bytes .../2a359fb09eaad968e57d353453908027645873d1 | Bin 0 -> 190 bytes .../2a6b65a8d6c28febaa081d220a4433f8366d02bc | Bin 0 -> 3325 bytes .../2b14dcade4d0919b0a17830fe353738015f492a6 | Bin 0 -> 214 bytes .../2b298a13abbd9829e965424a1486baa13d4166c4 | Bin 0 -> 146 bytes .../2b44d8cd8e70e25172b4c740ebe38ef411c965b3 | Bin 0 -> 168 bytes .../2b590c4e61fdfcf21c017b29440747a1894b1534 | Bin 0 -> 217 bytes .../2becb18a971ae30e1a8f6680982fd7305708caa0 | Bin 0 -> 324 bytes .../2bf78b02099a1fe4ce50d065254e843ca55e280f | Bin 0 -> 412 bytes .../2c1541ecd01aa7b9e99bccfe9804198b3e79f118 | Bin 0 -> 2267 bytes .../2c6798057af5894c27631ff63e845fe1e4bdc9ee | Bin 0 -> 221 bytes .../2cf7eb7fe489e5acd64df755e820c871784c2ba1 | Bin 0 -> 182 bytes .../2d49ba35ca404baa0d593925f36a81ce53943c8d | Bin 0 -> 466 bytes .../2d507d42ca43ffc2f3c8892826e1db74144ec096 | Bin 0 -> 2772 bytes .../2e4da693e3e336d2b1a40311a7ccf94def035b6b | Bin 0 -> 280 bytes .../2e71ff86128b5618f0f067c407a76ff645ae2019 | Bin 0 -> 602 bytes .../2eb777c6d7e6ee9bd7a44e37372595043aad596b | Bin 0 -> 141 bytes .../2ec3ebffba165b9dd49e755a9e77e23aed796628 | Bin 0 -> 138 bytes .../302703e3b0d74219868aca39ee7593944c0b2400 | Bin 0 -> 126 bytes .../3048c6908dc3176707fa8bcb0196824e3358357a | Bin 0 -> 395 bytes .../30616cb39d3ad6060324fada03709d611ad28d5c | Bin 0 -> 2593 bytes .../306beadd9b3135a00037323760eb5377c88a403e | Bin 0 -> 315 bytes .../31464a6fbad023923a7e4700fc11564e811bcbd2 | Bin 0 -> 2182 bytes .../317f4bcfecf066961ef1982d551cd14e63c9f008 | Bin 0 -> 215 bytes .../31b2248faaabbec69a06098c8cb0f69c5d0aa208 | Bin 0 -> 3848 bytes .../31d1c3d1147385d58dbe6f82898a5523320fbcac | Bin 0 -> 415 bytes .../32c9bc1616a78a230a3724abc02150db1cc40aa0 | Bin 0 -> 152 bytes .../331e2866416b091252f0299e98d32cfb29237029 | Bin 0 -> 5 bytes .../331eb3876dd2f3f0bd51f380ac431d86d6e3bb5e | Bin 0 -> 1072 bytes .../346bd6eaeadeafcb840ff9441614b309330db63e | Bin 0 -> 2850 bytes .../349931f447981f21476481448576e805c093a25b | Bin 0 -> 269 bytes .../34a2da1e9adaac1b4be1d40b1ece81fe00643d49 | Bin 0 -> 1302 bytes .../34bb8f475e7384a8a39618fd15fdc5fb1b12c1a1 | Bin 0 -> 391 bytes .../351a036c6eb95db9364706b861f7e75ad26194e8 | Bin 0 -> 1980 bytes .../355452c1da8e7689d816d67cdde040b5df7eabd7 | Bin 0 -> 298 bytes .../35c157ad2b100b4f334cddcf3dea6ef2d85462be | Bin 0 -> 127 bytes .../36a81a45eabfcf53e1ae0361aa234791e2fdb750 | Bin 0 -> 128 bytes .../36ee20f6dbeb3a34e91eafbbe2e379f9ac6cfa43 | Bin 0 -> 86 bytes .../377627c19bcac6adc880202048a9eac07b5417d4 | Bin 0 -> 350 bytes .../38747e7c8bec2f9c923739d50ba54ff88ba6503f | Bin 0 -> 603 bytes .../3945843a6fab2ec71030f09b237c125b97cd3ea5 | Bin 0 -> 601 bytes .../396321d39b82ffaccbc64115117df7e822b0f515 | Bin 0 -> 207 bytes .../396e78eb9b54e2cefb52cd76a22137c8abd6cbcf | Bin 0 -> 868 bytes .../39c1ab66035adc104cd06a6d98b77668172d21af | Bin 0 -> 243 bytes .../3a1078c35f5401ce09b5ba921fc348dde37530bb | Bin 0 -> 260 bytes .../3aa3d8f40392d1c863d23799b8ec0aedc7191302 | Bin 0 -> 192 bytes .../3b08c505601271cb92345ec7f0ff0b28daf90a9c | Bin 0 -> 525 bytes .../3b41702587be45f678b36823ad2f7e5002337dc4 | Bin 0 -> 343 bytes .../3b69108cc919aba0248f9b864d4e71c5f6d1931e | Bin 0 -> 208 bytes .../3b90507501bb3bcfe0094f9c92cc2869f1a7dda5 | Bin 0 -> 135 bytes .../3bc7fe44c3a1464dd35a4d22b482f46cdeda0405 | Bin 0 -> 188 bytes .../3ce99994986efb6df3f3568423e0077b53c7ef78 | Bin 0 -> 1178 bytes .../3d6cb3ba21181c9f0ab08b2608eab773f36773f2 | Bin 0 -> 279 bytes .../3d8ec41450b943d5dea73fb1e393960b03d7c3b9 | Bin 0 -> 2210 bytes .../3e29e8baaac0f6c7e4cf3d5adca2ab3a2c491ac7 | Bin 0 -> 310 bytes .../3e9469b3c68ba334671aacda7a7669b0e97b74d6 | Bin 0 -> 76 bytes .../3eeda3bfa7abef69911c94520c009a08c49b9942 | Bin 0 -> 237 bytes .../3f0f5021016451b57f673d0603cd9e4830c2198d | Bin 0 -> 473 bytes .../3f46540fbd94bf0337c1d0d7437ec992a3568f09 | Bin 0 -> 178 bytes .../402d9c25d5833d42630882ab5c57833266bef785 | Bin 0 -> 617 bytes .../4048bb3c26d67c345630ff9e86db551a3add6549 | Bin 0 -> 1308 bytes .../40792f23c1281842dab671e8b213fc408d1ec39f | Bin 0 -> 816 bytes .../41cd0b5d9a9540947b7b1841a55e4c11bd4346a2 | Bin 0 -> 32 bytes .../41d86e5ea3df4a0de60d42aeb16e2a5599aedeae | Bin 0 -> 465 bytes .../42b4e5430b2b1b17a361067fb9dd33ab74e52232 | Bin 0 -> 202 bytes .../42ef1c9d234b90acaf1651d930fc52d5f8f158f2 | Bin 0 -> 275 bytes .../4570c8ff26d7f31afe73b3d9a35a29bc1274d68a | Bin 0 -> 153 bytes .../45cf4751a5929930a7c30ec10134434b9ee13c3d | Bin 0 -> 2873 bytes .../46e9d351dd5bb71f7d4d8f15b3fad312c781452e | Bin 0 -> 164 bytes .../472421633b984556b96bc20f1fcf7a98c25736f3 | Bin 0 -> 322 bytes .../47f35b91699caee098cacdde0161ffab21bdfc57 | Bin 0 -> 123 bytes .../48b9da327218f9409287687a43b7eead4789a588 | Bin 0 -> 217 bytes .../48d14fca326d5d591d18d34c2821a457277819a2 | Bin 0 -> 153 bytes .../48f3a33e2a027f5735d0a333ec4acd5a2aa57118 | Bin 0 -> 2166 bytes .../49e0eee24eab094a9c62f6b37b6ba01f8aece4e4 | Bin 0 -> 2095 bytes .../4b45bcb707d2a0bc23b415e9bc3d7eb1f7f0e188 | Bin 0 -> 659 bytes .../4c428300fe4866fe81cff02ad4bc14b6848f7f73 | Bin 0 -> 281 bytes .../4d69c567df2e858c5f248b3fc8e4a9c04f02481c | Bin 0 -> 696 bytes .../4d88b6c9b513d5db2e07313a39b43d112d3d4562 | Bin 0 -> 66 bytes .../4da73370cf854ef8bd08c7f79b92a187cdbff278 | Bin 0 -> 81 bytes .../4e4b2827351bbfd414b718052a8f950a9e3eb7ee | Bin 0 -> 738 bytes .../4ed43f7d3c0305461edcbc86f62e0c6ad56df01e | Bin 0 -> 804 bytes .../4f011529809e88205421fa8ce39dcc025293bcb8 | Bin 0 -> 216 bytes .../4f1928b6376369ab6acf8a282284366cc3bf71ef | Bin 0 -> 2654 bytes .../4f669eca3416c44f0d003ef2720d03e697e2230e | Bin 0 -> 80 bytes .../4f750f24ecb5080bea2845061cfd3ce4529d30ee | Bin 0 -> 280 bytes .../4fab9bb2bacf562e65f4a8681c429e6ea92aaed7 | Bin 0 -> 1863 bytes .../4fd757c7251c17413b3005fb38aee0fd029d89ec | Bin 0 -> 861 bytes .../506092de91dcf93254cdd5ad9e02a953a38099ea | Bin 0 -> 280 bytes .../50e934fb52d9bc5cd2a531adced1cad7f102a112 | Bin 0 -> 385 bytes .../512e49a9e789656964988950009e6534907e6317 | Bin 0 -> 2021 bytes .../51404149f1ea30ee6959fafe81a52acabed97e9e | Bin 0 -> 607 bytes .../5150f8a67399ee16178a2b08198cf91a90c0e53e | Bin 0 -> 538 bytes .../51a1fd23dfe5a8062cd4601d235509247f3bc2dc | Bin 0 -> 218 bytes .../51a963486f041a60c422f0dd6da3b69c52f12fb7 | Bin 0 -> 131 bytes .../51fbf57a2a35ec33164838fa254fe605a3c868e9 | Bin 0 -> 986 bytes .../53068b9f9cb54bb52d076e9602ccd55f169ef39a | Bin 0 -> 410 bytes .../5314619e15fa5ee67df44481b8213a53786d39c5 | Bin 0 -> 146 bytes .../533f5f00275968129846522fe01e2819746272eb | Bin 0 -> 80 bytes .../53a62799135c282435a17e032deda03eaf9daf0f | Bin 0 -> 83 bytes .../53c9d5cd849977e523d92dd2d639e9b0e721be50 | Bin 0 -> 680 bytes .../54767a0bb3b96d39f5b2004ce3f274465f1a927e | Bin 0 -> 2022 bytes .../548de37dbe6a3829b73d976996ec9838cf608554 | Bin 0 -> 296 bytes .../5522cefa54b798ea4aba8ef2a42ad248a7fb02ee | Bin 0 -> 60 bytes .../554fab3eef5d8709f06d1d4319efe5c0c437421b | Bin 0 -> 192 bytes .../567fe73919dae39b0bcb78b03d655643a71714a8 | Bin 0 -> 409 bytes .../5717a281aa722ee4a32dfa1cc72fc5d6081f6755 | Bin 0 -> 2126 bytes .../577d814e0be43df9321c5b27119c398bd00a00c5 | Bin 0 -> 317 bytes .../58680611707c6188f9f067f8747b699cd2fe82d3 | Bin 0 -> 453 bytes .../5915b7f91dd43ec37a4718061c90cbec2686b916 | Bin 0 -> 1339 bytes .../599516e368ff621dd06d8450837350f4e9558c38 | Bin 0 -> 452 bytes .../5a2d01d141e4d523e718c30e20cb07c3ad98f33d | Bin 0 -> 308 bytes .../5a9803ef8cd88d1e8f1d6e5920b8afd170cafb11 | Bin 0 -> 280 bytes .../5ba93c9db0cff93f52b521d7420e43f6eda2784f | Bin 0 -> 1 bytes .../5bf0ca772092e6fa34b6822f61a1b1c3d7f2c6e3 | Bin 0 -> 318 bytes .../5cfbfb3e12b629dc9f74baf0a8741345ec288795 | Bin 0 -> 802 bytes .../5d8cc97b739c39820b761b6551d34dd647da6816 | Bin 0 -> 342 bytes .../5dcbb3e1c2fc9a191dd3f3443b86f6bc38c39e37 | Bin 0 -> 176 bytes .../5ec17d081aef9872f746e88ad8b03553719f9c36 | Bin 0 -> 402 bytes .../5f88e3ba60c11be25c47a842763d8870d23cc7f2 | Bin 0 -> 675 bytes .../6045e4d2bf85013c78a32e71b014ba3d4a4b7c61 | Bin 0 -> 540 bytes .../615c7ba7ffbce955ffd964682e2a0f7ef3c767e4 | Bin 0 -> 86 bytes .../6189f29cbbe88ac6cb32fdefecda1bd6194332a6 | Bin 0 -> 1007 bytes .../627224cb8484c62992dcbc4cdebdbfa48a3c021a | Bin 0 -> 153 bytes .../629fff0962d298a7283a3d1e1d1b940dfef9b315 | Bin 0 -> 251 bytes .../6322594cff2a99d0abb1139e6a43b06df76d539a | Bin 0 -> 284 bytes .../63de5e8e042222d53bf05640c87da376aefb76cc | Bin 0 -> 2084 bytes .../647dbb1d05fe0fab685bfe126bd9ac3a12b6bccf | Bin 0 -> 279 bytes .../647e5e265d8d1079784fc2a3da25f7ba58126acd | Bin 0 -> 73 bytes .../653bd480dfd1e5f4bdca702aba3dfd8da0c204b7 | Bin 0 -> 103 bytes .../65485740a465377213c80fa68028727f281299fb | Bin 0 -> 80 bytes .../6551f8c8c3028006d0cc4997943df8a86ee3f598 | Bin 0 -> 444 bytes .../67799e79d33883510f85ae9705ab3932862128a2 | Bin 0 -> 991 bytes .../67b475481e5a21351b49789874adbc988aefd64c | Bin 0 -> 89 bytes .../67e5a649967dee002d1c181e079748c404e29767 | Bin 0 -> 1116 bytes .../687424a4a31a66a78d1637c680c9c10746741007 | Bin 0 -> 1573 bytes .../68fa6dd52832657cb8dd7e1485d6fbafd4e93903 | Bin 0 -> 536 bytes .../691696af1c042115f4d9f9b8e24f7b8c06ed189b | Bin 0 -> 284 bytes .../6a80152f9b1afa3a3080bf3f6aa48e84c2e18497 | Bin 0 -> 2116 bytes .../6af27e4cf4c7bcce128a5949ee27fc73ab2cc71e | Bin 0 -> 1620 bytes .../6afd8f82d5639b774de0dfd418ae85322f4168dd | Bin 0 -> 253 bytes .../6c64a9e26e0e1480bb5e60b7044ca6ce17104a80 | Bin 0 -> 1043 bytes .../6c850c17db130ca0152f7c75562fa191f7ef89de | Bin 0 -> 41 bytes .../6c9afe4527371a2baf33c5e220e4ca21a3207f94 | Bin 0 -> 640 bytes .../6ce3d40b0225923a7f4123a919b1c5d70841fad7 | Bin 0 -> 268 bytes .../6cfd064aa6197813eb18f38df967ae4cdba9c6da | Bin 0 -> 357 bytes .../6e6675676c53bcddc870e06605d2432e3429f224 | Bin 0 -> 616 bytes .../6e6e82579b7abae2b43d90448d3f2ead4dfcba78 | Bin 0 -> 2115 bytes .../6f13d23c75a562eddefafe85e208e602832294e2 | Bin 0 -> 236 bytes .../6fed59b0472927f5d2396d0ee4d7fd13579377ce | Bin 0 -> 751 bytes .../71f7724196f9f8fcfe3ee0161a84893bb9c4ab11 | Bin 0 -> 795 bytes .../7335ecb1d41e713bf3909adf5802b90e22bc1581 | Bin 0 -> 153 bytes .../73afaa73175f461e1d19d5138e055c1649926dfe | Bin 0 -> 544 bytes .../73e2fcb45c4df90d19091056b235e7a317631a62 | Bin 0 -> 150 bytes .../741cb2d5ae11b0a9e0608b58ec7284d75129a1f2 | Bin 0 -> 69 bytes .../7431bb0097a9bb52e1ceaaa8674a13cd3486a387 | Bin 0 -> 1223 bytes .../7455b805995d0c96ac12f8a1c1264caaffcfac1c | Bin 0 -> 742 bytes .../74e39b8a82fc06f9ed8f83ea30545ddf6df66811 | Bin 0 -> 268 bytes .../75d51e413d3e916560dc0c2ee5092d2f4972aec1 | Bin 0 -> 343 bytes .../75e068964ea6beb7310a154d763de74a70071f48 | Bin 0 -> 453 bytes .../763bf498dd847bd2b4af7b611199619bd428bea6 | Bin 0 -> 1188 bytes .../77064ae04581a3c6d2a77158ef1a0b1e60db414a | Bin 0 -> 314 bytes .../783bb14d68021061f592601607f40fe232ad17c4 | Bin 0 -> 210 bytes .../7862814cb684310b54ef920b35403515efaba13c | Bin 0 -> 276 bytes .../791fd85b6ffb2429e9fa5ba29eebdce214ad88c7 | Bin 0 -> 436 bytes .../79396d4f6142a53e26e14aa6ccb4afb4fd8fc580 | Bin 0 -> 216 bytes .../79661b8e529e2182d5c612faba9f26e32a122b78 | Bin 0 -> 102 bytes .../7969143acb3334bffac46c6dfd96362c81644191 | Bin 0 -> 418 bytes .../79d84866dc8c067508c02516b65c0e48cf689b56 | Bin 0 -> 83 bytes .../7b61f8f4a96e309bbe64ed82637fc81492a9652f | Bin 0 -> 2710 bytes .../7b8123f973edfb0f3cab027c0cd6b8efc7b11d6b | Bin 0 -> 805 bytes .../7b8dd3093efba07f7a4d3bab4b90b8f6e4f28bfb | Bin 0 -> 1049 bytes .../7cc771aab0f3be7730881a46d952ae0a06958201 | Bin 0 -> 740 bytes .../7d177f4207de78d50df2493a3bc07f2cd578b363 | Bin 0 -> 82 bytes .../7d2df075f3e73ea9809c31586c37ece0f568b7fa | Bin 0 -> 362 bytes .../7d386e68e4c733a1fb11c0117f379fb4b9955fbb | 1 + .../7e4260830352479d29310bd6e1022e19a68ffe76 | Bin 0 -> 412 bytes .../7e4dfdae52be18cf95555c2eb1f54af7f69c6dde | Bin 0 -> 217 bytes .../7eafedf7e7f20e86ecdf9ba51febf8492bdbc1f1 | Bin 0 -> 593 bytes .../7ef1829a378d66b1dd70a767729127a0dc5edcae | Bin 0 -> 4 bytes .../80b7d2b9d7e8c8fd7ae239b8d307b592f97ee000 | Bin 0 -> 2303 bytes .../810f577ff5c1af7807a26226af912687558158cd | Bin 0 -> 281 bytes .../81603f1fe8d8e29005418d0fc9a9b33972366038 | Bin 0 -> 212 bytes .../81c8b4d6884f954935fa4a8e828c4637db04b61a | Bin 0 -> 262 bytes .../8226846e9b092561f85cc2956ab89d8cc1ae61e0 | Bin 0 -> 197 bytes .../825cfceea434e2392cce161356e3cb5f81ec2b3a | Bin 0 -> 274 bytes .../82603febce83d95adf68b85cabf15d43ca0c4ee9 | Bin 0 -> 532 bytes .../827f0826cc4156e19b4c4938bec74e38de62fe9c | Bin 0 -> 346 bytes .../8486397ff8d1156249676c19b419a7758ff53f9a | Bin 0 -> 1361 bytes .../84d99ee359bec1b8ee0f59e9bd96f1da062030b7 | Bin 0 -> 376 bytes .../84e629bc7416039f1feb81fa9168d7c1ee3141c2 | Bin 0 -> 539 bytes .../84e885752179076fb38739ca7bc4345716bee56a | Bin 0 -> 217 bytes .../859ef05494c8070057810b5c20df00fc81f81cf5 | Bin 0 -> 2796 bytes .../859fe592f33abc1d959c0e73ecd6cd4bffe23a97 | Bin 0 -> 345 bytes .../860da5e8a468805b76a44b9ac99b4575be16ea15 | Bin 0 -> 338 bytes .../865e415745cead02a826f058a5ee49099bdf9562 | Bin 0 -> 417 bytes .../878bfce051a9c7462847d4e99b7e926dc821b7b8 | Bin 0 -> 95 bytes .../880492e4dc7259577c227bb4f075d7165e875c29 | Bin 0 -> 150 bytes .../88b7de1bd1c96454a1350286d115c0ee368511f9 | Bin 0 -> 120 bytes .../896268e4a5775b7ce33923ac6daeb0810420c55b | Bin 0 -> 3274 bytes .../8978f8da89f9652878edabad164f5513ef508f27 | Bin 0 -> 244 bytes .../89a6525b7db0e6ec211a484efd2880abef928d4e | Bin 0 -> 152 bytes .../8ae86cba2bba6664fc5eb97be8e9777b8825d823 | Bin 0 -> 506 bytes .../8b845fbd2aa14e4f83c4dbc8b4b0b54d06482acd | Bin 0 -> 273 bytes .../8c4121e6ce5956cfa408b980f16d276f456374dc | Bin 0 -> 152 bytes .../8cb6a5b8ab41e3d27668d5735b5c09ff1f2eab65 | Bin 0 -> 403 bytes .../8d80a70ffd362a89b88663e27f11e8ab69b70c1b | Bin 0 -> 274 bytes .../8db603c1720b3680047f831f2ea9862567a7cdc4 | Bin 0 -> 1009 bytes .../8dd40b2d27c7dd4b986c35d87f826da287c09c4c | Bin 0 -> 229 bytes .../8e9d6e6408e5f708a1924e8370e687e2c202a4c4 | Bin 0 -> 519 bytes .../8f2dff1a30ee28e5985cb9379828aea5658d5849 | Bin 0 -> 222 bytes .../8f7d18cdd6e605b85784ada14571fd5e5a184f2a | Bin 0 -> 1125 bytes .../903ae52f0ac9af8348038b12f9259741b0de42f1 | Bin 0 -> 1198 bytes .../9119e331f59e9337d419739c324f49d1bd62c8bf | Bin 0 -> 3311 bytes .../91d54d03b0917314ea1d67a70690df9247dd08d2 | Bin 0 -> 536 bytes .../922da3b96725bfd0e3f6ce119f1e2249d53f9086 | Bin 0 -> 542 bytes .../9277561e0524cccba2f851970b0d88ec4f4d3f5e | Bin 0 -> 1304 bytes .../92a4d571804026b7bbe957396185e079e756b894 | Bin 0 -> 334 bytes .../931224cc80168fd362a360d99bab813ed7bbf8ce | Bin 0 -> 127 bytes .../936ea5dad3bf023c552aa0bbeea8f7f66a11612c | Bin 0 -> 454 bytes .../93aa4e0b1864933dce0abc0df69fe3d261f117f2 | Bin 0 -> 146 bytes .../93d5b084965cf1b09085c4079a972e25207b3659 | Bin 0 -> 159 bytes .../9443fd3468bcc0bc3ff8dfe765225f045ab43d0a | Bin 0 -> 225 bytes .../9624c26cefb5804b7906147d262e81ee4000b6d6 | Bin 0 -> 2327 bytes .../9890933a73f39208627bd36e2fe88a6d54343a74 | Bin 0 -> 186 bytes .../989dad0448e79af10040d5080f74eba2b8a401ba | Bin 0 -> 191 bytes .../98ed4808b4a8da66a91fcea1be63be6371a7c7ac | Bin 0 -> 214 bytes .../9928e516b85e22fbad58d562d3b7e814d9ce812d | Bin 0 -> 213 bytes .../994c7cc5599252b5628d89cd0ba4b5574d32bf00 | Bin 0 -> 3091 bytes .../99c8557c2a02ea030de42869af42c1f7c77114db | Bin 0 -> 86 bytes .../9a14c867272f102b84efdba73662d318c3e51cfe | Bin 0 -> 2161 bytes .../9a6f158c176d4a1982d541be2bc27a8afba4ea57 | Bin 0 -> 99 bytes .../9aa4af603192823a2fdc53d95ed36896bc3309b2 | Bin 0 -> 371 bytes .../9b40c2190123cec66af3b37212f6c567869efda3 | Bin 0 -> 152 bytes .../9b6268c11d78c35db5164f1346905e602b6a49fe | Bin 0 -> 989 bytes .../9c6883ba5cedb7d711b12733d66ef1a1156dd0af | Bin 0 -> 1988 bytes .../9c85c90f44b454ce0d52882c447f5ecb8d303634 | Bin 0 -> 348 bytes .../9cb7a2e89ec636da3fd41ecc49ebe25e5344e2c6 | Bin 0 -> 477 bytes .../9d912dc5a3497e4b5b40b37202fc0ffbf5263666 | Bin 0 -> 3848 bytes .../9dcbafe8c5345194ee0ce7eb4f6efaeb55543626 | Bin 0 -> 3972 bytes .../9f4b0f3d2d25e6405ba6093f24d0605327711573 | Bin 0 -> 452 bytes .../a047bf683239fa208dbac09424b105820ac23f43 | Bin 0 -> 539 bytes .../a1379dcd89ef5e73eabbfcc395113e3636e0ae09 | Bin 0 -> 134 bytes .../a38c7ef56adabd0916abac514154b1f362d40434 | Bin 0 -> 1704 bytes .../a38ec6ad4a8466b4feb88e67b16524e8f3feac64 | Bin 0 -> 487 bytes .../a3fdea21020268b3b2409c1115d50697d9ae8f8c | Bin 0 -> 257 bytes .../a45f1987a444b2c27e90fc1477e8b0815f75383f | Bin 0 -> 607 bytes .../a4682958fb7029384c0a01a4a1356ac6f2f44fe1 | Bin 0 -> 78 bytes .../a4de41561725960d6f48f210a4fb74d527f7b0c2 | Bin 0 -> 965 bytes .../a5935f34435ecdd6587ad4f77b20d479d3387dbe | Bin 0 -> 279 bytes .../a5b394beb2b1d463ad80924a8c8c70584bf5c629 | Bin 0 -> 234 bytes .../a62bc806f8c98ba7986243c2185a0548a8dd57ef | Bin 0 -> 118 bytes .../a7013e97948893e0118c686c06e332cc611bea7e | Bin 0 -> 214 bytes .../a74f5df8c7f25c37c15c0f74ed50019d17338225 | Bin 0 -> 539 bytes .../a7ab3559fb3da3f027e67091116253f3bdfd7828 | Bin 0 -> 1626 bytes .../a845c8258a02022d447ea9249788b345f5504648 | Bin 0 -> 144 bytes .../a8d3e026e2393587eb170afb32e94ff0e1f8a8be | Bin 0 -> 353 bytes .../a8d547e41ee21e163e65cf0a186d469dfa50ec19 | Bin 0 -> 2448 bytes .../a8fa22521dd6813e595cc0a9586ee71fff305fe2 | Bin 0 -> 127 bytes .../a9969442d585d9a53259c71c73b095701280eac5 | Bin 0 -> 160 bytes .../a99789d0ce2d7b937aaa8afa3cfc0f4ccd7be95f | Bin 0 -> 150 bytes .../aaca30ee3ab38edfa2b061fcbcbca0c0ea657f15 | Bin 0 -> 108 bytes .../aacdec3f05e98eb6eedddb9c6edb968e1a63c551 | Bin 0 -> 3654 bytes .../aadd85127241b94a41d02d9e9699e3e9773de1c9 | Bin 0 -> 539 bytes .../ab8ad126702803d21dbafc85713bbee7f25f36e5 | Bin 0 -> 3031 bytes .../ac26f9afd599ff6f33396c2e02130654f3e2390c | Bin 0 -> 324 bytes .../ac8b129e4756fda0c50c9dd0eb13e34c7b41ce8e | 1 + .../aceaf3b72c2627dd3dd065974b854150681c093f | Bin 0 -> 793 bytes .../ad1fcdc3bf806392e754a902eba9edd3b344c31f | Bin 0 -> 98 bytes .../ad8c80e532482f9dfbfbb7c0d447f1f4e592bf72 | Bin 0 -> 457 bytes .../add92b71bf897da2f71f691e6abcb6d02cb8e99f | Bin 0 -> 231 bytes .../aeb8ccf6d82be9236c9e689e1580d043bd701eb0 | Bin 0 -> 3419 bytes .../af1a827aedbf674fff2bdeb5589554eec62787ab | Bin 0 -> 215 bytes .../afaab9a75414d231176ad4582b6f8d81b5dbedb3 | Bin 0 -> 2686 bytes .../afc12c4ebed1f3ab962d7dcef110b5328b1e24c3 | Bin 0 -> 673 bytes .../b0044f3744cf019658d668a33f8d1e53ef8bd6ce | Bin 0 -> 406 bytes .../b06adc81a4e1cdcda3786970ca07ed9dee0b6401 | Bin 0 -> 344 bytes .../b139802a1cc90fd5b86cae044c221361892c688d | Bin 0 -> 3071 bytes .../b1b8f251542db01bdb01be3b6d5b117b07db1834 | Bin 0 -> 790 bytes .../b1b9af93f84ed6861b9c0ade39980e89ef828c8f | Bin 0 -> 213 bytes .../b2eae68035cafd4077f6a4c3e4e961fdc1e8122b | Bin 0 -> 1878 bytes .../b32897a6aedaa8c5a6e656dd808bafabc4ee5608 | Bin 0 -> 343 bytes .../b376e4fc517297f92ac1713803ae3b60d5ebbe43 | Bin 0 -> 32 bytes .../b3fd100b139cfbffaad68aacf7d462861e9dca35 | Bin 0 -> 136 bytes .../b40808ca955faab4829811bced1cccb2ab58ea58 | Bin 0 -> 87 bytes .../b43daf9f87a514bce74af3e5a39284c69c4e7011 | Bin 0 -> 187 bytes .../b477da07f3e5796ff4a98c8a5bdb0e4a634954bf | Bin 0 -> 342 bytes .../b4a2ef09cf59ca5ccf810a6f001cce710cc02f6b | Bin 0 -> 1248 bytes .../b4b75e588cb83430c502a34ec3dcfaf774a00359 | Bin 0 -> 1976 bytes .../b4ce98acd2b288b6cfc00461e2e15e0f8004030c | Bin 0 -> 1246 bytes .../b75563f30f7e4fb369d2449b723ee8b282d03eff | Bin 0 -> 1989 bytes .../b7a0a820afa7057081de186728d0d887131d9314 | Bin 0 -> 3572 bytes .../b7e880446146c735a3f820fb93969c8c172c2fb5 | Bin 0 -> 275 bytes .../b833073d3006e7cbac03c494603a9b75e7b2a723 | Bin 0 -> 150 bytes .../b89459c1fb6fc918db4c81a32a75ee66217f9ab8 | Bin 0 -> 101 bytes .../b8aab6c9b2c706f8df0ff695ff94969171f9c807 | Bin 0 -> 136 bytes .../b9751182a36acb79b77585e1e379857a530e95c8 | Bin 0 -> 1247 bytes .../b9ddb239b5a2c1348d972ec70a08507c35ba4432 | Bin 0 -> 247 bytes .../ba8f573256a0fbb95c5626f399ebc3ef50bbd826 | Bin 0 -> 69 bytes .../bc165749042d5425c5d6d4e29b17769a2315a80d | Bin 0 -> 344 bytes .../bc910bd349319e1ed44d7c7266e3ac99cc29ecc6 | Bin 0 -> 410 bytes .../bc97b1d4f57eb7770bc3983e2d57c8c01b21d29e | Bin 0 -> 942 bytes .../bd06f768e35ded4437cb88e2bc0ddd0bea3fa84c | Bin 0 -> 68 bytes .../bd702faff9725a7a1957fd0f85cc52799f37b682 | Bin 0 -> 411 bytes .../bee4464861e1cae3cfdd5fbcb340efbf02e8d8ca | Bin 0 -> 1840 bytes .../bf7ad994b098ec85d62683a16e067635e21a8af5 | Bin 0 -> 2455 bytes .../c054fc89ed72101dec861668ff1738ef85b728b9 | Bin 0 -> 114 bytes .../c06752415ac037fefe5172dc7245cd7c49ca7fca | Bin 0 -> 280 bytes .../c0c8b54354d172a0be751e3e9b80be961bb15ddb | Bin 0 -> 2211 bytes .../c0e7ca9b5b4d0e72d23d7dc9e9d1f2463a17a20d | Bin 0 -> 282 bytes .../c13576a29c98bee02aa47f646f5f170f9b7d83f9 | Bin 0 -> 1523 bytes .../c14edf1d34f40b3cc74772c81ebe5d72172cc662 | Bin 0 -> 956 bytes .../c2789364cb35d111f08f924d0d7550ea9785c61e | Bin 0 -> 2130 bytes .../c2d8b07acb13e43a89b6c4afb3ecb9817dd4a8e9 | Bin 0 -> 2088 bytes .../c36ed796c1bf839668db8fc3475a2ffb32ad8ceb | Bin 0 -> 1708 bytes .../c41ec9dd94427423e4704721e7f21eae0c44ef20 | Bin 0 -> 473 bytes .../c42c544fa9dbb1264b39bf920b40985384db1d16 | Bin 0 -> 1990 bytes .../c45ec3f594abc15de0a8cc3ad748ba23cb34ec64 | Bin 0 -> 81 bytes .../c49004d980961f288616a4eb9ebf68123fd68ffa | Bin 0 -> 129 bytes .../c4c3c3c8df24adf505127627b3090116de78d9a6 | Bin 0 -> 151 bytes .../c5c1921293af4a5953cb386092694042715fcfb3 | Bin 0 -> 89 bytes .../c615caad21cd8a754fcb2008420234c5511c62b7 | Bin 0 -> 2534 bytes .../c6a9ee3f8fdc42566c4799db3912a83c8c438d7f | Bin 0 -> 396 bytes .../c6b661e976282051285b913b3728383f36103ef8 | Bin 0 -> 792 bytes .../c716ba47f810c238fe7bda1fbdc7b1ccc34e9848 | 1 + .../c85b2fa4421302e2fa333a9e33d59a882aa04f4f | Bin 0 -> 2112 bytes .../c871d135f2d3117b326688355bc0fa6f26d56cd6 | Bin 0 -> 83 bytes .../c915b02265a27d185a8b028305f082ddb3ebd704 | Bin 0 -> 201 bytes .../c952d38b3e642db4795d7f954b85f4f6d2a041aa | Bin 0 -> 107 bytes .../c98ee52065736c4172f6ee0c31977bf1b560d685 | Bin 0 -> 471 bytes .../c99b183a2cd0dd8a4c1a141cc6eebb0311501fa5 | 1 + .../ca0cd26baff2f2c0759e619800ebbe7314d2bb95 | Bin 0 -> 262 bytes .../ca3e0d745c35d7cceb0f6e3f8a709eb658b7e5a8 | Bin 0 -> 86 bytes .../cac667320e99e93a796bb89842de4675735eb4a4 | Bin 0 -> 353 bytes .../cb41b00e9db33a07e27b3ee05d3bbecaf853b963 | Bin 0 -> 2238 bytes .../cbdbd3f320eee627097778f15b9fb2c1dc2bd15f | Bin 0 -> 2318 bytes .../cc7f114000c83abb2ab17f0deab6dcfc2acde7f5 | Bin 0 -> 806 bytes .../cc9bb93a6b7a1362a15f04898845dbe1447ec382 | Bin 0 -> 392 bytes .../cce7355f826bbcf3955394596d358abc7df6fe6f | Bin 0 -> 2458 bytes .../cceff2878a558166fb5bf2a0354c1be31dcc4e21 | Bin 0 -> 2605 bytes .../cd96909f3ded7aa54bb2ffd2f2f47f8acc6f99e2 | Bin 0 -> 81 bytes .../cee9f69d7d1a227833fba127a529ea2a10341da3 | Bin 0 -> 68 bytes .../d064f27a3109afde629165432f78f389da73ff07 | Bin 0 -> 32 bytes .../d07e3094f02b0c0e3bab370684c2d8c5634224d5 | Bin 0 -> 1178 bytes .../d0ba3413d5706de17de64824d78233d48c6efbec | Bin 0 -> 97 bytes .../d136511364a74973b009f2be9b021d4122f71a6c | Bin 0 -> 655 bytes .../d1d215c40bcc8dd4ce02b0c0621e90b183b40b3e | Bin 0 -> 191 bytes .../d1e35b137b2027b61def408f3f3c8cf9bcab274e | Bin 0 -> 1848 bytes .../d349d137e57fb1a60ab8babd20e2acedc7a9042e | Bin 0 -> 1989 bytes .../d3714ec4d3acc6262295b0fc99c6ba699f5bfe65 | Bin 0 -> 594 bytes .../d419df696512216074f1c6b17ea1dfc81c0e6e20 | Bin 0 -> 1251 bytes .../d49ad4fdafac251ceec32481826228c1698360aa | Bin 0 -> 1001 bytes .../d4f85ba549c87ccaba59971a25da7e07b57c9f4e | Bin 0 -> 538 bytes .../d51ade0715bcea7decee2a045934599a10c1b07a | Bin 0 -> 227 bytes .../d5447fb72c97462a3f47c8b2d55deb0afaa225f8 | Bin 0 -> 1113 bytes .../d6611a91c29291872ed2932455cb15ddb3801323 | Bin 0 -> 83 bytes .../d676f5e7efd6de6f2e1773231479471d2bba7261 | Bin 0 -> 37 bytes .../d6a21eaa08a957d8f428192e193c2508fca2c218 | Bin 0 -> 179 bytes .../d778052a29539344a9e3144e262e68df9628ebde | Bin 0 -> 330 bytes .../d884f6944adfff7cb41728062bf91cac5cdacfc9 | Bin 0 -> 466 bytes .../d89aae18d8e320bbae55eaae6a0514d7e005a883 | Bin 0 -> 2410 bytes .../d926fde818c63f7b34f38c9f018bc833bc0bf7e1 | Bin 0 -> 409 bytes .../d9d542d7c56774143cb6362e5a63739055469349 | Bin 0 -> 2801 bytes .../da99bc9ce5b831f132dfb2eb11b8537e5cccfcd4 | Bin 0 -> 120 bytes .../dabff2729fa69ab507fb00b7392aee1262056a29 | Bin 0 -> 296 bytes .../dac4f4b91e33847bcedf7c66ef6e4ad0181e8ad8 | Bin 0 -> 153 bytes .../db10ff6d01c7a66aa1823b9f99193590ddce99c6 | Bin 0 -> 252 bytes .../dbbda2208fa688a5275dda0d304630db01ca081d | Bin 0 -> 284 bytes .../dc47c5037be68a2747ff8a9fa450e1078a5ac5a5 | Bin 0 -> 209 bytes .../dc760f136b123e38677aec72853e3365f08010fc | Bin 0 -> 602 bytes .../dca41b901bf1612d4197e6a450366a00ac036ec3 | Bin 0 -> 346 bytes .../dca62f21fce50d1c8c51b82e0d7eeedc6746e652 | Bin 0 -> 169 bytes .../dcc7e6c444f95b10d634b1137413824e2cd68f62 | Bin 0 -> 152 bytes .../dcf4b6addda69040f792c9b860ade2af0b77a14c | Bin 0 -> 1888 bytes .../dd6178166ac1eed82d132fea491bcda0d953227c | Bin 0 -> 566 bytes .../ddbd5d3074323ccd7cd70bf5de5a2f30de977d99 | Bin 0 -> 130 bytes .../ddd8ec5632bf1b8153d03a4537d3d76517c497d5 | Bin 0 -> 150 bytes .../de7a56f36e10d7b9ff43160b1cea3e76b24386d1 | Bin 0 -> 146 bytes .../defa60aa46ea5a47c09b6962b4e4296ef1bcad92 | Bin 0 -> 80 bytes .../e0ae419425207832518d66c0ef35d11cbdc20361 | Bin 0 -> 1691 bytes .../e0f519accbf15bc57a1bf1d7cc46d2a0b07a67f5 | Bin 0 -> 214 bytes .../e128eff8ca7572d9bb0bfc84f64d79c52afc2c67 | Bin 0 -> 536 bytes .../e17fdc21ae03243bd1d31bb6301b4187cab6fe47 | Bin 0 -> 1617 bytes .../e340ace35a2db7f89d6aa21cc1300766a74be4e1 | Bin 0 -> 536 bytes .../e36dfc11bcaab1e42df13924a2d7da024684db2e | Bin 0 -> 353 bytes .../e39e0c87ac5ce0b78c89ae2df84226baba666372 | Bin 0 -> 864 bytes .../e46b4666c6bfcd6f589ec3617a48cce9c968e833 | Bin 0 -> 406 bytes .../e57219555e11f9221d3166d5029ed2ad92300608 | Bin 0 -> 101 bytes .../e58ce590c2454e7ebe18e0a31a943b0b754fbd13 | Bin 0 -> 2317 bytes .../e595f8fef5c8014cb0867978c6580301078ca0d9 | Bin 0 -> 2474 bytes .../e5b76398f60628e879328d7009b9fa89feea14cb | Bin 0 -> 452 bytes .../e5cec0217eea93b18a59d76b0aed6b46b13fa6a9 | Bin 0 -> 921 bytes .../e637b4e0b47d0d6cd870502e6a2d6a53bf917f73 | Bin 0 -> 1782 bytes .../e7a6cb6e5a1552837fdbee9025fc48a9373f8564 | Bin 0 -> 1370 bytes .../e7f57c48016e1180c9af95acd34470881f10bd06 | Bin 0 -> 90 bytes .../e8253c668bfe37df5c5ada3226860cee74fb33a2 | Bin 0 -> 218 bytes .../e8f9981443c34ece02bca3c66130f3429d7b3375 | Bin 0 -> 474 bytes .../e91ed5416bbcd1b03803197b99c08f42c9869139 | Bin 0 -> 537 bytes .../e94201cfa88df7b198abd3abae9007a6780b52a7 | Bin 0 -> 345 bytes .../e967bbd6a0d251ae62c9c38b784271d707f792c0 | Bin 0 -> 138 bytes .../ea01737ceed783b3e0f66d9d0c409cb496c1d526 | Bin 0 -> 86 bytes .../ea40f7879a58d1e52a46404c761f76a949e14a31 | Bin 0 -> 69 bytes .../ea5ad04a54f95963baea1f47845847626e08dd55 | Bin 0 -> 211 bytes .../ea608a401f54b0ca70e42b897f0c8ce6efdbc0ef | Bin 0 -> 404 bytes .../eb8700d6b3728e6e70c2a0fe504543771639f2b6 | Bin 0 -> 1989 bytes .../ec1f271b04c322353865f4819153d46df7def873 | Bin 0 -> 1754 bytes .../ee215536e7f0cfbd07b53dd65c5af9a604a01830 | Bin 0 -> 948 bytes .../ee4d4393d7d79b755f85ef5bf8f6e3d743bfa258 | Bin 0 -> 468 bytes .../ee8099331b2c392e7e036ffcd4a9b36ec2c2082d | Bin 0 -> 1908 bytes .../eede9da76db25513f8347f972e170102831de91a | Bin 0 -> 80 bytes .../ef707cdeaa9548b6c820f769c1d8ad607b3c4514 | Bin 0 -> 119 bytes .../ef98609d8196dc158365dfcbbc47e3d1699c50c2 | Bin 0 -> 1944 bytes .../efa38b4269f978f3714b44b501831bea678244e0 | Bin 0 -> 357 bytes .../efba428e29811d233720ccaaf41966a309312a29 | Bin 0 -> 86 bytes .../efd514f056d8d83498b4724249c4623560e0390d | Bin 0 -> 177 bytes .../f00e449ba67ef15e7f29df1e6948c28155d72baa | Bin 0 -> 3505 bytes .../f0a83929d588466051dced6eae0c387db307d646 | Bin 0 -> 944 bytes .../f0e53b72e5d69467e7c014474028ea734f4fcb26 | Bin 0 -> 5 bytes .../f186265b3f10f4383f4174e9fb74f0a0cdfa3fca | Bin 0 -> 95 bytes .../f18932fcce5a9db5d6c8f59d622eabc25e255e12 | Bin 0 -> 100 bytes .../f2ea163bddb95d67597e2a747779ebf4651cb2a9 | Bin 0 -> 417 bytes .../f2f7d48a6d86143ecb4969808d634163576065b1 | Bin 0 -> 2677 bytes .../f34a833faf2b0dcbae8aaad142c76c7c7e534e99 | Bin 0 -> 71 bytes .../f5c044ce01645c069334698fb8c4750e44835912 | Bin 0 -> 2625 bytes .../f680112645c2502f0612e9d017bbb50cb28affbf | Bin 0 -> 580 bytes .../f6b778d1b34415a7715905f54968c8b6eb057912 | Bin 0 -> 296 bytes .../f6ca6a62dc885c6b2a4b40c4aa1a7cb8118e30bb | Bin 0 -> 355 bytes .../f733a8770c23fde182d2fef7e0d96e67244274d5 | Bin 0 -> 90 bytes .../f8529ddf17d4505c0932c3d40abe33cbfd8c6f22 | Bin 0 -> 453 bytes .../f96f8419a3fc3719ae86d64e1147e7b7f66a2470 | Bin 0 -> 2139 bytes .../fae241a6c87af37781a3b49e534b7ddb6636eda8 | Bin 0 -> 803 bytes .../faf8817a04b77c6a976ab0a3d1e905f79bb7f799 | Bin 0 -> 1757 bytes .../fb3e769019fb25d384d4be9d38e4cbce00a6adbc | Bin 0 -> 1790 bytes .../fb9b4b2a46f1c65076340a7bd03b076eb101b760 | Bin 0 -> 144 bytes .../fca9b0a398832c9ba02cdc811f625b97d5beb18e | Bin 0 -> 351 bytes .../fcb1b42c706e61245d5e86f708be777ae63f2772 | Bin 0 -> 469 bytes .../fd6c463e7c30b0e51198c0d1ebbea25f20145e3f | Bin 0 -> 357 bytes .../fdcbaa49097ad120c6d7709b29d5b65b8cf8e719 | Bin 0 -> 613 bytes .../fe46775b28a2923b8770b44381552a8a1560d875 | Bin 0 -> 154 bytes .../ff04441135ef3308fec2687cf688069c6df8aa31 | Bin 0 -> 601 bytes src/commit_graph.c | 299 ++++++++++++++++++ src/commit_graph.h | 67 ++++ tests/graph/commit_graph.c | 20 ++ .../testrepo.git/objects/info/commit-graph | Bin 0 -> 1940 bytes 518 files changed, 466 insertions(+) create mode 100644 fuzzers/commit_graph_fuzzer.c create mode 100644 fuzzers/corpora/commit_graph/005682ce1cb5b20c20fccf4be5dbd47ca399e53e create mode 100644 fuzzers/corpora/commit_graph/00574fc29fd1323e93d18d625cde80d3ea20e8cc create mode 100644 fuzzers/corpora/commit_graph/00916ec21ddbd3c622bde6e4dc824250176b9e88 create mode 100644 fuzzers/corpora/commit_graph/00b6dde4b8d5e68a5ec40d88c39134cf2f1f8bc3 create mode 100644 fuzzers/corpora/commit_graph/020f0e77e42d8b3810019050f4c5ceadd205b37c create mode 100644 fuzzers/corpora/commit_graph/02739c05abc1715fac1ce995b532e482abc8d4dc create mode 100644 fuzzers/corpora/commit_graph/02a276faa5dc8c7df5b82a57ab6cd195a13e4ae0 create mode 100644 fuzzers/corpora/commit_graph/02de15987d68a97db3d9fd964cfd785bcbd54d3a create mode 100644 fuzzers/corpora/commit_graph/02e106f97a91b1d3aef4dd2d31368ae5077bd42b create mode 100644 fuzzers/corpora/commit_graph/038555bcb4cc2daf764840f79ebce4023bdb7670 create mode 100644 fuzzers/corpora/commit_graph/04c159a04b0732e04ac4c59ed3356860af8dffce create mode 100644 fuzzers/corpora/commit_graph/0560ec993882ffbd8d46dcab0ed430089c4f2aa1 create mode 100644 fuzzers/corpora/commit_graph/059b3aab3fde6b4c9404aff83fed638596f594bb create mode 100644 fuzzers/corpora/commit_graph/06168e726aa0260f520165be4ea0c88244831049 create mode 100644 fuzzers/corpora/commit_graph/066d1ec700a526b97009cedd0305b6a47242faba create mode 100644 fuzzers/corpora/commit_graph/086a5f8cbfa9f058b5c938a6eb724c9e4c5f84f3 create mode 100644 fuzzers/corpora/commit_graph/089313c698f3e351433e9a45af2ace1d85b9673e create mode 100644 fuzzers/corpora/commit_graph/092eb973a771fa14cf0b567d65bd2c99130f543e create mode 100644 fuzzers/corpora/commit_graph/094b8cd1aa3e40b1f9ff83680892d52e246df0f8 create mode 100644 fuzzers/corpora/commit_graph/0ce990c9c2ec121b8c78ba2bdf84679e04c0bdae create mode 100644 fuzzers/corpora/commit_graph/0dd0770c34fcf6b1f13219450190616d344db021 create mode 100644 fuzzers/corpora/commit_graph/0e2b2e6a32733b8a625bc7e812e2ea508d69a5e4 create mode 100644 fuzzers/corpora/commit_graph/0e8d0bd07c543d708aecaca377106492b7a74fa3 create mode 100644 fuzzers/corpora/commit_graph/0f0d16e1b8c8671dbe1074115c1d86aa9b359e7e create mode 100644 fuzzers/corpora/commit_graph/102ef78036de5a30927e7f751377b05441c41a08 create mode 100644 fuzzers/corpora/commit_graph/10494e7cc9cb8dff289c431d7560bcee0d1b14ed create mode 100644 fuzzers/corpora/commit_graph/107b11d86381345f50aa19b8485477a870ff399f create mode 100644 fuzzers/corpora/commit_graph/10bb37e18fb3c0897dabacf9c464b4d324007dc3 create mode 100644 fuzzers/corpora/commit_graph/10ee715f64b08549c3e8261204276694728eb841 create mode 100644 fuzzers/corpora/commit_graph/123e4eeb7a731f48d06e336b4d29af717f8b6550 create mode 100644 fuzzers/corpora/commit_graph/125a228afb923970e0a6d4412f7257ba998594a1 create mode 100644 fuzzers/corpora/commit_graph/130d96c16fba06dcbe7e2a661ab959a3274a4bd9 create mode 100644 fuzzers/corpora/commit_graph/131c5a2fec55cb0d63f7dc055d6fad5f3dc3c974 create mode 100644 fuzzers/corpora/commit_graph/13e562d61acb3aa36260a819a00b07ff16450335 create mode 100644 fuzzers/corpora/commit_graph/1414e6e8ab6bad1b5c51fed807c514a9d6575e66 create mode 100644 fuzzers/corpora/commit_graph/1432d191846ae2d0e381813efcfacff2f1dba0e4 create mode 100644 fuzzers/corpora/commit_graph/14a84cdc6f8d432be4cd3d3eafce92ae385e472f create mode 100644 fuzzers/corpora/commit_graph/14e3e735dba88791f2cadd6e0dc5d662a104a6d7 create mode 100644 fuzzers/corpora/commit_graph/1574abb020203103ea629d677edd21c967fc0f4c create mode 100644 fuzzers/corpora/commit_graph/169cc492ba94948a6206765436881a1a0c601780 create mode 100644 fuzzers/corpora/commit_graph/16a2130c1d75129f3bae3bf8f2c2de41fb3533c0 create mode 100644 fuzzers/corpora/commit_graph/16ba602eadfc9a3f74c0845394eda0de42b61571 create mode 100644 fuzzers/corpora/commit_graph/17555fb2dfc444d171ba686667d72e388bd6c041 create mode 100644 fuzzers/corpora/commit_graph/1a10450d99c1e53d9b7f97b8014cb7fc01906ef2 create mode 100644 fuzzers/corpora/commit_graph/1af670b5515231fc04b2be9038ee30a7e066b09b create mode 100644 fuzzers/corpora/commit_graph/1b72cfa68259e3f3b3802906902a0a29368f86b5 create mode 100644 fuzzers/corpora/commit_graph/1c62ac5d632aa9e449a4335b675941107d8825ae create mode 100644 fuzzers/corpora/commit_graph/1d95b5db2f802011b33d10212a66fbe40827dfd4 create mode 100644 fuzzers/corpora/commit_graph/1e068537ce1211a325aab42ae1263a109131c9f9 create mode 100644 fuzzers/corpora/commit_graph/1e9c882c9d33304a5791ef6c98eee65e142bd7fd create mode 100644 fuzzers/corpora/commit_graph/1f54935df929403a29e77591c97f767d94871aea create mode 100644 fuzzers/corpora/commit_graph/206015659641771bb0d668728c2fdc4209e65dda create mode 100644 fuzzers/corpora/commit_graph/2096493a2bcc2d15b7ae5bf3112fe49c39976ad8 create mode 100644 fuzzers/corpora/commit_graph/209b74e08abe8c787b7c5ba81e51cb69c57ecded create mode 100644 fuzzers/corpora/commit_graph/21137876575fbca357fc0c96db1de73c6737e1ae create mode 100644 fuzzers/corpora/commit_graph/2143d9db9802f076c72a71184cd9d0cb4581e9e7 create mode 100644 fuzzers/corpora/commit_graph/21a52a5282145407d951ac73c2ff27876783899d create mode 100644 fuzzers/corpora/commit_graph/21d5c8c8ac3a09bcba5388c472df32795986a5cb create mode 100644 fuzzers/corpora/commit_graph/22170d1110a1c18009b7feb21a470681f55e85fb create mode 100644 fuzzers/corpora/commit_graph/22f55dff94785f24252d7a070f713840f59b0870 create mode 100644 fuzzers/corpora/commit_graph/23d10ee9694e1c66bedc7060990f19a2ac3eaee3 create mode 100644 fuzzers/corpora/commit_graph/2435430ca19502c3b0ec4987508d4a8fbdbc898c create mode 100644 fuzzers/corpora/commit_graph/244d2ea0c5c3117000b599cfab37680ba8f04513 create mode 100644 fuzzers/corpora/commit_graph/248bf94143d150da2459cfdca099c30c6daff00a create mode 100644 fuzzers/corpora/commit_graph/25bc53498129bb3717671f00c355d2637a91c86a create mode 100644 fuzzers/corpora/commit_graph/2614f60da2d7e291501397238366d27513bff773 create mode 100644 fuzzers/corpora/commit_graph/2651b3d5a8b4616b1faa81dabe27ab2712a27561 create mode 100644 fuzzers/corpora/commit_graph/270257a2872b33dd13c4fd466cbc1ae67d613f9b create mode 100644 fuzzers/corpora/commit_graph/2830c6244c74656f6c5649c8226953905a582a38 create mode 100644 fuzzers/corpora/commit_graph/2889a85c07c20551ff0b97fc640e3c91b33aa4a1 create mode 100644 fuzzers/corpora/commit_graph/295ce43fdd56def8948d1ba2bfa7fdf0c47b5318 create mode 100644 fuzzers/corpora/commit_graph/296cbb94c4e68ab86972a174405308ee34d0c40f create mode 100644 fuzzers/corpora/commit_graph/2975adf222cad108ec90d8225fd655e30e3bf253 create mode 100644 fuzzers/corpora/commit_graph/29f5d27760c9254ab4db661a6cd0323dd11c34ca create mode 100644 fuzzers/corpora/commit_graph/2a359fb09eaad968e57d353453908027645873d1 create mode 100644 fuzzers/corpora/commit_graph/2a6b65a8d6c28febaa081d220a4433f8366d02bc create mode 100644 fuzzers/corpora/commit_graph/2b14dcade4d0919b0a17830fe353738015f492a6 create mode 100644 fuzzers/corpora/commit_graph/2b298a13abbd9829e965424a1486baa13d4166c4 create mode 100644 fuzzers/corpora/commit_graph/2b44d8cd8e70e25172b4c740ebe38ef411c965b3 create mode 100644 fuzzers/corpora/commit_graph/2b590c4e61fdfcf21c017b29440747a1894b1534 create mode 100644 fuzzers/corpora/commit_graph/2becb18a971ae30e1a8f6680982fd7305708caa0 create mode 100644 fuzzers/corpora/commit_graph/2bf78b02099a1fe4ce50d065254e843ca55e280f create mode 100644 fuzzers/corpora/commit_graph/2c1541ecd01aa7b9e99bccfe9804198b3e79f118 create mode 100644 fuzzers/corpora/commit_graph/2c6798057af5894c27631ff63e845fe1e4bdc9ee create mode 100644 fuzzers/corpora/commit_graph/2cf7eb7fe489e5acd64df755e820c871784c2ba1 create mode 100644 fuzzers/corpora/commit_graph/2d49ba35ca404baa0d593925f36a81ce53943c8d create mode 100644 fuzzers/corpora/commit_graph/2d507d42ca43ffc2f3c8892826e1db74144ec096 create mode 100644 fuzzers/corpora/commit_graph/2e4da693e3e336d2b1a40311a7ccf94def035b6b create mode 100644 fuzzers/corpora/commit_graph/2e71ff86128b5618f0f067c407a76ff645ae2019 create mode 100644 fuzzers/corpora/commit_graph/2eb777c6d7e6ee9bd7a44e37372595043aad596b create mode 100644 fuzzers/corpora/commit_graph/2ec3ebffba165b9dd49e755a9e77e23aed796628 create mode 100644 fuzzers/corpora/commit_graph/302703e3b0d74219868aca39ee7593944c0b2400 create mode 100644 fuzzers/corpora/commit_graph/3048c6908dc3176707fa8bcb0196824e3358357a create mode 100644 fuzzers/corpora/commit_graph/30616cb39d3ad6060324fada03709d611ad28d5c create mode 100644 fuzzers/corpora/commit_graph/306beadd9b3135a00037323760eb5377c88a403e create mode 100644 fuzzers/corpora/commit_graph/31464a6fbad023923a7e4700fc11564e811bcbd2 create mode 100644 fuzzers/corpora/commit_graph/317f4bcfecf066961ef1982d551cd14e63c9f008 create mode 100644 fuzzers/corpora/commit_graph/31b2248faaabbec69a06098c8cb0f69c5d0aa208 create mode 100644 fuzzers/corpora/commit_graph/31d1c3d1147385d58dbe6f82898a5523320fbcac create mode 100644 fuzzers/corpora/commit_graph/32c9bc1616a78a230a3724abc02150db1cc40aa0 create mode 100644 fuzzers/corpora/commit_graph/331e2866416b091252f0299e98d32cfb29237029 create mode 100644 fuzzers/corpora/commit_graph/331eb3876dd2f3f0bd51f380ac431d86d6e3bb5e create mode 100644 fuzzers/corpora/commit_graph/346bd6eaeadeafcb840ff9441614b309330db63e create mode 100644 fuzzers/corpora/commit_graph/349931f447981f21476481448576e805c093a25b create mode 100644 fuzzers/corpora/commit_graph/34a2da1e9adaac1b4be1d40b1ece81fe00643d49 create mode 100644 fuzzers/corpora/commit_graph/34bb8f475e7384a8a39618fd15fdc5fb1b12c1a1 create mode 100644 fuzzers/corpora/commit_graph/351a036c6eb95db9364706b861f7e75ad26194e8 create mode 100644 fuzzers/corpora/commit_graph/355452c1da8e7689d816d67cdde040b5df7eabd7 create mode 100644 fuzzers/corpora/commit_graph/35c157ad2b100b4f334cddcf3dea6ef2d85462be create mode 100644 fuzzers/corpora/commit_graph/36a81a45eabfcf53e1ae0361aa234791e2fdb750 create mode 100644 fuzzers/corpora/commit_graph/36ee20f6dbeb3a34e91eafbbe2e379f9ac6cfa43 create mode 100644 fuzzers/corpora/commit_graph/377627c19bcac6adc880202048a9eac07b5417d4 create mode 100644 fuzzers/corpora/commit_graph/38747e7c8bec2f9c923739d50ba54ff88ba6503f create mode 100644 fuzzers/corpora/commit_graph/3945843a6fab2ec71030f09b237c125b97cd3ea5 create mode 100644 fuzzers/corpora/commit_graph/396321d39b82ffaccbc64115117df7e822b0f515 create mode 100644 fuzzers/corpora/commit_graph/396e78eb9b54e2cefb52cd76a22137c8abd6cbcf create mode 100644 fuzzers/corpora/commit_graph/39c1ab66035adc104cd06a6d98b77668172d21af create mode 100644 fuzzers/corpora/commit_graph/3a1078c35f5401ce09b5ba921fc348dde37530bb create mode 100644 fuzzers/corpora/commit_graph/3aa3d8f40392d1c863d23799b8ec0aedc7191302 create mode 100644 fuzzers/corpora/commit_graph/3b08c505601271cb92345ec7f0ff0b28daf90a9c create mode 100644 fuzzers/corpora/commit_graph/3b41702587be45f678b36823ad2f7e5002337dc4 create mode 100644 fuzzers/corpora/commit_graph/3b69108cc919aba0248f9b864d4e71c5f6d1931e create mode 100644 fuzzers/corpora/commit_graph/3b90507501bb3bcfe0094f9c92cc2869f1a7dda5 create mode 100644 fuzzers/corpora/commit_graph/3bc7fe44c3a1464dd35a4d22b482f46cdeda0405 create mode 100644 fuzzers/corpora/commit_graph/3ce99994986efb6df3f3568423e0077b53c7ef78 create mode 100644 fuzzers/corpora/commit_graph/3d6cb3ba21181c9f0ab08b2608eab773f36773f2 create mode 100644 fuzzers/corpora/commit_graph/3d8ec41450b943d5dea73fb1e393960b03d7c3b9 create mode 100644 fuzzers/corpora/commit_graph/3e29e8baaac0f6c7e4cf3d5adca2ab3a2c491ac7 create mode 100644 fuzzers/corpora/commit_graph/3e9469b3c68ba334671aacda7a7669b0e97b74d6 create mode 100644 fuzzers/corpora/commit_graph/3eeda3bfa7abef69911c94520c009a08c49b9942 create mode 100644 fuzzers/corpora/commit_graph/3f0f5021016451b57f673d0603cd9e4830c2198d create mode 100644 fuzzers/corpora/commit_graph/3f46540fbd94bf0337c1d0d7437ec992a3568f09 create mode 100644 fuzzers/corpora/commit_graph/402d9c25d5833d42630882ab5c57833266bef785 create mode 100644 fuzzers/corpora/commit_graph/4048bb3c26d67c345630ff9e86db551a3add6549 create mode 100644 fuzzers/corpora/commit_graph/40792f23c1281842dab671e8b213fc408d1ec39f create mode 100644 fuzzers/corpora/commit_graph/41cd0b5d9a9540947b7b1841a55e4c11bd4346a2 create mode 100644 fuzzers/corpora/commit_graph/41d86e5ea3df4a0de60d42aeb16e2a5599aedeae create mode 100644 fuzzers/corpora/commit_graph/42b4e5430b2b1b17a361067fb9dd33ab74e52232 create mode 100644 fuzzers/corpora/commit_graph/42ef1c9d234b90acaf1651d930fc52d5f8f158f2 create mode 100644 fuzzers/corpora/commit_graph/4570c8ff26d7f31afe73b3d9a35a29bc1274d68a create mode 100644 fuzzers/corpora/commit_graph/45cf4751a5929930a7c30ec10134434b9ee13c3d create mode 100644 fuzzers/corpora/commit_graph/46e9d351dd5bb71f7d4d8f15b3fad312c781452e create mode 100644 fuzzers/corpora/commit_graph/472421633b984556b96bc20f1fcf7a98c25736f3 create mode 100644 fuzzers/corpora/commit_graph/47f35b91699caee098cacdde0161ffab21bdfc57 create mode 100644 fuzzers/corpora/commit_graph/48b9da327218f9409287687a43b7eead4789a588 create mode 100644 fuzzers/corpora/commit_graph/48d14fca326d5d591d18d34c2821a457277819a2 create mode 100644 fuzzers/corpora/commit_graph/48f3a33e2a027f5735d0a333ec4acd5a2aa57118 create mode 100644 fuzzers/corpora/commit_graph/49e0eee24eab094a9c62f6b37b6ba01f8aece4e4 create mode 100644 fuzzers/corpora/commit_graph/4b45bcb707d2a0bc23b415e9bc3d7eb1f7f0e188 create mode 100644 fuzzers/corpora/commit_graph/4c428300fe4866fe81cff02ad4bc14b6848f7f73 create mode 100644 fuzzers/corpora/commit_graph/4d69c567df2e858c5f248b3fc8e4a9c04f02481c create mode 100644 fuzzers/corpora/commit_graph/4d88b6c9b513d5db2e07313a39b43d112d3d4562 create mode 100644 fuzzers/corpora/commit_graph/4da73370cf854ef8bd08c7f79b92a187cdbff278 create mode 100644 fuzzers/corpora/commit_graph/4e4b2827351bbfd414b718052a8f950a9e3eb7ee create mode 100644 fuzzers/corpora/commit_graph/4ed43f7d3c0305461edcbc86f62e0c6ad56df01e create mode 100644 fuzzers/corpora/commit_graph/4f011529809e88205421fa8ce39dcc025293bcb8 create mode 100644 fuzzers/corpora/commit_graph/4f1928b6376369ab6acf8a282284366cc3bf71ef create mode 100644 fuzzers/corpora/commit_graph/4f669eca3416c44f0d003ef2720d03e697e2230e create mode 100644 fuzzers/corpora/commit_graph/4f750f24ecb5080bea2845061cfd3ce4529d30ee create mode 100644 fuzzers/corpora/commit_graph/4fab9bb2bacf562e65f4a8681c429e6ea92aaed7 create mode 100644 fuzzers/corpora/commit_graph/4fd757c7251c17413b3005fb38aee0fd029d89ec create mode 100644 fuzzers/corpora/commit_graph/506092de91dcf93254cdd5ad9e02a953a38099ea create mode 100644 fuzzers/corpora/commit_graph/50e934fb52d9bc5cd2a531adced1cad7f102a112 create mode 100644 fuzzers/corpora/commit_graph/512e49a9e789656964988950009e6534907e6317 create mode 100644 fuzzers/corpora/commit_graph/51404149f1ea30ee6959fafe81a52acabed97e9e create mode 100644 fuzzers/corpora/commit_graph/5150f8a67399ee16178a2b08198cf91a90c0e53e create mode 100644 fuzzers/corpora/commit_graph/51a1fd23dfe5a8062cd4601d235509247f3bc2dc create mode 100644 fuzzers/corpora/commit_graph/51a963486f041a60c422f0dd6da3b69c52f12fb7 create mode 100644 fuzzers/corpora/commit_graph/51fbf57a2a35ec33164838fa254fe605a3c868e9 create mode 100644 fuzzers/corpora/commit_graph/53068b9f9cb54bb52d076e9602ccd55f169ef39a create mode 100644 fuzzers/corpora/commit_graph/5314619e15fa5ee67df44481b8213a53786d39c5 create mode 100644 fuzzers/corpora/commit_graph/533f5f00275968129846522fe01e2819746272eb create mode 100644 fuzzers/corpora/commit_graph/53a62799135c282435a17e032deda03eaf9daf0f create mode 100644 fuzzers/corpora/commit_graph/53c9d5cd849977e523d92dd2d639e9b0e721be50 create mode 100644 fuzzers/corpora/commit_graph/54767a0bb3b96d39f5b2004ce3f274465f1a927e create mode 100644 fuzzers/corpora/commit_graph/548de37dbe6a3829b73d976996ec9838cf608554 create mode 100644 fuzzers/corpora/commit_graph/5522cefa54b798ea4aba8ef2a42ad248a7fb02ee create mode 100644 fuzzers/corpora/commit_graph/554fab3eef5d8709f06d1d4319efe5c0c437421b create mode 100644 fuzzers/corpora/commit_graph/567fe73919dae39b0bcb78b03d655643a71714a8 create mode 100644 fuzzers/corpora/commit_graph/5717a281aa722ee4a32dfa1cc72fc5d6081f6755 create mode 100644 fuzzers/corpora/commit_graph/577d814e0be43df9321c5b27119c398bd00a00c5 create mode 100644 fuzzers/corpora/commit_graph/58680611707c6188f9f067f8747b699cd2fe82d3 create mode 100644 fuzzers/corpora/commit_graph/5915b7f91dd43ec37a4718061c90cbec2686b916 create mode 100644 fuzzers/corpora/commit_graph/599516e368ff621dd06d8450837350f4e9558c38 create mode 100644 fuzzers/corpora/commit_graph/5a2d01d141e4d523e718c30e20cb07c3ad98f33d create mode 100644 fuzzers/corpora/commit_graph/5a9803ef8cd88d1e8f1d6e5920b8afd170cafb11 create mode 100644 fuzzers/corpora/commit_graph/5ba93c9db0cff93f52b521d7420e43f6eda2784f create mode 100644 fuzzers/corpora/commit_graph/5bf0ca772092e6fa34b6822f61a1b1c3d7f2c6e3 create mode 100644 fuzzers/corpora/commit_graph/5cfbfb3e12b629dc9f74baf0a8741345ec288795 create mode 100644 fuzzers/corpora/commit_graph/5d8cc97b739c39820b761b6551d34dd647da6816 create mode 100644 fuzzers/corpora/commit_graph/5dcbb3e1c2fc9a191dd3f3443b86f6bc38c39e37 create mode 100644 fuzzers/corpora/commit_graph/5ec17d081aef9872f746e88ad8b03553719f9c36 create mode 100644 fuzzers/corpora/commit_graph/5f88e3ba60c11be25c47a842763d8870d23cc7f2 create mode 100644 fuzzers/corpora/commit_graph/6045e4d2bf85013c78a32e71b014ba3d4a4b7c61 create mode 100644 fuzzers/corpora/commit_graph/615c7ba7ffbce955ffd964682e2a0f7ef3c767e4 create mode 100644 fuzzers/corpora/commit_graph/6189f29cbbe88ac6cb32fdefecda1bd6194332a6 create mode 100644 fuzzers/corpora/commit_graph/627224cb8484c62992dcbc4cdebdbfa48a3c021a create mode 100644 fuzzers/corpora/commit_graph/629fff0962d298a7283a3d1e1d1b940dfef9b315 create mode 100644 fuzzers/corpora/commit_graph/6322594cff2a99d0abb1139e6a43b06df76d539a create mode 100644 fuzzers/corpora/commit_graph/63de5e8e042222d53bf05640c87da376aefb76cc create mode 100644 fuzzers/corpora/commit_graph/647dbb1d05fe0fab685bfe126bd9ac3a12b6bccf create mode 100644 fuzzers/corpora/commit_graph/647e5e265d8d1079784fc2a3da25f7ba58126acd create mode 100644 fuzzers/corpora/commit_graph/653bd480dfd1e5f4bdca702aba3dfd8da0c204b7 create mode 100644 fuzzers/corpora/commit_graph/65485740a465377213c80fa68028727f281299fb create mode 100644 fuzzers/corpora/commit_graph/6551f8c8c3028006d0cc4997943df8a86ee3f598 create mode 100644 fuzzers/corpora/commit_graph/67799e79d33883510f85ae9705ab3932862128a2 create mode 100644 fuzzers/corpora/commit_graph/67b475481e5a21351b49789874adbc988aefd64c create mode 100644 fuzzers/corpora/commit_graph/67e5a649967dee002d1c181e079748c404e29767 create mode 100644 fuzzers/corpora/commit_graph/687424a4a31a66a78d1637c680c9c10746741007 create mode 100644 fuzzers/corpora/commit_graph/68fa6dd52832657cb8dd7e1485d6fbafd4e93903 create mode 100644 fuzzers/corpora/commit_graph/691696af1c042115f4d9f9b8e24f7b8c06ed189b create mode 100644 fuzzers/corpora/commit_graph/6a80152f9b1afa3a3080bf3f6aa48e84c2e18497 create mode 100644 fuzzers/corpora/commit_graph/6af27e4cf4c7bcce128a5949ee27fc73ab2cc71e create mode 100644 fuzzers/corpora/commit_graph/6afd8f82d5639b774de0dfd418ae85322f4168dd create mode 100644 fuzzers/corpora/commit_graph/6c64a9e26e0e1480bb5e60b7044ca6ce17104a80 create mode 100644 fuzzers/corpora/commit_graph/6c850c17db130ca0152f7c75562fa191f7ef89de create mode 100644 fuzzers/corpora/commit_graph/6c9afe4527371a2baf33c5e220e4ca21a3207f94 create mode 100644 fuzzers/corpora/commit_graph/6ce3d40b0225923a7f4123a919b1c5d70841fad7 create mode 100644 fuzzers/corpora/commit_graph/6cfd064aa6197813eb18f38df967ae4cdba9c6da create mode 100644 fuzzers/corpora/commit_graph/6e6675676c53bcddc870e06605d2432e3429f224 create mode 100644 fuzzers/corpora/commit_graph/6e6e82579b7abae2b43d90448d3f2ead4dfcba78 create mode 100644 fuzzers/corpora/commit_graph/6f13d23c75a562eddefafe85e208e602832294e2 create mode 100644 fuzzers/corpora/commit_graph/6fed59b0472927f5d2396d0ee4d7fd13579377ce create mode 100644 fuzzers/corpora/commit_graph/71f7724196f9f8fcfe3ee0161a84893bb9c4ab11 create mode 100644 fuzzers/corpora/commit_graph/7335ecb1d41e713bf3909adf5802b90e22bc1581 create mode 100644 fuzzers/corpora/commit_graph/73afaa73175f461e1d19d5138e055c1649926dfe create mode 100644 fuzzers/corpora/commit_graph/73e2fcb45c4df90d19091056b235e7a317631a62 create mode 100644 fuzzers/corpora/commit_graph/741cb2d5ae11b0a9e0608b58ec7284d75129a1f2 create mode 100644 fuzzers/corpora/commit_graph/7431bb0097a9bb52e1ceaaa8674a13cd3486a387 create mode 100644 fuzzers/corpora/commit_graph/7455b805995d0c96ac12f8a1c1264caaffcfac1c create mode 100644 fuzzers/corpora/commit_graph/74e39b8a82fc06f9ed8f83ea30545ddf6df66811 create mode 100644 fuzzers/corpora/commit_graph/75d51e413d3e916560dc0c2ee5092d2f4972aec1 create mode 100644 fuzzers/corpora/commit_graph/75e068964ea6beb7310a154d763de74a70071f48 create mode 100644 fuzzers/corpora/commit_graph/763bf498dd847bd2b4af7b611199619bd428bea6 create mode 100644 fuzzers/corpora/commit_graph/77064ae04581a3c6d2a77158ef1a0b1e60db414a create mode 100644 fuzzers/corpora/commit_graph/783bb14d68021061f592601607f40fe232ad17c4 create mode 100644 fuzzers/corpora/commit_graph/7862814cb684310b54ef920b35403515efaba13c create mode 100644 fuzzers/corpora/commit_graph/791fd85b6ffb2429e9fa5ba29eebdce214ad88c7 create mode 100644 fuzzers/corpora/commit_graph/79396d4f6142a53e26e14aa6ccb4afb4fd8fc580 create mode 100644 fuzzers/corpora/commit_graph/79661b8e529e2182d5c612faba9f26e32a122b78 create mode 100644 fuzzers/corpora/commit_graph/7969143acb3334bffac46c6dfd96362c81644191 create mode 100644 fuzzers/corpora/commit_graph/79d84866dc8c067508c02516b65c0e48cf689b56 create mode 100644 fuzzers/corpora/commit_graph/7b61f8f4a96e309bbe64ed82637fc81492a9652f create mode 100644 fuzzers/corpora/commit_graph/7b8123f973edfb0f3cab027c0cd6b8efc7b11d6b create mode 100644 fuzzers/corpora/commit_graph/7b8dd3093efba07f7a4d3bab4b90b8f6e4f28bfb create mode 100644 fuzzers/corpora/commit_graph/7cc771aab0f3be7730881a46d952ae0a06958201 create mode 100644 fuzzers/corpora/commit_graph/7d177f4207de78d50df2493a3bc07f2cd578b363 create mode 100644 fuzzers/corpora/commit_graph/7d2df075f3e73ea9809c31586c37ece0f568b7fa create mode 100644 fuzzers/corpora/commit_graph/7d386e68e4c733a1fb11c0117f379fb4b9955fbb create mode 100644 fuzzers/corpora/commit_graph/7e4260830352479d29310bd6e1022e19a68ffe76 create mode 100644 fuzzers/corpora/commit_graph/7e4dfdae52be18cf95555c2eb1f54af7f69c6dde create mode 100644 fuzzers/corpora/commit_graph/7eafedf7e7f20e86ecdf9ba51febf8492bdbc1f1 create mode 100644 fuzzers/corpora/commit_graph/7ef1829a378d66b1dd70a767729127a0dc5edcae create mode 100644 fuzzers/corpora/commit_graph/80b7d2b9d7e8c8fd7ae239b8d307b592f97ee000 create mode 100644 fuzzers/corpora/commit_graph/810f577ff5c1af7807a26226af912687558158cd create mode 100644 fuzzers/corpora/commit_graph/81603f1fe8d8e29005418d0fc9a9b33972366038 create mode 100644 fuzzers/corpora/commit_graph/81c8b4d6884f954935fa4a8e828c4637db04b61a create mode 100644 fuzzers/corpora/commit_graph/8226846e9b092561f85cc2956ab89d8cc1ae61e0 create mode 100644 fuzzers/corpora/commit_graph/825cfceea434e2392cce161356e3cb5f81ec2b3a create mode 100644 fuzzers/corpora/commit_graph/82603febce83d95adf68b85cabf15d43ca0c4ee9 create mode 100644 fuzzers/corpora/commit_graph/827f0826cc4156e19b4c4938bec74e38de62fe9c create mode 100644 fuzzers/corpora/commit_graph/8486397ff8d1156249676c19b419a7758ff53f9a create mode 100644 fuzzers/corpora/commit_graph/84d99ee359bec1b8ee0f59e9bd96f1da062030b7 create mode 100644 fuzzers/corpora/commit_graph/84e629bc7416039f1feb81fa9168d7c1ee3141c2 create mode 100644 fuzzers/corpora/commit_graph/84e885752179076fb38739ca7bc4345716bee56a create mode 100644 fuzzers/corpora/commit_graph/859ef05494c8070057810b5c20df00fc81f81cf5 create mode 100644 fuzzers/corpora/commit_graph/859fe592f33abc1d959c0e73ecd6cd4bffe23a97 create mode 100644 fuzzers/corpora/commit_graph/860da5e8a468805b76a44b9ac99b4575be16ea15 create mode 100644 fuzzers/corpora/commit_graph/865e415745cead02a826f058a5ee49099bdf9562 create mode 100644 fuzzers/corpora/commit_graph/878bfce051a9c7462847d4e99b7e926dc821b7b8 create mode 100644 fuzzers/corpora/commit_graph/880492e4dc7259577c227bb4f075d7165e875c29 create mode 100644 fuzzers/corpora/commit_graph/88b7de1bd1c96454a1350286d115c0ee368511f9 create mode 100644 fuzzers/corpora/commit_graph/896268e4a5775b7ce33923ac6daeb0810420c55b create mode 100644 fuzzers/corpora/commit_graph/8978f8da89f9652878edabad164f5513ef508f27 create mode 100644 fuzzers/corpora/commit_graph/89a6525b7db0e6ec211a484efd2880abef928d4e create mode 100644 fuzzers/corpora/commit_graph/8ae86cba2bba6664fc5eb97be8e9777b8825d823 create mode 100644 fuzzers/corpora/commit_graph/8b845fbd2aa14e4f83c4dbc8b4b0b54d06482acd create mode 100644 fuzzers/corpora/commit_graph/8c4121e6ce5956cfa408b980f16d276f456374dc create mode 100644 fuzzers/corpora/commit_graph/8cb6a5b8ab41e3d27668d5735b5c09ff1f2eab65 create mode 100644 fuzzers/corpora/commit_graph/8d80a70ffd362a89b88663e27f11e8ab69b70c1b create mode 100644 fuzzers/corpora/commit_graph/8db603c1720b3680047f831f2ea9862567a7cdc4 create mode 100644 fuzzers/corpora/commit_graph/8dd40b2d27c7dd4b986c35d87f826da287c09c4c create mode 100644 fuzzers/corpora/commit_graph/8e9d6e6408e5f708a1924e8370e687e2c202a4c4 create mode 100644 fuzzers/corpora/commit_graph/8f2dff1a30ee28e5985cb9379828aea5658d5849 create mode 100644 fuzzers/corpora/commit_graph/8f7d18cdd6e605b85784ada14571fd5e5a184f2a create mode 100644 fuzzers/corpora/commit_graph/903ae52f0ac9af8348038b12f9259741b0de42f1 create mode 100644 fuzzers/corpora/commit_graph/9119e331f59e9337d419739c324f49d1bd62c8bf create mode 100644 fuzzers/corpora/commit_graph/91d54d03b0917314ea1d67a70690df9247dd08d2 create mode 100644 fuzzers/corpora/commit_graph/922da3b96725bfd0e3f6ce119f1e2249d53f9086 create mode 100644 fuzzers/corpora/commit_graph/9277561e0524cccba2f851970b0d88ec4f4d3f5e create mode 100644 fuzzers/corpora/commit_graph/92a4d571804026b7bbe957396185e079e756b894 create mode 100644 fuzzers/corpora/commit_graph/931224cc80168fd362a360d99bab813ed7bbf8ce create mode 100644 fuzzers/corpora/commit_graph/936ea5dad3bf023c552aa0bbeea8f7f66a11612c create mode 100644 fuzzers/corpora/commit_graph/93aa4e0b1864933dce0abc0df69fe3d261f117f2 create mode 100644 fuzzers/corpora/commit_graph/93d5b084965cf1b09085c4079a972e25207b3659 create mode 100644 fuzzers/corpora/commit_graph/9443fd3468bcc0bc3ff8dfe765225f045ab43d0a create mode 100644 fuzzers/corpora/commit_graph/9624c26cefb5804b7906147d262e81ee4000b6d6 create mode 100644 fuzzers/corpora/commit_graph/9890933a73f39208627bd36e2fe88a6d54343a74 create mode 100644 fuzzers/corpora/commit_graph/989dad0448e79af10040d5080f74eba2b8a401ba create mode 100644 fuzzers/corpora/commit_graph/98ed4808b4a8da66a91fcea1be63be6371a7c7ac create mode 100644 fuzzers/corpora/commit_graph/9928e516b85e22fbad58d562d3b7e814d9ce812d create mode 100644 fuzzers/corpora/commit_graph/994c7cc5599252b5628d89cd0ba4b5574d32bf00 create mode 100644 fuzzers/corpora/commit_graph/99c8557c2a02ea030de42869af42c1f7c77114db create mode 100644 fuzzers/corpora/commit_graph/9a14c867272f102b84efdba73662d318c3e51cfe create mode 100644 fuzzers/corpora/commit_graph/9a6f158c176d4a1982d541be2bc27a8afba4ea57 create mode 100644 fuzzers/corpora/commit_graph/9aa4af603192823a2fdc53d95ed36896bc3309b2 create mode 100644 fuzzers/corpora/commit_graph/9b40c2190123cec66af3b37212f6c567869efda3 create mode 100644 fuzzers/corpora/commit_graph/9b6268c11d78c35db5164f1346905e602b6a49fe create mode 100644 fuzzers/corpora/commit_graph/9c6883ba5cedb7d711b12733d66ef1a1156dd0af create mode 100644 fuzzers/corpora/commit_graph/9c85c90f44b454ce0d52882c447f5ecb8d303634 create mode 100644 fuzzers/corpora/commit_graph/9cb7a2e89ec636da3fd41ecc49ebe25e5344e2c6 create mode 100644 fuzzers/corpora/commit_graph/9d912dc5a3497e4b5b40b37202fc0ffbf5263666 create mode 100644 fuzzers/corpora/commit_graph/9dcbafe8c5345194ee0ce7eb4f6efaeb55543626 create mode 100644 fuzzers/corpora/commit_graph/9f4b0f3d2d25e6405ba6093f24d0605327711573 create mode 100644 fuzzers/corpora/commit_graph/a047bf683239fa208dbac09424b105820ac23f43 create mode 100644 fuzzers/corpora/commit_graph/a1379dcd89ef5e73eabbfcc395113e3636e0ae09 create mode 100644 fuzzers/corpora/commit_graph/a38c7ef56adabd0916abac514154b1f362d40434 create mode 100644 fuzzers/corpora/commit_graph/a38ec6ad4a8466b4feb88e67b16524e8f3feac64 create mode 100644 fuzzers/corpora/commit_graph/a3fdea21020268b3b2409c1115d50697d9ae8f8c create mode 100644 fuzzers/corpora/commit_graph/a45f1987a444b2c27e90fc1477e8b0815f75383f create mode 100644 fuzzers/corpora/commit_graph/a4682958fb7029384c0a01a4a1356ac6f2f44fe1 create mode 100644 fuzzers/corpora/commit_graph/a4de41561725960d6f48f210a4fb74d527f7b0c2 create mode 100644 fuzzers/corpora/commit_graph/a5935f34435ecdd6587ad4f77b20d479d3387dbe create mode 100644 fuzzers/corpora/commit_graph/a5b394beb2b1d463ad80924a8c8c70584bf5c629 create mode 100644 fuzzers/corpora/commit_graph/a62bc806f8c98ba7986243c2185a0548a8dd57ef create mode 100644 fuzzers/corpora/commit_graph/a7013e97948893e0118c686c06e332cc611bea7e create mode 100644 fuzzers/corpora/commit_graph/a74f5df8c7f25c37c15c0f74ed50019d17338225 create mode 100644 fuzzers/corpora/commit_graph/a7ab3559fb3da3f027e67091116253f3bdfd7828 create mode 100644 fuzzers/corpora/commit_graph/a845c8258a02022d447ea9249788b345f5504648 create mode 100644 fuzzers/corpora/commit_graph/a8d3e026e2393587eb170afb32e94ff0e1f8a8be create mode 100644 fuzzers/corpora/commit_graph/a8d547e41ee21e163e65cf0a186d469dfa50ec19 create mode 100644 fuzzers/corpora/commit_graph/a8fa22521dd6813e595cc0a9586ee71fff305fe2 create mode 100644 fuzzers/corpora/commit_graph/a9969442d585d9a53259c71c73b095701280eac5 create mode 100644 fuzzers/corpora/commit_graph/a99789d0ce2d7b937aaa8afa3cfc0f4ccd7be95f create mode 100644 fuzzers/corpora/commit_graph/aaca30ee3ab38edfa2b061fcbcbca0c0ea657f15 create mode 100644 fuzzers/corpora/commit_graph/aacdec3f05e98eb6eedddb9c6edb968e1a63c551 create mode 100644 fuzzers/corpora/commit_graph/aadd85127241b94a41d02d9e9699e3e9773de1c9 create mode 100644 fuzzers/corpora/commit_graph/ab8ad126702803d21dbafc85713bbee7f25f36e5 create mode 100644 fuzzers/corpora/commit_graph/ac26f9afd599ff6f33396c2e02130654f3e2390c create mode 100644 fuzzers/corpora/commit_graph/ac8b129e4756fda0c50c9dd0eb13e34c7b41ce8e create mode 100644 fuzzers/corpora/commit_graph/aceaf3b72c2627dd3dd065974b854150681c093f create mode 100644 fuzzers/corpora/commit_graph/ad1fcdc3bf806392e754a902eba9edd3b344c31f create mode 100644 fuzzers/corpora/commit_graph/ad8c80e532482f9dfbfbb7c0d447f1f4e592bf72 create mode 100644 fuzzers/corpora/commit_graph/add92b71bf897da2f71f691e6abcb6d02cb8e99f create mode 100644 fuzzers/corpora/commit_graph/aeb8ccf6d82be9236c9e689e1580d043bd701eb0 create mode 100644 fuzzers/corpora/commit_graph/af1a827aedbf674fff2bdeb5589554eec62787ab create mode 100644 fuzzers/corpora/commit_graph/afaab9a75414d231176ad4582b6f8d81b5dbedb3 create mode 100644 fuzzers/corpora/commit_graph/afc12c4ebed1f3ab962d7dcef110b5328b1e24c3 create mode 100644 fuzzers/corpora/commit_graph/b0044f3744cf019658d668a33f8d1e53ef8bd6ce create mode 100644 fuzzers/corpora/commit_graph/b06adc81a4e1cdcda3786970ca07ed9dee0b6401 create mode 100644 fuzzers/corpora/commit_graph/b139802a1cc90fd5b86cae044c221361892c688d create mode 100644 fuzzers/corpora/commit_graph/b1b8f251542db01bdb01be3b6d5b117b07db1834 create mode 100644 fuzzers/corpora/commit_graph/b1b9af93f84ed6861b9c0ade39980e89ef828c8f create mode 100644 fuzzers/corpora/commit_graph/b2eae68035cafd4077f6a4c3e4e961fdc1e8122b create mode 100644 fuzzers/corpora/commit_graph/b32897a6aedaa8c5a6e656dd808bafabc4ee5608 create mode 100644 fuzzers/corpora/commit_graph/b376e4fc517297f92ac1713803ae3b60d5ebbe43 create mode 100644 fuzzers/corpora/commit_graph/b3fd100b139cfbffaad68aacf7d462861e9dca35 create mode 100644 fuzzers/corpora/commit_graph/b40808ca955faab4829811bced1cccb2ab58ea58 create mode 100644 fuzzers/corpora/commit_graph/b43daf9f87a514bce74af3e5a39284c69c4e7011 create mode 100644 fuzzers/corpora/commit_graph/b477da07f3e5796ff4a98c8a5bdb0e4a634954bf create mode 100644 fuzzers/corpora/commit_graph/b4a2ef09cf59ca5ccf810a6f001cce710cc02f6b create mode 100644 fuzzers/corpora/commit_graph/b4b75e588cb83430c502a34ec3dcfaf774a00359 create mode 100644 fuzzers/corpora/commit_graph/b4ce98acd2b288b6cfc00461e2e15e0f8004030c create mode 100644 fuzzers/corpora/commit_graph/b75563f30f7e4fb369d2449b723ee8b282d03eff create mode 100644 fuzzers/corpora/commit_graph/b7a0a820afa7057081de186728d0d887131d9314 create mode 100644 fuzzers/corpora/commit_graph/b7e880446146c735a3f820fb93969c8c172c2fb5 create mode 100644 fuzzers/corpora/commit_graph/b833073d3006e7cbac03c494603a9b75e7b2a723 create mode 100644 fuzzers/corpora/commit_graph/b89459c1fb6fc918db4c81a32a75ee66217f9ab8 create mode 100644 fuzzers/corpora/commit_graph/b8aab6c9b2c706f8df0ff695ff94969171f9c807 create mode 100644 fuzzers/corpora/commit_graph/b9751182a36acb79b77585e1e379857a530e95c8 create mode 100644 fuzzers/corpora/commit_graph/b9ddb239b5a2c1348d972ec70a08507c35ba4432 create mode 100644 fuzzers/corpora/commit_graph/ba8f573256a0fbb95c5626f399ebc3ef50bbd826 create mode 100644 fuzzers/corpora/commit_graph/bc165749042d5425c5d6d4e29b17769a2315a80d create mode 100644 fuzzers/corpora/commit_graph/bc910bd349319e1ed44d7c7266e3ac99cc29ecc6 create mode 100644 fuzzers/corpora/commit_graph/bc97b1d4f57eb7770bc3983e2d57c8c01b21d29e create mode 100644 fuzzers/corpora/commit_graph/bd06f768e35ded4437cb88e2bc0ddd0bea3fa84c create mode 100644 fuzzers/corpora/commit_graph/bd702faff9725a7a1957fd0f85cc52799f37b682 create mode 100644 fuzzers/corpora/commit_graph/bee4464861e1cae3cfdd5fbcb340efbf02e8d8ca create mode 100644 fuzzers/corpora/commit_graph/bf7ad994b098ec85d62683a16e067635e21a8af5 create mode 100644 fuzzers/corpora/commit_graph/c054fc89ed72101dec861668ff1738ef85b728b9 create mode 100644 fuzzers/corpora/commit_graph/c06752415ac037fefe5172dc7245cd7c49ca7fca create mode 100644 fuzzers/corpora/commit_graph/c0c8b54354d172a0be751e3e9b80be961bb15ddb create mode 100644 fuzzers/corpora/commit_graph/c0e7ca9b5b4d0e72d23d7dc9e9d1f2463a17a20d create mode 100644 fuzzers/corpora/commit_graph/c13576a29c98bee02aa47f646f5f170f9b7d83f9 create mode 100644 fuzzers/corpora/commit_graph/c14edf1d34f40b3cc74772c81ebe5d72172cc662 create mode 100644 fuzzers/corpora/commit_graph/c2789364cb35d111f08f924d0d7550ea9785c61e create mode 100644 fuzzers/corpora/commit_graph/c2d8b07acb13e43a89b6c4afb3ecb9817dd4a8e9 create mode 100644 fuzzers/corpora/commit_graph/c36ed796c1bf839668db8fc3475a2ffb32ad8ceb create mode 100644 fuzzers/corpora/commit_graph/c41ec9dd94427423e4704721e7f21eae0c44ef20 create mode 100644 fuzzers/corpora/commit_graph/c42c544fa9dbb1264b39bf920b40985384db1d16 create mode 100644 fuzzers/corpora/commit_graph/c45ec3f594abc15de0a8cc3ad748ba23cb34ec64 create mode 100644 fuzzers/corpora/commit_graph/c49004d980961f288616a4eb9ebf68123fd68ffa create mode 100644 fuzzers/corpora/commit_graph/c4c3c3c8df24adf505127627b3090116de78d9a6 create mode 100644 fuzzers/corpora/commit_graph/c5c1921293af4a5953cb386092694042715fcfb3 create mode 100644 fuzzers/corpora/commit_graph/c615caad21cd8a754fcb2008420234c5511c62b7 create mode 100644 fuzzers/corpora/commit_graph/c6a9ee3f8fdc42566c4799db3912a83c8c438d7f create mode 100644 fuzzers/corpora/commit_graph/c6b661e976282051285b913b3728383f36103ef8 create mode 100644 fuzzers/corpora/commit_graph/c716ba47f810c238fe7bda1fbdc7b1ccc34e9848 create mode 100644 fuzzers/corpora/commit_graph/c85b2fa4421302e2fa333a9e33d59a882aa04f4f create mode 100644 fuzzers/corpora/commit_graph/c871d135f2d3117b326688355bc0fa6f26d56cd6 create mode 100644 fuzzers/corpora/commit_graph/c915b02265a27d185a8b028305f082ddb3ebd704 create mode 100644 fuzzers/corpora/commit_graph/c952d38b3e642db4795d7f954b85f4f6d2a041aa create mode 100644 fuzzers/corpora/commit_graph/c98ee52065736c4172f6ee0c31977bf1b560d685 create mode 100644 fuzzers/corpora/commit_graph/c99b183a2cd0dd8a4c1a141cc6eebb0311501fa5 create mode 100644 fuzzers/corpora/commit_graph/ca0cd26baff2f2c0759e619800ebbe7314d2bb95 create mode 100644 fuzzers/corpora/commit_graph/ca3e0d745c35d7cceb0f6e3f8a709eb658b7e5a8 create mode 100644 fuzzers/corpora/commit_graph/cac667320e99e93a796bb89842de4675735eb4a4 create mode 100644 fuzzers/corpora/commit_graph/cb41b00e9db33a07e27b3ee05d3bbecaf853b963 create mode 100644 fuzzers/corpora/commit_graph/cbdbd3f320eee627097778f15b9fb2c1dc2bd15f create mode 100644 fuzzers/corpora/commit_graph/cc7f114000c83abb2ab17f0deab6dcfc2acde7f5 create mode 100644 fuzzers/corpora/commit_graph/cc9bb93a6b7a1362a15f04898845dbe1447ec382 create mode 100644 fuzzers/corpora/commit_graph/cce7355f826bbcf3955394596d358abc7df6fe6f create mode 100644 fuzzers/corpora/commit_graph/cceff2878a558166fb5bf2a0354c1be31dcc4e21 create mode 100644 fuzzers/corpora/commit_graph/cd96909f3ded7aa54bb2ffd2f2f47f8acc6f99e2 create mode 100644 fuzzers/corpora/commit_graph/cee9f69d7d1a227833fba127a529ea2a10341da3 create mode 100644 fuzzers/corpora/commit_graph/d064f27a3109afde629165432f78f389da73ff07 create mode 100644 fuzzers/corpora/commit_graph/d07e3094f02b0c0e3bab370684c2d8c5634224d5 create mode 100644 fuzzers/corpora/commit_graph/d0ba3413d5706de17de64824d78233d48c6efbec create mode 100644 fuzzers/corpora/commit_graph/d136511364a74973b009f2be9b021d4122f71a6c create mode 100644 fuzzers/corpora/commit_graph/d1d215c40bcc8dd4ce02b0c0621e90b183b40b3e create mode 100644 fuzzers/corpora/commit_graph/d1e35b137b2027b61def408f3f3c8cf9bcab274e create mode 100644 fuzzers/corpora/commit_graph/d349d137e57fb1a60ab8babd20e2acedc7a9042e create mode 100644 fuzzers/corpora/commit_graph/d3714ec4d3acc6262295b0fc99c6ba699f5bfe65 create mode 100644 fuzzers/corpora/commit_graph/d419df696512216074f1c6b17ea1dfc81c0e6e20 create mode 100644 fuzzers/corpora/commit_graph/d49ad4fdafac251ceec32481826228c1698360aa create mode 100644 fuzzers/corpora/commit_graph/d4f85ba549c87ccaba59971a25da7e07b57c9f4e create mode 100644 fuzzers/corpora/commit_graph/d51ade0715bcea7decee2a045934599a10c1b07a create mode 100644 fuzzers/corpora/commit_graph/d5447fb72c97462a3f47c8b2d55deb0afaa225f8 create mode 100644 fuzzers/corpora/commit_graph/d6611a91c29291872ed2932455cb15ddb3801323 create mode 100644 fuzzers/corpora/commit_graph/d676f5e7efd6de6f2e1773231479471d2bba7261 create mode 100644 fuzzers/corpora/commit_graph/d6a21eaa08a957d8f428192e193c2508fca2c218 create mode 100644 fuzzers/corpora/commit_graph/d778052a29539344a9e3144e262e68df9628ebde create mode 100644 fuzzers/corpora/commit_graph/d884f6944adfff7cb41728062bf91cac5cdacfc9 create mode 100644 fuzzers/corpora/commit_graph/d89aae18d8e320bbae55eaae6a0514d7e005a883 create mode 100644 fuzzers/corpora/commit_graph/d926fde818c63f7b34f38c9f018bc833bc0bf7e1 create mode 100644 fuzzers/corpora/commit_graph/d9d542d7c56774143cb6362e5a63739055469349 create mode 100644 fuzzers/corpora/commit_graph/da99bc9ce5b831f132dfb2eb11b8537e5cccfcd4 create mode 100644 fuzzers/corpora/commit_graph/dabff2729fa69ab507fb00b7392aee1262056a29 create mode 100644 fuzzers/corpora/commit_graph/dac4f4b91e33847bcedf7c66ef6e4ad0181e8ad8 create mode 100644 fuzzers/corpora/commit_graph/db10ff6d01c7a66aa1823b9f99193590ddce99c6 create mode 100644 fuzzers/corpora/commit_graph/dbbda2208fa688a5275dda0d304630db01ca081d create mode 100644 fuzzers/corpora/commit_graph/dc47c5037be68a2747ff8a9fa450e1078a5ac5a5 create mode 100644 fuzzers/corpora/commit_graph/dc760f136b123e38677aec72853e3365f08010fc create mode 100644 fuzzers/corpora/commit_graph/dca41b901bf1612d4197e6a450366a00ac036ec3 create mode 100644 fuzzers/corpora/commit_graph/dca62f21fce50d1c8c51b82e0d7eeedc6746e652 create mode 100644 fuzzers/corpora/commit_graph/dcc7e6c444f95b10d634b1137413824e2cd68f62 create mode 100644 fuzzers/corpora/commit_graph/dcf4b6addda69040f792c9b860ade2af0b77a14c create mode 100644 fuzzers/corpora/commit_graph/dd6178166ac1eed82d132fea491bcda0d953227c create mode 100644 fuzzers/corpora/commit_graph/ddbd5d3074323ccd7cd70bf5de5a2f30de977d99 create mode 100644 fuzzers/corpora/commit_graph/ddd8ec5632bf1b8153d03a4537d3d76517c497d5 create mode 100644 fuzzers/corpora/commit_graph/de7a56f36e10d7b9ff43160b1cea3e76b24386d1 create mode 100644 fuzzers/corpora/commit_graph/defa60aa46ea5a47c09b6962b4e4296ef1bcad92 create mode 100644 fuzzers/corpora/commit_graph/e0ae419425207832518d66c0ef35d11cbdc20361 create mode 100644 fuzzers/corpora/commit_graph/e0f519accbf15bc57a1bf1d7cc46d2a0b07a67f5 create mode 100644 fuzzers/corpora/commit_graph/e128eff8ca7572d9bb0bfc84f64d79c52afc2c67 create mode 100644 fuzzers/corpora/commit_graph/e17fdc21ae03243bd1d31bb6301b4187cab6fe47 create mode 100644 fuzzers/corpora/commit_graph/e340ace35a2db7f89d6aa21cc1300766a74be4e1 create mode 100644 fuzzers/corpora/commit_graph/e36dfc11bcaab1e42df13924a2d7da024684db2e create mode 100644 fuzzers/corpora/commit_graph/e39e0c87ac5ce0b78c89ae2df84226baba666372 create mode 100644 fuzzers/corpora/commit_graph/e46b4666c6bfcd6f589ec3617a48cce9c968e833 create mode 100644 fuzzers/corpora/commit_graph/e57219555e11f9221d3166d5029ed2ad92300608 create mode 100644 fuzzers/corpora/commit_graph/e58ce590c2454e7ebe18e0a31a943b0b754fbd13 create mode 100644 fuzzers/corpora/commit_graph/e595f8fef5c8014cb0867978c6580301078ca0d9 create mode 100644 fuzzers/corpora/commit_graph/e5b76398f60628e879328d7009b9fa89feea14cb create mode 100644 fuzzers/corpora/commit_graph/e5cec0217eea93b18a59d76b0aed6b46b13fa6a9 create mode 100644 fuzzers/corpora/commit_graph/e637b4e0b47d0d6cd870502e6a2d6a53bf917f73 create mode 100644 fuzzers/corpora/commit_graph/e7a6cb6e5a1552837fdbee9025fc48a9373f8564 create mode 100644 fuzzers/corpora/commit_graph/e7f57c48016e1180c9af95acd34470881f10bd06 create mode 100644 fuzzers/corpora/commit_graph/e8253c668bfe37df5c5ada3226860cee74fb33a2 create mode 100644 fuzzers/corpora/commit_graph/e8f9981443c34ece02bca3c66130f3429d7b3375 create mode 100644 fuzzers/corpora/commit_graph/e91ed5416bbcd1b03803197b99c08f42c9869139 create mode 100644 fuzzers/corpora/commit_graph/e94201cfa88df7b198abd3abae9007a6780b52a7 create mode 100644 fuzzers/corpora/commit_graph/e967bbd6a0d251ae62c9c38b784271d707f792c0 create mode 100644 fuzzers/corpora/commit_graph/ea01737ceed783b3e0f66d9d0c409cb496c1d526 create mode 100644 fuzzers/corpora/commit_graph/ea40f7879a58d1e52a46404c761f76a949e14a31 create mode 100644 fuzzers/corpora/commit_graph/ea5ad04a54f95963baea1f47845847626e08dd55 create mode 100644 fuzzers/corpora/commit_graph/ea608a401f54b0ca70e42b897f0c8ce6efdbc0ef create mode 100644 fuzzers/corpora/commit_graph/eb8700d6b3728e6e70c2a0fe504543771639f2b6 create mode 100644 fuzzers/corpora/commit_graph/ec1f271b04c322353865f4819153d46df7def873 create mode 100644 fuzzers/corpora/commit_graph/ee215536e7f0cfbd07b53dd65c5af9a604a01830 create mode 100644 fuzzers/corpora/commit_graph/ee4d4393d7d79b755f85ef5bf8f6e3d743bfa258 create mode 100644 fuzzers/corpora/commit_graph/ee8099331b2c392e7e036ffcd4a9b36ec2c2082d create mode 100644 fuzzers/corpora/commit_graph/eede9da76db25513f8347f972e170102831de91a create mode 100644 fuzzers/corpora/commit_graph/ef707cdeaa9548b6c820f769c1d8ad607b3c4514 create mode 100644 fuzzers/corpora/commit_graph/ef98609d8196dc158365dfcbbc47e3d1699c50c2 create mode 100644 fuzzers/corpora/commit_graph/efa38b4269f978f3714b44b501831bea678244e0 create mode 100644 fuzzers/corpora/commit_graph/efba428e29811d233720ccaaf41966a309312a29 create mode 100644 fuzzers/corpora/commit_graph/efd514f056d8d83498b4724249c4623560e0390d create mode 100644 fuzzers/corpora/commit_graph/f00e449ba67ef15e7f29df1e6948c28155d72baa create mode 100644 fuzzers/corpora/commit_graph/f0a83929d588466051dced6eae0c387db307d646 create mode 100644 fuzzers/corpora/commit_graph/f0e53b72e5d69467e7c014474028ea734f4fcb26 create mode 100644 fuzzers/corpora/commit_graph/f186265b3f10f4383f4174e9fb74f0a0cdfa3fca create mode 100644 fuzzers/corpora/commit_graph/f18932fcce5a9db5d6c8f59d622eabc25e255e12 create mode 100644 fuzzers/corpora/commit_graph/f2ea163bddb95d67597e2a747779ebf4651cb2a9 create mode 100644 fuzzers/corpora/commit_graph/f2f7d48a6d86143ecb4969808d634163576065b1 create mode 100644 fuzzers/corpora/commit_graph/f34a833faf2b0dcbae8aaad142c76c7c7e534e99 create mode 100644 fuzzers/corpora/commit_graph/f5c044ce01645c069334698fb8c4750e44835912 create mode 100644 fuzzers/corpora/commit_graph/f680112645c2502f0612e9d017bbb50cb28affbf create mode 100644 fuzzers/corpora/commit_graph/f6b778d1b34415a7715905f54968c8b6eb057912 create mode 100644 fuzzers/corpora/commit_graph/f6ca6a62dc885c6b2a4b40c4aa1a7cb8118e30bb create mode 100644 fuzzers/corpora/commit_graph/f733a8770c23fde182d2fef7e0d96e67244274d5 create mode 100644 fuzzers/corpora/commit_graph/f8529ddf17d4505c0932c3d40abe33cbfd8c6f22 create mode 100644 fuzzers/corpora/commit_graph/f96f8419a3fc3719ae86d64e1147e7b7f66a2470 create mode 100644 fuzzers/corpora/commit_graph/fae241a6c87af37781a3b49e534b7ddb6636eda8 create mode 100644 fuzzers/corpora/commit_graph/faf8817a04b77c6a976ab0a3d1e905f79bb7f799 create mode 100644 fuzzers/corpora/commit_graph/fb3e769019fb25d384d4be9d38e4cbce00a6adbc create mode 100644 fuzzers/corpora/commit_graph/fb9b4b2a46f1c65076340a7bd03b076eb101b760 create mode 100644 fuzzers/corpora/commit_graph/fca9b0a398832c9ba02cdc811f625b97d5beb18e create mode 100644 fuzzers/corpora/commit_graph/fcb1b42c706e61245d5e86f708be777ae63f2772 create mode 100644 fuzzers/corpora/commit_graph/fd6c463e7c30b0e51198c0d1ebbea25f20145e3f create mode 100644 fuzzers/corpora/commit_graph/fdcbaa49097ad120c6d7709b29d5b65b8cf8e719 create mode 100644 fuzzers/corpora/commit_graph/fe46775b28a2923b8770b44381552a8a1560d875 create mode 100644 fuzzers/corpora/commit_graph/ff04441135ef3308fec2687cf688069c6df8aa31 create mode 100644 src/commit_graph.c create mode 100644 src/commit_graph.h create mode 100644 tests/graph/commit_graph.c create mode 100644 tests/resources/testrepo.git/objects/info/commit-graph diff --git a/fuzzers/commit_graph_fuzzer.c b/fuzzers/commit_graph_fuzzer.c new file mode 100644 index 00000000000..f5b9c898816 --- /dev/null +++ b/fuzzers/commit_graph_fuzzer.c @@ -0,0 +1,75 @@ +/* + * libgit2 commit-graph fuzzer target. + * + * 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 + +#include "git2.h" + +#include "buffer.h" +#include "common.h" +#include "futils.h" +#include "hash.h" +#include "commit_graph.h" + +int LLVMFuzzerInitialize(int *argc, char ***argv) +{ + GIT_UNUSED(argc); + GIT_UNUSED(argv); + + if (git_libgit2_init() < 0) { + fprintf(stderr, "Failed to initialize libgit2\n"); + abort(); + } + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + git_commit_graph_file cgraph = {{0}}; + git_buf commit_graph_buf = GIT_BUF_INIT; + git_oid oid = {{0}}; + bool append_hash = false; + + if (size < 4) + return 0; + + /* + * If the first byte in the stream has the high bit set, append the + * SHA1 hash so that the file is somewhat valid. + */ + append_hash = *data & 0x80; + /* Keep a 4-byte alignment to avoid unaligned accesses. */ + data += 4; + size -= 4; + + if (append_hash) { + if (git_buf_init(&commit_graph_buf, size + sizeof(oid)) < 0) + goto cleanup; + if (git_hash_buf(&oid, data, size) < 0) { + fprintf(stderr, "Failed to compute the SHA1 hash\n"); + abort(); + } + memcpy(commit_graph_buf.ptr, data, size); + memcpy(commit_graph_buf.ptr + size, &oid, sizeof(oid)); + } else { + git_buf_attach_notowned(&commit_graph_buf, (char *)data, size); + } + + if (git_commit_graph_parse( + &cgraph, + (const unsigned char *)git_buf_cstr(&commit_graph_buf), + git_buf_len(&commit_graph_buf)) + < 0) + goto cleanup; + +cleanup: + git_commit_graph_close(&cgraph); + git_buf_dispose(&commit_graph_buf); + return 0; +} diff --git a/fuzzers/corpora/commit_graph/005682ce1cb5b20c20fccf4be5dbd47ca399e53e b/fuzzers/corpora/commit_graph/005682ce1cb5b20c20fccf4be5dbd47ca399e53e new file mode 100644 index 0000000000000000000000000000000000000000..15d0d281366c7407d8603085d062d739e5a0c156 GIT binary patch literal 1092 zcmZ3r3I_gz0E~m3W&i?b_W%z@MrH63!Jzaq0s#Oqe6q77K6IjW`T4)+!0S2S7xDF{n!kG*V*C_>X zv#>Fy1Kj}>hme>GV3`EPwP^A1O literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/00574fc29fd1323e93d18d625cde80d3ea20e8cc b/fuzzers/corpora/commit_graph/00574fc29fd1323e93d18d625cde80d3ea20e8cc new file mode 100644 index 0000000000000000000000000000000000000000..4eabd00da7a542cd90d29790acb0401c976eb3a8 GIT binary patch literal 2428 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^=B#VW!i(?3c!z;!%wASnqD@k6U`%V~udy#fY*1#V1gQ;aGM{*MRn0kz=6_rLabrLhWKY1S*@ z&(vr!?l}w8zyZWOKrG_@NA_|lYwZ<5zmhWxuLoRM_b>%w+S9Bh%kR91`DR@5vZZjo z|6S$zfv&9j%i`aDp7s6-)8*ZHD))U8;-7?+2kbLTUT0q!t?eAV=bTkg)rBSBzquT# zU^uRprTxGsT!!W9vP8FuuV(JOP|ZK9r}N{@=e|e&JadwL6Zd0Txx}lS=s#rVYZC<&kySn5AJ<^)(P|#cL9(90@8yM6eheNt@uI| zMGh8D7I?zR9}-Tcv<)YUJ^%kdiqA+11*lpERv-fzBWELAY)F<8pfH`9;R%0eIvxDs z56$M&fT73?O~V}CFAtpj%W3_;U_xT4aah>1b6F3Kf$mJm=04^)kS z-^AK-2>}z9Ss@EwgKb&7C}4}T(RE~Vyq|txYJ_R<{?#QeA#ndI&=5u_RzYHe#YBMu LAhG{Y0AvFI8YMl( literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/00b6dde4b8d5e68a5ec40d88c39134cf2f1f8bc3 b/fuzzers/corpora/commit_graph/00b6dde4b8d5e68a5ec40d88c39134cf2f1f8bc3 new file mode 100644 index 0000000000000000000000000000000000000000..98f2d0e9d4561766438967cf38a4aa72b680f611 GIT binary patch literal 82 zcmZQzU|?`|5Aa}QWM=U9ba7)~FktwP0|1pWSO69IfEWx6EEZ6f1CZ$q6yO13P6hz4 CH63CA literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/020f0e77e42d8b3810019050f4c5ceadd205b37c b/fuzzers/corpora/commit_graph/020f0e77e42d8b3810019050f4c5ceadd205b37c new file mode 100644 index 0000000000000000000000000000000000000000..d09327d5488e233a5bab3e48cd17391b6e30d92c GIT binary patch literal 965 zcmezWlYxVQ0gO4LfecPG%mw6wFgFeil;iWuTaY+c=|JvJ?#wujaaHUzVgg;ZG#kl7zPyxskkZC}ZWG|Pp z)?N|xD><|9dccKs4^wI;*lgpnWME(cnFItpKsCp7BiZBF8oxSt==vuqFYDufU&(zO zBo9@?;(uggZ15kWi$!IV=O3SUA$sk)Pq#T|GKc|{utL>v_(Z*YV_J8UQNKr_?Ykq( zjQ2}s9d??(=_^hz;|dCx`23!479}rR3g`RZRh}Q{%BsIC{_W>k@1HPT-kqm%-`79> zNl1CXKGWoN_Lb4v&cS=mSp`*HSn~aw%aIC(<7!z9*U1K;aB+4I@L*(QX7KlPaRc#z zzyipIun3ZxSXDSMFbDu8YRe@A%volIEPNfm+QBVi@uGk&&PLav;fPfunjk_0EP}il z_|Vhb(lC0gRe`JivqsOGc=P2t7HXBtf9L zs7Vl2FGd1PLZm=Ms-mW&LB20|O%iG_SzD$>9A5 E02cfB$p8QV literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/02739c05abc1715fac1ce995b532e482abc8d4dc b/fuzzers/corpora/commit_graph/02739c05abc1715fac1ce995b532e482abc8d4dc new file mode 100644 index 0000000000000000000000000000000000000000..b9de08e1d85aaa1159a7b856780a74f72c8171c6 GIT binary patch literal 982 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^=B#VW!i(?3c!z;%S&e*_bgg=`B4P?`o9Xe7u~RI@pOe00nO6a!&yLm&pxaQq614G{-Qkp#3S zx=pr9`g7!5;manY*9S!QbMF;r{$`kBQ<%{%+$-I)>xx}lS=s#rVYZC<&p+M!`m7UZ zJa+-a4hazTL#uDgX@wWP0tSBtZcJ)Zj4BNNj|cDpwNQc?Sb+vWFf-H{9NsSvoczma z{l8#BVySUh*t2t455k)Z+EallSwL!zt7U0F@Clb;xw?d?iq6}r-_SCRq= x_@`M*mfv|1^Ub2=rI<^{`obxv7LR%13`Zs!vZ@L*(QX7FbKf=3_%2#;-QE!a02=0mBwxfU|iR fM7;m-XKJ)CFbLfL+S{ek!ZPFitiw+8H+=;FmnRc9 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/02e106f97a91b1d3aef4dd2d31368ae5077bd42b b/fuzzers/corpora/commit_graph/02e106f97a91b1d3aef4dd2d31368ae5077bd42b new file mode 100644 index 0000000000000000000000000000000000000000..f1277396cf55c24c22b05d5412200453fc9e76ef GIT binary patch literal 146 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6cEjdz}!G45VHU&WDMkD NG1Ls7p%8*&7h-A3&xif(vGa zVS*qeAvDzt48OLDO9f@wM<<2($-SOv5(M1^lMe=|z4Da>dW M?iDcjE3oM+0F^u;<^TWy literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/04c159a04b0732e04ac4c59ed3356860af8dffce b/fuzzers/corpora/commit_graph/04c159a04b0732e04ac4c59ed3356860af8dffce new file mode 100644 index 0000000000000000000000000000000000000000..856af0f76aed0d0ffcaa2ea74cfb70a0d83417b0 GIT binary patch literal 1385 zcmZQzU|?`|5Aa}QWM=SRwTc_a#l##~#26Tuv8rWY-~ozb!@NLoB+LQiazZhZ8$4ay zfPx@k;_vC=17WgQIJ-E8K-jD|fi!yogu~(e@<7nO3tij>+qLF;y{(t}apIJaUvJ7z zkUUfki%-Ao literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/06168e726aa0260f520165be4ea0c88244831049 b/fuzzers/corpora/commit_graph/06168e726aa0260f520165be4ea0c88244831049 new file mode 100644 index 0000000000000000000000000000000000000000..4c9e9df0324f090928c753c811e360b9ba0ba6f8 GIT binary patch literal 430 zcmZQzU|@815Aa}QWM=U9ba7*V01F`72f}2raCUJFfv{Oqpz=V9y#dD7padvVq8X@{ zk%7So<`5XI2xI`oF)&CTn>e}{NF7#yt`Nv)0V;%HRv;T0^8@)fv1&h`*3?;Mehzzj fGTGmzF<-snzgwj&TEG#+kKVf_CnldA%@J<_w`VE{ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/066d1ec700a526b97009cedd0305b6a47242faba b/fuzzers/corpora/commit_graph/066d1ec700a526b97009cedd0305b6a47242faba new file mode 100644 index 0000000000000000000000000000000000000000..f5b17612a4a9267e9f080c5c14cf5bd304214eb5 GIT binary patch literal 1980 zcmezW|G%oUdjKPkZJBN1s{5SFr;1KHS(3x#SNG=m@%1fY>@w1BCqgz0w!WHPV*PAI zxl85z>lQD*Ppe_?J@>Y8f-(Pzl)k4~OP1ex5%bNW?q}$n-g(Rw7lCr@P&FJtH9`B>7?3RhYo@LR7rM9&VzuUay{(t} zapIJaUvJ7zWQY1hz1+KQ!biPVnbS4js)WWl?EITHccGRL0|Q3H0Rwd5>-g0UZV`(Y z1#EFPx(+mlh};AW(zEE`D7pX^J|td9iXY723v^}GUl#xN^Q`wzm@e`|k`1;cT*EbRwA;W8{&mnFJQd^L0Lg=+p;J)IwK zKKDKH=b4l2o46m#B42U{?6_~&a76ef^Ebm3o5GBC;a=&UU03W7i9xlktn7Y*Fk8m_ z=ZEioebxzd7&kDqplJj>!6EZe6CZkFgz%wR0z@HYIl^oXpn9rdNRa_4H}D(F3A7d+ vbAjB>z^cXIfZf?(X}rG2>T{?zbPASA(ZoTH0yzZY7_4ptNpV9lkOBb!gaBnx literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/086a5f8cbfa9f058b5c938a6eb724c9e4c5f84f3 b/fuzzers/corpora/commit_graph/086a5f8cbfa9f058b5c938a6eb724c9e4c5f84f3 new file mode 100644 index 0000000000000000000000000000000000000000..aa9cdca9769f56be7ac2e142efc0621f2a455d35 GIT binary patch literal 68 zcmZRuWMFc35Aa}QWMc4lS?zfx(5r&EJ#7!r8?!1SBrN;OXK6Vz8z# F001Qo2wVUF literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/089313c698f3e351433e9a45af2ace1d85b9673e b/fuzzers/corpora/commit_graph/089313c698f3e351433e9a45af2ace1d85b9673e new file mode 100644 index 0000000000000000000000000000000000000000..14fd3bbc336c244ee7467b384b08f11bcae8f136 GIT binary patch literal 86 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6b1%NMJzxCAbF515LhrU F005(w2@3!K literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/092eb973a771fa14cf0b567d65bd2c99130f543e b/fuzzers/corpora/commit_graph/092eb973a771fa14cf0b567d65bd2c99130f543e new file mode 100644 index 0000000000000000000000000000000000000000..3092a2bc457cf4a12730445c567d3182dba6a8b5 GIT binary patch literal 32 hcmZSJVPJ4}5Aa}QWM=U9ba7*V02T`uA0Ugx0suP816}|C literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/094b8cd1aa3e40b1f9ff83680892d52e246df0f8 b/fuzzers/corpora/commit_graph/094b8cd1aa3e40b1f9ff83680892d52e246df0f8 new file mode 100644 index 0000000000000000000000000000000000000000..ed62ec9e5a94bd5f5f7f585ff873f96d8db693fd GIT binary patch literal 155 zcmZQzU|?`|5Aa}QWM=U9baC?xaCZg@aWMEdFjz4B2Lm7<3fLQ9ENnEgIZ$~EpqV}p iHp>oY7sn6?n>7VQLre#fKsKW~h+qT}3=FIw!~p=<#Tpv` literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/0ce990c9c2ec121b8c78ba2bdf84679e04c0bdae b/fuzzers/corpora/commit_graph/0ce990c9c2ec121b8c78ba2bdf84679e04c0bdae new file mode 100644 index 0000000000000000000000000000000000000000..d708b683741bdc5bdd3623083abe19e4ee3fb710 GIT binary patch literal 278 zcmZQzU|?`|5Aa}QWM=R;^>lFq@rJ mQXCj0j7ttI?#hZ+9-Dq?*-q_w%i`bO_w|o|5>g((zzzUd%sE;B literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/0dd0770c34fcf6b1f13219450190616d344db021 b/fuzzers/corpora/commit_graph/0dd0770c34fcf6b1f13219450190616d344db021 new file mode 100644 index 0000000000000000000000000000000000000000..aea94b2c83e6019cb30ae4f67b6f23b4bf6812ce GIT binary patch literal 264 zcmezW|G%oUdjKPkZJBN1s{5SFr;1KHSu#J6f!~;cfuDf@K0o_=h}=V#u%H>n0V+

NL&U~BjUKc}C; zpPe?}|Em?l&Ma(ygl9w%o^ZoBC&ktnaH|}BJ zXJEjGPmll@6v+T^rxqR98a~0#>1Xg~r%m z-1qg5e-ct2u+KDkoqc7rwsY{Fb5=oB7nXeg=5nNh;ka6s_5+`A8J4Td65S@^bkz3{ zxrZ!aK{Jd4RGdCnetIn{nXt*Nuj z{2bn%Qrwply=9;WzL0_n*)I+kBLJ z^>GG)NgK|iPk<0Qcjb-ERy$|x#XUo4UAzk z;$j$A#!0}DaR!b5=V0-_Et3DyQn)>7tuH7feVj zH4Y1Vb}s8dcyqz@RG=Cbs2U#cUt2jGo39A^m7H049Vo#K!45D6*a;wKAY)b_pACwk t8bCU^fI@H+;0C}HV5N85w`({ee3SXxAP7H0VaP1^*!cWUaG% zfCnQZGlN0HvbWC;HhV8-i9NpSo1Ms_=vfv1o-S@sr&$2mK47+mvx{R0Lo}ETH3vko zrZ6!44F2r2ss8=LUDDOjDGdBTB`6rG8Yujq-`79>Nl1CXKGWoN_Lb4>Kru|bgMkAm zP9tpnY(=?C<^1awFTPK!VedWnwsC?n|A~~or&&vu-+2-9&7$OGOW}O~yUOzeU0L;) z#lQVL>-`g^%e(Vb?xVV0+c|j8Ijf+m3roI#b2(DMa9k}*`+-lm49nGJiEa~L&D?vT zntxVL=f|7ReUJQk<|O+j?#HsommC5+?%OpS5x&X%%`nBLFr!_#_sTA5yPmePvik|b zY#H;PAHMhXStro{+yy`a2qZwn53Rl}rxjlG3K;wqxG||sF{&_l8c>)Ss3tb}kI}`V zvdQz0&$|%4cHO7joHH53fO483eGClOA=E&TEI^A{iNQ%&)M>#qHb5lVfP6w2GdUq8 zu|6a=&@8yxAOHV@*tn7$IJ%6X(Iwrp>xvx_(N%{%x`5U&aCpBwaPlvw_5XqiiKWJ2 zVb9KGJqT|uXio*ou|T7p$NSe-4#(!E`yc=B*b5X#4@6ivfXpKbz%o22b9)AC-vh~& z42TTQzyitQVADX^8V1-KU@S200OvU~Osp-J5HM$%6|(Sk{Avfch{cNnwm2JI2l)Z& z4;JsIAD9|FIu}$NF#INWp$nuLUs&Uc19WkqF}%cJWd;U5pgK}9BB3!b&?GAGCS-WR zga#HtJ}5GQY7u}D$b@4ri{$-gF1hDte-Dv+$PyMb!!SU_>2oV1k8PQ4AwmyvEJ8Ut z0iIH^XK4qddq! W0CIuwzeneSiUS7UmGbiRq8(`Df7CZ&wG5LvS)h%74g76Epog63k}5 zzJLwIZ!oeY=xl10A0)*eIe7_Kl93#KKn<|614I)nKX610dYBR5kCq?MIs{UM00SPq zEJcnKyb*&^ePN4#py3cOn*QK*-(X39posYeYHUye42}A$3g}a4+6U2C(?2DFfio0% Rfu>@`C=Cz@$7%kiuK-{20jdB1 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/10bb37e18fb3c0897dabacf9c464b4d324007dc3 b/fuzzers/corpora/commit_graph/10bb37e18fb3c0897dabacf9c464b4d324007dc3 new file mode 100644 index 0000000000000000000000000000000000000000..e75a9c511aa1252177defc99c453d2840cbf9921 GIT binary patch literal 346 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_F-U%e90lO7J zU9oE`E4!Z{%$70#`QdwCpLGJYa2J4eGDv`^A6k7|PAk0V6)^ZKaAQ)NVpL)9e>{K> gs0ANpU;`=uVOrQvsr!KrkAKnt2TK@0L9pp70DwrGUH||9 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/10ee715f64b08549c3e8261204276694728eb841 b/fuzzers/corpora/commit_graph/10ee715f64b08549c3e8261204276694728eb841 new file mode 100644 index 0000000000000000000000000000000000000000..104eda6c3cd6514d6ffd7253c80c842dea3d5fca GIT binary patch literal 174 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+G*$qvOFKpHz{!XXY0&yj;R2of`LI`E34Ow=kFCjY&?#_VaxyjB-jtMfy4XdfuMaCy0{HuwdQ)g H1z8FJ*NmH~L~9@8E~m*}7Rmd~TyoFP{vIOtkR>c=hGl??)8|%39@{e8!d3SlFq@{ncjmYO;ulFHkuXRGWbJudU(|0{5|KBg=k}Q}!yj1~6*& Y@o=u4WAa30_R$8JQaafWvKsP|0NSnyG(+hOGwp&Sa10h*_6DrD0GHqt9D)^FHjH_4Vn=b5 z4=G)=L^HB2S$5j@Y$q1>pGWL~$Mf+C_Ni0Lb;j?J zeOO%|Woz8|fQ!7&HkQvN*}vhF_DhepS}x*SvLO?UElCrZBt#8We@)R%g$O8>sC0%; zNSIrk#U7A}erzgWoci{Lr)dRG+Q~EitTEp7w{xb0WI}5WvI<}^{nGko{$%oBF3dCB zIeM)XZ>4N9uCFpFrPI(Xab3=H)fvdoZSWJD?6d8C+$IMX^XsL2b^TjAviQHGV(ntj zIC1$;!W=%)EjgRuS{JjQ{FJ0t0;!cmm8-h?SA54Iz+B$y>R(s?%nf3-kLuw6tA8Uu p-yT+eT^p8N)1v;FItGxWdPY7Uzs%mryCoj!ve*SrW9(x~{Qw(*2K@j4 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/1414e6e8ab6bad1b5c51fed807c514a9d6575e66 b/fuzzers/corpora/commit_graph/1414e6e8ab6bad1b5c51fed807c514a9d6575e66 new file mode 100644 index 0000000000000000000000000000000000000000..c7f2386d0a41e8878143ff2edb3c3dbec367bc27 GIT binary patch literal 584 zcmeBTWB>#EE---dgdsc>5~24?BW;#VY8+{Xb{QX0A@oy4rY@< zU~@FG7$N^7tHs79q#x?!}nhU pD9K6=)U) zxr_|{j2=Kf2O8!C@`1PkNFe|Vh{=TDBeN8cIS6(wi23_J1Tg3UIfe`^)7WLC-A=e{ z7HoYry~O(2igK6A`PVI8e4kdsey(>y<6C3?6DfU9vz9Es^CIS(Maj#S!ukGpmFEY# zvg$93fBU&W;0e>^-FYhaef{H~gp>#DGfiG+Um30K9K7e8RZ!K1CEvff9I0U723m%U bkAuR7@%i!fQ2RsZY(Lm~pc6o@@L&J{0M~!% literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/14e3e735dba88791f2cadd6e0dc5d662a104a6d7 b/fuzzers/corpora/commit_graph/14e3e735dba88791f2cadd6e0dc5d662a104a6d7 new file mode 100644 index 0000000000000000000000000000000000000000..32fb993782f079774b1899ef5e3eb921871aafd3 GIT binary patch literal 214 zcmZQzU|?`|5Aa}QWM=U9=9d??(=_>#PDhZna literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/1574abb020203103ea629d677edd21c967fc0f4c b/fuzzers/corpora/commit_graph/1574abb020203103ea629d677edd21c967fc0f4c new file mode 100644 index 0000000000000000000000000000000000000000..b3da74c1a7f609cb9b13435638d6d9bf057a40e5 GIT binary patch literal 96 zcmZQzU|?`|5Aa}QWM=U9ba4Z6(Le*3&t%~P5ofV*c5w`Wuvt@pG&7j}_dkRM;W2{5 KHZw3VG5`R5eFw_` literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/169cc492ba94948a6206765436881a1a0c601780 b/fuzzers/corpora/commit_graph/169cc492ba94948a6206765436881a1a0c601780 new file mode 100644 index 0000000000000000000000000000000000000000..2ce25f66b34bf05ffe02e1e1f8450e410d444f83 GIT binary patch literal 199 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2EPylz5(e>*`RMEpB(-q4{|Eq-=0?MK d%>$c((EcCnnk)V)0*<@)M3?nsvPbXT0sxAYA^ZRU literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/16a2130c1d75129f3bae3bf8f2c2de41fb3533c0 b/fuzzers/corpora/commit_graph/16a2130c1d75129f3bae3bf8f2c2de41fb3533c0 new file mode 100644 index 0000000000000000000000000000000000000000..0b6638518bec1a165fddb90193a43d699ffd9025 GIT binary patch literal 351 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6fk`rNHQWYE0Bo`vjOD@ zVRoPzyqNz)O5fA0CCl%;i1}tw^0KAy?)>@w%7Lz|`pe?qexCLI3Df1>c`EmP{o|j6 yln3lHO@xphN+_e(V`{%{{^I+z8us3EZyPZssVIWQY9dTW3K6(!Br!-R!DWbG ztS3SZrjiN9{I)3!7~&W%L5{EGAmzPqfT8*Q`vfdvC<%iOiJcW!m-&~GVFdSFQ(thB>zy?%^jM;&F zb_Rj_UwgaKScR@M>y_|lYP1;loCS(=05J~`i+KN$yNO{0M)8us! zS53m=tZ*5YtIHDICcc`v_d+%Qte(z~H=p|+`SZ+4_D$T6WsxsA1a{oFYd9i&llhxr zicMigyKt{`&#o(WZDnQm6NK3^=087t@9VQppp&=@fCLaofQTPjeOpc|yyz7$_$zQ@ zQk!B_Veo&#U>Z;-Gt?Lk@0SNo{^hj(UoauD)Hp2c*}1F-;mrl@sX#R>P&GW>zqWEX zHaFe>_HCvvqR);feLuQn3aKt56Iwq znzdy4ofk3REJ|Ls6wdd*t2{r@l~sRP{M*m7-alcwygN_jzOR4$6OHnKeFn+v>?@$eK3y0GN?H*6{%dlKsmgqL|)y%yYs`+R2bbh?~-1o?zXHK$j v;(jcPe90lO~+ Z85j{5-A-gaA-h5H2)nVf85p>I82|>>7kK~x literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/1e068537ce1211a325aab42ae1263a109131c9f9 b/fuzzers/corpora/commit_graph/1e068537ce1211a325aab42ae1263a109131c9f9 new file mode 100644 index 0000000000000000000000000000000000000000..035173872bd1d7a7c45f3c39808b367acac39ab9 GIT binary patch literal 81 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^EL=)yQG8?{3u3O6UL}X&`tpD|0EEdi# Pjv)~F{|LaE!oUCku=p7F literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/1e9c882c9d33304a5791ef6c98eee65e142bd7fd b/fuzzers/corpora/commit_graph/1e9c882c9d33304a5791ef6c98eee65e142bd7fd new file mode 100644 index 0000000000000000000000000000000000000000..d5b9da4e5d773bbb7c13e0f7d07d7064de300966 GIT binary patch literal 114 zcmZQzU|?`|5Aa}QWM(k+ba7)~5CDqs;=l}iKnXque}qaPU&Q;5oD~ANPx0Z;^Zn%* c8JD;D&25pd{0|$GfU3A>yk9cQY5u0K0Owp62LJ#7 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/1f54935df929403a29e77591c97f767d94871aea b/fuzzers/corpora/commit_graph/1f54935df929403a29e77591c97f767d94871aea new file mode 100644 index 0000000000000000000000000000000000000000..6f9b0a07ba9691d0661076975e3c006b3d1aad72 GIT binary patch literal 202 zcmZQzU|?`|5Aa}QWM=U9ba4Z685o!tEP!kuFq?tJ!r8?!1j1%bfzUvb11Dy}BZs2T f0cr*}&?pE7k{|{%TmZ!Xpo|Lul>z118^AOGwCW3* literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/206015659641771bb0d668728c2fdc4209e65dda b/fuzzers/corpora/commit_graph/206015659641771bb0d668728c2fdc4209e65dda new file mode 100644 index 0000000000000000000000000000000000000000..086ab64694b37eacab3d5312c3189f436204adc9 GIT binary patch literal 152 zcmZQzU|?`|5Aa}QWM=U9ba4f8LBJxx^FI){F!+GEEEdi#jvy9$1A`=31eIV1aX}g| m08k513WPbZ;TPYh)v))TdzX5!~m;*SAb#myvcm5wcmZ_0{we>t`#qCpix=Og)v))Td)qj{nEymd-_xum%kMA& K6}^c0W&r@;6Ey7r literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/209b74e08abe8c787b7c5ba81e51cb69c57ecded b/fuzzers/corpora/commit_graph/209b74e08abe8c787b7c5ba81e51cb69c57ecded new file mode 100644 index 0000000000000000000000000000000000000000..55dca76e7ef3c9d341ece666c49562a6919196f7 GIT binary patch literal 519 zcmZ3L&j0~V7yu~Fh69ViB-nup$iW;yeQ9$SY6$^po&q2N1Ok2&Ys)1B%volIEPNfm z+QBWtk|AJ=v(a^sd_g3899!epH>Pzr8TES<+P*uo%y_?K)?uglo4zvef%SvTB!FSg vrltEW@Vj4)68D4r2l4|+?pK+8v_YoyWvTzt=xC;>-`qYEt$nzGh9F}AE%`(9 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/21137876575fbca357fc0c96db1de73c6737e1ae b/fuzzers/corpora/commit_graph/21137876575fbca357fc0c96db1de73c6737e1ae new file mode 100644 index 0000000000000000000000000000000000000000..fea1ac18ca3fd9a14240ebb1634b5c689e2481d6 GIT binary patch literal 32 gcmZQzU|?`|5Af(*&D#@J}}9^z{a2e z#1HJln+w`gfnqEL5D6adUt2jGo15-`{J&%G?-j;hZtOn$v|Fy;9V8D`!{Yt&!1iwp zm5kkKetwlkv+90^&gq@U92)1a^KaVRg<3*Dr94ozZ~Z3LmP-hju*?cs_&R>IgImPn zMFCr!jjp4Z_w)l(qeth0iUWq<c*7lNfaJh5R-r4+dL{gs8ZE{>XMyTCfS3oQ0ZSBFCV-;| J*+6_t7nR-8a1yv`w-%fTaI} e!4C+9mHdrW6e@^h11@Eh>PMK%z{0=?^aKE2s?v4< literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/21d5c8c8ac3a09bcba5388c472df32795986a5cb b/fuzzers/corpora/commit_graph/21d5c8c8ac3a09bcba5388c472df32795986a5cb new file mode 100644 index 00000000000..b148c6feb42 --- /dev/null +++ b/fuzzers/corpora/commit_graph/21d5c8c8ac3a09bcba5388c472df32795986a5cb @@ -0,0 +1 @@ +ÿúÿ¦ \ No newline at end of file diff --git a/fuzzers/corpora/commit_graph/22170d1110a1c18009b7feb21a470681f55e85fb b/fuzzers/corpora/commit_graph/22170d1110a1c18009b7feb21a470681f55e85fb new file mode 100644 index 0000000000000000000000000000000000000000..6c16354e8b4cf8808d925020c1aa968a88f3badd GIT binary patch literal 469 zcmZQzU|?`|5Aa}QWM=U9ba4Z6uM-1+>KH758hk(uJb=X~>LmjMJ5U7>??ou&12S2u zgxMGvHqa9=04;=LgqJ|9-~UnhSb5m|4KtE~1E_@*46*?jfgHf-GZg>^_8Zf>n*cjZ Bc!~f3 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/22f55dff94785f24252d7a070f713840f59b0870 b/fuzzers/corpora/commit_graph/22f55dff94785f24252d7a070f713840f59b0870 new file mode 100644 index 0000000000000000000000000000000000000000..b45c99ad2151a7b3c37d365bc2a9810c3dc8ffa6 GIT binary patch literal 609 zcmZQzU|?`|5Aa}QWM=SRMGm-*3I5{%1whMyfW;^3<=(SE1`iN(0I`VoA366aKKyyU zzZ@gu@;0A)b6eyq|HH;4pd2?;lLRA>gNm2mc@gu?qU2>u;e3$OJzd;@NY(NDt%noET0WpYXcYx9`J{k?=LIGGckj;S`2jh{$rw=3tL2$EsIzQfg?tA3V zGbh6uyomW`R`Rl? zaK8Ut<@tfGtoqC1-+rF;{t46N-FYhaeG}rJgp>#DGfiG+Um30K9K7e8RZ!K1CEvff z9I0S9u9oHZz$aXWAT>buYm?~y8q&ib?tWm9GdO|>2xeeqV1NfHPz)Kc KGAMwg8CU_a69KjW literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/2435430ca19502c3b0ec4987508d4a8fbdbc898c b/fuzzers/corpora/commit_graph/2435430ca19502c3b0ec4987508d4a8fbdbc898c new file mode 100644 index 0000000000000000000000000000000000000000..e1d58bd0d2a7b728015f1aba44e4022610d81b2e GIT binary patch literal 349 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&Cp2m&*Cq&0g3~ zt6}dw_qK6@G5?8_zNcABmfv|1^Ub26$bxDfNw5GDj1HdWobX~0a|`_St14Y>*0(- z-1Z|}g36i(3@T=5O5pH*dEn$>Kss58eL5o4x`7-}ZN* literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/25bc53498129bb3717671f00c355d2637a91c86a b/fuzzers/corpora/commit_graph/25bc53498129bb3717671f00c355d2637a91c86a new file mode 100644 index 0000000000000000000000000000000000000000..d86bb32ef337ad2bbfbfb446d89ed536546bcc70 GIT binary patch literal 531 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&7h-;mTqJdW@c! d31}Z7%nVe64YL5n@nKe=JUZqEiZP%^FaY{}2sZ!# literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/2614f60da2d7e291501397238366d27513bff773 b/fuzzers/corpora/commit_graph/2614f60da2d7e291501397238366d27513bff773 new file mode 100644 index 0000000000000000000000000000000000000000..57cd70aba092dbd28e01c984c11fc6f5e1762e6e GIT binary patch literal 80 zcmZpe&A`Cm9^k>aaU%l*djpUI0ro)ZD+DltnVei)Tu=cp1y#qu@Z&!WIJ-E8004TK BBX9r! literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/2651b3d5a8b4616b1faa81dabe27ab2712a27561 b/fuzzers/corpora/commit_graph/2651b3d5a8b4616b1faa81dabe27ab2712a27561 new file mode 100644 index 0000000000000000000000000000000000000000..5f838deaa94a57aad438b65f0eba36a5bb98d05a GIT binary patch literal 787 zcmezWlYxVQ0gO4LfecO%{v&(2l(qJXpkK+Eh1UZvtb3SJGr?vXR{;wHgC)cN|Nr?J zc)b6}9@C9vk7H~6>foX4pQOC3kNx%7XKp~V}t(~T`Ve_JpcH-3(;%W zeY(v#lR*q9#|l-$;S=@pjcMIYM*SXzw(pKCGu|(mb=YbCrmqa#KviH2v=12sRb5!} z{hP~?3WnoqS=tYL!ev;lE=zQq_-f|f3)TFydOAPeeC~VX&od|4H*r6fMZV+^*m2*k z^@#9I=5K~6Hia4O!oAWxyRO)^m6gGay`Lcbo?Bh{F;Gp~-Gy30K$-`tLcnigZMlSi z1f-@oP=XTi{v+o;#fLx7_m^X2 uT;Aq$Z*Gfx<$u_i1eAk&+RyPFmjrfmKxTl<0-A%K7^&}mn7e@X0RaGhCK?m~ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/270257a2872b33dd13c4fd466cbc1ae67d613f9b b/fuzzers/corpora/commit_graph/270257a2872b33dd13c4fd466cbc1ae67d613f9b new file mode 100644 index 0000000000000000000000000000000000000000..30904964ef126bda4ec259375b8f1507a3bcaaea GIT binary patch literal 600 zcmZQzU|?`|5Aa}QWM=U9q$jspH$?f9C00fNq@PCH)Xn^4aNE5;oh#^2B3x7`+ACMda1B(Tk zCj8vq-if_%fJJEn7P0s5d2GvU3s>FeTs~EF+R2g}CcnBj&yTNfnZ_>jAFFzj1=o|T zgJv3#{0g@NNo>&jpP*ae(ccUAAA&I&|488n4;CabwD^ZBA&&7Rq&xtUZ$ab(pKt~S G85RJW`!zQJ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/295ce43fdd56def8948d1ba2bfa7fdf0c47b5318 b/fuzzers/corpora/commit_graph/295ce43fdd56def8948d1ba2bfa7fdf0c47b5318 new file mode 100644 index 0000000000000000000000000000000000000000..4a3ce801f942ec3956465a03bb5ff590627afe3a GIT binary patch literal 2227 zcmZQDU|?`|5Aa}QWM=R;^>lG#VBllG0Sx^;U3?&NEEdi#jv){>YYIX=djo<^B+DAV zI#!@G8xfctsD=fBwfeT4R$zF+!T=H{fcb$+kTH;p0T_WIAPjU4GXpn6+5H4zi-0Z8 zM%SU@FnN45P$|rXAYYM!85kt|9N%$C2;5I&z4EoUxl2f|gg;ZG#khyw_J8f|N@Eqe z(hRZRu;(n$0USWg1H>ZUe`GJ0vesS^^eZ{D@Or?7bq`Z&CfID_0?M%z00{y13};{%AJdIw2L>mx?nYOK#~Wf)|6&PT`h+*BQb&b literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/296cbb94c4e68ab86972a174405308ee34d0c40f b/fuzzers/corpora/commit_graph/296cbb94c4e68ab86972a174405308ee34d0c40f new file mode 100644 index 0000000000000000000000000000000000000000..45c218ea3d973fa3b33103204491e65b47e37ccc GIT binary patch literal 3003 zcmZQzU|?`|5Aa}QWM*IivTDkUKemig@wjIs$+j zsGA3j8KE?TE`*OT8Lt&UkAhqQ^Dr*!-o*V_7WtAxV8?yCh9kl^nZFsP*c4{83-?O* z?7CvtR#tXDL6|LL{`154zCP;&8pmA#GL(Tq0z~}K>f3T!;YF{2!C!$JliC!c3WKKs zg_)shW=~-Usk#9K3=FJkXL^oq$?Lx9rJ!w+z2P?~c;GSX@7c=8V_RlhxavM9xsd>j z2UsL91C7R=P%!0Kf$EX5EHVc_Tb4cn_=M^5?mU(INJ-PaGFsa?c+WYjpsEW?zJGH$ zQo(RsElc}>Pq+-r)n$op6G15mhJh(zIL9BuAWJ{6B*O-b0(1<@5~N_Z|Ns93wIF2` zNHGU2mjtmFbF3*K^$@_`0As;uE+7Mhxs4FXgPQ?+@c=J`20{J>1{$ui8zhb^yTiPV zMuU6?29RQjdPNVg^cyYzN6UX|SD<8+|F355y->|RtEcnh&F8*H{ycLczN&)P8#Jgt zys{O3Z!o#3J(%i$VExfMnA#t(`U8a?;Pw-^(qaOWu(A_{zIgGX|I&*W8KR>Zt^-@i HQNI}g2^Ld= literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/2975adf222cad108ec90d8225fd655e30e3bf253 b/fuzzers/corpora/commit_graph/2975adf222cad108ec90d8225fd655e30e3bf253 new file mode 100644 index 0000000000000000000000000000000000000000..6a16429c5edaa448da638c8af85b0da81cc3fae2 GIT binary patch literal 407 zcmZSh&%og99^k>q$jsos3Jw^6fRRR+31}`1Gcd3Kc`W~7zyU1q3oKX#l>{na1!AhX z2WB^jhFHPC4`jfxYCoUW)LF)U4*%Q!b*K6HRT|Bz`x(l>r~w4PFfj&eLn25GCrtYh O{%6r>nP}}}&;lG#fB*}BPZu8ulf}Z>#W4iJW=(<011WY^1e<|_35kQj z?CnZp6}r-_SHhpE(PG?l7N~#+h`)0H2@&r!IY!3iZ9ezrw#ZjB86AWS x|HH*&F^tz%LLF$_6pX z2agD8WdSN+1u5b{U?3C31CtFfaZVr~9diN2K$sf|>x0;JC;%)A@(w~JPzVC3Za>&9 zaOg?)(HgSW46JbBHi;=yK;YE;_v3T>>7qFrD4Mw&Eoej1Ki@}hvgu5Tiz~X+O z5Co7EezHJ4$Z<%%{m9-SC;X6-3@}~H!yYlnmJq?_0fz`My`rR9a{OG10w4ixLTdhn zXrqv%fBpprG>y_9a@xa@v1pq9$+Ca6`~YWgP}q@@m+BE|2&j|V|mlNQ! zjubb;oQ#tFOCed9}Zi{^7f7+M?l;bV{5tMx j0%8zN2m_VCfg*&Z%kUopKwOCa11JA-S_gR8d%6GsG71sR literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/2b590c4e61fdfcf21c017b29440747a1894b1534 b/fuzzers/corpora/commit_graph/2b590c4e61fdfcf21c017b29440747a1894b1534 new file mode 100644 index 0000000000000000000000000000000000000000..c3ea72932fb9f86cfc27695625cbf071d4993b46 GIT binary patch literal 217 zcmZQzU|?`|5Aa}QWM=U9Y-QxJEwe3Lb)R$jRMBZCOLCa}>fSs*zP@D|yNtBkiIB~L zt*@q+SU+1)?ov7by2Xp{)3D2!0A*^}d(Tz#&+6&?c=NgMkw4G8WZ%U7SQhz`Ltw{! zyM`meH<`Z~rq~o_vg7bj z417Qi6>yxx&cA7M7itLsjpHc*5%{=er2 zsv;IM<50^36vu{nf#OIQ6zZH%jFg68E@faa0lL};r~n99ESy~&Lm+I{i$I#a0K(z$ zet95h--Rx2gY8;#z24SK{Wx(-$gekLCrBQuhQ%l9<=(SEKFCoZTSdJ8$hlAP;m`B^ z4xB1+g+ah22A2ucd<+!1mB#`0;8c)mbyomW`QS!2-a6TxdBOGdh-JyiSkv`#v z@COy#{}0(uv~)ixnh0T_5@14T08>~9^t6r4CpG^Pmw$kcKn@>5Y+8mNC_IK_{xL&j s^pO*OUnwYmkdpPFPJf^j2?i9E-`LUw74i|xZ44}+;vZC=dowTq0QslvAOHXW literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/2c6798057af5894c27631ff63e845fe1e4bdc9ee b/fuzzers/corpora/commit_graph/2c6798057af5894c27631ff63e845fe1e4bdc9ee new file mode 100644 index 0000000000000000000000000000000000000000..06a7d31fa14195cdad33a63a900d6b798e11a32c GIT binary patch literal 221 zcmZQzU|?`|5Aa}QWM=R;^>lFq^6x6o4|HYKUl#xN^Q`wzm@e`|k`1;cT*tk38FZ9dMudar_O0HbCf4<`e|_h~ikz31LG zPB7*_k9YyYY7j`^Ts~EF m+R2g}CcnBj&yTHdnZ_=&{XGHmAx`0EVBlBnm(zkc!Vmx|FIgb~ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/2cf7eb7fe489e5acd64df755e820c871784c2ba1 b/fuzzers/corpora/commit_graph/2cf7eb7fe489e5acd64df755e820c871784c2ba1 new file mode 100644 index 0000000000000000000000000000000000000000..5614c74b9f863b9b4b460977ff9c3b8bf0947732 GIT binary patch literal 182 zcmd;JU|?`|5Aa}QWX}9_xl8&+k`nKqdqLY782ErPAS@20VSEq`lmS!7Vnnf@W-VEM p=S9pni;|Zuh4cOID$fseWz}95|Mv4nQ~ojdt*(WGm1{oFrB;m?@ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/2d507d42ca43ffc2f3c8892826e1db74144ec096 b/fuzzers/corpora/commit_graph/2d507d42ca43ffc2f3c8892826e1db74144ec096 new file mode 100644 index 0000000000000000000000000000000000000000..35c28f488b5e3880fcb177cf61c3abac5db92802 GIT binary patch literal 2772 zcmZQzU|?`|5Aa}QWM=SRMJ8adA*hjo9cU36hH*K7QrIv912a&D8w=(EiebaNKyf4t zGL#dFk-X{Y;sz810TX{u7as_d#lqReF$BV9y$Gb)3m_a0@0SOH_Fd@WHrTE;*XwP) z)Q=OVg#3C_c7o)gYFK=tUhX{$vg_NrDl`LB-4OyomW`QS!2-a6Tw95DvA#?oe!DgDf^0e!w7R_>Taf;3ol(h94;W zfM5`&KWrriIbzTP;{5FIA#x8{!h&WP1gJQDZe`@LEwe3Lb)R$jR8btI8@$-Njsqal z9gOuG#`yn#IxtufJY?3ilO;J!esyo2A72j^W?;Z!KJmiH#zWcP;bOR5^8Y`~iQrTK zBTx%1h9Cd`J3*@umpxj&svx!g fgC|sAavUM$cj3rsKj12}VdXM`_8GdgHvlFq@)^m%KrJj#%nGDQ!3+!%eva?BBn0k%?d?iq6}r-_ zSHhpE(PG?l7HAR&5c2@Bi1#1a%cZQfR|Ne^&MdqhaADoUl$r@P+qi&oECoP0jiHjUJI&9p(r8xQ&(Jx&^O!3x0+q0X)Bynp zP)*Rj3tij>+qLF;y{(4|v-lrzWz}C64^ra%_VcXwPna(6&QrPX>mUClqsY4SSz e%4lup;63N8f~qbo`Tou2NCks?fCnQZ^Kk%Lc{k|* literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/302703e3b0d74219868aca39ee7593944c0b2400 b/fuzzers/corpora/commit_graph/302703e3b0d74219868aca39ee7593944c0b2400 new file mode 100644 index 0000000000000000000000000000000000000000..6b692e19cc02b5a3129a539719c7cdf497f67cad GIT binary patch literal 126 zcmZQ@WMFW15Aa}QWM=U9#W4iJW=(<011a_fC|iXQ$Y6zV Y*q~y_6i5sS7p}U`xqPZ91A{sX0Gaa&1poj5 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/3048c6908dc3176707fa8bcb0196824e3358357a b/fuzzers/corpora/commit_graph/3048c6908dc3176707fa8bcb0196824e3358357a new file mode 100644 index 0000000000000000000000000000000000000000..c58805fc4dd1209eb432605632f6bc6085c6c308 GIT binary patch literal 395 zcmeBTfB=gw7y$CQvEe)h2F8W2<5xSlMJ!$vu*Dgw5kfHnDSQ~KB#H@e4mM-hfU*$G p-T+sK%)q7zSqzW;5CcJqu>b`uV%UU`?ZU>!V?WTiChm}L8{L`-~vhBFm_T*$y6;Qec>xP-v{uRu1QKtZ(>iAS3KAR9TnCzI?1 zP9gvY5o*X%0ty!-AEPo!_rKTMdZ`~LPQd~jcd(;cgo8(#{pjhh0p<#9G!7e4g-N!5 zH2sm92&tU@@MUupIn;>8!6P~Tai@3mG>F4SRAG|sA5DJ)oc>13ztQ@aq$Eh?@(-N; H&=Vm5Q$bvy literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/306beadd9b3135a00037323760eb5377c88a403e b/fuzzers/corpora/commit_graph/306beadd9b3135a00037323760eb5377c88a403e new file mode 100644 index 0000000000000000000000000000000000000000..86c8672306dd7250564660962a7dcf4629ddd146 GIT binary patch literal 315 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBPTvLNhS@`VRpxK7wXsMX({PN9Y3Rd={VpSQiJ7 w0mBGIWa$SQ12PF=9*D<@1%uS!2YBq)WYObOQ=tOkiLDieq4qB5dN6iZKDrC4`yL)UW{g$e0z# zN5=d>K2EIK&!;tYmYE+=4G`RbP~?$>{muwd0tU!x(fteZA2tl}BPYY3|ET_DVc-Dy z--O~YaCn=>eD#X|Zk4iV0mnT(ne5Sfx8%g+v!cGd7?7=XoF1Y%ToWP(a}s%zqxaKCR+O#cR5Y=vPj-<=8}7U z_V*CEhb&=1GYkV%oIbZQ^4ONy7OuL_xqPbVw38({On!B5o*!S|GL2nE+U-QhX2I51 z(@U(MttfY?oPXWo#rJ77?7ipSHcl|+KM}!@()ToL$?`idV!m0Fylg3)?|)Z$exNI> z{<8SDpJ%;)!gP6ep2~e+|M({%T1`RCQs=_irvoDj1HdWobXi z3728Hx-3!P{@32FG*+Q2&3YyLnHnv|J!gTDzyrh_KrG@7@gCH6nBC~{2IFIkJCGQG y_%otu{L!IE0jB8zFF%06ObHmx|068_`wZ{=&m9dZNWsktW(I#x7dQOb<1GLI3v)mK literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/317f4bcfecf066961ef1982d551cd14e63c9f008 b/fuzzers/corpora/commit_graph/317f4bcfecf066961ef1982d551cd14e63c9f008 new file mode 100644 index 0000000000000000000000000000000000000000..5c2a5d70fbb4b70cea0948b3d0f640d98577f428 GIT binary patch literal 215 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBPalR^89gIqmb9D=sqp|Ibzc5$5pLI}o(*LKn9| ztkztwxAjs#PMi|*>rL4Sl835c@rio5cU=MBMbT*)*CbRz;~aMWO`E$=O9-fh2dYNE zZ(?n^gn$XltdNDT<5xSlMJ!$vu*KQvIJpb=1R8;YMIp`tiv5Rz JdLRuH1OT~LJ}LkJ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/31b2248faaabbec69a06098c8cb0f69c5d0aa208 b/fuzzers/corpora/commit_graph/31b2248faaabbec69a06098c8cb0f69c5d0aa208 new file mode 100644 index 0000000000000000000000000000000000000000..555c7b18f1606635b78a9a67997baeff25992e5a GIT binary patch literal 3848 zcmeHKJx;?g6m}qO14V*surst%1C3}aA*BOH;1~=Ydjlpe&>Jvu3J$@<%7V=IoY=7w zJ9b-v2`%PN?(hV~qiJ@1U&y_OVx=b)X(visvtoFA z8jIq^vV?q`zngxNvYGLJ8X5Ab+)c3nbnR>Ej2D}oxy3`f)iKtgdZ!E zSN^4prBFCH*Ne;|Xc~WVelvR%^VbNgDe4?~$Lpq+X;(F@tMNKgtR6U-&fZ9%e~f!w&af z^Bso@rsh_M?myP2PAuL(Z9S!IXdERYUYFfH)tUS6>M!1ZFNgcj_>Zy8`)F70Kha0O I+FLRE2DAbwsQ>@~ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/31d1c3d1147385d58dbe6f82898a5523320fbcac b/fuzzers/corpora/commit_graph/31d1c3d1147385d58dbe6f82898a5523320fbcac new file mode 100644 index 0000000000000000000000000000000000000000..1c5ef071906de16ce7b799a10d654e42d8286539 GIT binary patch literal 415 zcmZQzU|?`|5Aa}QWM*IivN3Sa(Jgu1H@y_JO|m!q<^`&NEBE(oW#q9fvn^b8pL6+C z(P<}3eEs8}gp>#DGfiFxRL2O#U=|Yt0}wG-B7i28>Fnaj#1O*3z=jh5^&tQ^jLDjI zrsvoe>e*&85iV+aK%d4MDc x^Wnlzvz9Es^CIS(Maj#S!ukGpmFEY#vg*%bC;(|!X#4KSGUNRcr}>k<0szL~8Lt2U literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/331e2866416b091252f0299e98d32cfb29237029 b/fuzzers/corpora/commit_graph/331e2866416b091252f0299e98d32cfb29237029 new file mode 100644 index 0000000000000000000000000000000000000000..241e719a58c3acd8feb8f851f63fa497a50308dc GIT binary patch literal 5 McmbPg$H3qS00bui6#xJL literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/331eb3876dd2f3f0bd51f380ac431d86d6e3bb5e b/fuzzers/corpora/commit_graph/331eb3876dd2f3f0bd51f380ac431d86d6e3bb5e new file mode 100644 index 0000000000000000000000000000000000000000..a52780fe2d0db3b84cc0c04b8b67f452111171ae GIT binary patch literal 1072 zcmZQzU}SK15Aa}QWX}9_xl8&+k`nKqdqLaZoVinV>T=2y27d+y27YQ|)qXy$sk6-d z9NwleU%leLTcs>oz;RDcCVR9nJJ2p5*t;bsCZ9F!OwZ9RdEGa?6tqpUH~i+^{{Hj% zf18hTuimTR8o;R8$HTdHj>!|1*+&~>N?(@xFO807iu%p%Gtt_|xXWp>mqqe^Gnd@+ zv%iPPJ!AFy=pz()ToL$?`idV!m0Fylg3)?|)Z$exNI>{<8SDpJxe5 z|JC1}r*hxdKmJKbdB8r?J3K%d8+?dp+7*!ZN4H%2e;JCy}@Bu|Ja0nVe zi$60`;t%HjmxSXF>VDMtV}v-{git)r+N`r$Fj(m90EJ; zL!$VbVTw&*M!RsYbkD9Uc5P*4_Y;KKGUh)&eDCYCPM{^+1rVDgK-3SdzAdN00r?k4 eKoXmNVg4r~{X+c@aR!h?PO*>}0c97E^a}t4IiimM literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/346bd6eaeadeafcb840ff9441614b309330db63e b/fuzzers/corpora/commit_graph/346bd6eaeadeafcb840ff9441614b309330db63e new file mode 100644 index 0000000000000000000000000000000000000000..50b7f93a8c434c91da4c931c185bbc666dde69ee GIT binary patch literal 2850 zcmZQzU|?`|5Aa}QWM=U9ba7)~1`0rc1(5Fp4sxbIJ9>53G z!pDF|0h$y@HFkXeYj0N?tI(BZy%PS+a2b}X%M#rtzM8rBLN))ap3aXqpZgy9^UO*1 zP27)VkuNy}cHFmXI3j$L`I}*iO<_j6aIbXFt}9ga91qZ;yg-cR;s!K6lKj)GCCl%; zi1}tw^0K9HzW-h2`GKyi`pe?qexCLI3Df1>c`EmP{o|j6ln3lHO+$W#Rer(b_M~Iw4l*q+;bKv z&H==rI1%ywBYU}&wf2gjU&)z;*8?uBdzb==6Il40;R*kQp%VVkj57`BV`gXu zfRZ&2Ftb2t2p_F{%X~uZ@(o`W2PHn*mw&CJ(2 z*IR}xGv@a(Fnu!p7Iw4Mva}!ggv+p8U6$xJ@zu<|7pnPZ^>lu``P}!&pJz_8Z{mI| zi+sr;u;ad6!x7<|%-;-Qj`jC!W#q9fvn^b8pL6+C(P<}3eEs8}gp>#DGfiFxbO<99 zgIP=r3_!$Si2#~VCeZav3_$lY1Eq2M9aD}KsGbbWDjUb}h5_AADK>=}?ZUm%J-e>h zwUw3K7fxWynE(9ny|2$Yf!1&r011Zd4ZnFoG%fruWcxRCf&VGi53UcVm~Wrue|3%T zX`og3!h;OIV+}7hpgk}Q@*V>Ndjpt4BDjET5au=lVh|0-ui$K;5HSFx6%1I@&h#AJ zLcR0@NkIsgA-fW0ClzR#x}SxC1L#ChD#MNIumCM2F^~g!K==kQe}Ka{uluH#g0=}Q b(=TfN{SN`wc+)Q|Z6l}Sec%*&73g{ZAD_`e literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/34bb8f475e7384a8a39618fd15fdc5fb1b12c1a1 b/fuzzers/corpora/commit_graph/34bb8f475e7384a8a39618fd15fdc5fb1b12c1a1 new file mode 100644 index 0000000000000000000000000000000000000000..f940f66f8dfd8cc3388bee5a0522ef561313ae11 GIT binary patch literal 391 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC`Ie;vp@P7m#poJ4C z&xv6sLi>L#`niE(IPm(GY3wqW?JJ|Top@_>D&$?NPZqqUub_nfl| zs=Bb``!|;(6%5DKva}!ggv+p8U6$wu_c<&C7#N)013VZRnHl^|Jzd;DjxGWb7XF?t zJ|G4I1B->Ti(?3c&6)zCK_q(vf{lj-vk64gDy%`~QW@}p!u}4{z{el(c-?`B6`(RT z1`Z&JjFGt91t5bsv0#umD*?;~lqZDQfoe#@DCrVw*!;$wFj3+j7P#hUDSHMoc>5WD zNFxGM4dN5zprj%jXcWja)TqK1Gh9G5Aj}O?3`hlM>mm-QgL8IqyF(ZvE(48nwp3T*P=qC*|18O*>z OlbWz$>d_N5IJg19>Js7r literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/355452c1da8e7689d816d67cdde040b5df7eabd7 b/fuzzers/corpora/commit_graph/355452c1da8e7689d816d67cdde040b5df7eabd7 new file mode 100644 index 0000000000000000000000000000000000000000..f135872e53e96721542aa6c1c6744858a237d57b GIT binary patch literal 298 zcmZQzU|?`|5Aa}QWM=U9Y-QxJEwe3Lb)R$jRMBZCOLCa}>fSs*zP@D|yNtBkiIB~L zt*@q+SU+1)?ov7by2Xp{(`wjz&%JG&V9b9arSEChlI3?^#C)?TdD&7p-~X=i{6JS$ z{bliQKmP}US?`}PUEZCia^KfK{z*uAz&_LDb@r9f+Rnjy&RGRjU0Cw{o6C_3hU02k z+7EofWmv8*OLUv~YUbVx)%>%1IzQfg?tA3VGbhJK( literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/35c157ad2b100b4f334cddcf3dea6ef2d85462be b/fuzzers/corpora/commit_graph/35c157ad2b100b4f334cddcf3dea6ef2d85462be new file mode 100644 index 0000000000000000000000000000000000000000..7d73ba721bd59486bb9c746fffdc77d0eb5205a1 GIT binary patch literal 127 zcmZQzuw`&|5Aa}QWM=U9ba7)~_>UKS2g@>mfI#op`wR?SY5)IUY1S*@&(vr!?l}vR c-~eJCAQtidBYU|N$N*UYq)@>YXT$3Z0KgJ9SO5S3 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/36a81a45eabfcf53e1ae0361aa234791e2fdb750 b/fuzzers/corpora/commit_graph/36a81a45eabfcf53e1ae0361aa234791e2fdb750 new file mode 100644 index 0000000000000000000000000000000000000000..fc1b8dde6f62bfbfbc5217b02dd93bcb77091c04 GIT binary patch literal 128 zcmX?h3=gQUKX$Ah0ZI|f`u|`y16IJ#pjX15snKHGa~3Gi1H>FaEaLq~&V7mxzo+jn Q$H=(6&F9|S7LjBC0EkvJVE_OC literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/36ee20f6dbeb3a34e91eafbbe2e379f9ac6cfa43 b/fuzzers/corpora/commit_graph/36ee20f6dbeb3a34e91eafbbe2e379f9ac6cfa43 new file mode 100644 index 0000000000000000000000000000000000000000..769017a8bb1a589e54b93978dbd868dc5e9b14b2 GIT binary patch literal 86 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_R#<{SkjePM3Y#2uzk}RCy8TFI0hu5kYFKju`REu)4_F6+Pn!K8 PySTw&4`i@_cpv}(f;0}B literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/3945843a6fab2ec71030f09b237c125b97cd3ea5 b/fuzzers/corpora/commit_graph/3945843a6fab2ec71030f09b237c125b97cd3ea5 new file mode 100644 index 0000000000000000000000000000000000000000..76191cad060c1c6d301e1371ee6ee3a578ba46ea GIT binary patch literal 601 zcmZP&WMFW15Aa}QWM=R;^>lG#fB*}BPZu8ulf}Z>#W4iJ{*MI+-2d9!WyC6UrCG0p zKU1T{xaTZTF$WOyfHc8PM>0GCZg_838oEx9uJ0i2BHn-G+^6{P=lT9}jEu|MeD2L{ zk+1v@8cGd7?7=XoF1Y%Tl=uU0Z*(S-qMp zV&V%_#st+S;Qec>xCGecRIpz{0OSH<>}RHt{h%mF0~6?>NmM*wiB%GWAd$t;3Ia@* IA(6oj0Mh;3-~a#s literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/396321d39b82ffaccbc64115117df7e822b0f515 b/fuzzers/corpora/commit_graph/396321d39b82ffaccbc64115117df7e822b0f515 new file mode 100644 index 0000000000000000000000000000000000000000..74715a9203aa38d9598857ae17e27217fe79d2bb GIT binary patch literal 207 zcmZQzU|?`|5Aa}QWX}9_xl8&+k`nKq|NsA+ow-wW>T=2y27gZ%H=r7Z5aIw(B_9^d zzz-C}hnX5ZIu}$NF#M)9b(Wc*!`n3Gt5^JYtCU3xIPU4mWRDhR2O0nbd$;7o*&D!YXLm3KB{+dJ z408e5Ak0l;%mXwZ8|DRy=?tks=N@Eqe(yUj)pQ+Je+;bLcCI^sa z#Db~mCv0v9iQ#iQNDc(ByWa@K{UY9f#%`li|;Q7#lau3RKGq)BvVIY@+aA6m@JsJ*ap+ tn9m3l2Vn~!1_2l!7ahM~(cxLkpKRN(^3{P^s0Jb|0I}E@*n!5uF#s)G5DWkS literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/3aa3d8f40392d1c863d23799b8ec0aedc7191302 b/fuzzers/corpora/commit_graph/3aa3d8f40392d1c863d23799b8ec0aedc7191302 new file mode 100644 index 0000000000000000000000000000000000000000..3cbeaaf681d7da10aac2b7bb9aa518b00a84f8b4 GIT binary patch literal 192 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_5m@NK?DLkQbVw@vRHtktRNW JU!wl&D*!ST2zdYi literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/3b08c505601271cb92345ec7f0ff0b28daf90a9c b/fuzzers/corpora/commit_graph/3b08c505601271cb92345ec7f0ff0b28daf90a9c new file mode 100644 index 0000000000000000000000000000000000000000..69b9baba1aa9598d6227153e855132057bcc8547 GIT binary patch literal 525 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&LpDPIM2Iy7LW4;51_YZBi;;nW z6{rS`S)g&9^F{aSl8Grp;Zb1*3(4 zN_n7a1^gz~mP-hju*?cs_&R>IgImPnMFCr!jjkh`=l%2pQ=>=cf{Fu%-{dZIZT;0| i^=h(+i7(I`Ca5_;|1l82So}}EgN-P3FwCtmM*{%omv>MA literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/3b41702587be45f678b36823ad2f7e5002337dc4 b/fuzzers/corpora/commit_graph/3b41702587be45f678b36823ad2f7e5002337dc4 new file mode 100644 index 0000000000000000000000000000000000000000..29069abc7b8bb645ad175e41bfacc52704924555 GIT binary patch literal 343 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bQ}0puxc20Ah0jF&7kb z18FQ+4=xClXJBMt;Lp@(G444F0x$+4S^(s61&At;Rb{q?tL}3ypDH@-BsW6|Lk<8G8yM~Y literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/3b69108cc919aba0248f9b864d4e71c5f6d1931e b/fuzzers/corpora/commit_graph/3b69108cc919aba0248f9b864d4e71c5f6d1931e new file mode 100644 index 0000000000000000000000000000000000000000..207df24697d7648ba11319fe268c4d911994f630 GIT binary patch literal 208 zcmZQzU|?`|5Aa}QWM=U9baC?xaCZg@fq;cS!+$VjoLN*5~YXLOV2f}9A m;q2lV0%5bJfM|&65RwtdCk?Z(GB5xU10TpJ4iEuka{vIbOB|X2 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/3b90507501bb3bcfe0094f9c92cc2869f1a7dda5 b/fuzzers/corpora/commit_graph/3b90507501bb3bcfe0094f9c92cc2869f1a7dda5 new file mode 100644 index 0000000000000000000000000000000000000000..57272325b67371495135a2a014bfe674507b9d8a GIT binary patch literal 135 zcmZQz6uFafQ6 I5%bLg04XOz^8f$< literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/3ce99994986efb6df3f3568423e0077b53c7ef78 b/fuzzers/corpora/commit_graph/3ce99994986efb6df3f3568423e0077b53c7ef78 new file mode 100644 index 0000000000000000000000000000000000000000..21f9ab814847c7cdd932acf927b317e0cf8550ac GIT binary patch literal 1178 zcmZQzU|?`|5Aa}QWM=U9ba4Z6uM-47MSMWaN+rz3z_5X8U;$y17=RYy#oj=9b}}#r zP!FjXsD)H;5~_g(NK-Km;6Va3mK@)M^x*P6)Wr;%Fa{;`|Ns9f(GJ!-Xwxs@MPK0b0Y<)Go#QNEa za+k{a*DYRrpH{=(d+u%H1Y`aaDSc0~mMp*XBIcV#$;+0)`Tlp6=La(I8#6HQGvLK1 zNB|6q6a&1jQSIl`nmWta&*5zv^VKWe)DdB|M~pC%}2Rc?^SROVASm6;aoe% zo?TZ=lh@f-Mr%6T1$i>>`MjV=7K2?;+l3d2u}df`X))JhNkQ$PKn2Sd?;t>F{= zoPGv>cG^_`{^2g^>gW`Brgdf2Ul#xN^Q`wzm@en{y_E7z4vs07BARqW}N^ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/3f46540fbd94bf0337c1d0d7437ec992a3568f09 b/fuzzers/corpora/commit_graph/3f46540fbd94bf0337c1d0d7437ec992a3568f09 new file mode 100644 index 0000000000000000000000000000000000000000..7fbf35089a793839706d667717149f7ac5c75a5f GIT binary patch literal 178 zcmZQzU|?`|5Aa}QWM=R;^>lG#U=RQb@#4ThVFo@v5CO$=dgn1$Tm*913xEU=aCpBw z5VY??7q`K7t+`%r>!p62I3?uQo3axmU%*hppQ+Je+;bMl;Q^@zViE5@a#jf7KE;PW h&-a&OWL)0nb8l{oeC2=Gm;_YDJ!95kr}>+{0st|dDlPy3 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/402d9c25d5833d42630882ab5c57833266bef785 b/fuzzers/corpora/commit_graph/402d9c25d5833d42630882ab5c57833266bef785 new file mode 100644 index 0000000000000000000000000000000000000000..66002819626eac16a8b9b4357d544d7c165da467 GIT binary patch literal 617 zcmcC(I3n!q9^k>q$jspH>Egx!0Tw{E4}{5L;q2lV!oUIIv8I5<_<$rBKh0XQ{LYJ* zZx$slTMFm<-&LL;=*p_UEdK51S?`}PUEZCia^KfK{z*uAz&_LDb@r9f+Rnjy&RGRj zU0Cw{o6C_3hU02k+7EofWmv8*OLUv~YUbVx)%>%1IzQfg?tA3VGbhy3Szpn&iIymRCJ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/4048bb3c26d67c345630ff9e86db551a3add6549 b/fuzzers/corpora/commit_graph/4048bb3c26d67c345630ff9e86db551a3add6549 new file mode 100644 index 0000000000000000000000000000000000000000..a07e1957b935dcf57a139abded528916e9e5edeb GIT binary patch literal 1308 zcmZQzU|?`|5Aa}QWM*Js1agSM|A_(lI1~ZxU|{in`hls@qjN#U0fTRH7rM6oYO{Jp zoZTSz;V>Chm}L8{L`-~vhBFm_T*$y6;Qec>xP-v{uRu1QKtZ(>iAS3KAR9TnCzI?1 xP9gvY5o*X%0ty!-AEPo!_rKTMdZ`~LPQd~jcd(;cgo8(#{iEq`H2tBcKLBv#FD?K8 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/40792f23c1281842dab671e8b213fc408d1ec39f b/fuzzers/corpora/commit_graph/40792f23c1281842dab671e8b213fc408d1ec39f new file mode 100644 index 0000000000000000000000000000000000000000..9a0f9c2988b990f4749fd29c1d2ef230bf78b438 GIT binary patch literal 816 zcmZQzU|?`|5Aa}QWM*IivTlP$tkSCI+Bo%s^?}4#kvX1*%8JvdA3# zY}q$)KbA$l%_^@J;4#hAB3M8STQo(mlJb*tM0F-A@o^%b5TC@V&3kI)V0Z z7XS$$kN^=swEDK3R(R2C@K@l*q&CH%Qrw zply=9;WsZx3Klc|o~?{Lwq>@3tL}3ypGx=eW1zGB1L1!LP+WlHgMr~967XMo@ghTX NG{bdZs*L*0000>WiY5R6 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/41cd0b5d9a9540947b7b1841a55e4c11bd4346a2 b/fuzzers/corpora/commit_graph/41cd0b5d9a9540947b7b1841a55e4c11bd4346a2 new file mode 100644 index 0000000000000000000000000000000000000000..a1b3a077a1953ba7d5450aa66b4cfe02f2b77909 GIT binary patch literal 32 dcmZQzU|?`|5Aa}QWMJ_3bOG`hL_q`$001wz0u}%O literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/41d86e5ea3df4a0de60d42aeb16e2a5599aedeae b/fuzzers/corpora/commit_graph/41d86e5ea3df4a0de60d42aeb16e2a5599aedeae new file mode 100644 index 0000000000000000000000000000000000000000..d749cf6e0bc7603023e079de9157d461a344a9c6 GIT binary patch literal 465 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&7gS>akdWMzIo! v*?{WUNwQiUMKwr2HViV8gEkmwEXZUCfZ4$b6TnI{0Y%X;BTxv2(On7vHKhlQ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/42b4e5430b2b1b17a361067fb9dd33ab74e52232 b/fuzzers/corpora/commit_graph/42b4e5430b2b1b17a361067fb9dd33ab74e52232 new file mode 100644 index 0000000000000000000000000000000000000000..6adf001bd6425a8a6e3eb993fc4d0123457b6bba GIT binary patch literal 202 zcmZQzU|?`|5Aa}QWM=U9Y-O|r@fSIgFaZT%7%U6pF@ty@0)!nr zbp4Z*m%ZojtK>dj02BaWAYk!7vN1OJkI}`VvdQz0&$|%4cHO7joHJqCNYaO}je!MZ LG!!#1xVQlT?8Ypk literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/42ef1c9d234b90acaf1651d930fc52d5f8f158f2 b/fuzzers/corpora/commit_graph/42ef1c9d234b90acaf1651d930fc52d5f8f158f2 new file mode 100644 index 0000000000000000000000000000000000000000..0514ae83705f1ff8fe0c339d4282f88534327063 GIT binary patch literal 275 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_5rh!8CWcwT^vKe90t}D2n{0H8xU+9ECC$i OR1{`m1R6$7%m4r~Dh7Q3 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/4570c8ff26d7f31afe73b3d9a35a29bc1274d68a b/fuzzers/corpora/commit_graph/4570c8ff26d7f31afe73b3d9a35a29bc1274d68a new file mode 100644 index 0000000000000000000000000000000000000000..834d62b346b495b653ee2d6786f0d7114a188222 GIT binary patch literal 153 zcmaFz9}XB87&wq|{Avfch{cNnwm2JIF91q_Fc3JLexfq_XoF1Y%ToWP(a}s%zqx%T zTKgDxIZgJmNZxPel6!vk_Yk>Lc; HMGOo8euqUk literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/45cf4751a5929930a7c30ec10134434b9ee13c3d b/fuzzers/corpora/commit_graph/45cf4751a5929930a7c30ec10134434b9ee13c3d new file mode 100644 index 0000000000000000000000000000000000000000..b761279db111007b314e11d4093665357db3fe23 GIT binary patch literal 2873 zcmX?p91IwMz}Y>(gOQP$!Qa!xje&s!D1wR?FACV=Y;+x@lt0fGNOFU49SQ(Rf&dE; zvw|2%MgW;09*P(PCy)=q(NG%1=7M6d`9L-*{T~R>#mM6G0F8!V0VoaT7XXEUzycTy zJ`g60g|mxe2!zd=0--@9djrTVK=2D824itEfF#Ir7n*-zCZf=fP1f5WBF9kX(vl^nEdMAJU_m^Wg5GTwA+c0&4R73rk7YhTT$*( zIsdxF3tXj3dnzdDL5n7SAe(Z`2s8y321>yq6G4xb|G;1w9OeHYDnLNl30nmS3@efV h*qqVw7f+ZGDicS`U*z^1dFAi-X*DP@fX+uq0sv_y?K=Pf literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/46e9d351dd5bb71f7d4d8f15b3fad312c781452e b/fuzzers/corpora/commit_graph/46e9d351dd5bb71f7d4d8f15b3fad312c781452e new file mode 100644 index 0000000000000000000000000000000000000000..ce26235334d53764abfbd67708c2d479780681ab GIT binary patch literal 164 zcmZQzU|?`|5Aa}QWM=R;^>lFq@7b{RL8yrs+op!P$hsp0v-Sgw?Tc)wgNC&#I>MygejMjDz-gC}r{-&=0;*A)U literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/472421633b984556b96bc20f1fcf7a98c25736f3 b/fuzzers/corpora/commit_graph/472421633b984556b96bc20f1fcf7a98c25736f3 new file mode 100644 index 0000000000000000000000000000000000000000..4a2faa137f02c0ad27b46454851ad44f9cd836dd GIT binary patch literal 322 zcmZQzU|?`|5Aa}QWM=U9ba4Z6uj2$jNf_V*GFYjE*%%l$&=8=yQ+Zh*|NBbr;{`y+ zCjc=Ju=pR@7#sY@$Nw^D@rN&`l&(38%2yZTE WPX(%BfvVy0e!pbaVW;_d3EFF6Eu+_!5uB7Bqin_-GgVMe=f zuXN9@D|T&VW%m<=*)rxoKYZ`&vreEhxC*wIkWJ3z=d@WQy?yVnzdy4ofk3R%t~Ii6wdd*t2{r@l~sRP{M*m7-alcw zygN_jzHh=%34dtROauCu85)fo-Y*ZF{L5+mzhFXQsc~4?vvXMw!kY`)Q-Nw&KxzhS z`aw=f4Y*SkEdDHT#9sw4{zmf;zI-&Af6z-bn&h9IqvbEY@)uYB9a7~ltnR~ITmcJQ Q2G$2ov)(V+ba?((0Ot}fTL1t6 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/49e0eee24eab094a9c62f6b37b6ba01f8aece4e4 b/fuzzers/corpora/commit_graph/49e0eee24eab094a9c62f6b37b6ba01f8aece4e4 new file mode 100644 index 0000000000000000000000000000000000000000..78f9425794bdac92483a4612abb37e958e3ca04b GIT binary patch literal 2095 zcmZShFU#QU9^k>q$jspH$?f9C00fK>{QfdF}7>0y5Skb4X%SC2Ny!JxOjQMln+C zz?CD3Q8&h5Hmrv+D5nX!6`o;xu~*&7gS5K9w{kC5d6 zF<&G2C@iofP=uXC4AO@kGvN@&Q15_6KTrrHimH|q$VbOqKrs*|&fRY@)M2q3>Tc5A j&%nS9bO|QLZ3ozY*!&N41L^jo+C#E_7O>NSK7arKZcYu; literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/4c428300fe4866fe81cff02ad4bc14b6848f7f73 b/fuzzers/corpora/commit_graph/4c428300fe4866fe81cff02ad4bc14b6848f7f73 new file mode 100644 index 0000000000000000000000000000000000000000..d7f09e3ba212d5ddb01495d2674f568540169f0e GIT binary patch literal 281 zcmZQzU|?`|5Aa}QWM=U9ba4Z6Q2-;5M*&9G4$$B570iYR- zcrX)C4h1s<1wa@GSfQ8=NTXv07N8(54AV#{4YL$z6)6Cpf2k31WdTClrG@FhLFm0H#J2p8x;= literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/4da73370cf854ef8bd08c7f79b92a187cdbff278 b/fuzzers/corpora/commit_graph/4da73370cf854ef8bd08c7f79b92a187cdbff278 new file mode 100644 index 0000000000000000000000000000000000000000..da1801e77014551b2eb3e741ba6c7e2cdc8edd54 GIT binary patch literal 81 rcmZQzU|?`|5Aa}QWM=U9baDI74isQuu{BoObH%sT8ef74e09V-b> literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/4e4b2827351bbfd414b718052a8f950a9e3eb7ee b/fuzzers/corpora/commit_graph/4e4b2827351bbfd414b718052a8f950a9e3eb7ee new file mode 100644 index 0000000000000000000000000000000000000000..77d2e785e2959c877a0a096c5c89f76c2d3e1d98 GIT binary patch literal 738 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bQ}00iPC qU){mP#?t@WB{r;KoN)_ zve}$KHRzZNC5UOJ*H* sn!o8Q10PU5wK2B%K@J}(vVlf{Ohb)Z^sooT=RZ~=9JFgMYd39nja9Om$_Ffi~iFmM1d Uh-To2Vj#;kfKjuLhm(N;0M!*5IRF3v literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/4f1928b6376369ab6acf8a282284366cc3bf71ef b/fuzzers/corpora/commit_graph/4f1928b6376369ab6acf8a282284366cc3bf71ef new file mode 100644 index 0000000000000000000000000000000000000000..ad3d1739ce93ab9dcc91aecf8582e7b79440141e GIT binary patch literal 2654 zcmZQzU|?`|5Aa}QWM*Js1agSM|A_(l#3&+F4bXuMEZ$E)Fg1E~E~q$Q@J;SQ*VbQc zRIPJF*G4TaTG8KSSFfa&s|Jo`pA#ndIkc}rqak_;x`$0BxcuywT z37kX#4kFZ$r34f%RP?{s+j^-VCr-fv8+Wkdv=do^wD3nye+@8KV55<(!O14s{?YVD zY9gd^`oovaQRHyOIkE)F@sB&bqo+Y+YjCnjwtqDJ4RHD!E&oRAUy_m_mCHYH`a@5I E0N47NV*mgE literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/4f669eca3416c44f0d003ef2720d03e697e2230e b/fuzzers/corpora/commit_graph/4f669eca3416c44f0d003ef2720d03e697e2230e new file mode 100644 index 0000000000000000000000000000000000000000..6a143b3a11acde682034cf5a372f14483885238a GIT binary patch literal 80 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_5so^3=Av`mX6LLAVK4>uxID8SV2rQz|O+J JzzBp43;>IU2oeAQ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/4f750f24ecb5080bea2845061cfd3ce4529d30ee b/fuzzers/corpora/commit_graph/4f750f24ecb5080bea2845061cfd3ce4529d30ee new file mode 100644 index 0000000000000000000000000000000000000000..ea36bdc1e64edd1550df72e307a745fc6b38b753 GIT binary patch literal 280 zcmZQzU|?`|5Aa}QWM=U9ba4Z6!GHrul7#;w0CuecFylCZ^5~cgC*&F^tz%LLF$_6pX z2agD8WdSN+1u5b{U?3C31CtFfaZVr~9diN2K$sf|>x0;JC;%)A@(w~JPzVC3Za>&9 zNY>lg)d6kd1_vj?eqtO4F~f6qXYx81qikRTn*SFECxdq zAh{pN#NvLS5Co7EezHJ4$Z-g?A9wnL*+3CZ|MZ6*|I`dWlq-r&albCI4WQf5fFfkSa_7Eo&(%e~GgnZa2~82V4gdgZkxHDHu4- H-}Ds#OAxn+ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/4fd757c7251c17413b3005fb38aee0fd029d89ec b/fuzzers/corpora/commit_graph/4fd757c7251c17413b3005fb38aee0fd029d89ec new file mode 100644 index 0000000000000000000000000000000000000000..4f4db7d47d6b28f6e384e4605043a82a634c730b GIT binary patch literal 861 zcmZQDXJBx45Aa}QWM=U9ba7*#Ex=-x1s)r(0|7+ZECIxZ13Y@LNx}6I$zWjM1{#Bm znIU{E?#E^yx)_nx!j(bou3}(#j|`gbfBe5=@9!1HUvBI^`?OoG-n{^569^LkaD$0t zp!yvY4p9H2gbBA9!df06Q-^_p4@jZmW4e*-acqrXVT5`R3)yS$U!(A_bMX3~#rx%f f?Ozxw!FC||6JjS#(+^5Kuz0^Xu$_U80qAc4Qmh~V literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/506092de91dcf93254cdd5ad9e02a953a38099ea b/fuzzers/corpora/commit_graph/506092de91dcf93254cdd5ad9e02a953a38099ea new file mode 100644 index 0000000000000000000000000000000000000000..64c5405f2c289c2aa1721049520989c126d98297 GIT binary patch literal 280 zcmZQzU|?`|5Aa}QWM=U9ba7*d1qv`QSOD2RU={<5g|mxe2!zd=0->QKH-aaCV4|}) zfdX7m4AOxG>%j$~nnCKFCVQDB?>BSFJwN+fS&Vf~k$M z!GDY{7L`q&cYNN3=(X!U-R7LhAO@6TEr2NF@QHf)#5lC1qy)7;Q?Y1 z??1AaOIfd!)C&5Y(YYRQVco-&nh7@BxGWhMSPCFId4Ot;=|-~0u{C~m@X+;7QeM`_ z|Gtv@I7l9i0$EH@3k1A> zZ55Z;{{Hj%f18hUuimTR8o;R8#{&!|f%{*3yV6*Nt~Bps1Zn``)d+A`d4Ax9uC2e? UtX@qPX?-=l#2VExP|Fw?0HUv8(*OVf literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/512e49a9e789656964988950009e6534907e6317 b/fuzzers/corpora/commit_graph/512e49a9e789656964988950009e6534907e6317 new file mode 100644 index 0000000000000000000000000000000000000000..7cf8e31811bb44a7fb024931b2bfb0f877ec1209 GIT binary patch literal 2021 zcmZQzU}JE05Aa}QWM=U9ba7*V01JN*jUwUc;scRmv2b>A41us&Qy?^)WN!d6Er2Gu zK!orrhUk@1HPT z-kqm%-`79>Nl1CXKGWoN_Lb4v&cS=mSp`*HSn~aw%aIC(<7!#R;mp9W0Tjp#42HlU zLyH3=U>tA*oq`K91Lb(IU|ygYPK@Sd^dP{(|MMRdyeRrsnFB>u5dg@EiD24+#5>Sb zLIA}bK*falgUkI`{0B?z*l37yejtU4H)1gdE(A&#aKQI8YsvCEFS2u)PhP)fJGs)o zW%VOdM-7+2X%k~8O2*m`e8Oc|t}aV-oA_$x-V4?IvwAu|-hA$R=}?ZUm%J-e>hwUw3KPY`CynE(9ny|2$Yfo|o7#n8 zmZXves2^U+5Wxl|$+Wo(wS<5)57a#ZeiLiUB?Qb_W`!(#9lzSaEn@MafGy5O*Fo}7 zH7wpwKQJ|VbS|hkVE9e$Lf6(`ZC0-)iFVedv>b}av8(qg xfHE%wt7`zGW&^NFVqnCM|KSkFr5-H431}8D#brUVz~BG>fA|0Y{~sub1OU_0PZI zVPMz*22lP?2oFJmT#E$&jbUV<-2I^NLkl0&FhLDFkQ~*+Zy@~-jmNNvRbXIa1ELrJ DeKOj( literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/5150f8a67399ee16178a2b08198cf91a90c0e53e b/fuzzers/corpora/commit_graph/5150f8a67399ee16178a2b08198cf91a90c0e53e new file mode 100644 index 0000000000000000000000000000000000000000..c0867a0a7ea509c15ac84be592676a2a017d1890 GIT binary patch literal 538 zcmZQzU|?`|5Aa}QWM=U9RO5DW0}6nEg}of2E~sHk O{qTc09T*hAPz3-$u%`?F literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/51a1fd23dfe5a8062cd4601d235509247f3bc2dc b/fuzzers/corpora/commit_graph/51a1fd23dfe5a8062cd4601d235509247f3bc2dc new file mode 100644 index 0000000000000000000000000000000000000000..c448928732ae9ceffb474c90696574a3fcce6cdb GIT binary patch literal 218 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6b1%HAQKDzcGPUqQIR>z zoljmp-7&qK+1HozBTyws2Mn-7G%^ACSTGY%Y~ED2b8!voI~RQJlVe+wVo}Jutqi2e P0h^6j#TXdapwMCVmU|=MGu_^%SfdP{B!!!a71^^Tz0xkdm literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/51fbf57a2a35ec33164838fa254fe605a3c868e9 b/fuzzers/corpora/commit_graph/51fbf57a2a35ec33164838fa254fe605a3c868e9 new file mode 100644 index 0000000000000000000000000000000000000000..d0c77cd132bb8ede42666e909593d09d988383f0 GIT binary patch literal 986 zcmZQzU|?`|5Aa}QWM=U9ba7)~U<8UVFfg500@D-{7C|477J$=#}Ke618WL|29fLy2sZgFkT(foN9<~jk^_K7v17p;KrsxAO(C)vh6Zeg zP)Q6HTgWsQ&}Gd)MQ zLYXGBW9}nl+IVMk3W*=>kDScV$zce~pfm(nm z>Nj_e&qQk<<1VMkUSPK)h_&G|ELWES)9s)C3=AwlaUcdc4ah4WYn%Rv;UM85met!R#cc z0Eokef*;t2H-Dx?>c@#wLVmp| zJCV)tiF&zr-Gq;NuQI1=zEug0bJ+PeZSF!X7%c>H57ayXzlpWw5&|YHvqBcWj$iHI z7O{9yz!qnt>&WJLKmEYe=+U{L;(*~dxeHxef3;b?nk-`C3p9rbVvfE(!cb)f1`Jb? SUCRJ>Hc&q(oM9NsWB>pVT5s3@ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/5314619e15fa5ee67df44481b8213a53786d39c5 b/fuzzers/corpora/commit_graph/5314619e15fa5ee67df44481b8213a53786d39c5 new file mode 100644 index 0000000000000000000000000000000000000000..a00e14dac1269d02554d32164c42c6e3c4e90cc4 GIT binary patch literal 146 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_5ri(8CWcwT^vK0z&r#25k>IHV!bh~yUD2E TqtNEaGUNS{S%;nGZ~6)VVBHYP literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/533f5f00275968129846522fe01e2819746272eb b/fuzzers/corpora/commit_graph/533f5f00275968129846522fe01e2819746272eb new file mode 100644 index 0000000000000000000000000000000000000000..0830b01dcd29d8ae3babaeb793d9d091fbb9ebbe GIT binary patch literal 80 zcmZQzU|?`|5Aa}QWM=R;@pN%xVBiA^Apj$SY2okb;sfEbSU9^lf|($BkX|6A0K@?L CW(8#c literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/53a62799135c282435a17e032deda03eaf9daf0f b/fuzzers/corpora/commit_graph/53a62799135c282435a17e032deda03eaf9daf0f new file mode 100644 index 0000000000000000000000000000000000000000..f6bfddbef53716d483d2ba86439578f74bedd199 GIT binary patch literal 83 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2EUcVe977-+))WX0CEu9V-DK47QE2<_ Q$TH*ol39nH=5P860KMuE%K!iX literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/53c9d5cd849977e523d92dd2d639e9b0e721be50 b/fuzzers/corpora/commit_graph/53c9d5cd849977e523d92dd2d639e9b0e721be50 new file mode 100644 index 0000000000000000000000000000000000000000..ed30c5e7b51e93e9b2b6c73abc6145ec65480921 GIT binary patch literal 680 zcmZQzXJBx45Aa}QWM=R;^>o?up8*Uk{5@TKAWRkuXBWp15F04RngS67kwC2o%?u2J zATBQOgz56`JeB*t{_#&j$^-V9C$F=wjMjDz-gC|>sOrKJ&2KJfIx7wsev`Y0dEEdZV3Cwb3ey-ToMBJzxH;eu?k&j)+^!9)Mzp8ISW+E0mM8Y zEpQKdy10S(Kwy!M#eZntYXGWaWWZ}bg9N$uCt$T7{<8SDpJx>b&bk(HmFvFUm+BK~>vDo$SSduk2c-y*6TndgjwT@IJ1EXXyut2< N#2SAd0|PK=0ssySj~f60 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/54767a0bb3b96d39f5b2004ce3f274465f1a927e b/fuzzers/corpora/commit_graph/54767a0bb3b96d39f5b2004ce3f274465f1a927e new file mode 100644 index 0000000000000000000000000000000000000000..fd9a0ac653c12bdc4f7e595ea0efd19d5d2e8c14 GIT binary patch literal 2022 zcmZShFU#QU9^k>q$jspH$?f9C00fK>{QfdF}7>0y5Skb4X%SC2Ny!JxOjQMln+C zz?CD3Q8&h5Hmrv+D5nX!6`o;xu~z>>Tn2n;1kZkAj1LxLfuN9 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/548de37dbe6a3829b73d976996ec9838cf608554 b/fuzzers/corpora/commit_graph/548de37dbe6a3829b73d976996ec9838cf608554 new file mode 100644 index 0000000000000000000000000000000000000000..89772e2009aa829bfd423ccb6debb3f5eef91f8a GIT binary patch literal 296 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESwqmflTsn%QSWwX}1$0n+026O)s&2 zwxZmna{hIT7vHDVu=k#O+c?3P|3pgP)2t=S@4SflW>NC8rEtFgUFG?KuB`gY;@__N z{qFSUqANGHO4?^8Y9`oh<6>Z7`40ioUjb8XT;c!# literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/5522cefa54b798ea4aba8ef2a42ad248a7fb02ee b/fuzzers/corpora/commit_graph/5522cefa54b798ea4aba8ef2a42ad248a7fb02ee new file mode 100644 index 0000000000000000000000000000000000000000..6a4da78121cb084b6d614420e31188e10753eaef GIT binary patch literal 60 ucmezW|Nl2<_W%z@MrHxTlERC072g*Y5fs=nZtphylJzW40XgD7L literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/567fe73919dae39b0bcb78b03d655643a71714a8 b/fuzzers/corpora/commit_graph/567fe73919dae39b0bcb78b03d655643a71714a8 new file mode 100644 index 0000000000000000000000000000000000000000..56b1e141a8bd6dd541f9c5a1530d6e040459ec12 GIT binary patch literal 409 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ES%5c1qD!b-Y*Yq|He?s*q!F*S7|h> z?q}$n-g(Rw7lG33P&FJtH9`9>ba5NRYR&a}TQBwF#3>=a-jtmXd5AO{!-MeVg7#FP zJ{G7x9`9eK9FEOR_dovMvG?~1<1aUMpMBabSMLszhpJ(r)P9&bK2b0CuAA^t?^Wh> w&9^F{aSl8Grp;ZbCB(q6rzev=8sfZWsPh_t4uAkk?1xym4Qe3+10&-+07>(gR{#J2 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/5717a281aa722ee4a32dfa1cc72fc5d6081f6755 b/fuzzers/corpora/commit_graph/5717a281aa722ee4a32dfa1cc72fc5d6081f6755 new file mode 100644 index 0000000000000000000000000000000000000000..77f0e516eeef48956059a6053f9eb6c253dc464d GIT binary patch literal 2126 zcmeyb%>V?>?g1W*jLZ!FNB%r>l6@QZV_D=&4uKu_?HY~<-(>z~m||0y(JtI8-Lvb8 zU0Ye%{RCmQjQP(G-~0Nk6R4ZJfI&BsJ&p}z5&~SmejUVt8|~@h#t;jZw($3K@qs90 zv2b>A41us&Qy?^mWN$#Q@v=C9vRqKi4WzMPJ-8sqBt`}X{!EP)0I`Vo z9FyoLDzlF^$dtY;^-o^1Eqh_D4pg2I}IffY(a_{1kL zknz|64)?>O9Ow_?+>bN<5pfT*3)vkoF;Ivjg&EP|Cjd)-U_(dq-)Q~=rz4`%54`*W zr602Mp8>%F9-KTSK;#dtzAdK}Ui1nW{1vz{sZBAeF!(Y gs^@=DUT319{O6>3`HvRFq=z5T=?|&=(q9%20NScc;s5{u literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/577d814e0be43df9321c5b27119c398bd00a00c5 b/fuzzers/corpora/commit_graph/577d814e0be43df9321c5b27119c398bd00a00c5 new file mode 100644 index 0000000000000000000000000000000000000000..c892728c8efd23c106ba2cffa590d3cc6bdccd40 GIT binary patch literal 317 zcmZ3r3I_gz0F?6{CWuNi0D-f6fCnQZGlPq#zZ(OC14!r?h=2l%1Wy+q5F2b9s}_*O qiiFvKY-9}Nq64r-G=hQQIvD`P5Jspy|G9w-5C%~&HaRp80|NlSrg%R9 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/58680611707c6188f9f067f8747b699cd2fe82d3 b/fuzzers/corpora/commit_graph/58680611707c6188f9f067f8747b699cd2fe82d3 new file mode 100644 index 0000000000000000000000000000000000000000..81efaf38a34f77f6054670c731e66aea079fc8ab GIT binary patch literal 453 zcmezW|G%oUdjKO30}uci9*m644F0B`E^Z(J2C@2|dvzy$Tr9`%?>_?rGf?F3|Ns9# z18ESO*|yBKaMgXz=YMJKu{CM5^H|#RfZYM(O>+7NFSU4H}{AZ}Iw*?9z zgRX{#24p@d?9GC$ucnt+KU-1mQaS&+(Tnd1HSE3T-ZoA!=0B0r_cUwC@;fhLzFCyK zY$=@Ye^+^aAp^fL0|P(MMPy^uemgrDw@O*Gfa9K?O!nx# zTXJIZS<}w+9Nm)FebWoKJ^T!>X70UE%|ENB^W)9uzDNE%bCP`%_hVV)OAdh@_w5>R SIu-8rO+c#|zJdrKUJUry`)1rriWjl;s8oy&R<-dxb03Y233sX4BerTxGsT!!W9vP8FuuV(JO zP|ZK9r}N{@=e|e&JadwL6Zd0Txx}lS=s#r zVYZC<&kx`G`m7UZ9yiot(%cV>4@!VX zXI~ku?Hs)4oK;ZOg(cs=xg4n&B;f~16y$~*Odl-#;52fw$Hj(Z0fGBpd%MzDg|0N~ zmGEb3w3zgq1;zz1J{fp`Sj78}?B!C{+AD&7C1)0154f=IVG1OcpJpvte&)h%ff2$nM2LY{ zns6=~ki`zf%`=?meZTIdcJo;0twoaAY{Dz@v_ay?n1K%{fWXW^9t0r7kmbo>Kh0XQ z{LYJ*Zx$slTMFm<-&LL;=*p_UEdK51S?`}PUEZCia^KfK{z*tV*xvPh!P9^Y<^qT- zIJ{pTIQf^;`hUTM#8Tt1uxID89)vd+w5I~4S)gioynk)waBOb6|MCBhy+CnRGz_ UVPVhCWj%PmWY%G)`J281048m2(*OVf literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/5ba93c9db0cff93f52b521d7420e43f6eda2784f b/fuzzers/corpora/commit_graph/5ba93c9db0cff93f52b521d7420e43f6eda2784f new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/5bf0ca772092e6fa34b6822f61a1b1c3d7f2c6e3 b/fuzzers/corpora/commit_graph/5bf0ca772092e6fa34b6822f61a1b1c3d7f2c6e3 new file mode 100644 index 0000000000000000000000000000000000000000..06dd1e1a82bd2a12a47c9203d776f31907cd9349 GIT binary patch literal 318 zcmZSJVPJ4}5Aa}QWM=U9ba7)q28^Z*j0_CnKn$WO!c0K@gfKHu4K~aI6vu~Q=3>(e k62qq#U5*u~o&gvpSTQeek3!pbN0u4ym&`isG=I}q00{OBU;qFB literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/5cfbfb3e12b629dc9f74baf0a8741345ec288795 b/fuzzers/corpora/commit_graph/5cfbfb3e12b629dc9f74baf0a8741345ec288795 new file mode 100644 index 0000000000000000000000000000000000000000..73e257d4b982708192a84d185e8b6e5393cf1932 GIT binary patch literal 802 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{Xb24=*&7gS@>x0z3>-k+ zMB)DkfT1NYaCJeqdK&ldUm@B2cAfL@F@;WKVBiF*gJCWp8-%%u#0(6KK$Squ2Bg@@ z#6WEvMEMP*kPt?A|34O`c>J}#Wg5GTwA+c0&4R73rk7YhTT$*(IsdxFi|^A8emEPq zEW_c>uW4%>t-l2n#VE8`S(LnNDV*Dy??@Vd3T=5eP93hCn4nl z`%IJ9*;htuI|uJMXBAX+VafMzE=MZBK?`&lH_R!=VPOxV3Hy(b8Vvt4fr5;9b20S8 Pbi>mG$ic8Q0*iJ4Ws`ME literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/5d8cc97b739c39820b761b6551d34dd647da6816 b/fuzzers/corpora/commit_graph/5d8cc97b739c39820b761b6551d34dd647da6816 new file mode 100644 index 0000000000000000000000000000000000000000..7a241f330307e5690d8dcc450f075ebabda3466f GIT binary patch literal 342 zcmZQzU|?`|5Aa}QWM=U9ba4Z64+F6UknIDcfq=!r*~Kvg!e&i@&>)h%ff2^x05S;U zRp@He@#q0cfn*^hH<0FG(8UBGVNA>m(#MC1wVi|aoU;n5y0GN?H*6{ z%k*tIt?;5(z~HaIjY(~a>-&PI0rj#1@jocd2BbkaNqJeH_WMfi;{`wt2m=9&X&u;c SZQmVPX1rfA>#)=OOw)oMZUobuK(j!Y3yQgcG(OA&lm}r?7at%A1S}TL zE{-7(Hfsum29fLy2sVhNiOR*zbHFVHlmP_<%p)M0P(YxEDF*`+EYt|m4w!mDT0o+Z QFak4>2xoUNCxC$g0BxXJoB#j- literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6045e4d2bf85013c78a32e71b014ba3d4a4b7c61 b/fuzzers/corpora/commit_graph/6045e4d2bf85013c78a32e71b014ba3d4a4b7c61 new file mode 100644 index 0000000000000000000000000000000000000000..5ebec5aee8efe1be479cce65fb7b4db53010519b GIT binary patch literal 540 zcmZQzU}SK15Aa}QWX}9_xl8&+k`nKqdqLaZoVinV>T=2y27gZ%HwFl>0J41`Ocskp z&MuB2Pzl`BnVzFt^15$&DQKHyZ}`o-{r%_j|27}xUcFbrHGomGkB4*Z9Fr$1vyV2& zl)fzWUm6|F6!n|iXQH)_ahKC%FN@^;W-htsXMYcod&m+NG{ZPR#p!b^BadyFZQ-i> zoXe+*PCHqW!{k@@=K1mUEz{U#q}@)0Y!+;NHNC|8nfZ(F(`wjz&%JG&V9b9arSECh zlI3?^#C)?TdD&7p-~X=i{6JS${bliQKhJvqgz56`JeB*t{_#&j$^-TpB(JltjMjDz z-gC|>sOrL!??=8dxKtch%hG<}6E4GYl_Ak>;;Wf^FI4l->goB2!+s0$?Ke$cN4fvW Su>VO2Ff}lMFfb&To&W%EDC#Ky literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/615c7ba7ffbce955ffd964682e2a0f7ef3c767e4 b/fuzzers/corpora/commit_graph/615c7ba7ffbce955ffd964682e2a0f7ef3c767e4 new file mode 100644 index 0000000000000000000000000000000000000000..8360672e47df68b063e89945734801eac6341d71 GIT binary patch literal 86 zcmZQzU|?`|5Aa}QWM=ROvfr@+2`I>YTBbf{>Z6oNIVlBy-zdHav0+JNVAw}A02Z6#Xy+b5QsrE9KS+hBa4&4 zwgno>1IDaS8pdZ};01~^@DYojW-VEM=S9pni;|Zuh4cOID$fseWz}C6|Mv5&_fMEE z@6J=X@9Q7`B&0lGpK0wc|1{6;s-hX!7w`;)k zf5mY0KR67COGD(vGc*ZI1BNU!G`VnizdUgAFQ@hYf(ePG#$jR4&SgDtn)QCk{KK2R F0s#B<5#ay; literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/627224cb8484c62992dcbc4cdebdbfa48a3c021a b/fuzzers/corpora/commit_graph/627224cb8484c62992dcbc4cdebdbfa48a3c021a new file mode 100644 index 0000000000000000000000000000000000000000..f73b59d91cdd3b4dca38a1079f6c806c4765c588 GIT binary patch literal 153 zcmZQzU}JE05Aa}QWM=U9ba7*V01F`72f}2raCUJFfv{Oq7#RKoLDhvN-@myWsbDy+ zmZkl`CtQZ*>as+)iLYkvy->|RtEcnh&F8*H{ycM%eG~U%S>#I&fgShl8jc9xWd3H5 kVpEvWF5D~Kv+IgoTUput1Yx#}`A}OK7=CCm038GZ04+anae^`biIl#lSxc7Rc@gu?qU2>u;e7wQ%JTym_>CDD z_!&@fKN=rh9)+*k&!;tYmYJW!+cf5@SNwOYltl|T?&-;7kKVf_CnldY?M%+{0sv%zViy1a literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/63de5e8e042222d53bf05640c87da376aefb76cc b/fuzzers/corpora/commit_graph/63de5e8e042222d53bf05640c87da376aefb76cc new file mode 100644 index 0000000000000000000000000000000000000000..2fd95a3fd50c01b47c008913d6800f45cea13af4 GIT binary patch literal 2084 zcmZShFU#QU9^k>q$jspH$?f9C00fL+%*Xvw`Bc$qCrfge{OaC3Kfb=@J>3Dr36QT4PIGa4-`hK}7Y?vEC;^Mu`}a6}G>u*6 zKUVc53$91#K(Y%ih$My_qBOA|ZYh}zf^LNee=imr20r|;IEt=9NZ|*!7fFmZ@ej8N zg@KuWK=}y>Ed4!Qd>~8~3uhO{5D1$UT7saK4!}|aRB)ik0lA25NzW2vkmi4+U`L8; zxG0hs4dOrl{rmNBt0-m=bn9sT#~a2-;RjcTBu0by2U_zaq&xtUhe6~6pKt~S85RIX C0~J63 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/647dbb1d05fe0fab685bfe126bd9ac3a12b6bccf b/fuzzers/corpora/commit_graph/647dbb1d05fe0fab685bfe126bd9ac3a12b6bccf new file mode 100644 index 0000000000000000000000000000000000000000..245d46b1801b2e2ee966d69a807969146ae806f0 GIT binary patch literal 279 zcmZQzU|?`|5Aa}QWM=U9ba7*_0SZ8XB?pkkhbzuLhqVzDet7efJr#p3<+ z15=|%=Yom@hTr5abZ!0BX7y^ah>0&ynhB~#!28!$aS4I@UwgaKScR@M>y_|lYP1;l zoCT`kVS-pL;{8X?eTol%p6@Tm$hf@C=ib~F`O5#WF^Q3nfg5U$grDO(E*$27Jir6Q zKyzd-m$KGg5%eoLv+#Prg>?^8Y9`oh;{wVtnAY7?X#4KSGUNS{S%;nGZ~6)Vm>^81 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/647e5e265d8d1079784fc2a3da25f7ba58126acd b/fuzzers/corpora/commit_graph/647e5e265d8d1079784fc2a3da25f7ba58126acd new file mode 100644 index 0000000000000000000000000000000000000000..633a2a3db7d168c5c96c85dd15f4f726163e004e GIT binary patch literal 73 zcmezW9|r1R3=qxm-;lxCJ-~yJ(T9P7?MX;^z&_LDb@r78+Rnjy&RGRjU3kCb`!|;( N6<3#ieb&hU1OPO{D*6Bb literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/653bd480dfd1e5f4bdca702aba3dfd8da0c204b7 b/fuzzers/corpora/commit_graph/653bd480dfd1e5f4bdca702aba3dfd8da0c204b7 new file mode 100644 index 0000000000000000000000000000000000000000..d12360225a6a5871daceed9efb77c0cb7a1b44c9 GIT binary patch literal 103 zcmZQzU|?`|5Aa}QWM=R;^>lFq@);PIpcujW_n(1*87TVq|9>D0qCkbg0nGTv!obP! U2Pn(}lwpHnAO&VKumc(F0IlE*6#xJL literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/65485740a465377213c80fa68028727f281299fb b/fuzzers/corpora/commit_graph/65485740a465377213c80fa68028727f281299fb new file mode 100644 index 0000000000000000000000000000000000000000..c100bdb51b5c54b2cb4a726b782aef859b54cc5c GIT binary patch literal 80 scmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY)`c)xES&!%gJxt78k>Ou0GXgHWdHyG literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6551f8c8c3028006d0cc4997943df8a86ee3f598 b/fuzzers/corpora/commit_graph/6551f8c8c3028006d0cc4997943df8a86ee3f598 new file mode 100644 index 0000000000000000000000000000000000000000..0ff4ddab708494e802806cf15b4a9ee03d6d6bfd GIT binary patch literal 444 zcmZ3r3I_gz0E~m3W&i?b_W%z@MrHm=OyG8vhF};SW;b=>jBItpc*h0$_)VL$!iAAP)ff z5FenC3^QiT`Tu_g831B5vJ=s~_v8P6Cuj&mRI&IU*%%wF(DvPtWybp@$T}GSJEMwE literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/67799e79d33883510f85ae9705ab3932862128a2 b/fuzzers/corpora/commit_graph/67799e79d33883510f85ae9705ab3932862128a2 new file mode 100644 index 0000000000000000000000000000000000000000..2782b4f37d2d6f87db35e3573281770bf3c38e69 GIT binary patch literal 991 zcmZSh&(7fN9^k>q$jspH*~-XMNd&Mhvn^b8pL6+CMg|BFop!P$hsm$*&GX~yTc)wg zNHefl{09OC1{Ma88Z?~w=`uqXR4c704xqv47~~`%utOKe!Uqa*Fw90XgA>SyU>TOH z%M#rtzM8rBLbcVbp3aXqpZgwR1xm9Kf!Tp-*ck-wf9>r`V->p6tXIOHsnKHGa~3EL zataR+QvkSudWpe!tU&e!#I+z7k@1HPT-kqm%-`79>Nl1CXKGWoN_Lb4v&cS=mSp`*H zSn~aw%aIC(<7!#j4}8LrLz*8J(tn;g$-asEu`Kc>hro{eb`3{_Z!&)~OtC4eu6Mt#{B1p?|psN2?~+|h=(OW)DNw`EvFS;^a>dK6}T~}O);u4cp6Zc w8LEcE`{jX?e>tuH7feVjH3mDJ-kyLYRjee~p^&VHlFq@);P!>VNLlo%C_B9K*l=3=GUbk-z`{|Nji6L2MXi c0kT;bI2rx`)i5xq05KZ_LoWjZJCMZ=0D2k`0ssI2 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/67e5a649967dee002d1c181e079748c404e29767 b/fuzzers/corpora/commit_graph/67e5a649967dee002d1c181e079748c404e29767 new file mode 100644 index 0000000000000000000000000000000000000000..3bb8714af9a8c0effbd5dac1de8dfe43b94d25dc GIT binary patch literal 1116 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^=B#VW!i(?3c!xx}lS=s#rVYZC<&kx`G`m7VEi@N}%pMgOFMEua|+j3gr zMX!LtUx6Ew+7zP-ga6|JMA-^77MD5(R-hy@Mg$Ekh%jk(pdNMxf%{*3yV6*Nt~BeF z@MmhY826k7igN%lD4ayR|Hxi0Wv#s;=vQ)P;q`zE>mH^+T=6t($?`idV!m0Fylg3) z?|)Z$exNI>{<8SDpJ%;)!gP6ep2~gSg!m^RT1`RCQs=_irvo zDj1HdWobX~3728Hx-8Lc;;Wf^FI4l->goJ=^SSSlKhK?1_+M!AO(aHb7D1j9uAa4V`1ONc(h9Lj| literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/687424a4a31a66a78d1637c680c9c10746741007 b/fuzzers/corpora/commit_graph/687424a4a31a66a78d1637c680c9c10746741007 new file mode 100644 index 0000000000000000000000000000000000000000..6b26c194ab357de7188bc1c73a215a8c8697ea86 GIT binary patch literal 1573 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&F^tz%LLF$_6pX z2agD8WdSN+1u5b{U?3C31CtFfaZVr~9diN2K$sgH*P#HgEXX?ul|Uf~z-B)?RqeN{ z1KPw54o-yq$Sy|qI))cPUdH0hUthq6;x`!C5_C4$A}j_&!V)F;u(=-+ct8?c_~DE{ zS)c~wI3(YGWbcp@ewayyfq@6?DWKy~(i}N%E=2*5up%P={jB?rl>Z>wC?tnu{==Dm okkby1j6u`%OM?B-cpKpG2e|@T7i50A+$DV@Ns0GQUERGP04nd1V*mgE literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/68fa6dd52832657cb8dd7e1485d6fbafd4e93903 b/fuzzers/corpora/commit_graph/68fa6dd52832657cb8dd7e1485d6fbafd4e93903 new file mode 100644 index 0000000000000000000000000000000000000000..fb966ffe938ce90b5d374101e7da2a6edab862f1 GIT binary patch literal 536 zcmZQzU|?`|5Aa}QWM=R;^>lFq@_k>fuZ7n;WxPpU0Z*( zSsB&cWYq6bX#4KSGUNS{S%;nGZ~FRbvWST{cp-A0p(v|1^Ta3kcW&4?1Q2 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/691696af1c042115f4d9f9b8e24f7b8c06ed189b b/fuzzers/corpora/commit_graph/691696af1c042115f4d9f9b8e24f7b8c06ed189b new file mode 100644 index 0000000000000000000000000000000000000000..e407bd3c785974c704ac6db87a2fa7eb9e9ebefc GIT binary patch literal 284 zcmZQzU|?`|5Aa}QWM=U9RO5Epu;D)#u+H3o27oHD0Y(M}Ac7De2AG3vXe%R+ZJBN1 vs{5SFr;1KHS(3x#SNG=m@%1g!*k%5|M}V-1RUk0X_OG%5Izm}_)hY%6qoHQi literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6a80152f9b1afa3a3080bf3f6aa48e84c2e18497 b/fuzzers/corpora/commit_graph/6a80152f9b1afa3a3080bf3f6aa48e84c2e18497 new file mode 100644 index 0000000000000000000000000000000000000000..a706cb042acbc7fc51e413429186a83e6fccc242 GIT binary patch literal 2116 zcmezW9|#yg1Q0Ml01KF61d>Sj$N&FM?g1W*jLc9~*eElEAPX}|AZ1V$8VNEL)oe~6A02Z6 z#Xy*wfq{o%4Uj=Jz!}y^5=0wDqC%i+K`zFNNi-5k`E@D*BqJM;*f1tMJ>pD`jv)}W ztSK-(z(m%7U{jNY6l*w{UlB6Xfp#N!VAfw4A0~m#d7!Kg0+e_jsknd?9WnW=X=i$l zZprJu>7}4;lD*+K@Amhf&;Q$elza7F1=j#Z%|0H^wR23KsLVdvAXECX)PHGoG?Ply zZ*HH7);&#jC+wq>@3tL}3ypDH@-WC>x1 zgZ)M~0#t&c7gkvLNm$frK{b;Q6?{M~=vV}c7*tKsfvw>a{G5IUe|Fkb|Nh}F>FVed z27aJ=T$q8i0pd_Xr7cJvZ)w|yLmpVYfb^l3xHat9T>7%5aK8Ut<@tfGtoqC1-+rF; z{t46N-FYhaef{H~gp>#DGfiG+Um30K9K7e8RZ!K1CEvff9I0S9u9l_!z$aXWE>jb(4DKNk(_Bc4jGB8*qpj1rI zlHfM~-V4?IvwAu|-hA$R%_^@J;4#hAB3M8STQo(mlJb z*tM0F-A@o^%b5TC@V&3kIzg5d00|(F01-d5`nH@_c+o3h@K@l*q&CHJUry`)1rriWjl;s8oy&R<-dxb03RJ@a zQbV%)4F)3p5Rr@*e8EV@7)b}{Uziw;l8xc4_it#GY-pWrapYZR$^kIkQOjqzk&prd on&}nbnI9HQ_-KML$PBU;2w=G%%&`F054ei~A7D8EQU)vw0EZm{UH||9 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6afd8f82d5639b774de0dfd418ae85322f4168dd b/fuzzers/corpora/commit_graph/6afd8f82d5639b774de0dfd418ae85322f4168dd new file mode 100644 index 0000000000000000000000000000000000000000..7840c31b1f688d1e8a05e335d9840cb26837f262 GIT binary patch literal 253 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&E<&Mj#7>*%}_$ zhc_3rrvlk51rTW-?_XOv9Gjc&fBe5=@9!1HUvBI^`?OoG-W?Y09y@n0x2{D E0FJ#cF8}}l literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6c64a9e26e0e1480bb5e60b7044ca6ce17104a80 b/fuzzers/corpora/commit_graph/6c64a9e26e0e1480bb5e60b7044ca6ce17104a80 new file mode 100644 index 0000000000000000000000000000000000000000..752046b9a63ff1d51ac6444cb06f0915f56ff244 GIT binary patch literal 1043 zcmZSJVPJ4}5Aa}QWM=U9ba4w{00WBzPZtOaOfmvVQZW-y4)^(24;CF#mA^U4f3dfMOubO#udKB^!{Mc8O6>C~bq}v88R0 d7_n&^q>dVC8)OEyv<(!7XMP4YaF%Ct0{~O~3JL%K literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6c850c17db130ca0152f7c75562fa191f7ef89de b/fuzzers/corpora/commit_graph/6c850c17db130ca0152f7c75562fa191f7ef89de new file mode 100644 index 0000000000000000000000000000000000000000..a7f693ba444468afdc10af323d335e474368ca23 GIT binary patch literal 41 dcmZ2w!N9;E1jMWU|Nqbae-#v5M*%=-1^}=K7PJ5W literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6c9afe4527371a2baf33c5e220e4ca21a3207f94 b/fuzzers/corpora/commit_graph/6c9afe4527371a2baf33c5e220e4ca21a3207f94 new file mode 100644 index 0000000000000000000000000000000000000000..d7b8ffca05ec4fc2e197a4b641b17b7004969a05 GIT binary patch literal 640 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ_TBiVr3V3-}qCKaRD>Hy?1QjS@HM&QCQ zx8kD-`yu}AXP_Ot1TY^^9)^+qh0ARqaeVHA$q{xR_ITg`nok?d1U2{n|NlTcxKS{p IV+fEB0F(9&7ytkO literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6ce3d40b0225923a7f4123a919b1c5d70841fad7 b/fuzzers/corpora/commit_graph/6ce3d40b0225923a7f4123a919b1c5d70841fad7 new file mode 100644 index 0000000000000000000000000000000000000000..3a2836b2cfcd82a0848d560d2abe0735e3909f99 GIT binary patch literal 268 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{ltKstNU}G;nJ@+;kb#C- sfkL=28&D1f7ohPufC^w3#Nq_<(J>cL41~E6_zZpkQVTK#&7}+s0E>+ve*gdg literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6cfd064aa6197813eb18f38df967ae4cdba9c6da b/fuzzers/corpora/commit_graph/6cfd064aa6197813eb18f38df967ae4cdba9c6da new file mode 100644 index 0000000000000000000000000000000000000000..51778d55c6a0b5e39bfa5eb3133ea24bbb7e3219 GIT binary patch literal 357 zcmZ3*z`($?iU9C*aRVv?0aJfZ7as_d#lqRe(XqMd{>T42_5y`i(J&j3j|+>zB-nw9 z$iW;yeQ9$SY6$^po&q2N1Ok2&Ys)1B%volIEPNfm+QBWtk|AJ=v(a^sd_g3899!ep mH>UMB8TES<+P*u29Y>DcAUy=_k7kPc&FwSM+Q+zyn*jj++&-iL literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6e6675676c53bcddc870e06605d2432e3429f224 b/fuzzers/corpora/commit_graph/6e6675676c53bcddc870e06605d2432e3429f224 new file mode 100644 index 0000000000000000000000000000000000000000..1ddebeff144475ad86dc806a2750ef0ace137cb8 GIT binary patch literal 616 zcmZQzU|?`|5Aa}QWM=SR1qVP;UJ@}MP(86Y{z*uAz&_LDb@r9f+Rnjy&RM-C1YY7& z0COj?c7xPm+8`|k`1;cT* zEbRwA;W8{&mnFJQd^L0Lg=+p;J)IwKKKDKH=b4l2o46m#B42U{?6_~&a76ef^Ebm3 zo5GBC;a=&UU03Yd%F6C12(x9(e}4Gh*JqtTr*ann2_TRF5kIv0wwzXY(JNr^SK!8^ zHpQsIVBA3j@+dDz7rtOZk%M{O0*~kY2f61Do@tl&Ir888z>^6Z3hh{%+on&yM0^M! zg%$%Vkb{ibfP6xj9jJz#L4d-?gapR?=M0C literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6f13d23c75a562eddefafe85e208e602832294e2 b/fuzzers/corpora/commit_graph/6f13d23c75a562eddefafe85e208e602832294e2 new file mode 100644 index 0000000000000000000000000000000000000000..49a53932feec13a04c68151521339e5f520d17b6 GIT binary patch literal 236 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bMZr$pX{Q1Z3dC%s@FP PW&|?H#SH8~%@7O#j)w)R literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/6fed59b0472927f5d2396d0ee4d7fd13579377ce b/fuzzers/corpora/commit_graph/6fed59b0472927f5d2396d0ee4d7fd13579377ce new file mode 100644 index 0000000000000000000000000000000000000000..6b3970fbf6fe4210c9501785fe52304396ce0683 GIT binary patch literal 751 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ_}qk?HbQRV`O6o>cA18hJh2EMTFVM@&e zn{8Y`NfxML9`8T0$8;mv<3OsB!1e3bK|DqV22~V?#DdizIfTW+*~KvgqLVcRLW4;5 z1_YaOmH=)eIDt|iAAvA8cB}`N0Lp{>#Gk3rV%BpO$l(EE4j>lso?{aIL}m8T2AR^A zrT)oFmi%4H@@4ZxYain-76y@WC1F{4M=yt1Cn2` zy5AVx{UF;>;))sW9;En!im{jjqYcDHjWcMf`o*9J*9&Hl?tXZX1N{MWKZ=*Y3K;(X G2hsrl0#xq+ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/71f7724196f9f8fcfe3ee0161a84893bb9c4ab11 b/fuzzers/corpora/commit_graph/71f7724196f9f8fcfe3ee0161a84893bb9c4ab11 new file mode 100644 index 0000000000000000000000000000000000000000..9e5c8ddb34e0d55e52a70f6e74ee1a29800eb4e5 GIT binary patch literal 795 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^=B#VW!i(?3c!NC8rEtFgUFG?KuB`gY;@^Ir_5KOd<=uHI_kI22pM;bL>@!JTXI~ku z?Hs)4oK;ZOg(cs=xg4orIIfnZ{lF(&hUMzAM7N2rX70UE%|ENB^W)9uzDNE%bCP`% z_hVV)OAdh@_w5>v2;XG>W|(4An9(lWE8Vl}id|b-+5H4zwv74D58wOxtP|*J?gEhe z85kr$#1E~$EvFS;^a_~%6}T~}O);u4_&-hn^EAHYCXi-2d9! imBuP`rCG0pKU1T{u;(n$EKu^{VOUWZGp*+S!b$+m6NXj* literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/7335ecb1d41e713bf3909adf5802b90e22bc1581 b/fuzzers/corpora/commit_graph/7335ecb1d41e713bf3909adf5802b90e22bc1581 new file mode 100644 index 0000000000000000000000000000000000000000..02e2fa6d16e9c44ff225d05d2255c63d67c40951 GIT binary patch literal 153 zcmZQzU|?`|5Aa}QWM=U9ba7)~U~d2lVFB--FkRlAr*hxd-#9?U>2oV1k8PQ0;i~(b z%cqJ?J6V#$= rzLXPpmONda^&;k*Maj#S!ukGpmFEY#vg$93fBSjX`zI_G3=Av)Te~?@ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/73afaa73175f461e1d19d5138e055c1649926dfe b/fuzzers/corpora/commit_graph/73afaa73175f461e1d19d5138e055c1649926dfe new file mode 100644 index 0000000000000000000000000000000000000000..0f45e0bdb4f1efc163543a03e18594d90a06c7b0 GIT binary patch literal 544 zcmZSJVPJ4}5Aa}QWM=U9ba7*V0E+}q7au4aC&dJmLB`BLJ~qq(6ekw50@dQfKxwJ~ zMxZIkZU?ckxg8`%tlL5A@VOl%2L#+e3=DNR1~Re4fEh40d^CV^K>N*{T^vKeOa|5z v2n{0H8xU*|3*;v(m>W%u9jFY3LE4xtKqLcyp6@Tm$hf@C=ic0gdxHT0mJAWe literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/73e2fcb45c4df90d19091056b235e7a317631a62 b/fuzzers/corpora/commit_graph/73e2fcb45c4df90d19091056b235e7a317631a62 new file mode 100644 index 0000000000000000000000000000000000000000..549eeb30619a4d2e15a4972adc7580377cb3242d GIT binary patch literal 150 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_R#<{SuC7g97DiN2G$e^tqGyH85mfBm;oC` Y7^{wCu2}-mT!?0vxr_`9K!k!B0K#SqN&o-= literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/741cb2d5ae11b0a9e0608b58ec7284d75129a1f2 b/fuzzers/corpora/commit_graph/741cb2d5ae11b0a9e0608b58ec7284d75129a1f2 new file mode 100644 index 0000000000000000000000000000000000000000..a16738d6fc28e85af1f5afd17d0752ae2b9709e0 GIT binary patch literal 69 XcmZ3r3I?vj!GC;UIs*d(nmj82{0cjJ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/7431bb0097a9bb52e1ceaaa8674a13cd3486a387 b/fuzzers/corpora/commit_graph/7431bb0097a9bb52e1ceaaa8674a13cd3486a387 new file mode 100644 index 0000000000000000000000000000000000000000..d681b26cd4725005f5537fa4b6d74c484743e6d5 GIT binary patch literal 1223 zcmZQzU|?`|5Aa}QWM=U9ba4Z6L4cb8W?*0hs(@lvAQKfQAWSj=n(6~ofB-BO&MuB2 z5I$=Pm}Uc#$e10-X98jnO$Y;(P!5nS;Q$&(0}M10WGbrJoIpN0<^qa=Ft;IkJiH

XW)b2XHK$j;(jcPe90lO6~uh_MfmEBJeX3LoW{P4Z6&pLs+xC=n~85kr$#1E~$EvFS;^a>dK6}T~}O);u4 z_&**1wH0PN$uv?r{CM-Z?~yJUry`)1rriWjl;s8 zoy&R<-dxb03RJ^l4+lFq@fq}(>705uwY(PFX%)r17l;I#B z?*ap`38ltiVb9KGJqT|uXio*2$Wj0#fPlyQ*H#Y4=BE1}|L@rQdxi0r8@taw?Ut)| S2gyU#uz0^bu>BhYGzb7))KG~4 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/75d51e413d3e916560dc0c2ee5092d2f4972aec1 b/fuzzers/corpora/commit_graph/75d51e413d3e916560dc0c2ee5092d2f4972aec1 new file mode 100644 index 0000000000000000000000000000000000000000..68f34e7ccf948f6a7a0324f1e7567b68c1e8e2c2 GIT binary patch literal 343 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&LpDPIM2Iy7LW4;51_YZBi;;nW z6{rS`S)gm=OyG8vhF};SW;b=>jBItpc*h0!Xe!VNM5{1{8ph zC^BFU!;Beo{{Npr27qWsb}O1cfBgUN1PyA4Di;4E8)JhN+P*uo%y_>9StkPkY66(S literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/763bf498dd847bd2b4af7b611199619bd428bea6 b/fuzzers/corpora/commit_graph/763bf498dd847bd2b4af7b611199619bd428bea6 new file mode 100644 index 0000000000000000000000000000000000000000..4c2893554c97bdf6c1aa68f20a0c18964ddcc5f9 GIT binary patch literal 1188 zcmZQzU|?`|5Aa}QWM=U9baC?xaCZg@fq;cSga$G^U3?&H77J$=#}EjcH3cdUp^#01 zN+2}uU~p!^s*$|`#Sk2v|AfGApo0Cl6d@UkO9@W#=|Ii6BpHEnAPfY^VL^$PfJU)c yf`eESY%W%V*&tGA+lL^>9vUJpdTE%9`51Mz{t!r#-y z2f`GwaCUJFfw0k}7#J9VBDgTfVT3R_>o49@@n literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/783bb14d68021061f592601607f40fe232ad17c4 b/fuzzers/corpora/commit_graph/783bb14d68021061f592601607f40fe232ad17c4 new file mode 100644 index 0000000000000000000000000000000000000000..3cfa562ac4a524707039a8668ef3e257a8038c85 GIT binary patch literal 210 ucmZQzU|?`|5Aa}QWM=U91acTG{XJcLKnwq$jspH>EgyfG|1%uDg|N)g0LH)Vho%>K04+Cih(dUI<7+jVA=mb s08t6#A^;1J$qM4a>_M|1E{SYL0;4#M*KR z0TY&4Aq!u}uXb>YSiC4;i?h*nWOKZqeqd_!=v+{7!0?;gg|4l?+N@qp7BTS!n!^M$ z2k23834!}xd%MzDg|0N~mGEb3v>5lC1=$6}-#LJUi1!~k_bER7dA`3KBjfTmpL=s# jg{#T$FBhi=%toA=TUa04YP8N1W` W{3;D+)%DI}uDA#k0Rm1KE(ZW3GfKq( literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/79661b8e529e2182d5c612faba9f26e32a122b78 b/fuzzers/corpora/commit_graph/79661b8e529e2182d5c612faba9f26e32a122b78 new file mode 100644 index 0000000000000000000000000000000000000000..75ebe29ce5344c116c7b7dfa44e7c33c01d12797 GIT binary patch literal 102 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{ltKstNU}G;nMe#*BsK#h Gi~|7Q;0CDx literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/7969143acb3334bffac46c6dfd96362c81644191 b/fuzzers/corpora/commit_graph/7969143acb3334bffac46c6dfd96362c81644191 new file mode 100644 index 0000000000000000000000000000000000000000..6ea2e668187a3a8bc9751b61cb43a3e3c78dacf9 GIT binary patch literal 418 zcmZQzU|?`|5Aa}QWM=U9ba4Z6VL-rdVr{vEfH}*okcF?~S39^xEM63_#o6e30Z;`9 z0|ATo(+^CI9-Rv+4j6uuyU+y^V+UdmGB77l4+Jv-SmhU z;n>`C|KtB1dx7Gl0g$O6%#4PKH3gr3R-hp;%m!o=!k{oh#^5+$0LFnCFcN$qF5(7J G+zbGd3?@AQ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/79d84866dc8c067508c02516b65c0e48cf689b56 b/fuzzers/corpora/commit_graph/79d84866dc8c067508c02516b65c0e48cf689b56 new file mode 100644 index 0000000000000000000000000000000000000000..3080da739b19e99bb589eb2783dc108b394aa429 GIT binary patch literal 83 zcmZQzU|?`|5Aa}QWM=U9ba7)~c>AA$LDd4t_5n%(0gHvRi(?3c&6)zCL8N*E10x%Z NtINW`zzF1kFaX=*2weaG literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/7b61f8f4a96e309bbe64ed82637fc81492a9652f b/fuzzers/corpora/commit_graph/7b61f8f4a96e309bbe64ed82637fc81492a9652f new file mode 100644 index 0000000000000000000000000000000000000000..28d93b7a1e135c889dafb4bad3fb526065abe98c GIT binary patch literal 2710 zcmZQzU|?`|5Aa}QWM=U9ba4Z6i3E&5b!eD{f#EDUfPs~PVJkD#ULYI92V#8&HXx0_ z55k)Z+EY0g82qQ{VUH~M3fW!OcfuMbC3=oAt0T!qPNFj$~bJP8g z|99;Dy~6m*jooLTcFWbfgXE!VSb&`wFZt2CNb_cL@(?>y!TObae_aT~;H z&GmX)FZJWZDIve!l%2@t_(Z+jyKcfmy;qsjHQ%a)#yRZ#n>Kf$mJkEOo}Nth=)GHV zV)8*A1O^@`{9u6y_ct&U;cTEZh>ZvX5F6Qh4M16NI8e`fs1|_C$74TOn!3S@#eV8q zfHVG>K)zvt#NS6^;tv*gAQ~QLgE0Qk!q13y>7S9v@Jl<>b974{F!3*Z9lzSa4H0^1 zsSRE@u{VGshkO9eYLI+{oPWRuq6H6y#lyg*U$AHJq+bReXjv!VHxY07x0UkpkEr~E zulxgMBY3J9E&u3Je~p%Z`0Iaf4hB#I16Tb~2TZY}xc{}cD~(m?O0!-Gf2Kx%>e0Rk2aXBWp12pdeYH$XW6#r#Cr literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/7b8dd3093efba07f7a4d3bab4b90b8f6e4f28bfb b/fuzzers/corpora/commit_graph/7b8dd3093efba07f7a4d3bab4b90b8f6e4f28bfb new file mode 100644 index 0000000000000000000000000000000000000000..3e686e9d55c16b60595611c106d3dc1c57100f55 GIT binary patch literal 1049 zcmZQzU|?`|5Aa}QWM=R;^>mqu3K$qzfeP3NVMYc9cAy#}Fh5WkG6r%n0MIlBN-@v~ z7AOY!0FK>|*vR5YYz77iKgV}m5(4+X_I9PQ3SDW|E8)-7Xff_N3sl7c#5_PO;{8YV zaw%)=6+yoeAQu^+xgBmdPz^C`((OO9@Or?7bq`Z&CfID_0@}h-0CEm5378M476Svl ziXjG7w+5F4K5^uDhq2MZ3Lfu3d$7hIP@GU0;tD@=obiV}{DAQcjN@avk?g?Wgt?QT i?dYx}n0J6aA|l^_)BwW_-E?exT>i(Me$o98@-6^jpJs*t literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/7cc771aab0f3be7730881a46d952ae0a06958201 b/fuzzers/corpora/commit_graph/7cc771aab0f3be7730881a46d952ae0a06958201 new file mode 100644 index 0000000000000000000000000000000000000000..ba94bfe7ddaf9940687d745ea72c43c472e6d630 GIT binary patch literal 740 zcmZQzU|?`|5Aa}QWM=aBba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&ASN4NAa6N;CuY zGBPk2!yE#mfnp43*a5@`0hsvz{~G`Q{r>~!!^BCUAto~1fYM}9F#DK+y0K!Q8(%VT zGW_|^z`z1jgTNdhwh4mIz`zQWN5=d>K2EIK&!;tYmYJW!+cf5@SNwOYltl|T?&-;7 zkKVf_CnldY?M%_bFbd3;2OZF*~i1Vc8&?m^@M1k rLqGr=QY#UFfx!ss{ss_@>~;_vr`tht$nFR7VX2tG-xQII!NLpxB#Bpm literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/7d177f4207de78d50df2493a3bc07f2cd578b363 b/fuzzers/corpora/commit_graph/7d177f4207de78d50df2493a3bc07f2cd578b363 new file mode 100644 index 0000000000000000000000000000000000000000..a936354f3a29e40cf62369dd6a007be5ee134d28 GIT binary patch literal 82 zcmZQzU|?`|5Aa}QWM=U9Y-QxJEwe3LeV=prR7Ri-2#8KQS(3x#*CZ^Vx8Ag68oP`% d1B=CfAYfo%VE`#&+yx@)PBAg)F)=WN000qd69oVO literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/7d2df075f3e73ea9809c31586c37ece0f568b7fa b/fuzzers/corpora/commit_graph/7d2df075f3e73ea9809c31586c37ece0f568b7fa new file mode 100644 index 0000000000000000000000000000000000000000..897276b67630fda7a1920eaf89b3da8cc01142cd GIT binary patch literal 362 zcmZQzU|?`|5Aa}QWM=U9y#UAoVIW}f ze)@r_(W7%g#R0=_au>QlV(dW7K?Mvl3mGs0IUvl8hLP0}#byMmLdBeDd~|sXJ}b}& UT$l|gM+k$$2pvO2fD$kO07r}w*Z=?k literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/7e4dfdae52be18cf95555c2eb1f54af7f69c6dde b/fuzzers/corpora/commit_graph/7e4dfdae52be18cf95555c2eb1f54af7f69c6dde new file mode 100644 index 0000000000000000000000000000000000000000..0f6d9768432e01c591562a2ca7f48adb5b400ff1 GIT binary patch literal 217 zcmZQzU|?`|5Aa}QWCpS@0c#4T722E_nv#(IKi0zL`vV&tR>6uyomW`QS!2-aK8Ut<@tfGtoqC1 i-+rF;{t46N-FfTmE5l{nmL*PPd3AN>UWPw%3=9D6=QEoC literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/7eafedf7e7f20e86ecdf9ba51febf8492bdbc1f1 b/fuzzers/corpora/commit_graph/7eafedf7e7f20e86ecdf9ba51febf8492bdbc1f1 new file mode 100644 index 0000000000000000000000000000000000000000..ae5f7c56cdef409fa04ddd855133e8ed3f7c7d21 GIT binary patch literal 593 zcmZ3*$N&a1t5yMNRwT>@WaGkOFbQ^`B62VXP+!{Ig<3*Dnx_Cr0D*wt#M*KR0dtmF zAq!VW#5=gXwqyv{;%sysBwrB89>>=B^^IxWO-B75g|_dGEHmCOnRVD{{-&=Cd|>?` zGYMdrvuWf0IE4FO$FFv9ivYVH-Ay1j(7=9vps{$dYCoUW)LCYJ4sX+#uU_%rtx^^( z;JBwJlRbLxmYkS;*0eJ{N4Mm4-}F+@Hp$-bn|J&B&*%SbKF+;*uYzj;qh=ou=h`_Y mPgG_fZICH_S?a$uI+`i!H@DA3Yae50_W%z@Zf>9pxETPd5LLJU literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/7ef1829a378d66b1dd70a767729127a0dc5edcae b/fuzzers/corpora/commit_graph/7ef1829a378d66b1dd70a767729127a0dc5edcae new file mode 100644 index 0000000000000000000000000000000000000000..e5d7355917579f02ff68fa8be2443c6b9eb6a336 GIT binary patch literal 4 LcmcCzuw?)M0dfF) literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/80b7d2b9d7e8c8fd7ae239b8d307b592f97ee000 b/fuzzers/corpora/commit_graph/80b7d2b9d7e8c8fd7ae239b8d307b592f97ee000 new file mode 100644 index 0000000000000000000000000000000000000000..58ddc12d3df48d9fbab5f52a123a9ca2dc22b6eb GIT binary patch literal 2303 zcmWe&U|?`|5Aa}QWM=SRMJ8adA*hjo9cU3T7~vXE7b3NA0M&soso+0R;44Dabf66g z9x4kafz1(&KtUw@4BkZ4qk(Rd90o-S@+#Xt#!wG51?>VPV^ zNx;lF)baquv0+}II1&cM4kr{Nr8k&M85k^puJ!;b00I^ZXBWp12%GgHkY+D{a5%hQ z9thfZp^MvKyVhKrL4Sl835c@rio5_biYPaumo`5$`{8?o)jD^L&3f zM#klBKKJIf$XEV{jY&W`Zm1>+q_}~`)ABnnV!m0Fylg3)56Ts&4)p=*1p;J;5(-Nk z;a80<>_B2jVFzLp3_lZK_+fF@z=fX)w(vtrfF(#ve2vAfhJpsRI~+#^AspVH7!RHsa6=(noFm&PKH758hk(u1_l-jXBWm02%9wpLW4;51_T?# z(nRH=^LT**$e4i*D1eNA{Qtl5|Ih#b|APeCp%~792rNM3162V5i~o_0vB7_gE*6zd Xo_~Dah3K`8EHmCOnRVD{{-&=0C(1tE literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8226846e9b092561f85cc2956ab89d8cc1ae61e0 b/fuzzers/corpora/commit_graph/8226846e9b092561f85cc2956ab89d8cc1ae61e0 new file mode 100644 index 0000000000000000000000000000000000000000..80d1cd91c53ddcdd0e8c272e3284acb246786c5a GIT binary patch literal 197 zcmdn81rzYtmf04ryU)3Ns_3+nB{@ufb#I;@U*9r~T}ImNM95~r)>qR@te>qYX8;0c z_W%z@MrH8-N5c;Qu#bR6*1bVdy^MO+!-IfW*ebB*K2E?*IQ)o!tR^ C00^A` literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/82603febce83d95adf68b85cabf15d43ca0c4ee9 b/fuzzers/corpora/commit_graph/82603febce83d95adf68b85cabf15d43ca0c4ee9 new file mode 100644 index 0000000000000000000000000000000000000000..d828b05afcafd018a3599dacd6b7eb46666975ae GIT binary patch literal 532 zcmZQzU|?`|5Aa}QWM=U9RO5DW0}6nEg}-`aJ~ajAJ7Ca2AK#4 zU_n)cBuo(@8fX9u6teTyJpZjGGXMaY-wUw- literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/827f0826cc4156e19b4c4938bec74e38de62fe9c b/fuzzers/corpora/commit_graph/827f0826cc4156e19b4c4938bec74e38de62fe9c new file mode 100644 index 0000000000000000000000000000000000000000..a391d62a97ff7587176a72e40cc6c496d924ded6 GIT binary patch literal 346 zcmZQzU|?`|5Aa}QWX}9_xl8&+k`nKqdqLaZoVinV>T=2y27gZ%H=r62umG}sAWRmE zMb0jcArKBK>43^5k;eyAkAXw*19bKLKr=vC3`)cJ=rmB8fyMs_h=K!jv%q|O)`JwN M{{s>*)1i!w0BSKRwg3PC literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8486397ff8d1156249676c19b419a7758ff53f9a b/fuzzers/corpora/commit_graph/8486397ff8d1156249676c19b419a7758ff53f9a new file mode 100644 index 0000000000000000000000000000000000000000..dac9bbe4cee3b67ed8da1c1d7d54b56bc3cf4bc2 GIT binary patch literal 1361 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^=B#VW!i(?3c! z%>J0Arz4O17|TXfK;#+fCMJKihuig z*83++mv`r>-1qg52gzW;AoH+ckVzc0!9Zg{CZn3q3FM<=E|{WCn>K-%Kwt}@fPP7V Ou?W+QKqVlI?jZo%k`k-{ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/84e629bc7416039f1feb81fa9168d7c1ee3141c2 b/fuzzers/corpora/commit_graph/84e629bc7416039f1feb81fa9168d7c1ee3141c2 new file mode 100644 index 0000000000000000000000000000000000000000..8ae4e395cb805141c9a63b097537b146a0b495c6 GIT binary patch literal 539 zcmZQzU|?`|5Aa}QWM=U9baC?xaCc?`iUEOzKZ7R2|NsAi3{Mvyh!_imf|8NQJY-X# z;s}j97@S#L977=DtSJb6>j6gXMh5)+w kA86H{o=o=Wy<2i(@>$c)^c>CW204#n|D*Vm1>`MO0MncB)&Kwi literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/84e885752179076fb38739ca7bc4345716bee56a b/fuzzers/corpora/commit_graph/84e885752179076fb38739ca7bc4345716bee56a new file mode 100644 index 0000000000000000000000000000000000000000..dd0c42692e134e11a51d1d4938fd820f136c7b89 GIT binary patch literal 217 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6ox763`}4SdjptqW?*0h hGVoxalrD-qNIw=VfGh?!8ykV*SZ1)r9EMmF0swW639|qI literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/859ef05494c8070057810b5c20df00fc81f81cf5 b/fuzzers/corpora/commit_graph/859ef05494c8070057810b5c20df00fc81f81cf5 new file mode 100644 index 0000000000000000000000000000000000000000..2e3f29900478095dfa605c2f995cefd633ae8803 GIT binary patch literal 2796 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC?*&ARia%dG5xGoML ziy;1w06^v3P#pjE^Q`wzm@e>ztF!nzIXK+I8 z1ko_e#lWBf20$?q08ks;3ox&s(+muZKvhu83S{EKY(P1D7!nSo`4i?p7!7hTK1V}M zH)3E1D#V6SA_J%f2B7gyP8uA@^oO2Y(IXFuuir9_T}ImNM95~r)>qR@te>qYcd49z z-T1}#X$Sd?;+ADN-1#+ajidFqfT9?M7AuRAmo0_!{qHKz4|HYKUxqD#n?lmJbMT&X zRzX!4mVEz)Bg}!x8{MH0KFE3Sv;|6IxY8CP+9*#y|A83{DO|v8Y~I@m^&i4+pj)x~ zgXH`ROV2QRH2*^41RA?0So1C@Kchqdhz|ug;{_;>B8QrOK)Q!W{#}nf|5}XZUtk=L q=3o4EFQ{IItFoghhDEB@z;aHu^Rx0ms*bi literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/859fe592f33abc1d959c0e73ecd6cd4bffe23a97 b/fuzzers/corpora/commit_graph/859fe592f33abc1d959c0e73ecd6cd4bffe23a97 new file mode 100644 index 0000000000000000000000000000000000000000..5289c8e1cf5e10ae5eed45bda873eca1c7619c68 GIT binary patch literal 345 zcmZQzU|?`|5Aa}QWM=Sx#k4Z-z=;^9^^v~*4Sc*(LMs&hLjh132t0-<^>l#<5KA&b n6x!oZ50WMo<1h-lFzxJzINPx2EQ3XYr;88J`d_pE|7QRIHuf4= literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/860da5e8a468805b76a44b9ac99b4575be16ea15 b/fuzzers/corpora/commit_graph/860da5e8a468805b76a44b9ac99b4575be16ea15 new file mode 100644 index 0000000000000000000000000000000000000000..c8b03da24aa5fc5c202cb9a185d04cd8b0b77f01 GIT binary patch literal 338 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ@7lWIUEj9_J8k`Y7_!t6jbgfIgSP!S9> zIR9s0;A7wb3ZY^LG(JdP0t6UXfNEiw705=$5M$Zk#)J60B;ZMHip%?gff^9NA^{j? GtPB7Mzze?s literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/865e415745cead02a826f058a5ee49099bdf9562 b/fuzzers/corpora/commit_graph/865e415745cead02a826f058a5ee49099bdf9562 new file mode 100644 index 0000000000000000000000000000000000000000..a4ce6588338e25680462a429b401fb4eb9d60237 GIT binary patch literal 417 zcmZQzU|?`|5Aa}QWM=U9ba7)~Pz8!GSOD2RAO-^ii-og`V+e%JngXFgB!2^lWCP;| z;mrl@sX!)60Yd|jV&L)qg(L(L0SRs8aBOb6|MCBhy}wr&ez~#x?9*;J)pqv+pezUj z0gLy`1KYnbR5Es_`S?{D&8qtuI;VFYbHzoV96Lk}9;dZ4f(>C{ZvfM*KoX2upfrpR nq#^Ex(J=RO5$}FunEUH-xZjU7_cI`Z7U+vWAXvX{J&*+e?ciDD literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/878bfce051a9c7462847d4e99b7e926dc821b7b8 b/fuzzers/corpora/commit_graph/878bfce051a9c7462847d4e99b7e926dc821b7b8 new file mode 100644 index 0000000000000000000000000000000000000000..efb0bc5514ed852bd9a1b9a2e30089eec8b226fa GIT binary patch literal 95 zcmZQzU|?`|5Aa}QWM=R;1#+0M;{X5u0LB0Q|Ns9pkY+~0f8ZiOK?XJiW(P9a0evG3 Axc~qF literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/880492e4dc7259577c227bb4f075d7165e875c29 b/fuzzers/corpora/commit_graph/880492e4dc7259577c227bb4f075d7165e875c29 new file mode 100644 index 0000000000000000000000000000000000000000..c977dffaf9075e172c725686c05cf1d6e5091206 GIT binary patch literal 150 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_K9YLaGYHnLm({H6bKC>*&7%b@)2C}SR5d2 LoDK-hoL~U}9?k~o literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/88b7de1bd1c96454a1350286d115c0ee368511f9 b/fuzzers/corpora/commit_graph/88b7de1bd1c96454a1350286d115c0ee368511f9 new file mode 100644 index 0000000000000000000000000000000000000000..7261eec17cb618e440112c42ae7a31a73135c4c7 GIT binary patch literal 120 zcmZQzU|?`|5Aa}QWM`r65^Tl Y{t46N-3*LCTNs$Yh{4&#k%=J$0CMCpU;qFB literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/896268e4a5775b7ce33923ac6daeb0810420c55b b/fuzzers/corpora/commit_graph/896268e4a5775b7ce33923ac6daeb0810420c55b new file mode 100644 index 0000000000000000000000000000000000000000..0897bdad0266beb4717a3041b42a15216d57b6a8 GIT binary patch literal 3274 zcmeHIJ5s|y43!}vfpCbllyspA5Dy_U%$R~Ba107cZonPFK{x@2prWN=%#(LlD`(d~ z#%`EsMwa&NN3x{Vek5clNe;jMNPNI*eSeE1DBCuYHCQi>Fl~A1i6($6IW{rH2F){! z`{q-e$-GJL@CA()tMux@=;KEt`8#>`I%{X;VQIupkDTlIMfOQF2BdhZbd9^X)yi0` z1cPnSVN>fmmSz3GIol*J%lnG_0AkeVigUyyb+t)v3_^>nG0=8pr3lQi@ngqa#@^hy zn9GUywiGue!2t39*EuK!#RUiQ#B!T^gr!|`m-Cdq zOtL0aq{bRs*EZZ7L5AvGoR3aCCwghIC-Mu8korgIGrCU%Ivfu$SYfRCpE~rE_t~3v zTKVUnk7cC`g=;bYc71D8^Ig~M-w&>V4!I6%25I6<`C8%}Fv;Ea4SoN9ATGOgZN~lP gfX|diRq6Zp1Hq`Fp?X(5=T)@;d_Mg9(OdtgUw+{tod5s; literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8978f8da89f9652878edabad164f5513ef508f27 b/fuzzers/corpora/commit_graph/8978f8da89f9652878edabad164f5513ef508f27 new file mode 100644 index 0000000000000000000000000000000000000000..0dd9ba4927678765fe853040c8f8fb42a954bd99 GIT binary patch literal 244 zcmZQzU|?`|5Aa}QWM=Sx#k4Z-z=;^9^^v~*4Sc*(LMs&JF|b%TyEujbl>x!G6bKC? z!8-RUfb_aDFn9umt2h}LIDj-5|3?6r4kf5no-S@sAv1qZ7as^4V%4AjARa4{RqPEv yp^EWP9NsSv1ns-f#cdF)HP`EHz0{8rr-b}^Q+5`BG_kz7eacSERM+N}XNi@6w literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/89a6525b7db0e6ec211a484efd2880abef928d4e b/fuzzers/corpora/commit_graph/89a6525b7db0e6ec211a484efd2880abef928d4e new file mode 100644 index 0000000000000000000000000000000000000000..e5dd1cdf809a9a706588f461cc7b490cf969932c GIT binary patch literal 152 zcmZQzU|?`|5Aa}QWM=U9baC?xaCZg@fq)5+?*n17SU9^lhCtY?DGbaImI8z#g1k-y JKsIL08UQL|CP4rI literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8ae86cba2bba6664fc5eb97be8e9777b8825d823 b/fuzzers/corpora/commit_graph/8ae86cba2bba6664fc5eb97be8e9777b8825d823 new file mode 100644 index 0000000000000000000000000000000000000000..04a4aa532dd80287a71cdd18cb6ea966c12a5c0a GIT binary patch literal 506 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LEt_yKpR8R9Sjki0v15qd?1#wSU9>khd|iaNCj+y r#EY?}Ak?xqAlT?EZlC}N^Wea|KyhL*P$>lb{{>?aMbpE6Xlw%jsv}`u literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8b845fbd2aa14e4f83c4dbc8b4b0b54d06482acd b/fuzzers/corpora/commit_graph/8b845fbd2aa14e4f83c4dbc8b4b0b54d06482acd new file mode 100644 index 0000000000000000000000000000000000000000..c711793c8fc62d6bcc8e66201e9c352afedcfe60 GIT binary patch literal 273 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBI^i_JJ^2ESy~&Lm+I{6cDWd=CC(_XrNv%WW9_) zF>IKLA%cMkCDoDYhTy-|n78$e|sfax0s K26mu090LGDRu2FG literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8c4121e6ce5956cfa408b980f16d276f456374dc b/fuzzers/corpora/commit_graph/8c4121e6ce5956cfa408b980f16d276f456374dc new file mode 100644 index 0000000000000000000000000000000000000000..1ba18917fe66cbe8392badac54ff588d528964e5 GIT binary patch literal 152 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBIsa_JJ^2ESw<>WRelcLBs#SfORH{I1^AEAYC_W&~2LK{53jP29 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8cb6a5b8ab41e3d27668d5735b5c09ff1f2eab65 b/fuzzers/corpora/commit_graph/8cb6a5b8ab41e3d27668d5735b5c09ff1f2eab65 new file mode 100644 index 0000000000000000000000000000000000000000..e23d11256a10ff28949129d607ab7415c934f795 GIT binary patch literal 403 zcmZQzU|?`|5Aa}QWM=Sx#k4Z-z=;^9^$ZM*KyhL*P$?EbQ1>@905pT39*~-!|H0~j zOm;NP0p!E*+r|kd{3lZSI)P%`1waA_BtXOut-dX%6<+iT82lBuF{w>4sxWvOP?#C2 zhQs^ifs=nZt^XHHNGvs03ww4h>p^&PL3=7t4GUBakN2;w9FEOR_dovMvG?~1<1aUM zpMBabSMLszFJPDsbcMi<`*saSgl{r`Gfc55%xD+xmG0Sf#jdTa?0$kUTgLq7hwpuT OhU&I?%oP`b`ndst@mhEQ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8d80a70ffd362a89b88663e27f11e8ab69b70c1b b/fuzzers/corpora/commit_graph/8d80a70ffd362a89b88663e27f11e8ab69b70c1b new file mode 100644 index 0000000000000000000000000000000000000000..02f765ea2847db2efd3b56cd1a0caa8ed7459880 GIT binary patch literal 274 zcmZQzU|?`|5Aa}QWCpUpfV~0Az(%pAAVl#hL?|2dEahc={O>Edj~6g7%-{4C0JQW7 A^#A|> literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8db603c1720b3680047f831f2ea9862567a7cdc4 b/fuzzers/corpora/commit_graph/8db603c1720b3680047f831f2ea9862567a7cdc4 new file mode 100644 index 0000000000000000000000000000000000000000..d02cb03541aa51559bdf81575f9046768c51984c GIT binary patch literal 1009 zcmZQzU=Vk95Aa}QWM=U9ba7*V01F`72f}2raCUJFfv{Oqpz=V9y#d0uVbGv6*sW3) zE#SDPCzCyT@0OgHeAcuxJx90Xb>H+-&^F56@SAu0`_Je9Z9dMudar_O0HbCf59iuB zCQnpmA8n8+eOcNj_e&qQk<<1VMkUIV8c7X&ZiEj}uFP0|-kX?Ib6XEvOjD96(1A70IB8=7M5iVzNlyZ|0JFe)jhexrZ!a zK{E^kRGdDyGV<7#*%q$4&$)c6=(Lk1IZS?aZ=N4t-!hF|hAQb7l3RU{GP8>tEC&PK K#sba77LEXOcPyI# literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8dd40b2d27c7dd4b986c35d87f826da287c09c4c b/fuzzers/corpora/commit_graph/8dd40b2d27c7dd4b986c35d87f826da287c09c4c new file mode 100644 index 0000000000000000000000000000000000000000..11aa235b17a854e2c3dc7b27e3728d8ff607b828 GIT binary patch literal 229 zcmZQzU|?`|5Aa}QWM=U9ba4Z6$p=^rvIH9H12K`s!r8?!1jzpX|9=mVVohNv05XxR jBU?WQ&=4?Q|J>{e)8*ZHD))W;szL=%SgMO2-z&y`f7TK^|KY_E|v4Io4)uy?I52~+_DUZJHMu_akTyxP!yxk zVr5bCvZZjo|6S$zfv&9j%i`aDp7s6-)8*ZHD))W;c@vn1!jIfdT48kU9X@8EG8= literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8f2dff1a30ee28e5985cb9379828aea5658d5849 b/fuzzers/corpora/commit_graph/8f2dff1a30ee28e5985cb9379828aea5658d5849 new file mode 100644 index 0000000000000000000000000000000000000000..b7220c3cbca63bb432c724449965e3c99cba7fca GIT binary patch literal 222 zcmZQzU|?`|5Aa}QWM-HZvha2MY6rK7#ft*AI2&Cr0Lpg{#T$FBhi=%toA=TUa04YP8N1W` c{3;D+)%^^e(>ss3;v!Ix9qbfNAPbDk0TMq=CIA2c literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/8f7d18cdd6e605b85784ada14571fd5e5a184f2a b/fuzzers/corpora/commit_graph/8f7d18cdd6e605b85784ada14571fd5e5a184f2a new file mode 100644 index 0000000000000000000000000000000000000000..80fe175ba1c33d82eb1afaf0123a709e38ec0d12 GIT binary patch literal 1125 zcmZQzU|?`|5Aa}QWM=U9ba4Z6fuIEp7}$YKe3%0$j~z4N5XVsOfJHx02qcQCmJ`TF z#vpfL(W?LvBi(+Gefa!}O%99wP&bioKayEMCWwdXKV-kd*jzw0AdIA!eEW%s|8H3) zEk{DX{C7(^m3TAdndTeQ%*oWUA7Kv3{>K(K2r(9%@roI434e4O?m+=8kG Yi~Z!s9|hru=?>EUk7Ndr3FARn043cYcmMzZ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/903ae52f0ac9af8348038b12f9259741b0de42f1 b/fuzzers/corpora/commit_graph/903ae52f0ac9af8348038b12f9259741b0de42f1 new file mode 100644 index 0000000000000000000000000000000000000000..da8c2209c627dd81ad3a7a10bb5779ef2c4331b8 GIT binary patch literal 1198 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2EF4{&Lm+G zSSJSq8TKQmofa@47#^7R!rV-T{Rsc!^Z#GuG=wYtu>Jpyd literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/9119e331f59e9337d419739c324f49d1bd62c8bf b/fuzzers/corpora/commit_graph/9119e331f59e9337d419739c324f49d1bd62c8bf new file mode 100644 index 0000000000000000000000000000000000000000..fc3a6963cd22d217eb0a9da319b002e161a434af GIT binary patch literal 3311 zcmezW|E8+5djKPkZJBN1s{5SFr;1KHS(3x#SNG=m@%1g!*kz>MPK0b0Y<)Go#QNEa za+k{a*DYRrpH{=(d+u%H1Y`aaDSc0~mMp*XBIcV#$;+0)`Tlp6=La(I8#6HQGZ2Tv zC-^!24F2r2ss8=LUDDOjDR5(4S@oC2zx_Px{S&6kyYp1;`})T}2`LZQXOz6ozA{?d zIe5=GtDve2OTK?|Ia0xJTrErcfls&$%hhFxZWCY4+N`r z$Fj(m90EJ;+cg{!zRCQ}Af@}Jmx8uQ_J-fQ+uwga|8MhA?$vu0Tmu+2`*=9l&M|qS zGW%$QOzF!~|E1B_y?0AaOg?McnVzFt@&--(ksk4bI{d6g(?9*nKQhz*Tbg75SeZSP^54K# zUwER=cn}p|R*-7k60I61tNtOX{#`(@{xuw?^)H_G4=*f#5u%4u{sXq(hFSeLVC_G6 pVL~|mN6UXuHw09Ey)mu3$*A9>(DvPtWybp@vkp7W-}Du$AOI18TrvOv literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/91d54d03b0917314ea1d67a70690df9247dd08d2 b/fuzzers/corpora/commit_graph/91d54d03b0917314ea1d67a70690df9247dd08d2 new file mode 100644 index 0000000000000000000000000000000000000000..290da4da4e7c1f3e4f5595b0f3552d5866e060ae GIT binary patch literal 536 zcmZQzU|?`|5Aa}QWM*Iive7X_#^1A*k;k^ows6&b&gD}@r=2YE^^boNQXa6+GFwp(1NbWbHv-`OjKrVq{22jue0M>?OL;wH) literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/922da3b96725bfd0e3f6ce119f1e2249d53f9086 b/fuzzers/corpora/commit_graph/922da3b96725bfd0e3f6ce119f1e2249d53f9086 new file mode 100644 index 0000000000000000000000000000000000000000..c3bb009f399dae695a388ee6b081191ed3a48453 GIT binary patch literal 542 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6ox763`}4Sdjpt)X=Y$! zU??>X3ww4h>%sdavkp7W-}Kdg69fPiGLnyhT6IzMgX|}S!ES>S{~_QRTz~`yF)oLi dPa(xYl&hd&3Z{q(SE9oY$$A$C24P_Q0|2hVZSVj9 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/9277561e0524cccba2f851970b0d88ec4f4d3f5e b/fuzzers/corpora/commit_graph/9277561e0524cccba2f851970b0d88ec4f4d3f5e new file mode 100644 index 0000000000000000000000000000000000000000..07d1da19be760734640c309cf0dcb991e11b0aec GIT binary patch literal 1304 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&F^tz%PUtg{((} z^s@jJu!0nEATW>#;(^Hqm^depkB+&3Vj#?oj_XhWSQg|ngi4?g1km1oyE>pvAQz%I z6YLjyyI&UQ2;?v%-+tr}XW#(ykb=Av1%SLhn*K;gf50fBV)}=sKUDis;|~};BxbW; lUx0cbhTt|B*%EX%b<+Q22ITw;O4_g_jgkUOo#t=)3IJ;Nhq(X% literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/92a4d571804026b7bbe957396185e079e756b894 b/fuzzers/corpora/commit_graph/92a4d571804026b7bbe957396185e079e756b894 new file mode 100644 index 0000000000000000000000000000000000000000..63b98b3b43faddd9ec2e37cd4e66848873f347b2 GIT binary patch literal 334 zcmZQDWngf25Aa}QWM=U9ba6Yt%m4xwK(-H<1ti$u_(6DcL3=8Y%TfT5Q z>Hf$6JNEuwVfN+5?z2z3?q}$n-g(Rw7lBIH zp=vmQYJ&E$F%YuAm<$U*&S!vFaG{IaAXaOx7f^r^fmwk}FlGVMM7dW5>Rtwht~6Gm ME6sW({EUqA0B2EQNB{r; literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/931224cc80168fd362a360d99bab813ed7bbf8ce b/fuzzers/corpora/commit_graph/931224cc80168fd362a360d99bab813ed7bbf8ce new file mode 100644 index 0000000000000000000000000000000000000000..df27b369676c913b7db3fcad9f4172638e00fb63 GIT binary patch literal 127 wcmZQzU|?`|5Aa}QWM=SRg#=b0u~)4Esse-m2mlizihcuE#R_5p4P*n80OJfHO#lD@ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/936ea5dad3bf023c552aa0bbeea8f7f66a11612c b/fuzzers/corpora/commit_graph/936ea5dad3bf023c552aa0bbeea8f7f66a11612c new file mode 100644 index 0000000000000000000000000000000000000000..847b537acb1f403d5bba7fcdf141b6147ea5a9e2 GIT binary patch literal 454 zcmeyb#{dM*?g1W*jLZ!Fp4={OAORq-@b`4N2w}2VIJ-E8K-jD)5E_GwW?+Pf+5P_x mWc()xFic=DLLpiZQ6zkN*JFzZV7o literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/93aa4e0b1864933dce0abc0df69fe3d261f117f2 b/fuzzers/corpora/commit_graph/93aa4e0b1864933dce0abc0df69fe3d261f117f2 new file mode 100644 index 0000000000000000000000000000000000000000..ac830ca5fd1f76b72becb33477933b5e535dcc64 GIT binary patch literal 146 zcmZQzU}Sc75Aa}QWM=Sx#k4Z-z=;^9^^v~*4Sc*(LMs&JF|b%TyEuk0fWfyE5VaM; kAwa5uEZ_Df`A2(?E_)5SeykiI2c$b81tV<>3f>Rzz`3T;bUk5 zVi1jrnf&VBJU_m^Wg5GTwA+c0&4R73rkDJ`Y5ilQD*Ppe@E8Gr!2=iW9> QFb46#P61i73IzBV07$VYF#rGn literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/9443fd3468bcc0bc3ff8dfe765225f045ab43d0a b/fuzzers/corpora/commit_graph/9443fd3468bcc0bc3ff8dfe765225f045ab43d0a new file mode 100644 index 0000000000000000000000000000000000000000..d1667ca74a92173452d7f6a694a7e6668e05c940 GIT binary patch literal 225 zcmZQzU|?`|5Aa}QWM=U9ba4Z62>?wj@&ynv0l$g0jGBEsoD2*C_rLabrLhWKY1S*@&(vr!?l}w8$^*n4KrG_@N6vkU4}YHTFUQEZ xyv^s{+!p!D|FAI$D8~)8L&DGT9hU?abH4rm{~c;p+jmEn8Sj_OIy`^VR{-kuI9mV! literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/9624c26cefb5804b7906147d262e81ee4000b6d6 b/fuzzers/corpora/commit_graph/9624c26cefb5804b7906147d262e81ee4000b6d6 new file mode 100644 index 0000000000000000000000000000000000000000..4c1883146bde95b12822b3e2da8f57b6b7c026be GIT binary patch literal 2327 zcmZSh|DVCxJ-~yJk(t5Y)5VQ}nE?hYfP5bq2TZeAIJ-E8K!jLRz%(0>M8@nuJ`)gw zXhImM1P{25D#tY;O5XTNxn9*e-JcE{m43b1xNwuR(X}c5$*AhUJY<_WfFcy*01PvL zMuJR573T!<(J>cL41~E2ffz)CF}f-cAG=DBj#o%JVJ47C+X5{*u9l_!z$aXW%OPt*q>Rf-qag{O5=7eSHR0#qdL` zZ_8Ec7d4QPBM`KMV+mfv|1^Ub2Hys^TZ_I1h5;)$=npCUukNjUu`wFZt26?-2;?dVW&_fA@OvO&U;qFQ C7Cq$v literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/9928e516b85e22fbad58d562d3b7e814d9ce812d b/fuzzers/corpora/commit_graph/9928e516b85e22fbad58d562d3b7e814d9ce812d new file mode 100644 index 0000000000000000000000000000000000000000..d1e5a0412224d8bab4f631deb9a62b5ef59cc272 GIT binary patch literal 213 zcmZQzU|?`|5Aa}QWM=U9ba4Z6A%Mlg*~KyBKZsM$2PA;l9z=lgv>Nu_b8j0b81tV< z>3f>BWck`VFJit~l)P*yobP{Ed48ZPtNyYAkX|6zou_i&*FXMANO^#cX|gvq@SnN> E00&!i8vp8aHoPeZ?!5$zp%$Ooa;20Dsa|0?0S`I_UA*g6+81vSa*HN_p{zG9YRPo#?6mI3jYOXSdsWERvC2$AfTbN+O zP^>r1aez39L-+_sgD~#ge~kQuMSg=35}#%H`LfnWclAtTvTAhFPF-_*R{Cw~7^@?O zs%Wt(T{$b>+;zlGcs$ox@0cEH&AwhCpI=hHTX=ov%5$(Ku|71W)oFnt+_QV;qjb%w zCkI^Qb^i(3vt;+_Tgs;?L=}ttl5EHfx@pF#XvWgY10uEYX`N711ZYQ<&I}P0hL5tm zc)G9n%S8C*?4{ThM(q64S78)z2!h2Q6w26mSy-x_PTwHci+%H2y@(y zzjpj(TK%8!7w58H)&D*za-QjP&xHA<`+e1ZAIU3;NF5S` zwre;dj4%UXHqag)kogP@EEdi#jv){>YYK!0k?ai!HUF{=oPGv>cG^_`{^2g^>gbf0Ers*_ z?<&s^bY<0F7XSA1toKitF7M7$x$o;A|0JY5V4rF7I{V6KZRg-U=d6ONE-d-}&E-f1 z!*R7N?FT;LGAvh@CAv*~HFNKUYW`V0ogZ&L_dW9GnUn0BxF5?RUvdcSxDSeko6O$~ zQ)~(|+J$?idv;wxHWI7Dr=vN%_uSjY3C8>}|Em?l&Ma(yg61c+|_>Bo94q!l$ zns{(W+Xh&)9Yv0||6~J!`(Jyzj97)PH0zb{XKJ(<_nZZ~mjj4-fEXzkAX0DwJO%f5 zrJ?Ht>G}@RF5>-1&V7mxf1d9z$H=(6&F9|S7WvBmurUcJ$6WvT5|4oq!0Nj}rXq?$raU5>uVIVsm$kjOH;}7C-?si~QVHASc;trH< zNCp!UOO3>*Ft{=V>{ZZYL@ok>MW5V-uC2e?tX@qPG4TZ|W`ZVL z0q=+kQ|HkOn4DbMpZC-xyK_A^Bf~$%4UmG6Mtc{f|_O OQL`3!$p?%%AO-*?FwF)4 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/9a6f158c176d4a1982d541be2bc27a8afba4ea57 b/fuzzers/corpora/commit_graph/9a6f158c176d4a1982d541be2bc27a8afba4ea57 new file mode 100644 index 0000000000000000000000000000000000000000..b99bc20328c87fd0012f2e53461cfdbd308b9b9a GIT binary patch literal 99 ocmZQzU|?`|5Aa}QWM=U9ba4Z6!GImcfYFRV1_A7VO`d@P0M>c}p8x;= literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/9aa4af603192823a2fdc53d95ed36896bc3309b2 b/fuzzers/corpora/commit_graph/9aa4af603192823a2fdc53d95ed36896bc3309b2 new file mode 100644 index 0000000000000000000000000000000000000000..c36e298fc1e60e5d84bd0a8c889544494b08e561 GIT binary patch literal 371 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+HEAVmh|0csQR{v&(2l(qJX zpkK+Eh1UZvtb3SJGr?vX7f_C+0Af4?!#S&ldFCYhCho_w$d?=fJMP;x91*_B{LL`MrZA&jxL3Mo*A=_A zvaSYH8UdID$j&9R4m-`?^c4X9L2*a` literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/9b40c2190123cec66af3b37212f6c567869efda3 b/fuzzers/corpora/commit_graph/9b40c2190123cec66af3b37212f6c567869efda3 new file mode 100644 index 0000000000000000000000000000000000000000..16623249243e0dbd0ce251eae6c6a6856cb15a85 GIT binary patch literal 152 zcmZQzU|?`|5Aa}QWd08Ub`1WWE^a_!+@KLfiWSI1#%w@7A{%4Oq16E)iFXbn8n1v07MLy2%rgNI=eVBF@!KMFaxDQwz3k$vTx#k zEQ@@}A+Y1VUBeOKo6O$~Qfvw{+J$?idv;y1Ybz_epCHVZG5`7DdtaY*0*&J?01`kT z0U~}(?Avl$;YF{2!C!$JliC!c3WKKsg_)shW=~-Usk#9KK)0lw={dS3ubW=}C+v63 z@L>bGmJkMci4@HC|NnnbD8N#Nzo&~Eh!2cXK_J@)#0JKe1u*V_F$V&yDG(Y&vNs^u z5Ed7Z0%2|=AO_KJ{0hzn3K0W9TERdR95+-+e+;1X2Tp+v2$vzd5@I96A7HS60F+A> f1$RFrZBfPj!2AQsy&OOXfpVyQWumq-(2;xqNoAMn literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/9c6883ba5cedb7d711b12733d66ef1a1156dd0af b/fuzzers/corpora/commit_graph/9c6883ba5cedb7d711b12733d66ef1a1156dd0af new file mode 100644 index 0000000000000000000000000000000000000000..84a193c4592489da5865fc263c9921e6c13d781f GIT binary patch literal 1988 zcmcb99WO9Im;Da`j0|AF0_8%f=|DkL5d;q=0nrF15t4LeF))B!kA#2x|L^1;;K9hq zjN~|?m`I@mQE!oOop`?>>Ap^sbqGbsT8UvJbOKq&3xEU&0|ATwk&Usze~c~`l}(<1 zeBOoVwd+3J=A6kO#=rrT1z}Dsmmqqe^Gnd@+v%iPPJ!A_ydp~%1IzQfg?tA3VGbh?%z*wD05Kt#l?P0MB$}6+#eumEJoyS~p z5#&N>oN@s3Q_#K(UEBuSwdQ)gt(W?7;*^kIZ^};OJm(Yja__ncAN5{kPS<>^5*p{Q l^KaVRg<3*Db9g}N{{IKDynk)waBL@UAk-Xo` zCHMU7?;&yzS;B&57ze00eQsssu`RPLTy>vw`Bc$qCrfge{OaC3Kfbg|grp8~~|ZHPDDs38^f41dhR?%ie$$7w9E81&3h8h6NjB-Z-&6 zah${?>LSpQCY~9Ooo3#A)HeZ|FCOlq==h^0u`9%C*GS}U=)y=v;RI^VGfQF!b0zyW zMmW%ww}E$@!q4S1*oen_=5yRnyiD)$1jUnidcDr%!DF`4lY-QWlG;--b_a}A&|@8X zIbFRM_u)I@{#<6*>l`Sp8f%N~k$zdzn%FZYH((;G(Us<6N&0W_r2F#H602o;OFC!* zxd9}2jm2<7-l0SQR8ms8!#8|!*Kzi)2$|Q8OWhcMNhv>-y*D^bYjDEXQsS%p z);7In8&dKhiwGKH1m+6a#*#)t8*KUS1g{rr-Hu4x88PGg797#J0}oZ{bspdzdAub?f!~Bk)z0 z6mz9(z0s|vZ~gQ6XY1=Q{|@u7SZAUAwJ-Ba%^@VbZyu4&)`BbVr8e+N(}k{h8)AQ! F#1FG|GxY!f literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/9dcbafe8c5345194ee0ce7eb4f6efaeb55543626 b/fuzzers/corpora/commit_graph/9dcbafe8c5345194ee0ce7eb4f6efaeb55543626 new file mode 100644 index 0000000000000000000000000000000000000000..42c5e7d3a414d6d5960b99b4f6c4a5f909f61de3 GIT binary patch literal 3972 zcmeHKOHRWu5OpA>fw15j901X-8fZkRgp@8g0>@y{WpBWW3-l74f1#566Q zZ%U}A$%pGlY{29BoN;gVKxs5w8;$~XWFFQuMtP3i8-NJ4c4`&5B>OLX(t6p^QpqyD zBO7v!c>_s^3e|W`(QSnYsFbME!yQuHO`XLNB@=NhD%3c`4u+>`4Nuz23w~^Byy+hc zW|N&mYhGmK!D9NQ_3h$0?Y~Y~!La+NvAu2!nX<{a&fDv(lFpQ7iR)^f>-K=_+u$p< zS*P!L?9+qW_t&*s@JnO9W@7B}$T+e6PO3RD5thI{EkBf zvwbVS|0XqkHLvk-|3$*N1VpIYFZ=dIT2J6@$_MrOfH%RSs;T3b~0t|Zy*&Cp2m&*CqEne79 zt6}dw_qK6@G5?8_zNcABmfv|1^Ub2oXe+*PCHow4_Z+0&foME0Q{|8vj6}9 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/a1379dcd89ef5e73eabbfcc395113e3636e0ae09 b/fuzzers/corpora/commit_graph/a1379dcd89ef5e73eabbfcc395113e3636e0ae09 new file mode 100644 index 0000000000000000000000000000000000000000..43d31b6d230476bce760ea03bff81ea6d6ff1a23 GIT binary patch literal 134 zcmeyy&A{O79^k>u;P2_;#sC7IEV6}ApyHOumeUF^dIb#r3f!2~rWjQiJPjz!TmVu5RO|in zz{$Uy*8dA8B$gV7g*`i$^&q^tpgk2R#{yNu;X zOfL`EXOg_mzA{?dIe5=GtDve2OTK?|Ia0xJTrErcfls&$%hhFxZWCY4+N`r$Fj(m90EJ;%QYMkzRCQ}FvX@Yqg}XHx@XrFySB2j`w7Bq8S|eX zzW4Q6Cj)~93Sa~VJ;dt>5-7$%Ps{|g4~Bth2FPOpC3r9ZaTpkWfdwIKumVu3N5=d> zK2EIK&!;tYmYJW!+cf5@SNwOYltl|T?&-;7kKVf_CnldY?M%zU|@kW zbwCv`Ft9hkm?+_?p>g9PngCwzExfXXC8-gAu&@Ww*ux(ZDKJSOjU4tMHqNjI$w9*3 gm_Yb<-}F+@CM(_Hb3Z5%LEH^VLleQ}lsN+f0G0v_YXATM literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/a38ec6ad4a8466b4feb88e67b16524e8f3feac64 b/fuzzers/corpora/commit_graph/a38ec6ad4a8466b4feb88e67b16524e8f3feac64 new file mode 100644 index 0000000000000000000000000000000000000000..a9d1adbb3673ecff6b7fa21a4de0d94311e180b7 GIT binary patch literal 487 zcmZShFU#QU9^k>q$Xw0I00oQ;4Da6q2@rrvGWdJ8GV<7#*%q$4&$)c6=(Lk1IZS?a zZ=N4t-|`+4^!85dg#%3K_X$|U-oM9T{xo)(|5(*iB8X%c+!!P=WdBjm{`GLHuresI O9~46FSOEir3=06BOID-+ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/a3fdea21020268b3b2409c1115d50697d9ae8f8c b/fuzzers/corpora/commit_graph/a3fdea21020268b3b2409c1115d50697d9ae8f8c new file mode 100644 index 0000000000000000000000000000000000000000..8d4f934fac6cdfec2b880540cdf8fc20d6456640 GIT binary patch literal 257 zcmZ3r3I_gz0E`2tSHM{y1_KZ_zG$YurrE;V$g literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/a45f1987a444b2c27e90fc1477e8b0815f75383f b/fuzzers/corpora/commit_graph/a45f1987a444b2c27e90fc1477e8b0815f75383f new file mode 100644 index 0000000000000000000000000000000000000000..d211a8b1f5fa142e59132dfbb7746c32b01b84c9 GIT binary patch literal 607 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^=B#VW!i(?3wV--|&VafMzE=MXDj;m#9 zKkx~cVY#|2(QV?ZnR_o(^Uvz({CM-Z?~y;xoMhj`{a6E>jWCkT>!C80!Z<}@RN}8fPJRP>+CC|wVi|a zoTHQd3_rB`wwzW#xC7=M95e$fPy!jV0r`Y5J5UWfgTVc-ywFim|9--LKNgXph5Pc*J;-KCG!t&`U(Jifz@gN literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/a4682958fb7029384c0a01a4a1356ac6f2f44fe1 b/fuzzers/corpora/commit_graph/a4682958fb7029384c0a01a4a1356ac6f2f44fe1 new file mode 100644 index 0000000000000000000000000000000000000000..e8f66dc88d16143d4ff4aeb08dc3893605cf5c56 GIT binary patch literal 78 ocmZQzU|?`|5Aa}QWMc4Ng%^B;%6huE0X4NS{09Lb3l2P80DS-<*Z=?k literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/a4de41561725960d6f48f210a4fb74d527f7b0c2 b/fuzzers/corpora/commit_graph/a4de41561725960d6f48f210a4fb74d527f7b0c2 new file mode 100644 index 0000000000000000000000000000000000000000..ac4c41c9caed48dec6ae2b09f7a8462a41322543 GIT binary patch literal 965 zcmezW|G%oUdjKPkZJBN1s{5SFr;1KHS(3x#SNG=m@%1g!*kz>MPK0b0Y<)Go#QNEa za+k{a*DYRrpH{=(d+u%H1Y`aaDSc0~mMp*XBIcV#$;+0)`Tlp6=La(I8#6HQGf;q4 z`}wq{&NB0Jc$>z2^@{&)m9l67$2~on?9qF-yD15}(oSAQiv7>W*T4WHoW^fUOg)290O4|hpdN2dV&O?vGJM8mHWQ_@lQg^1NNCFud}a=)^-lwbIvNL>cW!m-&~GVFdSFQ(th9* zF2izlS)$v-S2OossOF#5)A{k{bKfI>o;k_BiTklE@+F7Bj{9~EM}%)Oe=|(6Da>dW z?v?J@bp_eTk&{Ti%gqjlG#VBiA^F)%Q~F)NTo3T9xC@N;~}B_VMCYj0N?tI(BZ zy%PRRjTYmcvp|zLfS3n}MZEvWUM^*=y&~vWa%SQ6fD7v$;Ae3aIWTqkfM<+jmEn8Sj_OI_xxm(^mkT6*zqW literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/a5b394beb2b1d463ad80924a8c8c70584bf5c629 b/fuzzers/corpora/commit_graph/a5b394beb2b1d463ad80924a8c8c70584bf5c629 new file mode 100644 index 0000000000000000000000000000000000000000..eb8f700522f9ebd7624dbc582c81858950ac617f GIT binary patch literal 234 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6ox763`}4SdjpulqS+Xy wW{4?35~>-_hcY$+0hDP0VnYE?h!HmiO6fx79Y8b-#C;4J5Wt|p31Tn+02J~WhyVZp literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/a62bc806f8c98ba7986243c2185a0548a8dd57ef b/fuzzers/corpora/commit_graph/a62bc806f8c98ba7986243c2185a0548a8dd57ef new file mode 100644 index 0000000000000000000000000000000000000000..fb30d9e49ef353a407153ebcbac9bf9dfb1ce2df GIT binary patch literal 118 tcmexgFoA)AjR6_!F);l2|NsBb|0tr!Dj;m2Gy^+M%nXvokk^NZ0RTvl2;%?% literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/a7013e97948893e0118c686c06e332cc611bea7e b/fuzzers/corpora/commit_graph/a7013e97948893e0118c686c06e332cc611bea7e new file mode 100644 index 0000000000000000000000000000000000000000..ab501138e407202802296b9987af1623f083e73a GIT binary patch literal 214 zcmZQzU|?`|5Aa}QWM=SR1p)J>x}A$_P~W-WbDtcWMM~ik-fd-2DWGZ)_>UbxB%vfD vkcMLph9Cd`JGozg*yHKqhN_4IMJJGh-F&DhgFnmwpa8-Wuo;X%A?N=9K?GI! literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/a74f5df8c7f25c37c15c0f74ed50019d17338225 b/fuzzers/corpora/commit_graph/a74f5df8c7f25c37c15c0f74ed50019d17338225 new file mode 100644 index 0000000000000000000000000000000000000000..b234c15833b94bb808aca940d2c9541eafdb1181 GIT binary patch literal 539 zcmZQzU|?`|5Aa}QWM=U9ba4Z6S%BCA$o2u!Kw!jT;q2lV0^zWxKxh!j-hg03SZD@; z1T7H;!Oi*q|9=lq3TRdVkcp;s{qCJmA@c;F8$gZ$0-~J&QH~&i7C?;yi76l?h+uI5 z)le0$Z<)p}Bkgt~WV2xFtLY`y&sLPXRL;L{^y2%p8us3EZyP5V^PfoRdz!Umxy82^ zF?UK{wiM3yzpFeykQL|@5N4yuJvi*QeBtkUS2=J#tNyb1x3k_qVY zN?(@xFO807iu%p%Gtt_|xXWp>mqqe^Gnd@+v%iPPJ!A#9ifFBW#HbHSTrhVt$Hcl|+KatY+G;7K7J1=6sS(LnN!5gFZk%AuN z(gq+wUoa%oKPU$ArGMgskoxI=D5YmL;u1746&KF;zpFey(3MqxSv>!&p3aXqpZgy9 e^UO*1P27)VkuNy}fk7^?nQh^!`<%#I&fgShl8jc9xWd3HDVpEvWF5D~Kv+Igo zTUput1Yx#}`OgpE`}(XCXb(3ua3p|ih96peTTUyy=oK*dD{x~{8}0yn!gP6ep2~fs zP_eI!)^-lwbIvNL>cW!m-&~GVFdSFQ(th9*F2izlS)$v-S2OossOF#5)A{k{bKfI> zo;eZkR0eL4Ly<5C0|Q0QA7b&3KgyBQ3h`kI4!r>EZ)o19Q6tFz*9%J_xX;Kxh!j-hg03SX@8~gt?7SlQ=iS zD|nJe*Mox(${}C?Dch)5enCnwo?Tb$+RDoACkV6U&3}IQ-uJK1IvE%kxC?*;5J-TCA6k9-3=9Bx)hLDl literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/a9969442d585d9a53259c71c73b095701280eac5 b/fuzzers/corpora/commit_graph/a9969442d585d9a53259c71c73b095701280eac5 new file mode 100644 index 0000000000000000000000000000000000000000..f75792824ffc17ef127160e05f6ba43f90547ea5 GIT binary patch literal 160 zcmZQzU|?`|5Aa}QWM=U9ba7)~&|m}#SpeBSKpF^GESy~&Ll_u@fNa(j29PWmus1*% hAW9mE4P;iKao?Tb$+RDoACm@9S^cffci2Wn$ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/aacdec3f05e98eb6eedddb9c6edb968e1a63c551 b/fuzzers/corpora/commit_graph/aacdec3f05e98eb6eedddb9c6edb968e1a63c551 new file mode 100644 index 0000000000000000000000000000000000000000..622c24795f91bbe27782bbce733b30359adedff8 GIT binary patch literal 3654 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&F^tz%LLF$_6n> z0xUq)tRNj62n=L`cwn*tCe8`uqhl_h7zlGCVSNz04h4W^K@LQy1PVa_)$Iqn1=)JL zI-pJ5-~d9{kL+S(uVZ)-rN4jRR0fS)g7qhIGNHWw!kPYXrZuGW z3s*zi^fy|6QP%#%mffK3C-iEK=&F_0Rm(L2{q&su^Na3fbc>(A+aUegWW#x+cDNyO nmLb3)4*(`you7xDuskF<>}NETT~Gc8#3i2_C6v2_1Chm}L7Wit`#3L27xqX1pw z;0Zsvro`zb+9(;4U`mXC`+3&;Crp=j=c(NH^^boNQXa4moD!q8orCwBvkI!Zu;lwU zmm?Jn$JMg5ANYjJuv}f1=r-}y%)J+?`DgWXe!ThI_sE}TPO@*}ek_Z8$sw@gzFor+ z;hW6g3{z|hGunlFrF(W=K{j&mlq5u@f6C*p4z(m1&LtswHXN$yZ?yb{ROqASFKI1- z;gbI8(~_f8`AbYo4n5+AMEe12tG2}_>g5~Lx|@vpJqm5#9a(0)Uoz{k)BH_e0aG!Q Ay#N3J literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ac26f9afd599ff6f33396c2e02130654f3e2390c b/fuzzers/corpora/commit_graph/ac26f9afd599ff6f33396c2e02130654f3e2390c new file mode 100644 index 0000000000000000000000000000000000000000..843eaa25cd5f7a64baf6fbb67c5a70bbc4e0bf68 GIT binary patch literal 324 zcmezW|G%oUdjKPkZJBN1s{5SFr;1KHS(3x#SNG-`Md11I^)1ubWu)Csgw#_RFlnjo z`&uj^Uifg9$UKjLRb6UFcLA-~EZF*LdWrS373D6K^Re2Ue*DJUkT~ny|9?*e^au*? TvYg>Ohg7#QFfj0=;7wlvG1sd} literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ac8b129e4756fda0c50c9dd0eb13e34c7b41ce8e b/fuzzers/corpora/commit_graph/ac8b129e4756fda0c50c9dd0eb13e34c7b41ce8e new file mode 100644 index 00000000000..4b41d07c777 --- /dev/null +++ b/fuzzers/corpora/commit_graph/ac8b129e4756fda0c50c9dd0eb13e34c7b41ce8e @@ -0,0 +1 @@ +ïïïœïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïï@ïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïïë \ No newline at end of file diff --git a/fuzzers/corpora/commit_graph/aceaf3b72c2627dd3dd065974b854150681c093f b/fuzzers/corpora/commit_graph/aceaf3b72c2627dd3dd065974b854150681c093f new file mode 100644 index 0000000000000000000000000000000000000000..d490782e19f49ec39f9cb7817121e56cdbb485da GIT binary patch literal 793 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_5m?~ats_G29Ugt0>E4b25z7fGG<2OgXPRX z20#E0kkVmb-~&=<_?T`admLLMSQx4pO1;MmSb?fwm<`Cri5Wr0fn?c1_&*ph@B`Td zv1&h`*3?->en7QIp~dZj%7=s=d&7T_urY`r43L5pqS!0}N$C1@!X}`oK+#JC2Q}_M zaYd8(!*q#`2C5i}FOC;*0r?<|oU(vyCNw@+9;6jt5@ujvv2b>A3<0SFrj!&24J0?g R0pmU})5Q%$f#f$a0022twSNEr literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ad1fcdc3bf806392e754a902eba9edd3b344c31f b/fuzzers/corpora/commit_graph/ad1fcdc3bf806392e754a902eba9edd3b344c31f new file mode 100644 index 0000000000000000000000000000000000000000..1379b75e86fa3e141a4b3de70f253b2d4214ca91 GIT binary patch literal 98 zcmZQzU|?`|5Aa}QWM=R;^>lFq@);PIpcujW_n(1*87TVq|9>D0qCkbgfq{jAli?3g Sgas(b2E{-M%w}K*GS~rLOA8eM literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ad8c80e532482f9dfbfbb7c0d447f1f4e592bf72 b/fuzzers/corpora/commit_graph/ad8c80e532482f9dfbfbb7c0d447f1f4e592bf72 new file mode 100644 index 0000000000000000000000000000000000000000..bfe39118aef0e84ded6050bba91c9c0657266f98 GIT binary patch literal 457 zcmeyb#{dM*?g1W*jLZ!Fp4={OAORq-@b`4N2w}2VIJ-E8K-jD)5E_GwW?+Pf+5P_x mWc()xFic=DL literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/add92b71bf897da2f71f691e6abcb6d02cb8e99f b/fuzzers/corpora/commit_graph/add92b71bf897da2f71f691e6abcb6d02cb8e99f new file mode 100644 index 0000000000000000000000000000000000000000..1676dbfaf0861899af399789923952d8abc22237 GIT binary patch literal 231 zcmZQzU|?`|5Aa}QWM=ROvKjt^0q1W9hDRVS0|SeNvx{R0gw2`)p>dE<9XMox!Yn|{ h3XD!bR{#j~4~zf+ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/aeb8ccf6d82be9236c9e689e1580d043bd701eb0 b/fuzzers/corpora/commit_graph/aeb8ccf6d82be9236c9e689e1580d043bd701eb0 new file mode 100644 index 0000000000000000000000000000000000000000..10688e3dbbd6b7acde302a345905ff783cc32b95 GIT binary patch literal 3419 zcmcb5af)BNa&%U=?Z~!$>iaUrjgA=F@9diN2K$x4xmA41us& zQy?^m1O*aVzyYr=7N9IE5(Wo43oPjWTl&95l?STjKvs{;Mv8k_8UWF;$l|cLM#L=> z%rZi>140ixZ2*NpqHsQ#haQ(8J}L1DG7p|FJYC#Cd?2v!Cm2aURoo2h4ItIT0#F3t z1P(Z5kR_1A7siH#GgcZHWLU+4hGGe0sMwH+Crdo>^dAnU13e4o?En84E(m2nB>w+L z4rB&KAP))u`2XL@y#`WvqNqdVz|#@I;&m0OMjSj?`~qo2@oJAVI>FJ5Ev|9LGrlx{ zD%SyYBQfSsnja}CgNZL+8&E@B6ULnj1u#A)jT9&Fat~XW1I4fkV-qAMTnVWeUh#t& z?!<{W;8jM4`VXEaKmw Ga0UQojqc6> literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/af1a827aedbf674fff2bdeb5589554eec62787ab b/fuzzers/corpora/commit_graph/af1a827aedbf674fff2bdeb5589554eec62787ab new file mode 100644 index 0000000000000000000000000000000000000000..6f08ae5099fd8e1f4103c286e9b6e75d3ef4e906 GIT binary patch literal 215 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_5rh4SS*}f9RL6S|MUNU1~#A&5VHd*5az&% foAAh?=ySks1`|p88Mqg|d-qOM5D0)Y&`}Hkt~e8I literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/afaab9a75414d231176ad4582b6f8d81b5dbedb3 b/fuzzers/corpora/commit_graph/afaab9a75414d231176ad4582b6f8d81b5dbedb3 new file mode 100644 index 0000000000000000000000000000000000000000..87017801022905451ad332b88c3eaa2f1021783e GIT binary patch literal 2686 zcmdnY00B1N9a(0)Uoz{k)BH_eWlCR``Y(-+W{UdF?K9EZ$GFRBvX@2jelwTc^RvH) z$XT(31t6+&lx^ouPJF0Qo);Hj9Nb z+yIy^kPLeRL>^B5{SRm2WT@hlAs}%b0v14N5QV1W5tLttCJyJa09mXc9tQ#gnIImD z7y~DekB+&3Vj#?oj_XhWSoS}atpV8pF&G$sSe$_FBqI1gCFlSae(2&*z7_*T;Ri8A ze_8z70ti#UZ(?n^gn&8AtdNB`ti&nIh*Jh3;p~oJLs%5KpQQN59!(CUM;*EsfP4bc z#DEq}z@UPpad0x1h8YOrp(k+=AFDS9MfyYc7|^ju9z)L4SUm>wIFJSxX9-9GXiP-v zLKK$-S%`=k1mzFW=}!^pb&L`XNenGyKwJ{jA5aG=(KL9|-)Q+qeEmmc`uq3)|5sY4 kKh*M%U@(^b literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/afc12c4ebed1f3ab962d7dcef110b5328b1e24c3 b/fuzzers/corpora/commit_graph/afc12c4ebed1f3ab962d7dcef110b5328b1e24c3 new file mode 100644 index 0000000000000000000000000000000000000000..0e10f77368d4bd9737ffbb0c0884cbbc5ae44e6f GIT binary patch literal 673 zcmZQzU|?`|5Aa}QWM=SRMIHbeK?2}rU;rX8{{R2|Um)9=1IPzqP9zLuk^~rms)@&N zFMGPUL9May_jK`ruvsjeT^vIoY}OR0Jdk2<_zwZU5Msoznt@tD+JPA4&9u1-wS<5) zPXUks0s+5?wdE25<}9;97QT*O?cf%%cu~L>XQS&Nd9WH5hB-!0RAwJ-kSTpx>c2EP znknixx6edtALA~k$zB%8`^{W(&(HoIBKMFbENF&dfQr-SRz@D%GTXvc_c@nO6`gjn zB!|hb?#=V#>szL=%SgMO2-z&y`f7TK^|KY_E|v4ITfF!_t%ki9Xdld>$TZZ^8l*Xz pfnkmbilZ^@JNLG6f-(Pzl)k4~OP1ex5%bNg3{qs8;OXK6VlXhUSU9^l zhCtY?$^ZX7h literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b06adc81a4e1cdcda3786970ca07ed9dee0b6401 b/fuzzers/corpora/commit_graph/b06adc81a4e1cdcda3786970ca07ed9dee0b6401 new file mode 100644 index 0000000000000000000000000000000000000000..b5f08b21fb61eec8757e90163bf7f578de179c1a GIT binary patch literal 344 zcmZQDXJBx45Aa}QWajYq zNU=Bkhk#!|PJ1elU@3se@&hT#F(c3vTo@?Dfq@q<3fSUobR8(pz@O&}B)LJj4h4WD zL4XB_SwRdWV}MK$4@HcD6UYbQXebS0b3rlKd>|W@1_cVb7+HKCpwSR40HwivXdok^ z4je;3wGcqE&mcZT_+en&k1K`2yv4xq2*Je8BINT1SX{&66q&{!r!cxC$zk%Vd-MGG`j%!Q;(`sNr0H)#m(eT4ve}Y1a^7bgm3|#F|kT?*)8W;$gPHj?n J6CFKC0|1am5Gnuw literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b1b8f251542db01bdb01be3b6d5b117b07db1834 b/fuzzers/corpora/commit_graph/b1b8f251542db01bdb01be3b6d5b117b07db1834 new file mode 100644 index 0000000000000000000000000000000000000000..b42f7263bc619184a4f7da79161d78cfc9d47a9d GIT binary patch literal 790 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>3FtDzu8X|^W`YI* zaP5NR^-n41EdMR>GER3no5x@f(?>uHOqv14z)8a#K@rUe)XhW$W(KOkhFO5(EDW3s zfBu7L{FoIekBs?&e4JRdpHFM*EHgicw`t5*ulVm)DT@|x+|!fE9=&%c2EPnknix zx6edtALA~k$zB%8`^{W(&(HoIBKMF*8t4!ZXl3NFEwe3Lb)R$jRMBZC=Lfp7>Mx6b z`+3&;Crp=j=c(NH^^boNQXa6+GMPK0b0Y<)Go#QNEaa+gZg>y|IRPpe_?J@>Y8f-(Pzl)k4~OP1ex5%bNWfSs*zP@D|yM(mciIB~Lt*@q+SU+1??ov7b zy2Xp{(`wjz&%JG&V9b9arSEChlI3?^#C)?TdD&7p-~X=i{6JS${bliQKhJvqgz56` zJeB*t{_#(Y$^-V9Ca<%vjMjDz-gC|>sOrL!@84XGR4{M@od?6m8G#%IMxaY=lKBBZ CoKSQC literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b2eae68035cafd4077f6a4c3e4e961fdc1e8122b b/fuzzers/corpora/commit_graph/b2eae68035cafd4077f6a4c3e4e961fdc1e8122b new file mode 100644 index 0000000000000000000000000000000000000000..1c62898864c6a99e502a04d3dd669227dca96ed4 GIT binary patch literal 1878 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImYX1csPPvyR^fBch>@_>D&$?NPZqqUub_nfl| zs=Bb``!|;(6%5DKva}!ggv+p8U6$xJ@zu<|7pnPZ^>lu``P}!&pJz_8Z{mI|i+sr; zu;ad6!x7<|%-;-CYzi~lg?puYc3rV+D=WL7Ak3CA|M}s2U!QdX?d2{2ThAZ?qJC)g zZ8@#*qF2D+ufUB-ZHiHa!T-`g``x6G4`+;7-3#I`*#taPx4)2!-PX6Vz{$DU5vD7#$?Af`j2jR^H z?WsUDEFd)l5dO%HhlRhzU<-fRCPCyNKw|R%BZL=-A!(BsnwapzlK;NDT==%6DrjKx zACiZWnY~?UtU_0s^-B0NHCl{&&H}y90mPs%5%K;bd%2Xg_KKii$(e=ZmoT literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b3fd100b139cfbffaad68aacf7d462861e9dca35 b/fuzzers/corpora/commit_graph/b3fd100b139cfbffaad68aacf7d462861e9dca35 new file mode 100644 index 0000000000000000000000000000000000000000..da105f5fcb5150605da04974032cbf6f5f08ccb9 GIT binary patch literal 136 zcmbO|g`EKmSkun*9Nm(qsqdwbZIZp=H!n!k**(C6k&&6f-?NpG$F|J2aMgXzp^&PL3=7tn5EzwLnUK(nx9|g@mY00Lm3zuoSYb} Q7#ZgD;!zIN$RPI}0FPfA0RR91 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b43daf9f87a514bce74af3e5a39284c69c4e7011 b/fuzzers/corpora/commit_graph/b43daf9f87a514bce74af3e5a39284c69c4e7011 new file mode 100644 index 0000000000000000000000000000000000000000..5c8129df1821e91e3cdd6860a5d8c06e743cf7c4 GIT binary patch literal 187 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_F?$<|NnmmMj#i8S%FM2W`WW$K9FXEVs<$;2FvJj;VKwH6p Qfq@+&3$qhpJ2y}%08YauNdN!< literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b477da07f3e5796ff4a98c8a5bdb0e4a634954bf b/fuzzers/corpora/commit_graph/b477da07f3e5796ff4a98c8a5bdb0e4a634954bf new file mode 100644 index 0000000000000000000000000000000000000000..dbe8abee3cbdadcaf0968b06ed2eb0d8c53e98f8 GIT binary patch literal 342 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC^xq&n~X2v4MZHCas z17zwjFz^8>WDMl80x=tY%mI{!VR0ZEWCA}HtcXnzml&!a!0rb+1;t;4+}{fX3=E7A IKL9lY0N|VpN&o-= literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b4a2ef09cf59ca5ccf810a6f001cce710cc02f6b b/fuzzers/corpora/commit_graph/b4a2ef09cf59ca5ccf810a6f001cce710cc02f6b new file mode 100644 index 0000000000000000000000000000000000000000..3a5817375ba0c90d7a465bbd540b21e338a05196 GIT binary patch literal 1248 zcmX?p91IwMz}Y>(gOQP$!Qa!x4a5fm3n1GE%&No%7+5TvT^vKeiWpc^AT)?%Z}<-Z zzkruH;AIL_fL4krUMi!q3Xfy;1Kxr@^8pw#KBQA!3 zh9LuP2CBIe*;p9+5sZPA{s9aiEP&)lfkh5dq@YCxEZ{Lc%U}ji`(ydumEUyYz_bb literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b4b75e588cb83430c502a34ec3dcfaf774a00359 b/fuzzers/corpora/commit_graph/b4b75e588cb83430c502a34ec3dcfaf774a00359 new file mode 100644 index 0000000000000000000000000000000000000000..4afd452627d4c8fc7be430459237cbe01c7358ef GIT binary patch literal 1976 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^=B#VW!i(?3c!z;!%w$Wq9*Z~!F`m=DN<;rm~EyV6*Nt~BeF@MVU}uv}f1=r-}y%)J+?`DgWX ze!ThI_sE}TPO@*}ek_Z8$sw@gzFor+;hW6g3{z|hGunlFrF(W=v1=f3T!;YF{2!C!$JliC!c3WNXS1Ux_uydYgL7eeR;G(M92 z)2t=S@4SflW>NC8rEtFgUFG?KuB`gY;@^Ir_5KOd<=uHI_kI22pM;bL>@!VXXI~ku z?Hs)4oK;ZOg(cs=xg4orIIfnZ{lI51c>e!?R9_?c5+g*g%Q3J56(VEgM2L$GNh$(J zX@Ngeqs6%AEYK`avH``3i1#1a%cZQfR|Ne^&MdqhaADoU6iA%F!ru%}_$LgN@Q0?$ zX+R${L(?#a_sat(|8iRYFPM;6Y8)2!>|EA^@aBT{RG=CbkeY!@Ke+R!5v}s4){sb| nv@4(B1=kQsB5?P@8T2e-s9!(8ibz(>OzAZ1{gU~IH+=;FVNS?V literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b4ce98acd2b288b6cfc00461e2e15e0f8004030c b/fuzzers/corpora/commit_graph/b4ce98acd2b288b6cfc00461e2e15e0f8004030c new file mode 100644 index 0000000000000000000000000000000000000000..a7074267369ec04d5de8994e1d4a919c374b7430 GIT binary patch literal 1246 zcmZQzU|?`|5Aa}QWM=U9g^PKQTpt7U1k7%y^maSVZ#OFrQY H3^FVLkLW8+ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b75563f30f7e4fb369d2449b723ee8b282d03eff b/fuzzers/corpora/commit_graph/b75563f30f7e4fb369d2449b723ee8b282d03eff new file mode 100644 index 0000000000000000000000000000000000000000..a101bca5e12681ee8a9c70cdc96714a17d723379 GIT binary patch literal 1989 zcmcb99WO9Im;Da`j0|AF0_8%f=|DkL5d;q=0nrF15t4LeF))B!kA#2x|L^1;;K9hq z40Rj_kOpB+ESL)@2EyD}F}E2|7z%iRvHf$6 zJNEuwVf^LB?z2z3=hK=x%goQ=Z5s2{EB?Dx%Ay4v_w;14NAKN|6O+%H zcBbd(mb~tpUJBYq*&BZIZh!yz{J+h|xmWL1a1CJ8?Bn5FJICaS%Iu>JGNms|{g*~Z zGe!O8_L*qyW8CF5*~=n%znM$!`Ptt?6 zmtix=Og)v))Td)qj{nEymd-_xum z%kR91`DRh_vZZjo|6S$zfv&9j%i`aDp7s6-)8*ZHD))W;xx}lS=s#rVYZC<&kx`G`m7TeG2GB3BLQSH z{Lt##a$4ass3;v&dT(A3QVED(eCUFhOA*se9# z>utT%j}xba{CZP%A{UxIQ7`wdoA6QZRpxZfw<@7=4mSr0)NJ5X<}5 SRu0EzQi@-ixCoe7YS;l$J6!Dm literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b7a0a820afa7057081de186728d0d887131d9314 b/fuzzers/corpora/commit_graph/b7a0a820afa7057081de186728d0d887131d9314 new file mode 100644 index 0000000000000000000000000000000000000000..915cc26be3b3ab869056c9fbd025cfb4ca5d461d GIT binary patch literal 3572 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&7gS0<4gQuj5xc zxJ4{p6tKnF=z0MG<@lvFaYzd=FhOKC;{y!rKt&+T0mNx{7itLsX&xX(gu*If0Z11Z zkPs9wEdxz+GcW)V82|tO{x6X23Ny0l!Fc8j50&8-W0x zo`r8Re=|(6Da>dW?v?J@b;Yi&tn7Y*Fk8m_=ZEioebxz7%MDGo5+IE~wEDK3R(R1X zVDMMq#-ujIsKVfBKw;(ru z@&2`y!?C&P{>T42_5$^?qG2{59~r|EEGuA zHSE1W#~?cv#s=p&grk9~h;+0GilZ^@JNLG6f-(Pzl)k4~OP1ex5%bNWJS|veL-O|Aq7Y?<&s^ zbY<0F7XSA1toKitF7M7$x$o;A|0JY5V4rF7I{V6*_`q{C$!Klo;62_}K~)!)eE;Th zq=MnNT9)<$pKuwLtIHDICcc`v_d+%Qte(z~H=p|+`SZ+4_D$T6WsxsA1cB*PV8?yC zh9mGw2DPMt)@EP|Nd{S%DE4%q=Kud0SU^<}urlETa>>CsD(GLRh(N1}wL6 z#ajYWyn&PT8IFT5KQbW7N9Vw0tP!4Ok?rpuPw$cAf$ilI;d D=q3md literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b8aab6c9b2c706f8df0ff695ff94969171f9c807 b/fuzzers/corpora/commit_graph/b8aab6c9b2c706f8df0ff695ff94969171f9c807 new file mode 100644 index 0000000000000000000000000000000000000000..810a30544ac08ed53e025700e009c175bf6ec732 GIT binary patch literal 136 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC@@3S|+*$@Uhkm7)1 g5Ch7N0x~QtAY4wMGzf#FKr~m3dp>L0nV!6E01SHz)c^nh literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b9751182a36acb79b77585e1e379857a530e95c8 b/fuzzers/corpora/commit_graph/b9751182a36acb79b77585e1e379857a530e95c8 new file mode 100644 index 0000000000000000000000000000000000000000..eeb1ed05d860f12c7a2ebdddac5af039d0e9e4ae GIT binary patch literal 1247 zcmZQzU|?`|5Aa}QWM=U9BwxK(Mj0n1G@% z%$(1_zzpQ0V-}zov6vO87KHymX%L$aiur*wO|WV|pVrh_rhX1@)0nSb@!zdd7A@eo zrzev=dheE;n0(f>Gd)MQqg#vnE!08>j04Kf@X#+EK&VxSTQnl=H+a5O;x literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/b9ddb239b5a2c1348d972ec70a08507c35ba4432 b/fuzzers/corpora/commit_graph/b9ddb239b5a2c1348d972ec70a08507c35ba4432 new file mode 100644 index 0000000000000000000000000000000000000000..0d746e52c4754421ddc89825eb3b7eda40c98b3b GIT binary patch literal 247 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+HEAcYSz@B6tqpUH~i+^{{Hj%f18hTuimTR8o;R8$HN&M zZSq8A_R$8J(wC+FOQWNiqJDGx{I~xP2GSPE`^{W(&(HoIBKMFbENF&tfQr*+MjqQT OTcErs0|O%vG5`PppgQaT literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ba8f573256a0fbb95c5626f399ebc3ef50bbd826 b/fuzzers/corpora/commit_graph/ba8f573256a0fbb95c5626f399ebc3ef50bbd826 new file mode 100644 index 0000000000000000000000000000000000000000..330229e41a4301e7d80fee23cca716d442c98f5d GIT binary patch literal 69 zcmZ3@Y|+-(EcBr@H*e_@r?s)`8#c%Uu0|7By?QkR0|&!2b{T266Cs;>GTEc|Zpn$s NXH7fPb975yHvmO;9{K

p&>E#SDPCzCyT z@0OgHeAcuxJx90Xb>H+-&^F56@SAu0`_Je9Z9dMudar_O0HbCf59iuBCQnpmA8n8+ zeOcNj_e&qQk<<1R||J5Bb2IIg8|zW-h2`GKyi`pe?qex5by{S&6kyYp1; a`})T-Ft7j>A!Aks2I{yUZa>5oP!a&}OL-&! literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/bc910bd349319e1ed44d7c7266e3ac99cc29ecc6 b/fuzzers/corpora/commit_graph/bc910bd349319e1ed44d7c7266e3ac99cc29ecc6 new file mode 100644 index 0000000000000000000000000000000000000000..a38abe5802b656b5e6298b75ea2f182496e68ce4 GIT binary patch literal 410 zcmZQzU|?`|5Aa}QWM=SR1qVP;UJ@}MP(86Y{z*uAz&_LDb@r9f+Rnjy&RGRjU0Cw{ zo6C_3hU02k+7EofWmv8*OLUv~>NOO+gfY-*m^+EJ8>9}q{qL~ZKXdPeYJQj<_-G33 SmwglWV_D=&4uKs=eg^>K8f0An literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/bc97b1d4f57eb7770bc3983e2d57c8c01b21d29e b/fuzzers/corpora/commit_graph/bc97b1d4f57eb7770bc3983e2d57c8c01b21d29e new file mode 100644 index 0000000000000000000000000000000000000000..631754c10e780110567c966554298d5f75f2c863 GIT binary patch literal 942 zcmZQzU|?`|5Aa}QWM=U9ba7+gBmn^Rq5_}^KByuv9t(_tPG3g=h?H3ZLIlV{S5JVC zqL&B`0|PhEL}bj2#s|w8BCO>BGIbaj_<$4|KBgPV9>-Ss|KopzY6$B+si5ip$NxL_ z{$64H<;L!_PrK#n-6#D2|9=7l11KDUECPTZs0xe)p|om0pVrh_W_}>&AflVw1(gqs zejs3P0K4A;#3l@o!Wg2M`te8D5m;0pdY8f-x{UfocGjKn9%v literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/bd06f768e35ded4437cb88e2bc0ddd0bea3fa84c b/fuzzers/corpora/commit_graph/bd06f768e35ded4437cb88e2bc0ddd0bea3fa84c new file mode 100644 index 0000000000000000000000000000000000000000..954e73d68fcec81b81b9ae85f3d092c270f12eaf GIT binary patch literal 68 XcmZ3r3I?vj!GC;UIs*d(syr(Izm+!O!Vu@Mot@_3t0Pq+-r)n$op6JO2Td!d?tR!`^0o6mu^@ZrZlFJsz2KhTv`e_8xnO#2OS z*k6ppe%~X1o;k_BiTklE@+F7Bj{9~lmGiG#y!bw?hP~*()^HsD$8A4}{&$+}Ws$t! O%q16SBQO}C@c{s(^s_Di literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/bee4464861e1cae3cfdd5fbcb340efbf02e8d8ca b/fuzzers/corpora/commit_graph/bee4464861e1cae3cfdd5fbcb340efbf02e8d8ca new file mode 100644 index 0000000000000000000000000000000000000000..8f636ce9b0f120e7f9b80be9756dbdbd19d2b1ca GIT binary patch literal 1840 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&F^tz%PUtHkKwf zLF{6WunQwZS%6Gd5SIgiflLq&MT{HBC4hN=N+4JON`v_YAd`^%Z^6L8LYe;|20}>% z6dpQ7#N~fbl;M(th%+$o0o{d+rO@4pi%*gJ!SPiG0|+Y!7;40TEm2T0{UTgK zkVU|$`1SvxCctkME?I)^#}?FsDF0E-{h<7Vfw_QU-+^TfM!^D0vp^aWvRs4r?^+Y=noq zr;8g@sfE9%iw^^X4v@=Y;q2lV0ug6TK^Vo}fMDZc@c`vum>0-K!l1C?gkq%FN4UZm z;tHS=R99RC3a}S|gn{qjK2z6)L42HUmfdcCce`f=ivkY8`gPLMoQ4U13I%e`lT ze2_yxwu*TFk#nEo!=LB-%P}%8Z}Yh~w?)44KWt0_%5g(ANiYIAsCfCE7ct)~N?x`U z&IhGYghQdh1=N7zP;QWMcrY^#Iaqk1(@0?l3P*zBXEJER&vX7NU t6kR~$p=s$S7lI8F!=Oj=A2j_BuJRvNH~NrKT?0MD0;&K(KJsQ@002dI$GZRk literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c054fc89ed72101dec861668ff1738ef85b728b9 b/fuzzers/corpora/commit_graph/c054fc89ed72101dec861668ff1738ef85b728b9 new file mode 100644 index 0000000000000000000000000000000000000000..988ab6be6650d50a2639e1e578834e8eae7a36a1 GIT binary patch literal 114 zcmZQzU|?`|5Aa}QWM=U9ba9*bYUbVx)%>%1IzQfg4wU<$)wkue!i!!3gTDedCbcO> z6$VdZV0d}p=}&F`obc literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c06752415ac037fefe5172dc7245cd7c49ca7fca b/fuzzers/corpora/commit_graph/c06752415ac037fefe5172dc7245cd7c49ca7fca new file mode 100644 index 0000000000000000000000000000000000000000..d03fcac6c7f6b0adde2b5f08130630b6eb7c76f7 GIT binary patch literal 280 zcmZQzU|?`|5Aa}QWM=U9baC?xaCZg@G5jY2fYcEKkd69>%mJ|>R{cg7M&={gfh>&7 Trd0p`|BMjhoc0AUfC2*mN;|tt literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c0c8b54354d172a0be751e3e9b80be961bb15ddb b/fuzzers/corpora/commit_graph/c0c8b54354d172a0be751e3e9b80be961bb15ddb new file mode 100644 index 0000000000000000000000000000000000000000..233aa4e0372be8c0476e856a91898b811938b47a GIT binary patch literal 2211 zcmZQzU|?`|5Aa}QWM=U9Ft>Z(xt!yCo+k zpEd1F&(SS;-8a1yw2iVi{N~;M{`2{N8;^6Z-mBmmz^K{B!?|{j$rF{?M;l~HUzYkW zjgDrD`puo=Gtt_|xXWp>7sxoU5JZH5ffFbI!(2c%2+uO}b9kG^eD#X|Zk4iV0mnT( TnRxBrOoIKfK=V<6(_{t!c-d8! literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c13576a29c98bee02aa47f646f5f170f9b7d83f9 b/fuzzers/corpora/commit_graph/c13576a29c98bee02aa47f646f5f170f9b7d83f9 new file mode 100644 index 0000000000000000000000000000000000000000..95bdcb90c1680ba13deaa6c9b19bbeb8228d9deb GIT binary patch literal 1523 zcmZQzU|?`|5Aa}QWM=U9ba7)~1`05gfCvz<0E+qaFhV%oK#F8+3)I8|#;i~p!oP3V za76ef^Ebm3o5GBC;a=&UU03Yd%F6C12(x9(e}4Gh*Jqs|`wD;r5J-TCA6k7|PAk0V z6)^ZKaAQ)NVpL)9e`K&M(QP6!|NnnJpe{-<11rz~WXuNS6T<93HS7!m_rLabrLhWK zY1S*@&(vr!?l}t-=U`w^x$m10|0JY5V4rDn&^0-g3;dfDGO`bEIxAw8dhUUl@o}{* z?FT;LGAvg?{&_WX?}cjqSv?&eZ$9@u^5>b8?3=hB%OYQL2<)Im5TXVjj5m#80RuBM zCOEub9ys}z)B1nGgv3(gu&`(6vL1vt7qq7Wea8Y)gWdg|1LA&4;vS?ICGJ7#09)L* zp^2l$|L0lnpDk_Svc{;&kJ&b~5Q+c|j8Ijf+m3roI#b2(B0iU9KS z5G=}}G*SRUtTai+VI`I{iyY_BG9-Th(k>_-A*q*oX*U{_5P*R4;;RlN#5=*o0#$?9 T2wcKuJ#d=!e#!j9o4x`7|K?al literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c14edf1d34f40b3cc74772c81ebe5d72172cc662 b/fuzzers/corpora/commit_graph/c14edf1d34f40b3cc74772c81ebe5d72172cc662 new file mode 100644 index 0000000000000000000000000000000000000000..63b1e3900d2347821dccf0c163ed651f8c574a47 GIT binary patch literal 956 zcmZ3r3I_gz0E~m3W&i?b_W%z@MrH&O71ixJ2Kssd3s0VIMT(#${#q!=Be2>63!Jzaq0s#Oqe6q77K6IjW`T4)-P z0}#Z<0^lKs#6S+j%gDh=JR8Y0Oy+c;JAk4P5-tr(_b84;3;rMf|2si*5nLII|B;Qc S!3u5P9a(0)Uji4#%K!itV(`2G literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c2789364cb35d111f08f924d0d7550ea9785c61e b/fuzzers/corpora/commit_graph/c2789364cb35d111f08f924d0d7550ea9785c61e new file mode 100644 index 0000000000000000000000000000000000000000..0044eb5037b82e05713a53ac5da5e4ca2e3ebe1e GIT binary patch literal 2130 zcmZSJVPJ4}5Aa}QWM=U9ba7*V0E+}q7bp`>vA|ga&R_((fL@phXcsQb43xu$K|w_< zW(BIH24(}ALkP12)sTZZfcof#Ie~VeV=kZ=2y+vOfy#&m^h!rCdvK*CWN~b13M58s zngXfAm!`1AC3={H_~_wIbfA)`5EeG{qLITI7n{~`fG>W~oY9w#Mf(JMW{?7@|mki}`8uCT=&#o-Q%6b1%fQ1}B05dFrq?k1ytk3!pbN0u4y Mm&`isG=I}q0D=S;8vpR(V?rq})WBwBjrr;o|J^EO(E^TpdNSFg z_io9F$!ASF({pr7UiVEe1#Oe;4ZnG}zyEyx-{zy-tM@9n1~6*&@o=u4WAa30_R$8J z(wC+FOQWNi7=iYJK-6z;pNZB!3{p;$y)2UVo4EkR;9h{SaofL^T>H`Nh1rClPmll@ z6e$K6enz;2fgj?3V`_#!n*YsQa?j8H9wPUUB`j!$ae#``=jyM7Q>Z0c3N1RYHGG1f z)6d|~PMhlAKinl<9i0MAhKmDTS@oC2zx_Px{S&6kyYp1;`})T}2`LZQXPUguzA{?d zIe5=GtDve2OL}%)K^CG#)<6zhV%WITAKB@jvhb&%Xb`}XzX*lFpz}YD5)x1Pn@?Q& zi@UJo`!|;(6%5DKva}!ggv+p8U6$wuDZu$>^>lu``P}!&pJz_8Z{mI|i+sr;u;ad6 z!x7<|%-;-CYzi~lg?pvRNWbkQ7VU)M3tfJQ#UJ5_x literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c36ed796c1bf839668db8fc3475a2ffb32ad8ceb b/fuzzers/corpora/commit_graph/c36ed796c1bf839668db8fc3475a2ffb32ad8ceb new file mode 100644 index 0000000000000000000000000000000000000000..77dd76b6b37c9fa659444f6dde19e046e680490e GIT binary patch literal 1708 zcmcIkNe+TQ5Cj$XkN5x+Jh?zz5)(Z51fSu-qd)NE2mFuk@an~2H4M!lO$H=%(nC$z z)EKIJo)*H}9JaRIe*GDmgcUrDLFF8MAX8pT)R4wN$RRk&QNuZgKIP8eV?}ga&tD#6 z?405!t-VW%2~D!wDmw?oQg*?cvWFTeo<_z(-OdQ-2&f7kRpzcGb?W+D=MJfVKipO1tYAX(gy&!S=FH*aGlq(e Vi+yQi{%|yR=rkQ6H_$Fr>kB!3wln|$ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c41ec9dd94427423e4704721e7f21eae0c44ef20 b/fuzzers/corpora/commit_graph/c41ec9dd94427423e4704721e7f21eae0c44ef20 new file mode 100644 index 0000000000000000000000000000000000000000..9b828b8cfa8f172381c4f29bf3c8e6df508a9e47 GIT binary patch literal 473 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2EFd%yTcBQt})r;8f{1XuvsJ`g60g|mxe2!zcCq|mVl7BQ%rq61sQC-^!2 z4F2r2ss8=LUDDOjDGdBT^`zk2conPm^Jz_;W#;GbHjVk}7608TWzhnTdwMe2qxWvf ziOFY8JJWM?OJ4U)F9mIr>=K+^hF0xCSt4_VIA8on!JuW%khqnbMb~ z{!62ynWBDk`%JX}8R>-^?ZV{Os=`at~R;f@T;8s5pIYW#q9fvn^b8pL6+C z(P<}3a+v(;-aJ3PzGWJ_jI`T{kj;Xvucnt+KU-1mQaS&+#f$ILYS??vy=|Oe%zq-K z?`hVO<#%4he6uKd*-|*)|E}`+hDi(!Z2X{vH>q)jKYoTtGIeFu zUl#xN^Q`wzm@e`|k`1;cT*EbRwA z;W8{&mnFJQd^L0Lg=+p;J)IwKKKDKH=b4l2o46m#B42U{?6_~&a76ef^Ebm3o5GBC z;a=&UU03Yd%F6C12(x9(e}4Gh*Jqu;@a8VC1(FO55+LG-R^OJ>3NLyE4E_q-nAD~i zRTw-CD9l^{l4M}u@P2vVfvVy0{j4+mJxr;YV6%-2D2E7{KeESkBiZA=vN<$*==vuqFYDuf zU&(zO*@gZ`Fp~pCu?utn5J)gU3u+*n%8|Sm9Lvy9F(WQiWJw2)??ChbJwRfBZj257 zV|1~oZ1Vi$^DacMUH9oW=S&7MpgF9tv<6HTZ%pfMGV1pzw0(DEnel$ftiw+8H+=;F D;lrE# literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c45ec3f594abc15de0a8cc3ad748ba23cb34ec64 b/fuzzers/corpora/commit_graph/c45ec3f594abc15de0a8cc3ad748ba23cb34ec64 new file mode 100644 index 0000000000000000000000000000000000000000..6a711bab2a5748c07dff31064ad798982f81a767 GIT binary patch literal 81 zcmZQzU|?`|5Aa}QWM=U9ba4Z6fxyDK$}t4Ol!j0YtSL|i7D^AO!NoCTGXoF;03$sI A^8f$< literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c49004d980961f288616a4eb9ebf68123fd68ffa b/fuzzers/corpora/commit_graph/c49004d980961f288616a4eb9ebf68123fd68ffa new file mode 100644 index 0000000000000000000000000000000000000000..0b5a6bcfefab431e9dd24ed4ccc9efea9651c03a GIT binary patch literal 129 zcmbO_%goQAL8kO&ssGaGXr`#&+&&YneT=&p7&sXamc=hGBq;)8|%39@{e8!d3SEr8Lrm@RNyPXL6EZF+WpT+y- Xf$iTIDjB=e{QN47fW|Q}I5GeLI&>T=2y27gZ%HwJ8g4=9L%L-2zo zt04fS3Y&H`F@7MQCRnwfPiyKdGe3v7Y0Ouz`0rLJixzO))04>_EzAzI6A1Qh$%)Bl zO*_+bbW2|MO)mv)lk5$@dAGm+eE#3&qui_aD!2wPYWDGPuAO7@L}m8T2AR^ArT$B! zqnV<9bNfuR_A%~qn(SqfJm1VE_x$YdA#x8{!h&WP2dFrGZe`@LEwe3Lb)R$jRMBZC zOLCa}>fSs*zP@D|yNtBkiIB~Lt*@q+SUk@1HPT-kqm%-`79>Nl1CXKGWoN_Lb4v&cS=mSp`*H zSn~aw%aIC(<7!#j4}8L9SgtNhbes6fuHlIAP3CWgDK>=}?ZUm%J-e>hwUw12M=4Fh z9vHa%bPNCe^bCK67rg=oe+6z#YEz6V44ww`C^IN2VF$?J3}>U~o@6Sz|0{{AfqJC)gZ8?oMAO|@AP$f?c&-6c9{$P~KtNn0V+qR@te>qYcd49z-QvafX*KLc2eyV!@N@bZ{Ml(!{riWzq^qM-UbYm@_rI$=KhTv` ze_8z7&$AB9Ry=NQ!*097G`DD*QVZi@n-jk(qqUub_nfl|s=Bb``!|;(6%5DKva}!g zgv+p8U6$xJ@zu<|7pnPZ^>lu``P}!&pJz_8Z{mI|i+sr;u;cz@FN@^;W-htsXMYco zquBi>*&BZIZh!yz{J+gdxmPnlfD-50Im}N~W*=>kDScV$zcf0UDe5=3&qQk<1}Ue> SUM5tuKYYT=H%{|6eFXsN&B2oZ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c6b661e976282051285b913b3728383f36103ef8 b/fuzzers/corpora/commit_graph/c6b661e976282051285b913b3728383f36103ef8 new file mode 100644 index 0000000000000000000000000000000000000000..6a156d2fdf34a9809d5ce1b5b734653b2836eb86 GIT binary patch literal 792 zcmZQzU|?`|5Aa}QWM=R;^>lG#VBiA^VFRo{L1HiigM^>sJ1z-<`(Jyz(pZJAH0zb{ zXKJ(<_nZZqzyZWOKrG_@NA_|lYwZ<5zmhWxuLoRM_b{bqg3UHApd3p9kYL~?0fXF( zfq_Pu4R<5d6@oxvkSmzK8K&42X0!|UO84x#V%Jtyc0WOwEo1)k!}q>E>jWy|E`S&y z0iu3r^=&z=@S<11;IF`qNo|Tzg~8K+!pu-Lv!{SOSZ4siMam%c2Y5=F7f``>`zYC5OO{`*saSgm2O)0G}{j-kqm% zA1PGqf$kix;g37G(c_9v!9T>(FY)1r8lG&xG(`x5vNS1}?f?J(KrKjF9a8K8v$P=g zVvjWiq#gp;8(=IL%>`tDFt-s9gJ?K@1!n_=hyft2U;rtbs8{|#N+6K&JW$LE42Azz vuO>t6qY_C|_p>l?0G$acrE%jr0stNY!!`dXP$mCxGBDUzCTcqa^9dgSN@Yc_ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c871d135f2d3117b326688355bc0fa6f26d56cd6 b/fuzzers/corpora/commit_graph/c871d135f2d3117b326688355bc0fa6f26d56cd6 new file mode 100644 index 0000000000000000000000000000000000000000..6ead612d79ee8c92fe3a48a17ed7cb8cead31614 GIT binary patch literal 83 zcmezWA1h$^Z^+>69^k>q=)=Ik_9Ub{V4rF7I{QikZRg-U=d6ONE+jAc{>|k`1;cT* TEbRwA;W8{&mwkQK$p8cZ0ktj^ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c915b02265a27d185a8b028305f082ddb3ebd704 b/fuzzers/corpora/commit_graph/c915b02265a27d185a8b028305f082ddb3ebd704 new file mode 100644 index 0000000000000000000000000000000000000000..1960dfb4748c0d3afb766a6706a35c5c2926aec4 GIT binary patch literal 201 QcmaF=e&_=RPZtjc00M!x(f|Me literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c952d38b3e642db4795d7f954b85f4f6d2a041aa b/fuzzers/corpora/commit_graph/c952d38b3e642db4795d7f954b85f4f6d2a041aa new file mode 100644 index 0000000000000000000000000000000000000000..b8ee305562ef53653c177f056b10465155cb2998 GIT binary patch literal 107 zcmZQzU|?`|5Aa}QWM=U91ajbj5y(QvK%oW(h7C}_!0;WRhF#|GdnE7~3fO@vfEZ{H FBLK?-9J&Ai literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/c98ee52065736c4172f6ee0c31977bf1b560d685 b/fuzzers/corpora/commit_graph/c98ee52065736c4172f6ee0c31977bf1b560d685 new file mode 100644 index 0000000000000000000000000000000000000000..f8d7a23f1c8b9d14575049095010ee4e2be4d2ce GIT binary patch literal 471 zcmZQzU|?`|5Aa}QWM=U9ba4Z6H5@eX1E3lVzycIu1&MMXFpvr2p@=bX0{Q5e3n&J{ y+~~Lt1%PG$0|7!M12;$o77371NZ=6?8!M9{_hU5?MUb}k1H%pxbQ%mmzW@L6uyvWXFK6(9`?c_@Tmer3;9W`76r%jCc zW>NC8rEsqQUFG?Kj1a9RuB`gY;@^Ir_5R6arrmie_kI22pM)@fGfc55%xD+xmG0Sf z#SWW88^1bu==vuqFYDufU&(#E0B9Tt0|ATw5s*WT5Ds1U={Dy~1~H%V90mNp52q*)o MDuxSS4im#10Fa#s`Tzg` literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/cac667320e99e93a796bb89842de4675735eb4a4 b/fuzzers/corpora/commit_graph/cac667320e99e93a796bb89842de4675735eb4a4 new file mode 100644 index 0000000000000000000000000000000000000000..20e9db998fd5f2c80d8dee3baa23716a8a2fd096 GIT binary patch literal 353 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ@N7+8S}FlK?$NiYE*&4z*>*oQY4w5I~a zSPFmy5b${a+REYB+;sor{~ddOuQ2{{WB1vo-E#HrAbF@77Vnn_wtr)&Wb97!^Q$zP zRrfP=PVYSCii`*lvKs7=8E_87l#A?m;dRs5`Oh*$Fj(m90EJ;+cg{!zRCQ} zaAIw_gn$LhtdNDT<5xSlMJ!$vu*KQvITe45M~FeVP_Dy|FyR(jaBGMvt9{*rbdf#&sm^22N3fBv55B{ z*~_J@wO0iFO3p029&lmZ!xV^1pJpvte&>7U5-gEJ9OF9D2}Kj8AmfdQrbF&rM{52@+r7v6#dTLCge g>YrY;wg4#qp#%;zLn%OL%$mq)*83&%4{!Pk0Lr~F$p8QV literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/cbdbd3f320eee627097778f15b9fb2c1dc2bd15f b/fuzzers/corpora/commit_graph/cbdbd3f320eee627097778f15b9fb2c1dc2bd15f new file mode 100644 index 0000000000000000000000000000000000000000..a922018ee49327a9d75f878829dd1e902602c329 GIT binary patch literal 2318 zcmZQzU|?`|5Aa}QWM=U9ba7)~1`0rc1(5Fp<1p|8Svaw3KVR#s=_S_BR+PI`&cAN) z;`_83_TF=E8z&g^pGfI@nzdy4ofk3REJ|Ls6wdd*t2{rDf!`R9dHC#t$pP)unmWta z&*5zv^VKWe)DdB|M~pC%}2Rc z?^SROVASm6;aoe%=@~eCE{P_BoY3wr6ZYM%E3%0(pL<@$Z z16#u<_&NOy{_M1={{6#U($&!^@L+Id)n69>_VcXwPna(6&QrPX>mUClqsY4SSz z%4lup;63N8f~qbo`Tou2NCm@jwJhxiKH)MfSC=KaO?)+T?}cjqSv{Q}Z$9@u^5>b8 z?3=hB%OYQL2<*6T*KkDmCi6GL6#V{Ip@IL=lfl6H-=;95UAR}eXV(?vAjKMSXbx|u zOZqhA^!k=*>@w1BCqgz0 zw!WHPV*PAIxl85z>lQD*Ppe_?J@>Y8f-(Pzl)k4~OO{)Fdl7S|9)TFAy!upjEQ qX+UQ%L%qS_%?jj!Fmed7{f7!Llp2SHJv*26;Qf+Whn?nc`U(KX`fZH> literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/cce7355f826bbcf3955394596d358abc7df6fe6f b/fuzzers/corpora/commit_graph/cce7355f826bbcf3955394596d358abc7df6fe6f new file mode 100644 index 0000000000000000000000000000000000000000..9b780380014deccef0b8fbf0d5ab92a268bf6eaf GIT binary patch literal 2458 zcmZShFU#QU9^k>q$jspH$?f9C00fMrV~`dUeLyb4+*U>&+cMk2RrfiUPZgbZvLuJe zukOwB`wzhwPVtBE6)7yF@PlhZ5<||U1DJlH<m474!3|ui%Ok)!pB>4yKGz_8fh;pzy6DO@FfMmPh53=05H(5j#S literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/cceff2878a558166fb5bf2a0354c1be31dcc4e21 b/fuzzers/corpora/commit_graph/cceff2878a558166fb5bf2a0354c1be31dcc4e21 new file mode 100644 index 0000000000000000000000000000000000000000..94fec1bbc64b3a3b0272e159cd018f145d918373 GIT binary patch literal 2605 zcmezW|G%oUdjKPkZJBN1s{5SFr;1KHS(3x#SNG=m@%1g!*kz>MPK0b0Y<)Go#QNEa za+k{a*DYRrpH{=(d+u%H1Y`aaDSc0~mMp*XBIcV#$;+0)`Tlp6=La(I8#6HQGvLK1 zNB|6q6axaT0lIadfNDRV*3?p&>E#SDPCzCyT@0OgHeAcuxJx90X zb>H+-&^F25@SAu0`_Je9Z9dAqdar_O0HbCf59iuBCQnpmA8n8+eOcNmH~ zL~9=gDW}O^7Rmd~TyoFP{vIOtkR>c=hH-$3)9321q(l||sD!xRj1KNMLvlZ!6ifA_ zI#~RV9DjKHk0Zwx9oQN^!O!Vu@Mot@_3t0hro{eb`3{_Z!&)~OtC46(TGdMjxF*hau;NYJnTqh9%s)KGwx l;*f$I=s^yjsF!a{>uxgY_b9Y|cVwCIe#xxEPV+Z?1pp>T%(DOh literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/cd96909f3ded7aa54bb2ffd2f2f47f8acc6f99e2 b/fuzzers/corpora/commit_graph/cd96909f3ded7aa54bb2ffd2f2f47f8acc6f99e2 new file mode 100644 index 0000000000000000000000000000000000000000..22bbade2df578a0ef36d4104397df80b03f27afb GIT binary patch literal 81 zcmZQzU|?`|5Aa}QWM=U9ba7+&|NonXvx{R0P#g&OP_ZshAP_8}?Hs)4oK;ZO8vP!H Sw(pKCGu|(mb=YbCrmp~5KokG~ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/cee9f69d7d1a227833fba127a529ea2a10341da3 b/fuzzers/corpora/commit_graph/cee9f69d7d1a227833fba127a529ea2a10341da3 new file mode 100644 index 0000000000000000000000000000000000000000..2fff45e837b71523b4eb8d885eccd23b3235bcf0 GIT binary patch literal 68 ocmZQzU|?`|5Aa}QWMc4NwQ5zvs%=mJMPK0b0Y<)Go#QNEa za+k{a*DYRrpH{=(d+u%H1Y`aaDSc1XmMp*XBIcV#$;+0)`Tlp6=La(M@o=u4WAa30 z_R$8J(wC+FOQWNiqJDGxOtki4kaC*rWs$t!%q92y?C&9R4_U&3W*7&kIDM}EN{TZq z!Okc;ur+*wpVQCa&rX}_-#^?Xy;s3CfKihU_CtaJYCpo^(?m%Qzbwq~<2Pnt;Afx! ztM>D0O`T=t=kPX-`RWz_-700#0*-rnGTEc|Zpn$sXH7fPb975y_f0PaZIkQ`zj?R6 z|9t-6=A+!J2PXUw@mC$40#8P+toqC1-+rF;{t46N-FYhaef{H~gp>#DGfiG+Um30K z9K7e8RZ!K1CEvff9I0S9u9l_!z$aXWPx# literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/d0ba3413d5706de17de64824d78233d48c6efbec b/fuzzers/corpora/commit_graph/d0ba3413d5706de17de64824d78233d48c6efbec new file mode 100644 index 0000000000000000000000000000000000000000..96c82076020b69ccc60902def0f0dea659b16e05 GIT binary patch literal 97 zcmZQzU|?`|5Aa}QWM=U9ba4Z6Er7HSkOl%46K5C45D1$!1wtc81u&BlNFp#Jk8PQ4 Pp~L_G|AE3MOBizi)|d<6 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/d136511364a74973b009f2be9b021d4122f71a6c b/fuzzers/corpora/commit_graph/d136511364a74973b009f2be9b021d4122f71a6c new file mode 100644 index 0000000000000000000000000000000000000000..a663ab9152fd8f50dbb691dd64dc546ff4e2fd43 GIT binary patch literal 655 zcmZQzU|?`|5Aa}QWM=U9ba4Z6VZZ{&_knO&ESy~&Lm+I{6qo`A2KEL78^qE?<&w!` z0qSGLf;oUn_^OqcL;e8(jraQ|y>R~oC(m1eyX{!EP)as+)iLYkvy->|RYfb0Jo6miZ{CVai`zG$kvdEVl0z2;8H5?JX$^1>< zAjPIIqg}XHx@XrFySB2j`w7Bq8S|eXzW4Q6C(v-XLx60CA6k7|PAk0V6)^ZKaAQ)N z;`+YeX+U8nsAD<2UmiI5m(%)xL2U3J%Zo*2ljk3wcOiQ1x=*(`XEKNZRkFfV`b52a nV_J6;WGE_N)bCMf`|ijxTcBQt})r;8f{1egKYKGAFtju@Hpz)F9pJpvte&85)Ni-Y*ZF{L5+mzhFXQsc~4? zvvXMw!kY`)Q-Nw&Kx!c2Hy9Gn|Np3|1}T+bq$uoi46Hzf$e0btCxqF7YS<|9dccKs4^tp%nwa#P05pM{;S~^rXewY^ zpdlb<@c=ywp&@+i`THC7@;BiqLNAii(8?ql7CvCd4PfCnT=O5ZRT$85*047~8HA|+-~Rsxs=;L(NE{eL7?=wv2EyE=MPK0b0Y<)Go z#QNEaa+k{a*DYRrpH{=(d+u%H1Y`aaDGWT`zqWEXHaFe>_`wFZt2CNb_cL@(?>y#;i$FPcs2UESnxK7b3=hJa3))jb znxGQcEs!JAf(u>T2C-Umz24SK{Wx(-$gekLC$d9*qF(M@H{qk+tIX+|Z&gC$9CrRq zo4Zg;h=E~GPbPcx-Yq#X`K)PYdX8?%V_;xh_&R>IgImPnMFCr!jjjXD0VN^=7??uO zqJyL80$BLqqzy~rpkxliY(O>w;}5<-S62OH@ozuRdjEv!^6os9`@a71PeRHA_L(NH zv#*TSb`IWi&MK(t!jkXbT#i&Q99PTIe&7=>!*X?5qT9q*GxuJo=AYHm`SIp+-y?sX zImy0>`>`zYC5OO{`*saSgl{r`Gfc55%xD+xmG0Sf#SWerAV51QpL-r&p8=56S6u#_j@epW?%x=ljbsGA?iPxi_~(zVbh8OajV*k`@R^_&L7gf*53kY!F65z*VM` aoCtuHLiOwd0}v0dAy9c#Rj_h=H3I-x%fPb$ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/d3714ec4d3acc6262295b0fc99c6ba699f5bfe65 b/fuzzers/corpora/commit_graph/d3714ec4d3acc6262295b0fc99c6ba699f5bfe65 new file mode 100644 index 0000000000000000000000000000000000000000..7f6e30995bbe5223d0098d49b1b0225972d4ac5d GIT binary patch literal 594 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2%$!{uLm+I{6bKC>!MZfa1PEggtN;X) zI2I#N854G_1r#@6(g#Ui=;Ahr)tc+|wqEMTiBm#;y(v2jfZ`ww1S~#LFZZsS@KNto z=5)=sDxq->JO8H5U8p4ll;eS_5%8N>TP`7B!ZIsl;p_O-4sH>P7X@r_HoA^%j`!0K zOpP9$3n~s6f(<5uz~g?1zXr(t-{dZIZT;0|^=h(+i7(I}Owe%H7#sY@=weaXEKmiu01V|x=V{_B}kN=a-jtol=J-Ut+`DeVN4-~>(>33!gvL4S{F^p+p_UK>!=9c@_UOG^a$@p9o@7MD zaDTHP{0|dDgaIf#kiFLcGz1(Dlz5N2!Gr2RkozchAZi5T41Xq&T`WT{{87C}IQ)!g umwp+E48OE9Jx90X0Tc1U*YT?z+~7GDlwy%nE4*-ECpvo(_CH` z7I56tlgS>vcS}x8K5N>Uo}*jxx^H?ZXq#lK{N~;M{`2{Nn~!s^-mBmmz^K{B!?|{j z$rF{?M;l~HUzYkWjgDrD`pxY#(b~tj%W1NgMe=@4m)!HSzlX>@WC;tJVH}|1^tqLh z$F|J0aMgXz=@~eCE{P_BoY3wr6ZYM%E3%0(RUS$1jMY&7m{OcAkzE7)R z?>+anae^^_U&@I)OP(&zdJ*%@qU2>u;e7wQ%JTzVS@oC2zx_Px{S&6kyYo~^(6#D; zw4O-mdz!Um`5jzZ85r1rfd#_PeUJQk<|O+j?#Hr)3xs%J#@_e!kAD(U9^kppG zfnLPG=s^#THEcm|p10}MrP52&9(IOl8-J<)Fk$7!Zj6|O1vyb6{%R&La!^$&skKoIox*<^qa=FgH4`Ljhpf|3H9H2^4|=79hn6V#4f!SProtNYd1Pd!W4_2S98` r_Z^6j-G^Ym@B*cgF~}IGNGTFv1c_qxp$t%hJRg#5Kc4^t1A7Ai_4G7U literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/d51ade0715bcea7decee2a045934599a10c1b07a b/fuzzers/corpora/commit_graph/d51ade0715bcea7decee2a045934599a10c1b07a new file mode 100644 index 0000000000000000000000000000000000000000..2403b35513a60cfe6d3f9a2fc0f1637dd4d6d4a5 GIT binary patch literal 227 zcmZQzU|?`|5Aa}QWM=R;aB%~2LBPV_)5QnGU}OQ2M1n`?>IBdPK!&lRi6L`OLO5_` j96&w@gFyj=1ry_7&|}~PO29CX3AUdP$bexWbJJG<5#b2` literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/d5447fb72c97462a3f47c8b2d55deb0afaa225f8 b/fuzzers/corpora/commit_graph/d5447fb72c97462a3f47c8b2d55deb0afaa225f8 new file mode 100644 index 0000000000000000000000000000000000000000..07e14a4b03efc6a61ec539d32f1579dbee3aa49c GIT binary patch literal 1113 zcmZQzU|?`|5Aa}QWM=R;^>lG#VBiA^fdMy&WJJSgT$nUam<5Vifix+YfkDF0@g0|h z!2PeiU1_XBSDN)o_%k(HjC;-kP2vDz9v~L+{v&(2l(qJXpkK+Eh1UZvtb3SJGr?vX z7f_B;{VWAQLl}5Tz@RX~z(A*Bh(Xn@!6kuDoFAwe9Rr0h04xqbGy^*-CRIPOS){Om zwhmnUBgG#Raq);X*at)WkrL+M`2PR@|8G#d(NBzlcA*$sO&!!0GS}b N2*E%K%7Th90028{6`TM7 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/d676f5e7efd6de6f2e1773231479471d2bba7261 b/fuzzers/corpora/commit_graph/d676f5e7efd6de6f2e1773231479471d2bba7261 new file mode 100644 index 0000000000000000000000000000000000000000..f9756ab7e5ae839f8ebcf6e92c0f97bb7262c255 GIT binary patch literal 37 hcmZ2w!N9;E1jMV9{{LSE1lLu79ER&~z|g?J000bT5J&(3 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/d6a21eaa08a957d8f428192e193c2508fca2c218 b/fuzzers/corpora/commit_graph/d6a21eaa08a957d8f428192e193c2508fca2c218 new file mode 100644 index 0000000000000000000000000000000000000000..f845fbb6e3a3960982cce220115a027b556d2b59 GIT binary patch literal 179 zcmZQzU|?`|5Aa}QWM=U9ba7)~PyvcCSOD2R46hh8Xbu<|7)(Gm!ol(NEz{U#q}@({ ZMM|unttfY?oNvkS;`_83c81<_Zvn(MA)){P literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/d778052a29539344a9e3144e262e68df9628ebde b/fuzzers/corpora/commit_graph/d778052a29539344a9e3144e262e68df9628ebde new file mode 100644 index 0000000000000000000000000000000000000000..beace901be39ff409d08fbbee89c57d66e1c71d0 GIT binary patch literal 330 zcmZQzU|?`|5Aa}QWM=U9ba7)~U<8T)fd!D~17WgQI8RV7H3GuAHSE3T-ZoA!=0B0r_cUwC@;fhLzFCyKY$=@Ye^+^apew8XviP^3 zXT5*Iba{84%6(t|_$MLd0sBmo*V$J_YdZ(;IcF7Abz#Z(Z!Skv8IG%EX+Q7@mtncO zEYZ!3VdATqdoNV;&+6&?c=NgMkw4FzWZ%U7SQhz`Ltw{!yM`meH<`ZyUCCSkaVm%R z%L6C>a$5f{n2=a%40iE@@aBT{RG>5qSk2j|-E#HrASMw12LcwLmhInGmoQW^cBlFI tRT|Bz`x!c?cOG-aMW7;fh{4fM7(hk`?Yq#$ZBPdTAUnZ<$6&<9003ESgnIx0 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/d884f6944adfff7cb41728062bf91cac5cdacfc9 b/fuzzers/corpora/commit_graph/d884f6944adfff7cb41728062bf91cac5cdacfc9 new file mode 100644 index 0000000000000000000000000000000000000000..f6de6519c2da8eafb2dee64df79fc7fe62ab719b GIT binary patch literal 466 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_5m?aWfp^kkYpJcSS*}f977<&tSJy0Mgq-c zWbkM70P;D|Fei`?#J{6 z0hJ5m)q)tm|3d(S9#k00|E~??1ASiZQaS&+#f$ILYS_>9PH22<%zq-K?`hVO<#%4h ze6uKd*-|*)|E}`+CC|wVi|aoU;n5 Wy0GN?H| z>{<;(`Ghxf|^LGvzjaT{#cn(OtpUh2n*Q$l{dDLX;(P&F(*Q7`wN1@b|T z0@*6!{YTDyiVuID?=Q#5xV+8h-rN@X%Kxx22`I-6)g%E6Bm}+u&Wo6D79}rR3g?58 z0>Ysds19`u0h$9ciU6i__`#fo8Giey9DYct3QrI~!;d({*urwyh94;L;7WgH^iO}- r!X6|xBEx?)|5LgA9L@hjx&8rF;OLb%djnXI2!aJv*@9|MZw3YcKh>^- literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/d926fde818c63f7b34f38c9f018bc833bc0bf7e1 b/fuzzers/corpora/commit_graph/d926fde818c63f7b34f38c9f018bc833bc0bf7e1 new file mode 100644 index 0000000000000000000000000000000000000000..fe1e2743e5225c6215fefa1fe04fee38eb57d810 GIT binary patch literal 409 zcmZQzU|?`|5Aa}QWX}9_xl8&+k`nKqdqLaZoVioQz`zHTr7C`!wPg977ct)~N?x`U z&iB8oJU`HtRexFh+t0J!KViDO8)zRGumVYR3=%*RBglu``P}!&pDgVMKH*pcg&*i-jJ91QyyffN+` F008VWPZR(E literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/d9d542d7c56774143cb6362e5a63739055469349 b/fuzzers/corpora/commit_graph/d9d542d7c56774143cb6362e5a63739055469349 new file mode 100644 index 0000000000000000000000000000000000000000..946106f79aa6f642a797241fad77602fcb7a71fc GIT binary patch literal 2801 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&F^tz%LLF$_6pX z2agD8WdSN+1u5b{U?3C31CtFfaZVr~9diN2K$sf|>jT+j1MWH$05pdi91aL8;6_v3 z;b2c7Sr4~~EC&4p9^L&wuMBAT4Y>Vw*!+*2R8i7AdfEo@v83-`U%-KinJ|$Jh9zUF zg}*G&BxDC-aTp{MBBfvK;g9T0WdEZW53>rVHCQ}`Y%q)sRE85!n12;83Ldbf1pN

DMM3&V$++(E8O7=v4w~1ujo^pki21R|je8 zaOc8fuM`EqBLGxjk=!7`pDwA_@WF2n%-3+gkd&BcRQ|vngTmki@~~o*NP%#i=5P86 E052sMrT_o{ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/da99bc9ce5b831f132dfb2eb11b8537e5cccfcd4 b/fuzzers/corpora/commit_graph/da99bc9ce5b831f132dfb2eb11b8537e5cccfcd4 new file mode 100644 index 0000000000000000000000000000000000000000..91ed5b2f78128ced0460f9de1849d3ff7e7b5c2b GIT binary patch literal 120 zcmZQDVqkD~5Aa}QWM=U9baB&R00Rpk+XupAv2b>A41us&Qy?^mWCvm7aia~5t U0FnX8gJ_WYb`Y0=ftQg1076p+jsO4v literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/dabff2729fa69ab507fb00b7392aee1262056a29 b/fuzzers/corpora/commit_graph/dabff2729fa69ab507fb00b7392aee1262056a29 new file mode 100644 index 0000000000000000000000000000000000000000..9318cec858105e80ba8846fd83a11994b38a756d GIT binary patch literal 296 zcmZQzU|?`|5Aa}QWM=S>c5wr8!GIM=vJrvVfolH!|NkFEgRlZBVBi3X(EtOD1euCz hHYbpej=6whAk2*eBfAZ#1QZrvgQ4O;3Wz)yIRLkg3rzq3 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/dac4f4b91e33847bcedf7c66ef6e4ad0181e8ad8 b/fuzzers/corpora/commit_graph/dac4f4b91e33847bcedf7c66ef6e4ad0181e8ad8 new file mode 100644 index 0000000000000000000000000000000000000000..9587c539ba6b37142896eeeb4a161583b28132fe GIT binary patch literal 153 zcmZQzU|?`|5Aa}QWM=U9ba4Z68PpgUEP!ku5F0ySZ@?ms-xwAPXBTu$`_KiTd`2J* E0Cfflr~m)} literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/db10ff6d01c7a66aa1823b9f99193590ddce99c6 b/fuzzers/corpora/commit_graph/db10ff6d01c7a66aa1823b9f99193590ddce99c6 new file mode 100644 index 0000000000000000000000000000000000000000..2d8d099866fa4ce369e99c9e757d239cbec3fcfa GIT binary patch literal 252 zcmZQzU|?`|5Aa}QWM=SRwJI(&G;|dZFfuT(0%aH&*b!KlA*7rkfPrBjP!b4u(J&v7 z55qi2Y?v4_9seYxJYb(`@;dv`!z@5?76wj+KmS2A se#{D#X9X$((;zk(m<^~08-_XB0w@mxFg`9ie!-%{vz9+$2Py?)01G|~O#lD@ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/dc47c5037be68a2747ff8a9fa450e1078a5ac5a5 b/fuzzers/corpora/commit_graph/dc47c5037be68a2747ff8a9fa450e1078a5ac5a5 new file mode 100644 index 0000000000000000000000000000000000000000..e4ac972c2f1c55514d127fcac0775a5203188347 GIT binary patch literal 209 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBIk+u~;~}I0pa!|Nk!o18WLI3`hb6umi9PCLjsM m%s>VR0|6@(vjJ&z%)kN^#D!rRk!hfE1YiU*VVHrzkpTeiBq7iM literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/dc760f136b123e38677aec72853e3365f08010fc b/fuzzers/corpora/commit_graph/dc760f136b123e38677aec72853e3365f08010fc new file mode 100644 index 0000000000000000000000000000000000000000..855c7b3a7c32c265afd567f6981ea2f912e6e608 GIT binary patch literal 602 zcmZQzU|?`|5Aa}QWM=U9ba4Z6fk43m$o6622QopJfe#7mA+eFgiDEy^TC)7ki!8yFc^9R^=trv1_mPli`j)= literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/dca41b901bf1612d4197e6a450366a00ac036ec3 b/fuzzers/corpora/commit_graph/dca41b901bf1612d4197e6a450366a00ac036ec3 new file mode 100644 index 0000000000000000000000000000000000000000..9eec2738f60b9738458e09d596f63740b242761c GIT binary patch literal 346 zcmZQzU|?`|5Aa}QWM=U9ba4Z65dwT54l9GRi(?3g)yTk_0-_;+y#dPL2GW#Z9-w{* sW@KRaj|w<|a#*l17BLKUTtK}bjO;c}G(NH%xonvG8F)c%1wpWz0co}u!2kdN literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/dca62f21fce50d1c8c51b82e0d7eeedc6746e652 b/fuzzers/corpora/commit_graph/dca62f21fce50d1c8c51b82e0d7eeedc6746e652 new file mode 100644 index 0000000000000000000000000000000000000000..f8188c6918a6e7b360e74bcac223fdfeeef6e4e0 GIT binary patch literal 169 zcmZQzU|?`|5Aa}QWX}9_xl8&+k`nKqdqLaZoVinV>T=2y27gZ%H=r62umG}sAWRmE xCTADN5C{jE!p62I3?uQi!cOaFW7DXK&L8u literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/dcf4b6addda69040f792c9b860ade2af0b77a14c b/fuzzers/corpora/commit_graph/dcf4b6addda69040f792c9b860ade2af0b77a14c new file mode 100644 index 0000000000000000000000000000000000000000..6cbb0b7210027ce8455745d211a16e60648ef774 GIT binary patch literal 1888 zcmZQzU|?`|5Aa}QWM*IivTxC z@%4{?5>g(p&op@*P!%H-gIP=r3_!$Si2#~Vrn8G96GI3C12a$>WIHQCEc+(z$Fj(m z90EJ;+cg{!zRCQ}FvX@Yqg}XHx@XrFySB2j`w7Bq8S|eXzW4Q6C(t3NLyE4E_q-nAD~iRTw-CD9j91GkXd0JIGl(HO9loupqB_?P>>Ldfhrq-%25CpkO#utMnDXr;rJDt4HO~< zfV6@EByOme{vat3;WA`b!tA61O;h)?FmM2!2uh{6aUB5wav%>FGeT(wT?ijxDjwq* z82A{#t^m;>46_c%!{<8SD zpJ%;)!gP7J?|l{j_&iuqWM3Jr?Hs)4oK;ZOg(cs=xg4orIIfnZ{lF(&hUMzAM7N2r vX70UE%|ENB^W)9uzDNE%a~dsRu*DSd1IS{iVVKyKe z8~*X1f#v7_|NlX9>`=_WpvVto0)ex8fCnQZGlRdUiyH%j14!r?hya365Mh?!>EZ)o z08M}aAddqN<^;-tFjx_YCI}{4`xtjQP4==#-f!lTdw%x!5V?meVL>wt15}(ow=(kB zmf04ry3e_Ms_3+nB{@ufb#I;@U*9r~T}ImNM95~r)>qR@te>qYcd49z-QvafX*KM< z=iW9>Fy=pz()ToL$?`idV!m0Fylg3)?|)Z$exNI>{<8SDpJ%;)!gP5z10T?JBwEgx!0T%zkfJdHzfyKhv#W55j%$fp~2U6?}3?2*&+3IS! to0O%UG89ZV1ZySjiTKHmPy%Lg0F|N%!NeJWavVU+pylQn;O-1j1ps@n6h{C6 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/defa60aa46ea5a47c09b6962b4e4296ef1bcad92 b/fuzzers/corpora/commit_graph/defa60aa46ea5a47c09b6962b4e4296ef1bcad92 new file mode 100644 index 0000000000000000000000000000000000000000..297875550d91db336c9eea40295481e6c0c4829a GIT binary patch literal 80 zcmZQzU|?`|5Aa}QWM=U7ba4Z6LBPV_)5QnEWHB*vc5w`Wa9C3yG>BwJFkvjl8~{57 B1`7ZH literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e0ae419425207832518d66c0ef35d11cbdc20361 b/fuzzers/corpora/commit_graph/e0ae419425207832518d66c0ef35d11cbdc20361 new file mode 100644 index 0000000000000000000000000000000000000000..89404f4cc1c7cfba0de2de32ff0e22731eecc714 GIT binary patch literal 1691 zcmZQzU|?`|5Aa}QWM=U9ba7)~1`0rc1(5Fpy_|lYP1;loCTW20mM8&EaLq~_Hrp}?G-`4k~0gh2V7Y9Fa_e$r&&vu z-+2-9&8*~QOW}O~yUOzeU0L;)b$-10-1o?zXHK$j;(jcPe90lO7JU9oE`E4!Z{%$70#`QdwCpLGJQ;w}IZKrq6>&jL04;@^Ir_5KOd<=uHI z_k9z9!NJY&3Wz~86|gPP5Ky%8022#@hVTbL6oHZ<|EwN7>BnF+{SeN7sOcyENl1CX zKGWoN_Lb4v&cS=mSp`*HSn~aw%aIC(<7!#j4}8L9SgtNhbes5U=H3g{_`@GF{{mAI W2$+rLUr;arDz&ZZ4*;P}9~S@s literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e128eff8ca7572d9bb0bfc84f64d79c52afc2c67 b/fuzzers/corpora/commit_graph/e128eff8ca7572d9bb0bfc84f64d79c52afc2c67 new file mode 100644 index 0000000000000000000000000000000000000000..d963f77b5c69772cfc934cef8f28c1e218327837 GIT binary patch literal 536 zcmaF={{8#)K#UdiLI4)I1T13j-}Bg(*%q$4&$)c6=(Lk1IZS?aZ=N4t-!hF|=08^T qln5f(1vdssj5hYKhg*e}F#z_1!W!-t-1ftj;AgA{OEWOYumAwHO0w(# literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e17fdc21ae03243bd1d31bb6301b4187cab6fe47 b/fuzzers/corpora/commit_graph/e17fdc21ae03243bd1d31bb6301b4187cab6fe47 new file mode 100644 index 0000000000000000000000000000000000000000..381f8e1bdbb60d417cd1f015ef24fbf6216846cb GIT binary patch literal 1617 zcmds1F;W9D4AjAe1d<=n&{EQc3c}qaWQLhg@C2SgK}kW+AK(Z1KwgkXq)MBHF{}7a zmSa0k0S%gyz1p)*vZT3XK~{?5c)e~gwiBl}PN)kysj(M5IB4y|{%sxLo2=9N0V|{& zR`uw~;?A?(dF{SB%;?fLJ&Thr+tkhVY(>-orL?E8=5_6oI94m+5L+-}YOHJN zJki?6xQl@SXvf8(vdQy~&$|%4cHO7joHH53fSOnffCLb5_(Z*YV_J6;!b2fJW`i(= zfHMDs+z-dFuyUI0Ws$t!%q92y?C&9R4_U&3W*7#jIDKwqWb&(fgY4dovB7_gi19z8 t{(ZZKBf>YCzZs_36lSyw_e%Hh&+6&?c=NgMkw4FzWDno_`m7UVGyry9RpkHx literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e36dfc11bcaab1e42df13924a2d7da024684db2e b/fuzzers/corpora/commit_graph/e36dfc11bcaab1e42df13924a2d7da024684db2e new file mode 100644 index 0000000000000000000000000000000000000000..25dd8eacd31650830ec6846f190485fc033f4be9 GIT binary patch literal 353 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&7gS5K9x4i-qTa zMT~$D3s4>_RzMYJbzop%1*)YKvjNQ@gxP^=u;2g>28K?9O`?LfsYzPuLVRD07&w3` E0oV=lG#VBo7_zzz)kJzabtQY;qEE{-7(Hfst(IePSoR8py=}j6e}eG0+H@3qigj z2E*M!sofy`KtP=RR|Ne^&MdqhaADoUl$r@P+qfW_DRl!;_A{b{3&djF_Cjfs18Y=(* literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e46b4666c6bfcd6f589ec3617a48cce9c968e833 b/fuzzers/corpora/commit_graph/e46b4666c6bfcd6f589ec3617a48cce9c968e833 new file mode 100644 index 0000000000000000000000000000000000000000..92bca774e7eb799f7f4efdc35a93ff2d4a720dcb GIT binary patch literal 406 zcmZQzU|?`|5Aa}QWM*IivT@!VX2UNib#b6c_0|O8-SR#NXl$sfE~iXk001;iJs`>_Ejp3^alf0Ix6< A;Q#;t literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e58ce590c2454e7ebe18e0a31a943b0b754fbd13 b/fuzzers/corpora/commit_graph/e58ce590c2454e7ebe18e0a31a943b0b754fbd13 new file mode 100644 index 0000000000000000000000000000000000000000..89d479039ce46ba00eaf3aa7ef5078741e55cf93 GIT binary patch literal 2317 zcmey*00jTRfb%y4!y^!vVXEk~lO;J!esyo2A79@xja^3C?L^3C!PZyPORS%*D0iux zf8FB6_h~ikz31LGPB7*_k<#}xYsvCEFJit~l)P*yobP{Ed43=RzcB*?KhQWl_yih2 zSY?T3RndX1;S>Cveg=Pb+EoAk;V$Xw=oGkBj;#92;@^Ir_5KOd<=uHI_kI22pM;bL z>@!VXXI~ku?Hs)4oK;ZOg(cs=xg4orIIfnZ{lF(&hUMzAM7N2rX70UE%|ENB^W)9u zzDNE%bCP`%_akJP*!TDD3I`jG2;a0RWd3HDlF=^QE8Vl}3bK*(2_t;r$H1@J&!;tY zmYJW!+cf5@SNwOYltl|T?&-;7kKVf_CnldY?M%_ za^>N?Y{v|3l*Zk0Yz#O~0s9{mU`8b18PlZUAk{@GUbkGsUWHsDErLoxgtjxbxaH8u-~^v)!&G`hE%~LDPWoLe#xxEPV+Z?1pw8+;Ftga literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e595f8fef5c8014cb0867978c6580301078ca0d9 b/fuzzers/corpora/commit_graph/e595f8fef5c8014cb0867978c6580301078ca0d9 new file mode 100644 index 0000000000000000000000000000000000000000..339b09efdb78c1310d777d9bae3dad709a1d1e40 GIT binary patch literal 2474 zcmZQzU|?`|5Aa}QWM=U9ba7)~W?;DU|Nno6yzZM`3fd;w8-DX{fB*UXzs*OvSMODD z4Peyl~Z+22Ft91Xg~r%mmQaIoLuJZgqS62OH@ozuRdjEv! z^6os9`@a71PeRHA_L(NHv#*TSb`IWi&MK(t!jkXbT#i&Q99PTIe&7=>!*X?5qT9q* zGxuJo=AYHm`SIp+-y?sXImy0>`>`zYC5OO{`*saSgl{r`Gfbhs|ECWs|JxL1v_7-25ttLG6=5_08Ji+( literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e5cec0217eea93b18a59d76b0aed6b46b13fa6a9 b/fuzzers/corpora/commit_graph/e5cec0217eea93b18a59d76b0aed6b46b13fa6a9 new file mode 100644 index 0000000000000000000000000000000000000000..7ae3eb4183b02d3f2d1b4a1b35613aa0ceebd0af GIT binary patch literal 921 zcmZQzU|?`|5Aa}QWM=U9ba7)~1`0rc1(5Fp%1IzQfg?tA3VGbhFLg&FO_z0y6quGqDemEBJeX3LoW{P4Z6&pLtDaTh@BmH<&dwEDK3 zX5a&|VAvnVz(zB$0#zboHXxr6W(TTaXArpmwYMvcRp?5yUI~AuMvGa`S)e#J_ZyPx zeuWpk0tSBtZcK_)j4BNNj|X7$6DeXSeg}mEA-{vb-#+o1D5T3p}>YeqbB U@We@0_(RfMfQK- z2$>$Fd_F+*%(EX&QA5cMuy&Od<^RShF1D$>Va;^CC literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e7a6cb6e5a1552837fdbee9025fc48a9373f8564 b/fuzzers/corpora/commit_graph/e7a6cb6e5a1552837fdbee9025fc48a9373f8564 new file mode 100644 index 0000000000000000000000000000000000000000..a5ae268ec31d608e14dfaf3ebeb1e994f4289faf GIT binary patch literal 1370 zcmZQzU|?`|5Aa}QWM=R;^>lFq@9S+9gY zQ=`SW=PXbo2N3gs41k-CWOxGH@ZPR8be$kw-$B|%y#L6#Px0Z;^Zn%*8JD;D+?(4X zU-=(4CIRKR3xEU=NccIv| z;2OZF*~i1Vc8Bj*C=d|hfNVl7H@h1sbw(F+w|&E>7{88JHxb%ztn%2uySKJ mSb}PVvpd)*1!Mz>ia%(!p?3U%+(E#8i{YDokYfSHW(NSN->h{2 literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e7f57c48016e1180c9af95acd34470881f10bd06 b/fuzzers/corpora/commit_graph/e7f57c48016e1180c9af95acd34470881f10bd06 new file mode 100644 index 0000000000000000000000000000000000000000..07bbb9c5b810b8a9487c03f254ad8d6ce475d550 GIT binary patch literal 90 zcmZQzU|?`|5Aa}QWM=U9Y-QxJEwkleC|q@)bNN(8hH30F(hMvX|ABykfrWt)s2B}r Ze!AEteIrSU_s^RfSs*zP@D|yNtBkiIB~L zt*@q+I6PZX?ov7by2Xp{(`wjz&%JG&V9b9arSEChlI3?^#C)?TdD&7p-~X=i`~X*0 z{bliQKmP}US?`}PUEZCia^KfK{z*uAz&_LDb@r9f+Rnjy&RGRjU0Cw{o6C_3hU02k z+7EofWmv9O^Uvz({CM-Z?~y;xoMhj`{a|3Q@b`4_0lF9nSS(x|U*ZA`1`G@U8R2b> literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e8f9981443c34ece02bca3c66130f3429d7b3375 b/fuzzers/corpora/commit_graph/e8f9981443c34ece02bca3c66130f3429d7b3375 new file mode 100644 index 0000000000000000000000000000000000000000..09fe9ddc0acbb8ee5a80207689362b4b8db5c2c2 GIT binary patch literal 474 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm=#L43&)CX?}i{MziXEhR*4o z$6Rp{D8pU=k>>Dzc_3&X8^eR}=7RQApco5OLc{ylRu0GJru!fN@7Vi$h4GggyU#xD zmaBIM$wSq!05xwX%7P1B+y=2)bG_cyOZ_-;O31G_Whb&ZK2b0CuAA^t?^Wh>&9^F{ zaSl8Grp;ZbCB(q6rzev=dheE;n0!{Cy^K)Iz`#RI=h>5`_#5EEdi#jv*j*3=FI(5E@8sf&-Ayrd$w! G3j+Y}L|e`P literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/e94201cfa88df7b198abd3abae9007a6780b52a7 b/fuzzers/corpora/commit_graph/e94201cfa88df7b198abd3abae9007a6780b52a7 new file mode 100644 index 0000000000000000000000000000000000000000..0279a3c3bd632f0de954e652fda209bd30e74ed8 GIT binary patch literal 345 zcmZQzU|?`|5Aa}QWM=R;^>lFq@q$jspH`G5X@Fc6(~vc%Uv{z*uAz&=xk1_nl;Dh3eA1VWaUmYP5e L0?sauObj6aM|2bW literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ea5ad04a54f95963baea1f47845847626e08dd55 b/fuzzers/corpora/commit_graph/ea5ad04a54f95963baea1f47845847626e08dd55 new file mode 100644 index 0000000000000000000000000000000000000000..79a1c4f809d827f787347092ce00654ad0d2d31b GIT binary patch literal 211 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LEt{kfd$YuABbfv7LG2?ArLk}@;?}`0o8#p13MB9 L@L*tIWMBXQ_ETXL literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ea608a401f54b0ca70e42b897f0c8ce6efdbc0ef b/fuzzers/corpora/commit_graph/ea608a401f54b0ca70e42b897f0c8ce6efdbc0ef new file mode 100644 index 0000000000000000000000000000000000000000..26c55fe6e38816ccd975dcdc558f9fd2710144ad GIT binary patch literal 404 zcmZQzU|?`|5Aa}QWM=U9bOG}C85n^iUi_b2fX`S~pslzt8&HlAW(TSvjPJaN`DRh_ zvZZjo|6S$zfv&9j%i`aDp7s6-)8*ZHD))W;XdH$#}m z17zwjfIR{72ofgUe>lAT{(aN^kN%_^@J;4#hAB3M8STQo(mlJb*tM0F-A@o^ z%b5TC@V&3kI)U-R4NWl;KsLh4sxWvO?qU#6Nv8!g43yqb zatV!c2(EMuv>snV1xhn8;ERJN@JN_R3ZPDm*~6j?lznH_{S2McJCC{IBFInB2;%@| z@t}Pdy0{ItYt8j~TQBwF#3>=a-jtol#eh%L%f0I+eAIiDIbHLuN@$$J&cA7M7itLs d&EWy5`~M%r^8U4z!?Br^0)-|n0w$Ikb^x1X;9dX# literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ec1f271b04c322353865f4819153d46df7def873 b/fuzzers/corpora/commit_graph/ec1f271b04c322353865f4819153d46df7def873 new file mode 100644 index 0000000000000000000000000000000000000000..95cfa61ffd0641811f0de74bf7bfa2fffdfd7df0 GIT binary patch literal 1754 zcmZQzU|?`|5Aa}QWM*IivT>0&RPOuw$3F=v57=jtyw1KdTH85z&pE50 zstZfLe{(rf!EjtHOZ$OOxD3nHWr=PRU(MWmp_+eIPv^&*&wY>ldFCYhCho_w$d?=f zJMP;x91*_B{LL`MrZA&jxL3Mo*A=_AvadK6}T~}O);u4cp6Zc8LDRX6n2oR8$iIoz?ycZ=V)eL_f0PaZIkQ`zj;AY zFwgpXwlebAmf04ry3e_Ms_3+nB`{x^Ca(jkV}xQbi-~~&h!`vpKoiPzc5!542mv|( zD2+SpFy&Z*>XET5G6z4KP67CY2_>$9p+d{JX5a<}2r}kiU?33xHw1`@|1FUCHyYsh zM^7L4qZl=9psJ;Q^sC~_KhW?S?D+>2MnnKm3IhXh*|3Fr`5#gOASYmM23vT7hS^Fn oO;h)?FaR?h1E`e5jq3;ikOO%@7*_t$IsE{wPSke(&%nS303GOwYybcN literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ee215536e7f0cfbd07b53dd65c5af9a604a01830 b/fuzzers/corpora/commit_graph/ee215536e7f0cfbd07b53dd65c5af9a604a01830 new file mode 100644 index 0000000000000000000000000000000000000000..82241f0004a7d0916cb9d5d7418032bf8eb40236 GIT binary patch literal 948 zcmZQz;AC)i5Aa}QWM=U9ba7*V01F`72f}2raCUJt4p4FWT>X{Dw#>G0)qT$8Q$?qp zEXiT=t9$eO`1+P<>@w1BCqgz0w!WHPVqNuYMY&7m{OcAkzE7)RFFLR_e1f0T&*0Ba zo9f>`+$CKdo$|7!aK8Ut<@tfGtoqC1-+rF;{t46N-FYhaef{H~gp>#DGfiG+Um30K z9K7e8RZ!K1CEvff9I0S9u9l_!z$aXWl6@2R zV_D=&4uKu_?HY~<-(>z~m||0y(JtI8-LvZovXO9?1AWL%0_Fv(#fSNT@;LC|^nZ(A z-3QDF9N72+h9Mgo{_+3+|DQk%5@*MXpa15y0!o0u_V=I9|J!_=d-Yxg*8oP%J|51s zb4;G7%s$#6Q~I*he`$0yQ`B#6pNZB!#$8U6y)2UVo4MqkpZz^V?jcK9&OUw-~fsuFoK0OSD*xH@42^)6O8#!r1U+_TC)7ki3`cmlH+Wf=UK;j*ZVAO8U?elv0a literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ee8099331b2c392e7e036ffcd4a9b36ec2c2082d b/fuzzers/corpora/commit_graph/ee8099331b2c392e7e036ffcd4a9b36ec2c2082d new file mode 100644 index 0000000000000000000000000000000000000000..4e8f26bc199e2c496f941a585e28ea72a5b77e28 GIT binary patch literal 1908 zcmZQzU|?`|5Aa}QWM=U9Y-QxJEwe3Lb)R$jR7Ri-2#8KQS(3x#SNG=m@%1g!*kz;{ zSS%1IzQfg?t283j|ioI zkUS(j1@3?C?Mh=6y3(vy!k?+pV%&2UC#o_*kT_|Z0 z>lQD*Ppe_?J@>Y8f-(Pzls=k<^q*%=vTx#kEQ@@}A+X~3fl??311A84?N#ys literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/eede9da76db25513f8347f972e170102831de91a b/fuzzers/corpora/commit_graph/eede9da76db25513f8347f972e170102831de91a new file mode 100644 index 0000000000000000000000000000000000000000..d3646058fc63b222f5fffd82345dd044de89d634 GIT binary patch literal 80 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2EEYMtIEFZeK)8HB3WPy`kKveZBzqiN Q<5vd{UH>HIWt+YN0F(d?W&i*H literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ef707cdeaa9548b6c820f769c1d8ad607b3c4514 b/fuzzers/corpora/commit_graph/ef707cdeaa9548b6c820f769c1d8ad607b3c4514 new file mode 100644 index 0000000000000000000000000000000000000000..31daa3b3108f397b774d8bb78fd9c0757379b330 GIT binary patch literal 119 zcmZQzuwig^5Aa}QWM=U9ba7*V01F`72f}2rU~mSqSS*}f977;NtSMlc4M+m9DQ*B! N4kOtcKrBNL0RSS_41oXu literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ef98609d8196dc158365dfcbbc47e3d1699c50c2 b/fuzzers/corpora/commit_graph/ef98609d8196dc158365dfcbbc47e3d1699c50c2 new file mode 100644 index 0000000000000000000000000000000000000000..6cac8493c4bb619466f730edfbcce4012e015bf1 GIT binary patch literal 1944 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&7h-LB(POx`v*Z z31}Z7%nVe64YL5niN&lywba0DKywITcAy$^Fb7Z{y)Y-xE_BQV6a!&y8e<-y`PeWo zP@ELZ2UJgM%n!7KCRnwfPiyKdGe3v7Y0Ouz`0rLJixzO))04>_y?0AaOg?McnVzFt z^15$&DQKHyZ}`o-{r%_j|27}zUcFbrHGomGkB4*Z9Fr$1vyV2&l)fzWUm6|F6!n|i zXQH)_ahKC%FN@^;W-htsXMYcod&m+NG{ZPR#p!b^BadyFZQ-i>oXe+*PCHqW!{k@@ z=K1mUEz{U#q}@)0Y!+;NHNC|8*@|+P%K6tVUVNWc!`^%DZQ}%E{u3#EPqUURzw;vI zn?=dXmcse|ca`S{y0Ypoi+}rh*83++mv`r>-1qg5e-ct2u+KDkoqc7rwsY{Fb5=oB z7nXeg=5nNh;ka6s_5+`A8J4Td65S@gnz{EvHUF%h&W|^r`yTo8%t`i5+>d3EFF6Eu z+_!5uB7Bqin_-GgVMe=fuXN9@D|T&VW%m<=*)rxoKYZ`&vrb^Va2EgxAdmnNKeYO` zoK|?zD`4SA9IRbtYYs)1B%volIEPNfm+QBVi@uGk&&ZgIq&GCNvfvM4>b3w%c z!*6mIy0-pmvwAgI#Kae94in5ApufZ=1nz(B?Mh=6y3(vy!k?+pV%&2UWET*F${Z2z zKXUFq0Rl6@2RV_D=&4uKu_?HY~<-(>z~m||0y(JtI8-LvaTn_XGi|N9BTY#H;P zAHMhXStrmg?gAhI1QHAi+9uf>e)9s^KeYO`oK|?zD`2o!fZ+yEU{af6RAKNmAd4BQ zoWuL&fs=nZt^XHHNG$a<4hwsBF3aUXcymE}#{3?jI+DOQi;|ZN3~6^4Y6$`L@j$H* z@S9j$E+JsSGAm@^>-g0UZV`(Y1#EFPx(kDScV$zcf0UDe5=3&qQk<<1VMkUKYvw&0KQNCwvc)d&m+NG{ZPR#p!b^ zBadyFZQ-i>oXe+*3bwwQUSj=hMY&7m{OcAkzE7)R?>+anae^`biIl#lSxc7ByAZv0 H-KMVqc5^tW literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/f00e449ba67ef15e7f29df1e6948c28155d72baa b/fuzzers/corpora/commit_graph/f00e449ba67ef15e7f29df1e6948c28155d72baa new file mode 100644 index 0000000000000000000000000000000000000000..32153f74d24a6312559bcd22f067810d52286ba9 GIT binary patch literal 3505 zcmZQzU|?`|5Aa}QWM=SRMJ8adA*hjo9cU3T7~vXE7b3NA0M!w~KqbV3>(l`Mi3dRI z2sjQNMV>BhP^A|Bo-RHRHj9O`i(?3c&6^cgT!XRBphH2BpTIXG#&#mJRxBVlt5U^z=*02XdE{Qm>Gv! z9-ufj%nKAp!k}c$3B^bm73NX~1``~q;37~HdjXID0uJw&2ZHup=;Aimt~J-|ZM_tO z$|)hg-jtmnd8ir|pQx96&jR@%M}ce=@%|&{KE;PW&-a&OWL)0nb8l{oeC2=Gm;{vL zhH8>PiW_J=Ex+?3=9@*y%a+3VpyCATPz44C9Lbd%s1ILw(k=W98BlT&-thZzg3jTG zlmtP+PXeY}_%RIT@B;=I&h&>rJZTwzl+{@%brjHp_y9T8haUrb13oj!mqSX;c$mYv z`uIh39;Rjb1H~X&^#^Usza^ZVX3G1{jL~%?Xs}f?{qU4Z$o>8qC*&b3kS>GBEIGYP1;loCR`tKq4GI zQ7_+^*4+fL(Eu#OAi^urWHGobFcFZ8kbnRZ8;yzG{R|EWzc3JRKgf+D-g7|aq9g=n z28Pca=fYl!tkSmX@P4@4TDa?2G}BRT29TBL7#4)E07Rp0fm%Re#RH622+hC-6P4LV8)Qmfmii}y>;VB#*Z=_y!(RYw2R!_N84wum VPyoq<+zj&rU4hvF=o9^A@c=FGln(#^ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/f0e53b72e5d69467e7c014474028ea734f4fcb26 b/fuzzers/corpora/commit_graph/f0e53b72e5d69467e7c014474028ea734f4fcb26 new file mode 100644 index 0000000000000000000000000000000000000000..bad38e83bce6f023e05b2958bf4050dfe4bc401a GIT binary patch literal 5 KcmbQu00aO73;>(} literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/f186265b3f10f4383f4174e9fb74f0a0cdfa3fca b/fuzzers/corpora/commit_graph/f186265b3f10f4383f4174e9fb74f0a0cdfa3fca new file mode 100644 index 0000000000000000000000000000000000000000..2cc2dd040c158e511fd4ae67cfe87ef6c6f07a83 GIT binary patch literal 95 zcmZQzU|?`|5Aa}QWM=R;^>lFq@q$jspH>Eh-Y;O@)-0Tw{M4+F!$|Ns9ppr}EXXM}Lmm-QgLxu882D8*6$k>~OLwUxuMx#|AL|2y^qg^;WQv)O=RAWS^?PXM5p zga{26H=snD;`+YeX+Q=u)Oj4t`#`|k`1;cT*EbRwA;W8{& zmnFJQd^L0Lg=+p;J)IwKKKDKH=b4l2o46m#B42U{?6_~&a76ef^Ebm3`uiU}84Rrd zZ3;8mg?puYc3lAlDFZt&#lbK`;s5^y3=Fu^Z#!MmuNg7v*8*Sq-3Ls+!uct4HZ+KP z-df9U`|Q2-RA-$vAIVL>IO31T#W4g_5LhI5x`1c~1{MqMfzSU$g&$q>KaTJlp!|=T z{$WK5>E(CK9g7zwFPDF#cKJOp@i$ukK&#;asDJj-xc(h3`46-HL2WBR+CKx6e@JNt Z;;sJ~7&w4631>8j0Ac4V&3X*{B>-?ISDgR= literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/f34a833faf2b0dcbae8aaad142c76c7c7e534e99 b/fuzzers/corpora/commit_graph/f34a833faf2b0dcbae8aaad142c76c7c7e534e99 new file mode 100644 index 0000000000000000000000000000000000000000..2eaa521d6c2575db4269008701d6512782c73807 GIT binary patch literal 71 ucmZ3z8V|U_00hnq96%C+r?JaOyPXKx+>^;3y?0AaOg?McnVzFt^11;41H)Eks3U-E5Fd=$fHVR>2yZTEPvu}>_|yOY|9_wqkN2;w7lAZ;0gwO! z4)2!-g7&d7KokN6SfCOhg&dB}P4_?k-?8`i3ga&~cAtIPEm!Xjl835c0czg<{@Ea|Efb9rixkH=g0pakcFoLm`{}_#p+Hwg26P8&akODqp Y@uGk&&PLaP1rWH=!N9-|3;-Yo08f|!BLDyZ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/f680112645c2502f0612e9d017bbb50cb28affbf b/fuzzers/corpora/commit_graph/f680112645c2502f0612e9d017bbb50cb28affbf new file mode 100644 index 0000000000000000000000000000000000000000..dec09a840162b0860b7d6b6af23d7ad2c878a8d6 GIT binary patch literal 580 zcmexgFd?zjI4tbhxvU4_%?0hL3=9k`1waA_c)WjY<#23ny8rS2j=ey>IS{iVVKyKe z8~*X1f#v7_|NlX9>`=_WpvVto0)ex8fCnQZGlRdUiyH%j14!r?hya365Mh?!>EZ)o z08M}aAddqN<^;-tFjx_YCI}{4`xtjQP4==#-f!lTdw%x!5V?meVL>wt15}(ow=(kB zmf04ry3e_Ms_3+nB{@ufb#I;@U*9r~T}ImNM95~r)>qR@te>qYcd49z-QvafX*KM< z=iW9>Fy=pz()ToL$?`idV!m0Fylg3)?|)Z$exNI>{<8SDpJ%;)!gP5z10T?JBw;0U|>LX5ReDg%Lo88;YC0I literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/f6ca6a62dc885c6b2a4b40c4aa1a7cb8118e30bb b/fuzzers/corpora/commit_graph/f6ca6a62dc885c6b2a4b40c4aa1a7cb8118e30bb new file mode 100644 index 0000000000000000000000000000000000000000..29ed04c9c46448bf62022a193f2427641206da5a GIT binary patch literal 355 zcmZQzU|?`|5Aa}QWM=U9ba4Z68ICb9SOD2RAT|R7i-og`V+cb6h|QV;B5{I8IAx#` uEI^tS#O8nspi-pi2bqCt4q5tvMnFt~nFpddQ7|`<2g5)nPJqpRMil@Y$qN1e literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/f733a8770c23fde182d2fef7e0d96e67244274d5 b/fuzzers/corpora/commit_graph/f733a8770c23fde182d2fef7e0d96e67244274d5 new file mode 100644 index 0000000000000000000000000000000000000000..c6aa7585e78745d69d7630a7d5a13e389ce41541 GIT binary patch literal 90 ccmZ3r3I?vj!GC;UIs*d(raVv(3Vy&C03?P#YXATM literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/f8529ddf17d4505c0932c3d40abe33cbfd8c6f22 b/fuzzers/corpora/commit_graph/f8529ddf17d4505c0932c3d40abe33cbfd8c6f22 new file mode 100644 index 0000000000000000000000000000000000000000..f004ecbb75983656ccc8c1d33e599cf2ea4a76be GIT binary patch literal 453 zcmezW|35zi5IDOBcrY?DGx&SDFfgzI1<)}&Pz)KfSU9^lhJdsp0rmzY4sNC`ij*n} zj|9$j2v~6aIzCO#?xkj7Vb9KGJqT|uXio(yWhsED=kflvmBX>Q>Hf$6JN5#FSRpt8 r$lwKYU||4JP7L{<0KjPmNS`8DGo}(2pb*Gyf1xyx4GVjaFas+9U)4&M literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/f96f8419a3fc3719ae86d64e1147e7b7f66a2470 b/fuzzers/corpora/commit_graph/f96f8419a3fc3719ae86d64e1147e7b7f66a2470 new file mode 100644 index 0000000000000000000000000000000000000000..5dee3ca7c3564c5e52e5da588280c7de5371e350 GIT binary patch literal 2139 zcmezW|G%oUdjKPkZJBN1s{5SFr;1KHS(3x#SNG=m@%1g!*kz>MPK0b0Y<)Go#JcI( zigK6A`PVI8e4kds-h1wC;{;>=6DfU9r!QH4=S9pni;|Zuh4cOID$fsO;5TMaL;?H^ z3=BB2YCoUW)LF)U4sX+#uU_%rtx^^(;JBwJlRbLxmYkS;*0eJ{N4Mm4-}F+@Hp$-b zn|J&B&*%SbKFYm%uYzj;qh=ou=h`_YPgG_fZICH_S?a$uI+`i!H@DA3Yaa$Fr^#Lx z$@|S*a?j8H9wPUUB`j!$ae#``=jyM7J#ATHjpFB`16#u<_&NOy{_M1={{6#U($&!^ za6h}U>Mx6b`+3&;Crp=j=c(NH^^boNQXa6+Gp{B}H+ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/fae241a6c87af37781a3b49e534b7ddb6636eda8 b/fuzzers/corpora/commit_graph/fae241a6c87af37781a3b49e534b7ddb6636eda8 new file mode 100644 index 0000000000000000000000000000000000000000..fc4e26bfd219be28654f3957f48992e31e81134d GIT binary patch literal 803 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6d?To%zneb-T-D$k6>hA z03rwhV&KE&^3c@gh^M3{gJ_Zh;5IP15LBV5W023rgtD&o4ac9y9;| literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/faf8817a04b77c6a976ab0a3d1e905f79bb7f799 b/fuzzers/corpora/commit_graph/faf8817a04b77c6a976ab0a3d1e905f79bb7f799 new file mode 100644 index 0000000000000000000000000000000000000000..5164ecb6a5bd52086516b6b7b3888b13936ec1df GIT binary patch literal 1757 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&7gS(pf4ha6KGA z7D4szL=%SgMO2-z&y`f7TK^|KY_E|v4ITfF!_?I52~+_DUZJHMu_ zakTyxP!yxkVr5bCvZZjo|6S$zfv&9j%i`aDp7s6-)8*ZHD))W;~z=*)CKqfYf2p5F+{{z*+j0NdoBY+`_ zvFnGKgG_S*%|pjrKrs-;5ylKq(~U5~02U^27lUj<0#J)b)8Eicf5_q$jspH>Egz~EXn`{7C^oaj02`wESy~&Lm)z|DPWonNFrl)AfE|{ zK{PJRT>z8>0tpcDL#uDgX@wWP0tSBtZcJ)Zj4BNN4+B7H4hRNPAQqet=5Ye~=$H#A z2EyEiKn$XxX4#>d46^}F^8nTI0x<(03T{B-BgsF_TC)7kiz~m||0y(JtI8-Lvb8U0Ye%{RCmQ zjQP(G-~0Nk6KE^Z!2)+Qf`RI4Bv&GQ1B_^_;y@odFfgzJC6O_5oZ@0b;#c54Us37I zUvIT*v`Y9hHCjx1&H~K>#TF<`MZEvWUM^*=y&~vWa%SQ6fD7v$ra;0J7Jg>f!*6$< z%6;F2_$MLd0sBmo*V$J_YdZ(;IcF7Abz#Z(Z!SkF7>=uDX+Q7@mtncOEYWS^tC@Q* zRP)d3>HK)}x$lub&*&Te(3qG8^f5Cub#r*XJaF=#Sf_NM=hgZas!Gy!|y(#}TL834Z_ BGOqvt literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/fcb1b42c706e61245d5e86f708be777ae63f2772 b/fuzzers/corpora/commit_graph/fcb1b42c706e61245d5e86f708be777ae63f2772 new file mode 100644 index 0000000000000000000000000000000000000000..a98b66141ed7cb9a642e4010a1125fef8a5a48c5 GIT binary patch literal 469 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2ESy~&Lm+I{6bKC>*&ASNRv-h6wO|aO z6i9%L2+R&tgA@1Rko)ofKS&P;2p0eeAmH)-wUxuMx#|AL|2y^q`EW-;*)X?&)Dj2& j;{y1!gRDWf8Y@2ui#mAtK@EW!26H=%#_j;7nJ{qx@69cy literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/fd6c463e7c30b0e51198c0d1ebbea25f20145e3f b/fuzzers/corpora/commit_graph/fd6c463e7c30b0e51198c0d1ebbea25f20145e3f new file mode 100644 index 0000000000000000000000000000000000000000..b25332139ccc5d37491b705f0064c05c427e9437 GIT binary patch literal 357 zcmZQzU|?`|5Aa}QWM=U9ba4Z6LBImY_JJ^2EEt@DEEWrA7sn8Y5NisUW&@JQm>tMx z0%8zN2m_Vi0oNgNd_W3}IiThV-2d9!mBuP`rCG0pKU1T{s9m^Mx@XrFySB2j`w7Bq z8S|eXzW4Q6Cr}@E0mKXm5cNZ=Zwr`<;xA_xuyalE0EihxkoHhDK-xm!#-uhy|0qU? IkiDl10Ed_Kl!?|{j$rF{?M;l~H zUzYkWjgDrD`pxY#(b|VW%4xEfN%DR(m)!HSzlX?avV;ZAFb+_0`ds~$$F|J2aMgXz z=@~eCE{P_BoY3wr6ZYM%E3%0(RUSj=hMY&7m{Oe{fzE7)RFFLR_e1f0T zPX-2lptVr^n|J&B&*%SbKFYm%uYzj;qb9;R2e3NF0^yv81f7Gh2WB5(TD6}~Yw9dB zKZmzz%vZ1Y?^Y>`7I56tlgS>vcS}x8K5N>Uo}*jxx^H?ZXq#kjz~g@G!AX+)u?MFG fN^k~$cG^_WfF=B>WIrT1xB$}wFf{<9@cIM*f{EqZ literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/fe46775b28a2923b8770b44381552a8a1560d875 b/fuzzers/corpora/commit_graph/fe46775b28a2923b8770b44381552a8a1560d875 new file mode 100644 index 0000000000000000000000000000000000000000..0acef6edc76f9ec8d3940fe8d4b937c81c8fab40 GIT binary patch literal 154 zcmezW|G%oUdjKPkZJBN1s{5SFr;1KHS(3x#SNG-`Md11I^)1ubWu)CsgwzuQ>_Lja L1d!%u*z^?uU|e4| literal 0 HcmV?d00001 diff --git a/fuzzers/corpora/commit_graph/ff04441135ef3308fec2687cf688069c6df8aa31 b/fuzzers/corpora/commit_graph/ff04441135ef3308fec2687cf688069c6df8aa31 new file mode 100644 index 0000000000000000000000000000000000000000..33afa05c6fd5a9b96696d90ea997bb8dec6c4205 GIT binary patch literal 601 zcmZQzU|?`|5Aa}QWM=U9ba7)iOEM?`8UX|>-Y*Yq|He?s*q!F*S7|h>?q}$n-g(Rw z7lCr@P&FJtH9`9>ba5NRYR&a}TQBwF#3>=a-jtmnd6+pqQ7`wdoA6QZRpxZfw<@7= z4m`~-CqkN2;w9FEOR_dovMvG?~1<1ctDpv?bz3@pU>pB3mhMiBlF0fr0=AR#bj oL1IJ2*nl(wBYUp_C<6iH#~&o-?tks=N@Eqe(yUj)&&W6r0LPEpJpcdz literal 0 HcmV?d00001 diff --git a/src/commit_graph.c b/src/commit_graph.c new file mode 100644 index 00000000000..71a56e3da49 --- /dev/null +++ b/src/commit_graph.c @@ -0,0 +1,299 @@ +/* + * 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 "commit_graph.h" + +#include "futils.h" +#include "hash.h" + +#define GIT_COMMIT_GRAPH_MISSING_PARENT 0x70000000 + +#define COMMIT_GRAPH_SIGNATURE 0x43475048 /* "CGPH" */ +#define COMMIT_GRAPH_VERSION 1 +#define COMMIT_GRAPH_OBJECT_ID_VERSION 1 +struct git_commit_graph_header { + uint32_t signature; + uint8_t version; + uint8_t object_id_version; + uint8_t chunks; + uint8_t base_graph_files; +}; + +#define COMMIT_GRAPH_OID_FANOUT_ID 0x4f494446 /* "OIDF" */ +#define COMMIT_GRAPH_OID_LOOKUP_ID 0x4f49444c /* "OIDL" */ +#define COMMIT_GRAPH_COMMIT_DATA_ID 0x43444154 /* "CDAT" */ +#define COMMIT_GRAPH_EXTRA_EDGE_LIST_ID 0x45444745 /* "EDGE" */ +#define COMMIT_GRAPH_BLOOM_FILTER_INDEX_ID 0x42494458 /* "BIDX" */ +#define COMMIT_GRAPH_BLOOM_FILTER_DATA_ID 0x42444154 /* "BDAT" */ + +struct git_commit_graph_chunk { + off64_t offset; + size_t length; +}; + +static int commit_graph_error(const char *message) +{ + git_error_set(GIT_ERROR_ODB, "invalid commit-graph file - %s", message); + return -1; +} + +static int commit_graph_parse_oid_fanout( + git_commit_graph_file *cgraph, + const unsigned char *data, + struct git_commit_graph_chunk *chunk_oid_fanout) +{ + uint32_t i, nr; + if (chunk_oid_fanout->offset == 0) + return commit_graph_error("missing OID Fanout chunk"); + if (chunk_oid_fanout->length == 0) + return commit_graph_error("empty OID Fanout chunk"); + if (chunk_oid_fanout->length != 256 * 4) + return commit_graph_error("OID Fanout chunk has wrong length"); + + cgraph->oid_fanout = (const uint32_t *)(data + chunk_oid_fanout->offset); + nr = 0; + for (i = 0; i < 256; ++i) { + uint32_t n = ntohl(cgraph->oid_fanout[i]); + if (n < nr) + return commit_graph_error("index is non-monotonic"); + nr = n; + } + cgraph->num_commits = nr; + return 0; +} + +static int commit_graph_parse_oid_lookup( + git_commit_graph_file *cgraph, + const unsigned char *data, + struct git_commit_graph_chunk *chunk_oid_lookup) +{ + uint32_t i; + git_oid *oid, *prev_oid, zero_oid = {{0}}; + + if (chunk_oid_lookup->offset == 0) + return commit_graph_error("missing OID Lookup chunk"); + if (chunk_oid_lookup->length == 0) + return commit_graph_error("empty OID Lookup chunk"); + if (chunk_oid_lookup->length != cgraph->num_commits * GIT_OID_RAWSZ) + return commit_graph_error("OID Lookup chunk has wrong length"); + + cgraph->oid_lookup = oid = (git_oid *)(data + chunk_oid_lookup->offset); + prev_oid = &zero_oid; + for (i = 0; i < cgraph->num_commits; ++i, ++oid) { + if (git_oid_cmp(prev_oid, oid) >= 0) + return commit_graph_error("OID Lookup index is non-monotonic"); + prev_oid = oid; + } + + return 0; +} + +static int commit_graph_parse_commit_data( + git_commit_graph_file *cgraph, + const unsigned char *data, + struct git_commit_graph_chunk *chunk_commit_data) +{ + if (chunk_commit_data->offset == 0) + return commit_graph_error("missing Commit Data chunk"); + if (chunk_commit_data->length == 0) + return commit_graph_error("empty Commit Data chunk"); + if (chunk_commit_data->length != cgraph->num_commits * (GIT_OID_RAWSZ + 16)) + return commit_graph_error("Commit Data chunk has wrong length"); + + cgraph->commit_data = data + chunk_commit_data->offset; + + return 0; +} + +static int commit_graph_parse_extra_edge_list( + git_commit_graph_file *cgraph, + const unsigned char *data, + struct git_commit_graph_chunk *chunk_extra_edge_list) +{ + if (chunk_extra_edge_list->length == 0) + return 0; + if (chunk_extra_edge_list->length % 4 != 0) + return commit_graph_error("malformed Extra Edge List chunk"); + + cgraph->extra_edge_list = data + chunk_extra_edge_list->offset; + cgraph->num_extra_edge_list = chunk_extra_edge_list->length / 4; + + return 0; +} + +int git_commit_graph_parse(git_commit_graph_file *cgraph, const unsigned char *data, size_t size) +{ + struct git_commit_graph_header *hdr; + const unsigned char *chunk_hdr; + struct git_commit_graph_chunk *last_chunk; + uint32_t i; + off64_t last_chunk_offset, chunk_offset, trailer_offset; + git_oid cgraph_checksum = {{0}}; + int error; + struct git_commit_graph_chunk chunk_oid_fanout = {0}, chunk_oid_lookup = {0}, + chunk_commit_data = {0}, chunk_extra_edge_list = {0}, + chunk_unsupported = {0}; + + GIT_ASSERT_ARG(cgraph); + + if (size < sizeof(struct git_commit_graph_header) + GIT_OID_RAWSZ) + return commit_graph_error("commit-graph is too short"); + + hdr = ((struct git_commit_graph_header *)data); + + if (hdr->signature != htonl(COMMIT_GRAPH_SIGNATURE) || hdr->version != COMMIT_GRAPH_VERSION + || hdr->object_id_version != COMMIT_GRAPH_OBJECT_ID_VERSION) { + return commit_graph_error("unsupported commit-graph version"); + } + if (hdr->chunks == 0) + return commit_graph_error("no chunks in commit-graph"); + + /* + * The very first chunk's offset should be after the header, all the chunk + * headers, and a special zero chunk. + */ + last_chunk_offset = sizeof(struct git_commit_graph_header) + (1 + hdr->chunks) * 12; + trailer_offset = size - GIT_OID_RAWSZ; + if (trailer_offset < last_chunk_offset) + return commit_graph_error("wrong commit-graph size"); + git_oid_cpy(&cgraph->checksum, (git_oid *)(data + trailer_offset)); + + if (git_hash_buf(&cgraph_checksum, data, (size_t)trailer_offset) < 0) + return commit_graph_error("could not calculate signature"); + if (!git_oid_equal(&cgraph_checksum, &cgraph->checksum)) + return commit_graph_error("index signature mismatch"); + + chunk_hdr = data + sizeof(struct git_commit_graph_header); + last_chunk = NULL; + for (i = 0; i < hdr->chunks; ++i, chunk_hdr += 12) { + chunk_offset = ((off64_t)ntohl(*((uint32_t *)(chunk_hdr + 4)))) << 32 + | ((off64_t)ntohl(*((uint32_t *)(chunk_hdr + 8)))); + if (chunk_offset < last_chunk_offset) + return commit_graph_error("chunks are non-monotonic"); + if (chunk_offset >= trailer_offset) + return commit_graph_error("chunks extend beyond the trailer"); + if (last_chunk != NULL) + last_chunk->length = (size_t)(chunk_offset - last_chunk_offset); + last_chunk_offset = chunk_offset; + + switch (ntohl(*((uint32_t *)(chunk_hdr + 0)))) { + case COMMIT_GRAPH_OID_FANOUT_ID: + chunk_oid_fanout.offset = last_chunk_offset; + last_chunk = &chunk_oid_fanout; + break; + + case COMMIT_GRAPH_OID_LOOKUP_ID: + chunk_oid_lookup.offset = last_chunk_offset; + last_chunk = &chunk_oid_lookup; + break; + + case COMMIT_GRAPH_COMMIT_DATA_ID: + chunk_commit_data.offset = last_chunk_offset; + last_chunk = &chunk_commit_data; + break; + + case COMMIT_GRAPH_EXTRA_EDGE_LIST_ID: + chunk_extra_edge_list.offset = last_chunk_offset; + last_chunk = &chunk_extra_edge_list; + break; + + case COMMIT_GRAPH_BLOOM_FILTER_INDEX_ID: + case COMMIT_GRAPH_BLOOM_FILTER_DATA_ID: + chunk_unsupported.offset = last_chunk_offset; + last_chunk = &chunk_unsupported; + break; + + default: + return commit_graph_error("unrecognized chunk ID"); + } + } + last_chunk->length = (size_t)(trailer_offset - last_chunk_offset); + + error = commit_graph_parse_oid_fanout(cgraph, data, &chunk_oid_fanout); + if (error < 0) + return error; + error = commit_graph_parse_oid_lookup(cgraph, data, &chunk_oid_lookup); + if (error < 0) + return error; + error = commit_graph_parse_commit_data(cgraph, data, &chunk_commit_data); + if (error < 0) + return error; + error = commit_graph_parse_extra_edge_list(cgraph, data, &chunk_extra_edge_list); + if (error < 0) + return error; + + return 0; +} + +int git_commit_graph_open(git_commit_graph_file **cgraph_out, const char *path) +{ + git_commit_graph_file *cgraph; + git_file fd = -1; + size_t cgraph_size; + struct stat st; + int error; + + /* TODO: properly open the file without access time using O_NOATIME */ + fd = git_futils_open_ro(path); + if (fd < 0) + return fd; + + if (p_fstat(fd, &st) < 0) { + p_close(fd); + git_error_set(GIT_ERROR_ODB, "multi-pack-index file not found - '%s'", path); + return -1; + } + + if (!S_ISREG(st.st_mode) || !git__is_sizet(st.st_size)) { + p_close(fd); + git_error_set(GIT_ERROR_ODB, "invalid pack index '%s'", path); + return -1; + } + cgraph_size = (size_t)st.st_size; + + cgraph = git__calloc(1, sizeof(git_commit_graph_file)); + GIT_ERROR_CHECK_ALLOC(cgraph); + + error = git_buf_sets(&cgraph->filename, path); + if (error < 0) + return error; + + error = git_futils_mmap_ro(&cgraph->graph_map, fd, 0, cgraph_size); + p_close(fd); + if (error < 0) { + git_commit_graph_free(cgraph); + return error; + } + + if ((error = git_commit_graph_parse(cgraph, cgraph->graph_map.data, cgraph_size)) < 0) { + git_commit_graph_free(cgraph); + return error; + } + + *cgraph_out = cgraph; + return 0; +} + +int git_commit_graph_close(git_commit_graph_file *cgraph) +{ + GIT_ASSERT_ARG(cgraph); + + if (cgraph->graph_map.data) + git_futils_mmap_free(&cgraph->graph_map); + + return 0; +} + +void git_commit_graph_free(git_commit_graph_file *cgraph) +{ + if (!cgraph) + return; + + git_buf_dispose(&cgraph->filename); + git_commit_graph_close(cgraph); + git__free(cgraph); +} diff --git a/src/commit_graph.h b/src/commit_graph.h new file mode 100644 index 00000000000..01512d76faf --- /dev/null +++ b/src/commit_graph.h @@ -0,0 +1,67 @@ +/* + * 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_commit_graph_h__ +#define INCLUDE_commit_graph_h__ + +#include "common.h" + +#include "map.h" + +/** + * A commit-graph file. + * + * This file contains metadata about commits, particularly the generation + * number for each one. This can help speed up graph operations without + * requiring a full graph traversal. + * + * Support for this feature was added in git 2.19. + */ +typedef struct git_commit_graph_file { + git_map graph_map; + + /* The OID Fanout table. */ + const uint32_t *oid_fanout; + /* The total number of commits in the graph. */ + uint32_t num_commits; + + /* The OID Lookup table. */ + git_oid *oid_lookup; + + /* + * The Commit Data table. Each entry contains the OID of the commit followed + * by two 8-byte fields in network byte order: + * - The indices of the first two parents (32 bits each). + * - The generation number (first 30 bits) and commit time in seconds since + * UNIX epoch (34 bits). + */ + const unsigned char *commit_data; + + /* + * The Extra Edge List table. Each 4-byte entry is a network byte order index + * of one of the i-th (i > 0) parents of commits in the `commit_data` table, + * when the commit has more than 2 parents. + */ + const unsigned char *extra_edge_list; + /* The number of entries in the Extra Edge List table. Each entry is 4 bytes wide. */ + size_t num_extra_edge_list; + + /* The trailer of the file. Contains the SHA1-checksum of the whole file. */ + git_oid checksum; + + /* something like ".git/objects/info/commit-graph". */ + git_buf filename; +} git_commit_graph_file; + +int git_commit_graph_open(git_commit_graph_file **cgraph_out, const char *path); +int git_commit_graph_close(git_commit_graph_file *cgraph); +void git_commit_graph_free(git_commit_graph_file *cgraph); + +/* This is exposed for use in the fuzzers. */ +int git_commit_graph_parse(git_commit_graph_file *cgraph, const unsigned char *data, size_t size); + +#endif diff --git a/tests/graph/commit_graph.c b/tests/graph/commit_graph.c new file mode 100644 index 00000000000..329aa5b0040 --- /dev/null +++ b/tests/graph/commit_graph.c @@ -0,0 +1,20 @@ +#include "clar_libgit2.h" + +#include + +#include "commit_graph.h" + +void test_graph_commit_graph__parse(void) +{ + git_repository *repo; + struct git_commit_graph_file *cgraph; + git_buf commit_graph_path = GIT_BUF_INIT; + + cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); + cl_git_pass(git_buf_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph")); + cl_git_pass(git_commit_graph_open(&cgraph, git_buf_cstr(&commit_graph_path))); + + git_commit_graph_free(cgraph); + git_repository_free(repo); + git_buf_dispose(&commit_graph_path); +} diff --git a/tests/resources/testrepo.git/objects/info/commit-graph b/tests/resources/testrepo.git/objects/info/commit-graph new file mode 100644 index 0000000000000000000000000000000000000000..2ef31d83e01a9c46da9c061e972818ffe343b31c GIT binary patch literal 1940 zcmZ>E5Aa}QWM=U9ba7*V01F`72f}2raCUJFfv{Oqpz=V9y#c` z%s@5RFbhzeSj-AkOAX8hG=~so2dW_la{%?x3v&YPLdRS{F%agaG3Ei9j}7wz#Yw?@ zK=ri7{6ITsf>rzZw5HB7^K*Ec#(edP|8AACXaUDPJ(=v$d$;7oC008rP0w$QNOu;CR+O# zcR5Y=vPj-<=8}7U_V*CEhb&=1GmHaNoIbZQ^4ONy7OuL_xqPbVw38({On!B5o*!S| zGL2nE+U-QhX2I51(@U(MttfY?oPXWo#rJ77?7ipSHcl|+KatY+G;7K7J1=6sS(LnN zDV*Dy??@Vd3T=5eP93hCn4nl`%IJ9*;htuI|uJMXBAX+VafMz zE=MXDj;m#9Kkx~cVY#|2(QV?ZnR_o(^Uvz({CM-Z?~y;xoMhj`{a6E>jcINcL9(90tvqt0ro$%`nH@_ zc+o3h@K@l*q&CHz&GmX)FZJWZDIve!l%2@t_(Z+jyKcfqy;qsjHQ%a)#yRZ# zn>Kf$mJrY!9;i72eiLiUB?Qb_W`!(#9lzSaEn@MafGy6Z*OATfe)@r_(W7%g#R0=_ zau>R`{%W&&HCe>O7ibO>%p9P<#3cmof9>r`V->p6tXIOHsnKHGa~5P55QEAb5$`{8 z?o)jD^L&3fM#klBKKJIf$XEV{jY&W`L^wOX?^8Y9`oh1C=X?aQ-8EOgEA}j;-;lgNLqvlJc@X{`ZyK$C3Tze`I59@E@a#MP-xc xAD?$2dhNPTw>f7rhyl%Eh5CyF7=~{uHZ1$2weYV=M%a^>uO}qW{@&u@3IL+3Wk~=4 literal 0 HcmV?d00001 From 1f32ed25ee6f5ead60fff8cf5ba544ef2d567fe0 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Mon, 4 Jan 2021 19:33:48 -0800 Subject: [PATCH 0233/1616] commit-graph: Support lookups of entries in a commit-graph This change introduces `git_commit_graph_entry_find()` and `git_commit_graph_entry_parent()`. These two functions allow a much faster lookup of commits by ID, since the ODB does not need to be consulted, the commit object does not need to be inflated, and the contents of the commit object do not need to be parsed. Part of: #5757 --- fuzzers/commit_graph_fuzzer.c | 5 + src/commit_graph.c | 137 ++++++++++++++++++ src/commit_graph.h | 41 ++++++ tests/graph/commit_graph.c | 69 +++++++++ .../.gitted/objects/info/commit-graph | Bin 0 -> 4624 bytes 5 files changed, 252 insertions(+) create mode 100644 tests/resources/merge-recursive/.gitted/objects/info/commit-graph diff --git a/fuzzers/commit_graph_fuzzer.c b/fuzzers/commit_graph_fuzzer.c index f5b9c898816..eb2c3825852 100644 --- a/fuzzers/commit_graph_fuzzer.c +++ b/fuzzers/commit_graph_fuzzer.c @@ -32,6 +32,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { git_commit_graph_file cgraph = {{0}}; + git_commit_graph_entry e; git_buf commit_graph_buf = GIT_BUF_INIT; git_oid oid = {{0}}; bool append_hash = false; @@ -68,6 +69,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) < 0) goto cleanup; + /* Search for any oid, just to exercise that codepath. */ + if (git_commit_graph_entry_find(&e, &cgraph, &oid, GIT_OID_HEXSZ) < 0) + goto cleanup; + cleanup: git_commit_graph_close(&cgraph); git_buf_dispose(&commit_graph_buf); diff --git a/src/commit_graph.c b/src/commit_graph.c index 71a56e3da49..9740418e2fc 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -9,6 +9,7 @@ #include "futils.h" #include "hash.h" +#include "pack.h" #define GIT_COMMIT_GRAPH_MISSING_PARENT 0x70000000 @@ -278,6 +279,142 @@ int git_commit_graph_open(git_commit_graph_file **cgraph_out, const char *path) return 0; } +static int git_commit_graph_entry_get_byindex( + git_commit_graph_entry *e, + const git_commit_graph_file *cgraph, + size_t pos) +{ + const unsigned char *commit_data; + + GIT_ASSERT_ARG(e); + GIT_ASSERT_ARG(cgraph); + + if (pos >= cgraph->num_commits) { + git_error_set(GIT_ERROR_INVALID, "commit index %zu does not exist", pos); + return GIT_ENOTFOUND; + } + + commit_data = cgraph->commit_data + pos * (GIT_OID_RAWSZ + 4 * sizeof(uint32_t)); + git_oid_cpy(&e->tree_oid, (const git_oid *)commit_data); + e->parent_indices[0] = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ))); + e->parent_indices[1] + = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ + sizeof(uint32_t)))); + e->parent_count = (e->parent_indices[0] != GIT_COMMIT_GRAPH_MISSING_PARENT) + + (e->parent_indices[1] != GIT_COMMIT_GRAPH_MISSING_PARENT); + e->generation = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ + 2 * sizeof(uint32_t)))); + e->commit_time = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ + 3 * sizeof(uint32_t)))); + + e->commit_time |= (e->generation & 0x3ull) << 32ull; + e->generation >>= 2u; + if (e->parent_indices[1] & 0x80000000u) { + uint32_t extra_edge_list_pos = e->parent_indices[1] & 0x7fffffff; + + /* Make sure we're not being sent out of bounds */ + if (extra_edge_list_pos >= cgraph->num_extra_edge_list) { + git_error_set(GIT_ERROR_INVALID, + "commit %u does not exist", + extra_edge_list_pos); + return GIT_ENOTFOUND; + } + + e->extra_parents_index = extra_edge_list_pos; + while (extra_edge_list_pos < cgraph->num_extra_edge_list + && (ntohl(*( + (uint32_t *)(cgraph->extra_edge_list + + extra_edge_list_pos * sizeof(uint32_t)))) + & 0x80000000u) + == 0) { + extra_edge_list_pos++; + e->parent_count++; + } + + } + git_oid_cpy(&e->sha1, &cgraph->oid_lookup[pos]); + return 0; +} + +int git_commit_graph_entry_find( + git_commit_graph_entry *e, + const git_commit_graph_file *cgraph, + const git_oid *short_oid, + size_t len) +{ + int pos, found = 0; + uint32_t hi, lo; + const git_oid *current = NULL; + + GIT_ASSERT_ARG(e); + GIT_ASSERT_ARG(cgraph); + GIT_ASSERT_ARG(short_oid); + + hi = ntohl(cgraph->oid_fanout[(int)short_oid->id[0]]); + lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(cgraph->oid_fanout[(int)short_oid->id[0] - 1])); + + pos = git_pack__lookup_sha1(cgraph->oid_lookup, GIT_OID_RAWSZ, lo, hi, short_oid->id); + + if (pos >= 0) { + /* An object matching exactly the oid was found */ + found = 1; + current = cgraph->oid_lookup + pos; + } else { + /* No object was found */ + /* pos refers to the object with the "closest" oid to short_oid */ + pos = -1 - pos; + if (pos < (int)cgraph->num_commits) { + current = cgraph->oid_lookup + pos; + + if (!git_oid_ncmp(short_oid, current, len)) + found = 1; + } + } + + if (found && len != GIT_OID_HEXSZ && pos + 1 < (int)cgraph->num_commits) { + /* Check for ambiguousity */ + const git_oid *next = current + 1; + + if (!git_oid_ncmp(short_oid, next, len)) { + found = 2; + } + } + + if (!found) + return git_odb__error_notfound( + "failed to find offset for multi-pack index entry", short_oid, len); + if (found > 1) + return git_odb__error_ambiguous( + "found multiple offsets for multi-pack index entry"); + + return git_commit_graph_entry_get_byindex(e, cgraph, pos); +} + +int git_commit_graph_entry_parent( + git_commit_graph_entry *parent, + const git_commit_graph_file *cgraph, + const git_commit_graph_entry *entry, + size_t n) +{ + GIT_ASSERT_ARG(parent); + GIT_ASSERT_ARG(cgraph); + + if (n >= entry->parent_count) { + git_error_set(GIT_ERROR_INVALID, "parent index %zu does not exist", n); + return GIT_ENOTFOUND; + } + + if (n == 0 || (n == 1 && entry->parent_count == 2)) + return git_commit_graph_entry_get_byindex(parent, cgraph, entry->parent_indices[n]); + + return git_commit_graph_entry_get_byindex( + parent, + cgraph, + ntohl( + *(uint32_t *)(cgraph->extra_edge_list + + (entry->extra_parents_index + n - 1) + * sizeof(uint32_t))) + & 0x7fffffff); +} + + int git_commit_graph_close(git_commit_graph_file *cgraph) { GIT_ASSERT_ARG(cgraph); diff --git a/src/commit_graph.h b/src/commit_graph.h index 01512d76faf..f3a431705fc 100644 --- a/src/commit_graph.h +++ b/src/commit_graph.h @@ -57,7 +57,48 @@ typedef struct git_commit_graph_file { git_buf filename; } git_commit_graph_file; +/** + * An entry in the commit-graph file. Provides a subset of the information that + * can be obtained from the commit header. + */ +typedef struct git_commit_graph_entry { + /* The generation number of the commit within the graph */ + size_t generation; + + /* Time in seconds from UNIX epoch. */ + git_time_t commit_time; + + /* The number of parents of the commit. */ + size_t parent_count; + + /* + * The indices of the parent commits within the Commit Data table. The value + * of `GIT_COMMIT_GRAPH_MISSING_PARENT` indicates that no parent is in that + * position. + */ + size_t parent_indices[2]; + + /* The index within the Extra Edge List of any parent after the first two. */ + size_t extra_parents_index; + + /* The SHA-1 hash of the root tree of the commit. */ + git_oid tree_oid; + + /* The SHA-1 hash of the requested commit. */ + git_oid sha1; +} git_commit_graph_entry; + int git_commit_graph_open(git_commit_graph_file **cgraph_out, const char *path); +int git_commit_graph_entry_find( + git_commit_graph_entry *e, + const git_commit_graph_file *cgraph, + const git_oid *short_oid, + size_t len); +int git_commit_graph_entry_parent( + git_commit_graph_entry *parent, + const git_commit_graph_file *cgraph, + const git_commit_graph_entry *entry, + size_t n); int git_commit_graph_close(git_commit_graph_file *cgraph); void git_commit_graph_free(git_commit_graph_file *cgraph); diff --git a/tests/graph/commit_graph.c b/tests/graph/commit_graph.c index 329aa5b0040..43f56679664 100644 --- a/tests/graph/commit_graph.c +++ b/tests/graph/commit_graph.c @@ -8,12 +8,81 @@ void test_graph_commit_graph__parse(void) { git_repository *repo; struct git_commit_graph_file *cgraph; + struct git_commit_graph_entry e, parent; + git_oid id; git_buf commit_graph_path = GIT_BUF_INIT; cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); cl_git_pass(git_buf_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph")); cl_git_pass(git_commit_graph_open(&cgraph, git_buf_cstr(&commit_graph_path))); + cl_git_pass(git_oid_fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5")); + cl_git_pass(git_commit_graph_entry_find(&e, cgraph, &id, GIT_OID_HEXSZ)); + cl_assert_equal_oid(&e.sha1, &id); + cl_git_pass(git_oid_fromstr(&id, "418382dff1ffb8bdfba833f4d8bbcde58b1e7f47")); + cl_assert_equal_oid(&e.tree_oid, &id); + cl_assert_equal_i(e.generation, 1); + cl_assert_equal_i(e.commit_time, 1273610423ull); + cl_assert_equal_i(e.parent_count, 0); + + cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); + cl_git_pass(git_commit_graph_entry_find(&e, cgraph, &id, GIT_OID_HEXSZ)); + cl_assert_equal_oid(&e.sha1, &id); + cl_assert_equal_i(e.generation, 5); + cl_assert_equal_i(e.commit_time, 1274813907ull); + cl_assert_equal_i(e.parent_count, 2); + + cl_git_pass(git_oid_fromstr(&id, "9fd738e8f7967c078dceed8190330fc8648ee56a")); + cl_git_pass(git_commit_graph_entry_parent(&parent, cgraph, &e, 0)); + cl_assert_equal_oid(&parent.sha1, &id); + cl_assert_equal_i(parent.generation, 4); + + cl_git_pass(git_oid_fromstr(&id, "c47800c7266a2be04c571c04d5a6614691ea99bd")); + cl_git_pass(git_commit_graph_entry_parent(&parent, cgraph, &e, 1)); + cl_assert_equal_oid(&parent.sha1, &id); + cl_assert_equal_i(parent.generation, 3); + + git_commit_graph_free(cgraph); + git_repository_free(repo); + git_buf_dispose(&commit_graph_path); +} + +void test_graph_commit_graph__parse_octopus_merge(void) +{ + git_repository *repo; + struct git_commit_graph_file *cgraph; + struct git_commit_graph_entry e, parent; + git_oid id; + git_buf commit_graph_path = GIT_BUF_INIT; + + cl_git_pass(git_repository_open(&repo, cl_fixture("merge-recursive/.gitted"))); + cl_git_pass(git_buf_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph")); + cl_git_pass(git_commit_graph_open(&cgraph, git_buf_cstr(&commit_graph_path))); + + cl_git_pass(git_oid_fromstr(&id, "d71c24b3b113fd1d1909998c5bfe33b86a65ee03")); + cl_git_pass(git_commit_graph_entry_find(&e, cgraph, &id, GIT_OID_HEXSZ)); + cl_assert_equal_oid(&e.sha1, &id); + cl_git_pass(git_oid_fromstr(&id, "348f16ffaeb73f319a75cec5b16a0a47d2d5e27c")); + cl_assert_equal_oid(&e.tree_oid, &id); + cl_assert_equal_i(e.generation, 7); + cl_assert_equal_i(e.commit_time, 1447083009ull); + cl_assert_equal_i(e.parent_count, 3); + + cl_git_pass(git_oid_fromstr(&id, "ad2ace9e15f66b3d1138922e6ffdc3ea3f967fa6")); + cl_git_pass(git_commit_graph_entry_parent(&parent, cgraph, &e, 0)); + cl_assert_equal_oid(&parent.sha1, &id); + cl_assert_equal_i(parent.generation, 6); + + cl_git_pass(git_oid_fromstr(&id, "483065df53c0f4a02cdc6b2910b05d388fc17ffb")); + cl_git_pass(git_commit_graph_entry_parent(&parent, cgraph, &e, 1)); + cl_assert_equal_oid(&parent.sha1, &id); + cl_assert_equal_i(parent.generation, 2); + + cl_git_pass(git_oid_fromstr(&id, "815b5a1c80ca749d705c7aa0cb294a00cbedd340")); + cl_git_pass(git_commit_graph_entry_parent(&parent, cgraph, &e, 2)); + cl_assert_equal_oid(&parent.sha1, &id); + cl_assert_equal_i(parent.generation, 6); + git_commit_graph_free(cgraph); git_repository_free(repo); git_buf_dispose(&commit_graph_path); diff --git a/tests/resources/merge-recursive/.gitted/objects/info/commit-graph b/tests/resources/merge-recursive/.gitted/objects/info/commit-graph new file mode 100644 index 0000000000000000000000000000000000000000..da055f180f78f466a8a4df94788e6408a5033f50 GIT binary patch literal 4624 zcmb`L2{=^iAIB||oyge7&PW(bwvv6auh9@AOGVjfqbN(t7D}>b-*T-fBBCrIYAoqy z7ZOq`DvJO6UeirI-0pLq|2)sRCI(Bhy!KAl(2mP__}|pd7J|Ex`UA6hQM|pal2*8>oQp zcTfWj%?8kdvhUCVn|=crK-qe>f@{WKU;@{WZR=nL_C_E<`TqkJP|tc;!S#38fXz;X z1Dqk8L{Q-TE8L)LGkAax!n*-{plmbvflqK9LckUVpnpLGTtjvM#Qp(s;QNjQu)l)= zwj@C6Umy)M5Sf2qC-7~A94Oxic~HI?3c$A>MR5I{UBLd%Zeafxl)!zEJsY45%2a;K zd7iP7D4WEXqfU*2CmBb5X~L?u9IEtm>v(eQ9vxZ7^#+A&WInS6w3TlxmCq&hQcm3^ zJ7A2zf}Y;%LN`XXXq+$S$|)0U+o@*RcB-`H&DPxMuH#&(%;77F59M3E&!wA)a-rALz_vt0CzZIfk@yDGJ--v3VAqt;X!zjHG0 zO2!$AX-9VXTr)E0RT*fYVWTNuMM`?d-L>4UYUSS0dX&)B+eJS|&&sK3`rcQyhaHg@ z<5s0ra`55>tPjTA`J=N2*DijF5#M1qb+N+ULyqyWLC0n_-ShB?3nJqcl7kh_b;GC8 zGhV4WQb&f(>OZE754eajmf9#rH=JKKaCohQ=@I92qYC4oD7Qzy$j)Cd{K_?DmFk+1 zz#@e0788unoBjOQlo@Y%p>L2`@~x7lc$+1<`fjv>S@Kh+#vpMV9XDHBX&i~m8OBeP zILiD+JI>?&HwSsOX@{gWN)|lPc#+$mnimI+tPKyxJE`}&N__qp?*4&WE^DE%Va(V# zX$fCW>OsCF;Vm6Ff4`eSJD1SyY-2uQwDv~`t}q|vBfAD)yM!KZy8S}M_c5~La4_wetEWerW>4-+BSo>f z(eX_%Hx8lv&VD`^AI;5PkMr=95U)Jtl5*MDFG=e8z?=+?67LNHt)-CfQbBh{ptTh$ zpzTDeC;m)&yQm&X`7W)3u*e7x9s0#YpO#MLqj?c9bTJ1#H1JdzPqX5fCMH4valIj+}- z3mjuh77p)un5Oo?*zrDZiO!4zS#L^6%HS9)BE=cs@uI#ca1o)N8W!^=y)%qD*jO>y zIASt)R)gxOhJ;#1X5hJ}Q*9m-V(&6(B~50o-JLdP$&BQ0rO7%HaF|Qhgy~``XIPR` zaORTyYGclkOu;c>f;IbT<4aE)-(?wDv91)>lFQ}pyxAYb*7~78=km=PXqju@Bt1O- z>?{;)i+njP{))0_N9PTeMHgiz#j6;PZx5$cub3MC)qDRYi813_`_@|a-FmkkcOPs!bSuwUu596BNyYK%yb%hX+(+uoHZ zv}7MN51o%=tc_2g6CenfqzqoM{nO_%?ooF!Ut@5ae(5DPy@htuzP5t;wDHWy_BH|i zYMOAN`BR~Y6_aS>=3Wj=Y~wdVgNn@`#UuGWm8;)|IGH7U|W`vtg8+2sii;KzrLj@sXT zmCd1UL*D+xmbDG|M2H%3E88Y+Qunud9&fu{25!a{otD)dY--t412jrR4I@s}?D`}+ zoY&Eu$%}tdV%};;c%{nb1xwjw@BuzJ z=fOD~iNi$Ss7`${;(H+~3eRPBPsv?-)naix5csHw&)Ng(QA-ktsp|i^o_#tDf#}2M znknC9s0(y9mYK2i#XMRCn(cqLGbV+gX)fd&b&!jHaBnE#!If&GGT(d{>yLQUsy#dD zPZ)HKM*Z19R!S4w3E2Go@*Bpl(|53Y0InGR=UoUR{a)2z|%emC82 zLjUu#tD(ztx^Rsx|2-b?EXq++VUu^M31rA|cQ;ilF}{a=7W;wb$GaOD&S*;hk=`uP zge&sOloXs$&vuU33S*}E5f46VlRShu2y+qUVa2o@zmC;#dZ~i)^i7KXtL&MW7gN9o z*KROB#6fPjw)soDxg~u`6$*SE@GRo=g!l8UuYhj{@mWZmSzgpnZ6ZJabDunuP*CZ>>2YhEjbR4n4=Yi_j>BBZ@lw$Y zaVihd6tpct;|;9IDim5^uF?WT0U%e+Y{v*8OF{mY%m&kZcSncA6n8e`;M)I3J7bbp z#$xXe_6O#h)s(qJSWaFG8Y5G?LZ60sEgI(N9|Tzj6cj z|7d4NTRkkyE;o>>h4m zt?m0rNTn|8WnG2*R5bAY_!gr3lqn^`20r9DaX!?Gx@27`c`Nw|vJYtZiQgTJ&-go` zA)$FeMVhMj>6*|Zek&e&E_Szms>jH%x4xD#+`j9vK$Cb*C!%m*0N)UF185NI@~1h= zD%a*BzinqsTK&DwFkOP!Y&8~W?IN~PGr*Ql9*|jeviYPU_JuH!E;BpfW?uTO-9LwN1#&^7&E{b|d1pO>+ z@z^nTJ0z=3)7?LqWip zsm;}L@A1c)fr#bIotz3q2UF$;WuOo4?ckp8ulaP7c*FzN_V6H{d!&b^PAkn06+Aqa z5|?v=cA`4J?(#8k|MzhdjG0CnBP=t0N#6MpSFa2+oko@5J|3F-0yMCVVOzs?=G!D@ z7}H;IgP85Dqj+%biBorz9$;p}XBIUu9aQze&q926Bu Date: Tue, 5 Jan 2021 06:24:26 -0800 Subject: [PATCH 0234/1616] commit-graph: Introduce `git_commit_graph_needs_refresh()` This change introduces a function that allows the caller to know whether the `commit-graph` file has not been modified since it was parsed. Part of: #5757 --- src/commit_graph.c | 34 ++++++++++++++++++++++++++++++++++ src/commit_graph.h | 8 ++++++++ tests/graph/commit_graph.c | 1 + 3 files changed, 43 insertions(+) diff --git a/src/commit_graph.c b/src/commit_graph.c index 9740418e2fc..b301d3d4910 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -333,6 +333,40 @@ static int git_commit_graph_entry_get_byindex( return 0; } +bool git_commit_graph_needs_refresh(const git_commit_graph_file *cgraph, const char *path) +{ + git_file fd = -1; + struct stat st; + ssize_t bytes_read; + git_oid cgraph_checksum = {{0}}; + + if (path == NULL) + path = git_buf_cstr(&cgraph->filename); + + /* TODO: properly open the file without access time using O_NOATIME */ + fd = git_futils_open_ro(path); + if (fd < 0) + return true; + + if (p_fstat(fd, &st) < 0) { + p_close(fd); + return true; + } + + if (!S_ISREG(st.st_mode) || !git__is_sizet(st.st_size) + || (size_t)st.st_size != cgraph->graph_map.len) { + p_close(fd); + return true; + } + + bytes_read = p_pread(fd, cgraph_checksum.id, GIT_OID_RAWSZ, st.st_size - GIT_OID_RAWSZ); + p_close(fd); + if (bytes_read != GIT_OID_RAWSZ) + return true; + + return !git_oid_equal(&cgraph_checksum, &cgraph->checksum); +} + int git_commit_graph_entry_find( git_commit_graph_entry *e, const git_commit_graph_file *cgraph, diff --git a/src/commit_graph.h b/src/commit_graph.h index f3a431705fc..f21a03769ee 100644 --- a/src/commit_graph.h +++ b/src/commit_graph.h @@ -89,6 +89,14 @@ typedef struct git_commit_graph_entry { } git_commit_graph_entry; int git_commit_graph_open(git_commit_graph_file **cgraph_out, const char *path); + +/* + * Returns whether the commit_graph_file needs to be reloaded since the + * contents of the commit-graph file have changed on disk. If `path` is NULL, + * the filename stored in `cgraph` will be used. + */ +bool git_commit_graph_needs_refresh(const git_commit_graph_file *cgraph, const char *path); + int git_commit_graph_entry_find( git_commit_graph_entry *e, const git_commit_graph_file *cgraph, diff --git a/tests/graph/commit_graph.c b/tests/graph/commit_graph.c index 43f56679664..4c7c5a726a3 100644 --- a/tests/graph/commit_graph.c +++ b/tests/graph/commit_graph.c @@ -15,6 +15,7 @@ void test_graph_commit_graph__parse(void) cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); cl_git_pass(git_buf_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph")); cl_git_pass(git_commit_graph_open(&cgraph, git_buf_cstr(&commit_graph_path))); + cl_assert_equal_i(git_commit_graph_needs_refresh(cgraph, git_buf_cstr(&commit_graph_path)), 0); cl_git_pass(git_oid_fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5")); cl_git_pass(git_commit_graph_entry_find(&e, cgraph, &id, GIT_OID_HEXSZ)); From 75888f273e9beae91e48e3490e50b4db9c208117 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 15 Jan 2021 10:29:05 +0000 Subject: [PATCH 0235/1616] ci: don't use ninja on macOS Ninja is not installed by default on the macOS machines; stop trying to use it. Instead use `make -j` which should be roughly equivalent in performance but supported everywhere. --- .github/workflows/main.yml | 1 - .github/workflows/nightly.yml | 1 - ci/build.sh | 13 ++++++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f101eda65f3..3d2102c2102 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -153,7 +153,6 @@ jobs: env: CC: clang CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON - CMAKE_GENERATOR: Ninja PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 2f56fdb7f21..b52b398d8fd 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -112,7 +112,6 @@ jobs: env: CC: clang CMAKE_OPTIONS: -DREGEX_BACKEND=regcomp_l -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=leaks -DUSE_GSSAPI=ON - CMAKE_GENERATOR: Ninja PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true diff --git a/ci/build.sh b/ci/build.sh index c230e67d68a..5a51f925ad0 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -33,6 +33,9 @@ if [ -f "/etc/debian_version" ]; then (source /etc/lsb-release && echo "${DISTRIB_DESCRIPTION}") | indent fi +CORES=$(getconf _NPROCESSORS_ONLN || true) +echo "Number of cores: ${CORES:-(Unknown)}" + echo "Kernel version:" uname -a 2>&1 | indent @@ -64,4 +67,12 @@ echo "########################################################################## echo "## Building libgit2" echo "##############################################################################" -env PATH="${BUILD_PATH}" "${CMAKE}" --build . +# Determine parallelism; newer cmake supports `--build --parallel` but +# we cannot yet rely on that. +if [ "${CMAKE_GENERATOR}" = "Unix Makefiles" -a "${CORES}" != "" ]; then + BUILDER=(make -j ${CORES}) +else + BUILDER=("${CMAKE}" --build .) +fi + +env PATH="${BUILD_PATH}" "${BUILDER[@]}" From 2f382ab74b7b8568b47e118f1802763a911b84e3 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Wed, 20 Jan 2021 04:40:40 -0800 Subject: [PATCH 0236/1616] mwindow: Fix a bug in the LRU window finding code This change now updates the `lru_window` variable to match the current file's MRU window. This makes it such that it doesn't always choose the file that happened to come last in the list of window files, and instead should now correctly choose the file with the least-recently-used one. --- src/mwindow.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mwindow.c b/src/mwindow.c index 7832d9c8baf..5fcae2eed51 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -312,8 +312,10 @@ static int git_mwindow_find_lru_file_locked(git_mwindow_file **out) current_file, &mru_window, NULL, true, GIT_MWINDOW__MRU)) { continue; } - if (!lru_window || lru_window->last_used > mru_window->last_used) + if (!lru_window || lru_window->last_used > mru_window->last_used) { + lru_window = mru_window; lru_file = current_file; + } } if (!lru_file) { From 50f536222b6576a4204b980978d6094770a21038 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 22 Jan 2021 11:22:53 +0000 Subject: [PATCH 0237/1616] meta: tell "linguist" that the test resources are vendored Our test resources shouldn't count toward our language statistics. We have some PHP checked in to the test resources, but I assure you that we do not have any production code in PHP and we shouldn't be blamed for the test data. --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index 176a458f94e..3d90b7d61f8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ * text=auto +tests/resources/** linguist-vendored From e44890774c6c98a84c3eb881b1d7508dfe7d7373 Mon Sep 17 00:00:00 2001 From: Laurence McGlashan Date: Sun, 31 Jan 2021 15:35:56 +0000 Subject: [PATCH 0238/1616] Update .gitignore Only exclude tags files/folders and build folders at the repository root. --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index b38b7e16ee4..69d388f8ec4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ -build/ +/build/ .DS_Store *~ .*.swp -tags +/tags CMakeSettings.json .vs From 4732e03056b1b88fdeb3276d96dfd9400d75233a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 31 Jan 2021 00:36:54 +0000 Subject: [PATCH 0239/1616] revspec: rename git_revparse_mode_t to git_revspec_t The information about the type of a revision spec is not information about the parser. Name it accordingly, so that `git_revparse_mode_t` is now `git_revspec_t`. Deprecate the old name. --- examples/blame.c | 2 +- examples/log.c | 6 +++--- examples/rev-list.c | 2 +- examples/rev-parse.c | 6 +++--- include/git2/deprecated.h | 21 +++++++++++++++++++++ include/git2/revparse.h | 10 +++++----- src/revparse.c | 6 +++--- src/revwalk.c | 2 +- tests/refs/revparse.c | 26 +++++++++++++------------- 9 files changed, 51 insertions(+), 30 deletions(-) diff --git a/examples/blame.c b/examples/blame.c index 49350fc0f0a..954c97b17d1 100644 --- a/examples/blame.c +++ b/examples/blame.c @@ -54,7 +54,7 @@ int lg2_blame(git_repository *repo, int argc, char *argv[]) */ if (o.commitspec) { check_lg2(git_revparse(&revspec, repo, o.commitspec), "Couldn't parse commit spec", NULL); - if (revspec.flags & GIT_REVPARSE_SINGLE) { + if (revspec.flags & GIT_REVSPEC_SINGLE) { git_oid_cpy(&blameopts.newest_commit, git_object_id(revspec.from)); git_object_free(revspec.from); } else { diff --git a/examples/log.c b/examples/log.c index ee18df54225..9060f3f3ea2 100644 --- a/examples/log.c +++ b/examples/log.c @@ -245,7 +245,7 @@ static int add_revision(struct log_state *s, const char *revstr) } if (*revstr == '^') { - revs.flags = GIT_REVPARSE_SINGLE; + revs.flags = GIT_REVSPEC_SINGLE; hide = !hide; if (git_revparse_single(&revs.from, s->repo, revstr + 1) < 0) @@ -253,12 +253,12 @@ static int add_revision(struct log_state *s, const char *revstr) } else if (git_revparse(&revs, s->repo, revstr) < 0) return -1; - if ((revs.flags & GIT_REVPARSE_SINGLE) != 0) + if ((revs.flags & GIT_REVSPEC_SINGLE) != 0) push_rev(s, revs.from, hide); else { push_rev(s, revs.to, hide); - if ((revs.flags & GIT_REVPARSE_MERGE_BASE) != 0) { + if ((revs.flags & GIT_REVSPEC_MERGE_BASE) != 0) { git_oid base; check_lg2(git_merge_base(&base, s->repo, git_object_id(revs.from), git_object_id(revs.to)), diff --git a/examples/rev-list.c b/examples/rev-list.c index 75fb19e7079..d10f166900e 100644 --- a/examples/rev-list.c +++ b/examples/rev-list.c @@ -73,7 +73,7 @@ static int push_range(git_repository *repo, git_revwalk *walk, const char *range if ((error = git_revparse(&revspec, repo, range))) return error; - if (revspec.flags & GIT_REVPARSE_MERGE_BASE) { + if (revspec.flags & GIT_REVSPEC_MERGE_BASE) { /* TODO: support "..." */ return GIT_EINVALIDSPEC; } diff --git a/examples/rev-parse.c b/examples/rev-parse.c index 7d6e9986f28..90258c10139 100644 --- a/examples/rev-parse.c +++ b/examples/rev-parse.c @@ -69,17 +69,17 @@ static int parse_revision(git_repository *repo, struct parse_state *ps) check_lg2(git_revparse(&rs, repo, ps->spec), "Could not parse", ps->spec); - if ((rs.flags & GIT_REVPARSE_SINGLE) != 0) { + if ((rs.flags & GIT_REVSPEC_SINGLE) != 0) { git_oid_tostr(str, sizeof(str), git_object_id(rs.from)); printf("%s\n", str); git_object_free(rs.from); } - else if ((rs.flags & GIT_REVPARSE_RANGE) != 0) { + else if ((rs.flags & GIT_REVSPEC_RANGE) != 0) { git_oid_tostr(str, sizeof(str), git_object_id(rs.to)); printf("%s\n", str); git_object_free(rs.to); - if ((rs.flags & GIT_REVPARSE_MERGE_BASE) != 0) { + if ((rs.flags & GIT_REVSPEC_MERGE_BASE) != 0) { git_oid base; check_lg2(git_merge_base(&base, repo, git_object_id(rs.from), git_object_id(rs.to)), diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index 79f637a7f33..d18fffc0e3f 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -29,6 +29,7 @@ #include "trace.h" #include "repository.h" #include "revert.h" +#include "revparse.h" #include "stash.h" #include "status.h" #include "submodule.h" @@ -414,6 +415,25 @@ GIT_EXTERN(int) git_tag_create_frombuffer( /**@}*/ +/** @name Deprecated Revspec Constants + * + * These enumeration values are retained for backward compatibility. + * The newer versions of these values should be preferred in all new + * code. + * + * There is no plan to remove these backward compatibility values at + * this time. + */ +/**@{*/ + +typedef git_revspec_t git_revparse_mode_t; + +#define GIT_REVPARSE_SINGLE GIT_REVSPEC_SINGLE +#define GIT_REVPARSE_RANGE GIT_REVSPEC_RANGE +#define GIT_REVPARSE_MERGE_BASE GIT_REVSPEC_MERGE_BASE + +/**@}*/ + /** @name Deprecated Credential Types * * These types are retained for backward compatibility. The newer @@ -422,6 +442,7 @@ GIT_EXTERN(int) git_tag_create_frombuffer( * There is no plan to remove these backward compatibility values at * this time. */ +/**@{*/ typedef git_credential git_cred; typedef git_credential_userpass_plaintext git_cred_userpass_plaintext; diff --git a/include/git2/revparse.h b/include/git2/revparse.h index d170e162184..e14ddee96cf 100644 --- a/include/git2/revparse.h +++ b/include/git2/revparse.h @@ -70,12 +70,12 @@ GIT_EXTERN(int) git_revparse_ext( */ typedef enum { /** The spec targeted a single object. */ - GIT_REVPARSE_SINGLE = 1 << 0, + GIT_REVSPEC_SINGLE = 1 << 0, /** The spec targeted a range of commits. */ - GIT_REVPARSE_RANGE = 1 << 1, + GIT_REVSPEC_RANGE = 1 << 1, /** The spec used the '...' operator, which invokes special semantics. */ - GIT_REVPARSE_MERGE_BASE = 1 << 2, -} git_revparse_mode_t; + GIT_REVSPEC_MERGE_BASE = 1 << 2, +} git_revspec_t; /** * Git Revision Spec: output of a `git_revparse` operation @@ -85,7 +85,7 @@ typedef struct { git_object *from; /** The right element of the revspec; must be freed by the user */ git_object *to; - /** The intent of the revspec (i.e. `git_revparse_mode_t` flags) */ + /** The intent of the revspec (i.e. `git_revspec_mode_t` flags) */ unsigned int flags; } git_revspec; diff --git a/src/revparse.c b/src/revparse.c index 4b919d32a63..b0c312d722c 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -894,7 +894,7 @@ int git_revparse( if ((dotdot = strstr(spec, "..")) != NULL) { char *lstr; const char *rstr; - revspec->flags = GIT_REVPARSE_RANGE; + revspec->flags = GIT_REVSPEC_RANGE; /* * Following git.git, don't allow '..' because it makes command line @@ -910,7 +910,7 @@ int git_revparse( lstr = git__substrdup(spec, dotdot - spec); rstr = dotdot + 2; if (dotdot[2] == '.') { - revspec->flags |= GIT_REVPARSE_MERGE_BASE; + revspec->flags |= GIT_REVSPEC_MERGE_BASE; rstr++; } @@ -928,7 +928,7 @@ int git_revparse( git__free((void*)lstr); } else { - revspec->flags = GIT_REVPARSE_SINGLE; + revspec->flags = GIT_REVSPEC_SINGLE; error = git_revparse_single(&revspec->from, repo, spec); } diff --git a/src/revwalk.c b/src/revwalk.c index 249cb16bf96..a686a9f6fa9 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -238,7 +238,7 @@ int git_revwalk_push_range(git_revwalk *walk, const char *range) goto out; } - if (revspec.flags & GIT_REVPARSE_MERGE_BASE) { + if (revspec.flags & GIT_REVSPEC_MERGE_BASE) { /* TODO: support "..." */ git_error_set(GIT_ERROR_INVALID, "symmetric differences not implemented in revwalk"); error = GIT_EINVALIDSPEC; diff --git a/tests/refs/revparse.c b/tests/refs/revparse.c index 3c4ed9af5bf..bc6e0a4c411 100644 --- a/tests/refs/revparse.c +++ b/tests/refs/revparse.c @@ -50,7 +50,7 @@ static void test_id_inrepo( const char *spec, const char *expected_left, const char *expected_right, - git_revparse_mode_t expected_flags, + git_revspec_t expected_flags, git_repository *repo) { git_revspec revspec; @@ -90,7 +90,7 @@ static void test_object_and_ref(const char *spec, const char *expected_oid, cons static void test_rangelike(const char *rangelike, const char *expected_left, const char *expected_right, - git_revparse_mode_t expected_revparseflags) + git_revspec_t expected_revparseflags) { char objstr[64] = {0}; git_revspec revspec; @@ -117,7 +117,7 @@ static void test_id( const char *spec, const char *expected_left, const char *expected_right, - git_revparse_mode_t expected_flags) + git_revspec_t expected_flags) { test_id_inrepo(spec, expected_left, expected_right, expected_flags, g_repo); } @@ -735,53 +735,53 @@ void test_refs_revparse__range(void) test_rangelike("be3563a^1..be3563a", "9fd738e8f7967c078dceed8190330fc8648ee56a", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", - GIT_REVPARSE_RANGE); + GIT_REVSPEC_RANGE); test_rangelike("be3563a^1...be3563a", "9fd738e8f7967c078dceed8190330fc8648ee56a", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", - GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE); + GIT_REVSPEC_RANGE | GIT_REVSPEC_MERGE_BASE); test_rangelike("be3563a^1.be3563a", NULL, NULL, 0); } void test_refs_revparse__parses_range_operator(void) { - test_id("HEAD", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", NULL, GIT_REVPARSE_SINGLE); + test_id("HEAD", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", NULL, GIT_REVSPEC_SINGLE); test_id("HEAD~3..HEAD", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", - GIT_REVPARSE_RANGE); + GIT_REVSPEC_RANGE); test_id("HEAD~3...HEAD", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", - GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE); + GIT_REVSPEC_RANGE | GIT_REVSPEC_MERGE_BASE); test_id("HEAD~3..", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", - GIT_REVPARSE_RANGE); + GIT_REVSPEC_RANGE); test_id("HEAD~3...", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", - GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE); + GIT_REVSPEC_RANGE | GIT_REVSPEC_MERGE_BASE); test_id("..HEAD~3", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", - GIT_REVPARSE_RANGE); + GIT_REVSPEC_RANGE); test_id("...HEAD~3", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", - GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE); + GIT_REVSPEC_RANGE | GIT_REVSPEC_MERGE_BASE); test_id("...", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", - GIT_REVPARSE_RANGE | GIT_REVPARSE_MERGE_BASE); + GIT_REVSPEC_RANGE | GIT_REVSPEC_MERGE_BASE); test_invalid_revspec(".."); } From 82a091c49162acc87bf7638aac83e0a08335fa6e Mon Sep 17 00:00:00 2001 From: Jeroen Ooms Date: Thu, 11 Feb 2021 15:19:09 +0100 Subject: [PATCH 0240/1616] Add new bindings for the R language --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 23c569e4c67..1f72f277fe5 100644 --- a/README.md +++ b/README.md @@ -392,6 +392,7 @@ Here are the bindings to libgit2 that are currently available: * Python * pygit2 * R + * gert * git2r * Ruby * Rugged From 935f85131fa106730bbf66d49808b5aca375f729 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 15 Feb 2021 16:03:23 +0000 Subject: [PATCH 0241/1616] CI: add workflow_dispatch event to the main build Invert the workflow conditionals so that a workflow_dispatch event acts like an on: push build. --- .github/workflows/main.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3d2102c2102..7179a613d36 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,6 +7,7 @@ on: branches: [ main, maint/* ] pull_request: branches: [ main, maint/* ] + workflow_dispatch: env: docker-registry: docker.pkg.github.com @@ -48,7 +49,7 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 - if: github.event_name == 'push' + if: github.event_name != 'pull_request' - name: Setup QEMU run: docker run --rm --privileged multiarch/qemu-user-static:register --reset if: matrix.container.qemu == true @@ -59,7 +60,7 @@ jobs: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} working-directory: ${{ env.docker-config-path }} - if: github.event_name == 'push' + if: github.event_name != 'pull_request' - name: Build and publish image run: | if [ "${{ matrix.container.base }}" != "" ]; then @@ -68,7 +69,7 @@ jobs: docker build -t ${{ env.docker-registry-container-sha }} ${BASE_ARG} -f ${{ env.dockerfile }} . docker push ${{ env.docker-registry-container-sha }} working-directory: ${{ env.docker-config-path }} - if: github.event_name == 'push' && env.docker-container-exists != 'true' + if: github.event_name != 'pull_request' && env.docker-container-exists != 'true' # Run our CI/CD builds. We build a matrix with the various build targets # and their details. Then we build either in a docker container (Linux) @@ -292,4 +293,4 @@ jobs: path: api-documentation.zip - name: Push documentation branch run: git push origin gh-pages - if: github.event_name == 'push' && github.repository == 'libgit2/libgit2' + if: github.event_name != 'pull_request' && github.repository == 'libgit2/libgit2' From 7efddeb7376b3e10379ea662c9a235ae079119d7 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Mon, 15 Feb 2021 15:47:28 -0500 Subject: [PATCH 0242/1616] Fix some typos --- examples/checkout.c | 2 +- examples/common.h | 2 +- examples/tag.c | 4 ++-- src/cc-compat.h | 2 +- src/refs.c | 2 +- src/remote.c | 6 +++--- src/transports/winhttp.c | 2 +- src/win32/w32_leakcheck.c | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/checkout.c b/examples/checkout.c index 204b58d8825..ac7b7422d7b 100644 --- a/examples/checkout.c +++ b/examples/checkout.c @@ -14,7 +14,7 @@ #include "common.h" -/* Define the printf format specifer to use for size_t output */ +/* Define the printf format specifier to use for size_t output */ #if defined(_MSC_VER) || defined(__MINGW32__) # define PRIuZ "Iu" # define PRIxZ "Ix" diff --git a/examples/common.h b/examples/common.h index 0126568aba8..f86e92c3574 100644 --- a/examples/common.h +++ b/examples/common.h @@ -36,7 +36,7 @@ #endif #ifndef PRIuZ -/* Define the printf format specifer to use for size_t output */ +/* Define the printf format specifier to use for size_t output */ #if defined(_MSC_VER) || defined(__MINGW32__) # define PRIuZ "Iu" #else diff --git a/examples/tag.c b/examples/tag.c index 03d9c2bf9b2..e4f71ae625f 100644 --- a/examples/tag.c +++ b/examples/tag.c @@ -188,7 +188,7 @@ static void action_delete_tag(tag_state *state) git_object_free(obj); } -static void action_create_lighweight_tag(tag_state *state) +static void action_create_lightweight_tag(tag_state *state) { git_repository *repo = state->repo; struct tag_options *opts = state->opts; @@ -260,7 +260,7 @@ static void parse_options(tag_action *action, struct tag_options *opts, int argc print_usage(); if (*action != &action_create_tag) - *action = &action_create_lighweight_tag; + *action = &action_create_lightweight_tag; } else if (!strcmp(curr, "-n")) { opts->num_lines = 1; *action = &action_list_tags; diff --git a/src/cc-compat.h b/src/cc-compat.h index 7ade561f3de..de1469da85a 100644 --- a/src/cc-compat.h +++ b/src/cc-compat.h @@ -45,7 +45,7 @@ #define GIT_UNUSED(x) ((void)(x)) -/* Define the printf format specifer to use for size_t output */ +/* Define the printf format specifier to use for size_t output */ #if defined(_MSC_VER) || defined(__MINGW32__) /* Visual Studio 2012 and prior lack PRId64 entirely */ diff --git a/src/refs.c b/src/refs.c index a954b835949..4900afabf12 100644 --- a/src/refs.c +++ b/src/refs.c @@ -1343,7 +1343,7 @@ const char *git_reference__shorthand(const char *name) else if (!git__prefixcmp(name, GIT_REFS_DIR)) return name + strlen(GIT_REFS_DIR); - /* No shorthands are avaiable, so just return the name */ + /* No shorthands are available, so just return the name. */ return name; } diff --git a/src/remote.c b/src/remote.c index 55effccfb91..5f6ba5bf74e 100644 --- a/src/remote.c +++ b/src/remote.c @@ -121,7 +121,7 @@ static int write_add_refspec(git_repository *repo, const char *name, const char return error; /* - * "$^" is a unmatcheable regexp: it will not match anything at all, so + * "$^" is an unmatchable regexp: it will not match anything at all, so * all values will be considered new and we will not replace any * present value. */ @@ -1317,7 +1317,7 @@ int git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks) if (error == GIT_ENOTFOUND) continue; - /* if we did find a source, remove it from the candiates */ + /* If we did find a source, remove it from the candidates. */ if ((error = git_vector_set((void **) &src_name, &candidates, i, NULL)) < 0) goto cleanup; @@ -1682,7 +1682,7 @@ int git_remote_update_tips( goto out; } - /* only try to do opportunisitic updates if the refpec lists differ */ + /* Only try to do opportunistic updates if the refpec lists differ. */ if (remote->passed_refspecs) error = opportunistic_updates(remote, callbacks, &refs, reflog_message); diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index 54aacdba3a6..a2a71be95b5 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -268,7 +268,7 @@ static int acquire_fallback_cred( pISM->lpVtbl->Release(pISM); } - /* Only unitialize if the call to CoInitializeEx was successful. */ + /* Only uninitialize if the call to CoInitializeEx was successful. */ if (SUCCEEDED(hCoInitResult)) CoUninitialize(); } diff --git a/src/win32/w32_leakcheck.c b/src/win32/w32_leakcheck.c index 95187a570b6..ef17004436c 100644 --- a/src/win32/w32_leakcheck.c +++ b/src/win32/w32_leakcheck.c @@ -513,7 +513,7 @@ int git_win32_leakcheck_stacktrace_dump( */ void git_win32_leakcheck_stacktrace_cleanup(void) { - /* At shutdown/cleanup, dump cummulative leak info + /* At shutdown/cleanup, dump cumulative leak info * with everything since startup. This might generate * extra noise if the caller has been doing checkpoint * dumps, but it might also eliminate some false From 36232528105303843e8474c5406d533bee396a76 Mon Sep 17 00:00:00 2001 From: panda Date: Tue, 16 Feb 2021 13:08:02 -0800 Subject: [PATCH 0243/1616] refdb_fs: Check git_sortedcache wlock/rlock errors To prevent a race condition, these wlock/rlock calls should probably be checked for errors. --- src/refdb_fs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index aef5ab237ca..a5a6b3c0ec0 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -254,7 +254,8 @@ static int loose_lookup_to_packfile(refdb_fs_backend *backend, const char *name) if ((error = loose_parse_oid(&oid, name, &ref_file)) < 0) goto done; - git_sortedcache_wlock(backend->refcache); + if ((error = git_sortedcache_wlock(backend->refcache)) < 0) + goto done; if (!(error = git_sortedcache_upsert( (void **)&ref, backend->refcache, name))) { @@ -760,7 +761,8 @@ static int reference_path_available( } } - git_sortedcache_rlock(backend->refcache); + if ((error = git_sortedcache_rlock(backend->refcache)) < 0) + return error; for (i = 0; i < git_sortedcache_entrycount(backend->refcache); ++i) { struct packref *ref = git_sortedcache_entry(backend->refcache, i); From 21981f28627b65d43590166b6a1782bb101dcddd Mon Sep 17 00:00:00 2001 From: panda Date: Tue, 16 Feb 2021 13:43:09 -0800 Subject: [PATCH 0244/1616] index: Check git_vector_dup error in write_entries If allocating case_sorted.contents fails, git_vector_sort will segfault. --- src/index.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/index.c b/src/index.c index 7ebe0758239..263f8e58697 100644 --- a/src/index.c +++ b/src/index.c @@ -2868,7 +2868,9 @@ static int write_entries(git_index *index, git_filebuf *file) /* If index->entries is sorted case-insensitively, then we need * to re-sort it case-sensitively before writing */ if (index->ignore_case) { - git_vector_dup(&case_sorted, &index->entries, git_index_entry_cmp); + if ((error = git_vector_dup(&case_sorted, &index->entries, git_index_entry_cmp)) < 0) + return error; + git_vector_sort(&case_sorted); entries = &case_sorted; } else { From 409305081372c7e881dfa8f35a2696366abc712b Mon Sep 17 00:00:00 2001 From: panda Date: Thu, 18 Feb 2021 16:36:42 -0800 Subject: [PATCH 0245/1616] index: Initialize case_sorted to GIT_VECTOR_INIT This is for extra safety within write_entries --- src/index.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/index.c b/src/index.c index 263f8e58697..3d46030f7a3 100644 --- a/src/index.c +++ b/src/index.c @@ -2861,7 +2861,7 @@ static int write_entries(git_index *index, git_filebuf *file) { int error = 0; size_t i; - git_vector case_sorted, *entries; + git_vector case_sorted = GIT_VECTOR_INIT, *entries = NULL; git_index_entry *entry; const char *last = NULL; @@ -2869,7 +2869,7 @@ static int write_entries(git_index *index, git_filebuf *file) * to re-sort it case-sensitively before writing */ if (index->ignore_case) { if ((error = git_vector_dup(&case_sorted, &index->entries, git_index_entry_cmp)) < 0) - return error; + goto done; git_vector_sort(&case_sorted); entries = &case_sorted; @@ -2887,9 +2887,8 @@ static int write_entries(git_index *index, git_filebuf *file) last = entry->path; } - if (index->ignore_case) - git_vector_free(&case_sorted); - +done: + git_vector_free(&case_sorted); return error; } From 3bb5f29733808f18ffd009529a49ec4e4953a31b Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Mon, 22 Feb 2021 14:58:46 +0100 Subject: [PATCH 0246/1616] Fix documentation formating on repository.h The enum 'git_repository_init_flag_t', 'git_repository_init_mode_t' and the structure 'git_repository_init_options' does not follow the format used by docurium. --- include/git2/repository.h | 147 ++++++++++++++++++++++++-------------- 1 file changed, 95 insertions(+), 52 deletions(-) diff --git a/include/git2/repository.h b/include/git2/repository.h index 9ddcd340420..45becc73d97 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -219,36 +219,54 @@ GIT_EXTERN(int) git_repository_init( * * These flags configure extra behaviors to `git_repository_init_ext`. * In every case, the default behavior is the zero value (i.e. flag is - * not set). Just OR the flag values together for the `flags` parameter - * when initializing a new repo. Details of individual values are: - * - * * BARE - Create a bare repository with no working directory. - * * NO_REINIT - Return an GIT_EEXISTS error if the repo_path appears to - * already be an git repository. - * * NO_DOTGIT_DIR - Normally a "/.git/" will be appended to the repo - * path for non-bare repos (if it is not already there), but - * passing this flag prevents that behavior. - * * MKDIR - Make the repo_path (and workdir_path) as needed. Init is - * always willing to create the ".git" directory even without this - * flag. This flag tells init to create the trailing component of - * the repo and workdir paths as needed. - * * MKPATH - Recursively make all components of the repo and workdir - * paths as necessary. - * * EXTERNAL_TEMPLATE - libgit2 normally uses internal templates to - * initialize a new repo. This flags enables external templates, - * looking the "template_path" from the options if set, or the - * `init.templatedir` global config if not, or falling back on - * "/usr/share/git-core/templates" if it exists. - * * GIT_REPOSITORY_INIT_RELATIVE_GITLINK - If an alternate workdir is - * specified, use relative paths for the gitdir and core.worktree. + * not set). Just OR the flag values together for the `flags` parameter + * when initializing a new repo. */ typedef enum { + /** + * Create a bare repository with no working directory. + */ GIT_REPOSITORY_INIT_BARE = (1u << 0), + + /** + * Return an GIT_EEXISTS error if the repo_path appears to already be + * an git repository. + */ GIT_REPOSITORY_INIT_NO_REINIT = (1u << 1), + + /** + * Normally a "/.git/" will be appended to the repo path for + * non-bare repos (if it is not already there), but passing this flag + * prevents that behavior. + */ GIT_REPOSITORY_INIT_NO_DOTGIT_DIR = (1u << 2), + + /** + * Make the repo_path (and workdir_path) as needed. Init is always willing + * to create the ".git" directory even without this flag. This flag tells + * init to create the trailing component of the repo and workdir paths + * as needed. + */ GIT_REPOSITORY_INIT_MKDIR = (1u << 3), + + /** + * Recursively make all components of the repo and workdir paths as + * necessary. + */ GIT_REPOSITORY_INIT_MKPATH = (1u << 4), + + /** + * libgit2 normally uses internal templates to initialize a new repo. + * This flags enables external templates, looking the "template_path" from + * the options if set, or the `init.templatedir` global config if not, + * or falling back on "/usr/share/git-core/templates" if it exists. + */ GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE = (1u << 5), + + /** + * If an alternate workdir is specified, use relative paths for the gitdir + * and core.worktree. + */ GIT_REPOSITORY_INIT_RELATIVE_GITLINK = (1u << 6), } git_repository_init_flag_t; @@ -257,17 +275,23 @@ typedef enum { * * Set the mode field of the `git_repository_init_options` structure * either to the custom mode that you would like, or to one of the - * following modes: - * - * * SHARED_UMASK - Use permissions configured by umask - the default. - * * SHARED_GROUP - Use "--shared=group" behavior, chmod'ing the new repo - * to be group writable and "g+sx" for sticky group assignment. - * * SHARED_ALL - Use "--shared=all" behavior, adding world readability. - * * Anything else - Set to custom value. + * defined modes. */ typedef enum { + /** + * Use permissions configured by umask - the default. + */ GIT_REPOSITORY_INIT_SHARED_UMASK = 0, + + /** + * Use "--shared=group" behavior, chmod'ing the new repo to be group + * writable and "g+sx" for sticky group assignment. + */ GIT_REPOSITORY_INIT_SHARED_GROUP = 0002775, + + /** + * Use "--shared=all" behavior, adding world readability. + */ GIT_REPOSITORY_INIT_SHARED_ALL = 0002777, } git_repository_init_mode_t; @@ -275,38 +299,57 @@ typedef enum { * Extended options structure for `git_repository_init_ext`. * * This contains extra options for `git_repository_init_ext` that enable - * additional initialization features. The fields are: - * - * * flags - Combination of GIT_REPOSITORY_INIT flags above. - * * mode - Set to one of the standard GIT_REPOSITORY_INIT_SHARED_... - * constants above, or to a custom value that you would like. - * * workdir_path - The path to the working dir or NULL for default (i.e. - * repo_path parent on non-bare repos). IF THIS IS RELATIVE PATH, - * IT WILL BE EVALUATED RELATIVE TO THE REPO_PATH. If this is not - * the "natural" working directory, a .git gitlink file will be - * created here linking to the repo_path. - * * description - If set, this will be used to initialize the "description" - * file in the repository, instead of using the template content. - * * template_path - When GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE is set, - * this contains the path to use for the template directory. If - * this is NULL, the config or default directory options will be - * used instead. - * * initial_head - The name of the head to point HEAD at. If NULL, then - * this will be treated as "master" and the HEAD ref will be set - * to "refs/heads/master". If this begins with "refs/" it will be - * used verbatim; otherwise "refs/heads/" will be prefixed. - * * origin_url - If this is non-NULL, then after the rest of the - * repository initialization is completed, an "origin" remote - * will be added pointing to this URL. + * additional initialization features. */ typedef struct { unsigned int version; + + /** + * Combination of GIT_REPOSITORY_INIT flags above. + */ uint32_t flags; + + /** + * Set to one of the standard GIT_REPOSITORY_INIT_SHARED_... constants + * above, or to a custom value that you would like. + */ uint32_t mode; + + /** + * The path to the working dir or NULL for default (i.e. repo_path parent + * on non-bare repos). IF THIS IS RELATIVE PATH, IT WILL BE EVALUATED + * RELATIVE TO THE REPO_PATH. If this is not the "natural" working + * directory, a .git gitlink file will be created here linking to the + * repo_path. + */ const char *workdir_path; + + /** + * If set, this will be used to initialize the "description" file in the + * repository, instead of using the template content. + */ const char *description; + + /** + * When GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE is set, this contains + * the path to use for the template directory. If this is NULL, the config + * or default directory options will be used instead. + */ const char *template_path; + + /** + * The name of the head to point HEAD at. If NULL, then this will be + * treated as "master" and the HEAD ref will be set to "refs/heads/master". + * If this begins with "refs/" it will be used verbatim; + * otherwise "refs/heads/" will be prefixed. + */ const char *initial_head; + + /** + * If this is non-NULL, then after the rest of the repository + * initialization is completed, an "origin" remote will be added + * pointing to this URL. + */ const char *origin_url; } git_repository_init_options; From 25efbc4bd8e021bda4ab5894db436ced60bf34a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Mon, 22 Feb 2021 22:57:16 +0100 Subject: [PATCH 0247/1616] include: fix typos in comments --- include/git2/config.h | 2 +- include/git2/index.h | 2 +- include/git2/refs.h | 6 +++--- include/git2/transport.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/git2/config.h b/include/git2/config.h index abf5bbbd02e..7c8e388b237 100644 --- a/include/git2/config.h +++ b/include/git2/config.h @@ -263,7 +263,7 @@ GIT_EXTERN(int) git_config_open_level( * * Git allows you to store your global configuration at * `$HOME/.gitconfig` or `$XDG_CONFIG_HOME/git/config`. For backwards - * compatability, the XDG file shouldn't be used unless the use has + * compatibility, the XDG file shouldn't be used unless the use has * created it explicitly. With this function you'll open the correct * one to write to. * diff --git a/include/git2/index.h b/include/git2/index.h index 314135109ff..14a13249757 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -349,7 +349,7 @@ GIT_EXTERN(int) git_index_write_tree(git_oid *out, git_index *index); * * The index must not contain any file in conflict. * - * @param out Pointer where to store OID of the the written tree + * @param out Pointer where to store OID of the written tree * @param index Index to write * @param repo Repository where to write the tree * @return 0 on success, GIT_EUNMERGED when the index is not clean diff --git a/include/git2/refs.h b/include/git2/refs.h index a20a1265bf6..8bc99e15e7d 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -169,7 +169,7 @@ GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repositor * * The message for the reflog will be ignored if the reference does * not belong in the standard set (HEAD, branches and remote-tracking - * branches) and and it does not have a reflog. + * branches) and it does not have a reflog. * * @param out Pointer to the newly created reference * @param repo Repository where that reference will live @@ -206,7 +206,7 @@ GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, * * The message for the reflog will be ignored if the reference does * not belong in the standard set (HEAD, branches and remote-tracking - * branches) and and it does not have a reflog. + * branches) and it does not have a reflog. * * It will return GIT_EMODIFIED if the reference's value at the time * of updating does not match the one passed through `current_id` @@ -318,7 +318,7 @@ GIT_EXTERN(git_repository *) git_reference_owner(const git_reference *ref); * * The message for the reflog will be ignored if the reference does * not belong in the standard set (HEAD, branches and remote-tracking - * branches) and and it does not have a reflog. + * branches) and it does not have a reflog. * * @param out Pointer to the newly created reference * @param ref The reference diff --git a/include/git2/transport.h b/include/git2/transport.h index fc99ce8f309..5a27de9a860 100644 --- a/include/git2/transport.h +++ b/include/git2/transport.h @@ -23,7 +23,7 @@ GIT_BEGIN_DECL /** - * Callback for messages recieved by the transport. + * Callback for messages received by the transport. * * Return a negative value to cancel the network operation. * From 592a325229331f2e7f66cfca6b8ae2f653c57f35 Mon Sep 17 00:00:00 2001 From: Ian Hattendorf Date: Mon, 1 Mar 2021 11:00:37 -0700 Subject: [PATCH 0248/1616] winhttp: test proxy https clone --- tests/online/clone.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/online/clone.c b/tests/online/clone.c index c62baac2d75..6de687b3503 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -869,6 +869,28 @@ void test_online_clone__proxy_credentials_in_environment(void) git_buf_dispose(&url); } +void test_online_clone__proxy_credentials_in_url_https(void) +{ + git_buf url = GIT_BUF_INIT; + + if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) + cl_skip(); + + cl_git_pass(git_buf_printf(&url, "%s://%s:%s@%s/", + _remote_proxy_scheme ? _remote_proxy_scheme : "http", + _remote_proxy_user, _remote_proxy_pass, _remote_proxy_host)); + + g_options.fetch_opts.proxy_opts.type = GIT_PROXY_SPECIFIED; + g_options.fetch_opts.proxy_opts.url = url.ptr; + g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb; + g_options.fetch_opts.callbacks.certificate_check = ssl_cert; + called_proxy_creds = 0; + cl_git_pass(git_clone(&g_repo, "https://github.com/libgit2/TestGitRepository", "./foo", &g_options)); + cl_assert(called_proxy_creds == 0); + + git_buf_dispose(&url); +} + void test_online_clone__proxy_auto_not_detected(void) { g_options.fetch_opts.proxy_opts.type = GIT_PROXY_AUTO; From edffea1548d87cdb1c684792195166e7a1b36a4a Mon Sep 17 00:00:00 2001 From: Ian Hattendorf Date: Mon, 1 Mar 2021 16:26:58 -0700 Subject: [PATCH 0249/1616] winhttp: skip certificate check if unable to send request In some circumstances (e.g. when proxies are involved), winhttp will fail to reach the WINHTTP_CALLBACK_STATUS_SENDING_REQUEST phase. If this occurs, we'll error with ERROR_WINHTTP_INCORRECT_HANDLE_STATE when attempting to query the server certificate context (see https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsendrequest#remarks). To avoid this, verify that WinHttpSendRequest has reached the WINHTTP_CALLBACK_STATUS_SENDING_REQUEST phase before checking the certificate. Since we're using WinHTTP in synchronous mode, we know for sure that once WinHttpSendRequest returns we've either sent it successfully or not. NOTE: WINHTTP_CALLBACK_STATUS_SENDING_REQUEST appears to be deprecated with no direct replacement. WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE is only available in async mode, and there doesn't appear to be a method of querying this flag outside of the status callback. --- src/transports/winhttp.c | 72 +++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index a2a71be95b5..3da625acad8 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -111,7 +111,8 @@ typedef struct { DWORD post_body_len; unsigned sent_request : 1, received_response : 1, - chunked : 1; + chunked : 1, + status_sending_request_reached: 1; } winhttp_stream; typedef struct { @@ -713,30 +714,36 @@ static void CALLBACK winhttp_status( DWORD status; GIT_UNUSED(connection); - GIT_UNUSED(ctx); GIT_UNUSED(info_len); - if (code != WINHTTP_CALLBACK_STATUS_SECURE_FAILURE) - return; - - status = *((DWORD *)info); - - if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)) - git_error_set(GIT_ERROR_HTTP, "SSL certificate issued for different common name"); - else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)) - git_error_set(GIT_ERROR_HTTP, "SSL certificate has expired"); - else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)) - git_error_set(GIT_ERROR_HTTP, "SSL certificate signed by unknown CA"); - else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT)) - git_error_set(GIT_ERROR_HTTP, "SSL certificate is invalid"); - else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED)) - git_error_set(GIT_ERROR_HTTP, "certificate revocation check failed"); - else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED)) - git_error_set(GIT_ERROR_HTTP, "SSL certificate was revoked"); - else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR)) - git_error_set(GIT_ERROR_HTTP, "security libraries could not be loaded"); - else - git_error_set(GIT_ERROR_HTTP, "unknown security error %lu", status); + switch (code) { + case WINHTTP_CALLBACK_STATUS_SECURE_FAILURE: + status = *((DWORD *)info); + + if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)) + git_error_set(GIT_ERROR_HTTP, "SSL certificate issued for different common name"); + else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)) + git_error_set(GIT_ERROR_HTTP, "SSL certificate has expired"); + else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)) + git_error_set(GIT_ERROR_HTTP, "SSL certificate signed by unknown CA"); + else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT)) + git_error_set(GIT_ERROR_HTTP, "SSL certificate is invalid"); + else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED)) + git_error_set(GIT_ERROR_HTTP, "certificate revocation check failed"); + else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED)) + git_error_set(GIT_ERROR_HTTP, "SSL certificate was revoked"); + else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR)) + git_error_set(GIT_ERROR_HTTP, "security libraries could not be loaded"); + else + git_error_set(GIT_ERROR_HTTP, "unknown security error %lu", status); + + break; + + case WINHTTP_CALLBACK_STATUS_SENDING_REQUEST: + ((winhttp_stream *) ctx)->status_sending_request_reached = 1; + + break; + } } static int winhttp_connect( @@ -836,7 +843,12 @@ static int winhttp_connect( goto on_error; } - if (WinHttpSetStatusCallback(t->connection, winhttp_status, WINHTTP_CALLBACK_FLAG_SECURE_FAILURE, 0) == WINHTTP_INVALID_STATUS_CALLBACK) { + if (WinHttpSetStatusCallback( + t->connection, + winhttp_status, + WINHTTP_CALLBACK_FLAG_SECURE_FAILURE | WINHTTP_CALLBACK_FLAG_SEND_REQUEST, + 0 + ) == WINHTTP_INVALID_STATUS_CALLBACK) { git_error_set(GIT_ERROR_OS, "failed to set status callback"); goto on_error; } @@ -869,12 +881,12 @@ static int do_send_request(winhttp_stream *s, size_t len, bool chunked) success = WinHttpSendRequest(s->request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, - WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0); + WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, (DWORD_PTR)s); } else { success = WinHttpSendRequest(s->request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, - (DWORD)len, 0); + (DWORD)len, (DWORD_PTR)s); } if (success || GetLastError() != (DWORD)SEC_E_BUFFER_TOO_SMALL) @@ -911,7 +923,13 @@ static int send_request(winhttp_stream *s, size_t len, bool chunked) } } - if (!request_failed || !cert_valid) { + /* + * Only check the certificate if we were able to reach the sending request phase, or + * received a secure failure error. Otherwise, the server certificate won't be available + * since the request wasn't able to complete (e.g. proxy auth required) + */ + if (!cert_valid || + (!request_failed && s->status_sending_request_reached)) { git_error_clear(); if ((error = certificate_check(s, cert_valid)) < 0) { if (!git_error_last()) From b9bfe81292bfa77513193fd4ac75e9a1ab0ddc3b Mon Sep 17 00:00:00 2001 From: panda Date: Wed, 3 Mar 2021 14:03:06 -0800 Subject: [PATCH 0250/1616] Check git_signature_dup failure git_signature_dup can have an allocation failure --- src/blame.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/blame.c b/src/blame.c index 651b7a0035d..10e311aee55 100644 --- a/src/blame.c +++ b/src/blame.c @@ -76,6 +76,14 @@ static git_blame_hunk* new_hunk( return hunk; } +static void free_hunk(git_blame_hunk *hunk) +{ + git__free((void*)hunk->orig_path); + git_signature_free(hunk->final_signature); + git_signature_free(hunk->orig_signature); + git__free(hunk); +} + static git_blame_hunk* dup_hunk(git_blame_hunk *hunk) { git_blame_hunk *newhunk = new_hunk( @@ -90,17 +98,14 @@ static git_blame_hunk* dup_hunk(git_blame_hunk *hunk) git_oid_cpy(&newhunk->orig_commit_id, &hunk->orig_commit_id); git_oid_cpy(&newhunk->final_commit_id, &hunk->final_commit_id); newhunk->boundary = hunk->boundary; - git_signature_dup(&newhunk->final_signature, hunk->final_signature); - git_signature_dup(&newhunk->orig_signature, hunk->orig_signature); - return newhunk; -} -static void free_hunk(git_blame_hunk *hunk) -{ - git__free((void*)hunk->orig_path); - git_signature_free(hunk->final_signature); - git_signature_free(hunk->orig_signature); - git__free(hunk); + if (git_signature_dup(&newhunk->final_signature, hunk->final_signature) < 0 || + git_signature_dup(&newhunk->orig_signature, hunk->orig_signature) < 0) { + free_hunk(newhunk); + return NULL; + } + + return newhunk; } /* Starting with the hunk that includes start_line, shift all following hunks' From dc1095a5b7a1c17a11d9bc70a93c2191d78f4c18 Mon Sep 17 00:00:00 2001 From: panda Date: Wed, 3 Mar 2021 14:42:12 -0800 Subject: [PATCH 0251/1616] merge: Check insert_head_ids error in create_virtual_base insert_head_ids can fail due to allocation error --- src/merge.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/merge.c b/src/merge.c index e02ea9169d3..82b028b4a67 100644 --- a/src/merge.c +++ b/src/merge.c @@ -2277,8 +2277,11 @@ static int create_virtual_base( result->type = GIT_ANNOTATED_COMMIT_VIRTUAL; result->index = index; - insert_head_ids(&result->parents, one); - insert_head_ids(&result->parents, two); + if (insert_head_ids(&result->parents, one) < 0 || + insert_head_ids(&result->parents, two) < 0) { + git_annotated_commit_free(result); + return -1; + } *out = result; return 0; From 7eb21516ad9a1bd8e7e7b16198e0a4eda299e87d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 28 Feb 2021 00:20:28 +0000 Subject: [PATCH 0252/1616] tree: deprecate `git_treebuilder_write_with_buffer` The function `git_treebuilder_write_with_buffer` is unnecessary; it is used internally as part of treebuilder writing, but it has little use to external callers. For callers that repeatedly write a treebuilder, we can supply them with a buffer in the treebuilder struct instead of recreating it. For ourselves, when we want a single buffer in our write loop, we can use an internal function. --- include/git2/deprecated.h | 27 +++++++++ include/git2/tree.h | 14 ----- src/tree.c | 123 +++++++++++++++++++++----------------- src/tree.h | 1 + 4 files changed, 95 insertions(+), 70 deletions(-) diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index d18fffc0e3f..37857f8a21f 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -119,6 +119,33 @@ GIT_EXTERN(int) git_blob_filtered_content( /**@}*/ +/** @name Deprecated Tree Functions + * + * These functions are retained for backward compatibility. The + * newer versions of these functions and values should be preferred + * in all new code. + * + * There is no plan to remove these backward compatibility values at + * this time. + */ +/**@{*/ + +/** + * Write the contents of the tree builder as a tree object. + * This is an alias of `git_treebuilder_write` and is preserved + * for backward compatibility. + * + * This function is deprecated, but there is no plan to remove this + * function at this time. + * + * @deprecated Use git_treebuilder_write + * @see git_treebuilder_write + */ +GIT_EXTERN(int) git_treebuilder_write_with_buffer( + git_oid *oid, git_treebuilder *bld, git_buf *tree); + +/**@}*/ + /** @name Deprecated Buffer Functions * * These functions and enumeration values are retained for backward diff --git a/include/git2/tree.h b/include/git2/tree.h index 1a8e155fc7d..d7545ace929 100644 --- a/include/git2/tree.h +++ b/include/git2/tree.h @@ -378,20 +378,6 @@ GIT_EXTERN(int) git_treebuilder_filter( GIT_EXTERN(int) git_treebuilder_write( git_oid *id, git_treebuilder *bld); -/** - * Write the contents of the tree builder as a tree object - * using a shared git_buf. - * - * @see git_treebuilder_write - * - * @param oid Pointer to store the OID of the newly written tree - * @param bld Tree builder to write - * @param tree Shared buffer for writing the tree. Will be grown as necessary. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_treebuilder_write_with_buffer( - git_oid *oid, git_treebuilder *bld, git_buf *tree); - /** Callback for the tree traversal method */ typedef int GIT_CALLBACK(git_treewalk_cb)( const char *root, const git_tree_entry *entry, void *payload); diff --git a/src/tree.c b/src/tree.c index ba6383ef8da..5abcc9d3b8a 100644 --- a/src/tree.c +++ b/src/tree.c @@ -492,6 +492,56 @@ static int check_entry(git_repository *repo, const char *filename, const git_oid return 0; } +static int git_treebuilder__write_with_buffer( + git_oid *oid, + git_treebuilder *bld, + git_buf *buf) +{ + int error = 0; + size_t i, entrycount; + git_odb *odb; + git_tree_entry *entry; + git_vector entries = GIT_VECTOR_INIT; + + git_buf_clear(buf); + + entrycount = git_strmap_size(bld->map); + if ((error = git_vector_init(&entries, entrycount, entry_sort_cmp)) < 0) + goto out; + + if (buf->asize == 0 && + (error = git_buf_grow(buf, entrycount * 72)) < 0) + goto out; + + git_strmap_foreach_value(bld->map, entry, { + if ((error = git_vector_insert(&entries, entry)) < 0) + goto out; + }); + + git_vector_sort(&entries); + + for (i = 0; i < entries.length && !error; ++i) { + entry = git_vector_get(&entries, i); + + git_buf_printf(buf, "%o ", entry->attr); + git_buf_put(buf, entry->filename, entry->filename_len + 1); + git_buf_put(buf, (char *)entry->oid->id, GIT_OID_RAWSZ); + + if (git_buf_oom(buf)) { + error = -1; + goto out; + } + } + + if ((error = git_repository_odb__weakptr(&odb, bld->repo)) == 0) + error = git_odb_write(oid, odb, buf->ptr, buf->size, GIT_OBJECT_TREE); + +out: + git_vector_free(&entries); + + return error; +} + static int append_entry( git_treebuilder *bld, const char *filename, @@ -610,7 +660,7 @@ static int write_tree( } } - if (git_treebuilder_write_with_buffer(oid, bld, shared_buf) < 0) + if (git_treebuilder__write_with_buffer(oid, bld, shared_buf) < 0) goto on_error; git_treebuilder_free(bld); @@ -785,63 +835,10 @@ int git_treebuilder_remove(git_treebuilder *bld, const char *filename) int git_treebuilder_write(git_oid *oid, git_treebuilder *bld) { - int error; - git_buf buffer = GIT_BUF_INIT; - - error = git_treebuilder_write_with_buffer(oid, bld, &buffer); - - git_buf_dispose(&buffer); - return error; -} - -int git_treebuilder_write_with_buffer(git_oid *oid, git_treebuilder *bld, git_buf *tree) -{ - int error = 0; - size_t i, entrycount; - git_odb *odb; - git_tree_entry *entry; - git_vector entries = GIT_VECTOR_INIT; - + GIT_ASSERT_ARG(oid); GIT_ASSERT_ARG(bld); - GIT_ASSERT_ARG(tree); - - git_buf_clear(tree); - - entrycount = git_strmap_size(bld->map); - if ((error = git_vector_init(&entries, entrycount, entry_sort_cmp)) < 0) - goto out; - - if (tree->asize == 0 && - (error = git_buf_grow(tree, entrycount * 72)) < 0) - goto out; - - git_strmap_foreach_value(bld->map, entry, { - if ((error = git_vector_insert(&entries, entry)) < 0) - goto out; - }); - - git_vector_sort(&entries); - for (i = 0; i < entries.length && !error; ++i) { - entry = git_vector_get(&entries, i); - - git_buf_printf(tree, "%o ", entry->attr); - git_buf_put(tree, entry->filename, entry->filename_len + 1); - git_buf_put(tree, (char *)entry->oid->id, GIT_OID_RAWSZ); - - if (git_buf_oom(tree)) { - error = -1; - goto out; - } - } - - if ((error = git_repository_odb__weakptr(&odb, bld->repo)) == 0) - error = git_odb_write(oid, odb, tree->ptr, tree->size, GIT_OBJECT_TREE); - -out: - git_vector_free(&entries); - - return error; + return git_treebuilder__write_with_buffer(oid, bld, &bld->write_cache); } int git_treebuilder_filter( @@ -882,6 +879,7 @@ void git_treebuilder_free(git_treebuilder *bld) if (bld == NULL) return; + git_buf_dispose(&bld->write_cache); git_treebuilder_clear(bld); git_strmap_free(bld->map); git__free(bld); @@ -1306,3 +1304,16 @@ int git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseli git_vector_free(&entries); return error; } + +/* Deprecated Functions */ + +#ifndef GIT_DEPRECATE_HARD + +int git_treebuilder_write_with_buffer(git_oid *oid, git_treebuilder *bld, git_buf *buf) +{ + GIT_UNUSED(buf); + + return git_treebuilder_write(oid, bld); +} + +#endif diff --git a/src/tree.h b/src/tree.h index 973ba15d0a3..2f3027b5a27 100644 --- a/src/tree.h +++ b/src/tree.h @@ -32,6 +32,7 @@ struct git_tree { struct git_treebuilder { git_repository *repo; git_strmap *map; + git_buf write_cache; }; GIT_INLINE(bool) git_tree_entry__is_tree(const struct git_tree_entry *e) From 85af7f21692d92d7bdf18522ad19e2d411d11c5c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 4 Mar 2021 09:15:37 +0000 Subject: [PATCH 0253/1616] ci: enable UBSan stacktraces --- .github/workflows/main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7179a613d36..38c79faf885 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -123,6 +123,7 @@ jobs: SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 + UBSAN_OPTIONS: print_stacktrace=1 os: ubuntu-latest - # Focal, Clang 10, OpenSSL, UndefinedBehaviorSanitizer container: @@ -135,6 +136,7 @@ jobs: SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 + UBSAN_OPTIONS: print_stacktrace=1 os: ubuntu-latest - # Focal, Clang 10, OpenSSL, ThreadSanitizer container: @@ -147,6 +149,7 @@ jobs: SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 + UBSAN_OPTIONS: print_stacktrace=1 TSAN_OPTIONS: suppressions=/home/libgit2/source/script/thread-sanitizer.supp second_deadlock_stack=1 os: ubuntu-latest - # macOS @@ -242,6 +245,7 @@ jobs: -e SKIP_NEGOTIATE_TESTS \ -e SKIP_SSH_TESTS \ -e TSAN_OPTIONS \ + -e UBSAN_OPTIONS \ ${{ env.docker-registry-container-sha }} \ /bin/bash -c "mkdir build && cd build && ../ci/build.sh && ../ci/test.sh" else From 752dbecf9b0969145ed13dee11cf64fd515ef3c8 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 4 Mar 2021 09:45:12 +0000 Subject: [PATCH 0254/1616] README: it's actually our main branch [skip ci] --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1f72f277fe5..55358a981cd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ libgit2 - the Git linkable library | Build Status | | | ------------ | - | -| **master** branch CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush) | +| **main** branch CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush) | | **v1.1 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.1&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.1) | | **v1.0 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v1.0)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v1.0) | | **Nightly** builds | [![Nightly Build](https://github.com/libgit2/libgit2/workflows/Nightly%20Build/badge.svg)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22Nightly+Build%22) [![Coverity Scan Status](https://scan.coverity.com/projects/639/badge.svg)](https://scan.coverity.com/projects/639) | @@ -242,7 +242,7 @@ run the index tests: $ ./libgit2_clar -sindex To run a single test named `index::racy::diff`, which corresponds to the test -function [`test_index_racy__diff`](https://github.com/libgit2/libgit2/blob/master/tests/index/racy.c#L23): +function [`test_index_racy__diff`](https://github.com/libgit2/libgit2/blob/main/tests/index/racy.c#L23): $ ./libgit2_clar -sindex::racy::diff @@ -252,7 +252,7 @@ applicable to your platform or is particularly expensive. **Note:** There should be _no_ failing tests when you build an unmodified source tree from a [release](https://github.com/libgit2/libgit2/releases), -or from the [master branch](https://github.com/libgit2/libgit2/tree/master). +or from the [main branch](https://github.com/libgit2/libgit2/tree/main). Please contact us or [open an issue](https://github.com/libgit2/libgit2/issues) if you see test failures. From 248606ebb0906076367fcfce9574f522f818c26f Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 5 Jan 2021 17:20:27 -0800 Subject: [PATCH 0255/1616] commit-graph: Use the commit-graph in revwalks This change makes revwalks a bit faster by using the `commit-graph` file (if present). This is thanks to the `commit-graph` allow much faster parsing of the commit information by requiring near-zero I/O (aside from reading a few dozen bytes off of a `mmap(2)`-ed file) for each commit, instead of having to read the ODB, inflate the commit, and parse it. This is done by modifying `git_commit_list_parse()` and letting it use the ODB-owned commit-graph file. Part of: #5757 --- src/commit_list.c | 28 ++++++++++++++++++ src/commit_list.h | 1 + src/odb.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ src/odb.h | 15 ++++++++-- 4 files changed, 116 insertions(+), 2 deletions(-) diff --git a/src/commit_list.c b/src/commit_list.c index 2e103ec2281..dfdd5daabbe 100644 --- a/src/commit_list.c +++ b/src/commit_list.c @@ -124,6 +124,7 @@ static int commit_quick_parse( return -1; } + node->generation = 0; node->time = commit->committer->when.time; node->out_degree = (uint16_t) git_array_size(commit->parent_ids); node->parents = alloc_parents(walk, node, node->out_degree); @@ -143,11 +144,38 @@ static int commit_quick_parse( int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit) { git_odb_object *obj; + git_commit_graph_file *cgraph = NULL; int error; if (commit->parsed) return 0; + /* Let's try to use the commit graph first. */ + git_odb__get_commit_graph(&cgraph, walk->odb); + if (cgraph) { + git_commit_graph_entry e; + + error = git_commit_graph_entry_find(&e, cgraph, &commit->oid, GIT_OID_RAWSZ); + if (error == 0 && git__is_uint16(e.parent_count)) { + size_t i; + commit->generation = (uint32_t)e.generation; + commit->time = e.commit_time; + commit->out_degree = (uint16_t)e.parent_count; + commit->parents = alloc_parents(walk, commit, commit->out_degree); + GIT_ERROR_CHECK_ALLOC(commit->parents); + + for (i = 0; i < commit->out_degree; ++i) { + git_commit_graph_entry parent; + error = git_commit_graph_entry_parent(&parent, cgraph, &e, i); + if (error < 0) + return error; + commit->parents[i] = git_revwalk__commit_lookup(walk, &parent.sha1); + } + commit->parsed = 1; + return 0; + } + } + if ((error = git_odb_read(&obj, walk->odb, &commit->oid)) < 0) return error; diff --git a/src/commit_list.h b/src/commit_list.h index 6a65f8a7668..a3237703014 100644 --- a/src/commit_list.h +++ b/src/commit_list.h @@ -26,6 +26,7 @@ typedef struct git_commit_list_node { git_oid oid; int64_t time; + uint32_t generation; unsigned int seen:1, uninteresting:1, topo_delay:1, diff --git a/src/odb.c b/src/odb.c index b2988c42903..02f97915d6a 100644 --- a/src/odb.c +++ b/src/odb.c @@ -465,6 +465,13 @@ int git_odb_new(git_odb **out) git__free(db); return -1; } + if (git_buf_init(&db->objects_dir, 0) < 0) { + git_vector_free(&db->backends); + git_cache_dispose(&db->own_cache); + git_mutex_free(&db->lock); + git__free(db); + return -1; + } *out = db; GIT_REFCOUNT_INC(db); @@ -612,6 +619,17 @@ int git_odb__add_default_backends( git_mutex_unlock(&db->lock); #endif + if (git_mutex_lock(&db->lock) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return -1; + } + if (git_buf_len(&db->objects_dir) == 0 && git_buf_sets(&db->objects_dir, objects_dir) < 0) { + git_mutex_unlock(&db->lock); + git_odb_free(db); + return -1; + } + git_mutex_unlock(&db->lock); + /* add the loose object backend */ if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 || add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates, inode) < 0) @@ -742,6 +760,8 @@ static void odb_free(git_odb *db) if (locked) git_mutex_unlock(&db->lock); + git_buf_dispose(&db->objects_dir); + git_commit_graph_free(db->cgraph); git_vector_free(&db->backends); git_cache_dispose(&db->own_cache); git_mutex_free(&db->lock); @@ -786,6 +806,53 @@ static int odb_exists_1( return (int)found; } +int git_odb__get_commit_graph(git_commit_graph_file **out, git_odb *db) +{ + int error = 0; + + if ((error = git_mutex_lock(&db->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the db lock"); + return error; + } + if (!db->cgraph_checked) { + git_buf commit_graph_path = GIT_BUF_INIT; + git_commit_graph_file *cgraph = NULL; + + /* We only check once, no matter the result. */ + db->cgraph_checked = 1; + + if (git_buf_len(&db->objects_dir) == 0) { + /* + * This odb was not opened with an objects directory + * associated. Skip opening the commit graph. + */ + goto done; + } + + if ((error = git_buf_joinpath( + &commit_graph_path, + git_buf_cstr(&db->objects_dir), + "info/commit-graph")) + < 0) { + git_buf_dispose(&commit_graph_path); + goto done; + } + /* Best effort */ + error = git_commit_graph_open(&cgraph, git_buf_cstr(&commit_graph_path)); + git_buf_dispose(&commit_graph_path); + + if (error < 0) + goto done; + + db->cgraph = cgraph; + } + +done: + *out = db->cgraph; + git_mutex_unlock(&db->lock); + return 0; +} + static int odb_freshen_1( git_odb *db, const git_oid *id, @@ -1695,6 +1762,13 @@ int git_odb_refresh(struct git_odb *db) } } } + if (db->cgraph && git_commit_graph_needs_refresh(db->cgraph, NULL)) { + /* We just free the commit graph. The next time it is requested, it will be re-loaded. */ + git_commit_graph_free(db->cgraph); + db->cgraph = NULL; + } + /* Force a lazy re-check next time it is needed. */ + db->cgraph_checked = 0; git_mutex_unlock(&db->lock); return 0; diff --git a/src/odb.h b/src/odb.h index d71985668ff..dcf29c2e284 100644 --- a/src/odb.h +++ b/src/odb.h @@ -13,10 +13,11 @@ #include "git2/oid.h" #include "git2/types.h" -#include "vector.h" #include "cache.h" -#include "posix.h" +#include "commit_graph.h" #include "filter.h" +#include "posix.h" +#include "vector.h" #define GIT_OBJECTS_DIR "objects/" #define GIT_OBJECT_DIR_MODE 0777 @@ -43,7 +44,10 @@ struct git_odb { git_mutex lock; /* protects backends */ git_vector backends; git_cache own_cache; + git_buf objects_dir; + git_commit_graph_file *cgraph; unsigned int do_fsync :1; + unsigned int cgraph_checked :1; }; typedef enum { @@ -127,6 +131,13 @@ int git_odb__read_header_or_object( git_odb_object **out, size_t *len_p, git_object_t *type_p, git_odb *db, const git_oid *id); +/* + * Attempt to get the ODB's commit graph. This object is still owned by the + * ODB. If the repository does not contain a commit graph, it will return zero + * and `*out` will be set to NULL. + */ +int git_odb__get_commit_graph(git_commit_graph_file **out, git_odb *odb); + /* freshen an entry in the object database */ int git_odb__freshen(git_odb *db, const git_oid *id); From 25b75cd9bc01896a2b74c748ceef7110ea1b165f Mon Sep 17 00:00:00 2001 From: lhchavez Date: Wed, 10 Mar 2021 07:06:15 -0800 Subject: [PATCH 0256/1616] commit-graph: Create `git_commit_graph` as an abstraction for the file This change does a medium-size refactor of the git_commit_graph_file and the interaction with the ODB. Now instead of the ODB owning a direct reference to the git_commit_graph_file, there will be an intermediate git_commit_graph. The main advantage of that is that now end users can explicitly set a git_commit_graph that is eagerly checked for errors, while still being able to lazily use the commit-graph in a regular ODB, if the file is present. --- fuzzers/commit_graph_fuzzer.c | 10 +- include/git2/odb.h | 15 +++ include/git2/sys/commit_graph.h | 45 +++++++ include/git2/types.h | 3 + src/commit_graph.c | 231 +++++++++++++++++++++----------- src/commit_graph.h | 57 ++++++-- src/commit_list.c | 10 +- src/odb.c | 99 ++++++-------- src/odb.h | 13 +- tests/graph/commit_graph.c | 30 ++--- 10 files changed, 332 insertions(+), 181 deletions(-) create mode 100644 include/git2/sys/commit_graph.h diff --git a/fuzzers/commit_graph_fuzzer.c b/fuzzers/commit_graph_fuzzer.c index eb2c3825852..b41816ed951 100644 --- a/fuzzers/commit_graph_fuzzer.c +++ b/fuzzers/commit_graph_fuzzer.c @@ -31,7 +31,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - git_commit_graph_file cgraph = {{0}}; + git_commit_graph_file file = {{0}}; git_commit_graph_entry e; git_buf commit_graph_buf = GIT_BUF_INIT; git_oid oid = {{0}}; @@ -62,19 +62,19 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) git_buf_attach_notowned(&commit_graph_buf, (char *)data, size); } - if (git_commit_graph_parse( - &cgraph, + if (git_commit_graph_file_parse( + &file, (const unsigned char *)git_buf_cstr(&commit_graph_buf), git_buf_len(&commit_graph_buf)) < 0) goto cleanup; /* Search for any oid, just to exercise that codepath. */ - if (git_commit_graph_entry_find(&e, &cgraph, &oid, GIT_OID_HEXSZ) < 0) + if (git_commit_graph_entry_find(&e, &file, &oid, GIT_OID_HEXSZ) < 0) goto cleanup; cleanup: - git_commit_graph_close(&cgraph); + git_commit_graph_file_close(&file); git_buf_dispose(&commit_graph_buf); return 0; } diff --git a/include/git2/odb.h b/include/git2/odb.h index c4bfa5290b0..dd481e95053 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -544,6 +544,21 @@ GIT_EXTERN(size_t) git_odb_num_backends(git_odb *odb); */ GIT_EXTERN(int) git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos); +/** + * Set the git commit-graph for the ODB. + * + * After a successfull call, the ownership of the cgraph parameter will be + * transferred to libgit2, and the caller should not free it. + * + * The commit-graph can also be unset by explicitly passing NULL as the cgraph + * parameter. + * + * @param odb object database + * @param cgraph the git commit-graph + * @return 0 on success; error code otherwise + */ +GIT_EXTERN(int) git_odb_set_commit_graph(git_odb *odb, git_commit_graph *cgraph); + /** @} */ GIT_END_DECL #endif diff --git a/include/git2/sys/commit_graph.h b/include/git2/sys/commit_graph.h new file mode 100644 index 00000000000..038c9b73920 --- /dev/null +++ b/include/git2/sys/commit_graph.h @@ -0,0 +1,45 @@ +/* + * 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_sys_git_commit_graph_h__ +#define INCLUDE_sys_git_commit_graph_h__ + +#include "git2/common.h" +#include "git2/types.h" + +/** + * @file git2/sys/commit_graph.h + * @brief Git commit-graph + * @defgroup git_commit_graph Git commit-graph APIs + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Opens a `git_commit_graph` from a path to an objects directory. + * + * This finds, opens, and validates the `commit-graph` file. + * + * @param cgraph_out the `git_commit_graph` struct to initialize. + * @param objects_dir the path to a git objects directory. + * @return Zero on success; -1 on failure. + */ +GIT_EXTERN(int) git_commit_graph_open(git_commit_graph **cgraph_out, const char *objects_dir); + +/** + * Frees commit-graph data. This should only be called when memory allocated + * using `git_commit_graph_open` is not returned to libgit2 because it was not + * associated with the ODB through a successful call to + * `git_odb_set_commit_graph`. + * + * @param cgraph the commit-graph object to free. If NULL, no action is taken. + */ +GIT_EXTERN(void) git_commit_graph_free(git_commit_graph *cgraph); + +GIT_END_DECL + +#endif diff --git a/include/git2/types.h b/include/git2/types.h index ade0c7d3274..562eb8e5f25 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -102,6 +102,9 @@ typedef struct git_refdb git_refdb; /** A custom backend for refs */ typedef struct git_refdb_backend git_refdb_backend; +/** A git commit-graph */ +typedef struct git_commit_graph git_commit_graph; + /** * Representation of an existing git repository, * including all its object contents diff --git a/src/commit_graph.c b/src/commit_graph.c index b301d3d4910..6715d05dc62 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -43,7 +43,7 @@ static int commit_graph_error(const char *message) } static int commit_graph_parse_oid_fanout( - git_commit_graph_file *cgraph, + git_commit_graph_file *file, const unsigned char *data, struct git_commit_graph_chunk *chunk_oid_fanout) { @@ -55,20 +55,20 @@ static int commit_graph_parse_oid_fanout( if (chunk_oid_fanout->length != 256 * 4) return commit_graph_error("OID Fanout chunk has wrong length"); - cgraph->oid_fanout = (const uint32_t *)(data + chunk_oid_fanout->offset); + file->oid_fanout = (const uint32_t *)(data + chunk_oid_fanout->offset); nr = 0; for (i = 0; i < 256; ++i) { - uint32_t n = ntohl(cgraph->oid_fanout[i]); + uint32_t n = ntohl(file->oid_fanout[i]); if (n < nr) return commit_graph_error("index is non-monotonic"); nr = n; } - cgraph->num_commits = nr; + file->num_commits = nr; return 0; } static int commit_graph_parse_oid_lookup( - git_commit_graph_file *cgraph, + git_commit_graph_file *file, const unsigned char *data, struct git_commit_graph_chunk *chunk_oid_lookup) { @@ -79,12 +79,12 @@ static int commit_graph_parse_oid_lookup( return commit_graph_error("missing OID Lookup chunk"); if (chunk_oid_lookup->length == 0) return commit_graph_error("empty OID Lookup chunk"); - if (chunk_oid_lookup->length != cgraph->num_commits * GIT_OID_RAWSZ) + if (chunk_oid_lookup->length != file->num_commits * GIT_OID_RAWSZ) return commit_graph_error("OID Lookup chunk has wrong length"); - cgraph->oid_lookup = oid = (git_oid *)(data + chunk_oid_lookup->offset); + file->oid_lookup = oid = (git_oid *)(data + chunk_oid_lookup->offset); prev_oid = &zero_oid; - for (i = 0; i < cgraph->num_commits; ++i, ++oid) { + for (i = 0; i < file->num_commits; ++i, ++oid) { if (git_oid_cmp(prev_oid, oid) >= 0) return commit_graph_error("OID Lookup index is non-monotonic"); prev_oid = oid; @@ -94,7 +94,7 @@ static int commit_graph_parse_oid_lookup( } static int commit_graph_parse_commit_data( - git_commit_graph_file *cgraph, + git_commit_graph_file *file, const unsigned char *data, struct git_commit_graph_chunk *chunk_commit_data) { @@ -102,16 +102,16 @@ static int commit_graph_parse_commit_data( return commit_graph_error("missing Commit Data chunk"); if (chunk_commit_data->length == 0) return commit_graph_error("empty Commit Data chunk"); - if (chunk_commit_data->length != cgraph->num_commits * (GIT_OID_RAWSZ + 16)) + if (chunk_commit_data->length != file->num_commits * (GIT_OID_RAWSZ + 16)) return commit_graph_error("Commit Data chunk has wrong length"); - cgraph->commit_data = data + chunk_commit_data->offset; + file->commit_data = data + chunk_commit_data->offset; return 0; } static int commit_graph_parse_extra_edge_list( - git_commit_graph_file *cgraph, + git_commit_graph_file *file, const unsigned char *data, struct git_commit_graph_chunk *chunk_extra_edge_list) { @@ -120,13 +120,16 @@ static int commit_graph_parse_extra_edge_list( if (chunk_extra_edge_list->length % 4 != 0) return commit_graph_error("malformed Extra Edge List chunk"); - cgraph->extra_edge_list = data + chunk_extra_edge_list->offset; - cgraph->num_extra_edge_list = chunk_extra_edge_list->length / 4; + file->extra_edge_list = data + chunk_extra_edge_list->offset; + file->num_extra_edge_list = chunk_extra_edge_list->length / 4; return 0; } -int git_commit_graph_parse(git_commit_graph_file *cgraph, const unsigned char *data, size_t size) +int git_commit_graph_file_parse( + git_commit_graph_file *file, + const unsigned char *data, + size_t size) { struct git_commit_graph_header *hdr; const unsigned char *chunk_hdr; @@ -139,7 +142,7 @@ int git_commit_graph_parse(git_commit_graph_file *cgraph, const unsigned char *d chunk_commit_data = {0}, chunk_extra_edge_list = {0}, chunk_unsupported = {0}; - GIT_ASSERT_ARG(cgraph); + GIT_ASSERT_ARG(file); if (size < sizeof(struct git_commit_graph_header) + GIT_OID_RAWSZ) return commit_graph_error("commit-graph is too short"); @@ -161,11 +164,11 @@ int git_commit_graph_parse(git_commit_graph_file *cgraph, const unsigned char *d trailer_offset = size - GIT_OID_RAWSZ; if (trailer_offset < last_chunk_offset) return commit_graph_error("wrong commit-graph size"); - git_oid_cpy(&cgraph->checksum, (git_oid *)(data + trailer_offset)); + git_oid_cpy(&file->checksum, (git_oid *)(data + trailer_offset)); if (git_hash_buf(&cgraph_checksum, data, (size_t)trailer_offset) < 0) return commit_graph_error("could not calculate signature"); - if (!git_oid_equal(&cgraph_checksum, &cgraph->checksum)) + if (!git_oid_equal(&cgraph_checksum, &file->checksum)) return commit_graph_error("index signature mismatch"); chunk_hdr = data + sizeof(struct git_commit_graph_header); @@ -214,25 +217,60 @@ int git_commit_graph_parse(git_commit_graph_file *cgraph, const unsigned char *d } last_chunk->length = (size_t)(trailer_offset - last_chunk_offset); - error = commit_graph_parse_oid_fanout(cgraph, data, &chunk_oid_fanout); + error = commit_graph_parse_oid_fanout(file, data, &chunk_oid_fanout); if (error < 0) return error; - error = commit_graph_parse_oid_lookup(cgraph, data, &chunk_oid_lookup); + error = commit_graph_parse_oid_lookup(file, data, &chunk_oid_lookup); if (error < 0) return error; - error = commit_graph_parse_commit_data(cgraph, data, &chunk_commit_data); + error = commit_graph_parse_commit_data(file, data, &chunk_commit_data); if (error < 0) return error; - error = commit_graph_parse_extra_edge_list(cgraph, data, &chunk_extra_edge_list); + error = commit_graph_parse_extra_edge_list(file, data, &chunk_extra_edge_list); if (error < 0) return error; return 0; } -int git_commit_graph_open(git_commit_graph_file **cgraph_out, const char *path) +int git_commit_graph_new(git_commit_graph **cgraph_out, const char *objects_dir, bool open_file) { - git_commit_graph_file *cgraph; + git_commit_graph *cgraph = NULL; + int error = 0; + + GIT_ASSERT_ARG(cgraph_out); + GIT_ASSERT_ARG(objects_dir); + + cgraph = git__calloc(1, sizeof(git_commit_graph)); + GIT_ERROR_CHECK_ALLOC(cgraph); + + error = git_buf_joinpath(&cgraph->filename, objects_dir, "info/commit-graph"); + if (error < 0) + goto error; + + if (open_file) { + error = git_commit_graph_file_open(&cgraph->file, git_buf_cstr(&cgraph->filename)); + if (error < 0) + goto error; + cgraph->checked = 1; + } + + *cgraph_out = cgraph; + return 0; + +error: + git_commit_graph_free(cgraph); + return error; +} + +int git_commit_graph_open(git_commit_graph **cgraph_out, const char *objects_dir) +{ + return git_commit_graph_new(cgraph_out, objects_dir, true); +} + +int git_commit_graph_file_open(git_commit_graph_file **file_out, const char *path) +{ + git_commit_graph_file *file; git_file fd = -1; size_t cgraph_size; struct stat st; @@ -245,56 +283,92 @@ int git_commit_graph_open(git_commit_graph_file **cgraph_out, const char *path) if (p_fstat(fd, &st) < 0) { p_close(fd); - git_error_set(GIT_ERROR_ODB, "multi-pack-index file not found - '%s'", path); - return -1; + git_error_set(GIT_ERROR_ODB, "commit-graph file not found - '%s'", path); + return GIT_ENOTFOUND; } if (!S_ISREG(st.st_mode) || !git__is_sizet(st.st_size)) { p_close(fd); git_error_set(GIT_ERROR_ODB, "invalid pack index '%s'", path); - return -1; + return GIT_ENOTFOUND; } cgraph_size = (size_t)st.st_size; - cgraph = git__calloc(1, sizeof(git_commit_graph_file)); - GIT_ERROR_CHECK_ALLOC(cgraph); - - error = git_buf_sets(&cgraph->filename, path); - if (error < 0) - return error; + file = git__calloc(1, sizeof(git_commit_graph_file)); + GIT_ERROR_CHECK_ALLOC(file); - error = git_futils_mmap_ro(&cgraph->graph_map, fd, 0, cgraph_size); + error = git_futils_mmap_ro(&file->graph_map, fd, 0, cgraph_size); p_close(fd); if (error < 0) { - git_commit_graph_free(cgraph); + git_commit_graph_file_free(file); return error; } - if ((error = git_commit_graph_parse(cgraph, cgraph->graph_map.data, cgraph_size)) < 0) { - git_commit_graph_free(cgraph); + if ((error = git_commit_graph_file_parse(file, file->graph_map.data, cgraph_size)) < 0) { + git_commit_graph_file_free(file); return error; } - *cgraph_out = cgraph; + *file_out = file; return 0; } +int git_commit_graph_get_file(git_commit_graph_file **file_out, git_commit_graph *cgraph) +{ + if (!cgraph->checked) { + int error = 0; + git_commit_graph_file *result = NULL; + + /* We only check once, no matter the result. */ + cgraph->checked = 1; + + /* Best effort */ + error = git_commit_graph_file_open(&result, git_buf_cstr(&cgraph->filename)); + + if (error < 0) + return error; + + cgraph->file = result; + } + if (!cgraph->file) + return GIT_ENOTFOUND; + + *file_out = cgraph->file; + return 0; +} + +void git_commit_graph_refresh(git_commit_graph *cgraph) +{ + if (!cgraph->checked) + return; + + if (cgraph->file + && git_commit_graph_file_needs_refresh(cgraph->file, git_buf_cstr(&cgraph->filename))) { + /* We just free the commit graph. The next time it is requested, it will be + * re-loaded. */ + git_commit_graph_file_free(cgraph->file); + cgraph->file = NULL; + } + /* Force a lazy re-check next time it is needed. */ + cgraph->checked = 0; +} + static int git_commit_graph_entry_get_byindex( git_commit_graph_entry *e, - const git_commit_graph_file *cgraph, + const git_commit_graph_file *file, size_t pos) { const unsigned char *commit_data; GIT_ASSERT_ARG(e); - GIT_ASSERT_ARG(cgraph); + GIT_ASSERT_ARG(file); - if (pos >= cgraph->num_commits) { + if (pos >= file->num_commits) { git_error_set(GIT_ERROR_INVALID, "commit index %zu does not exist", pos); return GIT_ENOTFOUND; } - commit_data = cgraph->commit_data + pos * (GIT_OID_RAWSZ + 4 * sizeof(uint32_t)); + commit_data = file->commit_data + pos * (GIT_OID_RAWSZ + 4 * sizeof(uint32_t)); git_oid_cpy(&e->tree_oid, (const git_oid *)commit_data); e->parent_indices[0] = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ))); e->parent_indices[1] @@ -310,7 +384,7 @@ static int git_commit_graph_entry_get_byindex( uint32_t extra_edge_list_pos = e->parent_indices[1] & 0x7fffffff; /* Make sure we're not being sent out of bounds */ - if (extra_edge_list_pos >= cgraph->num_extra_edge_list) { + if (extra_edge_list_pos >= file->num_extra_edge_list) { git_error_set(GIT_ERROR_INVALID, "commit %u does not exist", extra_edge_list_pos); @@ -318,9 +392,9 @@ static int git_commit_graph_entry_get_byindex( } e->extra_parents_index = extra_edge_list_pos; - while (extra_edge_list_pos < cgraph->num_extra_edge_list + while (extra_edge_list_pos < file->num_extra_edge_list && (ntohl(*( - (uint32_t *)(cgraph->extra_edge_list + (uint32_t *)(file->extra_edge_list + extra_edge_list_pos * sizeof(uint32_t)))) & 0x80000000u) == 0) { @@ -329,20 +403,17 @@ static int git_commit_graph_entry_get_byindex( } } - git_oid_cpy(&e->sha1, &cgraph->oid_lookup[pos]); + git_oid_cpy(&e->sha1, &file->oid_lookup[pos]); return 0; } -bool git_commit_graph_needs_refresh(const git_commit_graph_file *cgraph, const char *path) +bool git_commit_graph_file_needs_refresh(const git_commit_graph_file *file, const char *path) { git_file fd = -1; struct stat st; ssize_t bytes_read; git_oid cgraph_checksum = {{0}}; - if (path == NULL) - path = git_buf_cstr(&cgraph->filename); - /* TODO: properly open the file without access time using O_NOATIME */ fd = git_futils_open_ro(path); if (fd < 0) @@ -354,7 +425,7 @@ bool git_commit_graph_needs_refresh(const git_commit_graph_file *cgraph, const c } if (!S_ISREG(st.st_mode) || !git__is_sizet(st.st_size) - || (size_t)st.st_size != cgraph->graph_map.len) { + || (size_t)st.st_size != file->graph_map.len) { p_close(fd); return true; } @@ -364,12 +435,12 @@ bool git_commit_graph_needs_refresh(const git_commit_graph_file *cgraph, const c if (bytes_read != GIT_OID_RAWSZ) return true; - return !git_oid_equal(&cgraph_checksum, &cgraph->checksum); + return !git_oid_equal(&cgraph_checksum, &file->checksum); } int git_commit_graph_entry_find( git_commit_graph_entry *e, - const git_commit_graph_file *cgraph, + const git_commit_graph_file *file, const git_oid *short_oid, size_t len) { @@ -378,31 +449,31 @@ int git_commit_graph_entry_find( const git_oid *current = NULL; GIT_ASSERT_ARG(e); - GIT_ASSERT_ARG(cgraph); + GIT_ASSERT_ARG(file); GIT_ASSERT_ARG(short_oid); - hi = ntohl(cgraph->oid_fanout[(int)short_oid->id[0]]); - lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(cgraph->oid_fanout[(int)short_oid->id[0] - 1])); + hi = ntohl(file->oid_fanout[(int)short_oid->id[0]]); + lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(file->oid_fanout[(int)short_oid->id[0] - 1])); - pos = git_pack__lookup_sha1(cgraph->oid_lookup, GIT_OID_RAWSZ, lo, hi, short_oid->id); + pos = git_pack__lookup_sha1(file->oid_lookup, GIT_OID_RAWSZ, lo, hi, short_oid->id); if (pos >= 0) { /* An object matching exactly the oid was found */ found = 1; - current = cgraph->oid_lookup + pos; + current = file->oid_lookup + pos; } else { /* No object was found */ /* pos refers to the object with the "closest" oid to short_oid */ pos = -1 - pos; - if (pos < (int)cgraph->num_commits) { - current = cgraph->oid_lookup + pos; + if (pos < (int)file->num_commits) { + current = file->oid_lookup + pos; if (!git_oid_ncmp(short_oid, current, len)) found = 1; } } - if (found && len != GIT_OID_HEXSZ && pos + 1 < (int)cgraph->num_commits) { + if (found && len != GIT_OID_HEXSZ && pos + 1 < (int)file->num_commits) { /* Check for ambiguousity */ const git_oid *next = current + 1; @@ -413,22 +484,22 @@ int git_commit_graph_entry_find( if (!found) return git_odb__error_notfound( - "failed to find offset for multi-pack index entry", short_oid, len); + "failed to find offset for commit-graph index entry", short_oid, len); if (found > 1) return git_odb__error_ambiguous( - "found multiple offsets for multi-pack index entry"); + "found multiple offsets for commit-graph index entry"); - return git_commit_graph_entry_get_byindex(e, cgraph, pos); + return git_commit_graph_entry_get_byindex(e, file, pos); } int git_commit_graph_entry_parent( git_commit_graph_entry *parent, - const git_commit_graph_file *cgraph, + const git_commit_graph_file *file, const git_commit_graph_entry *entry, size_t n) { GIT_ASSERT_ARG(parent); - GIT_ASSERT_ARG(cgraph); + GIT_ASSERT_ARG(file); if (n >= entry->parent_count) { git_error_set(GIT_ERROR_INVALID, "parent index %zu does not exist", n); @@ -436,35 +507,43 @@ int git_commit_graph_entry_parent( } if (n == 0 || (n == 1 && entry->parent_count == 2)) - return git_commit_graph_entry_get_byindex(parent, cgraph, entry->parent_indices[n]); + return git_commit_graph_entry_get_byindex(parent, file, entry->parent_indices[n]); return git_commit_graph_entry_get_byindex( parent, - cgraph, + file, ntohl( - *(uint32_t *)(cgraph->extra_edge_list + *(uint32_t *)(file->extra_edge_list + (entry->extra_parents_index + n - 1) * sizeof(uint32_t))) & 0x7fffffff); } - -int git_commit_graph_close(git_commit_graph_file *cgraph) +int git_commit_graph_file_close(git_commit_graph_file *file) { - GIT_ASSERT_ARG(cgraph); + GIT_ASSERT_ARG(file); - if (cgraph->graph_map.data) - git_futils_mmap_free(&cgraph->graph_map); + if (file->graph_map.data) + git_futils_mmap_free(&file->graph_map); return 0; } -void git_commit_graph_free(git_commit_graph_file *cgraph) +void git_commit_graph_free(git_commit_graph *cgraph) { if (!cgraph) return; git_buf_dispose(&cgraph->filename); - git_commit_graph_close(cgraph); + git_commit_graph_file_free(cgraph->file); git__free(cgraph); } + +void git_commit_graph_file_free(git_commit_graph_file *file) +{ + if (!file) + return; + + git_commit_graph_file_close(file); + git__free(file); +} diff --git a/src/commit_graph.h b/src/commit_graph.h index f21a03769ee..e5e3ea1fdaf 100644 --- a/src/commit_graph.h +++ b/src/commit_graph.h @@ -10,6 +10,9 @@ #include "common.h" +#include "git2/types.h" +#include "git2/sys/commit_graph.h" + #include "map.h" /** @@ -52,9 +55,6 @@ typedef struct git_commit_graph_file { /* The trailer of the file. Contains the SHA1-checksum of the whole file. */ git_oid checksum; - - /* something like ".git/objects/info/commit-graph". */ - git_buf filename; } git_commit_graph_file; /** @@ -88,29 +88,60 @@ typedef struct git_commit_graph_entry { git_oid sha1; } git_commit_graph_entry; -int git_commit_graph_open(git_commit_graph_file **cgraph_out, const char *path); +/* A wrapper for git_commit_graph_file to enable lazy loading in the ODB. */ +struct git_commit_graph { + /* The path to the commit-graph file. Something like ".git/objects/info/commit-graph". */ + git_buf filename; + + /* The underlying commit-graph file. */ + git_commit_graph_file *file; + + /* Whether the commit-graph file was already checked for validity. */ + bool checked; +}; + +/** Create a new commit-graph, optionally opening the underlying file. */ +int git_commit_graph_new(git_commit_graph **cgraph_out, const char *objects_dir, bool open_file); + +/** Open and validate a commit-graph file. */ +int git_commit_graph_file_open(git_commit_graph_file **file_out, const char *path); + +/* + * Attempt to get the git_commit_graph's commit-graph file. This object is + * still owned by the git_commit_graph. If the repository does not contain a commit graph, + * it will return GIT_ENOTFOUND. + * + * This function is not thread-safe. + */ +int git_commit_graph_get_file(git_commit_graph_file **file_out, git_commit_graph *cgraph); + +/* Marks the commit-graph file as needing a refresh. */ +void git_commit_graph_refresh(git_commit_graph *cgraph); /* - * Returns whether the commit_graph_file needs to be reloaded since the - * contents of the commit-graph file have changed on disk. If `path` is NULL, - * the filename stored in `cgraph` will be used. + * Returns whether the git_commit_graph_file needs to be reloaded since the + * contents of the commit-graph file have changed on disk. */ -bool git_commit_graph_needs_refresh(const git_commit_graph_file *cgraph, const char *path); +bool git_commit_graph_file_needs_refresh( + const git_commit_graph_file *file, const char *path); int git_commit_graph_entry_find( git_commit_graph_entry *e, - const git_commit_graph_file *cgraph, + const git_commit_graph_file *file, const git_oid *short_oid, size_t len); int git_commit_graph_entry_parent( git_commit_graph_entry *parent, - const git_commit_graph_file *cgraph, + const git_commit_graph_file *file, const git_commit_graph_entry *entry, size_t n); -int git_commit_graph_close(git_commit_graph_file *cgraph); -void git_commit_graph_free(git_commit_graph_file *cgraph); +int git_commit_graph_file_close(git_commit_graph_file *cgraph); +void git_commit_graph_file_free(git_commit_graph_file *cgraph); /* This is exposed for use in the fuzzers. */ -int git_commit_graph_parse(git_commit_graph_file *cgraph, const unsigned char *data, size_t size); +int git_commit_graph_file_parse( + git_commit_graph_file *file, + const unsigned char *data, + size_t size); #endif diff --git a/src/commit_list.c b/src/commit_list.c index dfdd5daabbe..11cc2e7d2e5 100644 --- a/src/commit_list.c +++ b/src/commit_list.c @@ -144,18 +144,18 @@ static int commit_quick_parse( int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit) { git_odb_object *obj; - git_commit_graph_file *cgraph = NULL; + git_commit_graph_file *cgraph_file = NULL; int error; if (commit->parsed) return 0; /* Let's try to use the commit graph first. */ - git_odb__get_commit_graph(&cgraph, walk->odb); - if (cgraph) { + git_odb__get_commit_graph_file(&cgraph_file, walk->odb); + if (cgraph_file) { git_commit_graph_entry e; - error = git_commit_graph_entry_find(&e, cgraph, &commit->oid, GIT_OID_RAWSZ); + error = git_commit_graph_entry_find(&e, cgraph_file, &commit->oid, GIT_OID_RAWSZ); if (error == 0 && git__is_uint16(e.parent_count)) { size_t i; commit->generation = (uint32_t)e.generation; @@ -166,7 +166,7 @@ int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit) for (i = 0; i < commit->out_degree; ++i) { git_commit_graph_entry parent; - error = git_commit_graph_entry_parent(&parent, cgraph, &e, i); + error = git_commit_graph_entry_parent(&parent, cgraph_file, &e, i); if (error < 0) return error; commit->parents[i] = git_revwalk__commit_lookup(walk, &parent.sha1); diff --git a/src/odb.c b/src/odb.c index 02f97915d6a..40504ca151f 100644 --- a/src/odb.c +++ b/src/odb.c @@ -465,13 +465,6 @@ int git_odb_new(git_odb **out) git__free(db); return -1; } - if (git_buf_init(&db->objects_dir, 0) < 0) { - git_vector_free(&db->backends); - git_cache_dispose(&db->own_cache); - git_mutex_free(&db->lock); - git__free(db); - return -1; - } *out = db; GIT_REFCOUNT_INC(db); @@ -619,17 +612,6 @@ int git_odb__add_default_backends( git_mutex_unlock(&db->lock); #endif - if (git_mutex_lock(&db->lock) < 0) { - git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); - return -1; - } - if (git_buf_len(&db->objects_dir) == 0 && git_buf_sets(&db->objects_dir, objects_dir) < 0) { - git_mutex_unlock(&db->lock); - git_odb_free(db); - return -1; - } - git_mutex_unlock(&db->lock); - /* add the loose object backend */ if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 || add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates, inode) < 0) @@ -640,6 +622,16 @@ int git_odb__add_default_backends( add_backend_internal(db, packed, GIT_PACKED_PRIORITY, as_alternates, inode) < 0) return -1; + if (git_mutex_lock(&db->lock) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock"); + return -1; + } + if (!db->cgraph && git_commit_graph_new(&db->cgraph, objects_dir, false) < 0) { + git_mutex_unlock(&db->lock); + return -1; + } + git_mutex_unlock(&db->lock); + return load_alternates(db, objects_dir, alternate_depth); } @@ -701,6 +693,23 @@ int git_odb_add_disk_alternate(git_odb *odb, const char *path) return git_odb__add_default_backends(odb, path, true, 0); } +int git_odb_set_commit_graph(git_odb *odb, git_commit_graph *cgraph) +{ + int error = 0; + + GIT_ASSERT_ARG(odb); + + if ((error = git_mutex_lock(&odb->lock)) < 0) { + git_error_set(GIT_ERROR_ODB, "failed to acquire the db lock"); + return error; + } + git_commit_graph_free(odb->cgraph); + odb->cgraph = cgraph; + git_mutex_unlock(&odb->lock); + + return error; +} + int git_odb_open(git_odb **out, const char *objects_dir) { git_odb *db; @@ -760,7 +769,6 @@ static void odb_free(git_odb *db) if (locked) git_mutex_unlock(&db->lock); - git_buf_dispose(&db->objects_dir); git_commit_graph_free(db->cgraph); git_vector_free(&db->backends); git_cache_dispose(&db->own_cache); @@ -806,51 +814,27 @@ static int odb_exists_1( return (int)found; } -int git_odb__get_commit_graph(git_commit_graph_file **out, git_odb *db) +int git_odb__get_commit_graph_file(git_commit_graph_file **out, git_odb *db) { int error = 0; + git_commit_graph_file *result = NULL; if ((error = git_mutex_lock(&db->lock)) < 0) { git_error_set(GIT_ERROR_ODB, "failed to acquire the db lock"); return error; } - if (!db->cgraph_checked) { - git_buf commit_graph_path = GIT_BUF_INIT; - git_commit_graph_file *cgraph = NULL; - - /* We only check once, no matter the result. */ - db->cgraph_checked = 1; - - if (git_buf_len(&db->objects_dir) == 0) { - /* - * This odb was not opened with an objects directory - * associated. Skip opening the commit graph. - */ - goto done; - } - - if ((error = git_buf_joinpath( - &commit_graph_path, - git_buf_cstr(&db->objects_dir), - "info/commit-graph")) - < 0) { - git_buf_dispose(&commit_graph_path); - goto done; - } - /* Best effort */ - error = git_commit_graph_open(&cgraph, git_buf_cstr(&commit_graph_path)); - git_buf_dispose(&commit_graph_path); - - if (error < 0) - goto done; - - db->cgraph = cgraph; + if (!db->cgraph) { + error = GIT_ENOTFOUND; + goto done; } + error = git_commit_graph_get_file(&result, db->cgraph); + if (error) + goto done; + *out = result; done: - *out = db->cgraph; git_mutex_unlock(&db->lock); - return 0; + return error; } static int odb_freshen_1( @@ -1762,13 +1746,8 @@ int git_odb_refresh(struct git_odb *db) } } } - if (db->cgraph && git_commit_graph_needs_refresh(db->cgraph, NULL)) { - /* We just free the commit graph. The next time it is requested, it will be re-loaded. */ - git_commit_graph_free(db->cgraph); - db->cgraph = NULL; - } - /* Force a lazy re-check next time it is needed. */ - db->cgraph_checked = 0; + if (db->cgraph) + git_commit_graph_refresh(db->cgraph); git_mutex_unlock(&db->lock); return 0; diff --git a/src/odb.h b/src/odb.h index dcf29c2e284..5bebb6edce4 100644 --- a/src/odb.h +++ b/src/odb.h @@ -12,6 +12,7 @@ #include "git2/odb.h" #include "git2/oid.h" #include "git2/types.h" +#include "git2/sys/commit_graph.h" #include "cache.h" #include "commit_graph.h" @@ -44,10 +45,8 @@ struct git_odb { git_mutex lock; /* protects backends */ git_vector backends; git_cache own_cache; - git_buf objects_dir; - git_commit_graph_file *cgraph; + git_commit_graph *cgraph; unsigned int do_fsync :1; - unsigned int cgraph_checked :1; }; typedef enum { @@ -132,11 +131,11 @@ int git_odb__read_header_or_object( git_odb *db, const git_oid *id); /* - * Attempt to get the ODB's commit graph. This object is still owned by the - * ODB. If the repository does not contain a commit graph, it will return zero - * and `*out` will be set to NULL. + * Attempt to get the ODB's commit-graph file. This object is still owned by + * the ODB. If the repository does not contain a commit-graph, it will return + * GIT_ENOTFOUND. */ -int git_odb__get_commit_graph(git_commit_graph_file **out, git_odb *odb); +int git_odb__get_commit_graph_file(git_commit_graph_file **out, git_odb *odb); /* freshen an entry in the object database */ int git_odb__freshen(git_odb *db, const git_oid *id); diff --git a/tests/graph/commit_graph.c b/tests/graph/commit_graph.c index 4c7c5a726a3..c6d84a007a2 100644 --- a/tests/graph/commit_graph.c +++ b/tests/graph/commit_graph.c @@ -7,18 +7,18 @@ void test_graph_commit_graph__parse(void) { git_repository *repo; - struct git_commit_graph_file *cgraph; + struct git_commit_graph_file *file; struct git_commit_graph_entry e, parent; git_oid id; git_buf commit_graph_path = GIT_BUF_INIT; cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); cl_git_pass(git_buf_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph")); - cl_git_pass(git_commit_graph_open(&cgraph, git_buf_cstr(&commit_graph_path))); - cl_assert_equal_i(git_commit_graph_needs_refresh(cgraph, git_buf_cstr(&commit_graph_path)), 0); + cl_git_pass(git_commit_graph_file_open(&file, git_buf_cstr(&commit_graph_path))); + cl_assert_equal_i(git_commit_graph_file_needs_refresh(file, git_buf_cstr(&commit_graph_path)), 0); cl_git_pass(git_oid_fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5")); - cl_git_pass(git_commit_graph_entry_find(&e, cgraph, &id, GIT_OID_HEXSZ)); + cl_git_pass(git_commit_graph_entry_find(&e, file, &id, GIT_OID_HEXSZ)); cl_assert_equal_oid(&e.sha1, &id); cl_git_pass(git_oid_fromstr(&id, "418382dff1ffb8bdfba833f4d8bbcde58b1e7f47")); cl_assert_equal_oid(&e.tree_oid, &id); @@ -27,23 +27,23 @@ void test_graph_commit_graph__parse(void) cl_assert_equal_i(e.parent_count, 0); cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); - cl_git_pass(git_commit_graph_entry_find(&e, cgraph, &id, GIT_OID_HEXSZ)); + cl_git_pass(git_commit_graph_entry_find(&e, file, &id, GIT_OID_HEXSZ)); cl_assert_equal_oid(&e.sha1, &id); cl_assert_equal_i(e.generation, 5); cl_assert_equal_i(e.commit_time, 1274813907ull); cl_assert_equal_i(e.parent_count, 2); cl_git_pass(git_oid_fromstr(&id, "9fd738e8f7967c078dceed8190330fc8648ee56a")); - cl_git_pass(git_commit_graph_entry_parent(&parent, cgraph, &e, 0)); + cl_git_pass(git_commit_graph_entry_parent(&parent, file, &e, 0)); cl_assert_equal_oid(&parent.sha1, &id); cl_assert_equal_i(parent.generation, 4); cl_git_pass(git_oid_fromstr(&id, "c47800c7266a2be04c571c04d5a6614691ea99bd")); - cl_git_pass(git_commit_graph_entry_parent(&parent, cgraph, &e, 1)); + cl_git_pass(git_commit_graph_entry_parent(&parent, file, &e, 1)); cl_assert_equal_oid(&parent.sha1, &id); cl_assert_equal_i(parent.generation, 3); - git_commit_graph_free(cgraph); + git_commit_graph_file_free(file); git_repository_free(repo); git_buf_dispose(&commit_graph_path); } @@ -51,17 +51,17 @@ void test_graph_commit_graph__parse(void) void test_graph_commit_graph__parse_octopus_merge(void) { git_repository *repo; - struct git_commit_graph_file *cgraph; + struct git_commit_graph_file *file; struct git_commit_graph_entry e, parent; git_oid id; git_buf commit_graph_path = GIT_BUF_INIT; cl_git_pass(git_repository_open(&repo, cl_fixture("merge-recursive/.gitted"))); cl_git_pass(git_buf_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph")); - cl_git_pass(git_commit_graph_open(&cgraph, git_buf_cstr(&commit_graph_path))); + cl_git_pass(git_commit_graph_file_open(&file, git_buf_cstr(&commit_graph_path))); cl_git_pass(git_oid_fromstr(&id, "d71c24b3b113fd1d1909998c5bfe33b86a65ee03")); - cl_git_pass(git_commit_graph_entry_find(&e, cgraph, &id, GIT_OID_HEXSZ)); + cl_git_pass(git_commit_graph_entry_find(&e, file, &id, GIT_OID_HEXSZ)); cl_assert_equal_oid(&e.sha1, &id); cl_git_pass(git_oid_fromstr(&id, "348f16ffaeb73f319a75cec5b16a0a47d2d5e27c")); cl_assert_equal_oid(&e.tree_oid, &id); @@ -70,21 +70,21 @@ void test_graph_commit_graph__parse_octopus_merge(void) cl_assert_equal_i(e.parent_count, 3); cl_git_pass(git_oid_fromstr(&id, "ad2ace9e15f66b3d1138922e6ffdc3ea3f967fa6")); - cl_git_pass(git_commit_graph_entry_parent(&parent, cgraph, &e, 0)); + cl_git_pass(git_commit_graph_entry_parent(&parent, file, &e, 0)); cl_assert_equal_oid(&parent.sha1, &id); cl_assert_equal_i(parent.generation, 6); cl_git_pass(git_oid_fromstr(&id, "483065df53c0f4a02cdc6b2910b05d388fc17ffb")); - cl_git_pass(git_commit_graph_entry_parent(&parent, cgraph, &e, 1)); + cl_git_pass(git_commit_graph_entry_parent(&parent, file, &e, 1)); cl_assert_equal_oid(&parent.sha1, &id); cl_assert_equal_i(parent.generation, 2); cl_git_pass(git_oid_fromstr(&id, "815b5a1c80ca749d705c7aa0cb294a00cbedd340")); - cl_git_pass(git_commit_graph_entry_parent(&parent, cgraph, &e, 2)); + cl_git_pass(git_commit_graph_entry_parent(&parent, file, &e, 2)); cl_assert_equal_oid(&parent.sha1, &id); cl_assert_equal_i(parent.generation, 6); - git_commit_graph_free(cgraph); + git_commit_graph_file_free(file); git_repository_free(repo); git_buf_dispose(&commit_graph_path); } From 8f52b0c55316f10cdeb8aaa5a69b36d30d44e834 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 17 Mar 2021 10:48:17 +0100 Subject: [PATCH 0257/1616] Remove duplicate line, in example code --- examples/general.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/general.c b/examples/general.c index 1622ff8b008..5da2b6f6fc4 100644 --- a/examples/general.c +++ b/examples/general.c @@ -154,11 +154,6 @@ static void oid_parsing(git_oid *oid) printf("\n*Raw to Hex*\n"); out[GIT_OID_HEXSZ] = '\0'; - /** - * If you have a oid, you can easily get the hex value of the SHA as well. - */ - git_oid_fmt(out, oid); - /** * If you have a oid, you can easily get the hex value of the SHA as well. */ From bc3d4065528004e0cd86c8b0ae79405196f86584 Mon Sep 17 00:00:00 2001 From: Anders Borum Date: Sat, 20 Mar 2021 21:39:02 +0100 Subject: [PATCH 0258/1616] fix check for ignoring of negate rules gitignore rule like "*.pdf" should be negated by "!dir/test.pdf" even though one is inside a directory since *.pdf isn't restricted to any directory this is fixed by making wildcard match treat * like ** by excluding WM_PATHNAME flag when the rule isn't for a full path --- src/ignore.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ignore.c b/src/ignore.c index 27a650b1b74..32e5c539bcc 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -101,7 +101,7 @@ static int does_negate_pattern(git_attr_fnmatch *rule, git_attr_fnmatch *neg) */ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match) { - int error = 0, wildmatch_flags; + int error = 0, wildmatch_flags, effective_flags; size_t i; git_attr_fnmatch *rule; char *path; @@ -141,8 +141,17 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match if (git_buf_oom(&buf)) goto out; + /* if rule isn't for full path we match without PATHNAME flag + as lines like *.txt should match something like dir/test.txt + requiring * to also match / + */ + effective_flags = wildmatch_flags; + if ((rule->flags & GIT_ATTR_FNMATCH_FULLPATH) == 0) { + effective_flags &= ~WM_PATHNAME; + } + /* if we found a match, we want to keep this rule */ - if ((wildmatch(git_buf_cstr(&buf), path, wildmatch_flags)) == WM_MATCH) { + if ((wildmatch(git_buf_cstr(&buf), path, effective_flags)) == WM_MATCH) { *out = 1; error = 0; goto out; From f05de9cb53d3470e7f6dc92cb2eaae425272d22f Mon Sep 17 00:00:00 2001 From: todaysoftware <80295432+todaysoftware@users.noreply.github.com> Date: Fri, 26 Mar 2021 10:22:08 +1300 Subject: [PATCH 0259/1616] Update README.md for additional Delphi bindings Delphi/Free pascal bindings targeting the latest version of libgit2 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 55358a981cd..b8448be8867 100644 --- a/README.md +++ b/README.md @@ -355,6 +355,7 @@ Here are the bindings to libgit2 that are currently available: * dlibgit * Delphi * GitForDelphi + * libgit2-delphi * Erlang * Geef * Go From 7891e15375e1f9737f8e6a348fae36f0d6f5c2f6 Mon Sep 17 00:00:00 2001 From: Ian Hattendorf Date: Thu, 1 Apr 2021 11:34:38 -0700 Subject: [PATCH 0260/1616] Default to GIT_BRANCH_DEFAULT if init.defaultBranch is empty string We already do this in repo_init_head --- src/repository.c | 5 +++-- tests/repo/getters.c | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/repository.c b/src/repository.c index de1a895828a..2c8b8192e19 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2384,10 +2384,11 @@ int git_repository_initialbranch(git_buf *out, git_repository *repo) if ((error = git_repository_config__weakptr(&config, repo)) < 0) return error; - if ((error = git_config_get_entry(&entry, config, "init.defaultbranch")) == 0) { + if ((error = git_config_get_entry(&entry, config, "init.defaultbranch")) == 0 && + *entry->value) { branch = entry->value; } - else if (error == GIT_ENOTFOUND) { + else if (!error || error == GIT_ENOTFOUND) { branch = GIT_BRANCH_DEFAULT; } else { diff --git a/tests/repo/getters.c b/tests/repo/getters.c index b8ede126c1d..d401bb8327f 100644 --- a/tests/repo/getters.c +++ b/tests/repo/getters.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" +#include "repo/repo_helpers.h" void test_repo_getters__is_empty_correctly_deals_with_pristine_looking_repos(void) { @@ -23,6 +24,18 @@ void test_repo_getters__is_empty_can_detect_used_repositories(void) git_repository_free(repo); } +void test_repo_getters__is_empty_can_detect_repositories_with_defaultbranch_config_empty(void) +{ + git_repository *repo; + + create_tmp_global_config("tmp_global_path", "init.defaultBranch", ""); + + cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); + cl_assert_equal_i(false, git_repository_is_empty(repo)); + + git_repository_free(repo); +} + void test_repo_getters__retrieving_the_odb_honors_the_refcount(void) { git_odb *odb; From 6591deefbf2443ef2162ac2384620bf0ec8065cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 11 Apr 2021 14:27:14 +0200 Subject: [PATCH 0261/1616] repo: remove an inappropriate use of PASSTHROUGH This error code is for callbacks where we should act as though the callback was not set. This is not something that makes sense for a `_foreach` and checking for that error message to bubble up mostly is happenstance precisely because this is not an error code we expect in the callback. As part of removing this, let's also remove a use of foreach as we can open-code this check. --- src/repository.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/repository.c b/src/repository.c index 2c8b8192e19..4ad87c11ec8 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2354,21 +2354,19 @@ int git_repository_head_unborn(git_repository *repo) return 0; } -static int at_least_one_cb(const char *refname, void *payload) -{ - GIT_UNUSED(refname); - GIT_UNUSED(payload); - return GIT_PASSTHROUGH; -} - static int repo_contains_no_reference(git_repository *repo) { - int error = git_reference_foreach_name(repo, &at_least_one_cb, NULL); + git_reference_iterator *iter; + const char *refname; + int error; - if (error == GIT_PASSTHROUGH) - return 0; + if ((error = git_reference_iterator_new(&iter, repo)) < 0) + return error; - if (!error) + error = git_reference_next_name(&refname, iter); + git_reference_iterator_free(iter); + + if (error == GIT_ITEROVER) return 1; return error; From 631fe56faeb0acc600074b89eaeca93e548d3e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 11 Apr 2021 21:22:33 +0200 Subject: [PATCH 0262/1616] repo: specify init.defaultbranch is meant to be a branch name We don't want the default branch's refname here but its name as branch. Returning an error saying it's not a valid reference here suggests we want the value of `init.defaultbranch` to be something like `refs/heads/default` which is not the case. --- src/repository.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/repository.c b/src/repository.c index 2c8b8192e19..124722bba27 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2401,7 +2401,7 @@ int git_repository_initialbranch(git_buf *out, git_repository *repo) goto done; if (!valid) { - git_error_set(GIT_ERROR_INVALID, "the value of init.defaultBranch is not a valid reference name"); + git_error_set(GIT_ERROR_INVALID, "the value of init.defaultBranch is not a valid branch name"); error = -1; } From 52447c5c95ee8d2834e42aa0c26cb47168e2cffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Sun, 11 Apr 2021 23:16:37 +0200 Subject: [PATCH 0263/1616] tests: fix variable name in list.c --- tests/object/tag/list.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/object/tag/list.c b/tests/object/tag/list.c index 8a1a2d26d2d..d15f09205c5 100644 --- a/tests/object/tag/list.c +++ b/tests/object/tag/list.c @@ -20,7 +20,7 @@ static void ensure_tag_pattern_match(git_repository *repo, int already_found[MAX_USED_TAGS] = { 0 }; git_strarray tag_list; int error = 0; - size_t sucessfully_found = 0; + size_t successfully_found = 0; size_t i, j; cl_assert(data->expected_matches <= MAX_USED_TAGS); @@ -42,12 +42,12 @@ static void ensure_tag_pattern_match(git_repository *repo, if (!already_found[j] && !strcmp(data->expected_results[j], tag_list.strings[i])) { already_found[j] = 1; - sucessfully_found++; + successfully_found++; break; } } } - cl_assert_equal_i((int)sucessfully_found, (int)data->expected_matches); + cl_assert_equal_i((int)successfully_found, (int)data->expected_matches); exit: git_strarray_dispose(&tag_list); From 965855970ec4e39502e7591f8bb088bbe3b1be0a Mon Sep 17 00:00:00 2001 From: Marco Sirabella Date: Mon, 12 Apr 2021 23:52:03 -0700 Subject: [PATCH 0264/1616] Fix diff_entrycount -> diff_num_deltas doc typo This just fixes a typo in the documentation, actual rename change was done in 5f69a31f --- include/git2/diff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/diff.h b/include/git2/diff.h index 3976ab1b919..e1055559594 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -998,7 +998,7 @@ GIT_EXTERN(size_t) git_diff_num_deltas(const git_diff *diff); /** * Query how many diff deltas are there in a diff filtered by type. * - * This works just like `git_diff_entrycount()` with an extra parameter + * This works just like `git_diff_num_deltas()` with an extra parameter * that is a `git_delta_t` and returns just the count of how many deltas * match that particular type. * From 958205a33d9e9d078f41a9a3ac04dc7c657840c7 Mon Sep 17 00:00:00 2001 From: Jochen Hunz Date: Wed, 14 Apr 2021 22:05:47 +0200 Subject: [PATCH 0265/1616] implement GIT_CHECKOUT_DRY_RUN to allow notifications without touching the working directory --- include/git2/checkout.h | 3 +++ src/checkout.c | 3 +++ tests/checkout/tree.c | 46 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/include/git2/checkout.h b/include/git2/checkout.h index 3c87001bf33..d4c1cfa0b84 100644 --- a/include/git2/checkout.h +++ b/include/git2/checkout.h @@ -177,6 +177,9 @@ typedef enum { /** Normally checkout writes the index upon completion; this prevents that. */ GIT_CHECKOUT_DONT_WRITE_INDEX = (1u << 23), + /** Stop checkout after the notifications happend but before the working directory is touched. */ + GIT_CHECKOUT_DRY_RUN = (1u << 24), + /** * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED */ diff --git a/src/checkout.c b/src/checkout.c index 65487993b74..7d3b035a932 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -2606,6 +2606,9 @@ int git_checkout_iterator( if ((error = checkout_get_actions(&actions, &counts, &data, workdir)) != 0) goto cleanup; + if (data.strategy & GIT_CHECKOUT_DRY_RUN) + goto cleanup; + data.total_steps = counts[CHECKOUT_ACTION__REMOVE] + counts[CHECKOUT_ACTION__REMOVE_CONFLICT] + counts[CHECKOUT_ACTION__UPDATE_BLOB] + diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c index f8d9abe552d..3241a3eb767 100644 --- a/tests/checkout/tree.c +++ b/tests/checkout/tree.c @@ -1636,3 +1636,49 @@ void test_checkout_tree__no_index_refresh(void) modify_index_and_checkout_tree(&opts); assert_status_entrycount(g_repo, 0); } + +void test_checkout_tree__dry_run(void) +{ + git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; + git_oid oid; + git_object *obj = NULL; + checkout_counts ct; + + /* first let's get things into a known state - by checkout out the HEAD */ + + assert_on_branch(g_repo, "master"); + + opts.checkout_strategy = GIT_CHECKOUT_FORCE; + cl_git_pass(git_checkout_head(g_repo, &opts)); + + cl_assert(!git_path_isdir("testrepo/a")); + + check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n"); + + /* now checkout branch but with dry run enabled */ + + memset(&ct, 0, sizeof(ct)); + opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_DRY_RUN; + opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL; + opts.notify_cb = checkout_count_callback; + opts.notify_payload = &ct; + + cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir")); + cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY)); + + cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); + cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); + + assert_on_branch(g_repo, "dir"); + + /* these normally would have been created and updated, but with + * DRY_RUN they will be unchanged. + */ + cl_assert(!git_path_isdir("testrepo/a")); + check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n"); + + /* check that notify callback was invoked */ + cl_assert_equal_i(ct.n_updates, 2); + + git_object_free(obj); +} From 1d95b59b4dbd8eda3f83f8af2a4ae07c7cdfc245 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 14 Apr 2021 15:47:27 +0100 Subject: [PATCH 0266/1616] utf8: refactor utf8 functions Move the utf8 functions into a proper namespace `git_utf8` instead of being in the namespaceless `git__` function group. Update them to have out-params first and use `char *` instead of `uint8_t *` to match our API treating strings as `char *` (even if they truly contain `uchar`s inside). --- src/common.h | 1 + src/diff_xdiff.c | 3 +- src/path.c | 6 +-- src/utf8.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++ src/utf8.h | 32 ++++++++++++ src/util.c | 117 ----------------------------------------- src/util.h | 21 -------- 7 files changed, 169 insertions(+), 143 deletions(-) create mode 100644 src/utf8.c create mode 100644 src/utf8.h diff --git a/src/common.h b/src/common.h index bda3edbc17e..9123fb595b3 100644 --- a/src/common.h +++ b/src/common.h @@ -83,6 +83,7 @@ #include "thread.h" #include "integer.h" #include "assert_safe.h" +#include "utf8.h" /* * Include the declarations for deprecated functions; this ensures diff --git a/src/diff_xdiff.c b/src/diff_xdiff.c index c4668fa2fdc..8622623afea 100644 --- a/src/diff_xdiff.c +++ b/src/diff_xdiff.c @@ -6,7 +6,6 @@ */ #include "diff_xdiff.h" -#include "util.h" #include "git2/errors.h" #include "diff.h" @@ -128,7 +127,7 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len) info->hunk.header_len = sizeof(info->hunk.header) - 1; /* Sanitize the hunk header in case there is invalid Unicode */ - buffer_len = git__utf8_valid_buf_length((const uint8_t *) bufs[0].ptr, info->hunk.header_len); + buffer_len = git_utf8_valid_buf_length(bufs[0].ptr, info->hunk.header_len); /* Sanitizing the hunk header may delete the newline, so add it back again if there is room */ if (buffer_len < info->hunk.header_len) { bufs[0].ptr[buffer_len] = '\n'; diff --git a/src/path.c b/src/path.c index dde3efb6387..8ebb581581d 100644 --- a/src/path.c +++ b/src/path.c @@ -1562,8 +1562,8 @@ GIT_INLINE(bool) verify_dospath( static int32_t next_hfs_char(const char **in, size_t *len) { while (*len) { - int32_t codepoint; - int cp_len = git__utf8_iterate((const uint8_t *)(*in), (int)(*len), &codepoint); + uint32_t codepoint; + int cp_len = git_utf8_iterate(&codepoint, *in, *len); if (cp_len < 0) return -1; @@ -1595,7 +1595,7 @@ static int32_t next_hfs_char(const char **in, size_t *len) * the ASCII range, which is perfectly fine, because the * git folder name can only be composed of ascii characters */ - return git__tolower(codepoint); + return git__tolower((int)codepoint); } return 0; /* NULL byte -- end of string */ } diff --git a/src/utf8.c b/src/utf8.c new file mode 100644 index 00000000000..1a37da6fba2 --- /dev/null +++ b/src/utf8.c @@ -0,0 +1,132 @@ +/* + * 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 "utf8.h" + +#include "common.h" + +/* + * git_utf8_iterate is taken from the utf8proc project, + * http://www.public-software-group.org/utf8proc + * + * Copyright (c) 2009 Public Software Group e. V., Berlin, Germany + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the ""Software""), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +static const uint8_t utf8proc_utf8class[256] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static int utf8_charlen(const uint8_t *str, size_t str_len) +{ + uint8_t length; + size_t i; + + length = utf8proc_utf8class[str[0]]; + if (!length) + return -1; + + if (str_len > 0 && length > str_len) + return -1; + + for (i = 1; i < length; i++) { + if ((str[i] & 0xC0) != 0x80) + return -1; + } + + return (int)length; +} + +int git_utf8_iterate(uint32_t *out, const char *_str, size_t str_len) +{ + const uint8_t *str = (const uint8_t *)_str; + uint32_t uc = 0; + int length; + + *out = 0; + + if ((length = utf8_charlen(str, str_len)) < 0) + return -1; + + switch (length) { + case 1: + uc = str[0]; + break; + case 2: + uc = ((str[0] & 0x1F) << 6) + (str[1] & 0x3F); + if (uc < 0x80) uc = -1; + break; + case 3: + uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) << 6) + + (str[2] & 0x3F); + if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000) || + (uc >= 0xFDD0 && uc < 0xFDF0)) uc = -1; + break; + case 4: + uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12) + + ((str[2] & 0x3F) << 6) + (str[3] & 0x3F); + if (uc < 0x10000 || uc >= 0x110000) uc = -1; + break; + default: + return -1; + } + + if ((uc & 0xFFFF) >= 0xFFFE) + return -1; + + *out = uc; + return length; +} + +size_t git_utf8_valid_buf_length(const char *_str, size_t str_len) +{ + const uint8_t *str = (const uint8_t *)_str; + size_t offset = 0; + + while (offset < str_len) { + int length = utf8_charlen(str + offset, str_len - offset); + + if (length < 0) + break; + + offset += length; + } + + return offset; +} diff --git a/src/utf8.h b/src/utf8.h new file mode 100644 index 00000000000..71c8f3bee5c --- /dev/null +++ b/src/utf8.h @@ -0,0 +1,32 @@ +/* + * 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_utf8_h__ +#define INCLUDE_utf8_h__ + +#include "common.h" + +/* + * Iterate through an UTF-8 string, yielding one codepoint at a time. + * + * @param out pointer where to store the current codepoint + * @param str current position in the string + * @param str_len size left in the string + * @return length in bytes of the read codepoint; -1 if the codepoint was invalid + */ +extern int git_utf8_iterate(uint32_t *out, const char *str, size_t str_len); + +/** + * Iterate through an UTF-8 string and stops after finding any invalid UTF-8 + * codepoints. + * + * @param str string to scan + * @param str_len size of the string + * @return length in bytes of the string that contains valid data + */ +extern size_t git_utf8_valid_buf_length(const char *str, size_t str_len); + +#endif diff --git a/src/util.c b/src/util.c index af825e4d252..c7af2961aa7 100644 --- a/src/util.c +++ b/src/util.c @@ -734,123 +734,6 @@ void git__qsort_r( #endif } -/* - * git__utf8_iterate is taken from the utf8proc project, - * http://www.public-software-group.org/utf8proc - * - * Copyright (c) 2009 Public Software Group e. V., Berlin, Germany - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the ""Software""), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -static const int8_t utf8proc_utf8class[256] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static int util_utf8_charlen(const uint8_t *str, size_t str_len) -{ - size_t length, i; - - length = utf8proc_utf8class[str[0]]; - if (!length) - return -1; - - if (str_len > 0 && length > str_len) - return -1; - - for (i = 1; i < length; i++) { - if ((str[i] & 0xC0) != 0x80) - return -1; - } - - return (int)length; -} - -int git__utf8_iterate(const uint8_t *str, int str_len, int32_t *dst) -{ - int length; - int32_t uc = -1; - - *dst = -1; - length = util_utf8_charlen(str, str_len); - if (length < 0) - return -1; - - switch (length) { - case 1: - uc = str[0]; - break; - case 2: - uc = ((str[0] & 0x1F) << 6) + (str[1] & 0x3F); - if (uc < 0x80) uc = -1; - break; - case 3: - uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) << 6) - + (str[2] & 0x3F); - if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000) || - (uc >= 0xFDD0 && uc < 0xFDF0)) uc = -1; - break; - case 4: - uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12) - + ((str[2] & 0x3F) << 6) + (str[3] & 0x3F); - if (uc < 0x10000 || uc >= 0x110000) uc = -1; - break; - } - - if (uc < 0 || ((uc & 0xFFFF) >= 0xFFFE)) - return -1; - - *dst = uc; - return length; -} - -size_t git__utf8_valid_buf_length(const uint8_t *str, size_t str_len) -{ - size_t offset = 0; - - while (offset < str_len) { - int length = util_utf8_charlen(str + offset, str_len - offset); - - if (length < 0) - break; - - offset += length; - } - - return offset; -} - #ifdef GIT_WIN32 int git__getenv(git_buf *out, const char *name) { diff --git a/src/util.h b/src/util.h index 5076df28201..dabd4c94a9d 100644 --- a/src/util.h +++ b/src/util.h @@ -316,27 +316,6 @@ extern int git__date_rfc2822_fmt(char *out, size_t len, const git_time *date); */ extern size_t git__unescape(char *str); -/* - * Iterate through an UTF-8 string, yielding one - * codepoint at a time. - * - * @param str current position in the string - * @param str_len size left in the string; -1 if the string is NULL-terminated - * @param dst pointer where to store the current codepoint - * @return length in bytes of the read codepoint; -1 if the codepoint was invalid - */ -extern int git__utf8_iterate(const uint8_t *str, int str_len, int32_t *dst); - -/* - * Iterate through an UTF-8 string and stops after finding any invalid UTF-8 - * codepoints. - * - * @param str string to scan - * @param str_len size of the string - * @return length in bytes of the string that contains valid data - */ -extern size_t git__utf8_valid_buf_length(const uint8_t *str, size_t str_len); - /* * Safely zero-out memory, making sure that the compiler * doesn't optimize away the operation. From cb136cddd93046d46c6a8c5ee2a3f5c30a001e97 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 14 Apr 2021 22:22:11 +0100 Subject: [PATCH 0267/1616] utf8: introduce git_utf8_char_length Introduce a function to determine the number of Unicode characters in a given UTF-8 string. --- src/utf8.c | 18 ++++++++++++++++++ src/utf8.h | 20 ++++++++++++++++++++ tests/core/utf8.c | 19 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 tests/core/utf8.c diff --git a/src/utf8.c b/src/utf8.c index 1a37da6fba2..77065cb710e 100644 --- a/src/utf8.c +++ b/src/utf8.c @@ -114,6 +114,24 @@ int git_utf8_iterate(uint32_t *out, const char *_str, size_t str_len) return length; } +size_t git_utf8_char_length(const char *_str, size_t str_len) +{ + const uint8_t *str = (const uint8_t *)_str; + size_t offset = 0, count = 0; + + while (offset < str_len) { + int length = utf8_charlen(str + offset, str_len - offset); + + if (length < 0) + length = 1; + + offset += length; + count++; + } + + return count; +} + size_t git_utf8_valid_buf_length(const char *_str, size_t str_len) { const uint8_t *str = (const uint8_t *)_str; diff --git a/src/utf8.h b/src/utf8.h index 71c8f3bee5c..dff91b2945a 100644 --- a/src/utf8.h +++ b/src/utf8.h @@ -19,6 +19,26 @@ */ extern int git_utf8_iterate(uint32_t *out, const char *str, size_t str_len); +/** + * Returns the number of characters in the given string. + * + * This function will count invalid codepoints; if any given byte is + * not part of a valid UTF-8 codepoint, then it will be counted toward + * the length in characters. + * + * In other words: + * 0x24 (U+0024 "$") has length 1 + * 0xc2 0xa2 (U+00A2 "¢") has length 1 + * 0x24 0xc2 0xa2 (U+0024 U+00A2 "$¢") has length 2 + * 0xf0 0x90 0x8d 0x88 (U+10348 "ðˆ") has length 1 + * 0x24 0xc0 0xc1 0x34 (U+0024 "4) has length 4 + * + * @param str string to scan + * @param str_len size of the string + * @return length in characters of the string + */ +extern size_t git_utf8_char_length(const char *str, size_t str_len); + /** * Iterate through an UTF-8 string and stops after finding any invalid UTF-8 * codepoints. diff --git a/tests/core/utf8.c b/tests/core/utf8.c new file mode 100644 index 00000000000..021828e9e1c --- /dev/null +++ b/tests/core/utf8.c @@ -0,0 +1,19 @@ +#include "clar_libgit2.h" + +void test_core_utf8__char_length(void) +{ + cl_assert_equal_i(0, git_utf8_char_length("", 0)); + cl_assert_equal_i(1, git_utf8_char_length("$", 1)); + cl_assert_equal_i(5, git_utf8_char_length("abcde", 5)); + cl_assert_equal_i(1, git_utf8_char_length("\xc2\xa2", 2)); + cl_assert_equal_i(2, git_utf8_char_length("\x24\xc2\xa2", 3)); + cl_assert_equal_i(1, git_utf8_char_length("\xf0\x90\x8d\x88", 4)); + + /* uncontinued character counted as single characters */ + cl_assert_equal_i(2, git_utf8_char_length("\x24\xc2", 2)); + cl_assert_equal_i(3, git_utf8_char_length("\x24\xc2\xc2\xa2", 4)); + + /* invalid characters are counted as single characters */ + cl_assert_equal_i(4, git_utf8_char_length("\x24\xc0\xc0\x34", 4)); + cl_assert_equal_i(4, git_utf8_char_length("\x24\xf5\xfd\xc2", 4)); +} From 78abfb172b170aca95527c32d8cea17994106c3e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 5 Apr 2021 10:59:02 +0100 Subject: [PATCH 0268/1616] docs: document core.longpaths support --- docs/win32-longpaths.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 docs/win32-longpaths.md diff --git a/docs/win32-longpaths.md b/docs/win32-longpaths.md new file mode 100644 index 00000000000..a18152fc90d --- /dev/null +++ b/docs/win32-longpaths.md @@ -0,0 +1,36 @@ +core.longpaths support +====================== + +Historically, Windows has limited absolute path lengths to `MAX_PATH` +(260) characters. + +Unfortunately, 260 characters is a punishing small maximum. This is +especially true for developers where dependencies may have dependencies +in a folder, each dependency themselves having dependencies in a +sub-folder, ad (seemingly) infinitum. + +So although the Windows APIs _by default_ honor this 260 character +maximum, you can get around this by using separate APIs. Git honors a +`core.longpaths` configuration option that allows some paths on Windows +to exceed these 260 character limits. + +And because they've gone and done it, that means that libgit2 has to +honor this value, too. + +Since `core.longpaths` is a _configuration option_ that means that we +need to be able to resolve a configuration - including in _the repository +itself_ in order to know whether long paths should be supported. + +Therefore, in libgit2, `core.longpaths` affects paths in working +directories _only_. Paths to the repository, and to items inside the +`.git` folder, must be no longer than 260 characters. + +This definition is required to avoid a paradoxical setting: if you +had a repository in a folder that was 280 characters long, how would +you know whether `core.longpaths` support should be enabled? Even if +`core.longpaths` was set to true in a system configuration file, the +repository itself may set `core.longpaths` to false in _its_ configuration +file, which you could only read if `core.longpaths` were set to true. + +Thus, `core.longpaths` must _only_ apply to working directory items, +and cannot apply to the `.git` folder or its contents. From 88323cd0723cf2f6cb6daa1d2fc275a3fdde5efc Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 20 Mar 2021 09:52:17 +0000 Subject: [PATCH 0269/1616] path: git_path_isvalid -> git_path_validate If we want to validate more and different types of paths, the name `git_path_validate` makes that easier and more expressive. We can add, for example, `git_path_validate_foo` while the current name makes that less ergonomic. --- src/checkout.c | 4 +- src/index.c | 2 +- src/path.c | 2 +- src/path.h | 11 +- src/refdb_fs.c | 4 +- src/submodule.c | 2 +- src/tree.c | 2 +- tests/path/core.c | 398 ++++++++++++++++++++++---------------------- tests/path/dotgit.c | 8 +- 9 files changed, 219 insertions(+), 214 deletions(-) diff --git a/src/checkout.c b/src/checkout.c index 65487993b74..ba75839f747 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -1278,14 +1278,14 @@ static int checkout_verify_paths( unsigned int flags = GIT_PATH_REJECT_WORKDIR_DEFAULTS; if (action & CHECKOUT_ACTION__REMOVE) { - if (!git_path_isvalid(repo, delta->old_file.path, delta->old_file.mode, flags)) { + if (!git_path_validate(repo, delta->old_file.path, delta->old_file.mode, flags)) { git_error_set(GIT_ERROR_CHECKOUT, "cannot remove invalid path '%s'", delta->old_file.path); return -1; } } if (action & ~CHECKOUT_ACTION__REMOVE) { - if (!git_path_isvalid(repo, delta->new_file.path, delta->new_file.mode, flags)) { + if (!git_path_validate(repo, delta->new_file.path, delta->new_file.mode, flags)) { git_error_set(GIT_ERROR_CHECKOUT, "cannot checkout to invalid path '%s'", delta->new_file.path); return -1; } diff --git a/src/index.c b/src/index.c index 3d46030f7a3..065cd490b90 100644 --- a/src/index.c +++ b/src/index.c @@ -944,7 +944,7 @@ static int index_entry_create( if (st) mode = st->st_mode; - if (!git_path_isvalid(repo, path, mode, path_valid_flags)) { + if (!git_path_validate(repo, path, mode, path_valid_flags)) { git_error_set(GIT_ERROR_INDEX, "invalid path: '%s'", path); return -1; } diff --git a/src/path.c b/src/path.c index 8ebb581581d..b4b15660b0e 100644 --- a/src/path.c +++ b/src/path.c @@ -1877,7 +1877,7 @@ GIT_INLINE(unsigned int) dotgit_flags( return flags; } -bool git_path_isvalid( +bool git_path_validate( git_repository *repo, const char *path, uint16_t mode, diff --git a/src/path.h b/src/path.h index bfef1b8a819..1ff15dff12a 100644 --- a/src/path.h +++ b/src/path.h @@ -626,15 +626,20 @@ extern int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or #define GIT_PATH_REJECT_INDEX_DEFAULTS \ GIT_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT -/* - * Determine whether a path is a valid git path or not - this must not contain +/** + * Validate a "bare" git path. This ensures that the given path is legal + * to place in the index or a tree. This should be checked by mechanisms + * like `git_index_add` and `git_treebuilder_insert` when taking user + * data, and by `git_checkout` before constructing on-disk paths. + * + * This will ensure that a git path does not contain any "unsafe" components, * a '.' or '..' component, or a component that is ".git" (in any case). * * `repo` is optional. If specified, it will be used to determine the short * path name to reject (if `GIT_PATH_REJECT_DOS_SHORTNAME` is specified), * in addition to the default of "git~1". */ -extern bool git_path_isvalid( +extern bool git_path_validate( git_repository *repo, const char *path, uint16_t mode, diff --git a/src/refdb_fs.c b/src/refdb_fs.c index a5a6b3c0ec0..551732f6e9c 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -789,7 +789,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char * GIT_ASSERT_ARG(backend); GIT_ASSERT_ARG(name); - if (!git_path_isvalid(backend->repo, name, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) { + if (!git_path_validate(backend->repo, name, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) { git_error_set(GIT_ERROR_INVALID, "invalid reference name '%s'", name); return GIT_EINVALIDSPEC; } @@ -1828,7 +1828,7 @@ static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char repo = backend->repo; - if (!git_path_isvalid(backend->repo, refname, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) { + if (!git_path_validate(backend->repo, refname, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) { git_error_set(GIT_ERROR_INVALID, "invalid reference name '%s'", refname); return GIT_EINVALIDSPEC; } diff --git a/src/submodule.c b/src/submodule.c index 50bde2c63e7..e54cd6a2975 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -418,7 +418,7 @@ int git_submodule_name_is_valid(git_repository *repo, const char *name, int flag git_buf_attach_notowned(&buf, name, strlen(name)); } - isvalid = git_path_isvalid(repo, buf.ptr, 0, flags); + isvalid = git_path_validate(repo, buf.ptr, 0, flags); git_buf_dispose(&buf); return isvalid; diff --git a/src/tree.c b/src/tree.c index 5abcc9d3b8a..76821e3a083 100644 --- a/src/tree.c +++ b/src/tree.c @@ -54,7 +54,7 @@ GIT_INLINE(git_filemode_t) normalize_filemode(git_filemode_t filemode) static int valid_entry_name(git_repository *repo, const char *filename) { return *filename != '\0' && - git_path_isvalid(repo, filename, 0, + git_path_validate(repo, filename, 0, GIT_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT | GIT_PATH_REJECT_SLASH); } diff --git a/tests/path/core.c b/tests/path/core.c index 48b518c8d4c..8294213ba92 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -44,266 +44,266 @@ void test_path_core__make_relative(void) test_make_relative("/path/to/foo.c", "/path/to/foo.c", "d:/path/to", GIT_ENOTFOUND); test_make_relative("d:/path/to/foo.c", "d:/path/to/foo.c", "/path/to", GIT_ENOTFOUND); - + test_make_relative("/path/to/foo.c", "/path/to/foo.c", "not-a-rooted-path", GIT_ENOTFOUND); test_make_relative("not-a-rooted-path", "not-a-rooted-path", "/path/to", GIT_ENOTFOUND); - + test_make_relative("/path", "/path", "pathtofoo", GIT_ENOTFOUND); test_make_relative("path", "path", "pathtofoo", GIT_ENOTFOUND); } void test_path_core__isvalid_standard(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/file.txt", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.file", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/file.txt", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/.file", 0, 0)); } void test_path_core__isvalid_empty_dir_component(void) { - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo//bar", 0, 0)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo//bar", 0, 0)); /* leading slash */ - cl_assert_equal_b(false, git_path_isvalid(NULL, "/", 0, 0)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo", 0, 0)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo/bar", 0, 0)); + cl_assert_equal_b(false, git_path_validate(NULL, "/", 0, 0)); + cl_assert_equal_b(false, git_path_validate(NULL, "/foo", 0, 0)); + cl_assert_equal_b(false, git_path_validate(NULL, "/foo/bar", 0, 0)); /* trailing slash */ - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/", 0, 0)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/", 0, 0)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/", 0, 0)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar/", 0, 0)); } void test_path_core__isvalid_dot_and_dotdot(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, ".", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0, 0)); - - cl_assert_equal_b(true, git_path_isvalid(NULL, "..", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/..", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0, 0)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, ".", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, "..", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/..", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(true, git_path_validate(NULL, ".", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "./foo", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "./foo", 0, 0)); + + cl_assert_equal_b(true, git_path_validate(NULL, "..", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "../foo", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/..", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "../foo", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, ".", 0, GIT_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/.", 0, GIT_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL)); + + cl_assert_equal_b(false, git_path_validate(NULL, "..", 0, GIT_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/..", 0, GIT_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL)); } void test_path_core__isvalid_dot_git(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".git/foo", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.GIT/bar", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.Git", 0, 0)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - - cl_assert_equal_b(true, git_path_isvalid(NULL, "!git", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/!git", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "!git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.tig", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig/bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git/foo", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git/bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.GIT/bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/.Git", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + + cl_assert_equal_b(true, git_path_validate(NULL, "!git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/!git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "!git/bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".tig", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.tig", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".tig/bar", 0, 0)); } void test_path_core__isvalid_backslash(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo\\file.txt", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\file.txt", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo\\file.txt", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar\\file.txt", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar\\", 0, 0)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\", 0, GIT_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar\\", 0, GIT_PATH_REJECT_BACKSLASH)); } void test_path_core__isvalid_trailing_dot(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo.", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo...", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar.", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo./bar", 0, 0)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo.", 0, GIT_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo...", 0, GIT_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar.", 0, GIT_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo./bar", 0, GIT_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo.", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo...", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar.", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo./bar", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, "foo.", 0, GIT_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo...", 0, GIT_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar.", 0, GIT_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo./bar", 0, GIT_PATH_REJECT_TRAILING_DOT)); } void test_path_core__isvalid_trailing_space(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo ", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo ", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar ", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, " ", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo /bar", 0, 0)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_isvalid(NULL, " ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo /bar", 0, GIT_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo ", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo ", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar ", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, " ", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo /bar", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_path_validate(NULL, " ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo /bar", 0, GIT_PATH_REJECT_TRAILING_SPACE)); } void test_path_core__isvalid_trailing_colon(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar:", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ":", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:/bar", 0, 0)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:", 0, GIT_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar:", 0, GIT_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ":", 0, GIT_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:/bar", 0, GIT_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo:", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar:", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ":", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo:/bar", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, "foo:", 0, GIT_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar:", 0, GIT_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_path_validate(NULL, ":", 0, GIT_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo:/bar", 0, GIT_PATH_REJECT_TRAILING_COLON)); } void test_path_core__isvalid_dotgit_ntfs(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".git ", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.. .", 0, 0)); - - cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1 ", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.. .", 0, 0)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git ", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git.", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git.. .", 0, 0)); + + cl_assert_equal_b(true, git_path_validate(NULL, "git~1", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "git~1 ", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "git~1.", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "git~1.. .", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + + cl_assert_equal_b(false, git_path_validate(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); } void test_path_core__isvalid_dos_paths(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, "aux", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf\\zippy", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:asdf\\foobar", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "con", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "prn", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "nul", 0, 0)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, "aux", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "con", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "prn", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "nul", 0, GIT_PATH_REJECT_DOS_PATHS)); - - cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "auxn", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "aux\\foo", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_path_validate(NULL, "aux", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "aux.", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "aux:", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "aux.asdf", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "aux.asdf\\zippy", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "aux:asdf\\foobar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "con", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "prn", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "nul", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, "aux", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "aux.", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "aux:", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "aux.asdf", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "aux.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "aux:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "con", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "prn", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "nul", 0, GIT_PATH_REJECT_DOS_PATHS)); + + cl_assert_equal_b(true, git_path_validate(NULL, "aux1", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "aux1", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_path_validate(NULL, "auxn", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_path_validate(NULL, "aux\\foo", 0, GIT_PATH_REJECT_DOS_PATHS)); } void test_path_core__isvalid_dos_paths_withnum(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, "com1", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf\\zippy", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:asdf\\foobar", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt1", 0, 0)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, "com1", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "com1/foo", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "lpt1", 0, GIT_PATH_REJECT_DOS_PATHS)); - - cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "comn", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt0", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt10", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "lptn", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_path_validate(NULL, "com1", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "com1.", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "com1:", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "com1.asdf", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "com1.asdf\\zippy", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "com1:asdf\\foobar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "com1\\foo", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "lpt1", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, "com1", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "com1.", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "com1:", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "com1.asdf", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "com1.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "com1:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "com1/foo", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_path_validate(NULL, "lpt1", 0, GIT_PATH_REJECT_DOS_PATHS)); + + cl_assert_equal_b(true, git_path_validate(NULL, "com0", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "com0", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_path_validate(NULL, "com10", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "com10", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_path_validate(NULL, "comn", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_path_validate(NULL, "com1\\foo", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_path_validate(NULL, "lpt0", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_path_validate(NULL, "lpt10", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_path_validate(NULL, "lptn", 0, GIT_PATH_REJECT_DOS_PATHS)); } void test_path_core__isvalid_nt_chars(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\001foo", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\037bar", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "asdffoo", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf:foo", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\"bar", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf|foo", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf?bar", 0, 0)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf*bar", 0, 0)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\001foo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\037bar", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "asdffoo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf:foo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\"bar", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf|foo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf?bar", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf*bar", 0, GIT_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(true, git_path_validate(NULL, "asdf\001foo", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "asdf\037bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "asdffoo", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "asdf:foo", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "asdf\"bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "asdf|foo", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "asdf?bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "asdf*bar", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, "asdf\001foo", 0, GIT_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_path_validate(NULL, "asdf\037bar", 0, GIT_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_path_validate(NULL, "asdffoo", 0, GIT_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_path_validate(NULL, "asdf:foo", 0, GIT_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_path_validate(NULL, "asdf\"bar", 0, GIT_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_path_validate(NULL, "asdf|foo", 0, GIT_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_path_validate(NULL, "asdf?bar", 0, GIT_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_path_validate(NULL, "asdf*bar", 0, GIT_PATH_REJECT_NT_CHARS)); } void test_path_core__isvalid_dotgit_with_hfs_ignorables(void) { - cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(true, git_path_isvalid(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + + cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + + cl_assert_equal_b(true, git_path_validate(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); } static void test_join_unrooted( diff --git a/tests/path/dotgit.c b/tests/path/dotgit.c index ceb7330d248..2f9fcae4fc8 100644 --- a/tests/path/dotgit.c +++ b/tests/path/dotgit.c @@ -113,8 +113,8 @@ void test_path_dotgit__dotgit_modules(void) void test_path_dotgit__dotgit_modules_symlink(void) { - cl_assert_equal_b(true, git_path_isvalid(NULL, ".gitmodules", 0, GIT_PATH_REJECT_DOT_GIT_HFS|GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_isvalid(NULL, ".gitmodules . .::$DATA", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gitmodules", 0, GIT_PATH_REJECT_DOT_GIT_HFS|GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules . .::$DATA", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); } From 3fa8ec52042db1764bc4c17de77e424a27918e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Sun, 18 Apr 2021 20:30:13 +0200 Subject: [PATCH 0270/1616] src: fix typos in header files --- src/runtime.h | 2 +- src/transports/httpclient.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime.h b/src/runtime.h index 2cbcafe529d..24ac58ee96c 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -42,7 +42,7 @@ int git_runtime_init_count(void); * such that there are no remaining `init` calls, then any * shutdown hooks that have been registered will be invoked. * - * The number of oustanding initializations will be returned. + * The number of outstanding initializations will be returned. * If this number is 0, then the runtime is shutdown. * * @return The number of outstanding initializations (after this one) or an error diff --git a/src/transports/httpclient.h b/src/transports/httpclient.h index 2a83bee3eb8..6d0ef9edbf4 100644 --- a/src/transports/httpclient.h +++ b/src/transports/httpclient.h @@ -90,7 +90,7 @@ extern int git_http_client_new( /* * Sends a request to the host specified by the request URL. If the - * method is POST, either the the content_length or the chunked flag must + * method is POST, either the content_length or the chunked flag must * be specified. The body should be provided in subsequent calls to * git_http_client_send_body. * From 95b7a6398fe499fb37e49a528292c9ab2e1e8fc9 Mon Sep 17 00:00:00 2001 From: David Turner Date: Wed, 14 Apr 2021 21:52:36 -0400 Subject: [PATCH 0271/1616] git_reference_create_matching: Treat all-zero OID as "must be absent" This is pretty useful in avoiding races: I want to create a ref only if it doesn't already exist. I can't check first because of TOCTOU -- by the time I finish the check, someone else might have already created the ref. And I can't take a lock because then I can't do the create, since the create expects to take the lock. The semantics are inspired by git update-ref, which allows an all-zero old value to mean that the ref must not exist. --- include/git2/refs.h | 3 +++ src/refdb_fs.c | 5 ++++- tests/refs/races.c | 13 +++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/git2/refs.h b/include/git2/refs.h index 8bc99e15e7d..7ebb209b291 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -97,6 +97,9 @@ GIT_EXTERN(int) git_reference_dwim(git_reference **out, git_repository *repo, co * of updating does not match the one passed through `current_value` * (i.e. if the ref has changed since the user read it). * + * If `current_value` is all zeros, this function will return GIT_EMODIFIED + * if the ref already exists. + * * @param out Pointer to the newly created reference * @param repo Repository where that reference will live * @param name The name of the reference diff --git a/src/refdb_fs.c b/src/refdb_fs.c index a5a6b3c0ec0..971dc021d2c 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -1145,8 +1145,11 @@ static int cmp_old_ref(int *cmp, git_refdb_backend *backend, const char *name, if (!old_id && !old_target) return 0; - if ((error = refdb_fs_backend__lookup(&old_ref, backend, name)) < 0) + if ((error = refdb_fs_backend__lookup(&old_ref, backend, name)) < 0) { + if (error == GIT_ENOTFOUND && old_id && git_oid_is_zero(old_id)) + return 0; goto out; + } /* If the types don't match, there's no way the values do */ if (old_id && old_ref->type != GIT_REFERENCE_DIRECT) { diff --git a/tests/refs/races.c b/tests/refs/races.c index 04a1bc17b3b..988072794d0 100644 --- a/tests/refs/races.c +++ b/tests/refs/races.c @@ -22,6 +22,19 @@ void test_refs_races__cleanup(void) cl_git_sandbox_cleanup(); } +void test_refs_races__create_matching_zero_old(void) +{ + git_reference *ref; + git_oid id, zero_id; + + git_oid_fromstr(&id, commit_id); + git_oid_fromstr(&zero_id, "0000000000000000000000000000000000000000"); + + cl_git_pass(git_reference_create_matching(&ref, g_repo, other_refname, &id, 1, &zero_id, NULL)); + + git_reference_free(ref); +} + void test_refs_races__create_matching(void) { git_reference *ref, *ref2, *ref3; From 51cb439006650fc429bd95690c89c7d18ecf7eb0 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 21 Apr 2021 15:34:50 +0200 Subject: [PATCH 0272/1616] Fix documentation formatting The return code description use '-' char as list of return value. But with the generation of the documentation the char '-' create an ambiguous return code value who seem an negative value. --- include/git2/odb.h | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/include/git2/odb.h b/include/git2/odb.h index c4bfa5290b0..ead67ca9c55 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -94,9 +94,8 @@ GIT_EXTERN(void) git_odb_free(git_odb *db); * @param out pointer where to store the read object * @param db database to search for the object in. * @param id identity of the object to read. - * @return - * - 0 if the object was read; - * - GIT_ENOTFOUND if the object is not in the database. + * @return 0 if the object was read, GIT_ENOTFOUND if the object is + * not in the database. */ GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id); @@ -122,10 +121,9 @@ GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *i * @param db database to search for the object in. * @param short_id a prefix of the id of the object to read. * @param len the length of the prefix - * @return - * - 0 if the object was read; - * - GIT_ENOTFOUND if the object is not in the database. - * - GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix) + * @return 0 if the object was read, GIT_ENOTFOUND if the object is not in the + * database. GIT_EAMBIGUOUS if the prefix is ambiguous + * (several objects match the prefix) */ GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len); @@ -143,9 +141,8 @@ GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git * @param type_out pointer where to store the type * @param db database to search for the object in. * @param id identity of the object to read. - * @return - * - 0 if the object was read; - * - GIT_ENOTFOUND if the object is not in the database. + * @return 0 if the object was read, GIT_ENOTFOUND if the object is not + * in the database. */ GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_object_t *type_out, git_odb *db, const git_oid *id); @@ -154,9 +151,7 @@ GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_object_t *type_out, git * * @param db database to be searched for the given object. * @param id the object to search for. - * @return - * - 1, if the object was found - * - 0, otherwise + * @return 1 if the object was found, 0 otherwise */ GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id); From 58697f6a59579cd7bcf8238785b75907203f9474 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 21 Apr 2021 15:44:39 +0200 Subject: [PATCH 0273/1616] Uniformise documentation return code separator --- include/git2/odb.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/git2/odb.h b/include/git2/odb.h index ead67ca9c55..62100d56af1 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -70,7 +70,7 @@ GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir); * * @param odb database to add the backend to * @param path path to the objects folder for the alternate - * @return 0 on success; error code otherwise + * @return 0 on success, error code otherwise */ GIT_EXTERN(int) git_odb_add_disk_alternate(git_odb *odb, const char *path); @@ -300,7 +300,7 @@ GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **out, git_odb *db, git_obje * @param stream the stream * @param buffer the data to write * @param len the buffer's length - * @return 0 if the write succeeded; error code otherwise + * @return 0 if the write succeeded, error code otherwise */ GIT_EXTERN(int) git_odb_stream_write(git_odb_stream *stream, const char *buffer, size_t len); @@ -315,7 +315,7 @@ GIT_EXTERN(int) git_odb_stream_write(git_odb_stream *stream, const char *buffer, * * @param out pointer to store the resulting object's id * @param stream the stream - * @return 0 on success; an error code otherwise + * @return 0 on success, an error code otherwise */ GIT_EXTERN(int) git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream); @@ -357,7 +357,7 @@ GIT_EXTERN(void) git_odb_stream_free(git_odb_stream *stream); * @param type pointer where to store the type of the object * @param db object database where the stream will read from * @param oid oid of the object the stream will read from - * @return 0 if the stream was created; error code otherwise + * @return 0 if the stream was created, error code otherwise */ GIT_EXTERN(int) git_odb_open_rstream( git_odb_stream **out, @@ -496,7 +496,7 @@ GIT_EXTERN(git_object_t) git_odb_object_type(git_odb_object *object); * @param odb database to add the backend to * @param backend pointer to a git_odb_backend instance * @param priority Value for ordering the backends queue - * @return 0 on success; error code otherwise + * @return 0 on success, error code otherwise */ GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority); @@ -517,7 +517,7 @@ GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int * @param odb database to add the backend to * @param backend pointer to a git_odb_backend instance * @param priority Value for ordering the backends queue - * @return 0 on success; error code otherwise + * @return 0 on success, error code otherwise */ GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority); @@ -535,7 +535,7 @@ GIT_EXTERN(size_t) git_odb_num_backends(git_odb *odb); * @param out output pointer to ODB backend at pos * @param odb object database * @param pos index into object database backend list - * @return 0 on success; GIT_ENOTFOUND if pos is invalid; other errors < 0 + * @return 0 on success, GIT_ENOTFOUND if pos is invalid, other errors < 0 */ GIT_EXTERN(int) git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos); From 330b24d76f7264645bf148c168d666cf19a1164f Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 21 Apr 2021 15:46:28 +0200 Subject: [PATCH 0274/1616] Fix typo --- include/git2/blob.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/blob.h b/include/git2/blob.h index ff473993ac4..3f673867504 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -245,7 +245,7 @@ GIT_EXTERN(int) git_blob_create_from_stream_commit( * Write an in-memory buffer to the ODB as a blob * * @param id return the id of the written blob - * @param repo repository where to blob will be written + * @param repo repository where the blob will be written * @param buffer data to be written into the blob * @param len length of the data * @return 0 or an error code From dc1ba018289aa40e1948a5fbb673652f86170677 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 20 Mar 2021 13:01:00 +0000 Subject: [PATCH 0275/1616] path: introduce ondisk and workdir path validation Introduce `git_path_validate_filesystem` which validates (absolute) on-disk paths and `git_path_validate_workdir` to perform validations on (absolute) working directory paths. These functions are useful as there may be system limitations on on-disk paths, particularly on Windows (for example, enforcing MAX_PATH). For working directory paths, these limitations may be per-repository, based on the `core.longpaths` configuration setting. --- src/config_cache.c | 1 + src/path.c | 40 ++++++++++++++++++++++++++ src/path.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++ src/repository.h | 3 ++ tests/path/core.c | 58 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 172 insertions(+) diff --git a/src/config_cache.c b/src/config_cache.c index 37617af387b..4bb91f52b9f 100644 --- a/src/config_cache.c +++ b/src/config_cache.c @@ -86,6 +86,7 @@ static struct map_data _configmaps[] = { {"core.protecthfs", NULL, 0, GIT_PROTECTHFS_DEFAULT }, {"core.protectntfs", NULL, 0, GIT_PROTECTNTFS_DEFAULT }, {"core.fsyncobjectfiles", NULL, 0, GIT_FSYNCOBJECTFILES_DEFAULT }, + {"core.longpaths", NULL, 0, GIT_LONGPATHS_DEFAULT }, }; int git_config__configmap_lookup(int *out, git_config *config, git_configmap_item item) diff --git a/src/path.c b/src/path.c index b4b15660b0e..a4c289e167a 100644 --- a/src/path.c +++ b/src/path.c @@ -1904,6 +1904,46 @@ bool git_path_validate( return verify_component(repo, start, (c - start), mode, flags); } +#ifdef GIT_WIN32 +GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) +{ + int longpaths = 0; + + if (repo && + git_repository__configmap_lookup(&longpaths, repo, GIT_CONFIGMAP_LONGPATHS) < 0) + longpaths = 0; + + return (longpaths == 0); +} + +#else +# define should_validate_longpaths(repo) (GIT_UNUSED(repo), false) +#endif + +int git_path_validate_workdir(git_repository *repo, const char *path) +{ + if (should_validate_longpaths(repo)) + return git_path_validate_ondisk(path, strlen(path)); + + return 0; +} + +int git_path_validate_workdir_with_len( + git_repository *repo, + const char *path, + size_t path_len) +{ + if (should_validate_longpaths(repo)) + return git_path_validate_ondisk(path, path_len); + + return 0; +} + +int git_path_validate_workdir_buf(git_repository *repo, git_buf *path) +{ + return git_path_validate_workdir_with_len(repo, path->ptr, path->size); +} + int git_path_normalize_slashes(git_buf *out, const char *path) { int error; diff --git a/src/path.h b/src/path.h index 1ff15dff12a..0cf2dbcdf87 100644 --- a/src/path.h +++ b/src/path.h @@ -635,6 +635,10 @@ extern int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or * This will ensure that a git path does not contain any "unsafe" components, * a '.' or '..' component, or a component that is ".git" (in any case). * + * (Note: if you take or construct an on-disk path -- a workdir path, + * a path to a git repository or a reference name that could be a loose + * ref -- you should _also_ validate that with `git_path_validate_workdir`.) + * * `repo` is optional. If specified, it will be used to determine the short * path name to reject (if `GIT_PATH_REJECT_DOS_SHORTNAME` is specified), * in addition to the default of "git~1". @@ -645,6 +649,72 @@ extern bool git_path_validate( uint16_t mode, unsigned int flags); +/** + * Validate an on-disk path, taking into account that it will have a + * suffix appended (eg, `.lock`). + */ +GIT_INLINE(int) git_path_validate_filesystem_with_suffix( + const char *path, + size_t path_len, + size_t suffix_len) +{ +#ifdef GIT_WIN32 + size_t path_chars, total_chars; + + path_chars = git_utf8_char_length(path, path_len); + + if (GIT_ADD_SIZET_OVERFLOW(&total_chars, path_chars, suffix_len) || + total_chars > MAX_PATH) { + git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%s'", path); + return -1; + } + return 0; +#else + GIT_UNUSED(path); + GIT_UNUSED(path_len); + GIT_UNUSED(suffix_len); + return 0; +#endif +} + +/** + * Validate an path on the filesystem. This ensures that the given + * path is valid for the operating system/platform; for example, this + * will ensure that the given absolute path is smaller than MAX_PATH on + * Windows. + * + * For paths within the working directory, you should use ensure that + * `core.longpaths` is obeyed. Use `git_path_validate_workdir`. + */ +GIT_INLINE(int) git_path_validate_filesystem( + const char *path, + size_t path_len) +{ + return git_path_validate_filesystem_with_suffix(path, path_len, 0); +} + +/** + * Validate a path relative to the repo's worktree. This ensures that + * the given working tree path is valid for the operating system/platform. + * This will ensure that an absolute path is smaller than MAX_PATH on + * Windows, while keeping `core.longpaths` configuration settings in mind. + * + * This should be checked by mechamisms like `git_checkout` after + * contructing on-disk paths and before trying to write them. + * + * If the repository is null, no repository configuration is applied. + */ +extern int git_path_validate_workdir( + git_repository *repo, + const char *path); +extern int git_path_validate_workdir_with_len( + git_repository *repo, + const char *path, + size_t path_len); +extern int git_path_validate_workdir_buf( + git_repository *repo, + git_buf *buf); + /** * Convert any backslashes into slashes */ diff --git a/src/repository.h b/src/repository.h index c0a28242aa8..4df85005c16 100644 --- a/src/repository.h +++ b/src/repository.h @@ -51,6 +51,7 @@ typedef enum { GIT_CONFIGMAP_PROTECTHFS, /* core.protectHFS */ GIT_CONFIGMAP_PROTECTNTFS, /* core.protectNTFS */ GIT_CONFIGMAP_FSYNCOBJECTFILES, /* core.fsyncObjectFiles */ + GIT_CONFIGMAP_LONGPATHS, /* core.longpaths */ GIT_CONFIGMAP_CACHE_MAX } git_configmap_item; @@ -116,6 +117,8 @@ typedef enum { GIT_PROTECTNTFS_DEFAULT = GIT_CONFIGMAP_TRUE, /* core.fsyncObjectFiles */ GIT_FSYNCOBJECTFILES_DEFAULT = GIT_CONFIGMAP_FALSE, + /* core.longpaths */ + GIT_LONGPATHS_DEFAULT = GIT_CONFIGMAP_FALSE, } git_configmap_value; /* internal repository init flags */ diff --git a/tests/path/core.c b/tests/path/core.c index 8294213ba92..6723216464f 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -1,6 +1,11 @@ #include "clar_libgit2.h" #include "path.h" +void test_path_core__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + static void test_make_relative( const char *expected_path, const char *path, @@ -306,6 +311,59 @@ void test_path_core__isvalid_dotgit_with_hfs_ignorables(void) cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); } +void test_path_core__validate_workdir(void) +{ + cl_must_pass(git_path_validate_workdir(NULL, "/foo/bar")); + cl_must_pass(git_path_validate_workdir(NULL, "C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_workdir(NULL, "\\\\?\\UNC\\server\\C$\\folder")); + +#ifdef GIT_WIN32 + /* + * In the absense of a repo configuration, 259 character paths + * succeed. >= 260 character paths fail. + */ + cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); + cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\260.txt")); + cl_must_fail(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\longer_than_260.txt")); + + /* count characters, not bytes */ + cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_fail(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); +#else + cl_must_pass(git_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/ok.txt")); + cl_must_pass(git_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/260.txt")); + cl_must_pass(git_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); +#endif +} + +void test_path_core__validate_workdir_with_core_longpath(void) +{ +#ifdef GIT_WIN32 + git_repository *repo; + git_config *config; + + repo = cl_git_sandbox_init("empty_bare.git"); + + cl_git_pass(git_repository_open(&repo, "empty_bare.git")); + cl_git_pass(git_repository_config(&config, repo)); + + /* fail by default */ + cl_must_fail(git_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + + /* set core.longpaths explicitly on */ + cl_git_pass(git_config_set_bool(config, "core.longpaths", 1)); + cl_must_pass(git_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + + /* set core.longpaths explicitly off */ + cl_git_pass(git_config_set_bool(config, "core.longpaths", 0)); + cl_must_fail(git_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); +#endif +} + static void test_join_unrooted( const char *expected_result, ssize_t expected_rootlen, From dbc03de479eec4f96ce3273bf76f49daccbeb496 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 20 Mar 2021 14:28:25 +0000 Subject: [PATCH 0276/1616] apply: ensure we validate paths There was no test ensuring that we validate `.git` paths. We do, but let's add a test to make sure that we never regress this. --- src/path.c | 4 ++-- tests/apply/apply_helpers.h | 9 +++++++++ tests/apply/both.c | 11 +++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/path.c b/src/path.c index a4c289e167a..50a0b468cf8 100644 --- a/src/path.c +++ b/src/path.c @@ -1923,7 +1923,7 @@ GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) int git_path_validate_workdir(git_repository *repo, const char *path) { if (should_validate_longpaths(repo)) - return git_path_validate_ondisk(path, strlen(path)); + return git_path_validate_filesystem(path, strlen(path)); return 0; } @@ -1934,7 +1934,7 @@ int git_path_validate_workdir_with_len( size_t path_len) { if (should_validate_longpaths(repo)) - return git_path_validate_ondisk(path, path_len); + return git_path_validate_filesystem(path, path_len); return 0; } diff --git a/tests/apply/apply_helpers.h b/tests/apply/apply_helpers.h index 2d0019abf24..82094773e15 100644 --- a/tests/apply/apply_helpers.h +++ b/tests/apply/apply_helpers.h @@ -474,6 +474,15 @@ "-asparagus which had been laid by, boil it until these last articles are\n" \ "-sufficiently done, thicken with flour, butter and milk, and serve it up.\n" +#define DIFF_ADD_INVALID_FILENAME \ + "diff --git a/.git/hello_world.txt b/.git/hello_world.txt\n" \ + "new file mode 100644\n" \ + "index 0000000..f75ba05\n" \ + "--- /dev/null\n" \ + "+++ b/.git/hello_world.txt\n" \ + "@@ -0,0 +1 @@\n" \ + "+Hello, world.\n" + void validate_apply_workdir( git_repository *repo, struct merge_index_entry *workdir_entries, diff --git a/tests/apply/both.c b/tests/apply/both.c index 400df5e3861..10896327025 100644 --- a/tests/apply/both.c +++ b/tests/apply/both.c @@ -734,3 +734,14 @@ void test_apply_both__cant_remove_file_twice(void) git_diff_free(diff); } + +void test_apply_both__cant_add_invalid_filename(void) +{ + git_diff *diff; + + cl_git_pass(git_diff_from_buffer(&diff, DIFF_ADD_INVALID_FILENAME, + strlen(DIFF_ADD_INVALID_FILENAME))); + cl_git_fail(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); + + git_diff_free(diff); +} From 50e012163619a1808bb7e06e658f3d47a472f0d1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 20 Mar 2021 16:39:29 +0000 Subject: [PATCH 0277/1616] repo: introduce git_repository_workdir_path Add a simple accessor for workdir paths to get an absolute on-disk path given a repository and a relative path within it. This is useful to avoid copy-pasta `git_buf_joinpath` and to ensure that we validate working directory paths while honoring `core.longpaths` settings. --- src/repository.c | 16 ++++++++++++++++ src/repository.h | 8 ++++++++ tests/win32/longpath.c | 16 ++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/repository.c b/src/repository.c index de1a895828a..c243f1d7d9d 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2494,6 +2494,22 @@ const char *git_repository_workdir(const git_repository *repo) return repo->workdir; } +int git_repository_workdir_path( + git_buf *out, git_repository *repo, const char *path) +{ + int error; + + if (!repo->workdir) { + git_error_set(GIT_ERROR_REPOSITORY, "repository has no working directory"); + return GIT_EBAREREPO; + } + + if (!(error = git_buf_joinpath(out, repo->workdir, path))) + error = git_path_validate_workdir_buf(repo, out); + + return error; +} + const char *git_repository_commondir(const git_repository *repo) { GIT_ASSERT_ARG_WITH_RETVAL(repo, NULL); diff --git a/src/repository.h b/src/repository.h index 4df85005c16..f48dd9edfe0 100644 --- a/src/repository.h +++ b/src/repository.h @@ -241,4 +241,12 @@ bool git_repository__reserved_names( */ int git_repository_initialbranch(git_buf *out, git_repository *repo); +/* + * Given a relative `path`, this makes it absolute based on the + * repository's working directory. This will perform validation + * to ensure that the path is not longer than MAX_PATH on Windows + * (unless `core.longpaths` is set in the repo config). + */ +int git_repository_workdir_path(git_buf *out, git_repository *repo, const char *path); + #endif diff --git a/tests/win32/longpath.c b/tests/win32/longpath.c index 80ae08d8bbd..b2efba4ed33 100644 --- a/tests/win32/longpath.c +++ b/tests/win32/longpath.c @@ -4,6 +4,7 @@ #include "clone.h" #include "buffer.h" #include "futils.h" +#include "repository.h" static git_buf path = GIT_BUF_INIT; @@ -29,6 +30,7 @@ void test_win32_longpath__initialize(void) void test_win32_longpath__cleanup(void) { git_buf_dispose(&path); + cl_git_sandbox_cleanup(); } #ifdef GIT_WIN32 @@ -60,3 +62,17 @@ void test_win32_longpath__errmsg_on_checkout(void) assert_name_too_long(); #endif } + +void test_win32_longpath__workdir_path_validated(void) +{ +#ifdef GIT_WIN32 + git_repository *repo = cl_git_sandbox_init("testrepo"); + git_buf out = GIT_BUF_INIT; + + cl_git_pass(git_repository_workdir_path(&out, repo, "a.txt")); + + /* even if the repo path is a drive letter, this is too long */ + cl_git_fail(git_repository_workdir_path(&out, repo, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt")); + cl_assert(git__prefixcmp(git_error_last()->message, "path too long") == 0); +#endif +} From 6b878db5e8f851b76ef19ffe724018cbe62b88bb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 20 Mar 2021 16:44:08 +0000 Subject: [PATCH 0278/1616] checkout: use target path; don't assume workdir We're not necessarily checking out into the working directory. We could be checking out into an arbitrary location. Ensure that when we are writing conflict data that we do it in the checkout target. --- src/checkout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/checkout.c b/src/checkout.c index ba75839f747..ea1a3547438 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -2032,7 +2032,7 @@ static int checkout_merge_path( const char *our_label_raw, *their_label_raw, *suffix; int error = 0; - if ((error = git_buf_joinpath(out, git_repository_workdir(data->repo), result->path)) < 0) + if ((error = git_buf_joinpath(out, data->opts.target_directory, result->path)) < 0) return error; /* Most conflicts simply use the filename in the index */ From 99ddfd5c251fb814b33d38e07529114f323527f6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 20 Mar 2021 16:54:09 +0000 Subject: [PATCH 0279/1616] checkout: validate path length Ensure that we are validating working directory paths before we try to write to them. --- src/checkout.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/checkout.c b/src/checkout.c index ea1a3547438..cadc4c82d44 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -329,6 +329,9 @@ static int checkout_target_fullpath( if (path && git_buf_puts(&data->target_path, path) < 0) return -1; + if (git_path_validate_workdir_buf(data->repo, &data->target_path) < 0) + return -1; + *out = &data->target_path; return 0; @@ -2032,7 +2035,8 @@ static int checkout_merge_path( const char *our_label_raw, *their_label_raw, *suffix; int error = 0; - if ((error = git_buf_joinpath(out, data->opts.target_directory, result->path)) < 0) + if ((error = git_buf_joinpath(out, data->opts.target_directory, result->path)) < 0 || + (error = git_path_validate_workdir_buf(data->repo, out)) < 0) return error; /* Most conflicts simply use the filename in the index */ @@ -2331,6 +2335,22 @@ static void checkout_data_clear(checkout_data *data) git_attr_session__free(&data->attr_session); } +static int validate_target_directory(checkout_data *data) +{ + int error; + + if ((error = git_path_validate_workdir(data->repo, data->opts.target_directory)) < 0) + return error; + + if (git_path_isdir(data->opts.target_directory)) + return 0; + + error = checkout_mkdir(data, data->opts.target_directory, NULL, + GIT_DIR_MODE, GIT_MKDIR_VERIFY_DIR); + + return error; +} + static int checkout_data_init( checkout_data *data, git_iterator *target, @@ -2363,10 +2383,7 @@ static int checkout_data_init( if (!data->opts.target_directory) data->opts.target_directory = git_repository_workdir(repo); - else if (!git_path_isdir(data->opts.target_directory) && - (error = checkout_mkdir(data, - data->opts.target_directory, NULL, - GIT_DIR_MODE, GIT_MKDIR_VERIFY_DIR)) < 0) + else if ((error = validate_target_directory(data)) < 0) goto cleanup; if ((error = git_repository_index(&data->index, data->repo)) < 0) From 578aeba97502df26a47255618baa27976bdd0d7f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 20 Mar 2021 17:00:33 +0000 Subject: [PATCH 0280/1616] use git_repository_workdir_path to generate paths Use `git_repository_workdir_path` to generate workdir paths since it will validate the length. --- src/blob.c | 6 +----- src/index.c | 4 ++-- src/mailmap.c | 4 ++++ src/reader.c | 3 +-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/blob.c b/src/blob.c index ef4ad2e7ec0..ddc2494c87e 100644 --- a/src/blob.c +++ b/src/blob.c @@ -198,11 +198,7 @@ int git_blob__create_from_paths( GIT_ASSERT_ARG(hint_path || !try_load_filters); if (!content_path) { - if (git_repository__ensure_not_bare(repo, "create blob from file") < 0) - return GIT_EBAREREPO; - - if (git_buf_joinpath( - &path, git_repository_workdir(repo), hint_path) < 0) + if (git_repository_workdir_path(&path, repo, hint_path) < 0) return -1; content_path = path.ptr; diff --git a/src/index.c b/src/index.c index 065cd490b90..5c330517008 100644 --- a/src/index.c +++ b/src/index.c @@ -988,7 +988,7 @@ static int index_entry_init( if (git_repository__ensure_not_bare(repo, "create blob from file") < 0) return GIT_EBAREREPO; - if (git_buf_joinpath(&path, git_repository_workdir(repo), rel_path) < 0) + if (git_repository_workdir_path(&path, repo, rel_path) < 0) return -1; error = git_path_lstat(path.ptr, &st); @@ -1532,7 +1532,7 @@ static int add_repo_as_submodule(git_index_entry **out, git_index *index, const struct stat st; int error; - if ((error = git_buf_joinpath(&abspath, git_repository_workdir(repo), path)) < 0) + if ((error = git_repository_workdir_path(&abspath, repo, path)) < 0) return error; if ((error = p_stat(abspath.ptr, &st)) < 0) { diff --git a/src/mailmap.c b/src/mailmap.c index 347b4339142..b69d55e2ee2 100644 --- a/src/mailmap.c +++ b/src/mailmap.c @@ -330,6 +330,10 @@ static int mailmap_add_file_ondisk( if (error < 0) goto cleanup; + error = git_path_validate_workdir_buf(repo, &fullpath); + if (error < 0) + goto cleanup; + error = git_futils_readbuffer(&content, fullpath.ptr); if (error < 0) goto cleanup; diff --git a/src/reader.c b/src/reader.c index 9672473e852..48928940dbc 100644 --- a/src/reader.c +++ b/src/reader.c @@ -98,8 +98,7 @@ static int workdir_reader_read( git_oid id; int error; - if ((error = git_buf_joinpath(&path, - git_repository_workdir(reader->repo), filename)) < 0) + if ((error = git_repository_workdir_path(&path, reader->repo, filename)) < 0) goto done; if ((error = p_lstat(path.ptr, &st)) < 0) { From 91156a0f2ebfd5bc674d5825c45bce0efb225754 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 4 Apr 2021 10:44:29 +0100 Subject: [PATCH 0281/1616] diff: use git_repository_workdir_path The new git_repository_workdir_path function does error checking on working directory inputs on Windows; use it to construct paths within working directories. --- src/diff_file.c | 3 +-- src/diff_generate.c | 3 +-- src/diff_tform.c | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/diff_file.c b/src/diff_file.c index 015e0706b4c..2116f00211c 100644 --- a/src/diff_file.c +++ b/src/diff_file.c @@ -394,8 +394,7 @@ static int diff_file_content_load_workdir( if (fc->file->mode == GIT_FILEMODE_TREE) return 0; - if (git_buf_joinpath( - &path, git_repository_workdir(fc->repo), fc->file->path) < 0) + if (git_repository_workdir_path(&path, fc->repo, fc->file->path) < 0) return -1; if (S_ISLNK(fc->file->mode)) diff --git a/src/diff_generate.c b/src/diff_generate.c index f05ae37133b..aba9e52ba7f 100644 --- a/src/diff_generate.c +++ b/src/diff_generate.c @@ -596,8 +596,7 @@ int git_diff__oid_for_entry( memset(out, 0, sizeof(*out)); - if (git_buf_joinpath(&full_path, - git_repository_workdir(diff->base.repo), entry.path) < 0) + if (git_repository_workdir_path(&full_path, diff->base.repo, entry.path) < 0) return -1; if (!mode) { diff --git a/src/diff_tform.c b/src/diff_tform.c index 03fc2b0a647..409142081e8 100644 --- a/src/diff_tform.c +++ b/src/diff_tform.c @@ -476,8 +476,8 @@ static int similarity_sig( git_diff_file *file = info->file; if (info->src == GIT_ITERATOR_WORKDIR) { - if ((error = git_buf_joinpath( - &info->data, git_repository_workdir(info->repo), file->path)) < 0) + if ((error = git_repository_workdir_path( + &info->data, info->repo, file->path)) < 0) return error; /* if path is not a regular file, just skip this item */ From 4470e48a7dc5447952188db2bea7e6f141082343 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 4 Apr 2021 14:24:35 +0100 Subject: [PATCH 0282/1616] workdir: validate working directory entry path length --- src/filter.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/filter.c b/src/filter.c index ccabdcdc8b2..b82becdf31a 100644 --- a/src/filter.c +++ b/src/filter.c @@ -972,8 +972,10 @@ int git_filter_list_stream_file( if ((error = stream_list_init( &stream_start, &filter_streams, filters, target)) < 0 || - (error = git_path_join_unrooted(&abspath, path, base, NULL)) < 0) + (error = git_path_join_unrooted(&abspath, path, base, NULL)) < 0 || + (error = git_path_validate_workdir_buf(repo, &abspath)) < 0) goto done; + initialized = 1; if ((fd = git_futils_open_ro(abspath.ptr)) < 0) { From e52c2989fb6911ef74cccd87a57bffd884842d36 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 4 Apr 2021 19:46:08 +0100 Subject: [PATCH 0283/1616] repository: validate workdir path lengths --- src/repository.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/repository.c b/src/repository.c index c243f1d7d9d..3544fa9296c 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2702,9 +2702,9 @@ int git_repository_hashfile( * now that is not possible because git_filters_load() needs it. */ - error = git_path_join_unrooted( - &full_path, path, git_repository_workdir(repo), NULL); - if (error < 0) + if ((error = git_path_join_unrooted( + &full_path, path, git_repository_workdir(repo), NULL)) < 0 || + (error = git_path_validate_workdir_buf(repo, &full_path)) < 0) return error; if (!as_path) From 9fb755d561e149b81950c7cc7d8cb5131b24079b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 4 Apr 2021 19:59:57 +0100 Subject: [PATCH 0284/1616] attr: validate workdir paths for attribute files We should allow attribute files - inside working directories - to have names longer than MAX_PATH when core.longpaths is set. `git_attr_path__init` takes a repository to validate the path with. --- src/attr.c | 6 +++--- src/attr_file.c | 11 ++++++++--- src/attr_file.h | 7 +++++-- src/attrcache.c | 11 ++++++++--- src/attrcache.h | 1 + src/ignore.c | 4 ++-- tests/attr/lookup.c | 6 +++--- 7 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/attr.c b/src/attr.c index e85e2716295..f9cd9307483 100644 --- a/src/attr.c +++ b/src/attr.c @@ -67,7 +67,7 @@ int git_attr_get( if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; - if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), dir_flag) < 0) + if (git_attr_path__init(&path, repo, pathname, git_repository_workdir(repo), dir_flag) < 0) return -1; if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0) @@ -133,7 +133,7 @@ int git_attr_get_many_with_session( if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; - if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), dir_flag) < 0) + if (git_attr_path__init(&path, repo, pathname, git_repository_workdir(repo), dir_flag) < 0) return -1; if ((error = collect_attr_files(repo, attr_session, flags, pathname, &files)) < 0) @@ -217,7 +217,7 @@ int git_attr_foreach( if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; - if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), dir_flag) < 0) + if (git_attr_path__init(&path, repo, pathname, git_repository_workdir(repo), dir_flag) < 0) return -1; if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0 || diff --git a/src/attr_file.c b/src/attr_file.c index adc56d53ea8..d1b90c5bae5 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -403,7 +403,7 @@ int git_attr_file__load_standalone(git_attr_file **out, const char *path) if ((error = git_attr_file__new(&file, NULL, GIT_ATTR_FILE__FROM_FILE)) < 0 || (error = git_attr_file__parse_buffer(NULL, file, content.ptr, true)) < 0 || - (error = git_attr_cache__alloc_file_entry(&file->entry, NULL, path, &file->pool)) < 0) + (error = git_attr_cache__alloc_file_entry(&file->entry, NULL, NULL, path, &file->pool)) < 0) goto out; *out = file; @@ -503,14 +503,19 @@ git_attr_assignment *git_attr_rule__lookup_assignment( } int git_attr_path__init( - git_attr_path *info, const char *path, const char *base, git_dir_flag dir_flag) + git_attr_path *info, + git_repository *repo, + const char *path, + const char *base, + git_dir_flag dir_flag) { ssize_t root; /* build full path as best we can */ git_buf_init(&info->full, 0); - if (git_path_join_unrooted(&info->full, path, base, &root) < 0) + if (git_path_join_unrooted(&info->full, path, base, &root) < 0 || + git_path_validate_workdir_buf(repo, &info->full) < 0) return -1; info->path = info->full.ptr + root; diff --git a/src/attr_file.h b/src/attr_file.h index 2b6b1d6232a..617436b1468 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -207,8 +207,11 @@ extern git_attr_assignment *git_attr_rule__lookup_assignment( typedef enum { GIT_DIR_FLAG_TRUE = 1, GIT_DIR_FLAG_FALSE = 0, GIT_DIR_FLAG_UNKNOWN = -1 } git_dir_flag; extern int git_attr_path__init( - git_attr_path *info, const char *path, const char *base, git_dir_flag is_dir); - + git_attr_path *out, + git_repository *repo, + const char *path, + const char *base, + git_dir_flag is_dir); extern void git_attr_path__free(git_attr_path *info); extern int git_attr_assignment__parse( diff --git a/src/attrcache.c b/src/attrcache.c index 2485b05996c..32513da0172 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -38,6 +38,7 @@ GIT_INLINE(git_attr_file_entry *) attr_cache_lookup_entry( int git_attr_cache__alloc_file_entry( git_attr_file_entry **out, + git_repository *repo, const char *base, const char *path, git_pool *pool) @@ -65,6 +66,9 @@ int git_attr_cache__alloc_file_entry( } memcpy(&ce->fullpath[baselen], path, pathlen); + if (git_path_validate_workdir_with_len(repo, ce->fullpath, pathlen + baselen) < 0) + return -1; + ce->path = &ce->fullpath[baselen]; *out = ce; @@ -79,8 +83,8 @@ static int attr_cache_make_entry( git_attr_file_entry *entry = NULL; int error; - if ((error = git_attr_cache__alloc_file_entry(&entry, git_repository_workdir(repo), - path, &cache->pool)) < 0) + if ((error = git_attr_cache__alloc_file_entry(&entry, repo, + git_repository_workdir(repo), path, &cache->pool)) < 0) return error; if ((error = git_strmap_set(cache->files, entry->path, entry)) < 0) @@ -169,7 +173,8 @@ static int attr_cache_lookup( if (base != NULL && git_path_root(filename) < 0) { git_buf *p = attr_session ? &attr_session->tmp : &path; - if (git_buf_joinpath(p, base, filename) < 0) + if (git_buf_joinpath(p, base, filename) < 0 || + git_path_validate_workdir_buf(repo, p) < 0) return -1; filename = p->ptr; diff --git a/src/attrcache.h b/src/attrcache.h index 4b1d5ce312b..5e2fb29f4f5 100644 --- a/src/attrcache.h +++ b/src/attrcache.h @@ -44,6 +44,7 @@ extern bool git_attr_cache__is_cached( extern int git_attr_cache__alloc_file_entry( git_attr_file_entry **out, + git_repository *repo, const char *base, const char *path, git_pool *pool); diff --git a/src/ignore.c b/src/ignore.c index 27a650b1b74..085b0e981fc 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -453,7 +453,7 @@ int git_ignore__lookup( *out = GIT_IGNORE_NOTFOUND; if (git_attr_path__init( - &path, pathname, git_repository_workdir(ignores->repo), dir_flag) < 0) + &path, ignores->repo, pathname, git_repository_workdir(ignores->repo), dir_flag) < 0) return -1; /* first process builtins - success means path was found */ @@ -537,7 +537,7 @@ int git_ignore_path_is_ignored( else if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; - if ((error = git_attr_path__init(&path, pathname, workdir, dir_flag)) < 0 || + if ((error = git_attr_path__init(&path, repo, pathname, workdir, dir_flag)) < 0 || (error = git_ignore__for_path(repo, path.path, &ignores)) < 0) goto cleanup; diff --git a/tests/attr/lookup.c b/tests/attr/lookup.c index 6063468cb46..29a66b0013c 100644 --- a/tests/attr/lookup.c +++ b/tests/attr/lookup.c @@ -13,7 +13,7 @@ void test_attr_lookup__simple(void) cl_assert_equal_s(cl_fixture("attr/attr0"), file->entry->path); cl_assert(file->rules.length == 1); - cl_git_pass(git_attr_path__init(&path, "test", NULL, GIT_DIR_FLAG_UNKNOWN)); + cl_git_pass(git_attr_path__init(&path, NULL, "test", NULL, GIT_DIR_FLAG_UNKNOWN)); cl_assert_equal_s("test", path.path); cl_assert_equal_s("test", path.basename); cl_assert(!path.is_dir); @@ -36,7 +36,7 @@ static void run_test_cases(git_attr_file *file, struct attr_expected *cases, int int error; for (c = cases; c->path != NULL; c++) { - cl_git_pass(git_attr_path__init(&path, c->path, NULL, GIT_DIR_FLAG_UNKNOWN)); + cl_git_pass(git_attr_path__init(&path, NULL, c->path, NULL, GIT_DIR_FLAG_UNKNOWN)); if (force_dir) path.is_dir = 1; @@ -133,7 +133,7 @@ void test_attr_lookup__match_variants(void) cl_assert_equal_s(cl_fixture("attr/attr1"), file->entry->path); cl_assert(file->rules.length == 10); - cl_git_pass(git_attr_path__init(&path, "/testing/for/pat0", NULL, GIT_DIR_FLAG_UNKNOWN)); + cl_git_pass(git_attr_path__init(&path, NULL, "/testing/for/pat0", NULL, GIT_DIR_FLAG_UNKNOWN)); cl_assert_equal_s("pat0", path.basename); run_test_cases(file, cases, 0); From 289aaa414b4d31a0a2412c0395ff7053cef1ccff Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 4 Apr 2021 20:46:40 +0100 Subject: [PATCH 0285/1616] ignore: validate workdir paths for ignore files --- src/ignore.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ignore.c b/src/ignore.c index 085b0e981fc..700a6729c3a 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -309,12 +309,17 @@ int git_ignore__for_path( if ((error = git_path_dirname_r(&local, path)) < 0 || (error = git_path_resolve_relative(&local, 0)) < 0 || (error = git_path_to_dir(&local)) < 0 || - (error = git_buf_joinpath(&ignores->dir, workdir, local.ptr)) < 0) - {;} /* Nothing, we just want to stop on the first error */ + (error = git_buf_joinpath(&ignores->dir, workdir, local.ptr)) < 0 || + (error = git_path_validate_workdir_buf(repo, &ignores->dir)) < 0) { + /* Nothing, we just want to stop on the first error */ + } + git_buf_dispose(&local); } else { - error = git_buf_joinpath(&ignores->dir, path, ""); + if (!(error = git_buf_joinpath(&ignores->dir, path, ""))) + error = git_path_validate_filesystem(ignores->dir.ptr, ignores->dir.size); } + if (error < 0) goto cleanup; @@ -590,7 +595,7 @@ int git_ignore__check_pathspec_for_exact_ignores( git_attr_fnmatch *match; int ignored; git_buf path = GIT_BUF_INIT; - const char *wd, *filename; + const char *filename; git_index *idx; if ((error = git_repository__ensure_not_bare( @@ -598,8 +603,6 @@ int git_ignore__check_pathspec_for_exact_ignores( (error = git_repository_index(&idx, repo)) < 0) return error; - wd = git_repository_workdir(repo); - git_vector_foreach(vspec, i, match) { /* skip wildcard matches (if they are being used) */ if ((match->flags & GIT_ATTR_FNMATCH_HASWILD) != 0 && @@ -612,7 +615,7 @@ int git_ignore__check_pathspec_for_exact_ignores( if (git_index_get_bypath(idx, filename, 0) != NULL) continue; - if ((error = git_buf_joinpath(&path, wd, filename)) < 0) + if ((error = git_repository_workdir_path(&path, repo, filename)) < 0) break; /* is there a file on disk that matches this exactly? */ From b457fe27465d92796090c60173fe906fb530155f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 4 Apr 2021 22:18:55 +0100 Subject: [PATCH 0286/1616] iterator: validate workdir paths Supply the repository for the filesystem and workdir iterators - for workdir iterators, this is non-null and we can lookup the core.longpaths configuration option. (For regular filesystem iterators, this is NULL, so core.longpaths does not apply.) --- src/iterator.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/iterator.c b/src/iterator.c index 073459501ac..ce9f305ef28 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -1278,7 +1278,8 @@ static int filesystem_iterator_entry_hash( return git_repository_hashfile(&entry->id, iter->base.repo, entry->path, GIT_OBJECT_BLOB, NULL); - if (!(error = git_buf_joinpath(&fullpath, iter->root, entry->path))) + if (!(error = git_buf_joinpath(&fullpath, iter->root, entry->path)) && + !(error = git_path_validate_workdir_buf(iter->base.repo, &fullpath))) error = git_odb_hashfile(&entry->id, fullpath.ptr, GIT_OBJECT_BLOB); git_buf_dispose(&fullpath); @@ -1359,7 +1360,8 @@ static int filesystem_iterator_frame_push( else git_buf_puts(&root, iter->root); - if (git_buf_oom(&root)) { + if (git_buf_oom(&root) || + git_path_validate_workdir_buf(iter->base.repo, &root) < 0) { error = -1; goto done; } @@ -1389,7 +1391,8 @@ static int filesystem_iterator_frame_push( iterator_pathlist_search_t pathlist_match = ITERATOR_PATHLIST_FULL; bool dir_expected = false; - if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0) + if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0 || + (error = git_path_validate_workdir_with_len(iter->base.repo, path, path_len)) < 0) goto done; GIT_ASSERT(path_len > iter->root_len); @@ -1562,7 +1565,8 @@ static int filesystem_iterator_is_dir( } if ((error = git_buf_joinpath(&fullpath, iter->root, entry->path)) < 0 || - (error = p_stat(fullpath.ptr, &st)) < 0) + (error = git_path_validate_workdir_buf(iter->base.repo, &fullpath)) < 0 || + (error = p_stat(fullpath.ptr, &st)) < 0) goto done; *is_dir = S_ISDIR(st.st_mode); From f3bcadd2bb87337aeca961d37e153c54cbecfadd Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 5 Apr 2021 10:57:49 +0100 Subject: [PATCH 0287/1616] submodule: validate path lengths Validate that working directory paths honor `core.longpaths` where appropriate. Paths to the submodule gitdirs must always honor the operating system length restrictions; `core.longpaths` does not affect gitdir paths. --- src/submodule.c | 54 ++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/submodule.c b/src/submodule.c index e54cd6a2975..1d059a043da 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -380,8 +380,10 @@ int git_submodule__lookup_with_cache( /* If it's not configured, we still check if there's a repo at the path */ if (git_repository_workdir(repo)) { git_buf path = GIT_BUF_INIT; - if (git_buf_join3(&path, - '/', git_repository_workdir(repo), name, DOT_GIT) < 0) + if (git_buf_join3(&path, '/', + git_repository_workdir(repo), + name, DOT_GIT) < 0 || + git_path_validate_workdir_buf(NULL, &path) < 0) return -1; if (git_path_exists(path.ptr)) @@ -553,10 +555,10 @@ int git_submodule__map(git_repository *repo, git_strmap *map) int error = 0; git_index *idx = NULL; git_tree *head = NULL; - const char *wd = NULL; git_buf path = GIT_BUF_INIT; git_submodule *sm; git_config *mods = NULL; + bool has_workdir; GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(map); @@ -567,12 +569,14 @@ int git_submodule__map(git_repository *repo, git_strmap *map) if (git_repository_head_tree(&head, repo) < 0) git_error_clear(); - wd = git_repository_workdir(repo); - if (wd && (error = git_buf_joinpath(&path, wd, GIT_MODULES_FILE)) < 0) + has_workdir = git_repository_workdir(repo) != NULL; + + if (has_workdir && + (error = git_repository_workdir_path(&path, repo, GIT_MODULES_FILE)) < 0) goto cleanup; /* add submodule information from .gitmodules */ - if (wd) { + if (has_workdir) { lfc_data data = { 0 }; data.map = map; data.repo = repo; @@ -599,7 +603,7 @@ int git_submodule__map(git_repository *repo, git_strmap *map) goto cleanup; } /* shallow scan submodules in work tree as needed */ - if (wd) { + if (has_workdir) { git_strmap_foreach_value(map, sm, { submodule_load_from_wd_lite(sm); }); @@ -683,7 +687,7 @@ static int submodule_repo_init( git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT; git_repository *subrepo = NULL; - error = git_buf_joinpath(&workdir, git_repository_workdir(parent_repo), path); + error = git_repository_workdir_path(&workdir, parent_repo, path); if (error < 0) goto cleanup; @@ -790,7 +794,7 @@ int git_submodule_add_setup( /* init submodule repository and add origin remote as needed */ - error = git_buf_joinpath(&name, git_repository_workdir(repo), path); + error = git_repository_workdir_path(&name, repo, path); if (error < 0) goto cleanup; @@ -896,10 +900,9 @@ int git_submodule_clone(git_repository **out, git_submodule *submodule, const gi opts.remote_cb = clone_return_origin; opts.remote_cb_payload = submodule; - git_buf_puts(&rel_path, git_repository_workdir(git_submodule_owner(submodule))); - git_buf_joinpath(&rel_path, git_buf_cstr(&rel_path), git_submodule_path(submodule)); - - GIT_ERROR_CHECK_ALLOC_BUF(&rel_path); + error = git_repository_workdir_path(&rel_path, git_submodule_owner(submodule), git_submodule_path(submodule)); + if (error < 0) + goto cleanup; error = git_clone__submodule(&clone, git_submodule_url(submodule), git_buf_cstr(&rel_path), &opts); if (error < 0) @@ -946,9 +949,8 @@ int git_submodule_add_to_index(git_submodule *sm, int write_index) sm->flags = sm->flags & ~GIT_SUBMODULE_STATUS__WD_OID_VALID; if ((error = git_repository_index__weakptr(&index, sm->repo)) < 0 || - (error = git_buf_joinpath( - &path, git_repository_workdir(sm->repo), sm->path)) < 0 || - (error = git_submodule_open(&sm_repo, sm)) < 0) + (error = git_repository_workdir_path(&path, sm->repo, sm->path)) < 0 || + (error = git_submodule_open(&sm_repo, sm)) < 0) goto cleanup; /* read stat information for submodule working directory */ @@ -1237,7 +1239,7 @@ static int submodule_repo_create( GIT_REPOSITORY_INIT_RELATIVE_GITLINK; /* Workdir: path to sub-repo working directory */ - error = git_buf_joinpath(&workdir, git_repository_workdir(parent_repo), path); + error = git_repository_workdir_path(&workdir, parent_repo, path); if (error < 0) goto cleanup; @@ -1534,8 +1536,7 @@ static int git_submodule__open( wd = git_repository_workdir(sm->repo); - if (git_buf_joinpath(&path, wd, sm->path) < 0 || - git_buf_joinpath(&path, path.ptr, DOT_GIT) < 0) + if (git_buf_join3(&path, '/', wd, sm->path, DOT_GIT) < 0) return -1; sm->flags = sm->flags & @@ -2080,7 +2081,7 @@ static int submodule_load_from_wd_lite(git_submodule *sm) { git_buf path = GIT_BUF_INIT; - if (git_buf_joinpath(&path, git_repository_workdir(sm->repo), sm->path) < 0) + if (git_repository_workdir_path(&path, sm->repo, sm->path) < 0) return -1; if (git_path_isdir(path.ptr)) @@ -2100,15 +2101,14 @@ static int submodule_load_from_wd_lite(git_submodule *sm) */ static int gitmodules_snapshot(git_config **snap, git_repository *repo) { - const char *workdir = git_repository_workdir(repo); git_config *mods = NULL; git_buf path = GIT_BUF_INIT; int error; - if (!workdir) + if (git_repository_workdir(repo) == NULL) return GIT_ENOTFOUND; - if ((error = git_buf_joinpath(&path, workdir, GIT_MODULES_FILE)) < 0) + if ((error = git_repository_workdir_path(&path, repo, GIT_MODULES_FILE)) < 0) return error; if ((error = git_config_open_ondisk(&mods, path.ptr)) < 0) @@ -2132,12 +2132,11 @@ static git_config_backend *open_gitmodules( git_repository *repo, int okay_to_create) { - const char *workdir = git_repository_workdir(repo); git_buf path = GIT_BUF_INIT; git_config_backend *mods = NULL; - if (workdir != NULL) { - if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) != 0) + if (git_repository_workdir(repo) != NULL) { + if (git_repository_workdir_path(&path, repo, GIT_MODULES_FILE) != 0) return NULL; if (okay_to_create || git_path_isfile(path.ptr)) { @@ -2250,8 +2249,9 @@ static int get_url_base(git_buf *url, git_repository *repo) if ((error = git_worktree_open_from_repository(&wt, repo)) < 0) goto out; error = git_buf_sets(url, wt->parent_path); - } else + } else { error = git_buf_sets(url, git_repository_workdir(repo)); + } out: git_remote_free(remote); From 717df1a4d201e713d8e16aae1d258d9cc27a86dc Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 15 Apr 2021 01:23:07 +0100 Subject: [PATCH 0288/1616] worktree: validate worktree paths Worktree paths need to fix within MAX_PATH always, regardless of `core.longpaths` setting. --- src/worktree.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/worktree.c b/src/worktree.c index 7d447e896d8..0bced6d4a65 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -135,6 +135,9 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char goto out; } + if ((error = git_path_validate_workdir(NULL, dir)) < 0) + goto out; + if ((wt = git__calloc(1, sizeof(*wt))) == NULL) { error = -1; goto out; @@ -264,14 +267,14 @@ int git_worktree_validate(const git_worktree *wt) wt->commondir_path); return GIT_ERROR; } - + if (!git_path_exists(wt->worktree_path)) { git_error_set(GIT_ERROR_WORKTREE, "worktree directory '%s' does not exist", wt->worktree_path); return GIT_ERROR; } - + return 0; } From 1016ad4f98f1db7f5912c36b7922375d4c387ca0 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 15 Apr 2021 01:31:12 +0100 Subject: [PATCH 0289/1616] path: don't join paths in git_path_find_dir Let `git_path_find_dir` simply take a `git_buf` that contains a directory or a file, instead of trying to both join a path AND then deal with prettifying it or its basename. This allows consumers to join paths themselves (and apply any necessary rules - like fitting within MAX_PATH). --- src/attr.c | 10 +++++++--- src/path.c | 12 +++++------- src/path.h | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/attr.c b/src/attr.c index f9cd9307483..cab5e8b9756 100644 --- a/src/attr.c +++ b/src/attr.c @@ -523,10 +523,14 @@ static int collect_attr_files( return error; /* Resolve path in a non-bare repo */ - if (workdir != NULL) - error = git_path_find_dir(&dir, path, workdir); - else + if (workdir != NULL) { + if (!(error = git_repository_workdir_path(&dir, repo, path))) + error = git_path_find_dir(&dir); + } + else { error = git_path_dirname_r(&dir, path); + } + if (error < 0) goto cleanup; diff --git a/src/path.c b/src/path.c index 50a0b468cf8..8928e49b832 100644 --- a/src/path.c +++ b/src/path.c @@ -754,15 +754,13 @@ bool git_path_contains_file(git_buf *base, const char *file) return _check_dir_contents(base, file, &git_path_isfile); } -int git_path_find_dir(git_buf *dir, const char *path, const char *base) +int git_path_find_dir(git_buf *dir) { - int error = git_path_join_unrooted(dir, path, base, NULL); + int error = 0; + char buf[GIT_PATH_MAX]; - if (!error) { - char buf[GIT_PATH_MAX]; - if (p_realpath(dir->ptr, buf) != NULL) - error = git_buf_sets(dir, buf); - } + if (p_realpath(dir->ptr, buf) != NULL) + error = git_buf_sets(dir, buf); /* call dirname if this is not a directory */ if (!error) /* && git_path_isdir(dir->ptr) == false) */ diff --git a/src/path.h b/src/path.h index 0cf2dbcdf87..dcf5652df05 100644 --- a/src/path.h +++ b/src/path.h @@ -283,7 +283,7 @@ extern int git_path_prettify_dir(git_buf *path_out, const char *path, const char * appends the trailing '/'. If the path does not exist, it is * treated like a regular filename. */ -extern int git_path_find_dir(git_buf *dir, const char *path, const char *base); +extern int git_path_find_dir(git_buf *dir); /** * Resolve relative references within a path. From e5851c62e2f467ebd49357a16bde5ed7d4f473c2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 24 Apr 2021 09:44:45 +0100 Subject: [PATCH 0290/1616] refs: ensure loose refs adhere to path validation On Windows, we need to enforce MAX_PATH for loose references and their reflogs. Ensure that any path - including the lock file - would fit within the 260 character maximum. We do not honor core.longpaths for loose reference files or reflogs. core.longpaths only applies to paths in the working directory. --- src/refdb_fs.c | 84 +++++++++++++++++++++++++++++----------------- tests/refs/basic.c | 40 ++++++++++++++++++++++ 2 files changed, 94 insertions(+), 30 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 551732f6e9c..ad8068ed6a3 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -68,6 +68,35 @@ typedef struct refdb_fs_backend { static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name); +GIT_INLINE(int) loose_path( + git_buf *out, + const char *base, + const char *refname) +{ + if (git_buf_joinpath(out, base, refname) < 0) + return -1; + + return git_path_validate_filesystem_with_suffix(out->ptr, out->size, + CONST_STRLEN(".lock")); +} + +GIT_INLINE(int) reflog_path( + git_buf *out, + git_repository *repo, + const char *refname) +{ + const char *base; + int error; + + base = (strcmp(refname, GIT_HEAD_FILE) == 0) ? repo->gitdir : + repo->commondir; + + if ((error = git_buf_joinpath(out, base, GIT_REFLOG_DIR)) < 0) + return error; + + return loose_path(out, out->ptr, refname); +} + static int packref_cmp(const void *a_, const void *b_) { const struct packref *a = a_, *b = b_; @@ -223,9 +252,8 @@ static int loose_readbuffer(git_buf *buf, const char *base, const char *path) { int error; - /* build full path to file */ - if ((error = git_buf_joinpath(buf, base, path)) < 0 || - (error = git_futils_readbuffer(buf, buf->ptr)) < 0) + if ((error = loose_path(buf, base, path)) < 0 || + (error = git_futils_readbuffer(buf, buf->ptr)) < 0) git_buf_dispose(buf); return error; @@ -336,7 +364,7 @@ static int refdb_fs_backend__exists( *exists = 0; - if ((error = git_buf_joinpath(&ref_path, backend->gitpath, ref_name)) < 0) + if ((error = loose_path(&ref_path, backend->gitpath, ref_name)) < 0) goto out; if (git_path_isfile(ref_path.ptr)) { @@ -805,8 +833,8 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char * if ((error = git_futils_rmdir_r(name, basedir, GIT_RMDIR_SKIP_NONEMPTY)) < 0) return error; - if (git_buf_joinpath(&ref_path, basedir, name) < 0) - return -1; + if ((error = loose_path(&ref_path, basedir, name)) < 0) + return error; filebuf_flags = GIT_FILEBUF_CREATE_LEADING_DIRS; if (backend->fsync) @@ -1329,6 +1357,9 @@ static int refdb_fs_backend__prune_refs( backend->commonpath, git_buf_cstr(&relative_path)); + if (!error) + error = git_path_validate_filesystem(base_path.ptr, base_path.size); + if (error < 0) goto cleanup; @@ -1371,19 +1402,19 @@ static int refdb_fs_backend__delete( static int loose_delete(refdb_fs_backend *backend, const char *ref_name) { - git_buf loose_path = GIT_BUF_INIT; + git_buf path = GIT_BUF_INIT; int error = 0; - if (git_buf_joinpath(&loose_path, backend->commonpath, ref_name) < 0) - return -1; + if ((error = loose_path(&path, backend->commonpath, ref_name)) < 0) + return error; - error = p_unlink(loose_path.ptr); + error = p_unlink(path.ptr); if (error < 0 && errno == ENOENT) error = GIT_ENOTFOUND; else if (error != 0) error = -1; - git_buf_dispose(&loose_path); + git_buf_dispose(&path); return error; } @@ -1677,13 +1708,6 @@ static int create_new_reflog_file(const char *filepath) return p_close(fd); } -GIT_INLINE(int) retrieve_reflog_path(git_buf *path, git_repository *repo, const char *name) -{ - if (strcmp(name, GIT_HEAD_FILE) == 0) - return git_buf_join3(path, '/', repo->gitdir, GIT_REFLOG_DIR, name); - return git_buf_join3(path, '/', repo->commondir, GIT_REFLOG_DIR, name); -} - static int refdb_reflog_fs__ensure_log(git_refdb_backend *_backend, const char *name) { refdb_fs_backend *backend; @@ -1696,7 +1720,7 @@ static int refdb_reflog_fs__ensure_log(git_refdb_backend *_backend, const char * backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); repo = backend->repo; - if ((error = retrieve_reflog_path(&path, repo, name)) < 0) + if ((error = reflog_path(&path, repo, name)) < 0) return error; error = create_new_reflog_file(git_buf_cstr(&path)); @@ -1710,7 +1734,7 @@ static int has_reflog(git_repository *repo, const char *name) int ret = 0; git_buf path = GIT_BUF_INIT; - if (retrieve_reflog_path(&path, repo, name) < 0) + if (reflog_path(&path, repo, name) < 0) goto cleanup; ret = git_path_isfile(git_buf_cstr(&path)); @@ -1751,7 +1775,7 @@ static int refdb_reflog_fs__read(git_reflog **out, git_refdb_backend *_backend, if (reflog_alloc(&log, name) < 0) return -1; - if (retrieve_reflog_path(&log_path, repo, name) < 0) + if (reflog_path(&log_path, repo, name) < 0) goto cleanup; error = git_futils_readbuffer(&log_file, git_buf_cstr(&log_path)); @@ -1833,7 +1857,7 @@ static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char return GIT_EINVALIDSPEC; } - if (retrieve_reflog_path(&log_path, repo, refname) < 0) + if (reflog_path(&log_path, repo, refname) < 0) return -1; if (!git_path_isfile(git_buf_cstr(&log_path))) { @@ -1934,7 +1958,7 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co if ((error = serialize_reflog_entry(&buf, &old_id, &new_id, who, message)) < 0) goto cleanup; - if ((error = retrieve_reflog_path(&path, repo, ref->name)) < 0) + if ((error = reflog_path(&path, repo, ref->name)) < 0) goto cleanup; if (((error = git_futils_mkpath2file(git_buf_cstr(&path), 0777)) < 0) && @@ -1997,11 +2021,11 @@ static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_ if (git_buf_joinpath(&temp_path, repo->gitdir, GIT_REFLOG_DIR) < 0) return -1; - if (git_buf_joinpath(&old_path, git_buf_cstr(&temp_path), old_name) < 0) - return -1; + if ((error = loose_path(&old_path, git_buf_cstr(&temp_path), old_name)) < 0) + return error; - if (git_buf_joinpath(&new_path, git_buf_cstr(&temp_path), git_buf_cstr(&normalized)) < 0) - return -1; + if ((error = loose_path(&new_path, git_buf_cstr(&temp_path), git_buf_cstr(&normalized))) < 0) + return error; if (!git_path_exists(git_buf_cstr(&old_path))) { error = GIT_ENOTFOUND; @@ -2015,8 +2039,8 @@ static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_ * - a/b -> a/b/c * - a/b/c/d -> a/b/c */ - if (git_buf_joinpath(&temp_path, git_buf_cstr(&temp_path), "temp_reflog") < 0) - return -1; + if ((error = loose_path(&temp_path, git_buf_cstr(&temp_path), "temp_reflog")) < 0) + return error; if ((fd = git_futils_mktmp(&temp_path, git_buf_cstr(&temp_path), GIT_REFLOG_FILE_MODE)) < 0) { error = -1; @@ -2065,7 +2089,7 @@ static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name GIT_ASSERT_ARG(_backend); GIT_ASSERT_ARG(name); - if ((error = retrieve_reflog_path(&path, backend->repo, name)) < 0) + if ((error = reflog_path(&path, backend->repo, name)) < 0) goto out; if (!git_path_exists(path.ptr)) diff --git a/tests/refs/basic.c b/tests/refs/basic.c index ed0c0bde6bc..d1ec2bbe646 100644 --- a/tests/refs/basic.c +++ b/tests/refs/basic.c @@ -42,3 +42,43 @@ void test_refs_basic__reference_realloc(void) git_reference_free(new_ref); git_reference_free(ref); } + +void test_refs_basic__longpaths(void) +{ +#ifdef GIT_WIN32 + const char *base; + size_t base_len, extra_len; + ssize_t remain_len, i; + git_buf refname = GIT_BUF_INIT; + git_reference *one = NULL, *two = NULL; + git_oid id; + + cl_git_pass(git_oid_fromstr(&id, "099fabac3a9ea935598528c27f866e34089c2eff")); + + base = git_repository_path(g_repo); + base_len = git_utf8_char_length(base, strlen(base)); + extra_len = CONST_STRLEN("logs/refs/heads/") + CONST_STRLEN(".lock"); + + remain_len = (ssize_t)MAX_PATH - (base_len + extra_len); + cl_assert(remain_len > 0); + + cl_git_pass(git_buf_puts(&refname, "refs/heads/")); + + for (i = 0; i < remain_len; i++) { + cl_git_pass(git_buf_putc(&refname, 'a')); + } + + /* + * The full path to the reflog lockfile is 260 characters, + * this is permitted. + */ + cl_git_pass(git_reference_create(&one, g_repo, refname.ptr, &id, 0, NULL)); + + /* Adding one more character gives us a path that is too long. */ + cl_git_pass(git_buf_putc(&refname, 'z')); + cl_git_fail(git_reference_create(&two, g_repo, refname.ptr, &id, 0, NULL)); + + git_reference_free(one); + git_reference_free(two); +#endif +} From 3589587d6dcd33d0d755886741d6ce22666cb000 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 24 Apr 2021 13:11:25 +0100 Subject: [PATCH 0291/1616] repo: factor the commondir detection --- src/repository.c | 69 ++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/src/repository.c b/src/repository.c index 3544fa9296c..87f5c1a6e41 100644 --- a/src/repository.c +++ b/src/repository.c @@ -186,6 +186,44 @@ void git_repository_free(git_repository *repo) git__free(repo); } +/* Check if we have a separate commondir (e.g. we have a worktree) */ +static int lookup_commondir(git_buf *out, git_buf *repository_path) +{ + git_buf common_link = GIT_BUF_INIT; + int error; + + /* + * If there's no commondir file, the repository path is the + * common path, but it needs a trailing slash. + */ + if (!git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) { + if ((error = git_buf_set(out, repository_path->ptr, repository_path->size)) == 0) + error = git_path_to_dir(out); + + goto done; + } + + if ((error = git_buf_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE)) < 0 || + (error = git_futils_readbuffer(&common_link, common_link.ptr)) < 0) + goto done; + + git_buf_rtrim(&common_link); + if (git_path_is_relative(common_link.ptr)) { + if ((error = git_buf_joinpath(out, repository_path->ptr, common_link.ptr)) < 0) + goto done; + } else { + git_buf_swap(out, &common_link); + } + + git_buf_dispose(&common_link); + + /* Make sure the commondir path always has a trailing slash */ + error = git_path_prettify_dir(out, out->ptr, NULL); + +done: + return error; +} + /* * Git repository open methods * @@ -197,38 +235,13 @@ static int is_valid_repository_path(bool *out, git_buf *repository_path, git_buf *out = false; - /* Check if we have a separate commondir (e.g. we have a - * worktree) */ - if (git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) { - git_buf common_link = GIT_BUF_INIT; - - if ((error = git_buf_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE)) < 0 || - (error = git_futils_readbuffer(&common_link, common_link.ptr)) < 0) - return error; - - git_buf_rtrim(&common_link); - if (git_path_is_relative(common_link.ptr)) { - if ((error = git_buf_joinpath(common_path, repository_path->ptr, common_link.ptr)) < 0) - return error; - } else { - git_buf_swap(common_path, &common_link); - } - - git_buf_dispose(&common_link); - } - else { - if ((error = git_buf_set(common_path, repository_path->ptr, repository_path->size)) < 0) - return error; - } - - /* Make sure the commondir path always has a trailing * slash */ - if (git_buf_rfind(common_path, '/') != (ssize_t)common_path->size - 1) - if ((error = git_buf_putc(common_path, '/')) < 0) - return error; + if ((error = lookup_commondir(common_path, repository_path)) < 0) + return error; /* Ensure HEAD file exists */ if (git_path_contains_file(repository_path, GIT_HEAD_FILE) == false) return 0; + /* Check files in common dir */ if (git_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false) return 0; From c15ed350bb95fa7b07a70c60212f55be169ad12e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 26 Apr 2021 12:23:25 +0100 Subject: [PATCH 0292/1616] repo: validate repository paths Ensure that a repository's path (at initialization or open time) is valid. On Windows systems, this means that the longest known path beneath the repository will fit within MAX_PATH: this is a lock file for a loose object within the repository itself. Other paths, like a very long loose reference, may fail to be opened after the repository is opened. These variable length paths will be checked when they are accessed themselves. This new functionality is done at open to prevent needlessly checking every file in the gitdir (eg, `MERGE_HEAD`) for its length when we could instead check once at repository open time. --- src/repository.c | 40 +++++++++++++++++++++++++++++++++------- tests/repo/init.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/repository.c b/src/repository.c index 87f5c1a6e41..8da6ccba00d 100644 --- a/src/repository.c +++ b/src/repository.c @@ -187,7 +187,7 @@ void git_repository_free(git_repository *repo) } /* Check if we have a separate commondir (e.g. we have a worktree) */ -static int lookup_commondir(git_buf *out, git_buf *repository_path) +static int lookup_commondir(bool *separate, git_buf *commondir, git_buf *repository_path) { git_buf common_link = GIT_BUF_INIT; int error; @@ -197,33 +197,52 @@ static int lookup_commondir(git_buf *out, git_buf *repository_path) * common path, but it needs a trailing slash. */ if (!git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) { - if ((error = git_buf_set(out, repository_path->ptr, repository_path->size)) == 0) - error = git_path_to_dir(out); + if ((error = git_buf_set(commondir, repository_path->ptr, repository_path->size)) == 0) + error = git_path_to_dir(commondir); + *separate = false; goto done; } + *separate = true; + if ((error = git_buf_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE)) < 0 || (error = git_futils_readbuffer(&common_link, common_link.ptr)) < 0) goto done; git_buf_rtrim(&common_link); if (git_path_is_relative(common_link.ptr)) { - if ((error = git_buf_joinpath(out, repository_path->ptr, common_link.ptr)) < 0) + if ((error = git_buf_joinpath(commondir, repository_path->ptr, common_link.ptr)) < 0) goto done; } else { - git_buf_swap(out, &common_link); + git_buf_swap(commondir, &common_link); } git_buf_dispose(&common_link); /* Make sure the commondir path always has a trailing slash */ - error = git_path_prettify_dir(out, out->ptr, NULL); + error = git_path_prettify_dir(commondir, commondir->ptr, NULL); done: return error; } +GIT_INLINE(int) validate_repo_path(git_buf *path) +{ + /* + * The longest static path in a repository (or commondir) is the + * packed refs file. (Loose refs may be longer since they + * include the reference name, but will be validated when the + * path is constructed.) + */ + static size_t suffix_len = + CONST_STRLEN("objects/pack/pack-.pack.lock") + + GIT_OID_HEXSZ; + + return git_path_validate_filesystem_with_suffix( + path->ptr, path->size, suffix_len); +} + /* * Git repository open methods * @@ -231,11 +250,12 @@ static int lookup_commondir(git_buf *out, git_buf *repository_path) */ static int is_valid_repository_path(bool *out, git_buf *repository_path, git_buf *common_path) { + bool separate_commondir = false; int error; *out = false; - if ((error = lookup_commondir(common_path, repository_path)) < 0) + if ((error = lookup_commondir(&separate_commondir, common_path, repository_path)) < 0) return error; /* Ensure HEAD file exists */ @@ -248,6 +268,12 @@ static int is_valid_repository_path(bool *out, git_buf *repository_path, git_buf if (git_path_contains_dir(common_path, GIT_REFS_DIR) == false) return 0; + /* Ensure the repo (and commondir) are valid paths */ + if ((error = validate_repo_path(common_path)) < 0 || + (separate_commondir && + (error = validate_repo_path(repository_path)) < 0)) + return error; + *out = true; return 0; } diff --git a/tests/repo/init.c b/tests/repo/init.c index 01371ba786e..1aa326f7f01 100644 --- a/tests/repo/init.c +++ b/tests/repo/init.c @@ -704,3 +704,35 @@ void test_repo_init__defaultbranch_config_empty(void) git_reference_free(head); } + +void test_repo_init__longpath(void) +{ +#ifdef GIT_WIN32 + size_t padding = CONST_STRLEN("objects/pack/pack-.pack.lock") + GIT_OID_HEXSZ; + size_t max, i; + git_buf path = GIT_BUF_INIT; + git_repository *one = NULL, *two = NULL; + + /* + * Files within repositories need to fit within MAX_PATH; + * that means a repo path must be at most (MAX_PATH - 18). + */ + cl_git_pass(git_buf_puts(&path, clar_sandbox_path())); + cl_git_pass(git_buf_putc(&path, '/')); + + max = ((MAX_PATH) - path.size) - padding; + + for (i = 0; i < max - 1; i++) + cl_git_pass(git_buf_putc(&path, 'a')); + + cl_git_pass(git_repository_init(&one, path.ptr, 1)); + + /* Paths longer than this are rejected */ + cl_git_pass(git_buf_putc(&path, 'z')); + cl_git_fail(git_repository_init(&two, path.ptr, 1)); + + git_repository_free(one); + git_repository_free(two); + git_buf_dispose(&path); +#endif +} From ed94f54940fed8c7e9882c222b4791140bc209ba Mon Sep 17 00:00:00 2001 From: yuuri Date: Sat, 1 May 2021 20:26:49 +0800 Subject: [PATCH 0293/1616] diff:add option to ignore blank line changes --- .gitignore | 1 + include/git2/diff.h | 4 ++++ src/diff_xdiff.c | 3 +++ 3 files changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index 69d388f8ec4..1b482f038af 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /tags CMakeSettings.json .vs +.idea diff --git a/include/git2/diff.h b/include/git2/diff.h index e1055559594..c63d93dc8af 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -168,6 +168,10 @@ typedef enum { * can apply given diff information to binary files. */ GIT_DIFF_SHOW_BINARY = (1u << 30), + + /** Ignore blank lines */ + GIT_DIFF_IGNORE_BLANK_LINES = (1u << 31), + } git_diff_option_t; /** diff --git a/src/diff_xdiff.c b/src/diff_xdiff.c index c4668fa2fdc..7a32ea43f4b 100644 --- a/src/diff_xdiff.c +++ b/src/diff_xdiff.c @@ -259,5 +259,8 @@ void git_xdiff_init(git_xdiff_output *xo, const git_diff_options *opts) if (flags & GIT_DIFF_MINIMAL) xo->params.flags |= XDF_NEED_MINIMAL; + if (flags & GIT_DIFF_IGNORE_BLANK_LINES) + xo->params.flags |= XDF_IGNORE_BLANK_LINES; + xo->callback.outf = git_xdiff_cb; } From 7ad81a42a27312a8156093e5c6fa5a6abbd604fb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 4 May 2021 12:23:17 +0100 Subject: [PATCH 0294/1616] ci: use GitHub for storing mingw-w64 build dependency --- ci/setup-mingw.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/setup-mingw.sh b/ci/setup-mingw.sh index d500da05855..f5a882d2bdf 100755 --- a/ci/setup-mingw.sh +++ b/ci/setup-mingw.sh @@ -9,9 +9,9 @@ BUILD_TEMP=$(cygpath $BUILD_TEMP) case "$ARCH" in amd64) - MINGW_URI="https://bintray.com/libgit2/build-dependencies/download_file?file_path=mingw-w64-x86_64-8.1.0-release-win32-seh-rt_v6-rev0.zip";; + MINGW_URI="https://github.com/libgit2/ci-dependencies/releases/download/2021-05-04/mingw-x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0.zip";; x86) - MINGW_URI="https://bintray.com/libgit2/build-dependencies/download_file?file_path=mingw-w64-i686-8.1.0-release-win32-sjlj-rt_v6-rev0.zip";; + MINGW_URI="https://github.com/libgit2/ci-dependencies/releases/download/2021-05-04/mingw-i686-8.1.0-release-win32-sjlj-rt_v6-rev0.zip";; esac if [ -z "$MINGW_URI" ]; then From 5368be3053d311cb7c65d44ce6643b5de32694ec Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 5 May 2021 23:01:57 +0100 Subject: [PATCH 0295/1616] clar: support long paths on Windows --- tests/CMakeLists.txt | 1 + tests/clar/fs.h | 80 +++++++++++++++++++++++++++++++++----------- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6f8a18ec048..4d8732d23a6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,6 +9,7 @@ SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/resources/") SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}") ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\") ADD_DEFINITIONS(-DCLAR_TMPDIR=\"libgit2_tests\") +ADD_DEFINITIONS(-DCLAR_WIN32_LONGPATHS) ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64) # Ensure that we do not use deprecated functions internally diff --git a/tests/clar/fs.h b/tests/clar/fs.h index d88f249c7c7..44ede457258 100644 --- a/tests/clar/fs.h +++ b/tests/clar/fs.h @@ -8,6 +8,12 @@ #ifdef _WIN32 +#ifdef CLAR_WIN32_LONGPATHS +# define CLAR_MAX_PATH 4096 +#else +# define CLAR_MAX_PATH MAX_PATH +#endif + #define RM_RETRY_COUNT 5 #define RM_RETRY_DELAY 10 @@ -48,21 +54,48 @@ fs_rmdir_rmdir(WCHAR *_wpath) return 0; } +static void translate_path(WCHAR *path, size_t path_size) +{ + size_t path_len, i; + + if (wcsncmp(path, L"\\\\?\\", 4) == 0) + return; + + path_len = wcslen(path); + cl_assert(path_size > path_len + 4); + + for (i = path_len; i > 0; i--) { + WCHAR c = path[i - 1]; + + if (c == L'/') + path[i + 3] = L'\\'; + else + path[i + 3] = path[i - 1]; + } + + path[0] = L'\\'; + path[1] = L'\\'; + path[2] = L'?'; + path[3] = L'\\'; + path[path_len + 4] = L'\0'; +} + static void fs_rmdir_helper(WCHAR *_wsource) { - WCHAR buffer[MAX_PATH]; + WCHAR buffer[CLAR_MAX_PATH]; HANDLE find_handle; WIN32_FIND_DATAW find_data; size_t buffer_prefix_len; /* Set up the buffer and capture the length */ - wcscpy_s(buffer, MAX_PATH, _wsource); - wcscat_s(buffer, MAX_PATH, L"\\"); + wcscpy_s(buffer, CLAR_MAX_PATH, _wsource); + translate_path(buffer, CLAR_MAX_PATH); + wcscat_s(buffer, CLAR_MAX_PATH, L"\\"); buffer_prefix_len = wcslen(buffer); /* FindFirstFile needs a wildcard to match multiple items */ - wcscat_s(buffer, MAX_PATH, L"*"); + wcscat_s(buffer, CLAR_MAX_PATH, L"*"); find_handle = FindFirstFileW(buffer, &find_data); cl_assert(INVALID_HANDLE_VALUE != find_handle); @@ -72,7 +105,7 @@ fs_rmdir_helper(WCHAR *_wsource) if (fs__dotordotdot(find_data.cFileName)) continue; - wcscpy_s(buffer + buffer_prefix_len, MAX_PATH - buffer_prefix_len, find_data.cFileName); + wcscpy_s(buffer + buffer_prefix_len, CLAR_MAX_PATH - buffer_prefix_len, find_data.cFileName); if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes) fs_rmdir_helper(buffer); @@ -123,7 +156,7 @@ fs_rm_wait(WCHAR *_wpath) static void fs_rm(const char *_source) { - WCHAR wsource[MAX_PATH]; + WCHAR wsource[CLAR_MAX_PATH]; DWORD attrs; /* The input path is UTF-8. Convert it to wide characters @@ -133,7 +166,9 @@ fs_rm(const char *_source) _source, -1, /* Indicates NULL termination */ wsource, - MAX_PATH)); + CLAR_MAX_PATH)); + + translate_path(wsource, CLAR_MAX_PATH); /* Does the item exist? If not, we have no work to do */ attrs = GetFileAttributesW(wsource); @@ -158,21 +193,23 @@ fs_rm(const char *_source) static void fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest) { - WCHAR buf_source[MAX_PATH], buf_dest[MAX_PATH]; + WCHAR buf_source[CLAR_MAX_PATH], buf_dest[CLAR_MAX_PATH]; HANDLE find_handle; WIN32_FIND_DATAW find_data; size_t buf_source_prefix_len, buf_dest_prefix_len; - wcscpy_s(buf_source, MAX_PATH, _wsource); - wcscat_s(buf_source, MAX_PATH, L"\\"); + wcscpy_s(buf_source, CLAR_MAX_PATH, _wsource); + wcscat_s(buf_source, CLAR_MAX_PATH, L"\\"); + translate_path(buf_source, CLAR_MAX_PATH); buf_source_prefix_len = wcslen(buf_source); - wcscpy_s(buf_dest, MAX_PATH, _wdest); - wcscat_s(buf_dest, MAX_PATH, L"\\"); + wcscpy_s(buf_dest, CLAR_MAX_PATH, _wdest); + wcscat_s(buf_dest, CLAR_MAX_PATH, L"\\"); + translate_path(buf_dest, CLAR_MAX_PATH); buf_dest_prefix_len = wcslen(buf_dest); /* Get an enumerator for the items in the source. */ - wcscat_s(buf_source, MAX_PATH, L"*"); + wcscat_s(buf_source, CLAR_MAX_PATH, L"*"); find_handle = FindFirstFileW(buf_source, &find_data); cl_assert(INVALID_HANDLE_VALUE != find_handle); @@ -185,8 +222,8 @@ fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest) if (fs__dotordotdot(find_data.cFileName)) continue; - wcscpy_s(buf_source + buf_source_prefix_len, MAX_PATH - buf_source_prefix_len, find_data.cFileName); - wcscpy_s(buf_dest + buf_dest_prefix_len, MAX_PATH - buf_dest_prefix_len, find_data.cFileName); + wcscpy_s(buf_source + buf_source_prefix_len, CLAR_MAX_PATH - buf_source_prefix_len, find_data.cFileName); + wcscpy_s(buf_dest + buf_dest_prefix_len, CLAR_MAX_PATH - buf_dest_prefix_len, find_data.cFileName); if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes) fs_copydir_helper(buf_source, buf_dest); @@ -205,7 +242,7 @@ fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest) static void fs_copy(const char *_source, const char *_dest) { - WCHAR wsource[MAX_PATH], wdest[MAX_PATH]; + WCHAR wsource[CLAR_MAX_PATH], wdest[CLAR_MAX_PATH]; DWORD source_attrs, dest_attrs; HANDLE find_handle; WIN32_FIND_DATAW find_data; @@ -217,14 +254,17 @@ fs_copy(const char *_source, const char *_dest) _source, -1, wsource, - MAX_PATH)); + CLAR_MAX_PATH)); cl_assert(MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, _dest, -1, wdest, - MAX_PATH)); + CLAR_MAX_PATH)); + + translate_path(wsource, CLAR_MAX_PATH); + translate_path(wdest, CLAR_MAX_PATH); /* Check the source for existence */ source_attrs = GetFileAttributesW(wsource); @@ -238,8 +278,8 @@ fs_copy(const char *_source, const char *_dest) * Use FindFirstFile to parse the path */ find_handle = FindFirstFileW(wsource, &find_data); cl_assert(INVALID_HANDLE_VALUE != find_handle); - wcscat_s(wdest, MAX_PATH, L"\\"); - wcscat_s(wdest, MAX_PATH, find_data.cFileName); + wcscat_s(wdest, CLAR_MAX_PATH, L"\\"); + wcscat_s(wdest, CLAR_MAX_PATH, find_data.cFileName); FindClose(find_handle); /* Check the new target for existence */ From 69c65b9a45d5ef7e0960623f5cb3dfeaf66b09ad Mon Sep 17 00:00:00 2001 From: Ian Hattendorf Date: Tue, 31 Dec 2019 12:38:03 -0700 Subject: [PATCH 0296/1616] path: bump most Win32 unicode buffer sizes from MAX_PATH to GIT_PATH_MAX --- src/win32/path_w32.c | 20 ++++++++++---------- src/win32/w32_common.h | 27 ++++++++++++++++++--------- tests/path/win32.c | 10 ++++------ tests/win32/longpath.c | 22 +--------------------- 4 files changed, 33 insertions(+), 46 deletions(-) diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c index 23efd926903..581673b1bec 100644 --- a/src/win32/path_w32.c +++ b/src/win32/path_w32.c @@ -170,7 +170,7 @@ static int win32_path_cwd(wchar_t *out, size_t len) * '\'s, but we we add a 'UNC' specifier to the path, plus * a trailing directory separator, plus a NUL. */ - if (cwd_len > MAX_PATH - 4) { + if (cwd_len > GIT_WIN_PATH_MAX - 4) { errno = ENAMETOOLONG; return -1; } @@ -187,7 +187,7 @@ static int win32_path_cwd(wchar_t *out, size_t len) * working directory. (One character for the directory separator, * one for the null. */ - else if (cwd_len > MAX_PATH - 2) { + else if (cwd_len > GIT_WIN_PATH_MAX - 2) { errno = ENAMETOOLONG; return -1; } @@ -205,13 +205,13 @@ int git_win32_path_from_utf8(git_win32_path out, const char *src) /* See if this is an absolute path (beginning with a drive letter) */ if (git_path_is_absolute(src)) { - if (git__utf8_to_16(dest, MAX_PATH, src) < 0) + if (git__utf8_to_16(dest, GIT_WIN_PATH_MAX, src) < 0) goto on_error; } /* File-prefixed NT-style paths beginning with \\?\ */ else if (path__is_nt_namespace(src)) { /* Skip the NT prefix, the destination already contains it */ - if (git__utf8_to_16(dest, MAX_PATH, src + PATH__NT_NAMESPACE_LEN) < 0) + if (git__utf8_to_16(dest, GIT_WIN_PATH_MAX, src + PATH__NT_NAMESPACE_LEN) < 0) goto on_error; } /* UNC paths */ @@ -220,12 +220,12 @@ int git_win32_path_from_utf8(git_win32_path out, const char *src) dest += 4; /* Skip the leading "\\" */ - if (git__utf8_to_16(dest, MAX_PATH - 2, src + 2) < 0) + if (git__utf8_to_16(dest, GIT_WIN_PATH_MAX - 2, src + 2) < 0) goto on_error; } /* Absolute paths omitting the drive letter */ else if (path__startswith_slash(src)) { - if (path__cwd(dest, MAX_PATH) < 0) + if (path__cwd(dest, GIT_WIN_PATH_MAX) < 0) goto on_error; if (!git_path_is_absolute(dest)) { @@ -234,19 +234,19 @@ int git_win32_path_from_utf8(git_win32_path out, const char *src) } /* Skip the drive letter specification ("C:") */ - if (git__utf8_to_16(dest + 2, MAX_PATH - 2, src) < 0) + if (git__utf8_to_16(dest + 2, GIT_WIN_PATH_MAX - 2, src) < 0) goto on_error; } /* Relative paths */ else { int cwd_len; - if ((cwd_len = win32_path_cwd(dest, MAX_PATH)) < 0) + if ((cwd_len = win32_path_cwd(dest, GIT_WIN_PATH_MAX)) < 0) goto on_error; dest[cwd_len++] = L'\\'; - if (git__utf8_to_16(dest + cwd_len, MAX_PATH - cwd_len, src) < 0) + if (git__utf8_to_16(dest + cwd_len, GIT_WIN_PATH_MAX - cwd_len, src) < 0) goto on_error; } @@ -273,7 +273,7 @@ int git_win32_path_relative_from_utf8(git_win32_path out, const char *src) return git_win32_path_from_utf8(out, src); } - if ((len = git__utf8_to_16(dest, MAX_PATH, src)) < 0) + if ((len = git__utf8_to_16(dest, GIT_WIN_PATH_MAX, src)) < 0) return -1; for (p = dest; p < (dest + len); p++) { diff --git a/src/win32/w32_common.h b/src/win32/w32_common.h index f9e74b9476f..c20b3e85e7e 100644 --- a/src/win32/w32_common.h +++ b/src/win32/w32_common.h @@ -8,24 +8,33 @@ #ifndef INCLUDE_win32_w32_common_h__ #define INCLUDE_win32_w32_common_h__ +#include + +/* + * 4096 is the max allowed Git path. `MAX_PATH` (260) is the typical max allowed + * Windows path length, however win32 Unicode APIs generally allow up to 32,767 + * if prefixed with "\\?\" (i.e. converted to an NT-style name). + */ +#define GIT_WIN_PATH_MAX GIT_PATH_MAX + /* - * Provides a large enough buffer to support Windows paths: MAX_PATH is - * 260, corresponding to a maximum path length of 259 characters plus a - * NULL terminator. Prefixing with "\\?\" adds 4 characters, but if the - * original was a UNC path, then we turn "\\server\share" into + * Provides a large enough buffer to support Windows Git paths: + * GIT_WIN_PATH_MAX is 4096, corresponding to a maximum path length of 4095 + * characters plus a NULL terminator. Prefixing with "\\?\" adds 4 characters, + * but if the original was a UNC path, then we turn "\\server\share" into * "\\?\UNC\server\share". So we replace the first two characters with - * 8 characters, a net gain of 6, so the maximum length is MAX_PATH+6. + * 8 characters, a net gain of 6, so the maximum length is GIT_WIN_PATH_MAX+6. */ -#define GIT_WIN_PATH_UTF16 MAX_PATH+6 +#define GIT_WIN_PATH_UTF16 GIT_WIN_PATH_MAX+6 -/* Maximum size of a UTF-8 Win32 path. We remove the "\\?\" or "\\?\UNC\" - * prefixes for presentation, bringing us back to 259 (non-NULL) +/* Maximum size of a UTF-8 Win32 Git path. We remove the "\\?\" or "\\?\UNC\" + * prefixes for presentation, bringing us back to 4095 (non-NULL) * characters. UTF-8 does have 4-byte sequences, but they are encoded in * UTF-16 using surrogate pairs, which takes up the space of two characters. * Two characters in the range U+0800 -> U+FFFF take up more space in UTF-8 * (6 bytes) than one surrogate pair (4 bytes). */ -#define GIT_WIN_PATH_UTF8 (259 * 3 + 1) +#define GIT_WIN_PATH_UTF8 ((GIT_WIN_PATH_MAX - 1) * 3 + 1) /* * The length of a Windows "shortname", for 8.3 compatibility. diff --git a/tests/path/win32.c b/tests/path/win32.c index b416e9e6026..46b5c9f7015 100644 --- a/tests/path/win32.c +++ b/tests/path/win32.c @@ -78,13 +78,11 @@ void test_path_win32__honors_max_path(void) #ifdef GIT_WIN32 git_win32_path path_utf16; - test_utf8_to_utf16("C:\\This path is 259 chars and is the max length in windows\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij", - L"\\\\?\\C:\\This path is 259 chars and is the max length in windows\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij"); - test_utf8_to_utf16("\\\\unc\\paths may also be 259 characters including the server\\123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij", - L"\\\\?\\UNC\\unc\\paths may also be 259 characters including the server\\123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij"); + test_utf8_to_utf16("C:\\This path is 261 characters which is fine for our path handling functions which cope with paths longer than MAX_PATH\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghijk", + L"\\\\?\\C:\\This path is 261 characters which is fine for our path handling functions which cope with paths longer than MAX_PATH\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghijk"); + + cl_check_fail(git_win32_path_from_utf8(path_utf16, "C:\\This path is 4097 chars and exceeds our maximum path length on Windows which is limited to 4096 characters\\alas\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij01")); - cl_check_fail(git_win32_path_from_utf8(path_utf16, "C:\\This path is 260 chars and is sadly too long for windows\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij")); - cl_check_fail(git_win32_path_from_utf8(path_utf16, "\\\\unc\\paths are also bound by 260 character restrictions\\including the server name portion\\bcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij")); #endif } diff --git a/tests/win32/longpath.c b/tests/win32/longpath.c index b2efba4ed33..cba92ea6d37 100644 --- a/tests/win32/longpath.c +++ b/tests/win32/longpath.c @@ -33,33 +33,13 @@ void test_win32_longpath__cleanup(void) cl_git_sandbox_cleanup(); } -#ifdef GIT_WIN32 -void assert_name_too_long(void) -{ - const git_error *err; - size_t expected_len, actual_len; - char *expected_msg; - - err = git_error_last(); - actual_len = strlen(err->message); - - expected_msg = git_win32_get_error_message(ERROR_FILENAME_EXCED_RANGE); - expected_len = strlen(expected_msg); - - /* check the suffix */ - cl_assert_equal_s(expected_msg, err->message + (actual_len - expected_len)); - - git__free(expected_msg); -} -#endif - void test_win32_longpath__errmsg_on_checkout(void) { #ifdef GIT_WIN32 git_repository *repo; cl_git_fail(git_clone(&repo, cl_fixture("testrepo.git"), path.ptr, NULL)); - assert_name_too_long(); + cl_assert(git__prefixcmp(git_error_last()->message, "path too long") == 0); #endif } From f8921ab9578f08d67cf960cb7ff50aeec74826d9 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 5 May 2021 23:26:24 +0100 Subject: [PATCH 0297/1616] win32: ensure core.longpaths is honored for workdir paths --- tests/win32/longpath.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/win32/longpath.c b/tests/win32/longpath.c index cba92ea6d37..5fa2edbede3 100644 --- a/tests/win32/longpath.c +++ b/tests/win32/longpath.c @@ -54,5 +54,9 @@ void test_win32_longpath__workdir_path_validated(void) /* even if the repo path is a drive letter, this is too long */ cl_git_fail(git_repository_workdir_path(&out, repo, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt")); cl_assert(git__prefixcmp(git_error_last()->message, "path too long") == 0); + + cl_repo_set_bool(repo, "core.longpaths", true); + cl_git_pass(git_repository_workdir_path(&out, repo, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt")); + git_buf_dispose(&out); #endif } From 33667c14eb000b56edb343b90cbdafe7a1f88e56 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 5 May 2021 23:59:05 +0100 Subject: [PATCH 0298/1616] win32: add file and get status on a long path --- tests/win32/longpath.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/win32/longpath.c b/tests/win32/longpath.c index 5fa2edbede3..ebfcc4d0d93 100644 --- a/tests/win32/longpath.c +++ b/tests/win32/longpath.c @@ -8,6 +8,8 @@ static git_buf path = GIT_BUF_INIT; +#define LONG_FILENAME "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt" + void test_win32_longpath__initialize(void) { #ifdef GIT_WIN32 @@ -52,11 +54,39 @@ void test_win32_longpath__workdir_path_validated(void) cl_git_pass(git_repository_workdir_path(&out, repo, "a.txt")); /* even if the repo path is a drive letter, this is too long */ - cl_git_fail(git_repository_workdir_path(&out, repo, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt")); + cl_git_fail(git_repository_workdir_path(&out, repo, LONG_FILENAME)); cl_assert(git__prefixcmp(git_error_last()->message, "path too long") == 0); cl_repo_set_bool(repo, "core.longpaths", true); cl_git_pass(git_repository_workdir_path(&out, repo, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt")); + cl_git_pass(git_repository_workdir_path(&out, repo, LONG_FILENAME)); + git_buf_dispose(&out); +#endif +} + +void test_win32_longpath__status_and_add(void) +{ +#ifdef GIT_WIN32 + git_repository *repo = cl_git_sandbox_init("testrepo"); + git_index *index; + git_buf out = GIT_BUF_INIT; + unsigned int status_flags; + + cl_repo_set_bool(repo, "core.longpaths", true); + cl_git_pass(git_repository_workdir_path(&out, repo, LONG_FILENAME)); + + cl_git_rewritefile(out.ptr, "This is a long path.\r\n"); + + cl_git_pass(git_status_file(&status_flags, repo, LONG_FILENAME)); + cl_assert_equal_i(GIT_STATUS_WT_NEW, status_flags); + + cl_git_pass(git_repository_index(&index, repo)); + cl_git_pass(git_index_add_bypath(index, LONG_FILENAME)); + + cl_git_pass(git_status_file(&status_flags, repo, LONG_FILENAME)); + cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status_flags); + + git_index_free(index); git_buf_dispose(&out); #endif } From b31795ef2c7196fd81d7e8714fd95c1fed3b0a09 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 6 May 2021 01:46:19 +0100 Subject: [PATCH 0299/1616] test: clean up memory leaks --- src/transports/winhttp.c | 1 + tests/path/core.c | 3 +++ tests/refs/basic.c | 1 + 3 files changed, 5 insertions(+) diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index 3da625acad8..97ceab2d442 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -859,6 +859,7 @@ static int winhttp_connect( if (error < 0) winhttp_close_connection(t); + git_buf_dispose(&ua); git_buf_dispose(&ipv6); git__free(wide_host); git__free(wide_ua); diff --git a/tests/path/core.c b/tests/path/core.c index 6723216464f..c875a862ce7 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -361,6 +361,9 @@ void test_path_core__validate_workdir_with_core_longpath(void) /* set core.longpaths explicitly off */ cl_git_pass(git_config_set_bool(config, "core.longpaths", 0)); cl_must_fail(git_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + + git_config_free(config); + git_repository_free(repo); #endif } diff --git a/tests/refs/basic.c b/tests/refs/basic.c index d1ec2bbe646..9e4c2296484 100644 --- a/tests/refs/basic.c +++ b/tests/refs/basic.c @@ -80,5 +80,6 @@ void test_refs_basic__longpaths(void) git_reference_free(one); git_reference_free(two); + git_buf_dispose(&refname); #endif } From 9869f1e5a30e735d3958c1fed3f6b0979d7f80de Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 6 May 2021 02:19:49 +0100 Subject: [PATCH 0300/1616] filter: deprecate git_filter_list_stream_data `git_filter_list_stream_data` takes user input in a `git_buf`. `git_buf` should only be used when libgit2 itself needs to allocate data and returned to a user that they can free when they wish. Replace it with `git_filter_list_stream_buffer` that takes a data buffer and length. --- include/git2/deprecated.h | 24 ++++++++++++++++++++++++ include/git2/filter.h | 8 +++++--- src/filter.c | 34 ++++++++++++++++++++++++---------- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index 37857f8a21f..a51950906cc 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -18,6 +18,7 @@ #include "describe.h" #include "diff.h" #include "errors.h" +#include "filter.h" #include "index.h" #include "indexer.h" #include "merge.h" @@ -119,6 +120,29 @@ GIT_EXTERN(int) git_blob_filtered_content( /**@}*/ +/** @name Deprecated Filter Functions + * + * These functions are retained for backward compatibility. The + * newer versions of these functions should be preferred in all + * new code. + * + * There is no plan to remove these backward compatibility values at + * this time. + */ +/**@{*/ + +/** Deprecated in favor of `git_filter_list_stream_buffer`. + * + * @deprecated Use git_filter_list_stream_buffer + * @see Use git_filter_list_stream_buffer + */ +GIT_EXTERN(int) git_filter_list_stream_data( + git_filter_list *filters, + git_buf *data, + git_writestream *target); + +/**@}*/ + /** @name Deprecated Tree Functions * * These functions are retained for backward compatibility. The diff --git a/include/git2/filter.h b/include/git2/filter.h index 8860590515c..641391b94af 100644 --- a/include/git2/filter.h +++ b/include/git2/filter.h @@ -175,12 +175,14 @@ GIT_EXTERN(int) git_filter_list_apply_to_blob( * Apply a filter list to an arbitrary buffer as a stream * * @param filters the list of filters to apply - * @param data the buffer to filter + * @param buffer the buffer to filter + * @param len the size of the buffer * @param target the stream into which the data will be written */ -GIT_EXTERN(int) git_filter_list_stream_data( +GIT_EXTERN(int) git_filter_list_stream_buffer( git_filter_list *filters, - git_buf *data, + const char *buffer, + size_t len, git_writestream *target); /** diff --git a/src/filter.c b/src/filter.c index b82becdf31a..f2ad837d19a 100644 --- a/src/filter.c +++ b/src/filter.c @@ -737,8 +737,8 @@ int git_filter_list_apply_to_data( buf_stream_init(&writer, tgt); - if ((error = git_filter_list_stream_data(filters, src, - &writer.parent)) < 0) + if ((error = git_filter_list_stream_buffer(filters, + src->ptr, src->size, &writer.parent)) < 0) return error; GIT_ASSERT(writer.complete); @@ -1002,24 +1002,21 @@ int git_filter_list_stream_file( return error; } -int git_filter_list_stream_data( +int git_filter_list_stream_buffer( git_filter_list *filters, - git_buf *data, + const char *buffer, + size_t len, git_writestream *target) { git_vector filter_streams = GIT_VECTOR_INIT; git_writestream *stream_start; int error, initialized = 0; - if ((error = git_buf_sanitize(data)) < 0) - return error; - if ((error = stream_list_init(&stream_start, &filter_streams, filters, target)) < 0) goto out; initialized = 1; - if ((error = stream_start->write( - stream_start, data->ptr, data->size)) < 0) + if ((error = stream_start->write(stream_start, buffer, len)) < 0) goto out; out: @@ -1043,7 +1040,7 @@ int git_filter_list_stream_blob( if (filters) git_oid_cpy(&filters->source.oid, git_blob_id(blob)); - return git_filter_list_stream_data(filters, &in, target); + return git_filter_list_stream_buffer(filters, in.ptr, in.size, target); } int git_filter_init(git_filter *filter, unsigned int version) @@ -1051,3 +1048,20 @@ int git_filter_init(git_filter *filter, unsigned int version) GIT_INIT_STRUCTURE_FROM_TEMPLATE(filter, version, git_filter, GIT_FILTER_INIT); return 0; } + +#ifndef GIT_DEPRECATE_HARD + +int git_filter_list_stream_data( + git_filter_list *filters, + git_buf *data, + git_writestream *target) +{ + int error; + + if ((error = git_buf_sanitize(data)) < 0) + return error; + + return git_filter_list_stream_buffer(filters, data->ptr, data->size, target); +} + +#endif From 26846f4cdbaca7eac5f1030f1c2a25c8b2f8c274 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 6 May 2021 15:19:58 +0100 Subject: [PATCH 0301/1616] filter: remove git_buf sharing in `git_filter_list_apply_to_data` The API `git_filter_list_apply_to_data` shares data between its out and in parameters to avoid unnecessarily copying it when there are no filters to apply. However, it does so in a manner that is potentially confusing, leaving both `git_buf`s populated with data. This is risky for end-users who have to know how to deal with this. Instead, we remove this optimization - users who want to avoid unnecessary copies can use the longstanding streaming API or check the filter status before invoking the filters. --- include/git2/filter.h | 12 ------------ src/filter.c | 32 ++++++++++++++++++++------------ 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/include/git2/filter.h b/include/git2/filter.h index 641391b94af..45aa6c5af03 100644 --- a/include/git2/filter.h +++ b/include/git2/filter.h @@ -122,18 +122,6 @@ GIT_EXTERN(int) git_filter_list_contains( /** * Apply filter list to a data buffer. * - * See `git2/buffer.h` for background on `git_buf` objects. - * - * If the `in` buffer holds data allocated by libgit2 (i.e. `in->asize` is - * not zero), then it will be overwritten when applying the filters. If - * not, then it will be left untouched. - * - * If there are no filters to apply (or `filters` is NULL), then the `out` - * buffer will reference the `in` buffer data (with `asize` set to zero) - * instead of allocating data. This keeps allocations to a minimum, but - * it means you have to be careful about freeing the `in` data since `out` - * may be pointing to it! - * * @param out Buffer to store the result of the filtering * @param filters A loaded git_filter_list (or NULL) * @param in Buffer containing the data to filter diff --git a/src/filter.c b/src/filter.c index f2ad837d19a..72a426e0a64 100644 --- a/src/filter.c +++ b/src/filter.c @@ -720,31 +720,39 @@ static void buf_stream_init(struct buf_stream *writer, git_buf *target) git_buf_clear(target); } -int git_filter_list_apply_to_data( - git_buf *tgt, git_filter_list *filters, git_buf *src) +static int git_filter_list_apply_to_buffer( + git_buf *out, + git_filter_list *filters, + const char *in, + size_t in_len) { struct buf_stream writer; int error; - if ((error = git_buf_sanitize(tgt)) < 0 || - (error = git_buf_sanitize(src)) < 0) - return error; - - if (!filters) { - git_buf_attach_notowned(tgt, src->ptr, src->size); - return 0; - } + if ((error = git_buf_sanitize(out)) < 0) + return error; - buf_stream_init(&writer, tgt); + buf_stream_init(&writer, out); if ((error = git_filter_list_stream_buffer(filters, - src->ptr, src->size, &writer.parent)) < 0) + in, in_len, &writer.parent)) < 0) return error; GIT_ASSERT(writer.complete); return error; } +int git_filter_list_apply_to_data( + git_buf *tgt, git_filter_list *filters, git_buf *src) +{ + int error; + + if ((error = git_buf_sanitize(src)) < 0) + return error; + + return git_filter_list_apply_to_buffer(tgt, filters, src->ptr, src->size); +} + int git_filter_list_apply_to_file( git_buf *out, git_filter_list *filters, From 5309b4654e5a387d18fe5181e376305332188eca Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 6 May 2021 15:24:30 +0100 Subject: [PATCH 0302/1616] filter: introduce git_filter_list_apply_to_buffer Provide a filter application mechanism that takes a user-provided string and length, instead of a `git_buf`. --- include/git2/filter.h | 15 +++++++++++++++ src/filter.c | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/git2/filter.h b/include/git2/filter.h index 45aa6c5af03..3e84877df62 100644 --- a/include/git2/filter.h +++ b/include/git2/filter.h @@ -119,6 +119,21 @@ GIT_EXTERN(int) git_filter_list_contains( git_filter_list *filters, const char *name); +/** + * Apply filter list to a data buffer. + * + * @param out Buffer to store the result of the filtering + * @param filters A loaded git_filter_list (or NULL) + * @param in Buffer containing the data to filter + * @param in_len The length of the input buffer + * @return 0 on success, an error code otherwise + */ +GIT_EXTERN(int) git_filter_list_apply_to_buffer( + git_buf *out, + git_filter_list *filters, + const char *in, + size_t in_len); + /** * Apply filter list to a data buffer. * diff --git a/src/filter.c b/src/filter.c index 72a426e0a64..2ba0f1e76a6 100644 --- a/src/filter.c +++ b/src/filter.c @@ -720,7 +720,7 @@ static void buf_stream_init(struct buf_stream *writer, git_buf *target) git_buf_clear(target); } -static int git_filter_list_apply_to_buffer( +int git_filter_list_apply_to_buffer( git_buf *out, git_filter_list *filters, const char *in, From 68b9605acc31d7cba3da322820b484c8db2e0a1e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 6 May 2021 15:37:31 +0100 Subject: [PATCH 0303/1616] filter: deprecate git_filter_list_apply_to_data Deprecate `git_filter_list_apply_to_data` as it takes user input as a `git_buf`. Users should use `git_filter_list_apply_to_buffer` instead. --- include/git2/deprecated.h | 10 ++++ include/git2/filter.h | 13 ----- src/filter.c | 22 ++++---- tests/filter/crlf.c | 116 +++++++++++++++++++++----------------- tests/filter/custom.c | 29 +++++++--- tests/filter/wildcard.c | 18 ++---- 6 files changed, 111 insertions(+), 97 deletions(-) diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index a51950906cc..ac60488acb6 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -141,6 +141,16 @@ GIT_EXTERN(int) git_filter_list_stream_data( git_buf *data, git_writestream *target); +/** Deprecated in favor of `git_filter_list_apply_to_buffer`. + * + * @deprecated Use git_filter_list_apply_to_buffer + * @see Use git_filter_list_apply_to_buffer + */ +GIT_EXTERN(int) git_filter_list_apply_to_data( + git_buf *out, + git_filter_list *filters, + git_buf *in); + /**@}*/ /** @name Deprecated Tree Functions diff --git a/include/git2/filter.h b/include/git2/filter.h index 3e84877df62..a0185ee88af 100644 --- a/include/git2/filter.h +++ b/include/git2/filter.h @@ -134,19 +134,6 @@ GIT_EXTERN(int) git_filter_list_apply_to_buffer( const char *in, size_t in_len); -/** - * Apply filter list to a data buffer. - * - * @param out Buffer to store the result of the filtering - * @param filters A loaded git_filter_list (or NULL) - * @param in Buffer containing the data to filter - * @return 0 on success, an error code otherwise - */ -GIT_EXTERN(int) git_filter_list_apply_to_data( - git_buf *out, - git_filter_list *filters, - git_buf *in); - /** * Apply a filter list to the contents of a file on disk * diff --git a/src/filter.c b/src/filter.c index 2ba0f1e76a6..200d7051745 100644 --- a/src/filter.c +++ b/src/filter.c @@ -742,17 +742,6 @@ int git_filter_list_apply_to_buffer( return error; } -int git_filter_list_apply_to_data( - git_buf *tgt, git_filter_list *filters, git_buf *src) -{ - int error; - - if ((error = git_buf_sanitize(src)) < 0) - return error; - - return git_filter_list_apply_to_buffer(tgt, filters, src->ptr, src->size); -} - int git_filter_list_apply_to_file( git_buf *out, git_filter_list *filters, @@ -1072,4 +1061,15 @@ int git_filter_list_stream_data( return git_filter_list_stream_buffer(filters, data->ptr, data->size, target); } +int git_filter_list_apply_to_data( + git_buf *tgt, git_filter_list *filters, git_buf *src) +{ + int error; + + if ((error = git_buf_sanitize(src)) < 0) + return error; + + return git_filter_list_apply_to_buffer(tgt, filters, src->ptr, src->size); +} + #endif diff --git a/tests/filter/crlf.c b/tests/filter/crlf.c index a266005d4de..bc9c7f28938 100644 --- a/tests/filter/crlf.c +++ b/tests/filter/crlf.c @@ -23,7 +23,9 @@ void test_filter_crlf__to_worktree(void) { git_filter_list *fl; git_filter *crlf; - git_buf in = { 0 }, out = { 0 }; + git_buf out = GIT_BUF_INIT; + const char *in; + size_t in_len; cl_git_pass(git_filter_list_new( &fl, g_repo, GIT_FILTER_TO_WORKTREE, 0)); @@ -33,10 +35,10 @@ void test_filter_crlf__to_worktree(void) cl_git_pass(git_filter_list_push(fl, crlf, NULL)); - in.ptr = "Some text\nRight here\n"; - in.size = strlen(in.ptr); + in = "Some text\nRight here\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_s("Some text\r\nRight here\r\n", out.ptr); @@ -48,7 +50,9 @@ void test_filter_crlf__to_odb(void) { git_filter_list *fl; git_filter *crlf; - git_buf in = { 0 }, out = { 0 }; + git_buf out = GIT_BUF_INIT; + const char *in; + size_t in_len; cl_git_pass(git_filter_list_new( &fl, g_repo, GIT_FILTER_TO_ODB, 0)); @@ -58,10 +62,10 @@ void test_filter_crlf__to_odb(void) cl_git_pass(git_filter_list_push(fl, crlf, NULL)); - in.ptr = "Some text\r\nRight here\r\n"; - in.size = strlen(in.ptr); + in = "Some text\r\nRight here\r\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_s("Some text\nRight here\n", out.ptr); @@ -73,7 +77,9 @@ void test_filter_crlf__with_safecrlf(void) { git_filter_list *fl; git_filter *crlf; - git_buf in = {0}, out = GIT_BUF_INIT; + git_buf out = GIT_BUF_INIT; + const char *in; + size_t in_len; cl_repo_set_bool(g_repo, "core.safecrlf", true); @@ -86,31 +92,31 @@ void test_filter_crlf__with_safecrlf(void) cl_git_pass(git_filter_list_push(fl, crlf, NULL)); /* Normalized \r\n succeeds with safecrlf */ - in.ptr = "Normal\r\nCRLF\r\nline-endings.\r\n"; - in.size = strlen(in.ptr); + in = "Normal\r\nCRLF\r\nline-endings.\r\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_s("Normal\nCRLF\nline-endings.\n", out.ptr); /* Mix of line endings fails with safecrlf */ - in.ptr = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n"; - in.size = strlen(in.ptr); + in = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n"; + in_len = strlen(in); - cl_git_fail(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_fail(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_i(git_error_last()->klass, GIT_ERROR_FILTER); /* Normalized \n fails for autocrlf=true when safecrlf=true */ - in.ptr = "Normal\nLF\nonly\nline-endings.\n"; - in.size = strlen(in.ptr); + in = "Normal\nLF\nonly\nline-endings.\n"; + in_len = strlen(in); - cl_git_fail(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_fail(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_i(git_error_last()->klass, GIT_ERROR_FILTER); /* String with \r but without \r\n does not fail with safecrlf */ - in.ptr = "Normal\nCR only\rand some more\nline-endings.\n"; - in.size = strlen(in.ptr); + in = "Normal\nCR only\rand some more\nline-endings.\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_s("Normal\nCR only\rand some more\nline-endings.\n", out.ptr); git_filter_list_free(fl); @@ -121,7 +127,9 @@ void test_filter_crlf__with_safecrlf_and_unsafe_allowed(void) { git_filter_list *fl; git_filter *crlf; - git_buf in = {0}, out = GIT_BUF_INIT; + git_buf out = GIT_BUF_INIT; + const char *in; + size_t in_len; cl_repo_set_bool(g_repo, "core.safecrlf", true); @@ -134,25 +142,25 @@ void test_filter_crlf__with_safecrlf_and_unsafe_allowed(void) cl_git_pass(git_filter_list_push(fl, crlf, NULL)); /* Normalized \r\n succeeds with safecrlf */ - in.ptr = "Normal\r\nCRLF\r\nline-endings.\r\n"; - in.size = strlen(in.ptr); + in = "Normal\r\nCRLF\r\nline-endings.\r\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_s("Normal\nCRLF\nline-endings.\n", out.ptr); /* Mix of line endings fails with safecrlf, but allowed to pass */ - in.ptr = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n"; - in.size = strlen(in.ptr); + in = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); /* TODO: check for warning */ cl_assert_equal_s("Mixed\nup\nLF\nand\nCRLF\nline-endings.\n", out.ptr); /* Normalized \n fails with safecrlf, but allowed to pass */ - in.ptr = "Normal\nLF\nonly\nline-endings.\n"; - in.size = strlen(in.ptr); + in = "Normal\nLF\nonly\nline-endings.\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); /* TODO: check for warning */ cl_assert_equal_s("Normal\nLF\nonly\nline-endings.\n", out.ptr); @@ -164,7 +172,9 @@ void test_filter_crlf__no_safecrlf(void) { git_filter_list *fl; git_filter *crlf; - git_buf in = {0}, out = GIT_BUF_INIT; + git_buf out = GIT_BUF_INIT; + const char *in; + size_t in_len; cl_git_pass(git_filter_list_new( &fl, g_repo, GIT_FILTER_TO_ODB, 0)); @@ -175,24 +185,24 @@ void test_filter_crlf__no_safecrlf(void) cl_git_pass(git_filter_list_push(fl, crlf, NULL)); /* Normalized \r\n succeeds with safecrlf */ - in.ptr = "Normal\r\nCRLF\r\nline-endings.\r\n"; - in.size = strlen(in.ptr); + in = "Normal\r\nCRLF\r\nline-endings.\r\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_s("Normal\nCRLF\nline-endings.\n", out.ptr); /* Mix of line endings fails with safecrlf */ - in.ptr = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n"; - in.size = strlen(in.ptr); + in = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_s("Mixed\nup\nLF\nand\nCRLF\nline-endings.\n", out.ptr); /* Normalized \n fails with safecrlf */ - in.ptr = "Normal\nLF\nonly\nline-endings.\n"; - in.size = strlen(in.ptr); + in = "Normal\nLF\nonly\nline-endings.\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_s("Normal\nLF\nonly\nline-endings.\n", out.ptr); git_filter_list_free(fl); @@ -203,7 +213,9 @@ void test_filter_crlf__safecrlf_warn(void) { git_filter_list *fl; git_filter *crlf; - git_buf in = {0}, out = GIT_BUF_INIT; + git_buf out = GIT_BUF_INIT; + const char *in; + size_t in_len; cl_repo_set_string(g_repo, "core.safecrlf", "warn"); @@ -216,26 +228,26 @@ void test_filter_crlf__safecrlf_warn(void) cl_git_pass(git_filter_list_push(fl, crlf, NULL)); /* Normalized \r\n succeeds with safecrlf=warn */ - in.ptr = "Normal\r\nCRLF\r\nline-endings.\r\n"; - in.size = strlen(in.ptr); + in = "Normal\r\nCRLF\r\nline-endings.\r\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_s("Normal\nCRLF\nline-endings.\n", out.ptr); /* Mix of line endings succeeds with safecrlf=warn */ - in.ptr = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n"; - in.size = strlen(in.ptr); + in = "Mixed\nup\r\nLF\nand\r\nCRLF\nline-endings.\r\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); /* TODO: check for warning */ cl_assert_equal_s("Mixed\nup\nLF\nand\nCRLF\nline-endings.\n", out.ptr); /* Normalized \n is reversible, so does not fail with safecrlf=warn */ - in.ptr = "Normal\nLF\nonly\nline-endings.\n"; - in.size = strlen(in.ptr); + in = "Normal\nLF\nonly\nline-endings.\n"; + in_len = strlen(in); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); - cl_assert_equal_s(in.ptr, out.ptr); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); + cl_assert_equal_s(in, out.ptr); git_filter_list_free(fl); git_buf_dispose(&out); diff --git a/tests/filter/custom.c b/tests/filter/custom.c index fe2025fc2c9..3554cb52cab 100644 --- a/tests/filter/custom.c +++ b/tests/filter/custom.c @@ -95,13 +95,17 @@ static void register_custom_filters(void) void test_filter_custom__to_odb(void) { git_filter_list *fl; - git_buf out = { 0 }; - git_buf in = GIT_BUF_INIT_CONST(workdir_data, strlen(workdir_data)); + git_buf out = GIT_BUF_INIT; + const char *in; + size_t in_len; cl_git_pass(git_filter_list_load( &fl, g_repo, NULL, "herofile", GIT_FILTER_TO_ODB, 0)); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + in = workdir_data; + in_len = strlen(workdir_data); + + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_i(BITFLIPPED_AND_REVERSED_DATA_LEN, out.size); @@ -115,14 +119,17 @@ void test_filter_custom__to_odb(void) void test_filter_custom__to_workdir(void) { git_filter_list *fl; - git_buf out = { 0 }; - git_buf in = GIT_BUF_INIT_CONST( - bitflipped_and_reversed_data, BITFLIPPED_AND_REVERSED_DATA_LEN); + git_buf out = GIT_BUF_INIT; + const char *in; + size_t in_len; cl_git_pass(git_filter_list_load( &fl, g_repo, NULL, "herofile", GIT_FILTER_TO_WORKTREE, 0)); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + in = (char *)bitflipped_and_reversed_data; + in_len = BITFLIPPED_AND_REVERSED_DATA_LEN; + + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, in, in_len)); cl_assert_equal_i(strlen(workdir_data), out.size); @@ -246,12 +253,16 @@ void test_filter_custom__erroneous_filter_fails(void) { git_filter_list *filters; git_buf out = GIT_BUF_INIT; - git_buf in = GIT_BUF_INIT_CONST(workdir_data, strlen(workdir_data)); + const char *in; + size_t in_len; cl_git_pass(git_filter_list_load( &filters, g_repo, NULL, "villain", GIT_FILTER_TO_WORKTREE, 0)); - cl_git_fail(git_filter_list_apply_to_data(&out, filters, &in)); + in = workdir_data; + in_len = strlen(workdir_data); + + cl_git_fail(git_filter_list_apply_to_buffer(&out, filters, in, in_len)); git_filter_list_free(filters); git_buf_dispose(&out); diff --git a/tests/filter/wildcard.c b/tests/filter/wildcard.c index 3c25ea26613..62a84ead528 100644 --- a/tests/filter/wildcard.c +++ b/tests/filter/wildcard.c @@ -123,13 +123,12 @@ static git_filter *create_wildcard_filter(void) void test_filter_wildcard__reverse(void) { git_filter_list *fl; - git_buf in = GIT_BUF_INIT, out = GIT_BUF_INIT; + git_buf out = GIT_BUF_INIT; cl_git_pass(git_filter_list_load( &fl, g_repo, NULL, "hero-reverse-foo", GIT_FILTER_TO_ODB, 0)); - cl_git_pass(git_buf_put(&in, (char *)input, DATA_LEN)); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, (char *)input, DATA_LEN)); cl_assert_equal_i(DATA_LEN, out.size); @@ -138,19 +137,17 @@ void test_filter_wildcard__reverse(void) git_filter_list_free(fl); git_buf_dispose(&out); - git_buf_dispose(&in); } void test_filter_wildcard__flip(void) { git_filter_list *fl; - git_buf in = GIT_BUF_INIT, out = GIT_BUF_INIT; + git_buf out = GIT_BUF_INIT; cl_git_pass(git_filter_list_load( &fl, g_repo, NULL, "hero-flip-foo", GIT_FILTER_TO_ODB, 0)); - cl_git_pass(git_buf_put(&in, (char *)input, DATA_LEN)); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, (char *)input, DATA_LEN)); cl_assert_equal_i(DATA_LEN, out.size); @@ -159,19 +156,17 @@ void test_filter_wildcard__flip(void) git_filter_list_free(fl); git_buf_dispose(&out); - git_buf_dispose(&in); } void test_filter_wildcard__none(void) { git_filter_list *fl; - git_buf in = GIT_BUF_INIT, out = GIT_BUF_INIT; + git_buf out = GIT_BUF_INIT; cl_git_pass(git_filter_list_load( &fl, g_repo, NULL, "none-foo", GIT_FILTER_TO_ODB, 0)); - cl_git_pass(git_buf_put(&in, (char *)input, DATA_LEN)); - cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in)); + cl_git_pass(git_filter_list_apply_to_buffer(&out, fl, (char *)input, DATA_LEN)); cl_assert_equal_i(DATA_LEN, out.size); @@ -180,5 +175,4 @@ void test_filter_wildcard__none(void) git_filter_list_free(fl); git_buf_dispose(&out); - git_buf_dispose(&in); } From 31d9c24b33b28155001f80f11bdb576cd366c207 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 6 May 2021 16:32:14 +0100 Subject: [PATCH 0304/1616] filter: internal git_buf filter handling function Introduce `git_filter_list__convert_buf` which behaves like the old implementation of `git_filter_list__apply_data`, where it might move the input data buffer over into the output data buffer space for efficiency. This new implementation will do so in a more predictible way, always freeing the given input buffer (either moving it to the output buffer or filtering it into the output buffer first). Convert internal users to it. --- src/checkout.c | 2 +- src/diff_file.c | 5 +---- src/filter.c | 22 ++++++++++++++++++++++ src/filter.h | 9 +++++++++ src/odb.c | 4 +--- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/checkout.c b/src/checkout.c index cadc4c82d44..f69b302d5f7 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -2121,7 +2121,7 @@ static int checkout_write_merge( if ((error = git_filter_list__load_ext( &fl, data->repo, NULL, git_buf_cstr(&path_workdir), GIT_FILTER_TO_WORKTREE, &filter_opts)) < 0 || - (error = git_filter_list_apply_to_data(&out_data, fl, &in_data)) < 0) + (error = git_filter_list__convert_buf(&out_data, fl, &in_data)) < 0) goto done; } else { out_data.ptr = (char *)result.ptr; diff --git a/src/diff_file.c b/src/diff_file.c index 2116f00211c..eeaf4a5a274 100644 --- a/src/diff_file.c +++ b/src/diff_file.c @@ -362,10 +362,7 @@ static int diff_file_content_load_workdir_file( if (!(error = git_futils_readbuffer_fd(&raw, fd, (size_t)fc->file->size))) { git_buf out = GIT_BUF_INIT; - error = git_filter_list_apply_to_data(&out, fl, &raw); - - if (out.ptr != raw.ptr) - git_buf_dispose(&raw); + error = git_filter_list__convert_buf(&out, fl, &raw); if (!error) { fc->map.len = out.size; diff --git a/src/filter.c b/src/filter.c index 200d7051745..6c09a6ad58f 100644 --- a/src/filter.c +++ b/src/filter.c @@ -742,6 +742,28 @@ int git_filter_list_apply_to_buffer( return error; } +int git_filter_list__convert_buf( + git_buf *out, + git_filter_list *filters, + git_buf *in) +{ + int error; + + if (!filters || git_filter_list_length(filters) == 0) { + git_buf_swap(out, in); + git_buf_dispose(in); + return 0; + } + + error = git_filter_list_apply_to_buffer(out, filters, + in->ptr, in->size); + + if (!error) + git_buf_dispose(in); + + return error; +} + int git_filter_list_apply_to_file( git_buf *out, git_filter_list *filters, diff --git a/src/filter.h b/src/filter.h index 34081fb4adf..bbc4c0fb23b 100644 --- a/src/filter.h +++ b/src/filter.h @@ -35,6 +35,15 @@ extern int git_filter_list__load_ext( git_filter_mode_t mode, git_filter_options *filter_opts); +/* + * The given input buffer will be converted to the given output buffer. + * The input buffer will be freed (_if_ it was allocated). + */ +extern int git_filter_list__convert_buf( + git_buf *out, + git_filter_list *filters, + git_buf *in); + /* * Available filters */ diff --git a/src/odb.c b/src/odb.c index b2988c42903..1b91434bf0a 100644 --- a/src/odb.c +++ b/src/odb.c @@ -260,9 +260,7 @@ int git_odb__hashfd_filtered( if (!(error = git_futils_readbuffer_fd(&raw, fd, size))) { git_buf post = GIT_BUF_INIT; - error = git_filter_list_apply_to_data(&post, fl, &raw); - - git_buf_dispose(&raw); + error = git_filter_list__convert_buf(&post, fl, &raw); if (!error) error = git_odb_hash(out, post.ptr, post.size, type); From d525e063ba4e478cc4afac4cdf60f7acd989dbf2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 10 May 2021 23:04:59 +0100 Subject: [PATCH 0305/1616] buf: remove internal `git_buf_text` namespace The `git_buf_text` namespace is unnecessary and strange. Remove it, just keep the functions prefixed with `git_buf`. --- src/attr_file.c | 3 +- src/blob.c | 3 +- src/buf_text.c | 316 --------------------------------- src/buf_text.h | 122 ------------- src/buffer.c | 320 ++++++++++++++++++++++++++++++++-- src/buffer.h | 92 ++++++++++ src/checkout.c | 1 - src/config.c | 3 +- src/config_parse.c | 4 +- src/crlf.c | 9 +- src/diff_driver.c | 5 +- src/ident.c | 3 +- src/pathspec.c | 5 +- src/submodule.c | 1 - tests/apply/fromdiff.c | 1 - tests/apply/fromfile.c | 1 - tests/apply/partial.c | 1 - tests/core/buffer.c | 89 +++++----- tests/diff/patch.c | 1 - tests/diff/rename.c | 3 +- tests/filter/custom.c | 1 - tests/filter/custom_helpers.c | 1 - tests/filter/stream.c | 1 - tests/filter/wildcard.c | 1 - tests/mailmap/parsing.c | 3 +- tests/object/blob/filter.c | 3 +- 26 files changed, 461 insertions(+), 532 deletions(-) delete mode 100644 src/buf_text.c delete mode 100644 src/buf_text.h diff --git a/src/attr_file.c b/src/attr_file.c index d1b90c5bae5..6575e5a4956 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -10,7 +10,6 @@ #include "repository.h" #include "filebuf.h" #include "attrcache.h" -#include "buf_text.h" #include "git2/blob.h" #include "git2/tree.h" #include "blob.h" @@ -192,7 +191,7 @@ int git_attr_file__load( /* advance over a UTF8 BOM */ content_str = git_buf_cstr(&content); - bom_offset = git_buf_text_detect_bom(&bom, &content); + bom_offset = git_buf_detect_bom(&bom, &content); if (bom == GIT_BOM_UTF8) content_str += bom_offset; diff --git a/src/blob.c b/src/blob.c index ddc2494c87e..169e3450338 100644 --- a/src/blob.c +++ b/src/blob.c @@ -14,7 +14,6 @@ #include "filebuf.h" #include "filter.h" -#include "buf_text.h" const void *git_blob_rawcontent(const git_blob *blob) { @@ -401,7 +400,7 @@ int git_blob_is_binary(const git_blob *blob) git_buf_attach_notowned(&content, git_blob_rawcontent(blob), (size_t)min(size, GIT_FILTER_BYTES_TO_CHECK_NUL)); - return git_buf_text_is_binary(&content); + return git_buf_is_binary(&content); } int git_blob_filter_options_init( diff --git a/src/buf_text.c b/src/buf_text.c deleted file mode 100644 index 0fd22319f0b..00000000000 --- a/src/buf_text.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * 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 "buf_text.h" - -int git_buf_text_puts_escaped( - git_buf *buf, - const char *string, - const char *esc_chars, - const char *esc_with) -{ - const char *scan; - size_t total = 0, esc_len = strlen(esc_with), count, alloclen; - - if (!string) - return 0; - - for (scan = string; *scan; ) { - /* count run of non-escaped characters */ - count = strcspn(scan, esc_chars); - total += count; - scan += count; - /* count run of escaped characters */ - count = strspn(scan, esc_chars); - total += count * (esc_len + 1); - scan += count; - } - - GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, total, 1); - if (git_buf_grow_by(buf, alloclen) < 0) - return -1; - - for (scan = string; *scan; ) { - count = strcspn(scan, esc_chars); - - memmove(buf->ptr + buf->size, scan, count); - scan += count; - buf->size += count; - - for (count = strspn(scan, esc_chars); count > 0; --count) { - /* copy escape sequence */ - memmove(buf->ptr + buf->size, esc_with, esc_len); - buf->size += esc_len; - /* copy character to be escaped */ - buf->ptr[buf->size] = *scan; - buf->size++; - scan++; - } - } - - buf->ptr[buf->size] = '\0'; - - return 0; -} - -void git_buf_text_unescape(git_buf *buf) -{ - buf->size = git__unescape(buf->ptr); -} - -int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src) -{ - const char *scan = src->ptr; - const char *scan_end = src->ptr + src->size; - const char *next = memchr(scan, '\r', src->size); - size_t new_size; - char *out; - - GIT_ASSERT(tgt != src); - - if (!next) - return git_buf_set(tgt, src->ptr, src->size); - - /* reduce reallocs while in the loop */ - GIT_ERROR_CHECK_ALLOC_ADD(&new_size, src->size, 1); - if (git_buf_grow(tgt, new_size) < 0) - return -1; - - out = tgt->ptr; - tgt->size = 0; - - /* Find the next \r and copy whole chunk up to there to tgt */ - for (; next; scan = next + 1, next = memchr(scan, '\r', scan_end - scan)) { - if (next > scan) { - size_t copylen = (size_t)(next - scan); - memcpy(out, scan, copylen); - out += copylen; - } - - /* Do not drop \r unless it is followed by \n */ - if (next + 1 == scan_end || next[1] != '\n') - *out++ = '\r'; - } - - /* Copy remaining input into dest */ - if (scan < scan_end) { - size_t remaining = (size_t)(scan_end - scan); - memcpy(out, scan, remaining); - out += remaining; - } - - tgt->size = (size_t)(out - tgt->ptr); - tgt->ptr[tgt->size] = '\0'; - - return 0; -} - -int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src) -{ - const char *start = src->ptr; - const char *end = start + src->size; - const char *scan = start; - const char *next = memchr(scan, '\n', src->size); - size_t alloclen; - - GIT_ASSERT(tgt != src); - - if (!next) - return git_buf_set(tgt, src->ptr, src->size); - - /* attempt to reduce reallocs while in the loop */ - GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, src->size, src->size >> 4); - GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1); - if (git_buf_grow(tgt, alloclen) < 0) - return -1; - tgt->size = 0; - - for (; next; scan = next + 1, next = memchr(scan, '\n', end - scan)) { - size_t copylen = next - scan; - - /* if we find mixed line endings, carry on */ - if (copylen && next[-1] == '\r') - copylen--; - - GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, copylen, 3); - if (git_buf_grow_by(tgt, alloclen) < 0) - return -1; - - if (copylen) { - memcpy(tgt->ptr + tgt->size, scan, copylen); - tgt->size += copylen; - } - - tgt->ptr[tgt->size++] = '\r'; - tgt->ptr[tgt->size++] = '\n'; - } - - tgt->ptr[tgt->size] = '\0'; - return git_buf_put(tgt, scan, end - scan); -} - -int git_buf_text_common_prefix(git_buf *buf, const git_strarray *strings) -{ - size_t i; - const char *str, *pfx; - - git_buf_clear(buf); - - if (!strings || !strings->count) - return 0; - - /* initialize common prefix to first string */ - if (git_buf_sets(buf, strings->strings[0]) < 0) - return -1; - - /* go through the rest of the strings, truncating to shared prefix */ - for (i = 1; i < strings->count; ++i) { - - for (str = strings->strings[i], pfx = buf->ptr; - *str && *str == *pfx; str++, pfx++) - /* scanning */; - - git_buf_truncate(buf, pfx - buf->ptr); - - if (!buf->size) - break; - } - - return 0; -} - -bool git_buf_text_is_binary(const git_buf *buf) -{ - const char *scan = buf->ptr, *end = buf->ptr + buf->size; - git_bom_t bom; - int printable = 0, nonprintable = 0; - - scan += git_buf_text_detect_bom(&bom, buf); - - if (bom > GIT_BOM_UTF8) - return 1; - - while (scan < end) { - unsigned char c = *scan++; - - /* Printable characters are those above SPACE (0x1F) excluding DEL, - * and including BS, ESC and FF. - */ - if ((c > 0x1F && c != 127) || c == '\b' || c == '\033' || c == '\014') - printable++; - else if (c == '\0') - return true; - else if (!git__isspace(c)) - nonprintable++; - } - - return ((printable >> 7) < nonprintable); -} - -bool git_buf_text_contains_nul(const git_buf *buf) -{ - return (memchr(buf->ptr, '\0', buf->size) != NULL); -} - -int git_buf_text_detect_bom(git_bom_t *bom, const git_buf *buf) -{ - const char *ptr; - size_t len; - - *bom = GIT_BOM_NONE; - /* need at least 2 bytes to look for any BOM */ - if (buf->size < 2) - return 0; - - ptr = buf->ptr; - len = buf->size; - - switch (*ptr++) { - case 0: - if (len >= 4 && ptr[0] == 0 && ptr[1] == '\xFE' && ptr[2] == '\xFF') { - *bom = GIT_BOM_UTF32_BE; - return 4; - } - break; - case '\xEF': - if (len >= 3 && ptr[0] == '\xBB' && ptr[1] == '\xBF') { - *bom = GIT_BOM_UTF8; - return 3; - } - break; - case '\xFE': - if (*ptr == '\xFF') { - *bom = GIT_BOM_UTF16_BE; - return 2; - } - break; - case '\xFF': - if (*ptr != '\xFE') - break; - if (len >= 4 && ptr[1] == 0 && ptr[2] == 0) { - *bom = GIT_BOM_UTF32_LE; - return 4; - } else { - *bom = GIT_BOM_UTF16_LE; - return 2; - } - break; - default: - break; - } - - return 0; -} - -bool git_buf_text_gather_stats( - git_buf_text_stats *stats, const git_buf *buf, bool skip_bom) -{ - const char *scan = buf->ptr, *end = buf->ptr + buf->size; - int skip; - - memset(stats, 0, sizeof(*stats)); - - /* BOM detection */ - skip = git_buf_text_detect_bom(&stats->bom, buf); - if (skip_bom) - scan += skip; - - /* Ignore EOF character */ - if (buf->size > 0 && end[-1] == '\032') - end--; - - /* Counting loop */ - while (scan < end) { - unsigned char c = *scan++; - - if (c > 0x1F && c != 0x7F) - stats->printable++; - else switch (c) { - case '\0': - stats->nul++; - stats->nonprintable++; - break; - case '\n': - stats->lf++; - break; - case '\r': - stats->cr++; - if (scan < end && *scan == '\n') - stats->crlf++; - break; - case '\t': case '\f': case '\v': case '\b': case 0x1b: /*ESC*/ - stats->printable++; - break; - default: - stats->nonprintable++; - break; - } - } - - /* Treat files with a bare CR as binary */ - return (stats->cr != stats->crlf || stats->nul > 0 || - ((stats->printable >> 7) < stats->nonprintable)); -} diff --git a/src/buf_text.h b/src/buf_text.h deleted file mode 100644 index 726b0ae7b80..00000000000 --- a/src/buf_text.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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_buf_text_h__ -#define INCLUDE_buf_text_h__ - -#include "common.h" - -#include "buffer.h" - -typedef enum { - GIT_BOM_NONE = 0, - GIT_BOM_UTF8 = 1, - GIT_BOM_UTF16_LE = 2, - GIT_BOM_UTF16_BE = 3, - GIT_BOM_UTF32_LE = 4, - GIT_BOM_UTF32_BE = 5 -} git_bom_t; - -typedef struct { - git_bom_t bom; /* BOM found at head of text */ - unsigned int nul, cr, lf, crlf; /* NUL, CR, LF and CRLF counts */ - unsigned int printable, nonprintable; /* These are just approximations! */ -} git_buf_text_stats; - -/** - * Append string to buffer, prefixing each character from `esc_chars` with - * `esc_with` string. - * - * @param buf Buffer to append data to - * @param string String to escape and append - * @param esc_chars Characters to be escaped - * @param esc_with String to insert in from of each found character - * @return 0 on success, <0 on failure (probably allocation problem) - */ -extern int git_buf_text_puts_escaped( - git_buf *buf, - const char *string, - const char *esc_chars, - const char *esc_with); - -/** - * Append string escaping characters that are regex special - */ -GIT_INLINE(int) git_buf_text_puts_escape_regex(git_buf *buf, const char *string) -{ - return git_buf_text_puts_escaped(buf, string, "^.[]$()|*+?{}\\", "\\"); -} - -/** - * Unescape all characters in a buffer in place - * - * I.e. remove backslashes - */ -extern void git_buf_text_unescape(git_buf *buf); - -/** - * Replace all \r\n with \n. - * - * @return 0 on success, -1 on memory error - */ -extern int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src); - -/** - * Replace all \n with \r\n. Does not modify existing \r\n. - * - * @return 0 on success, -1 on memory error - */ -extern int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src); - -/** - * Fill buffer with the common prefix of a array of strings - * - * Buffer will be set to empty if there is no common prefix - */ -extern int git_buf_text_common_prefix(git_buf *buf, const git_strarray *strs); - -/** - * Check quickly if buffer looks like it contains binary data - * - * @param buf Buffer to check - * @return true if buffer looks like non-text data - */ -extern bool git_buf_text_is_binary(const git_buf *buf); - -/** - * Check quickly if buffer contains a NUL byte - * - * @param buf Buffer to check - * @return true if buffer contains a NUL byte - */ -extern bool git_buf_text_contains_nul(const git_buf *buf); - -/** - * Check if a buffer begins with a UTF BOM - * - * @param bom Set to the type of BOM detected or GIT_BOM_NONE - * @param buf Buffer in which to check the first bytes for a BOM - * @return Number of bytes of BOM data (or 0 if no BOM found) - */ -extern int git_buf_text_detect_bom(git_bom_t *bom, const git_buf *buf); - -/** - * Gather stats for a piece of text - * - * Fill the `stats` structure with counts of unreadable characters, carriage - * returns, etc, so it can be used in heuristics. This automatically skips - * a trailing EOF (\032 character). Also it will look for a BOM at the - * start of the text and can be told to skip that as well. - * - * @param stats Structure to be filled in - * @param buf Text to process - * @param skip_bom Exclude leading BOM from stats if true - * @return Does the buffer heuristically look like binary data - */ -extern bool git_buf_text_gather_stats( - git_buf_text_stats *stats, const git_buf *buf, bool skip_bom); - -#endif diff --git a/src/buffer.c b/src/buffer.c index f6ecc6e4147..ffce73c68a1 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -7,7 +7,6 @@ #include "buffer.h" #include "posix.h" #include "git2/buffer.h" -#include "buf_text.h" #include /* Used as default value for git_buf->ptr so that people can always @@ -187,16 +186,6 @@ int git_buf_set(git_buf *buf, const void *data, size_t len) return 0; } -int git_buf_is_binary(const git_buf *buf) -{ - return git_buf_text_is_binary(buf); -} - -int git_buf_contains_nul(const git_buf *buf) -{ - return git_buf_text_contains_nul(buf); -} - int git_buf_sets(git_buf *buf, const char *string) { return git_buf_set(buf, string, string ? strlen(string) : 0); @@ -1058,3 +1047,312 @@ int git_buf_unquote(git_buf *buf) git_error_set(GIT_ERROR_INVALID, "invalid quoted line"); return -1; } + +int git_buf_puts_escaped( + git_buf *buf, + const char *string, + const char *esc_chars, + const char *esc_with) +{ + const char *scan; + size_t total = 0, esc_len = strlen(esc_with), count, alloclen; + + if (!string) + return 0; + + for (scan = string; *scan; ) { + /* count run of non-escaped characters */ + count = strcspn(scan, esc_chars); + total += count; + scan += count; + /* count run of escaped characters */ + count = strspn(scan, esc_chars); + total += count * (esc_len + 1); + scan += count; + } + + GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, total, 1); + if (git_buf_grow_by(buf, alloclen) < 0) + return -1; + + for (scan = string; *scan; ) { + count = strcspn(scan, esc_chars); + + memmove(buf->ptr + buf->size, scan, count); + scan += count; + buf->size += count; + + for (count = strspn(scan, esc_chars); count > 0; --count) { + /* copy escape sequence */ + memmove(buf->ptr + buf->size, esc_with, esc_len); + buf->size += esc_len; + /* copy character to be escaped */ + buf->ptr[buf->size] = *scan; + buf->size++; + scan++; + } + } + + buf->ptr[buf->size] = '\0'; + + return 0; +} + +void git_buf_unescape(git_buf *buf) +{ + buf->size = git__unescape(buf->ptr); +} + +int git_buf_crlf_to_lf(git_buf *tgt, const git_buf *src) +{ + const char *scan = src->ptr; + const char *scan_end = src->ptr + src->size; + const char *next = memchr(scan, '\r', src->size); + size_t new_size; + char *out; + + GIT_ASSERT(tgt != src); + + if (!next) + return git_buf_set(tgt, src->ptr, src->size); + + /* reduce reallocs while in the loop */ + GIT_ERROR_CHECK_ALLOC_ADD(&new_size, src->size, 1); + if (git_buf_grow(tgt, new_size) < 0) + return -1; + + out = tgt->ptr; + tgt->size = 0; + + /* Find the next \r and copy whole chunk up to there to tgt */ + for (; next; scan = next + 1, next = memchr(scan, '\r', scan_end - scan)) { + if (next > scan) { + size_t copylen = (size_t)(next - scan); + memcpy(out, scan, copylen); + out += copylen; + } + + /* Do not drop \r unless it is followed by \n */ + if (next + 1 == scan_end || next[1] != '\n') + *out++ = '\r'; + } + + /* Copy remaining input into dest */ + if (scan < scan_end) { + size_t remaining = (size_t)(scan_end - scan); + memcpy(out, scan, remaining); + out += remaining; + } + + tgt->size = (size_t)(out - tgt->ptr); + tgt->ptr[tgt->size] = '\0'; + + return 0; +} + +int git_buf_lf_to_crlf(git_buf *tgt, const git_buf *src) +{ + const char *start = src->ptr; + const char *end = start + src->size; + const char *scan = start; + const char *next = memchr(scan, '\n', src->size); + size_t alloclen; + + GIT_ASSERT(tgt != src); + + if (!next) + return git_buf_set(tgt, src->ptr, src->size); + + /* attempt to reduce reallocs while in the loop */ + GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, src->size, src->size >> 4); + GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1); + if (git_buf_grow(tgt, alloclen) < 0) + return -1; + tgt->size = 0; + + for (; next; scan = next + 1, next = memchr(scan, '\n', end - scan)) { + size_t copylen = next - scan; + + /* if we find mixed line endings, carry on */ + if (copylen && next[-1] == '\r') + copylen--; + + GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, copylen, 3); + if (git_buf_grow_by(tgt, alloclen) < 0) + return -1; + + if (copylen) { + memcpy(tgt->ptr + tgt->size, scan, copylen); + tgt->size += copylen; + } + + tgt->ptr[tgt->size++] = '\r'; + tgt->ptr[tgt->size++] = '\n'; + } + + tgt->ptr[tgt->size] = '\0'; + return git_buf_put(tgt, scan, end - scan); +} + +int git_buf_common_prefix(git_buf *buf, const git_strarray *strings) +{ + size_t i; + const char *str, *pfx; + + git_buf_clear(buf); + + if (!strings || !strings->count) + return 0; + + /* initialize common prefix to first string */ + if (git_buf_sets(buf, strings->strings[0]) < 0) + return -1; + + /* go through the rest of the strings, truncating to shared prefix */ + for (i = 1; i < strings->count; ++i) { + + for (str = strings->strings[i], pfx = buf->ptr; + *str && *str == *pfx; str++, pfx++) + /* scanning */; + + git_buf_truncate(buf, pfx - buf->ptr); + + if (!buf->size) + break; + } + + return 0; +} + +int git_buf_is_binary(const git_buf *buf) +{ + const char *scan = buf->ptr, *end = buf->ptr + buf->size; + git_bom_t bom; + int printable = 0, nonprintable = 0; + + scan += git_buf_detect_bom(&bom, buf); + + if (bom > GIT_BOM_UTF8) + return 1; + + while (scan < end) { + unsigned char c = *scan++; + + /* Printable characters are those above SPACE (0x1F) excluding DEL, + * and including BS, ESC and FF. + */ + if ((c > 0x1F && c != 127) || c == '\b' || c == '\033' || c == '\014') + printable++; + else if (c == '\0') + return true; + else if (!git__isspace(c)) + nonprintable++; + } + + return ((printable >> 7) < nonprintable); +} + +int git_buf_contains_nul(const git_buf *buf) +{ + return (memchr(buf->ptr, '\0', buf->size) != NULL); +} + +int git_buf_detect_bom(git_bom_t *bom, const git_buf *buf) +{ + const char *ptr; + size_t len; + + *bom = GIT_BOM_NONE; + /* need at least 2 bytes to look for any BOM */ + if (buf->size < 2) + return 0; + + ptr = buf->ptr; + len = buf->size; + + switch (*ptr++) { + case 0: + if (len >= 4 && ptr[0] == 0 && ptr[1] == '\xFE' && ptr[2] == '\xFF') { + *bom = GIT_BOM_UTF32_BE; + return 4; + } + break; + case '\xEF': + if (len >= 3 && ptr[0] == '\xBB' && ptr[1] == '\xBF') { + *bom = GIT_BOM_UTF8; + return 3; + } + break; + case '\xFE': + if (*ptr == '\xFF') { + *bom = GIT_BOM_UTF16_BE; + return 2; + } + break; + case '\xFF': + if (*ptr != '\xFE') + break; + if (len >= 4 && ptr[1] == 0 && ptr[2] == 0) { + *bom = GIT_BOM_UTF32_LE; + return 4; + } else { + *bom = GIT_BOM_UTF16_LE; + return 2; + } + break; + default: + break; + } + + return 0; +} + +bool git_buf_gather_text_stats( + git_buf_text_stats *stats, const git_buf *buf, bool skip_bom) +{ + const char *scan = buf->ptr, *end = buf->ptr + buf->size; + int skip; + + memset(stats, 0, sizeof(*stats)); + + /* BOM detection */ + skip = git_buf_detect_bom(&stats->bom, buf); + if (skip_bom) + scan += skip; + + /* Ignore EOF character */ + if (buf->size > 0 && end[-1] == '\032') + end--; + + /* Counting loop */ + while (scan < end) { + unsigned char c = *scan++; + + if (c > 0x1F && c != 0x7F) + stats->printable++; + else switch (c) { + case '\0': + stats->nul++; + stats->nonprintable++; + break; + case '\n': + stats->lf++; + break; + case '\r': + stats->cr++; + if (scan < end && *scan == '\n') + stats->crlf++; + break; + case '\t': case '\f': case '\v': case '\b': case 0x1b: /*ESC*/ + stats->printable++; + break; + default: + stats->nonprintable++; + break; + } + } + + /* Treat files with a bare CR as binary */ + return (stats->cr != stats->crlf || stats->nul > 0 || + ((stats->printable >> 7) < stats->nonprintable)); +} diff --git a/src/buffer.h b/src/buffer.h index 8c2096bcee9..e75ecc15c34 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -17,6 +17,21 @@ * } git_buf; */ +typedef enum { + GIT_BOM_NONE = 0, + GIT_BOM_UTF8 = 1, + GIT_BOM_UTF16_LE = 2, + GIT_BOM_UTF16_BE = 3, + GIT_BOM_UTF32_LE = 4, + GIT_BOM_UTF32_BE = 5 +} git_bom_t; + +typedef struct { + git_bom_t bom; /* BOM found at head of text */ + unsigned int nul, cr, lf, crlf; /* NUL, CR, LF and CRLF counts */ + unsigned int printable, nonprintable; /* These are just approximations! */ +} git_buf_text_stats; + extern char git_buf__initbuf[]; extern char git_buf__oom[]; @@ -219,4 +234,81 @@ int git_buf_splice( const char *data, size_t nb_to_insert); +/** + * Append string to buffer, prefixing each character from `esc_chars` with + * `esc_with` string. + * + * @param buf Buffer to append data to + * @param string String to escape and append + * @param esc_chars Characters to be escaped + * @param esc_with String to insert in from of each found character + * @return 0 on success, <0 on failure (probably allocation problem) + */ +extern int git_buf_puts_escaped( + git_buf *buf, + const char *string, + const char *esc_chars, + const char *esc_with); + +/** + * Append string escaping characters that are regex special + */ +GIT_INLINE(int) git_buf_puts_escape_regex(git_buf *buf, const char *string) +{ + return git_buf_puts_escaped(buf, string, "^.[]$()|*+?{}\\", "\\"); +} + +/** + * Unescape all characters in a buffer in place + * + * I.e. remove backslashes + */ +extern void git_buf_unescape(git_buf *buf); + +/** + * Replace all \r\n with \n. + * + * @return 0 on success, -1 on memory error + */ +extern int git_buf_crlf_to_lf(git_buf *tgt, const git_buf *src); + +/** + * Replace all \n with \r\n. Does not modify existing \r\n. + * + * @return 0 on success, -1 on memory error + */ +extern int git_buf_lf_to_crlf(git_buf *tgt, const git_buf *src); + +/** + * Fill buffer with the common prefix of a array of strings + * + * Buffer will be set to empty if there is no common prefix + */ +extern int git_buf_common_prefix(git_buf *buf, const git_strarray *strs); + +/** + * Check if a buffer begins with a UTF BOM + * + * @param bom Set to the type of BOM detected or GIT_BOM_NONE + * @param buf Buffer in which to check the first bytes for a BOM + * @return Number of bytes of BOM data (or 0 if no BOM found) + */ +extern int git_buf_detect_bom(git_bom_t *bom, const git_buf *buf); + +/** + * Gather stats for a piece of text + * + * Fill the `stats` structure with counts of unreadable characters, carriage + * returns, etc, so it can be used in heuristics. This automatically skips + * a trailing EOF (\032 character). Also it will look for a BOM at the + * start of the text and can be told to skip that as well. + * + * @param stats Structure to be filled in + * @param buf Text to process + * @param skip_bom Exclude leading BOM from stats if true + * @return Does the buffer heuristically look like binary data + */ +extern bool git_buf_gather_text_stats( + git_buf_text_stats *stats, const git_buf *buf, bool skip_bom); + #endif diff --git a/src/checkout.c b/src/checkout.c index cadc4c82d44..27bf6fe0053 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -26,7 +26,6 @@ #include "diff.h" #include "diff_generate.h" #include "pathspec.h" -#include "buf_text.h" #include "diff_xdiff.h" #include "path.h" #include "attr.h" diff --git a/src/config.c b/src/config.c index a6a8cb246a1..7a5dadd87cc 100644 --- a/src/config.c +++ b/src/config.c @@ -10,7 +10,6 @@ #include "git2/config.h" #include "git2/sys/config.h" -#include "buf_text.h" #include "config_backend.h" #include "regexp.h" #include "sysdir.h" @@ -1497,7 +1496,7 @@ int git_config_rename_section( int error = 0; struct rename_data data; - git_buf_text_puts_escape_regex(&pattern, old_section_name); + git_buf_puts_escape_regex(&pattern, old_section_name); if ((error = git_buf_puts(&pattern, "\\..+")) < 0) goto cleanup; diff --git a/src/config_parse.c b/src/config_parse.c index 7da92d3e72d..ea32c36bad2 100644 --- a/src/config_parse.c +++ b/src/config_parse.c @@ -7,8 +7,6 @@ #include "config_parse.h" -#include "buf_text.h" - #include const char *git_config_escapes = "ntb\"\\"; @@ -231,7 +229,7 @@ static int skip_bom(git_parse_ctx *parser) { git_buf buf = GIT_BUF_INIT_CONST(parser->content, parser->content_len); git_bom_t bom; - int bom_offset = git_buf_text_detect_bom(&bom, &buf); + int bom_offset = git_buf_detect_bom(&bom, &buf); if (bom == GIT_BOM_UTF8) git_parse_advance_chars(parser, bom_offset); diff --git a/src/crlf.c b/src/crlf.c index 81b5216bc17..1de9d8c3bc6 100644 --- a/src/crlf.c +++ b/src/crlf.c @@ -15,7 +15,6 @@ #include "futils.h" #include "hash.h" #include "filter.h" -#include "buf_text.h" #include "repository.h" typedef enum { @@ -219,7 +218,7 @@ static int crlf_apply_to_odb( if (ca->crlf_action == GIT_CRLF_BINARY || !git_buf_len(from)) return GIT_PASSTHROUGH; - is_binary = git_buf_text_gather_stats(&stats, from, false); + is_binary = git_buf_gather_text_stats(&stats, from, false); /* Heuristics to see if we can skip the conversion. * Straight from Core Git. @@ -247,7 +246,7 @@ static int crlf_apply_to_odb( return GIT_PASSTHROUGH; /* Actually drop the carriage returns */ - return git_buf_text_crlf_to_lf(to, from); + return git_buf_crlf_to_lf(to, from); } static int crlf_apply_to_workdir( @@ -262,7 +261,7 @@ static int crlf_apply_to_workdir( if (git_buf_len(from) == 0 || output_eol(ca) != GIT_EOL_CRLF) return GIT_PASSTHROUGH; - is_binary = git_buf_text_gather_stats(&stats, from, false); + is_binary = git_buf_gather_text_stats(&stats, from, false); /* If there are no LFs, or all LFs are part of a CRLF, nothing to do */ if (stats.lf == 0 || stats.lf == stats.crlf) @@ -281,7 +280,7 @@ static int crlf_apply_to_workdir( return GIT_PASSTHROUGH; } - return git_buf_text_lf_to_crlf(to, from); + return git_buf_lf_to_crlf(to, from); } static int convert_attrs( diff --git a/src/diff_driver.c b/src/diff_driver.c index 6b19012c771..e9f63cb1760 100644 --- a/src/diff_driver.c +++ b/src/diff_driver.c @@ -13,7 +13,6 @@ #include "diff.h" #include "strmap.h" #include "map.h" -#include "buf_text.h" #include "config.h" #include "regexp.h" #include "repository.h" @@ -428,8 +427,8 @@ int git_diff_driver_content_is_binary( * let's just use the simple NUL-byte detection that core git uses. */ - /* previously was: if (git_buf_text_is_binary(&search)) */ - if (git_buf_text_contains_nul(&search)) + /* previously was: if (git_buf_is_binary(&search)) */ + if (git_buf_contains_nul(&search)) return 1; return 0; diff --git a/src/ident.c b/src/ident.c index 7eccf9a4358..ae3ef1b4514 100644 --- a/src/ident.c +++ b/src/ident.c @@ -10,7 +10,6 @@ #include "git2/sys/filter.h" #include "filter.h" #include "buffer.h" -#include "buf_text.h" static int ident_find_id( const char **id_start, const char **id_end, const char *start, size_t len) @@ -105,7 +104,7 @@ static int ident_apply( GIT_UNUSED(self); GIT_UNUSED(payload); /* Don't filter binary files */ - if (git_buf_text_is_binary(from)) + if (git_buf_is_binary(from)) return GIT_PASSTHROUGH; if (git_filter_source_mode(src) == GIT_FILTER_SMUDGE) diff --git a/src/pathspec.c b/src/pathspec.c index 8b17a6e2774..8f1bdf0fa6c 100644 --- a/src/pathspec.c +++ b/src/pathspec.c @@ -9,7 +9,6 @@ #include "git2/pathspec.h" #include "git2/diff.h" -#include "buf_text.h" #include "attr_file.h" #include "iterator.h" #include "repository.h" @@ -25,7 +24,7 @@ char *git_pathspec_prefix(const git_strarray *pathspec) const char *scan; if (!pathspec || !pathspec->count || - git_buf_text_common_prefix(&prefix, pathspec) < 0) + git_buf_common_prefix(&prefix, pathspec) < 0) return NULL; /* diff prefix will only be leading non-wildcards */ @@ -41,7 +40,7 @@ char *git_pathspec_prefix(const git_strarray *pathspec) return NULL; } - git_buf_text_unescape(&prefix); + git_buf_unescape(&prefix); return git_buf_detach(&prefix); } diff --git a/src/submodule.c b/src/submodule.c index 1d059a043da..14869452fc0 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -12,7 +12,6 @@ #include "git2/types.h" #include "git2/index.h" #include "buffer.h" -#include "buf_text.h" #include "vector.h" #include "posix.h" #include "config_backend.h" diff --git a/tests/apply/fromdiff.c b/tests/apply/fromdiff.c index e9329f6d3fb..69dfe0987a8 100644 --- a/tests/apply/fromdiff.c +++ b/tests/apply/fromdiff.c @@ -3,7 +3,6 @@ #include "apply.h" #include "repository.h" -#include "buf_text.h" #include "../patch/patch_common.h" diff --git a/tests/apply/fromfile.c b/tests/apply/fromfile.c index 477e283adcb..ae519eab051 100644 --- a/tests/apply/fromfile.c +++ b/tests/apply/fromfile.c @@ -5,7 +5,6 @@ #include "patch.h" #include "patch_parse.h" #include "repository.h" -#include "buf_text.h" #include "../patch/patch_common.h" diff --git a/tests/apply/partial.c b/tests/apply/partial.c index 466a9271774..548faaadb14 100644 --- a/tests/apply/partial.c +++ b/tests/apply/partial.c @@ -3,7 +3,6 @@ #include "apply.h" #include "repository.h" -#include "buf_text.h" #include "../patch/patch_common.h" diff --git a/tests/core/buffer.c b/tests/core/buffer.c index 4e895afd97c..22fa75e39ed 100644 --- a/tests/core/buffer.c +++ b/tests/core/buffer.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "buffer.h" -#include "buf_text.h" #include "git2/sys/hashsig.h" #include "futils.h" @@ -644,37 +643,37 @@ void test_core_buffer__11(void) t.strings = t1; t.count = 3; - cl_git_pass(git_buf_text_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, &t)); cl_assert_equal_s(a.ptr, ""); t.strings = t2; t.count = 3; - cl_git_pass(git_buf_text_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, &t)); cl_assert_equal_s(a.ptr, "some"); t.strings = t3; t.count = 3; - cl_git_pass(git_buf_text_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, &t)); cl_assert_equal_s(a.ptr, ""); t.strings = t4; t.count = 3; - cl_git_pass(git_buf_text_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, &t)); cl_assert_equal_s(a.ptr, "happ"); t.strings = t5; t.count = 3; - cl_git_pass(git_buf_text_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, &t)); cl_assert_equal_s(a.ptr, "happ"); t.strings = t6; t.count = 3; - cl_git_pass(git_buf_text_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, &t)); cl_assert_equal_s(a.ptr, ""); t.strings = t7; t.count = 3; - cl_git_pass(git_buf_text_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, &t)); cl_assert_equal_s(a.ptr, ""); git_buf_dispose(&a); @@ -709,19 +708,19 @@ void test_core_buffer__puts_escaped(void) git_buf a = GIT_BUF_INIT; git_buf_clear(&a); - cl_git_pass(git_buf_text_puts_escaped(&a, "this is a test", "", "")); + cl_git_pass(git_buf_puts_escaped(&a, "this is a test", "", "")); cl_assert_equal_s("this is a test", a.ptr); git_buf_clear(&a); - cl_git_pass(git_buf_text_puts_escaped(&a, "this is a test", "t", "\\")); + cl_git_pass(git_buf_puts_escaped(&a, "this is a test", "t", "\\")); cl_assert_equal_s("\\this is a \\tes\\t", a.ptr); git_buf_clear(&a); - cl_git_pass(git_buf_text_puts_escaped(&a, "this is a test", "i ", "__")); + cl_git_pass(git_buf_puts_escaped(&a, "this is a test", "i ", "__")); cl_assert_equal_s("th__is__ __is__ a__ test", a.ptr); git_buf_clear(&a); - cl_git_pass(git_buf_text_puts_escape_regex(&a, "^match\\s*[A-Z]+.*")); + cl_git_pass(git_buf_puts_escape_regex(&a, "^match\\s*[A-Z]+.*")); cl_assert_equal_s("\\^match\\\\s\\*\\[A-Z\\]\\+\\.\\*", a.ptr); git_buf_dispose(&a); @@ -731,7 +730,7 @@ static void assert_unescape(char *expected, char *to_unescape) { git_buf buf = GIT_BUF_INIT; cl_git_pass(git_buf_sets(&buf, to_unescape)); - git_buf_text_unescape(&buf); + git_buf_unescape(&buf); cl_assert_equal_s(expected, buf.ptr); cl_assert_equal_sz(strlen(expected), buf.size); @@ -864,20 +863,20 @@ void test_core_buffer__classify_with_utf8(void) git_buf b; b.ptr = data0; b.size = b.asize = data0len; - cl_assert(!git_buf_text_is_binary(&b)); - cl_assert(!git_buf_text_contains_nul(&b)); + cl_assert(!git_buf_is_binary(&b)); + cl_assert(!git_buf_contains_nul(&b)); b.ptr = data1; b.size = b.asize = data1len; - cl_assert(!git_buf_text_is_binary(&b)); - cl_assert(!git_buf_text_contains_nul(&b)); + cl_assert(!git_buf_is_binary(&b)); + cl_assert(!git_buf_contains_nul(&b)); b.ptr = data2; b.size = b.asize = data2len; - cl_assert(git_buf_text_is_binary(&b)); - cl_assert(git_buf_text_contains_nul(&b)); + cl_assert(git_buf_is_binary(&b)); + cl_assert(git_buf_contains_nul(&b)); b.ptr = data3; b.size = b.asize = data3len; - cl_assert(!git_buf_text_is_binary(&b)); - cl_assert(!git_buf_text_contains_nul(&b)); + cl_assert(!git_buf_is_binary(&b)); + cl_assert(!git_buf_contains_nul(&b)); } #define SIMILARITY_TEST_DATA_1 \ @@ -1074,80 +1073,80 @@ void test_core_buffer__lf_and_crlf_conversions(void) git_buf_sets(&src, "lf\nlf\nlf\nlf\n"); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf("lf\r\nlf\r\nlf\r\nlf\r\n", tgt); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf(src.ptr, tgt); git_buf_sets(&src, "\nlf\nlf\nlf\nlf\nlf"); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf("\r\nlf\r\nlf\r\nlf\r\nlf\r\nlf", tgt); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf(src.ptr, tgt); /* CRLF source */ git_buf_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n"); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf("crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n", tgt); git_buf_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n"); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf("crlf\ncrlf\ncrlf\ncrlf\n", tgt); git_buf_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf"); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf("\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf", tgt); git_buf_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf"); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf("\ncrlf\ncrlf\ncrlf\ncrlf\ncrlf", tgt); /* CRLF in LF text */ git_buf_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n"); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf("\r\nlf\r\nlf\r\ncrlf\r\nlf\r\nlf\r\ncrlf\r\n", tgt); git_buf_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n"); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf("\nlf\nlf\ncrlf\nlf\nlf\ncrlf\n", tgt); /* LF in CRLF text */ git_buf_sets(&src, "\ncrlf\r\ncrlf\r\nlf\ncrlf\r\ncrlf"); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf("\r\ncrlf\r\ncrlf\r\nlf\r\ncrlf\r\ncrlf", tgt); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf("\ncrlf\ncrlf\nlf\ncrlf\ncrlf", tgt); /* bare CR test */ git_buf_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r"); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf("\rcrlf\r\nlf\r\nlf\r\ncr\rcrlf\r\nlf\r\ncr\r", tgt); git_buf_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r"); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf("\rcrlf\nlf\nlf\ncr\rcrlf\nlf\ncr\r", tgt); git_buf_sets(&src, "\rcr\r"); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf(src.ptr, tgt); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf("\rcr\r", tgt); git_buf_dispose(&src); @@ -1156,37 +1155,37 @@ void test_core_buffer__lf_and_crlf_conversions(void) /* blob correspondence tests */ git_buf_sets(&src, ALL_CRLF_TEXT_RAW); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf(ALL_CRLF_TEXT_AS_CRLF, tgt); git_buf_sets(&src, ALL_CRLF_TEXT_RAW); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf(ALL_CRLF_TEXT_AS_LF, tgt); git_buf_dispose(&src); git_buf_dispose(&tgt); git_buf_sets(&src, ALL_LF_TEXT_RAW); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf(ALL_LF_TEXT_AS_CRLF, tgt); git_buf_sets(&src, ALL_LF_TEXT_RAW); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf(ALL_LF_TEXT_AS_LF, tgt); git_buf_dispose(&src); git_buf_dispose(&tgt); git_buf_sets(&src, MORE_CRLF_TEXT_RAW); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf(MORE_CRLF_TEXT_AS_CRLF, tgt); git_buf_sets(&src, MORE_CRLF_TEXT_RAW); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf(MORE_CRLF_TEXT_AS_LF, tgt); git_buf_dispose(&src); git_buf_dispose(&tgt); git_buf_sets(&src, MORE_LF_TEXT_RAW); - cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); check_buf(MORE_LF_TEXT_AS_CRLF, tgt); git_buf_sets(&src, MORE_LF_TEXT_RAW); - cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); check_buf(MORE_LF_TEXT_AS_LF, tgt); git_buf_dispose(&src); git_buf_dispose(&tgt); diff --git a/tests/diff/patch.c b/tests/diff/patch.c index 7eb353627ad..d288bba58aa 100644 --- a/tests/diff/patch.c +++ b/tests/diff/patch.c @@ -4,7 +4,6 @@ #include "diff_helpers.h" #include "diff.h" #include "repository.h" -#include "buf_text.h" static git_repository *g_repo = NULL; diff --git a/tests/diff/rename.c b/tests/diff/rename.c index df32eebf247..aaae3e95bc5 100644 --- a/tests/diff/rename.c +++ b/tests/diff/rename.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "diff_helpers.h" -#include "buf_text.h" static git_repository *g_repo = NULL; @@ -513,7 +512,7 @@ void test_diff_rename__working_directory_changes(void) cl_git_pass( git_futils_readbuffer(&old_content, "renames/songof7cities.txt")); cl_git_pass( - git_buf_text_lf_to_crlf(&content, &old_content)); + git_buf_lf_to_crlf(&content, &old_content)); cl_git_pass( git_futils_writebuffer(&content, "renames/songof7cities.txt", 0, 0)); diff --git a/tests/filter/custom.c b/tests/filter/custom.c index fe2025fc2c9..8626e4b7c2a 100644 --- a/tests/filter/custom.c +++ b/tests/filter/custom.c @@ -2,7 +2,6 @@ #include "posix.h" #include "blob.h" #include "filter.h" -#include "buf_text.h" #include "git2/sys/filter.h" #include "git2/sys/repository.h" #include "custom_helpers.h" diff --git a/tests/filter/custom_helpers.c b/tests/filter/custom_helpers.c index d7f2afe7af9..233ba3219f9 100644 --- a/tests/filter/custom_helpers.c +++ b/tests/filter/custom_helpers.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "posix.h" #include "filter.h" -#include "buf_text.h" #include "git2/sys/filter.h" #define VERY_SECURE_ENCRYPTION(b) ((b) ^ 0xff) diff --git a/tests/filter/stream.c b/tests/filter/stream.c index 226092c3f32..b6a4c3ca1fa 100644 --- a/tests/filter/stream.c +++ b/tests/filter/stream.c @@ -2,7 +2,6 @@ #include "posix.h" #include "blob.h" #include "filter.h" -#include "buf_text.h" #include "git2/sys/filter.h" #include "git2/sys/repository.h" diff --git a/tests/filter/wildcard.c b/tests/filter/wildcard.c index 3c25ea26613..42f2960544a 100644 --- a/tests/filter/wildcard.c +++ b/tests/filter/wildcard.c @@ -2,7 +2,6 @@ #include "posix.h" #include "blob.h" #include "filter.h" -#include "buf_text.h" #include "git2/sys/filter.h" #include "git2/sys/repository.h" #include "custom_helpers.h" diff --git a/tests/mailmap/parsing.c b/tests/mailmap/parsing.c index e2ab05c99e0..ba3b3a2f6db 100644 --- a/tests/mailmap/parsing.c +++ b/tests/mailmap/parsing.c @@ -2,7 +2,6 @@ #include "repository.h" #include "git2/sys/repository.h" #include "mailmap_testdata.h" -#include "buf_text.h" static git_repository *g_repo; static git_mailmap *g_mailmap; @@ -109,7 +108,7 @@ void test_mailmap_parsing__windows_string(void) /* Parse with windows-style line endings */ git_buf_attach_notowned(&unixbuf, string_mailmap, strlen(string_mailmap)); - cl_git_pass(git_buf_text_lf_to_crlf(&winbuf, &unixbuf)); + cl_git_pass(git_buf_lf_to_crlf(&winbuf, &unixbuf)); cl_git_pass(git_mailmap_from_buffer(&g_mailmap, winbuf.ptr, winbuf.size)); git_buf_dispose(&winbuf); diff --git a/tests/object/blob/filter.c b/tests/object/blob/filter.c index 0f0f4845f39..a3921f4a047 100644 --- a/tests/object/blob/filter.c +++ b/tests/object/blob/filter.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "posix.h" #include "blob.h" -#include "buf_text.h" static git_repository *g_repo = NULL; @@ -97,7 +96,7 @@ void test_object_blob_filter__stats(void) for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) { cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i])); cl_git_pass(git_blob__getbuf(&buf, blob)); - git_buf_text_gather_stats(&stats, &buf, false); + git_buf_gather_text_stats(&stats, &buf, false); cl_assert_equal_i( 0, memcmp(&g_crlf_filtered_stats[i], &stats, sizeof(stats))); git_blob_free(blob); From 14f6950bcecd2f6c254ab3108b0ac8b267983713 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 10 May 2021 23:14:17 +0100 Subject: [PATCH 0306/1616] buf: bom enum is in the buf namespace Instead of a `git_bom_t` that a `git_buf` function returns, let's keep it `git_buf_bom_t`. --- src/attr_file.c | 4 ++-- src/buffer.c | 18 +++++++++--------- src/buffer.h | 18 +++++++++--------- src/config_parse.c | 4 ++-- tests/object/blob/filter.c | 6 +++--- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/attr_file.c b/src/attr_file.c index 6575e5a4956..82692727dd2 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -122,7 +122,7 @@ int git_attr_file__load( struct stat st; bool nonexistent = false; int bom_offset; - git_bom_t bom; + git_buf_bom_t bom; git_oid id; git_object_size_t blobsize; @@ -193,7 +193,7 @@ int git_attr_file__load( content_str = git_buf_cstr(&content); bom_offset = git_buf_detect_bom(&bom, &content); - if (bom == GIT_BOM_UTF8) + if (bom == GIT_BUF_BOM_UTF8) content_str += bom_offset; /* store the key of the attr_reader; don't bother with cache diff --git a/src/buffer.c b/src/buffer.c index ffce73c68a1..794e1f1abf6 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1227,12 +1227,12 @@ int git_buf_common_prefix(git_buf *buf, const git_strarray *strings) int git_buf_is_binary(const git_buf *buf) { const char *scan = buf->ptr, *end = buf->ptr + buf->size; - git_bom_t bom; + git_buf_bom_t bom; int printable = 0, nonprintable = 0; scan += git_buf_detect_bom(&bom, buf); - if (bom > GIT_BOM_UTF8) + if (bom > GIT_BUF_BOM_UTF8) return 1; while (scan < end) { @@ -1257,12 +1257,12 @@ int git_buf_contains_nul(const git_buf *buf) return (memchr(buf->ptr, '\0', buf->size) != NULL); } -int git_buf_detect_bom(git_bom_t *bom, const git_buf *buf) +int git_buf_detect_bom(git_buf_bom_t *bom, const git_buf *buf) { const char *ptr; size_t len; - *bom = GIT_BOM_NONE; + *bom = GIT_BUF_BOM_NONE; /* need at least 2 bytes to look for any BOM */ if (buf->size < 2) return 0; @@ -1273,19 +1273,19 @@ int git_buf_detect_bom(git_bom_t *bom, const git_buf *buf) switch (*ptr++) { case 0: if (len >= 4 && ptr[0] == 0 && ptr[1] == '\xFE' && ptr[2] == '\xFF') { - *bom = GIT_BOM_UTF32_BE; + *bom = GIT_BUF_BOM_UTF32_BE; return 4; } break; case '\xEF': if (len >= 3 && ptr[0] == '\xBB' && ptr[1] == '\xBF') { - *bom = GIT_BOM_UTF8; + *bom = GIT_BUF_BOM_UTF8; return 3; } break; case '\xFE': if (*ptr == '\xFF') { - *bom = GIT_BOM_UTF16_BE; + *bom = GIT_BUF_BOM_UTF16_BE; return 2; } break; @@ -1293,10 +1293,10 @@ int git_buf_detect_bom(git_bom_t *bom, const git_buf *buf) if (*ptr != '\xFE') break; if (len >= 4 && ptr[1] == 0 && ptr[2] == 0) { - *bom = GIT_BOM_UTF32_LE; + *bom = GIT_BUF_BOM_UTF32_LE; return 4; } else { - *bom = GIT_BOM_UTF16_LE; + *bom = GIT_BUF_BOM_UTF16_LE; return 2; } break; diff --git a/src/buffer.h b/src/buffer.h index e75ecc15c34..d043ed62609 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -18,16 +18,16 @@ */ typedef enum { - GIT_BOM_NONE = 0, - GIT_BOM_UTF8 = 1, - GIT_BOM_UTF16_LE = 2, - GIT_BOM_UTF16_BE = 3, - GIT_BOM_UTF32_LE = 4, - GIT_BOM_UTF32_BE = 5 -} git_bom_t; + GIT_BUF_BOM_NONE = 0, + GIT_BUF_BOM_UTF8 = 1, + GIT_BUF_BOM_UTF16_LE = 2, + GIT_BUF_BOM_UTF16_BE = 3, + GIT_BUF_BOM_UTF32_LE = 4, + GIT_BUF_BOM_UTF32_BE = 5 +} git_buf_bom_t; typedef struct { - git_bom_t bom; /* BOM found at head of text */ + git_buf_bom_t bom; /* BOM found at head of text */ unsigned int nul, cr, lf, crlf; /* NUL, CR, LF and CRLF counts */ unsigned int printable, nonprintable; /* These are just approximations! */ } git_buf_text_stats; @@ -293,7 +293,7 @@ extern int git_buf_common_prefix(git_buf *buf, const git_strarray *strs); * @param buf Buffer in which to check the first bytes for a BOM * @return Number of bytes of BOM data (or 0 if no BOM found) */ -extern int git_buf_detect_bom(git_bom_t *bom, const git_buf *buf); +extern int git_buf_detect_bom(git_buf_bom_t *bom, const git_buf *buf); /** * Gather stats for a piece of text diff --git a/src/config_parse.c b/src/config_parse.c index ea32c36bad2..a2d779bfaa5 100644 --- a/src/config_parse.c +++ b/src/config_parse.c @@ -228,10 +228,10 @@ static int parse_section_header(git_config_parser *reader, char **section_out) static int skip_bom(git_parse_ctx *parser) { git_buf buf = GIT_BUF_INIT_CONST(parser->content, parser->content_len); - git_bom_t bom; + git_buf_bom_t bom; int bom_offset = git_buf_detect_bom(&bom, &buf); - if (bom == GIT_BOM_UTF8) + if (bom == GIT_BUF_BOM_UTF8) git_parse_advance_chars(parser, bom_offset); /* TODO: reference implementation is pretty stupid with BoM */ diff --git a/tests/object/blob/filter.c b/tests/object/blob/filter.c index a3921f4a047..a8e3d3097b8 100644 --- a/tests/object/blob/filter.c +++ b/tests/object/blob/filter.c @@ -43,9 +43,9 @@ static git_buf_text_stats g_crlf_filtered_stats[CRLF_NUM_TEST_OBJECTS] = { { 0, 0, 2, 2, 2, 6, 0 }, { 0, 0, 4, 4, 1, 31, 0 }, { 0, 1, 1, 2, 1, 9, 5 }, - { GIT_BOM_UTF8, 0, 0, 1, 0, 16, 0 }, - { GIT_BOM_UTF8, 0, 2, 2, 2, 27, 0 }, - { GIT_BOM_UTF16_BE, 5, 0, 0, 0, 7, 5 }, + { GIT_BUF_BOM_UTF8, 0, 0, 1, 0, 16, 0 }, + { GIT_BUF_BOM_UTF8, 0, 2, 2, 2, 27, 0 }, + { GIT_BUF_BOM_UTF16_BE, 5, 0, 0, 0, 7, 5 }, }; void test_object_blob_filter__initialize(void) From a2d953e5ed48112ec132fc0f38f92ba66095c477 Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Wed, 12 May 2021 10:29:45 +0300 Subject: [PATCH 0307/1616] branch: git branch upstream with format has been added. --- src/branch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/branch.c b/src/branch.c index 29ff0b9d99d..ff790b980f9 100644 --- a/src/branch.c +++ b/src/branch.c @@ -468,7 +468,7 @@ int git_branch_upstream_name( return error; } -int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname) +static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, const char *refname, const char *format) { int error; git_config *cfg; @@ -480,7 +480,7 @@ int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *r return error; if ((error = git_buf_sanitize(buf)) < 0 || - (error = retrieve_upstream_configuration(buf, cfg, refname, "branch.%s.remote")) < 0) + (error = retrieve_upstream_configuration(buf, cfg, refname, format)) < 0) return error; if (git_buf_len(buf) == 0) { From 7d9599bd22521627b50527d394f1bb7c51252139 Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Wed, 12 May 2021 10:30:12 +0300 Subject: [PATCH 0308/1616] branch: git branch upstream merge has been exposed. --- include/git2/branch.h | 13 +++++++++++++ src/branch.c | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/include/git2/branch.h b/include/git2/branch.h index 0c0cc7ff78b..24ea7f7d0f3 100644 --- a/include/git2/branch.h +++ b/include/git2/branch.h @@ -304,6 +304,19 @@ GIT_EXTERN(int) git_branch_remote_name( */ GIT_EXTERN(int) git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname); +/** + * Retrieve the upstream merge of a local branch + * + * This will return the currently configured "branch.*.merge" for a given + * branch. This branch must be local. + * + * @param buf the buffer into which to write the name + * @param repo the repository in which to look + * @param refname the full name of the branch + * @return 0 or an error code + */ + GIT_EXTERN(int) git_branch_upstream_merge(git_buf *buf, git_repository *repo, const char *refname); + /** * Determine whether a branch name is valid, meaning that (when prefixed * with `refs/heads/`) that it is a valid reference name, and that any diff --git a/src/branch.c b/src/branch.c index ff790b980f9..55b748cb274 100644 --- a/src/branch.c +++ b/src/branch.c @@ -492,6 +492,14 @@ static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, c return error; } +int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname) { + git_branch_upstream_with_format(buf, repo, refname, "branch.%s.remote"); +} + +int git_branch_upstream_merge(git_buf *buf, git_repository *repo, const char *refname) { + git_branch_upstream_with_format(buf, repo, refname, "branch.%s.merge"); +} + int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refname) { git_strarray remote_list = {0}; From 049618cebe5848e8c5456c32fd136aefdeecccc6 Mon Sep 17 00:00:00 2001 From: Tyler Ang-Wanek Date: Fri, 30 Apr 2021 15:11:54 -0700 Subject: [PATCH 0309/1616] httpclient: git_http_client_skip_body should drain socket of body --- src/transports/httpclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index d3975746b73..4ba6da01720 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -1503,7 +1503,7 @@ int git_http_client_skip_body(git_http_client *client) "unexpected data handled in callback"); error = -1; } - } while (!error); + } while (error >= 0 && client->state != DONE); if (error < 0) client->connected = 0; From 3473a088c645b8361f7b72747610a4a21088a7ed Mon Sep 17 00:00:00 2001 From: Tyler Ang-Wanek Date: Wed, 12 May 2021 11:48:23 -0700 Subject: [PATCH 0310/1616] httpclient: no proxy creds in requests if proxy is CONNECT type --- src/transports/httpclient.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index 4ba6da01720..ba86184dfc8 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -681,6 +681,11 @@ static int generate_connect_request( return git_buf_oom(buf) ? -1 : 0; } +static bool use_connect_proxy(git_http_client *client) +{ + return client->proxy.url.host && !strcmp(client->server.url.scheme, "https"); +} + static int generate_request( git_http_client *client, git_http_request *request) @@ -734,7 +739,8 @@ static int generate_request( git_buf_printf(buf, "Expect: 100-continue\r\n"); if ((error = apply_server_credentials(buf, client, request)) < 0 || - (error = apply_proxy_credentials(buf, client, request)) < 0) + (!use_connect_proxy(client) && + (error = apply_proxy_credentials(buf, client, request)) < 0)) return error; if (request->custom_headers) { @@ -1027,8 +1033,7 @@ static int http_client_connect( reset_parser(client); /* Reconnect to the proxy if necessary. */ - use_proxy = client->proxy.url.host && - !strcmp(client->server.url.scheme, "https"); + use_proxy = use_connect_proxy(client); if (use_proxy) { if (!client->proxy_connected || !client->keepalive || From 4c462bb6f3a5c9122a98cc921123ce6696edfa89 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 13 Apr 2021 13:20:34 -0400 Subject: [PATCH 0311/1616] diff: Fix bug in git_diff_find_similar. When a split src gets turned into a rename, it should also lose the IS_RENAME_TARGET flag, so that it doesn't get processed in a subsequent iteration as a rename target. Doing so can cause an assertion failure because it no longer has the SPLIT flag. Fixes #5811. --- src/diff_tform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diff_tform.c b/src/diff_tform.c index 409142081e8..908175d3412 100644 --- a/src/diff_tform.c +++ b/src/diff_tform.c @@ -1039,7 +1039,7 @@ int git_diff_find_similar( memcpy(&src->old_file, &swap, sizeof(src->old_file)); /* if we've just swapped the new element into the correct - * place, clear the SPLIT flag + * place, clear the SPLIT and RENAME_TARGET flags */ if (tgt2src[s].idx == t && tgt2src[s].similarity > @@ -1047,7 +1047,7 @@ int git_diff_find_similar( src->status = GIT_DELTA_RENAMED; src->similarity = tgt2src[s].similarity; tgt2src[s].similarity = 0; - src->flags &= ~GIT_DIFF_FLAG__TO_SPLIT; + src->flags &= ~(GIT_DIFF_FLAG__TO_SPLIT | GIT_DIFF_FLAG__IS_RENAME_TARGET); num_rewrites--; } /* otherwise, if we just overwrote a source, update mapping */ From 2d24690c67713ce2e809f1393c96541bcf2662df Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Thu, 15 Apr 2021 07:48:43 -0400 Subject: [PATCH 0312/1616] Add testcase --- tests/diff/rename.c | 55 ++++++++++++++++++ tests/resources/renames/.gitted/ORIG_HEAD | 1 + tests/resources/renames/.gitted/index | Bin 352 -> 385 bytes tests/resources/renames/.gitted/logs/HEAD | 5 ++ .../41/2a2eaf2c13103ea976b3b02c17abee7a358432 | Bin 0 -> 82 bytes .../5a/71babaaac78a758b52576a60cea3c218c8b546 | Bin 0 -> 2804 bytes .../7e/7bfb88ba9bc65fd700fee1819cf1c317aafa56 | 2 + .../bf/102db0c9c0c1513909a90e0611b5dddfc87c93 | 2 + .../cc/980ffac5f1393696d4cd703ea9d2fde67dd367 | Bin 0 -> 2801 bytes .../db/98035f715427eef1f5e17f03e1801c05301e9e | Bin 0 -> 199 bytes .../eb/b3b7af1d25c8492d2f626826c92458b7cefd60 | Bin 0 -> 5164 bytes .../ed/2a95c4a6c295b9afcea50baff63ec544ccf600 | Bin 0 -> 5161 bytes .../f6/7e2f70efe89665e829ea0d77c46965ad1307e4 | Bin 0 -> 5164 bytes .../renames/.gitted/refs/heads/break_rewrite | 1 + 14 files changed, 66 insertions(+) create mode 100644 tests/resources/renames/.gitted/ORIG_HEAD create mode 100644 tests/resources/renames/.gitted/objects/41/2a2eaf2c13103ea976b3b02c17abee7a358432 create mode 100644 tests/resources/renames/.gitted/objects/5a/71babaaac78a758b52576a60cea3c218c8b546 create mode 100644 tests/resources/renames/.gitted/objects/7e/7bfb88ba9bc65fd700fee1819cf1c317aafa56 create mode 100644 tests/resources/renames/.gitted/objects/bf/102db0c9c0c1513909a90e0611b5dddfc87c93 create mode 100644 tests/resources/renames/.gitted/objects/cc/980ffac5f1393696d4cd703ea9d2fde67dd367 create mode 100644 tests/resources/renames/.gitted/objects/db/98035f715427eef1f5e17f03e1801c05301e9e create mode 100644 tests/resources/renames/.gitted/objects/eb/b3b7af1d25c8492d2f626826c92458b7cefd60 create mode 100644 tests/resources/renames/.gitted/objects/ed/2a95c4a6c295b9afcea50baff63ec544ccf600 create mode 100644 tests/resources/renames/.gitted/objects/f6/7e2f70efe89665e829ea0d77c46965ad1307e4 create mode 100644 tests/resources/renames/.gitted/refs/heads/break_rewrite diff --git a/tests/diff/rename.c b/tests/diff/rename.c index aaae3e95bc5..bd25d29aaba 100644 --- a/tests/diff/rename.c +++ b/tests/diff/rename.c @@ -21,6 +21,8 @@ void test_diff_rename__cleanup(void) #define RENAME_MODIFICATION_COMMIT "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13" #define REWRITE_DELETE_COMMIT "84d8efa38af7ace2b302de0adbda16b1f1cd2e1b" #define DELETE_RENAME_COMMIT "be053a189b0bbde545e0a3f59ce00b46ad29ce0d" +#define BREAK_REWRITE_BASE_COMMIT "db98035f715427eef1f5e17f03e1801c05301e9e" +#define BREAK_REWRITE_COMMIT "7e7bfb88ba9bc65fd700fee1819cf1c317aafa56" /* * Renames repo has: @@ -1977,3 +1979,56 @@ void test_diff_rename__delete_and_rename(void) git_tree_free(old_tree); git_tree_free(new_tree); } + +/* + * The break_rewrite branch contains a testcase reduced from + * a real-world scenario, rather than being "constructed" like + * the above tests seem to be. There are two commits layered + * on top of the repo's initial commit; the base commit which + * clears out the files from the initial commit and installs + * four files. And then there's the modification commit which + * mutates the files in such a way as to trigger the bug in + * libgit2. + * commit db98035f715427eef1f5e17f03e1801c05301e9e + * serving.txt (deleted) + * sevencities.txt (deleted) + * AAA (313 lines) + * BBB (314 lines) + * CCC (704 lines) + * DDD (314 lines, identical to BBB) + * commit 7e7bfb88ba9bc65fd700fee1819cf1c317aafa56 + * This deletes CCC and makes slight modifications + * to AAA, BBB, and DDD. The find_best_matches loop + * for git_diff_find_similar computes the following: + * CCC moved to AAA (similarity 91) + * CCC copied to AAA (similarity 91) + * DDD moved to BBB (similarity 52) + * CCC copied to BBB (similarity 90) + * BBB moved to DDD (similarity 52) + * CCC copied to DDD (similarity 90) + * The code to rewrite the diffs by resolving these + * copies/renames would resolve the BBB <-> DDD moves + * but then still leave BBB as a rename target for + * the deleted file CCC. Since the split flag on BBB + * was cleared, this would trigger an error. + */ +void test_diff_rename__break_rewrite(void) +{ + const char *old_sha = BREAK_REWRITE_BASE_COMMIT; + const char *new_sha = BREAK_REWRITE_COMMIT; + git_tree *old_tree, *new_tree; + git_diff *diff; + git_diff_find_options find_opts = GIT_DIFF_FIND_OPTIONS_INIT; + + old_tree = resolve_commit_oid_to_tree(g_repo, old_sha); + new_tree = resolve_commit_oid_to_tree(g_repo, new_sha); + + find_opts.flags = GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES | GIT_DIFF_BREAK_REWRITES | GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY; + + cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, old_tree, new_tree, NULL)); + cl_git_pass(git_diff_find_similar(diff, &find_opts)); + + git_diff_free(diff); + git_tree_free(old_tree); + git_tree_free(new_tree); +} diff --git a/tests/resources/renames/.gitted/ORIG_HEAD b/tests/resources/renames/.gitted/ORIG_HEAD new file mode 100644 index 00000000000..642c3198db7 --- /dev/null +++ b/tests/resources/renames/.gitted/ORIG_HEAD @@ -0,0 +1 @@ +19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 diff --git a/tests/resources/renames/.gitted/index b/tests/resources/renames/.gitted/index index 72363c0f52fba5560db5c0a127ddebfc47c0ba62..5882a8d605cebe2dfa9fb54c6e5fc3b610c0aced 100644 GIT binary patch delta 231 zcmaFB)W~e$;u+-3z`(!+#4HIF>W(Idk1)V!1_ll$hES>0p>Mjg|TAXitQLnRqZ6b!iH)K(wOifXwreZrRz iv6POPrym+}7A9HRJ5*km__nlY-i{s4&puwhq7MMs8%O2< delta 198 zcmZo_!TH6GSNUsB~Wb< z3q&1+2B~B0+181ot^uTOp&djWgodi?Kv8!Aq;7!$L>+{N*c*8XS>0p>Mjes-yh@Gf ThFsZ`SQVT#<1|!#^1{^sj;tqc diff --git a/tests/resources/renames/.gitted/logs/HEAD b/tests/resources/renames/.gitted/logs/HEAD index e697922635a..e6da6784e09 100644 --- a/tests/resources/renames/.gitted/logs/HEAD +++ b/tests/resources/renames/.gitted/logs/HEAD @@ -2,3 +2,8 @@ 31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 2bc7f351d20b53f1c72c16c4b036e491c478c49a Russell Belfer 1351024817 -0700 commit: copy and rename with no change 2bc7f351d20b53f1c72c16c4b036e491c478c49a 1c068dee5790ef1580cfc4cd670915b48d790084 Russell Belfer 1361485758 -0800 commit: rewrites, copies with changes, etc. 1c068dee5790ef1580cfc4cd670915b48d790084 19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 Russell Belfer 1361486360 -0800 commit: more renames and smallish modifications +19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 Kartikaya Gupta 1618486966 -0400 checkout: moving from master to break_rewrite +31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 db98035f715427eef1f5e17f03e1801c05301e9e Kartikaya Gupta 1618487039 -0400 commit: This test needs to start with a minimum of four files +db98035f715427eef1f5e17f03e1801c05301e9e 7e7bfb88ba9bc65fd700fee1819cf1c317aafa56 Kartikaya Gupta 1618487097 -0400 commit: Copy/modify files around +7e7bfb88ba9bc65fd700fee1819cf1c317aafa56 19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 Kartikaya Gupta 1618487105 -0400 checkout: moving from break_rewrite to master +19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 Kartikaya Gupta 1618487271 -0400 reset: moving to HEAD diff --git a/tests/resources/renames/.gitted/objects/41/2a2eaf2c13103ea976b3b02c17abee7a358432 b/tests/resources/renames/.gitted/objects/41/2a2eaf2c13103ea976b3b02c17abee7a358432 new file mode 100644 index 0000000000000000000000000000000000000000..d0d3334bf8e898c805b453e630d1f9a3591aa81f GIT binary patch literal 82 zcmV-Y0ImOc0V^p=O;xZoW-v4`Ff%bxaCCHJc&jz_$g)FIcdkFTlzaU*yQ3~=zQLrO ooSYcG)#(?!e=#lfh2|^X@*|n4YlYdLKy|ygxL}nA0O+YH!qw>~q5uE@ literal 0 HcmV?d00001 diff --git a/tests/resources/renames/.gitted/objects/5a/71babaaac78a758b52576a60cea3c218c8b546 b/tests/resources/renames/.gitted/objects/5a/71babaaac78a758b52576a60cea3c218c8b546 new file mode 100644 index 0000000000000000000000000000000000000000..e685bfaff3cd3ff871db0520b88a2abf237b1585 GIT binary patch literal 2804 zcmVsC4UybSX`Sa61HIJ!&T&G**$}?(x z@x?i5F|IE?SI^Gq**STED+66eV_aXDL4oI=lT#my*mLS?GKrGx&v(=!^gR(cl9ryH+2#5-4WhTH z05#Ua3rJvSxU#B3qy7yE%>rgxhiA>^a=C0Q)Q_I;i-wA(O$=zFn@0@QL@(JY*Nb)J zjT0?hO5n99Ta94*dME4=0UccqsWUtx_G5g)lD_SXUiI!q^zG$faM>NbrQS7NcHh!B zo$l2MN$3xm@-d8L45voqv2D_A&``1ijM^+`f#KJ}-v6Q~0It z)4&+ZVg@pn(F1&jFU<;q)mV4iySlq+Q@1y256^hm%OrH63DJ~Y{Z;dM^Yl5l^S|t4 zCH&P396y2iN39<3&(-LvF*~Xh%|ZNXbbB*WbAG@~mq?~Fs; z;r&(ny3=jncRE+qd1sh}aG;Ly?Swl!!@GXJHyGis&J~Ww_Gh0QsB1)+@hk@oR>Yne zY)mnUXK>5?`=+&g5nE+>C7x!ywKle(snG-OUMul_D8_3A@W?KUyhBy42KV_m6MMaod8h*NbBo}Li~d|fn544 z1{pH}2ItD!$&u7a6j;|kK0Xp4B=I#c&*jr~n8R^^f;bhF2mjgGzY`g)I+4~ZbkBtKFBvaF3X(t)9yB0JUKUwMWA(UbX{Mz+T6vSuJTT0uzy_J+{jw} z#ii>Gj?JYsYJ$P8RL!csa} z0JVXUC~=r5FiHZCZDviyn0XfK_T=sYZ}Y_gLL2z$89)NbVG;to1;SgA8GHf*7(Hba zfnr(c!+?X~6XG}n_AduRSd&628oP3tr$?Nn?2K+g=DSDPR9t$b%05A zJm*-dz_8A3|K|Sk>T1xwuI4(|@}5EarhPeVuXlZN3|`5Ju&EB4%K@b9o|eYSY0C48 zSlQhFPuc9;-m|m(&uWd%(m3XQ=6(6}Q+- zBUEwl*=iMIUzT>vq;N|+CQ9kjjgA0Y_R5jQ&>9r~ ze@_!Ky{BX8gZ*!1QycT|CH}vs^V5mblq;j+3?cMCD8;T%W~29H*5-j%7Xyv!9L!Y` z#j+)r^HE%m&**8aPiQ9n&=LaX-MmL!dqXk8R;L2glKDl!XOaZQW%iWc8c^MG=I30S z<~h#-_k==}3|Kf9_u`mK*|-KW1ag_%3+4t#(^A`?89={k{v(CYmpRkwa+w#_{?~gnxBw4C``J{^$)`iVORA!%4Qj9%31N***~RDd3)c` zMQqx&D&2YJRvBi*=_RxPk;ImJ7y(kyH2a@k_%;D?rWYw%@l}uuf){HDJMSuet?-a> zzJVi~BKG0nK1AhqS&GgKwR?I%lu@?dhOW#9_iVBb^-Xyqhle6@jM^$d5(SOs*EiKCP@NA#gbo4H1c{bkFBy&YJozovP4gO@o zGZPO6B0$y5{^?~yQRjvdjsEnuSB&L3cEf)Dg`_L z7!P<0hTeq;_xJ$Nm7bK{)iCR0mJ(s;;{m7K*9Ow}Ioi(rn6)MbVak^>efyTO6J?1H z%js5r5csg2BhcQwc|)&|?fydlN>Vb9YP~Jh=lpFS8{_B8Pq-MbC-C*FjnMQUB2OjA zxE_#~pJO@C!s%&26t$HAkH8TvQD+gTZ6J^0t2bGJnLP*}l|a6daGEu_yn**)kM9@R z(;OZxl({Q$;TLmeO3hgaGBJqiIGIlQjT*Qcd5(FRGfCOp2x@A+do2B#W_q#>PolnBOYkrvUbzWTco$*;Ojz0>&h+SsP37 zFwbuwh8$q{p;ec9N!jJKaVgV4c+yx`q-PSTxoZ^|wrM{-%uz*bYg=W-?3UB3mzX+W5YF#!kE4dZC zu?u?oqm1x;Yy!;&BPx^9<;Mj>KI8L^pA*m%rj|)yGCb@szg%G_92!w&EEALxKUH!2 zkqX5WiWE1C*T@7a`tJK8oUBiZ?W={W?FG=+fY@I-g8m1T Gj|E7_Yl;{E literal 0 HcmV?d00001 diff --git a/tests/resources/renames/.gitted/objects/7e/7bfb88ba9bc65fd700fee1819cf1c317aafa56 b/tests/resources/renames/.gitted/objects/7e/7bfb88ba9bc65fd700fee1819cf1c317aafa56 new file mode 100644 index 00000000000..e53c843dd35 --- /dev/null +++ b/tests/resources/renames/.gitted/objects/7e/7bfb88ba9bc65fd700fee1819cf1c317aafa56 @@ -0,0 +1,2 @@ +x¥ŽKn„0³ö)ú™éö)Š"e1‹9EcÚ +bÀÈ4 nî0ËWR•^®Ë2)ØŽ>´‰€'ËV¸ØLŽÐ ÷±܀׎<ˆDv!ygÍÆMV…qèºP"o£H¡„b¹TJHƒC’^ úW<¹é4óÉð86eøšY÷Ÿ×̳ÜvåYg¹åº|u”|ŠØGøDh.z½Uy·c~ëvÞ—:Nå„2½dnõXGó ©T´ \ No newline at end of file diff --git a/tests/resources/renames/.gitted/objects/bf/102db0c9c0c1513909a90e0611b5dddfc87c93 b/tests/resources/renames/.gitted/objects/bf/102db0c9c0c1513909a90e0611b5dddfc87c93 new file mode 100644 index 00000000000..69ddd683b18 --- /dev/null +++ b/tests/resources/renames/.gitted/objects/bf/102db0c9c0c1513909a90e0611b5dddfc87c93 @@ -0,0 +1,2 @@ +x+)JMU042a040031Qpttd83ƒÿ×Ñ–fÓ®œ-°[yéï³ÚËéPi'''†¨Â]»Vï*í +ÏJ8·øÄ‰­nPiggg†×›·¯—U=á©«Ÿ”¡vR%bû¹¿ Pi¬º¼:6Ž \ No newline at end of file diff --git a/tests/resources/renames/.gitted/objects/cc/980ffac5f1393696d4cd703ea9d2fde67dd367 b/tests/resources/renames/.gitted/objects/cc/980ffac5f1393696d4cd703ea9d2fde67dd367 new file mode 100644 index 0000000000000000000000000000000000000000..ac7a005e66865d4bb9d9e59f9e3e712e8d8c615d GIT binary patch literal 2801 zcmVM( z?(K3dt7-4I-!tUC=w+1`CFr$47YO1dm&2Li@R^50jeRwy=g*#g^QY!9)sO3Rqg;7P zt*^d1BQ3`DrRVC|DLpwOFK}g`>u8MY3-eLn`Df(R$0GKex|&R4sqv+ea@?#mk1KRc zqnRW}1sX$RQWMfMFQ$p-OA?W!I2r$2I-0aXhor95u_HoB{bcNW4qbbW3}VT0Udt%< zR6vg#kEqJu9(DWIN3}Crse~3{MS;?k#Byx{`QXSBX2)3_x!X6RO(Z!HD!y{rp#wRT4`_AZ9?{-ArUknBp-O*d>UC~AN zEq&MNUY?MI{*Wmj!brw&YD6B}Cfx=NB|E^V&2lE_k=(yqCTTp-Z-~4&tI1YP<)N zvt{M+EwxxAf#;;tv{V$T$h=@F`YN)sJCPLZz40m^%<*Ccge#*nRa-TB{QUW|;*<9Z zzwmt;7-Lz?K*lnWcfz(Pd+HR4E#R_|@p?Tvq3uVG_c9I>y@xcXo!i{eEvS!e5w?`pB$)bM40bc4jQb8 zJtNqdVi1qumb(uPYxyF!%JNJ+tb6f#b0k&FYSa&V%({#iV-`}+l#6vka67{H5lted zP(+%eRV5L%dN+07n@b>smeE8w@U0>lL1tgj;q@ek?* za_O%aV9Wp*oGWVwM^YzIU>*PP@IZi%#Mi((mv`1-4#(yR;#5!?_@}4;N@TR^WL~WT z|6^_K`x^-pX!pu?wy}qXN^R0P4X%hi zGH5gqk$8^Ry-w#;MdV@Q9@mgpy|@H5cu>j1_TZoNd7DhOw6Wj-MRG0rcC#SMfe|nc z{F?e?z_X^1VIuEWBn{|;JhS7l%vJAp7vcQTnQ1J-tZQTI>Y~-=F7|Vk*C_-1X29B04&#b5|)QW!;JS1v&!(j=Sh&rP@-81SxDIGnOLB~N2NBMoFN z91ZAaDCDkldV~#$hV=-shz7cO*SosAY2Wk)Z*9mGapdXxi!Dr_XFKYIsto3IjF4Oh zmQ=qpj-m=o>fH3N?=CJc2konBs&6fCAGELA7sGbZ@!64gDJQ}vH!LZKjj}6Q8X?b9 zR#!yG=Bj_r66Z-V{i9l=(=>8{k$8Le1@>8Htt)>c#{M_AHZzY7+azWo)(IV;BBgTx z3s-`@Y)N zX%or*5EobagKw4cGsHMOZHb^|b+7gZAaP$mq14io{M{H)V;e#27*J9n7QxOfFeAJ- zq-9d93)b_L9cG~dC$T?5<#!hP82zJmBr>;(7?43ml12oO5Q?s$}j17sR!6=`-Hq@bMw* zz0(n@G?zypeb#dYrG zDv5H~l8f~y9ml8iIMydLlYVHa0P}2KA+D~W;9%=d0V>6OU*I!2;%YQQ7~dqIe&x*1 zxbn3ex>FoWVQ*DEpy1jXNRz=dL4zaj4tIzfPYAxGWEV8 ziCD5LRl4rXsWQBX(}QLKAc-yL@a|6m)2x1awA%#3nO>ww#fLsF_?@qz>%6P8@4hZ+_4#(I&yVuG{YFu$P?x|i6_o4JF@c9 zrY*5vmFEW3i$xitYfqOC;6hf}0A&987WfucK*0}Mfg3hlk7ai@{w?(qSjE8Qu(vtiVyOeMn5#|2HfuMME@bF>}#DRWH>!jw;C`u0s_2g(v3 zmQ$^KBk*QBL!iBR^M+m_*Zqb5nWQux^>|y1&$-(^CdOBjpK%~wPv7f@8lmZ4M4n2J zZ#^I{U$t_Uh11ibCn_odE_fqaqPikb(Lff(t2bGJmE8*;H9wQdkz`FKZ{Tj&@xk&h_4-fh?Qi5$aT5co7&$}7|R$3L-uhS literal 0 HcmV?d00001 diff --git a/tests/resources/renames/.gitted/objects/db/98035f715427eef1f5e17f03e1801c05301e9e b/tests/resources/renames/.gitted/objects/db/98035f715427eef1f5e17f03e1801c05301e9e new file mode 100644 index 0000000000000000000000000000000000000000..48bc2e18692b6d7379916cb33b50aa9a75438ef3 GIT binary patch literal 199 zcmV;&067160i}*XPQ@?`1zGnLz5ri#(>96ph1juR%LUxTQKOQkN?ajsPw&9)X%;gt z)Kap-=4j4K8oFwjiKqi2tT3(-2q7*lXIcr%>bT%3(v z{X(-7lW?4(Ap0~9eCbvjd~(yg^Do24bt=PiXYKDNAAxsybmd(e2YG~A-hdWzle1_% zyyAp7-1L5{@?X#JwdD>fUEvUk_pETYo5D}l4H!y3a=8lB1gTyPQvQ}c`~lZTU!xEF BV7LGP literal 0 HcmV?d00001 diff --git a/tests/resources/renames/.gitted/objects/eb/b3b7af1d25c8492d2f626826c92458b7cefd60 b/tests/resources/renames/.gitted/objects/eb/b3b7af1d25c8492d2f626826c92458b7cefd60 new file mode 100644 index 0000000000000000000000000000000000000000..813e7ad903a322ee0d57d8d09e0fc603daaedb07 GIT binary patch literal 5164 zcmV+{6w~W?0qtCQZ{tRm-+$vzQPT_T+Mc%6ZKtz|3`CAtKyw7uS*qz-SYk5$fo( zn8`36fuKo{j_1KxigETq=4qUcMIMhQSehV>L=sQqGAKdj!r@JDFv)%VOaHwAxLz8U zagc~J`9UVx47iwu4Z#<#D^m|sHp@!=PqXQCp2ndb<}}M^S(ZgH@M7`m{ zb|!vN0A>ruS!|!~h}U0z^`&dF68K4yhyhQQzzk#|^ADgIJ~~@qR-WCvtF!kP=i>6} z=KQ)#&Ayq>B48rKm`MG3=gZDlUs5^!F+T<2-{Uk)=9vDAwD|Vs-No6>+5Y6kRtIJm)Eyv=WlzL=eNDy+4f!UdOiaI%K~37sj_$d zzTdwZ+~9w`Gl)m?*8=A>2?_;+IuIP1!!0JE;k5MYp#=}k<4`}_WeY!$b?WLpS%d`umxe)-fGvVT%!0fmw#(+ZIK6tem&A7xqF%~;6oeod_wS+0Yz_{CUH~L$ z8O2y6b+#=P0~&}eGS)`i6`+f33TeUuC}3P{`Ju@W;v2vSrbLF62q{DyF@9FTLGVM8 zIt9nJ4tgn;7J8{)=3<6FKqr;=$$~Tmcff=#vZ`|~%Xyxvh5GpMqktZmCnXeDL?ZGy zfDQL32NrMf^tOqV z`{zH;gQTbn^$ut$1g6>PM49NlPw&#~KHc93PvW;*rMfs4+u%J2;O-7gWL$W}pE`Md zG#~tt2?@%mfsGPzAY!rTD{+Crf^jF!@mu0!R8<8bb}H5(qLuQaXtP8zL#$txm*M!; z5f?f}yHwou_T==Os)*9tv{FWQ@9xwWa%b=BlPDU<(e@6tcYv<`wlRk`G2Z(1S+y}a zGIA8BteZ$5D3;h4JvdzO9tu=Ik+Hf81Lc=Vr>I$t;`Ze1Y;gV-lhV`M zu{DG9i}RD~^J>+T+3!q_0%hf}uEaZ;T23#Ue5L&~$0qfqf66-B`F6YZzuP;%JcERp zDMs>lGsFM$Oi?^eM0f?NE*%twcIcogA_?DZ3XLM}C-C^l8_PMU3lN8nxi7hUs3(^U z9aD}gRmg@GN{wXPv(0I1IPs1-0_Yt?sF)ZHCS*FF55wf=hGpAbL9f) zC?%W(Ibx=pV0?|1KmK(53rqoik~9TMZ-bZg$v;;X=2^O!QjIH%BA`*!%Vx7gmI#!q z4To70X_&S%`6naH9_6kq%5<|zSv+n+OS16p=XqAjm#$}SI#znl%Q8#3+_po?0-W3c z7{&m_({-K6U2m2}BL%HGwJ2^vi{cLk7dvc}m?AfVWMcBLw%sU}Nrd%lAgJj?ZC%qW zHvnweu56sn=EM-y zdBz3hwmwp+?Rhse?BvRlU?`IYcGF;H=3x6yp+9t?ElV>-k2twfR)l#xYc7R~LK%Q< znt4{2^w2mDW)q}@j9eil)IgB9nDZ-@R+OH)Ymll4re-D-U(JQ71%+-`# z=UHHQ*_D+L@#c~s38=bONK?!WGH!0jJSJLTEWlEJETN=>#-vNV#MKowOHwQIkQL5q zu6^4E)DHo(;;Ua9s_=kS;o*O+SA_>pQH4tF0ewdj)_M&^_yDCxu<*0g95xjVa+u5d z?E$K+j+$2;Dg9hSW3pP}>pn@{j7LS6@|B%MK6;`k)pC#n^(tOI=pNhFNw zK%YSxJwP{=NROCViELu(lRuKEC2=}rae8yOUYrhp1958c7nnCH>;=)$MHO*!UPOJ- zhFP@G%`JOj--DuIDt2Ycl_0>bjKr@F&g)26^X0lmuwEKT3$EgDG&sxaWOx?bE7iuy zpyBGs{(c>ejh%{={ZX2lCF6rMNg~HGRqJB`B-k^;%96ij%dF2(r(l|CyIg6yMiE(% z&+H$t*{@?)w441J#a3ATI>6Gy$t8Rq{j*bBWAp1k8;Xac(n%2BaSoj_SO`F+7)q79 zy2qYgmi}ic7P1tSfJKZN@UCT)F~F|NeXNEkL6oQmYo-O55XO z6-px2+v(W$UGbJ9;Cqu?b@3R*knDpL7&e@2>yXZ5gF?#7+JORWWbx1Tryz0r)t`>x z28NS-TZd@}FEtiO8xP@9-DxkU0Zj#I8^V0O8B7)AZ3uHiJlR_^AXS!(s89`1vpa;M z1=|p%q!gVT~YlIo#a9=yfEJuDkKjY{^4HO&>(7&n-ls%3h%? zeL!ObVoVAPbd5h|+f{bV9&kqj7C&Mrj#=6DI)vR&=yK)oLp<%C@)N18`=VT zM9E;ioW!85oVd+fmm6tT+KH4U0{1a;L3CgN2|*}mop%#D4+!!0p#_=qju4N%#Yvpr zc`J}}GB~x7>p{wOXdOoXaM8jHx6YDSj;4)P#0i?Du~y zGpihW{gXBeY>ACYDQ%ki&A_ zddt@?ixU}GMd_!naN5F>s^USC6I2cN?KXrZHaQ;E7B~v0Gu?{vwxM=V-FLZAsd8I_ zZxlEngKfG@;babX~UYhf6;8QG{;wrESj&FLqKl@C(=|+ zyB2zoVo!pFp^Y)JJ|D@21f~@U#|nMDWQwUZ=Xxe`fkW8g-MEVb*hm86Og8dQe4h2= zbVjEjW(iIoP;|$qw6X23MGOEguWr8WUH+BMTH$ygC!t7a7!nAgo&I z)u!1PPy?{)C6VT`bkZnS`1;fONG7dp5PKFQ2|8mnJ$$HAH5-n#ng2=K?h0U?<#B$( zSL_d{=GNe7@w|&?GjWfjE|d}0YobVl<9Yf#kMV@sO`{PgGhsTzwdaUO*} zJLHbxkWi~rr1bB@amje2$zWpa^a|aznxXA}r-4}IXj{38t@ZIDn$2dZi7G$TB-_Vn zgo5?epFUfoi_L7?*BpB-s!^RCZSv7TSR-iF$+i!sj&wXPNIslmKx)c$I`cG$vYbx- zDz9^u=2S^i1EM}r%l?WVErYBwHGIy*5AKos8MIxsA;8T7xq@781M$i1hGoTp83nG+ zMwF%Ymd}U&;ua&lM7PbR$%k>wG@Y_)@y$&Fkpoc=2ZRS+?Mm)OS5rq zZDS>zDo0ty*=`GFt%j3MHh zmD|ilRJNR#;40tJq!l|I+O?+ZquA_j@rn_gC@45AM+fr_NNuC&h7^1X-k=6EX)i|2 zLtP`l<-mWPB>w}RB=4p0sBr}Jc}|osA7NnCQ#W=GN(A|ggVFuY9Iz>AYl`#R70W?} z1tqU+>t{}V5-LV|tf1Ef(&yJc%mQ27EA#RiU}bWB&8_uy3YSf;x2++#Ypc(ek_%A5 z!Jh7M4JY3HY4#1M>ocqMimvvMyj8bh(#tCC@fvM!>2gf_`7QtR^DJJoZ z2mi)%y+z@MLr};+rM_+X=f380g|`cyRU_H>yx3WJzRGwib&XY#&PIiE_Zk%>OiB$j zDx7|(S3o3u?NMCY6Gl9~t&VmbA6qHY46-Bs`A;Xm%gyd5*xu%Z@y?EI*U(YAT-$yA zYKV>NPz&{)r+`ksH)%o+HZBpr;&Q5CUwr{g@%-9*sedH-=@t5xn9Q9FLH;+q6=rNW z^-%75olzrx^Hf754S{jw~b}rmpDHv3w{!KL z#St1+m54reQ)jYj5TM~yZ1mk_R=&;f+|sK2VVfmwv&mF$wgcz4)mit_ zPMM}r$C0)IZzgz)2JQut0TNhbw4T3Rv*SVaLbcq{Ohx9bloiBX4k&VS3x5q#_rQHCWaKIJLyyv z6guXa1Rq#Mn2lh))oUMTsiWT9ky?^W%cO3sIs|i0uu*CgK~0F!T8QEM#fR=G8=6QK(RnLcvr8JCRD^y&X<)MsfS{}^ruv@+* zy?F#JW$v>4N&NR*hl7+L)FfQv&(mvQPe}Mx4R|#;#zhNbyu%E^v?MKEQ(xu%q~lM+^A&A8?aAQnnmsmTmbyI}2o3_1j~3l_}$Bn_jj- zpGlV85fE5nyjwAxkH>VD0F7~ugP$H_qpTu?R`Y&MZo`j1LEYzgz7ReI&Uh4f+mIiK zL$C$2Ze4*>7&iC-b9!lkn&JvJcDvCW4;HFOo1t(g6O0>QfTu)9N_eK&U!g~y*f~J+ z$38W&=Xq=5J0>Xw5^z{}cFsJDKu@>w>;%neWq@I?IU#}#m;_(*i#K35dPB+QAU>AC zmRv+ECHaW-E=duO)w7W53=R~7*rt;<8P1LbVTm`pk_Ay72ZU2*1acb{_wjWjxg$n- zHZ@F%bwfS|UL}BoPgPGmB(hJL9Qs=47xvlXvZ)z*4aL4y!u=iFR39keXH(G7yfWgv z#!EP-|ByLe$742Atcb^0WJGT#vFlkJsXPEh5F3^ literal 0 HcmV?d00001 diff --git a/tests/resources/renames/.gitted/objects/ed/2a95c4a6c295b9afcea50baff63ec544ccf600 b/tests/resources/renames/.gitted/objects/ed/2a95c4a6c295b9afcea50baff63ec544ccf600 new file mode 100644 index 0000000000000000000000000000000000000000..4f439e293a2d3da657cbb67311e18ca2265d2f04 GIT binary patch literal 5161 zcmV+^6xQo_0qtCSZ{x}^vnKNh3dme*09f*U2!~MVfuDv66cXq|QG?Yi; z?9YEb7DX`FeTc$hawHCpMU;dxDRxnq?@qZ<62-@2xH|~)XtM!77|lA-Lhx7s^f zVn^Ieq!^}2fv&koN1~WSxfn&U6hS6MJ|Fy34hvDFsF0#7i+mW&r0C5DaWoW{(NHG2 zBsky7ERWJe?C-r1Eo%F!+q-}E+Yb*9d(-q^Q5*+*X*O=7 zK^xW7;yN7_4>YSV%8M)-%nKQcIjEMI(FEpRuEczTM7%n^7M<%?g6NpPCP@G2+AZjKenwt#w#I+;>FxmuXggW}n zXL1;gK+rfy#`9n-#W=l}SrR2ruS+vf!#r~IHe&L#|1b!OFqR*2hFnyWJ>>f13M|%s*%CmcSb^iYHLUgZg zF0PNL+1K+~2uy?+6RAIKf6@N(3o55S=BFV1Axehv9MgYw)(!5@Z_f87ueMxal7Dma z?(!zR14Gwq&iXg?qF#^zznjHOa_g;})@3NV*SF^vZ#&(K+fL`ab=SF`&p^H+$JcAB z>|DR^^{)Ci_+RH7!cqSd`&@mS%Wsdx|Y4>+aKj zOyC<*7E@VF(hv&(E*%DO47LbzF$=PS*e;!C;_T|(ZXDf7hM8Wknyt$ z4uU@!6chaiN!bMJ8tW19TGk5HCnma0g7-BC9%QvY2OyBK(IB9|ZKkJT9QP zLK2au5gbyG`b)-ycQ59CM#W;m!^|+$^?**!r0W@e;o+ z5OO41-S?N5;^d?@&Z9;FBmqh><-o8P{r*+|mf+s@t~%YDi~h2>G)w@Herc$BWbqbH zuSKNXyZC7y#CcVyw?RuGFwJ&5OhxB?a+jnJ$=)6~62F}?)y0Wuf%71KJKHdjQSK3c z>g4&+eDFucBqpO8HcB-B5sO7n2@A{>Ogrg;UlSjrcuEMdOR*Xe&CpMx%o4#2seWEw zgp)VNTDdKU5uIDKPDXR@Y*&|Yd-to;Fzm}wYn$3TKv#d?m_O?nZ~gM3 znwXpzIf@e2OQa1HL+ptToGo|`IVzyUSXB)J<&#OLq*;k%^C4M!(vZ-_$~bB;+)wGb z2IK2=tsNXHsG>U~R!8ts$cuokg?3jUjp~F3Ak8VW3_g-lduZ@v)d_H9{d%YUYs^Ng zQ51IN1H1vMf*cw7tg6dCEAQN~3aRQuyn#TXpv)mkqrq>y zy?T55?&955|9i!9j*p^Z_p6#tzcUi`TC_-+iyg3JS+QvRj){x5Fs07B-sSD-`Fa21 zZA;_3ZOi)?mlvnk7p~&joOdoqfiiAbQevA_t)!PjzSQoS$yJDtoSo)`sc&pd{YnsMJT^t>q z1<9Ghz18c(gF8GBdZw@KH&0@l<_NEjw220y)Yl0xetUX(4ZFpPrrid85aREP3H2`jQ~~r@EF%lg|w@Zf;09##&%3z(Rf~prV7?qzk>o zzMlFk0feIoDNx>K0915PKUpOI5qeS%o`>4 zg6Qa?k~ldpqPl2gJPYoXYU5##yE04}E;a;dH?ib8P!vfqkr3Z~_nr6# zpwSRnRf}$^?a7G>B$4H9w{80)@s{J?2a{KI@fbyr?1SVOb~tJ2kj~_ShLn=E0|nT@ z;-BqLA!6&z?@!lgt;M}>@69P zDn~|CC#Q{ho%fk{t#A({xuLM(Y+uFPYw=U#Y5BPt?OLYX!bk^QM@3nes8 zt~G9y6{fB=Z2>)^WUyLJV$f7h+~%#zj5I6lM9LC@`xv<(I;ntkAQZIDx(S^Hgn0YV zg3NhGh{oRHI7;rk705XmoSMk>DCIh^4x@j#aAAg9XGtu_SiCsxNE-q4<2^oGRa;?` zwsUK2v}3bbP=TVsZVlwa669u(+9BQ$=4Mtw<>od7xtZ}Ib$bMoRvDaJ@(qXC5c4!v z@ap5l<1C%e%veS=RtiUuEU;OcjLEU^2yM72Q*TBfL>-_{6>UTv2IDonvKe&{t855w zL!33SvFUCliF4Y{Ww0tX3|)>mEI6EH8N**qb8FP0s$;WEgjzES?V(Zo6oaL64g@ZNX|bW*o=aVM941#VeL}wSiN) zW}L&+gmzr)_kS%js~mdulQs)%iH%7qZKK$=nWT+;&ONItVX}WzQxcN{g?_Ew;ZnO# zz3o0*YWKMzhvmBUmakbBCo-^#(obLEw1p*A$%7;(s2uLwZ3s(jay-f{a0X6ix)tSZ zL+zlt?_!}+<+cRL1uA*gs;NO&P$WD0^r3)rIlf|K z(R{@m0(vVrk)~>zwa}v!dmJnbZH$ri`A9A#Fs(>9R_N;`Q%tQn*E5j|oW363jgN5h z8c9GL#zy{$53+uk&gcxpEXLUbithM$Hn!chhyg(N>gJnH_iuF23MT_O2}MG~km&R) ze$^$`L-=WCg~ntft-)TE5<(ol1|03sZ3rs+X)a&ZbDjpcxlmO~?KZ9nkOwRfw8h~Xli8Pm`lSaA3*B{qMGHGRl*ozoR&>5@g;X{?G*>J4Q z{7>3;R{*OlkMk40Vt+t2w+2Ux=Up_Li3c2Yp^UIz6Ga*v&C{oOj3?A=8jV1i3DXI_ zC28Z6&H6Ns^C+sajJt&bPc zY&J_xl=-0|**;Dq6s)iQ{Mi~^Y-ZcM=GbddjjHTulaB_%8bK>hws|mhq~m2l^5GN% zQd6$oo+m+=W_0XVd7Y~?r%I9<5Y>rV_E-F98Dy2I;d3T_a8KONpzW#+0d5w^<>Y!B zh|gv>EGrJoC~#FaqAazyd_M3OHyG(9x@|U1K8$0g>6BH2Z*CHZEa2v>lHKvPoG_$g zPUSDoZ8^`qFdOIAHkQJvVw9$w?Y004+LL!*?DqqMj~W9pioOM4^t=`2K(awZifkkC zD7@~obAPJPSFZe8wQ6=7yi=lJ(=dls9FOw33LA;6WiGeErA!=lh(GQ+d-o``|6#21 z^6tr_Vi9b~7$UA&xy@`uY0G&DuJSESTCv@xU2D2Gip}l@uNc9Jf`Y?xbTr?9)HaGP zN5QAy4Qeox_F~jL)FlF3w*2oo^8dJVP z12!a0O>ug=WH-pHpyZ8h{lbY)LdD3A74wQX`n=l5*EMxwXAc-Lk>; zwlxHIZS~1gasWy=*t0#Z;l#T;&7J{uePN|u($pT3H)=LadRd`8U7zhPU5qJTbM{`1 z3B)+MmkAuJ9lC=0e3o(8G`NgU0>$wFo*4f&z3Gs1vnaGF17%H z0(X(v9@uLw`6Qb0;9q;LwkX_i1Pa-w#J4H`vR7QL@L<7<>LVMQ=i4jKRv9m)s;^42 zS*viaUaf*eNhyI^h0_kz3J8R+J&G&)!HC6M>R8vwiIp+U9^2yI|8~;5-0We3t!+*g zZ*SXnH4UZ9waw?Rn$Wlol`!9V3F!1&lO^O|qXMxjZlxOL)mOh1$FIGR`kx~`om}4! zlbMqs$o_`+!HoT;9?DU#vMFVL>2w7Bsx@nm04?|MrtwG+82nQEsw`ATFKxG0D<+wR zRzrB@4vfN}3QF(i`NY(1A5^<=u3FEgR%3I})pDK8<381zQr@dtp)wRcj5pXBs)F)v zgPZGuYJ`ncgF4WvlA1nc@RYld=tI(4zHS<(63>4;&?`eo{^v(xKS#!3BI6l}IdUzy zS4@5AH4!|ppx)a^@Wc&0bQIHlP zr)5kGDNJ|Ls45tA%rgn@SwWcXU%kO=Ut_7FUf+jWl1$5_ZmcQ4;9&s>Lrlor$^T;s{pn`+NU^OenaIVi^U8>C00bPjtP z!PwFpab#sdbp6N+9+61!GF>Kcd*>m*BMz{l_>4vic=h+VKOQPe4kOE!e2-lPGOJLf z^wb!hVM;m5rpIj1XOgCO1O#>%Z&eKD<1w8eKx3TV;FreOB&*n<(YRle)9}NOQ1=;L zD}+aZlN~vpGUONG5N5%sTSwpwh7BIToZeTUrnq>GJ#I9|`-CdOW+>dr1mVUL;3?5T z5}qk`Rp?bGb`8+{sn1L7F1;`DEfbVN2skS|H|GuLsg@p^p!uu}EbPT5#H|5O|0{ms z2CPO;CM~;$&)}{l?-1)q?jb!yl1F3p1f)841FaxhbhswPagktH;DxSuL1f37;Dot= zJVwQOe8Wg?i&2(N4M$?pkc5Fl3E*H-)e|p=>{0rLzSg;fJ$AQjK8Bt@v5%8*f5$WB z7fJY?6f`u?ia3X{3%~SVGQ&%F%wviV@%oAk>8&L8I`dUn`%s>ARWI9TeXpH&F literal 0 HcmV?d00001 diff --git a/tests/resources/renames/.gitted/objects/f6/7e2f70efe89665e829ea0d77c46965ad1307e4 b/tests/resources/renames/.gitted/objects/f6/7e2f70efe89665e829ea0d77c46965ad1307e4 new file mode 100644 index 0000000000000000000000000000000000000000..1cad2134d867bd10bf0a109745b0328113887bd1 GIT binary patch literal 5164 zcmV+{6w~W?0qtCQZ{tRm-+$vzQPT_T%AU5>Z702n4F~bq?umBXwpMm$5(I%kktK<1 zid0Cd-I`41v(N9nx=5-h$wvnnUXN8ABi}PWLoZ`u-Kh)qcl#AM7TQ)ia6ZOMx#QOXvt7^x?A0y zEwLkRCQ^i1TB2(qvXLk!aUn)=B1Mo(QOt+`FT+xl87ic>lw}bHGb#G>VG@VpA`WF* zNP_d7%!@cn#p}ISqC;(8T=p+sY#)h5HW$-iA=0cA^FmezkRL-iD}gul53}hkiGwth z;yx}XYPkNzo)AB10NJn%;#34^I$J1Ifl>cL1SJ8Ol;!NO+r7WP-+a9+wt%t5u>j3zMmY9;0qq~gWNwdh^H5Jbn~B|-XY@8;X9 z_c!9NCxgMs<;@S`>a94r{6YMscX{?wNZ=2c^5ZO*1&Er9nC2#3ANDr5I-)WS++9Smg0|f~5)4NF?zzE`t(eE*#zj2b0{xzx3Z5fa|4k z83&0tlOJS~&47zp*bsc-x-#`JWwWf*|1_IU=V=`3VNSDrmgW3`rRZn58a>QqK-3#9 zY-i#Z1z@&doJHq!TfF}2t1n%XmB3GuL=1Sc1ZE%$nSTJy@X_4@v-0fTU7fwZI2V^! zH|N)f)a;x2ECMD%jEU5rcfag@^(B?lAM;ZX{xeR)WRB^-IK86vIlDRAo4nX^#cA>F z&AW@6><%p5tT`RrG>iH{4h(M=Gs&&D3R;;^TwdRvoxkl}p5OL*XPvv=^?U{bmIc0E zQf2S@eZPM-xWWH=XAqC(uMG~+Wf0t+;GjT(Xz6j91ce%vx=;_EHqG(Y_7z)9+TF+f zn8-JzFs8DcWDyntoEip60@er$F$?mNSTCFB;`Hj>ZW7-~h0O%Lr+a(gN&I%IR2Rph1KxuG?rg(M#)U@( zP$$oi=7T>nAwd~6uuD-)@~a6hH% zT8yyMw{~zSp_=}TSs}q&A#Vcu78+iGH0l#NfV8K~bNEV1^`XI|)hED_1?-;;t}z>} zN>O+z@2z=+EEyTCtIPqb@a-*PD95WJE+N%02d<2G0&PeoQsuFD1;Io?l~0srgBN*w z_4fAN`MayZ4~p>|H^t@d*A3l%XC&*T=#WwuJ7CPJg3&l05if0FV!e0$i`$d4v%&e> zj>UP~)(p-s&QGq-t5r|t!817ul&Qnw5(8ywO})JGm3G)1uhiH7DT{6Adw6L7+u0U} zBn!02v?xy(IWyfz{%&UbkIHn-6vg9YhF7EN<3V$14-dK{l5pmxP%+|u0vC|nvz#Nn z0Kw^)`;z~Mdh*fGG38)W#c^n%^h(A(+q}4jXYUv#fFeTJiiy!+LZ=SZfql-~N{lV?c;Qcv?vw>Zi2Y1CxyRiO`A@Np!@TV+Gobmv( z2I;B7zSAGTuRGWmdaf_+H&0`mW(i-9bc+U~RN66cetU9p4O_-)r`rXE5dOaw6ZqwC zUc+IZ4iT{{pFoE$;UvfrNZkbEYqb3Fr{iB>8}O4H7X{Y>zSL5m7epm z%u+75?U2U+CpQ3wF+lNjU1##&n`O~RL90$Jikr})_=Ca44jUz=$c-SGm^`d)H;QEv zVf`8iYC2I{*EGuw09!VBy*$ihzX5D=;A!-^r|b()*_$RX58aWwK+=diTg>7S#8MH| zl}(!~8>h25F+_EqaX|^Mk5p=V-VF^qxw0e}%A|qaG?(u~m~POg*{ zVII$#OQFJ224I_Jp4BBiG|q$B1bHGOSI84J5F{?HD%X%78qW3WhF$sxg^L8s;(8%6mx@&n;X)Ri53_Ou#_K5DCwXv=~6Fo zbw$mR)XF?$h4-3kXSV_ML%^)~>eq%U+-FsI@IUKS;r>%pp;CK5-;sp1UPBQ+KnN{ZI6a0#h*MTZYXAqV+K1uh9 zYDFyTK%YSp38OmDXOKn@&`l-MBW6}2o0$6Kk0feIoDNu=zBpJfP6xk%IJNi-%o`Q< zg6Qa?ia0qhqP}RuEL!O1mc6hULg6tLyE5fU5MWnE;#UXfbtJ6$a$O@>FO8%HS8+HR zoaJ>gJPYoXYU5^1fWt3rAlVqW1}xi|GN|mSqjR?B1R2(D>KR%E;b8kr?KKXP#j4ykr3a1|GoGY zpwSSyR*P<>?eVb+C6W8>c5VAZ@s=atdy{Q-@fgLB?1K~-Hk@>HNM|xbAth?VQz>gdrJnS z%9s%qssUAyrFF<`+cqtzqgdO{d15|XZ6svdTYXz0 ze7oc2g=w^+gXxRGRCrWdVA7Lbh$cd^5G$USEAtraxfh<%h>FORUZzb(WPcjkLJ5tN zYmFP_h^cEsTR@K}8LXF+7_^lWw|VPwBh5-Xk+MYKK1MExPB9=M2nDV4ZbIh)A>KZ; zAamXk;<2|liPJl81#(UXr#5muNVyKJ!{{F_TA1P1SrW@J7B5ab(zXEoc<0YnHCEW9 z?c5q0?bvP>RG?_ETLbx^0=XTec8E8GxtUc^xw#ENZf3kl-5!FZbp|Jwe8XWj#5_wB zyyiH`IM3!YGnNsJmBJCE3v8jLV{$A!LK|($)SD3qQ3vQ#M;lRx!FUa?Y(^c#DjUMv z5NAznY{gqi;+(c~8LWzpB9|kMN)BgP#_(6$+*)<0>ewz5k=BetduY^tg%(`1&~myV z(KcHIlUX)Et2#=BJl4^*M70$9wCc&(l=ek=kfz3QyG@C=8OL#U*ig<$@rtEgZQxX{ z8D}&#p&b|d{a?$>Du-VGq|E|bVq;QD+bDKzCuu96bI-a;n7lr0D2d6wLch`OV5!~b z-gaLswR>a8VYzO-3ZDC1O@gT_ws)qY^8^RKs9FJ-XoQ>0&Zbf<9 zP&=sZyIiPLxh+9*fl8jVYHH9G6v+=i`|LA4Rl~ziQBad|>QTg17Os%kPL;E3_RENZ zV_{mjPphU?PWoB74FQyo%Q=ejR;WEKUllSmq14WFUAFFrOFs5fmQTfqJ``|P$5)Ij zny;8cKyL*n(o{{m7J86kPlAP^jWM!5AIXITrWFat3Vpp~im5f{dM0v#liA_j_z_AEvcbjE6W_)w*4HXLg+ z|C6@e6~H>nEDOrlJQ29!Nl0<6}oFRL)-mM1F_1{wsI9)>*GZ< zo6S-aReq>RwvW>Y1?#IneYQpyo7uLnIrdsqqdGg<>3Cj{d^p8` z)RgOX=V=gSIUNO7Ugs*!sgk4yM17)`{S`l223cil_?(F!+#~lhXuE1dfSUz!1-ae^ z;*;48%ZdXt3S6CyC`;`vpAY@TEk=5YZktV$5963=I%U=3o0|k83%EI}WOuwRCxmp& zsrtpaE$6wHX5-x2#!5IJ(YFAMp0}bJNVbSbnQtT> zrPqCS?oS>1%9UTMR?TjMcS;m&8s@Ny<3T=GX(N%f%;i?Nl8M6(@uyv9?;eHrKa5pg z-aUCxEP^c=L&P;Jx0#KoY&kE%RlcQ3D|WlIYfX1bvDw|?6(cxNP;gj|4(S_^+D6fp zDfkq;K@DcoUW}TDx>A6PnEyUW{x5ivyqChG#u3oxIZ?iRgn?C0-Pk=S5#%!tM)x~& zz^0_FDb8nOs2J(7f?g9ypI`eh3v6+(%*$(lmC5xrx7ODwTsFDh zwua!Ytv*{yEXjI}Qj8lb#U37cz^xAChG2bt7n}J?%t3emi>1p`0S?EQ%Pl~l z#GNFz2=;1AF^Ok9_&1*GEebarfP_cfO*JZSK&8p+1z#rDecRmM}PYpjZN zHY%LE*Qg+2Qfi=4;q*hj0wUpSkK)>%Fyir!I@)!7Y^6*y$hP?V-<|v}H@lx;dz%x+ z+uOEXLr3XyZTI=BAvUfY%)v z;pWny8et>lppLbw)TU1zJmyX$`jEUjIx;S} zXH0$Qtr0xFpkCuh@dyq*g_O{}P+T%)oq*%{yU2KicSp1{Lw)w?T=xu5BoJ_V%%mvj z4IW&3ClgBV^I%Jt?XZ4Yasm! zLt|R=Yp#}N*feHEOZQCqx;vUZj(B(`#M~3L7l98C|18Th74-G_hAiYBXO(@LgS3IM zIR$h)pD8p2w{!Kp#St1+Rfs-xQ)jYj2%zCqEcD%FR=&;f0@JGOVVfOov&d9#HUsO( zsEEKP(`LI_)mi7#PMM}r$B{MyZzg!7h>wi(TUj))eaXoj|E^#8Xne*qv^n0edAa6i2Uz3>EMlfR=G8CU|*iRnLcvr8JCRD^whs z<)MsfS{}^ru3Nq(y?F#JWp1+kLHzGr2ZNLz)FfQv&C|PUPe}Jw4R|#)#x)$IN#kq| ziyOn-(mQfwXF+uR01Td!Nb!1IE^v$IKEQJhu%q~lM+V90F7~qgI^+JqpaeCR`Y&MZo`j1LEYzg z(GWfbPIwe}?vUS%L#PF_Ze4*>7&iC-b9!fin&JXB_PWs=Zy2gLo1t(g6N(#OfTu(U zN_eK&U7v?J7J0>ZG5pY;|cFrHrldU{CK{HwzT-Ym4h+YFGz}Nip z4VaA{R9bcq`K_5pGT4%fh@~VSkzOS!;<0)uQk}qoVh|lVXOrRNND!8I!Yf%2<#9YX zWkw*kQE?w%Hj>+7lxI`Jlvp=pW8hT+IQUfc#4{p$l*gg3b$(%=JuaJ=p|?=%OC{Xj zu}$@P5`HuV4b2-P&TG7cbNV-#JCqKW(VylA4{KG8;npX^#@ ap~q{ee>2eUkAeOK1^XLw&_4n7GF<&P%Lc3f literal 0 HcmV?d00001 diff --git a/tests/resources/renames/.gitted/refs/heads/break_rewrite b/tests/resources/renames/.gitted/refs/heads/break_rewrite new file mode 100644 index 00000000000..d170915c159 --- /dev/null +++ b/tests/resources/renames/.gitted/refs/heads/break_rewrite @@ -0,0 +1 @@ +7e7bfb88ba9bc65fd700fee1819cf1c317aafa56 From cf323cb9d94022e0301b5bb3bebdf2f6a5b4e338 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 16 May 2021 11:09:44 +0100 Subject: [PATCH 0313/1616] refs: test git_reference_create_matching failure for zero oid --- tests/refs/races.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/refs/races.c b/tests/refs/races.c index 988072794d0..9134bf92127 100644 --- a/tests/refs/races.c +++ b/tests/refs/races.c @@ -30,7 +30,10 @@ void test_refs_races__create_matching_zero_old(void) git_oid_fromstr(&id, commit_id); git_oid_fromstr(&zero_id, "0000000000000000000000000000000000000000"); + cl_git_fail(git_reference_create_matching(&ref, g_repo, refname, &id, 1, &zero_id, NULL)); + cl_git_pass(git_reference_create_matching(&ref, g_repo, other_refname, &id, 1, &zero_id, NULL)); + cl_git_fail(git_reference_create_matching(&ref, g_repo, other_refname, &id, 1, &zero_id, NULL)); git_reference_free(ref); } From f7c3d622ee978f9f9f10bb3098fe44a0ad436b84 Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Sun, 16 May 2021 13:58:51 +0300 Subject: [PATCH 0314/1616] branch: git branch upstream functions layouts have been fixed. --- src/branch.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/branch.c b/src/branch.c index 55b748cb274..e32c5bd2183 100644 --- a/src/branch.c +++ b/src/branch.c @@ -492,11 +492,13 @@ static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, c return error; } -int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname) { +int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname) +{ git_branch_upstream_with_format(buf, repo, refname, "branch.%s.remote"); } -int git_branch_upstream_merge(git_buf *buf, git_repository *repo, const char *refname) { +int git_branch_upstream_merge(git_buf *buf, git_repository *repo, const char *refname) +{ git_branch_upstream_with_format(buf, repo, refname, "branch.%s.merge"); } From ea889b3e1237fc4399f0907f923c8df4fff3a72b Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Sun, 16 May 2021 17:58:15 +0300 Subject: [PATCH 0315/1616] branch: git branch upstream format enum has been added. --- src/branch.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/branch.c b/src/branch.c index e32c5bd2183..007b93591fc 100644 --- a/src/branch.c +++ b/src/branch.c @@ -468,10 +468,33 @@ int git_branch_upstream_name( return error; } -static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, const char *refname, const char *format) +typedef enum { + GIT_BRANCH_UPSTREAM_FORMAT_REMOTE = 1, + GIT_BRANCH_UPSTREAM_FORMAT_MERGE = 2 +} git_branch_upstream_format; + +static const char* git_branch_upstream_format_string_for_id(git_branch_upstream_format id) { + switch (id) { + case GIT_BRANCH_UPSTREAM_FORMAT_REMOTE: return "branch.%s.remote"; + case GIT_BRANCH_UPSTREAM_FORMAT_MERGE: return "branch.%s.merge"; + default: return ""; // OK? + }; +} + +static const char* git_branch_upstream_format_name_for_id(git_branch_upstream_format id) { + switch (id) { + case GIT_BRANCH_UPSTREAM_FORMAT_REMOTE: return "remote"; + case GIT_BRANCH_UPSTREAM_FORMAT_MERGE: return "merge"; + default: return "UNDEFINED"; // OK? + }; +} + +static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, const char *refname, git_branch_upstream_format id) { int error; git_config *cfg; + const char *format = git_branch_upstream_format_string_for_id(id); + const char *format_name = git_branch_upstream_format_name_for_id(id); if (!git_reference__is_branch(refname)) return not_a_local_branch(refname); @@ -484,7 +507,7 @@ static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, c return error; if (git_buf_len(buf) == 0) { - git_error_set(GIT_ERROR_REFERENCE, "branch '%s' does not have an upstream remote", refname); + git_error_set(GIT_ERROR_REFERENCE, "branch '%s' does not have an upstream %s", refname, format_name); error = GIT_ENOTFOUND; git_buf_clear(buf); } @@ -494,12 +517,12 @@ static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, c int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname) { - git_branch_upstream_with_format(buf, repo, refname, "branch.%s.remote"); + return git_branch_upstream_with_format(buf, repo, refname, GIT_BRANCH_UPSTREAM_FORMAT_REMOTE); } int git_branch_upstream_merge(git_buf *buf, git_repository *repo, const char *refname) { - git_branch_upstream_with_format(buf, repo, refname, "branch.%s.merge"); + return git_branch_upstream_with_format(buf, repo, refname, GIT_BRANCH_UPSTREAM_FORMAT_MERGE); } int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refname) From 9836ca9177a56b6e170997b2e727c71ff8228848 Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Sun, 16 May 2021 18:02:23 +0300 Subject: [PATCH 0316/1616] branch: git branch upstream functions layouts have been fixed. --- src/branch.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/branch.c b/src/branch.c index 007b93591fc..831ccfcc78c 100644 --- a/src/branch.c +++ b/src/branch.c @@ -471,9 +471,10 @@ int git_branch_upstream_name( typedef enum { GIT_BRANCH_UPSTREAM_FORMAT_REMOTE = 1, GIT_BRANCH_UPSTREAM_FORMAT_MERGE = 2 -} git_branch_upstream_format; +} git_branch_upstream_format_type_t; -static const char* git_branch_upstream_format_string_for_id(git_branch_upstream_format id) { +static const char* git_branch_upstream_format_string_for_id(git_branch_upstream_format_type_t id) +{ switch (id) { case GIT_BRANCH_UPSTREAM_FORMAT_REMOTE: return "branch.%s.remote"; case GIT_BRANCH_UPSTREAM_FORMAT_MERGE: return "branch.%s.merge"; @@ -481,7 +482,8 @@ static const char* git_branch_upstream_format_string_for_id(git_branch_upstream_ }; } -static const char* git_branch_upstream_format_name_for_id(git_branch_upstream_format id) { +static const char* git_branch_upstream_format_name_for_id(git_branch_upstream_format_type_t id) +{ switch (id) { case GIT_BRANCH_UPSTREAM_FORMAT_REMOTE: return "remote"; case GIT_BRANCH_UPSTREAM_FORMAT_MERGE: return "merge"; @@ -489,7 +491,7 @@ static const char* git_branch_upstream_format_name_for_id(git_branch_upstream_fo }; } -static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, const char *refname, git_branch_upstream_format id) +static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, const char *refname, git_branch_upstream_format_type_t id) { int error; git_config *cfg; From 49f9941df594136c606bbb9b110869967e0f8e30 Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Sun, 16 May 2021 23:54:25 +0300 Subject: [PATCH 0317/1616] submodule: git submodule dup has been added. --- include/git2/submodule.h | 7 +++++++ src/submodule.c | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/include/git2/submodule.h b/include/git2/submodule.h index bedd76d6a86..139a0cbc1fd 100644 --- a/include/git2/submodule.h +++ b/include/git2/submodule.h @@ -223,6 +223,13 @@ GIT_EXTERN(int) git_submodule_lookup( git_repository *repo, const char *name); +/** + * Dup (retain) a submodule + * + * @param submodule Submodule object + */ +GIT_EXTERN(git_submodule *) git_submodule_dup(git_submodule *submodule); + /** * Release a submodule * diff --git a/src/submodule.c b/src/submodule.c index 14869452fc0..0460f475197 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -1854,6 +1854,14 @@ static void submodule_release(git_submodule *sm) git__free(sm); } +git_submodule* git_submodule_dup(git_submodule *sm) +{ + if (!sm) + return; + GIT_REFCOUNT_INC(sm); + return sm; +} + void git_submodule_free(git_submodule *sm) { if (!sm) From a6fb72a8ba3bf3f8bc8d78ef4104c6b083416a4b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 18 May 2021 11:51:25 +0100 Subject: [PATCH 0318/1616] tests: exit with error on win32 leakcheck --- src/win32/w32_leakcheck.c | 5 +++++ src/win32/w32_leakcheck.h | 2 ++ tests/main.c | 9 +++++++++ 3 files changed, 16 insertions(+) diff --git a/src/win32/w32_leakcheck.c b/src/win32/w32_leakcheck.c index ef17004436c..5c8425be3ac 100644 --- a/src/win32/w32_leakcheck.c +++ b/src/win32/w32_leakcheck.c @@ -558,6 +558,11 @@ static void git_win32_leakcheck_global_shutdown(void) git_win32_leakcheck_stack_cleanup(); } +bool git_win32_leakcheck_has_leaks(void) +{ + return (g_transient_count_total_leaks > 0); +} + int git_win32_leakcheck_global_init(void) { git_win32_leakcheck_stacktrace_init(); diff --git a/src/win32/w32_leakcheck.h b/src/win32/w32_leakcheck.h index 7da03ab0ec2..cb45e3675be 100644 --- a/src/win32/w32_leakcheck.h +++ b/src/win32/w32_leakcheck.h @@ -21,6 +21,8 @@ int git_win32_leakcheck_global_init(void); #include "git2/errors.h" #include "strnlen.h" +bool git_win32_leakcheck_has_leaks(void); + /* Stack frames (for stack tracing, below) */ /** diff --git a/tests/main.c b/tests/main.c index 00b2bae024a..207a6a8bed6 100644 --- a/tests/main.c +++ b/tests/main.c @@ -1,6 +1,10 @@ #include "clar_libgit2.h" #include "clar_libgit2_trace.h" +#ifdef GIT_WIN32_LEAKCHECK +# include "win32/w32_leakcheck.h" +#endif + #ifdef _WIN32 int __cdecl main(int argc, char *argv[]) #else @@ -29,6 +33,11 @@ int main(int argc, char *argv[]) cl_global_trace_disable(); git_libgit2_shutdown(); +#ifdef GIT_WIN32_LEAKCHECK + if (git_win32_leakcheck_has_leaks()) + res = res || 1; +#endif + at_exit_cmd = getenv("CLAR_AT_EXIT"); if (at_exit_cmd != NULL) { int at_exit = system(at_exit_cmd); From 1b1e541dd18d9b8548cf8de13a5fc0cc9bd49394 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 18 May 2021 11:52:51 +0100 Subject: [PATCH 0319/1616] tests: clean up refs::races zero oid test --- tests/refs/races.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/refs/races.c b/tests/refs/races.c index 9134bf92127..476789358d6 100644 --- a/tests/refs/races.c +++ b/tests/refs/races.c @@ -31,10 +31,12 @@ void test_refs_races__create_matching_zero_old(void) git_oid_fromstr(&zero_id, "0000000000000000000000000000000000000000"); cl_git_fail(git_reference_create_matching(&ref, g_repo, refname, &id, 1, &zero_id, NULL)); + git_reference_free(ref); cl_git_pass(git_reference_create_matching(&ref, g_repo, other_refname, &id, 1, &zero_id, NULL)); - cl_git_fail(git_reference_create_matching(&ref, g_repo, other_refname, &id, 1, &zero_id, NULL)); + git_reference_free(ref); + cl_git_fail(git_reference_create_matching(&ref, g_repo, other_refname, &id, 1, &zero_id, NULL)); git_reference_free(ref); } From 6b1f6e00bf7c91b3b5230e20ecb57a7d9792cee7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 18 May 2021 12:21:15 +0100 Subject: [PATCH 0320/1616] diff: test ignore-blank-lines --- tests/diff/workdir.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/diff/workdir.c b/tests/diff/workdir.c index f2404958eb5..00c52ff1b4c 100644 --- a/tests/diff/workdir.c +++ b/tests/diff/workdir.c @@ -2203,3 +2203,38 @@ void test_diff_workdir__order(void) git_diff_free(diff); git_tree_free(tree); } + +void test_diff_workdir__ignore_blank_lines(void) +{ + git_diff_options opts = GIT_DIFF_OPTIONS_INIT; + git_diff *diff; + git_patch *patch; + git_buf buf = GIT_BUF_INIT; + + g_repo = cl_git_sandbox_init("rebase"); + cl_git_rewritefile("rebase/gravy.txt", "GRAVY SOUP.\n\n\nGet eight pounds of coarse lean beef--wash it clean and lay it in your\n\npot, put in the same ingredients as for the shin soup, with the same\nquantity of water, and follow the process directed for that. Strain the\nsoup through a sieve, and serve it up clear, with nothing more than\ntoasted bread in it; two table-spoonsful of mushroom catsup will add a\nfine flavour to the soup!\n"); + + /* Perform the diff normally */ + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts)); + cl_git_pass(git_patch_from_diff(&patch, diff, 0)); + cl_git_pass(git_patch_to_buf(&buf, patch)); + + cl_assert_equal_s("diff --git a/gravy.txt b/gravy.txt\nindex c4e6cca..3c617e6 100644\n--- a/gravy.txt\n+++ b/gravy.txt\n@@ -1,8 +1,10 @@\n GRAVY SOUP.\n \n+\n Get eight pounds of coarse lean beef--wash it clean and lay it in your\n+\n pot, put in the same ingredients as for the shin soup, with the same\n quantity of water, and follow the process directed for that. Strain the\n soup through a sieve, and serve it up clear, with nothing more than\n toasted bread in it; two table-spoonsful of mushroom catsup will add a\n-fine flavour to the soup.\n+fine flavour to the soup!\n", buf.ptr); + + git_buf_dispose(&buf); + git_patch_free(patch); + git_diff_free(diff); + + /* Perform the diff ignoring blank lines */ + opts.flags |= GIT_DIFF_IGNORE_BLANK_LINES; + + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts)); + cl_git_pass(git_patch_from_diff(&patch, diff, 0)); + cl_git_pass(git_patch_to_buf(&buf, patch)); + + cl_assert_equal_s("diff --git a/gravy.txt b/gravy.txt\nindex c4e6cca..3c617e6 100644\n--- a/gravy.txt\n+++ b/gravy.txt\n@@ -5,4 +7,4 @@ pot, put in the same ingredients as for the shin soup, with the same\n quantity of water, and follow the process directed for that. Strain the\n soup through a sieve, and serve it up clear, with nothing more than\n toasted bread in it; two table-spoonsful of mushroom catsup will add a\n-fine flavour to the soup.\n+fine flavour to the soup!\n", buf.ptr); + + git_buf_dispose(&buf); + git_patch_free(patch); + git_diff_free(diff); +} From 94571908f82daba41c7368c79a4f4204405948cf Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Tue, 18 May 2021 16:07:04 +0300 Subject: [PATCH 0321/1616] branch: git branch upstream with format format name parameter has been added. --- src/branch.c | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/src/branch.c b/src/branch.c index 831ccfcc78c..e6818a86df5 100644 --- a/src/branch.c +++ b/src/branch.c @@ -468,35 +468,10 @@ int git_branch_upstream_name( return error; } -typedef enum { - GIT_BRANCH_UPSTREAM_FORMAT_REMOTE = 1, - GIT_BRANCH_UPSTREAM_FORMAT_MERGE = 2 -} git_branch_upstream_format_type_t; - -static const char* git_branch_upstream_format_string_for_id(git_branch_upstream_format_type_t id) -{ - switch (id) { - case GIT_BRANCH_UPSTREAM_FORMAT_REMOTE: return "branch.%s.remote"; - case GIT_BRANCH_UPSTREAM_FORMAT_MERGE: return "branch.%s.merge"; - default: return ""; // OK? - }; -} - -static const char* git_branch_upstream_format_name_for_id(git_branch_upstream_format_type_t id) -{ - switch (id) { - case GIT_BRANCH_UPSTREAM_FORMAT_REMOTE: return "remote"; - case GIT_BRANCH_UPSTREAM_FORMAT_MERGE: return "merge"; - default: return "UNDEFINED"; // OK? - }; -} - -static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, const char *refname, git_branch_upstream_format_type_t id) +static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, const char *refname, const char *format, const char *format_name) { int error; git_config *cfg; - const char *format = git_branch_upstream_format_string_for_id(id); - const char *format_name = git_branch_upstream_format_name_for_id(id); if (!git_reference__is_branch(refname)) return not_a_local_branch(refname); @@ -519,12 +494,12 @@ static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, c int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname) { - return git_branch_upstream_with_format(buf, repo, refname, GIT_BRANCH_UPSTREAM_FORMAT_REMOTE); + return git_branch_upstream_with_format(buf, repo, refname, "branch.%s.remote", "remote"); } int git_branch_upstream_merge(git_buf *buf, git_repository *repo, const char *refname) { - return git_branch_upstream_with_format(buf, repo, refname, GIT_BRANCH_UPSTREAM_FORMAT_MERGE); + return git_branch_upstream_with_format(buf, repo, refname, "branch.%s.merge", "merge"); } int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refname) From d6f57b9cfa4006c11ce17be74f3671cf42ea312e Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Wed, 19 May 2021 18:50:29 +0300 Subject: [PATCH 0322/1616] submodule: git submodule dup guard statement has been fixed. --- src/submodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/submodule.c b/src/submodule.c index 0460f475197..b78bef2e482 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -1857,7 +1857,7 @@ static void submodule_release(git_submodule *sm) git_submodule* git_submodule_dup(git_submodule *sm) { if (!sm) - return; + return NULL; GIT_REFCOUNT_INC(sm); return sm; } From 11aa20b0a28769aef959b1f8665b40aa5daadf0b Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Wed, 26 May 2021 14:06:31 +0300 Subject: [PATCH 0323/1616] submodule: git submodule dup object dup has been added. --- include/git2/submodule.h | 8 +++++--- src/submodule.c | 7 ++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/git2/submodule.h b/include/git2/submodule.h index 139a0cbc1fd..e5bd4c7b2f6 100644 --- a/include/git2/submodule.h +++ b/include/git2/submodule.h @@ -224,11 +224,13 @@ GIT_EXTERN(int) git_submodule_lookup( const char *name); /** - * Dup (retain) a submodule + * Create an in-memory copy of a submodule. The copy must be explicitly + * free'd or it will leak. * - * @param submodule Submodule object + * @param out Pointer to store the copy of the submodule + * @param source Original tag to copy */ -GIT_EXTERN(git_submodule *) git_submodule_dup(git_submodule *submodule); +GIT_EXTERN(int) git_submodule_dup(git_submodule **out, git_submodule *source); /** * Release a submodule diff --git a/src/submodule.c b/src/submodule.c index b78bef2e482..598a24a9e14 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -1854,12 +1854,9 @@ static void submodule_release(git_submodule *sm) git__free(sm); } -git_submodule* git_submodule_dup(git_submodule *sm) +int git_submodule_dup(git_submodule **out, git_submodule *source) { - if (!sm) - return NULL; - GIT_REFCOUNT_INC(sm); - return sm; + return git_object_dup((git_object **)out, (git_object *)source); } void git_submodule_free(git_submodule *sm) From bf1616d1dd1768efd5bafe4a683a3a45d3c1a33b Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Wed, 26 May 2021 15:32:05 +0300 Subject: [PATCH 0324/1616] submodule: git submodule dup implementation has been reverted. Assert has been added. --- src/submodule.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/submodule.c b/src/submodule.c index 598a24a9e14..ee31bd8a03c 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -1856,7 +1856,13 @@ static void submodule_release(git_submodule *sm) int git_submodule_dup(git_submodule **out, git_submodule *source) { - return git_object_dup((git_object **)out, (git_object *)source); + GIT_ASSERT_ARG(out); + + if (source != NULL) + GIT_REFCOUNT_INC(source); + + *out = source; + return 0; } void git_submodule_free(git_submodule *sm) From a25cba2c0f4d85dc030c8fd65f5660acf00e9463 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 27 May 2021 10:01:55 +0200 Subject: [PATCH 0325/1616] docs: fix incorrect comment marker --- docs/coding-style.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/coding-style.md b/docs/coding-style.md index d5188f0bc0c..b8b94d69ca8 100644 --- a/docs/coding-style.md +++ b/docs/coding-style.md @@ -172,7 +172,7 @@ tags: * * @param s String to froznicate * @return A newly allocated string or `NULL` in case an error occurred. - * / + */ char *froznicate(const char *s); ``` From 3e1785478245dcabe2d9e32813d1e1964d416e45 Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Thu, 27 May 2021 16:26:38 +0200 Subject: [PATCH 0326/1616] docs: fix some missing includes that cause Docurium to error out --- include/git2/cert.h | 1 + include/git2/sys/transport.h | 1 + 2 files changed, 2 insertions(+) diff --git a/include/git2/cert.h b/include/git2/cert.h index f111b136e30..0ed38ffcdd4 100644 --- a/include/git2/cert.h +++ b/include/git2/cert.h @@ -8,6 +8,7 @@ #define INCLUDE_git_cert_h__ #include "common.h" +#include "types.h" /** * @file git2/cert.h diff --git a/include/git2/sys/transport.h b/include/git2/sys/transport.h index 6cee42f545e..fee34544fa9 100644 --- a/include/git2/sys/transport.h +++ b/include/git2/sys/transport.h @@ -9,6 +9,7 @@ #define INCLUDE_sys_git_transport_h #include "git2/net.h" +#include "git2/transport.h" #include "git2/types.h" #include "git2/strarray.h" #include "git2/proxy.h" From cf9196bdbc009e79f3806f7353c1ce6885dd677e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 30 May 2021 10:42:25 -0700 Subject: [PATCH 0327/1616] Tolerate readlink size less than st_size --- src/odb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/odb.c b/src/odb.c index 1b91434bf0a..7625ce6e3a9 100644 --- a/src/odb.c +++ b/src/odb.c @@ -297,14 +297,15 @@ int git_odb__hashlink(git_oid *out, const char *path) GIT_ERROR_CHECK_ALLOC(link_data); read_len = p_readlink(path, link_data, size); - link_data[size] = '\0'; - if (read_len != size) { + if (read_len == -1) { git_error_set(GIT_ERROR_OS, "failed to read symlink data for '%s'", path); git__free(link_data); return -1; } + GIT_ASSERT(read_len <= size); + link_data[read_len] = '\0'; - result = git_odb_hash(out, link_data, size, GIT_OBJECT_BLOB); + result = git_odb_hash(out, link_data, read_len, GIT_OBJECT_BLOB); git__free(link_data); } else { int fd = git_futils_open_ro(path); From ca2ff5abb8d321b185007be11ea1ad8959e9708d Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Tue, 1 Jun 2021 17:52:57 +0300 Subject: [PATCH 0328/1616] submodule: git submodule dup documentation has been fixed. --- include/git2/submodule.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/git2/submodule.h b/include/git2/submodule.h index e5bd4c7b2f6..857c62f899b 100644 --- a/include/git2/submodule.h +++ b/include/git2/submodule.h @@ -227,8 +227,8 @@ GIT_EXTERN(int) git_submodule_lookup( * Create an in-memory copy of a submodule. The copy must be explicitly * free'd or it will leak. * - * @param out Pointer to store the copy of the submodule - * @param source Original tag to copy + * @param out Pointer to store the copy of the submodule. Cannot be NULL. + * @param source Original submodule to copy. */ GIT_EXTERN(int) git_submodule_dup(git_submodule **out, git_submodule *source); From 75defb75a81c68b5eaa9601d0d70b803928aa7a4 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Tue, 18 May 2021 10:51:20 +0200 Subject: [PATCH 0329/1616] Add documentation about GIT_OPT_GET_USER_AGENT --- include/git2/common.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/git2/common.h b/include/git2/common.h index 8dd30d506b4..dee260e05d9 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -356,6 +356,11 @@ typedef enum { * > * > - `ciphers` is the list of ciphers that are eanbled. * + * * opts(GIT_OPT_GET_USER_AGENT, git_buf *out) + * + * > Get the value of the User-Agent header. + * > The User-Agent is written to the `out` buffer. + * * * opts(GIT_OPT_ENABLE_OFS_DELTA, int enabled) * * > Enable or disable the use of "offset deltas" when creating packfiles, From 8b79a3f9baed9077a9163314bb3525166c792323 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 2 Jun 2021 14:46:12 +0200 Subject: [PATCH 0330/1616] Remove bad space in documentation --- include/git2/indexer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/indexer.h b/include/git2/indexer.h index 8059e4db361..dc02f0bc544 100644 --- a/include/git2/indexer.h +++ b/include/git2/indexer.h @@ -51,7 +51,7 @@ typedef struct git_indexer_progress { * Type for progress callbacks during indexing. Return a value less * than zero to cancel the indexing or download. * - * @param stats Structure containing information about the state of the tran sfer + * @param stats Structure containing information about the state of the transfer * @param payload Payload provided by caller */ typedef int GIT_CALLBACK(git_indexer_progress_cb)(const git_indexer_progress *stats, void *payload); From eeacd234ef67b73f983ba64f4aa40c16085039dd Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 2 Jun 2021 14:47:24 +0200 Subject: [PATCH 0331/1616] Fix struct indentation --- include/git2/indexer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/git2/indexer.h b/include/git2/indexer.h index dc02f0bc544..a434d243f26 100644 --- a/include/git2/indexer.h +++ b/include/git2/indexer.h @@ -64,6 +64,7 @@ typedef struct git_indexer_options { /** progress_cb function to call with progress information */ git_indexer_progress_cb progress_cb; + /** progress_cb_payload payload for the progress callback */ void *progress_cb_payload; From a2fa9a57728dddd1f69d9821d09f20c8305a1d92 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 2 Jun 2021 14:49:33 +0200 Subject: [PATCH 0332/1616] Add some missing documentation about return value --- include/git2/apply.h | 2 ++ include/git2/tree.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/git2/apply.h b/include/git2/apply.h index b248eaafea3..bc637df1c2a 100644 --- a/include/git2/apply.h +++ b/include/git2/apply.h @@ -100,6 +100,7 @@ GIT_EXTERN(int) git_apply_options_init(git_apply_options *opts, unsigned int ver * @param preimage the tree to apply the diff to * @param diff the diff to apply * @param options the options for the apply (or null for defaults) + * @return 0 or an error code */ GIT_EXTERN(int) git_apply_to_tree( git_index **out, @@ -137,6 +138,7 @@ typedef enum { * @param diff the diff to apply * @param location the location to apply (workdir, index or both) * @param options the options for the apply (or null for defaults) + * @return 0 or an error code */ GIT_EXTERN(int) git_apply( git_repository *repo, diff --git a/include/git2/tree.h b/include/git2/tree.h index d7545ace929..f2289fc7e6c 100644 --- a/include/git2/tree.h +++ b/include/git2/tree.h @@ -334,6 +334,7 @@ GIT_EXTERN(int) git_treebuilder_insert( * * @param bld Tree builder * @param filename Filename of the entry to remove + * @return 0 or an error code */ GIT_EXTERN(int) git_treebuilder_remove( git_treebuilder *bld, const char *filename); @@ -463,6 +464,7 @@ typedef struct { * @param baseline the tree to base these changes on * @param nupdates the number of elements in the update list * @param updates the list of updates to perform + * @return 0 or an error code */ GIT_EXTERN(int) git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseline, size_t nupdates, const git_tree_update *updates); From 7ed00c5c92682edea3a67581c534ea5e970db038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Wed, 2 Jun 2021 16:31:54 +0200 Subject: [PATCH 0333/1616] Support authentication in push example This adds basic support for user/password and SSH authentication to the push example. Authentication is implemented by using the cred_acquire_cb credential callback defined in examples/common.c. Co-authored-by: Marius Knaust --- examples/push.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/push.c b/examples/push.c index bcf307607b0..5113eed394b 100644 --- a/examples/push.c +++ b/examples/push.c @@ -32,6 +32,7 @@ /** Entry point for this command */ int lg2_push(git_repository *repo, int argc, char **argv) { git_push_options options; + git_remote_callbacks callbacks; git_remote* remote = NULL; char *refspec = "refs/heads/master"; const git_strarray refspecs = { @@ -47,7 +48,11 @@ int lg2_push(git_repository *repo, int argc, char **argv) { check_lg2(git_remote_lookup(&remote, repo, "origin" ), "Unable to lookup remote", NULL); + check_lg2(git_remote_init_callbacks(&callbacks, GIT_REMOTE_CALLBACKS_VERSION), "Error initializing remote callbacks", NULL); + callbacks.credentials = cred_acquire_cb; + check_lg2(git_push_options_init(&options, GIT_PUSH_OPTIONS_VERSION ), "Error initializing push", NULL); + options.callbacks = callbacks; check_lg2(git_remote_push(remote, &refspecs, &options), "Error pushing", NULL); From 11452ca143ebe063419b4991f5ee8279d9fbecee Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Thu, 3 Jun 2021 11:14:58 +0300 Subject: [PATCH 0334/1616] tests: submodule git lookup can be dupped test has been added. --- tests/submodule/lookup.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/submodule/lookup.c b/tests/submodule/lookup.c index 6f7506d2ce5..84ecd8539d3 100644 --- a/tests/submodule/lookup.c +++ b/tests/submodule/lookup.c @@ -42,6 +42,46 @@ void test_submodule_lookup__simple_lookup(void) assert_submodule_exists(g_repo, "sm_added_and_uncommited/"); } +void test_submodule_lookup__can_be_dupped(void) +{ + git_submodule *sm; + git_submodule *sm_duplicate; + const char *oid = "480095882d281ed676fe5b863569520e54a7d5c0"; + + // Check original + cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged")); + cl_assert(git_submodule_owner(sm) == g_repo); + cl_assert_equal_s("sm_unchanged", git_submodule_name(sm)); + cl_assert(git__suffixcmp(git_submodule_path(sm), "sm_unchanged") == 0); + cl_assert(git__suffixcmp(git_submodule_url(sm), "/submod2_target") == 0); + + cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0); + cl_assert(git_oid_streq(git_submodule_head_id(sm), oid) == 0); + cl_assert(git_oid_streq(git_submodule_wd_id(sm), oid) == 0); + + cl_assert(git_submodule_ignore(sm) == GIT_SUBMODULE_IGNORE_NONE); + cl_assert(git_submodule_update_strategy(sm) == GIT_SUBMODULE_UPDATE_CHECKOUT); + + // Duplicate and free original + cl_assert(git_submodule_dup(&sm_duplicate, sm) == 0); + git_submodule_free(sm); + + // Check duplicate + cl_assert(git_submodule_owner(sm_duplicate) == g_repo); + cl_assert_equal_s("sm_unchanged", git_submodule_name(sm_duplicate)); + cl_assert(git__suffixcmp(git_submodule_path(sm_duplicate), "sm_unchanged") == 0); + cl_assert(git__suffixcmp(git_submodule_url(sm_duplicate), "/submod2_target") == 0); + + cl_assert(git_oid_streq(git_submodule_index_id(sm_duplicate), oid) == 0); + cl_assert(git_oid_streq(git_submodule_head_id(sm_duplicate), oid) == 0); + cl_assert(git_oid_streq(git_submodule_wd_id(sm_duplicate), oid) == 0); + + cl_assert(git_submodule_ignore(sm_duplicate) == GIT_SUBMODULE_IGNORE_NONE); + cl_assert(git_submodule_update_strategy(sm_duplicate) == GIT_SUBMODULE_UPDATE_CHECKOUT); + + git_submodule_free(sm_duplicate); +} + void test_submodule_lookup__accessors(void) { git_submodule *sm; From 2934b4477a45f7960b62f7bac9301a6f4cc89679 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Thu, 3 Jun 2021 11:21:39 +0200 Subject: [PATCH 0335/1616] Fix memory leak in git_smart__connect The call to git_proxy_options_dup will replace the url pointer of the proxy. But if the url pointer is already set, the old address will be lost forever and will never be free. --- src/transports/smart.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/transports/smart.c b/src/transports/smart.c index da8fe8e221d..89ad05b377e 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -226,6 +226,9 @@ static int git_smart__connect( t->url = git__strdup(url); GIT_ERROR_CHECK_ALLOC(t->url); + if (t->proxy.url) + git_proxy_options_clear(&t->proxy); + if (git_proxy_options_dup(&t->proxy, proxy) < 0) return -1; From d07a0dc1f1b3e2afc2056a9c120fb58941372580 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Fri, 4 Jun 2021 16:34:32 +0200 Subject: [PATCH 0336/1616] Remove useless condition --- src/transports/smart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/transports/smart.c b/src/transports/smart.c index 89ad05b377e..587f1435889 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -226,8 +226,7 @@ static int git_smart__connect( t->url = git__strdup(url); GIT_ERROR_CHECK_ALLOC(t->url); - if (t->proxy.url) - git_proxy_options_clear(&t->proxy); + git_proxy_options_clear(&t->proxy); if (git_proxy_options_dup(&t->proxy, proxy) < 0) return -1; From 1713ab45510ceeae06d8d3f75e6e4b71a7630658 Mon Sep 17 00:00:00 2001 From: Alex Good Date: Sun, 2 May 2021 13:41:59 +0100 Subject: [PATCH 0337/1616] Respect the force flag on refspecs in git_remote_fetch --- docs/coding-style.md | 2 +- src/remote.c | 3 + tests/remote/fetch.c | 181 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 tests/remote/fetch.c diff --git a/docs/coding-style.md b/docs/coding-style.md index d5188f0bc0c..b8b94d69ca8 100644 --- a/docs/coding-style.md +++ b/docs/coding-style.md @@ -172,7 +172,7 @@ tags: * * @param s String to froznicate * @return A newly allocated string or `NULL` in case an error occurred. - * / + */ char *froznicate(const char *s); ``` diff --git a/src/remote.c b/src/remote.c index 5f6ba5bf74e..d17c3895187 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1460,6 +1460,9 @@ static int update_tips_for_spec( if (error < 0 && error != GIT_ENOTFOUND) goto on_error; + if (!error && !spec->force && !git_graph_descendant_of(remote->repo, &head->oid, &old)) + continue; + if (error == GIT_ENOTFOUND) { memset(&old, 0, GIT_OID_RAWSZ); diff --git a/tests/remote/fetch.c b/tests/remote/fetch.c new file mode 100644 index 00000000000..ac37fc2d332 --- /dev/null +++ b/tests/remote/fetch.c @@ -0,0 +1,181 @@ +#include "../clar_libgit2.h" + +#include "remote.h" +#include "repository.h" + +static git_repository *repo1; +static git_repository *repo2; + +static const char *REPO1_REFNAME = "refs/heads/main"; +static const char *REPO2_REFNAME = "refs/remotes/repo1/main"; +static char *FORCE_FETCHSPEC = "+refs/heads/main:refs/remotes/repo1/main"; +static char *NON_FORCE_FETCHSPEC = "refs/heads/main:refs/remotes/repo1/main"; + +char* strip_trailing_slash(char *path) { + char *result = NULL; + if (path[strlen(path) - 1] == '/') { + result = (char *) malloc(strlen(path) - 1); + memcpy(result, path, strlen(path) - 1); + } else { + result = (char *) malloc(strlen(path)); + strncpy(result, path, strlen(path)); + } + return result; +} + + +void test_remote_fetch__initialize(void) { + git_config *c; + git_buf repo1_path = GIT_BUF_INIT; + git_buf repo2_path = GIT_BUF_INIT; + const char *sandbox = clar_sandbox_path(); + + cl_git_pass(git_buf_join(&repo1_path, '/', sandbox, "fetchtest_repo1")); + cl_git_pass(git_repository_init(&repo1, repo1_path.ptr, true)); + + cl_git_pass(git_buf_join(&repo2_path, '/', sandbox, "fetchtest_repo2")); + cl_git_pass(git_repository_init(&repo2, repo2_path.ptr, true)); + + cl_git_pass(git_repository_config(&c, repo1)); + cl_git_pass(git_config_set_string(c, "user.email", "some@email")); + cl_git_pass(git_config_set_string(c, "user.name", "some@name")); + git_config_free(c); + git_buf_dispose(&repo1_path); + git_buf_dispose(&repo2_path); +} + +void test_remote_fetch__cleanup(void) { + char *repo1_path = strip_trailing_slash(repo1->gitdir); + char *repo2_path = strip_trailing_slash(repo2->gitdir); + + git_repository_free(repo1); + git_repository_free(repo2); + + cl_git_pass(git_futils_rmdir_r(repo1_path, NULL, GIT_RMDIR_REMOVE_FILES)); + free(repo1_path); + + cl_git_pass(git_futils_rmdir_r(repo2_path, NULL, GIT_RMDIR_REMOVE_FILES)); + free(repo2_path); +} + + +/** + * This checks that the '+' flag on fetchspecs is respected. We create a + * repository that has a reference to two commits, one a child of the other. + * We fetch this repository into a second repository. Then we reset the + * reference in the first repository and run the fetch again. If the '+' flag + * is used then the reference in the second repository will change, but if it + * is not then it should stay the same. + * + * @param commit1id A pointer to an OID which will be populated with the first + * commit. + * @param commit2id A pointer to an OID which will be populated with the second + * commit, which is a descendant of the first. + * @param force Whether to use a spec with '+' prefixed to force the refs + * to update + */ +void do_time_travelling_fetch(git_oid *commit1id, git_oid *commit2id, + bool force) { + char *refspec_strs = { + force ? FORCE_FETCHSPEC : NON_FORCE_FETCHSPEC, + }; + git_strarray refspecs = { + .count = 1, + .strings = &refspec_strs, + }; + + // create two commits in repo 1 and a reference to them + { + git_oid empty_tree_id; + git_tree *empty_tree; + git_signature *sig; + git_treebuilder *tb; + cl_git_pass(git_treebuilder_new(&tb, repo1, NULL)); + cl_git_pass(git_treebuilder_write(&empty_tree_id, tb)); + cl_git_pass(git_tree_lookup(&empty_tree, repo1, &empty_tree_id)); + cl_git_pass(git_signature_default(&sig, repo1)); + cl_git_pass(git_commit_create(commit1id, repo1, REPO1_REFNAME, sig, + sig, NULL, "one", empty_tree, 0, NULL)); + cl_git_pass(git_commit_create_v(commit2id, repo1, REPO1_REFNAME, sig, + sig, NULL, "two", empty_tree, 1, commit1id)); + + git_tree_free(empty_tree); + git_signature_free(sig); + git_treebuilder_free(tb); + } + + // fetch the reference via the remote + { + git_remote *remote; + + cl_git_pass(git_remote_create_anonymous(&remote, repo2, + git_repository_path(repo1))); + cl_git_pass(git_remote_fetch(remote, &refspecs, NULL, "some message")); + + git_remote_free(remote); + } + + // assert that repo2 references the second commit + { + const git_oid *target; + git_reference *ref; + cl_git_pass(git_reference_lookup(&ref, repo2, REPO2_REFNAME)); + target = git_reference_target(ref); + cl_assert_equal_b(git_oid_cmp(target, commit2id), 0); + git_reference_free(ref); + } + + // set the reference in repo1 to point to the older commit + { + git_reference *ref; + git_reference *ref2; + cl_git_pass(git_reference_lookup(&ref, repo1, REPO1_REFNAME)); + cl_git_pass(git_reference_set_target(&ref2, ref, commit1id, + "rollback")); + git_reference_free(ref); + git_reference_free(ref2); + } + + // fetch the reference again + { + git_remote *remote; + + cl_git_pass(git_remote_create_anonymous(&remote, repo2, + git_repository_path(repo1))); + cl_git_pass(git_remote_fetch(remote, &refspecs, NULL, "some message")); + + git_remote_free(remote); + } +} + +void test_remote_fetch__dont_update_refs_if_not_descendant_and_not_force(void) { + const git_oid *target; + git_oid commit1id; + git_oid commit2id; + git_reference *ref; + + do_time_travelling_fetch(&commit1id, &commit2id, false); + + // assert that the reference in repo2 has not changed + cl_git_pass(git_reference_lookup(&ref, repo2, REPO2_REFNAME)); + target = git_reference_target(ref); + cl_assert_equal_b(git_oid_cmp(target, &commit2id), 0); + + git_reference_free(ref); +} + +void test_remote_fetch__do_update_refs_if_not_descendant_and_force(void) { + const git_oid *target; + git_oid commit1id; + git_oid commit2id; + git_reference *ref; + + do_time_travelling_fetch(&commit1id, &commit2id, true); + + // assert that the reference in repo2 has changed + cl_git_pass(git_reference_lookup(&ref, repo2, REPO2_REFNAME)); + target = git_reference_target(ref); + cl_assert_equal_b(git_oid_cmp(target, &commit1id), 0); + + git_reference_free(ref); +} From 9410f2b52e3b56ec3c0571417b88d2a700c76558 Mon Sep 17 00:00:00 2001 From: Anders Borum Date: Sun, 13 Jun 2021 08:20:59 +0200 Subject: [PATCH 0338/1616] Update src/ignore.c Co-authored-by: lhchavez --- src/ignore.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ignore.c b/src/ignore.c index 32e5c539bcc..cb4f13f050e 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -146,7 +146,7 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match requiring * to also match / */ effective_flags = wildmatch_flags; - if ((rule->flags & GIT_ATTR_FNMATCH_FULLPATH) == 0) { + if (!(rule->flags & GIT_ATTR_FNMATCH_FULLPATH)) { effective_flags &= ~WM_PATHNAME; } @@ -645,4 +645,3 @@ int git_ignore__check_pathspec_for_exact_ignores( return error; } - From 8cad7e62cdbe13d41dbced7088a508366b416d6b Mon Sep 17 00:00:00 2001 From: Anders Borum Date: Sun, 13 Jun 2021 08:21:05 +0200 Subject: [PATCH 0339/1616] Update src/ignore.c Co-authored-by: lhchavez --- src/ignore.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ignore.c b/src/ignore.c index cb4f13f050e..f796d3d5b84 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -142,8 +142,8 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match goto out; /* if rule isn't for full path we match without PATHNAME flag - as lines like *.txt should match something like dir/test.txt - requiring * to also match / + * as lines like *.txt should match something like dir/test.txt + * requiring * to also match / */ effective_flags = wildmatch_flags; if (!(rule->flags & GIT_ATTR_FNMATCH_FULLPATH)) { From 0b3f6da411dd19ffa0b0ca03d5a6752d3d1f9dd2 Mon Sep 17 00:00:00 2001 From: Waleed Khan Date: Sun, 13 Jun 2021 16:42:00 -0700 Subject: [PATCH 0340/1616] Fix misleading doc for `git_index_find` In https://github.com/libgit2/libgit2/pull/5723/files/fc46dc06f52f854f74371682f911f13856c68edb#r540092847, I was confused by the semantics of `git_index_find`. The documentation says both that it returns the output value in `at_pos` and that it returns it directly as an `int`. This is incorrect; the return value is only returned via `at_pos`. --- include/git2/index.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/index.h b/include/git2/index.h index 14a13249757..dd9227755e7 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -702,7 +702,7 @@ GIT_EXTERN(int) git_index_update_all( * @param at_pos the address to which the position of the index entry is written (optional) * @param index an existing index object * @param path path to search - * @return a zero-based position in the index if found; GIT_ENOTFOUND otherwise + * @return 0 with valid value in at_pos; an error code otherwise */ GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *path); From b34aaf6c5f6b33062b3ccff6b80744492bd2b8f2 Mon Sep 17 00:00:00 2001 From: Anders Borum Date: Mon, 14 Jun 2021 14:39:20 +0200 Subject: [PATCH 0341/1616] test that specific lines can negate broader ignore lines --- tests/ignore/path.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/ignore/path.c b/tests/ignore/path.c index 5d53c9df936..d55bdc5dd23 100644 --- a/tests/ignore/path.c +++ b/tests/ignore/path.c @@ -575,3 +575,11 @@ void test_ignore_path__negative_prefix_rule(void) assert_is_ignored(true, "ff"); assert_is_ignored(false, "f"); } + +void test_ignore_path__negative_more_specific(void) +{ + cl_git_rewritefile("attr/.gitignore", "*.txt\n!/dir/test.txt\n"); + assert_is_ignored(true, "test.txt"); + assert_is_ignored(false, "dir/test.txt"); + assert_is_ignored(true, "outer/dir/test.txt"); +} From 6d2a6f3e06a2d0468c89ed4c2efced58434a8735 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 15 Jun 2021 00:22:30 +0100 Subject: [PATCH 0342/1616] Apply suggestions from code review --- src/ignore.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ignore.c b/src/ignore.c index f796d3d5b84..c9d0b014e4c 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -141,14 +141,14 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match if (git_buf_oom(&buf)) goto out; - /* if rule isn't for full path we match without PATHNAME flag + /* + * if rule isn't for full path we match without PATHNAME flag * as lines like *.txt should match something like dir/test.txt * requiring * to also match / - */ + */ effective_flags = wildmatch_flags; - if (!(rule->flags & GIT_ATTR_FNMATCH_FULLPATH)) { + if (!(rule->flags & GIT_ATTR_FNMATCH_FULLPATH)) effective_flags &= ~WM_PATHNAME; - } /* if we found a match, we want to keep this rule */ if ((wildmatch(git_buf_cstr(&buf), path, effective_flags)) == WM_MATCH) { From 1bdd937d162f8e2d8dd75c8a2606ff90bd37cde7 Mon Sep 17 00:00:00 2001 From: Waleed Khan Date: Mon, 14 Jun 2021 17:25:35 -0700 Subject: [PATCH 0343/1616] Update index.h --- include/git2/index.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/git2/index.h b/include/git2/index.h index dd9227755e7..532a52091f4 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -702,7 +702,7 @@ GIT_EXTERN(int) git_index_update_all( * @param at_pos the address to which the position of the index entry is written (optional) * @param index an existing index object * @param path path to search - * @return 0 with valid value in at_pos; an error code otherwise + * @return 0 or an error code */ GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *path); @@ -713,7 +713,7 @@ GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *pat * @param at_pos the address to which the position of the index entry is written (optional) * @param index an existing index object * @param prefix the prefix to search for - * @return 0 with valid value in at_pos; an error code otherwise + * @return 0 or an error code */ GIT_EXTERN(int) git_index_find_prefix(size_t *at_pos, git_index *index, const char *prefix); From 428f1acf97131614d63c23e632ef6ddee7450c51 Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Tue, 15 Jun 2021 17:33:03 +0300 Subject: [PATCH 0344/1616] submodule: git submodule dup out and source parameters have become mandatory. --- include/git2/submodule.h | 2 +- src/submodule.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/git2/submodule.h b/include/git2/submodule.h index 857c62f899b..29d8bc1ce55 100644 --- a/include/git2/submodule.h +++ b/include/git2/submodule.h @@ -227,7 +227,7 @@ GIT_EXTERN(int) git_submodule_lookup( * Create an in-memory copy of a submodule. The copy must be explicitly * free'd or it will leak. * - * @param out Pointer to store the copy of the submodule. Cannot be NULL. + * @param out Pointer to store the copy of the submodule. * @param source Original submodule to copy. */ GIT_EXTERN(int) git_submodule_dup(git_submodule **out, git_submodule *source); diff --git a/src/submodule.c b/src/submodule.c index ee31bd8a03c..7cbb9fa3a1a 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -1857,9 +1857,9 @@ static void submodule_release(git_submodule *sm) int git_submodule_dup(git_submodule **out, git_submodule *source) { GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(source); - if (source != NULL) - GIT_REFCOUNT_INC(source); + GIT_REFCOUNT_INC(source); *out = source; return 0; From 54a524524ca1609bcc78f8f60143e0423d5c4344 Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Tue, 15 Jun 2021 17:33:29 +0300 Subject: [PATCH 0345/1616] tests: submodule git lookup can be dupped test comments have been changed. --- tests/submodule/lookup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/submodule/lookup.c b/tests/submodule/lookup.c index 84ecd8539d3..f49ebb4bdc6 100644 --- a/tests/submodule/lookup.c +++ b/tests/submodule/lookup.c @@ -48,7 +48,7 @@ void test_submodule_lookup__can_be_dupped(void) git_submodule *sm_duplicate; const char *oid = "480095882d281ed676fe5b863569520e54a7d5c0"; - // Check original + /* Check original */ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged")); cl_assert(git_submodule_owner(sm) == g_repo); cl_assert_equal_s("sm_unchanged", git_submodule_name(sm)); @@ -62,11 +62,11 @@ void test_submodule_lookup__can_be_dupped(void) cl_assert(git_submodule_ignore(sm) == GIT_SUBMODULE_IGNORE_NONE); cl_assert(git_submodule_update_strategy(sm) == GIT_SUBMODULE_UPDATE_CHECKOUT); - // Duplicate and free original + /* Duplicate and free original */ cl_assert(git_submodule_dup(&sm_duplicate, sm) == 0); git_submodule_free(sm); - // Check duplicate + /* Check duplicate */ cl_assert(git_submodule_owner(sm_duplicate) == g_repo); cl_assert_equal_s("sm_unchanged", git_submodule_name(sm_duplicate)); cl_assert(git__suffixcmp(git_submodule_path(sm_duplicate), "sm_unchanged") == 0); From bea1b024e2c8e6b6b52e6f2fb74667937f687db2 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 16 Jun 2021 10:32:46 +0200 Subject: [PATCH 0346/1616] Add test for fetch proxy memleak --- tests/online/fetch.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/online/fetch.c b/tests/online/fetch.c index f939a16b8b6..67dfd69ed62 100644 --- a/tests/online/fetch.c +++ b/tests/online/fetch.c @@ -3,9 +3,19 @@ static git_repository *_repo; static int counter; +static char *_remote_proxy_scheme = NULL; +static char *_remote_proxy_host = NULL; +static char *_remote_proxy_user = NULL; +static char *_remote_proxy_pass = NULL; + void test_online_fetch__initialize(void) { cl_git_pass(git_repository_init(&_repo, "./fetch", 0)); + + _remote_proxy_scheme = cl_getenv("GITTEST_REMOTE_PROXY_SCHEME"); + _remote_proxy_host = cl_getenv("GITTEST_REMOTE_PROXY_HOST"); + _remote_proxy_user = cl_getenv("GITTEST_REMOTE_PROXY_USER"); + _remote_proxy_pass = cl_getenv("GITTEST_REMOTE_PROXY_PASS"); } void test_online_fetch__cleanup(void) @@ -14,6 +24,11 @@ void test_online_fetch__cleanup(void) _repo = NULL; cl_fixture_cleanup("./fetch"); + + git__free(_remote_proxy_scheme); + git__free(_remote_proxy_host); + git__free(_remote_proxy_user); + git__free(_remote_proxy_pass); } static int update_tips(const char *refname, const git_oid *a, const git_oid *b, void *data) @@ -207,3 +222,28 @@ void test_online_fetch__twice(void) git_remote_free(remote); } + +void test_online_fetch__proxy(void) +{ + git_remote *remote; + git_buf url = GIT_BUF_INIT; + git_fetch_options fetch_opts; + + if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) + cl_skip(); + + cl_git_pass(git_buf_printf(&url, "%s://%s:%s@%s/", + _remote_proxy_scheme ? _remote_proxy_scheme : "http", + _remote_proxy_user, _remote_proxy_pass, _remote_proxy_host)); + + cl_git_pass(git_fetch_options_init(&fetch_opts, GIT_FETCH_OPTIONS_VERSION)); + fetch_opts.proxy_opts.type = GIT_PROXY_SPECIFIED; + fetch_opts.proxy_opts.url = url.ptr; + + cl_git_pass(git_remote_create(&remote, _repo, "test", "https://github.com/libgit2/TestGitRepository.git")); + cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, &fetch_opts.proxy_opts, NULL)); + cl_git_pass(git_remote_fetch(remote, NULL, &fetch_opts, NULL)); + + git_remote_free(remote); + git_buf_dispose(&url); +} From b0fd4cf82c4652cba7b9de5aaab6cd95bc5fa925 Mon Sep 17 00:00:00 2001 From: David Turner Date: Wed, 16 Jun 2021 13:38:45 -0400 Subject: [PATCH 0347/1616] Consider files executable only if the user can execute them This is what git.git does, so we should follow suit. --- src/futils.h | 2 +- tests/status/worktree.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/futils.h b/src/futils.h index 4668d7b63cf..58936125ac2 100644 --- a/src/futils.h +++ b/src/futils.h @@ -257,7 +257,7 @@ extern int git_futils_truncate(const char *path, int mode); */ extern int git_futils_filesize(uint64_t *out, git_file fd); -#define GIT_PERMS_IS_EXEC(MODE) (((MODE) & 0111) != 0) +#define GIT_PERMS_IS_EXEC(MODE) (((MODE) & 0100) != 0) #define GIT_PERMS_CANONICAL(MODE) (GIT_PERMS_IS_EXEC(MODE) ? 0755 : 0644) #define GIT_PERMS_FOR_WRITE(MODE) (GIT_PERMS_IS_EXEC(MODE) ? 0777 : 0666) diff --git a/tests/status/worktree.c b/tests/status/worktree.c index d2842485b48..d9fce44046a 100644 --- a/tests/status/worktree.c +++ b/tests/status/worktree.c @@ -605,6 +605,45 @@ void test_status_worktree__filemode_changes(void) cl_assert_equal_i(0, counts.wrong_sorted_path); } +void test_status_worktree__filemode_non755(void) +{ + git_repository *repo = cl_git_sandbox_init("filemodes"); + status_entry_counts counts; + git_status_options opts = GIT_STATUS_OPTIONS_INIT; + git_buf executable_path = GIT_BUF_INIT; + git_buf nonexecutable_path = GIT_BUF_INIT; + + if (!cl_is_chmod_supported()) + return; + + opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED | + GIT_STATUS_OPT_INCLUDE_IGNORED | + GIT_STATUS_OPT_INCLUDE_UNMODIFIED; + + git_buf_joinpath(&executable_path, git_repository_workdir(repo), "exec_on"); + cl_must_pass(p_chmod(git_buf_cstr(&executable_path), 0744)); + git_buf_dispose(&executable_path); + + git_buf_joinpath(&nonexecutable_path, git_repository_workdir(repo), "exec_off"); + + cl_must_pass(p_chmod(git_buf_cstr(&nonexecutable_path), 0655)); + git_buf_dispose(&nonexecutable_path); + + memset(&counts, 0, sizeof(counts)); + counts.expected_entry_count = filemode_count; + counts.expected_paths = filemode_paths; + counts.expected_statuses = filemode_statuses; + + cl_git_pass( + git_status_foreach_ext(repo, &opts, cb_status__normal, &counts) + ); + + cl_assert_equal_i(counts.expected_entry_count, counts.entry_count); + cl_assert_equal_i(0, counts.wrong_status_flags_count); + cl_assert_equal_i(0, counts.wrong_sorted_path); +} + + static int cb_status__interrupt(const char *p, unsigned int s, void *payload) { volatile int *count = (int *)payload; From 045031bbdcc9017778d197cbbd13ddd719fe03f6 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Thu, 17 Jun 2021 19:56:00 +0200 Subject: [PATCH 0348/1616] Update from regex to pcre licensing information --- docs/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing.md b/docs/contributing.md index 21e42b1d92f..c51ab87efc5 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -18,7 +18,7 @@ The bundled dependencies in the `deps` directories are governed by the following licenses: - http-parser is licensed under [MIT license](../deps/http-parser/COPYING) -- regex is governed by [LGPL v2.1+ license](../deps/regex/COPYING) +- pcre is governed by [BSD license](../deps/pcre/LICENCE) - winhttp is governed by [LGPL v2.1+](../deps/winhttp/COPYING.LGPL) and [GPL v2 with linking exception](../deps/winhttp/COPYING.GPL) - zlib is governed by [zlib license](../deps/zlib/COPYING) From 55f2abb834e28fc6f04327a1a24b73f0de2b9487 Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Fri, 18 Jun 2021 15:47:15 +0300 Subject: [PATCH 0349/1616] tests: upstream merge test has been added. --- tests/refs/branches/upstream.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/refs/branches/upstream.c b/tests/refs/branches/upstream.c index 928a9ff7bee..f6fd509b869 100644 --- a/tests/refs/branches/upstream.c +++ b/tests/refs/branches/upstream.c @@ -71,6 +71,29 @@ void test_refs_branches_upstream__upstream_remote(void) git_buf_dispose(&buf); } +void test_refs_branches_upstream__upstream_merge(void) +{ + git_reference *branch; + git_repository *repository; + git_buf buf = GIT_BUF_INIT; + + repository = cl_git_sandbox_init("testrepo.git"); + + /* check repository */ + cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/test")); + cl_git_pass(git_branch_set_upstream(branch, "test/master")); + + assert_config_entry_value(repository, "branch.test.remote", "test"); + assert_config_entry_value(repository, "branch.test.merge", "refs/heads/master"); + + git_reference_free(branch); + + /* check merge branch */ + cl_git_pass(git_branch_upstream_merge(&buf, repository, "refs/heads/test")); + cl_assert_equal_s("refs/heads/master", buf.ptr); + git_buf_dispose(&buf); +} + void test_refs_branches_upstream__upstream_remote_empty_value(void) { git_repository *repository; From a2cd66be8a7a0da65a197eef69c4dadc9ecf7f49 Mon Sep 17 00:00:00 2001 From: Nicolas Cavallari Date: Wed, 23 Jun 2021 16:57:48 +0200 Subject: [PATCH 0350/1616] docs: stop mentioning libgit2's "master" branch The name of libgit2's main branch is now "main" but contributing.md and release.md still reference "master" as the main branch. Fix it. --- docs/contributing.md | 8 ++++---- docs/release.md | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/contributing.md b/docs/contributing.md index 21e42b1d92f..a6eca3d15ad 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -35,7 +35,7 @@ easily accessible permanent record of the conversation. ## Libgit2 Versions -The `master` branch is the main branch where development happens. +The `main` branch is the main branch where development happens. Releases are tagged (e.g. [v0.21.0](https://github.com/libgit2/libgit2/releases/tag/v0.21.0) ) and when a critical bug fix needs to be backported, it will be done on a @@ -51,7 +51,7 @@ commit SHA Using [`git describe`](http://git-scm.com/docs/git-describe) is a great way to tell us what version you're working with. -If you're not running against the latest `master` branch version, +If you're not running against the latest `main` branch version, please compile and test against that to avoid re-reporting an issue that's already been fixed. @@ -68,11 +68,11 @@ flow](https://guides.github.com/introduction/flow/index.html), where contributors fork the [libgit2 repository](https://github.com/libgit2/libgit2), make their changes on branch, and submit a [Pull Request](https://help.github.com/articles/using-pull-requests) -(a.k.a. "PR"). Pull requests should usually be targeted at the `master` +(a.k.a. "PR"). Pull requests should usually be targeted at the `main` branch. Life will be a lot easier for you (and us) if you follow this pattern -(i.e. fork, named branch, submit PR). If you use your fork's `master` +(i.e. fork, named branch, submit PR). If you use your fork's `main` branch directly, things can get messy. Please include a nice description of your changes when you submit your PR; diff --git a/docs/release.md b/docs/release.md index 22b35ede7db..507d58b8aaa 100644 --- a/docs/release.md +++ b/docs/release.md @@ -1,6 +1,6 @@ # Releasing the library -We have three kinds of releases: "full" releases, maintenance releases and security releases. Full ones release the state of the `master` branch whereas maintenance releases provide bugfixes building on top of the currently released series. Security releases are also for the current series but only contain security fixes on top of the previous release. +We have three kinds of releases: "full" releases, maintenance releases and security releases. Full ones release the state of the `main` branch whereas maintenance releases provide bugfixes building on top of the currently released series. Security releases are also for the current series but only contain security fixes on top of the previous release. ## Full release @@ -40,7 +40,7 @@ followed by the three sections in the changelog. For release candidates we can a During the freeze, and certainly after the first release candidate, any bindings the core team work with should be updated in order to discover any issues that might come up with the multitude of approaches to memory management, embedding or linking. -Create a branch `maint/v0.X` at the current state of `master` after you've created the tag. This will be used for maintenance releases and lets our dependents track the latest state of the series. +Create a branch `maint/v0.X` at the current state of `main` after you've created the tag. This will be used for maintenance releases and lets our dependents track the latest state of the series. ## Maintenance release @@ -76,7 +76,7 @@ We use docurium to generate our documentation. It is a tool written in ruby whic gem install docurium -and run it against our description file with the tip of master checked out. +and run it against our description file with the tip of main checked out. cm doc api.docurium From 4bf136b0c33c0066e1a4da8c236b42d4f655073f Mon Sep 17 00:00:00 2001 From: Nicolas Cavallari Date: Wed, 23 Jun 2021 16:53:53 +0200 Subject: [PATCH 0351/1616] config: fix included configs not refreshed more than once If an included config is refreshed twice, the second update is not taken into account. This is because the list of included files is cleared after re-reading the new configuration, instead of being cleared before. Fix it and add a test case to check for this bug. --- src/config_file.c | 20 ++++++++++++++------ tests/config/include.c | 24 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/config_file.c b/src/config_file.c index 7fba71a98ba..5267beb943d 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -164,23 +164,27 @@ static int config_file_is_modified(int *modified, config_file *file) return error; } +static void config_file_clear_includes(config_file_backend* cfg) +{ + config_file *include; + uint32_t i; + + git_array_foreach(cfg->file.includes, i, include) + config_file_clear(include); + git_array_clear(cfg->file.includes); +} + static int config_file_set_entries(git_config_backend *cfg, git_config_entries *entries) { config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent); git_config_entries *old = NULL; - config_file *include; int error; - uint32_t i; if (b->parent.readonly) { git_error_set(GIT_ERROR_CONFIG, "this backend is read-only"); return -1; } - git_array_foreach(b->file.includes, i, include) - config_file_clear(include); - git_array_clear(b->file.includes); - if ((error = git_mutex_lock(&b->values_mutex)) < 0) { git_error_set(GIT_ERROR_OS, "failed to lock config backend"); goto out; @@ -202,6 +206,8 @@ static int config_file_refresh_from_buffer(git_config_backend *cfg, const char * git_config_entries *entries = NULL; int error; + config_file_clear_includes(b); + if ((error = git_config_entries_new(&entries)) < 0 || (error = config_file_read_buffer(entries, b->repo, &b->file, b->level, 0, buf, buflen)) < 0 || @@ -229,6 +235,8 @@ static int config_file_refresh(git_config_backend *cfg) if (!modified) return 0; + config_file_clear_includes(b); + if ((error = git_config_entries_new(&entries)) < 0 || (error = config_file_read(entries, b->repo, &b->file, b->level, 0)) < 0 || (error = config_file_set_entries(cfg, entries)) < 0) diff --git a/tests/config/include.c b/tests/config/include.c index e2b0fc96cf1..b702d621140 100644 --- a/tests/config/include.c +++ b/tests/config/include.c @@ -178,6 +178,30 @@ void test_config_include__rewriting_include_refreshes_values(void) cl_git_pass(p_unlink("second")); } +void test_config_include__rewriting_include_twice_refreshes_values(void) +{ + cl_git_mkfile("top-level", "[include]\npath = included"); + cl_git_mkfile("included", "[foo]\nbar = first-value"); + + cl_git_pass(git_config_open_ondisk(&cfg, "top-level")); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar")); + + git_buf_clear(&buf); + cl_git_mkfile("included", "[foo]\nother = value2"); + cl_git_fail(git_config_get_string_buf(&buf, cfg, "foo.bar")); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.other")); + cl_assert_equal_s(buf.ptr, "value2"); + + git_buf_clear(&buf); + cl_git_mkfile("included", "[foo]\nanother = bar"); + cl_git_fail(git_config_get_string_buf(&buf, cfg, "foo.other")); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.another")); + cl_assert_equal_s(buf.ptr, "bar"); + + cl_git_pass(p_unlink("top-level")); + cl_git_pass(p_unlink("included")); +} + void test_config_include__included_variables_cannot_be_deleted(void) { cl_git_mkfile("top-level", "[include]\npath = included\n"); From 9eeee00fe27fa8741f72c83f5a5923aeaae4dee0 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 25 Jun 2021 14:49:33 -0500 Subject: [PATCH 0352/1616] Update docs/release.md Co-authored-by: lhchavez --- docs/release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release.md b/docs/release.md index 507d58b8aaa..3200c4449e4 100644 --- a/docs/release.md +++ b/docs/release.md @@ -76,7 +76,7 @@ We use docurium to generate our documentation. It is a tool written in ruby whic gem install docurium -and run it against our description file with the tip of main checked out. +and run it against our description file with the tip of `main` checked out. cm doc api.docurium From 416ea5b46de01b86961d29911f6298c47d30714b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 25 Jun 2021 14:58:06 -0500 Subject: [PATCH 0353/1616] README: libera.chat not Freenode --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b8448be8867..aa642549d7b 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,8 @@ Getting Help **Chat with us** -- via IRC: join [#libgit2](https://webchat.freenode.net/#libgit2) on Freenode +- via IRC: join [#libgit2](https://web.libera.chat/#libgit2) on + [libera](https://libera.chat). - via Slack: visit [slack.libgit2.org](http://slack.libgit2.org/) to sign up, then join us in `#libgit2` From a2cd10e52b1f8ef77946129448b33128cd01e984 Mon Sep 17 00:00:00 2001 From: Jacques Germishuys Date: Sat, 26 Jun 2021 18:52:21 +0100 Subject: [PATCH 0354/1616] define WINHTTP_NO_CLIENT_CERT_CONTEXT if needed --- src/transports/winhttp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index 97ceab2d442..d21c50651e2 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -52,6 +52,10 @@ # define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3 0x00002000 #endif +#ifndef WINHTTP_NO_CLIENT_CERT_CONTEXT +# define WINHTTP_NO_CLIENT_CERT_CONTEXT NULL +#endif + #ifndef HTTP_STATUS_PERMANENT_REDIRECT # define HTTP_STATUS_PERMANENT_REDIRECT 308 #endif From 8ad5998f9a150cdaf7d5d39bd1b008354bb4c1fe Mon Sep 17 00:00:00 2001 From: Alex Good Date: Wed, 30 Jun 2021 12:59:37 +0100 Subject: [PATCH 0355/1616] Fix memory sanitizer failures in tests --- tests/remote/fetch.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/tests/remote/fetch.c b/tests/remote/fetch.c index ac37fc2d332..8a61a26721e 100644 --- a/tests/remote/fetch.c +++ b/tests/remote/fetch.c @@ -5,6 +5,8 @@ static git_repository *repo1; static git_repository *repo2; +static char* repo1_path; +static char* repo2_path; static const char *REPO1_REFNAME = "refs/heads/main"; static const char *REPO2_REFNAME = "refs/remotes/repo1/main"; @@ -12,42 +14,43 @@ static char *FORCE_FETCHSPEC = "+refs/heads/main:refs/remotes/repo1/main"; static char *NON_FORCE_FETCHSPEC = "refs/heads/main:refs/remotes/repo1/main"; char* strip_trailing_slash(char *path) { - char *result = NULL; if (path[strlen(path) - 1] == '/') { - result = (char *) malloc(strlen(path) - 1); + char* result = (char *) calloc(strlen(path) - 1, sizeof(char)); memcpy(result, path, strlen(path) - 1); + return result; } else { - result = (char *) malloc(strlen(path)); + char* result = (char *) calloc(strlen(path), sizeof(char)); strncpy(result, path, strlen(path)); + return result; } - return result; } void test_remote_fetch__initialize(void) { git_config *c; - git_buf repo1_path = GIT_BUF_INIT; - git_buf repo2_path = GIT_BUF_INIT; + git_buf repo1_path_buf = GIT_BUF_INIT; + git_buf repo2_path_buf = GIT_BUF_INIT; const char *sandbox = clar_sandbox_path(); - cl_git_pass(git_buf_join(&repo1_path, '/', sandbox, "fetchtest_repo1")); - cl_git_pass(git_repository_init(&repo1, repo1_path.ptr, true)); + cl_git_pass(git_buf_join(&repo1_path_buf, '/', sandbox, "fetchtest_repo1")); + repo1_path = calloc(repo1_path_buf.size, sizeof(char)); + git_buf_copy_cstr(repo1_path, repo1_path_buf.size, &repo1_path_buf); + cl_git_pass(git_repository_init(&repo1, repo1_path, true)); - cl_git_pass(git_buf_join(&repo2_path, '/', sandbox, "fetchtest_repo2")); - cl_git_pass(git_repository_init(&repo2, repo2_path.ptr, true)); + cl_git_pass(git_buf_join(&repo2_path_buf, '/', sandbox, "fetchtest_repo2")); + repo2_path = calloc(repo2_path_buf.size, sizeof(char)); + git_buf_copy_cstr(repo2_path, repo2_path_buf.size, &repo2_path_buf); + cl_git_pass(git_repository_init(&repo2, repo2_path, true)); cl_git_pass(git_repository_config(&c, repo1)); cl_git_pass(git_config_set_string(c, "user.email", "some@email")); cl_git_pass(git_config_set_string(c, "user.name", "some@name")); git_config_free(c); - git_buf_dispose(&repo1_path); - git_buf_dispose(&repo2_path); + git_buf_dispose(&repo1_path_buf); + git_buf_dispose(&repo2_path_buf); } void test_remote_fetch__cleanup(void) { - char *repo1_path = strip_trailing_slash(repo1->gitdir); - char *repo2_path = strip_trailing_slash(repo2->gitdir); - git_repository_free(repo1); git_repository_free(repo2); From c960e0b1eb382e74676bda583084dc1d8b502e4b Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Tue, 8 Jun 2021 15:57:44 +0200 Subject: [PATCH 0356/1616] Fix bad char at the end of the word --- include/git2/remote.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/remote.h b/include/git2/remote.h index b82bd250b43..05f87099212 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -944,7 +944,7 @@ GIT_EXTERN(int) git_remote_delete(git_repository *repo, const char *name); * * This function must only be called after connecting. * - * @param out the buffern in which to store the reference name + * @param out the buffer in which to store the reference name * @param remote the remote * @return 0, GIT_ENOTFOUND if the remote does not have any references * or none of them point to HEAD's commit, or an error message. From 131f0805398fa7e9e12a803143ec6fa1512156d2 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 16 Jun 2021 17:45:01 +0200 Subject: [PATCH 0357/1616] Fix documentation formatting for git_diff_file --- include/git2/diff.h | 49 +++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/include/git2/diff.h b/include/git2/diff.h index c63d93dc8af..9497793c3d2 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -241,32 +241,43 @@ typedef enum { * Although this is called a "file", it could represent a file, a symbolic * link, a submodule commit id, or even a tree (although that only if you * are tracking type changes or ignored/untracked directories). - * - * The `id` is the `git_oid` of the item. If the entry represents an - * absent side of a diff (e.g. the `old_file` of a `GIT_DELTA_ADDED` delta), - * then the oid will be zeroes. - * - * `path` is the NUL-terminated path to the entry relative to the working - * directory of the repository. - * - * `size` is the size of the entry in bytes. - * - * `flags` is a combination of the `git_diff_flag_t` types - * - * `mode` is, roughly, the stat() `st_mode` value for the item. This will - * be restricted to one of the `git_filemode_t` values. - * - * The `id_abbrev` represents the known length of the `id` field, when - * converted to a hex string. It is generally `GIT_OID_HEXSZ`, unless this - * delta was created from reading a patch file, in which case it may be - * abbreviated to something reasonable, like 7 characters. */ typedef struct { + /** + * The `git_oid` of the item. If the entry represents an + * absent side of a diff (e.g. the `old_file` of a `GIT_DELTA_ADDED` delta), + * then the oid will be zeroes. + */ git_oid id; + + /** + * The NUL-terminated path to the entry relative to the working + * directory of the repository. + */ const char *path; + + /** + * The size of the entry in bytes. + */ git_object_size_t size; + + /** + * A combination of the `git_diff_flag_t` types + */ uint32_t flags; + + /** + * Roughly, the stat() `st_mode` value for the item. This will + * be restricted to one of the `git_filemode_t` values. + */ uint16_t mode; + + /** + * Represents the known length of the `id` field, when + * converted to a hex string. It is generally `GIT_OID_HEXSZ`, unless this + * delta was created from reading a patch file, in which case it may be + * abbreviated to something reasonable, like 7 characters. + */ uint16_t id_abbrev; } git_diff_file; From aefbd18948180cbe2ce7db2ca087b4dad8f2278d Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 16 Jun 2021 17:46:24 +0200 Subject: [PATCH 0358/1616] Add missing empty line --- include/git2/remote.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/git2/remote.h b/include/git2/remote.h index 05f87099212..c600e224855 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -878,6 +878,7 @@ GIT_EXTERN(git_remote_autotag_option_t) git_remote_autotag(const git_remote *rem * @param value the new value to take. */ GIT_EXTERN(int) git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_autotag_option_t value); + /** * Retrieve the ref-prune setting * From 48e3c25b930ac7156141dda07a0874958acbf96e Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 16 Jun 2021 17:50:40 +0200 Subject: [PATCH 0359/1616] Add missing return documentation --- include/git2/remote.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/git2/remote.h b/include/git2/remote.h index c600e224855..5d7a5367d8c 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -253,6 +253,7 @@ GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, con * @param repo the repository in which to perform the change * @param remote the remote's name * @param url the url to set + * @return 0, or an error code */ GIT_EXTERN(int) git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url); @@ -876,6 +877,7 @@ GIT_EXTERN(git_remote_autotag_option_t) git_remote_autotag(const git_remote *rem * @param repo the repository in which to make the change * @param remote the name of the remote * @param value the new value to take. + * @return 0, or an error code. */ GIT_EXTERN(int) git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_autotag_option_t value); From f1697936724dd4c6e4d7c1b679c2363c77ba7c32 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Tue, 6 Jul 2021 17:44:38 +0200 Subject: [PATCH 0360/1616] Fix struct documentation formatting --- include/git2/blame.h | 62 +++++++++++------ include/git2/checkout.h | 34 ++++++---- include/git2/status.h | 147 ++++++++++++++++++++++++++-------------- include/git2/worktree.h | 1 + 4 files changed, 158 insertions(+), 86 deletions(-) diff --git a/include/git2/blame.h b/include/git2/blame.h index f42c8155289..566d4db7bd7 100644 --- a/include/git2/blame.h +++ b/include/git2/blame.h @@ -108,41 +108,59 @@ GIT_EXTERN(int) git_blame_options_init( /** * Structure that represents a blame hunk. - * - * - `lines_in_hunk` is the number of lines in this hunk - * - `final_commit_id` is the OID of the commit where this line was last - * changed. - * - `final_start_line_number` is the 1-based line number where this hunk - * begins, in the final version of the file - * - `final_signature` is the author of `final_commit_id`. If - * `GIT_BLAME_USE_MAILMAP` has been specified, it will contain the canonical - * real name and email address. - * - `orig_commit_id` is the OID of the commit where this hunk was found. This - * will usually be the same as `final_commit_id`, except when - * `GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES` has been specified. - * - `orig_path` is the path to the file where this hunk originated, as of the - * commit specified by `orig_commit_id`. - * - `orig_start_line_number` is the 1-based line number where this hunk begins - * in the file named by `orig_path` in the commit specified by - * `orig_commit_id`. - * - `orig_signature` is the author of `orig_commit_id`. If - * `GIT_BLAME_USE_MAILMAP` has been specified, it will contain the canonical - * real name and email address. - * - `boundary` is 1 iff the hunk has been tracked to a boundary commit (the - * root, or the commit specified in git_blame_options.oldest_commit) */ typedef struct git_blame_hunk { + /** + * The number of lines in this hunk. + */ size_t lines_in_hunk; + /** + * The OID of the commit where this line was last changed. + */ git_oid final_commit_id; + + /** + * The 1-based line number where this hunk begins, in the final version + * of the file. + */ size_t final_start_line_number; + + /** + * The author of `final_commit_id`. If `GIT_BLAME_USE_MAILMAP` has been + * specified, it will contain the canonical real name and email address. + */ git_signature *final_signature; + /** + * The OID of the commit where this hunk was found. + * This will usually be the same as `final_commit_id`, except when + * `GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES` has been specified. + */ git_oid orig_commit_id; + + /** + * The path to the file where this hunk originated, as of the commit + * specified by `orig_commit_id`. + */ const char *orig_path; + + /** + * The 1-based line number where this hunk begins in the file named by + * `orig_path` in the commit specified by `orig_commit_id`. + */ size_t orig_start_line_number; + + /** + * The author of `orig_commit_id`. If `GIT_BLAME_USE_MAILMAP` has been + * specified, it will contain the canonical real name and email address. + */ git_signature *orig_signature; + /** + * The 1 iff the hunk has been tracked to a boundary commit (the root, or + * the commit specified in git_blame_options.oldest_commit) + */ char boundary; } git_blame_hunk; diff --git a/include/git2/checkout.h b/include/git2/checkout.h index 3c87001bf33..ca6f17aa662 100644 --- a/include/git2/checkout.h +++ b/include/git2/checkout.h @@ -194,18 +194,6 @@ typedef enum { * Checkout will invoke an options notification callback (`notify_cb`) for * certain cases - you pick which ones via `notify_flags`: * - * - GIT_CHECKOUT_NOTIFY_CONFLICT invokes checkout on conflicting paths. - * - * - GIT_CHECKOUT_NOTIFY_DIRTY notifies about "dirty" files, i.e. those that - * do not need an update but no longer match the baseline. Core git - * displays these files when checkout runs, but won't stop the checkout. - * - * - GIT_CHECKOUT_NOTIFY_UPDATED sends notification for any file changed. - * - * - GIT_CHECKOUT_NOTIFY_UNTRACKED notifies about untracked files. - * - * - GIT_CHECKOUT_NOTIFY_IGNORED notifies about ignored files. - * * Returning a non-zero value from this callback will cancel the checkout. * The non-zero return value will be propagated back and returned by the * git_checkout_... call. @@ -216,10 +204,32 @@ typedef enum { */ typedef enum { GIT_CHECKOUT_NOTIFY_NONE = 0, + + /** + * Invokes checkout on conflicting paths. + */ GIT_CHECKOUT_NOTIFY_CONFLICT = (1u << 0), + + /** + * Notifies about "dirty" files, i.e. those that do not need an update + * but no longer match the baseline. Core git displays these files when + * checkout runs, but won't stop the checkout. + */ GIT_CHECKOUT_NOTIFY_DIRTY = (1u << 1), + + /** + * Sends notification for any file changed. + */ GIT_CHECKOUT_NOTIFY_UPDATED = (1u << 2), + + /** + * Notifies about untracked files. + */ GIT_CHECKOUT_NOTIFY_UNTRACKED = (1u << 3), + + /** + * Notifies about ignored files. + */ GIT_CHECKOUT_NOTIFY_IGNORED = (1u << 4), GIT_CHECKOUT_NOTIFY_ALL = 0x0FFFFu diff --git a/include/git2/status.h b/include/git2/status.h index 9693cc47862..ed9856a2a33 100644 --- a/include/git2/status.h +++ b/include/git2/status.h @@ -69,89 +69,132 @@ typedef int GIT_CALLBACK(git_status_cb)( * With `git_status_foreach_ext`, this will control which changes get * callbacks. With `git_status_list_new`, these will control which * changes are included in the list. - * - * - GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This roughly - * matches `git status --porcelain` regarding which files are - * included and in what order. - * - GIT_STATUS_SHOW_INDEX_ONLY only gives status based on HEAD to index - * comparison, not looking at working directory changes. - * - GIT_STATUS_SHOW_WORKDIR_ONLY only gives status based on index to - * working directory comparison, not comparing the index to the HEAD. */ typedef enum { + /** + * The default. This roughly matches `git status --porcelain` regarding + * which files are included and in what order. + */ GIT_STATUS_SHOW_INDEX_AND_WORKDIR = 0, + + /** + * Only gives status based on HEAD to index comparison, not looking at + * working directory changes. + */ GIT_STATUS_SHOW_INDEX_ONLY = 1, + + /** + * Only gives status based on index to working directory comparison, + * not comparing the index to the HEAD. + */ GIT_STATUS_SHOW_WORKDIR_ONLY = 2, } git_status_show_t; /** * Flags to control status callbacks * - * - GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should be made - * on untracked files. These will only be made if the workdir files are - * included in the status "show" option. - * - GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files get callbacks. - * Again, these callbacks will only be made if the workdir files are - * included in the status "show" option. - * - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback should be - * made even on unmodified files. - * - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that submodules should be - * skipped. This only applies if there are no pending typechanges to - * the submodule (either from or to another type). - * - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that all files in - * untracked directories should be included. Normally if an entire - * directory is new, then just the top-level directory is included (with - * a trailing slash on the entry name). This flag says to include all - * of the individual files in the directory instead. - * - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given path - * should be treated as a literal path, and not as a pathspec pattern. - * - GIT_STATUS_OPT_RECURSE_IGNORED_DIRS indicates that the contents of - * ignored directories should be included in the status. This is like - * doing `git ls-files -o -i --exclude-standard` with core git. - * - GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX indicates that rename detection - * should be processed between the head and the index and enables - * the GIT_STATUS_INDEX_RENAMED as a possible status flag. - * - GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR indicates that rename - * detection should be run between the index and the working directory - * and enabled GIT_STATUS_WT_RENAMED as a possible status flag. - * - GIT_STATUS_OPT_SORT_CASE_SENSITIVELY overrides the native case - * sensitivity for the file system and forces the output to be in - * case-sensitive order - * - GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY overrides the native case - * sensitivity for the file system and forces the output to be in - * case-insensitive order - * - GIT_STATUS_OPT_RENAMES_FROM_REWRITES indicates that rename detection - * should include rewritten files - * - GIT_STATUS_OPT_NO_REFRESH bypasses the default status behavior of - * doing a "soft" index reload (i.e. reloading the index data if the - * file on disk has been modified outside libgit2). - * - GIT_STATUS_OPT_UPDATE_INDEX tells libgit2 to refresh the stat cache - * in the index for files that are unchanged but have out of date stat - * information in the index. It will result in less work being done on - * subsequent calls to get status. This is mutually exclusive with the - * NO_REFRESH option. - * * Calling `git_status_foreach()` is like calling the extended version * with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED, * and GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS. Those options are bundled * together as `GIT_STATUS_OPT_DEFAULTS` if you want them as a baseline. */ typedef enum { + /** + * Says that callbacks should be made on untracked files. + * These will only be made if the workdir files are included in the status + * "show" option. + */ GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1u << 0), + + /** + * Says that ignored files get callbacks. + * Again, these callbacks will only be made if the workdir files are + * included in the status "show" option. + */ GIT_STATUS_OPT_INCLUDE_IGNORED = (1u << 1), + + /** + * Indicates that callback should be made even on unmodified files. + */ GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1u << 2), + + /** + * Indicates that submodules should be skipped. + * This only applies if there are no pending typechanges to the submodule + * (either from or to another type). + */ GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1u << 3), + + /** + * Indicates that all files in untracked directories should be included. + * Normally if an entire directory is new, then just the top-level + * directory is included (with a trailing slash on the entry name). + * This flag says to include all of the individual files in the directory + * instead. + */ GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1u << 4), + + /** + * Indicates that the given path should be treated as a literal path, + * and not as a pathspec pattern. + */ GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1u << 5), + + /** + * Indicates that the contents of ignored directories should be included + * in the status. This is like doing `git ls-files -o -i --exclude-standard` + * with core git. + */ GIT_STATUS_OPT_RECURSE_IGNORED_DIRS = (1u << 6), + + /** + * Indicates that rename detection should be processed between the head and + * the index and enables the GIT_STATUS_INDEX_RENAMED as a possible status + * flag. + */ GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX = (1u << 7), + + /** + * Indicates that rename detection should be run between the index and the + * working directory and enabled GIT_STATUS_WT_RENAMED as a possible status + * flag. + */ GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR = (1u << 8), + + /** + * Overrides the native case sensitivity for the file system and forces + * the output to be in case-sensitive order. + */ GIT_STATUS_OPT_SORT_CASE_SENSITIVELY = (1u << 9), + + /** + * Overrides the native case sensitivity for the file system and forces + * the output to be in case-insensitive order. + */ GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY = (1u << 10), + + /** + * Iindicates that rename detection should include rewritten files. + */ GIT_STATUS_OPT_RENAMES_FROM_REWRITES = (1u << 11), + + /** + * Bypasses the default status behavior of doing a "soft" index reload + * (i.e. reloading the index data if the file on disk has been modified + * outside libgit2). + */ GIT_STATUS_OPT_NO_REFRESH = (1u << 12), + + /** + * Tells libgit2 to refresh the stat cache in the index for files that are + * unchanged but have out of date stat einformation in the index. + * It will result in less work being done on subsequent calls to get status. + * This is mutually exclusive with the NO_REFRESH option. + */ GIT_STATUS_OPT_UPDATE_INDEX = (1u << 13), + GIT_STATUS_OPT_INCLUDE_UNREADABLE = (1u << 14), + GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED = (1u << 15), } git_status_opt_t; diff --git a/include/git2/worktree.h b/include/git2/worktree.h index 049511da121..23084d8cd87 100644 --- a/include/git2/worktree.h +++ b/include/git2/worktree.h @@ -198,6 +198,7 @@ typedef enum { typedef struct git_worktree_prune_options { unsigned int version; + /** A combination of `git_worktree_prune_t` */ uint32_t flags; } git_worktree_prune_options; From b444918a9c68f8e5649b3dcc3894814d03b9ffc3 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Tue, 6 Jul 2021 20:51:14 +0200 Subject: [PATCH 0361/1616] Limit ITimer usage to AmigaOS4 --- src/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.h b/src/util.h index dabd4c94a9d..dd80c7868fa 100644 --- a/src/util.h +++ b/src/util.h @@ -359,7 +359,7 @@ GIT_INLINE(double) git__timer(void) return (double)time * scaling_factor / 1.0E9; } -#elif defined(AMIGA) +#elif defined(__amigaos4__) #include From be67f512d821d0bcc4f05a3f58e35d4146de5e7d Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Tue, 6 Jul 2021 22:27:14 -0300 Subject: [PATCH 0362/1616] Fix wrong time_t used in function This function doesn't interoperate with any system functions that use the system time_t, but rather only works with the git_time_t type in libgit2, which could be a different width than the system one. Fixes a compile warning. --- src/date.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/date.c b/src/date.c index f8594ed4e53..71bf631a0c8 100644 --- a/src/date.c +++ b/src/date.c @@ -204,7 +204,7 @@ static int is_date(int year, int month, int day, struct tm *now_tm, time_t now, if (month > 0 && month < 13 && day > 0 && day < 32) { struct tm check = *tm; struct tm *r = (now_tm ? &check : tm); - time_t specified; + git_time_t specified; r->tm_mon = month - 1; r->tm_mday = day; From c1aca3fedaf2cfe6d9bc7f5dbf5828a872dd74e5 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Tue, 6 Jul 2021 23:25:13 -0300 Subject: [PATCH 0363/1616] Initial pass at using int64_t instead of long long Even on systems without C99 where long long and stdint are both missing, we can shim stdint and point it to any compiler-specific type (i.e long long, _int64, etc.). Also next is constant suffixes and determining what needs to include stdint. --- src/hash/sha1/generic.h | 2 +- src/integer.h | 4 ++-- src/khash.h | 6 +----- src/win32/w32_util.h | 4 ++-- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/hash/sha1/generic.h b/src/hash/sha1/generic.h index e4cc6026b95..53fc0823e06 100644 --- a/src/hash/sha1/generic.h +++ b/src/hash/sha1/generic.h @@ -11,7 +11,7 @@ #include "hash/sha1.h" struct git_hash_sha1_ctx { - unsigned long long size; + uint64_t size; unsigned int H[5]; unsigned int W[16]; }; diff --git a/src/integer.h b/src/integer.h index a3a0f53ee11..63277177bf3 100644 --- a/src/integer.h +++ b/src/integer.h @@ -43,10 +43,10 @@ GIT_INLINE(int) git__is_ulong(int64_t p) } /** @return true if p fits into the range of an int */ -GIT_INLINE(int) git__is_int(long long p) +GIT_INLINE(int) git__is_int(int64_t p) { int r = (int)p; - return p == (long long)r; + return p == (int64_t)r; } /* Use clang/gcc compiler intrinsics whenever possible */ diff --git a/src/khash.h b/src/khash.h index 40e2d1848b7..5066b5883c1 100644 --- a/src/khash.h +++ b/src/khash.h @@ -137,11 +137,7 @@ typedef unsigned int khint32_t; typedef unsigned long khint32_t; #endif -#if ULONG_MAX == ULLONG_MAX -typedef unsigned long khint64_t; -#else -typedef unsigned long long khint64_t; -#endif +typedef int64_t khint64_t; #ifndef kh_inline #ifdef _MSC_VER diff --git a/src/win32/w32_util.h b/src/win32/w32_util.h index d7f9d3da6d8..060504ea00a 100644 --- a/src/win32/w32_util.h +++ b/src/win32/w32_util.h @@ -74,7 +74,7 @@ GIT_INLINE(void) git_win32__filetime_to_timespec( const FILETIME *ft, struct timespec *ts) { - long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime; + int64_t winTime = ((int64_t)ft->dwHighDateTime << 32) + ft->dwLowDateTime; winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */ ts->tv_sec = (time_t)(winTime / 10000000); #ifdef GIT_USE_NSEC @@ -87,7 +87,7 @@ GIT_INLINE(void) git_win32__filetime_to_timespec( GIT_INLINE(void) git_win32__timeval_to_filetime( FILETIME *ft, const struct p_timeval tv) { - long long ticks = (tv.tv_sec * 10000000LL) + + int64_t ticks = (tv.tv_sec * 10000000LL) + (tv.tv_usec * 10LL) + 116444736000000000LL; ft->dwHighDateTime = ((ticks >> 32) & 0xffffffffLL); From 52505ab5a2f0235d73553b6e8ecaa45943d1efc6 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Wed, 7 Jul 2021 19:12:02 -0300 Subject: [PATCH 0364/1616] Convert long long constant specifiers to stdint macros --- src/commit_graph.c | 2 +- src/diff_xdiff.h | 2 +- src/hashsig.c | 2 +- src/mwindow.c | 2 +- src/util.h | 2 +- src/win32/w32_util.h | 10 +++++----- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/commit_graph.c b/src/commit_graph.c index b301d3d4910..70b5b8c5f58 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -304,7 +304,7 @@ static int git_commit_graph_entry_get_byindex( e->generation = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ + 2 * sizeof(uint32_t)))); e->commit_time = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ + 3 * sizeof(uint32_t)))); - e->commit_time |= (e->generation & 0x3ull) << 32ull; + e->commit_time |= (e->generation & UINT64_C(0x3)) << UINT64_C(32); e->generation >>= 2u; if (e->parent_indices[1] & 0x80000000u) { uint32_t extra_edge_list_pos = e->parent_indices[1] & 0x7fffffff; diff --git a/src/diff_xdiff.h b/src/diff_xdiff.h index aca80b13106..9b303e9dc45 100644 --- a/src/diff_xdiff.h +++ b/src/diff_xdiff.h @@ -16,7 +16,7 @@ /* xdiff cannot cope with large files. these files should not be passed to * xdiff. callers should treat these large files as binary. */ -#define GIT_XDIFF_MAX_SIZE (1024LL * 1024 * 1023) +#define GIT_XDIFF_MAX_SIZE (INT64_C(1024) * 1024 * 1023) /* A git_xdiff_output is a git_patch_generate_output with extra fields * necessary to use libxdiff. Calling git_xdiff_init() will set the diff_cb diff --git a/src/hashsig.c b/src/hashsig.c index a5fbeee1012..43310ca4872 100644 --- a/src/hashsig.c +++ b/src/hashsig.c @@ -17,7 +17,7 @@ typedef uint64_t hashsig_state; #define HASHSIG_SCALE 100 #define HASHSIG_MAX_RUN 80 -#define HASHSIG_HASH_START 0x012345678ABCDEF0LL +#define HASHSIG_HASH_START INT64_C(0x012345678ABCDEF0) #define HASHSIG_HASH_SHIFT 5 #define HASHSIG_HASH_MIX(S,CH) \ diff --git a/src/mwindow.c b/src/mwindow.c index 5fcae2eed51..1ef35621e78 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -20,7 +20,7 @@ : 32 * 1024 * 1024) #define DEFAULT_MAPPED_LIMIT \ - ((1024 * 1024) * (sizeof(void*) >= 8 ? 8192ULL : 256UL)) + ((1024 * 1024) * (sizeof(void*) >= 8 ? UINT64_C(8192) : 256UL)) /* default is unlimited */ #define DEFAULT_FILE_LIMIT 0 diff --git a/src/util.h b/src/util.h index dabd4c94a9d..56a60a4a2f0 100644 --- a/src/util.h +++ b/src/util.h @@ -22,7 +22,7 @@ #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) #define bitsizeof(x) (CHAR_BIT * sizeof(x)) -#define MSB(x, bits) ((x) & (~0ULL << (bitsizeof(x) - (bits)))) +#define MSB(x, bits) ((x) & (~UINT64_C(0) << (bitsizeof(x) - (bits)))) #ifndef min # define min(a,b) ((a) < (b) ? (a) : (b)) #endif diff --git a/src/win32/w32_util.h b/src/win32/w32_util.h index 060504ea00a..1321d30e66b 100644 --- a/src/win32/w32_util.h +++ b/src/win32/w32_util.h @@ -75,7 +75,7 @@ GIT_INLINE(void) git_win32__filetime_to_timespec( struct timespec *ts) { int64_t winTime = ((int64_t)ft->dwHighDateTime << 32) + ft->dwLowDateTime; - winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */ + winTime -= INT64_C(116444736000000000); /* Windows to Unix Epoch conversion */ ts->tv_sec = (time_t)(winTime / 10000000); #ifdef GIT_USE_NSEC ts->tv_nsec = (winTime % 10000000) * 100; @@ -87,11 +87,11 @@ GIT_INLINE(void) git_win32__filetime_to_timespec( GIT_INLINE(void) git_win32__timeval_to_filetime( FILETIME *ft, const struct p_timeval tv) { - int64_t ticks = (tv.tv_sec * 10000000LL) + - (tv.tv_usec * 10LL) + 116444736000000000LL; + int64_t ticks = (tv.tv_sec * INT64_C(10000000)) + + (tv.tv_usec * INT64_C(10)) + INT64_C(116444736000000000); - ft->dwHighDateTime = ((ticks >> 32) & 0xffffffffLL); - ft->dwLowDateTime = (ticks & 0xffffffffLL); + ft->dwHighDateTime = ((ticks >> 32) & INT64_C(0xffffffff)); + ft->dwLowDateTime = (ticks & INT64_C(0xffffffff)); } GIT_INLINE(void) git_win32__stat_init( From 3f28eafeaf237aa9a3f902388aa632c6d81447de Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Wed, 7 Jul 2021 19:35:42 -0300 Subject: [PATCH 0365/1616] stdint constants in test suite Passes w/ gcc 11 on Fedora x64. Protip: So you don;t have to suffer, ``` perl -pe 's/(-?(?:0x)?[A-Fa-f0-9]+)([Uu])?[Ll][Ll]/\U$2INT64_C(\E$1)/mg' ``` --- tests/core/encoding.c | 6 +- tests/core/integer.c | 462 ++++++++++++++++++------------------- tests/core/strtol.c | 8 +- tests/graph/commit_graph.c | 6 +- tests/revwalk/basic.c | 2 +- 5 files changed, 242 insertions(+), 242 deletions(-) diff --git a/tests/core/encoding.c b/tests/core/encoding.c index a677afe2e92..6cec24679dc 100644 --- a/tests/core/encoding.c +++ b/tests/core/encoding.c @@ -14,7 +14,7 @@ void test_core_encoding__decode(void) cl_assert(size == 4); buf = (unsigned char *)"\xaa\xaa\xfe\xdc\xbaXY"; - cl_assert(git_decode_varint(buf, &size) == 1489279344088ULL); + cl_assert(git_decode_varint(buf, &size) == UINT64_C(1489279344088)); cl_assert(size == 6); buf = (unsigned char *)"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xfe\xdc\xbaXY"; @@ -35,8 +35,8 @@ void test_core_encoding__encode(void) cl_assert(git_encode_varint(buf, 100, 267869656) == 4); cl_assert(!memcmp(buf, "\xfe\xdc\xbaX", 4)); - cl_assert(git_encode_varint(buf, 100, 1489279344088ULL) == 6); + cl_assert(git_encode_varint(buf, 100, UINT64_C(1489279344088)) == 6); cl_assert(!memcmp(buf, "\xaa\xaa\xfe\xdc\xbaX", 6)); - cl_assert(git_encode_varint(buf, 1, 1489279344088ULL) == -1); + cl_assert(git_encode_varint(buf, 1, UINT64_C(1489279344088)) == -1); } diff --git a/tests/core/integer.c b/tests/core/integer.c index bd19651afe3..18364ba6225 100644 --- a/tests/core/integer.c +++ b/tests/core/integer.c @@ -4,168 +4,168 @@ void test_core_integer__multiply_int64_no_overflow(void) { #if !defined(git__multiply_int64_overflow) int64_t result = 0; - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x1ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x1ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x2ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x2ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x7ffffffffffffffll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x7ffffffffffffffll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x800000000000000ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x800000000000000ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, 0x7fffffffffffffffll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x7fffffffffffffffll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x0ll, -0x8000000000000000ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x1ll)); - cl_assert_equal_i(result, 0x1ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x1ll)); - cl_assert_equal_i(result, -0x1ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x2ll)); - cl_assert_equal_i(result, 0x2ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x2ll)); - cl_assert_equal_i(result, -0x2ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x7ffffffffffffffll)); - cl_assert_equal_i(result, 0x7ffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x7ffffffffffffffll)); - cl_assert_equal_i(result, -0x7ffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x800000000000000ll)); - cl_assert_equal_i(result, 0x800000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x800000000000000ll)); - cl_assert_equal_i(result, -0x800000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, 0x7fffffffffffffffll)); - cl_assert_equal_i(result, 0x7fffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, 0x1ll, -0x7fffffffffffffffll)); - cl_assert_equal_i(result, -0x7fffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x1ll)); - cl_assert_equal_i(result, -0x1ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x1ll)); - cl_assert_equal_i(result, 0x1ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x2ll)); - cl_assert_equal_i(result, -0x2ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x2ll)); - cl_assert_equal_i(result, 0x2ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x7ffffffffffffffll)); - cl_assert_equal_i(result, -0x7ffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x7ffffffffffffffll)); - cl_assert_equal_i(result, 0x7ffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x800000000000000ll)); - cl_assert_equal_i(result, -0x800000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x800000000000000ll)); - cl_assert_equal_i(result, 0x800000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, 0x7fffffffffffffffll)); - cl_assert_equal_i(result, -0x7fffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x7fffffffffffffffll)); - cl_assert_equal_i(result, 0x7fffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x1ll)); - cl_assert_equal_i(result, 0x2ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x1ll)); - cl_assert_equal_i(result, -0x2ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x2ll)); - cl_assert_equal_i(result, 0x4ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x2ll)); - cl_assert_equal_i(result, -0x4ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x7ffffffffffffffll)); - cl_assert_equal_i(result, 0xffffffffffffffell); - cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x7ffffffffffffffll)); - cl_assert_equal_i(result, -0xffffffffffffffell); - cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, 0x800000000000000ll)); - cl_assert_equal_i(result, 0x1000000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x800000000000000ll)); - cl_assert_equal_i(result, -0x1000000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x1ll)); - cl_assert_equal_i(result, -0x2ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x1ll)); - cl_assert_equal_i(result, 0x2ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x2ll)); - cl_assert_equal_i(result, -0x4ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x2ll)); - cl_assert_equal_i(result, 0x4ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x7ffffffffffffffll)); - cl_assert_equal_i(result, -0xffffffffffffffell); - cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x7ffffffffffffffll)); - cl_assert_equal_i(result, 0xffffffffffffffell); - cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, 0x800000000000000ll)); - cl_assert_equal_i(result, -0x1000000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x2ll, -0x800000000000000ll)); - cl_assert_equal_i(result, 0x1000000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x2ll, -0x4000000000000000ll)); - cl_assert_equal_i(result, -0x8000000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x1ll)); - cl_assert_equal_i(result, 0x7ffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x1ll)); - cl_assert_equal_i(result, -0x7ffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x2ll)); - cl_assert_equal_i(result, 0xffffffffffffffell); - cl_assert(!git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x2ll)); - cl_assert_equal_i(result, -0xffffffffffffffell); - cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x1ll)); - cl_assert_equal_i(result, -0x7ffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x1ll)); - cl_assert_equal_i(result, 0x7ffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x2ll)); - cl_assert_equal_i(result, -0xffffffffffffffell); - cl_assert(!git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x2ll)); - cl_assert_equal_i(result, 0xffffffffffffffell); - cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x1ll)); - cl_assert_equal_i(result, 0x800000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x1ll)); - cl_assert_equal_i(result, -0x800000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x2ll)); - cl_assert_equal_i(result, 0x1000000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x2ll)); - cl_assert_equal_i(result, -0x1000000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x1ll)); - cl_assert_equal_i(result, -0x800000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x1ll)); - cl_assert_equal_i(result, 0x800000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x2ll)); - cl_assert_equal_i(result, -0x1000000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x2ll)); - cl_assert_equal_i(result, 0x1000000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x1ll)); - cl_assert_equal_i(result, 0x7fffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x1ll)); - cl_assert_equal_i(result, -0x7fffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, -0x4000000000000000ll, 0x2ll)); - cl_assert_equal_i(result, -0x8000000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x1ll)); - cl_assert_equal_i(result, -0x7fffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x1ll)); - cl_assert_equal_i(result, 0x7fffffffffffffffll); - cl_assert(!git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x0ll)); - cl_assert_equal_i(result, 0x0ll); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(0x1))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(0x2))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(-0x2))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(0x7ffffffffffffff))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(-0x7ffffffffffffff))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(0x800000000000000))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(-0x800000000000000))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(0x7fffffffffffffff))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(-0x7fffffffffffffff))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x0), INT64_C(-0x8000000000000000))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(0x1))); + cl_assert_equal_i(result, INT64_C(0x1)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(-0x1)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(0x2))); + cl_assert_equal_i(result, INT64_C(0x2)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(-0x2))); + cl_assert_equal_i(result, INT64_C(-0x2)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(0x7ffffffffffffff))); + cl_assert_equal_i(result, INT64_C(0x7ffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(-0x7ffffffffffffff))); + cl_assert_equal_i(result, INT64_C(-0x7ffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(0x800000000000000))); + cl_assert_equal_i(result, INT64_C(0x800000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(-0x800000000000000))); + cl_assert_equal_i(result, INT64_C(-0x800000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(0x7fffffffffffffff))); + cl_assert_equal_i(result, INT64_C(0x7fffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(-0x7fffffffffffffff))); + cl_assert_equal_i(result, INT64_C(-0x7fffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(0x1))); + cl_assert_equal_i(result, INT64_C(-0x1)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(0x1)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(0x2))); + cl_assert_equal_i(result, INT64_C(-0x2)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(-0x2))); + cl_assert_equal_i(result, INT64_C(0x2)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(0x7ffffffffffffff))); + cl_assert_equal_i(result, INT64_C(-0x7ffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(-0x7ffffffffffffff))); + cl_assert_equal_i(result, INT64_C(0x7ffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(0x800000000000000))); + cl_assert_equal_i(result, INT64_C(-0x800000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(-0x800000000000000))); + cl_assert_equal_i(result, INT64_C(0x800000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(0x7fffffffffffffff))); + cl_assert_equal_i(result, INT64_C(-0x7fffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(-0x7fffffffffffffff))); + cl_assert_equal_i(result, INT64_C(0x7fffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(0x1))); + cl_assert_equal_i(result, INT64_C(0x2)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(-0x2)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(0x2))); + cl_assert_equal_i(result, INT64_C(0x4)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(-0x2))); + cl_assert_equal_i(result, INT64_C(-0x4)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(0x7ffffffffffffff))); + cl_assert_equal_i(result, INT64_C(0xffffffffffffffe)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(-0x7ffffffffffffff))); + cl_assert_equal_i(result, INT64_C(-0xffffffffffffffe)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(0x800000000000000))); + cl_assert_equal_i(result, INT64_C(0x1000000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(-0x800000000000000))); + cl_assert_equal_i(result, INT64_C(-0x1000000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(0x1))); + cl_assert_equal_i(result, INT64_C(-0x2)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(0x2)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(0x2))); + cl_assert_equal_i(result, INT64_C(-0x4)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(-0x2))); + cl_assert_equal_i(result, INT64_C(0x4)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(0x7ffffffffffffff))); + cl_assert_equal_i(result, INT64_C(-0xffffffffffffffe)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(-0x7ffffffffffffff))); + cl_assert_equal_i(result, INT64_C(0xffffffffffffffe)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(0x800000000000000))); + cl_assert_equal_i(result, INT64_C(-0x1000000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(-0x800000000000000))); + cl_assert_equal_i(result, INT64_C(0x1000000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(-0x4000000000000000))); + cl_assert_equal_i(result, INT64_C(-0x8000000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(0x1))); + cl_assert_equal_i(result, INT64_C(0x7ffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(-0x7ffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(0x2))); + cl_assert_equal_i(result, INT64_C(0xffffffffffffffe)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(-0x2))); + cl_assert_equal_i(result, INT64_C(-0xffffffffffffffe)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(0x1))); + cl_assert_equal_i(result, INT64_C(-0x7ffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(0x7ffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(0x2))); + cl_assert_equal_i(result, INT64_C(-0xffffffffffffffe)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(-0x2))); + cl_assert_equal_i(result, INT64_C(0xffffffffffffffe)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(0x1))); + cl_assert_equal_i(result, INT64_C(0x800000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(-0x800000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(0x2))); + cl_assert_equal_i(result, INT64_C(0x1000000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(-0x2))); + cl_assert_equal_i(result, INT64_C(-0x1000000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(0x1))); + cl_assert_equal_i(result, INT64_C(-0x800000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(0x800000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(0x2))); + cl_assert_equal_i(result, INT64_C(-0x1000000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(-0x2))); + cl_assert_equal_i(result, INT64_C(0x1000000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(0x1))); + cl_assert_equal_i(result, INT64_C(0x7fffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(-0x7fffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x4000000000000000), INT64_C(0x2))); + cl_assert_equal_i(result, INT64_C(-0x8000000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(0x1))); + cl_assert_equal_i(result, INT64_C(-0x7fffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(0x7fffffffffffffff)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(0x0))); + cl_assert_equal_i(result, INT64_C(0x0)); #endif } @@ -173,69 +173,69 @@ void test_core_integer__multiply_int64_overflow(void) { #if !defined(git__multiply_int64_overflow) int64_t result = 0; - cl_assert(git__multiply_int64_overflow(&result, 0x2ll, 0x4000000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x2ll, 0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x2ll, -0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x2ll, -0x8000000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x2ll, 0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x2ll, -0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x2ll, -0x8000000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, 0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7ffffffffffffffll, -0x8000000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, 0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7ffffffffffffffll, -0x8000000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, 0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x800000000000000ll, -0x8000000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, 0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x800000000000000ll, -0x8000000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x4000000000000000ll, 0x2ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x2ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x2ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, 0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, 0x7fffffffffffffffll, -0x8000000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x2ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x2ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, 0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x7fffffffffffffffll, -0x8000000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x2ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x2ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x7ffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x800000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x7fffffffffffffffll)); - cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x8000000000000000ll)); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(0x4000000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(-0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x2), INT64_C(-0x8000000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(-0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x2), INT64_C(-0x8000000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(-0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(-0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(-0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7ffffffffffffff), INT64_C(-0x8000000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(-0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(-0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(-0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7ffffffffffffff), INT64_C(-0x8000000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(-0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(-0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(-0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x800000000000000), INT64_C(-0x8000000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(-0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(-0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(-0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x800000000000000), INT64_C(-0x8000000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x4000000000000000), INT64_C(0x2))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(0x2))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(-0x2))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(-0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(-0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(-0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x7fffffffffffffff), INT64_C(-0x8000000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(0x2))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(-0x2))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(-0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(-0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(-0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x7fffffffffffffff), INT64_C(-0x8000000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(0x2))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(-0x2))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(-0x7ffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(-0x800000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(-0x7fffffffffffffff))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(-0x8000000000000000))); #endif } @@ -243,11 +243,11 @@ void test_core_integer__multiply_int64_edge_cases(void) { #if !defined(git__multiply_int64_overflow) int64_t result = 0; - cl_assert(!git__multiply_int64_overflow(&result, -0x8000000000000000ll, -0x1ll)); - cl_assert_equal_i(result, -0x8000000000000000ll); - cl_assert(!git__multiply_int64_overflow(&result, -0x1ll, -0x8000000000000000ll)); - cl_assert_equal_i(result, -0x8000000000000000ll); - cl_assert(git__multiply_int64_overflow(&result, 0x1ll, -0x8000000000000000ll)); - cl_assert(git__multiply_int64_overflow(&result, -0x8000000000000000ll, 0x1ll)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(-0x1))); + cl_assert_equal_i(result, INT64_C(-0x8000000000000000)); + cl_assert(!git__multiply_int64_overflow(&result, INT64_C(-0x1), INT64_C(-0x8000000000000000))); + cl_assert_equal_i(result, INT64_C(-0x8000000000000000)); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(0x1), INT64_C(-0x8000000000000000))); + cl_assert(git__multiply_int64_overflow(&result, INT64_C(-0x8000000000000000), INT64_C(0x1))); #endif } diff --git a/tests/core/strtol.c b/tests/core/strtol.c index cac6ca56bb7..851b91b0a40 100644 --- a/tests/core/strtol.c +++ b/tests/core/strtol.c @@ -32,7 +32,7 @@ void test_core_strtol__int32(void) assert_l32_parses(" +123 ", 123, 10); assert_l32_parses(" -123 ", -123, 10); assert_l32_parses(" +2147483647 ", 2147483647, 10); - assert_l32_parses(" -2147483648 ", -2147483648LL, 10); + assert_l32_parses(" -2147483648 ", INT64_C(-2147483648), 10); assert_l32_parses("A", 10, 16); assert_l32_parses("1x1", 1, 10); @@ -49,9 +49,9 @@ void test_core_strtol__int64(void) assert_l64_parses(" +123 ", 123, 10); assert_l64_parses(" -123 ", -123, 10); assert_l64_parses(" +2147483647 ", 2147483647, 10); - assert_l64_parses(" -2147483648 ", -2147483648LL, 10); - assert_l64_parses(" 2147483657 ", 2147483657LL, 10); - assert_l64_parses(" -2147483657 ", -2147483657LL, 10); + assert_l64_parses(" -2147483648 ", INT64_C(-2147483648), 10); + assert_l64_parses(" 2147483657 ", INT64_C(2147483657), 10); + assert_l64_parses(" -2147483657 ", INT64_C(-2147483657), 10); assert_l64_parses(" 9223372036854775807 ", INT64_MAX, 10); assert_l64_parses(" -9223372036854775808 ", INT64_MIN, 10); assert_l64_parses(" 0x7fffffffffffffff ", INT64_MAX, 16); diff --git a/tests/graph/commit_graph.c b/tests/graph/commit_graph.c index 4c7c5a726a3..ce0894fde0a 100644 --- a/tests/graph/commit_graph.c +++ b/tests/graph/commit_graph.c @@ -23,14 +23,14 @@ void test_graph_commit_graph__parse(void) cl_git_pass(git_oid_fromstr(&id, "418382dff1ffb8bdfba833f4d8bbcde58b1e7f47")); cl_assert_equal_oid(&e.tree_oid, &id); cl_assert_equal_i(e.generation, 1); - cl_assert_equal_i(e.commit_time, 1273610423ull); + cl_assert_equal_i(e.commit_time, UINT64_C(1273610423)); cl_assert_equal_i(e.parent_count, 0); cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); cl_git_pass(git_commit_graph_entry_find(&e, cgraph, &id, GIT_OID_HEXSZ)); cl_assert_equal_oid(&e.sha1, &id); cl_assert_equal_i(e.generation, 5); - cl_assert_equal_i(e.commit_time, 1274813907ull); + cl_assert_equal_i(e.commit_time, UINT64_C(1274813907)); cl_assert_equal_i(e.parent_count, 2); cl_git_pass(git_oid_fromstr(&id, "9fd738e8f7967c078dceed8190330fc8648ee56a")); @@ -66,7 +66,7 @@ void test_graph_commit_graph__parse_octopus_merge(void) cl_git_pass(git_oid_fromstr(&id, "348f16ffaeb73f319a75cec5b16a0a47d2d5e27c")); cl_assert_equal_oid(&e.tree_oid, &id); cl_assert_equal_i(e.generation, 7); - cl_assert_equal_i(e.commit_time, 1447083009ull); + cl_assert_equal_i(e.commit_time, INT64_C(1447083009)); cl_assert_equal_i(e.parent_count, 3); cl_git_pass(git_oid_fromstr(&id, "ad2ace9e15f66b3d1138922e6ffdc3ea3f967fa6")); diff --git a/tests/revwalk/basic.c b/tests/revwalk/basic.c index ee70ec635a4..2c8d885e24d 100644 --- a/tests/revwalk/basic.c +++ b/tests/revwalk/basic.c @@ -530,7 +530,7 @@ void test_revwalk_basic__big_timestamp(void) cl_git_pass(git_reference_peel((git_object **) &tip, head, GIT_OBJECT_COMMIT)); /* Commit with a far-ahead timestamp, we should be able to parse it in the revwalk */ - cl_git_pass(git_signature_new(&sig, "Joe", "joe@example.com", 2399662595ll, 0)); + cl_git_pass(git_signature_new(&sig, "Joe", "joe@example.com", INT64_C(2399662595), 0)); cl_git_pass(git_commit_tree(&tree, tip)); cl_git_pass(git_commit_create(&id, _repo, "HEAD", sig, sig, NULL, "some message", tree, 1, From fcfaea4d405ff92a2512dc8ada4df629a49291ec Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Wed, 7 Jul 2021 23:29:28 -0300 Subject: [PATCH 0366/1616] Remove sus unsigned long constant --- src/mwindow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mwindow.c b/src/mwindow.c index 1ef35621e78..da2dae2b9d6 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -20,7 +20,7 @@ : 32 * 1024 * 1024) #define DEFAULT_MAPPED_LIMIT \ - ((1024 * 1024) * (sizeof(void*) >= 8 ? UINT64_C(8192) : 256UL)) + ((1024 * 1024) * (sizeof(void*) >= 8 ? UINT64_C(8192) : UINT64_C(256))) /* default is unlimited */ #define DEFAULT_FILE_LIMIT 0 From e71505b3372028d073bf1d2268d3cdc7bc934708 Mon Sep 17 00:00:00 2001 From: Kevin Saul Date: Sun, 11 Jul 2021 21:24:25 +1200 Subject: [PATCH 0367/1616] repo: fix worktree iteration when repo has no common directory When applying an operation to a repository created without a common directory, which is known to occur in scenarios where custom odb/refdb backends are used, git_repository_foreach_worktree currently asserts while attempting to open the repository located in the common directory. Fix this issue by applying operation to repository supplied when there are no linked worktrees to iterate (implied by common directory being empty). --- src/repository.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/repository.c b/src/repository.c index 692f71861a2..790dc161bdd 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2339,6 +2339,12 @@ int git_repository_foreach_worktree(git_repository *repo, int error; size_t i; + /* apply operation to repository supplied when commondir is empty, implying there's + * no linked worktrees to iterate, which can occur when using custom odb/refdb + */ + if (!repo->commondir) + return cb(repo, payload); + if ((error = git_repository_open(&worktree_repo, repo->commondir)) < 0 || (error = cb(worktree_repo, payload) != 0)) goto out; From b7dce05cb5f6b2cd8fd5b79a2ab06f8d314c1700 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Wed, 16 Jun 2021 06:38:41 -0700 Subject: [PATCH 0368/1616] Make `FIND_PACKAGE(PythonInterp)` prefer `python3` This change makes it possible to prefer a python (version 3) interpreter on systems where python2 and python3 coexist (where python2 is found as `/usr/bin/python`). --- tests/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4d8732d23a6..600c617e8e4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,3 +1,4 @@ +SET(Python_ADDITIONAL_VERSIONS 3 2.7) FIND_PACKAGE(PythonInterp) IF(NOT PYTHONINTERP_FOUND) From e4e173e8744dbdf9bed4b814f1af6a8080c4c603 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Thu, 15 Jul 2021 21:00:02 +0200 Subject: [PATCH 0369/1616] Allow compilation on systems without CLOCK_MONOTONIC Makes usage of CLOCK_MONOTONIC conditional and makes functions that uses git__timer handle clock resynchronization. Call gettimeofday with tzp set to NULL as required by https://pubs.opengroup.org/onlinepubs/9699919799/functions/gettimeofday.html --- src/pack-objects.c | 4 ++-- src/transports/smart_protocol.c | 3 ++- src/util.h | 18 +++++++++--------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/pack-objects.c b/src/pack-objects.c index f9d8bfd35b0..2c964b1251a 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -251,7 +251,7 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid, double current_time = git__timer(); double elapsed = current_time - pb->last_progress_report_time; - if (elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) { + if (elapsed < 0 || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) { pb->last_progress_report_time = current_time; ret = pb->progress_cb( @@ -922,7 +922,7 @@ static int report_delta_progress( double current_time = git__timer(); double elapsed = current_time - pb->last_progress_report_time; - if (force || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) { + if (force || elapsed < 0 || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) { pb->last_progress_report_time = current_time; ret = pb->progress_cb( diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 9482915d886..91de163e91f 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -975,9 +975,10 @@ static int stream_thunk(void *buf, size_t size, void *data) if (payload->cb) { double current_time = git__timer(); + double elapsed = current_time - payload->last_progress_report_time; payload->last_bytes += size; - if ((current_time - payload->last_progress_report_time) >= MIN_PROGRESS_UPDATE_INTERVAL) { + if (elapsed < 0 || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) { payload->last_progress_report_time = current_time; error = payload->cb(payload->pb->nr_written, payload->pb->nr_objects, payload->last_bytes, payload->cb_payload); } diff --git a/src/util.h b/src/util.h index dd80c7868fa..1c6677b0e84 100644 --- a/src/util.h +++ b/src/util.h @@ -376,17 +376,17 @@ GIT_INLINE(double) git__timer(void) GIT_INLINE(double) git__timer(void) { - struct timespec tp; + struct timeval tv; - if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) { +#ifdef CLOCK_MONOTONIC + struct timespec tp; + if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) return (double) tp.tv_sec + (double) tp.tv_nsec / 1.0E9; - } else { - /* Fall back to using gettimeofday */ - struct timeval tv; - struct timezone tz; - gettimeofday(&tv, &tz); - return (double)tv.tv_sec + (double)tv.tv_usec / 1.0E6; - } +#endif + + /* Fall back to using gettimeofday */ + gettimeofday(&tv, NULL); + return (double)tv.tv_sec + (double)tv.tv_usec / 1.0E6; } #endif From 589654d8b420a32428a0f04daac8755e0aedf9a2 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Thu, 15 Jul 2021 20:34:14 -0300 Subject: [PATCH 0370/1616] khash 64-bit type is unsigned, use int32_t too For 32-bit int: There's no real reason for that ifdef if we explicitly specify the stdint.h type. For 64-bit int: ope, I made it signed accidentally --- src/khash.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/khash.h b/src/khash.h index 5066b5883c1..7adccdb0065 100644 --- a/src/khash.h +++ b/src/khash.h @@ -131,13 +131,8 @@ int main() { /* compiler specific configuration */ -#if UINT_MAX == 0xffffffffu -typedef unsigned int khint32_t; -#elif ULONG_MAX == 0xffffffffu -typedef unsigned long khint32_t; -#endif - -typedef int64_t khint64_t; +typedef uint32_t khint32_t; +typedef uint64_t khint64_t; #ifndef kh_inline #ifdef _MSC_VER From d6bea53d10ed59b774d0642c844974d3c167d6f0 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 16 Jul 2021 08:47:28 -0400 Subject: [PATCH 0371/1616] Update tests/graph/commit_graph.c --- tests/graph/commit_graph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/graph/commit_graph.c b/tests/graph/commit_graph.c index ce0894fde0a..75a6c529e02 100644 --- a/tests/graph/commit_graph.c +++ b/tests/graph/commit_graph.c @@ -66,7 +66,7 @@ void test_graph_commit_graph__parse_octopus_merge(void) cl_git_pass(git_oid_fromstr(&id, "348f16ffaeb73f319a75cec5b16a0a47d2d5e27c")); cl_assert_equal_oid(&e.tree_oid, &id); cl_assert_equal_i(e.generation, 7); - cl_assert_equal_i(e.commit_time, INT64_C(1447083009)); + cl_assert_equal_i(e.commit_time, UINT64_C(1447083009)); cl_assert_equal_i(e.parent_count, 3); cl_git_pass(git_oid_fromstr(&id, "ad2ace9e15f66b3d1138922e6ffdc3ea3f967fa6")); From 950a7f76e2db0bd578717c96123e5e59770c242c Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Sat, 17 Jul 2021 16:21:05 -0300 Subject: [PATCH 0372/1616] Variadic arguments aren't in C89 This refactors this to a wrapper function, as well as changing the existing API have a va_list and ... version. --- src/trace.h | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/trace.h b/src/trace.h index e15118ef55e..e93283788f7 100644 --- a/src/trace.h +++ b/src/trace.h @@ -21,31 +21,53 @@ struct git_trace_data { extern struct git_trace_data git_trace__data; -GIT_INLINE(void) git_trace__write_fmt( +GIT_INLINE(void) git_trace__vwrite_fmt( git_trace_level_t level, - const char *fmt, ...) + const char *fmt, va_list ap) { git_trace_cb callback = git_trace__data.callback; git_buf message = GIT_BUF_INIT; - va_list ap; - va_start(ap, fmt); git_buf_vprintf(&message, fmt, ap); - va_end(ap); callback(level, git_buf_cstr(&message)); git_buf_dispose(&message); } +GIT_INLINE(void) git_trace__write_fmt( + git_trace_level_t level, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + git_trace__vwrite_fmt(level, fmt, ap); + va_end(ap); +} + #define git_trace_level() (git_trace__data.level) +/* Varadic macros are a C99 feature */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define git_trace(l, ...) { \ if (git_trace__data.level >= l && \ git_trace__data.callback != NULL) { \ git_trace__write_fmt(l, __VA_ARGS__); \ } \ } +#else +GIT_INLINE(void) git_trace(git_trace_level_t level, const char *fmt, ...) +{ + if (git_trace__data.level >= level && + git_trace__data.callback != NULL) { + va_list ap; + va_start(ap, fmt); + git_trace__vwrite_fmt(level, fmt, ap); + va_end(ap); + } +} +#endif #else GIT_INLINE(void) git_trace__null( From 48e6b02be9b0639fdc25e17514f11d7ef141dfbc Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 19 Jul 2021 15:41:44 -0400 Subject: [PATCH 0373/1616] alloc: add GIT_DEBUG_STRICT_ALLOC Add `GIT_DEBUG_STRICT_ALLOC` to help identify problematic callers of allocation code that pass a `0` size to the allocators and then expect a non-`NULL` return. When given a 0-size allocation, `malloc` _may_ return either a `NULL` _or_ a pointer that is not writeable. Most systems return a non-`NULL` pointer; AIX is an outlier. We should be able to cope with this AIXy behavior, so this adds an option to emulate it. --- CMakeLists.txt | 1 + src/CMakeLists.txt | 5 ++++ src/allocators/stdalloc.c | 51 +++++++++++++++++++++++++++++++-------- src/features.h.in | 2 ++ 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65569797906..58214fd0e1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ OPTION(USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF) OPTION(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)" OFF) OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF) OPTION(DEBUG_POOL "Enable debug pool allocator" OFF) +OPTION(DEBUG_STRICT_ALLOC "Enable strict allocator behavior" OFF) OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF) OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib. Can be set to one of Bundled(ON)/Chromium. The Chromium option requires a x86_64 processor with SSE4.2 and CLMUL" OFF) SET(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4fde16d8a98..8d155955151 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,11 @@ IF(DEBUG_POOL) ENDIF() ADD_FEATURE_INFO(debugpool GIT_DEBUG_POOL "debug pool allocator") +IF(DEBUG_STRICT_ALLOC) + SET(GIT_DEBUG_STRICT_ALLOC 1) +ENDIF() +ADD_FEATURE_INFO(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators") + INCLUDE(PkgBuildConfig) INCLUDE(SanitizeBool) diff --git a/src/allocators/stdalloc.c b/src/allocators/stdalloc.c index c4938e32b6b..7215468b6cf 100644 --- a/src/allocators/stdalloc.c +++ b/src/allocators/stdalloc.c @@ -9,34 +9,56 @@ static void *stdalloc__malloc(size_t len, const char *file, int line) { - void *ptr = malloc(len); + void *ptr; GIT_UNUSED(file); GIT_UNUSED(line); - if (!ptr) git_error_set_oom(); +#ifdef GIT_DEBUG_STRICT_ALLOC + if (!len) + return NULL; +#endif + + ptr = malloc(len); + + if (!ptr) + git_error_set_oom(); + return ptr; } static void *stdalloc__calloc(size_t nelem, size_t elsize, const char *file, int line) { - void *ptr = calloc(nelem, elsize); + void *ptr; GIT_UNUSED(file); GIT_UNUSED(line); - if (!ptr) git_error_set_oom(); +#ifdef GIT_DEBUG_STRICT_ALLOC + if (!elsize) + return NULL; +#endif + + ptr = calloc(nelem, elsize); + + if (!ptr) + git_error_set_oom(); + return ptr; } static char *stdalloc__strdup(const char *str, const char *file, int line) { - char *ptr = strdup(str); + char *ptr; GIT_UNUSED(file); GIT_UNUSED(line); - if (!ptr) git_error_set_oom(); + ptr = strdup(str); + + if (!ptr) + git_error_set_oom(); + return ptr; } @@ -48,7 +70,7 @@ static char *stdalloc__strndup(const char *str, size_t n, const char *file, int length = p_strnlen(str, n); if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) || - !(ptr = stdalloc__malloc(alloclength, file, line))) + !(ptr = stdalloc__malloc(alloclength, file, line))) return NULL; if (length) @@ -65,7 +87,7 @@ static char *stdalloc__substrdup(const char *start, size_t n, const char *file, size_t alloclen; if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) || - !(ptr = stdalloc__malloc(alloclen, file, line))) + !(ptr = stdalloc__malloc(alloclen, file, line))) return NULL; memcpy(ptr, start, n); @@ -75,12 +97,21 @@ static char *stdalloc__substrdup(const char *start, size_t n, const char *file, static void *stdalloc__realloc(void *ptr, size_t size, const char *file, int line) { - void *new_ptr = realloc(ptr, size); + void *new_ptr; GIT_UNUSED(file); GIT_UNUSED(line); - if (!new_ptr) git_error_set_oom(); +#ifdef GIT_DEBUG_STRICT_ALLOC + if (!size) + return NULL; +#endif + + new_ptr = realloc(ptr, size); + + if (!new_ptr) + git_error_set_oom(); + return new_ptr; } diff --git a/src/features.h.in b/src/features.h.in index c8d01804f00..ab523f90bb6 100644 --- a/src/features.h.in +++ b/src/features.h.in @@ -2,6 +2,8 @@ #define INCLUDE_features_h__ #cmakedefine GIT_DEBUG_POOL 1 +#cmakedefine GIT_DEBUG_STRICT_ALLOC 1 + #cmakedefine GIT_TRACE 1 #cmakedefine GIT_THREADS 1 #cmakedefine GIT_WIN32_LEAKCHECK 1 From 419ffdde6aa3c4dce60c0ab219d0ca48eaea8f81 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 19 Jul 2021 15:51:53 -0400 Subject: [PATCH 0374/1616] packbuilder: don't try to malloc(0) --- src/pack-objects.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/pack-objects.c b/src/pack-objects.c index 2c964b1251a..faff310b40b 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -517,13 +517,18 @@ static int cb_tag_foreach(const char *name, git_oid *oid, void *data) return 0; } -static git_pobject **compute_write_order(git_packbuilder *pb) +static int compute_write_order(git_pobject ***out, git_packbuilder *pb) { size_t i, wo_end, last_untagged; git_pobject **wo; + *out = NULL; + + if (!pb->nr_objects) + return 0; + if ((wo = git__mallocarray(pb->nr_objects, sizeof(*wo))) == NULL) - return NULL; + return -1; for (i = 0; i < pb->nr_objects; i++) { git_pobject *po = pb->object_list + i; @@ -552,7 +557,7 @@ static git_pobject **compute_write_order(git_packbuilder *pb) */ if (git_tag_foreach(pb->repo, &cb_tag_foreach, pb) < 0) { git__free(wo); - return NULL; + return -1; } /* @@ -609,10 +614,11 @@ static git_pobject **compute_write_order(git_packbuilder *pb) if (wo_end != pb->nr_objects) { git__free(wo); git_error_set(GIT_ERROR_INVALID, "invalid write order"); - return NULL; + return -1; } - return wo; + *out = wo; + return 0; } static int write_pack(git_packbuilder *pb, @@ -625,15 +631,15 @@ static int write_pack(git_packbuilder *pb, struct git_pack_header ph; git_oid entry_oid; size_t i = 0; - int error = 0; + int error; - write_order = compute_write_order(pb); - if (write_order == NULL) - return -1; + if ((error = compute_write_order(&write_order, pb)) < 0) + return error; if (!git__is_uint32(pb->nr_objects)) { git_error_set(GIT_ERROR_INVALID, "too many objects"); - return -1; + error = -1; + goto done; } /* Write pack header */ From 31e84edb14327050ba74bf213c5b17451cca311e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 19 Jul 2021 16:02:30 -0400 Subject: [PATCH 0375/1616] merge: don't try to malloc(0) --- src/merge.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/merge.c b/src/merge.c index 82b028b4a67..c29b40e2367 100644 --- a/src/merge.c +++ b/src/merge.c @@ -1535,7 +1535,8 @@ int git_merge_diff_list__find_renames( GIT_ASSERT_ARG(diff_list); GIT_ASSERT_ARG(opts); - if ((opts->flags & GIT_MERGE_FIND_RENAMES) == 0) + if ((opts->flags & GIT_MERGE_FIND_RENAMES) == 0 || + !diff_list->conflicts.length) return 0; similarity_ours = git__calloc(diff_list->conflicts.length, From c69852d6bc254bbbfabb621f740d28f263877a76 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 19 Jul 2021 16:03:36 -0400 Subject: [PATCH 0376/1616] ci: enable strict allocation checking on one node --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 38c79faf885..2bc91e73c77 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -86,7 +86,7 @@ jobs: env: CC: gcc CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DDEBUG_STRICT_ALLOC=ON os: ubuntu-latest - # Xenial, GCC, mbedTLS container: From 688bf4ce38e995d88a8d58b85b648315d5e391be Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Mon, 19 Jul 2021 19:25:58 -0300 Subject: [PATCH 0377/1616] Remove macro magic --- src/trace.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/trace.h b/src/trace.h index e93283788f7..88d660d490a 100644 --- a/src/trace.h +++ b/src/trace.h @@ -47,15 +47,6 @@ GIT_INLINE(void) git_trace__write_fmt( } #define git_trace_level() (git_trace__data.level) -/* Varadic macros are a C99 feature */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#define git_trace(l, ...) { \ - if (git_trace__data.level >= l && \ - git_trace__data.callback != NULL) { \ - git_trace__write_fmt(l, __VA_ARGS__); \ - } \ - } -#else GIT_INLINE(void) git_trace(git_trace_level_t level, const char *fmt, ...) { if (git_trace__data.level >= level && @@ -67,7 +58,6 @@ GIT_INLINE(void) git_trace(git_trace_level_t level, const char *fmt, ...) va_end(ap); } } -#endif #else GIT_INLINE(void) git_trace__null( From b0980dcfb35fe1c8f783001296b4fea6b7373058 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 20 Jul 2021 08:25:59 -0400 Subject: [PATCH 0378/1616] Update src/allocators/stdalloc.c Co-authored-by: lhchavez --- src/allocators/stdalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/allocators/stdalloc.c b/src/allocators/stdalloc.c index 7215468b6cf..2b36d9f3df3 100644 --- a/src/allocators/stdalloc.c +++ b/src/allocators/stdalloc.c @@ -35,7 +35,7 @@ static void *stdalloc__calloc(size_t nelem, size_t elsize, const char *file, int GIT_UNUSED(line); #ifdef GIT_DEBUG_STRICT_ALLOC - if (!elsize) + if (!elsize || !nelem) return NULL; #endif From 5ee5048841b514e80695a2ec5d19cb1ad34eeffa Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 May 2021 18:47:03 +0100 Subject: [PATCH 0379/1616] attr: rename internal attr file source enum The enum `git_attr_file_source` is better suffixed with a `_t` since it's a type-of source. Similarly, its members should have a matching name. --- src/attr.c | 51 ++++++++++++++++++++++++------------------- src/attr_file.c | 42 +++++++++++++++++------------------ src/attr_file.h | 18 +++++++-------- src/attrcache.c | 24 ++++++++++---------- src/attrcache.h | 4 ++-- src/ignore.c | 11 ++++++---- tests/attr/repo.c | 12 +++++----- tests/ignore/status.c | 4 ++-- 8 files changed, 89 insertions(+), 77 deletions(-) diff --git a/src/attr.c b/src/attr.c index cab5e8b9756..a8848ca6cf8 100644 --- a/src/attr.c +++ b/src/attr.c @@ -256,7 +256,7 @@ int git_attr_foreach( static int preload_attr_file( git_repository *repo, git_attr_session *attr_session, - git_attr_file_source source, + git_attr_file_source_t source_type, const char *base, const char *file, bool allow_macros) @@ -266,8 +266,10 @@ static int preload_attr_file( if (!file) return 0; - if (!(error = git_attr_cache__get(&preload, repo, attr_session, source, base, file, - git_attr_file__parse_buffer, allow_macros))) + if (!(error = git_attr_cache__get(&preload, repo, attr_session, + source_type, base, file, + git_attr_file__parse_buffer, + allow_macros))) git_attr_file__free(preload); return error; @@ -333,36 +335,36 @@ static int attr_setup( */ if ((error = system_attr_file(&path, attr_session)) < 0 || - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE__FROM_FILE, + (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, NULL, path.ptr, true)) < 0) { if (error != GIT_ENOTFOUND) goto out; } - if ((error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE__FROM_FILE, + if ((error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, NULL, git_repository_attr_cache(repo)->cfg_attr_file, true)) < 0) goto out; git_buf_clear(&path); /* git_repository_item_path expects an empty buffer, because it uses git_buf_set */ if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE__FROM_FILE, + (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, path.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) { if (error != GIT_ENOTFOUND) goto out; } if ((workdir = git_repository_workdir(repo)) != NULL && - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE__FROM_FILE, + (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, workdir, GIT_ATTR_FILE, true)) < 0) goto out; if ((error = git_repository_index__weakptr(&idx, repo)) < 0 || - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE__FROM_INDEX, + (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_INDEX, NULL, GIT_ATTR_FILE, true)) < 0) goto out; if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0 && - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE__FROM_HEAD, + (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_HEAD, NULL, GIT_ATTR_FILE, true)) < 0) goto out; @@ -422,31 +424,34 @@ typedef struct { } attr_walk_up_info; static int attr_decide_sources( - uint32_t flags, bool has_wd, bool has_index, git_attr_file_source *srcs) + uint32_t flags, + bool has_wd, + bool has_index, + git_attr_file_source_t *srcs) { int count = 0; switch (flags & 0x03) { case GIT_ATTR_CHECK_FILE_THEN_INDEX: if (has_wd) - srcs[count++] = GIT_ATTR_FILE__FROM_FILE; + srcs[count++] = GIT_ATTR_FILE_SOURCE_FILE; if (has_index) - srcs[count++] = GIT_ATTR_FILE__FROM_INDEX; + srcs[count++] = GIT_ATTR_FILE_SOURCE_INDEX; break; case GIT_ATTR_CHECK_INDEX_THEN_FILE: if (has_index) - srcs[count++] = GIT_ATTR_FILE__FROM_INDEX; + srcs[count++] = GIT_ATTR_FILE_SOURCE_INDEX; if (has_wd) - srcs[count++] = GIT_ATTR_FILE__FROM_FILE; + srcs[count++] = GIT_ATTR_FILE_SOURCE_FILE; break; case GIT_ATTR_CHECK_INDEX_ONLY: if (has_index) - srcs[count++] = GIT_ATTR_FILE__FROM_INDEX; + srcs[count++] = GIT_ATTR_FILE_SOURCE_INDEX; break; } if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0) - srcs[count++] = GIT_ATTR_FILE__FROM_HEAD; + srcs[count++] = GIT_ATTR_FILE_SOURCE_HEAD; return count; } @@ -455,7 +460,7 @@ static int push_attr_file( git_repository *repo, git_attr_session *attr_session, git_vector *list, - git_attr_file_source source, + git_attr_file_source_t source_type, const char *base, const char *filename, bool allow_macros) @@ -464,7 +469,9 @@ static int push_attr_file( git_attr_file *file = NULL; error = git_attr_cache__get(&file, repo, attr_session, - source, base, filename, git_attr_file__parse_buffer, allow_macros); + source_type, base, filename, + git_attr_file__parse_buffer, + allow_macros); if (error < 0) return error; @@ -480,7 +487,7 @@ static int push_attr_file( static int push_one_attr(void *ref, const char *path) { attr_walk_up_info *info = (attr_walk_up_info *)ref; - git_attr_file_source src[GIT_ATTR_FILE_NUM_SOURCES]; + git_attr_file_source_t src[GIT_ATTR_FILE_NUM_SOURCES]; int error = 0, n_src, i; bool allow_macros; @@ -542,7 +549,7 @@ static int collect_attr_files( */ if ((error = git_repository_item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || - (error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE, + (error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE, attrfile.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) { if (error != GIT_ENOTFOUND) goto cleanup; @@ -565,7 +572,7 @@ static int collect_attr_files( goto cleanup; if (git_repository_attr_cache(repo)->cfg_attr_file != NULL) { - error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE, + error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE, NULL, git_repository_attr_cache(repo)->cfg_attr_file, true); if (error < 0) goto cleanup; @@ -575,7 +582,7 @@ static int collect_attr_files( error = system_attr_file(&dir, attr_session); if (!error) - error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE, + error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE, NULL, dir.ptr, true); else if (error == GIT_ENOTFOUND) error = 0; diff --git a/src/attr_file.c b/src/attr_file.c index 82692727dd2..f6f1d33c41a 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -33,7 +33,7 @@ static void attr_file_free(git_attr_file *file) int git_attr_file__new( git_attr_file **out, git_attr_file_entry *entry, - git_attr_file_source source) + git_attr_file_source_t source_type) { git_attr_file *attrs = git__calloc(1, sizeof(git_attr_file)); GIT_ERROR_CHECK_ALLOC(attrs); @@ -47,8 +47,8 @@ int git_attr_file__new( goto on_error; GIT_REFCOUNT_INC(attrs); - attrs->entry = entry; - attrs->source = source; + attrs->entry = entry; + attrs->source_type = source_type; *out = attrs; return 0; @@ -108,7 +108,7 @@ int git_attr_file__load( git_repository *repo, git_attr_session *attr_session, git_attr_file_entry *entry, - git_attr_file_source source, + git_attr_file_source_t source_type, git_attr_file_parser parser, bool allow_macros) { @@ -128,11 +128,11 @@ int git_attr_file__load( *out = NULL; - switch (source) { - case GIT_ATTR_FILE__IN_MEMORY: + switch (source_type) { + case GIT_ATTR_FILE_SOURCE_MEMORY: /* in-memory attribute file doesn't need data */ break; - case GIT_ATTR_FILE__FROM_INDEX: { + case GIT_ATTR_FILE_SOURCE_INDEX: { if ((error = attr_file_oid_from_index(&id, repo, entry->path)) < 0 || (error = git_blob_lookup(&blob, repo, &id)) < 0) return error; @@ -145,7 +145,7 @@ int git_attr_file__load( git_buf_put(&content, git_blob_rawcontent(blob), (size_t)blobsize); break; } - case GIT_ATTR_FILE__FROM_FILE: { + case GIT_ATTR_FILE_SOURCE_FILE: { int fd = -1; /* For open or read errors, pretend that we got ENOTFOUND. */ @@ -162,7 +162,7 @@ int git_attr_file__load( break; } - case GIT_ATTR_FILE__FROM_HEAD: { + case GIT_ATTR_FILE_SOURCE_HEAD: { if ((error = git_repository_head_tree(&tree, repo)) < 0 || (error = git_tree_entry_bypath(&tree_entry, tree, entry->path)) < 0 || (error = git_blob_lookup(&blob, repo, git_tree_entry_id(tree_entry))) < 0) @@ -182,11 +182,11 @@ int git_attr_file__load( break; } default: - git_error_set(GIT_ERROR_INVALID, "unknown file source %d", source); + git_error_set(GIT_ERROR_INVALID, "unknown file source %d", source_type); return -1; } - if ((error = git_attr_file__new(&file, entry, source)) < 0) + if ((error = git_attr_file__new(&file, entry, source_type)) < 0) goto cleanup; /* advance over a UTF8 BOM */ @@ -210,11 +210,11 @@ int git_attr_file__load( /* write cache breakers */ if (nonexistent) file->nonexistent = 1; - else if (source == GIT_ATTR_FILE__FROM_INDEX) + else if (source_type == GIT_ATTR_FILE_SOURCE_INDEX) git_oid_cpy(&file->cache_data.oid, git_blob_id(blob)); - else if (source == GIT_ATTR_FILE__FROM_HEAD) + else if (source_type == GIT_ATTR_FILE_SOURCE_HEAD) git_oid_cpy(&file->cache_data.oid, git_tree_id(tree)); - else if (source == GIT_ATTR_FILE__FROM_FILE) + else if (source_type == GIT_ATTR_FILE_SOURCE_FILE) git_futils_filestamp_set_from_stat(&file->cache_data.stamp, &st); /* else always cacheable */ @@ -245,15 +245,15 @@ int git_attr_file__out_of_date( else if (file->nonexistent) return 1; - switch (file->source) { - case GIT_ATTR_FILE__IN_MEMORY: + switch (file->source_type) { + case GIT_ATTR_FILE_SOURCE_MEMORY: return 0; - case GIT_ATTR_FILE__FROM_FILE: + case GIT_ATTR_FILE_SOURCE_FILE: return git_futils_filestamp_check( &file->cache_data.stamp, file->entry->fullpath); - case GIT_ATTR_FILE__FROM_INDEX: { + case GIT_ATTR_FILE_SOURCE_INDEX: { int error; git_oid id; @@ -264,7 +264,7 @@ int git_attr_file__out_of_date( return (git_oid__cmp(&file->cache_data.oid, &id) != 0); } - case GIT_ATTR_FILE__FROM_HEAD: { + case GIT_ATTR_FILE_SOURCE_HEAD: { git_tree *tree; int error; @@ -278,7 +278,7 @@ int git_attr_file__out_of_date( } default: - git_error_set(GIT_ERROR_INVALID, "invalid file type %d", file->source); + git_error_set(GIT_ERROR_INVALID, "invalid file type %d", file->source_type); return -1; } } @@ -400,7 +400,7 @@ int git_attr_file__load_standalone(git_attr_file **out, const char *path) * don't have to free it - freeing file+pool will free cache entry, too. */ - if ((error = git_attr_file__new(&file, NULL, GIT_ATTR_FILE__FROM_FILE)) < 0 || + if ((error = git_attr_file__new(&file, NULL, GIT_ATTR_FILE_SOURCE_FILE)) < 0 || (error = git_attr_file__parse_buffer(NULL, file, content.ptr, true)) < 0 || (error = git_attr_cache__alloc_file_entry(&file->entry, NULL, NULL, path, &file->pool)) < 0) goto out; diff --git a/src/attr_file.h b/src/attr_file.h index 617436b1468..330aed3eeba 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -37,13 +37,13 @@ (GIT_ATTR_FNMATCH_ALLOWSPACE | GIT_ATTR_FNMATCH_ALLOWNEG | GIT_ATTR_FNMATCH_ALLOWMACRO) typedef enum { - GIT_ATTR_FILE__IN_MEMORY = 0, - GIT_ATTR_FILE__FROM_FILE = 1, - GIT_ATTR_FILE__FROM_INDEX = 2, - GIT_ATTR_FILE__FROM_HEAD = 3, + GIT_ATTR_FILE_SOURCE_MEMORY = 0, + GIT_ATTR_FILE_SOURCE_FILE = 1, + GIT_ATTR_FILE_SOURCE_INDEX = 2, + GIT_ATTR_FILE_SOURCE_HEAD = 3, - GIT_ATTR_FILE_NUM_SOURCES = 4 -} git_attr_file_source; + GIT_ATTR_FILE_NUM_SOURCES = 4 +} git_attr_file_source_t; extern const char *git_attr__true; extern const char *git_attr__false; @@ -81,7 +81,7 @@ typedef struct { git_refcount rc; git_mutex lock; git_attr_file_entry *entry; - git_attr_file_source source; + git_attr_file_source_t source_type; git_vector rules; /* vector of or */ git_pool pool; unsigned int nonexistent:1; @@ -142,7 +142,7 @@ typedef int (*git_attr_file_parser)( int git_attr_file__new( git_attr_file **out, git_attr_file_entry *entry, - git_attr_file_source source); + git_attr_file_source_t source_type); void git_attr_file__free(git_attr_file *file); @@ -151,7 +151,7 @@ int git_attr_file__load( git_repository *repo, git_attr_session *attr_session, git_attr_file_entry *ce, - git_attr_file_source source, + git_attr_file_source_t source_type, git_attr_file_parser parser, bool allow_macros); diff --git a/src/attrcache.c b/src/attrcache.c index 32513da0172..322e6010015 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -112,7 +112,7 @@ static int attr_cache_upsert(git_attr_cache *cache, git_attr_file *file) * Replace the existing value if another thread has * created it in the meantime. */ - old = git_atomic_swap(entry->file[file->source], file); + old = git_atomic_swap(entry->file[file->source_type], file); if (old) { GIT_REFCOUNT_OWN(old, NULL); @@ -136,7 +136,7 @@ static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file) return error; if ((entry = attr_cache_lookup_entry(cache, file->entry->path)) != NULL) - old = git_atomic_compare_and_swap(&entry->file[file->source], file, NULL); + old = git_atomic_compare_and_swap(&entry->file[file->source_type], file, NULL); attr_cache_unlock(cache); @@ -158,7 +158,7 @@ static int attr_cache_lookup( git_attr_file_entry **out_entry, git_repository *repo, git_attr_session *attr_session, - git_attr_file_source source, + git_attr_file_source_t source_type, const char *base, const char *filename) { @@ -191,8 +191,8 @@ static int attr_cache_lookup( entry = attr_cache_lookup_entry(cache, relfile); if (!entry) error = attr_cache_make_entry(&entry, repo, relfile); - else if (entry->file[source] != NULL) { - file = entry->file[source]; + else if (entry->file[source_type] != NULL) { + file = entry->file[source_type]; GIT_REFCOUNT_INC(file); } @@ -210,7 +210,7 @@ int git_attr_cache__get( git_attr_file **out, git_repository *repo, git_attr_session *attr_session, - git_attr_file_source source, + git_attr_file_source_t source_type, const char *base, const char *filename, git_attr_file_parser parser, @@ -221,13 +221,15 @@ int git_attr_cache__get( git_attr_file_entry *entry = NULL; git_attr_file *file = NULL, *updated = NULL; - if ((error = attr_cache_lookup( - &file, &entry, repo, attr_session, source, base, filename)) < 0) + if ((error = attr_cache_lookup(&file, &entry, repo, attr_session, + source_type, base, filename)) < 0) return error; /* load file if we don't have one or if existing one is out of date */ if (!file || (error = git_attr_file__out_of_date(repo, attr_session, file)) > 0) - error = git_attr_file__load(&updated, repo, attr_session, entry, source, parser, allow_macros); + error = git_attr_file__load(&updated, repo, attr_session, + entry, source_type, parser, + allow_macros); /* if we loaded the file, insert into and/or update cache */ if (updated) { @@ -260,7 +262,7 @@ int git_attr_cache__get( bool git_attr_cache__is_cached( git_repository *repo, - git_attr_file_source source, + git_attr_file_source_t source_type, const char *filename) { git_attr_cache *cache = git_repository_attr_cache(repo); @@ -273,7 +275,7 @@ bool git_attr_cache__is_cached( if ((entry = git_strmap_get(files, filename)) == NULL) return false; - return entry && (entry->file[source] != NULL); + return entry && (entry->file[source_type] != NULL); } diff --git a/src/attrcache.h b/src/attrcache.h index 5e2fb29f4f5..6d1d968a743 100644 --- a/src/attrcache.h +++ b/src/attrcache.h @@ -31,7 +31,7 @@ extern int git_attr_cache__get( git_attr_file **file, git_repository *repo, git_attr_session *attr_session, - git_attr_file_source source, + git_attr_file_source_t source_type, const char *base, const char *filename, git_attr_file_parser parser, @@ -39,7 +39,7 @@ extern int git_attr_cache__get( extern bool git_attr_cache__is_cached( git_repository *repo, - git_attr_file_source source, + git_attr_file_source_t source_type, const char *path); extern int git_attr_cache__alloc_file_entry( diff --git a/src/ignore.c b/src/ignore.c index 948c58d8594..db342898d20 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -250,8 +250,10 @@ static int push_ignore_file( int error = 0; git_attr_file *file = NULL; - error = git_attr_cache__get(&file, ignores->repo, NULL, GIT_ATTR_FILE__FROM_FILE, - base, filename, parse_ignore_file, false); + error = git_attr_cache__get(&file, ignores->repo, NULL, + GIT_ATTR_FILE_SOURCE_FILE, base, + filename, parse_ignore_file, false); + if (error < 0) return error; @@ -277,8 +279,9 @@ static int get_internal_ignores(git_attr_file **out, git_repository *repo) if ((error = git_attr_cache__init(repo)) < 0) return error; - error = git_attr_cache__get(out, repo, NULL, GIT_ATTR_FILE__IN_MEMORY, NULL, - GIT_IGNORE_INTERNAL, NULL, false); + error = git_attr_cache__get(out, repo, NULL, + GIT_ATTR_FILE_SOURCE_MEMORY, NULL, + GIT_IGNORE_INTERNAL, NULL, false); /* if internal rules list is empty, insert default rules */ if (!error && !(*out)->rules.length) diff --git a/tests/attr/repo.c b/tests/attr/repo.c index 36beeb09542..8224e5c1ea6 100644 --- a/tests/attr/repo.c +++ b/tests/attr/repo.c @@ -71,11 +71,11 @@ void test_attr_repo__get_one(void) } cl_assert(git_attr_cache__is_cached( - g_repo, GIT_ATTR_FILE__FROM_FILE, ".git/info/attributes")); + g_repo, GIT_ATTR_FILE_SOURCE_FILE, ".git/info/attributes")); cl_assert(git_attr_cache__is_cached( - g_repo, GIT_ATTR_FILE__FROM_FILE, ".gitattributes")); + g_repo, GIT_ATTR_FILE_SOURCE_FILE, ".gitattributes")); cl_assert(git_attr_cache__is_cached( - g_repo, GIT_ATTR_FILE__FROM_FILE, "sub/.gitattributes")); + g_repo, GIT_ATTR_FILE_SOURCE_FILE, "sub/.gitattributes")); } void test_attr_repo__get_one_start_deep(void) @@ -92,11 +92,11 @@ void test_attr_repo__get_one_start_deep(void) } cl_assert(git_attr_cache__is_cached( - g_repo, GIT_ATTR_FILE__FROM_FILE, ".git/info/attributes")); + g_repo, GIT_ATTR_FILE_SOURCE_FILE, ".git/info/attributes")); cl_assert(git_attr_cache__is_cached( - g_repo, GIT_ATTR_FILE__FROM_FILE, ".gitattributes")); + g_repo, GIT_ATTR_FILE_SOURCE_FILE, ".gitattributes")); cl_assert(git_attr_cache__is_cached( - g_repo, GIT_ATTR_FILE__FROM_FILE, "sub/.gitattributes")); + g_repo, GIT_ATTR_FILE_SOURCE_FILE, "sub/.gitattributes")); } void test_attr_repo__get_many(void) diff --git a/tests/ignore/status.c b/tests/ignore/status.c index 188fbe46966..83e821bdd8c 100644 --- a/tests/ignore/status.c +++ b/tests/ignore/status.c @@ -70,9 +70,9 @@ void test_ignore_status__0(void) /* confirm that ignore files were cached */ cl_assert(git_attr_cache__is_cached( - g_repo, GIT_ATTR_FILE__FROM_FILE, ".git/info/exclude")); + g_repo, GIT_ATTR_FILE_SOURCE_FILE, ".git/info/exclude")); cl_assert(git_attr_cache__is_cached( - g_repo, GIT_ATTR_FILE__FROM_FILE, ".gitignore")); + g_repo, GIT_ATTR_FILE_SOURCE_FILE, ".gitignore")); } From 96dc1ffdc864c883e632989d75c32f602b107c83 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 May 2021 20:14:47 +0100 Subject: [PATCH 0380/1616] attr: the attr source is now a struct We may want to extend the attribute source; use a structure instead of an enum. --- src/attr_file.c | 25 +++++++++++++------------ src/attr_file.h | 10 +++++++--- src/attrcache.c | 7 ++++--- tests/attr/lookup.c | 3 ++- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/attr_file.c b/src/attr_file.c index f6f1d33c41a..db16a4793a6 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -33,7 +33,7 @@ static void attr_file_free(git_attr_file *file) int git_attr_file__new( git_attr_file **out, git_attr_file_entry *entry, - git_attr_file_source_t source_type) + git_attr_file_source *source) { git_attr_file *attrs = git__calloc(1, sizeof(git_attr_file)); GIT_ERROR_CHECK_ALLOC(attrs); @@ -48,7 +48,7 @@ int git_attr_file__new( GIT_REFCOUNT_INC(attrs); attrs->entry = entry; - attrs->source_type = source_type; + memcpy(&attrs->source, source, sizeof(git_attr_file_source)); *out = attrs; return 0; @@ -108,7 +108,7 @@ int git_attr_file__load( git_repository *repo, git_attr_session *attr_session, git_attr_file_entry *entry, - git_attr_file_source_t source_type, + git_attr_file_source *source, git_attr_file_parser parser, bool allow_macros) { @@ -128,7 +128,7 @@ int git_attr_file__load( *out = NULL; - switch (source_type) { + switch (source->type) { case GIT_ATTR_FILE_SOURCE_MEMORY: /* in-memory attribute file doesn't need data */ break; @@ -182,11 +182,11 @@ int git_attr_file__load( break; } default: - git_error_set(GIT_ERROR_INVALID, "unknown file source %d", source_type); + git_error_set(GIT_ERROR_INVALID, "unknown file source %d", source->type); return -1; } - if ((error = git_attr_file__new(&file, entry, source_type)) < 0) + if ((error = git_attr_file__new(&file, entry, source)) < 0) goto cleanup; /* advance over a UTF8 BOM */ @@ -210,11 +210,11 @@ int git_attr_file__load( /* write cache breakers */ if (nonexistent) file->nonexistent = 1; - else if (source_type == GIT_ATTR_FILE_SOURCE_INDEX) + else if (source->type == GIT_ATTR_FILE_SOURCE_INDEX) git_oid_cpy(&file->cache_data.oid, git_blob_id(blob)); - else if (source_type == GIT_ATTR_FILE_SOURCE_HEAD) + else if (source->type == GIT_ATTR_FILE_SOURCE_HEAD) git_oid_cpy(&file->cache_data.oid, git_tree_id(tree)); - else if (source_type == GIT_ATTR_FILE_SOURCE_FILE) + else if (source->type == GIT_ATTR_FILE_SOURCE_FILE) git_futils_filestamp_set_from_stat(&file->cache_data.stamp, &st); /* else always cacheable */ @@ -245,7 +245,7 @@ int git_attr_file__out_of_date( else if (file->nonexistent) return 1; - switch (file->source_type) { + switch (file->source.type) { case GIT_ATTR_FILE_SOURCE_MEMORY: return 0; @@ -278,7 +278,7 @@ int git_attr_file__out_of_date( } default: - git_error_set(GIT_ERROR_INVALID, "invalid file type %d", file->source_type); + git_error_set(GIT_ERROR_INVALID, "invalid file type %d", file->source.type); return -1; } } @@ -389,6 +389,7 @@ int git_attr_file__lookup_one( int git_attr_file__load_standalone(git_attr_file **out, const char *path) { git_buf content = GIT_BUF_INIT; + git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_FILE }; git_attr_file *file = NULL; int error; @@ -400,7 +401,7 @@ int git_attr_file__load_standalone(git_attr_file **out, const char *path) * don't have to free it - freeing file+pool will free cache entry, too. */ - if ((error = git_attr_file__new(&file, NULL, GIT_ATTR_FILE_SOURCE_FILE)) < 0 || + if ((error = git_attr_file__new(&file, NULL, &source)) < 0 || (error = git_attr_file__parse_buffer(NULL, file, content.ptr, true)) < 0 || (error = git_attr_cache__alloc_file_entry(&file->entry, NULL, NULL, path, &file->pool)) < 0) goto out; diff --git a/src/attr_file.h b/src/attr_file.h index 330aed3eeba..6f5318d0518 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -45,6 +45,10 @@ typedef enum { GIT_ATTR_FILE_NUM_SOURCES = 4 } git_attr_file_source_t; +typedef struct { + git_attr_file_source_t type; +} git_attr_file_source; + extern const char *git_attr__true; extern const char *git_attr__false; extern const char *git_attr__unset; @@ -81,7 +85,7 @@ typedef struct { git_refcount rc; git_mutex lock; git_attr_file_entry *entry; - git_attr_file_source_t source_type; + git_attr_file_source source; git_vector rules; /* vector of or */ git_pool pool; unsigned int nonexistent:1; @@ -142,7 +146,7 @@ typedef int (*git_attr_file_parser)( int git_attr_file__new( git_attr_file **out, git_attr_file_entry *entry, - git_attr_file_source_t source_type); + git_attr_file_source *source); void git_attr_file__free(git_attr_file *file); @@ -151,7 +155,7 @@ int git_attr_file__load( git_repository *repo, git_attr_session *attr_session, git_attr_file_entry *ce, - git_attr_file_source_t source_type, + git_attr_file_source *source, git_attr_file_parser parser, bool allow_macros); diff --git a/src/attrcache.c b/src/attrcache.c index 322e6010015..1f842c6e20c 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -112,7 +112,7 @@ static int attr_cache_upsert(git_attr_cache *cache, git_attr_file *file) * Replace the existing value if another thread has * created it in the meantime. */ - old = git_atomic_swap(entry->file[file->source_type], file); + old = git_atomic_swap(entry->file[file->source.type], file); if (old) { GIT_REFCOUNT_OWN(old, NULL); @@ -136,7 +136,7 @@ static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file) return error; if ((entry = attr_cache_lookup_entry(cache, file->entry->path)) != NULL) - old = git_atomic_compare_and_swap(&entry->file[file->source_type], file, NULL); + old = git_atomic_compare_and_swap(&entry->file[file->source.type], file, NULL); attr_cache_unlock(cache); @@ -220,6 +220,7 @@ int git_attr_cache__get( git_attr_cache *cache = git_repository_attr_cache(repo); git_attr_file_entry *entry = NULL; git_attr_file *file = NULL, *updated = NULL; + git_attr_file_source source = { source_type }; if ((error = attr_cache_lookup(&file, &entry, repo, attr_session, source_type, base, filename)) < 0) @@ -228,7 +229,7 @@ int git_attr_cache__get( /* load file if we don't have one or if existing one is out of date */ if (!file || (error = git_attr_file__out_of_date(repo, attr_session, file)) > 0) error = git_attr_file__load(&updated, repo, attr_session, - entry, source_type, parser, + entry, &source, parser, allow_macros); /* if we loaded the file, insert into and/or update cache */ diff --git a/tests/attr/lookup.c b/tests/attr/lookup.c index 29a66b0013c..bfb2e872f26 100644 --- a/tests/attr/lookup.c +++ b/tests/attr/lookup.c @@ -236,6 +236,7 @@ void test_attr_lookup__check_attr_examples(void) void test_attr_lookup__from_buffer(void) { git_attr_file *file; + git_attr_file_source source = {0}; struct attr_expected cases[] = { { "abc", "foo", EXPECT_TRUE, NULL }, @@ -250,7 +251,7 @@ void test_attr_lookup__from_buffer(void) { NULL, NULL, 0, NULL } }; - cl_git_pass(git_attr_file__new(&file, NULL, 0)); + cl_git_pass(git_attr_file__new(&file, NULL, &source)); cl_git_pass(git_attr_file__parse_buffer(NULL, file, "a* foo\nabc bar\n* baz", true)); From 1cd863fd16a60517d2e42402c69238bf03b5dae0 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 24 May 2021 13:44:45 +0100 Subject: [PATCH 0381/1616] attr: include the filename in the attr source The attribute source object is now the type and the path. --- src/attr.c | 109 +++++++++++++++++++++++++++++------------------- src/attr_file.c | 6 +-- src/attr_file.h | 10 ++++- src/attrcache.c | 39 ++++++++--------- src/attrcache.h | 6 +-- src/ignore.c | 12 +++--- 6 files changed, 104 insertions(+), 78 deletions(-) diff --git a/src/attr.c b/src/attr.c index a8848ca6cf8..86be08474dd 100644 --- a/src/attr.c +++ b/src/attr.c @@ -253,28 +253,43 @@ int git_attr_foreach( return error; } -static int preload_attr_file( +static int preload_attr_source( git_repository *repo, git_attr_session *attr_session, - git_attr_file_source_t source_type, - const char *base, - const char *file, - bool allow_macros) + git_attr_file_source *source) { int error; git_attr_file *preload = NULL; - if (!file) + if (!source) return 0; - if (!(error = git_attr_cache__get(&preload, repo, attr_session, - source_type, base, file, - git_attr_file__parse_buffer, - allow_macros))) + + error = git_attr_cache__get(&preload, repo, attr_session, source, + git_attr_file__parse_buffer, true); + + if (!error) git_attr_file__free(preload); return error; } +GIT_INLINE(int) preload_attr_file( + git_repository *repo, + git_attr_session *attr_session, + const char *base, + const char *filename) +{ + git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_FILE }; + + if (!filename) + return 0; + + source.base = base; + source.filename = filename; + + return preload_attr_source(repo, attr_session, &source); +} + static int system_attr_file( git_buf *out, git_attr_session *attr_session) @@ -318,7 +333,9 @@ static int attr_setup( git_attr_session *attr_session, uint32_t flags) { - git_buf path = GIT_BUF_INIT; + git_buf system = GIT_BUF_INIT, info = GIT_BUF_INIT; + git_attr_file_source index_source = { GIT_ATTR_FILE_SOURCE_INDEX, NULL, GIT_ATTR_FILE }; + git_attr_file_source head_source = { GIT_ATTR_FILE_SOURCE_COMMIT, NULL, GIT_ATTR_FILE }; git_index *idx = NULL; const char *workdir; int error = 0; @@ -334,45 +351,44 @@ static int attr_setup( * definitions will be available for later file parsing. */ - if ((error = system_attr_file(&path, attr_session)) < 0 || - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, - NULL, path.ptr, true)) < 0) { + if ((error = system_attr_file(&system, attr_session)) < 0 || + (error = preload_attr_file(repo, attr_session, NULL, system.ptr)) < 0) { if (error != GIT_ENOTFOUND) goto out; + + error = 0; } - if ((error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, - NULL, git_repository_attr_cache(repo)->cfg_attr_file, true)) < 0) + if ((error = preload_attr_file(repo, attr_session, NULL, + git_repository_attr_cache(repo)->cfg_attr_file)) < 0) goto out; - git_buf_clear(&path); /* git_repository_item_path expects an empty buffer, because it uses git_buf_set */ - if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, - path.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) { + if ((error = git_repository_item_path(&info, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || + (error = preload_attr_file(repo, attr_session, info.ptr, GIT_ATTR_FILE_INREPO)) < 0) { if (error != GIT_ENOTFOUND) goto out; + + error = 0; } if ((workdir = git_repository_workdir(repo)) != NULL && - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, - workdir, GIT_ATTR_FILE, true)) < 0) + (error = preload_attr_file(repo, attr_session, workdir, GIT_ATTR_FILE)) < 0) goto out; if ((error = git_repository_index__weakptr(&idx, repo)) < 0 || - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_INDEX, - NULL, GIT_ATTR_FILE, true)) < 0) + (error = preload_attr_source(repo, attr_session, &index_source)) < 0) goto out; if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0 && - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_HEAD, - NULL, GIT_ATTR_FILE, true)) < 0) + (error = preload_attr_source(repo, attr_session, &head_source)) < 0) goto out; if (attr_session) attr_session->init_setup = 1; out: - git_buf_dispose(&path); + git_buf_dispose(&system); + git_buf_dispose(&info); return error; } @@ -451,25 +467,23 @@ static int attr_decide_sources( } if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0) - srcs[count++] = GIT_ATTR_FILE_SOURCE_HEAD; + srcs[count++] = GIT_ATTR_FILE_SOURCE_COMMIT; return count; } -static int push_attr_file( +static int push_attr_source( git_repository *repo, git_attr_session *attr_session, git_vector *list, - git_attr_file_source_t source_type, - const char *base, - const char *filename, + git_attr_file_source *source, bool allow_macros) { int error = 0; git_attr_file *file = NULL; error = git_attr_cache__get(&file, repo, attr_session, - source_type, base, filename, + source, git_attr_file__parse_buffer, allow_macros); @@ -484,6 +498,17 @@ static int push_attr_file( return error; } +GIT_INLINE(int) push_attr_file( + git_repository *repo, + git_attr_session *attr_session, + git_vector *list, + const char *base, + const char *filename) +{ + git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_FILE, base, filename }; + return push_attr_source(repo, attr_session, list, &source, true); +} + static int push_one_attr(void *ref, const char *path) { attr_walk_up_info *info = (attr_walk_up_info *)ref; @@ -495,9 +520,12 @@ static int push_one_attr(void *ref, const char *path) info->flags, info->workdir != NULL, info->index != NULL, src); allow_macros = info->workdir ? !strcmp(info->workdir, path) : false; - for (i = 0; !error && i < n_src; ++i) - error = push_attr_file(info->repo, info->attr_session, info->files, - src[i], path, GIT_ATTR_FILE, allow_macros); + for (i = 0; !error && i < n_src; ++i) { + git_attr_file_source source = { src[i], path, GIT_ATTR_FILE }; + + error = push_attr_source(info->repo, info->attr_session, info->files, + &source, allow_macros); + } return error; } @@ -549,8 +577,7 @@ static int collect_attr_files( */ if ((error = git_repository_item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || - (error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE, - attrfile.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) { + (error = push_attr_file(repo, attr_session, files, attrfile.ptr, GIT_ATTR_FILE_INREPO)) < 0) { if (error != GIT_ENOTFOUND) goto cleanup; } @@ -572,8 +599,7 @@ static int collect_attr_files( goto cleanup; if (git_repository_attr_cache(repo)->cfg_attr_file != NULL) { - error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE, - NULL, git_repository_attr_cache(repo)->cfg_attr_file, true); + error = push_attr_file(repo, attr_session, files, NULL, git_repository_attr_cache(repo)->cfg_attr_file); if (error < 0) goto cleanup; } @@ -582,8 +608,7 @@ static int collect_attr_files( error = system_attr_file(&dir, attr_session); if (!error) - error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE, - NULL, dir.ptr, true); + error = push_attr_file(repo, attr_session, files, NULL, dir.ptr); else if (error == GIT_ENOTFOUND) error = 0; } diff --git a/src/attr_file.c b/src/attr_file.c index db16a4793a6..b5860238c68 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -162,7 +162,7 @@ int git_attr_file__load( break; } - case GIT_ATTR_FILE_SOURCE_HEAD: { + case GIT_ATTR_FILE_SOURCE_COMMIT: { if ((error = git_repository_head_tree(&tree, repo)) < 0 || (error = git_tree_entry_bypath(&tree_entry, tree, entry->path)) < 0 || (error = git_blob_lookup(&blob, repo, git_tree_entry_id(tree_entry))) < 0) @@ -212,7 +212,7 @@ int git_attr_file__load( file->nonexistent = 1; else if (source->type == GIT_ATTR_FILE_SOURCE_INDEX) git_oid_cpy(&file->cache_data.oid, git_blob_id(blob)); - else if (source->type == GIT_ATTR_FILE_SOURCE_HEAD) + else if (source->type == GIT_ATTR_FILE_SOURCE_COMMIT) git_oid_cpy(&file->cache_data.oid, git_tree_id(tree)); else if (source->type == GIT_ATTR_FILE_SOURCE_FILE) git_futils_filestamp_set_from_stat(&file->cache_data.stamp, &st); @@ -264,7 +264,7 @@ int git_attr_file__out_of_date( return (git_oid__cmp(&file->cache_data.oid, &id) != 0); } - case GIT_ATTR_FILE_SOURCE_HEAD: { + case GIT_ATTR_FILE_SOURCE_COMMIT: { git_tree *tree; int error; diff --git a/src/attr_file.h b/src/attr_file.h index 6f5318d0518..691dbda9e84 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -40,13 +40,21 @@ typedef enum { GIT_ATTR_FILE_SOURCE_MEMORY = 0, GIT_ATTR_FILE_SOURCE_FILE = 1, GIT_ATTR_FILE_SOURCE_INDEX = 2, - GIT_ATTR_FILE_SOURCE_HEAD = 3, + GIT_ATTR_FILE_SOURCE_COMMIT = 3, GIT_ATTR_FILE_NUM_SOURCES = 4 } git_attr_file_source_t; typedef struct { + /* The source location for the attribute file. */ git_attr_file_source_t type; + + /* + * The filename of the attribute file to read (relative to the + * given base path). + */ + const char *base; + const char *filename; } git_attr_file_source; extern const char *git_attr__true; diff --git a/src/attrcache.c b/src/attrcache.c index 1f842c6e20c..f0771273592 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -158,41 +158,42 @@ static int attr_cache_lookup( git_attr_file_entry **out_entry, git_repository *repo, git_attr_session *attr_session, - git_attr_file_source_t source_type, - const char *base, - const char *filename) + git_attr_file_source *source) { int error = 0; git_buf path = GIT_BUF_INIT; - const char *wd = git_repository_workdir(repo), *relfile; + const char *wd = git_repository_workdir(repo); + const char *filename; git_attr_cache *cache = git_repository_attr_cache(repo); git_attr_file_entry *entry = NULL; git_attr_file *file = NULL; /* join base and path as needed */ - if (base != NULL && git_path_root(filename) < 0) { + if (source->base != NULL && git_path_root(source->filename) < 0) { git_buf *p = attr_session ? &attr_session->tmp : &path; - if (git_buf_joinpath(p, base, filename) < 0 || + if (git_buf_joinpath(p, source->base, source->filename) < 0 || git_path_validate_workdir_buf(repo, p) < 0) return -1; filename = p->ptr; + } else { + filename = source->filename; } - relfile = filename; - if (wd && !git__prefixcmp(relfile, wd)) - relfile += strlen(wd); + if (wd && !git__prefixcmp(filename, wd)) + filename += strlen(wd); /* check cache for existing entry */ if ((error = attr_cache_lock(cache)) < 0) goto cleanup; - entry = attr_cache_lookup_entry(cache, relfile); - if (!entry) - error = attr_cache_make_entry(&entry, repo, relfile); - else if (entry->file[source_type] != NULL) { - file = entry->file[source_type]; + entry = attr_cache_lookup_entry(cache, filename); + + if (!entry) { + error = attr_cache_make_entry(&entry, repo, filename); + } else if (entry->file[source->type] != NULL) { + file = entry->file[source->type]; GIT_REFCOUNT_INC(file); } @@ -210,9 +211,7 @@ int git_attr_cache__get( git_attr_file **out, git_repository *repo, git_attr_session *attr_session, - git_attr_file_source_t source_type, - const char *base, - const char *filename, + git_attr_file_source *source, git_attr_file_parser parser, bool allow_macros) { @@ -220,16 +219,14 @@ int git_attr_cache__get( git_attr_cache *cache = git_repository_attr_cache(repo); git_attr_file_entry *entry = NULL; git_attr_file *file = NULL, *updated = NULL; - git_attr_file_source source = { source_type }; - if ((error = attr_cache_lookup(&file, &entry, repo, attr_session, - source_type, base, filename)) < 0) + if ((error = attr_cache_lookup(&file, &entry, repo, attr_session, source)) < 0) return error; /* load file if we don't have one or if existing one is out of date */ if (!file || (error = git_attr_file__out_of_date(repo, attr_session, file)) > 0) error = git_attr_file__load(&updated, repo, attr_session, - entry, &source, parser, + entry, source, parser, allow_macros); /* if we loaded the file, insert into and/or update cache */ diff --git a/src/attrcache.h b/src/attrcache.h index 6d1d968a743..b13e0e8f0a8 100644 --- a/src/attrcache.h +++ b/src/attrcache.h @@ -31,16 +31,14 @@ extern int git_attr_cache__get( git_attr_file **file, git_repository *repo, git_attr_session *attr_session, - git_attr_file_source_t source_type, - const char *base, - const char *filename, + git_attr_file_source *source, git_attr_file_parser parser, bool allow_macros); extern bool git_attr_cache__is_cached( git_repository *repo, git_attr_file_source_t source_type, - const char *path); + const char *filename); extern int git_attr_cache__alloc_file_entry( git_attr_file_entry **out, diff --git a/src/ignore.c b/src/ignore.c index db342898d20..f7551cddb6f 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -247,12 +247,11 @@ static int push_ignore_file( const char *base, const char *filename) { - int error = 0; + git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_FILE, base, filename }; git_attr_file *file = NULL; + int error = 0; - error = git_attr_cache__get(&file, ignores->repo, NULL, - GIT_ATTR_FILE_SOURCE_FILE, base, - filename, parse_ignore_file, false); + error = git_attr_cache__get(&file, ignores->repo, NULL, &source, parse_ignore_file, false); if (error < 0) return error; @@ -274,14 +273,13 @@ static int push_one_ignore(void *payload, const char *path) static int get_internal_ignores(git_attr_file **out, git_repository *repo) { + git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_MEMORY, NULL, GIT_IGNORE_INTERNAL }; int error; if ((error = git_attr_cache__init(repo)) < 0) return error; - error = git_attr_cache__get(out, repo, NULL, - GIT_ATTR_FILE_SOURCE_MEMORY, NULL, - GIT_IGNORE_INTERNAL, NULL, false); + error = git_attr_cache__get(out, repo, NULL, &source, NULL, false); /* if internal rules list is empty, insert default rules */ if (!error && !(*out)->rules.length) From 3779a04794333a0152a1d7ae39117278508c4680 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 27 May 2021 18:47:22 +0100 Subject: [PATCH 0382/1616] attr: introduce `git_attr_options` for extended queries Allow more advanced attribute queries using a `git_attr_options`, and extended functions to use it. Presently there is no additional configuration in a `git_attr_options` beyond the flags, but this is for future growth. --- include/git2/attr.h | 79 +++++++++++++++++++++++++++++++++++++++++++++ src/attr.c | 75 ++++++++++++++++++++++++++++++++++-------- src/attr_file.h | 2 +- src/filter.c | 8 ++--- tests/attr/repo.c | 2 +- 5 files changed, 146 insertions(+), 20 deletions(-) diff --git a/include/git2/attr.h b/include/git2/attr.h index a3ab5a7a258..306893c6721 100644 --- a/include/git2/attr.h +++ b/include/git2/attr.h @@ -134,6 +134,19 @@ GIT_EXTERN(git_attr_value_t) git_attr_value(const char *attr); #define GIT_ATTR_CHECK_NO_SYSTEM (1 << 2) #define GIT_ATTR_CHECK_INCLUDE_HEAD (1 << 3) +/** +* An options structure for querying attributes. +*/ +typedef struct { + unsigned int version; + + /** A combination of GIT_ATTR_CHECK flags */ + unsigned int flags; +} git_attr_options; + +#define GIT_ATTR_OPTIONS_VERSION 1 +#define GIT_ATTR_OPTIONS_INIT {GIT_ATTR_OPTIONS_VERSION} + /** * Look up the value of one git attribute for path. * @@ -156,6 +169,28 @@ GIT_EXTERN(int) git_attr_get( const char *path, const char *name); +/** + * Look up the value of one git attribute for path with extended options. + * + * @param value_out Output of the value of the attribute. Use the GIT_ATTR_... + * macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just + * use the string value for attributes set to a value. You + * should NOT modify or free this value. + * @param repo The repository containing the path. + * @param opts The `git_attr_options` to use when querying these attributes. + * @param path The path to check for attributes. Relative paths are + * interpreted relative to the repo root. The file does + * not have to exist, but if it does not, then it will be + * treated as a plain file (not a directory). + * @param name The name of the attribute to look up. + */ +GIT_EXTERN(int) git_attr_get_ext( + const char **value_out, + git_repository *repo, + git_attr_options *opts, + const char *path, + const char *name); + /** * Look up a list of git attributes for path. * @@ -193,6 +228,30 @@ GIT_EXTERN(int) git_attr_get_many( size_t num_attr, const char **names); +/** + * Look up a list of git attributes for path with extended options. + * + * @param values_out An array of num_attr entries that will have string + * pointers written into it for the values of the attributes. + * You should not modify or free the values that are written + * into this array (although of course, you should free the + * array itself if you allocated it). + * @param repo The repository containing the path. + * @param opts The `git_attr_options` to use when querying these attributes. + * @param path The path inside the repo to check attributes. This + * does not have to exist, but if it does not, then + * it will be treated as a plain file (i.e. not a directory). + * @param num_attr The number of attributes being looked up + * @param names An array of num_attr strings containing attribute names. + */ +GIT_EXTERN(int) git_attr_get_many_ext( + const char **values_out, + git_repository *repo, + git_attr_options *opts, + const char *path, + size_t num_attr, + const char **names); + /** * The callback used with git_attr_foreach. * @@ -231,6 +290,26 @@ GIT_EXTERN(int) git_attr_foreach( git_attr_foreach_cb callback, void *payload); +/** + * Loop over all the git attributes for a path with extended options. + * + * @param repo The repository containing the path. + * @param opts The `git_attr_options` to use when querying these attributes. + * @param path Path inside the repo to check attributes. This does not have + * to exist, but if it does not, then it will be treated as a + * plain file (i.e. not a directory). + * @param callback Function to invoke on each attribute name and value. + * See git_attr_foreach_cb. + * @param payload Passed on as extra parameter to callback function. + * @return 0 on success, non-zero callback return value, or error code + */ +GIT_EXTERN(int) git_attr_foreach_ext( + git_repository *repo, + git_attr_options *opts, + const char *path, + git_attr_foreach_cb callback, + void *payload); + /** * Flush the gitattributes cache. * diff --git a/src/attr.c b/src/attr.c index 86be08474dd..a2d78e68b92 100644 --- a/src/attr.c +++ b/src/attr.c @@ -36,16 +36,16 @@ git_attr_value_t git_attr_value(const char *attr) static int collect_attr_files( git_repository *repo, git_attr_session *attr_session, - uint32_t flags, + git_attr_options *opts, const char *path, git_vector *files); static void release_attr_files(git_vector *files); -int git_attr_get( +int git_attr_get_ext( const char **value, git_repository *repo, - uint32_t flags, + git_attr_options *opts, const char *pathname, const char *name) { @@ -61,6 +61,7 @@ int git_attr_get( GIT_ASSERT_ARG(value); GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(name); + GIT_ERROR_CHECK_VERSION(opts, GIT_ATTR_OPTIONS_VERSION, "git_attr_options"); *value = NULL; @@ -70,7 +71,7 @@ int git_attr_get( if (git_attr_path__init(&path, repo, pathname, git_repository_workdir(repo), dir_flag) < 0) return -1; - if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0) + if ((error = collect_attr_files(repo, NULL, opts, pathname, &files)) < 0) goto cleanup; memset(&attr, 0, sizeof(attr)); @@ -97,6 +98,20 @@ int git_attr_get( return error; } +int git_attr_get( + const char **value, + git_repository *repo, + uint32_t flags, + const char *pathname, + const char *name) +{ + git_attr_options opts = GIT_ATTR_OPTIONS_INIT; + + opts.flags = flags; + + return git_attr_get_ext(value, repo, &opts, pathname, name); +} + typedef struct { git_attr_name name; @@ -107,7 +122,7 @@ int git_attr_get_many_with_session( const char **values, git_repository *repo, git_attr_session *attr_session, - uint32_t flags, + git_attr_options *opts, const char *pathname, size_t num_attr, const char **names) @@ -129,6 +144,7 @@ int git_attr_get_many_with_session( GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(pathname); GIT_ASSERT_ARG(names); + GIT_ERROR_CHECK_VERSION(opts, GIT_ATTR_OPTIONS_VERSION, "git_attr_options"); if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; @@ -136,7 +152,7 @@ int git_attr_get_many_with_session( if (git_attr_path__init(&path, repo, pathname, git_repository_workdir(repo), dir_flag) < 0) return -1; - if ((error = collect_attr_files(repo, attr_session, flags, pathname, &files)) < 0) + if ((error = collect_attr_files(repo, attr_session, opts, pathname, &files)) < 0) goto cleanup; info = git__calloc(num_attr, sizeof(attr_get_many_info)); @@ -189,9 +205,25 @@ int git_attr_get_many( const char *pathname, size_t num_attr, const char **names) +{ + git_attr_options opts = GIT_ATTR_OPTIONS_INIT; + + opts.flags = flags; + + return git_attr_get_many_with_session( + values, repo, NULL, &opts, pathname, num_attr, names); +} + +int git_attr_get_many_ext( + const char **values, + git_repository *repo, + git_attr_options *opts, + const char *pathname, + size_t num_attr, + const char **names) { return git_attr_get_many_with_session( - values, repo, NULL, flags, pathname, num_attr, names); + values, repo, NULL, opts, pathname, num_attr, names); } int git_attr_foreach( @@ -200,6 +232,20 @@ int git_attr_foreach( const char *pathname, int (*callback)(const char *name, const char *value, void *payload), void *payload) +{ + git_attr_options opts = GIT_ATTR_OPTIONS_INIT; + + opts.flags = flags; + + return git_attr_foreach_ext(repo, &opts, pathname, callback, payload); +} + +int git_attr_foreach_ext( + git_repository *repo, + git_attr_options *opts, + const char *pathname, + int (*callback)(const char *name, const char *value, void *payload), + void *payload) { int error; git_attr_path path; @@ -213,6 +259,7 @@ int git_attr_foreach( GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(callback); + GIT_ERROR_CHECK_VERSION(opts, GIT_ATTR_OPTIONS_VERSION, "git_attr_options"); if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; @@ -220,7 +267,7 @@ int git_attr_foreach( if (git_attr_path__init(&path, repo, pathname, git_repository_workdir(repo), dir_flag) < 0) return -1; - if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0 || + if ((error = collect_attr_files(repo, NULL, opts, pathname, &files)) < 0 || (error = git_strmap_new(&seen)) < 0) goto cleanup; @@ -331,7 +378,7 @@ static int system_attr_file( static int attr_setup( git_repository *repo, git_attr_session *attr_session, - uint32_t flags) + git_attr_options *opts) { git_buf system = GIT_BUF_INIT, info = GIT_BUF_INIT; git_attr_file_source index_source = { GIT_ATTR_FILE_SOURCE_INDEX, NULL, GIT_ATTR_FILE }; @@ -379,7 +426,7 @@ static int attr_setup( (error = preload_attr_source(repo, attr_session, &index_source)) < 0) goto out; - if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0 && + if ((opts && (opts->flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0) && (error = preload_attr_source(repo, attr_session, &head_source)) < 0) goto out; @@ -545,7 +592,7 @@ static void release_attr_files(git_vector *files) static int collect_attr_files( git_repository *repo, git_attr_session *attr_session, - uint32_t flags, + git_attr_options *opts, const char *path, git_vector *files) { @@ -554,7 +601,7 @@ static int collect_attr_files( const char *workdir = git_repository_workdir(repo); attr_walk_up_info info = { NULL }; - if ((error = attr_setup(repo, attr_session, flags)) < 0) + if ((error = attr_setup(repo, attr_session, opts)) < 0) return error; /* Resolve path in a non-bare repo */ @@ -584,7 +631,7 @@ static int collect_attr_files( info.repo = repo; info.attr_session = attr_session; - info.flags = flags; + info.flags = opts ? opts->flags : 0; info.workdir = workdir; if (git_repository_index__weakptr(&info.index, repo) < 0) git_error_clear(); /* no error even if there is no index */ @@ -604,7 +651,7 @@ static int collect_attr_files( goto cleanup; } - if ((flags & GIT_ATTR_CHECK_NO_SYSTEM) == 0) { + if (!opts || (opts->flags & GIT_ATTR_CHECK_NO_SYSTEM) == 0) { error = system_attr_file(&dir, attr_session); if (!error) diff --git a/src/attr_file.h b/src/attr_file.h index 691dbda9e84..5c8a412910c 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -136,7 +136,7 @@ extern int git_attr_get_many_with_session( const char **values_out, git_repository *repo, git_attr_session *attr_session, - uint32_t flags, + git_attr_options *opts, const char *path, size_t num_attr, const char **names); diff --git a/src/filter.c b/src/filter.c index 6c09a6ad58f..d139a591170 100644 --- a/src/filter.c +++ b/src/filter.c @@ -430,20 +430,20 @@ static int filter_list_check_attributes( const git_filter_source *src) { const char **strs = git__calloc(fdef->nattrs, sizeof(const char *)); - uint32_t flags = 0; + git_attr_options attr_opts = GIT_ATTR_OPTIONS_INIT; size_t i; int error; GIT_ERROR_CHECK_ALLOC(strs); if ((src->flags & GIT_FILTER_NO_SYSTEM_ATTRIBUTES) != 0) - flags |= GIT_ATTR_CHECK_NO_SYSTEM; + attr_opts.flags |= GIT_ATTR_CHECK_NO_SYSTEM; if ((src->flags & GIT_FILTER_ATTRIBUTES_FROM_HEAD) != 0) - flags |= GIT_ATTR_CHECK_INCLUDE_HEAD; + attr_opts.flags |= GIT_ATTR_CHECK_INCLUDE_HEAD; error = git_attr_get_many_with_session( - strs, repo, attr_session, flags, src->path, fdef->nattrs, fdef->attrs); + strs, repo, attr_session, &attr_opts, src->path, fdef->nattrs, fdef->attrs); /* if no values were found but no matches are needed, it's okay! */ if (error == GIT_ENOTFOUND && !fdef->nmatches) { diff --git a/tests/attr/repo.c b/tests/attr/repo.c index 8224e5c1ea6..eabc033eb97 100644 --- a/tests/attr/repo.c +++ b/tests/attr/repo.c @@ -341,7 +341,7 @@ void test_attr_repo__sysdir_with_session(void) g_repo = cl_git_sandbox_reopen(); cl_git_pass(git_attr_session__init(&session, g_repo)); - cl_git_pass(git_attr_get_many_with_session(values, g_repo, &session, 0, "file", ARRAY_SIZE(attrs), attrs)); + cl_git_pass(git_attr_get_many_with_session(values, g_repo, &session, NULL, "file", ARRAY_SIZE(attrs), attrs)); cl_assert_equal_s(values[0], "1"); cl_assert_equal_s(values[1], "2"); From 1db5b2199b89bca0c2787945c407fd8b57c0c598 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 16 Jun 2021 09:06:26 +0100 Subject: [PATCH 0383/1616] filter: filter options are now "filter sessions" Filters use a short-lived structure to keep state during an operation to allow for caching and avoid unnecessary reallocations. This was previously called the "filter options", despite the fact that they contain no configurable options. Rename them to a "filter session" in keeping with an "attribute session", which more accurately describes their use (and allows us to create "filter options" in the future). --- src/checkout.c | 20 ++++++++++---------- src/filter.c | 23 ++++++++++++----------- src/filter.h | 10 +++++----- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/checkout.c b/src/checkout.c index 2f84df7a0c4..31d473ec856 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -1513,7 +1513,7 @@ static int blob_content_to_file( int flags = data->opts.file_open_flags; mode_t file_mode = data->opts.file_mode ? data->opts.file_mode : entry_filemode; - git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT; + git_filter_session filter_session = GIT_FILTER_SESSION_INIT; struct checkout_stream writer; mode_t mode; git_filter_list *fl = NULL; @@ -1536,13 +1536,13 @@ static int blob_content_to_file( return fd; } - filter_opts.attr_session = &data->attr_session; - filter_opts.temp_buf = &data->tmp; + filter_session.attr_session = &data->attr_session; + filter_session.temp_buf = &data->tmp; if (!data->opts.disable_filters && - (error = git_filter_list__load_ext( + (error = git_filter_list__load( &fl, data->repo, blob, hint_path, - GIT_FILTER_TO_WORKTREE, &filter_opts))) { + GIT_FILTER_TO_WORKTREE, &filter_session))) { p_close(fd); return error; } @@ -2064,7 +2064,7 @@ static int checkout_write_merge( git_merge_file_result result = {0}; git_filebuf output = GIT_FILEBUF_INIT; git_filter_list *fl = NULL; - git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT; + git_filter_session filter_session = GIT_FILTER_SESSION_INIT; int error = 0; if (data->opts.checkout_strategy & GIT_CHECKOUT_CONFLICT_STYLE_DIFF3) @@ -2114,12 +2114,12 @@ static int checkout_write_merge( in_data.ptr = (char *)result.ptr; in_data.size = result.len; - filter_opts.attr_session = &data->attr_session; - filter_opts.temp_buf = &data->tmp; + filter_session.attr_session = &data->attr_session; + filter_session.temp_buf = &data->tmp; - if ((error = git_filter_list__load_ext( + if ((error = git_filter_list__load( &fl, data->repo, NULL, git_buf_cstr(&path_workdir), - GIT_FILTER_TO_WORKTREE, &filter_opts)) < 0 || + GIT_FILTER_TO_WORKTREE, &filter_session)) < 0 || (error = git_filter_list__convert_buf(&out_data, fl, &in_data)) < 0) goto done; } else { diff --git a/src/filter.c b/src/filter.c index d139a591170..9606ac452e2 100644 --- a/src/filter.c +++ b/src/filter.c @@ -425,7 +425,7 @@ static int filter_list_new( static int filter_list_check_attributes( const char ***out, git_repository *repo, - git_attr_session *attr_session, + git_filter_session *filter_session, git_filter_def *fdef, const git_filter_source *src) { @@ -443,7 +443,7 @@ static int filter_list_check_attributes( attr_opts.flags |= GIT_ATTR_CHECK_INCLUDE_HEAD; error = git_attr_get_many_with_session( - strs, repo, attr_session, &attr_opts, src->path, fdef->nattrs, fdef->attrs); + strs, repo, filter_session->attr_session, &attr_opts, src->path, fdef->nattrs, fdef->attrs); /* if no values were found but no matches are needed, it's okay! */ if (error == GIT_ENOTFOUND && !fdef->nmatches) { @@ -492,13 +492,13 @@ int git_filter_list_new( return filter_list_new(out, &src); } -int git_filter_list__load_ext( +int git_filter_list__load( git_filter_list **filters, git_repository *repo, git_blob *blob, /* can be NULL */ const char *path, git_filter_mode_t mode, - git_filter_options *filter_opts) + git_filter_session *filter_session) { int error = 0; git_filter_list *fl = NULL; @@ -515,7 +515,7 @@ int git_filter_list__load_ext( src.repo = repo; src.path = path; src.mode = mode; - src.flags = filter_opts->flags; + src.flags = filter_session->flags; if (blob) git_oid_cpy(&src.oid, git_blob_id(blob)); @@ -529,7 +529,8 @@ int git_filter_list__load_ext( if (fdef->nattrs > 0) { error = filter_list_check_attributes( - &values, repo, filter_opts->attr_session, fdef, &src); + &values, repo, + filter_session, fdef, &src); if (error == GIT_ENOTFOUND) { error = 0; @@ -556,7 +557,7 @@ int git_filter_list__load_ext( if ((error = filter_list_new(&fl, &src)) < 0) break; - fl->temp_buf = filter_opts->temp_buf; + fl->temp_buf = filter_session->temp_buf; } fe = git_array_alloc(fl->filters); @@ -588,12 +589,12 @@ int git_filter_list_load( git_filter_mode_t mode, uint32_t flags) { - git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT; + git_filter_session filter_session = GIT_FILTER_SESSION_INIT; - filter_opts.flags = flags; + filter_session.flags = flags; - return git_filter_list__load_ext( - filters, repo, blob, path, mode, &filter_opts); + return git_filter_list__load( + filters, repo, blob, path, mode, &filter_session); } void git_filter_list_free(git_filter_list *fl) diff --git a/src/filter.h b/src/filter.h index bbc4c0fb23b..31a776e9bde 100644 --- a/src/filter.h +++ b/src/filter.h @@ -16,24 +16,24 @@ #define GIT_FILTER_BYTES_TO_CHECK_NUL 8000 typedef struct { + uint32_t flags; git_attr_session *attr_session; git_buf *temp_buf; - uint32_t flags; -} git_filter_options; +} git_filter_session; -#define GIT_FILTER_OPTIONS_INIT {0} +#define GIT_FILTER_SESSION_INIT {0} extern int git_filter_global_init(void); extern void git_filter_free(git_filter *filter); -extern int git_filter_list__load_ext( +extern int git_filter_list__load( git_filter_list **filters, git_repository *repo, git_blob *blob, /* can be NULL */ const char *path, git_filter_mode_t mode, - git_filter_options *filter_opts); + git_filter_session *filter_session); /* * The given input buffer will be converted to the given output buffer. From d7e8b9348cab441184b82c57cb2c847c11ffa5d8 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 16 Jun 2021 09:08:38 +0100 Subject: [PATCH 0384/1616] filter: add git_filter_options Allow filter users to provide an options structure instead of simply flags. This allows for future growth for filter options. --- include/git2/filter.h | 36 ++++++++++++++++++++++++++++++++++ src/filter.c | 45 ++++++++++++++++++++++++++++++------------- src/filter.h | 4 ++-- 3 files changed, 70 insertions(+), 15 deletions(-) diff --git a/include/git2/filter.h b/include/git2/filter.h index a0185ee88af..54581517119 100644 --- a/include/git2/filter.h +++ b/include/git2/filter.h @@ -51,6 +51,19 @@ typedef enum { GIT_FILTER_ATTRIBUTES_FROM_HEAD = (1u << 2), } git_filter_flag_t; +/** + * Filtering options + */ +typedef struct { + unsigned int version; + + /** See `git_filter_flag_t` above */ + uint32_t flags; +} git_filter_options; + + #define GIT_FILTER_OPTIONS_VERSION 1 + #define GIT_FILTER_OPTIONS_INIT {GIT_FILTER_OPTIONS_VERSION} + /** * A filter that can transform file data * @@ -103,6 +116,29 @@ GIT_EXTERN(int) git_filter_list_load( git_filter_mode_t mode, uint32_t flags); +/** + * Load the filter list for a given path. + * + * This will return 0 (success) but set the output git_filter_list to NULL + * if no filters are requested for the given file. + * + * @param filters Output newly created git_filter_list (or NULL) + * @param repo Repository object that contains `path` + * @param blob The blob to which the filter will be applied (if known) + * @param path Relative path of the file to be filtered + * @param mode Filtering direction (WT->ODB or ODB->WT) + * @param opts The `git_filter_options` to use when loading filters + * @return 0 on success (which could still return NULL if no filters are + * needed for the requested file), <0 on error + */ +GIT_EXTERN(int) git_filter_list_load_ext( + git_filter_list **filters, + git_repository *repo, + git_blob *blob, + const char *path, + git_filter_mode_t mode, + git_filter_options *opts); + /** * Query the filter list to see if a given filter (by name) will run. * The built-in filters "crlf" and "ident" can be queried, otherwise this diff --git a/src/filter.c b/src/filter.c index 9606ac452e2..3309ab71604 100644 --- a/src/filter.c +++ b/src/filter.c @@ -19,12 +19,12 @@ #include "array.h" struct git_filter_source { - git_repository *repo; - const char *path; - git_oid oid; /* zero if unknown (which is likely) */ - uint16_t filemode; /* zero if unknown */ - git_filter_mode_t mode; - uint32_t flags; + git_repository *repo; + const char *path; + git_oid oid; /* zero if unknown (which is likely) */ + uint16_t filemode; /* zero if unknown */ + git_filter_mode_t mode; + git_filter_options options; }; typedef struct { @@ -396,7 +396,7 @@ git_filter_mode_t git_filter_source_mode(const git_filter_source *src) uint32_t git_filter_source_flags(const git_filter_source *src) { - return src->flags; + return src->options.flags; } static int filter_list_new( @@ -416,7 +416,8 @@ static int filter_list_new( fl->source.repo = src->repo; fl->source.path = fl->path; fl->source.mode = src->mode; - fl->source.flags = src->flags; + + memcpy(&fl->source.options, &src->options, sizeof(git_filter_options)); *out = fl; return 0; @@ -436,10 +437,10 @@ static int filter_list_check_attributes( GIT_ERROR_CHECK_ALLOC(strs); - if ((src->flags & GIT_FILTER_NO_SYSTEM_ATTRIBUTES) != 0) + if ((src->options.flags & GIT_FILTER_NO_SYSTEM_ATTRIBUTES) != 0) attr_opts.flags |= GIT_ATTR_CHECK_NO_SYSTEM; - if ((src->flags & GIT_FILTER_ATTRIBUTES_FROM_HEAD) != 0) + if ((src->options.flags & GIT_FILTER_ATTRIBUTES_FROM_HEAD) != 0) attr_opts.flags |= GIT_ATTR_CHECK_INCLUDE_HEAD; error = git_attr_get_many_with_session( @@ -488,7 +489,7 @@ int git_filter_list_new( src.repo = repo; src.path = NULL; src.mode = mode; - src.flags = flags; + src.options.flags = flags; return filter_list_new(out, &src); } @@ -515,7 +516,8 @@ int git_filter_list__load( src.repo = repo; src.path = path; src.mode = mode; - src.flags = filter_session->flags; + + memcpy(&src.options, &filter_session->options, sizeof(git_filter_options)); if (blob) git_oid_cpy(&src.oid, git_blob_id(blob)); @@ -581,6 +583,23 @@ int git_filter_list__load( return error; } +int git_filter_list_load_ext( + git_filter_list **filters, + git_repository *repo, + git_blob *blob, /* can be NULL */ + const char *path, + git_filter_mode_t mode, + git_filter_options *opts) +{ + git_filter_session filter_session = GIT_FILTER_SESSION_INIT; + + if (opts) + memcpy(&filter_session.options, opts, sizeof(git_filter_options)); + + return git_filter_list__load( + filters, repo, blob, path, mode, &filter_session); +} + int git_filter_list_load( git_filter_list **filters, git_repository *repo, @@ -591,7 +610,7 @@ int git_filter_list_load( { git_filter_session filter_session = GIT_FILTER_SESSION_INIT; - filter_session.flags = flags; + filter_session.options.flags = flags; return git_filter_list__load( filters, repo, blob, path, mode, &filter_session); diff --git a/src/filter.h b/src/filter.h index 31a776e9bde..55ed50e97fd 100644 --- a/src/filter.h +++ b/src/filter.h @@ -16,12 +16,12 @@ #define GIT_FILTER_BYTES_TO_CHECK_NUL 8000 typedef struct { - uint32_t flags; + git_filter_options options; git_attr_session *attr_session; git_buf *temp_buf; } git_filter_session; -#define GIT_FILTER_SESSION_INIT {0} +#define GIT_FILTER_SESSION_INIT {GIT_FILTER_OPTIONS_INIT, 0} extern int git_filter_global_init(void); From 093d579f7be5636c52290a517eee1eebb7471e31 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 22 Jul 2021 15:07:35 -0400 Subject: [PATCH 0385/1616] attr: cache nonexistent attr files from commits When looking up an attribute file in a commit, we can cache a nonexistent attribute file indefinitely (since a commit could not somehow later contain an attribute file). Cache an empty buffer when an attribute file does not exist in a given commit. --- src/attr_file.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/attr_file.c b/src/attr_file.c index b5860238c68..3b8965a10b3 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -163,9 +163,24 @@ int git_attr_file__load( break; } case GIT_ATTR_FILE_SOURCE_COMMIT: { - if ((error = git_repository_head_tree(&tree, repo)) < 0 || - (error = git_tree_entry_bypath(&tree_entry, tree, entry->path)) < 0 || - (error = git_blob_lookup(&blob, repo, git_tree_entry_id(tree_entry))) < 0) + if ((error = git_repository_head_tree(&tree, repo)) < 0) + goto cleanup; + + if ((error = git_tree_entry_bypath(&tree_entry, tree, entry->path)) < 0) { + /* + * If the attributes file does not exist, we can + * cache an empty file for this commit to prevent + * needless future lookups. + */ + if (error == GIT_ENOTFOUND) { + error = 0; + break; + } + + goto cleanup; + } + + if ((error = git_blob_lookup(&blob, repo, git_tree_entry_id(tree_entry))) < 0) goto cleanup; /* From 0bd547a8bee02bf984ea5c7acdc8172044fcb3a4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 22 Jul 2021 15:29:46 -0400 Subject: [PATCH 0386/1616] attr: introduce GIT_ATTR_CHECK_INCLUDE_COMMIT Introduce `GIT_ATTR_CHECK_INCLUDE_COMMIT`, which like 4fd5748 allows attribute information to be read from files in the repository. 4fd5748 always reads the information from HEAD, while `GIT_ATTR_CHECK_INCLUDE_COMMIT` allows users to provide the commit to read the attributes from. --- include/git2/attr.h | 10 ++++++++++ src/attr.c | 29 ++++++++++++++++++++++------- src/attr_file.c | 34 ++++++++++++++++++++++++++++------ src/attr_file.h | 8 +++++++- src/attrcache.c | 7 ++++--- 5 files changed, 71 insertions(+), 17 deletions(-) diff --git a/include/git2/attr.h b/include/git2/attr.h index 306893c6721..62c2ed6e722 100644 --- a/include/git2/attr.h +++ b/include/git2/attr.h @@ -130,9 +130,13 @@ GIT_EXTERN(git_attr_value_t) git_attr_value(const char *attr); * * Passing the `GIT_ATTR_CHECK_INCLUDE_HEAD` flag will use attributes * from a `.gitattributes` file in the repository at the HEAD revision. + * + * Passing the `GIT_ATTR_CHECK_INCLUDE_COMMIT` flag will use attributes + * from a `.gitattributes` file in a specific commit. */ #define GIT_ATTR_CHECK_NO_SYSTEM (1 << 2) #define GIT_ATTR_CHECK_INCLUDE_HEAD (1 << 3) +#define GIT_ATTR_CHECK_INCLUDE_COMMIT (1 << 4) /** * An options structure for querying attributes. @@ -142,6 +146,12 @@ typedef struct { /** A combination of GIT_ATTR_CHECK flags */ unsigned int flags; + + /** + * The commit to load attributes from, when + * `GIT_ATTR_CHECK_INCLUDE_COMMIT` is specified. + */ + git_oid *commit_id; } git_attr_options; #define GIT_ATTR_OPTIONS_VERSION 1 diff --git a/src/attr.c b/src/attr.c index a2d78e68b92..03b720c5a3a 100644 --- a/src/attr.c +++ b/src/attr.c @@ -381,8 +381,9 @@ static int attr_setup( git_attr_options *opts) { git_buf system = GIT_BUF_INIT, info = GIT_BUF_INIT; - git_attr_file_source index_source = { GIT_ATTR_FILE_SOURCE_INDEX, NULL, GIT_ATTR_FILE }; - git_attr_file_source head_source = { GIT_ATTR_FILE_SOURCE_COMMIT, NULL, GIT_ATTR_FILE }; + git_attr_file_source index_source = { GIT_ATTR_FILE_SOURCE_INDEX, NULL, GIT_ATTR_FILE, NULL }; + git_attr_file_source head_source = { GIT_ATTR_FILE_SOURCE_COMMIT, NULL, GIT_ATTR_FILE, NULL }; + git_attr_file_source commit_source = { GIT_ATTR_FILE_SOURCE_COMMIT, NULL, GIT_ATTR_FILE, NULL }; git_index *idx = NULL; const char *workdir; int error = 0; @@ -430,6 +431,13 @@ static int attr_setup( (error = preload_attr_source(repo, attr_session, &head_source)) < 0) goto out; + if ((opts && (opts->flags & GIT_ATTR_CHECK_INCLUDE_COMMIT) != 0)) { + commit_source.commit_id = opts->commit_id; + + if ((error = preload_attr_source(repo, attr_session, &commit_source)) < 0) + goto out; + } + if (attr_session) attr_session->init_setup = 1; @@ -480,7 +488,7 @@ int git_attr_add_macro( typedef struct { git_repository *repo; git_attr_session *attr_session; - uint32_t flags; + git_attr_options *opts; const char *workdir; git_index *index; git_vector *files; @@ -513,7 +521,8 @@ static int attr_decide_sources( break; } - if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0) + if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0 || + (flags & GIT_ATTR_CHECK_INCLUDE_COMMIT) != 0) srcs[count++] = GIT_ATTR_FILE_SOURCE_COMMIT; return count; @@ -563,13 +572,19 @@ static int push_one_attr(void *ref, const char *path) int error = 0, n_src, i; bool allow_macros; - n_src = attr_decide_sources( - info->flags, info->workdir != NULL, info->index != NULL, src); + n_src = attr_decide_sources(info->opts ? info->opts->flags : 0, + info->workdir != NULL, + info->index != NULL, + src); + allow_macros = info->workdir ? !strcmp(info->workdir, path) : false; for (i = 0; !error && i < n_src; ++i) { git_attr_file_source source = { src[i], path, GIT_ATTR_FILE }; + if (src[i] == GIT_ATTR_FILE_SOURCE_COMMIT && info->opts) + source.commit_id = info->opts->commit_id; + error = push_attr_source(info->repo, info->attr_session, info->files, &source, allow_macros); } @@ -631,7 +646,7 @@ static int collect_attr_files( info.repo = repo; info.attr_session = attr_session; - info.flags = opts ? opts->flags : 0; + info.opts = opts; info.workdir = workdir; if (git_repository_index__weakptr(&info.index, repo) < 0) git_error_clear(); /* no error even if there is no index */ diff --git a/src/attr_file.c b/src/attr_file.c index 3b8965a10b3..f8627381c22 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -113,6 +113,7 @@ int git_attr_file__load( bool allow_macros) { int error = 0; + git_commit *commit = NULL; git_tree *tree = NULL; git_tree_entry *tree_entry = NULL; git_blob *blob = NULL; @@ -163,8 +164,14 @@ int git_attr_file__load( break; } case GIT_ATTR_FILE_SOURCE_COMMIT: { - if ((error = git_repository_head_tree(&tree, repo)) < 0) - goto cleanup; + if (source->commit_id) { + if ((error = git_commit_lookup(&commit, repo, source->commit_id)) < 0 || + (error = git_commit_tree(&tree, commit)) < 0) + goto cleanup; + } else { + if ((error = git_repository_head_tree(&tree, repo)) < 0) + goto cleanup; + } if ((error = git_tree_entry_bypath(&tree_entry, tree, entry->path)) < 0) { /* @@ -239,6 +246,7 @@ int git_attr_file__load( git_blob_free(blob); git_tree_entry_free(tree_entry); git_tree_free(tree); + git_commit_free(commit); git_buf_dispose(&content); return error; @@ -247,7 +255,8 @@ int git_attr_file__load( int git_attr_file__out_of_date( git_repository *repo, git_attr_session *attr_session, - git_attr_file *file) + git_attr_file *file, + git_attr_file_source *source) { if (!file) return 1; @@ -280,13 +289,26 @@ int git_attr_file__out_of_date( } case GIT_ATTR_FILE_SOURCE_COMMIT: { - git_tree *tree; + git_tree *tree = NULL; int error; - if ((error = git_repository_head_tree(&tree, repo)) < 0) + if (source->commit_id) { + git_commit *commit = NULL; + + if ((error = git_commit_lookup(&commit, repo, source->commit_id)) < 0) + return error; + + error = git_commit_tree(&tree, commit); + + git_commit_free(commit); + } else { + error = git_repository_head_tree(&tree, repo); + } + + if (error < 0) return error; - error = git_oid__cmp(&file->cache_data.oid, git_tree_id(tree)); + error = (git_oid__cmp(&file->cache_data.oid, git_tree_id(tree)) != 0); git_tree_free(tree); return error; diff --git a/src/attr_file.h b/src/attr_file.h index 5c8a412910c..16e33caf1e6 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -55,6 +55,12 @@ typedef struct { */ const char *base; const char *filename; + + /* + * The commit ID when the given source type is a commit (or NULL + * for the repository's HEAD commit.) + */ + git_oid *commit_id; } git_attr_file_source; extern const char *git_attr__true; @@ -171,7 +177,7 @@ int git_attr_file__load_standalone( git_attr_file **out, const char *path); int git_attr_file__out_of_date( - git_repository *repo, git_attr_session *session, git_attr_file *file); + git_repository *repo, git_attr_session *session, git_attr_file *file, git_attr_file_source *source); int git_attr_file__parse_buffer( git_repository *repo, git_attr_file *attrs, const char *data, bool allow_macros); diff --git a/src/attrcache.c b/src/attrcache.c index f0771273592..7fe2bfbdb84 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -224,16 +224,17 @@ int git_attr_cache__get( return error; /* load file if we don't have one or if existing one is out of date */ - if (!file || (error = git_attr_file__out_of_date(repo, attr_session, file)) > 0) + if (!file || + (error = git_attr_file__out_of_date(repo, attr_session, file, source)) > 0) error = git_attr_file__load(&updated, repo, attr_session, entry, source, parser, allow_macros); /* if we loaded the file, insert into and/or update cache */ if (updated) { - if ((error = attr_cache_upsert(cache, updated)) < 0) + if ((error = attr_cache_upsert(cache, updated)) < 0) { git_attr_file__free(updated); - else { + } else { git_attr_file__free(file); /* offset incref from lookup */ file = updated; } From 1439b9ff05524949b6b3fa6cad716a9bb3cbc249 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 22 Jul 2021 15:29:54 -0400 Subject: [PATCH 0387/1616] filter: introduce GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT Provide a mechanism to filter using attribute data from a specific commit (making use of `GIT_ATTR_CHECK_INCLUDE_COMMIT`). --- include/git2/blob.h | 12 ++++ include/git2/filter.h | 12 ++++ src/blob.c | 15 +++-- src/filter.c | 5 ++ tests/filter/bare.c | 60 ++++++++++++++++++ .../05/5c8729cdcc372500a08db659c045e16c4409fb | Bin 0 -> 20 bytes .../1e/c507638b806aba45d6142082885f2a9e88322d | Bin 0 -> 170 bytes .../44/b0be18671a284f1156117b6338edac2663341c | Bin 0 -> 658 bytes .../55/1b8fce462bba005ab6d34a2244d8a3f6b03dd0 | Bin 0 -> 658 bytes .../b8/986fec0f7bde90f78ac72706e782d82f24f2f0 | 3 + tests/resources/crlf.git/refs/heads/ident | 1 + tests/resources/crlf.git/refs/heads/no-ident | 1 + 12 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 tests/resources/crlf.git/objects/05/5c8729cdcc372500a08db659c045e16c4409fb create mode 100644 tests/resources/crlf.git/objects/1e/c507638b806aba45d6142082885f2a9e88322d create mode 100644 tests/resources/crlf.git/objects/44/b0be18671a284f1156117b6338edac2663341c create mode 100644 tests/resources/crlf.git/objects/55/1b8fce462bba005ab6d34a2244d8a3f6b03dd0 create mode 100644 tests/resources/crlf.git/objects/b8/986fec0f7bde90f78ac72706e782d82f24f2f0 create mode 100644 tests/resources/crlf.git/refs/heads/ident create mode 100644 tests/resources/crlf.git/refs/heads/no-ident diff --git a/include/git2/blob.h b/include/git2/blob.h index 3f673867504..fceb5c771f1 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -114,6 +114,12 @@ typedef enum { * in the HEAD commit. */ GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD = (1 << 2), + + /** + * When set, filters will be loaded from a `.gitattributes` file + * in the specified commit. + */ + GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT = (1 << 3), } git_blob_filter_flag_t; /** @@ -128,6 +134,12 @@ typedef struct { /** Flags to control the filtering process, see `git_blob_filter_flag_t` above */ uint32_t flags; + + /** + * The commit to load attributes from, when + * `GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT` is specified. + */ + git_oid *commit_id; } git_blob_filter_options; #define GIT_BLOB_FILTER_OPTIONS_VERSION 1 diff --git a/include/git2/filter.h b/include/git2/filter.h index 54581517119..044c3b87060 100644 --- a/include/git2/filter.h +++ b/include/git2/filter.h @@ -49,6 +49,12 @@ typedef enum { /** Load attributes from `.gitattributes` in the root of HEAD */ GIT_FILTER_ATTRIBUTES_FROM_HEAD = (1u << 2), + + /** + * Load attributes from `.gitattributes` in a given commit. + * This can only be specified in a `git_filter_options`. + */ + GIT_FILTER_ATTRIBUTES_FROM_COMMIT = (1u << 3), } git_filter_flag_t; /** @@ -59,6 +65,12 @@ typedef struct { /** See `git_filter_flag_t` above */ uint32_t flags; + + /** + * The commit to load attributes from, when + * `GIT_FILTER_ATTRIBUTES_FROM_COMMIT` is specified. + */ + git_oid *commit_id; } git_filter_options; #define GIT_FILTER_OPTIONS_VERSION 1 diff --git a/src/blob.c b/src/blob.c index 169e3450338..01ebf075e26 100644 --- a/src/blob.c +++ b/src/blob.c @@ -421,7 +421,7 @@ int git_blob_filter( int error = 0; git_filter_list *fl = NULL; git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT; - git_filter_flag_t flags = GIT_FILTER_DEFAULT; + git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT; GIT_ASSERT_ARG(blob); GIT_ASSERT_ARG(path); @@ -441,14 +441,19 @@ int git_blob_filter( return 0; if ((opts.flags & GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES) != 0) - flags |= GIT_FILTER_NO_SYSTEM_ATTRIBUTES; + filter_opts.flags |= GIT_FILTER_NO_SYSTEM_ATTRIBUTES; if ((opts.flags & GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD) != 0) - flags |= GIT_FILTER_ATTRIBUTES_FROM_HEAD; + filter_opts.flags |= GIT_FILTER_ATTRIBUTES_FROM_HEAD; - if (!(error = git_filter_list_load( + if ((opts.flags & GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT) != 0) { + filter_opts.flags |= GIT_FILTER_ATTRIBUTES_FROM_COMMIT; + filter_opts.commit_id = opts.commit_id; + } + + if (!(error = git_filter_list_load_ext( &fl, git_blob_owner(blob), blob, path, - GIT_FILTER_TO_WORKTREE, flags))) { + GIT_FILTER_TO_WORKTREE, &filter_opts))) { error = git_filter_list_apply_to_blob(out, fl, blob); diff --git a/src/filter.c b/src/filter.c index 3309ab71604..eed175e8841 100644 --- a/src/filter.c +++ b/src/filter.c @@ -443,6 +443,11 @@ static int filter_list_check_attributes( if ((src->options.flags & GIT_FILTER_ATTRIBUTES_FROM_HEAD) != 0) attr_opts.flags |= GIT_ATTR_CHECK_INCLUDE_HEAD; + if ((src->options.flags & GIT_FILTER_ATTRIBUTES_FROM_COMMIT) != 0) { + attr_opts.flags |= GIT_ATTR_CHECK_INCLUDE_COMMIT; + attr_opts.commit_id = src->options.commit_id; + } + error = git_attr_get_many_with_session( strs, repo, filter_session->attr_session, &attr_opts, src->path, fdef->nattrs, fdef->attrs); diff --git a/tests/filter/bare.c b/tests/filter/bare.c index 7319b5203a3..f8e34232fad 100644 --- a/tests/filter/bare.c +++ b/tests/filter/bare.c @@ -132,3 +132,63 @@ void test_filter_bare__sanitizes(void) git_blob_free(blob); } +void test_filter_bare__from_specific_commit_one(void) +{ + git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT; + git_blob *blob; + git_buf buf = { 0 }; + git_oid commit_id; + + cl_git_pass(git_oid_fromstr(&commit_id, "b8986fec0f7bde90f78ac72706e782d82f24f2f0")); + + opts.flags |= GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES; + opts.flags |= GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT; + opts.commit_id = &commit_id; + + cl_git_pass(git_revparse_single( + (git_object **)&blob, g_repo, "055c872")); /* ident */ + + cl_assert_equal_s("$Id$\n", git_blob_rawcontent(blob)); + + cl_git_pass(git_blob_filter(&buf, blob, "ident.bin", &opts)); + cl_assert_equal_s("$Id$\n", buf.ptr); + + cl_git_pass(git_blob_filter(&buf, blob, "ident.identlf", &opts)); + cl_assert_equal_s("$Id: 055c8729cdcc372500a08db659c045e16c4409fb $\n", buf.ptr); + + git_buf_dispose(&buf); + git_blob_free(blob); +} + +void test_filter_bare__from_specific_commit_with_no_attributes_file(void) +{ + git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT; + git_blob *blob; + git_buf buf = { 0 }; + git_oid commit_id; + + cl_git_pass(git_oid_fromstr(&commit_id, "5afb6a14a864e30787857dd92af837e8cdd2cb1b")); + + opts.flags |= GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES; + opts.flags |= GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT; + opts.commit_id = &commit_id; + + cl_git_pass(git_revparse_single( + (git_object **)&blob, g_repo, "799770d")); /* all-lf */ + + cl_assert_equal_s(ALL_LF_TEXT_RAW, git_blob_rawcontent(blob)); + + cl_git_pass(git_blob_filter(&buf, blob, "file.bin", &opts)); + cl_assert_equal_s(ALL_LF_TEXT_RAW, buf.ptr); + + /* we never convert CRLF -> LF on platforms that have LF */ + cl_git_pass(git_blob_filter(&buf, blob, "file.lf", &opts)); + cl_assert_equal_s(ALL_LF_TEXT_RAW, buf.ptr); + + /* we never convert CRLF -> LF on platforms that have LF */ + cl_git_pass(git_blob_filter(&buf, blob, "file.crlf", &opts)); + cl_assert_equal_s(ALL_LF_TEXT_RAW, buf.ptr); + + git_buf_dispose(&buf); + git_blob_free(blob); +} diff --git a/tests/resources/crlf.git/objects/05/5c8729cdcc372500a08db659c045e16c4409fb b/tests/resources/crlf.git/objects/05/5c8729cdcc372500a08db659c045e16c4409fb new file mode 100644 index 0000000000000000000000000000000000000000..44076ca3930681dc127b6498246621552d70a566 GIT binary patch literal 20 bcmbt+C8bZI0KHKtO$=+Dr$TT!Hx}_y)7D@TJ z3|!0e+ zuy5m+tsO__yvC^-5?HG~G_O1zeCu%9-17^bbSg&hCe1qz)smK44)&XFazEYff0XtrpUMFL4)g5>zqkeO{hNtH zJ<$4DIi|+{KF->k_ogpVAv-2;hIYeEm};azyC_%p&3gH5+07ew&bht*XjQA{k0qGO zAl`Q@Z~J4q`MA_lx5q!@w%)SoUEAXbQ=4Cu3Q@%Wb*a7N{!3fmE!-8#H1$ZSXnJQm zx*~X@dBx0Ylk-MVA@j|$8K-tF-4e<#Du}EY=ns~A44Wf98h1`<4=YxTc(v;NLYE#? zC2-U3bUfZEey>SRb(;38x`SV1d>#qvm>2+oLQ!Hl!-IW2{7ce5EDiB+c0Z`WR5>?? st+C8bZI0KHKtO$=+Dr$TT!Hx}_y)7D@TJ z3|!0e+ zuy5m+tsO__yvC^-5?HG~G_O1zeCu%9-17^bbSg&hCe1qz)smK44)&XFazEYff0XtrpUMFL4)g5>zqkeO{hNtH zJ<$4DIi|+{KF->k_ogpVAv-2;hIYeEm};azyC_%p&3gH5+07ew&bht*XjQA{k0qGO zAl`Q@Z~J4q`MA_lx5q!@w%)SoUEAXbQ=4Cu3Q@%Wb*a7N{!3fmE!-8#H1$ZSXnJQm zx*~X@dBx0Ylk-MVA@j|$8K-tF-4e<#Du}EY=ns~A44Wf98h1`<4=YxTc(v;NLYE#? zC2-U3bUfZEey>SRb(;38x`SV1d>#qvm>2+oLQ!Hl!-IW2{7ce5EDiB+c0Z`WR5>?? s Date: Thu, 22 Jul 2021 16:50:26 -0400 Subject: [PATCH 0388/1616] trace: drop unnecessary write indirection --- src/trace.h | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/trace.h b/src/trace.h index 88d660d490a..a233aa2257c 100644 --- a/src/trace.h +++ b/src/trace.h @@ -21,9 +21,10 @@ struct git_trace_data { extern struct git_trace_data git_trace__data; -GIT_INLINE(void) git_trace__vwrite_fmt( +GIT_INLINE(void) git_trace__write_fmt( git_trace_level_t level, - const char *fmt, va_list ap) + const char *fmt, + va_list ap) { git_trace_cb callback = git_trace__data.callback; git_buf message = GIT_BUF_INIT; @@ -35,29 +36,20 @@ GIT_INLINE(void) git_trace__vwrite_fmt( git_buf_dispose(&message); } -GIT_INLINE(void) git_trace__write_fmt( - git_trace_level_t level, - const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - git_trace__vwrite_fmt(level, fmt, ap); - va_end(ap); -} +#define git_trace_level() (git_trace__data.level) -#define git_trace_level() (git_trace__data.level) GIT_INLINE(void) git_trace(git_trace_level_t level, const char *fmt, ...) { if (git_trace__data.level >= level && - git_trace__data.callback != NULL) { + git_trace__data.callback != NULL) { va_list ap; va_start(ap, fmt); - git_trace__vwrite_fmt(level, fmt, ap); + git_trace__write_fmt(level, fmt, ap); va_end(ap); } } + #else GIT_INLINE(void) git_trace__null( @@ -68,8 +60,8 @@ GIT_INLINE(void) git_trace__null( GIT_UNUSED(fmt); } -#define git_trace_level() ((git_trace_level_t)0) -#define git_trace git_trace__null +#define git_trace_level() ((git_trace_level_t)0) +#define git_trace git_trace__null #endif From 88a3b8e1c863cea01a625a6f41205a306c2cccd2 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Mon, 26 Jul 2021 23:12:12 +0200 Subject: [PATCH 0389/1616] common.h: use inline when compiling for c99 and later --- src/common.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common.h b/src/common.h index 9123fb595b3..f83eeb69e72 100644 --- a/src/common.h +++ b/src/common.h @@ -19,6 +19,8 @@ # define GIT_INLINE(type) static __inline type #elif defined(__GNUC__) # define GIT_INLINE(type) static __inline__ type +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define GIT_INLINE(type) static inline type #else # define GIT_INLINE(type) static type #endif From 6f544140a097002fe5f15e43a4d3215c944140b7 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 5 Jan 2021 19:45:23 -0800 Subject: [PATCH 0390/1616] commit-graph: Introduce `git_commit_list_generation_cmp` This change makes calculations of merge-bases a bit faster when there are complex graphs and the commit times cause visiting nodes multiple times. This is done by visiting the nodes in the graph in reverse generation order when the generation number is available instead of commit timestamp. If the generation number is missing in any pair of commits, it can safely fall back to the old heuristic with no negative side-effects. Part of: #5757 --- src/commit_list.c | 18 ++++++++++++++++++ src/commit_list.h | 1 + src/graph.c | 2 +- src/merge.c | 2 +- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/commit_list.c b/src/commit_list.c index 11cc2e7d2e5..692b1495f51 100644 --- a/src/commit_list.c +++ b/src/commit_list.c @@ -12,6 +12,24 @@ #include "odb.h" #include "commit.h" +int git_commit_list_generation_cmp(const void *a, const void *b) +{ + uint32_t generation_a = ((git_commit_list_node *) a)->generation; + uint32_t generation_b = ((git_commit_list_node *) b)->generation; + + if (!generation_a || !generation_b) { + /* Fall back to comparing by timestamps if at least one commit lacks a generation. */ + return git_commit_list_time_cmp(a, b); + } + + if (generation_a < generation_b) + return 1; + if (generation_a > generation_b) + return -1; + + return 0; +} + int git_commit_list_time_cmp(const void *a, const void *b) { int64_t time_a = ((git_commit_list_node *) a)->time; diff --git a/src/commit_list.h b/src/commit_list.h index a3237703014..aad39f3513b 100644 --- a/src/commit_list.h +++ b/src/commit_list.h @@ -46,6 +46,7 @@ typedef struct git_commit_list { } git_commit_list; git_commit_list_node *git_commit_list_alloc_node(git_revwalk *walk); +int git_commit_list_generation_cmp(const void *a, const void *b); int git_commit_list_time_cmp(const void *a, const void *b); void git_commit_list_free(git_commit_list **list_p); git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p); diff --git a/src/graph.c b/src/graph.c index df82f0f713d..45fae847ec1 100644 --- a/src/graph.c +++ b/src/graph.c @@ -43,7 +43,7 @@ static int mark_parents(git_revwalk *walk, git_commit_list_node *one, return 0; } - if (git_pqueue_init(&list, 0, 2, git_commit_list_time_cmp) < 0) + if (git_pqueue_init(&list, 0, 2, git_commit_list_generation_cmp) < 0) return -1; if (git_commit_list_parse(walk, one) < 0) diff --git a/src/merge.c b/src/merge.c index c29b40e2367..fe450b0e707 100644 --- a/src/merge.c +++ b/src/merge.c @@ -387,7 +387,7 @@ static int paint_down_to_common( int error; unsigned int i; - if (git_pqueue_init(&list, 0, twos->length * 2, git_commit_list_time_cmp) < 0) + if (git_pqueue_init(&list, 0, twos->length * 2, git_commit_list_generation_cmp) < 0) return -1; one->flags |= PARENT1; From fff209c400dc054aa05575aa726fd0f03de788c5 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Mon, 17 Feb 2020 21:28:13 +0000 Subject: [PATCH 0391/1616] midx: Add a way to write multi-pack-index files This change adds the git_midx_writer_* functions to allow to write and create `multi-pack-index` files from `.idx`/`.pack` files. Part of: #5399 --- include/git2/sys/midx.h | 74 ++++++++ include/git2/types.h | 3 + src/midx.c | 396 ++++++++++++++++++++++++++++++++++++++++ src/midx.h | 16 ++ src/pack.c | 66 +++++++ src/pack.h | 16 ++ tests/pack/midx.c | 30 +++ 7 files changed, 601 insertions(+) create mode 100644 include/git2/sys/midx.h diff --git a/include/git2/sys/midx.h b/include/git2/sys/midx.h new file mode 100644 index 00000000000..e3d7498298c --- /dev/null +++ b/include/git2/sys/midx.h @@ -0,0 +1,74 @@ +/* + * 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_sys_git_midx_h__ +#define INCLUDE_sys_git_midx_h__ + +#include "git2/common.h" +#include "git2/types.h" + +/** + * @file git2/midx.h + * @brief Git multi-pack-index routines + * @defgroup git_midx Git multi-pack-index routines + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Create a new writer for `multi-pack-index` files. + * + * @param out location to store the writer pointer. + * @param pack_dir the directory where the `.pack` and `.idx` files are. The + * `multi-pack-index` file will be written in this directory, too. + * @return 0 or an error code + */ +GIT_EXTERN(int) git_midx_writer_new( + git_midx_writer **out, + const char *pack_dir); + +/** + * Free the multi-pack-index writer and its resources. + * + * @param w the writer to free. If NULL no action is taken. + */ +GIT_EXTERN(void) git_midx_writer_free(git_midx_writer *w); + +/** + * Add an `.idx` file to the writer. + * + * @param w the writer + * @param idx_path the path of an `.idx` file. + * @return 0 or an error code + */ +GIT_EXTERN(int) git_midx_writer_add( + git_midx_writer *w, + const char *idx_path); + +/** + * Write a `multi-pack-index` file to a file. + * + * @param w the writer + * @return 0 or an error code + */ +GIT_EXTERN(int) git_midx_writer_commit( + git_midx_writer *w); + +/** + * Dump the contents of the `multi-pack-index` to an in-memory buffer. + * + * @param midx Buffer where to store the contents of the `multi-pack-index`. + * @param w the writer + * @return 0 or an error code + */ +GIT_EXTERN(int) git_midx_writer_dump( + git_buf *midx, + git_midx_writer *w); + +/** @} */ +GIT_END_DECL +#endif diff --git a/include/git2/types.h b/include/git2/types.h index 562eb8e5f25..4de0672f9e8 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -96,6 +96,9 @@ typedef struct git_odb_stream git_odb_stream; /** A stream to write a packfile to the ODB */ typedef struct git_odb_writepack git_odb_writepack; +/** a writer for multi-pack-index files. */ +typedef struct git_midx_writer git_midx_writer; + /** An open refs database handle. */ typedef struct git_refdb git_refdb; diff --git a/src/midx.c b/src/midx.c index d6bb9c1e7f1..040a43fc452 100644 --- a/src/midx.c +++ b/src/midx.c @@ -7,11 +7,15 @@ #include "midx.h" +#include "array.h" #include "buffer.h" +#include "filebuf.h" #include "futils.h" #include "hash.h" #include "odb.h" #include "pack.h" +#include "path.h" +#include "repository.h" #define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */ #define MIDX_VERSION 1 @@ -36,6 +40,8 @@ struct git_midx_chunk { size_t length; }; +typedef int (*midx_write_cb)(const char *buf, size_t size, void *cb_data); + static int midx_error(const char *message) { git_error_set(GIT_ERROR_ODB, "invalid multi-pack-index file - %s", message); @@ -475,3 +481,393 @@ void git_midx_free(git_midx_file *idx) git_midx_close(idx); git__free(idx); } + +static int packfile__cmp(const void *a_, const void *b_) +{ + const struct git_pack_file *a = a_; + const struct git_pack_file *b = b_; + + return strcmp(a->pack_name, b->pack_name); +} + +int git_midx_writer_new( + git_midx_writer **out, + const char *pack_dir) +{ + git_midx_writer *w = git__calloc(1, sizeof(git_midx_writer)); + GIT_ERROR_CHECK_ALLOC(w); + + if (git_buf_sets(&w->pack_dir, pack_dir) < 0) { + git__free(w); + return -1; + } + git_path_squash_slashes(&w->pack_dir); + + if (git_vector_init(&w->packs, 0, packfile__cmp) < 0) { + git_buf_dispose(&w->pack_dir); + git__free(w); + return -1; + } + + *out = w; + return 0; +} + +void git_midx_writer_free(git_midx_writer *w) +{ + struct git_pack_file *p; + size_t i; + + if (!w) + return; + + git_vector_foreach (&w->packs, i, p) + git_mwindow_put_pack(p); + git_vector_free(&w->packs); + git_buf_dispose(&w->pack_dir); + git__free(w); +} + +int git_midx_writer_add( + git_midx_writer *w, + const char *idx_path) +{ + git_buf idx_path_buf = GIT_BUF_INIT; + int error; + struct git_pack_file *p; + + error = git_path_prettify(&idx_path_buf, idx_path, git_buf_cstr(&w->pack_dir)); + if (error < 0) + return error; + + error = git_mwindow_get_pack(&p, git_buf_cstr(&idx_path_buf)); + git_buf_dispose(&idx_path_buf); + if (error < 0) + return error; + + error = git_vector_insert(&w->packs, p); + if (error < 0) { + git_mwindow_put_pack(p); + return error; + } + + return 0; +} + +typedef git_array_t(git_midx_entry) object_entry_array_t; + +struct object_entry_cb_state { + uint32_t pack_index; + object_entry_array_t *object_entries_array; +}; + +static int object_entry__cb(const git_oid *oid, off64_t offset, void *data) +{ + struct object_entry_cb_state *state = (struct object_entry_cb_state *)data; + + git_midx_entry *entry = git_array_alloc(*state->object_entries_array); + GIT_ERROR_CHECK_ALLOC(entry); + + git_oid_cpy(&entry->sha1, oid); + entry->offset = offset; + entry->pack_index = state->pack_index; + + return 0; +} + +static int object_entry__cmp(const void *a_, const void *b_) +{ + const git_midx_entry *a = (const git_midx_entry *)a_; + const git_midx_entry *b = (const git_midx_entry *)b_; + + return git_oid_cmp(&a->sha1, &b->sha1); +} + +static int write_offset(off64_t offset, midx_write_cb write_cb, void *cb_data) +{ + int error; + uint32_t word; + + word = htonl((uint32_t)((offset >> 32) & 0xffffffffu)); + error = write_cb((const char *)&word, sizeof(word), cb_data); + if (error < 0) + return error; + word = htonl((uint32_t)((offset >> 0) & 0xffffffffu)); + error = write_cb((const char *)&word, sizeof(word), cb_data); + if (error < 0) + return error; + + return 0; +} + +static int write_chunk_header(int chunk_id, off64_t offset, midx_write_cb write_cb, void *cb_data) +{ + uint32_t word = htonl(chunk_id); + int error = write_cb((const char *)&word, sizeof(word), cb_data); + if (error < 0) + return error; + return write_offset(offset, write_cb, cb_data); + + return 0; +} + +static int midx_write_buf(const char *buf, size_t size, void *data) +{ + git_buf *b = (git_buf *)data; + return git_buf_put(b, buf, size); +} + +struct midx_write_hash_context { + midx_write_cb write_cb; + void *cb_data; + git_hash_ctx *ctx; +}; + +static int midx_write_hash(const char *buf, size_t size, void *data) +{ + struct midx_write_hash_context *ctx = (struct midx_write_hash_context *)data; + int error; + + error = git_hash_update(ctx->ctx, buf, size); + if (error < 0) + return error; + + return ctx->write_cb(buf, size, ctx->cb_data); +} + +static int midx_write( + git_midx_writer *w, + midx_write_cb write_cb, + void *cb_data) +{ + int error = 0; + size_t i; + struct git_pack_file *p; + struct git_midx_header hdr = { + .signature = htonl(MIDX_SIGNATURE), + .version = MIDX_VERSION, + .object_id_version = MIDX_OBJECT_ID_VERSION, + .base_midx_files = 0, + }; + uint32_t oid_fanout_count; + uint32_t object_large_offsets_count; + uint32_t oid_fanout[256]; + off64_t offset; + git_buf packfile_names = GIT_BUF_INIT, + oid_lookup = GIT_BUF_INIT, + object_offsets = GIT_BUF_INIT, + object_large_offsets = GIT_BUF_INIT; + git_oid idx_checksum = {{0}}; + git_midx_entry *entry; + object_entry_array_t object_entries_array = GIT_ARRAY_INIT; + git_vector object_entries = GIT_VECTOR_INIT; + git_hash_ctx ctx; + struct midx_write_hash_context hash_cb_data = { + .write_cb = write_cb, + .cb_data = cb_data, + .ctx = &ctx, + }; + + error = git_hash_ctx_init(&ctx); + if (error < 0) + return error; + cb_data = &hash_cb_data; + write_cb = midx_write_hash; + + git_vector_sort(&w->packs); + git_vector_foreach (&w->packs, i, p) { + git_buf relative_index = GIT_BUF_INIT; + struct object_entry_cb_state state = { + .pack_index = (uint32_t)i, + .object_entries_array = &object_entries_array, + }; + size_t path_len; + + error = git_buf_sets(&relative_index, p->pack_name); + if (error < 0) + goto cleanup; + error = git_path_make_relative(&relative_index, git_buf_cstr(&w->pack_dir)); + if (error < 0) { + git_buf_dispose(&relative_index); + goto cleanup; + } + path_len = git_buf_len(&relative_index); + if (path_len <= strlen(".pack") || git__suffixcmp(git_buf_cstr(&relative_index), ".pack") != 0) { + git_buf_dispose(&relative_index); + goto cleanup; + } + path_len -= strlen(".pack"); + + git_buf_put(&packfile_names, git_buf_cstr(&relative_index), path_len); + git_buf_puts(&packfile_names, ".idx"); + git_buf_putc(&packfile_names, '\0'); + git_buf_dispose(&relative_index); + + error = git_pack_foreach_entry_offset(p, object_entry__cb, &state); + if (error < 0) + goto cleanup; + } + + /* Sort the object entries. */ + error = git_vector_init(&object_entries, git_array_size(object_entries_array), object_entry__cmp); + if (error < 0) + goto cleanup; + git_array_foreach (object_entries_array, i, entry) + error = git_vector_set(NULL, &object_entries, i, entry); + git_vector_set_sorted(&object_entries, 0); + git_vector_sort(&object_entries); + git_vector_uniq(&object_entries, NULL); + + /* Pad the packfile names so it is a multiple of four. */ + while (git_buf_len(&packfile_names) & 3) + git_buf_putc(&packfile_names, '\0'); + + /* Fill the OID Fanout table. */ + oid_fanout_count = 0; + for (i = 0; i < 256; i++) { + while (oid_fanout_count < git_vector_length(&object_entries) && + ((const git_midx_entry *)git_vector_get(&object_entries, oid_fanout_count))->sha1.id[0] <= i) + ++oid_fanout_count; + oid_fanout[i] = htonl(oid_fanout_count); + } + + /* Fill the OID Lookup table. */ + git_vector_foreach (&object_entries, i, entry) { + error = git_buf_put(&oid_lookup, (const char *)&entry->sha1, sizeof(entry->sha1)); + if (error < 0) + goto cleanup; + } + + /* Fill the Object Offsets and Object Large Offsets tables. */ + object_large_offsets_count = 0; + git_vector_foreach (&object_entries, i, entry) { + uint32_t word; + + word = htonl((uint32_t)entry->pack_index); + error = git_buf_put(&object_offsets, (const char *)&word, sizeof(word)); + if (error < 0) + goto cleanup; + if (entry->offset >= 0x80000000l) { + word = htonl(0x80000000u | object_large_offsets_count++); + error = write_offset(entry->offset, midx_write_buf, &object_large_offsets); + } else { + word = htonl((uint32_t)entry->offset & 0x7fffffffu); + } + error = git_buf_put(&object_offsets, (const char *)&word, sizeof(word)); + if (error < 0) + goto cleanup; + } + + /* Write the header. */ + hdr.packfiles = htonl((uint32_t)git_vector_length(&w->packs)); + hdr.chunks = 4; + if (git_buf_len(&object_large_offsets) > 0) + hdr.chunks++; + error = write_cb((const char *)&hdr, sizeof(hdr), cb_data); + if (error < 0) + goto cleanup; + + /* Write the chunk headers. */ + offset = sizeof(hdr) + (hdr.chunks + 1) * 12; + error = write_chunk_header(MIDX_PACKFILE_NAMES_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += git_buf_len(&packfile_names); + error = write_chunk_header(MIDX_OID_FANOUT_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += sizeof(oid_fanout); + error = write_chunk_header(MIDX_OID_LOOKUP_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += git_buf_len(&oid_lookup); + error = write_chunk_header(MIDX_OBJECT_OFFSETS_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += git_buf_len(&object_offsets); + if (git_buf_len(&object_large_offsets) > 0) { + error = write_chunk_header(MIDX_OBJECT_LARGE_OFFSETS_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += git_buf_len(&object_large_offsets); + } + error = write_chunk_header(0, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + + /* Write all the chunks. */ + error = write_cb(git_buf_cstr(&packfile_names), git_buf_len(&packfile_names), cb_data); + if (error < 0) + goto cleanup; + error = write_cb((const char *)oid_fanout, sizeof(oid_fanout), cb_data); + if (error < 0) + goto cleanup; + error = write_cb(git_buf_cstr(&oid_lookup), git_buf_len(&oid_lookup), cb_data); + if (error < 0) + goto cleanup; + error = write_cb(git_buf_cstr(&object_offsets), git_buf_len(&object_offsets), cb_data); + if (error < 0) + goto cleanup; + error = write_cb(git_buf_cstr(&object_large_offsets), git_buf_len(&object_large_offsets), cb_data); + if (error < 0) + goto cleanup; + + /* Finalize the checksum and write the trailer. */ + error = git_hash_final(&idx_checksum, &ctx); + if (error < 0) + goto cleanup; + error = write_cb((const char *)&idx_checksum, sizeof(idx_checksum), cb_data); + if (error < 0) + goto cleanup; + +cleanup: + git_array_clear(object_entries_array); + git_vector_free(&object_entries); + git_buf_dispose(&packfile_names); + git_buf_dispose(&oid_lookup); + git_buf_dispose(&object_offsets); + git_buf_dispose(&object_large_offsets); + git_hash_ctx_cleanup(&ctx); + return error; +} + +static int midx_write_filebuf(const char *buf, size_t size, void *data) +{ + git_filebuf *f = (git_filebuf *)data; + return git_filebuf_write(f, buf, size); +} + +int git_midx_writer_commit( + git_midx_writer *w) +{ + int error; + int filebuf_flags = GIT_FILEBUF_DO_NOT_BUFFER; + git_buf midx_path = GIT_BUF_INIT; + git_filebuf output = GIT_FILEBUF_INIT; + + error = git_buf_joinpath(&midx_path, git_buf_cstr(&w->pack_dir), "multi-pack-index"); + if (error < 0) + return error; + + if (git_repository__fsync_gitdir) + filebuf_flags |= GIT_FILEBUF_FSYNC; + error = git_filebuf_open(&output, git_buf_cstr(&midx_path), filebuf_flags, 0644); + git_buf_dispose(&midx_path); + if (error < 0) + return error; + + error = midx_write(w, midx_write_filebuf, &output); + if (error < 0) { + git_filebuf_cleanup(&output); + return error; + } + + return git_filebuf_commit(&output); +} + +int git_midx_writer_dump( + git_buf *midx, + git_midx_writer *w) +{ + return midx_write(w, midx_write_buf, midx); +} diff --git a/src/midx.h b/src/midx.h index 543ff2178df..4ce17ce73a8 100644 --- a/src/midx.h +++ b/src/midx.h @@ -12,6 +12,8 @@ #include +#include "git2/sys/midx.h" + #include "map.h" #include "mwindow.h" #include "odb.h" @@ -67,6 +69,20 @@ typedef struct git_midx_entry { git_oid sha1; } git_midx_entry; +/* + * A writer for `multi-pack-index` files. + */ +struct git_midx_writer { + /* + * The path of the directory where the .pack/.idx files are stored. The + * `multi-pack-index` file will be written to the same directory. + */ + git_buf pack_dir; + + /* The list of `git_pack_file`s. */ + git_vector packs; +}; + int git_midx_open( git_midx_file **idx_out, const char *path); diff --git a/src/pack.c b/src/pack.c index 5d284ca9e12..31a4282b5dd 100644 --- a/src/pack.c +++ b/src/pack.c @@ -1368,6 +1368,72 @@ int git_pack_foreach_entry( return error; } +int git_pack_foreach_entry_offset( + struct git_pack_file *p, + git_pack_foreach_entry_offset_cb cb, + void *data) +{ + const unsigned char *index; + off64_t current_offset; + const git_oid *current_oid; + uint32_t i; + int error = 0; + + if (git_mutex_lock(&p->lock) < 0) + return packfile_error("failed to get lock for git_pack_foreach_entry_offset"); + + index = p->index_map.data; + if (index == NULL) { + if ((error = pack_index_open_locked(p)) < 0) + goto cleanup; + + GIT_ASSERT(p->index_map.data); + index = p->index_map.data; + } + + if (p->index_version > 1) + index += 8; + + index += 4 * 256; + + if (p->index_version > 1) { + const unsigned char *offsets = index + 24 * p->num_objects; + const unsigned char *large_offset_ptr; + const unsigned char *large_offsets = index + 28 * p->num_objects; + const unsigned char *large_offsets_end = ((const unsigned char *)p->index_map.data) + p->index_map.len - 20; + for (i = 0; i < p->num_objects; i++) { + current_offset = ntohl(*(const uint32_t *)(offsets + 4 * i)); + if (current_offset & 0x80000000) { + large_offset_ptr = large_offsets + (current_offset & 0x7fffffff) * 8; + if (large_offset_ptr >= large_offsets_end) { + error = -1; + goto cleanup; + } + current_offset = (((off64_t)ntohl(*((uint32_t *)(large_offset_ptr + 0)))) << 32) | + ntohl(*((uint32_t *)(large_offset_ptr + 4))); + } + current_oid = (const git_oid *)(index + 20 * i); + if ((error = cb(current_oid, current_offset, data)) != 0) { + error = git_error_set_after_callback(error); + goto cleanup; + } + } + } else { + for (i = 0; i < p->num_objects; i++) { + current_offset = ntohl(*(const uint32_t *)(index + 24 * i)); + current_oid = (const git_oid *)(index + 24 * i + 4); + if ((error = cb(current_oid, current_offset, data)) != 0) { + error = git_error_set_after_callback(error); + goto cleanup; + } + } + } + +cleanup: + git_mutex_unlock(&p->lock); + return error; +} + int git_pack__lookup_sha1(const void *oid_lookup_table, size_t stride, unsigned lo, unsigned hi, const unsigned char *oid_prefix) { diff --git a/src/pack.h b/src/pack.h index 1d077240d01..8aea7d8f9c6 100644 --- a/src/pack.h +++ b/src/pack.h @@ -20,6 +20,14 @@ #include "oidmap.h" #include "zstream.h" +/** + * Function type for callbacks from git_pack_foreach_entry_offset. + */ +typedef int GIT_CALLBACK(git_pack_foreach_entry_offset_cb)( + const git_oid *id, + off64_t offset, + void *payload); + #define GIT_PACK_FILE_MODE 0444 #define PACK_SIGNATURE 0x5041434b /* "PACK" */ @@ -176,5 +184,13 @@ int git_pack_foreach_entry( struct git_pack_file *p, git_odb_foreach_cb cb, void *data); +/** + * Similar to git_pack_foreach_entry, but it also provides the offset of the + * object within the packfile. It also does not sort the objects in any order. + */ +int git_pack_foreach_entry_offset( + struct git_pack_file *p, + git_pack_foreach_entry_offset_cb cb, + void *data); #endif diff --git a/tests/pack/midx.c b/tests/pack/midx.c index 0d7efbef10b..6e6c1a6d502 100644 --- a/tests/pack/midx.c +++ b/tests/pack/midx.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include +#include #include "midx.h" @@ -44,3 +45,32 @@ void test_pack_midx__lookup(void) git_commit_free(commit); git_repository_free(repo); } + +void test_pack_midx__writer(void) +{ + git_repository *repo; + git_midx_writer *w = NULL; + git_buf midx = GIT_BUF_INIT, expected_midx = GIT_BUF_INIT, path = GIT_BUF_INIT; + + cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); + + cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/pack")); + cl_git_pass(git_midx_writer_new(&w, git_buf_cstr(&path))); + + cl_git_pass(git_midx_writer_add(w, "pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx")); + cl_git_pass(git_midx_writer_add(w, "pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx")); + cl_git_pass(git_midx_writer_add(w, "pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx")); + + cl_git_pass(git_midx_writer_dump(&midx, w)); + cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/pack/multi-pack-index")); + cl_git_pass(git_futils_readbuffer(&expected_midx, git_buf_cstr(&path))); + + cl_assert_equal_i(git_buf_len(&midx), git_buf_len(&expected_midx)); + cl_assert_equal_strn(git_buf_cstr(&midx), git_buf_cstr(&expected_midx), git_buf_len(&midx)); + + git_buf_dispose(&midx); + git_buf_dispose(&expected_midx); + git_buf_dispose(&path); + git_midx_writer_free(w); + git_repository_free(repo); +} From ce5400cdc7cc52ace295a9fbd3cd7a6e7c63be34 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Wed, 6 Jan 2021 06:26:09 -0800 Subject: [PATCH 0392/1616] graph: Create `git_graph_reachable_from_any()` This change introduces a new API function `git_graph_reachable_from_any()`, that answers the question whether a commit is reachable from any of the provided commits through following parent edges. This function can take advantage of optimizations provided by the existence of a `commit-graph` file, since it makes it faster to know whether, given two commits X and Y, X cannot possibly be an reachable from Y. Part of: #5757 --- include/git2/graph.h | 22 ++- src/graph.c | 71 ++++++++-- src/merge.c | 28 ++-- src/merge.h | 3 +- tests/graph/reachable_from_any.c | 236 +++++++++++++++++++++++++++++++ 5 files changed, 340 insertions(+), 20 deletions(-) create mode 100644 tests/graph/reachable_from_any.c diff --git a/include/git2/graph.h b/include/git2/graph.h index 213ae977757..cd4897fef86 100644 --- a/include/git2/graph.h +++ b/include/git2/graph.h @@ -43,8 +43,9 @@ GIT_EXTERN(int) git_graph_ahead_behind(size_t *ahead, size_t *behind, git_reposi * Note that a commit is not considered a descendant of itself, in contrast * to `git merge-base --is-ancestor`. * - * @param commit a previously loaded commit. - * @param ancestor a potential ancestor commit. + * @param repo the repository where the commits exist + * @param commit a previously loaded commit + * @param ancestor a potential ancestor commit * @return 1 if the given commit is a descendant of the potential ancestor, * 0 if not, error code otherwise. */ @@ -53,6 +54,23 @@ GIT_EXTERN(int) git_graph_descendant_of( const git_oid *commit, const git_oid *ancestor); +/** + * Determine if a commit is reachable from any of a list of commits by + * following parent edges. + * + * @param repo the repository where the commits exist + * @param commit a previously loaded commit + * @param length the number of commits in the provided `descendant_array` + * @param descendant_array oids of the commits + * @return 1 if the given commit is an ancestor of any of the given potential + * descendants, 0 if not, error code otherwise. + */ +GIT_EXTERN(int) git_graph_reachable_from_any( + git_repository *repo, + const git_oid *commit, + size_t length, + const git_oid descendant_array[]); + /** @} */ GIT_END_DECL #endif diff --git a/src/graph.c b/src/graph.c index 45fae847ec1..6efeb4a5323 100644 --- a/src/graph.c +++ b/src/graph.c @@ -176,19 +176,74 @@ int git_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo, int git_graph_descendant_of(git_repository *repo, const git_oid *commit, const git_oid *ancestor) { - git_oid merge_base; - int error; - if (git_oid_equal(commit, ancestor)) return 0; - error = git_merge_base(&merge_base, repo, commit, ancestor); - /* No merge-base found, it's not a descendant */ - if (error == GIT_ENOTFOUND) + return git_graph_reachable_from_any(repo, ancestor, 1, commit); +} + +int git_graph_reachable_from_any( + git_repository *repo, + const git_oid *commit_id, + size_t length, + const git_oid descendant_array[]) +{ + git_revwalk *walk = NULL; + git_vector list; + git_commit_list *result = NULL; + git_commit_list_node *commit; + size_t i; + uint32_t minimum_generation = 0xffffffff; + int error = 0; + + if (!length) return 0; - if (error < 0) + for (i = 0; i < length; ++i) { + if (git_oid_equal(commit_id, &descendant_array[i])) + return 1; + } + + if ((error = git_vector_init(&list, length + 1, NULL)) < 0) return error; - return git_oid_equal(&merge_base, ancestor); + if ((error = git_revwalk_new(&walk, repo)) < 0) + goto done; + + for (i = 0; i < length; i++) { + commit = git_revwalk__commit_lookup(walk, &descendant_array[i]); + if (commit == NULL) { + error = -1; + goto done; + } + + git_vector_insert(&list, commit); + if (minimum_generation > commit->generation) + minimum_generation = commit->generation; + } + + commit = git_revwalk__commit_lookup(walk, commit_id); + if (commit == NULL) { + error = -1; + goto done; + } + + if (minimum_generation > commit->generation) + minimum_generation = commit->generation; + + if ((error = git_merge__bases_many(&result, walk, commit, &list, minimum_generation)) < 0) + goto done; + + if (result) { + error = git_oid_equal(commit_id, &result->item->oid); + } else { + /* No merge-base found, it's not a descendant */ + error = 0; + } + +done: + git_commit_list_free(&result); + git_vector_free(&list); + git_revwalk_free(walk); + return error; } diff --git a/src/merge.c b/src/merge.c index fe450b0e707..0e4bb582a35 100644 --- a/src/merge.c +++ b/src/merge.c @@ -112,7 +112,7 @@ static int merge_bases_many(git_commit_list **out, git_revwalk **walk_out, git_r if (commit == NULL) goto on_error; - if (git_merge__bases_many(&result, walk, commit, &list) < 0) + if (git_merge__bases_many(&result, walk, commit, &list, 0) < 0) goto on_error; if (!result) { @@ -243,7 +243,7 @@ static int merge_bases(git_commit_list **out, git_revwalk **walk_out, git_reposi if (commit == NULL) goto on_error; - if (git_merge__bases_many(&result, walk, commit, &list) < 0) + if (git_merge__bases_many(&result, walk, commit, &list, 0) < 0) goto on_error; if (!result) { @@ -378,7 +378,11 @@ static int clear_commit_marks(git_commit_list_node *commit, unsigned int mark) } static int paint_down_to_common( - git_commit_list **out, git_revwalk *walk, git_commit_list_node *one, git_vector *twos) + git_commit_list **out, + git_revwalk *walk, + git_commit_list_node *one, + git_vector *twos, + uint32_t minimum_generation) { git_pqueue list; git_commit_list *result = NULL; @@ -399,7 +403,6 @@ static int paint_down_to_common( return -1; two->flags |= PARENT2; - if (git_pqueue_insert(&list, two) < 0) return -1; } @@ -427,6 +430,8 @@ static int paint_down_to_common( git_commit_list_node *p = commit->parents[i]; if ((p->flags & flags) == flags) continue; + if (p->generation < minimum_generation) + continue; if ((error = git_commit_list_parse(walk, p)) < 0) return error; @@ -442,7 +447,7 @@ static int paint_down_to_common( return 0; } -static int remove_redundant(git_revwalk *walk, git_vector *commits) +static int remove_redundant(git_revwalk *walk, git_vector *commits, uint32_t minimum_generation) { git_vector work = GIT_VECTOR_INIT; unsigned char *redundant; @@ -478,7 +483,7 @@ static int remove_redundant(git_revwalk *walk, git_vector *commits) goto done; } - error = paint_down_to_common(&common, walk, commit, &work); + error = paint_down_to_common(&common, walk, commit, &work, minimum_generation); if (error < 0) goto done; @@ -510,7 +515,12 @@ static int remove_redundant(git_revwalk *walk, git_vector *commits) return error; } -int git_merge__bases_many(git_commit_list **out, git_revwalk *walk, git_commit_list_node *one, git_vector *twos) +int git_merge__bases_many( + git_commit_list **out, + git_revwalk *walk, + git_commit_list_node *one, + git_vector *twos, + uint32_t minimum_generation) { int error; unsigned int i; @@ -532,7 +542,7 @@ int git_merge__bases_many(git_commit_list **out, git_revwalk *walk, git_commit_l if (git_commit_list_parse(walk, one) < 0) return -1; - error = paint_down_to_common(&result, walk, one, twos); + error = paint_down_to_common(&result, walk, one, twos, minimum_generation); if (error < 0) return error; @@ -559,7 +569,7 @@ int git_merge__bases_many(git_commit_list **out, git_revwalk *walk, git_commit_l if ((error = clear_commit_marks(one, ALL_FLAGS)) < 0 || (error = clear_commit_marks_many(twos, ALL_FLAGS)) < 0 || - (error = remove_redundant(walk, &redundant)) < 0) { + (error = remove_redundant(walk, &redundant, minimum_generation)) < 0) { git_vector_free(&redundant); return error; } diff --git a/src/merge.h b/src/merge.h index b0a7de2becf..3e7f80c6ee2 100644 --- a/src/merge.h +++ b/src/merge.h @@ -129,7 +129,8 @@ int git_merge__bases_many( git_commit_list **out, git_revwalk *walk, git_commit_list_node *one, - git_vector *twos); + git_vector *twos, + uint32_t minimum_generation); /* * Three-way tree differencing diff --git a/tests/graph/reachable_from_any.c b/tests/graph/reachable_from_any.c new file mode 100644 index 00000000000..7dfd9ddd2e4 --- /dev/null +++ b/tests/graph/reachable_from_any.c @@ -0,0 +1,236 @@ +#include "clar_libgit2.h" + +#include + +#include "commit_graph.h" +#include "bitvec.h" +#include "vector.h" + +static git_repository *repo; + +#define TEST_REPO_PATH "merge-recursive" + +void test_graph_reachable_from_any__initialize(void) +{ + git_oid oid; + git_commit *commit; + + repo = cl_git_sandbox_init(TEST_REPO_PATH); + + git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707"); + cl_git_pass(git_commit_lookup(&commit, repo, &oid)); + cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL)); + git_commit_free(commit); +} + +void test_graph_reachable_from_any__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_graph_reachable_from_any__returns_correct_result(void) +{ + git_object *branchA1, *branchA2, *branchB1, *branchB2, *branchC1, *branchC2, *branchH1, + *branchH2; + git_oid descendants[7]; + + cl_git_pass(git_revparse_single(&branchA1, repo, "branchA-1")); + cl_git_pass(git_revparse_single(&branchA2, repo, "branchA-2")); + cl_git_pass(git_revparse_single(&branchB1, repo, "branchB-1")); + cl_git_pass(git_revparse_single(&branchB2, repo, "branchB-2")); + cl_git_pass(git_revparse_single(&branchC1, repo, "branchC-1")); + cl_git_pass(git_revparse_single(&branchC2, repo, "branchC-2")); + cl_git_pass(git_revparse_single(&branchH1, repo, "branchH-1")); + cl_git_pass(git_revparse_single(&branchH2, repo, "branchH-2")); + + cl_assert_equal_i( + git_graph_reachable_from_any( + repo, git_object_id(branchH1), 1, git_object_id(branchA1)), + 0); + cl_assert_equal_i( + git_graph_reachable_from_any( + repo, git_object_id(branchH1), 1, git_object_id(branchA2)), + 0); + + cl_git_pass(git_oid_cpy(&descendants[0], git_object_id(branchA1))); + cl_git_pass(git_oid_cpy(&descendants[1], git_object_id(branchA2))); + cl_git_pass(git_oid_cpy(&descendants[2], git_object_id(branchB1))); + cl_git_pass(git_oid_cpy(&descendants[3], git_object_id(branchB2))); + cl_git_pass(git_oid_cpy(&descendants[4], git_object_id(branchC1))); + cl_git_pass(git_oid_cpy(&descendants[5], git_object_id(branchC2))); + cl_git_pass(git_oid_cpy(&descendants[6], git_object_id(branchH2))); + cl_assert_equal_i( + git_graph_reachable_from_any(repo, git_object_id(branchH2), 6, descendants), + 0); + cl_assert_equal_i( + git_graph_reachable_from_any(repo, git_object_id(branchH2), 7, descendants), + 1); + + git_object_free(branchA1); + git_object_free(branchA2); + git_object_free(branchB1); + git_object_free(branchB2); + git_object_free(branchC1); + git_object_free(branchC2); + git_object_free(branchH1); + git_object_free(branchH2); +} + +struct exhaustive_state { + git_odb *db; + git_vector commits; +}; + +/** Get all commits from the repository. */ +static int exhaustive_commits(const git_oid *id, void *payload) +{ + struct exhaustive_state *mc = (struct exhaustive_state *)payload; + size_t header_len; + git_object_t header_type; + int error = 0; + + error = git_odb_read_header(&header_len, &header_type, mc->db, id); + if (error < 0) + return error; + + if (header_type == GIT_OBJECT_COMMIT) { + git_commit *commit = NULL; + + cl_git_pass(git_commit_lookup(&commit, repo, id)); + cl_git_pass(git_vector_insert(&mc->commits, commit)); + } + + return 0; +} + +/** Compare the `git_oid`s of two `git_commit` objects. */ +static int commit_id_cmp(const void *a, const void *b) +{ + return git_oid_cmp( + git_commit_id((const git_commit *)a), git_commit_id((const git_commit *)b)); +} + +/** Find a `git_commit` whose ID matches the provided `git_oid` key. */ +static int id_commit_id_cmp(const void *key, const void *commit) +{ + return git_oid_cmp((const git_oid *)key, git_commit_id((const git_commit *)commit)); +} + +void test_graph_reachable_from_any__exhaustive(void) +{ + struct exhaustive_state mc = { + .db = NULL, + .commits = GIT_VECTOR_INIT, + }; + size_t child_idx, commit_count; + size_t n_descendants; + git_commit *child_commit; + git_bitvec reachable; + + cl_git_pass(git_repository_odb(&mc.db, repo)); + cl_git_pass(git_odb_foreach(mc.db, &exhaustive_commits, &mc)); + git_vector_set_cmp(&mc.commits, commit_id_cmp); + git_vector_sort(&mc.commits); + cl_git_pass(git_bitvec_init( + &reachable, + git_vector_length(&mc.commits) * git_vector_length(&mc.commits))); + + commit_count = git_vector_length(&mc.commits); + git_vector_foreach (&mc.commits, child_idx, child_commit) { + unsigned int parent_i; + + /* We treat each commit as being able to reach itself. */ + git_bitvec_set(&reachable, child_idx * commit_count + child_idx, true); + + for (parent_i = 0; parent_i < git_commit_parentcount(child_commit); ++parent_i) { + size_t parent_idx = -1; + cl_git_pass(git_vector_bsearch2( + &parent_idx, + &mc.commits, + id_commit_id_cmp, + git_commit_parent_id(child_commit, parent_i))); + + /* We have established that parent_idx is reachable from child_idx */ + git_bitvec_set(&reachable, parent_idx * commit_count + child_idx, true); + } + } + + /* Floyd-Warshall */ + { + size_t i, j, k; + for (k = 0; k < commit_count; ++k) { + for (i = 0; i < commit_count; ++i) { + if (!git_bitvec_get(&reachable, i * commit_count + k)) + continue; + for (j = 0; j < commit_count; ++j) { + if (!git_bitvec_get(&reachable, k * commit_count + j)) + continue; + git_bitvec_set(&reachable, i * commit_count + j, true); + } + } + } + } + + /* Try 1000 subsets of 1 through 10 entries each. */ + srand(0x223ddc4b); + for (n_descendants = 1; n_descendants < 10; ++n_descendants) { + size_t test_iteration; + git_oid descendants[10]; + + for (test_iteration = 0; test_iteration < 1000; ++test_iteration) { + size_t descendant_i; + size_t child_idx, parent_idx; + int expected_reachable = false, actual_reachable; + git_commit *child_commit, *parent_commit; + + parent_idx = rand() % commit_count; + parent_commit = (git_commit *)git_vector_get(&mc.commits, parent_idx); + for (descendant_i = 0; descendant_i < n_descendants; ++descendant_i) { + child_idx = rand() % commit_count; + child_commit = (git_commit *)git_vector_get(&mc.commits, child_idx); + expected_reachable |= git_bitvec_get( + &reachable, parent_idx * commit_count + child_idx); + git_oid_cpy(&descendants[descendant_i], + git_commit_id(child_commit)); + } + + actual_reachable = git_graph_reachable_from_any( + repo, + git_commit_id(parent_commit), + n_descendants, + descendants); + if (actual_reachable != expected_reachable) { + git_buf error_message_buf = GIT_BUF_INIT; + char parent_oidbuf[9] = {0}, child_oidbuf[9] = {0}; + + cl_git_pass(git_oid_nfmt( + parent_oidbuf, 8, git_commit_id(parent_commit))); + git_buf_printf(&error_message_buf, + "git_graph_reachable_from_any(\"%s\", %zu, " + "{", + parent_oidbuf, + n_descendants); + for (descendant_i = 0; descendant_i < n_descendants; + ++descendant_i) { + cl_git_pass( + git_oid_nfmt(child_oidbuf, + 8, + &descendants[descendant_i])); + git_buf_printf(&error_message_buf, " \"%s\"", child_oidbuf); + } + git_buf_printf(&error_message_buf, + " }) = %d, expected = %d", + actual_reachable, + expected_reachable); + cl_check_(actual_reachable == expected_reachable, + git_buf_cstr(&error_message_buf)); + } + } + } + + git_vector_foreach (&mc.commits, child_idx, child_commit) + git_commit_free(child_commit); + git_bitvec_free(&reachable); + git_vector_free(&mc.commits); + git_odb_free(mc.db); +} From 8d453f16385c04abfba0211f1e7fb1621f26d609 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 27 Jul 2021 13:00:31 -0700 Subject: [PATCH 0393/1616] Swap the order of the `git_graph_reachable_from_any` params len, array -> array, len --- include/git2/graph.h | 4 ++-- src/graph.c | 6 +++--- tests/graph/reachable_from_any.c | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/git2/graph.h b/include/git2/graph.h index cd4897fef86..712ae474a06 100644 --- a/include/git2/graph.h +++ b/include/git2/graph.h @@ -68,8 +68,8 @@ GIT_EXTERN(int) git_graph_descendant_of( GIT_EXTERN(int) git_graph_reachable_from_any( git_repository *repo, const git_oid *commit, - size_t length, - const git_oid descendant_array[]); + const git_oid descendant_array[], + size_t length); /** @} */ GIT_END_DECL diff --git a/src/graph.c b/src/graph.c index 6efeb4a5323..35e914f7462 100644 --- a/src/graph.c +++ b/src/graph.c @@ -179,14 +179,14 @@ int git_graph_descendant_of(git_repository *repo, const git_oid *commit, const g if (git_oid_equal(commit, ancestor)) return 0; - return git_graph_reachable_from_any(repo, ancestor, 1, commit); + return git_graph_reachable_from_any(repo, ancestor, commit, 1); } int git_graph_reachable_from_any( git_repository *repo, const git_oid *commit_id, - size_t length, - const git_oid descendant_array[]) + const git_oid descendant_array[], + size_t length) { git_revwalk *walk = NULL; git_vector list; diff --git a/tests/graph/reachable_from_any.c b/tests/graph/reachable_from_any.c index 7dfd9ddd2e4..5c84164998f 100644 --- a/tests/graph/reachable_from_any.c +++ b/tests/graph/reachable_from_any.c @@ -45,11 +45,11 @@ void test_graph_reachable_from_any__returns_correct_result(void) cl_assert_equal_i( git_graph_reachable_from_any( - repo, git_object_id(branchH1), 1, git_object_id(branchA1)), + repo, git_object_id(branchH1), git_object_id(branchA1), 1), 0); cl_assert_equal_i( git_graph_reachable_from_any( - repo, git_object_id(branchH1), 1, git_object_id(branchA2)), + repo, git_object_id(branchH1), git_object_id(branchA2), 1), 0); cl_git_pass(git_oid_cpy(&descendants[0], git_object_id(branchA1))); @@ -60,10 +60,10 @@ void test_graph_reachable_from_any__returns_correct_result(void) cl_git_pass(git_oid_cpy(&descendants[5], git_object_id(branchC2))); cl_git_pass(git_oid_cpy(&descendants[6], git_object_id(branchH2))); cl_assert_equal_i( - git_graph_reachable_from_any(repo, git_object_id(branchH2), 6, descendants), + git_graph_reachable_from_any(repo, git_object_id(branchH2), descendants, 6), 0); cl_assert_equal_i( - git_graph_reachable_from_any(repo, git_object_id(branchH2), 7, descendants), + git_graph_reachable_from_any(repo, git_object_id(branchH2), descendants, 7), 1); git_object_free(branchA1); @@ -197,8 +197,8 @@ void test_graph_reachable_from_any__exhaustive(void) actual_reachable = git_graph_reachable_from_any( repo, git_commit_id(parent_commit), - n_descendants, - descendants); + descendants, + n_descendants); if (actual_reachable != expected_reachable) { git_buf error_message_buf = GIT_BUF_INIT; char parent_oidbuf[9] = {0}, child_oidbuf[9] = {0}; From 83862c83748b03d473a58d983916bec0bc385b62 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Mon, 17 Feb 2020 21:28:13 +0000 Subject: [PATCH 0394/1616] commit-graph: Add a way to write commit-graph files This change adds the git_commit_graph_writer_* functions to allow to write and create `commit-graph` files from `.idx`/`.pack` files or `git_revwalk`s. Part of: #5757 --- include/git2/sys/commit_graph.h | 132 ++++++- include/git2/types.h | 3 + src/commit_graph.c | 646 +++++++++++++++++++++++++++++++- src/commit_graph.h | 15 + tests/graph/commit_graph.c | 35 ++ 5 files changed, 829 insertions(+), 2 deletions(-) diff --git a/include/git2/sys/commit_graph.h b/include/git2/sys/commit_graph.h index 038c9b73920..01cf8d1bfa3 100644 --- a/include/git2/sys/commit_graph.h +++ b/include/git2/sys/commit_graph.h @@ -40,6 +40,136 @@ GIT_EXTERN(int) git_commit_graph_open(git_commit_graph **cgraph_out, const char */ GIT_EXTERN(void) git_commit_graph_free(git_commit_graph *cgraph); -GIT_END_DECL +/** + * Create a new writer for `commit-graph` files. + * + * @param out Location to store the writer pointer. + * @param objects_info_dir The `objects/info` directory. + * The `commit-graph` file will be written in this directory. + * @return 0 or an error code + */ +GIT_EXTERN(int) git_commit_graph_writer_new( + git_commit_graph_writer **out, + const char *objects_info_dir); + +/** + * Free the commit-graph writer and its resources. + * + * @param w The writer to free. If NULL no action is taken. + */ +GIT_EXTERN(void) git_commit_graph_writer_free(git_commit_graph_writer *w); + +/** + * Add an `.idx` file (associated to a packfile) to the writer. + * + * @param w The writer. + * @param repo The repository that owns the `.idx` file. + * @param idx_path The path of an `.idx` file. + * @return 0 or an error code + */ +GIT_EXTERN(int) git_commit_graph_writer_add_index_file( + git_commit_graph_writer *w, + git_repository *repo, + const char *idx_path); + +/** + * Add a revwalk to the writer. This will add all the commits from the revwalk + * to the commit-graph. + * + * @param w The writer. + * @param walk The git_revwalk. + * @return 0 or an error code + */ +GIT_EXTERN(int) git_commit_graph_writer_add_revwalk( + git_commit_graph_writer *w, + git_revwalk *walk); + +/** + * The strategy to use when adding a new set of commits to a pre-existing + * commit-graph chain. + */ +typedef enum { + /** + * Do not split commit-graph files. The other split strategy-related option + * fields are ignored. + */ + GIT_COMMIT_GRAPH_SPLIT_STRATEGY_SINGLE_FILE = 0, +} git_commit_graph_split_strategy_t; + +/** + * Options structure for + * `git_commit_graph_writer_commit`/`git_commit_graph_writer_dump`. + * + * Initialize with `GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT`. Alternatively, you + * can use `git_commit_graph_writer_options_init`. + */ +typedef struct { + unsigned int version; + + /** + * The strategy to use when adding new commits to a pre-existing commit-graph + * chain. + */ + git_commit_graph_split_strategy_t split_strategy; + + /** + * The number of commits in level N is less than X times the number of + * commits in level N + 1. + */ + float size_multiple; + + /** + * The number of commits in level N + 1 is more than C commits. + */ + size_t max_commits; +} git_commit_graph_writer_options; + +#define GIT_COMMIT_GRAPH_WRITER_OPTIONS_VERSION 1 +#define GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT \ + { \ + GIT_COMMIT_GRAPH_WRITER_OPTIONS_VERSION, \ + GIT_COMMIT_GRAPH_SPLIT_STRATEGY_SINGLE_FILE, 2.0f, 64000 \ + } + +/** + * Initialize git_commit_graph_writer_options structure + * + * Initializes a `git_commit_graph_writer_options` with default values. Equivalent to + * creating an instance with `GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT`. + * + * @param opts The `git_commit_graph_writer_options` struct to initialize. + * @param version The struct version; pass `GIT_COMMIT_GRAPH_WRITER_OPTIONS_VERSION`. + * @return Zero on success; -1 on failure. + */ +GIT_EXTERN(int) git_commit_graph_writer_options_init( + git_commit_graph_writer_options *opts, + unsigned int version); + +/** + * Write a `commit-graph` file to a file. + * + * @param w The writer + * @param opts Pointer to git_commit_graph_writer_options struct. + * @return 0 or an error code + */ +GIT_EXTERN(int) git_commit_graph_writer_commit( + git_commit_graph_writer *w, + git_commit_graph_writer_options *opts); + +/** + * Dump the contents of the `commit-graph` to an in-memory buffer. + * + * @param buffer Buffer where to store the contents of the `commit-graph`. + * @param w The writer. + * @param opts Pointer to git_commit_graph_writer_options struct. + * @return 0 or an error code + */ +GIT_EXTERN(int) git_commit_graph_writer_dump( + git_buf *buffer, + git_commit_graph_writer *w, + git_commit_graph_writer_options *opts); + +/** @} */ +GIT_END_DECL #endif diff --git a/include/git2/types.h b/include/git2/types.h index 562eb8e5f25..4d5c72324ce 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -96,6 +96,9 @@ typedef struct git_odb_stream git_odb_stream; /** A stream to write a packfile to the ODB */ typedef struct git_odb_writepack git_odb_writepack; +/** a writer for commit-graph files. */ +typedef struct git_commit_graph_writer git_commit_graph_writer; + /** An open refs database handle. */ typedef struct git_refdb git_refdb; diff --git a/src/commit_graph.c b/src/commit_graph.c index 556925600ff..3d1c03639cf 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -7,11 +7,19 @@ #include "commit_graph.h" +#include "array.h" +#include "filebuf.h" #include "futils.h" #include "hash.h" +#include "oidarray.h" +#include "oidmap.h" #include "pack.h" +#include "repository.h" +#include "revwalk.h" #define GIT_COMMIT_GRAPH_MISSING_PARENT 0x70000000 +#define GIT_COMMIT_GRAPH_GENERATION_NUMBER_MAX 0x3FFFFFFF +#define GIT_COMMIT_GRAPH_GENERATION_NUMBER_INFINITY 0xFFFFFFFF #define COMMIT_GRAPH_SIGNATURE 0x43475048 /* "CGPH" */ #define COMMIT_GRAPH_VERSION 1 @@ -36,6 +44,63 @@ struct git_commit_graph_chunk { size_t length; }; +typedef git_array_t(size_t) parent_index_array_t; + +struct packed_commit { + size_t index; + git_oid sha1; + git_oid tree_oid; + uint32_t generation; + git_time_t commit_time; + git_array_oid_t parents; + parent_index_array_t parent_indices; +}; + +static void packed_commit_free(struct packed_commit *p) +{ + if (!p) + return; + + git_array_clear(p->parents); + git_array_clear(p->parent_indices); + git__free(p); +} + +static struct packed_commit *packed_commit_new(git_commit *commit) +{ + unsigned int i, parentcount = git_commit_parentcount(commit); + struct packed_commit *p + = (struct packed_commit *)git__calloc(1, sizeof(struct packed_commit)); + if (!p) + goto cleanup; + + git_array_init_to_size(p->parents, parentcount); + if (parentcount && !p->parents.ptr) + goto cleanup; + + if (git_oid_cpy(&p->sha1, git_commit_id(commit)) < 0) + goto cleanup; + if (git_oid_cpy(&p->tree_oid, git_commit_tree_id(commit)) < 0) + goto cleanup; + p->commit_time = git_commit_time(commit); + + for (i = 0; i < parentcount; ++i) { + git_oid *parent_id = git_array_alloc(p->parents); + if (!parent_id) + goto cleanup; + if (git_oid_cpy(parent_id, git_commit_parent_id(commit, i)) < 0) + goto cleanup; + } + + return p; + +cleanup: + packed_commit_free(p); + return NULL; +} + +typedef int (*commit_graph_write_cb)(const char *buf, size_t size, void *cb_data); + static int commit_graph_error(const char *message) { git_error_set(GIT_ERROR_ODB, "invalid commit-graph file - %s", message); @@ -401,7 +466,6 @@ static int git_commit_graph_entry_get_byindex( extra_edge_list_pos++; e->parent_count++; } - } git_oid_cpy(&e->sha1, &file->oid_lookup[pos]); return 0; @@ -547,3 +611,583 @@ void git_commit_graph_file_free(git_commit_graph_file *file) git_commit_graph_file_close(file); git__free(file); } + +static int packed_commit__cmp(const void *a_, const void *b_) +{ + const struct packed_commit *a = a_; + const struct packed_commit *b = b_; + return git_oid_cmp(&a->sha1, &b->sha1); +} + +int git_commit_graph_writer_new(git_commit_graph_writer **out, const char *objects_info_dir) +{ + git_commit_graph_writer *w = git__calloc(1, sizeof(git_commit_graph_writer)); + GIT_ERROR_CHECK_ALLOC(w); + + if (git_buf_sets(&w->objects_info_dir, objects_info_dir) < 0) { + git__free(w); + return -1; + } + + if (git_vector_init(&w->commits, 0, packed_commit__cmp) < 0) { + git_buf_dispose(&w->objects_info_dir); + git__free(w); + return -1; + } + + *out = w; + return 0; +} + +void git_commit_graph_writer_free(git_commit_graph_writer *w) +{ + struct packed_commit *packed_commit; + size_t i; + + if (!w) + return; + + git_vector_foreach (&w->commits, i, packed_commit) + packed_commit_free(packed_commit); + git_vector_free(&w->commits); + git_buf_dispose(&w->objects_info_dir); + git__free(w); +} + +struct object_entry_cb_state { + git_repository *repo; + git_odb *db; + git_vector *commits; +}; + +static int object_entry__cb(const git_oid *id, void *data) +{ + struct object_entry_cb_state *state = (struct object_entry_cb_state *)data; + git_commit *commit = NULL; + struct packed_commit *packed_commit = NULL; + size_t header_len; + git_object_t header_type; + int error = 0; + + error = git_odb_read_header(&header_len, &header_type, state->db, id); + if (error < 0) + return error; + + if (header_type != GIT_OBJECT_COMMIT) + return 0; + + error = git_commit_lookup(&commit, state->repo, id); + if (error < 0) + return error; + + packed_commit = packed_commit_new(commit); + git_commit_free(commit); + GIT_ERROR_CHECK_ALLOC(packed_commit); + + error = git_vector_insert(state->commits, packed_commit); + if (error < 0) { + packed_commit_free(packed_commit); + return error; + } + + return 0; +} + +int git_commit_graph_writer_add_index_file( + git_commit_graph_writer *w, + git_repository *repo, + const char *idx_path) +{ + int error; + struct git_pack_file *p = NULL; + struct object_entry_cb_state state = { + .repo = repo, + .db = NULL, + .commits = &w->commits, + }; + + error = git_repository_odb(&state.db, repo); + if (error < 0) + goto cleanup; + + error = git_mwindow_get_pack(&p, idx_path); + if (error < 0) + goto cleanup; + + error = git_pack_foreach_entry(p, object_entry__cb, &state); + if (error < 0) + goto cleanup; + +cleanup: + git_mwindow_put_pack(p); + git_odb_free(state.db); + return error; +} + +int git_commit_graph_writer_add_revwalk(git_commit_graph_writer *w, git_revwalk *walk) +{ + int error; + git_oid id; + git_repository *repo = git_revwalk_repository(walk); + git_commit *commit; + struct packed_commit* packed_commit; + + while ((git_revwalk_next(&id, walk)) == 0) { + error = git_commit_lookup(&commit, repo, &id); + if (error < 0) + return error; + + packed_commit = packed_commit_new(commit); + git_commit_free(commit); + GIT_ERROR_CHECK_ALLOC(packed_commit); + + error = git_vector_insert(&w->commits, packed_commit); + if (error < 0) { + packed_commit_free(packed_commit); + return error; + } + } + + return 0; +} + +enum generation_number_commit_state { + GENERATION_NUMBER_COMMIT_STATE_UNVISITED = 0, + GENERATION_NUMBER_COMMIT_STATE_ADDED = 1, + GENERATION_NUMBER_COMMIT_STATE_EXPANDED = 2, + GENERATION_NUMBER_COMMIT_STATE_VISITED = 3, +}; + +static int compute_generation_numbers(git_vector *commits) +{ + git_array_t(size_t) index_stack = GIT_ARRAY_INIT; + size_t i, j; + size_t *parent_idx; + enum generation_number_commit_state *commit_states = NULL; + struct packed_commit *child_packed_commit; + git_oidmap *packed_commit_map = NULL; + int error = 0; + + /* First populate the parent indices fields */ + error = git_oidmap_new(&packed_commit_map); + if (error < 0) + goto cleanup; + git_vector_foreach (commits, i, child_packed_commit) { + child_packed_commit->index = i; + error = git_oidmap_set( + packed_commit_map, &child_packed_commit->sha1, child_packed_commit); + if (error < 0) + goto cleanup; + } + + git_vector_foreach (commits, i, child_packed_commit) { + size_t parent_i, *parent_idx_ptr; + struct packed_commit *parent_packed_commit; + git_oid *parent_id; + git_array_init_to_size( + child_packed_commit->parent_indices, + git_array_size(child_packed_commit->parents)); + if (git_array_size(child_packed_commit->parents) + && !child_packed_commit->parent_indices.ptr) { + error = -1; + goto cleanup; + } + git_array_foreach (child_packed_commit->parents, parent_i, parent_id) { + parent_packed_commit = git_oidmap_get(packed_commit_map, parent_id); + if (!parent_packed_commit) { + git_error_set(GIT_ERROR_ODB, + "parent commit %s not found in commit graph", + git_oid_tostr_s(parent_id)); + error = GIT_ENOTFOUND; + goto cleanup; + } + parent_idx_ptr = git_array_alloc(child_packed_commit->parent_indices); + if (!parent_idx_ptr) { + error = -1; + goto cleanup; + } + *parent_idx_ptr = parent_packed_commit->index; + } + } + + /* + * We copy all the commits to the stack and then during visitation, + * each node can be added up to two times to the stack. + */ + git_array_init_to_size(index_stack, 3 * git_vector_length(commits)); + if (!index_stack.ptr) { + error = -1; + goto cleanup; + } + + commit_states = (enum generation_number_commit_state *)git__calloc( + git_vector_length(commits), sizeof(enum generation_number_commit_state)); + if (!commit_states) { + error = -1; + goto cleanup; + } + + /* + * Perform a Post-Order traversal so that all parent nodes are fully + * visited before the child node. + */ + git_vector_foreach (commits, i, child_packed_commit) + *(size_t *)git_array_alloc(index_stack) = i; + + while (git_array_size(index_stack)) { + i = *git_array_pop(index_stack); + child_packed_commit = git_vector_get(commits, i); + + if (commit_states[i] == GENERATION_NUMBER_COMMIT_STATE_VISITED) { + /* This commit has already been fully visited. */ + continue; + } + if (commit_states[i] == GENERATION_NUMBER_COMMIT_STATE_EXPANDED) { + /* All of the commits parents have been visited. */ + child_packed_commit->generation = 0; + git_array_foreach (child_packed_commit->parent_indices, j, parent_idx) { + struct packed_commit *parent = git_vector_get(commits, *parent_idx); + if (child_packed_commit->generation < parent->generation) + child_packed_commit->generation = parent->generation; + } + if (child_packed_commit->generation + < GIT_COMMIT_GRAPH_GENERATION_NUMBER_MAX) { + ++child_packed_commit->generation; + } + commit_states[i] = GENERATION_NUMBER_COMMIT_STATE_VISITED; + continue; + } + + /* + * This is the first time we see this commit. We need + * to visit all its parents before we can fully visit + * it. + */ + if (git_array_size(child_packed_commit->parent_indices) == 0) { + /* + * Special case: if the commit has no parents, there's + * no need to add it to the stack just to immediately + * remove it. + */ + commit_states[i] = GENERATION_NUMBER_COMMIT_STATE_VISITED; + child_packed_commit->generation = 1; + continue; + } + + /* + * Add this current commit again so that it is visited + * again once all its children have been visited. + */ + *(size_t *)git_array_alloc(index_stack) = i; + git_array_foreach (child_packed_commit->parent_indices, j, parent_idx) { + if (commit_states[*parent_idx] + != GENERATION_NUMBER_COMMIT_STATE_UNVISITED) { + /* This commit has already been considered. */ + continue; + } + + commit_states[*parent_idx] = GENERATION_NUMBER_COMMIT_STATE_ADDED; + *(size_t *)git_array_alloc(index_stack) = *parent_idx; + } + commit_states[i] = GENERATION_NUMBER_COMMIT_STATE_EXPANDED; + } + +cleanup: + git_oidmap_free(packed_commit_map); + git__free(commit_states); + git_array_clear(index_stack); + + return error; +} + +static int write_offset(off64_t offset, commit_graph_write_cb write_cb, void *cb_data) +{ + int error; + uint32_t word; + + word = htonl((uint32_t)((offset >> 32) & 0xffffffffu)); + error = write_cb((const char *)&word, sizeof(word), cb_data); + if (error < 0) + return error; + word = htonl((uint32_t)((offset >> 0) & 0xffffffffu)); + error = write_cb((const char *)&word, sizeof(word), cb_data); + if (error < 0) + return error; + + return 0; +} + +static int +write_chunk_header(int chunk_id, off64_t offset, commit_graph_write_cb write_cb, void *cb_data) +{ + uint32_t word = htonl(chunk_id); + int error = write_cb((const char *)&word, sizeof(word), cb_data); + if (error < 0) + return error; + return write_offset(offset, write_cb, cb_data); +} + +static int commit_graph_write_buf(const char *buf, size_t size, void *data) +{ + git_buf *b = (git_buf *)data; + return git_buf_put(b, buf, size); +} + +struct commit_graph_write_hash_context { + commit_graph_write_cb write_cb; + void *cb_data; + git_hash_ctx *ctx; +}; + +static int commit_graph_write_hash(const char *buf, size_t size, void *data) +{ + struct commit_graph_write_hash_context *ctx + = (struct commit_graph_write_hash_context *)data; + int error; + + error = git_hash_update(ctx->ctx, buf, size); + if (error < 0) + return error; + + return ctx->write_cb(buf, size, ctx->cb_data); +} + +static void packed_commit_free_dup(void *packed_commit) +{ + packed_commit_free(packed_commit); +} + +static int +commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, void *cb_data) +{ + int error = 0; + size_t i; + struct packed_commit *packed_commit; + struct git_commit_graph_header hdr = { + .signature = htonl(COMMIT_GRAPH_SIGNATURE), + .version = COMMIT_GRAPH_VERSION, + .object_id_version = COMMIT_GRAPH_OBJECT_ID_VERSION, + .chunks = 0, + .base_graph_files = 0, + }; + uint32_t oid_fanout_count; + uint32_t extra_edge_list_count; + uint32_t oid_fanout[256]; + off64_t offset; + git_buf oid_lookup = GIT_BUF_INIT, + commit_data = GIT_BUF_INIT, extra_edge_list = GIT_BUF_INIT; + git_oid cgraph_checksum = {{0}}; + git_hash_ctx ctx; + struct commit_graph_write_hash_context hash_cb_data = { + .write_cb = write_cb, + .cb_data = cb_data, + .ctx = &ctx, + }; + + error = git_hash_ctx_init(&ctx); + if (error < 0) + return error; + cb_data = &hash_cb_data; + write_cb = commit_graph_write_hash; + + /* Sort the commits. */ + git_vector_sort(&w->commits); + git_vector_uniq(&w->commits, packed_commit_free_dup); + error = compute_generation_numbers(&w->commits); + if (error < 0) + goto cleanup; + + /* Fill the OID Fanout table. */ + oid_fanout_count = 0; + for (i = 0; i < 256; i++) { + while (oid_fanout_count < git_vector_length(&w->commits) + && ((struct packed_commit *)git_vector_get(&w->commits, oid_fanout_count)) + ->sha1.id[0] + <= i) + ++oid_fanout_count; + oid_fanout[i] = htonl(oid_fanout_count); + } + + /* Fill the OID Lookup table. */ + git_vector_foreach (&w->commits, i, packed_commit) { + error = git_buf_put( + &oid_lookup, (const char *)&packed_commit->sha1, sizeof(git_oid)); + if (error < 0) + goto cleanup; + } + + /* Fill the Commit Data and Extra Edge List tables. */ + extra_edge_list_count = 0; + git_vector_foreach (&w->commits, i, packed_commit) { + uint64_t commit_time; + uint32_t generation; + uint32_t word; + unsigned int parentcount = (unsigned int)git_array_size(packed_commit->parents); + + error + = git_buf_put(&commit_data, + (const char *)&packed_commit->tree_oid, + sizeof(git_oid)); + if (error < 0) + goto cleanup; + + if (parentcount == 0) + word = htonl(GIT_COMMIT_GRAPH_MISSING_PARENT); + else + word = htonl((uint32_t)*git_array_get(packed_commit->parent_indices, 0)); + error = git_buf_put(&commit_data, (const char *)&word, sizeof(word)); + if (error < 0) + goto cleanup; + + if (parentcount < 2) + word = htonl(GIT_COMMIT_GRAPH_MISSING_PARENT); + else if (parentcount == 2) + word = htonl((uint32_t)*git_array_get(packed_commit->parent_indices, 1)); + else + word = htonl(0x80000000u | extra_edge_list_count); + error = git_buf_put(&commit_data, (const char *)&word, sizeof(word)); + if (error < 0) + goto cleanup; + + if (parentcount > 2) { + unsigned int parent_i; + for (parent_i = 1; parent_i < parentcount; ++parent_i) { + word = htonl((uint32_t)( + *git_array_get(packed_commit->parent_indices, parent_i) + | (parent_i + 1 == parentcount ? 0x80000000u : 0))); + error + = git_buf_put(&extra_edge_list, + (const char *)&word, + sizeof(word)); + if (error < 0) + goto cleanup; + } + extra_edge_list_count += parentcount - 1; + } + + generation = packed_commit->generation; + commit_time = (uint64_t)packed_commit->commit_time; + if (generation > GIT_COMMIT_GRAPH_GENERATION_NUMBER_MAX) + generation = GIT_COMMIT_GRAPH_GENERATION_NUMBER_MAX; + word = ntohl((uint32_t)((generation << 2) | ((commit_time >> 32ull) & 0x3ull))); + error = git_buf_put(&commit_data, (const char *)&word, sizeof(word)); + if (error < 0) + goto cleanup; + word = ntohl((uint32_t)(commit_time & 0xffffffffull)); + error = git_buf_put(&commit_data, (const char *)&word, sizeof(word)); + if (error < 0) + goto cleanup; + } + + /* Write the header. */ + hdr.chunks = 3; + if (git_buf_len(&extra_edge_list) > 0) + hdr.chunks++; + error = write_cb((const char *)&hdr, sizeof(hdr), cb_data); + if (error < 0) + goto cleanup; + + /* Write the chunk headers. */ + offset = sizeof(hdr) + (hdr.chunks + 1) * 12; + error = write_chunk_header(COMMIT_GRAPH_OID_FANOUT_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += sizeof(oid_fanout); + error = write_chunk_header(COMMIT_GRAPH_OID_LOOKUP_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += git_buf_len(&oid_lookup); + error = write_chunk_header(COMMIT_GRAPH_COMMIT_DATA_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += git_buf_len(&commit_data); + if (git_buf_len(&extra_edge_list) > 0) { + error = write_chunk_header( + COMMIT_GRAPH_EXTRA_EDGE_LIST_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += git_buf_len(&extra_edge_list); + } + error = write_chunk_header(0, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + + /* Write all the chunks. */ + error = write_cb((const char *)oid_fanout, sizeof(oid_fanout), cb_data); + if (error < 0) + goto cleanup; + error = write_cb(git_buf_cstr(&oid_lookup), git_buf_len(&oid_lookup), cb_data); + if (error < 0) + goto cleanup; + error = write_cb(git_buf_cstr(&commit_data), git_buf_len(&commit_data), cb_data); + if (error < 0) + goto cleanup; + error + = write_cb(git_buf_cstr(&extra_edge_list), + git_buf_len(&extra_edge_list), + cb_data); + if (error < 0) + goto cleanup; + + /* Finalize the checksum and write the trailer. */ + error = git_hash_final(&cgraph_checksum, &ctx); + if (error < 0) + goto cleanup; + error = write_cb((const char *)&cgraph_checksum, sizeof(cgraph_checksum), cb_data); + if (error < 0) + goto cleanup; + +cleanup: + git_buf_dispose(&oid_lookup); + git_buf_dispose(&commit_data); + git_buf_dispose(&extra_edge_list); + git_hash_ctx_cleanup(&ctx); + return error; +} + +static int commit_graph_write_filebuf(const char *buf, size_t size, void *data) +{ + git_filebuf *f = (git_filebuf *)data; + return git_filebuf_write(f, buf, size); +} + +int git_commit_graph_writer_commit( + git_commit_graph_writer *w, + git_commit_graph_writer_options *opts) +{ + int error; + int filebuf_flags = GIT_FILEBUF_DO_NOT_BUFFER; + git_buf commit_graph_path = GIT_BUF_INIT; + git_filebuf output = GIT_FILEBUF_INIT; + + GIT_UNUSED(opts); + + error = git_buf_joinpath( + &commit_graph_path, git_buf_cstr(&w->objects_info_dir), "commit-graph"); + if (error < 0) + return error; + + if (git_repository__fsync_gitdir) + filebuf_flags |= GIT_FILEBUF_FSYNC; + error = git_filebuf_open(&output, git_buf_cstr(&commit_graph_path), filebuf_flags, 0644); + git_buf_dispose(&commit_graph_path); + if (error < 0) + return error; + + error = commit_graph_write(w, commit_graph_write_filebuf, &output); + if (error < 0) { + git_filebuf_cleanup(&output); + return error; + } + + return git_filebuf_commit(&output); +} + +int git_commit_graph_writer_dump( + git_buf *cgraph, + git_commit_graph_writer *w, + git_commit_graph_writer_options *opts) +{ + GIT_UNUSED(opts); + return commit_graph_write(w, commit_graph_write_buf, cgraph); +} diff --git a/src/commit_graph.h b/src/commit_graph.h index e5e3ea1fdaf..9d0a827de0a 100644 --- a/src/commit_graph.h +++ b/src/commit_graph.h @@ -14,6 +14,7 @@ #include "git2/sys/commit_graph.h" #include "map.h" +#include "vector.h" /** * A commit-graph file. @@ -118,6 +119,20 @@ int git_commit_graph_get_file(git_commit_graph_file **file_out, git_commit_graph /* Marks the commit-graph file as needing a refresh. */ void git_commit_graph_refresh(git_commit_graph *cgraph); +/* + * A writer for `commit-graph` files. + */ +struct git_commit_graph_writer { + /* + * The path of the `objects/info` directory where the `commit-graph` will be + * stored. + */ + git_buf objects_info_dir; + + /* The list of packed commits. */ + git_vector commits; +}; + /* * Returns whether the git_commit_graph_file needs to be reloaded since the * contents of the commit-graph file have changed on disk. diff --git a/tests/graph/commit_graph.c b/tests/graph/commit_graph.c index 2ff157eb457..5926dca6f32 100644 --- a/tests/graph/commit_graph.c +++ b/tests/graph/commit_graph.c @@ -1,8 +1,10 @@ #include "clar_libgit2.h" #include +#include #include "commit_graph.h" +#include "futils.h" void test_graph_commit_graph__parse(void) { @@ -88,3 +90,36 @@ void test_graph_commit_graph__parse_octopus_merge(void) git_repository_free(repo); git_buf_dispose(&commit_graph_path); } + +void test_graph_commit_graph__writer(void) +{ + git_repository *repo; + git_commit_graph_writer *w = NULL; + git_revwalk *walk; + git_commit_graph_writer_options opts = GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT; + git_buf cgraph = GIT_BUF_INIT, expected_cgraph = GIT_BUF_INIT, path = GIT_BUF_INIT; + + cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); + + cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/info")); + cl_git_pass(git_commit_graph_writer_new(&w, git_buf_cstr(&path))); + + /* This is equivalent to `git commit-graph write --reachable`. */ + cl_git_pass(git_revwalk_new(&walk, repo)); + cl_git_pass(git_revwalk_push_glob(walk, "refs/*")); + cl_git_pass(git_commit_graph_writer_add_revwalk(w, walk)); + git_revwalk_free(walk); + + cl_git_pass(git_commit_graph_writer_dump(&cgraph, w, &opts)); + cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/info/commit-graph")); + cl_git_pass(git_futils_readbuffer(&expected_cgraph, git_buf_cstr(&path))); + + cl_assert_equal_i(git_buf_len(&cgraph), git_buf_len(&expected_cgraph)); + cl_assert_equal_i(memcmp(git_buf_cstr(&cgraph), git_buf_cstr(&expected_cgraph), git_buf_len(&cgraph)), 0); + + git_buf_dispose(&cgraph); + git_buf_dispose(&expected_cgraph); + git_buf_dispose(&path); + git_commit_graph_writer_free(w); + git_repository_free(repo); +} From 59af78a48fac0966e6e26f1ea6323844c69aba48 Mon Sep 17 00:00:00 2001 From: Crayon Date: Wed, 28 Jul 2021 01:58:32 -0400 Subject: [PATCH 0395/1616] Fix typo in general.c --- examples/general.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/general.c b/examples/general.c index 5da2b6f6fc4..2127ec0e1ea 100644 --- a/examples/general.c +++ b/examples/general.c @@ -708,7 +708,7 @@ static void reference_listing(git_repository *repo) /** * ### Config Files * - * The [config API][config] allows you to list and updatee config values + * The [config API][config] allows you to list and update config values * in any of the accessible config file locations (system, global, local). * * [config]: http://libgit2.github.com/libgit2/#HEAD/group/config From 346f15ba8987b7ed24990d1d70f2724e4424500b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 30 Jul 2021 08:51:43 -0400 Subject: [PATCH 0396/1616] status: document `GIT_STATUS_OPT_INCLUDE_UNREADABLE` Document `GIT_STATUS_OPT_INCLUDE_UNREADABLE`, and some minor cleanups. --- include/git2/blame.h | 77 ++++++++++++++++++++++++++++++------------- include/git2/status.h | 27 +++++++++++---- 2 files changed, 75 insertions(+), 29 deletions(-) diff --git a/include/git2/blame.h b/include/git2/blame.h index 566d4db7bd7..d193ce14ed5 100644 --- a/include/git2/blame.h +++ b/include/git2/blame.h @@ -26,27 +26,52 @@ GIT_BEGIN_DECL typedef enum { /** Normal blame, the default */ GIT_BLAME_NORMAL = 0, - /** Track lines that have moved within a file (like `git blame -M`). - * NOT IMPLEMENTED. */ + + /** + * Track lines that have moved within a file (like `git blame -M`). + * + * This is not yet implemented and reserved for future use. + */ GIT_BLAME_TRACK_COPIES_SAME_FILE = (1<<0), - /** Track lines that have moved across files in the same commit (like `git blame -C`). - * NOT IMPLEMENTED. */ + + /** + * Track lines that have moved across files in the same commit + * (like `git blame -C`). + * + * This is not yet implemented and reserved for future use. + */ GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES = (1<<1), - /** Track lines that have been copied from another file that exists in the - * same commit (like `git blame -CC`). Implies SAME_FILE. - * NOT IMPLEMENTED. */ + + /** + * Track lines that have been copied from another file that exists + * in the same commit (like `git blame -CC`). Implies SAME_FILE. + * + * This is not yet implemented and reserved for future use. + */ GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES = (1<<2), - /** Track lines that have been copied from another file that exists in *any* - * commit (like `git blame -CCC`). Implies SAME_COMMIT_COPIES. - * NOT IMPLEMENTED. */ + + /** + * Track lines that have been copied from another file that exists in + * *any* commit (like `git blame -CCC`). Implies SAME_COMMIT_COPIES. + * + * This is not yet implemented and reserved for future use. + */ GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES = (1<<3), - /** Restrict the search of commits to those reachable following only the - * first parents. */ + + /** + * Restrict the search of commits to those reachable following only + * the first parents. + */ GIT_BLAME_FIRST_PARENT = (1<<4), - /** Use mailmap file to map author and committer names and email addresses - * to canonical real names and email addresses. The mailmap will be read - * from the working directory, or HEAD in a bare repository. */ + + /** + * Use mailmap file to map author and committer names and email + * addresses to canonical real names and email addresses. The + * mailmap will be read from the working directory, or HEAD in a + * bare repository. + */ GIT_BLAME_USE_MAILMAP = (1<<5), + /** Ignore whitespace differences */ GIT_BLAME_IGNORE_WHITESPACE = (1<<6), } git_blame_flag_t; @@ -63,25 +88,33 @@ typedef struct git_blame_options { /** A combination of `git_blame_flag_t` */ uint32_t flags; - /** The lower bound on the number of alphanumeric - * characters that must be detected as moving/copying within a file for it to - * associate those lines with the parent commit. The default value is 20. - * This value only takes effect if any of the `GIT_BLAME_TRACK_COPIES_*` - * flags are specified. + + /** + * The lower bound on the number of alphanumeric characters that + * must be detected as moving/copying within a file for it to + * associate those lines with the parent commit. The default value + * is 20. + * + * This value only takes effect if any of the `GIT_BLAME_TRACK_COPIES_*` + * flags are specified. */ uint16_t min_match_characters; + /** The id of the newest commit to consider. The default is HEAD. */ git_oid newest_commit; + /** * The id of the oldest commit to consider. * The default is the first commit encountered with a NULL parent. */ git_oid oldest_commit; + /** * The first line in the file to blame. * The default is 1 (line numbers start with 1). */ size_t min_line; + /** * The last line in the file to blame. * The default is the last line of the file. @@ -158,8 +191,8 @@ typedef struct git_blame_hunk { git_signature *orig_signature; /** - * The 1 iff the hunk has been tracked to a boundary commit (the root, or - * the commit specified in git_blame_options.oldest_commit) + * The 1 iff the hunk has been tracked to a boundary commit (the root, + * or the commit specified in git_blame_options.oldest_commit) */ char boundary; } git_blame_hunk; diff --git a/include/git2/status.h b/include/git2/status.h index ed9856a2a33..543e3faa8f7 100644 --- a/include/git2/status.h +++ b/include/git2/status.h @@ -193,8 +193,17 @@ typedef enum { */ GIT_STATUS_OPT_UPDATE_INDEX = (1u << 13), + /** + * Normally files that cannot be opened or read are ignored as + * these are often transient files; this option will return + * unreadable files as `GIT_STATUS_WT_UNREADABLE`. + */ GIT_STATUS_OPT_INCLUDE_UNREADABLE = (1u << 14), + /** + * Unreadable files will be detected and given the status + * untracked instead of unreadable. + */ GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED = (1u << 15), } git_status_opt_t; @@ -211,7 +220,10 @@ typedef enum { * */ typedef struct { - unsigned int version; /**< The version */ + /** + * The struct version; pass `GIT_STATUS_OPTIONS_VERSION`. + */ + unsigned int version; /** * The `show` value is one of the `git_status_show_t` constants that @@ -220,21 +232,22 @@ typedef struct { git_status_show_t show; /** - * The `flags` value is an OR'ed combination of the `git_status_opt_t` - * values above. + * The `flags` value is an OR'ed combination of the + * `git_status_opt_t` values above. */ unsigned int flags; /** * The `pathspec` is an array of path patterns to match (using - * fnmatch-style matching), or just an array of paths to match exactly if - * `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified in the flags. + * fnmatch-style matching), or just an array of paths to match + * exactly if `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified + * in the flags. */ git_strarray pathspec; /** - * The `baseline` is the tree to be used for comparison to the working directory - * and index; defaults to HEAD. + * The `baseline` is the tree to be used for comparison to the + * working directory and index; defaults to HEAD. */ git_tree *baseline; } git_status_options; From f2915ec488898efe956c90c322fff67d0030f92f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 30 Jul 2021 08:56:34 -0400 Subject: [PATCH 0397/1616] tests: reformat upstream merge --- tests/refs/branches/upstream.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/refs/branches/upstream.c b/tests/refs/branches/upstream.c index f6fd509b869..c94afe9e830 100644 --- a/tests/refs/branches/upstream.c +++ b/tests/refs/branches/upstream.c @@ -75,8 +75,8 @@ void test_refs_branches_upstream__upstream_merge(void) { git_reference *branch; git_repository *repository; - git_buf buf = GIT_BUF_INIT; - + git_buf buf = GIT_BUF_INIT; + repository = cl_git_sandbox_init("testrepo.git"); /* check repository */ @@ -89,9 +89,9 @@ void test_refs_branches_upstream__upstream_merge(void) git_reference_free(branch); /* check merge branch */ - cl_git_pass(git_branch_upstream_merge(&buf, repository, "refs/heads/test")); - cl_assert_equal_s("refs/heads/master", buf.ptr); - git_buf_dispose(&buf); + cl_git_pass(git_branch_upstream_merge(&buf, repository, "refs/heads/test")); + cl_assert_equal_s("refs/heads/master", buf.ptr); + git_buf_dispose(&buf); } void test_refs_branches_upstream__upstream_remote_empty_value(void) From d15b6132a6453d696b37c884765572a696e7af06 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Fri, 30 Jul 2021 07:18:57 -0700 Subject: [PATCH 0398/1616] Fix one memory leak in master There was one test that wasn't correctly disposing of the repository. --- tests/refs/branches/upstream.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/refs/branches/upstream.c b/tests/refs/branches/upstream.c index c94afe9e830..919705e07b4 100644 --- a/tests/refs/branches/upstream.c +++ b/tests/refs/branches/upstream.c @@ -92,6 +92,8 @@ void test_refs_branches_upstream__upstream_merge(void) cl_git_pass(git_branch_upstream_merge(&buf, repository, "refs/heads/test")); cl_assert_equal_s("refs/heads/master", buf.ptr); git_buf_dispose(&buf); + + cl_git_sandbox_cleanup(); } void test_refs_branches_upstream__upstream_remote_empty_value(void) From cd460522c516f18a12549626a356960370e3bcc7 Mon Sep 17 00:00:00 2001 From: Tony De La Nuez Date: Mon, 20 Apr 2020 22:16:52 +0000 Subject: [PATCH 0399/1616] odb: Implement option for overriding of default odb backend priority Introduce GIT_OPT_SET_ODB_LOOSE_PRIORITY and GIT_OPT_SET_ODB_PACKED_PRIORITY to allow overriding the default priority values for the default ODB backends. Libgit2 has historically assumed that most objects for long- running operations will be packed, therefore GIT_LOOSE_PRIORITY is set to 1 by default, and GIT_PACKED_PRIORITY to 2. When a client allows libgit2 to set the default backends, they can specify an override for the two priority values in order to change the order in which each ODB backend is accessed. --- include/git2/common.h | 12 +++++++++++- src/libgit2.c | 10 ++++++++++ src/odb.c | 12 ++++++------ tests/odb/sorting.c | 23 +++++++++++++++++++++++ 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/include/git2/common.h b/include/git2/common.h index dee260e05d9..4402dfda804 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -207,7 +207,9 @@ typedef enum { GIT_OPT_DISABLE_PACK_KEEP_FILE_CHECKS, GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE, GIT_OPT_GET_MWINDOW_FILE_LIMIT, - GIT_OPT_SET_MWINDOW_FILE_LIMIT + GIT_OPT_SET_MWINDOW_FILE_LIMIT, + GIT_OPT_SET_ODB_PACKED_PRIORITY, + GIT_OPT_SET_ODB_LOOSE_PRIORITY } git_libgit2_opt_t; /** @@ -421,6 +423,14 @@ typedef enum { * > authentication, use expect/continue when POSTing data. * > This option is not available on Windows. * + * opts(GIT_OPT_SET_ODB_PACKED_PRIORITY, int priority) + * > Override the default priority of the packed ODB backend which + * > is added when default backends are assigned to a repository + * + * opts(GIT_OPT_SET_ODB_LOOSE_PRIORITY, int priority) + * > Override the default priority of the loose ODB backend which + * > is added when default backends are assigned to a repository + * * @param option Option key * @param ... value to set the option * @return 0 on success, <0 on failure diff --git a/src/libgit2.c b/src/libgit2.c index f27c9997dce..089c8359059 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -50,6 +50,8 @@ extern size_t git_mwindow__mapped_limit; extern size_t git_mwindow__file_limit; extern size_t git_indexer__max_objects; extern bool git_disable_pack_keep_file_checks; +extern int git_odb__packed_priority; +extern int git_odb__loose_priority; char *git__user_agent; char *git__ssl_ciphers; @@ -368,6 +370,14 @@ int git_libgit2_opts(int key, ...) git_http__expect_continue = (va_arg(ap, int) != 0); break; + case GIT_OPT_SET_ODB_PACKED_PRIORITY: + git_odb__packed_priority = va_arg(ap, int); + break; + + case GIT_OPT_SET_ODB_LOOSE_PRIORITY: + git_odb__loose_priority = va_arg(ap, int); + break; + default: git_error_set(GIT_ERROR_INVALID, "invalid option key"); error = -1; diff --git a/src/odb.c b/src/odb.c index 05bdaf6a355..35e2259753c 100644 --- a/src/odb.c +++ b/src/odb.c @@ -23,14 +23,14 @@ #define GIT_ALTERNATES_FILE "info/alternates" +#define GIT_ALTERNATES_MAX_DEPTH 5 + /* * We work under the assumption that most objects for long-running * operations will be packed */ -#define GIT_LOOSE_PRIORITY 1 -#define GIT_PACKED_PRIORITY 2 - -#define GIT_ALTERNATES_MAX_DEPTH 5 +int git_odb__loose_priority = 1; +int git_odb__packed_priority = 2; bool git_odb__strict_hash_verification = true; @@ -613,12 +613,12 @@ int git_odb__add_default_backends( /* add the loose object backend */ if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 || - add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates, inode) < 0) + add_backend_internal(db, loose, git_odb__loose_priority, as_alternates, inode) < 0) return -1; /* add the packed file backend */ if (git_odb_backend_pack(&packed, objects_dir) < 0 || - add_backend_internal(db, packed, GIT_PACKED_PRIORITY, as_alternates, inode) < 0) + add_backend_internal(db, packed, git_odb__packed_priority, as_alternates, inode) < 0) return -1; if (git_mutex_lock(&db->lock) < 0) { diff --git a/tests/odb/sorting.c b/tests/odb/sorting.c index 6af8b0d1b86..dc87a854dd2 100644 --- a/tests/odb/sorting.c +++ b/tests/odb/sorting.c @@ -68,3 +68,26 @@ void test_odb_sorting__alternate_backends_sorting(void) check_backend_sorting(_odb); } + +void test_odb_sorting__override_default_backend_priority(void) +{ + git_odb *new_odb; + git_odb_backend *loose, *packed, *backend; + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_LOOSE_PRIORITY, 5)); + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_PACKED_PRIORITY, 3)); + git_odb_backend_pack(&packed, "./testrepo.git/objects"); + git_odb_backend_loose(&loose, "./testrepo.git/objects", -1, 0, 0, 0); + + cl_git_pass(git_odb_open(&new_odb, cl_fixture("testrepo.git/objects"))); + cl_assert_equal_sz(2, git_odb_num_backends(new_odb)); + + cl_git_pass(git_odb_get_backend(&backend, new_odb, 0)); + cl_assert_equal_p(loose->read, backend->read); + + cl_git_pass(git_odb_get_backend(&backend, new_odb, 1)); + cl_assert_equal_p(packed->read, backend->read); + + git_odb_free(new_odb); + loose->free(loose); + packed->free(packed); +} From e5975f36d7f00cb5bca7b2532bfcfb3130d2a069 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 30 Jul 2021 11:37:12 -0400 Subject: [PATCH 0400/1616] tests: reset odb backend priority --- src/odb.c | 4 ++-- src/odb.h | 3 +++ tests/odb/sorting.c | 6 ++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/odb.c b/src/odb.c index 35e2259753c..22c8c8c871f 100644 --- a/src/odb.c +++ b/src/odb.c @@ -29,8 +29,8 @@ * We work under the assumption that most objects for long-running * operations will be packed */ -int git_odb__loose_priority = 1; -int git_odb__packed_priority = 2; +int git_odb__loose_priority = GIT_ODB_DEFAULT_LOOSE_PRIORITY; +int git_odb__packed_priority = GIT_ODB_DEFAULT_PACKED_PRIORITY; bool git_odb__strict_hash_verification = true; diff --git a/src/odb.h b/src/odb.h index 5bebb6edce4..4a8ebff1913 100644 --- a/src/odb.h +++ b/src/odb.h @@ -24,6 +24,9 @@ #define GIT_OBJECT_DIR_MODE 0777 #define GIT_OBJECT_FILE_MODE 0444 +#define GIT_ODB_DEFAULT_LOOSE_PRIORITY 1 +#define GIT_ODB_DEFAULT_PACKED_PRIORITY 2 + extern bool git_odb__strict_hash_verification; /* DO NOT EXPORT */ diff --git a/tests/odb/sorting.c b/tests/odb/sorting.c index dc87a854dd2..e027230fac0 100644 --- a/tests/odb/sorting.c +++ b/tests/odb/sorting.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "git2/sys/odb_backend.h" +#include "odb.h" typedef struct { git_odb_backend base; @@ -43,6 +44,11 @@ void test_odb_sorting__cleanup(void) { git_odb_free(_odb); _odb = NULL; + + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_LOOSE_PRIORITY, + GIT_ODB_DEFAULT_LOOSE_PRIORITY)); + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ODB_PACKED_PRIORITY, + GIT_ODB_DEFAULT_PACKED_PRIORITY)); } void test_odb_sorting__basic_backends_sorting(void) From 3062a63364d6c213cb501809c727ff828eb9acae Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 30 Jul 2021 12:03:35 -0400 Subject: [PATCH 0401/1616] cmake: extended futimens checking on macOS --- CMakeLists.txt | 1 + cmake/Findfutimens.cmake | 14 ++++++++++++++ src/CMakeLists.txt | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 cmake/Findfutimens.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 58214fd0e1e..ff3411928cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ INCLUDE(AddCFlagIfSupported) INCLUDE(FindPkgLibraries) INCLUDE(FindThreads) INCLUDE(FindStatNsec) +INCLUDE(Findfutimens) INCLUDE(GNUInstallDirs) INCLUDE(IdeSplitSources) INCLUDE(FeatureSummary) diff --git a/cmake/Findfutimens.cmake b/cmake/Findfutimens.cmake new file mode 100644 index 00000000000..73b79528ac6 --- /dev/null +++ b/cmake/Findfutimens.cmake @@ -0,0 +1,14 @@ +INCLUDE(EnableWarnings) + +IF (APPLE) + # We cannot simply CHECK_FUNCTION_EXISTS on macOS because + # MACOSX_DEPLOYMENT_TARGET may be set to a version in the past + # that doesn't have futimens. Instead we need to enable warnings + # as errors, then check for the symbol existing in `sys/stat.h`, + # then reset warnings as errors. + ENABLE_WARNINGS(error) + CHECK_SYMBOL_EXISTS(futimens sys/stat.h HAVE_FUTIMENS) + DISABLE_WARNINGS(error) +ELSE () + CHECK_FUNCTION_EXISTS(futimens HAVE_FUTIMENS) +ENDIF () diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8d155955151..d3408999f97 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -38,10 +38,10 @@ IF(ENABLE_TRACE) ENDIF() ADD_FEATURE_INFO(tracing GIT_TRACE "tracing support") -CHECK_FUNCTION_EXISTS(futimens HAVE_FUTIMENS) IF (HAVE_FUTIMENS) SET(GIT_USE_FUTIMENS 1) ENDIF () +ADD_FEATURE_INFO(futimens GIT_USE_FUTIMENS "futimens support") CHECK_PROTOTYPE_DEFINITION(qsort_r "void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, int (*compar)(void *, const void *, const void *))" From f6b3f72634821a9fc899783964edf86f50087cad Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 30 Jul 2021 12:40:36 -0400 Subject: [PATCH 0402/1616] README: link to more information about cmake --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index aa642549d7b..c5ef0224f36 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,8 @@ On most systems you can build the library using the following commands Alternatively you can point the CMake GUI tool to the CMakeLists.txt file and generate platform specific build project or IDE workspace. +If you're not familiar with CMake, [a more detailed explanation](https://preshing.com/20170511/how-to-build-a-cmake-based-project/) may be helpful. + Running Tests ------------- From 2988f7367cda7337e2b293fb12814d272ef9c33b Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sun, 1 Aug 2021 06:28:33 -0700 Subject: [PATCH 0403/1616] Review feedback * Added the `PenaltyBreakAssignment: 1000` clang-format option to avoid breaking statements around the assignment operator. * Avoided using the dot initializer syntax. * Avoided casting allocations. * Also avoided casting `void *`. --- src/commit_graph.c | 68 +++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/src/commit_graph.c b/src/commit_graph.c index 3d1c03639cf..78ab436d6a2 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -69,8 +69,7 @@ static void packed_commit_free(struct packed_commit *p) static struct packed_commit *packed_commit_new(git_commit *commit) { unsigned int i, parentcount = git_commit_parentcount(commit); - struct packed_commit *p - = (struct packed_commit *)git__calloc(1, sizeof(struct packed_commit)); + struct packed_commit *p = git__calloc(1, sizeof(struct packed_commit)); if (!p) goto cleanup; @@ -436,8 +435,8 @@ static int git_commit_graph_entry_get_byindex( commit_data = file->commit_data + pos * (GIT_OID_RAWSZ + 4 * sizeof(uint32_t)); git_oid_cpy(&e->tree_oid, (const git_oid *)commit_data); e->parent_indices[0] = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ))); - e->parent_indices[1] - = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ + sizeof(uint32_t)))); + e->parent_indices[1] = ntohl( + *((uint32_t *)(commit_data + GIT_OID_RAWSZ + sizeof(uint32_t)))); e->parent_count = (e->parent_indices[0] != GIT_COMMIT_GRAPH_MISSING_PARENT) + (e->parent_indices[1] != GIT_COMMIT_GRAPH_MISSING_PARENT); e->generation = ntohl(*((uint32_t *)(commit_data + GIT_OID_RAWSZ + 2 * sizeof(uint32_t)))); @@ -700,11 +699,9 @@ int git_commit_graph_writer_add_index_file( { int error; struct git_pack_file *p = NULL; - struct object_entry_cb_state state = { - .repo = repo, - .db = NULL, - .commits = &w->commits, - }; + struct object_entry_cb_state state = {0}; + state.repo = repo; + state.commits = &w->commits; error = git_repository_odb(&state.db, repo); if (error < 0) @@ -941,8 +938,7 @@ struct commit_graph_write_hash_context { static int commit_graph_write_hash(const char *buf, size_t size, void *data) { - struct commit_graph_write_hash_context *ctx - = (struct commit_graph_write_hash_context *)data; + struct commit_graph_write_hash_context *ctx = data; int error; error = git_hash_update(ctx->ctx, buf, size); @@ -963,26 +959,25 @@ commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, v int error = 0; size_t i; struct packed_commit *packed_commit; - struct git_commit_graph_header hdr = { - .signature = htonl(COMMIT_GRAPH_SIGNATURE), - .version = COMMIT_GRAPH_VERSION, - .object_id_version = COMMIT_GRAPH_OBJECT_ID_VERSION, - .chunks = 0, - .base_graph_files = 0, - }; + struct git_commit_graph_header hdr = {0}; uint32_t oid_fanout_count; uint32_t extra_edge_list_count; uint32_t oid_fanout[256]; off64_t offset; - git_buf oid_lookup = GIT_BUF_INIT, - commit_data = GIT_BUF_INIT, extra_edge_list = GIT_BUF_INIT; + git_buf oid_lookup = GIT_BUF_INIT, commit_data = GIT_BUF_INIT, + extra_edge_list = GIT_BUF_INIT; git_oid cgraph_checksum = {{0}}; git_hash_ctx ctx; - struct commit_graph_write_hash_context hash_cb_data = { - .write_cb = write_cb, - .cb_data = cb_data, - .ctx = &ctx, - }; + struct commit_graph_write_hash_context hash_cb_data = {0}; + + hdr.signature = htonl(COMMIT_GRAPH_SIGNATURE); + hdr.version = COMMIT_GRAPH_VERSION; + hdr.object_id_version = COMMIT_GRAPH_OBJECT_ID_VERSION; + hdr.chunks = 0; + hdr.base_graph_files = 0; + hash_cb_data.write_cb = write_cb; + hash_cb_data.cb_data = cb_data; + hash_cb_data.ctx = &ctx; error = git_hash_ctx_init(&ctx); if (error < 0) @@ -1024,10 +1019,10 @@ commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, v uint32_t word; unsigned int parentcount = (unsigned int)git_array_size(packed_commit->parents); - error - = git_buf_put(&commit_data, - (const char *)&packed_commit->tree_oid, - sizeof(git_oid)); + error = git_buf_put( + &commit_data, + (const char *)&packed_commit->tree_oid, + sizeof(git_oid)); if (error < 0) goto cleanup; @@ -1055,10 +1050,10 @@ commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, v word = htonl((uint32_t)( *git_array_get(packed_commit->parent_indices, parent_i) | (parent_i + 1 == parentcount ? 0x80000000u : 0))); - error - = git_buf_put(&extra_edge_list, - (const char *)&word, - sizeof(word)); + error = git_buf_put( + &extra_edge_list, + (const char *)&word, + sizeof(word)); if (error < 0) goto cleanup; } @@ -1122,10 +1117,7 @@ commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, v error = write_cb(git_buf_cstr(&commit_data), git_buf_len(&commit_data), cb_data); if (error < 0) goto cleanup; - error - = write_cb(git_buf_cstr(&extra_edge_list), - git_buf_len(&extra_edge_list), - cb_data); + error = write_cb(git_buf_cstr(&extra_edge_list), git_buf_len(&extra_edge_list), cb_data); if (error < 0) goto cleanup; @@ -1160,6 +1152,7 @@ int git_commit_graph_writer_commit( git_buf commit_graph_path = GIT_BUF_INIT; git_filebuf output = GIT_FILEBUF_INIT; + /* TODO: support options. */ GIT_UNUSED(opts); error = git_buf_joinpath( @@ -1188,6 +1181,7 @@ int git_commit_graph_writer_dump( git_commit_graph_writer *w, git_commit_graph_writer_options *opts) { + /* TODO: support options. */ GIT_UNUSED(opts); return commit_graph_write(w, commit_graph_write_buf, cgraph); } From a8098903cd39114b4daeae2311f3f517566105d7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 10 May 2020 17:04:54 +0100 Subject: [PATCH 0404/1616] .devcontainer: settings for a codespace workflow Add devcontainer settings for running within a codespace. --- .devcontainer/devcontainer.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000000..2731eabd342 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,3 @@ +{ + "postCreateCommand": "sudo apt-get update && sudo apt-get -y --no-install-recommends install cmake" +} From a7bc8de4e77d5c0fb6313d6fc42977543c9df5c4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 2 Aug 2021 21:25:08 +0000 Subject: [PATCH 0405/1616] Update VSCode / Github Codespaces workflow --- .devcontainer/devcontainer.json | 2 +- .devcontainer/setup.sh | 9 +++++++++ .vscode/launch.json | 27 +++++++++++++++++++++++++++ .vscode/tasks.json | 27 +++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100755 .devcontainer/setup.sh create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2731eabd342..bc6344b93df 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,3 +1,3 @@ { - "postCreateCommand": "sudo apt-get update && sudo apt-get -y --no-install-recommends install cmake" + "postCreateCommand": "bash .devcontainer/setup.sh" } diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh new file mode 100755 index 00000000000..c328bf3b98b --- /dev/null +++ b/.devcontainer/setup.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -e + +sudo apt-get update +sudo apt-get -y --no-install-recommends install cmake + +mkdir build +cd build +cmake .. \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000000..d47d93aab10 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,27 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/libgit2_clar", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000000..9618f450297 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,27 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build", + "type": "shell", + "command": "cd build && cmake --build .", + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "label": "Run Tests", + "type": "shell", + "command": "build/libgit2_clar -v", + "group": "test", + "presentation": { + "reveal": "always", + "panel": "new" + } + } + ] + } \ No newline at end of file From e43cfb68794b43797af579e0e82996f4c449d33c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 2 Aug 2021 21:30:08 +0000 Subject: [PATCH 0406/1616] VSCode: build in parallel --- .vscode/tasks.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9618f450297..64142d3410d 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -6,7 +6,7 @@ { "label": "Build", "type": "shell", - "command": "cd build && cmake --build .", + "command": "cd build && cmake --build . --parallel", "group": "build", "presentation": { "reveal": "always", From a5696702dbd8c7abbd37f083a411adecab7cedfe Mon Sep 17 00:00:00 2001 From: Alex Good Date: Thu, 8 Jul 2021 11:58:28 +0100 Subject: [PATCH 0407/1616] skip descendant check if remote ref not found --- src/remote.c | 4 +++- tests/remote/fetch.c | 23 ++++------------------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/remote.c b/src/remote.c index d17c3895187..ec68cc0f651 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1460,7 +1460,9 @@ static int update_tips_for_spec( if (error < 0 && error != GIT_ENOTFOUND) goto on_error; - if (!error && !spec->force && !git_graph_descendant_of(remote->repo, &head->oid, &old)) + if (!(error || error == GIT_ENOTFOUND) + && !spec->force + && !git_graph_descendant_of(remote->repo, &head->oid, &old)) continue; if (error == GIT_ENOTFOUND) { diff --git a/tests/remote/fetch.c b/tests/remote/fetch.c index 8a61a26721e..392801e0b33 100644 --- a/tests/remote/fetch.c +++ b/tests/remote/fetch.c @@ -13,33 +13,18 @@ static const char *REPO2_REFNAME = "refs/remotes/repo1/main"; static char *FORCE_FETCHSPEC = "+refs/heads/main:refs/remotes/repo1/main"; static char *NON_FORCE_FETCHSPEC = "refs/heads/main:refs/remotes/repo1/main"; -char* strip_trailing_slash(char *path) { - if (path[strlen(path) - 1] == '/') { - char* result = (char *) calloc(strlen(path) - 1, sizeof(char)); - memcpy(result, path, strlen(path) - 1); - return result; - } else { - char* result = (char *) calloc(strlen(path), sizeof(char)); - strncpy(result, path, strlen(path)); - return result; - } -} - - void test_remote_fetch__initialize(void) { git_config *c; git_buf repo1_path_buf = GIT_BUF_INIT; git_buf repo2_path_buf = GIT_BUF_INIT; const char *sandbox = clar_sandbox_path(); - cl_git_pass(git_buf_join(&repo1_path_buf, '/', sandbox, "fetchtest_repo1")); - repo1_path = calloc(repo1_path_buf.size, sizeof(char)); - git_buf_copy_cstr(repo1_path, repo1_path_buf.size, &repo1_path_buf); + cl_git_pass(git_buf_joinpath(&repo1_path_buf, sandbox, "fetchtest_repo1")); + repo1_path = git_buf_detach(&repo1_path_buf); cl_git_pass(git_repository_init(&repo1, repo1_path, true)); - cl_git_pass(git_buf_join(&repo2_path_buf, '/', sandbox, "fetchtest_repo2")); - repo2_path = calloc(repo2_path_buf.size, sizeof(char)); - git_buf_copy_cstr(repo2_path, repo2_path_buf.size, &repo2_path_buf); + cl_git_pass(git_buf_joinpath(&repo2_path_buf, sandbox, "fetchtest_repo2")); + repo2_path = git_buf_detach(&repo2_path_buf); cl_git_pass(git_repository_init(&repo2, repo2_path, true)); cl_git_pass(git_repository_config(&c, repo1)); From 28841241745bdc30be0ef78235f3c4ba38345590 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 5 Aug 2021 08:12:28 -0400 Subject: [PATCH 0408/1616] http: don't require a password Attempt authentication when a username is presented but a password is not; this can happen in particular when users are doing token authentication and specifying the token in the URL itself. For example, `https://token@host/` is a valid URI and should be treated as a username of `token` with an empty password. --- src/transports/http.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/transports/http.c b/src/transports/http.c index 4538dd143e4..9871be5ad7d 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -104,6 +104,11 @@ static int apply_url_credentials( const char *username, const char *password) { + GIT_ASSERT_ARG(username); + + if (!password) + password = ""; + if (allowed_types & GIT_CREDENTIAL_USERPASS_PLAINTEXT) return git_credential_userpass_plaintext_new(cred, username, password); @@ -138,8 +143,7 @@ static int handle_auth( /* Start with URL-specified credentials, if there were any. */ if ((allowed_credtypes & GIT_CREDENTIAL_USERPASS_PLAINTEXT) && !server->url_cred_presented && - server->url.username && - server->url.password) { + server->url.username) { error = apply_url_credentials(&server->cred, allowed_credtypes, server->url.username, server->url.password); server->url_cred_presented = 1; From e96fc0283aea9afd02f64bdcb26613422e74dc3a Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Sun, 8 Aug 2021 13:22:53 +0200 Subject: [PATCH 0409/1616] tests: optional test for p_open() with empty path segments --- .github/workflows/main.yml | 2 +- CMakeLists.txt | 1 + src/CMakeLists.txt | 5 +++++ src/features.h.in | 1 + src/posix.c | 7 +++++++ src/win32/posix_w32.c | 7 +++++++ 6 files changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2bc91e73c77..4615504bedc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -86,7 +86,7 @@ jobs: env: CC: gcc CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DDEBUG_STRICT_ALLOC=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DDEBUG_STRICT_ALLOC=ON -DDEBUG_STRICT_OPEN=ON os: ubuntu-latest - # Xenial, GCC, mbedTLS container: diff --git a/CMakeLists.txt b/CMakeLists.txt index ff3411928cf..937503829e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ OPTION(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)" OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF) OPTION(DEBUG_POOL "Enable debug pool allocator" OFF) OPTION(DEBUG_STRICT_ALLOC "Enable strict allocator behavior" OFF) +OPTION(DEBUG_STRICT_OPEN "Enable path validation in open" OFF) OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF) OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib. Can be set to one of Bundled(ON)/Chromium. The Chromium option requires a x86_64 processor with SSE4.2 and CLMUL" OFF) SET(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d3408999f97..54099c384b7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,6 +11,11 @@ IF(DEBUG_STRICT_ALLOC) ENDIF() ADD_FEATURE_INFO(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators") +IF(DEBUG_STRICT_OPEN) + SET(GIT_DEBUG_STRICT_OPEN 1) +ENDIF() +ADD_FEATURE_INFO(debugopen GIT_DEBUG_STRICT_OPEN "path validation in open") + INCLUDE(PkgBuildConfig) INCLUDE(SanitizeBool) diff --git a/src/features.h.in b/src/features.h.in index ab523f90bb6..21e5fdc072a 100644 --- a/src/features.h.in +++ b/src/features.h.in @@ -3,6 +3,7 @@ #cmakedefine GIT_DEBUG_POOL 1 #cmakedefine GIT_DEBUG_STRICT_ALLOC 1 +#cmakedefine GIT_DEBUG_STRICT_OPEN 1 #cmakedefine GIT_TRACE 1 #cmakedefine GIT_THREADS 1 diff --git a/src/posix.c b/src/posix.c index bf764ae6b67..c40134824a4 100644 --- a/src/posix.c +++ b/src/posix.c @@ -109,6 +109,13 @@ int p_open(const char *path, volatile int flags, ...) { mode_t mode = 0; + #ifdef GIT_DEBUG_STRICT_OPEN + if (strstr(path, "//") != NULL) { + errno = EACCES; + return -1; + } + #endif + if (flags & O_CREAT) { va_list arg_list; diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index 0a8f2bee07f..7fcc472e970 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -543,6 +543,13 @@ int p_open(const char *path, int flags, ...) mode_t mode = 0; struct open_opts opts = {0}; + #ifdef GIT_DEBUG_STRICT_OPEN + if (strstr(path, "//") != NULL) { + errno = EACCES; + return -1; + } + #endif + if (git_win32_path_from_utf8(wpath, path) < 0) return -1; From d095502ed797e20a73a00b65cc9d70d91f7d7ab4 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Sun, 8 Aug 2021 13:34:06 +0200 Subject: [PATCH 0410/1616] tests: don't generate false positives on empty path segments --- tests/iterator/workdir.c | 2 +- tests/merge/workdir/setup.c | 4 ++-- tests/odb/foreach.c | 2 +- tests/worktree/merge.c | 6 +++--- tests/worktree/worktree.c | 17 +++++++++-------- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/tests/iterator/workdir.c b/tests/iterator/workdir.c index 547fb7d9577..82ee363f9f7 100644 --- a/tests/iterator/workdir.c +++ b/tests/iterator/workdir.c @@ -1024,7 +1024,7 @@ static void create_paths(const char *root, int depth) int i; cl_git_pass(git_buf_puts(&fullpath, root)); - cl_git_pass(git_buf_putc(&fullpath, '/')); + cl_git_pass(git_path_to_dir(&fullpath)); root_len = fullpath.size; diff --git a/tests/merge/workdir/setup.c b/tests/merge/workdir/setup.c index ad29fcd9424..0b85f271244 100644 --- a/tests/merge/workdir/setup.c +++ b/tests/merge/workdir/setup.c @@ -49,7 +49,7 @@ static bool test_file_contents(const char *filename, const char *expected) git_buf file_path_buf = GIT_BUF_INIT, file_buf = GIT_BUF_INIT; bool equals; - git_buf_printf(&file_path_buf, "%s/%s", git_repository_path(repo), filename); + git_buf_joinpath(&file_path_buf, git_repository_path(repo), filename); cl_git_pass(git_futils_readbuffer(&file_buf, file_path_buf.ptr)); equals = (strcmp(file_buf.ptr, expected) == 0); @@ -64,7 +64,7 @@ static void write_file_contents(const char *filename, const char *output) { git_buf file_path_buf = GIT_BUF_INIT; - git_buf_printf(&file_path_buf, "%s/%s", git_repository_path(repo), + git_buf_joinpath(&file_path_buf, git_repository_path(repo), filename); cl_git_rewritefile(file_path_buf.ptr, output); diff --git a/tests/odb/foreach.c b/tests/odb/foreach.c index 7a45a57ae93..02112380b80 100644 --- a/tests/odb/foreach.c +++ b/tests/odb/foreach.c @@ -127,7 +127,7 @@ void test_odb_foreach__files_in_objects_dir(void) cl_fixture_sandbox("testrepo.git"); cl_git_pass(git_repository_open(&repo, "testrepo.git")); - cl_git_pass(git_buf_printf(&buf, "%s/objects/somefile", git_repository_path(repo))); + cl_git_pass(git_buf_joinpath(&buf, git_repository_path(repo), "objects/somefile")); cl_git_mkfile(buf.ptr, ""); git_buf_dispose(&buf); diff --git a/tests/worktree/merge.c b/tests/worktree/merge.c index 4b743829cd8..2a1206032c8 100644 --- a/tests/worktree/merge.c +++ b/tests/worktree/merge.c @@ -70,9 +70,9 @@ void test_worktree_merge__merge_setup(void) ours, (const git_annotated_commit **)&theirs, 1)); for (i = 0; i < ARRAY_SIZE(merge_files); i++) { - git_buf_clear(&path); - cl_git_pass(git_buf_printf(&path, "%s/%s", - fixture.worktree->gitdir, merge_files[i])); + cl_git_pass(git_buf_joinpath(&path, + fixture.worktree->gitdir, + merge_files[i])); cl_assert(git_path_exists(path.ptr)); } diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index f2078a3f925..9b87bfae64f 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -44,8 +44,9 @@ void test_worktree_worktree__list_with_invalid_worktree_dirs(void) git_strarray wts; size_t i, j, len; - cl_git_pass(git_buf_printf(&path, "%s/worktrees/invalid", - fixture.repo->commondir)); + cl_git_pass(git_buf_joinpath(&path, + fixture.repo->commondir, + "worktrees/invalid")); cl_git_pass(p_mkdir(path.ptr, 0755)); len = path.size; @@ -145,9 +146,9 @@ void test_worktree_worktree__open_invalid_commondir(void) git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT; cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/commondir")); - cl_git_pass(git_buf_printf(&path, - "%s/worktrees/testrepo-worktree/commondir", - fixture.repo->commondir)); + cl_git_pass(git_buf_joinpath(&path, + fixture.repo->commondir, + "worktrees/testrepo-worktree/commondir")); cl_git_pass(git_futils_writebuffer(&buf, path.ptr, O_RDWR, 0644)); cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); @@ -165,9 +166,9 @@ void test_worktree_worktree__open_invalid_gitdir(void) git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT; cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/gitdir")); - cl_git_pass(git_buf_printf(&path, - "%s/worktrees/testrepo-worktree/gitdir", - fixture.repo->commondir)); + cl_git_pass(git_buf_joinpath(&path, + fixture.repo->commondir, + "worktrees/testrepo-worktree/gitdir")); cl_git_pass(git_futils_writebuffer(&buf, path.ptr, O_RDWR, 0644)); cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); From 4584660e11ee5fd6e9fb44b0d00bf7cb8df8edb4 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Sun, 8 Aug 2021 12:13:16 +0200 Subject: [PATCH 0411/1616] bugfix: don't generate paths with empty segments --- src/refdb_fs.c | 5 +++-- src/worktree.c | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 0b8e103c211..7cf48b13ddc 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -578,7 +578,7 @@ static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter) } } - if ((error = git_buf_printf(&path, "%s/", backend->commonpath)) < 0 || + if ((error = git_buf_puts(&path, backend->commonpath)) < 0 || (error = git_buf_put(&path, ref_prefix, ref_prefix_len)) < 0) { git_buf_dispose(&path); return error; @@ -1609,8 +1609,9 @@ static char *setup_namespace(git_repository *repo, const char *in) GIT_MKDIR_PATH, NULL) < 0) goto done; - /* Return root of the namespaced gitpath, i.e. without the trailing '/refs' */ + /* Return root of the namespaced gitpath, i.e. without the trailing 'refs' */ git_buf_rtruncate_at_char(&path, '/'); + git_buf_putc(&path, '/'); out = git_buf_detach(&path); done: diff --git a/src/worktree.c b/src/worktree.c index 0bced6d4a65..fe8db774305 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -43,7 +43,7 @@ int git_worktree_list(git_strarray *wts, git_repository *repo) wts->count = 0; wts->strings = NULL; - if ((error = git_buf_printf(&path, "%s/worktrees/", repo->commondir)) < 0) + if ((error = git_buf_joinpath(&path, repo->commondir, "worktrees/")) < 0) goto exit; if (!git_path_exists(path.ptr) || git_path_is_empty_dir(path.ptr)) goto exit; @@ -182,7 +182,7 @@ int git_worktree_lookup(git_worktree **out, git_repository *repo, const char *na *out = NULL; - if ((error = git_buf_printf(&path, "%s/worktrees/%s", repo->commondir, name)) < 0) + if ((error = git_buf_join3(&path, '/', repo->commondir, "worktrees", name)) < 0) goto out; if ((error = (open_worktree_dir(out, git_repository_workdir(repo), path.ptr, name))) < 0) @@ -592,7 +592,7 @@ int git_worktree_prune(git_worktree *wt, } /* Delete gitdir in parent repository */ - if ((err = git_buf_printf(&path, "%s/worktrees/%s", wt->commondir_path, wt->name)) < 0) + if ((err = git_buf_join3(&path, '/', wt->commondir_path, "worktrees", wt->name)) < 0) goto out; if (!git_path_exists(path.ptr)) { From 2c2cb3f3ecfac356bd5168125b1afd718aef6917 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Sun, 8 Aug 2021 14:35:07 +0200 Subject: [PATCH 0412/1616] amiga: use ';' as path list separator on AmigaOS Like on Windows ':' is used for volume names in absolute paths. --- include/git2/common.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/git2/common.h b/include/git2/common.h index 4402dfda804..d278c01b6ff 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -91,10 +91,10 @@ GIT_BEGIN_DECL /** * The separator used in path list strings (ie like in the PATH - * environment variable). A semi-colon ";" is used on Windows, and - * a colon ":" for all other systems. + * environment variable). A semi-colon ";" is used on Windows and + * AmigaOS, and a colon ":" for all other systems. */ -#ifdef GIT_WIN32 +#if defined(GIT_WIN32) || defined(AMIGA) #define GIT_PATH_LIST_SEPARATOR ';' #else #define GIT_PATH_LIST_SEPARATOR ':' From 9eb17d460cd681bbc14d56ed8fdf440bc69b5456 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 16 Feb 2021 19:38:34 -0800 Subject: [PATCH 0413/1616] Introduce GIT_WARN_UNUSED_RESULT This change adds the GIT_WARN_UNUSED_RESULT annotation, which makes the compiler warn when a return result is not used. This avoids bugs. --- include/git2/common.h | 7 +++++++ src/sortedcache.h | 28 ++++++++++++++++------------ src/vector.h | 6 ++++-- tests/core/vector.c | 12 ++++++------ tests/fetchhead/nonetwork.c | 2 +- 5 files changed, 34 insertions(+), 21 deletions(-) diff --git a/include/git2/common.h b/include/git2/common.h index 4402dfda804..5f64a37f8c9 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -71,6 +71,13 @@ typedef size_t size_t; # define GIT_FORMAT_PRINTF(a,b) /* empty */ #endif +/** Declare that a function's return value must be used. */ +#if defined(__GNUC__) +# define GIT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +# define GIT_WARN_UNUSED_RESULT +#endif + #if (defined(_WIN32)) && !defined(__CYGWIN__) #define GIT_WIN32 1 #endif diff --git a/src/sortedcache.h b/src/sortedcache.h index ca8b106743a..eb74be9e563 100644 --- a/src/sortedcache.h +++ b/src/sortedcache.h @@ -58,7 +58,7 @@ typedef struct { * may be NULL. The cache makes it easy to load this and check * if it has been modified since the last load and/or write. */ -int git_sortedcache_new( +GIT_WARN_UNUSED_RESULT int git_sortedcache_new( git_sortedcache **out, size_t item_path_offset, /* use offsetof(struct, path-field) macro */ git_sortedcache_free_item_fn free_item, @@ -71,7 +71,7 @@ int git_sortedcache_new( * - `copy_item` can be NULL to just use memcpy * - if `lock`, grabs read lock on `src` during copy and releases after */ -int git_sortedcache_copy( +GIT_WARN_UNUSED_RESULT int git_sortedcache_copy( git_sortedcache **out, git_sortedcache *src, bool lock, @@ -88,7 +88,7 @@ void git_sortedcache_free(git_sortedcache *sc); void git_sortedcache_incref(git_sortedcache *sc); /* Get the pathname associated with this cache at creation time */ -const char *git_sortedcache_path(git_sortedcache *sc); +GIT_WARN_UNUSED_RESULT const char *git_sortedcache_path(git_sortedcache *sc); /* * CACHE WRITE FUNCTIONS @@ -100,7 +100,7 @@ const char *git_sortedcache_path(git_sortedcache *sc); */ /* Lock sortedcache for write */ -int git_sortedcache_wlock(git_sortedcache *sc); +GIT_WARN_UNUSED_RESULT int git_sortedcache_wlock(git_sortedcache *sc); /* Unlock sorted cache when done with write */ void git_sortedcache_wunlock(git_sortedcache *sc); @@ -120,7 +120,8 @@ void git_sortedcache_wunlock(git_sortedcache *sc); * * @return 0 if up-to-date, 1 if out-of-date, <0 on error */ -int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf); +GIT_WARN_UNUSED_RESULT int git_sortedcache_lockandload( + git_sortedcache *sc, git_buf *buf); /* Refresh file timestamp after write completes * You should already be holding the write lock when you call this. @@ -137,13 +138,13 @@ int git_sortedcache_clear(git_sortedcache *sc, bool wlock); /* Find and/or insert item, returning pointer to item data. * You should already be holding the write lock when you call this. */ -int git_sortedcache_upsert( +GIT_WARN_UNUSED_RESULT int git_sortedcache_upsert( void **out, git_sortedcache *sc, const char *key); /* Removes entry at pos from cache * You should already be holding the write lock when you call this. */ -int git_sortedcache_remove(git_sortedcache *sc, size_t pos); +GIT_WARN_UNUSED_RESULT int git_sortedcache_remove(git_sortedcache *sc, size_t pos); /* * CACHE READ FUNCTIONS @@ -155,26 +156,29 @@ int git_sortedcache_remove(git_sortedcache *sc, size_t pos); */ /* Lock sortedcache for read */ -int git_sortedcache_rlock(git_sortedcache *sc); +GIT_WARN_UNUSED_RESULT int git_sortedcache_rlock(git_sortedcache *sc); /* Unlock sorted cache when done with read */ void git_sortedcache_runlock(git_sortedcache *sc); /* Lookup item by key - returns NULL if not found */ -void *git_sortedcache_lookup(const git_sortedcache *sc, const char *key); +GIT_WARN_UNUSED_RESULT void *git_sortedcache_lookup( + const git_sortedcache *sc, const char *key); /* Get how many items are in the cache * * You can call this function without holding a lock, but be aware * that it may change before you use it. */ -size_t git_sortedcache_entrycount(const git_sortedcache *sc); +GIT_WARN_UNUSED_RESULT size_t git_sortedcache_entrycount( + const git_sortedcache *sc); /* Lookup item by index - returns NULL if out of range */ -void *git_sortedcache_entry(git_sortedcache *sc, size_t pos); +GIT_WARN_UNUSED_RESULT void *git_sortedcache_entry( + git_sortedcache *sc, size_t pos); /* Lookup index of item by key - returns GIT_ENOTFOUND if not found */ -int git_sortedcache_lookup_index( +GIT_WARN_UNUSED_RESULT int git_sortedcache_lookup_index( size_t *out, git_sortedcache *sc, const char *key); #endif diff --git a/src/vector.h b/src/vector.h index cc4c314d5a3..3dcec3d1319 100644 --- a/src/vector.h +++ b/src/vector.h @@ -26,11 +26,13 @@ typedef struct git_vector { #define GIT_VECTOR_INIT {0} -int git_vector_init(git_vector *v, size_t initial_size, git_vector_cmp cmp); +GIT_WARN_UNUSED_RESULT int git_vector_init( + git_vector *v, size_t initial_size, git_vector_cmp cmp); void git_vector_free(git_vector *v); void git_vector_free_deep(git_vector *v); /* free each entry and self */ void git_vector_clear(git_vector *v); -int git_vector_dup(git_vector *v, const git_vector *src, git_vector_cmp cmp); +GIT_WARN_UNUSED_RESULT int git_vector_dup( + git_vector *v, const git_vector *src, git_vector_cmp cmp); void git_vector_swap(git_vector *a, git_vector *b); int git_vector_size_hint(git_vector *v, size_t size_hint); diff --git a/tests/core/vector.c b/tests/core/vector.c index a7e1a03257c..08cd2c19bf9 100644 --- a/tests/core/vector.c +++ b/tests/core/vector.c @@ -8,7 +8,7 @@ void test_core_vector__0(void) { git_vector x; int i; - git_vector_init(&x, 1, NULL); + cl_git_pass(git_vector_init(&x, 1, NULL)); for (i = 0; i < 10; ++i) { git_vector_insert(&x, (void*) 0xabc); } @@ -21,7 +21,7 @@ void test_core_vector__1(void) { git_vector x; /* make initial capacity exact for our insertions. */ - git_vector_init(&x, 3, NULL); + cl_git_pass(git_vector_init(&x, 3, NULL)); git_vector_insert(&x, (void*) 0xabc); git_vector_insert(&x, (void*) 0xdef); git_vector_insert(&x, (void*) 0x123); @@ -76,7 +76,7 @@ void test_core_vector__3(void) { git_vector x; intptr_t i; - git_vector_init(&x, 1, &compare_them); + cl_git_pass(git_vector_init(&x, 1, &compare_them)); for (i = 0; i < 10; i += 2) { git_vector_insert_sorted(&x, (void*)(i + 1), NULL); @@ -99,7 +99,7 @@ void test_core_vector__4(void) { git_vector x; intptr_t i; - git_vector_init(&x, 1, &compare_them); + cl_git_pass(git_vector_init(&x, 1, &compare_them)); for (i = 0; i < 10; i += 2) { git_vector_insert_sorted(&x, (void*)(i + 1), NULL); @@ -163,7 +163,7 @@ void test_core_vector__5(void) git_vector x; int i; - git_vector_init(&x, 1, &compare_structs); + cl_git_pass(git_vector_init(&x, 1, &compare_structs)); for (i = 0; i < 10; i += 2) git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs); @@ -205,7 +205,7 @@ void test_core_vector__remove_matching(void) size_t i; void *compare; - git_vector_init(&x, 1, NULL); + cl_git_pass(git_vector_init(&x, 1, NULL)); git_vector_insert(&x, (void*) 0x001); cl_assert(x.length == 1); diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c index 02e7ecfdb1a..6881af40a00 100644 --- a/tests/fetchhead/nonetwork.c +++ b/tests/fetchhead/nonetwork.c @@ -82,7 +82,7 @@ void test_fetchhead_nonetwork__write(void) int equals = 0; size_t i; - git_vector_init(&fetchhead_vector, 6, NULL); + cl_git_pass(git_vector_init(&fetchhead_vector, 6, NULL)); cl_set_cleanup(&cleanup_repository, "./test1"); cl_git_pass(git_repository_init(&g_repo, "./test1", 0)); From 231ca4fad36ce7b3dd5d79b599be46ab6001fc18 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 23 Feb 2021 19:33:34 -0800 Subject: [PATCH 0414/1616] Proof-of-concept for a more aggressive GIT_UNUSED() This adds a `-Wunused-result`-proof `GIT_UNUSED()`, just to demonstrate that it works. With this, sortedcache.h is now completely `GIT_WARN_UNUSED_RESULT`-annotated! --- src/cc-compat.h | 10 +++++++++- src/odb.c | 4 ++-- src/refdb_fs.c | 6 +++--- src/sortedcache.h | 3 ++- tests/core/sha1.c | 2 +- tests/core/sortedcache.c | 6 +++--- tests/index/addall.c | 4 +--- tests/index/bypath.c | 5 +---- 8 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/cc-compat.h b/src/cc-compat.h index de1469da85a..21f321124a6 100644 --- a/src/cc-compat.h +++ b/src/cc-compat.h @@ -43,7 +43,15 @@ # define GIT_ALIGN(x,size) x #endif -#define GIT_UNUSED(x) ((void)(x)) +#if defined(__GNUC__) +# define GIT_UNUSED(x) \ + do { \ + typeof(x) _unused __attribute__((unused)); \ + _unused = (x); \ + } while (0) +#else +# define GIT_UNUSED(x) ((void)(x)) +#endif /* Define the printf format specifier to use for size_t output */ #if defined(_MSC_VER) || defined(__MINGW32__) diff --git a/src/odb.c b/src/odb.c index 22c8c8c871f..e3a5381e640 100644 --- a/src/odb.c +++ b/src/odb.c @@ -573,7 +573,7 @@ int git_odb__add_default_backends( git_odb *db, const char *objects_dir, bool as_alternates, int alternate_depth) { - size_t i; + size_t i = 0; struct stat st; ino_t inode; git_odb_backend *loose, *packed; @@ -582,7 +582,7 @@ int git_odb__add_default_backends( * a cross-platform workaround for this */ #ifdef GIT_WIN32 GIT_UNUSED(i); - GIT_UNUSED(st); + GIT_UNUSED(&st); inode = 0; #else diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 0b8e103c211..82977cc2c67 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -122,7 +122,7 @@ static int packed_reload(refdb_fs_backend *backend) */ if (error <= 0) { if (error == GIT_ENOTFOUND) { - git_sortedcache_clear(backend->refcache, true); + GIT_UNUSED(git_sortedcache_clear(backend->refcache, true)); git_error_clear(); error = 0; } @@ -131,7 +131,7 @@ static int packed_reload(refdb_fs_backend *backend) /* At this point, refresh the packed refs from the loaded buffer. */ - git_sortedcache_clear(backend->refcache, false); + GIT_UNUSED(git_sortedcache_clear(backend->refcache, false)); scan = (char *)packedrefs.ptr; eof = scan + packedrefs.size; @@ -219,7 +219,7 @@ static int packed_reload(refdb_fs_backend *backend) parse_failed: git_error_set(GIT_ERROR_REFERENCE, "corrupted packed references file"); - git_sortedcache_clear(backend->refcache, false); + GIT_UNUSED(git_sortedcache_clear(backend->refcache, false)); git_sortedcache_wunlock(backend->refcache); git_buf_dispose(&packedrefs); diff --git a/src/sortedcache.h b/src/sortedcache.h index eb74be9e563..777b28bdaea 100644 --- a/src/sortedcache.h +++ b/src/sortedcache.h @@ -133,7 +133,8 @@ void git_sortedcache_updated(git_sortedcache *sc); * If `wlock` is true, grabs write lock and releases when done, otherwise * you should already be holding a write lock when you call this. */ -int git_sortedcache_clear(git_sortedcache *sc, bool wlock); +GIT_WARN_UNUSED_RESULT int git_sortedcache_clear( + git_sortedcache *sc, bool wlock); /* Find and/or insert item, returning pointer to item data. * You should already be holding the write lock when you call this. diff --git a/tests/core/sha1.c b/tests/core/sha1.c index f81d4085448..196b003525f 100644 --- a/tests/core/sha1.c +++ b/tests/core/sha1.c @@ -52,7 +52,7 @@ void test_core_sha1__detect_collision_attack(void) git_oid oid, expected; #ifdef GIT_SHA1_COLLISIONDETECT - GIT_UNUSED(expected); + GIT_UNUSED(&expected); cl_git_fail(sha1_file(&oid, FIXTURE_DIR "/shattered-1.pdf")); cl_assert_equal_s("SHA1 collision attack detected", git_error_last()->message); #else diff --git a/tests/core/sortedcache.c b/tests/core/sortedcache.c index 35e92ece9ce..d5bbcea19f2 100644 --- a/tests/core/sortedcache.c +++ b/tests/core/sortedcache.c @@ -54,7 +54,7 @@ void test_core_sortedcache__name_only(void) cl_assert_equal_i( GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "abc")); - git_sortedcache_clear(sc, true); + cl_git_pass(git_sortedcache_clear(sc, true)); cl_assert_equal_sz(0, git_sortedcache_entrycount(sc)); cl_assert(git_sortedcache_entry(sc, 0) == NULL); @@ -154,7 +154,7 @@ void test_core_sortedcache__in_memory(void) cl_assert_equal_i(0, free_count); - git_sortedcache_clear(sc, true); + cl_git_pass(git_sortedcache_clear(sc, true)); cl_assert_equal_i(5, free_count); @@ -247,7 +247,7 @@ static void sortedcache_test_reload(git_sortedcache *sc) cl_assert(git_sortedcache_lockandload(sc, &buf) > 0); - git_sortedcache_clear(sc, false); /* clear once we already have lock */ + cl_git_pass(git_sortedcache_clear(sc, false)); /* clear once we already have lock */ for (scan = buf.ptr; *scan; scan = after + 1) { int val = strtol(scan, &after, 0); diff --git a/tests/index/addall.c b/tests/index/addall.c index d1ef31dafe2..6f95f6386f4 100644 --- a/tests/index/addall.c +++ b/tests/index/addall.c @@ -318,11 +318,9 @@ void test_index_addall__files_in_folders(void) void test_index_addall__hidden_files(void) { +#ifdef GIT_WIN32 git_index *index; - GIT_UNUSED(index); - -#ifdef GIT_WIN32 addall_create_test_repo(true); cl_git_pass(git_repository_index(&index, g_repo)); diff --git a/tests/index/bypath.c b/tests/index/bypath.c index 21d3d3ed0b2..b32a0a789e6 100644 --- a/tests/index/bypath.c +++ b/tests/index/bypath.c @@ -49,13 +49,10 @@ void test_index_bypath__add_submodule_unregistered(void) void test_index_bypath__add_hidden(void) { +#ifdef GIT_WIN32 const git_index_entry *entry; bool hidden; - GIT_UNUSED(entry); - GIT_UNUSED(hidden); - -#ifdef GIT_WIN32 cl_git_mkfile("submod2/hidden_file", "you can't see me"); cl_git_pass(git_win32__hidden(&hidden, "submod2/hidden_file")); From 4bb1568f22b03642cc160aecab1c1e15093ec748 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Thu, 4 Mar 2021 06:14:36 -0800 Subject: [PATCH 0415/1616] Be a little bit less aggressive GIT_WARN_UNUSED_RESULT Now we're limiting ourselves to only functions that allocate or acquire locks. --- src/sortedcache.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/sortedcache.h b/src/sortedcache.h index 777b28bdaea..0e1f63ceb00 100644 --- a/src/sortedcache.h +++ b/src/sortedcache.h @@ -88,7 +88,7 @@ void git_sortedcache_free(git_sortedcache *sc); void git_sortedcache_incref(git_sortedcache *sc); /* Get the pathname associated with this cache at creation time */ -GIT_WARN_UNUSED_RESULT const char *git_sortedcache_path(git_sortedcache *sc); +const char *git_sortedcache_path(git_sortedcache *sc); /* * CACHE WRITE FUNCTIONS @@ -145,7 +145,7 @@ GIT_WARN_UNUSED_RESULT int git_sortedcache_upsert( /* Removes entry at pos from cache * You should already be holding the write lock when you call this. */ -GIT_WARN_UNUSED_RESULT int git_sortedcache_remove(git_sortedcache *sc, size_t pos); +int git_sortedcache_remove(git_sortedcache *sc, size_t pos); /* * CACHE READ FUNCTIONS @@ -163,23 +163,20 @@ GIT_WARN_UNUSED_RESULT int git_sortedcache_rlock(git_sortedcache *sc); void git_sortedcache_runlock(git_sortedcache *sc); /* Lookup item by key - returns NULL if not found */ -GIT_WARN_UNUSED_RESULT void *git_sortedcache_lookup( - const git_sortedcache *sc, const char *key); +void *git_sortedcache_lookup(const git_sortedcache *sc, const char *key); /* Get how many items are in the cache * * You can call this function without holding a lock, but be aware * that it may change before you use it. */ -GIT_WARN_UNUSED_RESULT size_t git_sortedcache_entrycount( - const git_sortedcache *sc); +size_t git_sortedcache_entrycount(const git_sortedcache *sc); /* Lookup item by index - returns NULL if out of range */ -GIT_WARN_UNUSED_RESULT void *git_sortedcache_entry( - git_sortedcache *sc, size_t pos); +void *git_sortedcache_entry(git_sortedcache *sc, size_t pos); /* Lookup index of item by key - returns GIT_ENOTFOUND if not found */ -GIT_WARN_UNUSED_RESULT int git_sortedcache_lookup_index( +int git_sortedcache_lookup_index( size_t *out, git_sortedcache *sc, const char *key); #endif From 7488705d45161fa8c6945a67570ac8d9fc2d7bfc Mon Sep 17 00:00:00 2001 From: lhchavez Date: Thu, 4 Mar 2021 06:19:49 -0800 Subject: [PATCH 0416/1616] Add guidelines for the GIT_WARN_UNUSED_RESULT annotation --- include/git2/common.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/include/git2/common.h b/include/git2/common.h index 5f64a37f8c9..a6069e36ecd 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -71,7 +71,18 @@ typedef size_t size_t; # define GIT_FORMAT_PRINTF(a,b) /* empty */ #endif -/** Declare that a function's return value must be used. */ +/** + * Declare that a function's return value must be used. + * + * Used mostly to guard against potential silent bugs at runtime. This is + * recommended to be added to functions that: + * + * - Allocate / reallocate memory. This prevents memory leaks or errors where + * buffers are expected to have grown to a certain size, but could not be + * resized. + * - Acquire locks. When a lock cannot be acquired, that will almost certainly + * cause a data race / undefined behavior. + */ #if defined(__GNUC__) # define GIT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) #else From c4cbab3201a1b5e75f6ef28e724956a36cb66dc0 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Fri, 30 Jul 2021 06:33:56 -0700 Subject: [PATCH 0417/1616] Handle one more unused variable introduced since the PR started --- src/path.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/path.c b/src/path.c index 8928e49b832..ec573220e90 100644 --- a/src/path.c +++ b/src/path.c @@ -1915,7 +1915,13 @@ GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) } #else -# define should_validate_longpaths(repo) (GIT_UNUSED(repo), false) + +GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) +{ + GIT_UNUSED(repo); + + return false; +} #endif int git_path_validate_workdir(git_repository *repo, const char *path) From 4e8376a98cedf82f9e5f5e1acbabba031ed7130c Mon Sep 17 00:00:00 2001 From: lhchavez Date: Fri, 30 Jul 2021 06:34:15 -0700 Subject: [PATCH 0418/1616] Move GIT_WARN_UNUSED_RESULT from the public to the private API --- include/git2/common.h | 18 ------------------ src/common.h | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/git2/common.h b/include/git2/common.h index a6069e36ecd..4402dfda804 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -71,24 +71,6 @@ typedef size_t size_t; # define GIT_FORMAT_PRINTF(a,b) /* empty */ #endif -/** - * Declare that a function's return value must be used. - * - * Used mostly to guard against potential silent bugs at runtime. This is - * recommended to be added to functions that: - * - * - Allocate / reallocate memory. This prevents memory leaks or errors where - * buffers are expected to have grown to a certain size, but could not be - * resized. - * - Acquire locks. When a lock cannot be acquired, that will almost certainly - * cause a data race / undefined behavior. - */ -#if defined(__GNUC__) -# define GIT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -# define GIT_WARN_UNUSED_RESULT -#endif - #if (defined(_WIN32)) && !defined(__CYGWIN__) #define GIT_WIN32 1 #endif diff --git a/src/common.h b/src/common.h index f83eeb69e72..a7c6e8e297a 100644 --- a/src/common.h +++ b/src/common.h @@ -135,6 +135,24 @@ GIT_INLINE(int) git_error__check_version(const void *structure, unsigned int exp } #define GIT_ERROR_CHECK_VERSION(S,V,N) if (git_error__check_version(S,V,N) < 0) return -1 +/** + * Declare that a function's return value must be used. + * + * Used mostly to guard against potential silent bugs at runtime. This is + * recommended to be added to functions that: + * + * - Allocate / reallocate memory. This prevents memory leaks or errors where + * buffers are expected to have grown to a certain size, but could not be + * resized. + * - Acquire locks. When a lock cannot be acquired, that will almost certainly + * cause a data race / undefined behavior. + */ +#if defined(__GNUC__) +# define GIT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +# define GIT_WARN_UNUSED_RESULT +#endif + /** * Initialize a structure with a version. */ From b060080e9f036ab45b86d5d37473a8ec49c29acf Mon Sep 17 00:00:00 2001 From: lhchavez Date: Fri, 30 Jul 2021 06:53:49 -0700 Subject: [PATCH 0419/1616] Get Win32 builds to build Previously, the location of `GIT_WARN_UNUSED_RESULT` was causing it to be included _after_ a bunch of other headers (namely `src/vector.h`), which broke the build. This change does two things: * Moves the `GIT_WARN_UNUSED_RESULT` above most of the `$include`s in `src/common.h`. * Stops including `vector.h` from `src/win32/path_w32.c` since the header itself does not use it. --- src/common.h | 36 ++++++++++++++++++------------------ src/win32/path_w32.h | 1 - 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/common.h b/src/common.h index a7c6e8e297a..9bb1116b531 100644 --- a/src/common.h +++ b/src/common.h @@ -30,6 +30,24 @@ # define __has_builtin(x) 0 #endif +/** + * Declare that a function's return value must be used. + * + * Used mostly to guard against potential silent bugs at runtime. This is + * recommended to be added to functions that: + * + * - Allocate / reallocate memory. This prevents memory leaks or errors where + * buffers are expected to have grown to a certain size, but could not be + * resized. + * - Acquire locks. When a lock cannot be acquired, that will almost certainly + * cause a data race / undefined behavior. + */ +#if defined(__GNUC__) +# define GIT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +# define GIT_WARN_UNUSED_RESULT +#endif + #include #include #include @@ -135,24 +153,6 @@ GIT_INLINE(int) git_error__check_version(const void *structure, unsigned int exp } #define GIT_ERROR_CHECK_VERSION(S,V,N) if (git_error__check_version(S,V,N) < 0) return -1 -/** - * Declare that a function's return value must be used. - * - * Used mostly to guard against potential silent bugs at runtime. This is - * recommended to be added to functions that: - * - * - Allocate / reallocate memory. This prevents memory leaks or errors where - * buffers are expected to have grown to a certain size, but could not be - * resized. - * - Acquire locks. When a lock cannot be acquired, that will almost certainly - * cause a data race / undefined behavior. - */ -#if defined(__GNUC__) -# define GIT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -# define GIT_WARN_UNUSED_RESULT -#endif - /** * Initialize a structure with a version. */ diff --git a/src/win32/path_w32.h b/src/win32/path_w32.h index dab8b96fa79..4fadf8d0848 100644 --- a/src/win32/path_w32.h +++ b/src/win32/path_w32.h @@ -8,7 +8,6 @@ #define INCLUDE_win32_path_w32_h__ #include "common.h" -#include "vector.h" /** * Create a Win32 path (in UCS-2 format) from a UTF-8 string. If the given From 991ccdc5bd2f42669389a0cad7c4cb816615da67 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sun, 1 Aug 2021 06:19:15 -0700 Subject: [PATCH 0420/1616] formatting --- src/cc-compat.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc-compat.h b/src/cc-compat.h index 21f321124a6..6bdc6514526 100644 --- a/src/cc-compat.h +++ b/src/cc-compat.h @@ -44,10 +44,10 @@ #endif #if defined(__GNUC__) -# define GIT_UNUSED(x) \ - do { \ - typeof(x) _unused __attribute__((unused)); \ - _unused = (x); \ +# define GIT_UNUSED(x) \ + do { \ + typeof(x) _unused __attribute__((unused)); \ + _unused = (x); \ } while (0) #else # define GIT_UNUSED(x) ((void)(x)) From b140e22e2e4e0bb47eea39485a5501497462023a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 8 Aug 2021 11:07:43 -0400 Subject: [PATCH 0421/1616] ci: remove the docker entrypoint Omitting an entrypoint.sh to configure the container and instead depending on docker primitives allows us to be more portable. (If a distribution uses a different mechanism for adding users, we need not have multiple entrypoint.sh files or invariants within it; instead we can configure that in the dockerfile itself along with all the other distribution specific components.) --- .github/workflows/main.yml | 20 +++++++++++--------- .github/workflows/nightly.yml | 12 +++++++----- ci/docker/bionic | 9 ++++----- ci/docker/entrypoint.sh | 4 ---- ci/docker/focal | 9 ++++----- ci/docker/xenial | 9 ++++----- 6 files changed, 30 insertions(+), 33 deletions(-) delete mode 100644 ci/docker/entrypoint.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2bc91e73c77..7d9c46eebdb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,7 +11,7 @@ on: env: docker-registry: docker.pkg.github.com - docker-config-path: ci/docker + docker-config-path: source/ci/docker jobs: # Build the docker container images that we will use for our Linux @@ -55,7 +55,7 @@ jobs: if: matrix.container.qemu == true - name: Download existing container run: | - "${{ github.workspace }}/ci/getcontainer.sh" "${{ matrix.container.name }}" "${{ matrix.container.dockerfile }}" + "${{ github.workspace }}/source/ci/getcontainer.sh" "${{ matrix.container.name }}" "${{ matrix.container.dockerfile }}" env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} @@ -206,9 +206,10 @@ jobs: - name: Check out repository uses: actions/checkout@v2 with: + path: source fetch-depth: 0 - name: Set up build environment - run: ci/setup-${{ matrix.platform.setup-script }}.sh + run: source/ci/setup-${{ matrix.platform.setup-script }}.sh shell: bash if: matrix.platform.setup-script != '' - name: Setup QEMU @@ -216,7 +217,7 @@ jobs: if: matrix.platform.container.qemu == true - name: Download container run: | - "${{ github.workspace }}/ci/getcontainer.sh" "${{ matrix.platform.container.name }}" "${{ matrix.platform.container.dockerfile }}" + "${{ github.workspace }}/source/ci/getcontainer.sh" "${{ matrix.platform.container.name }}" "${{ matrix.platform.container.dockerfile }}" env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} @@ -233,8 +234,9 @@ jobs: if [ -n "${{ matrix.platform.container.name }}" ]; then docker run \ --rm \ - -v "$(pwd):/home/libgit2/source" \ - -w /home/libgit2/source \ + --user libgit2:libgit2 \ + -v "$(pwd)/source:/home/libgit2/source" \ + -w /home/libgit2 \ -e ASAN_SYMBOLIZER_PATH \ -e CC \ -e CFLAGS \ @@ -247,11 +249,11 @@ jobs: -e TSAN_OPTIONS \ -e UBSAN_OPTIONS \ ${{ env.docker-registry-container-sha }} \ - /bin/bash -c "mkdir build && cd build && ../ci/build.sh && ../ci/test.sh" + /bin/bash -c "mkdir build && cd build && ../source/ci/build.sh && ../source/ci/test.sh" else mkdir build && cd build - ../ci/build.sh - ../ci/test.sh + ../source/ci/build.sh + ../source/ci/test.sh fi shell: bash diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index b52b398d8fd..e44f0d4bd52 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -215,6 +215,7 @@ jobs: - name: Check out repository uses: actions/checkout@v2 with: + path: source fetch-depth: 0 - name: Set up build environment run: ci/setup-${{ matrix.platform.setup-script }}.sh @@ -242,8 +243,9 @@ jobs: if [ -n "${{ matrix.platform.container.name }}" ]; then docker run \ --rm \ - -v "$(pwd):/home/libgit2/source" \ - -w /home/libgit2/source \ + --user libgit2:libgit2 \ + -v "$(pwd)/source:/home/libgit2/source" \ + -w /home/libgit2 \ -e ASAN_SYMBOLIZER_PATH \ -e CC \ -e CFLAGS \ @@ -255,11 +257,11 @@ jobs: -e SKIP_SSH_TESTS \ -e TSAN_OPTIONS \ ${{ env.docker-registry-container-sha }} \ - /bin/bash -c "mkdir build && cd build && ../ci/build.sh && ../ci/test.sh" + /bin/bash -c "mkdir build && cd build && ../source/ci/build.sh && ../source/ci/test.sh" else mkdir build && cd build - ../ci/build.sh - ../ci/test.sh + ../source/ci/build.sh + ../source/ci/test.sh fi shell: bash diff --git a/ci/docker/bionic b/ci/docker/bionic index 85bb6ecae2a..fb6a34b1c3c 100644 --- a/ci/docker/bionic +++ b/ci/docker/bionic @@ -36,9 +36,8 @@ RUN cd /tmp && \ cd .. && \ rm -rf mbedtls-2.16.2 -FROM mbedtls AS configure -COPY entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod a+x /usr/local/bin/entrypoint.sh -RUN mkdir /var/run/sshd +FROM mbedtls AS adduser +RUN useradd --shell /bin/bash libgit2 --create-home -ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +FROM adduser AS configure +RUN mkdir /var/run/sshd diff --git a/ci/docker/entrypoint.sh b/ci/docker/entrypoint.sh deleted file mode 100644 index 8d96e3acdf4..00000000000 --- a/ci/docker/entrypoint.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -e -useradd --shell /bin/bash libgit2 -chown --recursive libgit2:libgit2 /home/libgit2 -exec sudo --preserve-env --set-home --user=libgit2 "$@" diff --git a/ci/docker/focal b/ci/docker/focal index ce972687702..c0c57f6402c 100644 --- a/ci/docker/focal +++ b/ci/docker/focal @@ -72,9 +72,8 @@ RUN cd /tmp && \ cd .. && \ rm -rf valgrind-3.15.0 -FROM valgrind AS configure -COPY entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod a+x /usr/local/bin/entrypoint.sh -RUN mkdir /var/run/sshd +FROM valgrind AS adduser +RUN useradd --shell /bin/bash libgit2 --create-home -ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +FROM adduser AS configure +RUN mkdir /var/run/sshd diff --git a/ci/docker/xenial b/ci/docker/xenial index 1c8e585d26b..d2ba0313fc6 100644 --- a/ci/docker/xenial +++ b/ci/docker/xenial @@ -59,9 +59,8 @@ RUN cd /tmp && \ cd .. && \ rm -rf valgrind-3.15.0 -FROM valgrind AS configure -COPY entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod a+x /usr/local/bin/entrypoint.sh -RUN mkdir /var/run/sshd +FROM valgrind AS adduser +RUN useradd --shell /bin/bash libgit2 --create-home -ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +FROM adduser AS configure +RUN mkdir /var/run/sshd From 587494d0936d6f943b98d8caa447e956e20c195e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 10 Aug 2021 10:44:17 -0400 Subject: [PATCH 0422/1616] ci: update paths during docker build --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7d9c46eebdb..c78e327ddf9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -48,6 +48,7 @@ jobs: - name: Check out repository uses: actions/checkout@v2 with: + path: source fetch-depth: 0 if: github.event_name != 'pull_request' - name: Setup QEMU @@ -277,6 +278,7 @@ jobs: - name: Check out repository uses: actions/checkout@v2 with: + path: source fetch-depth: 0 - name: Generate documentation run: | From 0e38f2b30b07780bad5b665cdb72d32b17cb8efc Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 10 Aug 2021 11:28:17 -0400 Subject: [PATCH 0423/1616] ci: update path during documentation generation --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c78e327ddf9..fabc58c8acc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -288,7 +288,7 @@ jobs: docker login https://${{ env.docker-registry }} -u ${{ github.actor }} -p ${{ github.token }} docker run \ --rm \ - -v "$(pwd):/home/libgit2/source" \ + -v "$(pwd)/source:/home/libgit2/source" \ -w /home/libgit2/source \ ${{ env.docker-registry }}/${{ github.repository }}/docurium:latest \ cm doc api.docurium From fd54db0e45b3373b5537ad37247f032251449387 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 10 Aug 2021 13:13:10 -0400 Subject: [PATCH 0424/1616] ci: build docs in source directory for consistency All the other workflows jobs check out into the `source` directory; do this in the documentation build job as well, for consistency across jobs. --- .github/workflows/main.yml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fabc58c8acc..d4a74d6bd88 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -268,19 +268,13 @@ jobs: needs: [build_containers] runs-on: ubuntu-latest steps: - - name: Setup defaults - run: | - if [ "${{ matrix.container.dockerfile }}" = "" ]; then - echo "dockerfile=${{ matrix.container.dockerfile }}" >> $GITHUB_ENV - else - echo "dockerfile=${{ matrix.container.dockerfile }}" >> $GITHUB_ENV - fi - name: Check out repository uses: actions/checkout@v2 with: path: source fetch-depth: 0 - name: Generate documentation + working-directory: source run: | git config user.name 'Documentation Generation' git config user.email 'libgit2@users.noreply.github.com' @@ -288,7 +282,7 @@ jobs: docker login https://${{ env.docker-registry }} -u ${{ github.actor }} -p ${{ github.token }} docker run \ --rm \ - -v "$(pwd)/source:/home/libgit2/source" \ + -v "$(pwd):/home/libgit2" \ -w /home/libgit2/source \ ${{ env.docker-registry }}/${{ github.repository }}/docurium:latest \ cm doc api.docurium @@ -298,7 +292,8 @@ jobs: name: Upload artifact with: name: api-documentation - path: api-documentation.zip + path: source/api-documentation.zip - name: Push documentation branch + working-directory: source run: git push origin gh-pages if: github.event_name != 'pull_request' && github.repository == 'libgit2/libgit2' From 631ae5a67f17fd12c4c2b2406bec96fe61c473ff Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 10 Aug 2021 13:34:20 -0400 Subject: [PATCH 0425/1616] ci: final docs update --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d4a74d6bd88..f0e9da99370 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -283,7 +283,7 @@ jobs: docker run \ --rm \ -v "$(pwd):/home/libgit2" \ - -w /home/libgit2/source \ + -w /home/libgit2 \ ${{ env.docker-registry }}/${{ github.repository }}/docurium:latest \ cm doc api.docurium git checkout gh-pages From f01cddb140ab622f60ed6820e76bd318d3bd2656 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 14 Aug 2021 10:06:12 -0400 Subject: [PATCH 0426/1616] ci: update nightly to use source path --- .github/workflows/nightly.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index e44f0d4bd52..811745c4894 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -8,7 +8,7 @@ on: env: docker-registry: docker.pkg.github.com - docker-config-path: ci/docker + docker-config-path: source/ci/docker jobs: # Run our nightly builds. We build a matrix with the various build @@ -218,7 +218,7 @@ jobs: path: source fetch-depth: 0 - name: Set up build environment - run: ci/setup-${{ matrix.platform.setup-script }}.sh + run: source/ci/setup-${{ matrix.platform.setup-script }}.sh shell: bash if: matrix.platform.setup-script != '' - name: Setup QEMU @@ -226,7 +226,7 @@ jobs: if: matrix.platform.container.qemu == true - name: Download container run: | - "${{ github.workspace }}/ci/getcontainer.sh" "${{ matrix.platform.container.name }}" "${{ matrix.platform.container.dockerfile }}" + "${{ github.workspace }}/source/ci/getcontainer.sh" "${{ matrix.platform.container.name }}" "${{ matrix.platform.container.dockerfile }}" env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} @@ -272,15 +272,16 @@ jobs: - name: Check out repository uses: actions/checkout@v2 with: + path: source fetch-depth: 0 - name: Download container run: | - "${{ github.workspace }}/ci/getcontainer.sh" xenial + "${{ github.workspace }}/source/ci/getcontainer.sh" xenial env: DOCKER_REGISTRY: ${{ env.docker-registry }} GITHUB_TOKEN: ${{ secrets.github_token }} working-directory: ${{ env.docker-config-path }} - name: Run Coverity - run: ci/coverity.sh + run: source/ci/coverity.sh env: COVERITY_TOKEN: ${{ secrets.coverity_token }} From e6c9fcf08d3893a924f8961af7123a5a9c3c4ced Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 9 Aug 2021 08:42:06 -0400 Subject: [PATCH 0427/1616] ci: add centos7 and centos8 docker definitions --- ci/docker/centos7 | 39 +++++++++++++++++++++++++++++++++++++++ ci/docker/centos8 | 30 ++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 ci/docker/centos7 create mode 100644 ci/docker/centos8 diff --git a/ci/docker/centos7 b/ci/docker/centos7 new file mode 100644 index 00000000000..71645833ee9 --- /dev/null +++ b/ci/docker/centos7 @@ -0,0 +1,39 @@ +ARG BASE=centos:7 +FROM ${BASE} AS yum +RUN yum install -y \ + which \ + git \ + libarchive \ + cmake \ + gcc \ + gcc-c++ \ + make \ + openssl-devel \ + openssh-server \ + git-daemon \ + java-1.8.0-openjdk-headless \ + sudo \ + python + +FROM yum AS libssh2 +RUN cd /tmp && \ + curl https://libssh2.org/download/libssh2-1.8.0.tar.gz | tar -xz && \ + cd libssh2-1.8.0 && \ + ./configure && \ + make && \ + make install + +FROM libssh2 AS cmake +RUN cd /tmp && \ + curl -L https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1.tar.gz | tar -xz && \ + cd cmake-3.21.1 && \ + ./configure && \ + make && \ + make install + +FROM libssh2 AS adduser +RUN useradd --shell /bin/bash libgit2 --create-home + +FROM adduser AS configure +ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig +RUN mkdir /var/run/sshd diff --git a/ci/docker/centos8 b/ci/docker/centos8 new file mode 100644 index 00000000000..0414838d1a3 --- /dev/null +++ b/ci/docker/centos8 @@ -0,0 +1,30 @@ +ARG BASE=centos:8 +FROM ${BASE} AS yum +RUN yum install -y \ + which \ + git \ + libarchive \ + cmake \ + gcc \ + make \ + openssl-devel \ + openssh-server \ + git-daemon \ + java-1.8.0-openjdk-headless \ + sudo \ + python39 + +FROM yum AS libssh2 +RUN cd /tmp && \ + curl https://libssh2.org/download/libssh2-1.8.0.tar.gz | tar -xz && \ + cd libssh2-1.8.0 && \ + ./configure && \ + make && \ + make install + +FROM libssh2 AS adduser +RUN useradd --shell /bin/bash libgit2 --create-home + +FROM adduser AS configure +ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig +RUN mkdir /var/run/sshd From 624717774e70eee0af44c0f6e1be9ed0da1328d2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 15 Aug 2021 17:18:04 -0400 Subject: [PATCH 0428/1616] ci: run centos7 and centos8 builds nightly --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f0e9da99370..d1a0be720ab 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -43,6 +43,8 @@ jobs: dockerfile: bionic base: multiarch/ubuntu-core:arm64-bionic qemu: true + - name: centos7 + - name: centos8 runs-on: ubuntu-latest steps: - name: Check out repository From 8ea666b244880185593195f45718d6e9dc703f22 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 15 Aug 2021 18:00:22 -0400 Subject: [PATCH 0429/1616] ci: run centos7 and centos8 builds nightly --- .github/workflows/nightly.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 811745c4894..fc6108d4a4d 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -107,6 +107,18 @@ jobs: SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true os: ubuntu-latest + - # CentOS 7 + container: + name: centos7 + env: + CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + os: ubuntu-latest + - # CentOS 8 + container: + name: centos8 + env: + CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + os: ubuntu-latest - # macOS os: macos-10.15 env: From 1ebdb6f2034af941f989064a63b3a85d0a51074b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 15 Aug 2021 22:53:19 -0400 Subject: [PATCH 0430/1616] ci: update centos7 and centos8 build --- .github/workflows/nightly.yml | 1 + ci/docker/centos8 | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index fc6108d4a4d..d6c75b97268 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -112,6 +112,7 @@ jobs: name: centos7 env: CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + BUILD_PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin os: ubuntu-latest - # CentOS 8 container: diff --git a/ci/docker/centos8 b/ci/docker/centos8 index 0414838d1a3..fe059a1b759 100644 --- a/ci/docker/centos8 +++ b/ci/docker/centos8 @@ -12,7 +12,9 @@ RUN yum install -y \ git-daemon \ java-1.8.0-openjdk-headless \ sudo \ - python39 + python39 \ + krb5-workstation \ + krb5-libs FROM yum AS libssh2 RUN cd /tmp && \ From 5ad53ec762813522faac089576e62200e0045bdb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 15 Aug 2021 23:19:54 -0400 Subject: [PATCH 0431/1616] ci: update centos builds --- .github/workflows/nightly.yml | 2 ++ ci/docker/centos7 | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index d6c75b97268..c1abdc8ef73 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -112,6 +112,7 @@ jobs: name: centos7 env: CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + SKIP_NEGOTIATE_TESTS: true BUILD_PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin os: ubuntu-latest - # CentOS 8 @@ -119,6 +120,7 @@ jobs: name: centos8 env: CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + SKIP_NEGOTIATE_TESTS: true os: ubuntu-latest - # macOS os: macos-10.15 diff --git a/ci/docker/centos7 b/ci/docker/centos7 index 71645833ee9..d1f4993630c 100644 --- a/ci/docker/centos7 +++ b/ci/docker/centos7 @@ -4,7 +4,6 @@ RUN yum install -y \ which \ git \ libarchive \ - cmake \ gcc \ gcc-c++ \ make \ From d4416624fa6e74f7a07b7b2c021e049b315e5510 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 16 Aug 2021 13:49:38 -0400 Subject: [PATCH 0432/1616] ci: update centos builds --- ci/docker/centos7 | 24 ++++++++++++++++++++---- ci/docker/centos8 | 17 +++++++++++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/ci/docker/centos7 b/ci/docker/centos7 index d1f4993630c..082b9e225c2 100644 --- a/ci/docker/centos7 +++ b/ci/docker/centos7 @@ -2,6 +2,7 @@ ARG BASE=centos:7 FROM ${BASE} AS yum RUN yum install -y \ which \ + bzip2 \ git \ libarchive \ gcc \ @@ -20,17 +21,32 @@ RUN cd /tmp && \ cd libssh2-1.8.0 && \ ./configure && \ make && \ - make install + make install && \ + cd .. && \ + rm -rf libssh-1.8.0 -FROM libssh2 AS cmake +FROM libssh2 AS valgrind +RUN cd /tmp && \ + curl --insecure --location --silent --show-error https://sourceware.org/pub/valgrind/valgrind-3.15.0.tar.bz2 | \ + tar -xj && \ + cd valgrind-3.15.0 && \ + ./configure && \ + make MAKEFLAGS="-j -l$(grep -c ^processor /proc/cpuinfo)" && \ + make install && \ + cd .. && \ + rm -rf valgrind-3.15.0 + +FROM valgrind AS cmake RUN cd /tmp && \ curl -L https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1.tar.gz | tar -xz && \ cd cmake-3.21.1 && \ ./configure && \ make && \ - make install + make install && \ + cd .. && \ + rm -rf cmake-3.21.1 -FROM libssh2 AS adduser +FROM cmake AS adduser RUN useradd --shell /bin/bash libgit2 --create-home FROM adduser AS configure diff --git a/ci/docker/centos8 b/ci/docker/centos8 index fe059a1b759..da0f2da9476 100644 --- a/ci/docker/centos8 +++ b/ci/docker/centos8 @@ -22,9 +22,22 @@ RUN cd /tmp && \ cd libssh2-1.8.0 && \ ./configure && \ make && \ - make install + make install && \ + cd .. && \ + rm -rf libssh2-1.8.0 -FROM libssh2 AS adduser +FROM libssh2 AS valgrind +RUN cd /tmp && \ + curl --insecure --location --silent --show-error https://sourceware.org/pub/valgrind/valgrind-3.15.0.tar.bz2 | \ + tar -xj && \ + cd valgrind-3.15.0 && \ + CC=clang-10 ./configure && \ + make MAKEFLAGS="-j -l$(grep -c ^processor /proc/cpuinfo)" && \ + make install && \ + cd .. && \ + rm -rf valgrind-3.15.0 + +FROM valgrind AS adduser RUN useradd --shell /bin/bash libgit2 --create-home FROM adduser AS configure From a42577db27eb31b7f727188683cd1209b3f2f2d6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 16 Aug 2021 14:09:17 -0400 Subject: [PATCH 0433/1616] ci: update centos builds --- ci/docker/centos8 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/docker/centos8 b/ci/docker/centos8 index da0f2da9476..bda4ee795d9 100644 --- a/ci/docker/centos8 +++ b/ci/docker/centos8 @@ -2,6 +2,7 @@ ARG BASE=centos:8 FROM ${BASE} AS yum RUN yum install -y \ which \ + bzip2 \ git \ libarchive \ cmake \ @@ -31,7 +32,7 @@ RUN cd /tmp && \ curl --insecure --location --silent --show-error https://sourceware.org/pub/valgrind/valgrind-3.15.0.tar.bz2 | \ tar -xj && \ cd valgrind-3.15.0 && \ - CC=clang-10 ./configure && \ + ./configure && \ make MAKEFLAGS="-j -l$(grep -c ^processor /proc/cpuinfo)" && \ make install && \ cd .. && \ From 2dbe413e019a6e77a85b4e1f05fa0e312a7e9b4b Mon Sep 17 00:00:00 2001 From: Julien Richard Date: Tue, 17 Aug 2021 11:34:11 +0200 Subject: [PATCH 0434/1616] Fix LIBGIT2_FILENAME not being passed to the resource compiler --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d3408999f97..28ef258f366 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -390,7 +390,7 @@ if(SONAME) set_target_properties(git2 PROPERTIES VERSION ${libgit2_VERSION}) set_target_properties(git2 PROPERTIES SOVERSION "${libgit2_VERSION_MAJOR}.${libgit2_VERSION_MINOR}") if(LIBGIT2_FILENAME) - target_compile_definitions(git2internal PRIVATE LIBGIT2_FILENAME=\"${LIBGIT2_FILENAME}\") + target_compile_definitions(git2 PRIVATE LIBGIT2_FILENAME=\"${LIBGIT2_FILENAME}\") set_target_properties(git2 PROPERTIES OUTPUT_NAME ${LIBGIT2_FILENAME}) elseif(DEFINED LIBGIT2_PREFIX) set_target_properties(git2 PROPERTIES PREFIX "${LIBGIT2_PREFIX}") From 727d903a56ceefdafaa11bef924641dbaaa8446b Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Wed, 18 Aug 2021 21:01:36 +0200 Subject: [PATCH 0435/1616] sha1dc: remove conditional for --- src/hash/sha1/sha1dc/sha1.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hash/sha1/sha1dc/sha1.c b/src/hash/sha1/sha1dc/sha1.c index 9d3cf81d4d7..86b8cc075d1 100644 --- a/src/hash/sha1/sha1dc/sha1.c +++ b/src/hash/sha1/sha1dc/sha1.c @@ -10,10 +10,8 @@ #include #include #include -#ifdef __unix__ #include /* make sure macros like _BIG_ENDIAN visible */ #endif -#endif #ifdef SHA1DC_CUSTOM_INCLUDE_SHA1_C #include SHA1DC_CUSTOM_INCLUDE_SHA1_C From 1903cfef0b318c861bd29f03c783815b1349cf6d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 19 Aug 2021 16:49:41 -0400 Subject: [PATCH 0436/1616] openssl: don't fail when we can't customize allocators During valgrind runs, we try to swap out the OpenSSL allocators for our own. This allows us to avoid some unnecessary warnings about usage. Unfortunately, many builds of OpenSSL do not allow you to swap allocators; for example FIPS builds and the builds running in CentOS. Try to swap the allocators, but do not fail when they cannot be customized. --- src/streams/openssl.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/streams/openssl.c b/src/streams/openssl.c index d866832c618..01ce9ce2a01 100644 --- a/src/streams/openssl.c +++ b/src/streams/openssl.c @@ -251,13 +251,18 @@ int git_openssl_stream_global_init(void) #endif #ifdef VALGRIND - /* Swap in our own allocator functions that initialize allocated memory */ - if (!allocators_initialized && + /* + * Swap in our own allocator functions that initialize + * allocated memory to avoid spurious valgrind warnings. + * Don't error on failure; many builds of OpenSSL do not + * allow you to set these functions. + */ + if (!allocators_initialized) { CRYPTO_set_mem_functions(git_openssl_malloc, git_openssl_realloc, - git_openssl_free) != 1) - goto error; - allocators_initialized = true; + git_openssl_free); + allocators_initialized = true; + } #endif OPENSSL_init_ssl(0, NULL); From ecdb41f911783c3f21c88ed799efb38030336789 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 17 Aug 2021 08:19:10 -0400 Subject: [PATCH 0437/1616] ci: update centos to find libssh2 --- .github/workflows/nightly.yml | 4 +++- ci/docker/centos8 | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index c1abdc8ef73..e235a3ce760 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -112,15 +112,17 @@ jobs: name: centos7 env: CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + PKG_CONFIG_PATH: /usr/local/lib/pkgconfig SKIP_NEGOTIATE_TESTS: true - BUILD_PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin os: ubuntu-latest - # CentOS 8 container: name: centos8 env: CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + PKG_CONFIG_PATH: /usr/local/lib/pkgconfig SKIP_NEGOTIATE_TESTS: true + SKIP_SSH_TESTS: true os: ubuntu-latest - # macOS os: macos-10.15 diff --git a/ci/docker/centos8 b/ci/docker/centos8 index bda4ee795d9..e1fb7684a30 100644 --- a/ci/docker/centos8 +++ b/ci/docker/centos8 @@ -44,3 +44,5 @@ RUN useradd --shell /bin/bash libgit2 --create-home FROM adduser AS configure ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig RUN mkdir /var/run/sshd +RUN echo "/usr/local/lib" > /etc/ld.so.conf.d/local && \ + ldconfig From 3b603d319ee5f1f1436cd383505c47ec853c32c5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 23 Aug 2021 15:00:39 -0400 Subject: [PATCH 0438/1616] ci: tag new containers with the latest tag --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d1a0be720ab..b58f5775804 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -70,7 +70,9 @@ jobs: BASE_ARG="--build-arg BASE=${{ matrix.container.base }}" fi docker build -t ${{ env.docker-registry-container-sha }} ${BASE_ARG} -f ${{ env.dockerfile }} . + docker tag ${{ env.docker-registry-container-sha }} ${{ env.docker-registry-container-latest }} docker push ${{ env.docker-registry-container-sha }} + docker push ${{ env.docker-registry-container-latest }} working-directory: ${{ env.docker-config-path }} if: github.event_name != 'pull_request' && env.docker-container-exists != 'true' From dbcb1cd74696ea54fa0d80bc33f659a27d1254bf Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 23 Aug 2021 15:02:49 -0400 Subject: [PATCH 0439/1616] ci: update container versions Update all the container versions to force a rebuild so that they'll get tagged with latest (due to changes in the CI scripts). --- ci/docker/bionic | 1 + ci/docker/centos7 | 1 + ci/docker/centos8 | 1 + ci/docker/docurium | 1 + ci/docker/focal | 1 + ci/docker/xenial | 1 + 6 files changed, 6 insertions(+) diff --git a/ci/docker/bionic b/ci/docker/bionic index fb6a34b1c3c..51af5c01cfd 100644 --- a/ci/docker/bionic +++ b/ci/docker/bionic @@ -1,4 +1,5 @@ ARG BASE=ubuntu:bionic + FROM ${BASE} AS apt RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ diff --git a/ci/docker/centos7 b/ci/docker/centos7 index 082b9e225c2..098edb26a50 100644 --- a/ci/docker/centos7 +++ b/ci/docker/centos7 @@ -1,4 +1,5 @@ ARG BASE=centos:7 + FROM ${BASE} AS yum RUN yum install -y \ which \ diff --git a/ci/docker/centos8 b/ci/docker/centos8 index e1fb7684a30..f4719844624 100644 --- a/ci/docker/centos8 +++ b/ci/docker/centos8 @@ -1,4 +1,5 @@ ARG BASE=centos:8 + FROM ${BASE} AS yum RUN yum install -y \ which \ diff --git a/ci/docker/docurium b/ci/docker/docurium index 7aa24753274..1957bbb3bf3 100644 --- a/ci/docker/docurium +++ b/ci/docker/docurium @@ -1,4 +1,5 @@ ARG BASE=ubuntu:bionic + FROM ${BASE} RUN apt update && apt install -y cmake pkg-config ruby ruby-dev llvm libclang-dev libssl-dev python-pygments RUN gem install docurium diff --git a/ci/docker/focal b/ci/docker/focal index c0c57f6402c..17138769809 100644 --- a/ci/docker/focal +++ b/ci/docker/focal @@ -1,4 +1,5 @@ ARG BASE=ubuntu:focal + FROM ${BASE} AS apt RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ diff --git a/ci/docker/xenial b/ci/docker/xenial index d2ba0313fc6..4c3810af44f 100644 --- a/ci/docker/xenial +++ b/ci/docker/xenial @@ -1,4 +1,5 @@ ARG BASE=ubuntu:xenial + FROM ${BASE} AS apt RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ From 150eddd9425c060d617915d1989bde8532aeb5a2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 10 Aug 2021 21:41:05 -0400 Subject: [PATCH 0440/1616] openssl: separate legacy api Refactor the OpenSSL stream implementation so that the legacy code is better abstracted. This will enable future development. --- src/streams/openssl.c | 194 ++------------------------------- src/streams/openssl_legacy.c | 201 +++++++++++++++++++++++++++++++++++ src/streams/openssl_legacy.h | 42 ++++++++ 3 files changed, 249 insertions(+), 188 deletions(-) create mode 100644 src/streams/openssl_legacy.c create mode 100644 src/streams/openssl_legacy.h diff --git a/src/streams/openssl.c b/src/streams/openssl.c index 01ce9ce2a01..8b770b6e7f3 100644 --- a/src/streams/openssl.c +++ b/src/streams/openssl.c @@ -6,6 +6,7 @@ */ #include "streams/openssl.h" +#include "streams/openssl_legacy.h" #ifdef GIT_OPENSSL @@ -35,147 +36,6 @@ SSL_CTX *git__ssl_ctx; #define GIT_SSL_DEFAULT_CIPHERS "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA256:DHE-DSS-AES128-SHA:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA" -#if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) || \ - (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) -# define OPENSSL_LEGACY_API -#endif - -/* - * OpenSSL 1.1 made BIO opaque so we have to use functions to interact with it - * which do not exist in previous versions. We define these inline functions so - * we can program against the interface instead of littering the implementation - * with ifdefs. We do the same for OPENSSL_init_ssl. - */ -#if defined(OPENSSL_LEGACY_API) -static int OPENSSL_init_ssl(int opts, void *settings) -{ - GIT_UNUSED(opts); - GIT_UNUSED(settings); - SSL_load_error_strings(); - OpenSSL_add_ssl_algorithms(); - return 0; -} - -static BIO_METHOD* BIO_meth_new(int type, const char *name) -{ - BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD)); - if (!meth) { - return NULL; - } - - meth->type = type; - meth->name = name; - - return meth; -} - -static void BIO_meth_free(BIO_METHOD *biom) -{ - git__free(biom); -} - -static int BIO_meth_set_write(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)) -{ - biom->bwrite = write; - return 1; -} - -static int BIO_meth_set_read(BIO_METHOD *biom, int (*read) (BIO *, char *, int)) -{ - biom->bread = read; - return 1; -} - -static int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts) (BIO *, const char *)) -{ - biom->bputs = puts; - return 1; -} - -static int BIO_meth_set_gets(BIO_METHOD *biom, int (*gets) (BIO *, char *, int)) - -{ - biom->bgets = gets; - return 1; -} - -static int BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *)) -{ - biom->ctrl = ctrl; - return 1; -} - -static int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *)) -{ - biom->create = create; - return 1; -} - -static int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *)) -{ - biom->destroy = destroy; - return 1; -} - -static int BIO_get_new_index(void) -{ - /* This exists as of 1.1 so before we'd just have 0 */ - return 0; -} - -static void BIO_set_init(BIO *b, int init) -{ - b->init = init; -} - -static void BIO_set_data(BIO *a, void *ptr) -{ - a->ptr = ptr; -} - -static void *BIO_get_data(BIO *a) -{ - return a->ptr; -} - -static const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) -{ - return ASN1_STRING_data((ASN1_STRING *)x); -} - -# if defined(GIT_THREADS) -static git_mutex *openssl_locks; - -static void openssl_locking_function( - int mode, int n, const char *file, int line) -{ - int lock; - - GIT_UNUSED(file); - GIT_UNUSED(line); - - lock = mode & CRYPTO_LOCK; - - if (lock) { - (void)git_mutex_lock(&openssl_locks[n]); - } else { - git_mutex_unlock(&openssl_locks[n]); - } -} - -static void shutdown_ssl_locking(void) -{ - int num_locks, i; - - num_locks = CRYPTO_num_locks(); - CRYPTO_set_locking_callback(NULL); - - for (i = 0; i < num_locks; ++i) - git_mutex_free(&openssl_locks[i]); - git__free(openssl_locks); -} -# endif /* GIT_THREADS */ -#endif /* OPENSSL_LEGACY_API */ static BIO_METHOD *git_stream_bio_method; static int init_bio_method(void); @@ -198,22 +58,6 @@ static void shutdown_ssl(void) } #ifdef VALGRIND -#ifdef OPENSSL_LEGACY_API -static void *git_openssl_malloc(size_t bytes) -{ - return git__calloc(1, bytes); -} - -static void *git_openssl_realloc(void *mem, size_t size) -{ - return git__realloc(mem, size); -} - -static void git_openssl_free(void *mem) -{ - return git__free(mem); -} -#else static void *git_openssl_malloc(size_t bytes, const char *file, int line) { GIT_UNUSED(file); @@ -235,7 +79,6 @@ static void git_openssl_free(void *mem, const char *file, int line) return git__free(mem); } #endif -#endif int git_openssl_stream_global_init(void) { @@ -301,42 +144,17 @@ int git_openssl_stream_global_init(void) return -1; } -#if defined(GIT_THREADS) && defined(OPENSSL_LEGACY_API) -static void threadid_cb(CRYPTO_THREADID *threadid) -{ - GIT_UNUSED(threadid); - CRYPTO_THREADID_set_numeric(threadid, git_thread_currentid()); -} -#endif - +#ifndef GIT_OPENSSL_LEGACY int git_openssl_set_locking(void) { -#if defined(GIT_THREADS) && defined(OPENSSL_LEGACY_API) - int num_locks, i; - - CRYPTO_THREADID_set_callback(threadid_cb); - - num_locks = CRYPTO_num_locks(); - openssl_locks = git__calloc(num_locks, sizeof(git_mutex)); - GIT_ERROR_CHECK_ALLOC(openssl_locks); - - for (i = 0; i < num_locks; i++) { - if (git_mutex_init(&openssl_locks[i]) != 0) { - git_error_set(GIT_ERROR_SSL, "failed to initialize openssl locks"); - return -1; - } - } - - CRYPTO_set_locking_callback(openssl_locking_function); - return git_runtime_shutdown_register(shutdown_ssl_locking); - -#elif !defined(OPENSSL_LEGACY_API) +# ifdef GIT_THREADS return 0; -#else +# else git_error_set(GIT_ERROR_THREAD, "libgit2 was not built with threads"); return -1; -#endif +# endif } +#endif static int bio_create(BIO *b) diff --git a/src/streams/openssl_legacy.c b/src/streams/openssl_legacy.c new file mode 100644 index 00000000000..3f097be619f --- /dev/null +++ b/src/streams/openssl_legacy.c @@ -0,0 +1,201 @@ +/* + * 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 "streams/openssl.h" +#include "streams/openssl_legacy.h" + +#if defined(GIT_OPENSSL) && defined(GIT_OPENSSL_LEGACY) + +#include +#include +#include +#include + +#include "runtime.h" +#include "git2/sys/openssl.h" + +/* + * OpenSSL 1.1 made BIO opaque so we have to use functions to interact with it + * which do not exist in previous versions. We define these inline functions so + * we can program against the interface instead of littering the implementation + * with ifdefs. We do the same for OPENSSL_init_ssl. + */ + +int OPENSSL_init_ssl(int opts, void *settings) +{ + GIT_UNUSED(opts); + GIT_UNUSED(settings); + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); + return 0; +} + +BIO_METHOD* BIO_meth_new(int type, const char *name) +{ + BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD)); + if (!meth) { + return NULL; + } + + meth->type = type; + meth->name = name; + + return meth; +} + +void BIO_meth_free(BIO_METHOD *biom) +{ + git__free(biom); +} + +int BIO_meth_set_write(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)) +{ + biom->bwrite = write; + return 1; +} + +int BIO_meth_set_read(BIO_METHOD *biom, int (*read) (BIO *, char *, int)) +{ + biom->bread = read; + return 1; +} + +int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts) (BIO *, const char *)) +{ + biom->bputs = puts; + return 1; +} + +int BIO_meth_set_gets(BIO_METHOD *biom, int (*gets) (BIO *, char *, int)) + +{ + biom->bgets = gets; + return 1; +} + +int BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *)) +{ + biom->ctrl = ctrl; + return 1; +} + +int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *)) +{ + biom->create = create; + return 1; +} + +int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *)) +{ + biom->destroy = destroy; + return 1; +} + +int BIO_get_new_index(void) +{ + /* This exists as of 1.1 so before we'd just have 0 */ + return 0; +} + +void BIO_set_init(BIO *b, int init) +{ + b->init = init; +} + +void BIO_set_data(BIO *a, void *ptr) +{ + a->ptr = ptr; +} + +void *BIO_get_data(BIO *a) +{ + return a->ptr; +} + +const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) +{ + return ASN1_STRING_data((ASN1_STRING *)x); +} + +# if defined(GIT_THREADS) +static git_mutex *openssl_locks; + +static void openssl_locking_function( + int mode, int n, const char *file, int line) +{ + int lock; + + GIT_UNUSED(file); + GIT_UNUSED(line); + + lock = mode & CRYPTO_LOCK; + + if (lock) { + (void)git_mutex_lock(&openssl_locks[n]); + } else { + git_mutex_unlock(&openssl_locks[n]); + } +} + +static void shutdown_ssl_locking(void) +{ + int num_locks, i; + + num_locks = CRYPTO_num_locks(); + CRYPTO_set_locking_callback(NULL); + + for (i = 0; i < num_locks; ++i) + git_mutex_free(&openssl_locks[i]); + git__free(openssl_locks); +} + +static void threadid_cb(CRYPTO_THREADID *threadid) +{ + GIT_UNUSED(threadid); + CRYPTO_THREADID_set_numeric(threadid, git_thread_currentid()); +} + +int git_openssl_set_locking(void) +{ + int num_locks, i; + + CRYPTO_THREADID_set_callback(threadid_cb); + + num_locks = CRYPTO_num_locks(); + openssl_locks = git__calloc(num_locks, sizeof(git_mutex)); + GIT_ERROR_CHECK_ALLOC(openssl_locks); + + for (i = 0; i < num_locks; i++) { + if (git_mutex_init(&openssl_locks[i]) != 0) { + git_error_set(GIT_ERROR_SSL, "failed to initialize openssl locks"); + return -1; + } + } + + CRYPTO_set_locking_callback(openssl_locking_function); + return git_runtime_shutdown_register(shutdown_ssl_locking); +} +#endif /* GIT_THREADS */ + +#ifdef VALGRIND +void *git_openssl_malloc(size_t bytes) +{ + return git__calloc(1, bytes); +} + +void *git_openssl_realloc(void *mem, size_t size) +{ + return git__realloc(mem, size); +} + +void git_openssl_free(void *mem) +{ + return git__free(mem); +} +#endif + +#endif /* GIT_OPENSSL && GIT_OPENSSL_LEGACY */ diff --git a/src/streams/openssl_legacy.h b/src/streams/openssl_legacy.h new file mode 100644 index 00000000000..7ccc13838e3 --- /dev/null +++ b/src/streams/openssl_legacy.h @@ -0,0 +1,42 @@ +/* + * 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_streams_openssl_legacy_h__ +#define INCLUDE_streams_openssl_legacy_h__ + +#ifdef GIT_OPENSSL +# include +# include +# include +# include + +# if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) +# define GIT_OPENSSL_LEGACY +# endif +#endif + +#ifdef GIT_OPENSSL_LEGACY + +extern int OPENSSL_init_ssl(int opts, void *settings); +extern BIO_METHOD* BIO_meth_new(int type, const char *name); +extern void BIO_meth_free(BIO_METHOD *biom); +extern int BIO_meth_set_write(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)); +extern int BIO_meth_set_read(BIO_METHOD *biom, int (*read) (BIO *, char *, int)); +extern int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts) (BIO *, const char *)); +extern int BIO_meth_set_gets(BIO_METHOD *biom, int (*gets) (BIO *, char *, int)); +extern int BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *)); +extern int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *)); +extern int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *)); +extern int BIO_get_new_index(void); +extern void BIO_set_data(BIO *a, void *ptr); +extern void BIO_set_init(BIO *b, int init); +extern void *BIO_get_data(BIO *a); +extern const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); + +#endif + +#endif From 0903cac1d08817e87c556f5a3e6ec881be86c7f2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 11 Aug 2021 01:30:38 +0100 Subject: [PATCH 0441/1616] openssl: dynamically load libssl and symbols (optionally) Provide an interface around OpenSSL to dynamically load the libraries and symbols, so that users can distribute a libgit2 library that is not linked directly against OpenSSL. This enables users to target multiple distributions with a single binary. This mechanism is optional and disabled by default. Configure cmake with -DUSE_HTTPS=OpenSSL-Dynamic to use it. --- COPYING | 110 ++++++++++- cmake/SelectHTTPSBackend.cmake | 4 + src/features.h.in | 1 + src/libgit2.c | 8 - src/netops.h | 2 +- src/streams/openssl.c | 45 ++++- src/streams/openssl.h | 10 +- src/streams/openssl_dynamic.c | 307 +++++++++++++++++++++++++++++ src/streams/openssl_dynamic.h | 348 +++++++++++++++++++++++++++++++++ src/streams/openssl_legacy.c | 94 ++++----- src/streams/openssl_legacy.h | 57 ++++-- 11 files changed, 902 insertions(+), 84 deletions(-) create mode 100644 src/streams/openssl_dynamic.c create mode 100644 src/streams/openssl_dynamic.h diff --git a/COPYING b/COPYING index c0f61fb9158..6bb39b0c1d9 100644 --- a/COPYING +++ b/COPYING @@ -420,7 +420,7 @@ The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. - + The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -1019,3 +1019,111 @@ following restrictions are are met: THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +---------------------------------------------------------------------- + +Portions of the OpenSSL headers are included under the OpenSSL license: + +Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +All rights reserved. + +This package is an SSL implementation written +by Eric Young (eay@cryptsoft.com). +The implementation was written so as to conform with Netscapes SSL. + +This library is free for commercial and non-commercial use as long as +the following conditions are aheared to. The following conditions +apply to all code found in this distribution, be it the RC4, RSA, +lhash, DES, etc., code; not just the SSL code. The SSL documentation +included with this distribution is covered by the same copyright terms +except that the holder is Tim Hudson (tjh@cryptsoft.com). + +Copyright remains Eric Young's, and as such any Copyright notices in +the code are not to be removed. +If this package is used in a product, Eric Young should be given attribution +as the author of the parts of the library used. +This can be in the form of a textual message at program startup or +in documentation (online or textual) provided with the package. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + "This product includes cryptographic software written by + Eric Young (eay@cryptsoft.com)" + The word 'cryptographic' can be left out if the rouines from the library + being used are not cryptographic related :-). +4. If you include any Windows specific code (or a derivative thereof) from + the apps directory (application code) you must include an acknowledgement: + "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + +THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +The licence and distribution terms for any publically available version or +derivative of this code cannot be changed. i.e. this code cannot simply be +copied and put under another distribution licence +[including the GNU Public Licence.] + +==================================================================== +Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + "This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + +4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + endorse or promote products derived from this software without + prior written permission. For written permission, please contact + openssl-core@openssl.org. + +5. Products derived from this software may not be called "OpenSSL" + nor may "OpenSSL" appear in their names without prior written + permission of the OpenSSL Project. + +6. Redistributions of any form whatsoever must retain the following + acknowledgment: + "This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit (http://www.openssl.org/)" + +THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/cmake/SelectHTTPSBackend.cmake b/cmake/SelectHTTPSBackend.cmake index afbeac42445..4998f0f2ac9 100644 --- a/cmake/SelectHTTPSBackend.cmake +++ b/cmake/SelectHTTPSBackend.cmake @@ -108,6 +108,10 @@ IF(USE_HTTPS) LIST(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LIBRARIES}) ELSEIF (USE_HTTPS STREQUAL "WinHTTP") # WinHTTP setup was handled in the WinHTTP-specific block above + ELSEIF (USE_HTTPS STREQUAL "OpenSSL-Dynamic") + SET(GIT_OPENSSL 1) + SET(GIT_OPENSSL_DYNAMIC 1) + LIST(APPEND LIBGIT2_LIBS dl) ELSE() MESSAGE(FATAL_ERROR "Asked for backend ${USE_HTTPS} but it wasn't found") ENDIF() diff --git a/src/features.h.in b/src/features.h.in index ab523f90bb6..41f2734acb4 100644 --- a/src/features.h.in +++ b/src/features.h.in @@ -34,6 +34,7 @@ #cmakedefine GIT_WINHTTP 1 #cmakedefine GIT_HTTPS 1 #cmakedefine GIT_OPENSSL 1 +#cmakedefine GIT_OPENSSL_DYNAMIC 1 #cmakedefine GIT_SECURE_TRANSPORT 1 #cmakedefine GIT_MBEDTLS 1 diff --git a/src/libgit2.c b/src/libgit2.c index 089c8359059..aee9cf2cdeb 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -36,14 +36,6 @@ # include "win32/w32_leakcheck.h" #endif -#ifdef GIT_OPENSSL -# include -#endif - -#ifdef GIT_MBEDTLS -# include -#endif - /* Declarations for tuneable settings */ extern size_t git_mwindow__window_size; extern size_t git_mwindow__mapped_limit; diff --git a/src/netops.h b/src/netops.h index 771c87b64b7..7140b39bc45 100644 --- a/src/netops.h +++ b/src/netops.h @@ -14,7 +14,7 @@ #include "net.h" #ifdef GIT_OPENSSL -# include +# include "streams/openssl.h" #endif typedef struct gitno_ssl { diff --git a/src/streams/openssl.c b/src/streams/openssl.c index 8b770b6e7f3..212c0020010 100644 --- a/src/streams/openssl.c +++ b/src/streams/openssl.c @@ -7,11 +7,13 @@ #include "streams/openssl.h" #include "streams/openssl_legacy.h" +#include "streams/openssl_dynamic.h" #ifdef GIT_OPENSSL #include +#include "common.h" #include "runtime.h" #include "settings.h" #include "posix.h" @@ -27,10 +29,12 @@ # include #endif -#include -#include -#include -#include +#ifndef GIT_OPENSSL_DYNAMIC +# include +# include +# include +# include +#endif SSL_CTX *git__ssl_ctx; @@ -58,27 +62,45 @@ static void shutdown_ssl(void) } #ifdef VALGRIND +# if !defined(GIT_OPENSSL_LEGACY) && !defined(GIT_OPENSSL_DYNAMIC) + static void *git_openssl_malloc(size_t bytes, const char *file, int line) { GIT_UNUSED(file); GIT_UNUSED(line); return git__calloc(1, bytes); } - + static void *git_openssl_realloc(void *mem, size_t size, const char *file, int line) { GIT_UNUSED(file); GIT_UNUSED(line); return git__realloc(mem, size); } - + static void git_openssl_free(void *mem, const char *file, int line) { GIT_UNUSED(file); GIT_UNUSED(line); - return git__free(mem); + git__free(mem); +} +# else /* !GIT_OPENSSL_LEGACY && !GIT_OPENSSL_DYNAMIC */ +static void *git_openssl_malloc(size_t bytes) +{ + return git__calloc(1, bytes); +} + +static void *git_openssl_realloc(void *mem, size_t size) +{ + return git__realloc(mem, size); } -#endif + +static void git_openssl_free(void *mem) +{ + git__free(mem); +} +# endif /* !GIT_OPENSSL_LEGACY && !GIT_OPENSSL_DYNAMIC */ +#endif /* VALGRIND */ int git_openssl_stream_global_init(void) { @@ -93,6 +115,11 @@ int git_openssl_stream_global_init(void) ssl_opts |= SSL_OP_NO_COMPRESSION; #endif +#ifdef GIT_OPENSSL_DYNAMIC + if (git_openssl_stream_dynamic_init() < 0) + return -1; +#endif + #ifdef VALGRIND /* * Swap in our own allocator functions that initialize @@ -144,7 +171,7 @@ int git_openssl_stream_global_init(void) return -1; } -#ifndef GIT_OPENSSL_LEGACY +#if !defined(GIT_OPENSSL_LEGACY) && !defined(GIT_OPENSSL_DYNAMIC) int git_openssl_set_locking(void) { # ifdef GIT_THREADS diff --git a/src/streams/openssl.h b/src/streams/openssl.h index 826d1efbc77..89fb60a82ee 100644 --- a/src/streams/openssl.h +++ b/src/streams/openssl.h @@ -8,14 +8,22 @@ #define INCLUDE_streams_openssl_h__ #include "common.h" +#include "streams/openssl_legacy.h" +#include "streams/openssl_dynamic.h" #include "git2/sys/stream.h" extern int git_openssl_stream_global_init(void); +#if defined(GIT_OPENSSL) && !defined(GIT_OPENSSL_DYNAMIC) +# include +# include +# include +# include +# endif + #ifdef GIT_OPENSSL extern int git_openssl__set_cert_location(const char *file, const char *path); - extern int git_openssl_stream_new(git_stream **out, const char *host, const char *port); extern int git_openssl_stream_wrap(git_stream **out, git_stream *in, const char *host); #endif diff --git a/src/streams/openssl_dynamic.c b/src/streams/openssl_dynamic.c new file mode 100644 index 00000000000..37d7e734262 --- /dev/null +++ b/src/streams/openssl_dynamic.c @@ -0,0 +1,307 @@ +/* + * 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 "streams/openssl.h" +#include "streams/openssl_dynamic.h" + +#if defined(GIT_OPENSSL) && defined(GIT_OPENSSL_DYNAMIC) + +#include "runtime.h" + +#include + +unsigned char *(*ASN1_STRING_data)(ASN1_STRING *x); +const unsigned char *(*ASN1_STRING_get0_data)(const ASN1_STRING *x); +int (*ASN1_STRING_length)(const ASN1_STRING *x); +int (*ASN1_STRING_to_UTF8)(unsigned char **out, const ASN1_STRING *in); +int (*ASN1_STRING_type)(const ASN1_STRING *x); + +void *(*BIO_get_data)(BIO *a); +int (*BIO_get_new_index)(void); +int (*OPENSSL_init_ssl)(uint64_t opts, const void *settings); +void (*BIO_meth_free)(BIO_METHOD *biom); +int (*BIO_meth_set_create)(BIO_METHOD *biom, int (*create) (BIO *)); +int (*BIO_meth_set_ctrl)(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *)); +int (*BIO_meth_set_destroy)(BIO_METHOD *biom, int (*destroy) (BIO *)); +int (*BIO_meth_set_gets)(BIO_METHOD *biom, int (*gets) (BIO *, char *, int)); +int (*BIO_meth_set_puts)(BIO_METHOD *biom, int (*puts) (BIO *, const char *)); +int (*BIO_meth_set_read)(BIO_METHOD *biom, int (*read) (BIO *, char *, int)); +int (*BIO_meth_set_write)(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)); +BIO_METHOD *(*BIO_meth_new)(int type, const char *name); +BIO *(*BIO_new)(const BIO_METHOD *type); +void (*BIO_set_data)(BIO *a, void *ptr); +void (*BIO_set_init)(BIO *a, int init); + +void (*CRYPTO_free)(void *ptr, const char *file, int line); +void *(*CRYPTO_malloc)(size_t num, const char *file, int line); +int (*CRYPTO_num_locks)(void); +void (*CRYPTO_set_locking_callback)(void (*func)(int mode, int type, const char *file, int line)); +int (*CRYPTO_set_mem_functions)(void *(*m)(size_t bytes), void *(*r)(void *mem, size_t size), void (*f)(void *mem)); +int (*CRYPTO_THREADID_set_callback)(void (*func)(CRYPTO_THREADID *id)); +void (*CRYPTO_THREADID_set_numeric)(CRYPTO_THREADID *id, unsigned long val); + +char *(*ERR_error_string)(unsigned long e, char *buf); +void (*ERR_error_string_n)(unsigned long e, char *buf, size_t len); +unsigned long (*ERR_get_error)(void); + +int (*SSL_connect)(SSL *ssl); +long (*SSL_ctrl)(SSL *ssl, int cmd, long arg, void *parg); +void (*SSL_free)(SSL *ssl); +int (*SSL_get_error)(SSL *ssl, int ret); +X509 *(*SSL_get_peer_certificate)(const SSL *ssl); +long (*SSL_get_verify_result)(const SSL *ssl); +int (*SSL_library_init)(void); +void (*SSL_load_error_strings)(void); +SSL *(*SSL_new)(SSL_CTX *ctx); +int (*SSL_read)(SSL *ssl, const void *buf, int num); +void (*SSL_set_bio)(SSL *ssl, BIO *rbio, BIO *wbio); +int (*SSL_shutdown)(SSL *ssl); +int (*SSL_write)(SSL *ssl, const void *buf, int num); + +long (*SSL_CTX_ctrl)(SSL_CTX *ctx, int cmd, long larg, void *parg); +void (*SSL_CTX_free)(SSL_CTX *ctx); +SSL_CTX *(*SSL_CTX_new)(const SSL_METHOD *method); +int (*SSL_CTX_set_cipher_list)(SSL_CTX *ctx, const char *str); +int (*SSL_CTX_set_default_verify_paths)(SSL_CTX *ctx); +long (*SSL_CTX_set_options)(SSL_CTX *ctx, long options); +void (*SSL_CTX_set_verify)(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); +int (*SSL_CTX_load_verify_locations)(SSL_CTX *ctx, const char *CAfile, const char *CApath); + +const SSL_METHOD *(*SSLv23_method)(void); +const SSL_METHOD *(*TLS_method)(void); + +ASN1_STRING *(*X509_NAME_ENTRY_get_data)(const X509_NAME_ENTRY *ne); +X509_NAME_ENTRY *(*X509_NAME_get_entry)(X509_NAME *name, int loc); +int (*X509_NAME_get_index_by_NID)(X509_NAME *name, int nid, int lastpos); +void (*X509_free)(X509 *a); +void *(*X509_get_ext_d2i)(const X509 *x, int nid, int *crit, int *idx); +X509_NAME *(*X509_get_subject_name)(const X509 *x); + +int (*i2d_X509)(X509 *a, unsigned char **ppout); + +int (*OPENSSL_sk_num)(const void *sk); +void *(*OPENSSL_sk_value)(const void *sk, int i); +void (*OPENSSL_sk_free)(void *sk); + +int (*sk_num)(const void *sk); +void *(*sk_value)(const void *sk, int i); +void (*sk_free)(void *sk); + +void *openssl_handle; + +GIT_INLINE(void *) openssl_sym(int *err, const char *name, bool required) +{ + void *symbol; + + /* if we've seen an err, noop to retain it */ + if (*err) + return NULL; + + + if ((symbol = dlsym(openssl_handle, name)) == NULL && required) { + const char *msg = dlerror(); + git_error_set(GIT_ERROR_SSL, "could not load ssl function '%s': %s", name, msg ? msg : "unknown error"); + *err = -1; + } + + return symbol; +} + +static void dynamic_shutdown(void) +{ + dlclose(openssl_handle); + openssl_handle = NULL; +} + +int git_openssl_stream_dynamic_init(void) +{ + int err = 0; + + if ((openssl_handle = dlopen("libssl.so.1.1", RTLD_NOW)) == NULL && + (openssl_handle = dlopen("libssl.so.1.0.0", RTLD_NOW)) == NULL && + (openssl_handle = dlopen("libssl.so.10", RTLD_NOW)) == NULL) { + git_error_set(GIT_ERROR_SSL, "could not load ssl libraries"); + return -1; + } + + ASN1_STRING_data = (unsigned char *(*)(ASN1_STRING *x))openssl_sym(&err, "ASN1_STRING_data", false); + ASN1_STRING_get0_data = (const unsigned char *(*)(const ASN1_STRING *x))openssl_sym(&err, "ASN1_STRING_get0_data", false); + ASN1_STRING_length = (int (*)(const ASN1_STRING *))openssl_sym(&err, "ASN1_STRING_length", true); + ASN1_STRING_to_UTF8 = (int (*)(unsigned char **, const ASN1_STRING *))openssl_sym(&err, "ASN1_STRING_to_UTF8", true); + ASN1_STRING_type = (int (*)(const ASN1_STRING *))openssl_sym(&err, "ASN1_STRING_type", true); + + BIO_get_data = (void *(*)(BIO *))openssl_sym(&err, "BIO_get_data", false); + BIO_get_new_index = (int (*)(void))openssl_sym(&err, "BIO_get_new_index", false); + BIO_meth_free = (void (*)(BIO_METHOD *))openssl_sym(&err, "BIO_meth_free", false); + BIO_meth_new = (BIO_METHOD *(*)(int, const char *))openssl_sym(&err, "BIO_meth_new", false); + BIO_meth_set_create = (int (*)(BIO_METHOD *, int (*)(BIO *)))openssl_sym(&err, "BIO_meth_set_create", false); + BIO_meth_set_ctrl = (int (*)(BIO_METHOD *, long (*)(BIO *, int, long, void *)))openssl_sym(&err, "BIO_meth_set_ctrl", false); + BIO_meth_set_destroy = (int (*)(BIO_METHOD *, int (*)(BIO *)))openssl_sym(&err, "BIO_meth_set_destroy", false); + BIO_meth_set_gets = (int (*)(BIO_METHOD *, int (*)(BIO *, char *, int)))openssl_sym(&err, "BIO_meth_set_gets", false); + BIO_meth_set_puts = (int (*)(BIO_METHOD *, int (*)(BIO *, const char *)))openssl_sym(&err, "BIO_meth_set_puts", false); + BIO_meth_set_read = (int (*)(BIO_METHOD *, int (*)(BIO *, char *, int)))openssl_sym(&err, "BIO_meth_set_read", false); + BIO_meth_set_write = (int (*)(BIO_METHOD *, int (*)(BIO *, const char *, int)))openssl_sym(&err, "BIO_meth_set_write", false); + BIO_new = (BIO *(*)(const BIO_METHOD *))openssl_sym(&err, "BIO_new", true); + BIO_set_data = (void (*)(BIO *a, void *))openssl_sym(&err, "BIO_set_data", false); + BIO_set_init = (void (*)(BIO *a, int))openssl_sym(&err, "BIO_set_init", false); + + CRYPTO_free = (void (*)(void *, const char *, int))openssl_sym(&err, "CRYPTO_free", true); + CRYPTO_malloc = (void *(*)(size_t, const char *, int))openssl_sym(&err, "CRYPTO_malloc", true); + CRYPTO_num_locks = (int (*)(void))openssl_sym(&err, "CRYPTO_num_locks", false); + CRYPTO_set_locking_callback = (void (*)(void (*)(int, int, const char *, int)))openssl_sym(&err, "CRYPTO_set_locking_callback", false); + CRYPTO_set_mem_functions = (int (*)(void *(*)(size_t), void *(*)(void *, size_t), void (*f)(void *)))openssl_sym(&err, "CRYPTO_set_mem_functions", true); + + CRYPTO_THREADID_set_callback = (int (*)(void (*)(CRYPTO_THREADID *)))openssl_sym(&err, "CRYPTO_THREADID_set_callback", false); + CRYPTO_THREADID_set_numeric = (void (*)(CRYPTO_THREADID *, unsigned long))openssl_sym(&err, "CRYPTO_THREADID_set_numeric", false); + + ERR_error_string = (char *(*)(unsigned long, char *))openssl_sym(&err, "ERR_error_string", true); + ERR_error_string_n = (void (*)(unsigned long, char *, size_t))openssl_sym(&err, "ERR_error_string_n", true); + ERR_get_error = (unsigned long (*)(void))openssl_sym(&err, "ERR_get_error", true); + + OPENSSL_init_ssl = (int (*)(uint64_t opts, const void *settings))openssl_sym(&err, "OPENSSL_init_ssl", false); + OPENSSL_sk_num = (int (*)(const void *))openssl_sym(&err, "OPENSSL_sk_num", false); + OPENSSL_sk_value = (void *(*)(const void *sk, int i))openssl_sym(&err, "OPENSSL_sk_value", false); + OPENSSL_sk_free = (void (*)(void *))openssl_sym(&err, "OPENSSL_sk_free", false); + + sk_num = (int (*)(const void *))openssl_sym(&err, "sk_num", false); + sk_value = (void *(*)(const void *sk, int i))openssl_sym(&err, "sk_value", false); + sk_free = (void (*)(void *))openssl_sym(&err, "sk_free", false); + + SSL_connect = (int (*)(SSL *))openssl_sym(&err, "SSL_connect", true); + SSL_ctrl = (long (*)(SSL *, int, long, void *))openssl_sym(&err, "SSL_ctrl", true); + SSL_get_peer_certificate = (X509 *(*)(const SSL *))openssl_sym(&err, "SSL_get_peer_certificate", true); + SSL_library_init = (int (*)(void))openssl_sym(&err, "SSL_library_init", false); + SSL_free = (void (*)(SSL *))openssl_sym(&err, "SSL_free", true); + SSL_get_error = (int (*)(SSL *, int))openssl_sym(&err, "SSL_get_error", true); + SSL_get_verify_result = (long (*)(const SSL *ssl))openssl_sym(&err, "SSL_get_verify_result", true); + SSL_load_error_strings = (void (*)(void))openssl_sym(&err, "SSL_load_error_strings", false); + SSL_new = (SSL *(*)(SSL_CTX *))openssl_sym(&err, "SSL_new", true); + SSL_read = (int (*)(SSL *, const void *, int))openssl_sym(&err, "SSL_read", true); + SSL_set_bio = (void (*)(SSL *, BIO *, BIO *))openssl_sym(&err, "SSL_set_bio", true); + SSL_shutdown = (int (*)(SSL *ssl))openssl_sym(&err, "SSL_shutdown", true); + SSL_write = (int (*)(SSL *, const void *, int))openssl_sym(&err, "SSL_write", true); + + SSL_CTX_ctrl = (long (*)(SSL_CTX *, int, long, void *))openssl_sym(&err, "SSL_CTX_ctrl", true); + SSL_CTX_free = (void (*)(SSL_CTX *))openssl_sym(&err, "SSL_CTX_free", true); + SSL_CTX_new = (SSL_CTX *(*)(const SSL_METHOD *))openssl_sym(&err, "SSL_CTX_new", true); + SSL_CTX_set_cipher_list = (int (*)(SSL_CTX *, const char *))openssl_sym(&err, "SSL_CTX_set_cipher_list", true); + SSL_CTX_set_default_verify_paths = (int (*)(SSL_CTX *ctx))openssl_sym(&err, "SSL_CTX_set_default_verify_paths", true); + SSL_CTX_set_options = (long (*)(SSL_CTX *, long))openssl_sym(&err, "SSL_CTX_set_options", false); + SSL_CTX_set_verify = (void (*)(SSL_CTX *, int, int (*)(int, X509_STORE_CTX *)))openssl_sym(&err, "SSL_CTX_set_verify", true); + SSL_CTX_load_verify_locations = (int (*)(SSL_CTX *, const char *, const char *))openssl_sym(&err, "SSL_CTX_load_verify_locations", true); + + SSLv23_method = (const SSL_METHOD *(*)(void))openssl_sym(&err, "SSLv23_method", false); + TLS_method = (const SSL_METHOD *(*)(void))openssl_sym(&err, "TLS_method", false); + + X509_NAME_ENTRY_get_data = (ASN1_STRING *(*)(const X509_NAME_ENTRY *))openssl_sym(&err, "X509_NAME_ENTRY_get_data", true); + X509_NAME_get_entry = (X509_NAME_ENTRY *(*)(X509_NAME *, int))openssl_sym(&err, "X509_NAME_get_entry", true); + X509_NAME_get_index_by_NID = (int (*)(X509_NAME *, int, int))openssl_sym(&err, "X509_NAME_get_index_by_NID", true); + X509_free = (void (*)(X509 *))openssl_sym(&err, "X509_free", true); + X509_get_ext_d2i = (void *(*)(const X509 *x, int nid, int *crit, int *idx))openssl_sym(&err, "X509_get_ext_d2i", true); + X509_get_subject_name = (X509_NAME *(*)(const X509 *))openssl_sym(&err, "X509_get_subject_name", true); + + i2d_X509 = (int (*)(X509 *a, unsigned char **ppout))openssl_sym(&err, "i2d_X509", true); + + if (err) + goto on_error; + + /* Add legacy functionality */ + if (!OPENSSL_init_ssl) { + OPENSSL_init_ssl = OPENSSL_init_ssl__legacy; + + if (!SSL_library_init || + !SSL_load_error_strings || + !CRYPTO_num_locks || + !CRYPTO_set_locking_callback || + !CRYPTO_THREADID_set_callback || + !CRYPTO_THREADID_set_numeric) { + git_error_set(GIT_ERROR_SSL, "could not load legacy openssl initialization functions"); + goto on_error; + } + } + + if (!SSL_CTX_set_options) + SSL_CTX_set_options = SSL_CTX_set_options__legacy; + + if (TLS_method) + SSLv23_method = TLS_method; + + if (!BIO_meth_new) { + BIO_meth_new = BIO_meth_new__legacy; + BIO_meth_new = BIO_meth_new__legacy; + BIO_meth_free = BIO_meth_free__legacy; + BIO_meth_set_write = BIO_meth_set_write__legacy; + BIO_meth_set_read = BIO_meth_set_read__legacy; + BIO_meth_set_puts = BIO_meth_set_puts__legacy; + BIO_meth_set_gets = BIO_meth_set_gets__legacy; + BIO_meth_set_ctrl = BIO_meth_set_ctrl__legacy; + BIO_meth_set_create = BIO_meth_set_create__legacy; + BIO_meth_set_destroy = BIO_meth_set_destroy__legacy; + BIO_get_new_index = BIO_get_new_index__legacy; + BIO_set_data = BIO_set_data__legacy; + BIO_set_init = BIO_set_init__legacy; + BIO_get_data = BIO_get_data__legacy; + } + + if (!ASN1_STRING_get0_data) { + if (!ASN1_STRING_data) { + git_error_set(GIT_ERROR_SSL, "could not load legacy openssl string function"); + goto on_error; + } + + ASN1_STRING_get0_data = ASN1_STRING_get0_data__legacy; + } + + if ((!OPENSSL_sk_num && !sk_num) || + (!OPENSSL_sk_value && !sk_value) || + (!OPENSSL_sk_free && !sk_free)) { + git_error_set(GIT_ERROR_SSL, "could not load legacy openssl stack functions"); + goto on_error; + } + + if (git_runtime_shutdown_register(dynamic_shutdown) != 0) + goto on_error; + + return 0; + +on_error: + dlclose(openssl_handle); + return -1; +} + + +int sk_GENERAL_NAME_num(const GENERAL_NAME *sk) +{ + if (OPENSSL_sk_num) + return OPENSSL_sk_num(sk); + else if (sk_num) + return sk_num(sk); + + GIT_ASSERT_WITH_RETVAL(false, 0); + return 0; +} + +GENERAL_NAME *sk_GENERAL_NAME_value(const GENERAL_NAME *sk, int i) +{ + if (OPENSSL_sk_value) + return OPENSSL_sk_value(sk, i); + else if (sk_value) + return sk_value(sk, i); + + GIT_ASSERT_WITH_RETVAL(false, NULL); + return NULL; +} + +void GENERAL_NAMES_free(GENERAL_NAME *sk) +{ + if (OPENSSL_sk_free) + OPENSSL_sk_free(sk); + else if (sk_free) + sk_free(sk); +} + +#endif /* GIT_OPENSSL && GIT_OPENSSL_DYNAMIC */ diff --git a/src/streams/openssl_dynamic.h b/src/streams/openssl_dynamic.h new file mode 100644 index 00000000000..12d927a617f --- /dev/null +++ b/src/streams/openssl_dynamic.h @@ -0,0 +1,348 @@ +/* + * 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. + */ + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef INCLUDE_streams_openssl_dynamic_h__ +#define INCLUDE_streams_openssl_dynamic_h__ + +#ifdef GIT_OPENSSL_DYNAMIC + +# define BIO_CTRL_FLUSH 11 + +# define BIO_TYPE_SOURCE_SINK 0x0400 + +# define CRYPTO_LOCK 1 + +# define GEN_DNS 2 +# define GEN_IPADD 7 + +# define NID_commonName 13 +# define NID_subject_alt_name 85 + +# define SSL_VERIFY_NONE 0x00 + +# define SSL_CTRL_OPTIONS 32 +# define SSL_CTRL_MODE 33 +# define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 + +# define SSL_ERROR_NONE 0 +# define SSL_ERROR_SSL 1 +# define SSL_ERROR_WANT_READ 2 +# define SSL_ERROR_WANT_WRITE 3 +# define SSL_ERROR_WANT_X509_LOOKUP 4 +# define SSL_ERROR_SYSCALL 5 +# define SSL_ERROR_ZERO_RETURN 6 +# define SSL_ERROR_WANT_CONNECT 7 +# define SSL_ERROR_WANT_ACCEPT 8 + +# define SSL_OP_NO_COMPRESSION 0x00020000L +# define SSL_OP_NO_SSLv2 0x01000000L +# define SSL_OP_NO_SSLv3 0x02000000L + +# define SSL_MODE_AUTO_RETRY 0x00000004L + +# define TLSEXT_NAMETYPE_host_name 0 + +# define V_ASN1_UTF8STRING 12 + +# define X509_V_OK 0 + +/* Most of the OpenSSL types are mercifully opaque, so we can treat them like `void *` */ +typedef struct bio_st BIO; +typedef struct bio_method_st BIO_METHOD; +typedef void bio_info_cb; +typedef void * CRYPTO_EX_DATA; +typedef void CRYPTO_THREADID; +typedef void GENERAL_NAMES; +typedef void SSL; +typedef void SSL_CTX; +typedef void SSL_METHOD; +typedef void X509; +typedef void X509_NAME; +typedef void X509_NAME_ENTRY; +typedef void X509_STORE_CTX; + +typedef struct { + int length; + int type; + unsigned char *data; + long flags; +} ASN1_STRING; + +typedef struct { + int type; + union { + char *ptr; + ASN1_STRING *ia5; + } d; +} GENERAL_NAME; + +struct bio_st { + BIO_METHOD *method; + /* bio, mode, argp, argi, argl, ret */ + long (*callback) (struct bio_st *, int, const char *, int, long, long); + char *cb_arg; /* first argument for the callback */ + int init; + int shutdown; + int flags; /* extra storage */ + int retry_reason; + int num; + void *ptr; + struct bio_st *next_bio; /* used by filter BIOs */ + struct bio_st *prev_bio; /* used by filter BIOs */ + int references; + unsigned long num_read; + unsigned long num_write; + CRYPTO_EX_DATA ex_data; +}; + +struct bio_method_st { + int type; + const char *name; + int (*bwrite) (BIO *, const char *, int); + int (*bread) (BIO *, char *, int); + int (*bputs) (BIO *, const char *); + int (*bgets) (BIO *, char *, int); + long (*ctrl) (BIO *, int, long, void *); + int (*create) (BIO *); + int (*destroy) (BIO *); + long (*callback_ctrl) (BIO *, int, bio_info_cb *); +}; + +extern unsigned char *(*ASN1_STRING_data)(ASN1_STRING *x); +extern const unsigned char *(*ASN1_STRING_get0_data)(const ASN1_STRING *x); +extern int (*ASN1_STRING_length)(const ASN1_STRING *x); +extern int (*ASN1_STRING_to_UTF8)(unsigned char **out, const ASN1_STRING *in); +extern int (*ASN1_STRING_type)(const ASN1_STRING *x); + +extern void *(*BIO_get_data)(BIO *a); +extern int (*BIO_get_new_index)(void); +extern int (*OPENSSL_init_ssl)(uint64_t opts, const void *settings); +extern void (*BIO_meth_free)(BIO_METHOD *biom); +extern int (*BIO_meth_set_create)(BIO_METHOD *biom, int (*create) (BIO *)); +extern int (*BIO_meth_set_ctrl)(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *)); +extern int (*BIO_meth_set_destroy)(BIO_METHOD *biom, int (*destroy) (BIO *)); +extern int (*BIO_meth_set_gets)(BIO_METHOD *biom, int (*gets) (BIO *, char *, int)); +extern int (*BIO_meth_set_puts)(BIO_METHOD *biom, int (*puts) (BIO *, const char *)); +extern int (*BIO_meth_set_read)(BIO_METHOD *biom, int (*read) (BIO *, char *, int)); +extern int (*BIO_meth_set_write)(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)); +extern BIO_METHOD *(*BIO_meth_new)(int type, const char *name); +extern BIO *(*BIO_new)(const BIO_METHOD *type); +extern void (*BIO_set_data)(BIO *a, void *ptr); +extern void (*BIO_set_init)(BIO *a, int init); + +extern void (*CRYPTO_free)(void *ptr, const char *file, int line); +extern void *(*CRYPTO_malloc)(size_t num, const char *file, int line); +extern int (*CRYPTO_num_locks)(void); +extern void (*CRYPTO_set_locking_callback)(void (*func)(int mode, int type, const char *file, int line)); +extern int (*CRYPTO_set_mem_functions)(void *(*m)(size_t bytes), void *(*r)(void *mem, size_t size), void (*f)(void *mem)); +extern int (*CRYPTO_THREADID_set_callback)(void (*func)(CRYPTO_THREADID *id)); +extern void (*CRYPTO_THREADID_set_numeric)(CRYPTO_THREADID *id, unsigned long val); + +extern char *(*ERR_error_string)(unsigned long e, char *buf); +extern void (*ERR_error_string_n)(unsigned long e, char *buf, size_t len); +extern unsigned long (*ERR_get_error)(void); + +# define OPENSSL_malloc(num) CRYPTO_malloc(num, __FILE__, __LINE__) +# define OPENSSL_free(addr) CRYPTO_free(addr, __FILE__, __LINE__) + +extern int (*SSL_connect)(SSL *ssl); +extern long (*SSL_ctrl)(SSL *ssl, int cmd, long arg, void *parg); +extern void (*SSL_free)(SSL *ssl); +extern int (*SSL_get_error)(SSL *ssl, int ret); +extern X509 *(*SSL_get_peer_certificate)(const SSL *ssl); +extern long (*SSL_get_verify_result)(const SSL *ssl); +extern int (*SSL_library_init)(void); +extern void (*SSL_load_error_strings)(void); +extern SSL *(*SSL_new)(SSL_CTX *ctx); +extern int (*SSL_read)(SSL *ssl, const void *buf, int num); +extern void (*SSL_set_bio)(SSL *ssl, BIO *rbio, BIO *wbio); +extern int (*SSL_shutdown)(SSL *ssl); +extern int (*SSL_write)(SSL *ssl, const void *buf, int num); + +# define SSL_set_tlsext_host_name(s, name) SSL_ctrl((s), SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, (char *)(name)); + +extern long (*SSL_CTX_ctrl)(SSL_CTX *ctx, int cmd, long larg, void *parg); +extern void (*SSL_CTX_free)(SSL_CTX *ctx); +extern SSL_CTX *(*SSL_CTX_new)(const SSL_METHOD *method); +extern int (*SSL_CTX_set_cipher_list)(SSL_CTX *ctx, const char *str); +extern int (*SSL_CTX_set_default_verify_paths)(SSL_CTX *ctx); +extern long (*SSL_CTX_set_options)(SSL_CTX *ctx, long options); +extern void (*SSL_CTX_set_verify)(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); +extern int (*SSL_CTX_load_verify_locations)(SSL_CTX *ctx, const char *CAfile, const char *CApath); + +# define SSL_CTX_set_mode(ctx, mode) SSL_CTX_ctrl((ctx), SSL_CTRL_MODE, (mode), NULL); + +extern const SSL_METHOD *(*SSLv23_method)(void); +extern const SSL_METHOD *(*TLS_method)(void); + +extern ASN1_STRING *(*X509_NAME_ENTRY_get_data)(const X509_NAME_ENTRY *ne); +extern X509_NAME_ENTRY *(*X509_NAME_get_entry)(X509_NAME *name, int loc); +extern int (*X509_NAME_get_index_by_NID)(X509_NAME *name, int nid, int lastpos); +extern void (*X509_free)(X509 *a); +extern void *(*X509_get_ext_d2i)(const X509 *x, int nid, int *crit, int *idx); +extern X509_NAME *(*X509_get_subject_name)(const X509 *x); + +extern int (*i2d_X509)(X509 *a, unsigned char **ppout); + +extern int (*OPENSSL_sk_num)(const void *sk); +extern void *(*OPENSSL_sk_value)(const void *sk, int i); +extern void (*OPENSSL_sk_free)(void *sk); + +extern int (*sk_num)(const void *sk); +extern void *(*sk_value)(const void *sk, int i); +extern void (*sk_free)(void *sk); + +extern int sk_GENERAL_NAME_num(const GENERAL_NAME *sk); +extern GENERAL_NAME *sk_GENERAL_NAME_value(const GENERAL_NAME *sk, int i); +extern void GENERAL_NAMES_free(GENERAL_NAME *sk); + +extern int git_openssl_stream_dynamic_init(void); + +#endif /* GIT_OPENSSL_DYNAMIC */ + +#endif diff --git a/src/streams/openssl_legacy.c b/src/streams/openssl_legacy.c index 3f097be619f..1c1ff60c07b 100644 --- a/src/streams/openssl_legacy.c +++ b/src/streams/openssl_legacy.c @@ -8,16 +8,18 @@ #include "streams/openssl.h" #include "streams/openssl_legacy.h" -#if defined(GIT_OPENSSL) && defined(GIT_OPENSSL_LEGACY) - -#include -#include -#include -#include - #include "runtime.h" #include "git2/sys/openssl.h" +#if defined(GIT_OPENSSL) && !defined(GIT_OPENSSL_DYNAMIC) +# include +# include +# include +# include +#endif + +#if defined(GIT_OPENSSL_LEGACY) || defined(GIT_OPENSSL_DYNAMIC) + /* * OpenSSL 1.1 made BIO opaque so we have to use functions to interact with it * which do not exist in previous versions. We define these inline functions so @@ -25,16 +27,16 @@ * with ifdefs. We do the same for OPENSSL_init_ssl. */ -int OPENSSL_init_ssl(int opts, void *settings) +int OPENSSL_init_ssl__legacy(uint64_t opts, const void *settings) { GIT_UNUSED(opts); GIT_UNUSED(settings); SSL_load_error_strings(); - OpenSSL_add_ssl_algorithms(); + SSL_library_init(); return 0; } -BIO_METHOD* BIO_meth_new(int type, const char *name) +BIO_METHOD* BIO_meth_new__legacy(int type, const char *name) { BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD)); if (!meth) { @@ -47,85 +49,89 @@ BIO_METHOD* BIO_meth_new(int type, const char *name) return meth; } -void BIO_meth_free(BIO_METHOD *biom) +void BIO_meth_free__legacy(BIO_METHOD *biom) { git__free(biom); } -int BIO_meth_set_write(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)) +int BIO_meth_set_write__legacy(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)) { biom->bwrite = write; return 1; } -int BIO_meth_set_read(BIO_METHOD *biom, int (*read) (BIO *, char *, int)) +int BIO_meth_set_read__legacy(BIO_METHOD *biom, int (*read) (BIO *, char *, int)) { biom->bread = read; return 1; } -int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts) (BIO *, const char *)) +int BIO_meth_set_puts__legacy(BIO_METHOD *biom, int (*puts) (BIO *, const char *)) { biom->bputs = puts; return 1; } -int BIO_meth_set_gets(BIO_METHOD *biom, int (*gets) (BIO *, char *, int)) +int BIO_meth_set_gets__legacy(BIO_METHOD *biom, int (*gets) (BIO *, char *, int)) { biom->bgets = gets; return 1; } -int BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *)) +int BIO_meth_set_ctrl__legacy(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *)) { biom->ctrl = ctrl; return 1; } -int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *)) +int BIO_meth_set_create__legacy(BIO_METHOD *biom, int (*create) (BIO *)) { biom->create = create; return 1; } -int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *)) +int BIO_meth_set_destroy__legacy(BIO_METHOD *biom, int (*destroy) (BIO *)) { biom->destroy = destroy; return 1; } -int BIO_get_new_index(void) +int BIO_get_new_index__legacy(void) { /* This exists as of 1.1 so before we'd just have 0 */ return 0; } -void BIO_set_init(BIO *b, int init) +void BIO_set_init__legacy(BIO *b, int init) { b->init = init; } -void BIO_set_data(BIO *a, void *ptr) +void BIO_set_data__legacy(BIO *a, void *ptr) { a->ptr = ptr; } -void *BIO_get_data(BIO *a) +void *BIO_get_data__legacy(BIO *a) { return a->ptr; } -const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) +const unsigned char *ASN1_STRING_get0_data__legacy(const ASN1_STRING *x) { return ASN1_STRING_data((ASN1_STRING *)x); } +long SSL_CTX_set_options__legacy(SSL_CTX *ctx, long op) +{ + return SSL_CTX_ctrl(ctx, SSL_CTRL_OPTIONS, op, NULL); +} + # if defined(GIT_THREADS) static git_mutex *openssl_locks; -static void openssl_locking_function( - int mode, int n, const char *file, int line) +static void openssl_locking_function(int mode, int n, const char *file, int line) { int lock; @@ -134,11 +140,10 @@ static void openssl_locking_function( lock = mode & CRYPTO_LOCK; - if (lock) { + if (lock) (void)git_mutex_lock(&openssl_locks[n]); - } else { + else git_mutex_unlock(&openssl_locks[n]); - } } static void shutdown_ssl_locking(void) @@ -163,6 +168,20 @@ int git_openssl_set_locking(void) { int num_locks, i; +#ifndef GIT_THREADS + git_error_set(GIT_ERROR_THREAD, "libgit2 was not built with threads"); + return -1; +#endif + +#ifdef GIT_OPENSSL_DYNAMIC + /* + * This function is required on legacy versions of OpenSSL; when building + * with dynamically-loaded OpenSSL, we detect whether we loaded it or not. + */ + if (!CRYPTO_set_locking_callback) + return 0; +#endif + CRYPTO_THREADID_set_callback(threadid_cb); num_locks = CRYPTO_num_locks(); @@ -181,21 +200,4 @@ int git_openssl_set_locking(void) } #endif /* GIT_THREADS */ -#ifdef VALGRIND -void *git_openssl_malloc(size_t bytes) -{ - return git__calloc(1, bytes); -} - -void *git_openssl_realloc(void *mem, size_t size) -{ - return git__realloc(mem, size); -} - -void git_openssl_free(void *mem) -{ - return git__free(mem); -} -#endif - -#endif /* GIT_OPENSSL && GIT_OPENSSL_LEGACY */ +#endif /* GIT_OPENSSL_LEGACY || GIT_OPENSSL_DYNAMIC */ diff --git a/src/streams/openssl_legacy.h b/src/streams/openssl_legacy.h index 7ccc13838e3..1f74fd95ab9 100644 --- a/src/streams/openssl_legacy.h +++ b/src/streams/openssl_legacy.h @@ -7,7 +7,9 @@ #ifndef INCLUDE_streams_openssl_legacy_h__ #define INCLUDE_streams_openssl_legacy_h__ -#ifdef GIT_OPENSSL +#include "streams/openssl_dynamic.h" + +#if defined(GIT_OPENSSL) && !defined(GIT_OPENSSL_DYNAMIC) # include # include # include @@ -19,23 +21,42 @@ # endif #endif -#ifdef GIT_OPENSSL_LEGACY - -extern int OPENSSL_init_ssl(int opts, void *settings); -extern BIO_METHOD* BIO_meth_new(int type, const char *name); -extern void BIO_meth_free(BIO_METHOD *biom); -extern int BIO_meth_set_write(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)); -extern int BIO_meth_set_read(BIO_METHOD *biom, int (*read) (BIO *, char *, int)); -extern int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts) (BIO *, const char *)); -extern int BIO_meth_set_gets(BIO_METHOD *biom, int (*gets) (BIO *, char *, int)); -extern int BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *)); -extern int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *)); -extern int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *)); -extern int BIO_get_new_index(void); -extern void BIO_set_data(BIO *a, void *ptr); -extern void BIO_set_init(BIO *b, int init); -extern void *BIO_get_data(BIO *a); -extern const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); +#if defined(GIT_OPENSSL_LEGACY) && !defined(GIT_OPENSSL_DYNAMIC) +# define OPENSSL_init_ssl OPENSSL_init_ssl__legacy +# define BIO_meth_new BIO_meth_new__legacy +# define BIO_meth_free BIO_meth_free__legacy +# define BIO_meth_set_write BIO_meth_set_write__legacy +# define BIO_meth_set_read BIO_meth_set_read__legacy +# define BIO_meth_set_puts BIO_meth_set_puts__legacy +# define BIO_meth_set_gets BIO_meth_set_gets__legacy +# define BIO_meth_set_ctrl BIO_meth_set_ctrl__legacy +# define BIO_meth_set_create BIO_meth_set_create__legacy +# define BIO_meth_set_destroy BIO_meth_set_destroy__legacy +# define BIO_get_new_index BIO_get_new_index__legacy +# define BIO_set_data BIO_set_data__legacy +# define BIO_set_init BIO_set_init__legacy +# define BIO_get_data BIO_get_data__legacy +# define ASN1_STRING_get0_data ASN1_STRING_get0_data__legacy +#endif + +#if defined(GIT_OPENSSL_LEGACY) || defined(GIT_OPENSSL_DYNAMIC) + +extern int OPENSSL_init_ssl__legacy(uint64_t opts, const void *settings); +extern BIO_METHOD* BIO_meth_new__legacy(int type, const char *name); +extern void BIO_meth_free__legacy(BIO_METHOD *biom); +extern int BIO_meth_set_write__legacy(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)); +extern int BIO_meth_set_read__legacy(BIO_METHOD *biom, int (*read) (BIO *, char *, int)); +extern int BIO_meth_set_puts__legacy(BIO_METHOD *biom, int (*puts) (BIO *, const char *)); +extern int BIO_meth_set_gets__legacy(BIO_METHOD *biom, int (*gets) (BIO *, char *, int)); +extern int BIO_meth_set_ctrl__legacy(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *)); +extern int BIO_meth_set_create__legacy(BIO_METHOD *biom, int (*create) (BIO *)); +extern int BIO_meth_set_destroy__legacy(BIO_METHOD *biom, int (*destroy) (BIO *)); +extern int BIO_get_new_index__legacy(void); +extern void BIO_set_data__legacy(BIO *a, void *ptr); +extern void BIO_set_init__legacy(BIO *b, int init); +extern void *BIO_get_data__legacy(BIO *a); +extern const unsigned char *ASN1_STRING_get0_data__legacy(const ASN1_STRING *x); +extern long SSL_CTX_set_options__legacy(SSL_CTX *ctx, long op); #endif From c9b80c257309c68bcb66476dee42134d80975072 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 21 Aug 2021 15:28:45 -0400 Subject: [PATCH 0442/1616] valgrind: suppress leaks in dlopen and newer libraries dlopen sets up some thread-local state that isn't cleaned up by `dlclose`. Additionally, now that we're linking against different versions of libssh2 and OpenSSL, we're seeing different leak signatures. --- script/valgrind.supp | 64 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/script/valgrind.supp b/script/valgrind.supp index d938aa9c9c7..8c4549f62be 100644 --- a/script/valgrind.supp +++ b/script/valgrind.supp @@ -41,6 +41,38 @@ ... } +{ + ignore-openssl-init-leak + Memcheck:Leak + ... + fun:git_openssl_stream_global_init + ... +} + +{ + ignore-openssl-legacy-init-leak + Memcheck:Leak + ... + fun:OPENSSL_init_ssl__legacy + ... +} + +{ + ignore-openssl-malloc-leak + Memcheck:Leak + ... + fun:git_openssl_malloc + ... +} + +{ + ignore-openssl-realloc-leak + Memcheck:Leak + ... + fun:git_openssl_realloc + ... +} + { ignore-glibc-getaddrinfo-cache Memcheck:Leak @@ -64,6 +96,22 @@ ... } +{ + ignore-libssh2-session-create + Memcheck:Leak + ... + fun:_git_ssh_session_create + ... +} + +{ + ignore-libssh2-setup-conn + Memcheck:Leak + ... + fun:_git_ssh_setup_conn + ... +} + { ignore-libssh2-gcrypt-control-leak Memcheck:Leak @@ -178,3 +226,19 @@ obj:*libcrypto.so* ... } + +{ + ignore-dlopen-leak + Memcheck:Leak + ... + fun:dlopen + ... +} + +{ + ignore-dlopen-leak + Memcheck:Leak + ... + fun:_dlerror_run + ... +} From 5158b0b70ade89268b22b7c388802b5f5b6debce Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Aug 2021 11:56:22 -0400 Subject: [PATCH 0443/1616] ntlmclient: update to ntlmclient 0.9.1 The ntlmclient dependency can now dynamically load OpenSSL. --- deps/ntlmclient/CMakeLists.txt | 22 ++- deps/ntlmclient/crypt.h | 23 ++- deps/ntlmclient/crypt_commoncrypto.c | 40 ++-- deps/ntlmclient/crypt_commoncrypto.h | 6 +- deps/ntlmclient/crypt_mbedtls.c | 73 ++++---- deps/ntlmclient/crypt_mbedtls.h | 7 +- deps/ntlmclient/crypt_openssl.c | 229 ++++++++++++++++++----- deps/ntlmclient/crypt_openssl.h | 79 +++++++- deps/ntlmclient/ntlm.c | 268 +++++++++++++++------------ deps/ntlmclient/ntlm.h | 22 ++- deps/ntlmclient/ntlmclient.h | 19 +- deps/ntlmclient/unicode.h | 14 +- deps/ntlmclient/unicode_builtin.c | 43 ++--- deps/ntlmclient/unicode_builtin.h | 20 ++ deps/ntlmclient/unicode_iconv.c | 80 +++----- deps/ntlmclient/unicode_iconv.h | 22 +++ src/transports/auth_ntlm.c | 2 +- 17 files changed, 623 insertions(+), 346 deletions(-) create mode 100644 deps/ntlmclient/unicode_builtin.h create mode 100644 deps/ntlmclient/unicode_iconv.h diff --git a/deps/ntlmclient/CMakeLists.txt b/deps/ntlmclient/CMakeLists.txt index d933f4919ac..3e0d2c817b8 100644 --- a/deps/ntlmclient/CMakeLists.txt +++ b/deps/ntlmclient/CMakeLists.txt @@ -1,25 +1,37 @@ -FILE(GLOB SRC_NTLMCLIENT "ntlm.c" "unicode_builtin.c" "util.c") +FILE(GLOB SRC_NTLMCLIENT "ntlm.c" "ntlm.h" "util.c" "util.h") LIST(SORT SRC_NTLMCLIENT) ADD_DEFINITIONS(-DNTLM_STATIC=1) DISABLE_WARNINGS(implicit-fallthrough) +IF(USE_ICONV) + ADD_DEFINITIONS(-DUNICODE_ICONV=1) + FILE(GLOB SRC_NTLMCLIENT_UNICODE "unicode_iconv.c" "unicode_iconv.h") +ELSE() + ADD_DEFINITIONS(-DUNICODE_BUILTIN=1) + FILE(GLOB SRC_NTLMCLIENT_UNICODE "unicode_builtin.c" "unicode_builtin.h") +ENDIF() + IF(USE_HTTPS STREQUAL "SecureTransport") ADD_DEFINITIONS(-DCRYPT_COMMONCRYPTO) - SET(SRC_NTLMCLIENT_CRYPTO "crypt_commoncrypto.c") + SET(SRC_NTLMCLIENT_CRYPTO "crypt_commoncrypto.c" "crypt_commoncrypto.h") # CC_MD4 has been deprecated in macOS 10.15. SET_SOURCE_FILES_PROPERTIES("crypt_commoncrypto.c" COMPILE_FLAGS "-Wno-deprecated") ELSEIF(USE_HTTPS STREQUAL "OpenSSL") ADD_DEFINITIONS(-DCRYPT_OPENSSL) INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) - SET(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c") + SET(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c" "crypt_openssl.h") +ELSEIF(USE_HTTPS STREQUAL "OpenSSL-Dynamic") + ADD_DEFINITIONS(-DCRYPT_OPENSSL) + ADD_DEFINITIONS(-DCRYPT_OPENSSL_DYNAMIC) + SET(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c" "crypt_openssl.h") ELSEIF(USE_HTTPS STREQUAL "mbedTLS") ADD_DEFINITIONS(-DCRYPT_MBEDTLS) INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIR}) - SET(SRC_NTLMCLIENT_CRYPTO "crypt_mbedtls.c") + SET(SRC_NTLMCLIENT_CRYPTO "crypt_mbedtls.c" "crypt_mbedtls.h") ELSE() MESSAGE(FATAL_ERROR "Unable to use libgit2's HTTPS backend (${USE_HTTPS}) for NTLM crypto") ENDIF() -ADD_LIBRARY(ntlmclient OBJECT ${SRC_NTLMCLIENT} ${SRC_NTLMCLIENT_CRYPTO}) +ADD_LIBRARY(ntlmclient OBJECT ${SRC_NTLMCLIENT} ${SRC_NTLMCLIENT_UNICODE} ${SRC_NTLMCLIENT_CRYPTO}) diff --git a/deps/ntlmclient/crypt.h b/deps/ntlmclient/crypt.h index 48be3994631..4ad543ef78e 100644 --- a/deps/ntlmclient/crypt.h +++ b/deps/ntlmclient/crypt.h @@ -9,6 +9,9 @@ #ifndef PRIVATE_CRYPT_COMMON_H__ #define PRIVATE_CRYPT_COMMON_H__ +#include "ntlmclient.h" +#include "ntlm.h" + #if defined(CRYPT_OPENSSL) # include "crypt_openssl.h" #elif defined(CRYPT_MBEDTLS) @@ -25,40 +28,42 @@ typedef unsigned char ntlm_des_block[CRYPT_DES_BLOCKSIZE]; +typedef struct ntlm_crypt_ctx ntlm_crypt_ctx; + +extern bool ntlm_crypt_init(ntlm_client *ntlm); + extern bool ntlm_random_bytes( - ntlm_client *ntlm, unsigned char *out, + ntlm_client *ntlm, size_t len); extern bool ntlm_des_encrypt( ntlm_des_block *out, + ntlm_client *ntlm, ntlm_des_block *plaintext, ntlm_des_block *key); extern bool ntlm_md4_digest( unsigned char out[CRYPT_MD4_DIGESTSIZE], + ntlm_client *ntlm, const unsigned char *in, size_t in_len); -extern ntlm_hmac_ctx *ntlm_hmac_ctx_init(void); - -extern bool ntlm_hmac_ctx_reset(ntlm_hmac_ctx *ctx); - extern bool ntlm_hmac_md5_init( - ntlm_hmac_ctx *ctx, + ntlm_client *ntlm, const unsigned char *key, size_t key_len); extern bool ntlm_hmac_md5_update( - ntlm_hmac_ctx *ctx, + ntlm_client *ntlm, const unsigned char *data, size_t data_len); extern bool ntlm_hmac_md5_final( unsigned char *out, size_t *out_len, - ntlm_hmac_ctx *ctx); + ntlm_client *ntlm); -extern void ntlm_hmac_ctx_free(ntlm_hmac_ctx *ctx); +extern void ntlm_crypt_shutdown(ntlm_client *ntlm); #endif /* PRIVATE_CRYPT_COMMON_H__ */ diff --git a/deps/ntlmclient/crypt_commoncrypto.c b/deps/ntlmclient/crypt_commoncrypto.c index 54a0f097b9e..4ff57edd29a 100644 --- a/deps/ntlmclient/crypt_commoncrypto.c +++ b/deps/ntlmclient/crypt_commoncrypto.c @@ -18,9 +18,15 @@ #include "ntlm.h" #include "crypt.h" +bool ntlm_crypt_init(ntlm_client *ntlm) +{ + memset(&ntlm->crypt_ctx, 0, sizeof(ntlm_crypt_ctx)); + return true; +} + bool ntlm_random_bytes( - ntlm_client *ntlm, unsigned char *out, + ntlm_client *ntlm, size_t len) { int fd, ret; @@ -49,11 +55,14 @@ bool ntlm_random_bytes( bool ntlm_des_encrypt( ntlm_des_block *out, + ntlm_client *ntlm, ntlm_des_block *plaintext, ntlm_des_block *key) { size_t written; + NTLM_UNUSED(ntlm); + CCCryptorStatus result = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key, sizeof(ntlm_des_block), NULL, @@ -65,56 +74,47 @@ bool ntlm_des_encrypt( bool ntlm_md4_digest( unsigned char out[CRYPT_MD4_DIGESTSIZE], + ntlm_client *ntlm, const unsigned char *in, size_t in_len) { + NTLM_UNUSED(ntlm); return !!CC_MD4(in, in_len, out); } -ntlm_hmac_ctx *ntlm_hmac_ctx_init(void) -{ - return calloc(1, sizeof(ntlm_hmac_ctx)); -} - -bool ntlm_hmac_ctx_reset(ntlm_hmac_ctx *ctx) -{ - memset(ctx, 0, sizeof(ntlm_hmac_ctx)); - return true; -} - bool ntlm_hmac_md5_init( - ntlm_hmac_ctx *ctx, + ntlm_client *ntlm, const unsigned char *key, size_t key_len) { - CCHmacInit(&ctx->native, kCCHmacAlgMD5, key, key_len); + CCHmacInit(&ntlm->crypt_ctx.hmac, kCCHmacAlgMD5, key, key_len); return true; } bool ntlm_hmac_md5_update( - ntlm_hmac_ctx *ctx, + ntlm_client *ntlm, const unsigned char *data, size_t data_len) { - CCHmacUpdate(&ctx->native, data, data_len); + CCHmacUpdate(&ntlm->crypt_ctx.hmac, data, data_len); return true; } bool ntlm_hmac_md5_final( unsigned char *out, size_t *out_len, - ntlm_hmac_ctx *ctx) + ntlm_client *ntlm) { if (*out_len < CRYPT_MD5_DIGESTSIZE) return false; - CCHmacFinal(&ctx->native, out); + CCHmacFinal(&ntlm->crypt_ctx.hmac, out); *out_len = CRYPT_MD5_DIGESTSIZE; return true; } -void ntlm_hmac_ctx_free(ntlm_hmac_ctx *ctx) +void ntlm_crypt_shutdown(ntlm_client *ntlm) { - free(ctx); + NTLM_UNUSED(ntlm); } diff --git a/deps/ntlmclient/crypt_commoncrypto.h b/deps/ntlmclient/crypt_commoncrypto.h index e4075c9f634..e4df91d2951 100644 --- a/deps/ntlmclient/crypt_commoncrypto.h +++ b/deps/ntlmclient/crypt_commoncrypto.h @@ -11,8 +11,8 @@ #include -typedef struct { - CCHmacContext native; -} ntlm_hmac_ctx; +struct ntlm_crypt_ctx { + CCHmacContext hmac; +}; #endif /* PRIVATE_CRYPT_COMMONCRYPTO_H__ */ diff --git a/deps/ntlmclient/crypt_mbedtls.c b/deps/ntlmclient/crypt_mbedtls.c index bbab02d7de5..6283c3eec08 100644 --- a/deps/ntlmclient/crypt_mbedtls.c +++ b/deps/ntlmclient/crypt_mbedtls.c @@ -17,9 +17,24 @@ #include "ntlm.h" #include "crypt.h" +bool ntlm_crypt_init(ntlm_client *ntlm) +{ + const mbedtls_md_info_t *info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5); + + mbedtls_md_init(&ntlm->crypt_ctx.hmac); + + if (mbedtls_md_setup(&ntlm->crypt_ctx.hmac, info, 1) != 0) { + ntlm_client_set_errmsg(ntlm, "could not setup mbedtls digest"); + return false; + } + + return true; +} + + bool ntlm_random_bytes( - ntlm_client *ntlm, unsigned char *out, + ntlm_client *ntlm, size_t len) { mbedtls_ctr_drbg_context ctr_drbg; @@ -51,6 +66,7 @@ bool ntlm_random_bytes( bool ntlm_des_encrypt( ntlm_des_block *out, + ntlm_client *ntlm, ntlm_des_block *plaintext, ntlm_des_block *key) { @@ -60,8 +76,10 @@ bool ntlm_des_encrypt( mbedtls_des_init(&ctx); if (mbedtls_des_setkey_enc(&ctx, *key) || - mbedtls_des_crypt_ecb(&ctx, *plaintext, *out)) + mbedtls_des_crypt_ecb(&ctx, *plaintext, *out)) { + ntlm_client_set_errmsg(ntlm, "DES encryption failed"); goto done; + } success = true; @@ -72,11 +90,14 @@ bool ntlm_des_encrypt( bool ntlm_md4_digest( unsigned char out[CRYPT_MD4_DIGESTSIZE], + ntlm_client *ntlm, const unsigned char *in, size_t in_len) { mbedtls_md4_context ctx; + NTLM_UNUSED(ntlm); + mbedtls_md4_init(&ctx); mbedtls_md4_starts(&ctx); mbedtls_md4_update(&ctx, in, in_len); @@ -86,60 +107,40 @@ bool ntlm_md4_digest( return true; } -ntlm_hmac_ctx *ntlm_hmac_ctx_init(void) -{ - ntlm_hmac_ctx *ctx; - const mbedtls_md_info_t *info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5); - - if ((ctx = calloc(1, sizeof(ntlm_hmac_ctx))) == NULL) - return NULL; - - mbedtls_md_init(&ctx->mbed); - - if (mbedtls_md_setup(&ctx->mbed, info, 1) != 0) { - free(ctx); - return false; - } - - return ctx; -} - -bool ntlm_hmac_ctx_reset(ntlm_hmac_ctx *ctx) -{ - return !mbedtls_md_hmac_reset(&ctx->mbed); -} - bool ntlm_hmac_md5_init( - ntlm_hmac_ctx *ctx, + ntlm_client *ntlm, const unsigned char *key, size_t key_len) { - return !mbedtls_md_hmac_starts(&ctx->mbed, key, key_len); + if (ntlm->crypt_ctx.hmac_initialized) { + if (mbedtls_md_hmac_reset(&ntlm->crypt_ctx.hmac)) + return false; + } + + ntlm->crypt_ctx.hmac_initialized = !mbedtls_md_hmac_starts(&ntlm->crypt_ctx.hmac, key, key_len); + return ntlm->crypt_ctx.hmac_initialized; } bool ntlm_hmac_md5_update( - ntlm_hmac_ctx *ctx, + ntlm_client *ntlm, const unsigned char *in, size_t in_len) { - return !mbedtls_md_hmac_update(&ctx->mbed, in, in_len); + return !mbedtls_md_hmac_update(&ntlm->crypt_ctx.hmac, in, in_len); } bool ntlm_hmac_md5_final( unsigned char *out, size_t *out_len, - ntlm_hmac_ctx *ctx) + ntlm_client *ntlm) { if (*out_len < CRYPT_MD5_DIGESTSIZE) return false; - return !mbedtls_md_hmac_finish(&ctx->mbed, out); + return !mbedtls_md_hmac_finish(&ntlm->crypt_ctx.hmac, out); } -void ntlm_hmac_ctx_free(ntlm_hmac_ctx *ctx) +void ntlm_crypt_shutdown(ntlm_client *ntlm) { - if (ctx) { - mbedtls_md_free(&ctx->mbed); - free(ctx); - } + mbedtls_md_free(&ntlm->crypt_ctx.hmac); } diff --git a/deps/ntlmclient/crypt_mbedtls.h b/deps/ntlmclient/crypt_mbedtls.h index eb49a459646..2fc85035d9f 100644 --- a/deps/ntlmclient/crypt_mbedtls.h +++ b/deps/ntlmclient/crypt_mbedtls.h @@ -11,8 +11,9 @@ #include "mbedtls/md.h" -typedef struct { - mbedtls_md_context_t mbed; -} ntlm_hmac_ctx; +struct ntlm_crypt_ctx { + mbedtls_md_context_t hmac; + unsigned int hmac_initialized : 1; +}; #endif /* PRIVATE_CRYPT_MBEDTLS_H__ */ diff --git a/deps/ntlmclient/crypt_openssl.c b/deps/ntlmclient/crypt_openssl.c index c0d36d891bc..463eae4f8fe 100644 --- a/deps/ntlmclient/crypt_openssl.c +++ b/deps/ntlmclient/crypt_openssl.c @@ -9,26 +9,166 @@ #include #include -#include -#include -#include -#include -#include +#ifdef CRYPT_OPENSSL_DYNAMIC +# include +#else +# include +# include +# include +# include +# include +#endif #include "ntlm.h" #include "compat.h" #include "util.h" #include "crypt.h" +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(CRYPT_OPENSSL_DYNAMIC) + +static inline HMAC_CTX *HMAC_CTX_new(void) +{ + return calloc(1, sizeof(HMAC_CTX)); +} + +static inline int HMAC_CTX_reset(HMAC_CTX *ctx) +{ + ntlm_memzero(ctx, sizeof(HMAC_CTX)); + return 1; +} + +static inline void HMAC_CTX_free(HMAC_CTX *ctx) +{ + free(ctx); +} + +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L || defined(CRYPT_OPENSSL_DYNAMIC) + +static inline void HMAC_CTX_cleanup(HMAC_CTX *ctx) +{ + NTLM_UNUSED(ctx); +} + +#endif + + +#ifdef CRYPT_OPENSSL_DYNAMIC + +static bool ntlm_crypt_init_functions(ntlm_client *ntlm) +{ + void *handle; + + if ((handle = dlopen("libssl.so.1.1", RTLD_NOW)) == NULL && + (handle = dlopen("libssl.1.1.dylib", RTLD_NOW)) == NULL && + (handle = dlopen("libssl.so.1.0.0", RTLD_NOW)) == NULL && + (handle = dlopen("libssl.1.0.0.dylib", RTLD_NOW)) == NULL && + (handle = dlopen("libssl.so.10", RTLD_NOW)) == NULL) { + ntlm_client_set_errmsg(ntlm, "could not open libssl"); + return false; + } + + ntlm->crypt_ctx.des_set_key_fn = dlsym(handle, "DES_set_key"); + ntlm->crypt_ctx.des_ecb_encrypt_fn = dlsym(handle, "DES_ecb_encrypt"); + ntlm->crypt_ctx.err_get_error_fn = dlsym(handle, "ERR_get_error"); + ntlm->crypt_ctx.err_lib_error_string_fn = dlsym(handle, "ERR_lib_error_string"); + ntlm->crypt_ctx.evp_md5_fn = dlsym(handle, "EVP_md5"); + ntlm->crypt_ctx.hmac_ctx_new_fn = dlsym(handle, "HMAC_CTX_new"); + ntlm->crypt_ctx.hmac_ctx_free_fn = dlsym(handle, "HMAC_CTX_free"); + ntlm->crypt_ctx.hmac_ctx_reset_fn = dlsym(handle, "HMAC_CTX_reset"); + ntlm->crypt_ctx.hmac_init_ex_fn = dlsym(handle, "HMAC_Init_ex"); + ntlm->crypt_ctx.hmac_update_fn = dlsym(handle, "HMAC_Update"); + ntlm->crypt_ctx.hmac_final_fn = dlsym(handle, "HMAC_Final"); + ntlm->crypt_ctx.md4_fn = dlsym(handle, "MD4"); + ntlm->crypt_ctx.rand_bytes_fn = dlsym(handle, "RAND_bytes"); + + if (!ntlm->crypt_ctx.des_set_key_fn || + !ntlm->crypt_ctx.des_ecb_encrypt_fn || + !ntlm->crypt_ctx.err_get_error_fn || + !ntlm->crypt_ctx.err_lib_error_string_fn || + !ntlm->crypt_ctx.evp_md5_fn || + !ntlm->crypt_ctx.hmac_init_ex_fn || + !ntlm->crypt_ctx.hmac_update_fn || + !ntlm->crypt_ctx.hmac_final_fn || + !ntlm->crypt_ctx.md4_fn || + !ntlm->crypt_ctx.rand_bytes_fn) { + ntlm_client_set_errmsg(ntlm, "could not load libssl functions"); + dlclose(handle); + return false; + } + + /* Toggle legacy HMAC context functions */ + if (ntlm->crypt_ctx.hmac_ctx_new_fn && + ntlm->crypt_ctx.hmac_ctx_free_fn && + ntlm->crypt_ctx.hmac_ctx_reset_fn) { + ntlm->crypt_ctx.hmac_ctx_cleanup_fn = HMAC_CTX_cleanup; + } else { + ntlm->crypt_ctx.hmac_ctx_cleanup_fn = dlsym(handle, "HMAC_CTX_cleanup"); + + if (!ntlm->crypt_ctx.hmac_ctx_cleanup_fn) { + ntlm_client_set_errmsg(ntlm, "could not load legacy libssl functions"); + dlclose(handle); + return false; + } + + ntlm->crypt_ctx.hmac_ctx_new_fn = HMAC_CTX_new; + ntlm->crypt_ctx.hmac_ctx_free_fn = HMAC_CTX_free; + ntlm->crypt_ctx.hmac_ctx_reset_fn = HMAC_CTX_reset; + } + + ntlm->crypt_ctx.openssl_handle = handle; + return true; +} + +#else /* CRYPT_OPENSSL_DYNAMIC */ + +static bool ntlm_crypt_init_functions(ntlm_client *ntlm) +{ + ntlm->crypt_ctx.des_set_key_fn = DES_set_key; + ntlm->crypt_ctx.des_ecb_encrypt_fn = DES_ecb_encrypt; + ntlm->crypt_ctx.err_get_error_fn = ERR_get_error; + ntlm->crypt_ctx.err_lib_error_string_fn = ERR_lib_error_string; + ntlm->crypt_ctx.evp_md5_fn = EVP_md5; + ntlm->crypt_ctx.hmac_ctx_new_fn = HMAC_CTX_new; + ntlm->crypt_ctx.hmac_ctx_free_fn = HMAC_CTX_free; + ntlm->crypt_ctx.hmac_ctx_reset_fn = HMAC_CTX_reset; + ntlm->crypt_ctx.hmac_ctx_cleanup_fn = HMAC_CTX_cleanup; + ntlm->crypt_ctx.hmac_init_ex_fn = HMAC_Init_ex; + ntlm->crypt_ctx.hmac_update_fn = HMAC_Update; + ntlm->crypt_ctx.hmac_final_fn = HMAC_Final; + ntlm->crypt_ctx.md4_fn = MD4; + ntlm->crypt_ctx.rand_bytes_fn = RAND_bytes; + + return true; +} + +#endif /* CRYPT_OPENSSL_DYNAMIC */ + +bool ntlm_crypt_init(ntlm_client *ntlm) +{ + if (!ntlm_crypt_init_functions(ntlm)) + return false; + + ntlm->crypt_ctx.hmac = ntlm->crypt_ctx.hmac_ctx_new_fn(); + + if (ntlm->crypt_ctx.hmac == NULL) { + ntlm_client_set_errmsg(ntlm, "out of memory"); + return false; + } + + return true; +} + bool ntlm_random_bytes( - ntlm_client *ntlm, unsigned char *out, + ntlm_client *ntlm, size_t len) { - int rc = RAND_bytes(out, len); + int rc = ntlm->crypt_ctx.rand_bytes_fn(out, len); if (rc != 1) { - ntlm_client_set_errmsg(ntlm, ERR_lib_error_string(ERR_get_error())); + ntlm_client_set_errmsg(ntlm, ntlm->crypt_ctx.err_lib_error_string_fn(ntlm->crypt_ctx.err_get_error_fn())); return false; } @@ -37,94 +177,81 @@ bool ntlm_random_bytes( bool ntlm_des_encrypt( ntlm_des_block *out, + ntlm_client *ntlm, ntlm_des_block *plaintext, ntlm_des_block *key) { DES_key_schedule keysched; + NTLM_UNUSED(ntlm); + memset(out, 0, sizeof(ntlm_des_block)); - DES_set_key(key, &keysched); - DES_ecb_encrypt(plaintext, out, &keysched, DES_ENCRYPT); + ntlm->crypt_ctx.des_set_key_fn(key, &keysched); + ntlm->crypt_ctx.des_ecb_encrypt_fn(plaintext, out, &keysched, DES_ENCRYPT); return true; } bool ntlm_md4_digest( unsigned char out[CRYPT_MD4_DIGESTSIZE], + ntlm_client *ntlm, const unsigned char *in, size_t in_len) { - MD4(in, in_len, out); + ntlm->crypt_ctx.md4_fn(in, in_len, out); return true; } -#if OPENSSL_VERSION_NUMBER < 0x10100000L -static inline void HMAC_CTX_free(HMAC_CTX *ctx) -{ - if (ctx) - HMAC_CTX_cleanup(ctx); - - free(ctx); -} - -static inline int HMAC_CTX_reset(HMAC_CTX *ctx) -{ - HMAC_CTX_cleanup(ctx); - ntlm_memzero(ctx, sizeof(HMAC_CTX)); - return 1; -} - -static inline HMAC_CTX *HMAC_CTX_new(void) -{ - return calloc(1, sizeof(HMAC_CTX)); -} -#endif - -ntlm_hmac_ctx *ntlm_hmac_ctx_init(void) -{ - return HMAC_CTX_new(); -} - -bool ntlm_hmac_ctx_reset(ntlm_hmac_ctx *ctx) -{ - return HMAC_CTX_reset(ctx); -} - bool ntlm_hmac_md5_init( - ntlm_hmac_ctx *ctx, + ntlm_client *ntlm, const unsigned char *key, size_t key_len) { - return HMAC_Init_ex(ctx, key, key_len, EVP_md5(), NULL); + const EVP_MD *md5 = ntlm->crypt_ctx.evp_md5_fn(); + + ntlm->crypt_ctx.hmac_ctx_cleanup_fn(ntlm->crypt_ctx.hmac); + + return ntlm->crypt_ctx.hmac_ctx_reset_fn(ntlm->crypt_ctx.hmac) && + ntlm->crypt_ctx.hmac_init_ex_fn(ntlm->crypt_ctx.hmac, key, key_len, md5, NULL); } bool ntlm_hmac_md5_update( - ntlm_hmac_ctx *ctx, + ntlm_client *ntlm, const unsigned char *in, size_t in_len) { - return HMAC_Update(ctx, in, in_len); + return ntlm->crypt_ctx.hmac_update_fn(ntlm->crypt_ctx.hmac, in, in_len); } bool ntlm_hmac_md5_final( unsigned char *out, size_t *out_len, - ntlm_hmac_ctx *ctx) + ntlm_client *ntlm) { unsigned int len; if (*out_len < CRYPT_MD5_DIGESTSIZE) return false; - if (!HMAC_Final(ctx, out, &len)) + if (!ntlm->crypt_ctx.hmac_final_fn(ntlm->crypt_ctx.hmac, out, &len)) return false; *out_len = len; return true; } -void ntlm_hmac_ctx_free(ntlm_hmac_ctx *ctx) +void ntlm_crypt_shutdown(ntlm_client *ntlm) { - HMAC_CTX_free(ctx); + if (ntlm->crypt_ctx.hmac) { + ntlm->crypt_ctx.hmac_ctx_cleanup_fn(ntlm->crypt_ctx.hmac); + ntlm->crypt_ctx.hmac_ctx_free_fn(ntlm->crypt_ctx.hmac); + } + +#ifdef CRYPT_OPENSSL_DYNAMIC + if (ntlm->crypt_ctx.openssl_handle) + dlclose(ntlm->crypt_ctx.openssl_handle); +#endif + + memset(&ntlm->crypt_ctx, 0, sizeof(ntlm_crypt_ctx)); } diff --git a/deps/ntlmclient/crypt_openssl.h b/deps/ntlmclient/crypt_openssl.h index 4195db9a51c..8654027dbff 100644 --- a/deps/ntlmclient/crypt_openssl.h +++ b/deps/ntlmclient/crypt_openssl.h @@ -9,13 +9,82 @@ #ifndef PRIVATE_CRYPT_OPENSSL_H__ #define PRIVATE_CRYPT_OPENSSL_H__ -#include +#ifndef CRYPT_OPENSSL_DYNAMIC +# include +# include +#endif /* OpenSSL 1.1.0 uses opaque structs, we'll reuse these. */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L -typedef struct hmac_ctx_st ntlm_hmac_ctx; -#else -# define ntlm_hmac_ctx HMAC_CTX +#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L +# define HMAC_CTX struct hmac_ctx_st +#endif + +#ifdef CRYPT_OPENSSL_DYNAMIC +typedef unsigned char DES_cblock[8]; +typedef unsigned char const_DES_cblock[8]; + +typedef unsigned long DES_LONG; + +typedef struct DES_ks { + union { + DES_cblock cblock; + DES_LONG deslong[2]; + } ks[16]; +} DES_key_schedule; + +#define DES_ENCRYPT 1 + +typedef void EVP_MD; +typedef void ENGINE; +typedef void EVP_PKEY_CTX; + +#define HMAC_MAX_MD_CBLOCK 128 + +typedef struct env_md_ctx_st EVP_MD_CTX; +struct env_md_ctx_st { + const EVP_MD *digest; + ENGINE *engine; + unsigned long flags; + void *md_data; + EVP_PKEY_CTX *pctx; + int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); +}; + +typedef struct hmac_ctx_st { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; + unsigned int key_length; + unsigned char key[HMAC_MAX_MD_CBLOCK]; +} HMAC_CTX; #endif +struct ntlm_crypt_ctx { + HMAC_CTX *hmac; + + void *openssl_handle; + + void (*des_ecb_encrypt_fn)(const_DES_cblock *input, DES_cblock *output, DES_key_schedule *ks, int enc); + int (*des_set_key_fn)(const_DES_cblock *key, DES_key_schedule *schedule); + + unsigned long (*err_get_error_fn)(void); + const char *(*err_lib_error_string_fn)(unsigned long e); + + const EVP_MD *(*evp_md5_fn)(void); + + HMAC_CTX *(*hmac_ctx_new_fn)(void); + int (*hmac_ctx_reset_fn)(HMAC_CTX *ctx); + void (*hmac_ctx_free_fn)(HMAC_CTX *ctx); + void (*hmac_ctx_cleanup_fn)(HMAC_CTX *ctx); + + int (*hmac_init_ex_fn)(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl); + int (*hmac_update_fn)(HMAC_CTX *ctx, const unsigned char *data, size_t len); + int (*hmac_final_fn)(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); + + unsigned char *(*md4_fn)(const unsigned char *d, size_t n, unsigned char *md); + + int (*rand_bytes_fn)(unsigned char *buf, int num); +}; + #endif /* PRIVATE_CRYPT_OPENSSL_H__ */ diff --git a/deps/ntlmclient/ntlm.c b/deps/ntlmclient/ntlm.c index 470a9014373..3393be915d5 100644 --- a/deps/ntlmclient/ntlm.c +++ b/deps/ntlmclient/ntlm.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -24,6 +23,18 @@ #include "compat.h" #include "util.h" +#define NTLM_ASSERT_ARG(expr) do { \ + if (!(expr)) \ + return NTLM_CLIENT_ERROR_INVALID_INPUT; \ + } while(0) + +#define NTLM_ASSERT(ntlm, expr) do { \ + if (!(expr)) { \ + ntlm_client_set_errmsg(ntlm, "internal error: " #expr); \ + return -1; \ + } \ + } while(0) + unsigned char ntlm_client_signature[] = NTLM_SIGNATURE; static bool supports_unicode(ntlm_client *ntlm) @@ -52,17 +63,20 @@ ntlm_client *ntlm_client_init(ntlm_client_flags flags) ntlm->flags = flags; - if ((ntlm->hmac_ctx = ntlm_hmac_ctx_init()) == NULL || - (ntlm->unicode_ctx = ntlm_unicode_ctx_init(ntlm)) == NULL) { - ntlm_hmac_ctx_free(ntlm->hmac_ctx); - ntlm_unicode_ctx_free(ntlm->unicode_ctx); - free(ntlm); - return NULL; - } - return ntlm; } +#define ENSURE_INITIALIZED(ntlm) \ + do { \ + if (!(ntlm)->unicode_initialized) \ + (ntlm)->unicode_initialized = ntlm_unicode_init((ntlm)); \ + if (!(ntlm)->crypt_initialized) \ + (ntlm)->crypt_initialized = ntlm_crypt_init((ntlm)); \ + if (!(ntlm)->unicode_initialized || \ + !(ntlm)->crypt_initialized) \ + return -1; \ + } while(0) + void ntlm_client_set_errmsg(ntlm_client *ntlm, const char *errmsg) { ntlm->state = NTLM_STATE_ERROR; @@ -71,7 +85,9 @@ void ntlm_client_set_errmsg(ntlm_client *ntlm, const char *errmsg) const char *ntlm_client_errmsg(ntlm_client *ntlm) { - assert(ntlm); + if (!ntlm) + return "internal error"; + return ntlm->errmsg ? ntlm->errmsg : "no error"; } @@ -81,7 +97,7 @@ int ntlm_client_set_version( uint8_t minor, uint16_t build) { - assert(ntlm); + NTLM_ASSERT_ARG(ntlm); ntlm->host_version.major = major; ntlm->host_version.minor = minor; @@ -93,20 +109,25 @@ int ntlm_client_set_version( return 0; } +#define reset(ptr) do { free(ptr); ptr = NULL; } while(0) + +static void free_hostname(ntlm_client *ntlm) +{ + reset(ntlm->hostname); + reset(ntlm->hostdomain); + reset(ntlm->hostname_utf16); + ntlm->hostname_utf16_len = 0; +} + int ntlm_client_set_hostname( ntlm_client *ntlm, const char *hostname, const char *domain) { - assert(ntlm); + NTLM_ASSERT_ARG(ntlm); + ENSURE_INITIALIZED(ntlm); - free(ntlm->hostname); - free(ntlm->hostdomain); - free(ntlm->hostname_utf16); - - ntlm->hostname = NULL; - ntlm->hostdomain = NULL; - ntlm->hostname_utf16 = NULL; + free_hostname(ntlm); if (hostname && (ntlm->hostname = strdup(hostname)) == NULL) { ntlm_client_set_errmsg(ntlm, "out of memory"); @@ -121,7 +142,7 @@ int ntlm_client_set_hostname( if (hostname && supports_unicode(ntlm) && !ntlm_unicode_utf8_to_16( &ntlm->hostname_utf16, &ntlm->hostname_utf16_len, - ntlm->unicode_ctx, + ntlm, hostname, strlen(hostname))) return -1; @@ -137,25 +158,20 @@ static void free_credentials(ntlm_client *ntlm) if (ntlm->password_utf16) ntlm_memzero(ntlm->password_utf16, ntlm->password_utf16_len); - free(ntlm->username); - free(ntlm->username_upper); - free(ntlm->userdomain); - free(ntlm->password); - - free(ntlm->username_utf16); - free(ntlm->username_upper_utf16); - free(ntlm->userdomain_utf16); - free(ntlm->password_utf16); - - ntlm->username = NULL; - ntlm->username_upper = NULL; - ntlm->userdomain = NULL; - ntlm->password = NULL; - - ntlm->username_utf16 = NULL; - ntlm->username_upper_utf16 = NULL; - ntlm->userdomain_utf16 = NULL; - ntlm->password_utf16 = NULL; + reset(ntlm->username); + reset(ntlm->username_upper); + reset(ntlm->userdomain); + reset(ntlm->password); + + reset(ntlm->username_utf16); + reset(ntlm->username_upper_utf16); + reset(ntlm->userdomain_utf16); + reset(ntlm->password_utf16); + + ntlm->username_utf16_len = 0; + ntlm->username_upper_utf16_len = 0; + ntlm->userdomain_utf16_len = 0; + ntlm->password_utf16_len = 0; } int ntlm_client_set_credentials( @@ -164,7 +180,8 @@ int ntlm_client_set_credentials( const char *domain, const char *password) { - assert(ntlm); + NTLM_ASSERT_ARG(ntlm); + ENSURE_INITIALIZED(ntlm); free_credentials(ntlm); @@ -185,7 +202,7 @@ int ntlm_client_set_credentials( if (!ntlm_unicode_utf8_to_16( &ntlm->username_utf16, &ntlm->username_utf16_len, - ntlm->unicode_ctx, + ntlm, ntlm->username, strlen(ntlm->username))) return -1; @@ -193,7 +210,7 @@ int ntlm_client_set_credentials( if (!ntlm_unicode_utf8_to_16( &ntlm->username_upper_utf16, &ntlm->username_upper_utf16_len, - ntlm->unicode_ctx, + ntlm, ntlm->username_upper, strlen(ntlm->username_upper))) return -1; @@ -202,7 +219,7 @@ int ntlm_client_set_credentials( if (domain && supports_unicode(ntlm) && !ntlm_unicode_utf8_to_16( &ntlm->userdomain_utf16, &ntlm->userdomain_utf16_len, - ntlm->unicode_ctx, + ntlm, ntlm->userdomain, strlen(ntlm->userdomain))) return -1; @@ -212,7 +229,8 @@ int ntlm_client_set_credentials( int ntlm_client_set_target(ntlm_client *ntlm, const char *target) { - assert(ntlm); + NTLM_ASSERT_ARG(ntlm); + ENSURE_INITIALIZED(ntlm); free(ntlm->target); free(ntlm->target_utf16); @@ -229,7 +247,7 @@ int ntlm_client_set_target(ntlm_client *ntlm, const char *target) if (supports_unicode(ntlm) && !ntlm_unicode_utf8_to_16( &ntlm->target_utf16, &ntlm->target_utf16_len, - ntlm->unicode_ctx, + ntlm, ntlm->target, strlen(ntlm->target))) return -1; @@ -240,14 +258,16 @@ int ntlm_client_set_target(ntlm_client *ntlm, const char *target) int ntlm_client_set_nonce(ntlm_client *ntlm, uint64_t nonce) { - assert(ntlm); + NTLM_ASSERT_ARG(ntlm); + ntlm->nonce = nonce; return 0; } int ntlm_client_set_timestamp(ntlm_client *ntlm, uint64_t timestamp) { - assert(ntlm); + NTLM_ASSERT_ARG(ntlm); + ntlm->timestamp = timestamp; return 0; } @@ -475,7 +495,7 @@ static inline bool read_string_unicode( size_t out_len; int ret = ntlm_unicode_utf16_to_8(out, &out_len, - ntlm->unicode_ctx, + ntlm, (char *)&message->buf[message->pos], string_len); @@ -593,7 +613,9 @@ int ntlm_client_negotiate( size_t hostname_offset = 0; uint32_t flags = 0; - assert(out && out_len && ntlm); + NTLM_ASSERT_ARG(out); + NTLM_ASSERT_ARG(out_len); + NTLM_ASSERT_ARG(ntlm); *out = NULL; *out_len = 0; @@ -676,20 +698,22 @@ int ntlm_client_negotiate( return -1; if (hostname_len > 0) { - assert(hostname_offset == ntlm->negotiate.pos); + NTLM_ASSERT(ntlm, hostname_offset == ntlm->negotiate.pos); + if (!write_buf(ntlm, &ntlm->negotiate, (const unsigned char *)ntlm->hostname, hostname_len)) return -1; } if (domain_len > 0) { - assert(domain_offset == ntlm->negotiate.pos); + NTLM_ASSERT(ntlm, domain_offset == ntlm->negotiate.pos); + if (!write_buf(ntlm, &ntlm->negotiate, (const unsigned char *)ntlm->hostdomain, domain_len)) return -1; } - assert(ntlm->negotiate.pos == ntlm->negotiate.len); + NTLM_ASSERT(ntlm, ntlm->negotiate.pos == ntlm->negotiate.len); ntlm->state = NTLM_STATE_CHALLENGE; @@ -711,7 +735,10 @@ int ntlm_client_set_challenge( uint32_t name_offset, info_offset = 0; bool unicode, has_target_info = false; - assert(ntlm && (challenge_msg || !challenge_msg_len)); + NTLM_ASSERT_ARG(ntlm); + NTLM_ASSERT_ARG(challenge_msg || !challenge_msg_len); + + ENSURE_INITIALIZED(ntlm); if (ntlm->state != NTLM_STATE_NEGOTIATE && ntlm->state != NTLM_STATE_CHALLENGE) { @@ -940,6 +967,7 @@ static void des_key_from_password( static inline bool generate_lm_hash( ntlm_des_block out[2], + ntlm_client *ntlm, const char *password) { /* LM encrypts this known plaintext using the password as a key */ @@ -968,8 +996,8 @@ static inline bool generate_lm_hash( des_key_from_password(&key1, keystr1, keystr1_len); des_key_from_password(&key2, keystr2, keystr2_len); - return ntlm_des_encrypt(&out[0], &plaintext, &key1) && - ntlm_des_encrypt(&out[1], &plaintext, &key2); + return ntlm_des_encrypt(&out[0], ntlm, &plaintext, &key1) && + ntlm_des_encrypt(&out[1], ntlm, &plaintext, &key2); } static void des_keys_from_lm_hash(ntlm_des_block out[3], ntlm_des_block lm_hash[2]) @@ -994,16 +1022,16 @@ static bool generate_lm_response(ntlm_client *ntlm) ntlm_des_block *challenge = (ntlm_des_block *)&ntlm->challenge.nonce; /* Generate the LM hash from the password */ - if (!generate_lm_hash(lm_hash, ntlm->password)) + if (!generate_lm_hash(lm_hash, ntlm, ntlm->password)) return false; /* Convert that LM hash to three DES keys */ des_keys_from_lm_hash(key, lm_hash); /* Finally, encrypt the challenge with each of these keys */ - if (!ntlm_des_encrypt(&lm_response[0], challenge, &key[0]) || - !ntlm_des_encrypt(&lm_response[1], challenge, &key[1]) || - !ntlm_des_encrypt(&lm_response[2], challenge, &key[2])) + if (!ntlm_des_encrypt(&lm_response[0], ntlm, challenge, &key[0]) || + !ntlm_des_encrypt(&lm_response[1], ntlm, challenge, &key[1]) || + !ntlm_des_encrypt(&lm_response[2], ntlm, challenge, &key[2])) return false; memcpy(&ntlm->lm_response[0], lm_response[0], 8); @@ -1022,12 +1050,13 @@ static bool generate_ntlm_hash( if (ntlm->password && !ntlm_unicode_utf8_to_16( &ntlm->password_utf16, &ntlm->password_utf16_len, - ntlm->unicode_ctx, + ntlm, ntlm->password, strlen(ntlm->password))) return false; return ntlm_md4_digest(out, + ntlm, (const unsigned char *)ntlm->password_utf16, ntlm->password_utf16_len); } @@ -1048,9 +1077,9 @@ static bool generate_ntlm_response(ntlm_client *ntlm) des_key_from_password(&key[2], &ntlm_hash[14], 2); /* Finally, encrypt the challenge with each of these keys */ - if (!ntlm_des_encrypt(&ntlm_response[0], challenge, &key[0]) || - !ntlm_des_encrypt(&ntlm_response[1], challenge, &key[1]) || - !ntlm_des_encrypt(&ntlm_response[2], challenge, &key[2])) + if (!ntlm_des_encrypt(&ntlm_response[0], ntlm, challenge, &key[0]) || + !ntlm_des_encrypt(&ntlm_response[1], ntlm, challenge, &key[1]) || + !ntlm_des_encrypt(&ntlm_response[2], ntlm, challenge, &key[2])) return false; memcpy(&ntlm->ntlm_response[0], ntlm_response[0], 8); @@ -1081,16 +1110,15 @@ static bool generate_ntlm2_hash( target_len = ntlm->target_utf16_len; } - if (!ntlm_hmac_ctx_reset(ntlm->hmac_ctx) || - !ntlm_hmac_md5_init(ntlm->hmac_ctx, ntlm_hash, sizeof(ntlm_hash)) || - !ntlm_hmac_md5_update(ntlm->hmac_ctx, username, username_len) || - !ntlm_hmac_md5_update(ntlm->hmac_ctx, target, target_len) || - !ntlm_hmac_md5_final(out, &out_len, ntlm->hmac_ctx)) { + if (!ntlm_hmac_md5_init(ntlm, ntlm_hash, sizeof(ntlm_hash)) || + !ntlm_hmac_md5_update(ntlm, username, username_len) || + !ntlm_hmac_md5_update(ntlm, target, target_len) || + !ntlm_hmac_md5_final(out, &out_len, ntlm)) { ntlm_client_set_errmsg(ntlm, "failed to create HMAC-MD5"); return false; } - assert(out_len == NTLM_NTLM2_HASH_LEN); + NTLM_ASSERT(ntlm, out_len == NTLM_NTLM2_HASH_LEN); return true; } @@ -1103,18 +1131,15 @@ static bool generate_ntlm2_challengehash( { size_t out_len = 16; - if (!ntlm_hmac_ctx_reset(ntlm->hmac_ctx) || - !ntlm_hmac_md5_init(ntlm->hmac_ctx, - ntlm2_hash, NTLM_NTLM2_HASH_LEN) || - !ntlm_hmac_md5_update(ntlm->hmac_ctx, - (const unsigned char *)&ntlm->challenge.nonce, 8) || - !ntlm_hmac_md5_update(ntlm->hmac_ctx, blob, blob_len) || - !ntlm_hmac_md5_final(out, &out_len, ntlm->hmac_ctx)) { + if (!ntlm_hmac_md5_init(ntlm, ntlm2_hash, NTLM_NTLM2_HASH_LEN) || + !ntlm_hmac_md5_update(ntlm, (const unsigned char *)&ntlm->challenge.nonce, 8) || + !ntlm_hmac_md5_update(ntlm, blob, blob_len) || + !ntlm_hmac_md5_final(out, &out_len, ntlm)) { ntlm_client_set_errmsg(ntlm, "failed to create HMAC-MD5"); return false; } - assert(out_len == 16); + NTLM_ASSERT(ntlm, out_len == 16); return true; } @@ -1127,19 +1152,15 @@ static bool generate_lm2_response(ntlm_client *ntlm, local_nonce = ntlm_htonll(ntlm->nonce); - if (!ntlm_hmac_ctx_reset(ntlm->hmac_ctx) || - !ntlm_hmac_md5_init(ntlm->hmac_ctx, - ntlm2_hash, NTLM_NTLM2_HASH_LEN) || - !ntlm_hmac_md5_update(ntlm->hmac_ctx, - (const unsigned char *)&ntlm->challenge.nonce, 8) || - !ntlm_hmac_md5_update(ntlm->hmac_ctx, - (const unsigned char *)&local_nonce, 8) || - !ntlm_hmac_md5_final(lm2_challengehash, &lm2_len, ntlm->hmac_ctx)) { + if (!ntlm_hmac_md5_init(ntlm, ntlm2_hash, NTLM_NTLM2_HASH_LEN) || + !ntlm_hmac_md5_update(ntlm, (const unsigned char *)&ntlm->challenge.nonce, 8) || + !ntlm_hmac_md5_update(ntlm, (const unsigned char *)&local_nonce, 8) || + !ntlm_hmac_md5_final(lm2_challengehash, &lm2_len, ntlm)) { ntlm_client_set_errmsg(ntlm, "failed to create HMAC-MD5"); return false; } - assert(lm2_len == 16); + NTLM_ASSERT(ntlm, lm2_len == 16); memcpy(&ntlm->lm_response[0], lm2_challengehash, 16); memcpy(&ntlm->lm_response[16], &local_nonce, 8); @@ -1163,7 +1184,7 @@ static bool generate_nonce(ntlm_client *ntlm) if (ntlm->nonce) return true; - if (!ntlm_random_bytes(ntlm, buf, 8)) + if (!ntlm_random_bytes(buf, ntlm, 8)) return false; memcpy(&ntlm->nonce, buf, sizeof(uint64_t)); @@ -1233,7 +1254,11 @@ int ntlm_client_response( uint32_t flags = 0; bool unicode; - assert(out && out_len && ntlm); + NTLM_ASSERT_ARG(out); + NTLM_ASSERT_ARG(out_len); + NTLM_ASSERT_ARG(ntlm); + + ENSURE_INITIALIZED(ntlm); *out = NULL; *out_len = 0; @@ -1356,7 +1381,7 @@ int ntlm_client_response( !write_buf(ntlm, &ntlm->response, session, session_len)) return -1; - assert(ntlm->response.pos == ntlm->response.len); + NTLM_ASSERT(ntlm, ntlm->response.pos == ntlm->response.len); ntlm->state = NTLM_STATE_COMPLETE; @@ -1368,41 +1393,48 @@ int ntlm_client_response( void ntlm_client_reset(ntlm_client *ntlm) { - ntlm_client_flags flags; - ntlm_hmac_ctx *hmac_ctx; - ntlm_unicode_ctx *unicode_ctx; - - assert(ntlm); + if (!ntlm) + return; - free(ntlm->negotiate.buf); - free(ntlm->challenge.target_info); - free(ntlm->challenge.target); - free(ntlm->challenge.target_domain); - free(ntlm->challenge.target_domain_dns); - free(ntlm->challenge.target_server); - free(ntlm->challenge.target_server_dns); - free(ntlm->response.buf); + ntlm->state = NTLM_STATE_NEGOTIATE; - free(ntlm->hostname); - free(ntlm->hostname_utf16); - free(ntlm->hostdomain); + free_hostname(ntlm); - free(ntlm->target); - free(ntlm->target_utf16); + memset(&ntlm->host_version, 0, sizeof(ntlm_version)); - free(ntlm->ntlm2_response); + reset(ntlm->target); + reset(ntlm->target_utf16); + ntlm->target_utf16_len = 0; free_credentials(ntlm); - flags = ntlm->flags; - hmac_ctx = ntlm->hmac_ctx; - unicode_ctx = ntlm->unicode_ctx; + ntlm->nonce = 0; + ntlm->timestamp = 0; - memset(ntlm, 0, sizeof(struct ntlm_client)); + memset(ntlm->lm_response, 0, NTLM_LM_RESPONSE_LEN); + ntlm->lm_response_len = 0; - ntlm->flags = flags; - ntlm->hmac_ctx = hmac_ctx; - ntlm->unicode_ctx = unicode_ctx; + memset(ntlm->ntlm_response, 0, NTLM_NTLM_RESPONSE_LEN); + ntlm->ntlm_response_len = 0; + + reset(ntlm->ntlm2_response); + ntlm->ntlm2_response_len = 0; + + reset(ntlm->negotiate.buf); + ntlm->negotiate.pos = 0; + ntlm->negotiate.len = 0; + + reset(ntlm->response.buf); + ntlm->response.pos = 0; + ntlm->response.len = 0; + + free(ntlm->challenge.target_info); + free(ntlm->challenge.target); + free(ntlm->challenge.target_domain); + free(ntlm->challenge.target_domain_dns); + free(ntlm->challenge.target_server); + free(ntlm->challenge.target_server_dns); + memset(&ntlm->challenge, 0, sizeof(ntlm_challenge)); } void ntlm_client_free(ntlm_client *ntlm) @@ -1410,10 +1442,10 @@ void ntlm_client_free(ntlm_client *ntlm) if (!ntlm) return; - ntlm_client_reset(ntlm); + ntlm_crypt_shutdown(ntlm); + ntlm_unicode_shutdown(ntlm); - ntlm_hmac_ctx_free(ntlm->hmac_ctx); - ntlm_unicode_ctx_free(ntlm->unicode_ctx); + ntlm_client_reset(ntlm); free(ntlm); } diff --git a/deps/ntlmclient/ntlm.h b/deps/ntlmclient/ntlm.h index 0dad91ec0dc..227f5bcbafa 100644 --- a/deps/ntlmclient/ntlm.h +++ b/deps/ntlmclient/ntlm.h @@ -14,6 +14,8 @@ #include "crypt.h" #include "compat.h" +#define NTLM_UNUSED(x) ((void)(x)) + #define NTLM_LM_RESPONSE_LEN 24 #define NTLM_NTLM_RESPONSE_LEN 24 #define NTLM_NTLM_HASH_LEN 16 @@ -66,9 +68,11 @@ struct ntlm_client { ntlm_state state; - /* crypto contexts */ - ntlm_hmac_ctx *hmac_ctx; - ntlm_unicode_ctx *unicode_ctx; + /* subsystem contexts */ + ntlm_crypt_ctx crypt_ctx; + ntlm_unicode_ctx unicode_ctx; + int crypt_initialized : 1, + unicode_initialized : 1; /* error message as set by the library */ const char *errmsg; @@ -85,24 +89,24 @@ struct ntlm_client { char *password; /* strings as converted to utf16 */ + char *hostname_utf16; char *target_utf16; char *username_utf16; char *username_upper_utf16; char *userdomain_utf16; - char *hostname_utf16; char *password_utf16; - /* timestamp and nonce; only for debugging */ - uint64_t nonce; - uint64_t timestamp; - + size_t hostname_utf16_len; size_t username_utf16_len; size_t username_upper_utf16_len; size_t userdomain_utf16_len; - size_t hostname_utf16_len; size_t password_utf16_len; size_t target_utf16_len; + /* timestamp and nonce; only for debugging */ + uint64_t nonce; + uint64_t timestamp; + unsigned char lm_response[NTLM_LM_RESPONSE_LEN]; size_t lm_response_len; diff --git a/deps/ntlmclient/ntlmclient.h b/deps/ntlmclient/ntlmclient.h index d109a5c894a..bf57b17c6fd 100644 --- a/deps/ntlmclient/ntlmclient.h +++ b/deps/ntlmclient/ntlmclient.h @@ -15,13 +15,26 @@ extern "C" { #endif -#define NTLM_CLIENT_VERSION "0.0.1" +#define NTLM_CLIENT_VERSION "0.9.0" #define NTLM_CLIENT_VERSION_MAJOR 0 -#define NTLM_CLIENT_VERSION_MINOR 0 -#define NTLM_CLIENT_VERSION_TEENY 1 +#define NTLM_CLIENT_VERSION_MINOR 9 +#define NTLM_CLIENT_VERSION_TEENY 0 typedef struct ntlm_client ntlm_client; +typedef enum { + /** + * An error occurred; more details are available by querying + * `ntlm_client_errmsg`. + */ + NTLM_CLIENT_ERROR = -1, + + /** + * The input provided to the function is missing or invalid. + */ + NTLM_CLIENT_ERROR_INVALID_INPUT = -2, +} ntlm_error_code; + /* * Flags for initializing the `ntlm_client` context. A combination of * these flags can be provided to `ntlm_client_init`. diff --git a/deps/ntlmclient/unicode.h b/deps/ntlmclient/unicode.h index e3b17bcf7f7..b7c63f2ed46 100644 --- a/deps/ntlmclient/unicode.h +++ b/deps/ntlmclient/unicode.h @@ -11,26 +11,32 @@ #include "compat.h" +#ifdef UNICODE_ICONV +# include "unicode_iconv.h" +#elif UNICODE_BUILTIN +# include "unicode_builtin.h" +#endif + #define NTLM_UNICODE_MAX_LEN 2048 typedef struct ntlm_unicode_ctx ntlm_unicode_ctx; -extern ntlm_unicode_ctx *ntlm_unicode_ctx_init(ntlm_client *ntlm); +extern bool ntlm_unicode_init(ntlm_client *ntlm); bool ntlm_unicode_utf8_to_16( char **converted, size_t *converted_len, - ntlm_unicode_ctx *ctx, + ntlm_client *ntlm, const char *string, size_t string_len); bool ntlm_unicode_utf16_to_8( char **converted, size_t *converted_len, - ntlm_unicode_ctx *ctx, + ntlm_client *ntlm, const char *string, size_t string_len); -extern void ntlm_unicode_ctx_free(ntlm_unicode_ctx *ctx); +extern void ntlm_unicode_shutdown(ntlm_client *ntlm); #endif /* PRIVATE_UNICODE_H__ */ diff --git a/deps/ntlmclient/unicode_builtin.c b/deps/ntlmclient/unicode_builtin.c index e1856cca988..e2ee0abf71e 100644 --- a/deps/ntlmclient/unicode_builtin.c +++ b/deps/ntlmclient/unicode_builtin.c @@ -13,10 +13,6 @@ #include "unicode.h" #include "compat.h" -struct ntlm_unicode_ctx { - ntlm_client *ntlm; -}; - typedef unsigned int UTF32; /* at least 32 bits */ typedef unsigned short UTF16; /* at least 16 bits */ typedef unsigned char UTF8; /* typically 8 bits */ @@ -281,15 +277,10 @@ static ConversionResult ConvertUTF8toUTF16 ( } -ntlm_unicode_ctx *ntlm_unicode_ctx_init(ntlm_client *ntlm) +bool ntlm_unicode_init(ntlm_client *ntlm) { - ntlm_unicode_ctx *ctx; - - if ((ctx = malloc(sizeof(ntlm_unicode_ctx))) == NULL) - return NULL; - - ctx->ntlm = ntlm; - return ctx; + NTLM_UNUSED(ntlm); + return true; } typedef enum { @@ -300,7 +291,7 @@ typedef enum { static inline bool unicode_builtin_encoding_convert( char **converted, size_t *converted_len, - ntlm_unicode_ctx *ctx, + ntlm_client *ntlm, const char *string, size_t string_len, unicode_builtin_encoding_direction direction) @@ -332,7 +323,7 @@ static inline bool unicode_builtin_encoding_convert( out_size = (out_size + 7) & ~7; if ((out = malloc(out_size)) == NULL) { - ntlm_client_set_errmsg(ctx->ntlm, "out of memory"); + ntlm_client_set_errmsg(ntlm, "out of memory"); return false; } @@ -358,17 +349,17 @@ static inline bool unicode_builtin_encoding_convert( success = true; goto done; case sourceExhausted: - ntlm_client_set_errmsg(ctx->ntlm, + ntlm_client_set_errmsg(ntlm, "invalid unicode string; trailing data remains"); goto done; case targetExhausted: break; case sourceIllegal: - ntlm_client_set_errmsg(ctx->ntlm, + ntlm_client_set_errmsg(ntlm, "invalid unicode string; trailing data remains"); goto done; default: - ntlm_client_set_errmsg(ctx->ntlm, + ntlm_client_set_errmsg(ntlm, "unknown unicode conversion failure"); goto done; } @@ -377,13 +368,12 @@ static inline bool unicode_builtin_encoding_convert( out_size = ((((out_size << 1) - (out_size >> 1)) + 7) & ~7); if (out_size > NTLM_UNICODE_MAX_LEN) { - ntlm_client_set_errmsg(ctx->ntlm, - "unicode conversion too large"); + ntlm_client_set_errmsg(ntlm, "unicode conversion too large"); goto done; } if ((new_out = realloc(out, out_size)) == NULL) { - ntlm_client_set_errmsg(ctx->ntlm, "out of memory"); + ntlm_client_set_errmsg(ntlm, "out of memory"); goto done; } @@ -419,27 +409,26 @@ static inline bool unicode_builtin_encoding_convert( bool ntlm_unicode_utf8_to_16( char **converted, size_t *converted_len, - ntlm_unicode_ctx *ctx, + ntlm_client *client, const char *string, size_t string_len) { return unicode_builtin_encoding_convert(converted, converted_len, - ctx, string, string_len, unicode_builtin_utf8_to_16); + client, string, string_len, unicode_builtin_utf8_to_16); } bool ntlm_unicode_utf16_to_8( char **converted, size_t *converted_len, - ntlm_unicode_ctx *ctx, + ntlm_client *client, const char *string, size_t string_len) { return unicode_builtin_encoding_convert(converted, converted_len, - ctx, string, string_len, unicode_builtin_utf16_to_8); + client, string, string_len, unicode_builtin_utf16_to_8); } -void ntlm_unicode_ctx_free(ntlm_unicode_ctx *ctx) +void ntlm_unicode_shutdown(ntlm_client *ntlm) { - if (ctx) - free(ctx); + NTLM_UNUSED(ntlm); } diff --git a/deps/ntlmclient/unicode_builtin.h b/deps/ntlmclient/unicode_builtin.h new file mode 100644 index 00000000000..eabec40bfdc --- /dev/null +++ b/deps/ntlmclient/unicode_builtin.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) Edward Thomson. All rights reserved. + * + * This file is part of ntlmclient, distributed under the MIT license. + * For full terms and copyright information, and for third-party + * copyright information, see the included LICENSE.txt file. + */ + +#ifndef PRIVATE_UNICODE_BUILTIN_H__ +#define PRIVATE_UNICODE_BUILTIN_H__ + +#include +#include + +#include "ntlmclient.h" + +struct ntlm_unicode_ctx { +}; + +#endif /* PRIVATE_UNICODE_BUILTIN_H__ */ diff --git a/deps/ntlmclient/unicode_iconv.c b/deps/ntlmclient/unicode_iconv.c index d1fe07e2686..e14da21f545 100644 --- a/deps/ntlmclient/unicode_iconv.c +++ b/deps/ntlmclient/unicode_iconv.c @@ -16,43 +16,23 @@ #include "ntlm.h" #include "compat.h" -struct ntlm_unicode_ctx { - ntlm_client *ntlm; - iconv_t utf8_to_16; - iconv_t utf16_to_8; -}; - -ntlm_unicode_ctx *ntlm_unicode_ctx_init(ntlm_client *ntlm) -{ - ntlm_unicode_ctx *ctx; - - if ((ctx = calloc(1, sizeof(ntlm_unicode_ctx))) == NULL) - return NULL; - - ctx->ntlm = ntlm; - ctx->utf8_to_16 = (iconv_t)-1; - ctx->utf16_to_8 = (iconv_t)-1; - - return ctx; -} - typedef enum { unicode_iconv_utf8_to_16, unicode_iconv_utf16_to_8 } unicode_iconv_encoding_direction; -static inline bool unicode_iconv_init(ntlm_unicode_ctx *ctx) +bool ntlm_unicode_init(ntlm_client *ntlm) { - if (ctx->utf8_to_16 != (iconv_t)-1 || ctx->utf16_to_8 != (iconv_t)-1) - return true; + ntlm->unicode_ctx.utf8_to_16 = iconv_open("UTF-16LE", "UTF-8"); + ntlm->unicode_ctx.utf16_to_8 = iconv_open("UTF-8", "UTF-16LE"); - if ((ctx->utf8_to_16 = iconv_open("UTF-16LE", "UTF-8")) == (iconv_t)-1 || - (ctx->utf16_to_8 = iconv_open("UTF-8", "UTF-16LE")) == (iconv_t)-1) { + if (ntlm->unicode_ctx.utf8_to_16 == (iconv_t)-1 || + ntlm->unicode_ctx.utf16_to_8 == (iconv_t)-1) { if (errno == EINVAL) - ntlm_client_set_errmsg(ctx->ntlm, + ntlm_client_set_errmsg(ntlm, "iconv does not support UTF8 <-> UTF16 conversion"); else - ntlm_client_set_errmsg(ctx->ntlm, strerror(errno)); + ntlm_client_set_errmsg(ntlm, strerror(errno)); return false; } @@ -63,7 +43,7 @@ static inline bool unicode_iconv_init(ntlm_unicode_ctx *ctx) static inline bool unicode_iconv_encoding_convert( char **converted, size_t *converted_len, - ntlm_unicode_ctx *ctx, + ntlm_client *ntlm, const char *string, size_t string_len, unicode_iconv_encoding_direction direction) @@ -75,9 +55,6 @@ static inline bool unicode_iconv_encoding_convert( *converted = NULL; *converted_len = 0; - if (!unicode_iconv_init(ctx)) - return false; - /* * When translating UTF8 to UTF16, these strings are only used * internally, and we obey the given length, so we can simply @@ -86,11 +63,11 @@ static inline bool unicode_iconv_encoding_convert( * terminate and expect an extra byte for UTF8, two for UTF16. */ if (direction == unicode_iconv_utf8_to_16) { - converter = ctx->utf8_to_16; + converter = ntlm->unicode_ctx.utf8_to_16; out_size = (string_len * 2) + 2; nul_size = 2; } else { - converter = ctx->utf16_to_8; + converter = ntlm->unicode_ctx.utf16_to_8; out_size = (string_len / 2) + 1; nul_size = 1; } @@ -99,7 +76,7 @@ static inline bool unicode_iconv_encoding_convert( out_size = (out_size + 7) & ~7; if ((out = malloc(out_size)) == NULL) { - ntlm_client_set_errmsg(ctx->ntlm, "out of memory"); + ntlm_client_set_errmsg(ntlm, "out of memory"); return false; } @@ -117,7 +94,7 @@ static inline bool unicode_iconv_encoding_convert( break; if (ret == (size_t)-1 && errno != E2BIG) { - ntlm_client_set_errmsg(ctx->ntlm, strerror(errno)); + ntlm_client_set_errmsg(ntlm, strerror(errno)); goto on_error; } @@ -125,13 +102,12 @@ static inline bool unicode_iconv_encoding_convert( out_size = ((((out_size << 1) - (out_size >> 1)) + 7) & ~7); if (out_size > NTLM_UNICODE_MAX_LEN) { - ntlm_client_set_errmsg(ctx->ntlm, - "unicode conversion too large"); + ntlm_client_set_errmsg(ntlm, "unicode conversion too large"); goto on_error; } if ((new_out = realloc(out, out_size)) == NULL) { - ntlm_client_set_errmsg(ctx->ntlm, "out of memory"); + ntlm_client_set_errmsg(ntlm, "out of memory"); goto on_error; } @@ -139,7 +115,7 @@ static inline bool unicode_iconv_encoding_convert( } if (in_start_len != 0) { - ntlm_client_set_errmsg(ctx->ntlm, + ntlm_client_set_errmsg(ntlm, "invalid unicode string; trailing data remains"); goto on_error; } @@ -165,37 +141,37 @@ static inline bool unicode_iconv_encoding_convert( bool ntlm_unicode_utf8_to_16( char **converted, size_t *converted_len, - ntlm_unicode_ctx *ctx, + ntlm_client *ntlm, const char *string, size_t string_len) { return unicode_iconv_encoding_convert( - converted, converted_len, ctx, string, string_len, + converted, converted_len, ntlm, string, string_len, unicode_iconv_utf8_to_16); } bool ntlm_unicode_utf16_to_8( char **converted, size_t *converted_len, - ntlm_unicode_ctx *ctx, + ntlm_client *ntlm, const char *string, size_t string_len) { return unicode_iconv_encoding_convert( - converted, converted_len, ctx, string, string_len, + converted, converted_len, ntlm, string, string_len, unicode_iconv_utf16_to_8); } -void ntlm_unicode_ctx_free(ntlm_unicode_ctx *ctx) +void ntlm_unicode_shutdown(ntlm_client *ntlm) { - if (!ctx) - return; - - if (ctx->utf16_to_8 != (iconv_t)-1) - iconv_close(ctx->utf16_to_8); + if (ntlm->unicode_ctx.utf16_to_8 != (iconv_t)0 && + ntlm->unicode_ctx.utf16_to_8 != (iconv_t)-1) + iconv_close(ntlm->unicode_ctx.utf16_to_8); - if (ctx->utf8_to_16 != (iconv_t)-1) - iconv_close(ctx->utf8_to_16); + if (ntlm->unicode_ctx.utf8_to_16 != (iconv_t)0 && + ntlm->unicode_ctx.utf8_to_16 != (iconv_t)-1) + iconv_close(ntlm->unicode_ctx.utf8_to_16); - free(ctx); + ntlm->unicode_ctx.utf8_to_16 = (iconv_t)-1; + ntlm->unicode_ctx.utf16_to_8 = (iconv_t)-1; } diff --git a/deps/ntlmclient/unicode_iconv.h b/deps/ntlmclient/unicode_iconv.h new file mode 100644 index 00000000000..87a96a67d87 --- /dev/null +++ b/deps/ntlmclient/unicode_iconv.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) Edward Thomson. All rights reserved. + * + * This file is part of ntlmclient, distributed under the MIT license. + * For full terms and copyright information, and for third-party + * copyright information, see the included LICENSE.txt file. + */ + +#ifndef PRIVATE_UNICODE_ICONV_H__ +#define PRIVATE_UNICODE_ICONV_H__ + +#include +#include + +#include "ntlmclient.h" + +struct ntlm_unicode_ctx { + iconv_t utf8_to_16; + iconv_t utf16_to_8; +}; + +#endif /* PRIVATE_UNICODE_ICONV_H__ */ diff --git a/src/transports/auth_ntlm.c b/src/transports/auth_ntlm.c index e0960bf9d3b..b5110616b2a 100644 --- a/src/transports/auth_ntlm.c +++ b/src/transports/auth_ntlm.c @@ -14,7 +14,7 @@ #ifdef GIT_NTLM -#include "ntlm.h" +#include "ntlmclient.h" typedef struct { git_http_auth_context parent; From e265eb2f51a13d0a1172330075bdd1c69aed5e8c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Aug 2021 13:58:24 -0400 Subject: [PATCH 0444/1616] tests: show errors when libgit2_init fails --- tests/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/main.c b/tests/main.c index 207a6a8bed6..56751c28869 100644 --- a/tests/main.c +++ b/tests/main.c @@ -18,7 +18,9 @@ int main(int argc, char *argv[]) res = git_libgit2_init(); if (res < 0) { - fprintf(stderr, "failed to init libgit2"); + const git_error *err = git_error_last(); + const char *msg = err ? err->message : "unknown failure"; + fprintf(stderr, "failed to init libgit2: %s\n", msg); return res; } From aad497cb1c79b2bf751b45a38aac60595c7cc382 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Aug 2021 14:08:43 -0400 Subject: [PATCH 0445/1616] openssl: dynamically load on macOS --- src/streams/openssl_dynamic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/streams/openssl_dynamic.c b/src/streams/openssl_dynamic.c index 37d7e734262..da16b6ed70c 100644 --- a/src/streams/openssl_dynamic.c +++ b/src/streams/openssl_dynamic.c @@ -122,7 +122,9 @@ int git_openssl_stream_dynamic_init(void) int err = 0; if ((openssl_handle = dlopen("libssl.so.1.1", RTLD_NOW)) == NULL && + (openssl_handle = dlopen("libssl.1.1.dylib", RTLD_NOW)) == NULL && (openssl_handle = dlopen("libssl.so.1.0.0", RTLD_NOW)) == NULL && + (openssl_handle = dlopen("libssl.1.0.0.dylib", RTLD_NOW)) == NULL && (openssl_handle = dlopen("libssl.so.10", RTLD_NOW)) == NULL) { git_error_set(GIT_ERROR_SSL, "could not load ssl libraries"); return -1; From 9fce506ce358f51d5556d39e68ab507202da48c3 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Aug 2021 15:53:10 -0400 Subject: [PATCH 0446/1616] openssl: lazily load libraries when dynamically loading Defer dlopen until it's needed when dynamically loading OpenSSL libraries. --- src/streams/openssl.c | 59 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/src/streams/openssl.c b/src/streams/openssl.c index 212c0020010..89c96780c14 100644 --- a/src/streams/openssl.c +++ b/src/streams/openssl.c @@ -102,7 +102,7 @@ static void git_openssl_free(void *mem) # endif /* !GIT_OPENSSL_LEGACY && !GIT_OPENSSL_DYNAMIC */ #endif /* VALGRIND */ -int git_openssl_stream_global_init(void) +static int openssl_init(void) { long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; const char *ciphers = git_libgit2__ssl_ciphers(); @@ -115,11 +115,6 @@ int git_openssl_stream_global_init(void) ssl_opts |= SSL_OP_NO_COMPRESSION; #endif -#ifdef GIT_OPENSSL_DYNAMIC - if (git_openssl_stream_dynamic_init() < 0) - return -1; -#endif - #ifdef VALGRIND /* * Swap in our own allocator functions that initialize @@ -171,6 +166,49 @@ int git_openssl_stream_global_init(void) return -1; } +/* + * When we use dynamic loading, we defer OpenSSL initialization until + * it's first used. `openssl_ensure_initialized` will do the work + * under a mutex. + */ +git_mutex openssl_mutex; +bool openssl_initialized; + +int git_openssl_stream_global_init(void) +{ +#ifndef GIT_OPENSSL_DYNAMIC + return openssl_init(); +#else + if (git_mutex_init(&openssl_mutex) != 0) + return -1; + + return 0; +#endif +} + +static int openssl_ensure_initialized(void) +{ +#ifdef GIT_OPENSSL_DYNAMIC + int error = 0; + + if (git_mutex_lock(&openssl_mutex) != 0) + return -1; + + if (!openssl_initialized) { + if ((error = git_openssl_stream_dynamic_init()) == 0) + error = openssl_init(); + + openssl_initialized = true; + } + + error |= git_mutex_unlock(&openssl_mutex); + return error; + +#else + return 0; +#endif +} + #if !defined(GIT_OPENSSL_LEGACY) && !defined(GIT_OPENSSL_DYNAMIC) int git_openssl_set_locking(void) { @@ -644,6 +682,9 @@ static int openssl_stream_wrap( int git_openssl_stream_wrap(git_stream **out, git_stream *in, const char *host) { + if (openssl_ensure_initialized() < 0) + return -1; + return openssl_stream_wrap(out, in, host, 0); } @@ -656,6 +697,9 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port) GIT_ASSERT_ARG(host); GIT_ASSERT_ARG(port); + if (openssl_ensure_initialized() < 0) + return -1; + if ((error = git_socket_stream_new(&stream, host, port)) < 0) return error; @@ -669,6 +713,9 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port) int git_openssl__set_cert_location(const char *file, const char *path) { + if (openssl_ensure_initialized() < 0) + return -1; + if (SSL_CTX_load_verify_locations(git__ssl_ctx, file, path) == 0) { char errmsg[256]; From 314469f90aefe86900c00bff21fa84be5e99f985 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 24 Aug 2021 16:23:09 -0400 Subject: [PATCH 0447/1616] ci: run dynamically loaded openssl workflows nightly Add Xenial, Bionic, CentOS 7 and 8 workflows with OpenSSL-Dynamic builds nightly. --- .github/workflows/nightly.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index e235a3ce760..47ebf464d11 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -59,6 +59,14 @@ jobs: CMAKE_OPTIONS: -DTHREADSAFE=OFF -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest + - # Xenial, Clang, OpenSSL (dynamically loaded) + container: + name: xenial + env: + CC: clang + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_GENERATOR: Ninja + os: ubuntu-latest - # Focal, Clang 10, mbedTLS, MemorySanitizer container: name: focal @@ -115,6 +123,14 @@ jobs: PKG_CONFIG_PATH: /usr/local/lib/pkgconfig SKIP_NEGOTIATE_TESTS: true os: ubuntu-latest + - # CentOS 7, OpenSSL (dynamically loaded) + container: + name: centos7 + env: + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + PKG_CONFIG_PATH: /usr/local/lib/pkgconfig + SKIP_NEGOTIATE_TESTS: true + os: ubuntu-latest - # CentOS 8 container: name: centos8 @@ -124,6 +140,15 @@ jobs: SKIP_NEGOTIATE_TESTS: true SKIP_SSH_TESTS: true os: ubuntu-latest + - # CentOS 8, OpenSSL (dynamically loaded) + container: + name: centos8 + env: + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + PKG_CONFIG_PATH: /usr/local/lib/pkgconfig + SKIP_NEGOTIATE_TESTS: true + SKIP_SSH_TESTS: true + os: ubuntu-latest - # macOS os: macos-10.15 env: @@ -180,6 +205,16 @@ jobs: BUILD_PATH: D:\Temp\mingw32\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true + - # Bionic, GCC, OpenSSL (dynamically loaded) + container: + name: bionic + dockerfile: bionic + env: + CC: gcc + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + RUN_INVASIVE_TESTS: true + os: ubuntu-latest - # Bionic, x86, Clang, OpenSSL container: name: bionic-x86 From 51d69dda8c58b293f95fc6e344f987b8d7469ec4 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Wed, 25 Aug 2021 11:34:59 +0200 Subject: [PATCH 0448/1616] enable warnings for C11 specific extensions --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff3411928cf..96bdb4cf093 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -233,6 +233,7 @@ ELSE () enable_warnings(unused-const-variable) enable_warnings(unused-function) enable_warnings(int-conversion) + enable_warnings(c11-extensions) # MinGW uses gcc, which expects POSIX formatting for printf, but # uses the Windows C library, which uses its own format specifiers. From 40f3702cb19410afaaef1772a9174029db2fef21 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Wed, 25 Aug 2021 11:36:06 +0200 Subject: [PATCH 0449/1616] c90/c99: name the unnamed union in git_hash_ctx --- src/hash.c | 10 +++++----- src/hash.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hash.c b/src/hash.c index d334236609a..5a7278e4225 100644 --- a/src/hash.c +++ b/src/hash.c @@ -16,7 +16,7 @@ int git_hash_ctx_init(git_hash_ctx *ctx) { int error; - if ((error = git_hash_sha1_ctx_init(&ctx->sha1)) < 0) + if ((error = git_hash_sha1_ctx_init(&ctx->ctx.sha1)) < 0) return error; ctx->algo = GIT_HASH_ALGO_SHA1; @@ -28,7 +28,7 @@ void git_hash_ctx_cleanup(git_hash_ctx *ctx) { switch (ctx->algo) { case GIT_HASH_ALGO_SHA1: - git_hash_sha1_ctx_cleanup(&ctx->sha1); + git_hash_sha1_ctx_cleanup(&ctx->ctx.sha1); return; default: /* unreachable */ ; @@ -39,7 +39,7 @@ int git_hash_init(git_hash_ctx *ctx) { switch (ctx->algo) { case GIT_HASH_ALGO_SHA1: - return git_hash_sha1_init(&ctx->sha1); + return git_hash_sha1_init(&ctx->ctx.sha1); default: /* unreachable */ ; } @@ -51,7 +51,7 @@ int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) { switch (ctx->algo) { case GIT_HASH_ALGO_SHA1: - return git_hash_sha1_update(&ctx->sha1, data, len); + return git_hash_sha1_update(&ctx->ctx.sha1, data, len); default: /* unreachable */ ; } @@ -63,7 +63,7 @@ int git_hash_final(git_oid *out, git_hash_ctx *ctx) { switch (ctx->algo) { case GIT_HASH_ALGO_SHA1: - return git_hash_sha1_final(out, &ctx->sha1); + return git_hash_sha1_final(out, &ctx->ctx.sha1); default: /* unreachable */ ; } diff --git a/src/hash.h b/src/hash.h index 017bb286c34..87305cc7920 100644 --- a/src/hash.h +++ b/src/hash.h @@ -27,7 +27,7 @@ typedef enum { typedef struct git_hash_ctx { union { git_hash_sha1_ctx sha1; - }; + } ctx; git_hash_algo_t algo; } git_hash_ctx; From b01895822f74ab7488c6fee24180ce73dc50d025 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Wed, 25 Aug 2021 18:07:01 +0200 Subject: [PATCH 0450/1616] enable gcc warnings for C11 specific extensions --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96bdb4cf093..bf8d8f5411e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,6 +234,7 @@ ELSE () enable_warnings(unused-function) enable_warnings(int-conversion) enable_warnings(c11-extensions) + enable_warnings(c99-c11-compat) # MinGW uses gcc, which expects POSIX formatting for printf, but # uses the Windows C library, which uses its own format specifiers. From 4bbe5e6ea6f2084c4153fb6205115bd43db0a300 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Wed, 25 Aug 2021 18:14:10 +0200 Subject: [PATCH 0451/1616] win32: name the dummy union in GIT_REPARSE_DATA_BUFFER Instead of buf->"typeofbuffer"ReparseBuffer the members will be referenced with buf->ReparseBuffer."typeofbuffer" https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_reparse_data_buffer?redirectedfrom=MSDN calls the union DUMMYUNIONNAME but that looks a bit cluttered. --- src/win32/path_w32.c | 12 ++++++------ src/win32/reparse.h | 8 ++++---- tests/core/link.c | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c index 581673b1bec..e6640c85ed4 100644 --- a/src/win32/path_w32.c +++ b/src/win32/path_w32.c @@ -381,14 +381,14 @@ int git_win32_path_readlink_w(git_win32_path dest, const git_win32_path path) switch (reparse_buf->ReparseTag) { case IO_REPARSE_TAG_SYMLINK: - target = reparse_buf->SymbolicLinkReparseBuffer.PathBuffer + - (reparse_buf->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)); - target_len = reparse_buf->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR); + target = reparse_buf->ReparseBuffer.SymbolicLink.PathBuffer + + (reparse_buf->ReparseBuffer.SymbolicLink.SubstituteNameOffset / sizeof(WCHAR)); + target_len = reparse_buf->ReparseBuffer.SymbolicLink.SubstituteNameLength / sizeof(WCHAR); break; case IO_REPARSE_TAG_MOUNT_POINT: - target = reparse_buf->MountPointReparseBuffer.PathBuffer + - (reparse_buf->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)); - target_len = reparse_buf->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR); + target = reparse_buf->ReparseBuffer.MountPoint.PathBuffer + + (reparse_buf->ReparseBuffer.MountPoint.SubstituteNameOffset / sizeof(WCHAR)); + target_len = reparse_buf->ReparseBuffer.MountPoint.SubstituteNameLength / sizeof(WCHAR); break; default: errno = EINVAL; diff --git a/src/win32/reparse.h b/src/win32/reparse.h index 5f7408a1b39..23312319f68 100644 --- a/src/win32/reparse.h +++ b/src/win32/reparse.h @@ -26,18 +26,18 @@ typedef struct _GIT_REPARSE_DATA_BUFFER { USHORT PrintNameLength; ULONG Flags; WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; + } SymbolicLink; struct { USHORT SubstituteNameOffset; USHORT SubstituteNameLength; USHORT PrintNameOffset; USHORT PrintNameLength; WCHAR PathBuffer[1]; - } MountPointReparseBuffer; + } MountPoint; struct { UCHAR DataBuffer[1]; - } GenericReparseBuffer; - }; + } Generic; + } ReparseBuffer; } GIT_REPARSE_DATA_BUFFER; #define REPARSE_DATA_HEADER_SIZE 8 diff --git a/tests/core/link.c b/tests/core/link.c index 1e5ed454cc4..0493edf1dd7 100644 --- a/tests/core/link.c +++ b/tests/core/link.c @@ -123,7 +123,7 @@ static void do_junction(const char *old, const char *new) reparse_buf = LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, reparse_buflen); cl_assert(reparse_buf); - subst_utf16 = reparse_buf->MountPointReparseBuffer.PathBuffer; + subst_utf16 = reparse_buf->ReparseBuffer.MountPoint.PathBuffer; print_utf16 = subst_utf16 + subst_utf16_len + 1; ret = git__utf8_to_16(subst_utf16, subst_utf16_len + 1, @@ -135,10 +135,10 @@ static void do_junction(const char *old, const char *new) cl_assert_equal_i(print_utf16_len, ret); reparse_buf->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - reparse_buf->MountPointReparseBuffer.SubstituteNameOffset = 0; - reparse_buf->MountPointReparseBuffer.SubstituteNameLength = subst_byte_len; - reparse_buf->MountPointReparseBuffer.PrintNameOffset = (USHORT)(subst_byte_len + sizeof(WCHAR)); - reparse_buf->MountPointReparseBuffer.PrintNameLength = print_byte_len; + reparse_buf->ReparseBuffer.MountPoint.SubstituteNameOffset = 0; + reparse_buf->ReparseBuffer.MountPoint.SubstituteNameLength = subst_byte_len; + reparse_buf->ReparseBuffer.MountPoint.PrintNameOffset = (USHORT)(subst_byte_len + sizeof(WCHAR)); + reparse_buf->ReparseBuffer.MountPoint.PrintNameLength = print_byte_len; reparse_buf->ReparseDataLength = reparse_buflen - REPARSE_DATA_HEADER_SIZE; cl_win32_pass(DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, From bcc0d750298d18ccc18e5b57317d1d7833498018 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Wed, 25 Aug 2021 18:58:39 +0200 Subject: [PATCH 0452/1616] array: make gcc keep the type of the NULL return value --- src/array.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/array.h b/src/array.h index 03537e79666..e649d845b33 100644 --- a/src/array.h +++ b/src/array.h @@ -70,13 +70,13 @@ GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size) #define git_array_alloc(a) \ (((a).size >= (a).asize) ? \ git_array_grow(&(a), sizeof(*(a).ptr)) : \ - ((a).ptr ? &(a).ptr[(a).size++] : NULL)) + ((a).ptr ? &(a).ptr[(a).size++] : (void *)NULL)) -#define git_array_last(a) ((a).size ? &(a).ptr[(a).size - 1] : NULL) +#define git_array_last(a) ((a).size ? &(a).ptr[(a).size - 1] : (void *)NULL) -#define git_array_pop(a) ((a).size ? &(a).ptr[--(a).size] : NULL) +#define git_array_pop(a) ((a).size ? &(a).ptr[--(a).size] : (void *)NULL) -#define git_array_get(a, i) (((i) < (a).size) ? &(a).ptr[(i)] : NULL) +#define git_array_get(a, i) (((i) < (a).size) ? &(a).ptr[(i)] : (void *)NULL) #define git_array_size(a) (a).size From 7f1dd7030664fa15caeb6e20578bcb9543026ba7 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Wed, 25 Aug 2021 20:08:58 +0200 Subject: [PATCH 0453/1616] array: fix dereference from void * type --- src/diff_driver.c | 6 +++--- src/tree.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/diff_driver.c b/src/diff_driver.c index e9f63cb1760..8e9131feb33 100644 --- a/src/diff_driver.c +++ b/src/diff_driver.c @@ -389,13 +389,13 @@ int git_diff_driver_lookup( void git_diff_driver_free(git_diff_driver *driver) { - size_t i; + git_diff_driver_pattern *pat; if (!driver) return; - for (i = 0; i < git_array_size(driver->fn_patterns); ++i) - git_regexp_dispose(& git_array_get(driver->fn_patterns, i)->re); + while ((pat = git_array_pop(driver->fn_patterns)) != NULL) + git_regexp_dispose(&pat->re); git_array_clear(driver->fn_patterns); git_regexp_dispose(&driver->word_pattern); diff --git a/src/tree.c b/src/tree.c index 76821e3a083..b1df79eacfc 100644 --- a/src/tree.c +++ b/src/tree.c @@ -1251,8 +1251,9 @@ int git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseli } case GIT_TREE_UPDATE_REMOVE: { + tree_stack_entry *last = git_array_last(stack); char *basename = git_path_basename(update->path); - error = git_treebuilder_remove(git_array_last(stack)->bld, basename); + error = git_treebuilder_remove(last->bld, basename); git__free(basename); break; } From f062eb62116f7c3d7c71054a658dd023b319f280 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Wed, 25 Aug 2021 22:12:57 +0200 Subject: [PATCH 0454/1616] git_array_alloc: return objects of correct type --- src/array.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/array.h b/src/array.h index e649d845b33..e97688b365f 100644 --- a/src/array.h +++ b/src/array.h @@ -41,8 +41,8 @@ typedef git_array_t(char) git_array_generic_t; -/* use a generic array for growth so this can return the new item */ -GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size) +/* use a generic array for growth, return 0 on success */ +GIT_INLINE(int) git_array_grow(void *_a, size_t item_size) { volatile git_array_generic_t *a = _a; size_t new_size; @@ -59,18 +59,18 @@ GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size) if ((new_array = git__reallocarray(a->ptr, new_size, item_size)) == NULL) goto on_oom; - a->ptr = new_array; a->asize = new_size; a->size++; - return a->ptr + (a->size - 1) * item_size; + a->ptr = new_array; + a->asize = new_size; + return 0; on_oom: git_array_clear(*a); - return NULL; + return -1; } #define git_array_alloc(a) \ - (((a).size >= (a).asize) ? \ - git_array_grow(&(a), sizeof(*(a).ptr)) : \ - ((a).ptr ? &(a).ptr[(a).size++] : (void *)NULL)) + (((a).size < (a).asize || git_array_grow(&(a), sizeof(*(a).ptr)) == 0) ? \ + &(a).ptr[(a).size++] : (void *)NULL) #define git_array_last(a) ((a).size ? &(a).ptr[(a).size - 1] : (void *)NULL) From 8643b524522c67ea24848699be01ab0e49d4a4a0 Mon Sep 17 00:00:00 2001 From: Alexander Ovchinnikov Date: Mon, 8 Feb 2021 00:40:50 +0100 Subject: [PATCH 0455/1616] Revert "Merge pull request #5775 from libgit2/ethomson/clone_branch" This reverts commit 487f2a8287c4d1d41d39e05ac53d0e50c679d7e9, reversing changes made to c6cf7f0e6927f1b264a7dda2467d70b9f744a01f. --- src/clone.c | 63 ++++++++++++++--------------------------- tests/clone/nonetwork.c | 8 ------ 2 files changed, 21 insertions(+), 50 deletions(-) diff --git a/src/clone.c b/src/clone.c index 6d5ebf6b059..7ae90b09ea3 100644 --- a/src/clone.c +++ b/src/clone.c @@ -162,37 +162,6 @@ static int update_head_to_default(git_repository *repo) return error; } -static int update_remote_head_byname( - git_repository *repo, - const char *remote_name, - const char *tracking_branch_name, - const char *reflog_message) -{ - git_buf tracking_head_name = GIT_BUF_INIT; - git_reference *remote_head = NULL; - int error; - - if ((error = git_buf_printf(&tracking_head_name, - "%s%s/%s", - GIT_REFS_REMOTES_DIR, - remote_name, - GIT_HEAD_FILE)) < 0) - goto cleanup; - - error = git_reference_symbolic_create( - &remote_head, - repo, - git_buf_cstr(&tracking_head_name), - tracking_branch_name, - true, - reflog_message); - -cleanup: - git_reference_free(remote_head); - git_buf_dispose(&tracking_head_name); - return error; -} - static int update_remote_head( git_repository *repo, git_remote *remote, @@ -200,7 +169,9 @@ static int update_remote_head( const char *reflog_message) { git_refspec *refspec; - git_buf tracking_branch_name = GIT_BUF_INIT; + git_reference *remote_head = NULL; + git_buf remote_head_name = GIT_BUF_INIT; + git_buf remote_branch_name = GIT_BUF_INIT; int error; /* Determine the remote tracking ref name from the local branch */ @@ -213,19 +184,30 @@ static int update_remote_head( } if ((error = git_refspec_transform( - &tracking_branch_name, + &remote_branch_name, refspec, git_buf_cstr(target))) < 0) goto cleanup; - error = update_remote_head_byname( - repo, + if ((error = git_buf_printf(&remote_head_name, + "%s%s/%s", + GIT_REFS_REMOTES_DIR, git_remote_name(remote), - git_buf_cstr(&tracking_branch_name), + GIT_HEAD_FILE)) < 0) + goto cleanup; + + error = git_reference_symbolic_create( + &remote_head, + repo, + git_buf_cstr(&remote_head_name), + git_buf_cstr(&remote_branch_name), + true, reflog_message); cleanup: - git_buf_dispose(&tracking_branch_name); + git_reference_free(remote_head); + git_buf_dispose(&remote_branch_name); + git_buf_dispose(&remote_head_name); return error; } @@ -295,11 +277,8 @@ static int update_head_to_branch( if ((retcode = git_reference_lookup(&remote_ref, repo, git_buf_cstr(&remote_branch_name))) < 0) goto cleanup; - if ((retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch, - reflog_message)) < 0) - goto cleanup; - - retcode = update_remote_head_byname(repo, remote_name, remote_branch_name.ptr, reflog_message); + retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch, + reflog_message); cleanup: git_reference_free(remote_ref); diff --git a/tests/clone/nonetwork.c b/tests/clone/nonetwork.c index d4da3d3af32..7ca49085cfe 100644 --- a/tests/clone/nonetwork.c +++ b/tests/clone/nonetwork.c @@ -158,8 +158,6 @@ void test_clone_nonetwork__can_prevent_the_checkout_of_a_standard_repo(void) void test_clone_nonetwork__can_checkout_given_branch(void) { - git_reference *remote_head; - g_options.checkout_branch = "test"; cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); @@ -169,12 +167,6 @@ void test_clone_nonetwork__can_checkout_given_branch(void) cl_assert_equal_s(git_reference_name(g_ref), "refs/heads/test"); cl_assert(git_path_exists("foo/readme.txt")); - - cl_git_pass(git_reference_lookup(&remote_head, g_repo, "refs/remotes/origin/HEAD")); - cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(remote_head)); - cl_assert_equal_s("refs/remotes/origin/test", git_reference_symbolic_target(remote_head)); - - git_reference_free(remote_head); } static int clone_cancel_fetch_transfer_progress_cb( From 6bb35878629d77e002e5f744aaf2e62f5bb4cb42 Mon Sep 17 00:00:00 2001 From: Alexander Ovchinnikov Date: Mon, 8 Feb 2021 00:49:21 +0100 Subject: [PATCH 0456/1616] clone: set refs/remotes/origin/HEAD to default branch when branch is specified, attempt 2 --- src/clone.c | 21 ++++++++++++++------- tests/clone/nonetwork.c | 8 ++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/clone.c b/src/clone.c index 7ae90b09ea3..962cf126390 100644 --- a/src/clone.c +++ b/src/clone.c @@ -259,30 +259,38 @@ static int update_head_to_remote( static int update_head_to_branch( git_repository *repo, - const char *remote_name, + git_remote *remote, const char *branch, const char *reflog_message) { int retcode; git_buf remote_branch_name = GIT_BUF_INIT; git_reference* remote_ref = NULL; + git_buf default_branch = GIT_BUF_INIT; - GIT_ASSERT_ARG(remote_name); + GIT_ASSERT_ARG(remote); GIT_ASSERT_ARG(branch); if ((retcode = git_buf_printf(&remote_branch_name, GIT_REFS_REMOTES_DIR "%s/%s", - remote_name, branch)) < 0 ) + git_remote_name(remote), branch)) < 0 ) goto cleanup; if ((retcode = git_reference_lookup(&remote_ref, repo, git_buf_cstr(&remote_branch_name))) < 0) goto cleanup; - retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch, - reflog_message); + if ((retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch, + reflog_message)) < 0) + goto cleanup; + + if ((retcode = git_remote_default_branch(&default_branch, remote)) < 0) + goto cleanup; + + retcode = update_remote_head(repo, remote, &default_branch, reflog_message); cleanup: git_reference_free(remote_ref); git_buf_dispose(&remote_branch_name); + git_buf_dispose(&default_branch); return retcode; } @@ -367,8 +375,7 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c int error; if (branch) - error = update_head_to_branch(repo, git_remote_name(remote), branch, - reflog_message); + error = update_head_to_branch(repo, remote, branch, reflog_message); /* Point HEAD to the same ref as the remote's head */ else error = update_head_to_remote(repo, remote, reflog_message); diff --git a/tests/clone/nonetwork.c b/tests/clone/nonetwork.c index 7ca49085cfe..ec12fee18a1 100644 --- a/tests/clone/nonetwork.c +++ b/tests/clone/nonetwork.c @@ -158,6 +158,8 @@ void test_clone_nonetwork__can_prevent_the_checkout_of_a_standard_repo(void) void test_clone_nonetwork__can_checkout_given_branch(void) { + git_reference *remote_head; + g_options.checkout_branch = "test"; cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); @@ -167,6 +169,12 @@ void test_clone_nonetwork__can_checkout_given_branch(void) cl_assert_equal_s(git_reference_name(g_ref), "refs/heads/test"); cl_assert(git_path_exists("foo/readme.txt")); + + cl_git_pass(git_reference_lookup(&remote_head, g_repo, "refs/remotes/origin/HEAD")); + cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(remote_head)); + cl_assert_equal_s("refs/remotes/origin/master", git_reference_symbolic_target(remote_head)); + + git_reference_free(remote_head); } static int clone_cancel_fetch_transfer_progress_cb( From cb078d5194e67e093cdd53b235bc1bd837490ca3 Mon Sep 17 00:00:00 2001 From: Alexander Ovchinnikov Date: Thu, 5 Aug 2021 14:02:54 +0200 Subject: [PATCH 0457/1616] Check if default branch matches refspec --- src/clone.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/clone.c b/src/clone.c index 962cf126390..e29a4aab35b 100644 --- a/src/clone.c +++ b/src/clone.c @@ -285,6 +285,9 @@ static int update_head_to_branch( if ((retcode = git_remote_default_branch(&default_branch, remote)) < 0) goto cleanup; + if (!git_remote__matching_refspec(remote, git_buf_cstr(&default_branch))) + goto cleanup; + retcode = update_remote_head(repo, remote, &default_branch, reflog_message); cleanup: From 63f08e4258122d6f6ea1f04ec8c08779bf300b6c Mon Sep 17 00:00:00 2001 From: lhchavez Date: Thu, 26 Aug 2021 05:29:34 -0700 Subject: [PATCH 0458/1616] Make the defaultable fields defaultable Also, add `git_commit_graph_writer_options_init`! --- include/git2/sys/commit_graph.h | 4 ++-- src/commit_graph.c | 14 +++++++++++++- tests/core/structinit.c | 8 ++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/git2/sys/commit_graph.h b/include/git2/sys/commit_graph.h index 01cf8d1bfa3..67d95469c7c 100644 --- a/include/git2/sys/commit_graph.h +++ b/include/git2/sys/commit_graph.h @@ -115,12 +115,13 @@ typedef struct { /** * The number of commits in level N is less than X times the number of - * commits in level N + 1. + * commits in level N + 1. Default is 2. */ float size_multiple; /** * The number of commits in level N + 1 is more than C commits. + * Default is 64000. */ size_t max_commits; } git_commit_graph_writer_options; @@ -129,7 +130,6 @@ typedef struct { #define GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT \ { \ GIT_COMMIT_GRAPH_WRITER_OPTIONS_VERSION, \ - GIT_COMMIT_GRAPH_SPLIT_STRATEGY_SINGLE_FILE, 2.0f, 64000 \ } /** diff --git a/src/commit_graph.c b/src/commit_graph.c index 78ab436d6a2..1601c630cdb 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -1143,6 +1143,18 @@ static int commit_graph_write_filebuf(const char *buf, size_t size, void *data) return git_filebuf_write(f, buf, size); } +int git_commit_graph_writer_options_init( + git_commit_graph_writer_options *opts, + unsigned int version) +{ + GIT_INIT_STRUCTURE_FROM_TEMPLATE( + opts, + version, + git_commit_graph_writer_options, + GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT); + return 0; +} + int git_commit_graph_writer_commit( git_commit_graph_writer *w, git_commit_graph_writer_options *opts) @@ -1152,7 +1164,7 @@ int git_commit_graph_writer_commit( git_buf commit_graph_path = GIT_BUF_INIT; git_filebuf output = GIT_FILEBUF_INIT; - /* TODO: support options. */ + /* TODO: support options and fill in defaults. */ GIT_UNUSED(opts); error = git_buf_joinpath( diff --git a/tests/core/structinit.c b/tests/core/structinit.c index b6377bdde57..d24da874da5 100644 --- a/tests/core/structinit.c +++ b/tests/core/structinit.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" +#include #include #include #include @@ -97,6 +98,13 @@ void test_core_structinit__compare(void) git_clone_options, GIT_CLONE_OPTIONS_VERSION, \ GIT_CLONE_OPTIONS_INIT, git_clone_options_init); + /* commit_graph_writer */ + CHECK_MACRO_FUNC_INIT_EQUAL( \ + git_commit_graph_writer_options, \ + GIT_COMMIT_GRAPH_WRITER_OPTIONS_VERSION, \ + GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT, \ + git_commit_graph_writer_options_init); + /* diff */ CHECK_MACRO_FUNC_INIT_EQUAL( \ git_diff_options, GIT_DIFF_OPTIONS_VERSION, \ From 74708a813d586df3ba22a81b475f6aba0498e2ef Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sun, 20 Dec 2020 12:45:01 -0800 Subject: [PATCH 0459/1616] Homogenize semantics for atomic-related functions There were some subtle semantic differences between the various implementations of atomic functions. Now they behave the same, have tests and are better documented to avoid this from happening again in the future. Of note: * The semantics chosen for `git_atomic_compare_and_swap` match `InterlockedCompareExchangePointer`/`__sync_cal_compare_and_swap` now. * The semantics chosen for `git_atomic_add` match `InterlockedAdd`/`__atomic_add_fetch`. * `git_atomic_swap` and `git_atomic_load` still have a bit of semantic difference with the gcc builtins / msvc interlocked operations, since they require an l-value (not a pointer). If desired, this can be homogenized. --- src/attrcache.c | 13 ++--- src/diff_driver.c | 25 +++++---- src/repository.c | 12 ++-- src/thread.h | 111 +++++++++++++++++++++++++++--------- tests/threads/atomic.c | 125 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 234 insertions(+), 52 deletions(-) create mode 100644 tests/threads/atomic.c diff --git a/src/attrcache.c b/src/attrcache.c index 7fe2bfbdb84..2b36b7a9c98 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -127,7 +127,7 @@ static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file) { int error = 0; git_attr_file_entry *entry; - git_attr_file *old = NULL; + git_attr_file *oldfile = NULL; if (!file) return 0; @@ -136,13 +136,13 @@ static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file) return error; if ((entry = attr_cache_lookup_entry(cache, file->entry->path)) != NULL) - old = git_atomic_compare_and_swap(&entry->file[file->source.type], file, NULL); + oldfile = git_atomic_compare_and_swap(&entry->file[file->source.type], file, NULL); attr_cache_unlock(cache); - if (old) { - GIT_REFCOUNT_OWN(old, NULL); - git_attr_file__free(old); + if (oldfile == file) { + GIT_REFCOUNT_OWN(file, NULL); + git_attr_file__free(file); } return error; @@ -401,8 +401,7 @@ int git_attr_cache__init(git_repository *repo) (ret = git_pool_init(&cache->pool, 1)) < 0) goto cancel; - cache = git_atomic_compare_and_swap(&repo->attrcache, NULL, cache); - if (cache) + if (git_atomic_compare_and_swap(&repo->attrcache, NULL, cache) != NULL) goto cancel; /* raced with another thread, free this but no error */ git_config_free(cfg); diff --git a/src/diff_driver.c b/src/diff_driver.c index 8e9131feb33..a3892d35eea 100644 --- a/src/diff_driver.c +++ b/src/diff_driver.c @@ -141,18 +141,23 @@ static int diff_driver_funcname(const git_config_entry *entry, void *payload) static git_diff_driver_registry *git_repository_driver_registry( git_repository *repo) { - if (!repo->diff_drivers) { - git_diff_driver_registry *reg = git_diff_driver_registry_new(); - reg = git_atomic_compare_and_swap(&repo->diff_drivers, NULL, reg); + git_diff_driver_registry *reg = git_atomic_load(repo->diff_drivers), *newreg; + if (reg) + return reg; - if (reg != NULL) /* if we race, free losing allocation */ - git_diff_driver_registry_free(reg); - } - - if (!repo->diff_drivers) + newreg = git_diff_driver_registry_new(); + if (!newreg) { git_error_set(GIT_ERROR_REPOSITORY, "unable to create diff driver registry"); - - return repo->diff_drivers; + return newreg; + } + reg = git_atomic_compare_and_swap(&repo->diff_drivers, NULL, newreg); + if (!reg) { + reg = newreg; + } else { + /* if we race, free losing allocation */ + git_diff_driver_registry_free(newreg); + } + return reg; } static int diff_driver_alloc( diff --git a/src/repository.c b/src/repository.c index 692f71861a2..9ed46bf4dcd 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1093,8 +1093,7 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo) if (!error) { GIT_REFCOUNT_OWN(config, repo); - config = git_atomic_compare_and_swap(&repo->_config, NULL, config); - if (config != NULL) { + if (git_atomic_compare_and_swap(&repo->_config, NULL, config) != NULL) { GIT_REFCOUNT_OWN(config, NULL); git_config_free(config); } @@ -1164,8 +1163,7 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo) return error; } - odb = git_atomic_compare_and_swap(&repo->_odb, NULL, odb); - if (odb != NULL) { + if (git_atomic_compare_and_swap(&repo->_odb, NULL, odb) != NULL) { GIT_REFCOUNT_OWN(odb, NULL); git_odb_free(odb); } @@ -1209,8 +1207,7 @@ int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo) if (!error) { GIT_REFCOUNT_OWN(refdb, repo); - refdb = git_atomic_compare_and_swap(&repo->_refdb, NULL, refdb); - if (refdb != NULL) { + if (git_atomic_compare_and_swap(&repo->_refdb, NULL, refdb) != NULL) { GIT_REFCOUNT_OWN(refdb, NULL); git_refdb_free(refdb); } @@ -1257,8 +1254,7 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo) if (!error) { GIT_REFCOUNT_OWN(index, repo); - index = git_atomic_compare_and_swap(&repo->_index, NULL, index); - if (index != NULL) { + if (git_atomic_compare_and_swap(&repo->_index, NULL, index) != NULL) { GIT_REFCOUNT_OWN(index, NULL); git_index_free(index); } diff --git a/src/thread.h b/src/thread.h index b4f869243e9..4b091c0a29a 100644 --- a/src/thread.h +++ b/src/thread.h @@ -74,6 +74,9 @@ typedef git_atomic32 git_atomic_ssize; # include "unix/pthread.h" #endif +/* + * Atomically sets the contents of *a to be val. + */ GIT_INLINE(void) git_atomic32_set(git_atomic32 *a, int val) { #if defined(GIT_WIN32) @@ -87,6 +90,10 @@ GIT_INLINE(void) git_atomic32_set(git_atomic32 *a, int val) #endif } +/* + * Atomically increments the contents of *a by 1, and stores the result back into *a. + * @return the result of the operation. + */ GIT_INLINE(int) git_atomic32_inc(git_atomic32 *a) { #if defined(GIT_WIN32) @@ -100,10 +107,14 @@ GIT_INLINE(int) git_atomic32_inc(git_atomic32 *a) #endif } +/* + * Atomically adds the contents of *a and addend, and stores the result back into *a. + * @return the result of the operation. + */ GIT_INLINE(int) git_atomic32_add(git_atomic32 *a, int32_t addend) { #if defined(GIT_WIN32) - return InterlockedExchangeAdd(&a->val, addend); + return InterlockedAdd(&a->val, addend); #elif defined(GIT_BUILTIN_ATOMIC) return __atomic_add_fetch(&a->val, addend, __ATOMIC_SEQ_CST); #elif defined(GIT_BUILTIN_SYNC) @@ -113,6 +124,10 @@ GIT_INLINE(int) git_atomic32_add(git_atomic32 *a, int32_t addend) #endif } +/* + * Atomically decrements the contents of *a by 1, and stores the result back into *a. + * @return the result of the operation. + */ GIT_INLINE(int) git_atomic32_dec(git_atomic32 *a) { #if defined(GIT_WIN32) @@ -126,6 +141,10 @@ GIT_INLINE(int) git_atomic32_dec(git_atomic32 *a) #endif } +/* + * Atomically gets the contents of *a. + * @return the contents of *a. + */ GIT_INLINE(int) git_atomic32_get(git_atomic32 *a) { #if defined(GIT_WIN32) @@ -143,16 +162,13 @@ GIT_INLINE(void *) git_atomic__compare_and_swap( void * volatile *ptr, void *oldval, void *newval) { #if defined(GIT_WIN32) - volatile void *foundval; - foundval = InterlockedCompareExchangePointer((volatile PVOID *)ptr, newval, oldval); - return (foundval == oldval) ? oldval : newval; + return InterlockedCompareExchangePointer((volatile PVOID *)ptr, newval, oldval); #elif defined(GIT_BUILTIN_ATOMIC) - bool success = __atomic_compare_exchange(ptr, &oldval, &newval, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); - return success ? oldval : newval; + void *foundval = oldval; + __atomic_compare_exchange(ptr, &foundval, &newval, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return foundval; #elif defined(GIT_BUILTIN_SYNC) - volatile void *foundval; - foundval = __sync_val_compare_and_swap(ptr, oldval, newval); - return (foundval == oldval) ? oldval : newval; + return __sync_val_compare_and_swap(ptr, oldval, newval); #else # error "Unsupported architecture for atomic operations" #endif @@ -164,11 +180,11 @@ GIT_INLINE(volatile void *) git_atomic__swap( #if defined(GIT_WIN32) return InterlockedExchangePointer(ptr, newval); #elif defined(GIT_BUILTIN_ATOMIC) - void * volatile foundval; + void * volatile foundval = NULL; __atomic_exchange(ptr, &newval, &foundval, __ATOMIC_SEQ_CST); return foundval; #elif defined(GIT_BUILTIN_SYNC) - return __sync_lock_test_and_set(ptr, newval); + return (volatile void *)__sync_lock_test_and_set(ptr, newval); #else # error "Unsupported architecture for atomic operations" #endif @@ -178,9 +194,7 @@ GIT_INLINE(volatile void *) git_atomic__load(void * volatile *ptr) { #if defined(GIT_WIN32) void *newval = NULL, *oldval = NULL; - volatile void *foundval = NULL; - foundval = InterlockedCompareExchangePointer((volatile PVOID *)ptr, newval, oldval); - return foundval; + return (volatile void *)InterlockedCompareExchangePointer((volatile PVOID *)ptr, newval, oldval); #elif defined(GIT_BUILTIN_ATOMIC) return (volatile void *)__atomic_load_n(ptr, __ATOMIC_SEQ_CST); #elif defined(GIT_BUILTIN_SYNC) @@ -192,10 +206,14 @@ GIT_INLINE(volatile void *) git_atomic__load(void * volatile *ptr) #ifdef GIT_ARCH_64 +/* + * Atomically adds the contents of *a and addend, and stores the result back into *a. + * @return the result of the operation. + */ GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend) { #if defined(GIT_WIN32) - return InterlockedExchangeAdd64(&a->val, addend); + return InterlockedAdd64(&a->val, addend); #elif defined(GIT_BUILTIN_ATOMIC) return __atomic_add_fetch(&a->val, addend, __ATOMIC_SEQ_CST); #elif defined(GIT_BUILTIN_SYNC) @@ -205,6 +223,9 @@ GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend) #endif } +/* + * Atomically sets the contents of *a to be val. + */ GIT_INLINE(void) git_atomic64_set(git_atomic64 *a, int64_t val) { #if defined(GIT_WIN32) @@ -218,6 +239,10 @@ GIT_INLINE(void) git_atomic64_set(git_atomic64 *a, int64_t val) #endif } +/* + * Atomically gets the contents of *a. + * @return the contents of *a. + */ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a) { #if defined(GIT_WIN32) @@ -297,11 +322,10 @@ GIT_INLINE(int) git_atomic32_get(git_atomic32 *a) GIT_INLINE(void *) git_atomic__compare_and_swap( void * volatile *ptr, void *oldval, void *newval) { - if (*ptr == oldval) + void *foundval = *ptr; + if (foundval == oldval) *ptr = newval; - else - oldval = newval; - return oldval; + return foundval; } GIT_INLINE(volatile void *) git_atomic__swap( @@ -339,17 +363,50 @@ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a) #endif -/* Atomically replace oldval with newval - * @return oldval if it was replaced or newval if it was not +/* + * Atomically replace the contents of *ptr (if they are equal to oldval) with + * newval. ptr must point to a pointer or a value that is the same size as a + * pointer. This is semantically compatible with: + * + * #define git_atomic_compare_and_swap(ptr, oldval, newval) \ + * ({ \ + * void *foundval = *ptr; \ + * if (foundval == oldval) \ + * *ptr = newval; \ + * foundval; \ + * }) + * + * @return the original contents of *ptr. */ -#define git_atomic_compare_and_swap(P,O,N) \ - git_atomic__compare_and_swap((void * volatile *)P, O, N) +#define git_atomic_compare_and_swap(ptr, oldval, newval) \ + git_atomic__compare_and_swap((void * volatile *)ptr, oldval, newval) -#define git_atomic_swap(ptr, val) \ - (void *)git_atomic__swap((void * volatile *)&ptr, val) +/* + * Atomically replace the contents of v with newval. v must be the same size as + * a pointer. This is semantically compatible with: + * + * #define git_atomic_swap(v, newval) \ + * ({ \ + * volatile void *old = v; \ + * v = newval; \ + * old; \ + * }) + * + * @return the original contents of v. + */ +#define git_atomic_swap(v, newval) \ + (void *)git_atomic__swap((void * volatile *)&(v), newval) -#define git_atomic_load(ptr) \ - (void *)git_atomic__load((void * volatile *)&ptr) +/* + * Atomically reads the contents of v. v must be the same size as a pointer. + * This is semantically compatible with: + * + * #define git_atomic_load(v) v + * + * @return the contents of v. + */ +#define git_atomic_load(v) \ + (void *)git_atomic__load((void * volatile *)&(v)) #if defined(GIT_THREADS) diff --git a/tests/threads/atomic.c b/tests/threads/atomic.c new file mode 100644 index 00000000000..4d04a777a65 --- /dev/null +++ b/tests/threads/atomic.c @@ -0,0 +1,125 @@ +#include "clar_libgit2.h" + +void test_threads_atomic__atomic32_set(void) +{ + git_atomic32 v = {0}; + git_atomic32_set(&v, 1); + cl_assert_equal_i(v.val, 1); +} + +void test_threads_atomic__atomic32_get(void) +{ + git_atomic32 v = {1}; + cl_assert_equal_i(git_atomic32_get(&v), 1); +} + +void test_threads_atomic__atomic32_inc(void) +{ + git_atomic32 v = {0}; + cl_assert_equal_i(git_atomic32_inc(&v), 1); + cl_assert_equal_i(v.val, 1); +} + +void test_threads_atomic__atomic32_add(void) +{ + git_atomic32 v = {0}; + cl_assert_equal_i(git_atomic32_add(&v, 1), 1); + cl_assert_equal_i(v.val, 1); +} + +void test_threads_atomic__atomic32_dec(void) +{ + git_atomic32 v = {1}; + cl_assert_equal_i(git_atomic32_dec(&v), 0); + cl_assert_equal_i(v.val, 0); +} + +void test_threads_atomic__atomic64_set(void) +{ +#ifndef GIT_ARCH_64 + cl_skip(); +#else + git_atomic64 v = {0}; + git_atomic64_set(&v, 1); + cl_assert_equal_i(v.val, 1); +#endif +} + +void test_threads_atomic__atomic64_get(void) +{ +#ifndef GIT_ARCH_64 + cl_skip(); +#else + git_atomic64 v = {1}; + cl_assert_equal_i(git_atomic64_get(&v), 1); +#endif +} + +void test_threads_atomic__atomic64_add(void) +{ +#ifndef GIT_ARCH_64 + cl_skip(); +#else + git_atomic64 v = {0}; + cl_assert_equal_i(git_atomic64_add(&v, 1), 1); + cl_assert_equal_i(v.val, 1); +#endif +} + +void test_threads_atomic__cas_pointer(void) +{ + int *value = NULL; + int newvalue1 = 1, newvalue2 = 2; + + /* value is updated */ + cl_assert_equal_p(git_atomic_compare_and_swap(&value, NULL, &newvalue1), NULL); + cl_assert_equal_p(value, &newvalue1); + + /* value is not updated */ + cl_assert_equal_p(git_atomic_compare_and_swap(&value, NULL, &newvalue2), &newvalue1); + cl_assert_equal_p(value, &newvalue1); +} + +void test_threads_atomic__cas_intptr(void) +{ + intptr_t value = 0; + intptr_t oldvalue; + intptr_t newvalue; + + /* value is updated */ + oldvalue = 0; + newvalue = 1; + cl_assert_equal_i((intptr_t)git_atomic_compare_and_swap(&value, (void *)oldvalue, (void *)newvalue), 0); + cl_assert_equal_i(value, 1); + + /* value is not updated */ + oldvalue = 0; + newvalue = 2; + cl_assert_equal_i((intptr_t)git_atomic_compare_and_swap(&value, (void *)oldvalue, (void *)newvalue), 1); + cl_assert_equal_i(value, 1); +} + +void test_threads_atomic__swap(void) +{ + int *value = NULL; + int newvalue = 1; + + cl_assert_equal_p(git_atomic_swap(value, &newvalue), NULL); + cl_assert_equal_p(value, &newvalue); + + cl_assert_equal_p(git_atomic_swap(value, NULL), &newvalue); + cl_assert_equal_p(value, NULL); +} + +void test_threads_atomic__load_ptr(void) +{ + int value = 1; + int *ptr = &value; + cl_assert_equal_p(git_atomic_load(ptr), &value); +} + +void test_threads_atomic__load_intptr(void) +{ + intptr_t value = 1; + cl_assert_equal_i((intptr_t)git_atomic_load(value), 1); +} From 94008e6aae0b4f1b4fcaa2e772da99764072cd7f Mon Sep 17 00:00:00 2001 From: lhchavez Date: Thu, 26 Aug 2021 05:50:23 -0700 Subject: [PATCH 0460/1616] Fixups for the latest changes in the array interface --- src/commit_graph.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/commit_graph.c b/src/commit_graph.c index 1601c630cdb..8323485b6ef 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -832,7 +832,8 @@ static int compute_generation_numbers(git_vector *commits) *(size_t *)git_array_alloc(index_stack) = i; while (git_array_size(index_stack)) { - i = *git_array_pop(index_stack); + size_t *index_ptr = git_array_pop(index_stack); + i = *index_ptr; child_packed_commit = git_vector_get(commits, i); if (commit_states[i] == GENERATION_NUMBER_COMMIT_STATE_VISITED) { @@ -1017,6 +1018,7 @@ commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, v uint64_t commit_time; uint32_t generation; uint32_t word; + size_t *packed_index; unsigned int parentcount = (unsigned int)git_array_size(packed_commit->parents); error = git_buf_put( @@ -1026,20 +1028,24 @@ commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, v if (error < 0) goto cleanup; - if (parentcount == 0) + if (parentcount == 0) { word = htonl(GIT_COMMIT_GRAPH_MISSING_PARENT); - else - word = htonl((uint32_t)*git_array_get(packed_commit->parent_indices, 0)); + } else { + packed_index = git_array_get(packed_commit->parent_indices, 0); + word = htonl((uint32_t)*packed_index); + } error = git_buf_put(&commit_data, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; - if (parentcount < 2) + if (parentcount < 2) { word = htonl(GIT_COMMIT_GRAPH_MISSING_PARENT); - else if (parentcount == 2) - word = htonl((uint32_t)*git_array_get(packed_commit->parent_indices, 1)); - else + } else if (parentcount == 2) { + packed_index = git_array_get(packed_commit->parent_indices, 1); + word = htonl((uint32_t)*packed_index); + } else { word = htonl(0x80000000u | extra_edge_list_count); + } error = git_buf_put(&commit_data, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; @@ -1047,9 +1053,13 @@ commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, v if (parentcount > 2) { unsigned int parent_i; for (parent_i = 1; parent_i < parentcount; ++parent_i) { - word = htonl((uint32_t)( - *git_array_get(packed_commit->parent_indices, parent_i) - | (parent_i + 1 == parentcount ? 0x80000000u : 0))); + packed_index = git_array_get( + packed_commit->parent_indices, parent_i); + word = htonl( + (uint32_t)(*packed_index + | (parent_i + 1 == parentcount + ? 0x80000000u + : 0))); error = git_buf_put( &extra_edge_list, (const char *)&word, From 366115e0e3e426047bb2be008e5962aa6598a0d4 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Fri, 27 Aug 2021 04:06:31 -0700 Subject: [PATCH 0461/1616] Review feedback --- src/midx.c | 32 +++++++++++++++++--------------- src/pack.c | 3 ++- src/pack.h | 9 ++++++--- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/midx.c b/src/midx.c index 040a43fc452..9aab8b58890 100644 --- a/src/midx.c +++ b/src/midx.c @@ -643,12 +643,7 @@ static int midx_write( int error = 0; size_t i; struct git_pack_file *p; - struct git_midx_header hdr = { - .signature = htonl(MIDX_SIGNATURE), - .version = MIDX_VERSION, - .object_id_version = MIDX_OBJECT_ID_VERSION, - .base_midx_files = 0, - }; + struct git_midx_header hdr = {0}; uint32_t oid_fanout_count; uint32_t object_large_offsets_count; uint32_t oid_fanout[256]; @@ -662,11 +657,16 @@ static int midx_write( object_entry_array_t object_entries_array = GIT_ARRAY_INIT; git_vector object_entries = GIT_VECTOR_INIT; git_hash_ctx ctx; - struct midx_write_hash_context hash_cb_data = { - .write_cb = write_cb, - .cb_data = cb_data, - .ctx = &ctx, - }; + struct midx_write_hash_context hash_cb_data = {0}; + + hdr.signature = htonl(MIDX_SIGNATURE); + hdr.version = MIDX_VERSION; + hdr.object_id_version = MIDX_OBJECT_ID_VERSION; + hdr.base_midx_files = 0; + + hash_cb_data.write_cb = write_cb; + hash_cb_data.cb_data = cb_data; + hash_cb_data.ctx = &ctx; error = git_hash_ctx_init(&ctx); if (error < 0) @@ -677,12 +677,12 @@ static int midx_write( git_vector_sort(&w->packs); git_vector_foreach (&w->packs, i, p) { git_buf relative_index = GIT_BUF_INIT; - struct object_entry_cb_state state = { - .pack_index = (uint32_t)i, - .object_entries_array = &object_entries_array, - }; + struct object_entry_cb_state state = {0}; size_t path_len; + state.pack_index = (uint32_t)i; + state.object_entries_array = &object_entries_array; + error = git_buf_sets(&relative_index, p->pack_name); if (error < 0) goto cleanup; @@ -694,6 +694,8 @@ static int midx_write( path_len = git_buf_len(&relative_index); if (path_len <= strlen(".pack") || git__suffixcmp(git_buf_cstr(&relative_index), ".pack") != 0) { git_buf_dispose(&relative_index); + git_error_set(GIT_ERROR_INVALID, "invalid packfile name: '%s'", p->pack_name); + error = -1; goto cleanup; } path_len -= strlen(".pack"); diff --git a/src/pack.c b/src/pack.c index 31a4282b5dd..94b1ecd9d61 100644 --- a/src/pack.c +++ b/src/pack.c @@ -1396,6 +1396,7 @@ int git_pack_foreach_entry_offset( index += 4 * 256; + /* all offsets should have been validated by pack_index_check_locked */ if (p->index_version > 1) { const unsigned char *offsets = index + 24 * p->num_objects; const unsigned char *large_offset_ptr; @@ -1406,7 +1407,7 @@ int git_pack_foreach_entry_offset( if (current_offset & 0x80000000) { large_offset_ptr = large_offsets + (current_offset & 0x7fffffff) * 8; if (large_offset_ptr >= large_offsets_end) { - error = -1; + error = packfile_error("invalid large offset"); goto cleanup; } current_offset = (((off64_t)ntohl(*((uint32_t *)(large_offset_ptr + 0)))) << 32) | diff --git a/src/pack.h b/src/pack.h index 8aea7d8f9c6..bf279c6b6ac 100644 --- a/src/pack.h +++ b/src/pack.h @@ -23,7 +23,7 @@ /** * Function type for callbacks from git_pack_foreach_entry_offset. */ -typedef int GIT_CALLBACK(git_pack_foreach_entry_offset_cb)( +typedef int git_pack_foreach_entry_offset_cb( const git_oid *id, off64_t offset, void *payload); @@ -185,8 +185,11 @@ int git_pack_foreach_entry( git_odb_foreach_cb cb, void *data); /** - * Similar to git_pack_foreach_entry, but it also provides the offset of the - * object within the packfile. It also does not sort the objects in any order. + * Similar to git_pack_foreach_entry, but: + * - It also provides the offset of the object within the + * packfile. + * - It does not sort the objects in any order. + * - It retains the lock while invoking the callback. */ int git_pack_foreach_entry_offset( struct git_pack_file *p, From 9d117e3857b447b47df38081d7f40f4b2226621b Mon Sep 17 00:00:00 2001 From: lhchavez Date: Mon, 17 Feb 2020 21:28:13 +0000 Subject: [PATCH 0462/1616] midx: Add a way to write multi-pack-index files This change adds the git_midx_writer_* functions to allow to write and create `multi-pack-index` files from `.idx`/`.pack` files. Part of: #5399 --- include/git2/sys/midx.h | 74 ++++++++ include/git2/types.h | 3 + src/midx.c | 398 ++++++++++++++++++++++++++++++++++++++++ src/midx.h | 16 ++ src/pack.c | 67 +++++++ src/pack.h | 19 ++ tests/pack/midx.c | 30 +++ 7 files changed, 607 insertions(+) create mode 100644 include/git2/sys/midx.h diff --git a/include/git2/sys/midx.h b/include/git2/sys/midx.h new file mode 100644 index 00000000000..e3d7498298c --- /dev/null +++ b/include/git2/sys/midx.h @@ -0,0 +1,74 @@ +/* + * 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_sys_git_midx_h__ +#define INCLUDE_sys_git_midx_h__ + +#include "git2/common.h" +#include "git2/types.h" + +/** + * @file git2/midx.h + * @brief Git multi-pack-index routines + * @defgroup git_midx Git multi-pack-index routines + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Create a new writer for `multi-pack-index` files. + * + * @param out location to store the writer pointer. + * @param pack_dir the directory where the `.pack` and `.idx` files are. The + * `multi-pack-index` file will be written in this directory, too. + * @return 0 or an error code + */ +GIT_EXTERN(int) git_midx_writer_new( + git_midx_writer **out, + const char *pack_dir); + +/** + * Free the multi-pack-index writer and its resources. + * + * @param w the writer to free. If NULL no action is taken. + */ +GIT_EXTERN(void) git_midx_writer_free(git_midx_writer *w); + +/** + * Add an `.idx` file to the writer. + * + * @param w the writer + * @param idx_path the path of an `.idx` file. + * @return 0 or an error code + */ +GIT_EXTERN(int) git_midx_writer_add( + git_midx_writer *w, + const char *idx_path); + +/** + * Write a `multi-pack-index` file to a file. + * + * @param w the writer + * @return 0 or an error code + */ +GIT_EXTERN(int) git_midx_writer_commit( + git_midx_writer *w); + +/** + * Dump the contents of the `multi-pack-index` to an in-memory buffer. + * + * @param midx Buffer where to store the contents of the `multi-pack-index`. + * @param w the writer + * @return 0 or an error code + */ +GIT_EXTERN(int) git_midx_writer_dump( + git_buf *midx, + git_midx_writer *w); + +/** @} */ +GIT_END_DECL +#endif diff --git a/include/git2/types.h b/include/git2/types.h index 562eb8e5f25..4de0672f9e8 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -96,6 +96,9 @@ typedef struct git_odb_stream git_odb_stream; /** A stream to write a packfile to the ODB */ typedef struct git_odb_writepack git_odb_writepack; +/** a writer for multi-pack-index files. */ +typedef struct git_midx_writer git_midx_writer; + /** An open refs database handle. */ typedef struct git_refdb git_refdb; diff --git a/src/midx.c b/src/midx.c index d6bb9c1e7f1..9aab8b58890 100644 --- a/src/midx.c +++ b/src/midx.c @@ -7,11 +7,15 @@ #include "midx.h" +#include "array.h" #include "buffer.h" +#include "filebuf.h" #include "futils.h" #include "hash.h" #include "odb.h" #include "pack.h" +#include "path.h" +#include "repository.h" #define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */ #define MIDX_VERSION 1 @@ -36,6 +40,8 @@ struct git_midx_chunk { size_t length; }; +typedef int (*midx_write_cb)(const char *buf, size_t size, void *cb_data); + static int midx_error(const char *message) { git_error_set(GIT_ERROR_ODB, "invalid multi-pack-index file - %s", message); @@ -475,3 +481,395 @@ void git_midx_free(git_midx_file *idx) git_midx_close(idx); git__free(idx); } + +static int packfile__cmp(const void *a_, const void *b_) +{ + const struct git_pack_file *a = a_; + const struct git_pack_file *b = b_; + + return strcmp(a->pack_name, b->pack_name); +} + +int git_midx_writer_new( + git_midx_writer **out, + const char *pack_dir) +{ + git_midx_writer *w = git__calloc(1, sizeof(git_midx_writer)); + GIT_ERROR_CHECK_ALLOC(w); + + if (git_buf_sets(&w->pack_dir, pack_dir) < 0) { + git__free(w); + return -1; + } + git_path_squash_slashes(&w->pack_dir); + + if (git_vector_init(&w->packs, 0, packfile__cmp) < 0) { + git_buf_dispose(&w->pack_dir); + git__free(w); + return -1; + } + + *out = w; + return 0; +} + +void git_midx_writer_free(git_midx_writer *w) +{ + struct git_pack_file *p; + size_t i; + + if (!w) + return; + + git_vector_foreach (&w->packs, i, p) + git_mwindow_put_pack(p); + git_vector_free(&w->packs); + git_buf_dispose(&w->pack_dir); + git__free(w); +} + +int git_midx_writer_add( + git_midx_writer *w, + const char *idx_path) +{ + git_buf idx_path_buf = GIT_BUF_INIT; + int error; + struct git_pack_file *p; + + error = git_path_prettify(&idx_path_buf, idx_path, git_buf_cstr(&w->pack_dir)); + if (error < 0) + return error; + + error = git_mwindow_get_pack(&p, git_buf_cstr(&idx_path_buf)); + git_buf_dispose(&idx_path_buf); + if (error < 0) + return error; + + error = git_vector_insert(&w->packs, p); + if (error < 0) { + git_mwindow_put_pack(p); + return error; + } + + return 0; +} + +typedef git_array_t(git_midx_entry) object_entry_array_t; + +struct object_entry_cb_state { + uint32_t pack_index; + object_entry_array_t *object_entries_array; +}; + +static int object_entry__cb(const git_oid *oid, off64_t offset, void *data) +{ + struct object_entry_cb_state *state = (struct object_entry_cb_state *)data; + + git_midx_entry *entry = git_array_alloc(*state->object_entries_array); + GIT_ERROR_CHECK_ALLOC(entry); + + git_oid_cpy(&entry->sha1, oid); + entry->offset = offset; + entry->pack_index = state->pack_index; + + return 0; +} + +static int object_entry__cmp(const void *a_, const void *b_) +{ + const git_midx_entry *a = (const git_midx_entry *)a_; + const git_midx_entry *b = (const git_midx_entry *)b_; + + return git_oid_cmp(&a->sha1, &b->sha1); +} + +static int write_offset(off64_t offset, midx_write_cb write_cb, void *cb_data) +{ + int error; + uint32_t word; + + word = htonl((uint32_t)((offset >> 32) & 0xffffffffu)); + error = write_cb((const char *)&word, sizeof(word), cb_data); + if (error < 0) + return error; + word = htonl((uint32_t)((offset >> 0) & 0xffffffffu)); + error = write_cb((const char *)&word, sizeof(word), cb_data); + if (error < 0) + return error; + + return 0; +} + +static int write_chunk_header(int chunk_id, off64_t offset, midx_write_cb write_cb, void *cb_data) +{ + uint32_t word = htonl(chunk_id); + int error = write_cb((const char *)&word, sizeof(word), cb_data); + if (error < 0) + return error; + return write_offset(offset, write_cb, cb_data); + + return 0; +} + +static int midx_write_buf(const char *buf, size_t size, void *data) +{ + git_buf *b = (git_buf *)data; + return git_buf_put(b, buf, size); +} + +struct midx_write_hash_context { + midx_write_cb write_cb; + void *cb_data; + git_hash_ctx *ctx; +}; + +static int midx_write_hash(const char *buf, size_t size, void *data) +{ + struct midx_write_hash_context *ctx = (struct midx_write_hash_context *)data; + int error; + + error = git_hash_update(ctx->ctx, buf, size); + if (error < 0) + return error; + + return ctx->write_cb(buf, size, ctx->cb_data); +} + +static int midx_write( + git_midx_writer *w, + midx_write_cb write_cb, + void *cb_data) +{ + int error = 0; + size_t i; + struct git_pack_file *p; + struct git_midx_header hdr = {0}; + uint32_t oid_fanout_count; + uint32_t object_large_offsets_count; + uint32_t oid_fanout[256]; + off64_t offset; + git_buf packfile_names = GIT_BUF_INIT, + oid_lookup = GIT_BUF_INIT, + object_offsets = GIT_BUF_INIT, + object_large_offsets = GIT_BUF_INIT; + git_oid idx_checksum = {{0}}; + git_midx_entry *entry; + object_entry_array_t object_entries_array = GIT_ARRAY_INIT; + git_vector object_entries = GIT_VECTOR_INIT; + git_hash_ctx ctx; + struct midx_write_hash_context hash_cb_data = {0}; + + hdr.signature = htonl(MIDX_SIGNATURE); + hdr.version = MIDX_VERSION; + hdr.object_id_version = MIDX_OBJECT_ID_VERSION; + hdr.base_midx_files = 0; + + hash_cb_data.write_cb = write_cb; + hash_cb_data.cb_data = cb_data; + hash_cb_data.ctx = &ctx; + + error = git_hash_ctx_init(&ctx); + if (error < 0) + return error; + cb_data = &hash_cb_data; + write_cb = midx_write_hash; + + git_vector_sort(&w->packs); + git_vector_foreach (&w->packs, i, p) { + git_buf relative_index = GIT_BUF_INIT; + struct object_entry_cb_state state = {0}; + size_t path_len; + + state.pack_index = (uint32_t)i; + state.object_entries_array = &object_entries_array; + + error = git_buf_sets(&relative_index, p->pack_name); + if (error < 0) + goto cleanup; + error = git_path_make_relative(&relative_index, git_buf_cstr(&w->pack_dir)); + if (error < 0) { + git_buf_dispose(&relative_index); + goto cleanup; + } + path_len = git_buf_len(&relative_index); + if (path_len <= strlen(".pack") || git__suffixcmp(git_buf_cstr(&relative_index), ".pack") != 0) { + git_buf_dispose(&relative_index); + git_error_set(GIT_ERROR_INVALID, "invalid packfile name: '%s'", p->pack_name); + error = -1; + goto cleanup; + } + path_len -= strlen(".pack"); + + git_buf_put(&packfile_names, git_buf_cstr(&relative_index), path_len); + git_buf_puts(&packfile_names, ".idx"); + git_buf_putc(&packfile_names, '\0'); + git_buf_dispose(&relative_index); + + error = git_pack_foreach_entry_offset(p, object_entry__cb, &state); + if (error < 0) + goto cleanup; + } + + /* Sort the object entries. */ + error = git_vector_init(&object_entries, git_array_size(object_entries_array), object_entry__cmp); + if (error < 0) + goto cleanup; + git_array_foreach (object_entries_array, i, entry) + error = git_vector_set(NULL, &object_entries, i, entry); + git_vector_set_sorted(&object_entries, 0); + git_vector_sort(&object_entries); + git_vector_uniq(&object_entries, NULL); + + /* Pad the packfile names so it is a multiple of four. */ + while (git_buf_len(&packfile_names) & 3) + git_buf_putc(&packfile_names, '\0'); + + /* Fill the OID Fanout table. */ + oid_fanout_count = 0; + for (i = 0; i < 256; i++) { + while (oid_fanout_count < git_vector_length(&object_entries) && + ((const git_midx_entry *)git_vector_get(&object_entries, oid_fanout_count))->sha1.id[0] <= i) + ++oid_fanout_count; + oid_fanout[i] = htonl(oid_fanout_count); + } + + /* Fill the OID Lookup table. */ + git_vector_foreach (&object_entries, i, entry) { + error = git_buf_put(&oid_lookup, (const char *)&entry->sha1, sizeof(entry->sha1)); + if (error < 0) + goto cleanup; + } + + /* Fill the Object Offsets and Object Large Offsets tables. */ + object_large_offsets_count = 0; + git_vector_foreach (&object_entries, i, entry) { + uint32_t word; + + word = htonl((uint32_t)entry->pack_index); + error = git_buf_put(&object_offsets, (const char *)&word, sizeof(word)); + if (error < 0) + goto cleanup; + if (entry->offset >= 0x80000000l) { + word = htonl(0x80000000u | object_large_offsets_count++); + error = write_offset(entry->offset, midx_write_buf, &object_large_offsets); + } else { + word = htonl((uint32_t)entry->offset & 0x7fffffffu); + } + error = git_buf_put(&object_offsets, (const char *)&word, sizeof(word)); + if (error < 0) + goto cleanup; + } + + /* Write the header. */ + hdr.packfiles = htonl((uint32_t)git_vector_length(&w->packs)); + hdr.chunks = 4; + if (git_buf_len(&object_large_offsets) > 0) + hdr.chunks++; + error = write_cb((const char *)&hdr, sizeof(hdr), cb_data); + if (error < 0) + goto cleanup; + + /* Write the chunk headers. */ + offset = sizeof(hdr) + (hdr.chunks + 1) * 12; + error = write_chunk_header(MIDX_PACKFILE_NAMES_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += git_buf_len(&packfile_names); + error = write_chunk_header(MIDX_OID_FANOUT_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += sizeof(oid_fanout); + error = write_chunk_header(MIDX_OID_LOOKUP_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += git_buf_len(&oid_lookup); + error = write_chunk_header(MIDX_OBJECT_OFFSETS_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += git_buf_len(&object_offsets); + if (git_buf_len(&object_large_offsets) > 0) { + error = write_chunk_header(MIDX_OBJECT_LARGE_OFFSETS_ID, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + offset += git_buf_len(&object_large_offsets); + } + error = write_chunk_header(0, offset, write_cb, cb_data); + if (error < 0) + goto cleanup; + + /* Write all the chunks. */ + error = write_cb(git_buf_cstr(&packfile_names), git_buf_len(&packfile_names), cb_data); + if (error < 0) + goto cleanup; + error = write_cb((const char *)oid_fanout, sizeof(oid_fanout), cb_data); + if (error < 0) + goto cleanup; + error = write_cb(git_buf_cstr(&oid_lookup), git_buf_len(&oid_lookup), cb_data); + if (error < 0) + goto cleanup; + error = write_cb(git_buf_cstr(&object_offsets), git_buf_len(&object_offsets), cb_data); + if (error < 0) + goto cleanup; + error = write_cb(git_buf_cstr(&object_large_offsets), git_buf_len(&object_large_offsets), cb_data); + if (error < 0) + goto cleanup; + + /* Finalize the checksum and write the trailer. */ + error = git_hash_final(&idx_checksum, &ctx); + if (error < 0) + goto cleanup; + error = write_cb((const char *)&idx_checksum, sizeof(idx_checksum), cb_data); + if (error < 0) + goto cleanup; + +cleanup: + git_array_clear(object_entries_array); + git_vector_free(&object_entries); + git_buf_dispose(&packfile_names); + git_buf_dispose(&oid_lookup); + git_buf_dispose(&object_offsets); + git_buf_dispose(&object_large_offsets); + git_hash_ctx_cleanup(&ctx); + return error; +} + +static int midx_write_filebuf(const char *buf, size_t size, void *data) +{ + git_filebuf *f = (git_filebuf *)data; + return git_filebuf_write(f, buf, size); +} + +int git_midx_writer_commit( + git_midx_writer *w) +{ + int error; + int filebuf_flags = GIT_FILEBUF_DO_NOT_BUFFER; + git_buf midx_path = GIT_BUF_INIT; + git_filebuf output = GIT_FILEBUF_INIT; + + error = git_buf_joinpath(&midx_path, git_buf_cstr(&w->pack_dir), "multi-pack-index"); + if (error < 0) + return error; + + if (git_repository__fsync_gitdir) + filebuf_flags |= GIT_FILEBUF_FSYNC; + error = git_filebuf_open(&output, git_buf_cstr(&midx_path), filebuf_flags, 0644); + git_buf_dispose(&midx_path); + if (error < 0) + return error; + + error = midx_write(w, midx_write_filebuf, &output); + if (error < 0) { + git_filebuf_cleanup(&output); + return error; + } + + return git_filebuf_commit(&output); +} + +int git_midx_writer_dump( + git_buf *midx, + git_midx_writer *w) +{ + return midx_write(w, midx_write_buf, midx); +} diff --git a/src/midx.h b/src/midx.h index 543ff2178df..4ce17ce73a8 100644 --- a/src/midx.h +++ b/src/midx.h @@ -12,6 +12,8 @@ #include +#include "git2/sys/midx.h" + #include "map.h" #include "mwindow.h" #include "odb.h" @@ -67,6 +69,20 @@ typedef struct git_midx_entry { git_oid sha1; } git_midx_entry; +/* + * A writer for `multi-pack-index` files. + */ +struct git_midx_writer { + /* + * The path of the directory where the .pack/.idx files are stored. The + * `multi-pack-index` file will be written to the same directory. + */ + git_buf pack_dir; + + /* The list of `git_pack_file`s. */ + git_vector packs; +}; + int git_midx_open( git_midx_file **idx_out, const char *path); diff --git a/src/pack.c b/src/pack.c index 5d284ca9e12..94b1ecd9d61 100644 --- a/src/pack.c +++ b/src/pack.c @@ -1368,6 +1368,73 @@ int git_pack_foreach_entry( return error; } +int git_pack_foreach_entry_offset( + struct git_pack_file *p, + git_pack_foreach_entry_offset_cb cb, + void *data) +{ + const unsigned char *index; + off64_t current_offset; + const git_oid *current_oid; + uint32_t i; + int error = 0; + + if (git_mutex_lock(&p->lock) < 0) + return packfile_error("failed to get lock for git_pack_foreach_entry_offset"); + + index = p->index_map.data; + if (index == NULL) { + if ((error = pack_index_open_locked(p)) < 0) + goto cleanup; + + GIT_ASSERT(p->index_map.data); + index = p->index_map.data; + } + + if (p->index_version > 1) + index += 8; + + index += 4 * 256; + + /* all offsets should have been validated by pack_index_check_locked */ + if (p->index_version > 1) { + const unsigned char *offsets = index + 24 * p->num_objects; + const unsigned char *large_offset_ptr; + const unsigned char *large_offsets = index + 28 * p->num_objects; + const unsigned char *large_offsets_end = ((const unsigned char *)p->index_map.data) + p->index_map.len - 20; + for (i = 0; i < p->num_objects; i++) { + current_offset = ntohl(*(const uint32_t *)(offsets + 4 * i)); + if (current_offset & 0x80000000) { + large_offset_ptr = large_offsets + (current_offset & 0x7fffffff) * 8; + if (large_offset_ptr >= large_offsets_end) { + error = packfile_error("invalid large offset"); + goto cleanup; + } + current_offset = (((off64_t)ntohl(*((uint32_t *)(large_offset_ptr + 0)))) << 32) | + ntohl(*((uint32_t *)(large_offset_ptr + 4))); + } + current_oid = (const git_oid *)(index + 20 * i); + if ((error = cb(current_oid, current_offset, data)) != 0) { + error = git_error_set_after_callback(error); + goto cleanup; + } + } + } else { + for (i = 0; i < p->num_objects; i++) { + current_offset = ntohl(*(const uint32_t *)(index + 24 * i)); + current_oid = (const git_oid *)(index + 24 * i + 4); + if ((error = cb(current_oid, current_offset, data)) != 0) { + error = git_error_set_after_callback(error); + goto cleanup; + } + } + } + +cleanup: + git_mutex_unlock(&p->lock); + return error; +} + int git_pack__lookup_sha1(const void *oid_lookup_table, size_t stride, unsigned lo, unsigned hi, const unsigned char *oid_prefix) { diff --git a/src/pack.h b/src/pack.h index 1d077240d01..bf279c6b6ac 100644 --- a/src/pack.h +++ b/src/pack.h @@ -20,6 +20,14 @@ #include "oidmap.h" #include "zstream.h" +/** + * Function type for callbacks from git_pack_foreach_entry_offset. + */ +typedef int git_pack_foreach_entry_offset_cb( + const git_oid *id, + off64_t offset, + void *payload); + #define GIT_PACK_FILE_MODE 0444 #define PACK_SIGNATURE 0x5041434b /* "PACK" */ @@ -176,5 +184,16 @@ int git_pack_foreach_entry( struct git_pack_file *p, git_odb_foreach_cb cb, void *data); +/** + * Similar to git_pack_foreach_entry, but: + * - It also provides the offset of the object within the + * packfile. + * - It does not sort the objects in any order. + * - It retains the lock while invoking the callback. + */ +int git_pack_foreach_entry_offset( + struct git_pack_file *p, + git_pack_foreach_entry_offset_cb cb, + void *data); #endif diff --git a/tests/pack/midx.c b/tests/pack/midx.c index 0d7efbef10b..6e6c1a6d502 100644 --- a/tests/pack/midx.c +++ b/tests/pack/midx.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include +#include #include "midx.h" @@ -44,3 +45,32 @@ void test_pack_midx__lookup(void) git_commit_free(commit); git_repository_free(repo); } + +void test_pack_midx__writer(void) +{ + git_repository *repo; + git_midx_writer *w = NULL; + git_buf midx = GIT_BUF_INIT, expected_midx = GIT_BUF_INIT, path = GIT_BUF_INIT; + + cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); + + cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/pack")); + cl_git_pass(git_midx_writer_new(&w, git_buf_cstr(&path))); + + cl_git_pass(git_midx_writer_add(w, "pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx")); + cl_git_pass(git_midx_writer_add(w, "pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx")); + cl_git_pass(git_midx_writer_add(w, "pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx")); + + cl_git_pass(git_midx_writer_dump(&midx, w)); + cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/pack/multi-pack-index")); + cl_git_pass(git_futils_readbuffer(&expected_midx, git_buf_cstr(&path))); + + cl_assert_equal_i(git_buf_len(&midx), git_buf_len(&expected_midx)); + cl_assert_equal_strn(git_buf_cstr(&midx), git_buf_cstr(&expected_midx), git_buf_len(&midx)); + + git_buf_dispose(&midx); + git_buf_dispose(&expected_midx); + git_buf_dispose(&path); + git_midx_writer_free(w); + git_repository_free(repo); +} From ea285904dcb1350d99703df86a5f38662935cbbc Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 18 Feb 2020 00:02:13 +0000 Subject: [PATCH 0463/1616] midx: Introduce git_odb_write_multi_pack_index() This change introduces git_odb_write_multi_pack_index(), which creates a `multi-pack-index` file from all the `.pack` files that have been loaded in the ODB. Fixes: #5399 --- include/git2/odb.h | 14 ++++++ include/git2/sys/odb_backend.h | 7 +++ src/odb.c | 29 ++++++++++++ src/odb_pack.c | 84 ++++++++++++++++++++++++++++++++-- tests/pack/midx.c | 34 ++++++++++++++ 5 files changed, 163 insertions(+), 5 deletions(-) diff --git a/include/git2/odb.h b/include/git2/odb.h index 702e1bd30d2..dd484553ff2 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -390,6 +390,20 @@ GIT_EXTERN(int) git_odb_write_pack( git_indexer_progress_cb progress_cb, void *progress_payload); +/** + * Write a `multi-pack-index` file from all the `.pack` files in the ODB. + * + * If the ODB layer understands pack files, then this will create a file called + * `multi-pack-index` next to the `.pack` and `.idx` files, which will contain + * an index of all objects stored in `.pack` files. This will allow for + * O(log n) lookup for n objects (regardless of how many packfiles there + * exist). + * + * @param db object database where the `multi-pack-index` file will be written. + */ +GIT_EXTERN(int) git_odb_write_multi_pack_index( + git_odb *db); + /** * Determine the object-ID (sha1 hash) of a data buffer * diff --git a/include/git2/sys/odb_backend.h b/include/git2/sys/odb_backend.h index 4dba460af39..9ae0ed9b3ed 100644 --- a/include/git2/sys/odb_backend.h +++ b/include/git2/sys/odb_backend.h @@ -84,6 +84,13 @@ struct git_odb_backend { git_odb_writepack **, git_odb_backend *, git_odb *odb, git_indexer_progress_cb progress_cb, void *progress_payload); + /** + * If the backend supports pack files, this will create a + * `multi-pack-index` file which will contain an index of all objects + * across all the `.pack` files. + */ + int GIT_CALLBACK(writemidx)(git_odb_backend *); + /** * "Freshens" an already existing object, updating its last-used * time. This occurs when `git_odb_write` was called, but the diff --git a/src/odb.c b/src/odb.c index e3a5381e640..7834e5f15cf 100644 --- a/src/odb.c +++ b/src/odb.c @@ -1703,6 +1703,35 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_ return error; } +int git_odb_write_multi_pack_index(git_odb *db) +{ + size_t i, writes = 0; + int error = GIT_ERROR; + + GIT_ASSERT_ARG(db); + + for (i = 0; i < db->backends.length && error < 0; ++i) { + backend_internal *internal = git_vector_get(&db->backends, i); + git_odb_backend *b = internal->backend; + + /* we don't write in alternates! */ + if (internal->is_alternate) + continue; + + if (b->writemidx != NULL) { + ++writes; + error = b->writemidx(b); + } + } + + if (error == GIT_PASSTHROUGH) + error = 0; + if (error < 0 && !writes) + error = git_odb__error_unsupported_in_backend("write multi-pack-index"); + + return error; +} + void *git_odb_backend_data_alloc(git_odb_backend *backend, size_t len) { GIT_UNUSED(backend); diff --git a/src/odb_pack.c b/src/odb_pack.c index 3df8a426743..f4cb9a558b7 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -402,7 +402,6 @@ static int process_multi_pack_index_pack( const char *packfile_name) { int error; - size_t cmp_len = strlen(packfile_name); struct git_pack_file *pack; size_t found_position; git_buf pack_path = GIT_BUF_INIT, index_prefix = GIT_BUF_INIT; @@ -411,12 +410,11 @@ static int process_multi_pack_index_pack( if (error < 0) return error; - /* This is ensured by midx__parse_packfile_name() */ - if (cmp_len <= strlen(".idx") || git__suffixcmp(git_buf_cstr(&pack_path), ".idx") != 0) + /* This is ensured by midx_parse_packfile_name() */ + if (git_buf_len(&pack_path) <= strlen(".idx") || git__suffixcmp(git_buf_cstr(&pack_path), ".idx") != 0) return git_odb__error_notfound("midx file contained a non-index", NULL, 0); - cmp_len -= strlen(".idx"); - git_buf_attach_notowned(&index_prefix, git_buf_cstr(&pack_path), cmp_len); + git_buf_attach_notowned(&index_prefix, git_buf_cstr(&pack_path), git_buf_len(&pack_path) - strlen(".idx")); if (git_vector_search2(&found_position, &backend->packs, packfile_byname_search_cmp, &index_prefix) == 0) { /* Pack was found in the packs list. Moving it to the midx_packs list. */ @@ -744,6 +742,81 @@ static int pack_backend__writepack(struct git_odb_writepack **out, return 0; } +static int get_idx_path( + git_buf *idx_path, + struct pack_backend *backend, + struct git_pack_file *p) +{ + size_t path_len; + int error; + + error = git_path_prettify(idx_path, p->pack_name, backend->pack_folder); + if (error < 0) + return error; + path_len = git_buf_len(idx_path); + if (path_len <= strlen(".pack") || git__suffixcmp(git_buf_cstr(idx_path), ".pack") != 0) + return git_odb__error_notfound("packfile does not end in .pack", NULL, 0); + path_len -= strlen(".pack"); + error = git_buf_splice(idx_path, path_len, strlen(".pack"), ".idx", strlen(".idx")); + if (error < 0) + return error; + + return 0; +} + +static int pack_backend__writemidx(git_odb_backend *_backend) +{ + struct pack_backend *backend; + git_midx_writer *w = NULL; + struct git_pack_file *p; + size_t i; + int error = 0; + + GIT_ASSERT_ARG(_backend); + + backend = (struct pack_backend *)_backend; + + error = git_midx_writer_new(&w, backend->pack_folder); + if (error < 0) + return error; + + git_vector_foreach(&backend->midx_packs, i, p) { + git_buf idx_path = GIT_BUF_INIT; + error = get_idx_path(&idx_path, backend, p); + if (error < 0) + goto cleanup; + error = git_midx_writer_add(w, git_buf_cstr(&idx_path)); + git_buf_dispose(&idx_path); + if (error < 0) + goto cleanup; + } + git_vector_foreach(&backend->packs, i, p) { + git_buf idx_path = GIT_BUF_INIT; + error = get_idx_path(&idx_path, backend, p); + if (error < 0) + goto cleanup; + error = git_midx_writer_add(w, git_buf_cstr(&idx_path)); + git_buf_dispose(&idx_path); + if (error < 0) + goto cleanup; + } + + /* + * Invalidate the previous midx before writing the new one. + */ + error = remove_multi_pack_index(backend); + if (error < 0) + goto cleanup; + error = git_midx_writer_commit(w); + if (error < 0) + goto cleanup; + error = refresh_multi_pack_index(backend); + +cleanup: + git_midx_writer_free(w); + return error; +} + static void pack_backend__free(git_odb_backend *_backend) { struct pack_backend *backend; @@ -792,6 +865,7 @@ static int pack_backend__alloc(struct pack_backend **out, size_t initial_size) backend->parent.refresh = &pack_backend__refresh; backend->parent.foreach = &pack_backend__foreach; backend->parent.writepack = &pack_backend__writepack; + backend->parent.writemidx = &pack_backend__writemidx; backend->parent.freshen = &pack_backend__freshen; backend->parent.free = &pack_backend__free; diff --git a/tests/pack/midx.c b/tests/pack/midx.c index 6e6c1a6d502..9e7bdb04030 100644 --- a/tests/pack/midx.c +++ b/tests/pack/midx.c @@ -3,6 +3,7 @@ #include #include +#include "futils.h" #include "midx.h" void test_pack_midx__parse(void) @@ -74,3 +75,36 @@ void test_pack_midx__writer(void) git_midx_writer_free(w); git_repository_free(repo); } + +void test_pack_midx__odb_create(void) +{ + git_repository *repo; + git_odb *odb; + git_clone_options opts = GIT_CLONE_OPTIONS_INIT; + git_buf midx = GIT_BUF_INIT, expected_midx = GIT_BUF_INIT, midx_path = GIT_BUF_INIT; + struct stat st; + + opts.bare = true; + opts.local = GIT_CLONE_LOCAL; + cl_git_pass(git_clone(&repo, cl_fixture("testrepo/.gitted"), "./clone.git", &opts)); + cl_git_pass(git_buf_joinpath(&midx_path, git_repository_path(repo), "objects/pack/multi-pack-index")); + cl_git_fail(p_stat(git_buf_cstr(&midx_path), &st)); + + cl_git_pass(git_repository_odb(&odb, repo)); + cl_git_pass(git_odb_write_multi_pack_index(odb)); + git_odb_free(odb); + + cl_git_pass(p_stat(git_buf_cstr(&midx_path), &st)); + + cl_git_pass(git_futils_readbuffer(&expected_midx, cl_fixture("testrepo.git/objects/pack/multi-pack-index"))); + cl_git_pass(git_futils_readbuffer(&midx, git_buf_cstr(&midx_path))); + cl_assert_equal_i(git_buf_len(&midx), git_buf_len(&expected_midx)); + cl_assert_equal_strn(git_buf_cstr(&midx), git_buf_cstr(&expected_midx), git_buf_len(&midx)); + + git_repository_free(repo); + git_buf_dispose(&midx); + git_buf_dispose(&midx_path); + git_buf_dispose(&expected_midx); + + cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES)); +} From 672406773e677e69dba0ccf1c6a116cb2886b60a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 14 May 2021 00:33:08 +0100 Subject: [PATCH 0464/1616] remote: introduce set_instance_url Users may want to override the URL on a particular instance of a remote, instead of updating the configuration. Previously, users could use a callback to do this, but this is not particularly idiomatic. --- include/git2/remote.h | 28 ++++++++++++++++++--- src/remote.c | 32 ++++++++++++++++++++++++ tests/network/remote/remotes.c | 45 ++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/include/git2/remote.h b/include/git2/remote.h index 5d7a5367d8c..5b67717eb6f 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -212,7 +212,8 @@ GIT_EXTERN(const char *) git_remote_name(const git_remote *remote); * Get the remote's url * * If url.*.insteadOf has been configured for this URL, it will - * return the modified URL. + * return the modified URL. If `git_remote_set_instance_pushurl` + * has been called for this remote, then that URL will be returned. * * @param remote the remote * @return a pointer to the url @@ -220,10 +221,11 @@ GIT_EXTERN(const char *) git_remote_name(const git_remote *remote); GIT_EXTERN(const char *) git_remote_url(const git_remote *remote); /** - * Get the remote's url for pushing + * Get the remote's url for pushing. * * If url.*.pushInsteadOf has been configured for this URL, it - * will return the modified URL. + * will return the modified URL. If `git_remote_set_instance_pushurl` + * has been called for this remote, then that URL will be returned. * * @param remote the remote * @return a pointer to the url or NULL if no special url for pushing is set @@ -257,6 +259,26 @@ GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, con */ GIT_EXTERN(int) git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url); +/** + * Set the url for this particular url instance. The URL in the + * configuration will be ignored, and will not be changed. + * + * @param remote the remote's name + * @param url the url to set + * @return 0 or an error value + */ +GIT_EXTERN(int) git_remote_set_instance_url(git_remote *remote, const char *url); + +/** + * Set the push url for this particular url instance. The URL in the + * configuration will be ignored, and will not be changed. + * + * @param remote the remote's name + * @param url the url to set + * @return 0 or an error value + */ +GIT_EXTERN(int) git_remote_set_instance_pushurl(git_remote *remote, const char *url); + /** * Add a fetch refspec to the remote's configuration * diff --git a/src/remote.c b/src/remote.c index ec68cc0f651..236f39abab6 100644 --- a/src/remote.c +++ b/src/remote.c @@ -600,6 +600,22 @@ const char *git_remote_url(const git_remote *remote) return remote->url; } +int git_remote_set_instance_url(git_remote *remote, const char *url) +{ + char *tmp; + + GIT_ASSERT_ARG(remote); + GIT_ASSERT_ARG(url); + + if ((tmp = git__strdup(url)) == NULL) + return -1; + + git__free(remote->url); + remote->url = tmp; + + return 0; +} + static int set_url(git_repository *repo, const char *remote, const char *pattern, const char *url) { git_config *cfg; @@ -645,6 +661,22 @@ const char *git_remote_pushurl(const git_remote *remote) return remote->pushurl; } +int git_remote_set_instance_pushurl(git_remote *remote, const char *url) +{ + char *tmp; + + GIT_ASSERT_ARG(remote); + GIT_ASSERT_ARG(url); + + if ((tmp = git__strdup(url)) == NULL) + return -1; + + git__free(remote->pushurl); + remote->pushurl = tmp; + + return 0; +} + int git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url) { return set_url(repo, remote, CONFIG_PUSHURL_FMT, url); diff --git a/tests/network/remote/remotes.c b/tests/network/remote/remotes.c index 0694a6f66d1..a962d92932b 100644 --- a/tests/network/remote/remotes.c +++ b/tests/network/remote/remotes.c @@ -121,6 +121,51 @@ void test_network_remote_remotes__urlresolve_passthrough(void) git_buf_dispose(&url); } +void test_network_remote_remotes__instance_url(void) +{ + git_buf url = GIT_BUF_INIT; + const char *orig_url = "git://github.com/libgit2/libgit2"; + + cl_assert_equal_s(git_remote_name(_remote), "test"); + cl_assert_equal_s(git_remote_url(_remote), orig_url); + + cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, NULL)); + cl_assert_equal_s(url.ptr, orig_url); + git_buf_clear(&url); + + cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, NULL)); + cl_assert_equal_s(url.ptr, orig_url); + git_buf_clear(&url); + + /* Setting the instance url updates the fetch and push URLs */ + git_remote_set_instance_url(_remote, "https://github.com/new/remote/url"); + cl_assert_equal_s(git_remote_url(_remote), "https://github.com/new/remote/url"); + cl_assert_equal_p(git_remote_pushurl(_remote), NULL); + + cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, NULL)); + cl_assert_equal_s(url.ptr, "https://github.com/new/remote/url"); + git_buf_clear(&url); + + cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, NULL)); + cl_assert_equal_s(url.ptr, "https://github.com/new/remote/url"); + git_buf_clear(&url); + + /* Setting the instance push url updates only the push URL */ + git_remote_set_instance_pushurl(_remote, "https://github.com/new/push/url"); + cl_assert_equal_s(git_remote_url(_remote), "https://github.com/new/remote/url"); + cl_assert_equal_s(git_remote_pushurl(_remote), "https://github.com/new/push/url"); + + cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, NULL)); + cl_assert_equal_s(url.ptr, "https://github.com/new/remote/url"); + git_buf_clear(&url); + + cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, NULL)); + cl_assert_equal_s(url.ptr, "https://github.com/new/push/url"); + git_buf_clear(&url); + + git_buf_dispose(&url); +} + void test_network_remote_remotes__pushurl(void) { const char *name = git_remote_name(_remote); From a9a7bfb506ee4db156abf1ba55cda9de86c18fdb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 12 May 2021 22:13:12 +0100 Subject: [PATCH 0465/1616] filter: add docs for `git_filter_stream_fn` --- include/git2/sys/filter.h | 69 +++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/include/git2/sys/filter.h b/include/git2/sys/filter.h index e43fde55c2f..098f8f7d3df 100644 --- a/include/git2/sys/filter.h +++ b/include/git2/sys/filter.h @@ -167,16 +167,16 @@ typedef void GIT_CALLBACK(git_filter_shutdown_fn)(git_filter *self); * * The `payload` will be a pointer to a reference payload for the filter. * This will start as NULL, but `check` can assign to this pointer for - * later use by the `apply` callback. Note that the value should be heap - * allocated (not stack), so that it doesn't go away before the `apply` + * later use by the `stream` callback. Note that the value should be heap + * allocated (not stack), so that it doesn't go away before the `stream` * callback can use it. If a filter allocates and assigns a value to the * `payload`, it will need a `cleanup` callback to free the payload. */ typedef int GIT_CALLBACK(git_filter_check_fn)( - git_filter *self, - void **payload, /* points to NULL ptr on entry, may be set */ + git_filter *self, + void **payload, /* NULL on entry, may be set */ const git_filter_source *src, - const char **attr_values); + const char **attr_values); /** * Callback to actually perform the data filtering @@ -191,30 +191,40 @@ typedef int GIT_CALLBACK(git_filter_check_fn)( * `check` callback. It may be read from or written to as needed. */ typedef int GIT_CALLBACK(git_filter_apply_fn)( - git_filter *self, - void **payload, /* may be read and/or set */ - git_buf *to, - const git_buf *from, + git_filter *self, + void **payload, /* may be read and/or set */ + git_buf *to, + const git_buf *from, const git_filter_source *src); +/** + * Callback to perform the data filtering. + * + * Specified as `filter.stream`, this is a callback that filters data + * in a streaming manner. This function will provide a + * `git_writestream` that will the original data will be written to; + * with that data, the `git_writestream` will then perform the filter + * translation and stream the filtered data out to the `next` location. + */ typedef int GIT_CALLBACK(git_filter_stream_fn)( - git_writestream **out, - git_filter *self, - void **payload, + git_writestream **out, + git_filter *self, + void **payload, const git_filter_source *src, - git_writestream *next); + git_writestream *next); /** * Callback to clean up after filtering has been applied * * Specified as `filter.cleanup`, this is an optional callback invoked - * after the filter has been applied. If the `check` or `apply` callbacks - * allocated a `payload` to keep per-source filter state, use this - * callback to free that payload and release resources as required. + * after the filter has been applied. If the `check`, `apply`, or + * `stream` callbacks allocated a `payload` to keep per-source filter + * state, use this callback to free that payload and release resources + * as required. */ typedef void GIT_CALLBACK(git_filter_cleanup_fn)( - git_filter *self, - void *payload); + git_filter *self, + void *payload); /** * Filter structure used to register custom filters. @@ -248,21 +258,24 @@ struct git_filter { /** * Called to determine whether the filter should be invoked for a * given file. If this function returns `GIT_PASSTHROUGH` then the - * `apply` function will not be invoked and the contents will be passed - * through unmodified. + * `stream` or `apply` functions will not be invoked and the + * contents will be passed through unmodified. */ git_filter_check_fn check; /** - * Called to actually apply the filter to file contents. If this - * function returns `GIT_PASSTHROUGH` then the contents will be passed - * through unmodified. + * Provided for backward compatibility; this will apply the + * filter to the given contents in a `git_buf`. Callers should + * provide a `stream` function instead. */ git_filter_apply_fn apply; /** - * Called to apply the filter in a streaming manner. If this is not - * specified then the system will call `apply` with the whole buffer. + * Called to apply the filter, this function will provide a + * `git_writestream` that will the original data will be + * written to; with that data, the `git_writestream` will then + * perform the filter translation and stream the filtered data + * out to the `next` location. */ git_filter_stream_fn stream; @@ -289,9 +302,9 @@ GIT_EXTERN(int) git_filter_init(git_filter *filter, unsigned int version); * As mentioned elsewhere, the initialize callback will not be invoked * immediately. It is deferred until the filter is used in some way. * - * A filter's attribute checks and `check` and `apply` callbacks will be - * issued in order of `priority` on smudge (to workdir), and in reverse - * order of `priority` on clean (to odb). + * A filter's attribute checks and `check` and `stream` (or `apply`) + * callbacks will be issued in order of `priority` on smudge (to + * workdir), and in reverse order of `priority` on clean (to odb). * * Two filters are preregistered with libgit2: * - GIT_FILTER_CRLF with priority 0 From a8943c04dcb8079595c075daf1b7ba76d4bb455e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 27 Aug 2021 15:59:01 -0400 Subject: [PATCH 0466/1616] filter: proxy_stream is now git_filter_buffered_stream The filter's proxy_stream is used to adapt filters that only provided an `apply` function into a `stream` function. Make this internal to the library instead of private to the filter file. This will allow the filters to use it directly, instead of relying on the filter functionality to do the proxying. --- src/filter.c | 89 +++++++++++++++++++++++++++------------------------- src/filter.h | 10 ++++++ 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/src/filter.c b/src/filter.c index eed175e8841..21ae2716728 100644 --- a/src/filter.c +++ b/src/filter.c @@ -839,9 +839,10 @@ int git_filter_list_apply_to_blob( return error; } -struct proxy_stream { +struct buffered_stream { git_writestream parent; git_filter *filter; + int (*write_fn)(git_filter *, void **, git_buf *, const git_buf *, const git_filter_source *); const git_filter_source *source; void **payload; git_buf input; @@ -850,89 +851,91 @@ struct proxy_stream { git_writestream *target; }; -static int proxy_stream_write( +static int buffered_stream_write( git_writestream *s, const char *buffer, size_t len) { - struct proxy_stream *proxy_stream = (struct proxy_stream *)s; - GIT_ASSERT_ARG(proxy_stream); + struct buffered_stream *buffered_stream = (struct buffered_stream *)s; + GIT_ASSERT_ARG(buffered_stream); - return git_buf_put(&proxy_stream->input, buffer, len); + return git_buf_put(&buffered_stream->input, buffer, len); } -static int proxy_stream_close(git_writestream *s) +static int buffered_stream_close(git_writestream *s) { - struct proxy_stream *proxy_stream = (struct proxy_stream *)s; + struct buffered_stream *buffered_stream = (struct buffered_stream *)s; git_buf *writebuf; git_error_state error_state = {0}; int error; - GIT_ASSERT_ARG(proxy_stream); + GIT_ASSERT_ARG(buffered_stream); - error = proxy_stream->filter->apply( - proxy_stream->filter, - proxy_stream->payload, - proxy_stream->output, - &proxy_stream->input, - proxy_stream->source); + error = buffered_stream->write_fn( + buffered_stream->filter, + buffered_stream->payload, + buffered_stream->output, + &buffered_stream->input, + buffered_stream->source); if (error == GIT_PASSTHROUGH) { - writebuf = &proxy_stream->input; + writebuf = &buffered_stream->input; } else if (error == 0) { - if ((error = git_buf_sanitize(proxy_stream->output)) < 0) + if ((error = git_buf_sanitize(buffered_stream->output)) < 0) return error; - writebuf = proxy_stream->output; + writebuf = buffered_stream->output; } else { /* close stream before erroring out taking care * to preserve the original error */ git_error_state_capture(&error_state, error); - proxy_stream->target->close(proxy_stream->target); + buffered_stream->target->close(buffered_stream->target); git_error_state_restore(&error_state); return error; } - if ((error = proxy_stream->target->write( - proxy_stream->target, writebuf->ptr, writebuf->size)) == 0) - error = proxy_stream->target->close(proxy_stream->target); + if ((error = buffered_stream->target->write( + buffered_stream->target, writebuf->ptr, writebuf->size)) == 0) + error = buffered_stream->target->close(buffered_stream->target); return error; } -static void proxy_stream_free(git_writestream *s) +static void buffered_stream_free(git_writestream *s) { - struct proxy_stream *proxy_stream = (struct proxy_stream *)s; + struct buffered_stream *buffered_stream = (struct buffered_stream *)s; - if (proxy_stream) { - git_buf_dispose(&proxy_stream->input); - git_buf_dispose(&proxy_stream->temp_buf); - git__free(proxy_stream); + if (buffered_stream) { + git_buf_dispose(&buffered_stream->input); + git_buf_dispose(&buffered_stream->temp_buf); + git__free(buffered_stream); } } -static int proxy_stream_init( +int git_filter_buffered_stream_new( git_writestream **out, git_filter *filter, + int (*write_fn)(git_filter *, void **, git_buf *, const git_buf *, const git_filter_source *), git_buf *temp_buf, void **payload, const git_filter_source *source, git_writestream *target) { - struct proxy_stream *proxy_stream = git__calloc(1, sizeof(struct proxy_stream)); - GIT_ERROR_CHECK_ALLOC(proxy_stream); - - proxy_stream->parent.write = proxy_stream_write; - proxy_stream->parent.close = proxy_stream_close; - proxy_stream->parent.free = proxy_stream_free; - proxy_stream->filter = filter; - proxy_stream->payload = payload; - proxy_stream->source = source; - proxy_stream->target = target; - proxy_stream->output = temp_buf ? temp_buf : &proxy_stream->temp_buf; + struct buffered_stream *buffered_stream = git__calloc(1, sizeof(struct buffered_stream)); + GIT_ERROR_CHECK_ALLOC(buffered_stream); + + buffered_stream->parent.write = buffered_stream_write; + buffered_stream->parent.close = buffered_stream_close; + buffered_stream->parent.free = buffered_stream_free; + buffered_stream->filter = filter; + buffered_stream->write_fn = write_fn; + buffered_stream->output = temp_buf ? temp_buf : &buffered_stream->temp_buf; + buffered_stream->payload = payload; + buffered_stream->source = source; + buffered_stream->target = target; if (temp_buf) git_buf_clear(temp_buf); - *out = (git_writestream *)proxy_stream; + *out = (git_writestream *)buffered_stream; return 0; } @@ -970,9 +973,9 @@ static int stream_list_init( &fe->payload, &filters->source, last_stream); else /* Create a stream that proxies the one-shot apply */ - error = proxy_stream_init(&filter_stream, fe->filter, - filters->temp_buf, &fe->payload, &filters->source, - last_stream); + error = git_filter_buffered_stream_new(&filter_stream, + fe->filter, fe->filter->apply, filters->temp_buf, + &fe->payload, &filters->source, last_stream); if (error < 0) goto out; diff --git a/src/filter.h b/src/filter.h index 55ed50e97fd..241791276cd 100644 --- a/src/filter.h +++ b/src/filter.h @@ -11,6 +11,7 @@ #include "attr_file.h" #include "git2/filter.h" +#include "git2/sys/filter.h" /* Amount of file to examine for NUL byte when checking binary-ness */ #define GIT_FILTER_BYTES_TO_CHECK_NUL 8000 @@ -51,4 +52,13 @@ extern int git_filter_list__convert_buf( extern git_filter *git_crlf_filter_new(void); extern git_filter *git_ident_filter_new(void); +extern int git_filter_buffered_stream_new( + git_writestream **out, + git_filter *filter, + int (*write_fn)(git_filter *, void **, git_buf *, const git_buf *, const git_filter_source *), + git_buf *temp_buf, + void **payload, + const git_filter_source *source, + git_writestream *target); + #endif From c1f4f45ef84d11d1baf41469eac28ec1b90dabf3 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 27 Aug 2021 16:43:00 -0400 Subject: [PATCH 0467/1616] crlf: use streaming filters --- src/crlf.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/crlf.c b/src/crlf.c index 1de9d8c3bc6..406f7140f21 100644 --- a/src/crlf.c +++ b/src/crlf.c @@ -386,6 +386,17 @@ static int crlf_apply( return crlf_apply_to_odb(*payload, to, from, src); } +static int crlf_stream( + git_writestream **out, + git_filter *self, + void **payload, + const git_filter_source *src, + git_writestream *next) +{ + return git_filter_buffered_stream_new(out, + self, crlf_apply, NULL, payload, src, next); +} + static void crlf_cleanup( git_filter *self, void *payload) @@ -405,7 +416,7 @@ git_filter *git_crlf_filter_new(void) f->f.initialize = NULL; f->f.shutdown = git_filter_free; f->f.check = crlf_check; - f->f.apply = crlf_apply; + f->f.stream = crlf_stream; f->f.cleanup = crlf_cleanup; return (git_filter *)f; From f593fa979319d628295cf7a4d57051e68caa4823 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 27 Aug 2021 16:46:21 -0400 Subject: [PATCH 0468/1616] ident: use streaming filters --- src/ident.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ident.c b/src/ident.c index ae3ef1b4514..e5aab80ed1e 100644 --- a/src/ident.c +++ b/src/ident.c @@ -113,6 +113,17 @@ static int ident_apply( return ident_remove_id(to, from); } +static int ident_stream( + git_writestream **out, + git_filter *self, + void **payload, + const git_filter_source *src, + git_writestream *next) +{ + return git_filter_buffered_stream_new(out, + self, ident_apply, NULL, payload, src, next); +} + git_filter *git_ident_filter_new(void) { git_filter *f = git__calloc(1, sizeof(git_filter)); @@ -122,7 +133,7 @@ git_filter *git_ident_filter_new(void) f->version = GIT_FILTER_VERSION; f->attributes = "+ident"; /* apply to files with ident attribute set */ f->shutdown = git_filter_free; - f->apply = ident_apply; + f->stream = ident_stream; return f; } From c089d5ac6145e4498167c9a3157835e416084d18 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 27 Aug 2021 16:51:38 -0400 Subject: [PATCH 0469/1616] filter: use streaming filters in tests --- tests/filter/custom_helpers.c | 26 ++++++++++++++++++++++++-- tests/filter/wildcard.c | 13 ++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/tests/filter/custom_helpers.c b/tests/filter/custom_helpers.c index 233ba3219f9..ee3b6353b32 100644 --- a/tests/filter/custom_helpers.c +++ b/tests/filter/custom_helpers.c @@ -37,6 +37,17 @@ int bitflip_filter_apply( return 0; } +static int bitflip_filter_stream( + git_writestream **out, + git_filter *self, + void **payload, + const git_filter_source *src, + git_writestream *next) +{ + return git_filter_buffered_stream_new(out, + self, bitflip_filter_apply, NULL, payload, src, next); +} + static void bitflip_filter_free(git_filter *f) { git__free(f); @@ -50,7 +61,7 @@ git_filter *create_bitflip_filter(void) filter->version = GIT_FILTER_VERSION; filter->attributes = "+bitflip"; filter->shutdown = bitflip_filter_free; - filter->apply = bitflip_filter_apply; + filter->stream = bitflip_filter_stream; return filter; } @@ -88,6 +99,17 @@ int reverse_filter_apply( return 0; } +static int reverse_filter_stream( + git_writestream **out, + git_filter *self, + void **payload, + const git_filter_source *src, + git_writestream *next) +{ + return git_filter_buffered_stream_new(out, + self, reverse_filter_apply, NULL, payload, src, next); +} + static void reverse_filter_free(git_filter *f) { git__free(f); @@ -101,7 +123,7 @@ git_filter *create_reverse_filter(const char *attrs) filter->version = GIT_FILTER_VERSION; filter->attributes = attrs; filter->shutdown = reverse_filter_free; - filter->apply = reverse_filter_apply; + filter->stream = reverse_filter_stream; return filter; } diff --git a/tests/filter/wildcard.c b/tests/filter/wildcard.c index ca1ba1a284a..0c9c13b1e4c 100644 --- a/tests/filter/wildcard.c +++ b/tests/filter/wildcard.c @@ -93,6 +93,17 @@ static int wildcard_filter_apply( return GIT_PASSTHROUGH; } +static int wildcard_filter_stream( + git_writestream **out, + git_filter *self, + void **payload, + const git_filter_source *src, + git_writestream *next) +{ + return git_filter_buffered_stream_new(out, + self, wildcard_filter_apply, NULL, payload, src, next); +} + static void wildcard_filter_cleanup(git_filter *self, void *payload) { GIT_UNUSED(self); @@ -112,7 +123,7 @@ static git_filter *create_wildcard_filter(void) filter->version = GIT_FILTER_VERSION; filter->attributes = "filter=*"; filter->check = wildcard_filter_check; - filter->apply = wildcard_filter_apply; + filter->stream = wildcard_filter_stream; filter->cleanup = wildcard_filter_cleanup; filter->shutdown = wildcard_filter_free; From 08b3ee2f83414dab084a35a7aa9daa81fc6f764e Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Sat, 7 Aug 2021 15:56:29 +0300 Subject: [PATCH 0470/1616] cmake: select hashes missing umbrella header has been added. --- cmake/SelectHashes.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/SelectHashes.cmake b/cmake/SelectHashes.cmake index 06672ab0339..5c8b5ec939d 100644 --- a/cmake/SelectHashes.cmake +++ b/cmake/SelectHashes.cmake @@ -56,6 +56,8 @@ ELSE() MESSAGE(FATAL_ERROR "Asked for unknown SHA1 backend: ${USE_SHA1}") ENDIF() +FILE(GLOB SRC_SHA1_UMBRELLA "hash/sha1.h") +list(APPEND SRC_SHA1 ${SRC_SHA1_UMBRELLA}) list(SORT SRC_SHA1) ADD_FEATURE_INFO(SHA ON "using ${USE_SHA1}") From 4c0ea9f06d7fa1d5345544617620a762a4e6e5d7 Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Sat, 28 Aug 2021 20:18:38 +0300 Subject: [PATCH 0471/1616] cmake: select hashes umbrella variable has been removed. Co-authored-by: Edward Thomson --- cmake/SelectHashes.cmake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/SelectHashes.cmake b/cmake/SelectHashes.cmake index 5c8b5ec939d..092cdfd051a 100644 --- a/cmake/SelectHashes.cmake +++ b/cmake/SelectHashes.cmake @@ -56,8 +56,7 @@ ELSE() MESSAGE(FATAL_ERROR "Asked for unknown SHA1 backend: ${USE_SHA1}") ENDIF() -FILE(GLOB SRC_SHA1_UMBRELLA "hash/sha1.h") -list(APPEND SRC_SHA1 ${SRC_SHA1_UMBRELLA}) +list(APPEND SRC_SHA1 "hash/sha1.h") list(SORT SRC_SHA1) ADD_FEATURE_INFO(SHA ON "using ${USE_SHA1}") From d17e67e6ab2765ce2c83fdf174d28e64400b7218 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Sun, 29 Aug 2021 12:19:49 +0200 Subject: [PATCH 0472/1616] tests: change comments to c89 style --- tests/config/read.c | 4 ++-- tests/remote/fetch.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/config/read.c b/tests/config/read.c index 10990875080..badf5118e8d 100644 --- a/tests/config/read.c +++ b/tests/config/read.c @@ -964,7 +964,7 @@ void test_config_read__get_mapped(void) " key9 = off\n"); cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig")); - // check parsing bool and string + /* check parsing bool and string */ cl_git_pass(git_config_get_mapped(&val, cfg, "header.key1", _test_map1, ARRAY_SIZE(_test_map1))); cl_assert_equal_i(val, MAP_TRUE); cl_git_pass(git_config_get_mapped(&val, cfg, "header.key2", _test_map1, ARRAY_SIZE(_test_map1))); @@ -986,7 +986,7 @@ void test_config_read__get_mapped(void) cl_git_fail(git_config_get_mapped(&val, cfg, "header.key7", _test_map1, ARRAY_SIZE(_test_map1))); - // check parsing int values + /* check parsing int values */ cl_git_pass(git_config_get_mapped(&val, cfg, "header.key1", _test_map2, ARRAY_SIZE(_test_map2))); cl_git_pass(git_config_get_int32(&known_good, cfg, "header.key1")); cl_assert_equal_i(val, known_good); diff --git a/tests/remote/fetch.c b/tests/remote/fetch.c index 392801e0b33..7e825ca16ca 100644 --- a/tests/remote/fetch.c +++ b/tests/remote/fetch.c @@ -72,7 +72,7 @@ void do_time_travelling_fetch(git_oid *commit1id, git_oid *commit2id, .strings = &refspec_strs, }; - // create two commits in repo 1 and a reference to them + /* create two commits in repo 1 and a reference to them */ { git_oid empty_tree_id; git_tree *empty_tree; @@ -92,7 +92,7 @@ void do_time_travelling_fetch(git_oid *commit1id, git_oid *commit2id, git_treebuilder_free(tb); } - // fetch the reference via the remote + /* fetch the reference via the remote */ { git_remote *remote; @@ -103,7 +103,7 @@ void do_time_travelling_fetch(git_oid *commit1id, git_oid *commit2id, git_remote_free(remote); } - // assert that repo2 references the second commit + /* assert that repo2 references the second commit */ { const git_oid *target; git_reference *ref; @@ -113,7 +113,7 @@ void do_time_travelling_fetch(git_oid *commit1id, git_oid *commit2id, git_reference_free(ref); } - // set the reference in repo1 to point to the older commit + /* set the reference in repo1 to point to the older commit */ { git_reference *ref; git_reference *ref2; @@ -124,7 +124,7 @@ void do_time_travelling_fetch(git_oid *commit1id, git_oid *commit2id, git_reference_free(ref2); } - // fetch the reference again + /* fetch the reference again */ { git_remote *remote; @@ -144,7 +144,7 @@ void test_remote_fetch__dont_update_refs_if_not_descendant_and_not_force(void) { do_time_travelling_fetch(&commit1id, &commit2id, false); - // assert that the reference in repo2 has not changed + /* assert that the reference in repo2 has not changed */ cl_git_pass(git_reference_lookup(&ref, repo2, REPO2_REFNAME)); target = git_reference_target(ref); cl_assert_equal_b(git_oid_cmp(target, &commit2id), 0); @@ -160,7 +160,7 @@ void test_remote_fetch__do_update_refs_if_not_descendant_and_force(void) { do_time_travelling_fetch(&commit1id, &commit2id, true); - // assert that the reference in repo2 has changed + /* assert that the reference in repo2 has changed */ cl_git_pass(git_reference_lookup(&ref, repo2, REPO2_REFNAME)); target = git_reference_target(ref); cl_assert_equal_b(git_oid_cmp(target, &commit1id), 0); From d3bdf33b58f16939a4fd43ab541dcd2ee535b6a3 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 29 Aug 2021 09:36:01 -0400 Subject: [PATCH 0473/1616] rebase: introduce git_commit_create_cb Introduce a new mechanism for `git_rebase_commit` for callers to customize the experience. Instead of assuming that we produce the commit for them, provide a commit creation callback that allows callers to produce the commit themselves and return the resulting commit id. --- include/git2/commit.h | 37 +++++++ include/git2/rebase.h | 15 +++ src/rebase.c | 101 +++++++++++------- tests/rebase/sign.c | 231 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 349 insertions(+), 35 deletions(-) diff --git a/include/git2/commit.h b/include/git2/commit.h index e6c4656a9cc..650bf65a583 100644 --- a/include/git2/commit.h +++ b/include/git2/commit.h @@ -502,6 +502,43 @@ GIT_EXTERN(int) git_commit_create_with_signature( */ GIT_EXTERN(int) git_commit_dup(git_commit **out, git_commit *source); +/** + * Commit creation callback: used when a function is going to create + * commits (for example, in `git_rebase_commit`) to allow callers to + * override the commit creation behavior. For example, users may + * wish to sign commits by providing this information to + * `git_commit_create_buffer`, signing that buffer, then calling + * `git_commit_create_with_signature`. The resultant commit id + * should be set in the `out` object id parameter. + * + * @param out pointer that this callback will populate with the object + * id of the commit that is created + * @param author the author name and time of the commit + * @param committer the committer name and time of the commit + * @param message_encoding the encoding of the given message, or NULL + * to assume UTF8 + * @param message the commit message + * @param tree the tree to be committed + * @param parent_count the number of parents for this commit + * @param parents the commit parents + * @param payload the payload pointer in the rebase options + * @return 0 if this callback has created the commit and populated the out + * parameter, GIT_PASSTHROUGH if the callback has not created a + * commit and wants the calling function to create the commit as + * if no callback had been specified, any other value to stop + * and return a failure + */ +typedef int (*git_commit_create_cb)( + git_oid *out, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + size_t parent_count, + const git_commit *parents[], + void *payload); + /** * Commit signing callback. * diff --git a/include/git2/rebase.h b/include/git2/rebase.h index 99a02fef9f1..7d2d5de69fb 100644 --- a/include/git2/rebase.h +++ b/include/git2/rebase.h @@ -74,12 +74,27 @@ typedef struct { */ git_checkout_options checkout_options; + /** + * Optional callback that allows users to override commit + * creation in `git_rebase_commit`. If specified, users can + * create their own commit and provide the commit ID, which + * may be useful for signing commits or otherwise customizing + * the commit creation. + * + * If this callback returns `GIT_PASSTHROUGH`, then + * `git_rebase_commit` will continue to create the commit. + */ + git_commit_create_cb commit_create_cb; + /** * If provided, this will be called with the commit content, allowing * a signature to be added to the rebase commit. Can be skipped with * GIT_PASSTHROUGH. If GIT_PASSTHROUGH is returned, a commit will be made * without a signature. * This field is only used when performing git_rebase_commit. + * + * This callback is not invoked if a `git_commit_create_cb` is + * specified. */ git_commit_signing_cb signing_cb; diff --git a/src/rebase.c b/src/rebase.c index bf6581a1b18..ddd82e91098 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -943,6 +943,52 @@ int git_rebase_inmemory_index( return 0; } +static int create_signed( + git_oid *out, + git_rebase *rebase, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + git_tree *tree, + size_t parent_count, + const git_commit **parents) +{ + git_buf commit_content = GIT_BUF_INIT, + commit_signature = GIT_BUF_INIT, + signature_field = GIT_BUF_INIT; + int error; + + git_error_clear(); + + if ((error = git_commit_create_buffer(&commit_content, + rebase->repo, author, committer, message_encoding, + message, tree, parent_count, parents)) < 0) + goto done; + + error = rebase->options.signing_cb(&commit_signature, + &signature_field, commit_content.ptr, + rebase->options.payload); + + if (error) { + if (error != GIT_PASSTHROUGH) + git_error_set_after_callback_function(error, "signing_cb"); + + goto done; + } + + error = git_commit_create_with_signature(out, rebase->repo, + commit_content.ptr, + commit_signature.size > 0 ? commit_signature.ptr : NULL, + signature_field.size > 0 ? signature_field.ptr : NULL); + +done: + git_buf_dispose(&commit_signature); + git_buf_dispose(&signature_field); + git_buf_dispose(&commit_content); + return error; +} + static int rebase_commit__create( git_commit **out, git_rebase *rebase, @@ -957,10 +1003,6 @@ static int rebase_commit__create( git_commit *current_commit = NULL, *commit = NULL; git_tree *parent_tree = NULL, *tree = NULL; git_oid tree_id, commit_id; - git_buf commit_content = GIT_BUF_INIT, commit_signature = GIT_BUF_INIT, - signature_field = GIT_BUF_INIT; - const char *signature_field_string = NULL, - *commit_signature_string = NULL; int error; operation = git_array_get(rebase->operations, rebase->current); @@ -991,37 +1033,29 @@ static int rebase_commit__create( message = git_commit_message(current_commit); } - if ((error = git_commit_create_buffer(&commit_content, rebase->repo, author, committer, - message_encoding, message, tree, 1, (const git_commit **)&parent_commit)) < 0) - goto done; - - if (rebase->options.signing_cb) { - git_error_clear(); - error = git_error_set_after_callback_function(rebase->options.signing_cb( - &commit_signature, &signature_field, git_buf_cstr(&commit_content), - rebase->options.payload), "commit signing_cb failed"); - if (error == GIT_PASSTHROUGH) { - git_buf_dispose(&commit_signature); - git_buf_dispose(&signature_field); - git_error_clear(); - error = GIT_OK; - } else if (error < 0) - goto done; - } - - if (git_buf_is_allocated(&commit_signature)) { - GIT_ASSERT(git_buf_contains_nul(&commit_signature)); - commit_signature_string = git_buf_cstr(&commit_signature); + git_error_clear(); + error = GIT_PASSTHROUGH; + + if (rebase->options.commit_create_cb) { + error = rebase->options.commit_create_cb(&commit_id, + author, committer, message_encoding, message, + tree, 1, (const git_commit **)&parent_commit, + rebase->options.payload); + + git_error_set_after_callback_function(error, + "commit_create_cb"); + } else if (rebase->options.signing_cb) { + error = create_signed(&commit_id, rebase, author, + committer, message_encoding, message, tree, + 1, (const git_commit **)&parent_commit); } - if (git_buf_is_allocated(&signature_field)) { - GIT_ASSERT(git_buf_contains_nul(&signature_field)); - signature_field_string = git_buf_cstr(&signature_field); - } + if (error == GIT_PASSTHROUGH) + error = git_commit_create(&commit_id, rebase->repo, NULL, + author, committer, message_encoding, message, + tree, 1, (const git_commit **)&parent_commit); - if ((error = git_commit_create_with_signature(&commit_id, rebase->repo, - git_buf_cstr(&commit_content), commit_signature_string, - signature_field_string))) + if (error) goto done; if ((error = git_commit_lookup(&commit, rebase->repo, &commit_id)) < 0) @@ -1033,9 +1067,6 @@ static int rebase_commit__create( if (error < 0) git_commit_free(commit); - git_buf_dispose(&commit_signature); - git_buf_dispose(&signature_field); - git_buf_dispose(&commit_content); git_commit_free(current_commit); git_tree_free(parent_tree); git_tree_free(tree); diff --git a/tests/rebase/sign.c b/tests/rebase/sign.c index fa477666188..46476780048 100644 --- a/tests/rebase/sign.c +++ b/tests/rebase/sign.c @@ -18,6 +18,236 @@ void test_rebase_sign__cleanup(void) cl_git_sandbox_cleanup(); } +static int create_cb_passthrough( + git_oid *out, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + size_t parent_count, + const git_commit *parents[], + void *payload) +{ + GIT_UNUSED(out); + GIT_UNUSED(author); + GIT_UNUSED(committer); + GIT_UNUSED(message_encoding); + GIT_UNUSED(message); + GIT_UNUSED(tree); + GIT_UNUSED(parent_count); + GIT_UNUSED(parents); + GIT_UNUSED(payload); + + return GIT_PASSTHROUGH; +} + +/* git checkout gravy ; git rebase --merge veal */ +void test_rebase_sign__passthrough_create_cb(void) +{ + git_rebase *rebase; + git_reference *branch_ref, *upstream_ref; + git_annotated_commit *branch_head, *upstream_head; + git_rebase_operation *rebase_operation; + git_oid commit_id, expected_id; + git_rebase_options rebase_opts = GIT_REBASE_OPTIONS_INIT; + git_commit *commit; + const char *expected_commit_raw_header = "tree cd99b26250099fc38d30bfaed7797a7275ed3366\n\ +parent f87d14a4a236582a0278a916340a793714256864\n\ +author Edward Thomson 1405625055 -0400\n\ +committer Rebaser 1405694510 +0000\n"; + + rebase_opts.commit_create_cb = create_cb_passthrough; + + cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/gravy")); + cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/veal")); + + cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref)); + cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref)); + + cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, &rebase_opts)); + + cl_git_pass(git_rebase_next(&rebase_operation, rebase)); + cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); + + git_oid_fromstr(&expected_id, "129183968a65abd6c52da35bff43325001bfc630"); + cl_assert_equal_oid(&expected_id, &commit_id); + + cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); + cl_assert_equal_s(expected_commit_raw_header, git_commit_raw_header(commit)); + + cl_git_fail_with(GIT_ITEROVER, git_rebase_next(&rebase_operation, rebase)); + + git_reference_free(branch_ref); + git_reference_free(upstream_ref); + git_annotated_commit_free(branch_head); + git_annotated_commit_free(upstream_head); + git_commit_free(commit); + git_rebase_free(rebase); +} + +int create_cb_signed_gpg( + git_oid *out, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + size_t parent_count, + const git_commit *parents[], + void *payload) +{ + git_buf commit_content = GIT_BUF_INIT; + const char *gpg_signature = "-----BEGIN PGP SIGNATURE-----\n\ +\n\ +iQIzBAEBCgAdFiEEgVlDEfSlmKn0fvGgK++h5T2/ctIFAlwZcrAACgkQK++h5T2/\n\ +ctIPVhAA42RyZhMdKl5Bm0KtQco2scsukIg2y7tjSwhti91zDu3HQgpusjjo0fQx\n\ +ZzB+OrmlvQ9CDcGpZ0THIzXD8GRJoDMPqdrvZVrBWkGcHvw7/YPA8skzsjkauJ8W\n\ +7lzF5LCuHSS6OUmPT/+5hEHPin5PB3zhfszyC+Q7aujnIuPJMrKiMnUa+w1HWifM\n\ +km49OOygQ9S6NQoVuEQede22+c76DlDL7yFghGoo1f0sKCE/9LW6SEnwI/bWv9eo\n\ +nom5vOPrvQeJiYCQk+2DyWo8RdSxINtY+G9bPE4RXm+6ZgcXECPm9TYDIWpL36fC\n\ +jvtGLs98woWFElOziBMp5Tb630GMcSI+q5ivHfJ3WS5NKLYLHBNK4iSFN0/dgAnB\n\ +dj6GcKXKWnIBWn6ZM4o40pcM5KSRUUCLtA0ZmjJH4c4zx3X5fUxd+enwkf3e9VZO\n\ +fNKC/+xfq6NfoPUPK9+UnchHpJaJw7RG5tZS+sWCz2xpQ1y3/o49xImNyM3wnpvB\n\ +cRAZabqIHpZa9/DIUkELOtCzln6niqkjRgg3M/YCCNznwV+0RNgz87VtyTPerdef\n\ +xrqn0+ROMF6ebVqIs6PPtuPkxnAJu7TMKXVB5rFnAewS24e6cIGFzeIA7810py3l\n\ +cttVRsdOoego+fiy08eFE+aJIeYiINRGhqOBTsuqG4jIdpdKxPE=\n\ +=KbsY\n\ +-----END PGP SIGNATURE-----"; + + git_repository *repo = (git_repository *)payload; + int error; + + if ((error = git_commit_create_buffer(&commit_content, + repo, author, committer, message_encoding, message, + tree, parent_count, parents)) < 0) + goto done; + + error = git_commit_create_with_signature(out, repo, + commit_content.ptr, + gpg_signature, + NULL); + +done: + git_buf_dispose(&commit_content); + return error; +} + +/* git checkout gravy ; git rebase --merge veal */ +void test_rebase_sign__create_gpg_signed(void) +{ + git_rebase *rebase; + git_reference *branch_ref, *upstream_ref; + git_annotated_commit *branch_head, *upstream_head; + git_rebase_operation *rebase_operation; + git_oid commit_id, expected_id; + git_rebase_options rebase_opts = GIT_REBASE_OPTIONS_INIT; + git_commit *commit; + const char *expected_commit_raw_header = "tree cd99b26250099fc38d30bfaed7797a7275ed3366\n\ +parent f87d14a4a236582a0278a916340a793714256864\n\ +author Edward Thomson 1405625055 -0400\n\ +committer Rebaser 1405694510 +0000\n\ +gpgsig -----BEGIN PGP SIGNATURE-----\n\ + \n\ + iQIzBAEBCgAdFiEEgVlDEfSlmKn0fvGgK++h5T2/ctIFAlwZcrAACgkQK++h5T2/\n\ + ctIPVhAA42RyZhMdKl5Bm0KtQco2scsukIg2y7tjSwhti91zDu3HQgpusjjo0fQx\n\ + ZzB+OrmlvQ9CDcGpZ0THIzXD8GRJoDMPqdrvZVrBWkGcHvw7/YPA8skzsjkauJ8W\n\ + 7lzF5LCuHSS6OUmPT/+5hEHPin5PB3zhfszyC+Q7aujnIuPJMrKiMnUa+w1HWifM\n\ + km49OOygQ9S6NQoVuEQede22+c76DlDL7yFghGoo1f0sKCE/9LW6SEnwI/bWv9eo\n\ + nom5vOPrvQeJiYCQk+2DyWo8RdSxINtY+G9bPE4RXm+6ZgcXECPm9TYDIWpL36fC\n\ + jvtGLs98woWFElOziBMp5Tb630GMcSI+q5ivHfJ3WS5NKLYLHBNK4iSFN0/dgAnB\n\ + dj6GcKXKWnIBWn6ZM4o40pcM5KSRUUCLtA0ZmjJH4c4zx3X5fUxd+enwkf3e9VZO\n\ + fNKC/+xfq6NfoPUPK9+UnchHpJaJw7RG5tZS+sWCz2xpQ1y3/o49xImNyM3wnpvB\n\ + cRAZabqIHpZa9/DIUkELOtCzln6niqkjRgg3M/YCCNznwV+0RNgz87VtyTPerdef\n\ + xrqn0+ROMF6ebVqIs6PPtuPkxnAJu7TMKXVB5rFnAewS24e6cIGFzeIA7810py3l\n\ + cttVRsdOoego+fiy08eFE+aJIeYiINRGhqOBTsuqG4jIdpdKxPE=\n\ + =KbsY\n\ + -----END PGP SIGNATURE-----\n"; + + rebase_opts.commit_create_cb = create_cb_signed_gpg; + rebase_opts.payload = repo; + + cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/gravy")); + cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/veal")); + + cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref)); + cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref)); + + cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, &rebase_opts)); + + cl_git_pass(git_rebase_next(&rebase_operation, rebase)); + cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); + + git_oid_fromstr(&expected_id, "bf78348e45c8286f52b760f1db15cb6da030f2ef"); + cl_assert_equal_oid(&expected_id, &commit_id); + + cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); + cl_assert_equal_s(expected_commit_raw_header, git_commit_raw_header(commit)); + + cl_git_fail_with(GIT_ITEROVER, git_rebase_next(&rebase_operation, rebase)); + + git_reference_free(branch_ref); + git_reference_free(upstream_ref); + git_annotated_commit_free(branch_head); + git_annotated_commit_free(upstream_head); + git_commit_free(commit); + git_rebase_free(rebase); +} + +static int create_cb_error( + git_oid *out, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + size_t parent_count, + const git_commit *parents[], + void *payload) +{ + GIT_UNUSED(out); + GIT_UNUSED(author); + GIT_UNUSED(committer); + GIT_UNUSED(message_encoding); + GIT_UNUSED(message); + GIT_UNUSED(tree); + GIT_UNUSED(parent_count); + GIT_UNUSED(parents); + GIT_UNUSED(payload); + + return GIT_EUSER; +} + +/* git checkout gravy ; git rebase --merge veal */ +void test_rebase_sign__create_propagates_error(void) +{ + git_rebase *rebase; + git_reference *branch_ref, *upstream_ref; + git_annotated_commit *branch_head, *upstream_head; + git_oid commit_id; + git_rebase_operation *rebase_operation; + git_rebase_options rebase_opts = GIT_REBASE_OPTIONS_INIT; + + rebase_opts.commit_create_cb = create_cb_error; + + cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/gravy")); + cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/veal")); + + cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref)); + cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref)); + + cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, &rebase_opts)); + + cl_git_pass(git_rebase_next(&rebase_operation, rebase)); + cl_git_fail_with(GIT_EUSER, git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); + + git_reference_free(branch_ref); + git_reference_free(upstream_ref); + git_annotated_commit_free(branch_head); + git_annotated_commit_free(upstream_head); + git_rebase_free(rebase); +} + static const char *expected_commit_content = "tree cd99b26250099fc38d30bfaed7797a7275ed3366\n\ parent f87d14a4a236582a0278a916340a793714256864\n\ author Edward Thomson 1405625055 -0400\n\ @@ -241,3 +471,4 @@ magicsig magic word: pretty please\n"; git_commit_free(commit); git_rebase_free(rebase); } + From ef03e15038824c8951eede2f17ad9dafbd5a32d3 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 29 Aug 2021 10:14:01 -0400 Subject: [PATCH 0474/1616] rebase: deprecate signing_cb The signing callback should not be used; instead, callers should provide a commit_create_cb, perform the signing and commit creation themselves. --- include/git2/commit.h | 21 --------------------- include/git2/deprecated.h | 21 +++++++++++++++++++++ include/git2/rebase.h | 11 ++++++++++- src/rebase.c | 7 ++++++- tests/rebase/sign.c | 37 ++++++++++++++++++++++++++----------- 5 files changed, 63 insertions(+), 34 deletions(-) diff --git a/include/git2/commit.h b/include/git2/commit.h index 650bf65a583..4d74b8994fc 100644 --- a/include/git2/commit.h +++ b/include/git2/commit.h @@ -539,27 +539,6 @@ typedef int (*git_commit_create_cb)( const git_commit *parents[], void *payload); -/** - * Commit signing callback. - * - * The callback will be called with the commit content, giving a user an - * opportunity to sign the commit content. The signature_field - * buf may be left empty to specify the default field "gpgsig". - * - * Signatures can take the form of any string, and can be created on an arbitrary - * header field. Signatures are most commonly used for verifying authorship of a - * commit using GPG or a similar cryptographically secure signing algorithm. - * See https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work for more - * details. - * - * When the callback: - * - returns GIT_PASSTHROUGH, no signature will be added to the commit. - * - returns < 0, commit creation will be aborted. - * - returns GIT_OK, the signature parameter is expected to be filled. - */ -typedef int (*git_commit_signing_cb)( - git_buf *signature, git_buf *signature_field, const char *commit_content, void *payload); - /** @} */ GIT_END_DECL #endif diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index ac60488acb6..611848e10d7 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -205,6 +205,27 @@ GIT_EXTERN(void) git_buf_free(git_buf *buffer); /**@}*/ +/** @name Deprecated Commit Definitions + */ +/**@{*/ + +/** + * Provide a commit signature during commit creation. + * + * Callers should instead define a `git_commit_create_cb` that + * generates a commit buffer using `git_commit_create_buffer`, sign + * that buffer and call `git_commit_create_with_signature`. + * + * @deprecated use a `git_commit_create_cb` instead + */ +typedef int (*git_commit_signing_cb)( + git_buf *signature, + git_buf *signature_field, + const char *commit_content, + void *payload); + +/**@}*/ + /** @name Deprecated Config Functions and Constants */ /**@{*/ diff --git a/include/git2/rebase.h b/include/git2/rebase.h index 7d2d5de69fb..11e452cbf01 100644 --- a/include/git2/rebase.h +++ b/include/git2/rebase.h @@ -86,17 +86,26 @@ typedef struct { */ git_commit_create_cb commit_create_cb; +#ifdef GIT_DEPRECATE_HARD + void *reserved; +#else /** * If provided, this will be called with the commit content, allowing * a signature to be added to the rebase commit. Can be skipped with * GIT_PASSTHROUGH. If GIT_PASSTHROUGH is returned, a commit will be made * without a signature. + * * This field is only used when performing git_rebase_commit. * * This callback is not invoked if a `git_commit_create_cb` is * specified. + * + * This callback is deprecated; users should provide a + * creation callback as `commit_create_cb` that produces a + * commit buffer, signs it, and commits it. */ - git_commit_signing_cb signing_cb; + int (*signing_cb)(git_buf *, git_buf *, const char *, void *); +#endif /** * This will be passed to each of the callbacks in this struct diff --git a/src/rebase.c b/src/rebase.c index ddd82e91098..4f10c296bdd 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -943,6 +943,7 @@ int git_rebase_inmemory_index( return 0; } +#ifndef GIT_DEPRECATE_HARD static int create_signed( git_oid *out, git_rebase *rebase, @@ -988,6 +989,7 @@ static int create_signed( git_buf_dispose(&commit_content); return error; } +#endif static int rebase_commit__create( git_commit **out, @@ -1044,11 +1046,14 @@ static int rebase_commit__create( git_error_set_after_callback_function(error, "commit_create_cb"); - } else if (rebase->options.signing_cb) { + } +#ifndef GIT_DEPRECATE_HARD + else if (rebase->options.signing_cb) { error = create_signed(&commit_id, rebase, author, committer, message_encoding, message, tree, 1, (const git_commit **)&parent_commit); } +#endif if (error == GIT_PASSTHROUGH) error = git_commit_create(&commit_id, rebase->repo, NULL, diff --git a/tests/rebase/sign.c b/tests/rebase/sign.c index 46476780048..8b0473c3c43 100644 --- a/tests/rebase/sign.c +++ b/tests/rebase/sign.c @@ -248,29 +248,33 @@ void test_rebase_sign__create_propagates_error(void) git_rebase_free(rebase); } -static const char *expected_commit_content = "tree cd99b26250099fc38d30bfaed7797a7275ed3366\n\ -parent f87d14a4a236582a0278a916340a793714256864\n\ -author Edward Thomson 1405625055 -0400\n\ -committer Rebaser 1405694510 +0000\n\ -\n\ -Modification 3 to gravy\n"; - +#ifndef GIT_DEPRECATE_HARD int signing_cb_passthrough( git_buf *signature, git_buf *signature_field, const char *commit_content, void *payload) { + static const char *expected_commit_content = "\ +tree cd99b26250099fc38d30bfaed7797a7275ed3366\n\ +parent f87d14a4a236582a0278a916340a793714256864\n\ +author Edward Thomson 1405625055 -0400\n\ +committer Rebaser 1405694510 +0000\n\ +\n\ +Modification 3 to gravy\n"; + cl_assert_equal_b(false, git_buf_is_allocated(signature)); cl_assert_equal_b(false, git_buf_is_allocated(signature_field)); cl_assert_equal_s(expected_commit_content, commit_content); cl_assert_equal_p(NULL, payload); return GIT_PASSTHROUGH; } +#endif /* !GIT_DEPRECATE_HARD */ /* git checkout gravy ; git rebase --merge veal */ void test_rebase_sign__passthrough_signing_cb(void) { +#ifndef GIT_DEPRECATE_HARD git_rebase *rebase; git_reference *branch_ref, *upstream_ref; git_annotated_commit *branch_head, *upstream_head; @@ -310,15 +314,18 @@ committer Rebaser 1405694510 +0000\n"; git_annotated_commit_free(upstream_head); git_commit_free(commit); git_rebase_free(rebase); +#endif /* !GIT_DEPRECATE_HARD */ } +#ifndef GIT_DEPRECATE_HARD int signing_cb_gpg( git_buf *signature, git_buf *signature_field, const char *commit_content, void *payload) { - const char *gpg_signature = "-----BEGIN PGP SIGNATURE-----\n\ + const char *gpg_signature = "\ +-----BEGIN PGP SIGNATURE-----\n\ \n\ iQIzBAEBCgAdFiEEgVlDEfSlmKn0fvGgK++h5T2/ctIFAlwZcrAACgkQK++h5T2/\n\ ctIPVhAA42RyZhMdKl5Bm0KtQco2scsukIg2y7tjSwhti91zDu3HQgpusjjo0fQx\n\ @@ -343,10 +350,12 @@ cttVRsdOoego+fiy08eFE+aJIeYiINRGhqOBTsuqG4jIdpdKxPE=\n\ cl_git_pass(git_buf_set(signature, gpg_signature, strlen(gpg_signature) + 1)); return GIT_OK; } +#endif /* !GIT_DEPRECATE_HARD */ /* git checkout gravy ; git rebase --merge veal */ void test_rebase_sign__gpg_with_no_field(void) { +#ifndef GIT_DEPRECATE_HARD git_rebase *rebase; git_reference *branch_ref, *upstream_ref; git_annotated_commit *branch_head, *upstream_head; @@ -354,7 +363,8 @@ void test_rebase_sign__gpg_with_no_field(void) git_oid commit_id, expected_id; git_rebase_options rebase_opts = GIT_REBASE_OPTIONS_INIT; git_commit *commit; - const char *expected_commit_raw_header = "tree cd99b26250099fc38d30bfaed7797a7275ed3366\n\ + const char *expected_commit_raw_header = "\ +tree cd99b26250099fc38d30bfaed7797a7275ed3366\n\ parent f87d14a4a236582a0278a916340a793714256864\n\ author Edward Thomson 1405625055 -0400\n\ committer Rebaser 1405694510 +0000\n\ @@ -402,9 +412,11 @@ gpgsig -----BEGIN PGP SIGNATURE-----\n\ git_annotated_commit_free(upstream_head); git_commit_free(commit); git_rebase_free(rebase); +#endif /* !GIT_DEPRECATE_HARD */ } +#ifndef GIT_DEPRECATE_HARD int signing_cb_magic_field( git_buf *signature, git_buf *signature_field, @@ -426,10 +438,12 @@ int signing_cb_magic_field( return GIT_OK; } +#endif /* !GIT_DEPRECATE_HARD */ /* git checkout gravy ; git rebase --merge veal */ void test_rebase_sign__custom_signature_field(void) { +#ifndef GIT_DEPRECATE_HARD git_rebase *rebase; git_reference *branch_ref, *upstream_ref; git_annotated_commit *branch_head, *upstream_head; @@ -437,7 +451,8 @@ void test_rebase_sign__custom_signature_field(void) git_oid commit_id, expected_id; git_rebase_options rebase_opts = GIT_REBASE_OPTIONS_INIT; git_commit *commit; - const char *expected_commit_raw_header = "tree cd99b26250099fc38d30bfaed7797a7275ed3366\n\ + const char *expected_commit_raw_header = "\ +tree cd99b26250099fc38d30bfaed7797a7275ed3366\n\ parent f87d14a4a236582a0278a916340a793714256864\n\ author Edward Thomson 1405625055 -0400\n\ committer Rebaser 1405694510 +0000\n\ @@ -470,5 +485,5 @@ magicsig magic word: pretty please\n"; git_annotated_commit_free(upstream_head); git_commit_free(commit); git_rebase_free(rebase); +#endif /* !GIT_DEPRECATE_HARD */ } - From 72df17c659619707e4e5f27b2a51db60848a1d04 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 27 Aug 2021 10:59:51 -0400 Subject: [PATCH 0475/1616] remote: introduce git_remote_ready_cb Introduce a new callback that fires when the remote is ready to connect. --- include/git2/remote.h | 17 ++++++++++++++ src/remote.c | 15 +++++++++--- tests/network/remote/remotes.c | 42 ++++++++++++++++++++++++++++++++++ tests/online/push_util.h | 2 +- 4 files changed, 72 insertions(+), 4 deletions(-) diff --git a/include/git2/remote.h b/include/git2/remote.h index 5b67717eb6f..b75a9911c35 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -513,6 +513,18 @@ typedef int GIT_CALLBACK(git_push_update_reference_cb)(const char *refname, cons */ typedef int GIT_CALLBACK(git_url_resolve_cb)(git_buf *url_resolved, const char *url, int direction, void *payload); +/** + * Callback invoked immediately before we attempt to connect to the + * given url. Callers may change the URL before the connection by + * calling `git_remote_set_instance_url` in the callback. + * + * @param remote The remote to be connected + * @param direction GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH + * @param payload Payload provided by the caller + * @return 0 on success, or an error + */ +typedef int GIT_CALLBACK(git_remote_ready_cb)(git_remote *remote, int direction, void *payload); + /** * The callback settings structure * @@ -597,6 +609,11 @@ struct git_remote_callbacks { */ git_transport_cb transport; + /** + * Callback when the remote is ready to connect. + */ + git_remote_ready_cb remote_ready; + /** * This will be passed to each of the callbacks in this struct * as the last parameter. diff --git a/src/remote.c b/src/remote.c index 236f39abab6..8050e65f311 100644 --- a/src/remote.c +++ b/src/remote.c @@ -709,11 +709,19 @@ int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int GIT_ASSERT_ARG(remote); GIT_ASSERT_ARG(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH); - if (direction == GIT_DIRECTION_FETCH) { + if (callbacks && callbacks->remote_ready) { + int status = callbacks->remote_ready(remote, direction, callbacks->payload); + + if (status != 0 && status != GIT_PASSTHROUGH) { + git_error_set_after_callback_function(status, "git_remote_ready_cb"); + return status; + } + } + + if (direction == GIT_DIRECTION_FETCH) url = remote->url; - } else if (direction == GIT_DIRECTION_PUSH) { + else if (direction == GIT_DIRECTION_PUSH) url = remote->pushurl ? remote->pushurl : remote->url; - } if (!url) { git_error_set(GIT_ERROR_INVALID, @@ -722,6 +730,7 @@ int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int direction == GIT_DIRECTION_FETCH ? "fetch" : "push"); return GIT_EINVALID; } + return resolve_url(url_out, url, direction, callbacks); } diff --git a/tests/network/remote/remotes.c b/tests/network/remote/remotes.c index a962d92932b..4a9f5ae7268 100644 --- a/tests/network/remote/remotes.c +++ b/tests/network/remote/remotes.c @@ -56,6 +56,48 @@ void test_network_remote_remotes__parsing(void) git_buf_dispose(&url); } +static int remote_ready_callback(git_remote *remote, int direction, void *payload) +{ + if (direction == GIT_DIRECTION_PUSH) { + const char *url = git_remote_pushurl(remote); + + cl_assert_equal_p(url, NULL);; + cl_assert_equal_s(payload, "payload"); + return git_remote_set_instance_pushurl(remote, "push_url"); + } + + if (direction == GIT_DIRECTION_FETCH) { + const char *url = git_remote_url(remote); + + cl_assert_equal_s(url, "git://github.com/libgit2/libgit2"); + cl_assert_equal_s(payload, "payload"); + return git_remote_set_instance_url(remote, "fetch_url"); + } + + return -1; +} + +void test_network_remote_remotes__remote_ready(void) +{ + git_buf url = GIT_BUF_INIT; + + git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + callbacks.remote_ready = remote_ready_callback; + callbacks.payload = "payload"; + + cl_assert_equal_s(git_remote_name(_remote), "test"); + cl_assert_equal_s(git_remote_url(_remote), "git://github.com/libgit2/libgit2"); + cl_assert(git_remote_pushurl(_remote) == NULL); + + cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, &callbacks)); + cl_assert_equal_s(url.ptr, "fetch_url"); + + cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, &callbacks)); + cl_assert_equal_s(url.ptr, "push_url"); + + git_buf_dispose(&url); +} + static int urlresolve_callback(git_buf *url_resolved, const char *url, int direction, void *payload) { cl_assert(strcmp(url, "git://github.com/libgit2/libgit2") == 0); diff --git a/tests/online/push_util.h b/tests/online/push_util.h index d829bbc4ad7..5f669feaf0c 100644 --- a/tests/online/push_util.h +++ b/tests/online/push_util.h @@ -12,7 +12,7 @@ extern const git_oid OID_ZERO; * @param data pointer to a record_callbacks_data instance */ #define RECORD_CALLBACKS_INIT(data) \ - { GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, NULL, data, NULL } + { GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, NULL, NULL, data, NULL } typedef struct { char *name; From 7442c000d95faffd9a2f44d5822101525eb8d0d9 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 27 Aug 2021 11:25:51 -0400 Subject: [PATCH 0476/1616] remote: deprecate resolve_url callback Using a callback to set a resolve_url is not particularly idiomatic. Deprecate it in favor of the `set_instance_url` and `set_instance_pushurl` functions which can now be called from the `git_remote_ready_cb` callback. --- include/git2/remote.h | 10 ++++++++++ src/remote.c | 19 ++++++++++++++++--- tests/network/remote/remotes.c | 8 ++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/git2/remote.h b/include/git2/remote.h index b75a9911c35..1f52fcd949c 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -499,6 +499,7 @@ typedef int GIT_CALLBACK(git_push_negotiation)(const git_push_update **updates, */ typedef int GIT_CALLBACK(git_push_update_reference_cb)(const char *refname, const char *status, void *data); +#ifndef GIT_DEPRECATE_HARD /** * Callback to resolve URLs before connecting to remote * @@ -510,8 +511,10 @@ typedef int GIT_CALLBACK(git_push_update_reference_cb)(const char *refname, cons * @param direction GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH * @param payload Payload provided by the caller * @return 0 on success, GIT_PASSTHROUGH or an error + * @deprecated Use `git_remote_set_instance_url` */ typedef int GIT_CALLBACK(git_url_resolve_cb)(git_buf *url_resolved, const char *url, int direction, void *payload); +#endif /** * Callback invoked immediately before we attempt to connect to the @@ -620,11 +623,18 @@ struct git_remote_callbacks { */ void *payload; +#ifdef GIT_DEPRECATE_HARD + void *reserved; +#else /** * Resolve URL before connecting to remote. * The returned URL will be used to connect to the remote instead. + * + * This callback is deprecated; users should use + * git_remote_ready_cb and configure the instance URL instead. */ git_url_resolve_cb resolve_url; +#endif }; #define GIT_REMOTE_CALLBACKS_VERSION 1 diff --git a/src/remote.c b/src/remote.c index 8050e65f311..73375b35288 100644 --- a/src/remote.c +++ b/src/remote.c @@ -682,8 +682,16 @@ int git_remote_set_pushurl(git_repository *repo, const char *remote, const char* return set_url(repo, remote, CONFIG_PUSHURL_FMT, url); } -static int resolve_url(git_buf *resolved_url, const char *url, int direction, const git_remote_callbacks *callbacks) -{ +static int resolve_url( + git_buf *resolved_url, + const char *url, + int direction, + const git_remote_callbacks *callbacks) +{ +#ifdef GIT_DEPRECATE_HARD + GIT_UNUSED(direction); + GIT_UNUSED(callbacks); +#else int status, error; if (callbacks && callbacks->resolve_url) { @@ -698,11 +706,16 @@ static int resolve_url(git_buf *resolved_url, const char *url, int direction, co return status; } } +#endif return git_buf_sets(resolved_url, url); } -int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int direction, const git_remote_callbacks *callbacks) +int git_remote__urlfordirection( + git_buf *url_out, + struct git_remote *remote, + int direction, + const git_remote_callbacks *callbacks) { const char *url = NULL; diff --git a/tests/network/remote/remotes.c b/tests/network/remote/remotes.c index 4a9f5ae7268..ed6a890751f 100644 --- a/tests/network/remote/remotes.c +++ b/tests/network/remote/remotes.c @@ -98,6 +98,7 @@ void test_network_remote_remotes__remote_ready(void) git_buf_dispose(&url); } +#ifndef GIT_DEPRECATE_HARD static int urlresolve_callback(git_buf *url_resolved, const char *url, int direction, void *payload) { cl_assert(strcmp(url, "git://github.com/libgit2/libgit2") == 0); @@ -111,9 +112,11 @@ static int urlresolve_callback(git_buf *url_resolved, const char *url, int direc return GIT_OK; } +#endif void test_network_remote_remotes__urlresolve(void) { +#ifndef GIT_DEPRECATE_HARD git_buf url = GIT_BUF_INIT; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; @@ -131,8 +134,10 @@ void test_network_remote_remotes__urlresolve(void) cl_assert_equal_s(url.ptr, "pushresolve"); git_buf_dispose(&url); +#endif } +#ifndef GIT_DEPRECATE_HARD static int urlresolve_passthrough_callback(git_buf *url_resolved, const char *url, int direction, void *payload) { GIT_UNUSED(url_resolved); @@ -141,9 +146,11 @@ static int urlresolve_passthrough_callback(git_buf *url_resolved, const char *ur GIT_UNUSED(payload); return GIT_PASSTHROUGH; } +#endif void test_network_remote_remotes__urlresolve_passthrough(void) { +#ifndef GIT_DEPRECATE_HARD git_buf url = GIT_BUF_INIT; const char *orig_url = "git://github.com/libgit2/libgit2"; @@ -161,6 +168,7 @@ void test_network_remote_remotes__urlresolve_passthrough(void) cl_assert_equal_s(url.ptr, orig_url); git_buf_dispose(&url); +#endif } void test_network_remote_remotes__instance_url(void) From 5bcef522f382042c68d6a7577ec67732687305f2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 27 Aug 2021 17:06:50 -0400 Subject: [PATCH 0477/1616] filter: deprecate apply function --- include/git2/sys/filter.h | 8 ++++++++ src/filter.c | 41 ++++++++++++++++++++++++++------------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/include/git2/sys/filter.h b/include/git2/sys/filter.h index 098f8f7d3df..b3759416a1d 100644 --- a/include/git2/sys/filter.h +++ b/include/git2/sys/filter.h @@ -178,6 +178,7 @@ typedef int GIT_CALLBACK(git_filter_check_fn)( const git_filter_source *src, const char **attr_values); +#ifndef GIT_DEPRECATE_HARD /** * Callback to actually perform the data filtering * @@ -189,6 +190,8 @@ typedef int GIT_CALLBACK(git_filter_check_fn)( * * The `payload` value will refer to any payload that was set by the * `check` callback. It may be read from or written to as needed. + * + * @deprecated use git_filter_stream_fn */ typedef int GIT_CALLBACK(git_filter_apply_fn)( git_filter *self, @@ -196,6 +199,7 @@ typedef int GIT_CALLBACK(git_filter_apply_fn)( git_buf *to, const git_buf *from, const git_filter_source *src); +#endif /** * Callback to perform the data filtering. @@ -263,12 +267,16 @@ struct git_filter { */ git_filter_check_fn check; +#ifdef GIT_DEPRECATE_HARD + void *reserved; +#else /** * Provided for backward compatibility; this will apply the * filter to the given contents in a `git_buf`. Callers should * provide a `stream` function instead. */ git_filter_apply_fn apply; +#endif /** * Called to apply the filter, this function will provide a diff --git a/src/filter.c b/src/filter.c index 21ae2716728..f1d9614060a 100644 --- a/src/filter.c +++ b/src/filter.c @@ -939,6 +939,32 @@ int git_filter_buffered_stream_new( return 0; } +static int setup_stream( + git_writestream **out, + git_filter_entry *fe, + git_filter_list *filters, + git_writestream *last_stream) +{ +#ifndef GIT_DEPRECATE_HARD + GIT_ASSERT(fe->filter->stream || fe->filter->apply); + + /* + * If necessary, create a stream that proxies the traditional + * application. + */ + if (!fe->filter->stream) { + /* Create a stream that proxies the one-shot apply */ + return git_filter_buffered_stream_new(out, + fe->filter, fe->filter->apply, filters->temp_buf, + &fe->payload, &filters->source, last_stream); + } +#endif + + GIT_ASSERT(fe->filter->stream); + return fe->filter->stream(out, fe->filter, + &fe->payload, &filters->source, last_stream); +} + static int stream_list_init( git_writestream **out, git_vector *streams, @@ -960,22 +986,11 @@ static int stream_list_init( for (i = 0; i < git_array_size(filters->filters); ++i) { size_t filter_idx = (filters->source.mode == GIT_FILTER_TO_WORKTREE) ? git_array_size(filters->filters) - 1 - i : i; + git_filter_entry *fe = git_array_get(filters->filters, filter_idx); git_writestream *filter_stream; - GIT_ASSERT(fe->filter->stream || fe->filter->apply); - - /* If necessary, create a stream that proxies the traditional - * application. - */ - if (fe->filter->stream) - error = fe->filter->stream(&filter_stream, fe->filter, - &fe->payload, &filters->source, last_stream); - else - /* Create a stream that proxies the one-shot apply */ - error = git_filter_buffered_stream_new(&filter_stream, - fe->filter, fe->filter->apply, filters->temp_buf, - &fe->payload, &filters->source, last_stream); + error = setup_stream(&filter_stream, fe, filters, last_stream); if (error < 0) goto out; From d2316d574694a1943499553c535fa3830c198380 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 29 Aug 2021 13:10:44 -0400 Subject: [PATCH 0478/1616] buf: deprecate public git_buf writing functions A `git_buf` is now a read-only structure as far as callers are concerned. This is a mechanism that we can return data to callers using memory that is owned by the library and can be cleaned up by callers (using `git_buf_dispose`). A `git_buf` can no longer be allocated by callers or provided to the library. --- include/git2/deprecated.h | 55 ++++++++++++++++++++++++++++++++++++ src/buffer.h | 59 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index ac60488acb6..739f0b53f97 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -191,6 +191,61 @@ GIT_EXTERN(int) git_treebuilder_write_with_buffer( */ /**@{*/ +/** + * Static initializer for git_buf from static buffer + */ +#define GIT_BUF_INIT_CONST(STR,LEN) { (char *)(STR), 0, (size_t)(LEN) } + +/** + * Resize the buffer allocation to make more space. + * + * This will attempt to grow the buffer to accommodate the target size. + * + * If the buffer refers to memory that was not allocated by libgit2 (i.e. + * the `asize` field is zero), then `ptr` will be replaced with a newly + * allocated block of data. Be careful so that memory allocated by the + * caller is not lost. As a special variant, if you pass `target_size` as + * 0 and the memory is not allocated by libgit2, this will allocate a new + * buffer of size `size` and copy the external data into it. + * + * Currently, this will never shrink a buffer, only expand it. + * + * If the allocation fails, this will return an error and the buffer will be + * marked as invalid for future operations, invaliding the contents. + * + * @param buffer The buffer to be resized; may or may not be allocated yet + * @param target_size The desired available size + * @return 0 on success, -1 on allocation failure + */ +GIT_EXTERN(int) git_buf_grow(git_buf *buffer, size_t target_size); + +/** + * Set buffer to a copy of some raw data. + * + * @param buffer The buffer to set + * @param data The data to copy into the buffer + * @param datalen The length of the data to copy into the buffer + * @return 0 on success, -1 on allocation failure + */ +GIT_EXTERN(int) git_buf_set( + git_buf *buffer, const void *data, size_t datalen); + +/** +* Check quickly if buffer looks like it contains binary data +* +* @param buf Buffer to check +* @return 1 if buffer looks like non-text data +*/ +GIT_EXTERN(int) git_buf_is_binary(const git_buf *buf); + +/** +* Check quickly if buffer contains a NUL byte +* +* @param buf Buffer to check +* @return 1 if buffer contains a NUL byte +*/ +GIT_EXTERN(int) git_buf_contains_nul(const git_buf *buf); + /** * Free the memory referred to by the git_buf. This is an alias of * `git_buf_dispose` and is preserved for backward compatibility. diff --git a/src/buffer.h b/src/buffer.h index d043ed62609..7faa9fdc801 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -38,6 +38,13 @@ extern char git_buf__oom[]; /* Use to initialize buffer structure when git_buf is on stack */ #define GIT_BUF_INIT { git_buf__initbuf, 0, 0 } +/** + * Static initializer for git_buf from static buffer + */ +#ifdef GIT_DEPRECATE_HARD +# define GIT_BUF_INIT_CONST(STR,LEN) { (char *)(STR), 0, (size_t)(LEN) } +#endif + GIT_INLINE(bool) git_buf_is_allocated(const git_buf *buf) { return (buf->ptr != NULL && buf->asize > 0); @@ -51,6 +58,33 @@ GIT_INLINE(bool) git_buf_is_allocated(const git_buf *buf) */ extern int git_buf_init(git_buf *buf, size_t initial_size); +#ifdef GIT_DEPRECATE_HARD + +/** + * Resize the buffer allocation to make more space. + * + * This will attempt to grow the buffer to accommodate the target size. + * + * If the buffer refers to memory that was not allocated by libgit2 (i.e. + * the `asize` field is zero), then `ptr` will be replaced with a newly + * allocated block of data. Be careful so that memory allocated by the + * caller is not lost. As a special variant, if you pass `target_size` as + * 0 and the memory is not allocated by libgit2, this will allocate a new + * buffer of size `size` and copy the external data into it. + * + * Currently, this will never shrink a buffer, only expand it. + * + * If the allocation fails, this will return an error and the buffer will be + * marked as invalid for future operations, invaliding the contents. + * + * @param buffer The buffer to be resized; may or may not be allocated yet + * @param target_size The desired available size + * @return 0 on success, -1 on allocation failure + */ +int git_buf_grow(git_buf *buffer, size_t target_size); + +#endif + /** * Resize the buffer allocation to make more space. * @@ -120,6 +154,11 @@ GIT_INLINE(bool) git_buf_oom(const git_buf *buf) * return code of these functions and call them in a series then just call * git_buf_oom at the end. */ + +#ifdef GIT_DEPRECATE_HARD +int git_buf_set(git_buf *buffer, const void *data, size_t datalen); +#endif + int git_buf_sets(git_buf *buf, const char *string); int git_buf_putc(git_buf *buf, char c); int git_buf_putcn(git_buf *buf, char c, size_t len); @@ -311,4 +350,24 @@ extern int git_buf_detect_bom(git_buf_bom_t *bom, const git_buf *buf); extern bool git_buf_gather_text_stats( git_buf_text_stats *stats, const git_buf *buf, bool skip_bom); +#ifdef GIT_DEPRECATE_HARD + +/** +* Check quickly if buffer looks like it contains binary data +* +* @param buf Buffer to check +* @return 1 if buffer looks like non-text data +*/ +int git_buf_is_binary(const git_buf *buf); + +/** +* Check quickly if buffer contains a NUL byte +* +* @param buf Buffer to check +* @return 1 if buffer contains a NUL byte +*/ +int git_buf_contains_nul(const git_buf *buf); + +#endif + #endif From a5d6a5768f5537ef0a408cf51ce8c13742412041 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 29 Aug 2021 13:21:40 -0400 Subject: [PATCH 0479/1616] ci: stop on test failure --- ci/test.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ci/test.sh b/ci/test.sh index 2b43ba19863..da3c01c2f35 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -17,6 +17,7 @@ TMPDIR=${TMPDIR:-/tmp} USER=${USER:-$(whoami)} SUCCESS=1 +CONTINUE_ON_FAILURE=0 cleanup() { echo "Cleaning up..." @@ -64,6 +65,10 @@ run_test() { done if [ "$FAILED" -ne 0 ]; then + if [ "$CONTINUE_ON_FAILURE" -ne 1 ]; then + exit 1 + fi + SUCCESS=0 fi } From aebdee8e3d2871ef4606f1feb0f46a82cfca1373 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 29 Aug 2021 21:49:26 -0400 Subject: [PATCH 0480/1616] Update include/git2/checkout.h --- include/git2/checkout.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/git2/checkout.h b/include/git2/checkout.h index d4c1cfa0b84..e0069b66110 100644 --- a/include/git2/checkout.h +++ b/include/git2/checkout.h @@ -177,7 +177,10 @@ typedef enum { /** Normally checkout writes the index upon completion; this prevents that. */ GIT_CHECKOUT_DONT_WRITE_INDEX = (1u << 23), - /** Stop checkout after the notifications happend but before the working directory is touched. */ + /** + * Show what would be done by a checkout. Stop after sending + * notifications; don't update the working directory or index. + */ GIT_CHECKOUT_DRY_RUN = (1u << 24), /** From 0e0472686680102ebfc81e85089273990fb86757 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 25 Aug 2021 18:01:34 -0400 Subject: [PATCH 0481/1616] opts: test GIT_OPT_SET_SSL_CERT_LOCATIONS Include a self-signed certificate for test.libgit2.org:1443 that we can use to verify that GIT_OPT_SET_SSL_CERT_LOCATIONS works. --- ci/test.sh | 14 ++++-- tests/CMakeLists.txt | 3 +- tests/online/clone.c | 2 + tests/online/customcert.c | 79 ++++++++++++++++++++++++++++++++ tests/resources/certs/61f2ddb6.0 | 31 +++++++++++++ tests/resources/certs/db4f60b0.0 | 31 +++++++++++++ tests/resources/self-signed.pem | 20 ++++++++ 7 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 tests/online/customcert.c create mode 100644 tests/resources/certs/61f2ddb6.0 create mode 100644 tests/resources/certs/db4f60b0.0 create mode 100644 tests/resources/self-signed.pem diff --git a/ci/test.sh b/ci/test.sh index da3c01c2f35..4d6c41f7675 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -179,9 +179,9 @@ if [ -n "$RUN_INVASIVE_TESTS" ]; then fi if [ -z "$SKIP_ONLINE_TESTS" ]; then - # Run the various online tests. The "online" test suite only includes the - # default online tests that do not require additional configuration. The - # "proxy" and "ssh" test suites require further setup. + # Run the online tests. The "online" test suite only includes the + # default online tests that do not require additional configuration. + # The "proxy" and "ssh" test suites require further setup. echo "" echo "##############################################################################" @@ -191,6 +191,14 @@ if [ -z "$SKIP_ONLINE_TESTS" ]; then export GITTEST_FLAKY_RETRY=5 run_test online unset GITTEST_FLAKY_RETRY + + # Run the online tests that immutably change global state separately + # to avoid polluting the test environment. + echo "" + echo "##############################################################################" + echo "## Running (online_customcert) tests" + echo "##############################################################################" + run_test online_customcert fi if [ -z "$SKIP_GITDAEMON_TESTS" ]; then diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 600c617e8e4..49999f4815e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -64,7 +64,8 @@ ENDFUNCTION(ADD_CLAR_TEST) ADD_CLAR_TEST(offline -v -xonline) ADD_CLAR_TEST(invasive -v -score::ftruncate -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root) -ADD_CLAR_TEST(online -v -sonline) +ADD_CLAR_TEST(online -v -sonline -xonline::customcert) +ADD_CLAR_TEST(online_customcert -v -sonline::customcert) ADD_CLAR_TEST(gitdaemon -v -sonline::push) ADD_CLAR_TEST(ssh -v -sonline::push -sonline::clone::ssh_cert -sonline::clone::ssh_with_paths -sonline::clone::path_whitespace_ssh) ADD_CLAR_TEST(proxy -v -sonline::clone::proxy) diff --git a/tests/online/clone.c b/tests/online/clone.c index 6de687b3503..dbf45dcb3e4 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -114,6 +114,8 @@ void test_online_clone__cleanup(void) git__free(_orig_http_proxy); git__free(_orig_https_proxy); } + + git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, NULL, NULL); } void test_online_clone__network_full(void) diff --git a/tests/online/customcert.c b/tests/online/customcert.c new file mode 100644 index 00000000000..c7a0de1a18e --- /dev/null +++ b/tests/online/customcert.c @@ -0,0 +1,79 @@ +#include "clar_libgit2.h" + +#include "path.h" +#include "git2/clone.h" +#include "git2/cred_helpers.h" +#include "remote.h" +#include "futils.h" +#include "refs.h" + +/* + * Certificate one is in the `certs` folder; certificate two is in the + * `self-signed.pem` file. + */ +#define CUSTOM_CERT_ONE_URL "https://test.libgit2.org:1443/anonymous/test.git" +#define CUSTOM_CERT_ONE_PATH "certs" + +#define CUSTOM_CERT_TWO_URL "https://test.libgit2.org:2443/anonymous/test.git" +#define CUSTOM_CERT_TWO_FILE "self-signed.pem" + +#if (GIT_OPENSSL || GIT_MBEDTLS) +static git_repository *g_repo; +static int initialized = false; +#endif + +void test_online_customcert__initialize(void) +{ +#if (GIT_OPENSSL || GIT_MBEDTLS) + g_repo = NULL; + + if (!initialized) { + git_buf path = GIT_BUF_INIT, file = GIT_BUF_INIT; + char cwd[GIT_PATH_MAX]; + + cl_fixture_sandbox(CUSTOM_CERT_ONE_PATH); + cl_fixture_sandbox(CUSTOM_CERT_TWO_FILE); + + cl_must_pass(p_getcwd(cwd, GIT_PATH_MAX)); + cl_git_pass(git_buf_joinpath(&path, cwd, CUSTOM_CERT_ONE_PATH)); + cl_git_pass(git_buf_joinpath(&file, cwd, CUSTOM_CERT_TWO_FILE)); + + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, + file.ptr, path.ptr)); + initialized = true; + + git_buf_dispose(&file); + git_buf_dispose(&path); + } +#endif +} + +void test_online_customcert__cleanup(void) +{ +#if (GIT_OPENSSL || GIT_MBEDTLS) + if (g_repo) { + git_repository_free(g_repo); + g_repo = NULL; + } + + cl_fixture_cleanup("./cloned"); + cl_fixture_cleanup(CUSTOM_CERT_ONE_PATH); + cl_fixture_cleanup(CUSTOM_CERT_TWO_FILE); +#endif +} + +void test_online_customcert__file(void) +{ +#if (GIT_OPENSSL || GIT_MBEDTLS) + cl_git_pass(git_clone(&g_repo, CUSTOM_CERT_ONE_URL, "./cloned", NULL)); + cl_assert(git_path_exists("./cloned/master.txt")); +#endif +} + +void test_online_customcert__path(void) +{ +#if (GIT_OPENSSL || GIT_MBEDTLS) + cl_git_pass(git_clone(&g_repo, CUSTOM_CERT_TWO_URL, "./cloned", NULL)); + cl_assert(git_path_exists("./cloned/master.txt")); +#endif +} diff --git a/tests/resources/certs/61f2ddb6.0 b/tests/resources/certs/61f2ddb6.0 new file mode 100644 index 00000000000..7d9ef6fce2a --- /dev/null +++ b/tests/resources/certs/61f2ddb6.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWzCCA0MCFESY816VkhBPUOsdp7djKW5q4ZVzMA0GCSqGSIb3DQEBCwUAMGox +CzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMRIwEAYDVQQHDAlD +YW1icmlkZ2UxFDASBgNVBAoMC2xpYmdpdDIub3JnMRkwFwYDVQQDDBB0ZXN0Lmxp +YmdpdDIub3JnMB4XDTIxMDgyNTE4NTExMVoXDTMxMDgyMzE4NTExMVowajELMAkG +A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJy +aWRnZTEUMBIGA1UECgwLbGliZ2l0Mi5vcmcxGTAXBgNVBAMMEHRlc3QubGliZ2l0 +Mi5vcmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvaRUaM3IJh9N +G6Yc7tHioUsIGU0MkzSvy/X6O/vONnuuioiJQyPIvfRSvZR2iQj8THTypDGhWn3r +6h2wk5eOUGwJH2N9FrrlEBdpsMc7SKdiJXwTI30mkK3/qru8NzE71dgCkYp1xhKw +edTkAFK+PkvyVLFL7K35cx8Bxfamyssdb+qGWa7g4P27CWUdvQgmurrzzPIMZiLD +/cI1Kwer/N7nTY/6CSs9dcHTlanyZdf+mQ50+//vI4F6+OduGHJkxRF48jLUz1rz +P3WGRMRbHjCmvWpX/9DLgqGk7XTy0hNgNUCit6kawwcv5y7SP/ii86MkynAHn5i8 +d+zhXjdrSSy8i0IbRJafnxmtrsmjGeIzraJSRqMlv7KKWEBz+alm6vlePnRUbWB7 +0po5uSsRPya6kJJCzMjIfKq1dgXq33m9jCG2wU+L4fEHVlEkFGXYTspMlIBNUjTc +c45+e1EpamF8aHm32PP8gTF8fGZzQjOXmNW5g7t0joWMGZ+Ao2jYc1pG3SOARi36 +azrmB5/XJqbbfVZEzIue01fO/5R8RgabOP1qWUjH2KLb8zTDok+CW0ULNseU+MKf +PHXG2OjxcR0vTqop2V6JlKTXXx3/TOD16/+mSrrPzNDejLrkvAH9oN38YpMBM8eg +vfivHNRm0jjdGbv2OOPEBLEf1cNimQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQBZ +znFta24sWoqdgKXKAK5RHAh/HyOvTInwcXi9RU4XjYlbqNVs0ODR74VRZINoyAL2 +bo+x/iUuAp9+b8fjr79fpVof3nSMU7UtMcT1nvzVmaUYSkKQ0f/9vK4yg0kao1bV +WwhIc0slKgOJjEicPVs3kd+duv5vakQeUajLPGM8SiS1F/nF67rIuZLdJn2Qp+im +w5Q3Pjgqw5VrJxyk3AaUcntKHpWy1POLyNV79tXra6BxbtQVlRS0+h1MHELARDFx +1ZtgyAe5YbWM7WrIiFKD4mmKZu4GMnJDXVpfUub5g0U/e7L/gg6Z1UyYZuln6axw +RojuAHo1uAWFUsjhWLYV/7P/l/dC+7gFjvSsUqb1+U7jXObzfKjXo/FwYcy4VsVv +xNbglbhdVjAo/YBTJuf3L0UZjSbxvQIYS+v8u1ECeWE6SH6cHRzryeo5wO4h8NJR +n30xsvocHFbs4LWy5BVfMUo6wGUy0Y+1gSwSqVMv3JPuLwxUsv0HPdeC00Ab9cHq +kYXPNZXg3a6orTDa4hJLdAm2V/fn/2KKJYlNj7iCL664QgoCHl7LFyLMiwFVCu5h +4JjGL3Q+8MondaLZlq5YDmvtj979AyM/7qL4XAE2oofQ4J5dqnKKpMkWdAM/fI/9 +N5DK/4zMXJWgIED0yo2SSZHQmuqZplacOhmfjjZigQ== +-----END CERTIFICATE----- diff --git a/tests/resources/certs/db4f60b0.0 b/tests/resources/certs/db4f60b0.0 new file mode 100644 index 00000000000..7d9ef6fce2a --- /dev/null +++ b/tests/resources/certs/db4f60b0.0 @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWzCCA0MCFESY816VkhBPUOsdp7djKW5q4ZVzMA0GCSqGSIb3DQEBCwUAMGox +CzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMRIwEAYDVQQHDAlD +YW1icmlkZ2UxFDASBgNVBAoMC2xpYmdpdDIub3JnMRkwFwYDVQQDDBB0ZXN0Lmxp +YmdpdDIub3JnMB4XDTIxMDgyNTE4NTExMVoXDTMxMDgyMzE4NTExMVowajELMAkG +A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJy +aWRnZTEUMBIGA1UECgwLbGliZ2l0Mi5vcmcxGTAXBgNVBAMMEHRlc3QubGliZ2l0 +Mi5vcmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvaRUaM3IJh9N +G6Yc7tHioUsIGU0MkzSvy/X6O/vONnuuioiJQyPIvfRSvZR2iQj8THTypDGhWn3r +6h2wk5eOUGwJH2N9FrrlEBdpsMc7SKdiJXwTI30mkK3/qru8NzE71dgCkYp1xhKw +edTkAFK+PkvyVLFL7K35cx8Bxfamyssdb+qGWa7g4P27CWUdvQgmurrzzPIMZiLD +/cI1Kwer/N7nTY/6CSs9dcHTlanyZdf+mQ50+//vI4F6+OduGHJkxRF48jLUz1rz +P3WGRMRbHjCmvWpX/9DLgqGk7XTy0hNgNUCit6kawwcv5y7SP/ii86MkynAHn5i8 +d+zhXjdrSSy8i0IbRJafnxmtrsmjGeIzraJSRqMlv7KKWEBz+alm6vlePnRUbWB7 +0po5uSsRPya6kJJCzMjIfKq1dgXq33m9jCG2wU+L4fEHVlEkFGXYTspMlIBNUjTc +c45+e1EpamF8aHm32PP8gTF8fGZzQjOXmNW5g7t0joWMGZ+Ao2jYc1pG3SOARi36 +azrmB5/XJqbbfVZEzIue01fO/5R8RgabOP1qWUjH2KLb8zTDok+CW0ULNseU+MKf +PHXG2OjxcR0vTqop2V6JlKTXXx3/TOD16/+mSrrPzNDejLrkvAH9oN38YpMBM8eg +vfivHNRm0jjdGbv2OOPEBLEf1cNimQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQBZ +znFta24sWoqdgKXKAK5RHAh/HyOvTInwcXi9RU4XjYlbqNVs0ODR74VRZINoyAL2 +bo+x/iUuAp9+b8fjr79fpVof3nSMU7UtMcT1nvzVmaUYSkKQ0f/9vK4yg0kao1bV +WwhIc0slKgOJjEicPVs3kd+duv5vakQeUajLPGM8SiS1F/nF67rIuZLdJn2Qp+im +w5Q3Pjgqw5VrJxyk3AaUcntKHpWy1POLyNV79tXra6BxbtQVlRS0+h1MHELARDFx +1ZtgyAe5YbWM7WrIiFKD4mmKZu4GMnJDXVpfUub5g0U/e7L/gg6Z1UyYZuln6axw +RojuAHo1uAWFUsjhWLYV/7P/l/dC+7gFjvSsUqb1+U7jXObzfKjXo/FwYcy4VsVv +xNbglbhdVjAo/YBTJuf3L0UZjSbxvQIYS+v8u1ECeWE6SH6cHRzryeo5wO4h8NJR +n30xsvocHFbs4LWy5BVfMUo6wGUy0Y+1gSwSqVMv3JPuLwxUsv0HPdeC00Ab9cHq +kYXPNZXg3a6orTDa4hJLdAm2V/fn/2KKJYlNj7iCL664QgoCHl7LFyLMiwFVCu5h +4JjGL3Q+8MondaLZlq5YDmvtj979AyM/7qL4XAE2oofQ4J5dqnKKpMkWdAM/fI/9 +N5DK/4zMXJWgIED0yo2SSZHQmuqZplacOhmfjjZigQ== +-----END CERTIFICATE----- diff --git a/tests/resources/self-signed.pem b/tests/resources/self-signed.pem new file mode 100644 index 00000000000..e13417e483a --- /dev/null +++ b/tests/resources/self-signed.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUzCCAjsCFAb11im6DYQyGJ0GNQCIehXtegq6MA0GCSqGSIb3DQEBCwUAMGYx +CzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMRIwEAYDVQQHDAlD +YW1icmlkZ2UxEDAOBgNVBAoMB2xpYmdpdDIxGTAXBgNVBAMMEHRlc3QubGliZ2l0 +Mi5vcmcwHhcNMjEwODMwMDAyMTQyWhcNMzEwODI4MDAyMTQyWjBmMQswCQYDVQQG +EwJVUzEWMBQGA1UECAwNTWFzc2FjaHVzZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdl +MRAwDgYDVQQKDAdsaWJnaXQyMRkwFwYDVQQDDBB0ZXN0LmxpYmdpdDIub3JnMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtqe6b1vnMni+z8Z+a2bGtykI +ITvBged15rn+0qG6Fz+sn9bYG+ceFupztFfoN3cVpUgQDBTzr3CaAx036BlV0z8i +CrG0Oh/XGL+9TITQLumEe4iGi8NoMSujBAyXPSNgmpzDmCTGrNFfmq3HzUtO8t3x +i8OT7d9qCVjFimLvZbgnfHGQ38xvt1XyPgYIVqDQczmMEZ5BdYWB0A1VmnWuP2dH +BgjwPEC3HwMmm1+PL0VoPTdvE5Su092Qdt8QsiA56466DQyll1d/omnOJfrK7z0N +OnfDmnDpARSTy6vDofEAYUQoc3dyvBUk8IIzv2UDcR7fTVvYqseQReIOTEnXmQID +AQABMA0GCSqGSIb3DQEBCwUAA4IBAQBmUEq+JhwWTbB5ODGOKrMG1fKJ+sf6ZH6M +c4BgLEcdoi/nOTfPuw+ols72LuhH7NKaEcqxWev0jGF0WKqMcM8AGVbywZJ3mBWo +sKdh6rAGFNkikW4TzhjtDfFbMR45Didl28Be7ieHQL4CQ0Lse3RMOxp250WpiEYV +W2hIKMwIqOLKGShVD7lI+eHlv+QSH4yOYKHfRHve8s82Tac5OXinc8CJm9ySOtkO +MfLgfkHtHdFBnV6OVbf4p/596MfMXdwT/bBxT6WPkDGc1AYhoDlmLFTpRgHIDCSK +2wgV+qHppl7Kn+p3mFQ9sW/1IaRd+jNZOrgZ8Uu5tJ00OaqR/LVG +-----END CERTIFICATE----- From cdb9f3903ef650a5289ea944770ba38d688e5899 Mon Sep 17 00:00:00 2001 From: Zachary Michaels Date: Tue, 24 Aug 2021 17:37:15 -0700 Subject: [PATCH 0482/1616] mbedTLS: Fix setting certificate directory fixes #6003 --- src/libgit2.c | 5 +---- src/streams/mbedtls.c | 17 +++++++---------- src/streams/mbedtls.h | 2 +- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/libgit2.c b/src/libgit2.c index aee9cf2cdeb..09f7ab533c8 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -261,10 +261,7 @@ int git_libgit2_opts(int key, ...) { const char *file = va_arg(ap, const char *); const char *path = va_arg(ap, const char *); - if (file) - error = git_mbedtls__set_cert_location(file, 0); - if (error && path) - error = git_mbedtls__set_cert_location(path, 1); + error = git_mbedtls__set_cert_location(file, path); } #else git_error_set(GIT_ERROR_SSL, "TLS backend doesn't support certificate locations"); diff --git a/src/streams/mbedtls.c b/src/streams/mbedtls.c index 22b9f47df55..b3a35ab0200 100644 --- a/src/streams/mbedtls.c +++ b/src/streams/mbedtls.c @@ -68,8 +68,6 @@ static void shutdown_ssl(void) } } -int git_mbedtls__set_cert_location(const char *path, int is_dir); - int git_mbedtls_stream_global_init(void) { int loaded = 0; @@ -148,9 +146,9 @@ int git_mbedtls_stream_global_init(void) /* load default certificates */ if (crtpath != NULL && stat(crtpath, &statbuf) == 0 && S_ISREG(statbuf.st_mode)) - loaded = (git_mbedtls__set_cert_location(crtpath, 0) == 0); + loaded = (git_mbedtls__set_cert_location(crtpath, NULL) == 0); if (!loaded && crtpath != NULL && stat(crtpath, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) - loaded = (git_mbedtls__set_cert_location(crtpath, 1) == 0); + loaded = (git_mbedtls__set_cert_location(NULL, crtpath) == 0); return git_runtime_shutdown_register(shutdown_ssl); @@ -438,23 +436,22 @@ int git_mbedtls_stream_new( return error; } -int git_mbedtls__set_cert_location(const char *path, int is_dir) +int git_mbedtls__set_cert_location(const char *file, const char *path) { int ret = 0; char errbuf[512]; mbedtls_x509_crt *cacert; - GIT_ASSERT_ARG(path); + GIT_ASSERT_ARG(file || path); cacert = git__malloc(sizeof(mbedtls_x509_crt)); GIT_ERROR_CHECK_ALLOC(cacert); mbedtls_x509_crt_init(cacert); - if (is_dir) { + if (file) + ret = mbedtls_x509_crt_parse_file(cacert, file); + if (ret >= 0 && path) ret = mbedtls_x509_crt_parse_path(cacert, path); - } else { - ret = mbedtls_x509_crt_parse_file(cacert, path); - } /* mbedtls_x509_crt_parse_path returns the number of invalid certs on success */ if (ret < 0) { mbedtls_x509_crt_free(cacert); diff --git a/src/streams/mbedtls.h b/src/streams/mbedtls.h index 7de94b9fbcc..bcca6dd401a 100644 --- a/src/streams/mbedtls.h +++ b/src/streams/mbedtls.h @@ -14,7 +14,7 @@ extern int git_mbedtls_stream_global_init(void); #ifdef GIT_MBEDTLS -extern int git_mbedtls__set_cert_location(const char *path, int is_dir); +extern int git_mbedtls__set_cert_location(const char *file, const char *path); extern int git_mbedtls_stream_new(git_stream **out, const char *host, const char *port); extern int git_mbedtls_stream_wrap(git_stream **out, git_stream *in, const char *host); From 2bd3c80e7c30371e2d412b463f758d95bcefd6bc Mon Sep 17 00:00:00 2001 From: Dmitry Lobanov Date: Mon, 30 Aug 2021 11:41:11 +0300 Subject: [PATCH 0483/1616] include: stdint header condition has been reverted. --- include/git2/stdint.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/git2/stdint.h b/include/git2/stdint.h index c66fbb817c0..6950427d2d0 100644 --- a/include/git2/stdint.h +++ b/include/git2/stdint.h @@ -29,9 +29,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] +#ifdef _MSC_VER // [ #ifndef _MSC_STDINT_H_ // [ #define _MSC_STDINT_H_ @@ -245,3 +243,5 @@ typedef uint64_t uintmax_t; #endif // _MSC_STDINT_H_ ] + +#endif // _MSC_VER ] \ No newline at end of file From 5eb2b0b31b8994265a5125595a5830bb0981b3c6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 30 Aug 2021 08:27:27 -0400 Subject: [PATCH 0484/1616] httpclient: actually return `GIT_EAUTH` --- src/transports/httpclient.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index 4612b43344e..d40c1627ca0 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -598,7 +598,6 @@ static int apply_credentials( } else if (!token.size) { git_error_set(GIT_ERROR_HTTP, "failed to respond to authentication challenge"); error = GIT_EAUTH; - error = -1; goto done; } From e7eb6c6bb024f0735798494f4e070b370d8caf8b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 30 Aug 2021 08:28:56 -0400 Subject: [PATCH 0485/1616] midx: return an error when detected --- src/midx.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/midx.c b/src/midx.c index 9aab8b58890..6a885eddca5 100644 --- a/src/midx.c +++ b/src/midx.c @@ -714,8 +714,10 @@ static int midx_write( error = git_vector_init(&object_entries, git_array_size(object_entries_array), object_entry__cmp); if (error < 0) goto cleanup; - git_array_foreach (object_entries_array, i, entry) - error = git_vector_set(NULL, &object_entries, i, entry); + git_array_foreach (object_entries_array, i, entry) { + if ((error = git_vector_set(NULL, &object_entries, i, entry)) < 0) + goto cleanup; + } git_vector_set_sorted(&object_entries, 0); git_vector_sort(&object_entries); git_vector_uniq(&object_entries, NULL); @@ -751,10 +753,12 @@ static int midx_write( goto cleanup; if (entry->offset >= 0x80000000l) { word = htonl(0x80000000u | object_large_offsets_count++); - error = write_offset(entry->offset, midx_write_buf, &object_large_offsets); + if ((error = write_offset(entry->offset, midx_write_buf, &object_large_offsets)) < 0) + goto cleanup; } else { word = htonl((uint32_t)entry->offset & 0x7fffffffu); } + error = git_buf_put(&object_offsets, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; From 50b3c2d56d736c9168b46038ab996ca5c248aa46 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 30 Aug 2021 08:31:50 -0400 Subject: [PATCH 0486/1616] pack: don't assert in the lock --- src/pack.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/pack.c b/src/pack.c index 94b1ecd9d61..aadf3f2be7c 100644 --- a/src/pack.c +++ b/src/pack.c @@ -1298,7 +1298,12 @@ int git_pack_foreach_entry( return error; } - GIT_ASSERT(p->index_map.data); + if (!p->index_map.data) { + git_error_set(GIT_ERROR_INTERNAL, "internal error: p->index_map.data == NULL"); + git_mutex_unlock(&p->lock); + return -1; + } + index = p->index_map.data; if (p->index_version > 1) @@ -1387,7 +1392,11 @@ int git_pack_foreach_entry_offset( if ((error = pack_index_open_locked(p)) < 0) goto cleanup; - GIT_ASSERT(p->index_map.data); + if (!p->index_map.data) { + git_error_set(GIT_ERROR_INTERNAL, "internal error: p->index_map.data == NULL"); + goto cleanup; + } + index = p->index_map.data; } @@ -1479,7 +1488,11 @@ static int pack_entry_find_offset( if ((error = pack_index_open_locked(p)) < 0) goto cleanup; - GIT_ASSERT(p->index_map.data); + if (!p->index_map.data) { + git_error_set(GIT_ERROR_INTERNAL, "internal error: p->index_map.data == NULL"); + goto cleanup; + } + index = p->index_map.data; level1_ofs = p->index_map.data; From 9191ef70e22ec8e6eb102c55147b47ce49a2b633 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 30 Aug 2021 08:40:26 -0400 Subject: [PATCH 0487/1616] error: don't check string after assert --- src/errors.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/errors.c b/src/errors.c index 3d1d1c9a116..ce883b2dad1 100644 --- a/src/errors.c +++ b/src/errors.c @@ -107,11 +107,6 @@ int git_error_set_str(int error_class, const char *string) GIT_ASSERT_ARG(string); - if (!string) { - git_error_set(GIT_ERROR_INVALID, "unspecified caller error"); - return -1; - } - git_buf_clear(buf); git_buf_puts(buf, string); From 036be15070bf7384f9391ddd52d1fc084b1ef8da Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 30 Aug 2021 08:47:04 -0400 Subject: [PATCH 0488/1616] hashsig: close fd on error --- src/hashsig.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hashsig.c b/src/hashsig.c index 43310ca4872..6b4fb835216 100644 --- a/src/hashsig.c +++ b/src/hashsig.c @@ -286,8 +286,10 @@ int git_hashsig_create_fromfile( return fd; } - if ((error = hashsig_in_progress_init(&prog, sig)) < 0) + if ((error = hashsig_in_progress_init(&prog, sig)) < 0) { + p_close(fd); return error; + } while (!error) { if ((buflen = p_read(fd, buf, sizeof(buf))) <= 0) { From f93beebcba473dc4c60fa25272b805f04ef0541b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 30 Aug 2021 08:49:00 -0400 Subject: [PATCH 0489/1616] filter: don't overwrite error value --- src/filter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/filter.c b/src/filter.c index f1d9614060a..dd7d2f7ec77 100644 --- a/src/filter.c +++ b/src/filter.c @@ -206,7 +206,8 @@ int git_filter_global_init(void) GIT_FILTER_IDENT, ident, GIT_FILTER_IDENT_PRIORITY) < 0) error = -1; - error = git_runtime_shutdown_register(git_filter_global_shutdown); + if (!error) + error = git_runtime_shutdown_register(git_filter_global_shutdown); done: if (error) { From ed0ea96ed9ab19c0757a7b81619ace39e71a22c5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 30 Aug 2021 09:02:26 -0400 Subject: [PATCH 0490/1616] date: promote before multiply --- src/date.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/date.c b/src/date.c index 71bf631a0c8..2297ee66cf3 100644 --- a/src/date.c +++ b/src/date.c @@ -722,7 +722,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm while (tl->type) { size_t len = strlen(tl->type); if (match_string(date, tl->type) >= len-1) { - update_tm(tm, now, tl->length * *num); + update_tm(tm, now, tl->length * (unsigned long)*num); *num = 0; *touched = 1; return end; From d390c07819f632f2ec77932b1b3f77931c08dc1b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 30 Aug 2021 16:52:58 -0400 Subject: [PATCH 0491/1616] Add a .clang-format with our style --- .clang-format | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000000..d6e9cfceb0f --- /dev/null +++ b/.clang-format @@ -0,0 +1,92 @@ +# This file is an example configuration for clang-format 5.0. +# +# Note that this style definition should only be understood as a hint +# for writing new code. The rules are still work-in-progress and does +# not yet exactly match the style we have in the existing code. + +# C Language specifics +Language: Cpp + +# Use tabs whenever we need to fill whitespace that spans at least from one tab +# stop to the next one. +# +# These settings are mirrored in .editorconfig. Keep them in sync. +UseTab: ForIndentation +TabWidth: 8 +IndentWidth: 8 +ContinuationIndentWidth: 8 +ColumnLimit: 80 + +AlignAfterOpenBracket: AlwaysBreak +AlignEscapedNewlines: Left +AlignTrailingComments: false + +# Allow putting parameters onto the next line +AllowAllArgumentsOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false + +# Don't allow short braced statements to be on a single line +# if (a) not if (a) return; +# return; +AllowShortBlocksOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortLoopsOnASingleLine: false +AllowShortLambdasOnASingleLine: None + +# Pack as many parameters or arguments onto the same line as possible +# int myFunction(int aaaaaaaaaaaa, int bbbbbbbb, +# int cccc); +BinPackArguments: true +BinPackParameters: false + +BreakBeforeBraces: Linux +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: false +BreakStringLiterals: false + +# The number of spaces before trailing line comments (// - comments). +# This does not affect trailing block comments (/* - comments). +SpacesBeforeTrailingComments: 1 + +# Don't insert spaces in casts +# x = (int32) y; not x = ( int32 ) y; +SpacesInCStyleCastParentheses: false + +# Don't insert spaces inside container literals +# var arr = [1, 2, 3]; not var arr = [ 1, 2, 3 ]; +SpacesInContainerLiterals: false + +# Don't insert spaces after '(' or before ')' +# f(arg); not f( arg ); +SpacesInParentheses: false + +# Don't insert spaces after '[' or before ']' +# int a[5]; not int a[ 5 ]; +SpacesInSquareBrackets: false + +# Insert a space after '{' and before '}' in struct initializers +Cpp11BracedListStyle: false + +# A list of macros that should be interpreted as foreach loops instead of as +# function calls. +ForEachMacros: + - 'git_array_foreach' + - 'git_vector_foreach' + +# The maximum number of consecutive empty lines to keep. +MaxEmptyLinesToKeep: 1 + +# No empty line at the start of a block. +KeepEmptyLinesAtTheStartOfBlocks: false + +# Penalties +# This decides what order things should be done if a line is too long +PenaltyBreakAssignment: 10 +PenaltyBreakBeforeFirstCallParameter: 30 +PenaltyBreakComment: 10 +PenaltyBreakFirstLessLess: 0 +PenaltyBreakString: 10 +PenaltyExcessCharacter: 100 +PenaltyReturnTypeOnItsOwnLine: 60 + +SortIncludes: false From fc5d0e80f9b41f8df73de2e03d143da80fae42c1 Mon Sep 17 00:00:00 2001 From: Jesse Hathaway Date: Mon, 30 Aug 2021 21:24:54 +0000 Subject: [PATCH 0492/1616] Set Host Header to match CONNECT authority target Prior to this change, for CONNECT requests, the Host header was set to the host and port of the target http proxy. However, per the rfc7230 for HTTP/1.1 this is incorrect as the Host header should match the target of the CONNECT request, as detailed in section 5.3.3 & 5.4. 5.3.3. authority-form The authority-form of request-target is only used for CONNECT requests (Section 4.3.6 of [RFC7231]). authority-form = authority When making a CONNECT request to establish a tunnel through one or more proxies, a client MUST send only the target URI's authority component (excluding any userinfo and its "@" delimiter) as the request-target. For example, CONNECT www.example.com:80 HTTP/1.1 5.4. Host A client MUST send a Host header field in all HTTP/1.1 request messages. If the target URI includes an authority component, then a client MUST send a field-value for Host that is identical to that authority component, excluding any userinfo subcomponent and its "@" delimiter (Section 2.7.1). If the authority component is missing or undefined for the target URI, then a client MUST send a Host header field with an empty field-value. This issue was noticed when proxying requests through HAProxy 2.2 which rejects these invalid http requests. --- src/transports/httpclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index ba86184dfc8..4c2d1d14571 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -670,7 +670,7 @@ static int generate_connect_request( git_buf_puts(buf, "\r\n"); git_buf_puts(buf, "Host: "); - puts_host_and_port(buf, &client->proxy.url, false); + puts_host_and_port(buf, &client->server.url, true); git_buf_puts(buf, "\r\n"); if ((error = apply_proxy_credentials(buf, client, request) < 0)) From 34fa6311423f55827184c6338226dde4ee46d4e5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 30 Aug 2021 17:55:13 -0400 Subject: [PATCH 0493/1616] commit graph: formatting fixes --- include/git2/sys/commit_graph.h | 5 ++--- src/commit_graph.c | 39 ++++++++++++++++----------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/include/git2/sys/commit_graph.h b/include/git2/sys/commit_graph.h index 67d95469c7c..f6c0fc4b5db 100644 --- a/include/git2/sys/commit_graph.h +++ b/include/git2/sys/commit_graph.h @@ -127,9 +127,8 @@ typedef struct { } git_commit_graph_writer_options; #define GIT_COMMIT_GRAPH_WRITER_OPTIONS_VERSION 1 -#define GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT \ - { \ - GIT_COMMIT_GRAPH_WRITER_OPTIONS_VERSION, \ +#define GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT { \ + GIT_COMMIT_GRAPH_WRITER_OPTIONS_VERSION \ } /** diff --git a/src/commit_graph.c b/src/commit_graph.c index 8323485b6ef..9abe373da71 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -915,8 +915,11 @@ static int write_offset(off64_t offset, commit_graph_write_cb write_cb, void *cb return 0; } -static int -write_chunk_header(int chunk_id, off64_t offset, commit_graph_write_cb write_cb, void *cb_data) +static int write_chunk_header( + int chunk_id, + off64_t offset, + commit_graph_write_cb write_cb, + void *cb_data) { uint32_t word = htonl(chunk_id); int error = write_cb((const char *)&word, sizeof(word), cb_data); @@ -954,8 +957,10 @@ static void packed_commit_free_dup(void *packed_commit) packed_commit_free(packed_commit); } -static int -commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, void *cb_data) +static int commit_graph_write( + git_commit_graph_writer *w, + commit_graph_write_cb write_cb, + void *cb_data) { int error = 0; size_t i; @@ -996,18 +1001,17 @@ commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, v /* Fill the OID Fanout table. */ oid_fanout_count = 0; for (i = 0; i < 256; i++) { - while (oid_fanout_count < git_vector_length(&w->commits) - && ((struct packed_commit *)git_vector_get(&w->commits, oid_fanout_count)) - ->sha1.id[0] - <= i) + while (oid_fanout_count < git_vector_length(&w->commits) && + (packed_commit = (struct packed_commit *)git_vector_get(&w->commits, oid_fanout_count)) && + packed_commit->sha1.id[0] <= i) ++oid_fanout_count; oid_fanout[i] = htonl(oid_fanout_count); } /* Fill the OID Lookup table. */ git_vector_foreach (&w->commits, i, packed_commit) { - error = git_buf_put( - &oid_lookup, (const char *)&packed_commit->sha1, sizeof(git_oid)); + error = git_buf_put(&oid_lookup, + (const char *)&packed_commit->sha1, sizeof(git_oid)); if (error < 0) goto cleanup; } @@ -1021,8 +1025,7 @@ commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, v size_t *packed_index; unsigned int parentcount = (unsigned int)git_array_size(packed_commit->parents); - error = git_buf_put( - &commit_data, + error = git_buf_put(&commit_data, (const char *)&packed_commit->tree_oid, sizeof(git_oid)); if (error < 0) @@ -1054,14 +1057,10 @@ commit_graph_write(git_commit_graph_writer *w, commit_graph_write_cb write_cb, v unsigned int parent_i; for (parent_i = 1; parent_i < parentcount; ++parent_i) { packed_index = git_array_get( - packed_commit->parent_indices, parent_i); - word = htonl( - (uint32_t)(*packed_index - | (parent_i + 1 == parentcount - ? 0x80000000u - : 0))); - error = git_buf_put( - &extra_edge_list, + packed_commit->parent_indices, parent_i); + word = htonl((uint32_t)(*packed_index | (parent_i + 1 == parentcount ? 0x80000000u : 0))); + + error = git_buf_put(&extra_edge_list, (const char *)&word, sizeof(word)); if (error < 0) From 0e585d368eef69b03890297d2e3625bd6a798319 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 31 Aug 2021 00:11:56 -0400 Subject: [PATCH 0494/1616] v1.2: changelog --- docs/changelog.md | 186 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 170 insertions(+), 16 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 1bbbe607d22..2a800afec67 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,21 +1,175 @@ -vNext +v1.2 ----- -### Changes or improvements - -* Branch and tag name validation functions have been introduced: - `git_branch_name_is_valid` will check if a branch name is valid, - and `git_tag_name_is_valid` will check if a tag name is valid. - -* Some remote and reference validity checking functions have been - introduced with error reporting semantics. `git_remote_name_is_valid` - replaces `git_remote_is_valid_name`. `git_reference_name_is_valid` - replaces `git_reference_is_valid_name`. Tthe former functions are - deprecated. - -### Breaking CMake configuration changes - -The `MVSC_CRTDBG` configuration option is now `WIN32_LEAKCHECK`. +This is release v1.2.0, "Absacker". This release includes many new features: in particular, support for commit graphs, multi-pack indexes, and `core.longpaths` support. + +This is meant to be the final minor release in the v1 lineage. v2.0 will be the next major release and will remove deprecated APIs and may include breaking changes. + +## Deprecated APIs + +* revspec: rename git_revparse_mode_t to git_revspec_t by @ethomson in https://github.com/libgit2/libgit2/pull/5786 +* tree: deprecate `git_treebuilder_write_with_buffer` by @ethomson in https://github.com/libgit2/libgit2/pull/5815 +* Deprecate `is_valid_name` functions; replace with `name_is_valid` functions by @ethomson in https://github.com/libgit2/libgit2/pull/5659 +* filter: stop taking git_buf as user input by @ethomson in https://github.com/libgit2/libgit2/pull/5859 +* remote: introduce remote_ready_cb, deprecate resolve_url callback by @ethomson in https://github.com/libgit2/libgit2/pull/6012 +* Introduce `create_commit_cb`, deprecate `signing_cb` by @ethomson in https://github.com/libgit2/libgit2/pull/6016 +* filter: filter drivers stop taking git_buf as user input by @ethomson in https://github.com/libgit2/libgit2/pull/6011 +* buf: deprecate public git_buf writing functions by @ethomson in https://github.com/libgit2/libgit2/pull/6017 + +## New features + +* winhttp: support optional client cert by @ianhattendorf in https://github.com/libgit2/libgit2/pull/5384 +* Add support for additional SSH hostkey types. by @arroz in https://github.com/libgit2/libgit2/pull/5750 +* Handle ipv6 addresses by @ethomson in https://github.com/libgit2/libgit2/pull/5741 +* zlib: Add support for building with Chromium's zlib implementation by @lhchavez in https://github.com/libgit2/libgit2/pull/5748 +* commit-graph: Introduce a parser for commit-graph files by @lhchavez in https://github.com/libgit2/libgit2/pull/5762 +* patch: add owner accessor by @KOLANICH in https://github.com/libgit2/libgit2/pull/5731 +* commit-graph: Support lookups of entries in a commit-graph by @lhchavez in https://github.com/libgit2/libgit2/pull/5763 +* commit-graph: Introduce `git_commit_graph_needs_refresh()` by @lhchavez in https://github.com/libgit2/libgit2/pull/5764 +* Working directory path validation by @ethomson in https://github.com/libgit2/libgit2/pull/5823 +* Support `core.longpaths` on Windows by @ethomson in https://github.com/libgit2/libgit2/pull/5857 +* git_reference_create_matching: Treat all-zero OID as "must be absent" by @novalis in https://github.com/libgit2/libgit2/pull/5842 +* diff:add option to ignore blank line changes by @yuuri in https://github.com/libgit2/libgit2/pull/5853 +* [Submodule] Git submodule dup by @lolgear in https://github.com/libgit2/libgit2/pull/5890 +* commit-graph: Use the commit-graph in revwalks by @lhchavez in https://github.com/libgit2/libgit2/pull/5765 +* commit-graph: Introduce `git_commit_list_generation_cmp` by @lhchavez in https://github.com/libgit2/libgit2/pull/5766 +* graph: Create `git_graph_reachable_from_any()` by @lhchavez in https://github.com/libgit2/libgit2/pull/5767 +* Support reading attributes from a specific commit by @ethomson in https://github.com/libgit2/libgit2/pull/5952 +* [Branch] Branch upstream with format by @lolgear in https://github.com/libgit2/libgit2/pull/5861 +* Dynamically load OpenSSL (optionally) by @ethomson in https://github.com/libgit2/libgit2/pull/5974 +* Set refs/remotes/origin/HEAD to default branch when branch is specified by @A-Ovchinnikov-mx in https://github.com/libgit2/libgit2/pull/6010 +* midx: Add a way to write multi-pack-index files by @lhchavez in https://github.com/libgit2/libgit2/pull/5404 +* Use error code GIT_EAUTH for authentication failures by @josharian in https://github.com/libgit2/libgit2/pull/5395 +* midx: Introduce git_odb_write_multi_pack_index() by @lhchavez in https://github.com/libgit2/libgit2/pull/5405 +* Checkout dry-run by @J0Nes90 in https://github.com/libgit2/libgit2/pull/5841 +* mbedTLS: Fix setting certificate directory by @mikezackles in https://github.com/libgit2/libgit2/pull/6004 +* remote: introduce remote_ready_cb, deprecate resolve_url callback by @ethomson in https://github.com/libgit2/libgit2/pull/6012 +* Introduce `create_commit_cb`, deprecate `signing_cb` by @ethomson in https://github.com/libgit2/libgit2/pull/6016 +* commit-graph: Add a way to write commit-graph files by @lhchavez in https://github.com/libgit2/libgit2/pull/5778 + +## Bug fixes + +* Define `git___load` when building with `-DTHREADSAFE=OFF` by @lhchavez in https://github.com/libgit2/libgit2/pull/5664 +* Make the Windows leak detection more robust by @lhchavez in https://github.com/libgit2/libgit2/pull/5661 +* Refactor "global" state by @ethomson in https://github.com/libgit2/libgit2/pull/5546 +* threadstate: rename tlsdata when building w/o threads by @ethomson in https://github.com/libgit2/libgit2/pull/5668 +* Include `${MBEDTLS_INCLUDE_DIR}` when compiling `crypt_mbedtls.c` by @staticfloat in https://github.com/libgit2/libgit2/pull/5685 +* Fix the `-DTHREADSAFE=OFF` build by @lhchavez in https://github.com/libgit2/libgit2/pull/5690 +* Add missing worktree_dir check and test case by @rbmclean in https://github.com/libgit2/libgit2/pull/5692 +* msvc crtdbg -> win32 leakcheck by @ethomson in https://github.com/libgit2/libgit2/pull/5580 +* Introduce GIT_ASSERT macros by @ethomson in https://github.com/libgit2/libgit2/pull/5327 +* Also add the raw hostkey to `git_cert_hostkey` by @lhchavez in https://github.com/libgit2/libgit2/pull/5704 +* Make the odb race-free by @lhchavez in https://github.com/libgit2/libgit2/pull/5595 +* Make the pack and mwindow implementations data-race-free by @lhchavez in https://github.com/libgit2/libgit2/pull/5593 +* Thread-free implementation by @ethomson in https://github.com/libgit2/libgit2/pull/5719 +* Thread-local storage: a generic internal library (with no allocations) by @ethomson in https://github.com/libgit2/libgit2/pull/5720 +* Friendlier getting started in the lack of git_libgit2_init by @ethomson in https://github.com/libgit2/libgit2/pull/5578 +* Make git__strntol64() ~70%* faster by @lhchavez in https://github.com/libgit2/libgit2/pull/5735 +* Cache the parsed submodule config when diffing by @lhchavez in https://github.com/libgit2/libgit2/pull/5727 +* pack: continue zlib while we can make progress by @ethomson in https://github.com/libgit2/libgit2/pull/5740 +* Avoid using `__builtin_mul_overflow` with the clang+32-bit combo by @lhchavez in https://github.com/libgit2/libgit2/pull/5742 +* repository: use intptr_t's in the config map cache by @ethomson in https://github.com/libgit2/libgit2/pull/5746 +* Build with NO_MMAP by @0xdky in https://github.com/libgit2/libgit2/pull/5583 +* Add documentation for git_blob_filter_options.version by @JoshuaS3 in https://github.com/libgit2/libgit2/pull/5759 +* blob: fix name of `GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD` by @ethomson in https://github.com/libgit2/libgit2/pull/5760 +* Cope with empty default branch by @ethomson in https://github.com/libgit2/libgit2/pull/5770 +* README: instructions for using libgit2 without compiling by @ethomson in https://github.com/libgit2/libgit2/pull/5772 +* Use `p_pwrite`/`p_pread` consistently throughout the codebase by @lhchavez in https://github.com/libgit2/libgit2/pull/5769 +* midx: Fix a bug in `git_midx_needs_refresh()` by @lhchavez in https://github.com/libgit2/libgit2/pull/5768 +* mwindow: Fix a bug in the LRU window finding code by @lhchavez in https://github.com/libgit2/libgit2/pull/5783 +* refdb_fs: Check git_sortedcache wlock/rlock errors by @mamapanda in https://github.com/libgit2/libgit2/pull/5800 +* index: Check git_vector_dup error in write_entries by @mamapanda in https://github.com/libgit2/libgit2/pull/5801 +* Fix documentation formating on repository.h by @punkymaniac in https://github.com/libgit2/libgit2/pull/5806 +* include: fix typos in comments by @tniessen in https://github.com/libgit2/libgit2/pull/5805 +* Fix some typos by @aaronfranke in https://github.com/libgit2/libgit2/pull/5797 +* Check git_signature_dup failure by @mamapanda in https://github.com/libgit2/libgit2/pull/5817 +* merge: Check insert_head_ids error in create_virtual_base by @mamapanda in https://github.com/libgit2/libgit2/pull/5818 +* winhttp: skip certificate check if unable to send request by @ianhattendorf in https://github.com/libgit2/libgit2/pull/5814 +* Default to GIT_BRANCH_DEFAULT if init.defaultBranch is empty string by @ianhattendorf in https://github.com/libgit2/libgit2/pull/5832 +* Fix diff_entrycount -> diff_num_deltas doc typo by @mjsir911 in https://github.com/libgit2/libgit2/pull/5838 +* repo: specify init.defaultbranch is meant to be a branch name by @carlosmn in https://github.com/libgit2/libgit2/pull/5835 +* repo: remove an inappropriate use of PASSTHROUGH by @carlosmn in https://github.com/libgit2/libgit2/pull/5834 +* src: fix typos in header files by @tniessen in https://github.com/libgit2/libgit2/pull/5843 +* test: clean up memory leaks by @ethomson in https://github.com/libgit2/libgit2/pull/5858 +* buf: remove unnecessary buf_text namespace by @ethomson in https://github.com/libgit2/libgit2/pull/5860 +* Fix bug in git_diff_find_similar. by @staktrace in https://github.com/libgit2/libgit2/pull/5839 +* Fix issues with Proxy Authentication after httpclient refactor by @implausible in https://github.com/libgit2/libgit2/pull/5852 +* tests: clean up memory leak, fail on leak for win32 by @ethomson in https://github.com/libgit2/libgit2/pull/5892 +* Tolerate readlink size less than st_size by @dtolnay in https://github.com/libgit2/libgit2/pull/5900 +* Define WINHTTP_NO_CLIENT_CERT_CONTEXT if needed by @jacquesg in https://github.com/libgit2/libgit2/pull/5929 +* Update from regex to pcre licensing information in docs/contributing.md by @boretrk in https://github.com/libgit2/libgit2/pull/5916 +* Consider files executable only if the user can execute them by @novalis in https://github.com/libgit2/libgit2/pull/5915 +* git__timer: Limit ITimer usage to AmigaOS4 by @boretrk in https://github.com/libgit2/libgit2/pull/5936 +* Fix memory leak in git_smart__connect by @punkymaniac in https://github.com/libgit2/libgit2/pull/5908 +* config: fix included configs not refreshed more than once by @Batchyx in https://github.com/libgit2/libgit2/pull/5926 +* Fix wrong time_t used in function by @NattyNarwhal in https://github.com/libgit2/libgit2/pull/5938 +* fix check for ignoring of negate rules by @palmin in https://github.com/libgit2/libgit2/pull/5824 +* Make `FIND_PACKAGE(PythonInterp)` prefer `python3` by @lhchavez in https://github.com/libgit2/libgit2/pull/5913 +* git__timer: Allow compilation on systems without CLOCK_MONOTONIC by @boretrk in https://github.com/libgit2/libgit2/pull/5945 +* stdintification: use int64_t and INT64_C instead of long long by @NattyNarwhal in https://github.com/libgit2/libgit2/pull/5941 +* Optional stricter allocation checking (for `malloc(0)` cases) by @ethomson in https://github.com/libgit2/libgit2/pull/5951 +* Variadic arguments aren't in C89 by @NattyNarwhal in https://github.com/libgit2/libgit2/pull/5948 +* Fix typo in general.c by @Crayon2000 in https://github.com/libgit2/libgit2/pull/5954 +* common.h: use inline when compiling for C99 and later by @boretrk in https://github.com/libgit2/libgit2/pull/5953 +* Fix one memory leak in master by @lhchavez in https://github.com/libgit2/libgit2/pull/5957 +* tests: reset odb backend priority by @ethomson in https://github.com/libgit2/libgit2/pull/5961 +* cmake: extended futimens checking on macOS by @ethomson in https://github.com/libgit2/libgit2/pull/5962 +* amiga: use ';' as path list separator on AmigaOS by @boretrk in https://github.com/libgit2/libgit2/pull/5978 +* Respect the force flag on refspecs in git_remote_fetch by @alexjg in https://github.com/libgit2/libgit2/pull/5854 +* Fix LIBGIT2_FILENAME not being passed to the resource compiler by @jairbubbles in https://github.com/libgit2/libgit2/pull/5994 +* sha1dc: remove conditional for by @boretrk in https://github.com/libgit2/libgit2/pull/5997 +* openssl: don't fail when we can't customize allocators by @ethomson in https://github.com/libgit2/libgit2/pull/5999 +* C11 warnings by @boretrk in https://github.com/libgit2/libgit2/pull/6005 +* open: input validation for empty segments in path by @boretrk in https://github.com/libgit2/libgit2/pull/5950 +* Introduce GIT_WARN_UNUSED_RESULT by @lhchavez in https://github.com/libgit2/libgit2/pull/5802 +* GCC C11 warnings by @boretrk in https://github.com/libgit2/libgit2/pull/6006 +* array: check dereference from void * type by @boretrk in https://github.com/libgit2/libgit2/pull/6007 +* Homogenize semantics for atomic-related functions by @lhchavez in https://github.com/libgit2/libgit2/pull/5747 +* git_array_alloc: return objects of correct type by @boretrk in https://github.com/libgit2/libgit2/pull/6008 +* CMake. hash sha1 header has been added. by @lolgear in https://github.com/libgit2/libgit2/pull/6013 +* tests: change comments to c89 style by @boretrk in https://github.com/libgit2/libgit2/pull/6015 +* Set Host Header to match CONNECT authority target by @lollipopman in https://github.com/libgit2/libgit2/pull/6022 +* Fix worktree iteration when repository has no common directory by @kcsaul in https://github.com/libgit2/libgit2/pull/5943 + +## Documentation improvements + +* Update README.md for additional Delphi bindings by @todaysoftware in https://github.com/libgit2/libgit2/pull/5831 +* Fix documentation formatting by @punkymaniac in https://github.com/libgit2/libgit2/pull/5850 +* docs: fix incorrect comment marker by @tiennou in https://github.com/libgit2/libgit2/pull/5897 +* Patch documentation by @punkymaniac in https://github.com/libgit2/libgit2/pull/5903 +* Fix misleading doc for `git_index_find` by @arxanas in https://github.com/libgit2/libgit2/pull/5910 +* docs: stop mentioning libgit2's "master" branch by @Batchyx in https://github.com/libgit2/libgit2/pull/5925 +* docs: fix some missing includes that cause Docurium to error out by @tiennou in https://github.com/libgit2/libgit2/pull/5917 +* Patch documentation by @punkymaniac in https://github.com/libgit2/libgit2/pull/5940 + +## Development improvements + +* WIP: .devcontainer: settings for a codespace workflow by @ethomson in https://github.com/libgit2/libgit2/pull/5508 + +## CI Improvements + +* Add a ThreadSanitizer build by @lhchavez in https://github.com/libgit2/libgit2/pull/5597 +* ci: more GitHub Actions by @ethomson in https://github.com/libgit2/libgit2/pull/5706 +* ci: run coverity in the nightly builds by @ethomson in https://github.com/libgit2/libgit2/pull/5707 +* ci: only report main branch in README status by @ethomson in https://github.com/libgit2/libgit2/pull/5708 +* Fix the `ENABLE_WERROR=ON` build in Groovy Gorilla (gcc 10.2) by @lhchavez in https://github.com/libgit2/libgit2/pull/5715 +* Re-enable the RC4 test by @carlosmn in https://github.com/libgit2/libgit2/pull/4418 +* ci: run codeql by @ethomson in https://github.com/libgit2/libgit2/pull/5709 +* github-actions: Also rename the main branch here by @lhchavez in https://github.com/libgit2/libgit2/pull/5771 +* ci: don't use ninja on macOS by @ethomson in https://github.com/libgit2/libgit2/pull/5780 +* ci: use GitHub for storing mingw-w64 build dependency by @ethomson in https://github.com/libgit2/libgit2/pull/5855 +* docker: remove the entrypoint by @ethomson in https://github.com/libgit2/libgit2/pull/5980 +* http: don't require a password by @ethomson in https://github.com/libgit2/libgit2/pull/5972 +* ci: update nightly to use source path by @ethomson in https://github.com/libgit2/libgit2/pull/5989 +* ci: add centos 7 and centos 8 by @ethomson in https://github.com/libgit2/libgit2/pull/5992 +* ci: update centos builds by @ethomson in https://github.com/libgit2/libgit2/pull/5995 +* ci: tag new containers with the latest tag by @ethomson in https://github.com/libgit2/libgit2/pull/6000 + +## Dependency updates + +* ntlm: [ntlmclient](https://github.com/ethomson/ntlmclient) is now v0.9.1 + +**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.1.0...v1.2.0 v1.1 ---- From c811fc361be92226eec463f92e33d838fa0e9d54 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 31 Aug 2021 00:13:42 -0400 Subject: [PATCH 0495/1616] v1.2: update version information --- CMakeLists.txt | 2 +- include/git2/version.h | 6 +++--- package.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fd046eb5c7c..36170a5dc9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1) -project(libgit2 VERSION "1.1.0" LANGUAGES C) +project(libgit2 VERSION "1.2.0" LANGUAGES C) # Add find modules to the path set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${libgit2_SOURCE_DIR}/cmake/") diff --git a/include/git2/version.h b/include/git2/version.h index c1020bbea35..46adfec14de 100644 --- a/include/git2/version.h +++ b/include/git2/version.h @@ -7,12 +7,12 @@ #ifndef INCLUDE_git_version_h__ #define INCLUDE_git_version_h__ -#define LIBGIT2_VERSION "1.1.0" +#define LIBGIT2_VERSION "1.2.0" #define LIBGIT2_VER_MAJOR 1 -#define LIBGIT2_VER_MINOR 1 +#define LIBGIT2_VER_MINOR 2 #define LIBGIT2_VER_REVISION 0 #define LIBGIT2_VER_PATCH 0 -#define LIBGIT2_SOVERSION "1.1" +#define LIBGIT2_SOVERSION "1.2" #endif diff --git a/package.json b/package.json index 5e74f3bd5af..e0544f653b6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "libgit2", - "version": "1.1.0", + "version": "1.2.0", "repo": "https://github.com/libgit2/libgit2", "description": " A cross-platform, linkable library implementation of Git that you can use in your application.", "install": "mkdir build && cd build && cmake .. && cmake --build ." From 1e49f12793c4d39fffb64a08db0d1fddafaf0338 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 31 Aug 2021 05:23:20 -0700 Subject: [PATCH 0496/1616] Fix a possible null pointer dereference This change fixes a possible null pointer dereference if anything inside `git_commit_graph_writer_add_index_file` fails before the packfile being valid. https://scan6.coverity.com/reports.htm#v52218/p10377/fileInstanceId=122935896&defectInstanceId=32525576&mergedDefectId=1461634 --- src/commit_graph.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/commit_graph.c b/src/commit_graph.c index 9abe373da71..71e415e99d1 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -716,7 +716,8 @@ int git_commit_graph_writer_add_index_file( goto cleanup; cleanup: - git_mwindow_put_pack(p); + if (p) + git_mwindow_put_pack(p); git_odb_free(state.db); return error; } From e5a3277452095a908787c3ea0279fbec21c0a76a Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Thu, 11 Feb 2021 22:53:16 +0100 Subject: [PATCH 0497/1616] Add NO_PROXY env support Item 2 of 3 from #4164 Signed-off-by: Mathieu Parent --- src/remote.c | 93 +++++++++++++++++++++++++++++++++++++--- src/remote.h | 4 +- src/transports/http.c | 2 +- src/transports/winhttp.c | 4 +- tests/online/clone.c | 66 ++++++++++++++++++++++++++++ tests/remote/no_proxy.c | 40 +++++++++++++++++ 6 files changed, 200 insertions(+), 9 deletions(-) create mode 100644 tests/remote/no_proxy.c diff --git a/src/remote.c b/src/remote.c index 73375b35288..e63f54a9b70 100644 --- a/src/remote.c +++ b/src/remote.c @@ -849,11 +849,70 @@ int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote return remote->transport->ls(out, size, remote->transport); } -int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_url) +int git_remote__get_http_proxy_bypass(git_net_url *url, git_buf *no_proxy_env, bool *bypass) +{ + int error = 0; + char *p_start = no_proxy_env->ptr; + size_t p_length = 0; + char c; + git_buf hostport = GIT_BUF_INIT; + + error = git_buf_printf(&hostport, "%s:%s", url->host, url->port); + if (error < 0) + return error; + + *bypass = false; + + do { + c = *(p_start + p_length); + if ((c == ',') || (c == 0)) { + if ((p_length == 1) && (*p_start == '*')) { + // wildcard match (*) + goto found; + } else if ((p_length == strlen(url->host)) && !memcmp(p_start, url->host, p_length)) { + // exact host match + goto found; + } else if ((p_length == strlen(hostport.ptr)) && !memcmp(p_start, hostport.ptr, p_length)) { + // exact host:port match + goto found; + } else { + if ((p_length >= 2) && (*p_start == '*') && (*(p_start + 1) == '.')) { + // *.foo == .foo + p_start++; + p_length--; + } + if ((*p_start == '.') && (strlen(url->host) > p_length) && !memcmp(p_start, url->host + strlen(url->host) - p_length, p_length)) { + // host suffix match (.example.org) + goto found; + } else if ((*p_start == '.') && (strlen(hostport.ptr) > p_length) && !memcmp(p_start, hostport.ptr + strlen(hostport.ptr) - p_length, p_length)) { + // host:port suffix match (.example.org:443) + goto found; + } + } + p_start += p_length + 1; + p_length = 0; + } else { + p_length++; + } + } while(c != 0); + + goto end; + +found: + *bypass = true; + +end: + git_buf_dispose(&hostport); + return 0; +} + +int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, git_net_url *url, char **proxy_url) { git_config *cfg; git_config_entry *ce = NULL; - git_buf val = GIT_BUF_INIT; + git_buf proxy_env = GIT_BUF_INIT; + git_buf no_proxy_env = GIT_BUF_INIT; + bool bypass = false; int error; GIT_ASSERT_ARG(remote); @@ -898,11 +957,11 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur } /* http_proxy / https_proxy environment variables */ - error = git__getenv(&val, use_ssl ? "https_proxy" : "http_proxy"); + error = git__getenv(&proxy_env, use_ssl ? "https_proxy" : "http_proxy"); /* try uppercase environment variables */ if (error == GIT_ENOTFOUND) - error = git__getenv(&val, use_ssl ? "HTTPS_PROXY" : "HTTP_PROXY"); + error = git__getenv(&proxy_env, use_ssl ? "HTTPS_PROXY" : "HTTP_PROXY"); if (error < 0) { if (error == GIT_ENOTFOUND) { @@ -913,13 +972,35 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur return error; } - *proxy_url = git_buf_detach(&val); + /* no_proxy/NO_PROXY environment variables */ + error = git__getenv(&no_proxy_env, "no_proxy"); + if (error == GIT_ENOTFOUND) + error = git__getenv(&no_proxy_env, "NO_PROXY"); + + if (error == GIT_ENOTFOUND) { + git_error_clear(); + error = 0; + } else if (error < 0) { + goto cleanup; + } else { + error = git_remote__get_http_proxy_bypass(url, &no_proxy_env, &bypass); + } + + if (bypass) { + git_buf_dispose(&proxy_env); + goto cleanup; + } else { + *proxy_url = git_buf_detach(&proxy_env); + } found: GIT_ERROR_CHECK_ALLOC(*proxy_url); + +cleanup: + git_buf_dispose(&no_proxy_env); git_config_entry_free(ce); - return 0; + return error; } /* DWIM `refspecs` based on `refs` and append the output to `out` */ diff --git a/src/remote.h b/src/remote.h index df75ed3597b..ffcefdf7f86 100644 --- a/src/remote.h +++ b/src/remote.h @@ -9,6 +9,7 @@ #include "common.h" +#include "net.h" #include "git2/remote.h" #include "git2/transport.h" #include "git2/sys/transport.h" @@ -46,7 +47,8 @@ typedef struct git_remote_connection_opts { int git_remote__connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_remote_connection_opts *conn); int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int direction, const git_remote_callbacks *callbacks); -int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_url); +int git_remote__get_http_proxy_bypass(git_net_url *url, git_buf *no_proxy_env, bool *bypass); +int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, git_net_url *url, char **proxy_url); git_refspec *git_remote__matching_refspec(git_remote *remote, const char *refname); git_refspec *git_remote__matching_dst_refspec(git_remote *remote, const char *refname); diff --git a/src/transports/http.c b/src/transports/http.c index 691bceb758e..5468674e0d4 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -306,7 +306,7 @@ static int lookup_proxy( remote = transport->owner->owner; use_ssl = !strcmp(transport->server.url.scheme, "https"); - error = git_remote__get_http_proxy(remote, use_ssl, &config); + error = git_remote__get_http_proxy(remote, use_ssl, &transport->server.url, &config); if (error || !config) goto done; diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index ea2195a9942..8dc39d8bb3e 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -373,6 +373,7 @@ static int winhttp_stream_connect(winhttp_stream *s) { winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); git_buf buf = GIT_BUF_INIT; + bool use_ssl; char *proxy_url = NULL; wchar_t ct[MAX_CONTENT_TYPE_LEN]; LPCWSTR types[] = { L"*/*", NULL }; @@ -429,7 +430,8 @@ static int winhttp_stream_connect(winhttp_stream *s) proxy_opts = &t->owner->proxy; if (proxy_opts->type == GIT_PROXY_AUTO) { /* Set proxy if necessary */ - if (git_remote__get_http_proxy(t->owner->owner, (strcmp(t->server.url.scheme, "https") == 0), &proxy_url) < 0) + use_ssl = strcmp(t->server.url.scheme, "https") == 0; + if (git_remote__get_http_proxy(t->owner->owner, use_ssl, &t->server.url, &proxy_url) < 0) goto on_error; } else if (proxy_opts->type == GIT_PROXY_SPECIFIED) { diff --git a/tests/online/clone.c b/tests/online/clone.c index dbf45dcb3e4..d9b1837df43 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -36,6 +36,7 @@ static char *_remote_expectcontinue = NULL; static int _orig_proxies_need_reset = 0; static char *_orig_http_proxy = NULL; static char *_orig_https_proxy = NULL; +static char *_orig_no_proxy = NULL; static int ssl_cert(git_cert *cert, int valid, const char *host, void *payload) { @@ -110,9 +111,11 @@ void test_online_clone__cleanup(void) if (_orig_proxies_need_reset) { cl_setenv("HTTP_PROXY", _orig_http_proxy); cl_setenv("HTTPS_PROXY", _orig_https_proxy); + cl_setenv("NO_PROXY", _orig_no_proxy); git__free(_orig_http_proxy); git__free(_orig_https_proxy); + git__free(_orig_no_proxy); } git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, NULL, NULL); @@ -854,6 +857,7 @@ void test_online_clone__proxy_credentials_in_environment(void) _orig_http_proxy = cl_getenv("HTTP_PROXY"); _orig_https_proxy = cl_getenv("HTTPS_PROXY"); + _orig_no_proxy = cl_getenv("NO_PROXY"); _orig_proxies_need_reset = 1; g_options.fetch_opts.proxy_opts.type = GIT_PROXY_AUTO; @@ -865,6 +869,7 @@ void test_online_clone__proxy_credentials_in_environment(void) cl_setenv("HTTP_PROXY", url.ptr); cl_setenv("HTTPS_PROXY", url.ptr); + cl_setenv("NO_PROXY", NULL); cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); @@ -893,6 +898,67 @@ void test_online_clone__proxy_credentials_in_url_https(void) git_buf_dispose(&url); } +struct no_proxy_test_entry { + char no_proxy[128]; + bool bypass; +}; + +static struct no_proxy_test_entry no_proxy_test_entries[] = { + {"*", true}, + {"github.com", true}, + {"github.com:443", true}, + {"github.com:80", false}, + {".github.com", false}, + {"*.github.com", false}, + {".com", true}, + {"*.com", true}, + {".com:443", true}, + {"*.com:443", true}, + {".com:80", false}, + {"*.com:80", false}, + {"", false} +}; + +void test_online_clone__no_proxy_in_environment(void) +{ + int error = 0; + unsigned int i; + git_buf proxy_url = GIT_BUF_INIT; + + _orig_http_proxy = cl_getenv("HTTP_PROXY"); + _orig_https_proxy = cl_getenv("HTTPS_PROXY"); + _orig_no_proxy = cl_getenv("NO_PROXY"); + _orig_proxies_need_reset = 1; + + g_options.fetch_opts.proxy_opts.type = GIT_PROXY_AUTO; + g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb; + + cl_git_pass(git_buf_printf(&proxy_url, "http://does-not-exists.example.org:1234/")); + + cl_setenv("HTTP_PROXY", proxy_url.ptr); + cl_setenv("HTTPS_PROXY", proxy_url.ptr); + + + for (i = 0; i < ARRAY_SIZE(no_proxy_test_entries); ++i) { + cl_setenv("NO_PROXY", no_proxy_test_entries[i].no_proxy); + error = git_clone(&g_repo, "https://github.com/libgit2/TestGitRepository", "./foo", &g_options); + + if (no_proxy_test_entries[i].bypass) { + cl_assert_(error == 0, no_proxy_test_entries[i].no_proxy); + } else { + cl_assert_(error == -1, no_proxy_test_entries[i].no_proxy); + } + + if (g_repo) { + git_repository_free(g_repo); + g_repo = NULL; + } + cl_fixture_cleanup("./foo"); + } + + git_buf_dispose(&proxy_url); +} + void test_online_clone__proxy_auto_not_detected(void) { g_options.fetch_opts.proxy_opts.type = GIT_PROXY_AUTO; diff --git a/tests/remote/no_proxy.c b/tests/remote/no_proxy.c new file mode 100644 index 00000000000..4f758415c30 --- /dev/null +++ b/tests/remote/no_proxy.c @@ -0,0 +1,40 @@ +#include "clar_libgit2.h" +#include "remote.h" + +/* Suite data */ +struct no_proxy_test_entry { + char url[128]; + char no_proxy[128]; + bool bypass; +}; + +static struct no_proxy_test_entry no_proxy_test_entries[] = { + {"https://example.com/", "", false}, + {"https://example.com/", "example.org", false}, + {"https://example.com/", "*", true}, + {"https://example.com/", "example.com,example.org", true}, + {"https://example.com/", ".example.com,example.org", false}, + {"https://foo.example.com/", ".example.com,example.org", true}, + {"https://example.com/", "foo.example.com,example.org", false}, + +}; + +void test_remote_no_proxy__entries(void) +{ + unsigned int i; + git_net_url url = GIT_NET_URL_INIT; + git_buf no_proxy = GIT_BUF_INIT; + bool bypass = false; + + for (i = 0; i < ARRAY_SIZE(no_proxy_test_entries); ++i) { + cl_git_pass(git_net_url_parse(&url, no_proxy_test_entries[i].url)); + cl_git_pass(git_buf_sets(&no_proxy, no_proxy_test_entries[i].no_proxy)); + cl_git_pass(git_remote__get_http_proxy_bypass(&url, &no_proxy, &bypass)); + + cl_assert_(bypass == no_proxy_test_entries[i].bypass, no_proxy_test_entries[i].no_proxy); + + git_net_url_dispose(&url); + git_buf_dispose(&no_proxy); + } + +} From 1196de4f263bdbb02c2c5b7030f159c2ff23af34 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 31 Aug 2021 15:22:44 -0400 Subject: [PATCH 0498/1616] util: introduce `git__strlcmp` Introduce a utility function that compares a NUL terminated string to a possibly not-NUL terminated string with length. This is similar to `strncmp` but with an added check to ensure that the lengths match (not just the `size` portion of the two strings). --- src/util.h | 11 +++++++++++ tests/core/string.c | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/util.h b/src/util.h index a7735366b6e..68c2b1804e7 100644 --- a/src/util.h +++ b/src/util.h @@ -168,6 +168,17 @@ extern int git__strncasecmp(const char *a, const char *b, size_t sz); extern int git__strcasesort_cmp(const char *a, const char *b); +/* + * Compare some NUL-terminated `a` to a possibly non-NUL terminated + * `b` of length `b_len`; like `strncmp` but ensuring that + * `strlen(a) == b_len` as well. + */ +GIT_INLINE(int) git__strlcmp(const char *a, const char *b, size_t b_len) +{ + int cmp = strncmp(a, b, b_len); + return cmp ? cmp : (int)a[b_len]; +} + typedef struct { git_atomic32 refcount; void *owner; diff --git a/tests/core/string.c b/tests/core/string.c index 85db0c66230..928dfbcc1fc 100644 --- a/tests/core/string.c +++ b/tests/core/string.c @@ -123,3 +123,14 @@ void test_core_string__strcasecmp(void) cl_assert(git__strcasecmp("et", "e\342\202\254ghi=") < 0); cl_assert(git__strcasecmp("\303\215", "\303\255") < 0); } + +void test_core_string__strlcmp(void) +{ + const char foo[3] = { 'f', 'o', 'o' }; + + cl_assert(git__strlcmp("foo", "foo", 3) == 0); + cl_assert(git__strlcmp("foo", foo, 3) == 0); + cl_assert(git__strlcmp("foo", "foobar", 3) == 0); + cl_assert(git__strlcmp("foobar", "foo", 3) > 0); + cl_assert(git__strlcmp("foo", "foobar", 6) < 0); +} From 3680f0bf527d69a7a1bb14e4012d07204440fd6e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 31 Aug 2021 09:41:14 -0400 Subject: [PATCH 0499/1616] tests: create the network::url test hierarcy --- tests/network/{ => url}/joinpath.c | 16 ++--- tests/network/{urlparse.c => url/parse.c} | 78 +++++++++++------------ tests/network/{ => url}/redirect.c | 24 +++---- 3 files changed, 59 insertions(+), 59 deletions(-) rename tests/network/{ => url}/joinpath.c (93%) rename tests/network/{urlparse.c => url/parse.c} (90%) rename tests/network/{ => url}/redirect.c (84%) diff --git a/tests/network/joinpath.c b/tests/network/url/joinpath.c similarity index 93% rename from tests/network/joinpath.c rename to tests/network/url/joinpath.c index da8393b916c..bf4557138a1 100644 --- a/tests/network/joinpath.c +++ b/tests/network/url/joinpath.c @@ -4,19 +4,19 @@ static git_net_url source, target; -void test_network_joinpath__initialize(void) +void test_network_url_joinpath__initialize(void) { memset(&source, 0, sizeof(source)); memset(&target, 0, sizeof(target)); } -void test_network_joinpath__cleanup(void) +void test_network_url_joinpath__cleanup(void) { git_net_url_dispose(&source); git_net_url_dispose(&target); } -void test_network_joinpath__target_paths_and_queries(void) +void test_network_url_joinpath__target_paths_and_queries(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com/a/b")); @@ -31,7 +31,7 @@ void test_network_joinpath__target_paths_and_queries(void) git_net_url_dispose(&target); } -void test_network_joinpath__source_query_removed(void) +void test_network_url_joinpath__source_query_removed(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com/a/b?query&one&two")); @@ -46,7 +46,7 @@ void test_network_joinpath__source_query_removed(void) git_net_url_dispose(&target); } -void test_network_joinpath__source_lacks_path(void) +void test_network_url_joinpath__source_lacks_path(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com")); @@ -91,7 +91,7 @@ void test_network_joinpath__source_lacks_path(void) git_net_url_dispose(&target); } -void test_network_joinpath__source_is_slash(void) +void test_network_url_joinpath__source_is_slash(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com/")); @@ -137,7 +137,7 @@ void test_network_joinpath__source_is_slash(void) } -void test_network_joinpath__source_has_query(void) +void test_network_url_joinpath__source_has_query(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com?query")); @@ -183,7 +183,7 @@ void test_network_joinpath__source_has_query(void) } -void test_network_joinpath__empty_query_ignored(void) +void test_network_url_joinpath__empty_query_ignored(void) { cl_git_pass(git_net_url_parse(&source, "http://example.com/foo")); diff --git a/tests/network/urlparse.c b/tests/network/url/parse.c similarity index 90% rename from tests/network/urlparse.c rename to tests/network/url/parse.c index 91c1a527cd9..edfd6abecaa 100644 --- a/tests/network/urlparse.c +++ b/tests/network/url/parse.c @@ -3,19 +3,19 @@ static git_net_url conndata; -void test_network_urlparse__initialize(void) +void test_network_url_parse__initialize(void) { memset(&conndata, 0, sizeof(conndata)); } -void test_network_urlparse__cleanup(void) +void test_network_url_parse__cleanup(void) { git_net_url_dispose(&conndata); } /* Hostname */ -void test_network_urlparse__hostname_trivial(void) +void test_network_url_parse__hostname_trivial(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -27,7 +27,7 @@ void test_network_urlparse__hostname_trivial(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__hostname_root(void) +void test_network_url_parse__hostname_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com/")); cl_assert_equal_s(conndata.scheme, "http"); @@ -39,7 +39,7 @@ void test_network_urlparse__hostname_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__hostname_implied_root(void) +void test_network_url_parse__hostname_implied_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com")); cl_assert_equal_s(conndata.scheme, "http"); @@ -51,7 +51,7 @@ void test_network_urlparse__hostname_implied_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__hostname_implied_root_custom_port(void) +void test_network_url_parse__hostname_implied_root_custom_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com:42")); cl_assert_equal_s(conndata.scheme, "http"); @@ -63,7 +63,7 @@ void test_network_urlparse__hostname_implied_root_custom_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__hostname_implied_root_empty_port(void) +void test_network_url_parse__hostname_implied_root_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com:")); cl_assert_equal_s(conndata.scheme, "http"); @@ -75,7 +75,7 @@ void test_network_urlparse__hostname_implied_root_empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__hostname_encoded_password(void) +void test_network_url_parse__hostname_encoded_password(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass%2fis%40bad@hostname.com:1234/")); @@ -88,7 +88,7 @@ void test_network_urlparse__hostname_encoded_password(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__hostname_user(void) +void test_network_url_parse__hostname_user(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@example.com/resource")); @@ -101,7 +101,7 @@ void test_network_urlparse__hostname_user(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__hostname_user_pass(void) +void test_network_url_parse__hostname_user_pass(void) { /* user:pass@hostname.tld/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -115,7 +115,7 @@ void test_network_urlparse__hostname_user_pass(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__hostname_port(void) +void test_network_url_parse__hostname_port(void) { /* hostname.tld:port/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -129,7 +129,7 @@ void test_network_urlparse__hostname_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__hostname_empty_port(void) +void test_network_url_parse__hostname_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com:/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -141,7 +141,7 @@ void test_network_urlparse__hostname_empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__hostname_user_port(void) +void test_network_url_parse__hostname_user_port(void) { /* user@hostname.tld:port/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -155,7 +155,7 @@ void test_network_urlparse__hostname_user_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__hostname_user_pass_port(void) +void test_network_url_parse__hostname_user_pass_port(void) { /* user:pass@hostname.tld:port/resource */ cl_git_pass(git_net_url_parse(&conndata, @@ -171,7 +171,7 @@ void test_network_urlparse__hostname_user_pass_port(void) /* IPv4 addresses */ -void test_network_urlparse__ipv4_trivial(void) +void test_network_url_parse__ipv4_trivial(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -183,7 +183,7 @@ void test_network_urlparse__ipv4_trivial(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv4_root(void) +void test_network_url_parse__ipv4_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1/")); cl_assert_equal_s(conndata.scheme, "http"); @@ -195,7 +195,7 @@ void test_network_urlparse__ipv4_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv4_implied_root(void) +void test_network_url_parse__ipv4_implied_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1")); cl_assert_equal_s(conndata.scheme, "http"); @@ -207,7 +207,7 @@ void test_network_urlparse__ipv4_implied_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv4_implied_root_custom_port(void) +void test_network_url_parse__ipv4_implied_root_custom_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:42")); cl_assert_equal_s(conndata.scheme, "http"); @@ -219,7 +219,7 @@ void test_network_urlparse__ipv4_implied_root_custom_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__ipv4_implied_root_empty_port(void) +void test_network_url_parse__ipv4_implied_root_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:")); cl_assert_equal_s(conndata.scheme, "http"); @@ -231,7 +231,7 @@ void test_network_urlparse__ipv4_implied_root_empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv4_encoded_password(void) +void test_network_url_parse__ipv4_encoded_password(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass%2fis%40bad@192.168.1.1:1234/")); @@ -244,7 +244,7 @@ void test_network_urlparse__ipv4_encoded_password(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__ipv4_user(void) +void test_network_url_parse__ipv4_user(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@192.168.1.1/resource")); @@ -257,7 +257,7 @@ void test_network_urlparse__ipv4_user(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv4_user_pass(void) +void test_network_url_parse__ipv4_user_pass(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@192.168.1.1/resource")); @@ -270,7 +270,7 @@ void test_network_urlparse__ipv4_user_pass(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv4_port(void) +void test_network_url_parse__ipv4_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://192.168.1.1:9191/resource")); @@ -283,7 +283,7 @@ void test_network_urlparse__ipv4_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__ipv4_empty_port(void) +void test_network_url_parse__ipv4_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://192.168.1.1:/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -295,7 +295,7 @@ void test_network_urlparse__ipv4_empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv4_user_port(void) +void test_network_url_parse__ipv4_user_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@192.168.1.1:9191/resource")); @@ -308,7 +308,7 @@ void test_network_urlparse__ipv4_user_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__ipv4_user_pass_port(void) +void test_network_url_parse__ipv4_user_pass_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@192.168.1.1:9191/resource")); @@ -323,7 +323,7 @@ void test_network_urlparse__ipv4_user_pass_port(void) /* IPv6 addresses */ -void test_network_urlparse__ipv6_trivial(void) +void test_network_url_parse__ipv6_trivial(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -335,7 +335,7 @@ void test_network_urlparse__ipv6_trivial(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv6_root(void) +void test_network_url_parse__ipv6_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]/")); cl_assert_equal_s(conndata.scheme, "http"); @@ -347,7 +347,7 @@ void test_network_urlparse__ipv6_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv6_implied_root(void) +void test_network_url_parse__ipv6_implied_root(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]")); cl_assert_equal_s(conndata.scheme, "http"); @@ -359,7 +359,7 @@ void test_network_urlparse__ipv6_implied_root(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv6_implied_root_custom_port(void) +void test_network_url_parse__ipv6_implied_root_custom_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:42")); cl_assert_equal_s(conndata.scheme, "http"); @@ -371,7 +371,7 @@ void test_network_urlparse__ipv6_implied_root_custom_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__ipv6_implied_root_empty_port(void) +void test_network_url_parse__ipv6_implied_root_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:")); cl_assert_equal_s(conndata.scheme, "http"); @@ -383,7 +383,7 @@ void test_network_urlparse__ipv6_implied_root_empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv6_encoded_password(void) +void test_network_url_parse__ipv6_encoded_password(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass%2fis%40bad@[fe80::dcad:beff:fe00:0001]:1234/")); @@ -396,7 +396,7 @@ void test_network_urlparse__ipv6_encoded_password(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__ipv6_user(void) +void test_network_url_parse__ipv6_user(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@[fe80::dcad:beff:fe00:0001]/resource")); @@ -409,7 +409,7 @@ void test_network_urlparse__ipv6_user(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv6_user_pass(void) +void test_network_url_parse__ipv6_user_pass(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@[fe80::dcad:beff:fe00:0001]/resource")); @@ -422,7 +422,7 @@ void test_network_urlparse__ipv6_user_pass(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv6_port(void) +void test_network_url_parse__ipv6_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://[fe80::dcad:beff:fe00:0001]:9191/resource")); @@ -435,7 +435,7 @@ void test_network_urlparse__ipv6_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__ipv6_empty_port(void) +void test_network_url_parse__ipv6_empty_port(void) { cl_git_pass(git_net_url_parse(&conndata, "http://[fe80::dcad:beff:fe00:0001]:/resource")); cl_assert_equal_s(conndata.scheme, "http"); @@ -447,7 +447,7 @@ void test_network_urlparse__ipv6_empty_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); } -void test_network_urlparse__ipv6_user_port(void) +void test_network_url_parse__ipv6_user_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user@[fe80::dcad:beff:fe00:0001]:9191/resource")); @@ -460,7 +460,7 @@ void test_network_urlparse__ipv6_user_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__ipv6_user_pass_port(void) +void test_network_url_parse__ipv6_user_pass_port(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user:pass@[fe80::dcad:beff:fe00:0001]:9191/resource")); @@ -473,7 +473,7 @@ void test_network_urlparse__ipv6_user_pass_port(void) cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); } -void test_network_urlparse__ipv6_invalid_addresses(void) +void test_network_url_parse__ipv6_invalid_addresses(void) { /* Opening bracket missing */ cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, diff --git a/tests/network/redirect.c b/tests/network/url/redirect.c similarity index 84% rename from tests/network/redirect.c rename to tests/network/url/redirect.c index 7ce1310dbb5..2c0b614d995 100644 --- a/tests/network/redirect.c +++ b/tests/network/url/redirect.c @@ -4,17 +4,17 @@ static git_net_url conndata; -void test_network_redirect__initialize(void) +void test_network_url_redirect__initialize(void) { memset(&conndata, 0, sizeof(conndata)); } -void test_network_redirect__cleanup(void) +void test_network_url_redirect__cleanup(void) { git_net_url_dispose(&conndata); } -void test_network_redirect__redirect_http(void) +void test_network_url_redirect__redirect_http(void) { cl_git_pass(git_net_url_parse(&conndata, "http://example.com/foo/bar/baz")); @@ -28,7 +28,7 @@ void test_network_redirect__redirect_http(void) cl_assert_equal_p(conndata.password, NULL); } -void test_network_redirect__redirect_ssl(void) +void test_network_url_redirect__redirect_ssl(void) { cl_git_pass(git_net_url_parse(&conndata, "https://example.com/foo/bar/baz")); @@ -42,7 +42,7 @@ void test_network_redirect__redirect_ssl(void) cl_assert_equal_p(conndata.password, NULL); } -void test_network_redirect__redirect_leaves_root_path(void) +void test_network_url_redirect__redirect_leaves_root_path(void) { cl_git_pass(git_net_url_parse(&conndata, "https://example.com/foo/bar/baz")); @@ -56,7 +56,7 @@ void test_network_redirect__redirect_leaves_root_path(void) cl_assert_equal_p(conndata.password, NULL); } -void test_network_redirect__redirect_encoded_username_password(void) +void test_network_url_redirect__redirect_encoded_username_password(void) { cl_git_pass(git_net_url_parse(&conndata, "https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz")); @@ -70,7 +70,7 @@ void test_network_redirect__redirect_encoded_username_password(void) cl_assert_equal_s(conndata.password, "pass@word%zyx%v"); } -void test_network_redirect__redirect_cross_host_denied(void) +void test_network_url_redirect__redirect_cross_host_denied(void) { cl_git_pass(git_net_url_parse(&conndata, "https://bar.com/bar/baz")); cl_git_fail_with(git_net_url_apply_redirect(&conndata, @@ -78,7 +78,7 @@ void test_network_redirect__redirect_cross_host_denied(void) -1); } -void test_network_redirect__redirect_http_downgrade_denied(void) +void test_network_url_redirect__redirect_http_downgrade_denied(void) { cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/baz")); cl_git_fail_with(git_net_url_apply_redirect(&conndata, @@ -86,7 +86,7 @@ void test_network_redirect__redirect_http_downgrade_denied(void) -1); } -void test_network_redirect__redirect_relative(void) +void test_network_url_redirect__redirect_relative(void) { cl_git_pass(git_net_url_parse(&conndata, "http://foo.com/bar/baz/biff")); cl_git_pass(git_net_url_apply_redirect(&conndata, @@ -99,7 +99,7 @@ void test_network_redirect__redirect_relative(void) cl_assert_equal_p(conndata.password, NULL); } -void test_network_redirect__redirect_relative_ssl(void) +void test_network_url_redirect__redirect_relative_ssl(void) { cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/baz/biff")); cl_git_pass(git_net_url_apply_redirect(&conndata, @@ -112,7 +112,7 @@ void test_network_redirect__redirect_relative_ssl(void) cl_assert_equal_p(conndata.password, NULL); } -void test_network_redirect__service_query_no_query_params_in_location(void) +void test_network_url_redirect__service_query_no_query_params_in_location(void) { cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/info/refs?service=git-upload-pack")); cl_git_pass(git_net_url_apply_redirect(&conndata, @@ -120,7 +120,7 @@ void test_network_redirect__service_query_no_query_params_in_location(void) cl_assert_equal_s(conndata.path, "/baz"); } -void test_network_redirect__service_query_with_query_params_in_location(void) +void test_network_url_redirect__service_query_with_query_params_in_location(void) { cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/info/refs?service=git-upload-pack")); cl_git_pass(git_net_url_apply_redirect(&conndata, From e5ba0a3c37a5a1a24f1904d56ebf8d30df9df75f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 31 Aug 2021 20:41:45 -0400 Subject: [PATCH 0500/1616] url: introduce `git_net_url_matches_pattern` Provide a method to determine if a given URL matches a host:port pattern like the ones found in `NO_PROXY` environment variables. --- src/net.c | 55 +++++++++++++++++++++++++++++++++++++ src/net.h | 5 ++++ tests/network/url/pattern.c | 54 ++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 tests/network/url/pattern.c diff --git a/src/net.c b/src/net.c index d4a9f8a6d6e..f3cca5da75b 100644 --- a/src/net.c +++ b/src/net.c @@ -404,6 +404,61 @@ int git_net_url_fmt_path(git_buf *buf, git_net_url *url) return git_buf_oom(buf) ? -1 : 0; } +static bool matches_pattern( + git_net_url *url, + const char *pattern, + size_t pattern_len) +{ + const char *domain, *port = NULL, *colon; + size_t host_len, domain_len, port_len = 0, wildcard = 0; + + GIT_UNUSED(url); + GIT_UNUSED(pattern); + + if (!pattern_len) + return false; + else if (pattern_len == 1 && pattern[0] == '*') + return true; + else if (pattern_len > 1 && pattern[0] == '*' && pattern[1] == '.') + wildcard = 2; + else if (pattern[0] == '.') + wildcard = 1; + + domain = pattern + wildcard; + domain_len = pattern_len - wildcard; + + if ((colon = memchr(domain, ':', domain_len)) != NULL) { + domain_len = colon - domain; + port = colon + 1; + port_len = pattern_len - wildcard - domain_len - 1; + } + + /* A pattern's port *must* match if it's specified */ + if (port_len && git__strlcmp(url->port, port, port_len) != 0) + return false; + + /* No wildcard? Host must match exactly. */ + if (!wildcard) + return !git__strlcmp(url->host, domain, domain_len); + + /* Wildcard: ensure there's (at least) a suffix match */ + if ((host_len = strlen(url->host)) < domain_len || + memcmp(url->host + (host_len - domain_len), domain, domain_len)) + return false; + + /* The pattern is *.domain and the host is simply domain */ + if (host_len == domain_len) + return true; + + /* The pattern is *.domain and the host is foo.domain */ + return (url->host[host_len - domain_len - 1] == '.'); +} + +bool git_net_url_matches_pattern(git_net_url *url, const char *pattern) +{ + return matches_pattern(url, pattern, strlen(pattern)); +} + void git_net_url_dispose(git_net_url *url) { if (url->username) diff --git a/src/net.h b/src/net.h index 391b99a9fe0..4d4c7c7fe3e 100644 --- a/src/net.h +++ b/src/net.h @@ -54,6 +54,11 @@ extern int git_net_url_fmt(git_buf *out, git_net_url *url); /** Place the path and query string into the given buffer. */ extern int git_net_url_fmt_path(git_buf *buf, git_net_url *url); +/** Determines if the url matches given pattern or pattern list */ +extern bool git_net_url_matches_pattern( + git_net_url *url, + const char *pattern); + /** Disposes the contents of the structure. */ extern void git_net_url_dispose(git_net_url *url); diff --git a/tests/network/url/pattern.c b/tests/network/url/pattern.c new file mode 100644 index 00000000000..fbe1f9e5500 --- /dev/null +++ b/tests/network/url/pattern.c @@ -0,0 +1,54 @@ +#include "clar_libgit2.h" +#include "net.h" + +struct url_pattern { + const char *url; + const char *pattern; + bool matches; +}; + +void test_network_url_pattern__single(void) +{ + git_net_url url; + size_t i; + + struct url_pattern url_patterns[] = { + /* Wildcard matches */ + { "https://example.com/", "", false }, + { "https://example.com/", "*", true }, + + /* Literal and wildcard matches */ + { "https://example.com/", "example.com", true }, + { "https://example.com/", ".example.com", true }, + { "https://example.com/", "*.example.com", true }, + { "https://www.example.com/", "www.example.com", true }, + { "https://www.example.com/", ".example.com", true }, + { "https://www.example.com/", "*.example.com", true }, + + /* Literal and wildcard failures */ + { "https://example.com/", "example.org", false }, + { "https://example.com/", ".example.org", false }, + { "https://example.com/", "*.example.org", false }, + { "https://foo.example.com/", "www.example.com", false }, + + /* + * A port in the pattern is optional; if no port is + * present, it matches *all* ports. + */ + { "https://example.com/", "example.com:443", true }, + { "https://example.com/", "example.com:80", false }, + { "https://example.com:1443/", "example.com", true }, + + /* Failures with similar prefix/suffix */ + { "https://texample.com/", "example.com", false }, + { "https://example.com/", "mexample.com", false }, + { "https://example.com:44/", "example.com:443", false }, + { "https://example.com:443/", "example.com:44", false }, + }; + + for (i = 0; i < ARRAY_SIZE(url_patterns); i++) { + cl_git_pass(git_net_url_parse(&url, url_patterns[i].url)); + cl_assert_(git_net_url_matches_pattern(&url, url_patterns[i].pattern) == url_patterns[i].matches, url_patterns[i].pattern); + git_net_url_dispose(&url); + } +} From 9e98e443ca5e95bfb570536187c6e155bc126e59 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 31 Aug 2021 22:01:34 -0400 Subject: [PATCH 0501/1616] url: introduce `git_net_url_matches_pattern_list` Provide a utility method on a url to determine if it matches any pattern in a comma-separated list, similar to what one would find in `NO_PROXY` environment variables. --- src/net.c | 19 ++++++++++++++ src/net.h | 3 +++ tests/network/url/pattern.c | 49 +++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/src/net.c b/src/net.c index f3cca5da75b..3322f68c2ed 100644 --- a/src/net.c +++ b/src/net.c @@ -459,6 +459,25 @@ bool git_net_url_matches_pattern(git_net_url *url, const char *pattern) return matches_pattern(url, pattern, strlen(pattern)); } +bool git_net_url_matches_pattern_list( + git_net_url *url, + const char *pattern_list) +{ + const char *pattern, *pattern_end, *sep; + + for (pattern = pattern_list; + pattern && *pattern; + pattern = sep ? sep + 1 : NULL) { + sep = strchr(pattern, ','); + pattern_end = sep ? sep : strchr(pattern, '\0'); + + if (matches_pattern(url, pattern, (pattern_end - pattern))) + return true; + } + + return false; +} + void git_net_url_dispose(git_net_url *url) { if (url->username) diff --git a/src/net.h b/src/net.h index 4d4c7c7fe3e..971e002b64b 100644 --- a/src/net.h +++ b/src/net.h @@ -58,6 +58,9 @@ extern int git_net_url_fmt_path(git_buf *buf, git_net_url *url); extern bool git_net_url_matches_pattern( git_net_url *url, const char *pattern); +extern bool git_net_url_matches_pattern_list( + git_net_url *url, + const char *pattern_list); /** Disposes the contents of the structure. */ extern void git_net_url_dispose(git_net_url *url); diff --git a/tests/network/url/pattern.c b/tests/network/url/pattern.c index fbe1f9e5500..5e4495f7085 100644 --- a/tests/network/url/pattern.c +++ b/tests/network/url/pattern.c @@ -52,3 +52,52 @@ void test_network_url_pattern__single(void) git_net_url_dispose(&url); } } + +void test_network_url_pattern__list(void) +{ + git_net_url url; + size_t i; + + struct url_pattern url_patterns[] = { + /* Wildcard matches */ + { "https://example.com/", "", false }, + { "https://example.com/", "*", true }, + { "https://example.com/", ",example.com,", true }, + { "https://example.com/", "foo,,example.com,,bar", true }, + { "https://example.com/", "foo,,zzz,,*,,bar", true }, + + /* Literals */ + { "https://example.com/", "example.com", true }, + { "https://example.com/", "foo.bar,example.com", true }, + { "https://example.com/", "foo.bar", false }, + { "https://example.com/", "foo.bar,example.org", false }, + { "https://www.example.com/", "foo.example.com,www.example.com,bar.example.com", true }, + { "https://www.example.com/", "foo.example.com,baz.example.com,bar.example.com", false }, + { "https://foo.example.com/", "www.example.com", false }, + { "https://foo.example.com/", "bar.example.com,www.example.com,", false }, + + /* Wildcards */ + { "https://example.com/", ".example.com", true }, + { "https://example.com/", "*.example.com", true }, + { "https://example.com/", "foo.com,bar.com,.example.com", true }, + { "https://example.com/", ".foo.com,.bar.com,.example.com", true }, + { "https://example.com/", ".foo.com,.bar.com,asdf.com", false }, + { "https://example.com/", "*.foo,*.bar,*.example.com,*.asdf", true }, + { "https://example.com/", "*.foo,*.bar,*.asdf", false }, + + + /* Ports! */ + { "https://example.com/", "example.com:443", true }, + { "https://example.com/", "example.com:42,example.com:443,example.com:99", true }, + { "https://example.com/", "example.com:42,example.com:80,example.org:443", false }, + { "https://example.com:1443/", "example.com", true }, + { "https://example.com:44/", "example.com:443", false }, + { "https://example.com:443/", "example.com:44", false }, + }; + + for (i = 0; i < ARRAY_SIZE(url_patterns); i++) { + cl_git_pass(git_net_url_parse(&url, url_patterns[i].url)); + cl_assert_(git_net_url_matches_pattern_list(&url, url_patterns[i].pattern) == url_patterns[i].matches, url_patterns[i].pattern); + git_net_url_dispose(&url); + } +} From f89dc917d7cb1504b651fdb58c96397b3081a80d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 1 Sep 2021 20:30:59 -0400 Subject: [PATCH 0502/1616] url: introduce `git_net_url_dup` --- src/net.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/net.h | 3 +++ 2 files changed, 43 insertions(+) diff --git a/src/net.c b/src/net.c index 3322f68c2ed..a685e48938b 100644 --- a/src/net.c +++ b/src/net.c @@ -35,6 +35,46 @@ static const char *default_port_for_scheme(const char *scheme) return NULL; } +int git_net_url_dup(git_net_url *out, git_net_url *in) +{ + if (in->scheme) { + out->scheme = git__strdup(in->scheme); + GIT_ERROR_CHECK_ALLOC(out->scheme); + } + + if (in->host) { + out->host = git__strdup(in->host); + GIT_ERROR_CHECK_ALLOC(out->host); + } + + if (in->port) { + out->port = git__strdup(in->port); + GIT_ERROR_CHECK_ALLOC(out->port); + } + + if (in->path) { + out->path = git__strdup(in->path); + GIT_ERROR_CHECK_ALLOC(out->path); + } + + if (in->query) { + out->query = git__strdup(in->query); + GIT_ERROR_CHECK_ALLOC(out->query); + } + + if (in->username) { + out->username = git__strdup(in->username); + GIT_ERROR_CHECK_ALLOC(out->username); + } + + if (in->password) { + out->password = git__strdup(in->password); + GIT_ERROR_CHECK_ALLOC(out->password); + } + + return 0; +} + int git_net_url_parse(git_net_url *url, const char *given) { struct http_parser_url u = {0}; diff --git a/src/net.h b/src/net.h index 971e002b64b..322d0bda908 100644 --- a/src/net.h +++ b/src/net.h @@ -21,6 +21,9 @@ typedef struct git_net_url { #define GIT_NET_URL_INIT { NULL } +/** Duplicate a URL */ +extern int git_net_url_dup(git_net_url *out, git_net_url *in); + /** Parses a string containing a URL into a structure. */ extern int git_net_url_parse(git_net_url *url, const char *str); From 3c0f14cc95debb426bd53150aac0eef1a7f625d8 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 1 Sep 2021 20:34:28 -0400 Subject: [PATCH 0503/1616] remote: refactor proxy detection Update the proxy detection for a remote. 1. Honor `http..proxy` syntax for a remote's direct URL and parent URLs. 2. Honor an empty configuration URL to override a proxy configuration. Add tests to ensure that configuration specificity is honored. --- src/remote.c | 204 ++++++++++++++++++--------------------- src/remote.h | 5 +- src/transports/http.c | 4 +- src/transports/winhttp.c | 6 +- tests/online/clone.c | 61 ------------ tests/remote/httpproxy.c | 139 ++++++++++++++++++++++++++ tests/remote/no_proxy.c | 40 -------- 7 files changed, 238 insertions(+), 221 deletions(-) create mode 100644 tests/remote/httpproxy.c delete mode 100644 tests/remote/no_proxy.c diff --git a/src/remote.c b/src/remote.c index e63f54a9b70..7dddea93afd 100644 --- a/src/remote.c +++ b/src/remote.c @@ -849,112 +849,91 @@ int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote return remote->transport->ls(out, size, remote->transport); } -int git_remote__get_http_proxy_bypass(git_net_url *url, git_buf *no_proxy_env, bool *bypass) +static int lookup_config(char **out, git_config *cfg, const char *name) { - int error = 0; - char *p_start = no_proxy_env->ptr; - size_t p_length = 0; - char c; - git_buf hostport = GIT_BUF_INIT; + git_config_entry *ce = NULL; + int error; - error = git_buf_printf(&hostport, "%s:%s", url->host, url->port); - if (error < 0) + if ((error = git_config__lookup_entry(&ce, cfg, name, false)) < 0) return error; - *bypass = false; - - do { - c = *(p_start + p_length); - if ((c == ',') || (c == 0)) { - if ((p_length == 1) && (*p_start == '*')) { - // wildcard match (*) - goto found; - } else if ((p_length == strlen(url->host)) && !memcmp(p_start, url->host, p_length)) { - // exact host match - goto found; - } else if ((p_length == strlen(hostport.ptr)) && !memcmp(p_start, hostport.ptr, p_length)) { - // exact host:port match - goto found; - } else { - if ((p_length >= 2) && (*p_start == '*') && (*(p_start + 1) == '.')) { - // *.foo == .foo - p_start++; - p_length--; - } - if ((*p_start == '.') && (strlen(url->host) > p_length) && !memcmp(p_start, url->host + strlen(url->host) - p_length, p_length)) { - // host suffix match (.example.org) - goto found; - } else if ((*p_start == '.') && (strlen(hostport.ptr) > p_length) && !memcmp(p_start, hostport.ptr + strlen(hostport.ptr) - p_length, p_length)) { - // host:port suffix match (.example.org:443) - goto found; - } - } - p_start += p_length + 1; - p_length = 0; - } else { - p_length++; - } - } while(c != 0); + if (ce && ce->value) { + *out = git__strdup(ce->value); + GIT_ERROR_CHECK_ALLOC(*out); + } else { + error = GIT_ENOTFOUND; + } + + git_config_entry_free(ce); + return error; +} - goto end; +static void url_config_trim(git_net_url *url) +{ + size_t len = strlen(url->path); -found: - *bypass = true; + if (url->path[len - 1] == '/') { + len--; + } else { + while (len && url->path[len - 1] != '/') + len--; + } -end: - git_buf_dispose(&hostport); - return 0; + url->path[len] = '\0'; } -int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, git_net_url *url, char **proxy_url) +static int http_proxy_config(char **out, git_remote *remote, git_net_url *url) { git_config *cfg; - git_config_entry *ce = NULL; - git_buf proxy_env = GIT_BUF_INIT; - git_buf no_proxy_env = GIT_BUF_INIT; - bool bypass = false; + git_buf buf = GIT_BUF_INIT; + git_net_url lookup_url = GIT_NET_URL_INIT; int error; - GIT_ASSERT_ARG(remote); + if ((error = git_net_url_dup(&lookup_url, url)) < 0 || + (error = git_repository_config__weakptr(&cfg, remote->repo)) < 0) + goto done; - if (!proxy_url || !remote->repo) - return -1; + /* remote..proxy config setting */ + if (remote->name && remote->name[0]) { + git_buf_clear(&buf); - *proxy_url = NULL; + if ((error = git_buf_printf(&buf, "remote.%s.proxy", remote->name)) < 0 || + (error = lookup_config(out, cfg, buf.ptr)) != GIT_ENOTFOUND) + goto done; + } - if ((error = git_repository_config__weakptr(&cfg, remote->repo)) < 0) - return error; + while (true) { + git_buf_clear(&buf); - /* Go through the possible sources for proxy configuration, from most specific - * to least specific. */ + if ((error = git_buf_puts(&buf, "http.")) < 0 || + (error = git_net_url_fmt(&buf, &lookup_url)) < 0 || + (error = git_buf_puts(&buf, ".proxy")) < 0 || + (error = lookup_config(out, cfg, buf.ptr)) != GIT_ENOTFOUND) + goto done; - /* remote..proxy config setting */ - if (remote->name && remote->name[0]) { - git_buf buf = GIT_BUF_INIT; + if (! lookup_url.path[0]) + break; - if ((error = git_buf_printf(&buf, "remote.%s.proxy", remote->name)) < 0) - return error; + url_config_trim(&lookup_url); + } - error = git_config__lookup_entry(&ce, cfg, git_buf_cstr(&buf), false); - git_buf_dispose(&buf); + git_buf_clear(&buf); - if (error < 0) - return error; + error = lookup_config(out, cfg, "http.proxy"); - if (ce && ce->value) { - *proxy_url = git__strdup(ce->value); - goto found; - } - } +done: + git_buf_dispose(&buf); + git_net_url_dispose(&lookup_url); + return error; +} - /* http.proxy config setting */ - if ((error = git_config__lookup_entry(&ce, cfg, "http.proxy", false)) < 0) - return error; +static int http_proxy_env(char **out, git_remote *remote, git_net_url *url) +{ + git_buf proxy_env = GIT_BUF_INIT, no_proxy_env = GIT_BUF_INIT; + bool use_ssl = (strcmp(url->scheme, "https") == 0); + int error; - if (ce && ce->value) { - *proxy_url = git__strdup(ce->value); - goto found; - } + GIT_UNUSED(remote); /* http_proxy / https_proxy environment variables */ error = git__getenv(&proxy_env, use_ssl ? "https_proxy" : "http_proxy"); @@ -963,46 +942,51 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, git_net_url *ur if (error == GIT_ENOTFOUND) error = git__getenv(&proxy_env, use_ssl ? "HTTPS_PROXY" : "HTTP_PROXY"); - if (error < 0) { - if (error == GIT_ENOTFOUND) { - git_error_clear(); - error = 0; - } - - return error; - } + if (error) + goto done; /* no_proxy/NO_PROXY environment variables */ error = git__getenv(&no_proxy_env, "no_proxy"); + if (error == GIT_ENOTFOUND) error = git__getenv(&no_proxy_env, "NO_PROXY"); - if (error == GIT_ENOTFOUND) { - git_error_clear(); - error = 0; - } else if (error < 0) { - goto cleanup; - } else { - error = git_remote__get_http_proxy_bypass(url, &no_proxy_env, &bypass); - } - - if (bypass) { - git_buf_dispose(&proxy_env); - goto cleanup; - } else { - *proxy_url = git_buf_detach(&proxy_env); - } + if (error && error != GIT_ENOTFOUND) + goto done; -found: - GIT_ERROR_CHECK_ALLOC(*proxy_url); + if (!git_net_url_matches_pattern_list(url, no_proxy_env.ptr)) + *out = git_buf_detach(&proxy_env); + else + error = GIT_ENOTFOUND; -cleanup: +done: + git_buf_dispose(&proxy_env); git_buf_dispose(&no_proxy_env); - git_config_entry_free(ce); - return error; } +int git_remote__http_proxy(char **out, git_remote *remote, git_net_url *url) +{ + int error; + + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(remote); + GIT_ASSERT_ARG(remote->repo); + + *out = NULL; + + /* + * Go through the possible sources for proxy configuration, + * Examine the various git config options first, then + * consult environment variables. + */ + if ((error = http_proxy_config(out, remote, url)) != GIT_ENOTFOUND || + (error = http_proxy_env(out, remote, url)) != GIT_ENOTFOUND) + return error; + + return 0; +} + /* DWIM `refspecs` based on `refs` and append the output to `out` */ static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs) { diff --git a/src/remote.h b/src/remote.h index ffcefdf7f86..ce92db76aa5 100644 --- a/src/remote.h +++ b/src/remote.h @@ -9,13 +9,13 @@ #include "common.h" -#include "net.h" #include "git2/remote.h" #include "git2/transport.h" #include "git2/sys/transport.h" #include "refspec.h" #include "vector.h" +#include "net.h" #define GIT_REMOTE_ORIGIN "origin" @@ -47,8 +47,7 @@ typedef struct git_remote_connection_opts { int git_remote__connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_remote_connection_opts *conn); int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int direction, const git_remote_callbacks *callbacks); -int git_remote__get_http_proxy_bypass(git_net_url *url, git_buf *no_proxy_env, bool *bypass); -int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, git_net_url *url, char **proxy_url); +int git_remote__http_proxy(char **out, git_remote *remote, git_net_url *url); git_refspec *git_remote__matching_refspec(git_remote *remote, const char *refname); git_refspec *git_remote__matching_dst_refspec(git_remote *remote, const char *refname); diff --git a/src/transports/http.c b/src/transports/http.c index 5468674e0d4..914335aba57 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -290,7 +290,6 @@ static int lookup_proxy( { const char *proxy; git_remote *remote; - bool use_ssl; char *config = NULL; int error = 0; @@ -304,9 +303,8 @@ static int lookup_proxy( case GIT_PROXY_AUTO: remote = transport->owner->owner; - use_ssl = !strcmp(transport->server.url.scheme, "https"); - error = git_remote__get_http_proxy(remote, use_ssl, &transport->server.url, &config); + error = git_remote__http_proxy(&config, remote, &transport->server.url); if (error || !config) goto done; diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index 8dc39d8bb3e..178773a41a3 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -373,7 +373,6 @@ static int winhttp_stream_connect(winhttp_stream *s) { winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); git_buf buf = GIT_BUF_INIT; - bool use_ssl; char *proxy_url = NULL; wchar_t ct[MAX_CONTENT_TYPE_LEN]; LPCWSTR types[] = { L"*/*", NULL }; @@ -430,8 +429,7 @@ static int winhttp_stream_connect(winhttp_stream *s) proxy_opts = &t->owner->proxy; if (proxy_opts->type == GIT_PROXY_AUTO) { /* Set proxy if necessary */ - use_ssl = strcmp(t->server.url.scheme, "https") == 0; - if (git_remote__get_http_proxy(t->owner->owner, use_ssl, &t->server.url, &proxy_url) < 0) + if (git_remote__http_proxy(&proxy_url, t->owner->owner, &t->server.url) < 0) goto on_error; } else if (proxy_opts->type == GIT_PROXY_SPECIFIED) { @@ -744,7 +742,7 @@ static void CALLBACK winhttp_status( git_error_set(GIT_ERROR_HTTP, "unknown security error %lu", status); break; - + case WINHTTP_CALLBACK_STATUS_SENDING_REQUEST: ((winhttp_stream *) ctx)->status_sending_request_reached = 1; diff --git a/tests/online/clone.c b/tests/online/clone.c index d9b1837df43..7d43c6a098f 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -898,67 +898,6 @@ void test_online_clone__proxy_credentials_in_url_https(void) git_buf_dispose(&url); } -struct no_proxy_test_entry { - char no_proxy[128]; - bool bypass; -}; - -static struct no_proxy_test_entry no_proxy_test_entries[] = { - {"*", true}, - {"github.com", true}, - {"github.com:443", true}, - {"github.com:80", false}, - {".github.com", false}, - {"*.github.com", false}, - {".com", true}, - {"*.com", true}, - {".com:443", true}, - {"*.com:443", true}, - {".com:80", false}, - {"*.com:80", false}, - {"", false} -}; - -void test_online_clone__no_proxy_in_environment(void) -{ - int error = 0; - unsigned int i; - git_buf proxy_url = GIT_BUF_INIT; - - _orig_http_proxy = cl_getenv("HTTP_PROXY"); - _orig_https_proxy = cl_getenv("HTTPS_PROXY"); - _orig_no_proxy = cl_getenv("NO_PROXY"); - _orig_proxies_need_reset = 1; - - g_options.fetch_opts.proxy_opts.type = GIT_PROXY_AUTO; - g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb; - - cl_git_pass(git_buf_printf(&proxy_url, "http://does-not-exists.example.org:1234/")); - - cl_setenv("HTTP_PROXY", proxy_url.ptr); - cl_setenv("HTTPS_PROXY", proxy_url.ptr); - - - for (i = 0; i < ARRAY_SIZE(no_proxy_test_entries); ++i) { - cl_setenv("NO_PROXY", no_proxy_test_entries[i].no_proxy); - error = git_clone(&g_repo, "https://github.com/libgit2/TestGitRepository", "./foo", &g_options); - - if (no_proxy_test_entries[i].bypass) { - cl_assert_(error == 0, no_proxy_test_entries[i].no_proxy); - } else { - cl_assert_(error == -1, no_proxy_test_entries[i].no_proxy); - } - - if (g_repo) { - git_repository_free(g_repo); - g_repo = NULL; - } - cl_fixture_cleanup("./foo"); - } - - git_buf_dispose(&proxy_url); -} - void test_online_clone__proxy_auto_not_detected(void) { g_options.fetch_opts.proxy_opts.type = GIT_PROXY_AUTO; diff --git a/tests/remote/httpproxy.c b/tests/remote/httpproxy.c new file mode 100644 index 00000000000..097db4cd587 --- /dev/null +++ b/tests/remote/httpproxy.c @@ -0,0 +1,139 @@ +#include "clar_libgit2.h" +#include "remote.h" +#include "net.h" + +static git_repository *repo; +static git_net_url url = GIT_NET_URL_INIT; + +static int orig_proxies_need_reset = 0; +static char *orig_http_proxy = NULL; +static char *orig_https_proxy = NULL; +static char *orig_no_proxy = NULL; + +void test_remote_httpproxy__initialize(void) +{ + git_remote *remote; + + repo = cl_git_sandbox_init("testrepo"); + cl_git_pass(git_remote_create(&remote, repo, "lg2", "https://github.com/libgit2/libgit2")); + cl_git_pass(git_net_url_parse(&url, "https://github.com/libgit2/libgit2")); + + git_remote_free(remote); + + orig_proxies_need_reset = 0; +} + +void test_remote_httpproxy__cleanup(void) +{ + if (orig_proxies_need_reset) { + cl_setenv("HTTP_PROXY", orig_http_proxy); + cl_setenv("HTTPS_PROXY", orig_https_proxy); + cl_setenv("NO_PROXY", orig_no_proxy); + + git__free(orig_http_proxy); + git__free(orig_https_proxy); + git__free(orig_no_proxy); + } + + git_net_url_dispose(&url); + cl_git_sandbox_cleanup(); +} + +void assert_proxy_is(const char *expected) +{ + git_remote *remote; + char *proxy; + + cl_git_pass(git_remote_lookup(&remote, repo, "lg2")); + cl_git_pass(git_remote__http_proxy(&proxy, remote, &url)); + + if (expected) + cl_assert_equal_s(proxy, expected); + else + cl_assert_equal_p(proxy, expected); + + git_remote_free(remote); + git__free(proxy); +} + +void assert_config_match(const char *config, const char *expected) +{ + git_remote *remote; + char *proxy; + + if (config) + cl_repo_set_string(repo, config, expected); + + cl_git_pass(git_remote_lookup(&remote, repo, "lg2")); + cl_git_pass(git_remote__http_proxy(&proxy, remote, &url)); + + if (expected) + cl_assert_equal_s(proxy, expected); + else + cl_assert_equal_p(proxy, expected); + + git_remote_free(remote); + git__free(proxy); +} + +void test_remote_httpproxy__config_overrides(void) +{ + /* + * http.proxy should be honored, then http..proxy should + * be honored in increasing specificity of the url. finally, + * remote..proxy is the most specific. + */ + assert_config_match(NULL, NULL); + assert_config_match("http.proxy", "http://localhost:1/"); + assert_config_match("http.https://github.com.proxy", "http://localhost:2/"); + assert_config_match("http.https://github.com/.proxy", "http://localhost:3/"); + assert_config_match("http.https://github.com/libgit2.proxy", "http://localhost:4/"); + assert_config_match("http.https://github.com/libgit2/.proxy", "http://localhost:5/"); + assert_config_match("http.https://github.com/libgit2/libgit2.proxy", "http://localhost:6/"); + assert_config_match("remote.lg2.proxy", "http://localhost:7/"); +} + +void test_remote_httpproxy__config_empty_overrides(void) +{ + /* + * with greater specificity, an empty config entry overrides + * a set one + */ + assert_config_match("http.proxy", "http://localhost:1/"); + assert_config_match("http.https://github.com.proxy", ""); + assert_config_match("http.https://github.com/libgit2/libgit2.proxy", "http://localhost:2/"); + assert_config_match("remote.lg2.proxy", ""); +} + +void test_remote_httpproxy__env(void) +{ + orig_http_proxy = cl_getenv("HTTP_PROXY"); + orig_https_proxy = cl_getenv("HTTPS_PROXY"); + orig_no_proxy = cl_getenv("NO_PROXY"); + orig_proxies_need_reset = 1; + + /* HTTP proxy is ignored for HTTPS */ + cl_setenv("HTTP_PROXY", "http://localhost:9/"); + assert_proxy_is(NULL); + + /* HTTPS proxy is honored for HTTPS */ + cl_setenv("HTTPS_PROXY", "http://localhost:10/"); + assert_proxy_is("http://localhost:10/"); + + /* NO_PROXY is honored */ + cl_setenv("NO_PROXY", "github.com:443"); + assert_proxy_is(NULL); + + cl_setenv("NO_PROXY", "github.com:80"); + assert_proxy_is("http://localhost:10/"); + + cl_setenv("NO_PROXY", "github.com"); + assert_proxy_is(NULL); + + cl_setenv("NO_PROXY", "github.dev,github.com,github.foo"); + assert_proxy_is(NULL); + + /* configuration overrides environment variables */ + cl_setenv("NO_PROXY", "github.none"); + assert_config_match("http.https://github.com.proxy", "http://localhost:11/"); +} diff --git a/tests/remote/no_proxy.c b/tests/remote/no_proxy.c deleted file mode 100644 index 4f758415c30..00000000000 --- a/tests/remote/no_proxy.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "clar_libgit2.h" -#include "remote.h" - -/* Suite data */ -struct no_proxy_test_entry { - char url[128]; - char no_proxy[128]; - bool bypass; -}; - -static struct no_proxy_test_entry no_proxy_test_entries[] = { - {"https://example.com/", "", false}, - {"https://example.com/", "example.org", false}, - {"https://example.com/", "*", true}, - {"https://example.com/", "example.com,example.org", true}, - {"https://example.com/", ".example.com,example.org", false}, - {"https://foo.example.com/", ".example.com,example.org", true}, - {"https://example.com/", "foo.example.com,example.org", false}, - -}; - -void test_remote_no_proxy__entries(void) -{ - unsigned int i; - git_net_url url = GIT_NET_URL_INIT; - git_buf no_proxy = GIT_BUF_INIT; - bool bypass = false; - - for (i = 0; i < ARRAY_SIZE(no_proxy_test_entries); ++i) { - cl_git_pass(git_net_url_parse(&url, no_proxy_test_entries[i].url)); - cl_git_pass(git_buf_sets(&no_proxy, no_proxy_test_entries[i].no_proxy)); - cl_git_pass(git_remote__get_http_proxy_bypass(&url, &no_proxy, &bypass)); - - cl_assert_(bypass == no_proxy_test_entries[i].bypass, no_proxy_test_entries[i].no_proxy); - - git_net_url_dispose(&url); - git_buf_dispose(&no_proxy); - } - -} From fd50810aeb3f2eb968521e9b540dfa211b4f1350 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 1 Sep 2021 22:49:14 -0400 Subject: [PATCH 0504/1616] url: ensure minimum components for formatting --- src/net.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/net.c b/src/net.c index a685e48938b..de28bf9f8cd 100644 --- a/src/net.c +++ b/src/net.c @@ -401,6 +401,9 @@ void git_net_url_swap(git_net_url *a, git_net_url *b) int git_net_url_fmt(git_buf *buf, git_net_url *url) { + GIT_ASSERT_ARG(in->scheme); + GIT_ASSERT_ARG(in->host); + git_buf_puts(buf, url->scheme); git_buf_puts(buf, "://"); From 4fd32be01c79a5c003bb47674ac1d76d948518b7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 1 Sep 2021 23:06:19 -0400 Subject: [PATCH 0505/1616] url: ensure minimum components for formatting --- src/net.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/net.c b/src/net.c index de28bf9f8cd..361e40e7b05 100644 --- a/src/net.c +++ b/src/net.c @@ -401,8 +401,9 @@ void git_net_url_swap(git_net_url *a, git_net_url *b) int git_net_url_fmt(git_buf *buf, git_net_url *url) { - GIT_ASSERT_ARG(in->scheme); - GIT_ASSERT_ARG(in->host); + GIT_ASSERT_ARG(url); + GIT_ASSERT_ARG(url->scheme); + GIT_ASSERT_ARG(url->host); git_buf_puts(buf, url->scheme); git_buf_puts(buf, "://"); From 27f50a66124054518d5febe984bccad02ee0846b Mon Sep 17 00:00:00 2001 From: Miguel Arroz <750683+arroz@users.noreply.github.com> Date: Thu, 2 Sep 2021 18:59:19 -0700 Subject: [PATCH 0506/1616] #6028: Check if `threadstate->error_t.message` is not `git_buf__initbuf` before freeing. This follows the same principle as `buffer.c` where the same check is done before freeing the buffer. It fixes the crash described in #6028. --- src/threadstate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/threadstate.c b/src/threadstate.c index 6031e8280ff..e2c08975fd9 100644 --- a/src/threadstate.c +++ b/src/threadstate.c @@ -36,7 +36,8 @@ static void threadstate_dispose(git_threadstate *threadstate) if (!threadstate) return; - git__free(threadstate->error_t.message); + if (threadstate->error_t.message != git_buf__initbuf) + git__free(threadstate->error_t.message); threadstate->error_t.message = NULL; } From 2f3074da512624c9522683f9aa6bca6642a3e4f7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 3 Sep 2021 17:03:00 -0400 Subject: [PATCH 0507/1616] repo: refactor extensions tests into their own file --- tests/repo/extensions.c | 44 +++++++++++++++++++++++++++++++++++++++++ tests/repo/open.c | 42 --------------------------------------- 2 files changed, 44 insertions(+), 42 deletions(-) create mode 100644 tests/repo/extensions.c diff --git a/tests/repo/extensions.c b/tests/repo/extensions.c new file mode 100644 index 00000000000..8ba89f1a988 --- /dev/null +++ b/tests/repo/extensions.c @@ -0,0 +1,44 @@ +#include "clar_libgit2.h" +#include "futils.h" +#include "sysdir.h" +#include + +git_repository *repo; + +void test_repo_extensions__initialize(void) +{ + git_config *config; + + repo = cl_git_sandbox_init("empty_bare.git"); + + cl_git_pass(git_repository_config(&config, repo)); + cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1)); + git_config_free(config); +} + +void test_repo_extensions__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_repo_extensions__builtin(void) +{ + git_repository *extended; + + cl_repo_set_string(repo, "extensions.noop", "foobar"); + + cl_git_pass(git_repository_open(&extended, "empty_bare.git")); + cl_assert(git_repository_path(extended) != NULL); + cl_assert(git__suffixcmp(git_repository_path(extended), "/") == 0); + git_repository_free(extended); +} + +void test_repo_extensions__unsupported(void) +{ + git_repository *extended = NULL; + + cl_repo_set_string(repo, "extensions.unknown", "foobar"); + + cl_git_fail(git_repository_open(&extended, "empty_bare.git")); + git_repository_free(extended); +} diff --git a/tests/repo/open.c b/tests/repo/open.c index 881a23d34e5..bd60c12c29b 100644 --- a/tests/repo/open.c +++ b/tests/repo/open.c @@ -42,48 +42,6 @@ void test_repo_open__format_version_1(void) git_repository_free(repo); } -void test_repo_open__format_version_1_with_valid_extension(void) -{ - git_repository *repo; - git_config *config; - - repo = cl_git_sandbox_init("empty_bare.git"); - - cl_git_pass(git_repository_open(&repo, "empty_bare.git")); - cl_git_pass(git_repository_config(&config, repo)); - - cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1)); - cl_git_pass(git_config_set_int32(config, "extensions.noop", 1)); - - git_config_free(config); - git_repository_free(repo); - - cl_git_pass(git_repository_open(&repo, "empty_bare.git")); - cl_assert(git_repository_path(repo) != NULL); - cl_assert(git__suffixcmp(git_repository_path(repo), "/") == 0); - git_repository_free(repo); -} - -void test_repo_open__format_version_1_with_invalid_extension(void) -{ - git_repository *repo; - git_config *config; - - repo = cl_git_sandbox_init("empty_bare.git"); - - cl_git_pass(git_repository_open(&repo, "empty_bare.git")); - cl_git_pass(git_repository_config(&config, repo)); - - cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 1)); - cl_git_pass(git_config_set_int32(config, "extensions.invalid", 1)); - - git_config_free(config); - git_repository_free(repo); - - cl_git_fail(git_repository_open(&repo, "empty_bare.git")); - git_repository_free(repo); -} - void test_repo_open__standard_empty_repo_through_gitdir(void) { git_repository *repo; From a24e656a4e6278157d2aec885e0d300f47f74938 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 4 Sep 2021 10:16:41 -0400 Subject: [PATCH 0508/1616] common: support custom repository extensions Allow users to specify additional repository extensions that they want to support. For example, callers can specify that they support `preciousObjects` and then may open repositories that support `extensions.preciousObjects`. Similarly, callers may opt out of supporting extensions that the library itself supports. --- include/git2/common.h | 20 ++++++- src/libgit2.c | 23 ++++++++ src/repository.c | 115 ++++++++++++++++++++++++++++++++++++++-- src/repository.h | 4 ++ tests/core/opts.c | 46 ++++++++++++++++ tests/repo/extensions.c | 28 ++++++++++ 6 files changed, 232 insertions(+), 4 deletions(-) diff --git a/include/git2/common.h b/include/git2/common.h index d278c01b6ff..2ee82902529 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -209,7 +209,9 @@ typedef enum { GIT_OPT_GET_MWINDOW_FILE_LIMIT, GIT_OPT_SET_MWINDOW_FILE_LIMIT, GIT_OPT_SET_ODB_PACKED_PRIORITY, - GIT_OPT_SET_ODB_LOOSE_PRIORITY + GIT_OPT_SET_ODB_LOOSE_PRIORITY, + GIT_OPT_GET_EXTENSIONS, + GIT_OPT_SET_EXTENSIONS } git_libgit2_opt_t; /** @@ -431,6 +433,22 @@ typedef enum { * > Override the default priority of the loose ODB backend which * > is added when default backends are assigned to a repository * + * opts(GIT_OPT_GET_EXTENSIONS, git_strarray *out) + * > Returns the list of git extensions that are supported. This + * > is the list of built-in extensions supported by libgit2 and + * > custom extensions that have been added with + * > `GIT_OPT_SET_EXTENSIONS`. Extensions that have been negated + * > will not be returned. The returned list should be released + * > with `git_strarray_dispose`. + * + * opts(GIT_OPT_SET_EXTENSIONS, const char **extensions, size_t len) + * > Set that the given git extensions are supported by the caller. + * > Extensions supported by libgit2 may be negated by prefixing + * > them with a `!`. For example: setting extensions to + * > { "!noop", "newext" } indicates that the caller does not want + * > to support repositories with the `noop` extension but does want + * > to support repositories with the `newext` extension. + * * @param option Option key * @param ... value to set the option * @return 0 on success, <0 on failure diff --git a/src/libgit2.c b/src/libgit2.c index 09f7ab533c8..cc793b4587f 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -52,6 +52,7 @@ static void libgit2_settings_global_shutdown(void) { git__free(git__user_agent); git__free(git__ssl_ciphers); + git_repository__free_extensions(); } static int git_libgit2_settings_global_init(void) @@ -367,6 +368,28 @@ int git_libgit2_opts(int key, ...) git_odb__loose_priority = va_arg(ap, int); break; + case GIT_OPT_SET_EXTENSIONS: + { + const char **extensions = va_arg(ap, const char **); + size_t len = va_arg(ap, size_t); + error = git_repository__set_extensions(extensions, len); + } + break; + + case GIT_OPT_GET_EXTENSIONS: + { + git_strarray *out = va_arg(ap, git_strarray *); + char **extensions; + size_t len; + + if ((error = git_repository__extensions(&extensions, &len)) < 0) + break; + + out->strings = extensions; + out->count = len; + } + break; + default: git_error_set(GIT_ERROR_INVALID, "invalid option key"); error = -1; diff --git a/src/repository.c b/src/repository.c index aae0c910ba5..d3211137962 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1427,15 +1427,60 @@ static int check_repositoryformatversion(int *version, git_config *config) return 0; } +static const char *builtin_extensions[] = { + "noop" +}; + +static git_vector user_extensions = GIT_VECTOR_INIT; + static int check_valid_extension(const git_config_entry *entry, void *payload) { + git_buf cfg = GIT_BUF_INIT; + bool reject; + const char *extension; + size_t i; + int error = 0; + GIT_UNUSED(payload); - if (!strcmp(entry->name, "extensions.noop")) - return 0; + git_vector_foreach (&user_extensions, i, extension) { + git_buf_clear(&cfg); + + /* + * Users can specify that they don't want to support an + * extension with a '!' prefix. + */ + if ((reject = (extension[0] == '!')) == true) + extension = &extension[1]; + + if ((error = git_buf_printf(&cfg, "extensions.%s", extension)) < 0) + goto done; + if (strcmp(entry->name, cfg.ptr) == 0) { + if (reject) + goto fail; + + goto done; + } + } + + for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) { + extension = builtin_extensions[i]; + + if ((error = git_buf_printf(&cfg, "extensions.%s", extension)) < 0) + goto done; + + if (strcmp(entry->name, cfg.ptr) == 0) + goto done; + } + +fail: git_error_set(GIT_ERROR_REPOSITORY, "unsupported extension name %s", entry->name); - return -1; + error = -1; + +done: + git_buf_dispose(&cfg); + return error; } static int check_extensions(git_config *config, int version) @@ -1446,6 +1491,70 @@ static int check_extensions(git_config *config, int version) return git_config_foreach_match(config, "^extensions\\.", check_valid_extension, NULL); } +int git_repository__extensions(char ***out, size_t *out_len) +{ + git_vector extensions; + const char *builtin, *user; + char *extension; + size_t i, j; + + if (git_vector_init(&extensions, 8, NULL) < 0) + return -1; + + for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) { + bool match = false; + + builtin = builtin_extensions[i]; + + git_vector_foreach (&user_extensions, j, user) { + if (user[0] == '!' && strcmp(builtin, &user[1]) == 0) { + match = true; + break; + } + } + + if (match) + continue; + + if ((extension = git__strdup(builtin)) == NULL || + git_vector_insert(&extensions, extension) < 0) + return -1; + } + + git_vector_foreach (&user_extensions, i, user) { + if (user[0] == '!') + continue; + + if ((extension = git__strdup(user)) == NULL || + git_vector_insert(&extensions, extension) < 0) + return -1; + } + + *out = (char **)git_vector_detach(out_len, NULL, &extensions); + return 0; +} + +int git_repository__set_extensions(const char **extensions, size_t len) +{ + char *extension; + size_t i; + + git_repository__free_extensions(); + + for (i = 0; i < len; i++) { + if ((extension = git__strdup(extensions[i])) == NULL || + git_vector_insert(&user_extensions, extension) < 0) + return -1; + } + + return 0; +} + +void git_repository__free_extensions(void) +{ + git_vector_free_deep(&user_extensions); +} + int git_repository_create_head(const char *git_dir, const char *ref_name) { git_buf ref_path = GIT_BUF_INIT; diff --git a/src/repository.h b/src/repository.h index f48dd9edfe0..cbc160140f3 100644 --- a/src/repository.h +++ b/src/repository.h @@ -249,4 +249,8 @@ int git_repository_initialbranch(git_buf *out, git_repository *repo); */ int git_repository_workdir_path(git_buf *out, git_repository *repo, const char *path); +int git_repository__extensions(char ***out, size_t *out_len); +int git_repository__set_extensions(const char **extensions, size_t len); +void git_repository__free_extensions(void); + #endif diff --git a/tests/core/opts.c b/tests/core/opts.c index 72408cbe821..e8f65d51017 100644 --- a/tests/core/opts.c +++ b/tests/core/opts.c @@ -1,6 +1,11 @@ #include "clar_libgit2.h" #include "cache.h" +void test_core_opts__cleanup(void) +{ + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, NULL, 0)); +} + void test_core_opts__readwrite(void) { size_t old_val = 0; @@ -23,3 +28,44 @@ void test_core_opts__invalid_option(void) cl_git_fail(git_libgit2_opts(-1, "foobar")); } +void test_core_opts__extensions_query(void) +{ + git_strarray out = { 0 }; + + cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out)); + + cl_assert_equal_sz(out.count, 1); + cl_assert_equal_s("noop", out.strings[0]); + + git_strarray_dispose(&out); +} + +void test_core_opts__extensions_add(void) +{ + const char *in[] = { "foo" }; + git_strarray out = { 0 }; + + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in))); + cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out)); + + cl_assert_equal_sz(out.count, 2); + cl_assert_equal_s("noop", out.strings[0]); + cl_assert_equal_s("foo", out.strings[1]); + + git_strarray_dispose(&out); +} + +void test_core_opts__extensions_remove(void) +{ + const char *in[] = { "bar", "!negate", "!noop", "baz" }; + git_strarray out = { 0 }; + + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in))); + cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out)); + + cl_assert_equal_sz(out.count, 2); + cl_assert_equal_s("bar", out.strings[0]); + cl_assert_equal_s("baz", out.strings[1]); + + git_strarray_dispose(&out); +} diff --git a/tests/repo/extensions.c b/tests/repo/extensions.c index 8ba89f1a988..e7772acd512 100644 --- a/tests/repo/extensions.c +++ b/tests/repo/extensions.c @@ -19,6 +19,7 @@ void test_repo_extensions__initialize(void) void test_repo_extensions__cleanup(void) { cl_git_sandbox_cleanup(); + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, NULL, 0)); } void test_repo_extensions__builtin(void) @@ -33,6 +34,19 @@ void test_repo_extensions__builtin(void) git_repository_free(extended); } +void test_repo_extensions__negate_builtin(void) +{ + const char *in[] = { "foo", "!noop", "baz" }; + git_repository *extended; + + cl_repo_set_string(repo, "extensions.noop", "foobar"); + + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in))); + + cl_git_fail(git_repository_open(&extended, "empty_bare.git")); + git_repository_free(extended); +} + void test_repo_extensions__unsupported(void) { git_repository *extended = NULL; @@ -42,3 +56,17 @@ void test_repo_extensions__unsupported(void) cl_git_fail(git_repository_open(&extended, "empty_bare.git")); git_repository_free(extended); } + +void test_repo_extensions__adds_extension(void) +{ + const char *in[] = { "foo", "!noop", "newextension", "baz" }; + git_repository *extended; + + cl_repo_set_string(repo, "extensions.newextension", "foobar"); + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in))); + + cl_git_pass(git_repository_open(&extended, "empty_bare.git")); + cl_assert(git_repository_path(extended) != NULL); + cl_assert(git__suffixcmp(git_repository_path(extended), "/") == 0); + git_repository_free(extended); +} From 62ee779ea4cdd877419571442860a0d29896a59c Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sat, 4 Sep 2021 18:01:10 -0700 Subject: [PATCH 0509/1616] remote: Mark `git_remote_name_is_valid` as `GIT_EXTERN` This change makes `git_remote_name_is_valid` be part of the public interface of the library. This is needed for other language bindings to be able to find this symbol (like in git2go, when linking against libgit2 dynamically). --- include/git2/remote.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/remote.h b/include/git2/remote.h index 1f52fcd949c..51a7d1cdc65 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -971,7 +971,7 @@ GIT_EXTERN(int) git_remote_rename( * @param remote_name name to be checked. * @return 0 on success or an error code */ -int git_remote_name_is_valid(int *valid, const char *remote_name); +GIT_EXTERN(int) git_remote_name_is_valid(int *valid, const char *remote_name); /** * Delete an existing persisted remote. From f1b89a201e9329e6df48f8d6cf320781570c936a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 5 Sep 2021 09:55:59 -0400 Subject: [PATCH 0510/1616] README: update build badges for our branches --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c5ef0224f36..9ecb706bd6c 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ libgit2 - the Git linkable library | Build Status | | | ------------ | - | | **main** branch CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush) | +| **v1.2 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.2&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.2) | | **v1.1 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.1&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.1) | -| **v1.0 branch** CI builds | [![Azure Pipelines Build Status](https://dev.azure.com/libgit2/libgit2/_apis/build/status/libgit2?branchName=maint/v1.0)](https://dev.azure.com/libgit2/libgit2/_build/latest?definitionId=7&branchName=maint/v1.0) | | **Nightly** builds | [![Nightly Build](https://github.com/libgit2/libgit2/workflows/Nightly%20Build/badge.svg)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22Nightly+Build%22) [![Coverity Scan Status](https://scan.coverity.com/projects/639/badge.svg)](https://scan.coverity.com/projects/639) | `libgit2` is a portable, pure C implementation of the Git core methods From 66a75fdee622557346700bae8314ca4af166e0f9 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 7 Sep 2021 07:14:39 -0700 Subject: [PATCH 0511/1616] indexer: Avoid one `mmap(2)`/`munmap(2)` pair per `git_indexer_append` call This change makes `append_to_pack` completely rely on `p_pwrite` to do all its I/O instead of splitting it between `p_pwrite` and a `mmap(2)`/`munmap(2)`+`memcpy(3)`. This saves a good chunk of user CPU time and avoids making two syscalls per round, but doesn't really cut down a lot of wall time (~1% on cloning the [git](https://github.com/git/git.git) repository). --- src/indexer.c | 49 ++----------------------------------------------- 1 file changed, 2 insertions(+), 47 deletions(-) diff --git a/src/indexer.c b/src/indexer.c index d546888ccd9..a5c282a2442 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -603,7 +603,6 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size) static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t size) { -#ifdef NO_MMAP size_t remaining_size = size; const char *ptr = (const char *)data; @@ -619,65 +618,21 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s offset += nb; remaining_size -= nb; } -#else - git_file fd = idx->pack->mwf.fd; - size_t mmap_alignment; - size_t page_offset; - off64_t page_start; - unsigned char *map_data; - git_map map; - int error; - - GIT_ASSERT_ARG(data); - GIT_ASSERT_ARG(size); - - if ((error = git__mmap_alignment(&mmap_alignment)) < 0) - return error; - - /* the offset needs to be at the mmap boundary for the platform */ - page_offset = offset % mmap_alignment; - page_start = offset - page_offset; - - if ((error = p_mmap(&map, page_offset + size, GIT_PROT_WRITE, GIT_MAP_SHARED, fd, page_start)) < 0) - return error; - - map_data = (unsigned char *)map.data; - memcpy(map_data + page_offset, data, size); - p_munmap(&map); -#endif return 0; } static int append_to_pack(git_indexer *idx, const void *data, size_t size) { - off64_t new_size; - size_t mmap_alignment; - size_t page_offset; - off64_t page_start; - off64_t current_size = idx->pack->mwf.size; - int error; - if (!size) return 0; - if ((error = git__mmap_alignment(&mmap_alignment)) < 0) - return error; - - /* Write a single byte to force the file system to allocate space now or - * report an error, since we can't report errors when writing using mmap. - * Round the size up to the nearest page so that we only need to perform file - * I/O when we add a page, instead of whenever we write even a single byte. */ - new_size = current_size + size; - page_offset = new_size % mmap_alignment; - page_start = new_size - page_offset; - - if (p_pwrite(idx->pack->mwf.fd, data, 1, page_start + mmap_alignment - 1) < 0) { + if (write_at(idx, data, idx->pack->mwf.size, size) < 0) { git_error_set(GIT_ERROR_OS, "cannot extend packfile '%s'", idx->pack->pack_name); return -1; } - return write_at(idx, data, idx->pack->mwf.size, size); + return 0; } static int read_stream_object(git_indexer *idx, git_indexer_progress *stats) From eeceaac06c12b488ca1cb538db067b44664f4db9 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 7 Sep 2021 08:38:35 -0700 Subject: [PATCH 0512/1616] Also remove a `ftruncate(2)` call in `git_indexer_commit` Now that we're not using `mmap(2)` for writing stuff, we don't need to truncate the file afterwards, since it'll have the correct size at the end of the process. Whee~! --- src/indexer.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/indexer.c b/src/indexer.c index a5c282a2442..d1e354af7fb 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -1234,12 +1234,6 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) if (git_mwindow_free_all(&idx->pack->mwf) < 0) goto on_error; - /* Truncate file to undo rounding up to next page_size in append_to_pack */ - if (p_ftruncate(idx->pack->mwf.fd, idx->pack->mwf.size) < 0) { - git_error_set(GIT_ERROR_OS, "failed to truncate pack file '%s'", idx->pack->pack_name); - return -1; - } - if (idx->do_fsync && p_fsync(idx->pack->mwf.fd) < 0) { git_error_set(GIT_ERROR_OS, "failed to fsync packfile"); goto on_error; From 6571ba7b3585a390b6de164aaa5eb93036ef295c Mon Sep 17 00:00:00 2001 From: lhchavez Date: Wed, 8 Sep 2021 06:29:58 -0700 Subject: [PATCH 0513/1616] Only avoid `mmap(2)`/`ftruncate(2)` when in non-Windows It turns out that if we use `mmap(2)`, non-Windows remote filesystems break due to permissions. If we don't, _Windows_ remote filesystems break due to lack of coherence between memory mapped views of the file and direct I/O operations done to the files. To break out of this impossible situation, conditionally-compile versions of Windows-specific `write_at` and `append_to_pack`. --- src/indexer.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/src/indexer.c b/src/indexer.c index d1e354af7fb..d5e32888073 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -601,6 +601,8 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size) idx->inbuf_len += size - to_expell; } +#if defined(NO_MMAP) || !defined(GIT_WIN32) + static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t size) { size_t remaining_size = size; @@ -624,17 +626,86 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s static int append_to_pack(git_indexer *idx, const void *data, size_t size) { + if (write_at(idx, data, idx->pack->mwf.size, size) < 0) { + git_error_set(GIT_ERROR_OS, "cannot extend packfile '%s'", idx->pack->pack_name); + return -1; + } + + return 0; +} + +#else + +/* + * Windows may keep different views to a networked file for the mmap- and + * open-accessed versions of a file, so any writes done through + * `write(2)`/`pwrite(2)` may not be reflected on the data that `mmap(2)` is + * able to read. + */ + +static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t size) +{ + git_file fd = idx->pack->mwf.fd; + size_t mmap_alignment; + size_t page_offset; + off64_t page_start; + unsigned char *map_data; + git_map map; + int error; + + GIT_ASSERT_ARG(data); + GIT_ASSERT_ARG(size); + + if ((error = git__mmap_alignment(&mmap_alignment)) < 0) + return error; + + /* the offset needs to be at the mmap boundary for the platform */ + page_offset = offset % mmap_alignment; + page_start = offset - page_offset; + + if ((error = p_mmap(&map, page_offset + size, GIT_PROT_WRITE, GIT_MAP_SHARED, fd, page_start)) < 0) + return error; + + map_data = (unsigned char *)map.data; + memcpy(map_data + page_offset, data, size); + p_munmap(&map); + + return 0; +} + +static int append_to_pack(git_indexer *idx, const void *data, size_t size) +{ + off64_t new_size; + size_t mmap_alignment; + size_t page_offset; + off64_t page_start; + off64_t current_size = idx->pack->mwf.size; + int error; + if (!size) return 0; - if (write_at(idx, data, idx->pack->mwf.size, size) < 0) { + if ((error = git__mmap_alignment(&mmap_alignment)) < 0) + return error; + + /* Write a single byte to force the file system to allocate space now or + * report an error, since we can't report errors when writing using mmap. + * Round the size up to the nearest page so that we only need to perform file + * I/O when we add a page, instead of whenever we write even a single byte. */ + new_size = current_size + size; + page_offset = new_size % mmap_alignment; + page_start = new_size - page_offset; + + if (p_pwrite(idx->pack->mwf.fd, data, 1, page_start + mmap_alignment - 1) < 0) { git_error_set(GIT_ERROR_OS, "cannot extend packfile '%s'", idx->pack->pack_name); return -1; } - return 0; + return write_at(idx, data, idx->pack->mwf.size, size); } +#endif + static int read_stream_object(git_indexer *idx, git_indexer_progress *stats) { git_packfile_stream *stream = &idx->stream; @@ -1234,6 +1305,17 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) if (git_mwindow_free_all(&idx->pack->mwf) < 0) goto on_error; +#if !defined(NO_MMAP) && defined(GIT_WIN32) + /* + * Truncate file to undo rounding up to next page_size in append_to_pack only + * when mmap was used, to prevent failures in non-Windows remote filesystems. + */ + if (p_ftruncate(idx->pack->mwf.fd, idx->pack->mwf.size) < 0) { + git_error_set(GIT_ERROR_OS, "failed to truncate pack file '%s'", idx->pack->pack_name); + return -1; + } +#endif + if (idx->do_fsync && p_fsync(idx->pack->mwf.fd) < 0) { git_error_set(GIT_ERROR_OS, "failed to fsync packfile"); goto on_error; From c65eb24c546a37c8225a1e8b00bd3ab81818243f Mon Sep 17 00:00:00 2001 From: lhchavez Date: Wed, 8 Sep 2021 08:47:39 -0700 Subject: [PATCH 0514/1616] Avoid double negatives in the justification for truncation Turns out, double negatives are harder to parse than positive statements. --- src/indexer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/indexer.c b/src/indexer.c index d5e32888073..ce77375007c 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -1307,8 +1307,11 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) #if !defined(NO_MMAP) && defined(GIT_WIN32) /* - * Truncate file to undo rounding up to next page_size in append_to_pack only - * when mmap was used, to prevent failures in non-Windows remote filesystems. + * Some non-Windows remote filesystems fail when truncating files if the + * file permissions change after opening the file (done by p_mkstemp). + * + * Truncation is only needed when mmap is used to undo rounding up to next + * page_size in append_to_pack. */ if (p_ftruncate(idx->pack->mwf.fd, idx->pack->mwf.size) < 0) { git_error_set(GIT_ERROR_OS, "failed to truncate pack file '%s'", idx->pack->pack_name); From 6c53d6ab393fec13e9af8a3d9df5b74959352f4b Mon Sep 17 00:00:00 2001 From: Duncan Thomson Date: Wed, 8 Sep 2021 18:42:42 +0100 Subject: [PATCH 0515/1616] Use __typeof__ GNUC keyword for ISO C compatibility --- src/cc-compat.h | 8 +------- src/util.h | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/cc-compat.h b/src/cc-compat.h index 6bdc6514526..f701b2d9351 100644 --- a/src/cc-compat.h +++ b/src/cc-compat.h @@ -29,12 +29,6 @@ # endif #endif -#ifdef __GNUC__ -# define GIT_TYPEOF(x) (__typeof__(x)) -#else -# define GIT_TYPEOF(x) -#endif - #if defined(__GNUC__) # define GIT_ALIGN(x,size) x __attribute__ ((aligned(size))) #elif defined(_MSC_VER) @@ -46,7 +40,7 @@ #if defined(__GNUC__) # define GIT_UNUSED(x) \ do { \ - typeof(x) _unused __attribute__((unused)); \ + __typeof__(x) _unused __attribute__((unused)); \ _unused = (x); \ } while (0) #else diff --git a/src/util.h b/src/util.h index 68c2b1804e7..e8074fcb9da 100644 --- a/src/util.h +++ b/src/util.h @@ -34,7 +34,7 @@ # define GIT_CONTAINER_OF(ptr, type, member) \ __builtin_choose_expr( \ __builtin_offsetof(type, member) == 0 && \ - __builtin_types_compatible_p(typeof(&((type *) 0)->member), typeof(ptr)), \ + __builtin_types_compatible_p(__typeof__(&((type *) 0)->member), __typeof__(ptr)), \ ((type *) (ptr)), \ (void)0) #else From 379c46463cbdd73e04c5efc180309d4600e56624 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Thu, 9 Sep 2021 19:49:04 +0200 Subject: [PATCH 0516/1616] Fix coding style for pointer Make some syntax change to follow coding style. --- include/git2/clone.h | 2 +- include/git2/notes.h | 4 ++-- include/git2/remote.h | 6 +++--- include/git2/repository.h | 10 +++++----- include/git2/stash.h | 2 +- src/blame.c | 8 ++++---- src/blame_git.c | 2 +- src/buffer.c | 4 ++-- src/clone.c | 2 +- src/commit_graph.c | 2 +- src/config.c | 2 +- src/config_file.c | 4 ++-- src/describe.c | 2 +- src/hash/sha1/sha1dc/sha1.c | 16 ++++++++-------- src/merge.c | 2 +- src/notes.c | 6 +++--- src/path.c | 2 +- src/path.h | 2 +- src/refdb_fs.c | 2 +- src/refs.c | 4 ++-- src/refspec.c | 2 +- src/remote.c | 2 +- src/repository.c | 10 +++++----- src/reset.c | 2 +- src/revparse.c | 8 ++++---- src/stash.c | 2 +- src/streams/openssl_legacy.c | 2 +- src/streams/openssl_legacy.h | 2 +- src/trailer.c | 2 +- src/transports/ssh.c | 8 ++++---- src/transports/winhttp.c | 2 +- src/win32/findfile.c | 2 +- src/win32/posix.h | 12 ++++++------ src/win32/posix_w32.c | 12 ++++++------ 34 files changed, 76 insertions(+), 76 deletions(-) diff --git a/include/git2/clone.h b/include/git2/clone.h index 2d6f687050f..3c3ea260eff 100644 --- a/include/git2/clone.h +++ b/include/git2/clone.h @@ -133,7 +133,7 @@ typedef struct git_clone_options { * The name of the branch to checkout. NULL means use the * remote's default branch. */ - const char* checkout_branch; + const char *checkout_branch; /** * A callback used to create the new repository into which to diff --git a/include/git2/notes.h b/include/git2/notes.h index c36149e5ba0..c135881a7c8 100644 --- a/include/git2/notes.h +++ b/include/git2/notes.h @@ -84,8 +84,8 @@ GIT_EXTERN(void) git_note_iterator_free(git_note_iterator *it); * (negative value) */ GIT_EXTERN(int) git_note_next( - git_oid* note_id, - git_oid* annotated_id, + git_oid *note_id, + git_oid *annotated_id, git_note_iterator *it); diff --git a/include/git2/remote.h b/include/git2/remote.h index 51a7d1cdc65..4d57eaaf74f 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -243,7 +243,7 @@ GIT_EXTERN(const char *) git_remote_pushurl(const git_remote *remote); * @param url the url to set * @return 0 or an error value */ -GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, const char* url); +GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, const char *url); /** * Set the remote's url for pushing in the configuration. @@ -257,7 +257,7 @@ GIT_EXTERN(int) git_remote_set_url(git_repository *repo, const char *remote, con * @param url the url to set * @return 0, or an error code */ -GIT_EXTERN(int) git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url); +GIT_EXTERN(int) git_remote_set_pushurl(git_repository *repo, const char *remote, const char *url); /** * Set the url for this particular url instance. The URL in the @@ -451,7 +451,7 @@ typedef int GIT_CALLBACK(git_push_transfer_progress_cb)( unsigned int current, unsigned int total, size_t bytes, - void* payload); + void *payload); /** * Represents an update which will be performed on the remote during push diff --git a/include/git2/repository.h b/include/git2/repository.h index 45becc73d97..e699016447d 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -797,8 +797,8 @@ GIT_EXTERN(int) git_repository_hashfile( * @return 0 on success, or an error code */ GIT_EXTERN(int) git_repository_set_head( - git_repository* repo, - const char* refname); + git_repository *repo, + const char *refname); /** * Make the repository HEAD directly point to the Commit. @@ -817,8 +817,8 @@ GIT_EXTERN(int) git_repository_set_head( * @return 0 on success, or an error code */ GIT_EXTERN(int) git_repository_set_head_detached( - git_repository* repo, - const git_oid* commitish); + git_repository *repo, + const git_oid *commitish); /** * Make the repository HEAD directly point to the Commit. @@ -854,7 +854,7 @@ GIT_EXTERN(int) git_repository_set_head_detached_from_annotated( * branch or an error code */ GIT_EXTERN(int) git_repository_detach_head( - git_repository* repo); + git_repository *repo); /** * Repository state diff --git a/include/git2/stash.h b/include/git2/stash.h index 625e51b4b4f..795920ebc76 100644 --- a/include/git2/stash.h +++ b/include/git2/stash.h @@ -200,7 +200,7 @@ GIT_EXTERN(int) git_stash_apply( */ typedef int GIT_CALLBACK(git_stash_cb)( size_t index, - const char* message, + const char *message, const git_oid *stash_id, void *payload); diff --git a/src/blame.c b/src/blame.c index 10e311aee55..a6ab43efd8f 100644 --- a/src/blame.c +++ b/src/blame.c @@ -59,7 +59,7 @@ static bool hunk_starts_at_or_after_line(git_blame_hunk *hunk, size_t line) return line <= hunk->final_start_line_number; } -static git_blame_hunk* new_hunk( +static git_blame_hunk *new_hunk( size_t start, size_t lines, size_t orig_start, @@ -84,7 +84,7 @@ static void free_hunk(git_blame_hunk *hunk) git__free(hunk); } -static git_blame_hunk* dup_hunk(git_blame_hunk *hunk) +static git_blame_hunk *dup_hunk(git_blame_hunk *hunk) { git_blame_hunk *newhunk = new_hunk( hunk->final_start_line_number, @@ -122,7 +122,7 @@ static void shift_hunks_by(git_vector *v, size_t start_line, int shift_by) } } -git_blame* git_blame__alloc( +git_blame *git_blame__alloc( git_repository *repo, git_blame_options opts, const char *path) @@ -299,7 +299,7 @@ static int index_blob_lines(git_blame *blame) return blame->num_lines; } -static git_blame_hunk* hunk_from_entry(git_blame__entry *e, git_blame *blame) +static git_blame_hunk *hunk_from_entry(git_blame__entry *e, git_blame *blame) { git_blame_hunk *h = new_hunk( e->lno+1, e->num_lines, e->s_lno+1, e->suspect->path); diff --git a/src/blame_git.c b/src/blame_git.c index 073137a68a1..3d514a1bc0f 100644 --- a/src/blame_git.c +++ b/src/blame_git.c @@ -429,7 +429,7 @@ static int paths_on_dup(void **old, void *new) return -1; } -static git_blame__origin* find_origin( +static git_blame__origin *find_origin( git_blame *blame, git_commit *parent, git_blame__origin *origin) diff --git a/src/buffer.c b/src/buffer.c index 794e1f1abf6..ab2a6139a45 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -670,7 +670,7 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...) va_start(ap, nbuf); for (i = 0; i < nbuf; ++i) { - const char* segment; + const char *segment; size_t segment_len; segment = va_arg(ap, const char *); @@ -702,7 +702,7 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...) va_start(ap, nbuf); for (i = 0; i < nbuf; ++i) { - const char* segment; + const char *segment; size_t segment_len; segment = va_arg(ap, const char *); diff --git a/src/clone.c b/src/clone.c index e29a4aab35b..752df3b92d8 100644 --- a/src/clone.c +++ b/src/clone.c @@ -265,7 +265,7 @@ static int update_head_to_branch( { int retcode; git_buf remote_branch_name = GIT_BUF_INIT; - git_reference* remote_ref = NULL; + git_reference *remote_ref = NULL; git_buf default_branch = GIT_BUF_INIT; GIT_ASSERT_ARG(remote); diff --git a/src/commit_graph.c b/src/commit_graph.c index 71e415e99d1..f663fc5d3be 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -728,7 +728,7 @@ int git_commit_graph_writer_add_revwalk(git_commit_graph_writer *w, git_revwalk git_oid id; git_repository *repo = git_revwalk_repository(walk); git_commit *commit; - struct packed_commit* packed_commit; + struct packed_commit *packed_commit; while ((git_revwalk_next(&id, walk)) == 0) { error = git_commit_lookup(&commit, repo, &id); diff --git a/src/config.c b/src/config.c index 7a5dadd87cc..3251cd51fdb 100644 --- a/src/config.c +++ b/src/config.c @@ -511,7 +511,7 @@ int git_config_backend_foreach_match( void *payload) { git_config_entry *entry; - git_config_iterator* iter; + git_config_iterator *iter; git_regexp regex; int error = 0; diff --git a/src/config_file.c b/src/config_file.c index 5267beb943d..3588e6be6c4 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -164,7 +164,7 @@ static int config_file_is_modified(int *modified, config_file *file) return error; } -static void config_file_clear_includes(config_file_backend* cfg) +static void config_file_clear_includes(config_file_backend *cfg) { config_file *include; uint32_t i; @@ -1104,7 +1104,7 @@ static int write_on_eof( /* * This is pretty much the parsing, except we write out anything we don't have */ -static int config_file_write(config_file_backend *cfg, const char *orig_key, const char *key, const git_regexp *preg, const char* value) +static int config_file_write(config_file_backend *cfg, const char *orig_key, const char *key, const git_regexp *preg, const char *value) { char *orig_section = NULL, *section = NULL, *orig_name, *name, *ldot; diff --git a/src/describe.c b/src/describe.c index 3648ccef632..103d0da5c8d 100644 --- a/src/describe.c +++ b/src/describe.c @@ -391,7 +391,7 @@ static int show_suffix( git_buf *buf, int depth, git_repository *repo, - const git_oid* id, + const git_oid *id, unsigned int abbrev_size) { int error, size = 0; diff --git a/src/hash/sha1/sha1dc/sha1.c b/src/hash/sha1/sha1dc/sha1.c index 86b8cc075d1..4d03c75d8c2 100644 --- a/src/hash/sha1/sha1dc/sha1.c +++ b/src/hash/sha1/sha1dc/sha1.c @@ -1710,7 +1710,7 @@ static void sha1_recompression_step(uint32_t step, uint32_t ihvin[5], uint32_t i -static void sha1_process(SHA1_CTX* ctx, const uint32_t block[16]) +static void sha1_process(SHA1_CTX *ctx, const uint32_t block[16]) { unsigned i, j; uint32_t ubc_dv_mask[DVMASKSIZE] = { 0xFFFFFFFF }; @@ -1762,7 +1762,7 @@ static void sha1_process(SHA1_CTX* ctx, const uint32_t block[16]) } } -void SHA1DCInit(SHA1_CTX* ctx) +void SHA1DCInit(SHA1_CTX *ctx) { ctx->total = 0; ctx->ihv[0] = 0x67452301; @@ -1778,7 +1778,7 @@ void SHA1DCInit(SHA1_CTX* ctx) ctx->callback = NULL; } -void SHA1DCSetSafeHash(SHA1_CTX* ctx, int safehash) +void SHA1DCSetSafeHash(SHA1_CTX *ctx, int safehash) { if (safehash) ctx->safe_hash = 1; @@ -1787,7 +1787,7 @@ void SHA1DCSetSafeHash(SHA1_CTX* ctx, int safehash) } -void SHA1DCSetUseUBC(SHA1_CTX* ctx, int ubc_check) +void SHA1DCSetUseUBC(SHA1_CTX *ctx, int ubc_check) { if (ubc_check) ctx->ubc_check = 1; @@ -1795,7 +1795,7 @@ void SHA1DCSetUseUBC(SHA1_CTX* ctx, int ubc_check) ctx->ubc_check = 0; } -void SHA1DCSetUseDetectColl(SHA1_CTX* ctx, int detect_coll) +void SHA1DCSetUseDetectColl(SHA1_CTX *ctx, int detect_coll) { if (detect_coll) ctx->detect_coll = 1; @@ -1803,7 +1803,7 @@ void SHA1DCSetUseDetectColl(SHA1_CTX* ctx, int detect_coll) ctx->detect_coll = 0; } -void SHA1DCSetDetectReducedRoundCollision(SHA1_CTX* ctx, int reduced_round_coll) +void SHA1DCSetDetectReducedRoundCollision(SHA1_CTX *ctx, int reduced_round_coll) { if (reduced_round_coll) ctx->reduced_round_coll = 1; @@ -1811,12 +1811,12 @@ void SHA1DCSetDetectReducedRoundCollision(SHA1_CTX* ctx, int reduced_round_coll) ctx->reduced_round_coll = 0; } -void SHA1DCSetCallback(SHA1_CTX* ctx, collision_block_callback callback) +void SHA1DCSetCallback(SHA1_CTX *ctx, collision_block_callback callback) { ctx->callback = callback; } -void SHA1DCUpdate(SHA1_CTX* ctx, const char* buf, size_t len) +void SHA1DCUpdate(SHA1_CTX *ctx, const char *buf, size_t len) { unsigned left, fill; diff --git a/src/merge.c b/src/merge.c index 0e4bb582a35..191fb98ba46 100644 --- a/src/merge.c +++ b/src/merge.c @@ -1151,7 +1151,7 @@ static void deletes_by_oid_free(git_oidmap *map) { git_oidmap_free(map); } -static int deletes_by_oid_enqueue(git_oidmap *map, git_pool* pool, const git_oid *id, size_t idx) +static int deletes_by_oid_enqueue(git_oidmap *map, git_pool *pool, const git_oid *id, size_t idx) { deletes_by_oid_queue *queue; size_t *array_entry; diff --git a/src/notes.c b/src/notes.c index b9e198599d9..be52a5f13e9 100644 --- a/src/notes.c +++ b/src/notes.c @@ -674,7 +674,7 @@ void git_note_free(git_note *note) } static int process_entry_path( - const char* entry_path, + const char *entry_path, git_oid *annotated_object_id) { int error = 0; @@ -796,8 +796,8 @@ int git_note_iterator_new( } int git_note_next( - git_oid* note_id, - git_oid* annotated_id, + git_oid *note_id, + git_oid *annotated_id, git_note_iterator *it) { int error; diff --git a/src/path.c b/src/path.c index ec573220e90..c444b31a771 100644 --- a/src/path.c +++ b/src/path.c @@ -413,7 +413,7 @@ int git_path_to_dir(git_buf *path) return git_buf_oom(path) ? -1 : 0; } -void git_path_string_to_dir(char* path, size_t size) +void git_path_string_to_dir(char *path, size_t size) { size_t end = strlen(path); diff --git a/src/path.h b/src/path.h index dcf5652df05..de6ec8ff248 100644 --- a/src/path.h +++ b/src/path.h @@ -85,7 +85,7 @@ extern int git_path_to_dir(git_buf *path); /** * Ensure string has a trailing '/' if there is space for it. */ -extern void git_path_string_to_dir(char* path, size_t size); +extern void git_path_string_to_dir(char *path, size_t size); /** * Taken from git.git; returns nonzero if the given path is "." or "..". diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 0cb92551653..24cb22fb06f 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -764,7 +764,7 @@ static bool ref_is_available( static int reference_path_available( refdb_fs_backend *backend, const char *new_ref, - const char* old_ref, + const char *old_ref, int force) { size_t i; diff --git a/src/refs.c b/src/refs.c index 4900afabf12..8acfa84a5a6 100644 --- a/src/refs.c +++ b/src/refs.c @@ -249,7 +249,7 @@ int git_reference_dwim(git_reference **out, git_repository *repo, const char *re git_reference *ref; git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT; - static const char* formatters[] = { + static const char *formatters[] = { "%s", GIT_REFS_DIR "%s", GIT_REFS_TAGS_DIR "%s", @@ -1246,7 +1246,7 @@ int git_reference_is_note(const git_reference *ref) return git_reference__is_note(ref->name); } -static int peel_error(int error, const git_reference *ref, const char* msg) +static int peel_error(int error, const git_reference *ref, const char *msg) { git_error_set( GIT_ERROR_INVALID, diff --git a/src/refspec.c b/src/refspec.c index d0be29bf691..c72721a4373 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -359,7 +359,7 @@ int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs) git_remote_head key; git_refspec *cur; - const char* formatters[] = { + const char *formatters[] = { GIT_REFS_DIR "%s", GIT_REFS_TAGS_DIR "%s", GIT_REFS_HEADS_DIR "%s", diff --git a/src/remote.c b/src/remote.c index 7dddea93afd..154300bd2fe 100644 --- a/src/remote.c +++ b/src/remote.c @@ -677,7 +677,7 @@ int git_remote_set_instance_pushurl(git_remote *remote, const char *url) return 0; } -int git_remote_set_pushurl(git_repository *repo, const char *remote, const char* url) +int git_remote_set_pushurl(git_repository *repo, const char *remote, const char *url) { return set_url(repo, remote, CONFIG_PUSHURL_FMT, url); } diff --git a/src/repository.c b/src/repository.c index aae0c910ba5..4b63a1f7ef1 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2850,8 +2850,8 @@ static int detach(git_repository *repo, const git_oid *id, const char *new) } int git_repository_set_head( - git_repository* repo, - const char* refname) + git_repository *repo, + const char *refname) { git_reference *ref = NULL, *current = NULL, *new_head = NULL; git_buf log_message = GIT_BUF_INIT; @@ -2900,8 +2900,8 @@ int git_repository_set_head( } int git_repository_set_head_detached( - git_repository* repo, - const git_oid* commitish) + git_repository *repo, + const git_oid *commitish) { return detach(repo, commitish, NULL); } @@ -2916,7 +2916,7 @@ int git_repository_set_head_detached_from_annotated( return detach(repo, git_annotated_commit_id(commitish), commitish->description); } -int git_repository_detach_head(git_repository* repo) +int git_repository_detach_head(git_repository *repo) { git_reference *old_head = NULL, *new_head = NULL, *current = NULL; git_object *object = NULL; diff --git a/src/reset.c b/src/reset.c index dfae91d6fab..f21a620c653 100644 --- a/src/reset.c +++ b/src/reset.c @@ -22,7 +22,7 @@ int git_reset_default( git_repository *repo, const git_object *target, - const git_strarray* pathspecs) + const git_strarray *pathspecs) { git_object *commit = NULL; git_tree *tree = NULL; diff --git a/src/revparse.c b/src/revparse.c index b0c312d722c..b4d5d475938 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -14,7 +14,7 @@ #include "git2.h" -static int maybe_sha_or_abbrev(git_object** out, git_repository *repo, const char *spec, size_t speclen) +static int maybe_sha_or_abbrev(git_object **out, git_repository *repo, const char *spec, size_t speclen) { git_oid oid; @@ -24,7 +24,7 @@ static int maybe_sha_or_abbrev(git_object** out, git_repository *repo, const cha return git_object_lookup_prefix(out, repo, &oid, speclen, GIT_OBJECT_ANY); } -static int maybe_sha(git_object** out, git_repository *repo, const char *spec) +static int maybe_sha(git_object **out, git_repository *repo, const char *spec) { size_t speclen = strlen(spec); @@ -34,7 +34,7 @@ static int maybe_sha(git_object** out, git_repository *repo, const char *spec) return maybe_sha_or_abbrev(out, repo, spec, speclen); } -static int maybe_abbrev(git_object** out, git_repository *repo, const char *spec) +static int maybe_abbrev(git_object **out, git_repository *repo, const char *spec) { size_t speclen = strlen(spec); @@ -310,7 +310,7 @@ static int retrieve_remote_tracking_reference(git_reference **base_ref, const ch return error; } -static int handle_at_syntax(git_object **out, git_reference **ref, const char *spec, size_t identifier_len, git_repository* repo, const char *curly_braces_content) +static int handle_at_syntax(git_object **out, git_reference **ref, const char *spec, size_t identifier_len, git_repository *repo, const char *curly_braces_content) { bool is_numeric; int parsed = 0, error = -1; diff --git a/src/stash.c b/src/stash.c index 8ee12732295..49ea26fdd52 100644 --- a/src/stash.c +++ b/src/stash.c @@ -56,7 +56,7 @@ static int append_abbreviated_oid(git_buf *out, const git_oid *b_commit) return git_buf_oom(out) ? -1 : 0; } -static int append_commit_description(git_buf *out, git_commit* commit) +static int append_commit_description(git_buf *out, git_commit *commit) { const char *summary = git_commit_summary(commit); GIT_ERROR_CHECK_ALLOC(summary); diff --git a/src/streams/openssl_legacy.c b/src/streams/openssl_legacy.c index 1c1ff60c07b..e61e6efbb5e 100644 --- a/src/streams/openssl_legacy.c +++ b/src/streams/openssl_legacy.c @@ -36,7 +36,7 @@ int OPENSSL_init_ssl__legacy(uint64_t opts, const void *settings) return 0; } -BIO_METHOD* BIO_meth_new__legacy(int type, const char *name) +BIO_METHOD *BIO_meth_new__legacy(int type, const char *name) { BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD)); if (!meth) { diff --git a/src/streams/openssl_legacy.h b/src/streams/openssl_legacy.h index 1f74fd95ab9..e6dae957207 100644 --- a/src/streams/openssl_legacy.h +++ b/src/streams/openssl_legacy.h @@ -42,7 +42,7 @@ #if defined(GIT_OPENSSL_LEGACY) || defined(GIT_OPENSSL_DYNAMIC) extern int OPENSSL_init_ssl__legacy(uint64_t opts, const void *settings); -extern BIO_METHOD* BIO_meth_new__legacy(int type, const char *name); +extern BIO_METHOD *BIO_meth_new__legacy(int type, const char *name); extern void BIO_meth_free__legacy(BIO_METHOD *biom); extern int BIO_meth_set_write__legacy(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)); extern int BIO_meth_set_read__legacy(BIO_METHOD *biom, int (*read) (BIO *, char *, int)); diff --git a/src/trailer.c b/src/trailer.c index ca81fd0205d..61cdd1ba170 100644 --- a/src/trailer.c +++ b/src/trailer.c @@ -258,7 +258,7 @@ static size_t find_trailer_end(const char *buf, size_t len) return len - ignore_non_trailer(buf, len); } -static char *extract_trailer_block(const char *message, size_t* len) +static char *extract_trailer_block(const char *message, size_t *len) { size_t patch_start = find_patch_start(message); size_t trailer_end = find_trailer_end(message, patch_start); diff --git a/src/transports/ssh.c b/src/transports/ssh.c index efa77a798eb..1b00be79cd6 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -476,11 +476,11 @@ static int request_creds(git_credential **out, ssh_subtransport *t, const char * } static int _git_ssh_session_create( - LIBSSH2_SESSION** session, + LIBSSH2_SESSION **session, git_stream *io) { int rc = 0; - LIBSSH2_SESSION* s; + LIBSSH2_SESSION *s; git_socket_stream *socket = GIT_CONTAINER_OF(io, git_socket_stream, parent); GIT_ASSERT_ARG(session); @@ -521,8 +521,8 @@ static int _git_ssh_setup_conn( size_t i; ssh_stream *s; git_credential *cred = NULL; - LIBSSH2_SESSION* session=NULL; - LIBSSH2_CHANNEL* channel=NULL; + LIBSSH2_SESSION *session=NULL; + LIBSSH2_CHANNEL *channel=NULL; t->current_stream = NULL; diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index 178773a41a3..f4801a4516b 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -250,7 +250,7 @@ static int acquire_fallback_cred( hCoInitResult = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (SUCCEEDED(hCoInitResult) || hCoInitResult == RPC_E_CHANGED_MODE) { - IInternetSecurityManager* pISM; + IInternetSecurityManager *pISM; /* And if the target URI is in the My Computer, Intranet, or Trusted zones */ if (SUCCEEDED(CoCreateInstance(&CLSID_InternetSecurityManager, NULL, diff --git a/src/win32/findfile.c b/src/win32/findfile.c index f541a03d4bc..40d2d518a18 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -49,7 +49,7 @@ static int win32_path_to_8(git_buf *dest, const wchar_t *src) return git_buf_sets(dest, utf8_path); } -static wchar_t* win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen) +static wchar_t *win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen) { wchar_t term, *base = path; diff --git a/src/win32/posix.h b/src/win32/posix.h index f115088b435..87c6b436ae7 100644 --- a/src/win32/posix.h +++ b/src/win32/posix.h @@ -23,7 +23,7 @@ typedef SOCKET GIT_SOCKET; extern int p_fstat(int fd, struct stat *buf); extern int p_lstat(const char *file_name, struct stat *buf); -extern int p_stat(const char* path, struct stat *buf); +extern int p_stat(const char *path, struct stat *buf); extern int p_utimes(const char *filename, const struct p_timeval times[2]); extern int p_futimes(int fd, const struct p_timeval times[2]); @@ -38,15 +38,15 @@ extern char *p_realpath(const char *orig_path, char *buffer); extern int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags); extern int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags); -extern int p_inet_pton(int af, const char* src, void* dst); +extern int p_inet_pton(int af, const char *src, void* dst); extern int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr); extern int p_snprintf(char *buffer, size_t count, const char *format, ...) GIT_FORMAT_PRINTF(3, 4); extern int p_mkstemp(char *tmp_path); -extern int p_chdir(const char* path); -extern int p_chmod(const char* path, mode_t mode); -extern int p_rmdir(const char* path); -extern int p_access(const char* path, mode_t mode); +extern int p_chdir(const char *path); +extern int p_chmod(const char *path, mode_t mode); +extern int p_rmdir(const char *path); +extern int p_access(const char *path, mode_t mode); extern int p_ftruncate(int fd, off64_t size); /* p_lstat is almost but not quite POSIX correct. Specifically, the use of diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index 7fcc472e970..66d12cfcfa9 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -690,7 +690,7 @@ static int getfinalpath_w( return (int)git_win32_path_remove_namespace(dest, dwChars); } -static int follow_and_lstat_link(git_win32_path path, struct stat* buf) +static int follow_and_lstat_link(git_win32_path path, struct stat *buf) { git_win32_path target_w; @@ -716,7 +716,7 @@ int p_fstat(int fd, struct stat *buf) return 0; } -int p_stat(const char* path, struct stat* buf) +int p_stat(const char *path, struct stat *buf) { git_win32_path path_w; int len; @@ -733,7 +733,7 @@ int p_stat(const char* path, struct stat* buf) return 0; } -int p_chdir(const char* path) +int p_chdir(const char *path) { git_win32_path buf; @@ -743,7 +743,7 @@ int p_chdir(const char* path) return _wchdir(buf); } -int p_chmod(const char* path, mode_t mode) +int p_chmod(const char *path, mode_t mode) { git_win32_path buf; @@ -753,7 +753,7 @@ int p_chmod(const char* path, mode_t mode) return _wchmod(buf, mode); } -int p_rmdir(const char* path) +int p_rmdir(const char *path) { git_win32_path buf; int error; @@ -873,7 +873,7 @@ int p_mkstemp(char *tmp_path) return p_open(tmp_path, O_RDWR | O_CREAT | O_EXCL, 0744); /* -V536 */ } -int p_access(const char* path, mode_t mode) +int p_access(const char *path, mode_t mode) { git_win32_path buf; From 5eab4dafbe441ef22f06bb1eae6f544a862b822b Mon Sep 17 00:00:00 2001 From: Basile Henry Date: Thu, 9 Sep 2021 21:51:52 +0200 Subject: [PATCH 0517/1616] Add test config parsing This tests parsing a multiline string containing multiple quoted comment chars. See #6019 --- tests/config/read.c | 7 +++++++ tests/resources/config/config21 | 5 +++++ 2 files changed, 12 insertions(+) create mode 100644 tests/resources/config/config21 diff --git a/tests/config/read.c b/tests/config/read.c index badf5118e8d..8d1bb8b0afa 100644 --- a/tests/config/read.c +++ b/tests/config/read.c @@ -213,6 +213,13 @@ void test_config_read__symbol_headers(void) git_config_free(cfg); } +void test_config_read__multiline_multiple_quoted_comment_chars(void) +{ + git_config *cfg; + cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config21"))); + git_config_free(cfg); +} + void test_config_read__header_in_last_line(void) { git_config *cfg; diff --git a/tests/resources/config/config21 b/tests/resources/config/config21 new file mode 100644 index 00000000000..aa5eb411538 --- /dev/null +++ b/tests/resources/config/config21 @@ -0,0 +1,5 @@ +[alias] + m = '\ + ";" \ + ";" \ + ' From 574c590f3095535e55e8f99b7f571ede28c8c211 Mon Sep 17 00:00:00 2001 From: Basile Henry Date: Thu, 9 Sep 2021 21:53:45 +0200 Subject: [PATCH 0518/1616] Fix multiline strip_comments logic The strip_comments function uses the count of quotes to know if a comment char (';' or '#') is the start of a comment or part of the multiline as a string. Unfortunately converting the count of quotes from previous lines to a boolean meant that it would only work as expected in some cases (0 quotes or an odd number of quotes). --- src/config_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config_parse.c b/src/config_parse.c index a2d779bfaa5..9f95e67d78c 100644 --- a/src/config_parse.c +++ b/src/config_parse.c @@ -349,7 +349,7 @@ static int parse_multiline_variable(git_config_parser *reader, git_buf *value, i } /* If it was just a comment, pretend it didn't exist */ - quote_count = strip_comments(line, !!in_quotes); + quote_count = strip_comments(line, in_quotes); if (line[0] == '\0') goto next; From cd0fd0f51eaacf302017c82161903297d3b76764 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 10 Sep 2021 07:19:06 -0400 Subject: [PATCH 0519/1616] notes: use a buffer internally Code cleanup to use `git_buf`s instead of simple c strings. --- src/notes.c | 56 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/notes.c b/src/notes.c index b9e198599d9..5eb16001934 100644 --- a/src/notes.c +++ b/src/notes.c @@ -407,31 +407,33 @@ static int note_remove( return error; } -static int note_get_default_ref(char **out, git_repository *repo) +static int note_get_default_ref(git_buf *out, git_repository *repo) { git_config *cfg; - int ret = git_repository_config__weakptr(&cfg, repo); + int error; + + if ((error = git_repository_config__weakptr(&cfg, repo)) < 0) + return error; - *out = (ret != 0) ? NULL : git_config__get_string_force( - cfg, "core.notesref", GIT_NOTES_DEFAULT_REF); + error = git_config_get_string_buf(out, cfg, "core.notesref"); - return ret; + if (error == GIT_ENOTFOUND) + error = git_buf_puts(out, GIT_NOTES_DEFAULT_REF); + + return error; } -static int normalize_namespace(char **out, git_repository *repo, const char *notes_ref) +static int normalize_namespace(git_buf *out, git_repository *repo, const char *notes_ref) { - if (notes_ref) { - *out = git__strdup(notes_ref); - GIT_ERROR_CHECK_ALLOC(*out); - return 0; - } + if (notes_ref) + return git_buf_puts(out, notes_ref); return note_get_default_ref(out, repo); } static int retrieve_note_commit( git_commit **commit_out, - char **notes_ref_out, + git_buf *notes_ref_out, git_repository *repo, const char *notes_ref) { @@ -441,7 +443,7 @@ static int retrieve_note_commit( if ((error = normalize_namespace(notes_ref_out, repo, notes_ref)) < 0) return error; - if ((error = git_reference_name_to_id(&oid, repo, *notes_ref_out)) < 0) + if ((error = git_reference_name_to_id(&oid, repo, notes_ref_out->ptr)) < 0) return error; if (git_commit_lookup(commit_out, repo, &oid) < 0) @@ -476,7 +478,7 @@ int git_note_read(git_note **out, git_repository *repo, const char *notes_ref_in, const git_oid *oid) { int error; - char *notes_ref = NULL; + git_buf notes_ref = GIT_BUF_INIT; git_commit *commit = NULL; error = retrieve_note_commit(&commit, ¬es_ref, repo, notes_ref_in); @@ -487,7 +489,7 @@ int git_note_read(git_note **out, git_repository *repo, error = git_note_commit_read(out, repo, commit, oid); cleanup: - git__free(notes_ref); + git_buf_dispose(¬es_ref); git_commit_free(commit); return error; } @@ -534,7 +536,7 @@ int git_note_create( int allow_note_overwrite) { int error; - char *notes_ref = NULL; + git_buf notes_ref = GIT_BUF_INIT; git_commit *existing_notes_commit = NULL; git_reference *ref = NULL; git_oid notes_blob_oid, notes_commit_oid; @@ -553,14 +555,14 @@ int git_note_create( if (error < 0) goto cleanup; - error = git_reference_create(&ref, repo, notes_ref, + error = git_reference_create(&ref, repo, notes_ref.ptr, ¬es_commit_oid, 1, NULL); if (out != NULL) git_oid_cpy(out, ¬es_blob_oid); cleanup: - git__free(notes_ref); + git_buf_dispose(¬es_ref); git_commit_free(existing_notes_commit); git_reference_free(ref); return error; @@ -596,7 +598,7 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in, const git_oid *oid) { int error; - char *notes_ref_target = NULL; + git_buf notes_ref_target = GIT_BUF_INIT; git_commit *existing_notes_commit = NULL; git_oid new_notes_commit; git_reference *notes_ref = NULL; @@ -612,11 +614,11 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in, if (error < 0) goto cleanup; - error = git_reference_create(¬es_ref, repo, notes_ref_target, + error = git_reference_create(¬es_ref, repo, notes_ref_target.ptr, &new_notes_commit, 1, NULL); cleanup: - git__free(notes_ref_target); + git_buf_dispose(¬es_ref_target); git_reference_free(notes_ref); git_commit_free(existing_notes_commit); return error; @@ -624,18 +626,16 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in, int git_note_default_ref(git_buf *out, git_repository *repo) { - char *default_ref; int error; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(repo); if ((error = git_buf_sanitize(out)) < 0 || - (error = note_get_default_ref(&default_ref, repo)) < 0) - return error; + (error = note_get_default_ref(out, repo)) < 0) + git_buf_dispose(out); - git_buf_attach(out, default_ref, strlen(default_ref)); - return 0; + return error; } const git_signature *git_note_committer(const git_note *note) @@ -780,7 +780,7 @@ int git_note_iterator_new( { int error; git_commit *commit = NULL; - char *notes_ref; + git_buf notes_ref = GIT_BUF_INIT; error = retrieve_note_commit(&commit, ¬es_ref, repo, notes_ref_in); if (error < 0) @@ -789,7 +789,7 @@ int git_note_iterator_new( error = git_note_commit_iterator_new(it, commit); cleanup: - git__free(notes_ref); + git_buf_dispose(¬es_ref); git_commit_free(commit); return error; From dfbb25f183a6f55ad02b5456ecda82fb0903e037 Mon Sep 17 00:00:00 2001 From: shijing Date: Sun, 12 Sep 2021 23:39:03 -0400 Subject: [PATCH 0520/1616] Update README.md Add git24j to the language bindings --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9ecb706bd6c..0cbde525b5a 100644 --- a/README.md +++ b/README.md @@ -371,6 +371,7 @@ Here are the bindings to libgit2 that are currently available: * hgit2 * Java * Jagged + * Git24j * Javascript / WebAssembly ( browser and nodejs ) * WASM-git * Julia From 31e32ddf35b0710fa528cfc1b7c67c5697207a66 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Tue, 14 Sep 2021 09:34:25 +0200 Subject: [PATCH 0521/1616] Add test to ensure empty proxy env behaves like unset env Signed-off-by: Mathieu Parent --- tests/remote/httpproxy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/remote/httpproxy.c b/tests/remote/httpproxy.c index 097db4cd587..00115a812ab 100644 --- a/tests/remote/httpproxy.c +++ b/tests/remote/httpproxy.c @@ -136,4 +136,8 @@ void test_remote_httpproxy__env(void) /* configuration overrides environment variables */ cl_setenv("NO_PROXY", "github.none"); assert_config_match("http.https://github.com.proxy", "http://localhost:11/"); + + /* empty env behaves like unset env */ + cl_setenv("HTTPS_PROXY", ""); + assert_proxy_is(NULL); } From 0a3a220fa9eba8cf9f8e250509958c2131b0a3c6 Mon Sep 17 00:00:00 2001 From: Laurent Stacul Date: Tue, 14 Sep 2021 09:53:24 +0000 Subject: [PATCH 0522/1616] Discover libssh2 without pkg-config --- cmake/FindLibSSH2.cmake | 13 +++++++++++++ src/CMakeLists.txt | 7 +++++++ 2 files changed, 20 insertions(+) create mode 100644 cmake/FindLibSSH2.cmake diff --git a/cmake/FindLibSSH2.cmake b/cmake/FindLibSSH2.cmake new file mode 100644 index 00000000000..ff5893525a6 --- /dev/null +++ b/cmake/FindLibSSH2.cmake @@ -0,0 +1,13 @@ +# LIBSSH2_FOUND - system has the libssh2 library +# LIBSSH2_INCLUDE_DIR - the libssh2 include directory +# LIBSSH2_LIBRARY - the libssh2 library name + +FIND_PATH(LIBSSH2_INCLUDE_DIR libssh2.h) + +FIND_LIBRARY(LIBSSH2_LIBRARY NAMES ssh2 libssh2) + +INCLUDE(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LibSSH2 + REQUIRED_VARS LIBSSH2_LIBRARY LIBSSH2_INCLUDE_DIR) + +MARK_AS_ADVANCED(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 45dec27962d..c3029a99fb1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -232,6 +232,13 @@ ENDIF() # Optional external dependency: libssh2 IF (USE_SSH) FIND_PKGLIBRARIES(LIBSSH2 libssh2) + IF (NOT LIBSSH2_FOUND) + FIND_PACKAGE(LibSSH2) + SET(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR}) + GET_FILENAME_COMPONENT(LIBSSH2_LIBRARY_DIRS "${LIBSSH2_LIBRARY}" DIRECTORY) + SET(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY}) + SET(LIBSSH2_LDFLAGS "-lssh2") + ENDIF() ENDIF() IF (LIBSSH2_FOUND) SET(GIT_SSH 1) From 26bf94c07b444a10108086174513e50e42fb9d4c Mon Sep 17 00:00:00 2001 From: Laurence McGlashan Date: Tue, 14 Sep 2021 12:19:54 +0100 Subject: [PATCH 0523/1616] If longpaths is true and filters are enabled, pass git_repository through the filtering code to ensure the cached longpath setting is returned. Fixes: #6054 --- src/blob.c | 7 ++++--- tests/win32/longpath.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/blob.c b/src/blob.c index 01ebf075e26..79096ee9544 100644 --- a/src/blob.c +++ b/src/blob.c @@ -138,12 +138,13 @@ static int write_file_filtered( git_object_size_t *size, git_odb *odb, const char *full_path, - git_filter_list *fl) + git_filter_list *fl, + git_repository* repo) { int error; git_buf tgt = GIT_BUF_INIT; - error = git_filter_list_apply_to_file(&tgt, fl, NULL, full_path); + error = git_filter_list_apply_to_file(&tgt, fl, repo, full_path); /* Write the file to disk if it was properly filtered */ if (!error) { @@ -238,7 +239,7 @@ int git_blob__create_from_paths( error = write_file_stream(id, odb, content_path, size); else { /* We need to apply one or more filters */ - error = write_file_filtered(id, &size, odb, content_path, fl); + error = write_file_filtered(id, &size, odb, content_path, fl, repo); git_filter_list_free(fl); } diff --git a/tests/win32/longpath.c b/tests/win32/longpath.c index ebfcc4d0d93..4bc8a837d87 100644 --- a/tests/win32/longpath.c +++ b/tests/win32/longpath.c @@ -90,3 +90,31 @@ void test_win32_longpath__status_and_add(void) git_buf_dispose(&out); #endif } + +void test_win32_longpath__status_and_add_with_filter(void) +{ +#ifdef GIT_WIN32 + git_repository *repo = cl_git_sandbox_init("testrepo"); + git_index *index; + git_buf out = GIT_BUF_INIT; + unsigned int status_flags; + + cl_repo_set_bool(repo, "core.longpaths", true); + cl_repo_set_bool(repo, "core.autocrlf", true); + cl_git_pass(git_repository_workdir_path(&out, repo, LONG_FILENAME)); + + cl_git_rewritefile(out.ptr, "This is a long path.\r\n"); + + cl_git_pass(git_status_file(&status_flags, repo, LONG_FILENAME)); + cl_assert_equal_i(GIT_STATUS_WT_NEW, status_flags); + + cl_git_pass(git_repository_index(&index, repo)); + cl_git_pass(git_index_add_bypath(index, LONG_FILENAME)); + + cl_git_pass(git_status_file(&status_flags, repo, LONG_FILENAME)); + cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status_flags); + + git_index_free(index); + git_buf_dispose(&out); +#endif +} From 6cf9a0b3ee341b8f56be7c1de4f2b23e98c28bbd Mon Sep 17 00:00:00 2001 From: Laurence McGlashan Date: Tue, 14 Sep 2021 12:34:45 +0100 Subject: [PATCH 0524/1616] Refactor shared code in longpath test. --- tests/win32/longpath.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/tests/win32/longpath.c b/tests/win32/longpath.c index 4bc8a837d87..294faea996c 100644 --- a/tests/win32/longpath.c +++ b/tests/win32/longpath.c @@ -64,15 +64,11 @@ void test_win32_longpath__workdir_path_validated(void) #endif } -void test_win32_longpath__status_and_add(void) -{ -#ifdef GIT_WIN32 - git_repository *repo = cl_git_sandbox_init("testrepo"); +static void assert_longpath_status_and_add(git_repository* repo) { git_index *index; git_buf out = GIT_BUF_INIT; unsigned int status_flags; - cl_repo_set_bool(repo, "core.longpaths", true); cl_git_pass(git_repository_workdir_path(&out, repo, LONG_FILENAME)); cl_git_rewritefile(out.ptr, "This is a long path.\r\n"); @@ -88,33 +84,27 @@ void test_win32_longpath__status_and_add(void) git_index_free(index); git_buf_dispose(&out); -#endif } -void test_win32_longpath__status_and_add_with_filter(void) +void test_win32_longpath__status_and_add(void) { #ifdef GIT_WIN32 git_repository *repo = cl_git_sandbox_init("testrepo"); - git_index *index; - git_buf out = GIT_BUF_INIT; - unsigned int status_flags; cl_repo_set_bool(repo, "core.longpaths", true); - cl_repo_set_bool(repo, "core.autocrlf", true); - cl_git_pass(git_repository_workdir_path(&out, repo, LONG_FILENAME)); - cl_git_rewritefile(out.ptr, "This is a long path.\r\n"); - - cl_git_pass(git_status_file(&status_flags, repo, LONG_FILENAME)); - cl_assert_equal_i(GIT_STATUS_WT_NEW, status_flags); + assert_longpath_status_and_add(repo); +#endif +} - cl_git_pass(git_repository_index(&index, repo)); - cl_git_pass(git_index_add_bypath(index, LONG_FILENAME)); +void test_win32_longpath__status_and_add_with_filter(void) +{ +#ifdef GIT_WIN32 + git_repository *repo = cl_git_sandbox_init("testrepo"); - cl_git_pass(git_status_file(&status_flags, repo, LONG_FILENAME)); - cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status_flags); + cl_repo_set_bool(repo, "core.longpaths", true); + cl_repo_set_bool(repo, "core.autocrlf", true); - git_index_free(index); - git_buf_dispose(&out); + assert_longpath_status_and_add(repo); #endif } From 413bfb83b2dfde9482a756fbcd1d5f5ba9315696 Mon Sep 17 00:00:00 2001 From: Laurent Stacul Date: Tue, 14 Sep 2021 13:53:29 +0200 Subject: [PATCH 0525/1616] Update src/CMakeLists.txt Co-authored-by: Edward Thomson --- src/CMakeLists.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c3029a99fb1..fdb367335b4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -232,13 +232,13 @@ ENDIF() # Optional external dependency: libssh2 IF (USE_SSH) FIND_PKGLIBRARIES(LIBSSH2 libssh2) - IF (NOT LIBSSH2_FOUND) - FIND_PACKAGE(LibSSH2) - SET(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR}) - GET_FILENAME_COMPONENT(LIBSSH2_LIBRARY_DIRS "${LIBSSH2_LIBRARY}" DIRECTORY) - SET(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY}) - SET(LIBSSH2_LDFLAGS "-lssh2") - ENDIF() + IF (NOT LIBSSH2_FOUND) + FIND_PACKAGE(LibSSH2) + SET(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR}) + GET_FILENAME_COMPONENT(LIBSSH2_LIBRARY_DIRS "${LIBSSH2_LIBRARY}" DIRECTORY) + SET(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY}) + SET(LIBSSH2_LDFLAGS "-lssh2") + ENDIF() ENDIF() IF (LIBSSH2_FOUND) SET(GIT_SSH 1) From 0d30e7bb3df520bb4f36d54b339baf231864b05d Mon Sep 17 00:00:00 2001 From: Laurence McGlashan Date: Tue, 14 Sep 2021 13:07:33 +0100 Subject: [PATCH 0526/1616] Apply suggestions from code review Co-authored-by: Edward Thomson --- tests/win32/longpath.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/win32/longpath.c b/tests/win32/longpath.c index 294faea996c..f300544f48d 100644 --- a/tests/win32/longpath.c +++ b/tests/win32/longpath.c @@ -64,6 +64,7 @@ void test_win32_longpath__workdir_path_validated(void) #endif } +#ifdef GIT_WIN32 static void assert_longpath_status_and_add(git_repository* repo) { git_index *index; git_buf out = GIT_BUF_INIT; @@ -85,6 +86,7 @@ static void assert_longpath_status_and_add(git_repository* repo) { git_index_free(index); git_buf_dispose(&out); } +#endif void test_win32_longpath__status_and_add(void) { From aa993f76ca556b06194e7da0f56afcf30cb5ee5e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 13 Sep 2021 11:40:38 -0400 Subject: [PATCH 0527/1616] buf: introduce `git_buf_truncate_at` --- src/buffer.c | 7 +++++++ src/buffer.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/buffer.c b/src/buffer.c index ab2a6139a45..a57df128498 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -600,6 +600,13 @@ void git_buf_shorten(git_buf *buf, size_t amount) git_buf_clear(buf); } +void git_buf_truncate_at_char(git_buf *buf, char separator) +{ + ssize_t idx = git_buf_find(buf, separator); + if (idx >= 0) + git_buf_truncate(buf, (size_t)idx); +} + void git_buf_rtruncate_at_char(git_buf *buf, char separator) { ssize_t idx = git_buf_rfind_next(buf, separator); diff --git a/src/buffer.h b/src/buffer.h index 7faa9fdc801..a356bebeae5 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -171,6 +171,7 @@ void git_buf_consume_bytes(git_buf *buf, size_t len); void git_buf_consume(git_buf *buf, const char *end); void git_buf_truncate(git_buf *buf, size_t len); void git_buf_shorten(git_buf *buf, size_t amount); +void git_buf_truncate_at_char(git_buf *buf, char separator); void git_buf_rtruncate_at_char(git_buf *path, char separator); /** General join with separator */ From 479a38bf153f13966a423124994e4ed91561e595 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 9 Sep 2021 15:21:48 -0500 Subject: [PATCH 0528/1616] merge: Check file mode when resolving renames. When determining if ours or theirs changed, we check the oids but not their respective file modes. This can lead to merges introducing incorrect file mode changes (eg., in a revert). A simple linear example might be: commit A - introduces file `foo` with chmod 0755 commit B - updates some unrelated file commit C - renames `foo` to `bar` and chmod 0644 If B is reverted, `bar` will unexpectedly acquire mode 0755. --- src/merge.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/merge.c b/src/merge.c index 191fb98ba46..1c841bdfbf2 100644 --- a/src/merge.c +++ b/src/merge.c @@ -816,8 +816,11 @@ static int merge_conflict_resolve_one_renamed( conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED) return 0; - ours_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->our_entry.id) != 0); - theirs_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->their_entry.id) != 0); + ours_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->our_entry.id) != 0) || + (conflict->ancestor_entry.mode != conflict->our_entry.mode); + + theirs_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->their_entry.id) != 0) || + (conflict->ancestor_entry.mode != conflict->their_entry.mode); /* if both are modified (and not to a common target) require a merge */ if (ours_changed && theirs_changed && From 516f7519f0b0b38cabc6c98ff1428b46b1f20b3e Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 9 Sep 2021 15:08:36 -0500 Subject: [PATCH 0529/1616] Add test for revert+rename bug. --- tests/resources/revert-rename.git/HEAD | 1 + tests/resources/revert-rename.git/config | 5 ++ tests/resources/revert-rename.git/index | Bin 0 -> 209 bytes .../revert-rename.git/objects/info/packs | 2 + ...63774fb90141e8aa7a326ace0566366114e869.idx | Bin 0 -> 1296 bytes ...3774fb90141e8aa7a326ace0566366114e869.pack | Bin 0 -> 783 bytes tests/resources/revert-rename.git/packed-refs | 2 + .../revert-rename.git/refs/heads/master | 1 + tests/revert/rename.c | 49 ++++++++++++++++++ 9 files changed, 60 insertions(+) create mode 100644 tests/resources/revert-rename.git/HEAD create mode 100644 tests/resources/revert-rename.git/config create mode 100644 tests/resources/revert-rename.git/index create mode 100644 tests/resources/revert-rename.git/objects/info/packs create mode 100644 tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.idx create mode 100644 tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.pack create mode 100644 tests/resources/revert-rename.git/packed-refs create mode 100644 tests/resources/revert-rename.git/refs/heads/master create mode 100644 tests/revert/rename.c diff --git a/tests/resources/revert-rename.git/HEAD b/tests/resources/revert-rename.git/HEAD new file mode 100644 index 00000000000..cb089cd89a7 --- /dev/null +++ b/tests/resources/revert-rename.git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/tests/resources/revert-rename.git/config b/tests/resources/revert-rename.git/config new file mode 100644 index 00000000000..a4ef456cbc2 --- /dev/null +++ b/tests/resources/revert-rename.git/config @@ -0,0 +1,5 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = true + logallrefupdates = true diff --git a/tests/resources/revert-rename.git/index b/tests/resources/revert-rename.git/index new file mode 100644 index 0000000000000000000000000000000000000000..232325dfb9ededfb2dacf48c7608a51b058b8d51 GIT binary patch literal 209 zcmZ?q402{*U|<5_M5}~DOvesy1JW5x`-@LAF#Ka>2;!K;z|gpafr0r21T%<#_~w(? zC+2o(N|$Ti^&@+JT@B97VBkp4&riwCPf2B90P0^Lw^HR0n9h-212tzlnmHn~;-}WF zVAr2lbW8jUgZU1T2Dh$c29DzV+|;zp9H2QNL9VVqcS$lBDHw2Vh_OBs@zCnV&OlL> i#V2i-$Sx?o=J}+auj?XX%GXN=_UiD~tL@^Nk^%q&Nl0%1 literal 0 HcmV?d00001 diff --git a/tests/resources/revert-rename.git/objects/info/packs b/tests/resources/revert-rename.git/objects/info/packs new file mode 100644 index 00000000000..5d971426edc --- /dev/null +++ b/tests/resources/revert-rename.git/objects/info/packs @@ -0,0 +1,2 @@ +P pack-4363774fb90141e8aa7a326ace0566366114e869.pack + diff --git a/tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.idx b/tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.idx new file mode 100644 index 0000000000000000000000000000000000000000..3fb48ea94b69a9ddfb5d85df8b0711190f17439d GIT binary patch literal 1296 zcmexg;-AdGz`z8=qkyy!U<4{3s+bw*_JP7IK)Y#yS%Kz`B+Lf%FEVBa@?n?*$R-K< zyqY7qsvt~d+l?l*eE%2fy~d9ks(owBJ2yv279VhEKV9x)V_J4kzxw^6ze*op9h(s3 zYkO#tW&Oh|;!?BXr`D}t*PmB(OZ*Ij`3{i=x31(3G1g}y9$MYl87Qi<_@wO;*#)K7 z-n`Fh6}QfJ$tYfEUmaB)vLfcD(1&k6iG5;jm!@>N=3PIs=hxNX+>FmYis$|3t>hF_ z<$e`r+rk%URBwO$@8bk(0%#_Asz#WDNi^#gu0n4Lu`fkoI^pr5w^ zX%L$mh&6$H9$*%I1;k0t$>sh#8697&sxrzt$C_rADDooH?bhjVeid6W;RP22Yv;Nj JzLv)r0RXA-bCdu8 literal 0 HcmV?d00001 diff --git a/tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.pack b/tests/resources/revert-rename.git/objects/pack/pack-4363774fb90141e8aa7a326ace0566366114e869.pack new file mode 100644 index 0000000000000000000000000000000000000000..e078ec2aa21e1108ae1e7139b57087f65badfaae GIT binary patch literal 783 zcmWG=boORoU|<4bj!6O)bLO7D$a%;>pyAK^ZsqBEpd1{PGe z<~_K5oWK6IS7VN+L3e---{fO=CKq4%*>Y*I+Iy2oHQr|vw{0?e@MbEjzjOUN5FHp`x{KpTT?cd{v`%=9MX@`s{*53F!|Fc5eC}#$?s?>dJ@YnCSN6)u-9^FTSefZ}Ft& z|AUvCdR{00JDF?CQ3rl{`khhHle%eFOS4IoCS~Cip}1J9bZsiFDA&T=z7OWXiqx#P9L^+J&EyOMD5OPXRMgx9pZ8N zjAy9Ed7YC19w8oHK7l9B`g=ZQVu%f9pSlI4z{k_mH_+qEY5kKPxfw5tr$NBUACxQA>e|$KrzR~~8+e=gQuJ3v6{_W2$sX4O~IRb;{%%44L z+RVwP47BUA?sAp=t#sXff5Zxr><~ZZtOy1^NxQ6B!v^sPp$aCzt#0WORJ7s>&$q9BZ0cqR5L( E0LgP@Hvj+t literal 0 HcmV?d00001 diff --git a/tests/resources/revert-rename.git/packed-refs b/tests/resources/revert-rename.git/packed-refs new file mode 100644 index 00000000000..e062909d40f --- /dev/null +++ b/tests/resources/revert-rename.git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +ecef6a85173b6f446873a13f7b5a7b54a85cd912 refs/heads/master diff --git a/tests/resources/revert-rename.git/refs/heads/master b/tests/resources/revert-rename.git/refs/heads/master new file mode 100644 index 00000000000..3771102fb04 --- /dev/null +++ b/tests/resources/revert-rename.git/refs/heads/master @@ -0,0 +1 @@ +ecef6a85173b6f446873a13f7b5a7b54a85cd912 diff --git a/tests/revert/rename.c b/tests/revert/rename.c new file mode 100644 index 00000000000..0d713c60fa0 --- /dev/null +++ b/tests/revert/rename.c @@ -0,0 +1,49 @@ +#include "clar.h" +#include "clar_libgit2.h" + +#include "git2/revert.h" +#include "../merge/merge_helpers.h" + +#define TEST_REPO_PATH "revert-rename.git" + +static git_repository *repo; + +/* Fixture setup and teardown */ +void test_revert_rename__initialize(void) +{ + repo = cl_git_sandbox_init(TEST_REPO_PATH); +} + +void test_revert_rename__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +/* Attempt a revert when there is a file rename AND change of file mode, + * but the file contents remain the same. Check that the file mode doesn't + * change following the revert. + */ +void test_revert_rename__automerge(void) +{ + git_commit *head_commit, *revert_commit; + git_oid revert_oid; + git_index *index; + git_reference *head_ref; + + struct merge_index_entry merge_index_entries[] = { + { 0100644, "f0f64c618e1646d2948a456ed7c4bcfad5536d68", 0, "goodmode" }}; + + cl_git_pass(git_repository_head(&head_ref, repo)); + cl_git_pass(git_reference_peel((git_object **)&head_commit, head_ref, GIT_OBJECT_COMMIT)); + + cl_git_pass(git_oid_fromstr(&revert_oid, "7b4d7c3789b3581973c04087cb774c3c3576de2f")); + cl_git_pass(git_commit_lookup(&revert_commit, repo, &revert_oid)); + + cl_git_pass(git_revert_commit(&index, repo, revert_commit, head_commit, 0, NULL)); + cl_assert(merge_test_index(index, merge_index_entries, 1)); + + git_commit_free(revert_commit); + git_commit_free(head_commit); + git_index_free(index); + git_reference_free(head_ref); +} From eb41276fe08eeedd27509f69d9465cfbdd6cb7f7 Mon Sep 17 00:00:00 2001 From: Laurence McGlashan Date: Thu, 16 Sep 2021 11:44:04 +0100 Subject: [PATCH 0530/1616] Allow proxy options when connecting with a detached remote. --- src/remote.c | 18 ++++++++++++++--- tests/remote/httpproxy.c | 42 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/remote.c b/src/remote.c index 154300bd2fe..9f604c3bea7 100644 --- a/src/remote.c +++ b/src/remote.c @@ -888,11 +888,21 @@ static int http_proxy_config(char **out, git_remote *remote, git_net_url *url) git_buf buf = GIT_BUF_INIT; git_net_url lookup_url = GIT_NET_URL_INIT; int error; + int cleanup_config = 0; - if ((error = git_net_url_dup(&lookup_url, url)) < 0 || - (error = git_repository_config__weakptr(&cfg, remote->repo)) < 0) + if ((error = git_net_url_dup(&lookup_url, url)) < 0) goto done; + if (remote->repo) { + if ((error = git_repository_config__weakptr(&cfg, remote->repo)) < 0) + goto done; + } else { + if ((error = git_config_open_default(&cfg)) < 0) + goto done; + + cleanup_config = 1; + } + /* remote..proxy config setting */ if (remote->name && remote->name[0]) { git_buf_clear(&buf); @@ -922,6 +932,9 @@ static int http_proxy_config(char **out, git_remote *remote, git_net_url *url) error = lookup_config(out, cfg, "http.proxy"); done: + if (cleanup_config) + git_config_free(cfg); + git_buf_dispose(&buf); git_net_url_dispose(&lookup_url); return error; @@ -971,7 +984,6 @@ int git_remote__http_proxy(char **out, git_remote *remote, git_net_url *url) GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(remote); - GIT_ASSERT_ARG(remote->repo); *out = NULL; diff --git a/tests/remote/httpproxy.c b/tests/remote/httpproxy.c index 097db4cd587..803ef11adb8 100644 --- a/tests/remote/httpproxy.c +++ b/tests/remote/httpproxy.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" -#include "remote.h" +#include "futils.h" #include "net.h" +#include "remote.h" static git_repository *repo; static git_net_url url = GIT_NET_URL_INIT; @@ -105,6 +106,45 @@ void test_remote_httpproxy__config_empty_overrides(void) assert_config_match("remote.lg2.proxy", ""); } +void assert_global_config_match(const char *config, const char *expected) +{ + git_remote *remote; + char *proxy; + git_config* cfg; + + if (config) { + cl_git_pass(git_config_open_default(&cfg)); + git_config_set_string(cfg, config, expected); + git_config_free(cfg); + } + + cl_git_pass(git_remote_create_detached(&remote, "https://github.com/libgit2/libgit2")); + cl_git_pass(git_remote__http_proxy(&proxy, remote, &url)); + + if (expected) + cl_assert_equal_s(proxy, expected); + else + cl_assert_equal_p(proxy, expected); + + git_remote_free(remote); + git__free(proxy); +} + +void test_remote_httpproxy__config_overrides_detached_remote(void) +{ + cl_fake_home(); + + assert_global_config_match(NULL, NULL); + assert_global_config_match("http.proxy", "http://localhost:1/"); + assert_global_config_match("http.https://github.com.proxy", "http://localhost:2/"); + assert_global_config_match("http.https://github.com/.proxy", "http://localhost:3/"); + assert_global_config_match("http.https://github.com/libgit2.proxy", "http://localhost:4/"); + assert_global_config_match("http.https://github.com/libgit2/.proxy", "http://localhost:5/"); + assert_global_config_match("http.https://github.com/libgit2/libgit2.proxy", "http://localhost:6/"); + + cl_git_pass(git_futils_rmdir_r("home", NULL, GIT_RMDIR_REMOVE_FILES)); +} + void test_remote_httpproxy__env(void) { orig_http_proxy = cl_getenv("HTTP_PROXY"); From e994299f8b109c1ba336f0734871ceef944ac09d Mon Sep 17 00:00:00 2001 From: Laurence McGlashan Date: Thu, 16 Sep 2021 11:53:32 +0100 Subject: [PATCH 0531/1616] Update formatting. --- tests/remote/httpproxy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/remote/httpproxy.c b/tests/remote/httpproxy.c index 803ef11adb8..182ea24670a 100644 --- a/tests/remote/httpproxy.c +++ b/tests/remote/httpproxy.c @@ -113,9 +113,9 @@ void assert_global_config_match(const char *config, const char *expected) git_config* cfg; if (config) { - cl_git_pass(git_config_open_default(&cfg)); - git_config_set_string(cfg, config, expected); - git_config_free(cfg); + cl_git_pass(git_config_open_default(&cfg)); + git_config_set_string(cfg, config, expected); + git_config_free(cfg); } cl_git_pass(git_remote_create_detached(&remote, "https://github.com/libgit2/libgit2")); From 75d4676a64a73be937916361d2f0471055dec0e7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 12 Sep 2021 17:06:14 -0400 Subject: [PATCH 0532/1616] email: introduce `git_email_create_from_commit` Create `git_email_*` which will encapsulate email creation and application, and `git_email_create_from_commit` in particular, which creates an email for a single commit. --- include/git2.h | 1 + include/git2/email.h | 106 ++++++++++++++++++++++ src/email.c | 211 +++++++++++++++++++++++++++++++++++++++++++ tests/email/create.c | 163 +++++++++++++++++++++++++++++++++ 4 files changed, 481 insertions(+) create mode 100644 include/git2/email.h create mode 100644 src/email.c create mode 100644 tests/email/create.c diff --git a/include/git2.h b/include/git2.h index f39d7fbe228..2961cc3e5de 100644 --- a/include/git2.h +++ b/include/git2.h @@ -26,6 +26,7 @@ #include "git2/deprecated.h" #include "git2/describe.h" #include "git2/diff.h" +#include "git2/email.h" #include "git2/errors.h" #include "git2/filter.h" #include "git2/global.h" diff --git a/include/git2/email.h b/include/git2/email.h new file mode 100644 index 00000000000..6014c6c7ccf --- /dev/null +++ b/include/git2/email.h @@ -0,0 +1,106 @@ +/* + * 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_git_email_h__ +#define INCLUDE_git_email_h__ + +#include "common.h" + +/** + * @file git2/email.h + * @brief Git email formatting and application routines. + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Formatting options for diff e-mail generation + */ +typedef enum { + /** Normal patch, the default */ + GIT_EMAIL_CREATE_DEFAULT = 0, + + /** Do not include patch numbers in the subject prefix. */ + GIT_EMAIL_CREATE_OMIT_NUMBERS = (1u << 0), + + /** + * Include numbers in the subject prefix even when the + * patch is for a single commit (1/1). + */ + GIT_EMAIL_CREATE_ALWAYS_NUMBER = (1u << 1), +} git_email_create_flags_t; + +/** + * Options for controlling the formatting of the generated e-mail. + */ +typedef struct { + unsigned int version; + + /** see `git_email_create_flags_t` above */ + uint32_t flags; + + /** Options to use when creating diffs */ + git_diff_options diff_opts; + + /** + * The subject prefix, by default "PATCH". If set to an empty + * string ("") then only the patch numbers will be shown in the + * prefix. If the subject_prefix is empty and patch numbers + * are not being shown, the prefix will be omitted entirely. + */ + const char *subject_prefix; + + /** + * The starting patch number; this cannot be 0. By default, + * this is 1. + */ + size_t start_number; + + /** The "re-roll" number. By default, there is no re-roll. */ + size_t reroll_number; +} git_email_create_options; + +#define GIT_EMAIL_CREATE_OPTIONS_VERSION 1 +#define GIT_EMAIL_CREATE_OPTIONS_INIT { \ + GIT_EMAIL_CREATE_OPTIONS_VERSION, \ + GIT_EMAIL_CREATE_DEFAULT, \ + GIT_DIFF_OPTIONS_INIT \ + } + +/** + * Create a diff for a commit in mbox format for sending via email. + * The commit must not be a merge commit. + * + * @param out buffer to store the e-mail patch in + * @param commit commit to create a patch for + * @param opts email creation options + */ +GIT_EXTERN(int) git_email_create_from_commit( + git_buf *out, + git_commit *commit, + const git_email_create_options *opts); + +/** + * Create an mbox format diff for the given commits in the revision + * spec, excluding merge commits. + * + * @param out buffer to store the e-mail patches in + * @param commits the array of commits to create patches for + * @param len the length of the `commits` array + * @param opts email creation options + */ +GIT_EXTERN(int) git_email_create_from_commits( + git_strarray *out, + git_commit **commits, + size_t len, + const git_email_create_options *opts); + +GIT_END_DECL + +/** @} */ + +#endif diff --git a/src/email.c b/src/email.c new file mode 100644 index 00000000000..b269dee67aa --- /dev/null +++ b/src/email.c @@ -0,0 +1,211 @@ +/* + * 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 "buffer.h" +#include "common.h" +#include "diff_generate.h" + +#include "git2/email.h" +#include "git2/patch.h" +#include "git2/version.h" + +/* + * Git uses a "magic" timestamp to indicate that an email message + * is from `git format-patch` (or our equivalent). + */ +#define EMAIL_TIMESTAMP "Mon Sep 17 00:00:00 2001" + +GIT_INLINE(int) include_prefix( + size_t patch_count, + git_email_create_options *opts) +{ + return ((!opts->subject_prefix || *opts->subject_prefix) || + (opts->flags & GIT_EMAIL_CREATE_ALWAYS_NUMBER) != 0 || + opts->reroll_number || + (patch_count > 1 && !(opts->flags & GIT_EMAIL_CREATE_OMIT_NUMBERS))); +} + +static int append_prefix( + git_buf *out, + size_t patch_idx, + size_t patch_count, + git_email_create_options *opts) +{ + const char *subject_prefix = opts->subject_prefix ? + opts->subject_prefix : "PATCH"; + + if (!include_prefix(patch_count, opts)) + return 0; + + git_buf_putc(out, '['); + + if (*subject_prefix) + git_buf_puts(out, subject_prefix); + + if (opts->reroll_number) { + if (*subject_prefix) + git_buf_putc(out, ' '); + + git_buf_printf(out, "v%" PRIuZ, opts->reroll_number); + } + + if ((opts->flags & GIT_EMAIL_CREATE_ALWAYS_NUMBER) != 0 || + (patch_count > 1 && !(opts->flags & GIT_EMAIL_CREATE_OMIT_NUMBERS))) { + size_t start_number = opts->start_number ? + opts->start_number : 1; + + if (*subject_prefix || opts->reroll_number) + git_buf_putc(out, ' '); + + git_buf_printf(out, "%" PRIuZ "/%" PRIuZ, + patch_idx + (start_number - 1), + patch_count + (start_number - 1)); + } + + git_buf_puts(out, "] "); + + return git_buf_oom(out) ? -1 : 0; +} + +static int append_subject( + git_buf *out, + git_commit *commit, + size_t patch_idx, + size_t patch_count, + git_email_create_options *opts) +{ + int error; + + if ((error = git_buf_puts(out, "Subject: ")) < 0 || + (error = append_prefix(out, patch_idx, patch_count, opts)) < 0 || + (error = git_buf_puts(out, git_commit_summary(commit))) < 0 || + (error = git_buf_putc(out, '\n')) < 0) + return error; + + return 0; +} + +static int append_header( + git_buf *out, + git_commit *commit, + size_t patch_idx, + size_t patch_count, + git_email_create_options *opts) +{ + const git_signature *author = git_commit_author(commit); + char id[GIT_OID_HEXSZ]; + char date[GIT_DATE_RFC2822_SZ]; + int error; + + if ((error = git_oid_fmt(id, git_commit_id(commit))) < 0 || + (error = git_buf_printf(out, "From %.*s %s\n", GIT_OID_HEXSZ, id, EMAIL_TIMESTAMP)) < 0 || + (error = git_buf_printf(out, "From: %s <%s>\n", author->name, author->email)) < 0 || + (error = git__date_rfc2822_fmt(date, sizeof(date), &author->when)) < 0 || + (error = git_buf_printf(out, "Date: %s\n", date)) < 0 || + (error = append_subject(out, commit, patch_idx, patch_count, opts)) < 0) + return error; + + if ((error = git_buf_putc(out, '\n')) < 0) + return error; + + return 0; +} + +static int append_body(git_buf *out, git_commit *commit) +{ + const char *body = git_commit_body(commit); + size_t body_len; + int error; + + if (!body) + return 0; + + body_len = strlen(body); + + if ((error = git_buf_puts(out, body)) < 0) + return error; + + if (body_len && body[body_len - 1] != '\n') + error = git_buf_putc(out, '\n'); + + return error; +} + +static int append_diffstat(git_buf *out, git_diff *diff) +{ + git_diff_stats *stats = NULL; + unsigned int format_flags; + int error; + + format_flags = GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_INCLUDE_SUMMARY; + + if ((error = git_diff_get_stats(&stats, diff)) == 0 && + (error = git_diff_stats_to_buf(out, stats, format_flags, 0)) == 0) + error = git_buf_putc(out, '\n'); + + git_diff_stats_free(stats); + return error; +} + +static int append_patches(git_buf *out, git_diff *diff) +{ + size_t i, deltas; + int error = 0; + + deltas = git_diff_num_deltas(diff); + + for (i = 0; i < deltas; ++i) { + git_patch *patch = NULL; + + if ((error = git_patch_from_diff(&patch, diff, i)) >= 0) + error = git_patch_to_buf(out, patch); + + git_patch_free(patch); + + if (error < 0) + break; + } + + return error; +} + +int git_email_create_from_commit( + git_buf *out, + git_commit *commit, + const git_email_create_options *given_opts) +{ + git_diff *diff = NULL; + git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; + git_repository *repo; + int error = 0; + + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(commit); + + GIT_ERROR_CHECK_VERSION(given_opts, + GIT_EMAIL_CREATE_OPTIONS_VERSION, + "git_email_create_options"); + + if (given_opts) + memcpy(&opts, given_opts, sizeof(git_email_create_options)); + + git_buf_sanitize(out); + git_buf_clear(out); + + repo = git_commit_owner(commit); + + if ((error = git_diff__commit(&diff, repo, commit, &opts.diff_opts)) == 0 && + (error = append_header(out, commit, 1, 1, &opts)) == 0 && + (error = append_body(out, commit)) == 0 && + (error = git_buf_puts(out, "---\n")) == 0 && + (error = append_diffstat(out, diff)) == 0 && + (error = append_patches(out, diff)) == 0) + error = git_buf_puts(out, "--\nlibgit2 " LIBGIT2_VERSION "\n\n"); + + git_diff_free(diff); + return error; +} diff --git a/tests/email/create.c b/tests/email/create.c new file mode 100644 index 00000000000..3a17ff59f64 --- /dev/null +++ b/tests/email/create.c @@ -0,0 +1,163 @@ +#include "clar.h" +#include "clar_libgit2.h" + +#include "buffer.h" + +static git_repository *repo; + +void test_email_create__initialize(void) +{ + repo = cl_git_sandbox_init("diff_format_email"); +} + +void test_email_create__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +static void email_for_commit( + git_buf *out, + const char *commit_id, + git_email_create_options *opts) +{ + git_oid oid; + git_commit *commit = NULL; + git_diff *diff = NULL; + + git_oid_fromstr(&oid, commit_id); + + cl_git_pass(git_commit_lookup(&commit, repo, &oid)); + + cl_git_pass(git_email_create_from_commit(out, commit, opts)); + + git_diff_free(diff); + git_commit_free(commit); +} + +static void assert_email_match( + const char *expected, + const char *commit_id, + git_email_create_options *opts) +{ + git_buf buf = GIT_BUF_INIT; + + email_for_commit(&buf, commit_id, opts); + cl_assert_equal_s(expected, git_buf_cstr(&buf)); + + git_buf_dispose(&buf); +} + +static void assert_subject_match( + const char *expected, + const char *commit_id, + git_email_create_options *opts) +{ + git_buf buf = GIT_BUF_INIT; + const char *loc; + + email_for_commit(&buf, commit_id, opts); + + cl_assert((loc = strstr(buf.ptr, "\nSubject: ")) != NULL); + git_buf_consume(&buf, (loc + 10)); + git_buf_truncate_at_char(&buf, '\n'); + + cl_assert_equal_s(expected, git_buf_cstr(&buf)); + + git_buf_dispose(&buf); +} + +void test_email_create__commit(void) +{ + const char *email = + "From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Wed, 9 Apr 2014 20:57:01 +0200\n" \ + "Subject: [PATCH] Modify some content\n" \ + "\n" \ + "---\n" \ + " file1.txt | 8 +++++---\n" \ + " 1 file changed, 5 insertions(+), 3 deletions(-)\n" \ + "\n" \ + "diff --git a/file1.txt b/file1.txt\n" \ + "index 94aaae8..af8f41d 100644\n" \ + "--- a/file1.txt\n" \ + "+++ b/file1.txt\n" \ + "@@ -1,15 +1,17 @@\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "+_file1.txt_\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "+\n" \ + "+\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "+_file1.txt_\n" \ + "+_file1.txt_\n" \ + " file1.txt\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + assert_email_match( + email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", NULL); +} + +void test_email_create__mode_change(void) +{ + const char *expected = + "From 7ade76dd34bba4733cf9878079f9fd4a456a9189 Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Thu, 10 Apr 2014 10:05:03 +0200\n" \ + "Subject: [PATCH] Update permissions\n" \ + "\n" \ + "---\n" \ + " file1.txt.renamed | 0\n" \ + " 1 file changed, 0 insertions(+), 0 deletions(-)\n" \ + " mode change 100644 => 100755 file1.txt.renamed\n" \ + "\n" \ + "diff --git a/file1.txt.renamed b/file1.txt.renamed\n" \ + "old mode 100644\n" \ + "new mode 100755\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + assert_email_match(expected, "7ade76dd34bba4733cf9878079f9fd4a456a9189", NULL); +} + +void test_email_create__commit_subjects(void) +{ + git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; + + assert_subject_match("[PATCH] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.reroll_number = 42; + assert_subject_match("[PATCH v42] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.flags |= GIT_EMAIL_CREATE_ALWAYS_NUMBER; + assert_subject_match("[PATCH v42 1/1] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.start_number = 9; + assert_subject_match("[PATCH v42 9/9] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.subject_prefix = ""; + assert_subject_match("[v42 9/9] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.reroll_number = 0; + assert_subject_match("[9/9] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.start_number = 0; + assert_subject_match("[1/1] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.flags = GIT_EMAIL_CREATE_OMIT_NUMBERS; + assert_subject_match("Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); +} From 6aa349667974a521dbe0c7e0f543f9086156689d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 13 Sep 2021 08:17:21 -0400 Subject: [PATCH 0533/1616] email: introduce `git_email_create_from_diff` Introduce a function to create an email from a diff and multiple inputs about the source of the diff. Creating an email from a diff requires many more inputs, and should be discouraged in favor of building directly from a commit, and is thus in the `sys` namespace. --- include/git2/email.h | 35 ++++++++----- include/git2/sys/email.h | 45 ++++++++++++++++ src/email.c | 108 +++++++++++++++++++++++++++++---------- tests/email/create.c | 60 +++++++++++++++++----- 4 files changed, 195 insertions(+), 53 deletions(-) create mode 100644 include/git2/sys/email.h diff --git a/include/git2/email.h b/include/git2/email.h index 6014c6c7ccf..48715fe7654 100644 --- a/include/git2/email.h +++ b/include/git2/email.h @@ -73,30 +73,39 @@ typedef struct { /** * Create a diff for a commit in mbox format for sending via email. - * The commit must not be a merge commit. * * @param out buffer to store the e-mail patch in - * @param commit commit to create a patch for + * @param diff the changes to include in the email + * @param patch_idx the patch index + * @param patch_count the total number of patches that will be included + * @param commit_id the commit id for this change + * @param summary the commit message for this change + * @param body optional text to include above the diffstat + * @param author the person who authored this commit * @param opts email creation options */ -GIT_EXTERN(int) git_email_create_from_commit( +GIT_EXTERN(int) git_email_create_from_diff( git_buf *out, - git_commit *commit, + git_diff *diff, + size_t patch_idx, + size_t patch_count, + const git_oid *commit_id, + const char *summary, + const char *body, + const git_signature *author, const git_email_create_options *opts); /** - * Create an mbox format diff for the given commits in the revision - * spec, excluding merge commits. + * Create a diff for a commit in mbox format for sending via email. + * The commit must not be a merge commit. * - * @param out buffer to store the e-mail patches in - * @param commits the array of commits to create patches for - * @param len the length of the `commits` array + * @param out buffer to store the e-mail patch in + * @param commit commit to create a patch for * @param opts email creation options */ -GIT_EXTERN(int) git_email_create_from_commits( - git_strarray *out, - git_commit **commits, - size_t len, +GIT_EXTERN(int) git_email_create_from_commit( + git_buf *out, + git_commit *commit, const git_email_create_options *opts); GIT_END_DECL diff --git a/include/git2/sys/email.h b/include/git2/sys/email.h new file mode 100644 index 00000000000..6f4a2866209 --- /dev/null +++ b/include/git2/sys/email.h @@ -0,0 +1,45 @@ +/* + * 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_sys_git_email_h__ +#define INCLUDE_sys_git_email_h__ + +/** + * @file git2/sys/email.h + * @brief Advanced git email creation routines + * @defgroup git_email Advanced git email creation routines + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Create a diff for a commit in mbox format for sending via email. + * + * @param out buffer to store the e-mail patch in + * @param diff the changes to include in the email + * @param patch_idx the patch index + * @param patch_count the total number of patches that will be included + * @param commit_id the commit id for this change + * @param summary the commit message for this change + * @param body optional text to include above the diffstat + * @param author the person who authored this commit + * @param opts email creation options + */ +GIT_EXTERN(int) git_email_create_from_diff( + git_buf *out, + git_diff *diff, + size_t patch_idx, + size_t patch_count, + const git_oid *commit_id, + const char *summary, + const char *body, + const git_signature *author, + const git_email_create_options *opts); + +/** @} */ +GIT_END_DECL +#endif diff --git a/src/email.c b/src/email.c index b269dee67aa..b238f5b47bc 100644 --- a/src/email.c +++ b/src/email.c @@ -38,9 +38,6 @@ static int append_prefix( const char *subject_prefix = opts->subject_prefix ? opts->subject_prefix : "PATCH"; - if (!include_prefix(patch_count, opts)) - return 0; - git_buf_putc(out, '['); if (*subject_prefix) @@ -66,47 +63,65 @@ static int append_prefix( patch_count + (start_number - 1)); } - git_buf_puts(out, "] "); + git_buf_puts(out, "]"); return git_buf_oom(out) ? -1 : 0; } static int append_subject( git_buf *out, - git_commit *commit, size_t patch_idx, size_t patch_count, + const char *summary, git_email_create_options *opts) { + bool prefix = include_prefix(patch_count, opts); + size_t summary_len = summary ? strlen(summary) : 0; int error; - if ((error = git_buf_puts(out, "Subject: ")) < 0 || - (error = append_prefix(out, patch_idx, patch_count, opts)) < 0 || - (error = git_buf_puts(out, git_commit_summary(commit))) < 0 || - (error = git_buf_putc(out, '\n')) < 0) + if (summary_len) { + const char *nl = strchr(summary, '\n'); + + if (nl) + summary_len = (nl - summary); + } + + if ((error = git_buf_puts(out, "Subject: ")) < 0) return error; - return 0; + if (prefix && + (error = append_prefix(out, patch_idx, patch_count, opts)) < 0) + return error; + + if (prefix && summary_len && (error = git_buf_putc(out, ' ')) < 0) + return error; + + if (summary_len && + (error = git_buf_put(out, summary, summary_len)) < 0) + return error; + + return git_buf_putc(out, '\n'); } static int append_header( git_buf *out, - git_commit *commit, size_t patch_idx, size_t patch_count, + const git_oid *commit_id, + const char *summary, + const git_signature *author, git_email_create_options *opts) { - const git_signature *author = git_commit_author(commit); char id[GIT_OID_HEXSZ]; char date[GIT_DATE_RFC2822_SZ]; int error; - if ((error = git_oid_fmt(id, git_commit_id(commit))) < 0 || + if ((error = git_oid_fmt(id, commit_id)) < 0 || (error = git_buf_printf(out, "From %.*s %s\n", GIT_OID_HEXSZ, id, EMAIL_TIMESTAMP)) < 0 || (error = git_buf_printf(out, "From: %s <%s>\n", author->name, author->email)) < 0 || (error = git__date_rfc2822_fmt(date, sizeof(date), &author->when)) < 0 || (error = git_buf_printf(out, "Date: %s\n", date)) < 0 || - (error = append_subject(out, commit, patch_idx, patch_count, opts)) < 0) + (error = append_subject(out, patch_idx, patch_count, summary, opts)) < 0) return error; if ((error = git_buf_putc(out, '\n')) < 0) @@ -115,9 +130,8 @@ static int append_header( return 0; } -static int append_body(git_buf *out, git_commit *commit) +static int append_body(git_buf *out, const char *body) { - const char *body = git_commit_body(commit); size_t body_len; int error; @@ -173,18 +187,25 @@ static int append_patches(git_buf *out, git_diff *diff) return error; } -int git_email_create_from_commit( +int git_email_create_from_diff( git_buf *out, - git_commit *commit, + git_diff *diff, + size_t patch_idx, + size_t patch_count, + const git_oid *commit_id, + const char *summary, + const char *body, + const git_signature *author, const git_email_create_options *given_opts) { - git_diff *diff = NULL; git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; - git_repository *repo; - int error = 0; + int error; GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(commit); + GIT_ASSERT_ARG(diff); + GIT_ASSERT_ARG(!patch_idx || patch_idx <= patch_count); + GIT_ASSERT_ARG(commit_id); + GIT_ASSERT_ARG(author); GIT_ERROR_CHECK_VERSION(given_opts, GIT_EMAIL_CREATE_OPTIONS_VERSION, @@ -196,16 +217,49 @@ int git_email_create_from_commit( git_buf_sanitize(out); git_buf_clear(out); - repo = git_commit_owner(commit); - - if ((error = git_diff__commit(&diff, repo, commit, &opts.diff_opts)) == 0 && - (error = append_header(out, commit, 1, 1, &opts)) == 0 && - (error = append_body(out, commit)) == 0 && + if ((error = append_header(out, patch_idx, patch_count, commit_id, summary, author, &opts)) == 0 && + (error = append_body(out, body)) == 0 && (error = git_buf_puts(out, "---\n")) == 0 && (error = append_diffstat(out, diff)) == 0 && (error = append_patches(out, diff)) == 0) error = git_buf_puts(out, "--\nlibgit2 " LIBGIT2_VERSION "\n\n"); + return error; +} + +int git_email_create_from_commit( + git_buf *out, + git_commit *commit, + const git_email_create_options *opts) +{ + const git_diff_options *diff_opts; + git_diff *diff = NULL; + git_repository *repo; + const git_signature *author; + const char *summary, *body; + const git_oid *commit_id; + int error = -1; + + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(commit); + + GIT_ERROR_CHECK_VERSION(opts, + GIT_EMAIL_CREATE_OPTIONS_VERSION, + "git_email_create_options"); + + repo = git_commit_owner(commit); + author = git_commit_author(commit); + summary = git_commit_summary(commit); + body = git_commit_body(commit); + commit_id = git_commit_id(commit); + diff_opts = opts ? &opts->diff_opts : NULL; + + if ((error = git_diff__commit(&diff, repo, commit, diff_opts)) < 0) + goto done; + + error = git_email_create_from_diff(out, diff, 1, 1, commit_id, summary, body, author, opts); + +done: git_diff_free(diff); return error; } diff --git a/tests/email/create.c b/tests/email/create.c index 3a17ff59f64..2b16d1da1a2 100644 --- a/tests/email/create.c +++ b/tests/email/create.c @@ -2,6 +2,7 @@ #include "clar_libgit2.h" #include "buffer.h" +#include "diff_generate.h" static git_repository *repo; @@ -111,27 +112,60 @@ void test_email_create__commit(void) email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", NULL); } -void test_email_create__mode_change(void) +void test_email_create__custom_summary_and_body(void) { - const char *expected = - "From 7ade76dd34bba4733cf9878079f9fd4a456a9189 Mon Sep 17 00:00:00 2001\n" \ - "From: Jacques Germishuys \n" \ - "Date: Thu, 10 Apr 2014 10:05:03 +0200\n" \ - "Subject: [PATCH] Update permissions\n" \ + const char *expected = "From 627e7e12d87e07a83fad5b6bfa25e86ead4a5270 Mon Sep 17 00:00:00 2001\n" \ + "From: Patrick Steinhardt \n" \ + "Date: Tue, 24 Nov 2015 13:34:39 +0100\n" \ + "Subject: [PPPPPATCH 2/4] This is a subject\n" \ + "\n" \ + "Modify content of file3.txt by appending a new line. Make this\n" \ + "commit message somewhat longer to test behavior with newlines\n" \ + "embedded in the message body.\n" \ "\n" \ + "Also test if new paragraphs are included correctly.\n" \ "---\n" \ - " file1.txt.renamed | 0\n" \ - " 1 file changed, 0 insertions(+), 0 deletions(-)\n" \ - " mode change 100644 => 100755 file1.txt.renamed\n" \ + " file3.txt | 1 +\n" \ + " 1 file changed, 1 insertion(+)\n" \ "\n" \ - "diff --git a/file1.txt.renamed b/file1.txt.renamed\n" \ - "old mode 100644\n" \ - "new mode 100755\n" \ + "diff --git a/file3.txt b/file3.txt\n" \ + "index 9a2d780..7309653 100644\n" \ + "--- a/file3.txt\n" \ + "+++ b/file3.txt\n" \ + "@@ -3,3 +3,4 @@ file3!\n" \ + " file3\n" \ + " file3\n" \ + " file3\n" \ + "+file3\n" \ "--\n" \ "libgit2 " LIBGIT2_VERSION "\n" \ "\n"; - assert_email_match(expected, "7ade76dd34bba4733cf9878079f9fd4a456a9189", NULL); + const char *summary = "This is a subject\nwith\nnewlines"; + const char *body = "Modify content of file3.txt by appending a new line. Make this\n" \ + "commit message somewhat longer to test behavior with newlines\n" \ + "embedded in the message body.\n" \ + "\n" \ + "Also test if new paragraphs are included correctly."; + + git_oid oid; + git_commit *commit = NULL; + git_diff *diff = NULL; + git_buf buf = GIT_BUF_INIT; + git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; + + opts.subject_prefix = "PPPPPATCH"; + + git_oid_fromstr(&oid, "627e7e12d87e07a83fad5b6bfa25e86ead4a5270"); + cl_git_pass(git_commit_lookup(&commit, repo, &oid)); + cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); + cl_git_pass(git_email_create_from_diff(&buf, diff, 2, 4, &oid, summary, body, git_commit_author(commit), &opts)); + + cl_assert_equal_s(expected, git_buf_cstr(&buf)); + + git_diff_free(diff); + git_commit_free(commit); + git_buf_dispose(&buf); } void test_email_create__commit_subjects(void) From 3f13d2e8a3244018ae4e94d115b419eb84924ed6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 13 Sep 2021 10:36:48 -0400 Subject: [PATCH 0534/1616] email: allow `git_diff_commit_as_email` to take 0 as patch index Allow a `0` patch index and `0` patch count; in this case, simply don't display these in the email. --- tests/diff/format_email.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/diff/format_email.c b/tests/diff/format_email.c index bdfc4cac326..6d39b9026c2 100644 --- a/tests/diff/format_email.c +++ b/tests/diff/format_email.c @@ -327,7 +327,6 @@ void test_diff_format_email__invalid_no(void) cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); cl_git_fail(git_diff_format_email(&buf, diff, &opts)); cl_git_fail(git_diff_commit_as_email(&buf, repo, commit, 2, 1, 0, NULL)); - cl_git_fail(git_diff_commit_as_email(&buf, repo, commit, 0, 0, 0, NULL)); git_diff_free(diff); git_commit_free(commit); From f407d3fae5983411a5d785fa2f0c29a84cbb9d52 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 13 Sep 2021 10:51:42 -0400 Subject: [PATCH 0535/1616] diff_commit_as_email: use `email_create` Move the `git_diff_commit_as_email` function to use `email_create`. --- src/diff.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/diff.c b/src/diff.c index 4085c5f78fd..ed12cbe3e9e 100644 --- a/src/diff.c +++ b/src/diff.c @@ -8,6 +8,7 @@ #include "diff.h" #include "git2/version.h" +#include "git2/email.h" #include "diff_generate.h" #include "patch.h" #include "commit.h" @@ -323,26 +324,28 @@ int git_diff_commit_as_email( const git_diff_options *diff_opts) { git_diff *diff = NULL; - git_diff_format_email_options opts = - GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; + git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; + const git_oid *commit_id; + const char *summary, *body; + const git_signature *author; int error; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(commit); - opts.flags = flags; - opts.patch_no = patch_no; - opts.total_patches = total_patches; - opts.id = git_commit_id(commit); - opts.summary = git_commit_summary(commit); - opts.body = git_commit_body(commit); - opts.author = git_commit_author(commit); + commit_id = git_commit_id(commit); + summary = git_commit_summary(commit); + body = git_commit_body(commit); + author = git_commit_author(commit); + + if ((flags & GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER) != 0) + opts.subject_prefix = ""; if ((error = git_diff__commit(&diff, repo, commit, diff_opts)) < 0) return error; - error = git_diff_format_email(out, diff, &opts); + error = git_email_create_from_diff(out, diff, patch_no, total_patches, commit_id, summary, body, author, &opts); git_diff_free(diff); return error; From 971ed7537cae0b7f27dab7fa310d71a4cce3db27 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 13 Sep 2021 13:26:55 -0400 Subject: [PATCH 0536/1616] email: introduce 'append_from_diff' Introduce `git_email__append_from_diff` so that we don't always overwrite the input buffer. --- src/email.c | 27 ++++++++++++++++++++++++++- src/email.h | 25 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/email.h diff --git a/src/email.c b/src/email.c index b238f5b47bc..0bec5155cc4 100644 --- a/src/email.c +++ b/src/email.c @@ -5,6 +5,8 @@ * a Linking Exception. For full terms see the included COPYING file. */ +#include "email.h" + #include "buffer.h" #include "common.h" #include "diff_generate.h" @@ -187,7 +189,7 @@ static int append_patches(git_buf *out, git_diff *diff) return error; } -int git_email_create_from_diff( +int git_email__append_from_diff( git_buf *out, git_diff *diff, size_t patch_idx, @@ -227,6 +229,29 @@ int git_email_create_from_diff( return error; } +int git_email_create_from_diff( + git_buf *out, + git_diff *diff, + size_t patch_idx, + size_t patch_count, + const git_oid *commit_id, + const char *summary, + const char *body, + const git_signature *author, + const git_email_create_options *given_opts) +{ + int error; + + git_buf_sanitize(out); + git_buf_clear(out); + + error = git_email__append_from_diff(out, diff, patch_idx, + patch_count, commit_id, summary, body, author, + given_opts); + + return error; +} + int git_email_create_from_commit( git_buf *out, git_commit *commit, diff --git a/src/email.h b/src/email.h new file mode 100644 index 00000000000..7aeb462abc1 --- /dev/null +++ b/src/email.h @@ -0,0 +1,25 @@ +/* + * 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_email_h__ +#define INCLUDE_email_h__ + +#include "common.h" + +#include "git2/email.h" + +extern int git_email__append_from_diff( + git_buf *out, + git_diff *diff, + size_t patch_idx, + size_t patch_count, + const git_oid *commit_id, + const char *summary, + const char *body, + const git_signature *author, + const git_email_create_options *given_opts); + +#endif From c443495bd36ef2a22d3828d449d4f03c85464cf6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 13 Sep 2021 13:29:46 -0400 Subject: [PATCH 0537/1616] diff: use `git_email_create` in `diff_format_email` --- src/diff.c | 149 +++-------------------------------------------------- 1 file changed, 7 insertions(+), 142 deletions(-) diff --git a/src/diff.c b/src/diff.c index ed12cbe3e9e..81467714fcf 100644 --- a/src/diff.c +++ b/src/diff.c @@ -11,6 +11,7 @@ #include "git2/email.h" #include "diff_generate.h" #include "patch.h" +#include "email.h" #include "commit.h" #include "index.h" @@ -151,97 +152,12 @@ int git_diff_foreach( return error; } -static int diff_format_email_append_header_tobuf( - git_buf *out, - const git_oid *id, - const git_signature *author, - const char *summary, - const char *body, - size_t patch_no, - size_t total_patches, - bool exclude_patchno_marker) -{ - char idstr[GIT_OID_HEXSZ + 1]; - char date_str[GIT_DATE_RFC2822_SZ]; - int error = 0; - - git_oid_fmt(idstr, id); - idstr[GIT_OID_HEXSZ] = '\0'; - - if ((error = git__date_rfc2822_fmt(date_str, sizeof(date_str), - &author->when)) < 0) - return error; - - error = git_buf_printf(out, - "From %s Mon Sep 17 00:00:00 2001\n" \ - "From: %s <%s>\n" \ - "Date: %s\n" \ - "Subject: ", - idstr, - author->name, author->email, - date_str); - - if (error < 0) - return error; - - if (!exclude_patchno_marker) { - if (total_patches == 1) { - error = git_buf_puts(out, "[PATCH] "); - } else { - error = git_buf_printf(out, "[PATCH %"PRIuZ"/%"PRIuZ"] ", - patch_no, total_patches); - } - - if (error < 0) - return error; - } - - error = git_buf_printf(out, "%s\n\n", summary); - - if (body) { - git_buf_puts(out, body); - - if (out->ptr[out->size - 1] != '\n') - git_buf_putc(out, '\n'); - } - - return error; -} - -static int diff_format_email_append_patches_tobuf( - git_buf *out, - git_diff *diff) -{ - size_t i, deltas; - int error = 0; - - deltas = git_diff_num_deltas(diff); - - for (i = 0; i < deltas; ++i) { - git_patch *patch = NULL; - - if ((error = git_patch_from_diff(&patch, diff, i)) >= 0) - error = git_patch_to_buf(out, patch); - - git_patch_free(patch); - - if (error < 0) - break; - } - - return error; -} - int git_diff_format_email( git_buf *out, git_diff *diff, const git_diff_format_email_options *opts) { - git_diff_stats *stats = NULL; - char *summary = NULL, *loc = NULL; - bool ignore_marker; - unsigned int format_flags = 0; - size_t allocsize; + git_email_create_options email_create_opts = GIT_EMAIL_CREATE_OPTIONS_INIT; int error; GIT_ASSERT_ARG(out); @@ -252,64 +168,13 @@ int git_diff_format_email( GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, "git_format_email_options"); - ignore_marker = (opts->flags & - GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER) != 0; - - if (!ignore_marker) { - if (opts->patch_no > opts->total_patches) { - git_error_set(GIT_ERROR_INVALID, - "patch %"PRIuZ" out of range. max %"PRIuZ, - opts->patch_no, opts->total_patches); - return -1; - } - - if (opts->patch_no == 0) { - git_error_set(GIT_ERROR_INVALID, - "invalid patch no %"PRIuZ". should be >0", opts->patch_no); - return -1; - } - } - - /* the summary we receive may not be clean. - * it could potentially contain new line characters - * or not be set, sanitize, */ - if ((loc = strpbrk(opts->summary, "\r\n")) != NULL) { - size_t offset = 0; - - if ((offset = (loc - opts->summary)) == 0) { - git_error_set(GIT_ERROR_INVALID, "summary is empty"); - error = -1; - goto on_error; - } - - GIT_ERROR_CHECK_ALLOC_ADD(&allocsize, offset, 1); - summary = git__calloc(allocsize, sizeof(char)); - GIT_ERROR_CHECK_ALLOC(summary); - - strncpy(summary, opts->summary, offset); - } - - error = diff_format_email_append_header_tobuf(out, - opts->id, opts->author, summary == NULL ? opts->summary : summary, - opts->body, opts->patch_no, opts->total_patches, ignore_marker); - - if (error < 0) - goto on_error; - - format_flags = GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_INCLUDE_SUMMARY; - - if ((error = git_buf_puts(out, "---\n")) < 0 || - (error = git_diff_get_stats(&stats, diff)) < 0 || - (error = git_diff_stats_to_buf(out, stats, format_flags, 0)) < 0 || - (error = git_buf_putc(out, '\n')) < 0 || - (error = diff_format_email_append_patches_tobuf(out, diff)) < 0) - goto on_error; + if ((opts->flags & GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER) != 0) + email_create_opts.subject_prefix = ""; - error = git_buf_puts(out, "--\nlibgit2 " LIBGIT2_VERSION "\n\n"); -on_error: - git__free(summary); - git_diff_stats_free(stats); + error = git_email__append_from_diff(out, diff, opts->patch_no, + opts->total_patches, opts->id, opts->summary, opts->body, + opts->author, &email_create_opts); return error; } From 323f222f7ec8967f8610b603a67959215d3a5b1f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 14 Sep 2021 09:44:52 -0400 Subject: [PATCH 0538/1616] email: include binary diffs by default `git format-patch` includes binary diffs by default when creating emails. Match this behavior. --- include/git2/email.h | 14 +++++++----- src/email.c | 12 ++++++---- tests/email/create.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/include/git2/email.h b/include/git2/email.h index 48715fe7654..4b2d70ead2d 100644 --- a/include/git2/email.h +++ b/include/git2/email.h @@ -64,12 +64,16 @@ typedef struct { size_t reroll_number; } git_email_create_options; +/* + * By default, our options include binary diffs to match `git format-patch`. + */ #define GIT_EMAIL_CREATE_OPTIONS_VERSION 1 -#define GIT_EMAIL_CREATE_OPTIONS_INIT { \ - GIT_EMAIL_CREATE_OPTIONS_VERSION, \ - GIT_EMAIL_CREATE_DEFAULT, \ - GIT_DIFF_OPTIONS_INIT \ - } +#define GIT_EMAIL_CREATE_OPTIONS_INIT \ +{ \ + GIT_EMAIL_CREATE_OPTIONS_VERSION, \ + GIT_EMAIL_CREATE_DEFAULT, \ + { GIT_DIFF_OPTIONS_VERSION, GIT_DIFF_SHOW_BINARY, GIT_SUBMODULE_IGNORE_UNSPECIFIED, {NULL,0}, NULL, NULL, NULL, 3 } \ +} /** * Create a diff for a commit in mbox format for sending via email. diff --git a/src/email.c b/src/email.c index 0bec5155cc4..8b6e1334781 100644 --- a/src/email.c +++ b/src/email.c @@ -255,8 +255,9 @@ int git_email_create_from_diff( int git_email_create_from_commit( git_buf *out, git_commit *commit, - const git_email_create_options *opts) + const git_email_create_options *given_opts) { + git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; const git_diff_options *diff_opts; git_diff *diff = NULL; git_repository *repo; @@ -268,21 +269,24 @@ int git_email_create_from_commit( GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(commit); - GIT_ERROR_CHECK_VERSION(opts, + GIT_ERROR_CHECK_VERSION(given_opts, GIT_EMAIL_CREATE_OPTIONS_VERSION, "git_email_create_options"); + if (given_opts) + memcpy(&opts, given_opts, sizeof(git_email_create_options)); + repo = git_commit_owner(commit); author = git_commit_author(commit); summary = git_commit_summary(commit); body = git_commit_body(commit); commit_id = git_commit_id(commit); - diff_opts = opts ? &opts->diff_opts : NULL; + diff_opts = &opts.diff_opts; if ((error = git_diff__commit(&diff, repo, commit, diff_opts)) < 0) goto done; - error = git_email_create_from_diff(out, diff, 1, 1, commit_id, summary, body, author, opts); + error = git_email_create_from_diff(out, diff, 1, 1, commit_id, summary, body, author, &opts); done: git_diff_free(diff); diff --git a/tests/email/create.c b/tests/email/create.c index 2b16d1da1a2..8bbde20d770 100644 --- a/tests/email/create.c +++ b/tests/email/create.c @@ -112,6 +112,59 @@ void test_email_create__commit(void) email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", NULL); } +void test_email_create__binary(void) +{ + const char *expected = + "From 8d7523f6fcb2404257889abe0d96f093d9f524f9 Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Sun, 13 Apr 2014 18:10:18 +0200\n" \ + "Subject: [PATCH] Modified binary file\n" \ + "\n" \ + "---\n" \ + " binary.bin | Bin 3 -> 5 bytes\n" \ + " 1 file changed, 0 insertions(+), 0 deletions(-)\n" \ + "\n" \ + "diff --git a/binary.bin b/binary.bin\n" \ + "index bd474b2519cc15eab801ff851cc7d50f0dee49a1..9ac35ff15cd8864aeafd889e4826a3150f0b06c4 100644\n" \ + "GIT binary patch\n" \ + "literal 5\n" \ + "Mc${NkU}WL~000&M4gdfE\n" \ + "\n" \ + "literal 3\n" \ + "Kc${Nk-~s>u4FC%O\n" \ + "\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + assert_email_match(expected, "8d7523f6fcb2404257889abe0d96f093d9f524f9", NULL); +} + +void test_email_create__binary_not_included(void) +{ + const char *expected = + "From 8d7523f6fcb2404257889abe0d96f093d9f524f9 Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Sun, 13 Apr 2014 18:10:18 +0200\n" \ + "Subject: [PATCH] Modified binary file\n" \ + "\n" \ + "---\n" \ + " binary.bin | Bin 3 -> 5 bytes\n" \ + " 1 file changed, 0 insertions(+), 0 deletions(-)\n" \ + "\n" \ + "diff --git a/binary.bin b/binary.bin\n" \ + "index bd474b2..9ac35ff 100644\n" \ + "Binary files a/binary.bin and b/binary.bin differ\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; + opts.diff_opts.flags &= ~GIT_DIFF_SHOW_BINARY; + + assert_email_match(expected, "8d7523f6fcb2404257889abe0d96f093d9f524f9", &opts); +} + void test_email_create__custom_summary_and_body(void) { const char *expected = "From 627e7e12d87e07a83fad5b6bfa25e86ead4a5270 Mon Sep 17 00:00:00 2001\n" \ From 67b1d019a8ad93201c86d98d96782b13ba28fbbe Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 14 Sep 2021 09:49:31 -0400 Subject: [PATCH 0539/1616] email: include renames by default `git format-patch` includes diffs with rename detection enabled by default when creating emails. Match this behavior. --- include/git2/email.h | 12 ++++- src/email.c | 8 ++- tests/email/create.c | 117 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 132 insertions(+), 5 deletions(-) diff --git a/include/git2/email.h b/include/git2/email.h index 4b2d70ead2d..b56be5d0edc 100644 --- a/include/git2/email.h +++ b/include/git2/email.h @@ -32,6 +32,9 @@ typedef enum { * patch is for a single commit (1/1). */ GIT_EMAIL_CREATE_ALWAYS_NUMBER = (1u << 1), + + /** Do not perform rename or similarity detection. */ + GIT_EMAIL_CREATE_NO_RENAMES = (1u << 2), } git_email_create_flags_t; /** @@ -46,6 +49,9 @@ typedef struct { /** Options to use when creating diffs */ git_diff_options diff_opts; + /** Options for finding similarities within diffs */ + git_diff_find_options diff_find_opts; + /** * The subject prefix, by default "PATCH". If set to an empty * string ("") then only the patch numbers will be shown in the @@ -65,14 +71,16 @@ typedef struct { } git_email_create_options; /* - * By default, our options include binary diffs to match `git format-patch`. + * By default, our options include rename detection and binary + * diffs to match `git format-patch`. */ #define GIT_EMAIL_CREATE_OPTIONS_VERSION 1 #define GIT_EMAIL_CREATE_OPTIONS_INIT \ { \ GIT_EMAIL_CREATE_OPTIONS_VERSION, \ GIT_EMAIL_CREATE_DEFAULT, \ - { GIT_DIFF_OPTIONS_VERSION, GIT_DIFF_SHOW_BINARY, GIT_SUBMODULE_IGNORE_UNSPECIFIED, {NULL,0}, NULL, NULL, NULL, 3 } \ + { GIT_DIFF_OPTIONS_VERSION, GIT_DIFF_SHOW_BINARY, GIT_SUBMODULE_IGNORE_UNSPECIFIED, {NULL,0}, NULL, NULL, NULL, 3 }, \ + GIT_DIFF_FIND_OPTIONS_INIT \ } /** diff --git a/src/email.c b/src/email.c index 8b6e1334781..8957d9a38d6 100644 --- a/src/email.c +++ b/src/email.c @@ -258,9 +258,10 @@ int git_email_create_from_commit( const git_email_create_options *given_opts) { git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; - const git_diff_options *diff_opts; git_diff *diff = NULL; git_repository *repo; + git_diff_options *diff_opts; + git_diff_find_options *find_opts; const git_signature *author; const char *summary, *body; const git_oid *commit_id; @@ -282,10 +283,15 @@ int git_email_create_from_commit( body = git_commit_body(commit); commit_id = git_commit_id(commit); diff_opts = &opts.diff_opts; + find_opts = &opts.diff_find_opts; if ((error = git_diff__commit(&diff, repo, commit, diff_opts)) < 0) goto done; + if ((opts.flags & GIT_EMAIL_CREATE_NO_RENAMES) == 0 && + (error = git_diff_find_similar(diff, find_opts)) < 0) + goto done; + error = git_email_create_from_diff(out, diff, 1, 1, commit_id, summary, body, author, &opts); done: diff --git a/tests/email/create.c b/tests/email/create.c index 8bbde20d770..ccf79c2aa71 100644 --- a/tests/email/create.c +++ b/tests/email/create.c @@ -69,7 +69,7 @@ static void assert_subject_match( void test_email_create__commit(void) { - const char *email = + const char *expected = "From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \ "From: Jacques Germishuys \n" \ "Date: Wed, 9 Apr 2014 20:57:01 +0200\n" \ @@ -109,7 +109,120 @@ void test_email_create__commit(void) "\n"; assert_email_match( - email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", NULL); + expected, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", NULL); +} + +void test_email_create__rename(void) +{ + const char *expected = + "From 6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Wed, 9 Apr 2014 21:15:56 +0200\n" \ + "Subject: [PATCH] Renamed file1.txt -> file1.txt.renamed\n" \ + "\n" \ + "---\n" \ + " file1.txt => file1.txt.renamed | 4 ++--\n" \ + " 1 file changed, 2 insertions(+), 2 deletions(-)\n" \ + "\n" \ + "diff --git a/file1.txt b/file1.txt.renamed\n" \ + "similarity index 86%\n" \ + "rename from file1.txt\n" \ + "rename to file1.txt.renamed\n" \ + "index af8f41d..a97157a 100644\n" \ + "--- a/file1.txt\n" \ + "+++ b/file1.txt.renamed\n" \ + "@@ -3,13 +3,13 @@ file1.txt\n" \ + " _file1.txt_\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "-file1.txt\n" \ + "+file1.txt_renamed\n" \ + " file1.txt\n" \ + " \n" \ + " \n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "-file1.txt\n" \ + "+file1.txt_renamed\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " _file1.txt_\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + assert_email_match(expected, "6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d", NULL); +} + +void test_email_create__rename_as_add_delete(void) +{ + const char *expected = + "From 6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Wed, 9 Apr 2014 21:15:56 +0200\n" \ + "Subject: [PATCH] Renamed file1.txt -> file1.txt.renamed\n" \ + "\n" \ + "---\n" \ + " file1.txt | 17 -----------------\n" \ + " file1.txt.renamed | 17 +++++++++++++++++\n" \ + " 2 files changed, 17 insertions(+), 17 deletions(-)\n" \ + " delete mode 100644 file1.txt\n" \ + " create mode 100644 file1.txt.renamed\n" \ + "\n" \ + "diff --git a/file1.txt b/file1.txt\n" \ + "deleted file mode 100644\n" \ + "index af8f41d..0000000\n" \ + "--- a/file1.txt\n" \ + "+++ /dev/null\n" \ + "@@ -1,17 +0,0 @@\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-_file1.txt_\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-\n" \ + "-\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-_file1.txt_\n" \ + "-_file1.txt_\n" \ + "-file1.txt\n" \ + "diff --git a/file1.txt.renamed b/file1.txt.renamed\n" \ + "new file mode 100644\n" \ + "index 0000000..a97157a\n" \ + "--- /dev/null\n" \ + "+++ b/file1.txt.renamed\n" \ + "@@ -0,0 +1,17 @@\n" \ + "+file1.txt\n" \ + "+file1.txt\n" \ + "+_file1.txt_\n" \ + "+file1.txt\n" \ + "+file1.txt\n" \ + "+file1.txt_renamed\n" \ + "+file1.txt\n" \ + "+\n" \ + "+\n" \ + "+file1.txt\n" \ + "+file1.txt\n" \ + "+file1.txt_renamed\n" \ + "+file1.txt\n" \ + "+file1.txt\n" \ + "+_file1.txt_\n" \ + "+_file1.txt_\n" \ + "+file1.txt\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; + opts.flags |= GIT_EMAIL_CREATE_NO_RENAMES; + + assert_email_match(expected, "6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d", &opts); } void test_email_create__binary(void) From ba3595af0f3f788427868abb0b499da9f82dc9d1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 13 Sep 2021 16:25:00 -0400 Subject: [PATCH 0540/1616] diff: deprecate diff_format_email `git_diff_format_email` is deprecated in favor of `git_email_create`. --- include/git2/deprecated.h | 96 +++++++++++++++++++++++++++++++++++++++ include/git2/diff.h | 93 ------------------------------------- src/diff.c | 46 +++++++++---------- tests/diff/format_email.c | 20 ++++++++ 4 files changed, 139 insertions(+), 116 deletions(-) diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index a2b117f53a6..6b268eb791f 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -294,6 +294,102 @@ typedef git_configmap git_cvar_map; /**@}*/ +/** @name Deprecated Diff Functions and Constants + * + * These functions and enumeration values are retained for backward + * compatibility. The newer versions of these functions and values + * should be preferred in all new code. + * + * There is no plan to remove these backward compatibility values at + * this time. + */ +/**@{*/ + +/** + * Formatting options for diff e-mail generation + */ +typedef enum { + /** Normal patch, the default */ + GIT_DIFF_FORMAT_EMAIL_NONE = 0, + + /** Don't insert "[PATCH]" in the subject header*/ + GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER = (1 << 0), + +} git_diff_format_email_flags_t; + +/** + * Options for controlling the formatting of the generated e-mail. + */ +typedef struct { + unsigned int version; + + /** see `git_diff_format_email_flags_t` above */ + uint32_t flags; + + /** This patch number */ + size_t patch_no; + + /** Total number of patches in this series */ + size_t total_patches; + + /** id to use for the commit */ + const git_oid *id; + + /** Summary of the change */ + const char *summary; + + /** Commit message's body */ + const char *body; + + /** Author of the change */ + const git_signature *author; +} git_diff_format_email_options; + +#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION 1 +#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT {GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, 0, 1, 1, NULL, NULL, NULL, NULL} + +/** + * Create an e-mail ready patch from a diff. + * + * @deprecated git_email_create_from_diff + * @see git_email_create_from_diff + */ +GIT_EXTERN(int) git_diff_format_email( + git_buf *out, + git_diff *diff, + const git_diff_format_email_options *opts); + +/** + * Create an e-mail ready patch for a commit. + * + * @deprecated git_email_create_from_commit + * @see git_email_create_from_commit + */ +GIT_EXTERN(int) git_diff_commit_as_email( + git_buf *out, + git_repository *repo, + git_commit *commit, + size_t patch_no, + size_t total_patches, + uint32_t flags, + const git_diff_options *diff_opts); + +/** + * Initialize git_diff_format_email_options structure + * + * Initializes a `git_diff_format_email_options` with default values. Equivalent + * to creating an instance with GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT. + * + * @param opts The `git_blame_options` struct to initialize. + * @param version The struct version; pass `GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION`. + * @return Zero on success; -1 on failure. + */ +GIT_EXTERN(int) git_diff_format_email_options_init( + git_diff_format_email_options *opts, + unsigned int version); + +/**@}*/ + /** @name Deprecated Error Functions and Constants * * These functions and enumeration values are retained for backward diff --git a/include/git2/diff.h b/include/git2/diff.h index 9497793c3d2..a0a15e76fa9 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -1376,99 +1376,6 @@ GIT_EXTERN(int) git_diff_stats_to_buf( */ GIT_EXTERN(void) git_diff_stats_free(git_diff_stats *stats); -/** - * Formatting options for diff e-mail generation - */ -typedef enum { - /** Normal patch, the default */ - GIT_DIFF_FORMAT_EMAIL_NONE = 0, - - /** Don't insert "[PATCH]" in the subject header*/ - GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER = (1 << 0), - -} git_diff_format_email_flags_t; - -/** - * Options for controlling the formatting of the generated e-mail. - */ -typedef struct { - unsigned int version; - - /** see `git_diff_format_email_flags_t` above */ - uint32_t flags; - - /** This patch number */ - size_t patch_no; - - /** Total number of patches in this series */ - size_t total_patches; - - /** id to use for the commit */ - const git_oid *id; - - /** Summary of the change */ - const char *summary; - - /** Commit message's body */ - const char *body; - - /** Author of the change */ - const git_signature *author; -} git_diff_format_email_options; - -#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION 1 -#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT {GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, 0, 1, 1, NULL, NULL, NULL, NULL} - -/** - * Create an e-mail ready patch from a diff. - * - * @param out buffer to store the e-mail patch in - * @param diff containing the commit - * @param opts structure with options to influence content and formatting. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_diff_format_email( - git_buf *out, - git_diff *diff, - const git_diff_format_email_options *opts); - -/** - * Create an e-mail ready patch for a commit. - * - * Does not support creating patches for merge commits (yet). - * - * @param out buffer to store the e-mail patch in - * @param repo containing the commit - * @param commit pointer to up commit - * @param patch_no patch number of the commit - * @param total_patches total number of patches in the patch set - * @param flags determines the formatting of the e-mail - * @param diff_opts structure with options to influence diff or NULL for defaults. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_diff_commit_as_email( - git_buf *out, - git_repository *repo, - git_commit *commit, - size_t patch_no, - size_t total_patches, - uint32_t flags, - const git_diff_options *diff_opts); - -/** - * Initialize git_diff_format_email_options structure - * - * Initializes a `git_diff_format_email_options` with default values. Equivalent - * to creating an instance with GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT. - * - * @param opts The `git_blame_options` struct to initialize. - * @param version The struct version; pass `GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION`. - * @return Zero on success; -1 on failure. - */ -GIT_EXTERN(int) git_diff_format_email_options_init( - git_diff_format_email_options *opts, - unsigned int version); - /** * Patch ID options structure * diff --git a/src/diff.c b/src/diff.c index 81467714fcf..30b9f647a45 100644 --- a/src/diff.c +++ b/src/diff.c @@ -7,13 +7,15 @@ #include "diff.h" -#include "git2/version.h" -#include "git2/email.h" -#include "diff_generate.h" +#include "common.h" #include "patch.h" #include "email.h" #include "commit.h" #include "index.h" +#include "diff_generate.h" + +#include "git2/version.h" +#include "git2/email.h" struct patch_id_args { git_hash_ctx ctx; @@ -152,6 +154,8 @@ int git_diff_foreach( return error; } +#ifndef GIT_DEPRECATE_HARD + int git_diff_format_email( git_buf *out, git_diff *diff, @@ -216,35 +220,16 @@ int git_diff_commit_as_email( return error; } -int git_diff_options_init(git_diff_options *opts, unsigned int version) -{ - GIT_INIT_STRUCTURE_FROM_TEMPLATE( - opts, version, git_diff_options, GIT_DIFF_OPTIONS_INIT); - return 0; -} - -#ifndef GIT_DEPRECATE_HARD int git_diff_init_options(git_diff_options *opts, unsigned int version) { return git_diff_options_init(opts, version); } -#endif -int git_diff_find_options_init( - git_diff_find_options *opts, unsigned int version) -{ - GIT_INIT_STRUCTURE_FROM_TEMPLATE( - opts, version, git_diff_find_options, GIT_DIFF_FIND_OPTIONS_INIT); - return 0; -} - -#ifndef GIT_DEPRECATE_HARD int git_diff_find_init_options( git_diff_find_options *opts, unsigned int version) { return git_diff_find_options_init(opts, version); } -#endif int git_diff_format_email_options_init( git_diff_format_email_options *opts, unsigned int version) @@ -255,14 +240,29 @@ int git_diff_format_email_options_init( return 0; } -#ifndef GIT_DEPRECATE_HARD int git_diff_format_email_init_options( git_diff_format_email_options *opts, unsigned int version) { return git_diff_format_email_options_init(opts, version); } + #endif +int git_diff_options_init(git_diff_options *opts, unsigned int version) +{ + GIT_INIT_STRUCTURE_FROM_TEMPLATE( + opts, version, git_diff_options, GIT_DIFF_OPTIONS_INIT); + return 0; +} + +int git_diff_find_options_init( + git_diff_find_options *opts, unsigned int version) +{ + GIT_INIT_STRUCTURE_FROM_TEMPLATE( + opts, version, git_diff_find_options, GIT_DIFF_FIND_OPTIONS_INIT); + return 0; +} + static int flush_hunk(git_oid *result, git_hash_ctx *ctx) { git_oid hash; diff --git a/tests/diff/format_email.c b/tests/diff/format_email.c index 6d39b9026c2..ea7aa070fa2 100644 --- a/tests/diff/format_email.c +++ b/tests/diff/format_email.c @@ -18,6 +18,7 @@ void test_diff_format_email__cleanup(void) cl_git_sandbox_cleanup(); } +#ifndef GIT_DEPRECATE_HARD static void assert_email_match( const char *expected, const char *oidstr, @@ -51,9 +52,11 @@ static void assert_email_match( git_commit_free(commit); git_buf_dispose(&buf); } +#endif void test_diff_format_email__simple(void) { +#ifndef GIT_DEPRECATE_HARD git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; const char *email = "From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \ @@ -96,10 +99,12 @@ void test_diff_format_email__simple(void) assert_email_match( email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); +#endif } void test_diff_format_email__with_message(void) { +#ifndef GIT_DEPRECATE_HARD git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; const char *email = "From 627e7e12d87e07a83fad5b6bfa25e86ead4a5270 Mon Sep 17 00:00:00 2001\n" \ "From: Patrick Steinhardt \n" \ @@ -136,11 +141,13 @@ void test_diff_format_email__with_message(void) assert_email_match( email, "627e7e12d87e07a83fad5b6bfa25e86ead4a5270", &opts); +#endif } void test_diff_format_email__multiple(void) { +#ifndef GIT_DEPRECATE_HARD git_oid oid; git_commit *commit = NULL; git_diff *diff = NULL; @@ -256,10 +263,12 @@ void test_diff_format_email__multiple(void) git_diff_free(diff); git_commit_free(commit); git_buf_dispose(&buf); +#endif } void test_diff_format_email__exclude_marker(void) { +#ifndef GIT_DEPRECATE_HARD git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; const char *email = "From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \ @@ -304,10 +313,12 @@ void test_diff_format_email__exclude_marker(void) assert_email_match( email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); +#endif } void test_diff_format_email__invalid_no(void) { +#ifndef GIT_DEPRECATE_HARD git_oid oid; git_commit *commit = NULL; git_diff *diff = NULL; @@ -331,10 +342,12 @@ void test_diff_format_email__invalid_no(void) git_diff_free(diff); git_commit_free(commit); git_buf_dispose(&buf); +#endif } void test_diff_format_email__mode_change(void) { +#ifndef GIT_DEPRECATE_HARD git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; const char *email = "From 7ade76dd34bba4733cf9878079f9fd4a456a9189 Mon Sep 17 00:00:00 2001\n" \ @@ -356,10 +369,12 @@ void test_diff_format_email__mode_change(void) assert_email_match( email, "7ade76dd34bba4733cf9878079f9fd4a456a9189", &opts); +#endif } void test_diff_format_email__rename_add_remove(void) { +#ifndef GIT_DEPRECATE_HARD git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; const char *email = "From 6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d Mon Sep 17 00:00:00 2001\n" \ @@ -426,10 +441,12 @@ void test_diff_format_email__rename_add_remove(void) assert_email_match( email, "6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d", &opts); +#endif } void test_diff_format_email__multiline_summary(void) { +#ifndef GIT_DEPRECATE_HARD git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; const char *email = "From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \ @@ -474,10 +491,12 @@ void test_diff_format_email__multiline_summary(void) assert_email_match( email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); +#endif } void test_diff_format_email__binary(void) { +#ifndef GIT_DEPRECATE_HARD git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; const char *email = "From 8d7523f6fcb2404257889abe0d96f093d9f524f9 Mon Sep 17 00:00:00 2001\n" \ @@ -500,5 +519,6 @@ void test_diff_format_email__binary(void) assert_email_match( email, "8d7523f6fcb2404257889abe0d96f093d9f524f9", &opts); +#endif } From c8823fb05097cf38fa7f5cce0929e63c186f7a21 Mon Sep 17 00:00:00 2001 From: Laurence McGlashan Date: Sat, 18 Sep 2021 21:00:48 +0100 Subject: [PATCH 0541/1616] Apply suggestions from code review Co-authored-by: Edward Thomson --- src/remote.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/remote.c b/src/remote.c index 9f604c3bea7..2ff1f7d1342 100644 --- a/src/remote.c +++ b/src/remote.c @@ -888,19 +888,16 @@ static int http_proxy_config(char **out, git_remote *remote, git_net_url *url) git_buf buf = GIT_BUF_INIT; git_net_url lookup_url = GIT_NET_URL_INIT; int error; - int cleanup_config = 0; if ((error = git_net_url_dup(&lookup_url, url)) < 0) goto done; if (remote->repo) { - if ((error = git_repository_config__weakptr(&cfg, remote->repo)) < 0) + if ((error = git_repository_config(&cfg, remote->repo)) < 0) goto done; } else { if ((error = git_config_open_default(&cfg)) < 0) goto done; - - cleanup_config = 1; } /* remote..proxy config setting */ @@ -932,9 +929,7 @@ static int http_proxy_config(char **out, git_remote *remote, git_net_url *url) error = lookup_config(out, cfg, "http.proxy"); done: - if (cleanup_config) - git_config_free(cfg); - + git_config_free(cfg); git_buf_dispose(&buf); git_net_url_dispose(&lookup_url); return error; From 3bd462a113a9bbf4fb6e61c56c3a32ac3636b664 Mon Sep 17 00:00:00 2001 From: Laurence McGlashan Date: Sat, 18 Sep 2021 21:08:20 +0100 Subject: [PATCH 0542/1616] Update remote.c Initialise cfg variable. --- src/remote.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/remote.c b/src/remote.c index 2ff1f7d1342..56d7e42db0b 100644 --- a/src/remote.c +++ b/src/remote.c @@ -884,7 +884,7 @@ static void url_config_trim(git_net_url *url) static int http_proxy_config(char **out, git_remote *remote, git_net_url *url) { - git_config *cfg; + git_config *cfg = NULL; git_buf buf = GIT_BUF_INIT; git_net_url lookup_url = GIT_NET_URL_INIT; int error; From 005c740b15bf2b77e5ef1112aed887751fc2c827 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 20 Sep 2021 14:06:09 +0100 Subject: [PATCH 0543/1616] win32: ensure content filtering occurs in longpath test --- tests/win32/longpath.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/tests/win32/longpath.c b/tests/win32/longpath.c index f300544f48d..f8b8c4b0ae8 100644 --- a/tests/win32/longpath.c +++ b/tests/win32/longpath.c @@ -65,14 +65,16 @@ void test_win32_longpath__workdir_path_validated(void) } #ifdef GIT_WIN32 -static void assert_longpath_status_and_add(git_repository* repo) { +static void assert_longpath_status_and_add(git_repository *repo, const char *wddata, const char *repodata) { git_index *index; + git_blob *blob; git_buf out = GIT_BUF_INIT; + const git_index_entry *entry; unsigned int status_flags; cl_git_pass(git_repository_workdir_path(&out, repo, LONG_FILENAME)); - cl_git_rewritefile(out.ptr, "This is a long path.\r\n"); + cl_git_rewritefile(out.ptr, wddata); cl_git_pass(git_status_file(&status_flags, repo, LONG_FILENAME)); cl_assert_equal_i(GIT_STATUS_WT_NEW, status_flags); @@ -83,6 +85,11 @@ static void assert_longpath_status_and_add(git_repository* repo) { cl_git_pass(git_status_file(&status_flags, repo, LONG_FILENAME)); cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status_flags); + cl_assert((entry = git_index_get_bypath(index, LONG_FILENAME, 0)) != NULL); + cl_git_pass(git_blob_lookup(&blob, repo, &entry->id)); + cl_assert_equal_s(repodata, git_blob_rawcontent(blob)); + + git_blob_free(blob); git_index_free(index); git_buf_dispose(&out); } @@ -95,7 +102,13 @@ void test_win32_longpath__status_and_add(void) cl_repo_set_bool(repo, "core.longpaths", true); - assert_longpath_status_and_add(repo); + /* + * Doing no content filtering, we expect the data we add + * to be the data in the repository. + */ + assert_longpath_status_and_add(repo, + "This is a long path.\r\n", + "This is a long path.\r\n"); #endif } @@ -107,6 +120,12 @@ void test_win32_longpath__status_and_add_with_filter(void) cl_repo_set_bool(repo, "core.longpaths", true); cl_repo_set_bool(repo, "core.autocrlf", true); - assert_longpath_status_and_add(repo); + /* + * With `core.autocrlf`, we expect the data we add to have + * newline conversion performed. + */ + assert_longpath_status_and_add(repo, + "This is a long path.\r\n", + "This is a long path.\n"); #endif } From 8e7621241d7246a5cf516df296bc85f3164efbf9 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 20 Sep 2021 12:19:05 -0400 Subject: [PATCH 0544/1616] httpproxy: move empty string test above config The configuration change will override the environment variable, so the environment variable check needs to come first. --- tests/remote/httpproxy.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/remote/httpproxy.c b/tests/remote/httpproxy.c index 00115a812ab..0985c8cd50f 100644 --- a/tests/remote/httpproxy.c +++ b/tests/remote/httpproxy.c @@ -112,6 +112,11 @@ void test_remote_httpproxy__env(void) orig_no_proxy = cl_getenv("NO_PROXY"); orig_proxies_need_reset = 1; + /* Clear everything for a fresh start */ + cl_setenv("HTTP_PROXY", NULL); + cl_setenv("HTTPS_PROXY", NULL); + cl_setenv("NO_PROXY", NULL); + /* HTTP proxy is ignored for HTTPS */ cl_setenv("HTTP_PROXY", "http://localhost:9/"); assert_proxy_is(NULL); @@ -133,11 +138,11 @@ void test_remote_httpproxy__env(void) cl_setenv("NO_PROXY", "github.dev,github.com,github.foo"); assert_proxy_is(NULL); + cl_setenv("HTTPS_PROXY", ""); + assert_proxy_is(NULL); + /* configuration overrides environment variables */ + cl_setenv("HTTPS_PROXY", "http://localhost:10/"); cl_setenv("NO_PROXY", "github.none"); assert_config_match("http.https://github.com.proxy", "http://localhost:11/"); - - /* empty env behaves like unset env */ - cl_setenv("HTTPS_PROXY", ""); - assert_proxy_is(NULL); } From 18fc751e00cfaeed17ad9360b06c07723c0b90fc Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 20 Sep 2021 13:07:37 -0400 Subject: [PATCH 0545/1616] win32: allow empty environment variables A length of 0 indicates an error and GetLastError() will be set. If GetLastError() is unset then the environment variable has a length of 0. --- src/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.c b/src/util.c index c7af2961aa7..9b0c45ce825 100644 --- a/src/util.c +++ b/src/util.c @@ -755,7 +755,7 @@ int git__getenv(git_buf *out, const char *name) if (value_len) error = git_buf_put_w(out, wide_value, value_len); - else if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) + else if (GetLastError() == ERROR_SUCCESS || GetLastError() == ERROR_ENVVAR_NOT_FOUND) error = GIT_ENOTFOUND; else git_error_set(GIT_ERROR_OS, "could not read environment variable '%s'", name); From 62eb2f8316902f81f5d55f684f3994672a1073bf Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 21 Sep 2021 10:59:49 -0400 Subject: [PATCH 0546/1616] email: don't clear buffer in append function `git_email__append_from_diff` is meant to - well, append from a diff. Clearing the buffer, by definition, is not appending. Stop doing that. --- src/email.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/email.c b/src/email.c index 8957d9a38d6..df63b6ec3b6 100644 --- a/src/email.c +++ b/src/email.c @@ -217,7 +217,6 @@ int git_email__append_from_diff( memcpy(&opts, given_opts, sizeof(git_email_create_options)); git_buf_sanitize(out); - git_buf_clear(out); if ((error = append_header(out, patch_idx, patch_count, commit_id, summary, author, &opts)) == 0 && (error = append_body(out, body)) == 0 && From 470acc718888782646347ae6e450bc167144acfd Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 21 Sep 2021 11:01:27 -0400 Subject: [PATCH 0547/1616] rebase: fix (deprecated) signing test --- tests/rebase/sign.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/rebase/sign.c b/tests/rebase/sign.c index 8b0473c3c43..06c18937aa1 100644 --- a/tests/rebase/sign.c +++ b/tests/rebase/sign.c @@ -249,13 +249,7 @@ void test_rebase_sign__create_propagates_error(void) } #ifndef GIT_DEPRECATE_HARD -int signing_cb_passthrough( - git_buf *signature, - git_buf *signature_field, - const char *commit_content, - void *payload) -{ - static const char *expected_commit_content = "\ +static const char *expected_commit_content = "\ tree cd99b26250099fc38d30bfaed7797a7275ed3366\n\ parent f87d14a4a236582a0278a916340a793714256864\n\ author Edward Thomson 1405625055 -0400\n\ @@ -263,6 +257,12 @@ committer Rebaser 1405694510 +0000\n\ \n\ Modification 3 to gravy\n"; +int signing_cb_passthrough( + git_buf *signature, + git_buf *signature_field, + const char *commit_content, + void *payload) +{ cl_assert_equal_b(false, git_buf_is_allocated(signature)); cl_assert_equal_b(false, git_buf_is_allocated(signature_field)); cl_assert_equal_s(expected_commit_content, commit_content); From 90656858ce6ec0f4cba5ba5f8690ace9b83161d0 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 21 Sep 2021 11:28:39 -0400 Subject: [PATCH 0548/1616] filter: use a `git_oid` in filter options, not a pointer Using a `git_oid *` in filter options was a mistake; it is a deviation from our typical pattern, and callers in some languages that GC may need very special treatment in order to pass both an options structure and a pointer outside of it. --- include/git2/attr.h | 8 +++++++- include/git2/blob.h | 8 +++++++- include/git2/filter.h | 8 +++++++- src/attr.c | 25 +++++++++++++++++++------ src/attr_file.c | 34 ++++++++++++++++++++++------------ src/attr_file.h | 5 +++-- src/blob.c | 8 +++++++- src/filter.c | 8 +++++++- tests/filter/bare.c | 10 ++-------- 9 files changed, 81 insertions(+), 33 deletions(-) diff --git a/include/git2/attr.h b/include/git2/attr.h index 62c2ed6e722..3891a0c9729 100644 --- a/include/git2/attr.h +++ b/include/git2/attr.h @@ -147,11 +147,17 @@ typedef struct { /** A combination of GIT_ATTR_CHECK flags */ unsigned int flags; +#ifdef GIT_DEPRECATE_HARD + void *reserved; +#else + git_oid *commit_id; +#endif + /** * The commit to load attributes from, when * `GIT_ATTR_CHECK_INCLUDE_COMMIT` is specified. */ - git_oid *commit_id; + git_oid attr_commit_id; } git_attr_options; #define GIT_ATTR_OPTIONS_VERSION 1 diff --git a/include/git2/blob.h b/include/git2/blob.h index fceb5c771f1..8fc73919d93 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -135,11 +135,17 @@ typedef struct { /** Flags to control the filtering process, see `git_blob_filter_flag_t` above */ uint32_t flags; +#ifdef GIT_DEPRECATE_HARD + void *reserved; +#else + git_oid *commit_id; +#endif + /** * The commit to load attributes from, when * `GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT` is specified. */ - git_oid *commit_id; + git_oid attr_commit_id; } git_blob_filter_options; #define GIT_BLOB_FILTER_OPTIONS_VERSION 1 diff --git a/include/git2/filter.h b/include/git2/filter.h index 044c3b87060..0465e5b144a 100644 --- a/include/git2/filter.h +++ b/include/git2/filter.h @@ -66,11 +66,17 @@ typedef struct { /** See `git_filter_flag_t` above */ uint32_t flags; +#ifdef GIT_DEPRECATE_HARD + void *reserved; +#else + git_oid *commit_id; +#endif + /** * The commit to load attributes from, when * `GIT_FILTER_ATTRIBUTES_FROM_COMMIT` is specified. */ - git_oid *commit_id; + git_oid attr_commit_id; } git_filter_options; #define GIT_FILTER_OPTIONS_VERSION 1 diff --git a/src/attr.c b/src/attr.c index 03b720c5a3a..14eab5b46d7 100644 --- a/src/attr.c +++ b/src/attr.c @@ -382,7 +382,7 @@ static int attr_setup( { git_buf system = GIT_BUF_INIT, info = GIT_BUF_INIT; git_attr_file_source index_source = { GIT_ATTR_FILE_SOURCE_INDEX, NULL, GIT_ATTR_FILE, NULL }; - git_attr_file_source head_source = { GIT_ATTR_FILE_SOURCE_COMMIT, NULL, GIT_ATTR_FILE, NULL }; + git_attr_file_source head_source = { GIT_ATTR_FILE_SOURCE_HEAD, NULL, GIT_ATTR_FILE, NULL }; git_attr_file_source commit_source = { GIT_ATTR_FILE_SOURCE_COMMIT, NULL, GIT_ATTR_FILE, NULL }; git_index *idx = NULL; const char *workdir; @@ -432,7 +432,12 @@ static int attr_setup( goto out; if ((opts && (opts->flags & GIT_ATTR_CHECK_INCLUDE_COMMIT) != 0)) { - commit_source.commit_id = opts->commit_id; +#ifndef GIT_DEPRECATE_HARD + if (opts->commit_id) + commit_source.commit_id = opts->commit_id; + else +#endif + commit_source.commit_id = &opts->attr_commit_id; if ((error = preload_attr_source(repo, attr_session, &commit_source)) < 0) goto out; @@ -521,8 +526,10 @@ static int attr_decide_sources( break; } - if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0 || - (flags & GIT_ATTR_CHECK_INCLUDE_COMMIT) != 0) + if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0) + srcs[count++] = GIT_ATTR_FILE_SOURCE_HEAD; + + if ((flags & GIT_ATTR_CHECK_INCLUDE_COMMIT) != 0) srcs[count++] = GIT_ATTR_FILE_SOURCE_COMMIT; return count; @@ -582,8 +589,14 @@ static int push_one_attr(void *ref, const char *path) for (i = 0; !error && i < n_src; ++i) { git_attr_file_source source = { src[i], path, GIT_ATTR_FILE }; - if (src[i] == GIT_ATTR_FILE_SOURCE_COMMIT && info->opts) - source.commit_id = info->opts->commit_id; + if (src[i] == GIT_ATTR_FILE_SOURCE_COMMIT && info->opts) { +#ifndef GIT_DEPRECATE_HARD + if (info->opts->commit_id) + source.commit_id = info->opts->commit_id; + else +#endif + source.commit_id = &info->opts->attr_commit_id; + } error = push_attr_source(info->repo, info->attr_session, info->files, &source, allow_macros); diff --git a/src/attr_file.c b/src/attr_file.c index f8627381c22..694967a1cae 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -163,8 +163,9 @@ int git_attr_file__load( break; } + case GIT_ATTR_FILE_SOURCE_HEAD: case GIT_ATTR_FILE_SOURCE_COMMIT: { - if (source->commit_id) { + if (source->type == GIT_ATTR_FILE_SOURCE_COMMIT) { if ((error = git_commit_lookup(&commit, repo, source->commit_id)) < 0 || (error = git_commit_tree(&tree, commit)) < 0) goto cleanup; @@ -234,6 +235,8 @@ int git_attr_file__load( file->nonexistent = 1; else if (source->type == GIT_ATTR_FILE_SOURCE_INDEX) git_oid_cpy(&file->cache_data.oid, git_blob_id(blob)); + else if (source->type == GIT_ATTR_FILE_SOURCE_HEAD) + git_oid_cpy(&file->cache_data.oid, git_tree_id(tree)); else if (source->type == GIT_ATTR_FILE_SOURCE_COMMIT) git_oid_cpy(&file->cache_data.oid, git_tree_id(tree)); else if (source->type == GIT_ATTR_FILE_SOURCE_FILE) @@ -288,22 +291,29 @@ int git_attr_file__out_of_date( return (git_oid__cmp(&file->cache_data.oid, &id) != 0); } - case GIT_ATTR_FILE_SOURCE_COMMIT: { + case GIT_ATTR_FILE_SOURCE_HEAD: { git_tree *tree = NULL; - int error; + int error = git_repository_head_tree(&tree, repo); - if (source->commit_id) { - git_commit *commit = NULL; + if (error < 0) + return error; - if ((error = git_commit_lookup(&commit, repo, source->commit_id)) < 0) - return error; + error = (git_oid__cmp(&file->cache_data.oid, git_tree_id(tree)) != 0); - error = git_commit_tree(&tree, commit); + git_tree_free(tree); + return error; + } - git_commit_free(commit); - } else { - error = git_repository_head_tree(&tree, repo); - } + case GIT_ATTR_FILE_SOURCE_COMMIT: { + git_commit *commit = NULL; + git_tree *tree = NULL; + int error; + + if ((error = git_commit_lookup(&commit, repo, source->commit_id)) < 0) + return error; + + error = git_commit_tree(&tree, commit); + git_commit_free(commit); if (error < 0) return error; diff --git a/src/attr_file.h b/src/attr_file.h index 16e33caf1e6..a07cb4268d8 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -40,9 +40,10 @@ typedef enum { GIT_ATTR_FILE_SOURCE_MEMORY = 0, GIT_ATTR_FILE_SOURCE_FILE = 1, GIT_ATTR_FILE_SOURCE_INDEX = 2, - GIT_ATTR_FILE_SOURCE_COMMIT = 3, + GIT_ATTR_FILE_SOURCE_HEAD = 3, + GIT_ATTR_FILE_SOURCE_COMMIT = 4, - GIT_ATTR_FILE_NUM_SOURCES = 4 + GIT_ATTR_FILE_NUM_SOURCES = 5 } git_attr_file_source_t; typedef struct { diff --git a/src/blob.c b/src/blob.c index 79096ee9544..06a4a002688 100644 --- a/src/blob.c +++ b/src/blob.c @@ -449,7 +449,13 @@ int git_blob_filter( if ((opts.flags & GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT) != 0) { filter_opts.flags |= GIT_FILTER_ATTRIBUTES_FROM_COMMIT; - filter_opts.commit_id = opts.commit_id; + +#ifndef GIT_DEPRECATE_HARD + if (opts.commit_id) + git_oid_cpy(&filter_opts.attr_commit_id, opts.commit_id); + else +#endif + git_oid_cpy(&filter_opts.attr_commit_id, &opts.attr_commit_id); } if (!(error = git_filter_list_load_ext( diff --git a/src/filter.c b/src/filter.c index dd7d2f7ec77..73497cb3024 100644 --- a/src/filter.c +++ b/src/filter.c @@ -446,7 +446,13 @@ static int filter_list_check_attributes( if ((src->options.flags & GIT_FILTER_ATTRIBUTES_FROM_COMMIT) != 0) { attr_opts.flags |= GIT_ATTR_CHECK_INCLUDE_COMMIT; - attr_opts.commit_id = src->options.commit_id; + +#ifndef GIT_DEPRECATE_HARD + if (src->options.commit_id) + git_oid_cpy(&attr_opts.attr_commit_id, src->options.commit_id); + else +#endif + git_oid_cpy(&attr_opts.attr_commit_id, &src->options.attr_commit_id); } error = git_attr_get_many_with_session( diff --git a/tests/filter/bare.c b/tests/filter/bare.c index f8e34232fad..8402638cefc 100644 --- a/tests/filter/bare.c +++ b/tests/filter/bare.c @@ -137,13 +137,10 @@ void test_filter_bare__from_specific_commit_one(void) git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT; git_blob *blob; git_buf buf = { 0 }; - git_oid commit_id; - - cl_git_pass(git_oid_fromstr(&commit_id, "b8986fec0f7bde90f78ac72706e782d82f24f2f0")); opts.flags |= GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES; opts.flags |= GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT; - opts.commit_id = &commit_id; + cl_git_pass(git_oid_fromstr(&opts.attr_commit_id, "b8986fec0f7bde90f78ac72706e782d82f24f2f0")); cl_git_pass(git_revparse_single( (git_object **)&blob, g_repo, "055c872")); /* ident */ @@ -165,13 +162,10 @@ void test_filter_bare__from_specific_commit_with_no_attributes_file(void) git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT; git_blob *blob; git_buf buf = { 0 }; - git_oid commit_id; - - cl_git_pass(git_oid_fromstr(&commit_id, "5afb6a14a864e30787857dd92af837e8cdd2cb1b")); opts.flags |= GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES; opts.flags |= GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT; - opts.commit_id = &commit_id; + cl_git_pass(git_oid_fromstr(&opts.attr_commit_id, "5afb6a14a864e30787857dd92af837e8cdd2cb1b")); cl_git_pass(git_revparse_single( (git_object **)&blob, g_repo, "799770d")); /* all-lf */ From 825dd544ab719b1c6c3952cc292a20643392054d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 20 Sep 2021 12:41:13 -0400 Subject: [PATCH 0549/1616] ci: pull libssh2 from www.libssh2.org libssh2.org and www.libssh2.org were previously identical; now this is a redirect. --- ci/docker/centos7 | 2 +- ci/docker/centos8 | 2 +- ci/docker/focal | 3 +-- ci/docker/xenial | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ci/docker/centos7 b/ci/docker/centos7 index 098edb26a50..8105f1442f0 100644 --- a/ci/docker/centos7 +++ b/ci/docker/centos7 @@ -18,7 +18,7 @@ RUN yum install -y \ FROM yum AS libssh2 RUN cd /tmp && \ - curl https://libssh2.org/download/libssh2-1.8.0.tar.gz | tar -xz && \ + curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.8.0.tar.gz | tar -xz && \ cd libssh2-1.8.0 && \ ./configure && \ make && \ diff --git a/ci/docker/centos8 b/ci/docker/centos8 index f4719844624..cca088103a0 100644 --- a/ci/docker/centos8 +++ b/ci/docker/centos8 @@ -20,7 +20,7 @@ RUN yum install -y \ FROM yum AS libssh2 RUN cd /tmp && \ - curl https://libssh2.org/download/libssh2-1.8.0.tar.gz | tar -xz && \ + curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.8.0.tar.gz | tar -xz && \ cd libssh2-1.8.0 && \ ./configure && \ make && \ diff --git a/ci/docker/focal b/ci/docker/focal index 17138769809..37d7d6356dc 100644 --- a/ci/docker/focal +++ b/ci/docker/focal @@ -49,8 +49,7 @@ RUN cd /tmp && \ FROM mbedtls AS libssh2 RUN cd /tmp && \ - curl --insecure --location --silent --show-error https://www.libssh2.org/download/libssh2-1.9.0.tar.gz | \ - tar -xz && \ + curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.9.0.tar.gz | tar -xz && \ cd libssh2-1.9.0 && \ mkdir build build-msan && \ cd build && \ diff --git a/ci/docker/xenial b/ci/docker/xenial index 4c3810af44f..c19fe421de7 100644 --- a/ci/docker/xenial +++ b/ci/docker/xenial @@ -41,8 +41,7 @@ RUN cd /tmp && \ FROM mbedtls AS libssh2 RUN cd /tmp && \ - curl --insecure --location --silent --show-error https://www.libssh2.org/download/libssh2-1.8.2.tar.gz | \ - tar -xz && \ + curl --location --silent --show-error https://www.libssh2.org/download/libssh2-1.8.2.tar.gz | tar -xz && \ cd libssh2-1.8.2 && \ CFLAGS=-fPIC cmake -G Ninja -DBUILD_SHARED_LIBS=ON -DCRYPTO_BACKEND=Libgcrypt . && \ ninja install && \ From 1ba7c32709cb7bc1cc0d11d1a87a7d952eb514ae Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 21 Sep 2021 20:23:44 -0400 Subject: [PATCH 0550/1616] diff: update `GIT_DIFF_IGNORE_BLANK_LINES` `GIT_DIFF_IGNORE_BLANK_LINES` needs to be within a (signed) int, per the `enum` definition of ISO C. --- include/git2/diff.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/git2/diff.h b/include/git2/diff.h index a0a15e76fa9..a14c01993fa 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -133,6 +133,9 @@ typedef enum { */ GIT_DIFF_INDENT_HEURISTIC = (1u << 18), + /** Ignore blank lines */ + GIT_DIFF_IGNORE_BLANK_LINES = (1u << 19), + /** Treat all files as text, disabling binary attributes & detection */ GIT_DIFF_FORCE_TEXT = (1u << 20), /** Treat all files as binary, disabling text diffs */ @@ -168,10 +171,6 @@ typedef enum { * can apply given diff information to binary files. */ GIT_DIFF_SHOW_BINARY = (1u << 30), - - /** Ignore blank lines */ - GIT_DIFF_IGNORE_BLANK_LINES = (1u << 31), - } git_diff_option_t; /** From e0531f2c1467a3d6598cbf9e8a352a2b10a73cf1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 22 Sep 2021 08:34:10 -0400 Subject: [PATCH 0551/1616] v1.3: changelog --- docs/changelog.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 2a800afec67..494007610c5 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,3 +1,49 @@ +v1.3 +---- + +This is release v1.3.0, "Zugunruhe". This release includes only minor new featuers that will be helpful for users to have an orderly transition to the v2.0 lineage. + +## New Features +* Support custom git extensions by @ethomson in https://github.com/libgit2/libgit2/pull/6031 +* Introduce `git_email_create`; deprecate `git_diff_format_email` by @ethomson in https://github.com/libgit2/libgit2/pull/6061 + +## Bug fixes +* #6028: Check if `threadstate->error_t.message` is not `git_buf__initbuf` before freeing. by @arroz in https://github.com/libgit2/libgit2/pull/6029 +* remote: Mark `git_remote_name_is_valid` as `GIT_EXTERN` by @lhchavez in https://github.com/libgit2/libgit2/pull/6032 +* Fix config parsing for multiline with multiple quoted comment chars by @basile-henry in https://github.com/libgit2/libgit2/pull/6043 +* indexer: Avoid one `mmap(2)`/`munmap(2)` pair per `git_indexer_append` call by @lhchavez in https://github.com/libgit2/libgit2/pull/6039 +* merge: Check file mode when resolving renames by @ccstolley in https://github.com/libgit2/libgit2/pull/6060 +* Allow proxy options when connecting with a detached remote. by @lrm29 in https://github.com/libgit2/libgit2/pull/6058 +* win32: allow empty environment variables by @ethomson in https://github.com/libgit2/libgit2/pull/6063 +* Fixes for deprecated APIs by @ethomson in https://github.com/libgit2/libgit2/pull/6066 +* filter: use a `git_oid` in filter options, not a pointer by @ethomson in https://github.com/libgit2/libgit2/pull/6067 + +## Code cleanups +* notes: use a buffer internally by @ethomson in https://github.com/libgit2/libgit2/pull/6047 +* Fix coding style for pointer by @punkymaniac in https://github.com/libgit2/libgit2/pull/6045 +* Use __typeof__ GNUC keyword for ISO C compatibility by @duncanthomson in https://github.com/libgit2/libgit2/pull/6041 +* Discover libssh2 without pkg-config by @stac47 in https://github.com/libgit2/libgit2/pull/6053 +* Longpath filter bug by @lrm29 in https://github.com/libgit2/libgit2/pull/6055 +* Add test to ensure empty proxy env behaves like unset env by @sathieu in https://github.com/libgit2/libgit2/pull/6052 +* Stdint header condition has been reverted. by @lolgear in https://github.com/libgit2/libgit2/pull/6020 +* diff: update `GIT_DIFF_IGNORE_BLANK_LINES` by @ethomson in https://github.com/libgit2/libgit2/pull/6068 + +## CI Improvements +* ci: pull libssh2 from www.libssh2.org by @ethomson in https://github.com/libgit2/libgit2/pull/6064 + +## Documentation changes +* Update README.md by @shijinglu in https://github.com/libgit2/libgit2/pull/6050 + +## New Contributors +* @basile-henry made their first contribution in https://github.com/libgit2/libgit2/pull/6043 +* @duncanthomson made their first contribution in https://github.com/libgit2/libgit2/pull/6041 +* @stac47 made their first contribution in https://github.com/libgit2/libgit2/pull/6053 +* @shijinglu made their first contribution in https://github.com/libgit2/libgit2/pull/6050 +* @ccstolley made their first contribution in https://github.com/libgit2/libgit2/pull/6060 +* @sathieu made their first contribution in https://github.com/libgit2/libgit2/pull/6052 + +**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.2.0...v1.3.0 + v1.2 ----- From e7437162ff5d47b2e0d62425517f919904795e5b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 22 Sep 2021 08:35:02 -0400 Subject: [PATCH 0552/1616] v1.3: update version number --- CMakeLists.txt | 2 +- include/git2/version.h | 6 +++--- package.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36170a5dc9b..3dccec3109a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1) -project(libgit2 VERSION "1.2.0" LANGUAGES C) +project(libgit2 VERSION "1.3.0" LANGUAGES C) # Add find modules to the path set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${libgit2_SOURCE_DIR}/cmake/") diff --git a/include/git2/version.h b/include/git2/version.h index 46adfec14de..3503a62781a 100644 --- a/include/git2/version.h +++ b/include/git2/version.h @@ -7,12 +7,12 @@ #ifndef INCLUDE_git_version_h__ #define INCLUDE_git_version_h__ -#define LIBGIT2_VERSION "1.2.0" +#define LIBGIT2_VERSION "1.3.0" #define LIBGIT2_VER_MAJOR 1 -#define LIBGIT2_VER_MINOR 2 +#define LIBGIT2_VER_MINOR 3 #define LIBGIT2_VER_REVISION 0 #define LIBGIT2_VER_PATCH 0 -#define LIBGIT2_SOVERSION "1.2" +#define LIBGIT2_SOVERSION "1.3" #endif diff --git a/package.json b/package.json index e0544f653b6..e2e672f9fe6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "libgit2", - "version": "1.2.0", + "version": "1.3.0", "repo": "https://github.com/libgit2/libgit2", "description": " A cross-platform, linkable library implementation of Git that you can use in your application.", "install": "mkdir build && cd build && cmake .. && cmake --build ." From 61bbb2d11a917a4ca74e1acc24fc3e822f16fb99 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 22 Sep 2021 15:28:23 -0400 Subject: [PATCH 0553/1616] changelog: fix typo --- docs/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 494007610c5..9e51296a191 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,7 +1,7 @@ v1.3 ---- -This is release v1.3.0, "Zugunruhe". This release includes only minor new featuers that will be helpful for users to have an orderly transition to the v2.0 lineage. +This is release v1.3.0, "Zugunruhe". This release includes only minor new features that will be helpful for users to have an orderly transition to the v2.0 lineage. ## New Features * Support custom git extensions by @ethomson in https://github.com/libgit2/libgit2/pull/6031 From 136901086ecfdd2b5cc106782310355a9c0b1a9a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 22 Sep 2021 15:31:21 -0400 Subject: [PATCH 0554/1616] changelog: separate releases with a horizontal rule --- docs/changelog.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 9e51296a191..5625be3148c 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -44,6 +44,8 @@ This is release v1.3.0, "Zugunruhe". This release includes only minor new featu **Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.2.0...v1.3.0 +--------------------------------------------------------------------- + v1.2 ----- @@ -217,6 +219,8 @@ This is meant to be the final minor release in the v1 lineage. v2.0 will be the **Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.1.0...v1.2.0 +--------------------------------------------------------------------- + v1.1 ---- @@ -306,6 +310,8 @@ This is a bugfix release with the following changes: has been fixed. Previously, fetching from servers like Gerrit, that sent large data packets, would error. +--------------------------------------------------------------------- + v1.0 ---- @@ -785,6 +791,8 @@ release: * Tyler Ang-Wanek * Tyler Wanek +--------------------------------------------------------------------- + v0.28 ----- @@ -933,6 +941,8 @@ v0.28 out such files is not allowed as this can make a Git implementation write outside of the repository and bypass the fsck checks for CVE-2018-11235. +--------------------------------------------------------------------- + v0.27 --------- @@ -1049,6 +1059,8 @@ v0.27 `git_odb_backend` interface have changed their signatures to allow providing the object's size and type to the caller. +--------------------------------------------------------------------- + v0.26 ----- @@ -1293,6 +1305,8 @@ v0.25 to provide the name of a merge driver to be used to handle files changed during a merge. +--------------------------------------------------------------------- + v0.24 ------- @@ -1408,6 +1422,8 @@ v0.24 * `git_remote_connect()` now takes a `custom_headers` argument to set the extra HTTP header fields to send. +--------------------------------------------------------------------- + v0.23 ------ @@ -1707,6 +1723,8 @@ v0.23 * It is no longer allowed to call `git_buf_grow()` on buffers borrowing the memory they point to. +--------------------------------------------------------------------- + v0.22 ------ From 581cfbda85939a5336fb39f6068b2c19ddd59f33 Mon Sep 17 00:00:00 2001 From: Paymon MARANDI Date: Thu, 23 Sep 2021 11:59:52 -0400 Subject: [PATCH 0555/1616] examples: Free the git_config and git_config_entry after use --- examples/config.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/config.c b/examples/config.c index f7fa70e4d70..6e14ce8c866 100644 --- a/examples/config.c +++ b/examples/config.c @@ -26,6 +26,10 @@ static int config_get(git_config *cfg, const char *key) } puts(entry->value); + + /* Free the git_config_entry after use with `git_config_entry_free()`. */ + git_config_entry_free(entry); + return 0; } @@ -57,6 +61,11 @@ int lg2_config(git_repository *repo, int argc, char **argv) error = 1; } + /** + * The configuration file must be freed once it's no longer + * being used by the user. + */ + git_config_free(cfg); out: return error; } From d6c7ca3ea99aa97d520d741dee2a8542cd0f2e38 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 25 Sep 2021 14:36:25 +0100 Subject: [PATCH 0556/1616] win32: posixify the output of p_getcwd Make p_getcwd match the rest of our win32 path handling semantics. (This is currently only used in tests, which is why this disparity went unnoticed.) --- src/win32/posix_w32.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index 66d12cfcfa9..8af07e6fa77 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -648,6 +648,8 @@ int p_getcwd(char *buffer_out, size_t size) if (!cwd) return -1; + git_win32_path_remove_namespace(cwd, wcslen(cwd)); + /* Convert the working directory back to UTF-8 */ if (git__utf16_to_8(buffer_out, size, cwd) < 0) { DWORD code = GetLastError(); @@ -660,6 +662,7 @@ int p_getcwd(char *buffer_out, size_t size) return -1; } + git_path_mkposix(buffer_out); return 0; } From 0f4256b8d78cf602192e0546d185953ee1b30fd5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 24 Sep 2021 15:23:34 -0400 Subject: [PATCH 0557/1616] repository: improve `hashfile` for absolute paths When `git_repository_hashfile` is handed an absolute path, it determines whether the path is within the repository's working directory or not. This is necessary when there is no `as_path` specified. If the path is within the working directory, then the given path should be used for attribute lookups (it is the effective `as_path`). If it is not within the working directory, then it is _not_ eligible. Importantly, now we will _never_ pass an absolute path down to attribute lookup functions. --- include/git2/repository.h | 12 +++--- src/repository.c | 24 ++++++----- tests/repo/hashfile.c | 89 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 108 insertions(+), 17 deletions(-) diff --git a/include/git2/repository.h b/include/git2/repository.h index e699016447d..8d1cffc9bf6 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -762,13 +762,15 @@ GIT_EXTERN(int) git_repository_mergehead_foreach( * * @param out Output value of calculated SHA * @param repo Repository pointer - * @param path Path to file on disk whose contents should be hashed. If the - * repository is not NULL, this can be a relative path. + * @param path Path to file on disk whose contents should be hashed. This + * may be an absolute path or a relative path, in which case it + * will be treated as a path within the working directory. * @param type The object type to hash as (e.g. GIT_OBJECT_BLOB) * @param as_path The path to use to look up filtering rules. If this is - * NULL, then the `path` parameter will be used instead. If - * this is passed as the empty string, then no filters will be - * applied when calculating the hash. + * an empty string then no filters will be applied when + * calculating the hash. If this is `NULL` and the `path` + * parameter is a file within the repository's working + * directory, then the `path` will be used. * @return 0 on success, or an error code */ GIT_EXTERN(int) git_repository_hashfile( diff --git a/src/repository.c b/src/repository.c index 8f0f477c433..9b3e9c9e3b1 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2840,34 +2840,36 @@ int git_repository_hashfile( git_file fd = -1; uint64_t len; git_buf full_path = GIT_BUF_INIT; + const char *workdir = git_repository_workdir(repo); /* as_path can be NULL */ GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(path); GIT_ASSERT_ARG(repo); - /* At some point, it would be nice if repo could be NULL to just - * apply filter rules defined in system and global files, but for - * now that is not possible because git_filters_load() needs it. - */ - - if ((error = git_path_join_unrooted( - &full_path, path, git_repository_workdir(repo), NULL)) < 0 || + if ((error = git_path_join_unrooted(&full_path, path, workdir, NULL)) < 0 || (error = git_path_validate_workdir_buf(repo, &full_path)) < 0) return error; - if (!as_path) - as_path = path; + /* + * NULL as_path means that we should derive it from the + * given path. + */ + if (!as_path) { + if (workdir && !git__prefixcmp(full_path.ptr, workdir)) + as_path = full_path.ptr + strlen(workdir); + else + as_path = ""; + } /* passing empty string for "as_path" indicated --no-filters */ if (strlen(as_path) > 0) { error = git_filter_list_load( &fl, repo, NULL, as_path, GIT_FILTER_TO_ODB, GIT_FILTER_DEFAULT); + if (error < 0) return error; - } else { - error = 0; } /* at this point, error is a count of the number of loaded filters */ diff --git a/tests/repo/hashfile.c b/tests/repo/hashfile.c index 0fb4e6772a1..bffb51bb56b 100644 --- a/tests/repo/hashfile.c +++ b/tests/repo/hashfile.c @@ -10,6 +10,7 @@ void test_repo_hashfile__initialize(void) void test_repo_hashfile__cleanup(void) { + cl_fixture_cleanup("absolute"); cl_git_sandbox_cleanup(); _repo = NULL; } @@ -38,10 +39,18 @@ void test_repo_hashfile__simple(void) git_buf_dispose(&full); } -void test_repo_hashfile__filtered(void) +void test_repo_hashfile__filtered_in_workdir(void) { + git_buf root = GIT_BUF_INIT, txt = GIT_BUF_INIT, bin = GIT_BUF_INIT; + char cwd[GIT_PATH_MAX]; git_oid a, b; + cl_must_pass(p_getcwd(cwd, GIT_PATH_MAX)); + cl_must_pass(p_mkdir("absolute", 0777)); + cl_git_pass(git_buf_joinpath(&root, cwd, "status")); + cl_git_pass(git_buf_joinpath(&txt, root.ptr, "testfile.txt")); + cl_git_pass(git_buf_joinpath(&bin, root.ptr, "testfile.bin")); + cl_repo_set_bool(_repo, "core.autocrlf", true); cl_git_append2file("status/.gitattributes", "*.txt text\n*.bin binary\n\n"); @@ -55,21 +64,41 @@ void test_repo_hashfile__filtered(void) cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJECT_BLOB, NULL)); cl_assert(git_oid_cmp(&a, &b)); + /* not equal hashes because of filtering when specified by absolute path */ + cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_repository_hashfile(&b, _repo, txt.ptr, GIT_OBJECT_BLOB, NULL)); + cl_assert(git_oid_cmp(&a, &b)); + /* equal hashes because filter is binary */ cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB)); cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJECT_BLOB, NULL)); cl_assert_equal_oid(&a, &b); + /* equal hashes because filter is binary when specified by absolute path */ + cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_repository_hashfile(&b, _repo, bin.ptr, GIT_OBJECT_BLOB, NULL)); + cl_assert_equal_oid(&a, &b); + /* equal hashes when 'as_file' points to binary filtering */ cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB)); cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJECT_BLOB, "foo.bin")); cl_assert_equal_oid(&a, &b); + /* equal hashes when 'as_file' points to binary filtering (absolute path) */ + cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_repository_hashfile(&b, _repo, txt.ptr, GIT_OBJECT_BLOB, "foo.bin")); + cl_assert_equal_oid(&a, &b); + /* not equal hashes when 'as_file' points to text filtering */ cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB)); cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJECT_BLOB, "foo.txt")); cl_assert(git_oid_cmp(&a, &b)); + /* not equal hashes when 'as_file' points to text filtering */ + cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_repository_hashfile(&b, _repo, bin.ptr, GIT_OBJECT_BLOB, "foo.txt")); + cl_assert(git_oid_cmp(&a, &b)); + /* equal hashes when 'as_file' is empty and turns off filtering */ cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB)); cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJECT_BLOB, "")); @@ -79,7 +108,65 @@ void test_repo_hashfile__filtered(void) cl_git_pass(git_repository_hashfile(&b, _repo, "testfile.bin", GIT_OBJECT_BLOB, "")); cl_assert_equal_oid(&a, &b); + cl_git_pass(git_odb_hashfile(&a, "status/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_repository_hashfile(&b, _repo, txt.ptr, GIT_OBJECT_BLOB, "")); + cl_assert_equal_oid(&a, &b); + + cl_git_pass(git_odb_hashfile(&a, "status/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_repository_hashfile(&b, _repo, bin.ptr, GIT_OBJECT_BLOB, "")); + cl_assert_equal_oid(&a, &b); + /* some hash type failures */ cl_git_fail(git_odb_hashfile(&a, "status/testfile.txt", 0)); cl_git_fail(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJECT_ANY, NULL)); + + git_buf_dispose(&txt); + git_buf_dispose(&bin); + git_buf_dispose(&root); +} + +void test_repo_hashfile__filtered_outside_workdir(void) +{ + git_buf root = GIT_BUF_INIT, txt = GIT_BUF_INIT, bin = GIT_BUF_INIT; + char cwd[GIT_PATH_MAX]; + git_oid a, b; + + cl_must_pass(p_getcwd(cwd, GIT_PATH_MAX)); + cl_must_pass(p_mkdir("absolute", 0777)); + cl_git_pass(git_buf_joinpath(&root, cwd, "absolute")); + cl_git_pass(git_buf_joinpath(&txt, root.ptr, "testfile.txt")); + cl_git_pass(git_buf_joinpath(&bin, root.ptr, "testfile.bin")); + + cl_repo_set_bool(_repo, "core.autocrlf", true); + cl_git_append2file("status/.gitattributes", "*.txt text\n*.bin binary\n\n"); + + /* create some sample content with CRLF in it */ + cl_git_mkfile("absolute/testfile.txt", "content\r\n"); + cl_git_mkfile("absolute/testfile.bin", "other\r\nstuff\r\n"); + + /* not equal hashes because of filtering */ + cl_git_pass(git_odb_hashfile(&a, "absolute/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_repository_hashfile(&b, _repo, txt.ptr, GIT_OBJECT_BLOB, "testfile.txt")); + cl_assert(git_oid_cmp(&a, &b)); + + /* equal hashes because filter is binary */ + cl_git_pass(git_odb_hashfile(&a, "absolute/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_repository_hashfile(&b, _repo, bin.ptr, GIT_OBJECT_BLOB, "testfile.bin")); + cl_assert_equal_oid(&a, &b); + + /* + * equal hashes because no filtering occurs for absolute paths outside the working + * directory unless as_path is specified + */ + cl_git_pass(git_odb_hashfile(&a, "absolute/testfile.txt", GIT_OBJECT_BLOB)); + cl_git_pass(git_repository_hashfile(&b, _repo, txt.ptr, GIT_OBJECT_BLOB, NULL)); + cl_assert_equal_oid(&a, &b); + + cl_git_pass(git_odb_hashfile(&a, "absolute/testfile.bin", GIT_OBJECT_BLOB)); + cl_git_pass(git_repository_hashfile(&b, _repo, bin.ptr, GIT_OBJECT_BLOB, NULL)); + cl_assert_equal_oid(&a, &b); + + git_buf_dispose(&txt); + git_buf_dispose(&bin); + git_buf_dispose(&root); } From 848bd0098a0dfa2c0502691bf76d3dbb0a00526d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 24 Sep 2021 16:05:23 -0400 Subject: [PATCH 0558/1616] blob: improve `create_from_disk` attribute lookups Resolve absolute paths to be working directory relative when looking up attributes. Importantly, now we will _never_ pass an absolute path down to attribute lookup functions. --- src/blob.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/blob.c b/src/blob.c index 06a4a002688..09b5b5d9121 100644 --- a/src/blob.c +++ b/src/blob.c @@ -277,21 +277,20 @@ int git_blob_create_from_disk( { int error; git_buf full_path = GIT_BUF_INIT; - const char *workdir, *hintpath; + const char *workdir, *hintpath = NULL; if ((error = git_path_prettify(&full_path, path, NULL)) < 0) { git_buf_dispose(&full_path); return error; } - hintpath = git_buf_cstr(&full_path); workdir = git_repository_workdir(repo); - if (workdir && !git__prefixcmp(hintpath, workdir)) - hintpath += strlen(workdir); + if (workdir && !git__prefixcmp(full_path.ptr, workdir)) + hintpath = full_path.ptr + strlen(workdir); error = git_blob__create_from_paths( - id, NULL, repo, git_buf_cstr(&full_path), hintpath, 0, true); + id, NULL, repo, git_buf_cstr(&full_path), hintpath, 0, !!hintpath); git_buf_dispose(&full_path); return error; From 3d8749d323380d47aad7afaa64bf0999dd3992b3 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 24 Sep 2021 16:07:17 -0400 Subject: [PATCH 0559/1616] checkout: always provide a path for attribute lookup Always pass a working-directory relative path to attribute lookups during checkout. --- src/checkout.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/checkout.c b/src/checkout.c index 71315915214..3a171066b4e 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -1520,8 +1520,7 @@ static int blob_content_to_file( int fd; int error = 0; - if (hint_path == NULL) - hint_path = path; + GIT_ASSERT(hint_path != NULL); if ((error = mkpath2file(data, path, data->opts.dir_mode)) < 0) return error; @@ -1789,7 +1788,7 @@ static int checkout_blob( } error = checkout_write_content( - data, &file->id, fullpath->ptr, NULL, file->mode, &st); + data, &file->id, fullpath->ptr, file->path, file->mode, &st); /* update the index unless prevented */ if (!error && (data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) == 0) @@ -1975,7 +1974,7 @@ static int checkout_write_entry( checkout_conflictdata *conflict, const git_index_entry *side) { - const char *hint_path = NULL, *suffix; + const char *hint_path, *suffix; git_buf *fullpath; struct stat st; int error; @@ -1998,10 +1997,10 @@ static int checkout_write_entry( if (checkout_path_suffixed(fullpath, suffix) < 0) return -1; - - hint_path = side->path; } + hint_path = side->path; + if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0 && (error = checkout_safe_for_update_only(data, fullpath->ptr, side->mode)) <= 0) return error; @@ -2118,7 +2117,7 @@ static int checkout_write_merge( filter_session.temp_buf = &data->tmp; if ((error = git_filter_list__load( - &fl, data->repo, NULL, git_buf_cstr(&path_workdir), + &fl, data->repo, NULL, result.path, GIT_FILTER_TO_WORKTREE, &filter_session)) < 0 || (error = git_filter_list__convert_buf(&out_data, fl, &in_data)) < 0) goto done; From 091bd738d79d5485936578ed2cb7edb96efbc80f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 24 Sep 2021 17:00:43 -0400 Subject: [PATCH 0560/1616] attr: ensure lookups are on repo-relative paths Attribute lookups are done on paths relative to the repository. Fail if erroneously presented with an absolute path. --- src/attr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/attr.c b/src/attr.c index 14eab5b46d7..cd704a4901b 100644 --- a/src/attr.c +++ b/src/attr.c @@ -629,6 +629,8 @@ static int collect_attr_files( const char *workdir = git_repository_workdir(repo); attr_walk_up_info info = { NULL }; + GIT_ASSERT(!git_path_is_absolute(path)); + if ((error = attr_setup(repo, attr_session, opts)) < 0) return error; From f5a9f0a2587f4fa2d02ee74b0522a0fd99fabe98 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 25 Sep 2021 15:19:22 -0400 Subject: [PATCH 0561/1616] attr_file: don't validate workdir paths in attr lookups When looking up attributes for a file, we construct an absolute path to the queried file within the working directory so that we can accept both absolute paths and working directory relative paths. We then trim the leading working directory path to give us an in-repo path. Since we only want the in-repo path to look up attributes - and not to read it from disk - we don't need to validate its length. --- src/attr_file.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/attr_file.c b/src/attr_file.c index 694967a1cae..4a0d66e92cc 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -561,8 +561,7 @@ int git_attr_path__init( /* build full path as best we can */ git_buf_init(&info->full, 0); - if (git_path_join_unrooted(&info->full, path, base, &root) < 0 || - git_path_validate_workdir_buf(repo, &info->full) < 0) + if (git_path_join_unrooted(&info->full, path, base, &root) < 0) return -1; info->path = info->full.ptr + root; From 46508fe64737c2fe71d9e3221c56fbe0fae6996c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 26 Sep 2021 11:28:47 -0400 Subject: [PATCH 0562/1616] attr_file: don't take the `repo` as an arg The `repo` argument is now unnecessary. Remove it. --- src/attr.c | 6 +++--- src/attr_file.c | 1 - src/attr_file.h | 1 - src/ignore.c | 4 ++-- tests/attr/lookup.c | 6 +++--- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/attr.c b/src/attr.c index 14eab5b46d7..92ff6c7a5ec 100644 --- a/src/attr.c +++ b/src/attr.c @@ -68,7 +68,7 @@ int git_attr_get_ext( if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; - if (git_attr_path__init(&path, repo, pathname, git_repository_workdir(repo), dir_flag) < 0) + if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), dir_flag) < 0) return -1; if ((error = collect_attr_files(repo, NULL, opts, pathname, &files)) < 0) @@ -149,7 +149,7 @@ int git_attr_get_many_with_session( if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; - if (git_attr_path__init(&path, repo, pathname, git_repository_workdir(repo), dir_flag) < 0) + if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), dir_flag) < 0) return -1; if ((error = collect_attr_files(repo, attr_session, opts, pathname, &files)) < 0) @@ -264,7 +264,7 @@ int git_attr_foreach_ext( if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; - if (git_attr_path__init(&path, repo, pathname, git_repository_workdir(repo), dir_flag) < 0) + if (git_attr_path__init(&path, pathname, git_repository_workdir(repo), dir_flag) < 0) return -1; if ((error = collect_attr_files(repo, NULL, opts, pathname, &files)) < 0 || diff --git a/src/attr_file.c b/src/attr_file.c index 4a0d66e92cc..71bd20a0f64 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -551,7 +551,6 @@ git_attr_assignment *git_attr_rule__lookup_assignment( int git_attr_path__init( git_attr_path *info, - git_repository *repo, const char *path, const char *base, git_dir_flag dir_flag) diff --git a/src/attr_file.h b/src/attr_file.h index a07cb4268d8..d634e6da948 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -227,7 +227,6 @@ typedef enum { GIT_DIR_FLAG_TRUE = 1, GIT_DIR_FLAG_FALSE = 0, GIT_DIR_FLAG_UNKNO extern int git_attr_path__init( git_attr_path *out, - git_repository *repo, const char *path, const char *base, git_dir_flag is_dir); diff --git a/src/ignore.c b/src/ignore.c index f7551cddb6f..9ead96ba67e 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -468,7 +468,7 @@ int git_ignore__lookup( *out = GIT_IGNORE_NOTFOUND; if (git_attr_path__init( - &path, ignores->repo, pathname, git_repository_workdir(ignores->repo), dir_flag) < 0) + &path, pathname, git_repository_workdir(ignores->repo), dir_flag) < 0) return -1; /* first process builtins - success means path was found */ @@ -552,7 +552,7 @@ int git_ignore_path_is_ignored( else if (git_repository_is_bare(repo)) dir_flag = GIT_DIR_FLAG_FALSE; - if ((error = git_attr_path__init(&path, repo, pathname, workdir, dir_flag)) < 0 || + if ((error = git_attr_path__init(&path, pathname, workdir, dir_flag)) < 0 || (error = git_ignore__for_path(repo, path.path, &ignores)) < 0) goto cleanup; diff --git a/tests/attr/lookup.c b/tests/attr/lookup.c index bfb2e872f26..f19f38fbb3a 100644 --- a/tests/attr/lookup.c +++ b/tests/attr/lookup.c @@ -13,7 +13,7 @@ void test_attr_lookup__simple(void) cl_assert_equal_s(cl_fixture("attr/attr0"), file->entry->path); cl_assert(file->rules.length == 1); - cl_git_pass(git_attr_path__init(&path, NULL, "test", NULL, GIT_DIR_FLAG_UNKNOWN)); + cl_git_pass(git_attr_path__init(&path, "test", NULL, GIT_DIR_FLAG_UNKNOWN)); cl_assert_equal_s("test", path.path); cl_assert_equal_s("test", path.basename); cl_assert(!path.is_dir); @@ -36,7 +36,7 @@ static void run_test_cases(git_attr_file *file, struct attr_expected *cases, int int error; for (c = cases; c->path != NULL; c++) { - cl_git_pass(git_attr_path__init(&path, NULL, c->path, NULL, GIT_DIR_FLAG_UNKNOWN)); + cl_git_pass(git_attr_path__init(&path, c->path, NULL, GIT_DIR_FLAG_UNKNOWN)); if (force_dir) path.is_dir = 1; @@ -133,7 +133,7 @@ void test_attr_lookup__match_variants(void) cl_assert_equal_s(cl_fixture("attr/attr1"), file->entry->path); cl_assert(file->rules.length == 10); - cl_git_pass(git_attr_path__init(&path, NULL, "/testing/for/pat0", NULL, GIT_DIR_FLAG_UNKNOWN)); + cl_git_pass(git_attr_path__init(&path, "/testing/for/pat0", NULL, GIT_DIR_FLAG_UNKNOWN)); cl_assert_equal_s("pat0", path.basename); run_test_cases(file, cases, 0); From 0bd132ab829f41971355537ecc4f9d24f953ccec Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 26 Sep 2021 17:58:08 -0400 Subject: [PATCH 0563/1616] oidarray: introduce `git_oidarray_dispose` Since users are disposing the _contents_ of the oidarray, not freeing the oidarray itself, the proper cleanup function is `git_oidarray_dispose`. Deprecate `git_oidarray_free`. --- include/git2/deprecated.h | 24 +++++++++++++ include/git2/oidarray.h | 13 +++---- src/merge.c | 2 +- src/oidarray.c | 11 +++++- tests/revwalk/mergebase.c | 74 +++++++++++++++++++-------------------- 5 files changed, 77 insertions(+), 47 deletions(-) diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index 6b268eb791f..37b9fa0e2f1 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -779,6 +779,30 @@ GIT_EXTERN(int) git_oid_iszero(const git_oid *id); /**@}*/ +/** @name Deprecated OID Array Functions + * + * These types are retained for backward compatibility. The newer + * versions of these values should be preferred in all new code. + * + * There is no plan to remove these backward compatibility values at + * this time. + */ +/**@{*/ + +/** + * Free the memory referred to by the git_oidarray. This is an alias of + * `git_oidarray_dispose` and is preserved for backward compatibility. + * + * This function is deprecated, but there is no plan to remove this + * function at this time. + * + * @deprecated Use git_oidarray_dispose + * @see git_oidarray_dispose + */ +GIT_EXTERN(void) git_oidarray_free(git_oidarray *array); + +/**@}*/ + /** @name Deprecated Transfer Progress Types * * These types are retained for backward compatibility. The newer diff --git a/include/git2/oidarray.h b/include/git2/oidarray.h index 0b320459787..94fc58daba4 100644 --- a/include/git2/oidarray.h +++ b/include/git2/oidarray.h @@ -19,19 +19,16 @@ typedef struct git_oidarray { } git_oidarray; /** - * Free the OID array - * - * This method must (and must only) be called on `git_oidarray` - * objects where the array is allocated by the library. Not doing so, - * will result in a memory leak. + * Free the object IDs contained in an oid_array. This method should + * be called on `git_oidarray` objects that were provided by the + * library. Not doing so will result in a memory leak. * * This does not free the `git_oidarray` itself, since the library will - * never allocate that object directly itself (it is more commonly embedded - * inside another struct or created on the stack). + * never allocate that object directly itself. * * @param array git_oidarray from which to free oid data */ -GIT_EXTERN(void) git_oidarray_free(git_oidarray *array); +GIT_EXTERN(void) git_oidarray_dispose(git_oidarray *array); /** @} */ GIT_END_DECL diff --git a/src/merge.c b/src/merge.c index 1c841bdfbf2..d838e4ba92c 100644 --- a/src/merge.c +++ b/src/merge.c @@ -2369,7 +2369,7 @@ static int compute_base( git_annotated_commit_free(other); git_annotated_commit_free(new_base); - git_oidarray_free(&bases); + git_oidarray_dispose(&bases); git_array_clear(head_ids); return error; } diff --git a/src/oidarray.c b/src/oidarray.c index e70e9dd6185..583017c4ee2 100644 --- a/src/oidarray.c +++ b/src/oidarray.c @@ -10,7 +10,7 @@ #include "git2/oidarray.h" #include "array.h" -void git_oidarray_free(git_oidarray *arr) +void git_oidarray_dispose(git_oidarray *arr) { git__free(arr->ids); } @@ -32,3 +32,12 @@ void git_oidarray__reverse(git_oidarray *arr) git_oid_cpy(&arr->ids[(arr->count-1)-i], &tmp); } } + +#ifndef GIT_DEPRECATE_HARD + +void git_oidarray_free(git_oidarray *arr) +{ + git_oidarray_dispose(arr); +} + +#endif diff --git a/tests/revwalk/mergebase.c b/tests/revwalk/mergebase.c index bee0b926e08..0378c869b71 100644 --- a/tests/revwalk/mergebase.c +++ b/tests/revwalk/mergebase.c @@ -150,7 +150,7 @@ void test_revwalk_mergebase__multiple_merge_bases(void) cl_assert_equal_oid(&expected1, &result.ids[0]); cl_assert_equal_oid(&expected2, &result.ids[1]); - git_oidarray_free(&result); + git_oidarray_dispose(&result); } void test_revwalk_mergebase__multiple_merge_bases_many_commits(void) @@ -170,7 +170,7 @@ void test_revwalk_mergebase__multiple_merge_bases_many_commits(void) cl_assert_equal_oid(&expected1, &result.ids[0]); cl_assert_equal_oid(&expected2, &result.ids[1]); - git_oidarray_free(&result); + git_oidarray_dispose(&result); git__free(input); } @@ -186,7 +186,7 @@ void test_revwalk_mergebase__no_off_by_one_missing(void) static void assert_mergebase_many(const char *expected_sha, int count, ...) { va_list ap; - int i; + int i; git_oid *oids; git_oid oid, expected; char *partial_oid; @@ -376,9 +376,9 @@ void test_revwalk_mergebase__octopus_merge_branch(void) * * commit 8496071c1b46c854b31185ea97743be6a8774479 * Author: Scott Chacon * Date: Sat May 8 16:13:06 2010 -0700 - * + * * testing - * + * * * commit 41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 * | Author: Scott Chacon * | Date: Tue May 11 13:40:41 2010 -0700 @@ -388,7 +388,7 @@ void test_revwalk_mergebase__octopus_merge_branch(void) * * commit 5001298e0c09ad9c34e4249bc5801c75e9754fa5 * Author: Scott Chacon * Date: Tue May 11 13:40:23 2010 -0700 - * + * * packed commit one */ @@ -398,94 +398,94 @@ void test_revwalk_mergebase__octopus_merge_branch(void) * |\ Merge: c37a783 2224e19 * | | Author: Scott J. Goldman * | | Date: Tue Nov 27 20:31:04 2012 -0800 - * | | + * | | * | | Merge branch 'first-branch' into second-branch - * | | + * | | * | * commit 2224e191514cb4bd8c566d80dac22dfcb1e9bb83 * | | Author: Scott J. Goldman * | | Date: Tue Nov 27 20:28:51 2012 -0800 - * | | + * | | * | | j - * | | + * | | * | * commit a41a49f8f5cd9b6cb14a076bf8394881ed0b4d19 * | | Author: Scott J. Goldman * | | Date: Tue Nov 27 20:28:39 2012 -0800 - * | | + * | | * | | i - * | | + * | | * | * commit 82bf9a1a10a4b25c1f14c9607b60970705e92545 * | | Author: Scott J. Goldman * | | Date: Tue Nov 27 20:28:28 2012 -0800 - * | | + * | | * | | h - * | | + * | | * * | commit c37a783c20d92ac92362a78a32860f7eebf938ef * | | Author: Scott J. Goldman * | | Date: Tue Nov 27 20:30:57 2012 -0800 - * | | + * | | * | | n - * | | + * | | * * | commit 8b82fb1794cb1c8c7f172ec730a4c2db0ae3e650 * | | Author: Scott J. Goldman * | | Date: Tue Nov 27 20:30:43 2012 -0800 - * | | + * | | * | | m - * | | + * | | * * | commit 6ab5d28acbf3c3bdff276f7ccfdf29c1520e542f * | | Author: Scott J. Goldman * | | Date: Tue Nov 27 20:30:38 2012 -0800 - * | | + * | | * | | l - * | | + * | | * * | commit 7b8c336c45fc6895c1c60827260fe5d798e5d247 * | | Author: Scott J. Goldman * | | Date: Tue Nov 27 20:30:24 2012 -0800 - * | | + * | | * | | k - * | | + * | | * | | * commit 1c30b88f5f3ee66d78df6520a7de9e89b890818b * | | | Author: Scott J. Goldman * | | | Date: Tue Nov 27 20:28:10 2012 -0800 - * | | | + * | | | * | | | e - * | | | + * | | | * | | * commit 42b7311aa626e712891940c1ec5d5cba201946a4 * | | | Author: Scott J. Goldman * | | | Date: Tue Nov 27 20:28:06 2012 -0800 - * | | | + * | | | * | | | d - * | | | + * | | | * | | * commit a953a018c5b10b20c86e69fef55ebc8ad4c5a417 * | | |\ Merge: bd1732c cdf97fd * | | |/ Author: Scott J. Goldman * | |/| Date: Tue Nov 27 20:26:43 2012 -0800 - * | | | + * | | | * | | | Merge branch 'first-branch' - * | | | + * | | | * | * | commit cdf97fd3bb48eb3827638bb33d208f5fd32d0aa6 * | | | Author: Scott J. Goldman * | | | Date: Tue Nov 27 20:24:46 2012 -0800 - * | | | + * | | | * | | | g - * | | | + * | | | * | * | commit ef0488f0b722f0be8bcb90a7730ac7efafd1d694 * | | | Author: Scott J. Goldman * | | | Date: Tue Nov 27 20:24:39 2012 -0800 - * | | | + * | | | * | | | f - * | | | + * | | | * | | * commit bd1732c43c68d712ad09e1d872b9be6d4b9efdc4 * | |/ Author: Scott J. Goldman * | | Date: Tue Nov 27 17:43:58 2012 -0800 - * | | + * | | * | | c - * | | + * | | * | * commit 0c8a3f1f3d5f421cf83048c7c73ee3b55a5e0f29 * |/ Author: Scott J. Goldman * | Date: Tue Nov 27 17:43:48 2012 -0800 - * | + * | * | b - * | + * | * * commit 1f4c0311a24b63f6fc209a59a1e404942d4a5006 * Author: Scott J. Goldman * Date: Tue Nov 27 17:43:41 2012 -0800 @@ -509,6 +509,6 @@ void test_revwalk_mergebase__remove_redundant(void) cl_assert_equal_i(1, result.count); cl_assert_equal_oid(&base, &result.ids[0]); - git_oidarray_free(&result); + git_oidarray_dispose(&result); git_repository_free(repo); } From 7e7cfe8acdc8e506a5e670e7cfb74e43c031ccaf Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 26 Sep 2021 20:20:03 -0400 Subject: [PATCH 0564/1616] buf: common_prefix takes a string array `git_strarray` is a public-facing type. Change `git_buf_text_common_prefix` to not use it, and just take an array of strings instead. --- src/buffer.c | 13 +++++++------ src/buffer.h | 2 +- src/pathspec.c | 2 +- tests/core/buffer.c | 29 +++++++---------------------- 4 files changed, 16 insertions(+), 30 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index a57df128498..fe087ea1116 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1201,25 +1201,26 @@ int git_buf_lf_to_crlf(git_buf *tgt, const git_buf *src) return git_buf_put(tgt, scan, end - scan); } -int git_buf_common_prefix(git_buf *buf, const git_strarray *strings) +int git_buf_common_prefix(git_buf *buf, char *const *const strings, size_t count) { size_t i; const char *str, *pfx; git_buf_clear(buf); - if (!strings || !strings->count) + if (!strings || !count) return 0; /* initialize common prefix to first string */ - if (git_buf_sets(buf, strings->strings[0]) < 0) + if (git_buf_sets(buf, strings[0]) < 0) return -1; /* go through the rest of the strings, truncating to shared prefix */ - for (i = 1; i < strings->count; ++i) { + for (i = 1; i < count; ++i) { - for (str = strings->strings[i], pfx = buf->ptr; - *str && *str == *pfx; str++, pfx++) + for (str = strings[i], pfx = buf->ptr; + *str && *str == *pfx; + str++, pfx++) /* scanning */; git_buf_truncate(buf, pfx - buf->ptr); diff --git a/src/buffer.h b/src/buffer.h index a356bebeae5..75930e20944 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -324,7 +324,7 @@ extern int git_buf_lf_to_crlf(git_buf *tgt, const git_buf *src); * * Buffer will be set to empty if there is no common prefix */ -extern int git_buf_common_prefix(git_buf *buf, const git_strarray *strs); +extern int git_buf_common_prefix(git_buf *buf, char *const *const strings, size_t count); /** * Check if a buffer begins with a UTF BOM diff --git a/src/pathspec.c b/src/pathspec.c index 8f1bdf0fa6c..c6ad16571ec 100644 --- a/src/pathspec.c +++ b/src/pathspec.c @@ -24,7 +24,7 @@ char *git_pathspec_prefix(const git_strarray *pathspec) const char *scan; if (!pathspec || !pathspec->count || - git_buf_common_prefix(&prefix, pathspec) < 0) + git_buf_common_prefix(&prefix, pathspec->strings, pathspec->count) < 0) return NULL; /* diff prefix will only be leading non-wildcards */ diff --git a/tests/core/buffer.c b/tests/core/buffer.c index 22fa75e39ed..2af4a87126b 100644 --- a/tests/core/buffer.c +++ b/tests/core/buffer.c @@ -632,7 +632,6 @@ void test_core_buffer__join3(void) void test_core_buffer__11(void) { git_buf a = GIT_BUF_INIT; - git_strarray t; char *t1[] = { "nothing", "in", "common" }; char *t2[] = { "something", "something else", "some other" }; char *t3[] = { "something", "some fun", "no fun" }; @@ -641,39 +640,25 @@ void test_core_buffer__11(void) char *t6[] = { "no", "nope", "" }; char *t7[] = { "", "doesn't matter" }; - t.strings = t1; - t.count = 3; - cl_git_pass(git_buf_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, t1, 3)); cl_assert_equal_s(a.ptr, ""); - t.strings = t2; - t.count = 3; - cl_git_pass(git_buf_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, t2, 3)); cl_assert_equal_s(a.ptr, "some"); - t.strings = t3; - t.count = 3; - cl_git_pass(git_buf_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, t3, 3)); cl_assert_equal_s(a.ptr, ""); - t.strings = t4; - t.count = 3; - cl_git_pass(git_buf_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, t4, 3)); cl_assert_equal_s(a.ptr, "happ"); - t.strings = t5; - t.count = 3; - cl_git_pass(git_buf_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, t5, 3)); cl_assert_equal_s(a.ptr, "happ"); - t.strings = t6; - t.count = 3; - cl_git_pass(git_buf_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, t6, 3)); cl_assert_equal_s(a.ptr, ""); - t.strings = t7; - t.count = 3; - cl_git_pass(git_buf_common_prefix(&a, &t)); + cl_git_pass(git_buf_common_prefix(&a, t7, 3)); cl_assert_equal_s(a.ptr, ""); git_buf_dispose(&a); From 13f1270a7a8f99bfd5abdf5e374b7fc9634e18ae Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 27 Sep 2021 08:58:28 -0400 Subject: [PATCH 0565/1616] v1.3: changelog updates for last-minute changes --- docs/changelog.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 5625be3148c..ba7ad695831 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,9 @@ This is release v1.3.0, "Zugunruhe". This release includes only minor new featu * Support custom git extensions by @ethomson in https://github.com/libgit2/libgit2/pull/6031 * Introduce `git_email_create`; deprecate `git_diff_format_email` by @ethomson in https://github.com/libgit2/libgit2/pull/6061 +## Deprecated APIs +* `git_oidarray_free` is deprecated; callers should use `git_oidarray_dispose` + ## Bug fixes * #6028: Check if `threadstate->error_t.message` is not `git_buf__initbuf` before freeing. by @arroz in https://github.com/libgit2/libgit2/pull/6029 * remote: Mark `git_remote_name_is_valid` as `GIT_EXTERN` by @lhchavez in https://github.com/libgit2/libgit2/pull/6032 @@ -17,6 +20,9 @@ This is release v1.3.0, "Zugunruhe". This release includes only minor new featu * win32: allow empty environment variables by @ethomson in https://github.com/libgit2/libgit2/pull/6063 * Fixes for deprecated APIs by @ethomson in https://github.com/libgit2/libgit2/pull/6066 * filter: use a `git_oid` in filter options, not a pointer by @ethomson in https://github.com/libgit2/libgit2/pull/6067 +* diff: update `GIT_DIFF_IGNORE_BLANK_LINES` by @ethomson in https://github.com/libgit2/libgit2/pull/6068 +* Attribute lookups are always on relative paths by @ethomson in https://github.com/libgit2/libgit2/pull/6073 +* Handle long paths when querying attributes by @ethomson in https://github.com/libgit2/libgit2/pull/6075 ## Code cleanups * notes: use a buffer internally by @ethomson in https://github.com/libgit2/libgit2/pull/6047 @@ -26,7 +32,8 @@ This is release v1.3.0, "Zugunruhe". This release includes only minor new featu * Longpath filter bug by @lrm29 in https://github.com/libgit2/libgit2/pull/6055 * Add test to ensure empty proxy env behaves like unset env by @sathieu in https://github.com/libgit2/libgit2/pull/6052 * Stdint header condition has been reverted. by @lolgear in https://github.com/libgit2/libgit2/pull/6020 -* diff: update `GIT_DIFF_IGNORE_BLANK_LINES` by @ethomson in https://github.com/libgit2/libgit2/pull/6068 +* buf: `common_prefix` takes a string array by @ethomson in https://github.com/libgit2/libgit2/pull/6077 +* oidarray: introduce `git_oidarray_dispose` by @ethomson in https://github.com/libgit2/libgit2/pull/6076 ## CI Improvements * ci: pull libssh2 from www.libssh2.org by @ethomson in https://github.com/libgit2/libgit2/pull/6064 From b7bad55e4bb0a285b073ba5e02b01d3f522fc95d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 27 Sep 2021 16:09:50 -0400 Subject: [PATCH 0566/1616] v1.3: very very last-minute changelog updates --- docs/changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index ba7ad695831..8060874df0e 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -34,6 +34,7 @@ This is release v1.3.0, "Zugunruhe". This release includes only minor new featu * Stdint header condition has been reverted. by @lolgear in https://github.com/libgit2/libgit2/pull/6020 * buf: `common_prefix` takes a string array by @ethomson in https://github.com/libgit2/libgit2/pull/6077 * oidarray: introduce `git_oidarray_dispose` by @ethomson in https://github.com/libgit2/libgit2/pull/6076 +* examples: Free the git_config and git_config_entry after use by @257 in https://github.com/libgit2/libgit2/pull/6071 ## CI Improvements * ci: pull libssh2 from www.libssh2.org by @ethomson in https://github.com/libgit2/libgit2/pull/6064 @@ -48,6 +49,7 @@ This is release v1.3.0, "Zugunruhe". This release includes only minor new featu * @shijinglu made their first contribution in https://github.com/libgit2/libgit2/pull/6050 * @ccstolley made their first contribution in https://github.com/libgit2/libgit2/pull/6060 * @sathieu made their first contribution in https://github.com/libgit2/libgit2/pull/6052 +* @257 made their first contribution in https://github.com/libgit2/libgit2/pull/6071 **Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.2.0...v1.3.0 From 3fff59705fec852b97639364ca7b3e84ff7040b7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 29 Sep 2021 21:02:38 -0400 Subject: [PATCH 0567/1616] hash: don't abbreviate algorithm --- src/hash.c | 18 +++++++++--------- src/hash.h | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/hash.c b/src/hash.c index 5a7278e4225..d56c7722130 100644 --- a/src/hash.c +++ b/src/hash.c @@ -19,15 +19,15 @@ int git_hash_ctx_init(git_hash_ctx *ctx) if ((error = git_hash_sha1_ctx_init(&ctx->ctx.sha1)) < 0) return error; - ctx->algo = GIT_HASH_ALGO_SHA1; + ctx->algorithm = GIT_HASH_ALGORITHM_SHA1; return 0; } void git_hash_ctx_cleanup(git_hash_ctx *ctx) { - switch (ctx->algo) { - case GIT_HASH_ALGO_SHA1: + switch (ctx->algorithm) { + case GIT_HASH_ALGORITHM_SHA1: git_hash_sha1_ctx_cleanup(&ctx->ctx.sha1); return; default: @@ -37,8 +37,8 @@ void git_hash_ctx_cleanup(git_hash_ctx *ctx) int git_hash_init(git_hash_ctx *ctx) { - switch (ctx->algo) { - case GIT_HASH_ALGO_SHA1: + switch (ctx->algorithm) { + case GIT_HASH_ALGORITHM_SHA1: return git_hash_sha1_init(&ctx->ctx.sha1); default: /* unreachable */ ; @@ -49,8 +49,8 @@ int git_hash_init(git_hash_ctx *ctx) int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) { - switch (ctx->algo) { - case GIT_HASH_ALGO_SHA1: + switch (ctx->algorithm) { + case GIT_HASH_ALGORITHM_SHA1: return git_hash_sha1_update(&ctx->ctx.sha1, data, len); default: /* unreachable */ ; @@ -61,8 +61,8 @@ int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) int git_hash_final(git_oid *out, git_hash_ctx *ctx) { - switch (ctx->algo) { - case GIT_HASH_ALGO_SHA1: + switch (ctx->algorithm) { + case GIT_HASH_ALGORITHM_SHA1: return git_hash_sha1_final(out, &ctx->ctx.sha1); default: /* unreachable */ ; diff --git a/src/hash.h b/src/hash.h index 87305cc7920..31a31b325c8 100644 --- a/src/hash.h +++ b/src/hash.h @@ -18,9 +18,9 @@ typedef struct { } git_buf_vec; typedef enum { - GIT_HASH_ALGO_UNKNOWN = 0, - GIT_HASH_ALGO_SHA1, -} git_hash_algo_t; + GIT_HASH_ALGORITHM_NONE = 0, + GIT_HASH_ALGORITHM_SHA1 +} git_hash_algorithm_t; #include "hash/sha1.h" @@ -28,7 +28,7 @@ typedef struct git_hash_ctx { union { git_hash_sha1_ctx sha1; } ctx; - git_hash_algo_t algo; + git_hash_algorithm_t algorithm; } git_hash_ctx; int git_hash_global_init(void); From 2a713da1ec2e9f74c9edc75b06540ab095c68c34 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 29 Sep 2021 21:31:17 -0400 Subject: [PATCH 0568/1616] hash: accept the algorithm in inputs --- src/commit_graph.c | 4 +-- src/config_file.c | 4 +-- src/diff.c | 2 +- src/filebuf.c | 2 +- src/futils.c | 2 +- src/hash.c | 76 ++++++++++++++++++++++++---------------- src/hash.h | 6 ++-- src/index.c | 2 +- src/indexer.c | 4 +-- src/midx.c | 4 +-- src/odb.c | 6 ++-- src/odb_loose.c | 2 +- src/pack-objects.c | 2 +- tests/core/sha1.c | 2 +- tests/object/raw/hash.c | 6 ++-- tests/object/raw/short.c | 2 +- tests/odb/largefiles.c | 2 +- tests/pack/packbuilder.c | 2 +- 18 files changed, 73 insertions(+), 57 deletions(-) diff --git a/src/commit_graph.c b/src/commit_graph.c index f663fc5d3be..8bb2397d735 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -230,7 +230,7 @@ int git_commit_graph_file_parse( return commit_graph_error("wrong commit-graph size"); git_oid_cpy(&file->checksum, (git_oid *)(data + trailer_offset)); - if (git_hash_buf(&cgraph_checksum, data, (size_t)trailer_offset) < 0) + if (git_hash_buf(&cgraph_checksum, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) return commit_graph_error("could not calculate signature"); if (!git_oid_equal(&cgraph_checksum, &file->checksum)) return commit_graph_error("index signature mismatch"); @@ -986,7 +986,7 @@ static int commit_graph_write( hash_cb_data.cb_data = cb_data; hash_cb_data.ctx = &ctx; - error = git_hash_ctx_init(&ctx); + error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1); if (error < 0) return error; cb_data = &hash_cb_data; diff --git a/src/config_file.c b/src/config_file.c index 3588e6be6c4..e1adb2cbc1e 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -144,7 +144,7 @@ static int config_file_is_modified(int *modified, config_file *file) if ((error = git_futils_readbuffer(&buf, file->path)) < 0) goto out; - if ((error = git_hash_buf(&hash, buf.ptr, buf.size)) < 0) + if ((error = git_hash_buf(&hash, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) goto out; if (!git_oid_equal(&hash, &file->checksum)) { @@ -869,7 +869,7 @@ static int config_file_read( goto out; git_futils_filestamp_set_from_stat(&file->stamp, &st); - if ((error = git_hash_buf(&file->checksum, contents.ptr, contents.size)) < 0) + if ((error = git_hash_buf(&file->checksum, contents.ptr, contents.size, GIT_HASH_ALGORITHM_SHA1)) < 0) goto out; if ((error = config_file_read_buffer(entries, repo, file, level, depth, diff --git a/src/diff.c b/src/diff.c index 30b9f647a45..4434d37d4b0 100644 --- a/src/diff.c +++ b/src/diff.c @@ -352,7 +352,7 @@ int git_diff_patchid(git_oid *out, git_diff *diff, git_diff_patchid_options *opt memset(&args, 0, sizeof(args)); args.first_file = 1; - if ((error = git_hash_ctx_init(&args.ctx)) < 0) + if ((error = git_hash_ctx_init(&args.ctx, GIT_HASH_ALGORITHM_SHA1)) < 0) goto out; if ((error = git_diff_print(diff, diff --git a/src/filebuf.c b/src/filebuf.c index a3f6b14839a..40cd9a44514 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -305,7 +305,7 @@ int git_filebuf_open_withsize(git_filebuf *file, const char *path, int flags, mo if (flags & GIT_FILEBUF_HASH_CONTENTS) { file->compute_digest = 1; - if (git_hash_ctx_init(&file->digest) < 0) + if (git_hash_ctx_init(&file->digest, GIT_HASH_ALGORITHM_SHA1) < 0) goto cleanup; } diff --git a/src/futils.c b/src/futils.c index a44820875b1..5d120eaed52 100644 --- a/src/futils.c +++ b/src/futils.c @@ -216,7 +216,7 @@ int git_futils_readbuffer_updated( p_close(fd); if (checksum) { - if ((error = git_hash_buf(&checksum_new, buf.ptr, buf.size)) < 0) { + if ((error = git_hash_buf(&checksum_new, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) { git_buf_dispose(&buf); return error; } diff --git a/src/hash.c b/src/hash.c index d56c7722130..2f11a88e8d0 100644 --- a/src/hash.c +++ b/src/hash.c @@ -12,71 +12,83 @@ int git_hash_global_init(void) return git_hash_sha1_global_init(); } -int git_hash_ctx_init(git_hash_ctx *ctx) +int git_hash_ctx_init(git_hash_ctx *ctx, git_hash_algorithm_t algorithm) { int error; - if ((error = git_hash_sha1_ctx_init(&ctx->ctx.sha1)) < 0) - return error; - - ctx->algorithm = GIT_HASH_ALGORITHM_SHA1; + switch (algorithm) { + case GIT_HASH_ALGORITHM_SHA1: + error = git_hash_sha1_ctx_init(&ctx->ctx.sha1); + break; + default: + git_error_set(GIT_ERROR_INTERNAL, "unknown hash algorithm"); + error = -1; + } - return 0; + ctx->algorithm = algorithm; + return error; } void git_hash_ctx_cleanup(git_hash_ctx *ctx) { switch (ctx->algorithm) { - case GIT_HASH_ALGORITHM_SHA1: - git_hash_sha1_ctx_cleanup(&ctx->ctx.sha1); - return; - default: - /* unreachable */ ; + case GIT_HASH_ALGORITHM_SHA1: + git_hash_sha1_ctx_cleanup(&ctx->ctx.sha1); + return; + default: + /* unreachable */ ; } } int git_hash_init(git_hash_ctx *ctx) { switch (ctx->algorithm) { - case GIT_HASH_ALGORITHM_SHA1: - return git_hash_sha1_init(&ctx->ctx.sha1); - default: - /* unreachable */ ; + case GIT_HASH_ALGORITHM_SHA1: + return git_hash_sha1_init(&ctx->ctx.sha1); + default: + /* unreachable */ ; } - GIT_ASSERT(0); + + git_error_set(GIT_ERROR_INTERNAL, "unknown hash algorithm"); return -1; } int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) { switch (ctx->algorithm) { - case GIT_HASH_ALGORITHM_SHA1: - return git_hash_sha1_update(&ctx->ctx.sha1, data, len); - default: - /* unreachable */ ; + case GIT_HASH_ALGORITHM_SHA1: + return git_hash_sha1_update(&ctx->ctx.sha1, data, len); + default: + /* unreachable */ ; } - GIT_ASSERT(0); + + git_error_set(GIT_ERROR_INTERNAL, "unknown hash algorithm"); return -1; } int git_hash_final(git_oid *out, git_hash_ctx *ctx) { switch (ctx->algorithm) { - case GIT_HASH_ALGORITHM_SHA1: - return git_hash_sha1_final(out, &ctx->ctx.sha1); - default: - /* unreachable */ ; + case GIT_HASH_ALGORITHM_SHA1: + return git_hash_sha1_final(out, &ctx->ctx.sha1); + default: + /* unreachable */ ; } - GIT_ASSERT(0); + + git_error_set(GIT_ERROR_INTERNAL, "unknown hash algorithm"); return -1; } -int git_hash_buf(git_oid *out, const void *data, size_t len) +int git_hash_buf( + git_oid *out, + const void *data, + size_t len, + git_hash_algorithm_t algorithm) { git_hash_ctx ctx; int error = 0; - if (git_hash_ctx_init(&ctx) < 0) + if (git_hash_ctx_init(&ctx, algorithm) < 0) return -1; if ((error = git_hash_update(&ctx, data, len)) >= 0) @@ -87,13 +99,17 @@ int git_hash_buf(git_oid *out, const void *data, size_t len) return error; } -int git_hash_vec(git_oid *out, git_buf_vec *vec, size_t n) +int git_hash_vec( + git_oid *out, + git_buf_vec *vec, + size_t n, + git_hash_algorithm_t algorithm) { git_hash_ctx ctx; size_t i; int error = 0; - if (git_hash_ctx_init(&ctx) < 0) + if (git_hash_ctx_init(&ctx, algorithm) < 0) return -1; for (i = 0; i < n; i++) { diff --git a/src/hash.h b/src/hash.h index 31a31b325c8..7938e3b220e 100644 --- a/src/hash.h +++ b/src/hash.h @@ -33,14 +33,14 @@ typedef struct git_hash_ctx { int git_hash_global_init(void); -int git_hash_ctx_init(git_hash_ctx *ctx); +int git_hash_ctx_init(git_hash_ctx *ctx, git_hash_algorithm_t algorithm); void git_hash_ctx_cleanup(git_hash_ctx *ctx); int git_hash_init(git_hash_ctx *c); int git_hash_update(git_hash_ctx *c, const void *data, size_t len); int git_hash_final(git_oid *out, git_hash_ctx *c); -int git_hash_buf(git_oid *out, const void *data, size_t len); -int git_hash_vec(git_oid *out, git_buf_vec *vec, size_t n); +int git_hash_buf(git_oid *out, const void *data, size_t len, git_hash_algorithm_t algorithm); +int git_hash_vec(git_oid *out, git_buf_vec *vec, size_t n, git_hash_algorithm_t algorithm); #endif diff --git a/src/index.c b/src/index.c index 5c330517008..838f43c2df0 100644 --- a/src/index.c +++ b/src/index.c @@ -2648,7 +2648,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) /* Precalculate the SHA1 of the files's contents -- we'll match it to * the provided SHA1 in the footer */ - git_hash_buf(&checksum_calculated, buffer, buffer_size - INDEX_FOOTER_SIZE); + git_hash_buf(&checksum_calculated, buffer, buffer_size - INDEX_FOOTER_SIZE, GIT_HASH_ALGORITHM_SHA1); /* Parse header */ if ((error = read_header(&header, buffer)) < 0) diff --git a/src/indexer.c b/src/indexer.c index ce77375007c..c3b1aee32a4 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -152,8 +152,8 @@ int git_indexer_new( idx->mode = mode ? mode : GIT_PACK_FILE_MODE; git_buf_init(&idx->entry_data, 0); - if ((error = git_hash_ctx_init(&idx->hash_ctx)) < 0 || - (error = git_hash_ctx_init(&idx->trailer)) < 0 || + if ((error = git_hash_ctx_init(&idx->hash_ctx, GIT_HASH_ALGORITHM_SHA1)) < 0 || + (error = git_hash_ctx_init(&idx->trailer, GIT_HASH_ALGORITHM_SHA1)) < 0 || (error = git_oidmap_new(&idx->expected_oids)) < 0) goto cleanup; diff --git a/src/midx.c b/src/midx.c index 6a885eddca5..7ef85248cd1 100644 --- a/src/midx.c +++ b/src/midx.c @@ -212,7 +212,7 @@ int git_midx_parse( return midx_error("wrong index size"); git_oid_cpy(&idx->checksum, (git_oid *)(data + trailer_offset)); - if (git_hash_buf(&idx_checksum, data, (size_t)trailer_offset) < 0) + if (git_hash_buf(&idx_checksum, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) return midx_error("could not calculate signature"); if (!git_oid_equal(&idx_checksum, &idx->checksum)) return midx_error("index signature mismatch"); @@ -668,7 +668,7 @@ static int midx_write( hash_cb_data.cb_data = cb_data; hash_cb_data.ctx = &ctx; - error = git_hash_ctx_init(&ctx); + error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1); if (error < 0) return error; cb_data = &hash_cb_data; diff --git a/src/odb.c b/src/odb.c index 7834e5f15cf..c2478083465 100644 --- a/src/odb.c +++ b/src/odb.c @@ -136,7 +136,7 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj) vec[1].data = obj->data; vec[1].len = obj->len; - return git_hash_vec(id, vec, 2); + return git_hash_vec(id, vec, 2, GIT_HASH_ALGORITHM_SHA1); } @@ -210,7 +210,7 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_object_t type) return -1; } - if ((error = git_hash_ctx_init(&ctx)) < 0) + if ((error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1)) < 0) return error; if ((error = git_odb__format_object_header(&hdr_len, hdr, @@ -1561,7 +1561,7 @@ int git_odb_open_wstream( ctx = git__malloc(sizeof(git_hash_ctx)); GIT_ERROR_CHECK_ALLOC(ctx); - if ((error = git_hash_ctx_init(ctx)) < 0 || + if ((error = git_hash_ctx_init(ctx, GIT_HASH_ALGORITHM_SHA1)) < 0 || (error = hash_header(ctx, size, type)) < 0) goto done; diff --git a/src/odb_loose.c b/src/odb_loose.c index b0abbbf4c27..1f8a0bb21b9 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -1023,7 +1023,7 @@ static int loose_backend__readstream( hash_ctx = git__malloc(sizeof(git_hash_ctx)); GIT_ERROR_CHECK_ALLOC(hash_ctx); - if ((error = git_hash_ctx_init(hash_ctx)) < 0 || + if ((error = git_hash_ctx_init(hash_ctx, GIT_HASH_ALGORITHM_SHA1)) < 0 || (error = git_futils_mmap_ro_file(&stream->map, object_path.ptr)) < 0 || (error = git_zstream_init(&stream->zstream, GIT_ZSTREAM_INFLATE)) < 0) goto done; diff --git a/src/pack-objects.c b/src/pack-objects.c index faff310b40b..560f57d03b4 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -141,7 +141,7 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo) pb->repo = repo; pb->nr_threads = 1; /* do not spawn any thread by default */ - if (git_hash_ctx_init(&pb->ctx) < 0 || + if (git_hash_ctx_init(&pb->ctx, GIT_HASH_ALGORITHM_SHA1) < 0 || git_zstream_init(&pb->zstream, GIT_ZSTREAM_DEFLATE) < 0 || git_repository_odb(&pb->odb, repo) < 0 || packbuilder_config(pb) < 0) diff --git a/tests/core/sha1.c b/tests/core/sha1.c index 196b003525f..aa351935b82 100644 --- a/tests/core/sha1.c +++ b/tests/core/sha1.c @@ -23,7 +23,7 @@ static int sha1_file(git_oid *oid, const char *filename) fd = p_open(filename, O_RDONLY); cl_assert(fd >= 0); - cl_git_pass(git_hash_ctx_init(&ctx)); + cl_git_pass(git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1)); while ((read_len = p_read(fd, buf, 2048)) > 0) cl_git_pass(git_hash_update(&ctx, buf, (size_t)read_len)); diff --git a/tests/object/raw/hash.c b/tests/object/raw/hash.c index 830f1caa190..e9a647627fe 100644 --- a/tests/object/raw/hash.c +++ b/tests/object/raw/hash.c @@ -26,7 +26,7 @@ void test_object_raw_hash__hash_by_blocks(void) git_hash_ctx ctx; git_oid id1, id2; - cl_git_pass(git_hash_ctx_init(&ctx)); + cl_git_pass(git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1)); /* should already be init'd */ cl_git_pass(git_hash_update(&ctx, hello_text, strlen(hello_text))); @@ -49,7 +49,7 @@ void test_object_raw_hash__hash_buffer_in_single_call(void) git_oid id1, id2; cl_git_pass(git_oid_fromstr(&id1, hello_id)); - git_hash_buf(&id2, hello_text, strlen(hello_text)); + git_hash_buf(&id2, hello_text, strlen(hello_text), GIT_HASH_ALGORITHM_SHA1); cl_assert(git_oid_cmp(&id1, &id2) == 0); } @@ -65,7 +65,7 @@ void test_object_raw_hash__hash_vector(void) vec[1].data = hello_text+4; vec[1].len = strlen(hello_text)-4; - git_hash_vec(&id2, vec, 2); + git_hash_vec(&id2, vec, 2, GIT_HASH_ALGORITHM_SHA1); cl_assert(git_oid_cmp(&id1, &id2) == 0); } diff --git a/tests/object/raw/short.c b/tests/object/raw/short.c index 813cd86b6f2..626c9654be3 100644 --- a/tests/object/raw/short.c +++ b/tests/object/raw/short.c @@ -33,7 +33,7 @@ static int insert_sequential_oids( for (i = 0; i < n; ++i) { p_snprintf(numbuf, sizeof(numbuf), "%u", (unsigned int)i); - git_hash_buf(&oid, numbuf, strlen(numbuf)); + git_hash_buf(&oid, numbuf, strlen(numbuf), GIT_HASH_ALGORITHM_SHA1); oids[i] = git__malloc(GIT_OID_HEXSZ + 1); cl_assert(oids[i]); diff --git a/tests/odb/largefiles.c b/tests/odb/largefiles.c index 8be2cfd02d6..03b183cd582 100644 --- a/tests/odb/largefiles.c +++ b/tests/odb/largefiles.c @@ -107,7 +107,7 @@ void test_odb_largefiles__streamread(void) cl_assert_equal_sz(LARGEFILE_SIZE, len); cl_assert_equal_i(GIT_OBJECT_BLOB, type); - cl_git_pass(git_hash_ctx_init(&hash)); + cl_git_pass(git_hash_ctx_init(&hash, GIT_HASH_ALGORITHM_SHA1)); cl_git_pass(git_odb__format_object_header(&hdr_len, hdr, sizeof(hdr), len, type)); cl_git_pass(git_hash_update(&hash, hdr, hdr_len)); diff --git a/tests/pack/packbuilder.c b/tests/pack/packbuilder.c index 5f5441a5ded..42d446a8b37 100644 --- a/tests/pack/packbuilder.c +++ b/tests/pack/packbuilder.c @@ -126,7 +126,7 @@ void test_pack_packbuilder__create_pack(void) cl_git_pass(git_futils_readbuffer(&buf, git_buf_cstr(&path))); - cl_git_pass(git_hash_ctx_init(&ctx)); + cl_git_pass(git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1)); cl_git_pass(git_hash_update(&ctx, buf.ptr, buf.size)); cl_git_pass(git_hash_final(&hash, &ctx)); git_hash_ctx_cleanup(&ctx); From 31ecaca2d3e87d20782a54cb319f5c19e6c6e62f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 30 Sep 2021 08:11:40 -0400 Subject: [PATCH 0569/1616] hash: hash functions operate on byte arrays not git_oids Separate the concerns of the hash functions from the git_oid functions. The git_oid structure will need to understand either SHA1 or SHA256; the hash functions should only deal with the appropriate one of these. --- src/commit_graph.c | 4 ++-- src/config_file.c | 4 ++-- src/diff.c | 2 +- src/filebuf.c | 2 +- src/futils.c | 2 +- src/hash.c | 6 +++--- src/hash.h | 9 ++++----- src/hash/sha1.h | 4 +++- src/hash/sha1/collisiondetect.c | 4 ++-- src/hash/sha1/common_crypto.c | 4 ++-- src/hash/sha1/generic.c | 4 ++-- src/hash/sha1/mbedtls.c | 4 ++-- src/hash/sha1/openssl.c | 4 ++-- src/hash/sha1/win32.c | 12 ++++++------ src/index.c | 2 +- src/indexer.c | 6 +++--- src/midx.c | 4 ++-- src/odb.c | 6 +++--- src/pack-objects.c | 2 +- tests/core/sha1.c | 4 ++-- tests/object/raw/hash.c | 8 ++++---- tests/object/raw/short.c | 2 +- tests/odb/largefiles.c | 2 +- tests/pack/packbuilder.c | 2 +- 24 files changed, 52 insertions(+), 51 deletions(-) diff --git a/src/commit_graph.c b/src/commit_graph.c index 8bb2397d735..df760b5f8ca 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -230,7 +230,7 @@ int git_commit_graph_file_parse( return commit_graph_error("wrong commit-graph size"); git_oid_cpy(&file->checksum, (git_oid *)(data + trailer_offset)); - if (git_hash_buf(&cgraph_checksum, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) + if (git_hash_buf(cgraph_checksum.id, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) return commit_graph_error("could not calculate signature"); if (!git_oid_equal(&cgraph_checksum, &file->checksum)) return commit_graph_error("index signature mismatch"); @@ -1132,7 +1132,7 @@ static int commit_graph_write( goto cleanup; /* Finalize the checksum and write the trailer. */ - error = git_hash_final(&cgraph_checksum, &ctx); + error = git_hash_final(cgraph_checksum.id, &ctx); if (error < 0) goto cleanup; error = write_cb((const char *)&cgraph_checksum, sizeof(cgraph_checksum), cb_data); diff --git a/src/config_file.c b/src/config_file.c index e1adb2cbc1e..2f83a407071 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -144,7 +144,7 @@ static int config_file_is_modified(int *modified, config_file *file) if ((error = git_futils_readbuffer(&buf, file->path)) < 0) goto out; - if ((error = git_hash_buf(&hash, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) + if ((error = git_hash_buf(hash.id, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) goto out; if (!git_oid_equal(&hash, &file->checksum)) { @@ -869,7 +869,7 @@ static int config_file_read( goto out; git_futils_filestamp_set_from_stat(&file->stamp, &st); - if ((error = git_hash_buf(&file->checksum, contents.ptr, contents.size, GIT_HASH_ALGORITHM_SHA1)) < 0) + if ((error = git_hash_buf(file->checksum.id, contents.ptr, contents.size, GIT_HASH_ALGORITHM_SHA1)) < 0) goto out; if ((error = config_file_read_buffer(entries, repo, file, level, depth, diff --git a/src/diff.c b/src/diff.c index 4434d37d4b0..44b67ee0622 100644 --- a/src/diff.c +++ b/src/diff.c @@ -269,7 +269,7 @@ static int flush_hunk(git_oid *result, git_hash_ctx *ctx) unsigned short carry = 0; int error, i; - if ((error = git_hash_final(&hash, ctx)) < 0 || + if ((error = git_hash_final(hash.id, ctx)) < 0 || (error = git_hash_init(ctx)) < 0) return error; diff --git a/src/filebuf.c b/src/filebuf.c index 40cd9a44514..4296b2226d3 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -397,7 +397,7 @@ int git_filebuf_hash(git_oid *oid, git_filebuf *file) if (verify_last_error(file) < 0) return -1; - git_hash_final(oid, &file->digest); + git_hash_final(oid->id, &file->digest); git_hash_ctx_cleanup(&file->digest); file->compute_digest = 0; diff --git a/src/futils.c b/src/futils.c index 5d120eaed52..138fc2c8264 100644 --- a/src/futils.c +++ b/src/futils.c @@ -216,7 +216,7 @@ int git_futils_readbuffer_updated( p_close(fd); if (checksum) { - if ((error = git_hash_buf(&checksum_new, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) { + if ((error = git_hash_buf(checksum_new.id, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) { git_buf_dispose(&buf); return error; } diff --git a/src/hash.c b/src/hash.c index 2f11a88e8d0..222eadf4019 100644 --- a/src/hash.c +++ b/src/hash.c @@ -66,7 +66,7 @@ int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) return -1; } -int git_hash_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_final(unsigned char *out, git_hash_ctx *ctx) { switch (ctx->algorithm) { case GIT_HASH_ALGORITHM_SHA1: @@ -80,7 +80,7 @@ int git_hash_final(git_oid *out, git_hash_ctx *ctx) } int git_hash_buf( - git_oid *out, + unsigned char *out, const void *data, size_t len, git_hash_algorithm_t algorithm) @@ -100,7 +100,7 @@ int git_hash_buf( } int git_hash_vec( - git_oid *out, + unsigned char *out, git_buf_vec *vec, size_t n, git_hash_algorithm_t algorithm) diff --git a/src/hash.h b/src/hash.h index 7938e3b220e..ec91fa43a2a 100644 --- a/src/hash.h +++ b/src/hash.h @@ -11,6 +11,7 @@ #include "common.h" #include "git2/oid.h" +#include "hash/sha1.h" typedef struct { void *data; @@ -22,8 +23,6 @@ typedef enum { GIT_HASH_ALGORITHM_SHA1 } git_hash_algorithm_t; -#include "hash/sha1.h" - typedef struct git_hash_ctx { union { git_hash_sha1_ctx sha1; @@ -38,9 +37,9 @@ void git_hash_ctx_cleanup(git_hash_ctx *ctx); int git_hash_init(git_hash_ctx *c); int git_hash_update(git_hash_ctx *c, const void *data, size_t len); -int git_hash_final(git_oid *out, git_hash_ctx *c); +int git_hash_final(unsigned char *out, git_hash_ctx *c); -int git_hash_buf(git_oid *out, const void *data, size_t len, git_hash_algorithm_t algorithm); -int git_hash_vec(git_oid *out, git_buf_vec *vec, size_t n, git_hash_algorithm_t algorithm); +int git_hash_buf(unsigned char *out, const void *data, size_t len, git_hash_algorithm_t algorithm); +int git_hash_vec(unsigned char *out, git_buf_vec *vec, size_t n, git_hash_algorithm_t algorithm); #endif diff --git a/src/hash/sha1.h b/src/hash/sha1.h index fb8d62f8071..4b4dae3f831 100644 --- a/src/hash/sha1.h +++ b/src/hash/sha1.h @@ -26,6 +26,8 @@ typedef struct git_hash_sha1_ctx git_hash_sha1_ctx; # include "sha1/generic.h" #endif +#define GIT_HASH_SHA1_SIZE 20 + int git_hash_sha1_global_init(void); int git_hash_sha1_ctx_init(git_hash_sha1_ctx *ctx); @@ -33,6 +35,6 @@ void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx); int git_hash_sha1_init(git_hash_sha1_ctx *c); int git_hash_sha1_update(git_hash_sha1_ctx *c, const void *data, size_t len); -int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *c); +int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *c); #endif diff --git a/src/hash/sha1/collisiondetect.c b/src/hash/sha1/collisiondetect.c index 722ebf36f38..ec7059c4c7f 100644 --- a/src/hash/sha1/collisiondetect.c +++ b/src/hash/sha1/collisiondetect.c @@ -36,10 +36,10 @@ int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) return 0; } -int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) +int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx) { GIT_ASSERT_ARG(ctx); - if (SHA1DCFinal(out->id, &ctx->c)) { + if (SHA1DCFinal(out, &ctx->c)) { git_error_set(GIT_ERROR_SHA1, "SHA1 collision attack detected"); return -1; } diff --git a/src/hash/sha1/common_crypto.c b/src/hash/sha1/common_crypto.c index 4250e0b614f..9d608f4490e 100644 --- a/src/hash/sha1/common_crypto.c +++ b/src/hash/sha1/common_crypto.c @@ -49,9 +49,9 @@ int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *_data, size_t len) return 0; } -int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) +int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx) { GIT_ASSERT_ARG(ctx); - CC_SHA1_Final(out->id, &ctx->c); + CC_SHA1_Final(out, &ctx->c); return 0; } diff --git a/src/hash/sha1/generic.c b/src/hash/sha1/generic.c index 607fe3a43c9..85b34c578f8 100644 --- a/src/hash/sha1/generic.c +++ b/src/hash/sha1/generic.c @@ -278,7 +278,7 @@ int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) return 0; } -int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) +int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx) { static const unsigned char pad[64] = { 0x80 }; unsigned int padlen[2]; @@ -294,7 +294,7 @@ int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) /* Output hash */ for (i = 0; i < 5; i++) - put_be32(out->id + i*4, ctx->H[i]); + put_be32(out + i*4, ctx->H[i]); return 0; } diff --git a/src/hash/sha1/mbedtls.c b/src/hash/sha1/mbedtls.c index 04e7da5facb..56016bec8e1 100644 --- a/src/hash/sha1/mbedtls.c +++ b/src/hash/sha1/mbedtls.c @@ -38,9 +38,9 @@ int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) return 0; } -int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) +int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx) { GIT_ASSERT_ARG(ctx); - mbedtls_sha1_finish(&ctx->c, out->id); + mbedtls_sha1_finish(&ctx->c, out); return 0; } diff --git a/src/hash/sha1/openssl.c b/src/hash/sha1/openssl.c index 68d9611d4ad..64bf99b3cb2 100644 --- a/src/hash/sha1/openssl.c +++ b/src/hash/sha1/openssl.c @@ -46,11 +46,11 @@ int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) return 0; } -int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) +int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx) { GIT_ASSERT_ARG(ctx); - if (SHA1_Final(out->id, &ctx->c) != 1) { + if (SHA1_Final(out, &ctx->c) != 1) { git_error_set(GIT_ERROR_SHA1, "hash_openssl: failed to finalize hash"); return -1; } diff --git a/src/hash/sha1/win32.c b/src/hash/sha1/win32.c index a6e7061c6ac..b89dfbad87d 100644 --- a/src/hash/sha1/win32.c +++ b/src/hash/sha1/win32.c @@ -181,14 +181,14 @@ GIT_INLINE(int) hash_cryptoapi_update(git_hash_sha1_ctx *ctx, const void *_data, return 0; } -GIT_INLINE(int) hash_cryptoapi_final(git_oid *out, git_hash_sha1_ctx *ctx) +GIT_INLINE(int) hash_cryptoapi_final(unsigned char *out, git_hash_sha1_ctx *ctx) { - DWORD len = 20; + DWORD len = GIT_HASH_SHA1_SIZE; int error = 0; GIT_ASSERT(ctx->ctx.cryptoapi.valid); - if (!CryptGetHashParam(ctx->ctx.cryptoapi.hash_handle, HP_HASHVAL, out->id, &len, 0)) { + if (!CryptGetHashParam(ctx->ctx.cryptoapi.hash_handle, HP_HASHVAL, out, &len, 0)) { git_error_set(GIT_ERROR_OS, "legacy hash data could not be finished"); error = -1; } @@ -262,9 +262,9 @@ GIT_INLINE(int) hash_cng_update(git_hash_sha1_ctx *ctx, const void *_data, size_ return 0; } -GIT_INLINE(int) hash_cng_final(git_oid *out, git_hash_sha1_ctx *ctx) +GIT_INLINE(int) hash_cng_final(unsigned char *out, git_hash_sha1_ctx *ctx) { - if (ctx->prov->prov.cng.finish_hash(ctx->ctx.cng.hash_handle, out->id, GIT_OID_RAWSZ, 0) < 0) { + if (ctx->prov->prov.cng.finish_hash(ctx->ctx.cng.hash_handle, out, GIT_HASH_SHA1_SIZE, 0) < 0) { git_error_set(GIT_ERROR_OS, "hash could not be finished"); return -1; } @@ -315,7 +315,7 @@ int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) return (ctx->type == CNG) ? hash_cng_update(ctx, data, len) : hash_cryptoapi_update(ctx, data, len); } -int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) +int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx) { GIT_ASSERT_ARG(ctx); GIT_ASSERT_ARG(ctx->type); diff --git a/src/index.c b/src/index.c index 838f43c2df0..2e24fff6948 100644 --- a/src/index.c +++ b/src/index.c @@ -2648,7 +2648,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) /* Precalculate the SHA1 of the files's contents -- we'll match it to * the provided SHA1 in the footer */ - git_hash_buf(&checksum_calculated, buffer, buffer_size - INDEX_FOOTER_SIZE, GIT_HASH_ALGORITHM_SHA1); + git_hash_buf(checksum_calculated.id, buffer, buffer_size - INDEX_FOOTER_SIZE, GIT_HASH_ALGORITHM_SHA1); /* Parse header */ if ((error = read_header(&header, buffer)) < 0) diff --git a/src/indexer.c b/src/indexer.c index c3b1aee32a4..16ed7bfae22 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -426,7 +426,7 @@ static int store_object(git_indexer *idx) pentry = git__calloc(1, sizeof(struct git_pack_entry)); GIT_ERROR_CHECK_ALLOC(pentry); - if (git_hash_final(&oid, &idx->hash_ctx)) { + if (git_hash_final(oid.id, &idx->hash_ctx)) { git__free(pentry); goto on_error; } @@ -1183,7 +1183,7 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) git_oid_fromraw(&file_hash, packfile_trailer); git_mwindow_close(&w); - git_hash_final(&trailer_hash, &idx->trailer); + git_hash_final(trailer_hash.id, &idx->trailer); if (git_oid_cmp(&file_hash, &trailer_hash)) { git_error_set(GIT_ERROR_INDEXER, "packfile trailer mismatch"); return -1; @@ -1204,7 +1204,7 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) if (update_header_and_rehash(idx, stats) < 0) return -1; - git_hash_final(&trailer_hash, &idx->trailer); + git_hash_final(trailer_hash.id, &idx->trailer); write_at(idx, &trailer_hash, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ); } diff --git a/src/midx.c b/src/midx.c index 7ef85248cd1..cd3c98cef3d 100644 --- a/src/midx.c +++ b/src/midx.c @@ -212,7 +212,7 @@ int git_midx_parse( return midx_error("wrong index size"); git_oid_cpy(&idx->checksum, (git_oid *)(data + trailer_offset)); - if (git_hash_buf(&idx_checksum, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) + if (git_hash_buf(idx_checksum.id, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) return midx_error("could not calculate signature"); if (!git_oid_equal(&idx_checksum, &idx->checksum)) return midx_error("index signature mismatch"); @@ -819,7 +819,7 @@ static int midx_write( goto cleanup; /* Finalize the checksum and write the trailer. */ - error = git_hash_final(&idx_checksum, &ctx); + error = git_hash_final(idx_checksum.id, &ctx); if (error < 0) goto cleanup; error = write_cb((const char *)&idx_checksum, sizeof(idx_checksum), cb_data); diff --git a/src/odb.c b/src/odb.c index c2478083465..baa28734849 100644 --- a/src/odb.c +++ b/src/odb.c @@ -136,7 +136,7 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj) vec[1].data = obj->data; vec[1].len = obj->len; - return git_hash_vec(id, vec, 2, GIT_HASH_ALGORITHM_SHA1); + return git_hash_vec(id->id, vec, 2, GIT_HASH_ALGORITHM_SHA1); } @@ -237,7 +237,7 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_object_t type) goto done; } - error = git_hash_final(out, &ctx); + error = git_hash_final(out->id, &ctx); done: git_hash_ctx_cleanup(&ctx); @@ -1607,7 +1607,7 @@ int git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream) return git_odb_stream__invalid_length(stream, "stream_finalize_write()"); - git_hash_final(out, stream->hash_ctx); + git_hash_final(out->id, stream->hash_ctx); if (git_odb__freshen(stream->backend->odb, out)) return 0; diff --git a/src/pack-objects.c b/src/pack-objects.c index 560f57d03b4..d89a4e78044 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -664,7 +664,7 @@ static int write_pack(git_packbuilder *pb, pb->nr_remaining -= pb->nr_written; } while (pb->nr_remaining && i < pb->nr_objects); - if ((error = git_hash_final(&entry_oid, &pb->ctx)) < 0) + if ((error = git_hash_final(entry_oid.id, &pb->ctx)) < 0) goto done; error = write_cb(entry_oid.id, GIT_OID_RAWSZ, cb_data); diff --git a/tests/core/sha1.c b/tests/core/sha1.c index aa351935b82..92582d69a2b 100644 --- a/tests/core/sha1.c +++ b/tests/core/sha1.c @@ -13,7 +13,7 @@ void test_core_sha1__cleanup(void) cl_fixture_cleanup(FIXTURE_DIR); } -static int sha1_file(git_oid *oid, const char *filename) +static int sha1_file(git_oid *out, const char *filename) { git_hash_ctx ctx; char buf[2048]; @@ -31,7 +31,7 @@ static int sha1_file(git_oid *oid, const char *filename) cl_assert_equal_i(0, read_len); p_close(fd); - ret = git_hash_final(oid, &ctx); + ret = git_hash_final(out->id, &ctx); git_hash_ctx_cleanup(&ctx); return ret; diff --git a/tests/object/raw/hash.c b/tests/object/raw/hash.c index e9a647627fe..3be1f83b39b 100644 --- a/tests/object/raw/hash.c +++ b/tests/object/raw/hash.c @@ -30,14 +30,14 @@ void test_object_raw_hash__hash_by_blocks(void) /* should already be init'd */ cl_git_pass(git_hash_update(&ctx, hello_text, strlen(hello_text))); - cl_git_pass(git_hash_final(&id2, &ctx)); + cl_git_pass(git_hash_final(id2.id, &ctx)); cl_git_pass(git_oid_fromstr(&id1, hello_id)); cl_assert(git_oid_cmp(&id1, &id2) == 0); /* reinit should permit reuse */ cl_git_pass(git_hash_init(&ctx)); cl_git_pass(git_hash_update(&ctx, bye_text, strlen(bye_text))); - cl_git_pass(git_hash_final(&id2, &ctx)); + cl_git_pass(git_hash_final(id2.id, &ctx)); cl_git_pass(git_oid_fromstr(&id1, bye_id)); cl_assert(git_oid_cmp(&id1, &id2) == 0); @@ -49,7 +49,7 @@ void test_object_raw_hash__hash_buffer_in_single_call(void) git_oid id1, id2; cl_git_pass(git_oid_fromstr(&id1, hello_id)); - git_hash_buf(&id2, hello_text, strlen(hello_text), GIT_HASH_ALGORITHM_SHA1); + git_hash_buf(id2.id, hello_text, strlen(hello_text), GIT_HASH_ALGORITHM_SHA1); cl_assert(git_oid_cmp(&id1, &id2) == 0); } @@ -65,7 +65,7 @@ void test_object_raw_hash__hash_vector(void) vec[1].data = hello_text+4; vec[1].len = strlen(hello_text)-4; - git_hash_vec(&id2, vec, 2, GIT_HASH_ALGORITHM_SHA1); + git_hash_vec(id2.id, vec, 2, GIT_HASH_ALGORITHM_SHA1); cl_assert(git_oid_cmp(&id1, &id2) == 0); } diff --git a/tests/object/raw/short.c b/tests/object/raw/short.c index 626c9654be3..e8d2cf5a5bf 100644 --- a/tests/object/raw/short.c +++ b/tests/object/raw/short.c @@ -33,7 +33,7 @@ static int insert_sequential_oids( for (i = 0; i < n; ++i) { p_snprintf(numbuf, sizeof(numbuf), "%u", (unsigned int)i); - git_hash_buf(&oid, numbuf, strlen(numbuf), GIT_HASH_ALGORITHM_SHA1); + git_hash_buf(oid.id, numbuf, strlen(numbuf), GIT_HASH_ALGORITHM_SHA1); oids[i] = git__malloc(GIT_OID_HEXSZ + 1); cl_assert(oids[i]); diff --git a/tests/odb/largefiles.c b/tests/odb/largefiles.c index 03b183cd582..ff82291b301 100644 --- a/tests/odb/largefiles.c +++ b/tests/odb/largefiles.c @@ -119,7 +119,7 @@ void test_odb_largefiles__streamread(void) cl_assert_equal_sz(LARGEFILE_SIZE, total); - git_hash_final(&read_oid, &hash); + git_hash_final(read_oid.id, &hash); cl_assert_equal_oid(&oid, &read_oid); diff --git a/tests/pack/packbuilder.c b/tests/pack/packbuilder.c index 42d446a8b37..5d93ede06fe 100644 --- a/tests/pack/packbuilder.c +++ b/tests/pack/packbuilder.c @@ -128,7 +128,7 @@ void test_pack_packbuilder__create_pack(void) cl_git_pass(git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1)); cl_git_pass(git_hash_update(&ctx, buf.ptr, buf.size)); - cl_git_pass(git_hash_final(&hash, &ctx)); + cl_git_pass(git_hash_final(hash.id, &ctx)); git_hash_ctx_cleanup(&ctx); git_buf_dispose(&path); From 923364c58eaca0c54f09def3292dff848975906c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 30 Sep 2021 08:40:29 -0400 Subject: [PATCH 0570/1616] futils: use a particular hash not a git_oid In `git_futils_readbuffer_updated`, always take a particular hash instead of a `git_oid`. This lets us change the checksum algorithm independently of `git_oid` usage. --- src/futils.c | 13 ++++++++----- src/futils.h | 7 +++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/futils.c b/src/futils.c index 138fc2c8264..d28b231ce70 100644 --- a/src/futils.c +++ b/src/futils.c @@ -177,13 +177,16 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len) } int git_futils_readbuffer_updated( - git_buf *out, const char *path, git_oid *checksum, int *updated) + git_buf *out, + const char *path, + unsigned char checksum[GIT_HASH_SHA1_SIZE], + int *updated) { int error; git_file fd; struct stat st; git_buf buf = GIT_BUF_INIT; - git_oid checksum_new; + unsigned char checksum_new[GIT_HASH_SHA1_SIZE]; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(path && *path); @@ -216,7 +219,7 @@ int git_futils_readbuffer_updated( p_close(fd); if (checksum) { - if ((error = git_hash_buf(checksum_new.id, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) { + if ((error = git_hash_buf(checksum_new, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) { git_buf_dispose(&buf); return error; } @@ -224,7 +227,7 @@ int git_futils_readbuffer_updated( /* * If we were given a checksum, we only want to use it if it's different */ - if (!git_oid__cmp(checksum, &checksum_new)) { + if (!memcmp(checksum, checksum_new, GIT_HASH_SHA1_SIZE)) { git_buf_dispose(&buf); if (updated) *updated = 0; @@ -232,7 +235,7 @@ int git_futils_readbuffer_updated( return 0; } - git_oid_cpy(checksum, &checksum_new); + memcpy(checksum, checksum_new, GIT_HASH_SHA1_SIZE); } /* diff --git a/src/futils.h b/src/futils.h index 58936125ac2..373cc3042eb 100644 --- a/src/futils.h +++ b/src/futils.h @@ -14,7 +14,7 @@ #include "path.h" #include "pool.h" #include "strmap.h" -#include "oid.h" +#include "hash.h" /** * Filebuffer methods @@ -23,7 +23,10 @@ */ extern int git_futils_readbuffer(git_buf *obj, const char *path); extern int git_futils_readbuffer_updated( - git_buf *obj, const char *path, git_oid *checksum, int *updated); + git_buf *obj, + const char *path, + unsigned char checksum[GIT_HASH_SHA1_SIZE], + int *updated); extern int git_futils_readbuffer_fd(git_buf *obj, git_file fd, size_t len); /* Additional constants for `git_futils_writebuffer`'s `open_flags`. We From f0a0916028ef1c599030f513c0685b77d74e6c21 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 2 Oct 2021 13:50:12 -0400 Subject: [PATCH 0571/1616] fuzzers: use updated hash functions --- fuzzers/commit_graph_fuzzer.c | 9 ++++++--- fuzzers/midx_fuzzer.c | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/fuzzers/commit_graph_fuzzer.c b/fuzzers/commit_graph_fuzzer.c index b41816ed951..39b52088279 100644 --- a/fuzzers/commit_graph_fuzzer.c +++ b/fuzzers/commit_graph_fuzzer.c @@ -34,6 +34,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) git_commit_graph_file file = {{0}}; git_commit_graph_entry e; git_buf commit_graph_buf = GIT_BUF_INIT; + unsigned char hash[GIT_HASH_SHA1_SIZE]; git_oid oid = {{0}}; bool append_hash = false; @@ -50,14 +51,16 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) size -= 4; if (append_hash) { - if (git_buf_init(&commit_graph_buf, size + sizeof(oid)) < 0) + if (git_buf_init(&commit_graph_buf, size + GIT_HASH_SHA1_SIZE) < 0) goto cleanup; - if (git_hash_buf(&oid, data, size) < 0) { + if (git_hash_buf(hash, data, size, GIT_HASH_ALGORITHM_SHA1) < 0) { fprintf(stderr, "Failed to compute the SHA1 hash\n"); abort(); } memcpy(commit_graph_buf.ptr, data, size); - memcpy(commit_graph_buf.ptr + size, &oid, sizeof(oid)); + memcpy(commit_graph_buf.ptr + size, hash, GIT_HASH_SHA1_SIZE); + + memcpy(oid.id, hash, GIT_OID_RAWSZ); } else { git_buf_attach_notowned(&commit_graph_buf, (char *)data, size); } diff --git a/fuzzers/midx_fuzzer.c b/fuzzers/midx_fuzzer.c index e67873faa53..9739f0a40a6 100644 --- a/fuzzers/midx_fuzzer.c +++ b/fuzzers/midx_fuzzer.c @@ -34,6 +34,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) git_midx_file idx = {{0}}; git_midx_entry e; git_buf midx_buf = GIT_BUF_INIT; + unsigned char hash[GIT_HASH_SHA1_SIZE]; git_oid oid = {{0}}; bool append_hash = false; @@ -50,14 +51,16 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) size -= 4; if (append_hash) { - if (git_buf_init(&midx_buf, size + sizeof(oid)) < 0) + if (git_buf_init(&midx_buf, size + GIT_HASH_SHA1_SIZE) < 0) goto cleanup; - if (git_hash_buf(&oid, data, size) < 0) { + if (git_hash_buf(hash, data, size, GIT_HASH_ALGORITHM_SHA1) < 0) { fprintf(stderr, "Failed to compute the SHA1 hash\n"); abort(); } memcpy(midx_buf.ptr, data, size); - memcpy(midx_buf.ptr + size, &oid, sizeof(oid)); + memcpy(midx_buf.ptr + size, hash, GIT_HASH_SHA1_SIZE); + + memcpy(oid.id, hash, GIT_OID_RAWSZ); } else { git_buf_attach_notowned(&midx_buf, (char *)data, size); } From d174381c44ea67cd08bc214611a9a63ffeef24a9 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 13 Oct 2021 11:34:56 -0400 Subject: [PATCH 0572/1616] diff: make the default rename_limit 1000 git's default rename limit is 1000, ours should match. --- src/diff_tform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diff_tform.c b/src/diff_tform.c index 908175d3412..597e64e45eb 100644 --- a/src/diff_tform.c +++ b/src/diff_tform.c @@ -241,7 +241,7 @@ int git_diff_find_similar__calc_similarity( #define DEFAULT_THRESHOLD 50 #define DEFAULT_BREAK_REWRITE_THRESHOLD 60 -#define DEFAULT_RENAME_LIMIT 200 +#define DEFAULT_RENAME_LIMIT 1000 static int normalize_find_opts( git_diff *diff, From 1738f7320d81e316f782a2fddc45233864dc6929 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 13 Oct 2021 11:36:07 -0400 Subject: [PATCH 0573/1616] diff: document updated rename limit --- include/git2/diff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/diff.h b/include/git2/diff.h index a14c01993fa..b0119b9f79f 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -768,7 +768,7 @@ typedef struct { * * This is a little different from the `-l` option from Git because we * will still process up to this many matches before abandoning the search. - * Defaults to 200. + * Defaults to 1000. */ size_t rename_limit; From 5346be3ddd3bcf19779c5d62e71f8442a0171133 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 23 Sep 2021 21:16:36 -0400 Subject: [PATCH 0574/1616] docs: document `git_buf` We have been inconsistent about the way that we handle `git_buf`s provided by users. _Usually_ we require that it has been properly initialized with `GIT_BUF_INIT`, but _sometimes_ we simply overwrite the data in it regardless. And even more rarely, we will grow a user-provided buffer and concatenate data onto it (see `git_diff_format_email`). Document the path forward for `git_buf`, which is that we always require that the buffer is intitialized with `GIT_BUF_INIT`. `git_diff_format_email` will be kept backward compatible but users are encouraged to switch to the new `git_email` APIs. --- docs/buffers.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 docs/buffers.md diff --git a/docs/buffers.md b/docs/buffers.md new file mode 100644 index 00000000000..2f2148bc527 --- /dev/null +++ b/docs/buffers.md @@ -0,0 +1,63 @@ +Memory allocation and ownership +------------------------------- + +Any library needs to _take_ data from users, and then _return_ data to +users. With some types this is simple - integer parameters and return +types are trivial. But with more complex data types, things are more +complicated. Even something seemingly simple, like a C string, requires +discipline: we cannot simple return an allocated hunk of memory for +callers to `free`, since some systems have multiple allocators and users +cannot necessarily reason about the allocator used and which corresponding +deallocation function to call to free the memory. + +## Objects + +Most types in libgit2 are "opaque" types, which we treat as "objects" (even +though C is "not an object oriented language"). You may create an object - +for example, with `git_odb_new`, or libgit2 may return you an object as an +"out" parameter - for example, with `git_repository_open`. With any of +these objects, you should call their corresponding `_free` function (for +example, `git_odb_free` or `git_repository_free`) when you are done using +them. + +## Structures + +libgit2 will often take _input_ as structures (for example, options +structures like `git_merge_options`). Rarely, libgit2 will return data in +a structure. This is typically used for simpler data types, like `git_buf` +and `git_strarray`. Users should allocate the structure themselves (either +on the stack or the heap) and pass a pointer to it. Since libgit2 does not +allocate the structure itself, only the data inside of it, the deallocation +functions are suffixed with `_dispose` instead of `_free`, since they only +free the data _inside_ the structure. + +## Strings or continuous memory buffers (`git_buf`) + +libgit2 typically _takes_ NUL-terminated strings ("C strings") with a +`const char *`, and typically _takes_ raw data with a `const char *` and a +corresponding `size_t` for its size. libgit2 typically _returns_ strings +or raw data in a `git_buf` structure. The given data buffer will always be +NUL terminated (even if it contains binary data) and the `size` member will +always contain the size (in bytes) of the contents of the pointer (excluding +the NUL terminator). + +In other words, if a `git_buf` contains the string `foo` then the memory +buffer will be { `f`, `o`, `o`, `\0` } and the size will be `3`. + +Callers _must_ initialize the buffer with `GIT_BUF_INIT` (or by setting +all the members to `0`) when it is created, before passing a pointer +to the buffer to libgit2 for the first time. + +Subsequent calls to libgit2 APIs that take a buffer can re-use a +buffer that was previously used. The buffer will be cleared and grown +to accommodate the new contents (if necessary). The new data will +written into the buffer, overwriting the previous contents. This +allows callers to reduce the number of allocations performed by the +library. + +Callers must call `git_buf_dispose` when they have finished. + +Note that the deprecated `git_diff_format_email` API does not follow +this behavior; subsequent calls will concatenate data to the buffer +instead of rewriting it. Users should move to the new `git_email` +APIs that follow the `git_buf` standards. From f0e693b18afbe1de37d7da5b5a8967b6c87d8e53 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 7 Sep 2021 17:53:49 -0400 Subject: [PATCH 0575/1616] str: introduce `git_str` for internal, `git_buf` is external libgit2 has two distinct requirements that were previously solved by `git_buf`. We require: 1. A general purpose string class that provides a number of utility APIs for manipulating data (eg, concatenating, truncating, etc). 2. A structure that we can use to return strings to callers that they can take ownership of. By using a single class (`git_buf`) for both of these purposes, we have confused the API to the point that refactorings are difficult and reasoning about correctness is also difficult. Move the utility class `git_buf` to be called `git_str`: this represents its general purpose, as an internal string buffer class. The name also is an homage to Junio Hamano ("gitstr"). The public API remains `git_buf`, and has a much smaller footprint. It is generally only used as an "out" param with strict requirements that follow the documentation. (Exceptions exist for some legacy APIs to avoid breaking callers unnecessarily.) Utility functions exist to convert a user-specified `git_buf` to a `git_str` so that we can call internal functions, then converting it back again. --- examples/diff.c | 2 +- fuzzers/commit_graph_fuzzer.c | 14 +- fuzzers/midx_fuzzer.c | 11 +- fuzzers/packfile_fuzzer.c | 16 +- fuzzers/standalone_driver.c | 4 +- include/git2/buffer.h | 96 +-- src/apply.c | 36 +- src/apply.h | 4 +- src/attr.c | 26 +- src/attr_file.c | 28 +- src/attr_file.h | 8 +- src/attrcache.c | 16 +- src/blob.c | 46 +- src/blob.h | 2 +- src/branch.c | 252 ++++---- src/branch.h | 18 +- src/buf.c | 126 ++++ src/buf.h | 50 ++ src/buffer.h | 374 ------------ src/checkout.c | 96 +-- src/cherrypick.c | 20 +- src/clone.c | 116 ++-- src/commit.c | 148 +++-- src/commit.h | 23 + src/commit_graph.c | 85 +-- src/commit_graph.h | 9 +- src/common.h | 7 +- src/config.c | 163 ++--- src/config.h | 15 +- src/config_file.c | 144 ++--- src/config_mem.c | 18 +- src/config_parse.c | 38 +- src/crlf.c | 43 +- src/describe.c | 46 +- src/diff.c | 29 +- src/diff.h | 4 +- src/diff_driver.c | 52 +- src/diff_driver.h | 6 +- src/diff_file.c | 34 +- src/diff_generate.c | 8 +- src/diff_print.c | 197 +++--- src/diff_stats.c | 67 ++- src/{message.h => diff_stats.h} | 13 +- src/diff_tform.c | 6 +- src/email.c | 76 +-- src/email.h | 2 +- src/errors.c | 36 +- src/fetchhead.c | 38 +- src/filebuf.c | 34 +- src/filter.c | 143 +++-- src/filter.h | 31 +- src/futils.c | 82 +-- src/futils.h | 10 +- src/hash.c | 2 +- src/hash.h | 4 +- src/ident.c | 36 +- src/ignore.c | 44 +- src/ignore.h | 2 +- src/index.c | 68 +-- src/indexer.c | 66 +- src/iterator.c | 82 +-- src/iterator.h | 6 +- src/libgit2.c | 31 +- src/mailmap.c | 67 ++- src/merge.c | 38 +- src/merge_driver.c | 2 +- src/message.c | 31 +- src/midx.c | 111 ++-- src/midx.h | 4 +- src/net.c | 128 ++-- src/net.h | 4 +- src/netops.c | 2 +- src/notes.c | 49 +- src/object.c | 13 +- src/object.h | 2 +- src/odb.c | 34 +- src/odb_loose.c | 116 ++-- src/odb_mempack.c | 23 +- src/odb_pack.c | 80 +-- src/oid.c | 8 +- src/pack-objects.c | 45 +- src/pack-objects.h | 4 +- src/pack.c | 18 +- src/patch.c | 6 +- src/patch.h | 1 + src/patch_generate.c | 10 +- src/patch_parse.c | 40 +- src/path.c | 194 +++--- src/path.h | 64 +- src/pathspec.c | 12 +- src/pathspec.h | 2 +- src/push.c | 14 +- src/reader.c | 16 +- src/reader.h | 4 +- src/rebase.c | 163 ++--- src/refdb_fs.c | 264 ++++---- src/refs.c | 56 +- src/refs.h | 4 +- src/refspec.c | 69 +-- src/refspec.h | 7 +- src/remote.c | 359 +++++------ src/remote.h | 4 +- src/repository.c | 524 ++++++++-------- src/repository.h | 16 +- src/reset.c | 8 +- src/revert.c | 20 +- src/revparse.c | 62 +- src/revwalk.c | 12 +- src/signature.c | 4 +- src/signature.h | 2 +- src/sortedcache.c | 2 +- src/sortedcache.h | 2 +- src/stash.c | 73 ++- src/{buffer.c => str.c} | 279 +++++---- src/str.h | 354 +++++++++++ src/submodule.c | 297 ++++----- src/sysdir.c | 96 +-- src/sysdir.h | 18 +- src/tag.c | 47 +- src/threadstate.c | 4 +- src/threadstate.h | 2 +- src/trace.c | 2 +- src/trace.h | 10 +- src/transport.c | 14 +- src/transports/auth.c | 16 +- src/transports/auth.h | 3 +- src/transports/auth_negotiate.c | 25 +- src/transports/auth_ntlm.c | 20 +- src/transports/auth_ntlm.h | 1 - src/transports/git.c | 20 +- src/transports/http.c | 4 +- src/transports/http.h | 5 +- src/transports/httpclient.c | 130 ++-- src/transports/local.c | 81 ++- src/transports/smart.c | 10 +- src/transports/smart.h | 10 +- src/transports/smart_pkt.c | 66 +- src/transports/smart_protocol.c | 60 +- src/transports/ssh.c | 24 +- src/transports/winhttp.c | 70 +-- src/tree-cache.c | 10 +- src/tree-cache.h | 4 +- src/tree.c | 54 +- src/tree.h | 2 +- src/util.c | 12 +- src/util.h | 8 +- src/win32/findfile.c | 44 +- src/win32/findfile.h | 8 +- src/win32/posix_w32.c | 9 +- src/win32/w32_buffer.c | 5 +- src/win32/w32_buffer.h | 5 +- src/worktree.c | 150 +++-- src/zstream.c | 10 +- src/zstream.h | 6 +- tests/apply/fromdiff.c | 26 +- tests/apply/fromfile.c | 8 +- tests/apply/partial.c | 8 +- tests/attr/repo.c | 26 +- tests/buf/basic.c | 51 -- tests/buf/splice.c | 93 --- tests/checkout/checkout_helpers.c | 6 +- tests/checkout/checkout_helpers.h | 1 - tests/checkout/conflict.c | 38 +- tests/checkout/crlf.c | 84 +-- tests/checkout/icase.c | 8 +- tests/checkout/index.c | 18 +- tests/checkout/nasty.c | 13 +- tests/checkout/tree.c | 23 +- tests/checkout/typechange.c | 22 +- tests/cherrypick/bare.c | 1 - tests/cherrypick/workdir.c | 19 +- tests/clar_libgit2.c | 74 ++- tests/clar_libgit2_timer.c | 1 - tests/clone/local.c | 57 +- tests/clone/nonetwork.c | 14 +- tests/commit/parse.c | 18 +- tests/config/conditionals.c | 34 +- tests/config/config_helpers.c | 5 +- tests/config/configlevel.c | 2 +- tests/config/global.c | 19 +- tests/config/include.c | 45 +- tests/config/new.c | 6 +- tests/config/read.c | 55 +- tests/config/stress.c | 4 +- tests/config/write.c | 49 +- tests/core/buf.c | 54 ++ tests/core/dirent.c | 18 +- tests/core/env.c | 50 +- tests/core/filebuf.c | 10 +- tests/core/futils.c | 28 +- tests/core/{buffer.c => gitstr.c} | 793 ++++++++++++------------- tests/core/link.c | 119 ++-- tests/core/mkdir.c | 20 +- tests/core/path.c | 106 ++-- tests/core/posix.c | 12 +- tests/core/rmdir.c | 66 +- tests/core/sortedcache.c | 4 +- tests/core/stat.c | 6 +- tests/core/useragent.c | 4 +- tests/core/zstream.c | 35 +- tests/describe/describe.c | 4 +- tests/describe/describe_helpers.c | 4 +- tests/describe/describe_helpers.h | 1 - tests/diff/binary.c | 35 +- tests/diff/blob.c | 16 +- tests/diff/drivers.c | 19 +- tests/diff/format_email.c | 9 +- tests/diff/parse.c | 14 +- tests/diff/patch.c | 50 +- tests/diff/rename.c | 70 +-- tests/diff/stats.c | 37 +- tests/diff/submodules.c | 2 +- tests/diff/workdir.c | 29 +- tests/email/create.c | 17 +- tests/fetchhead/nonetwork.c | 16 +- tests/filter/crlf.c | 1 - tests/filter/custom_helpers.c | 12 +- tests/filter/custom_helpers.h | 8 +- tests/filter/file.c | 7 +- tests/filter/query.c | 1 - tests/filter/stream.c | 6 +- tests/filter/systemattrs.c | 14 +- tests/filter/wildcard.c | 4 +- tests/graph/commit_graph.c | 37 +- tests/graph/reachable_from_any.c | 10 +- tests/ignore/status.c | 8 +- tests/index/crlf.c | 84 +-- tests/index/filemodes.c | 11 +- tests/index/nsec.c | 6 +- tests/index/racy.c | 25 +- tests/index/tests.c | 30 +- tests/iterator/index.c | 18 +- tests/iterator/tree.c | 6 +- tests/iterator/workdir.c | 18 +- tests/mailmap/parsing.c | 10 +- tests/merge/analysis.c | 24 +- tests/merge/driver.c | 28 +- tests/merge/files.c | 1 - tests/merge/merge_helpers.c | 32 +- tests/merge/trees/automerge.c | 1 - tests/merge/trees/modeconflict.c | 1 - tests/merge/trees/renames.c | 9 +- tests/merge/trees/trivial.c | 10 +- tests/merge/trees/whitespace.c | 1 - tests/merge/workdir/dirty.c | 31 +- tests/merge/workdir/recursive.c | 8 +- tests/merge/workdir/renames.c | 1 - tests/merge/workdir/setup.c | 58 +- tests/merge/workdir/simple.c | 37 +- tests/merge/workdir/submodules.c | 1 - tests/merge/workdir/trivial.c | 10 +- tests/message/trailer.c | 1 - tests/network/fetchlocal.c | 1 - tests/network/remote/defaultbranch.c | 1 - tests/network/remote/local.c | 17 +- tests/network/remote/remotes.c | 41 +- tests/notes/notes.c | 4 +- tests/notes/notesref.c | 3 +- tests/object/blob/filter.c | 18 +- tests/object/blob/fromstream.c | 13 +- tests/object/blob/write.c | 17 +- tests/object/commit/commitstagedfile.c | 3 +- tests/object/lookup.c | 18 +- tests/object/message.c | 4 +- tests/object/raw/hash.c | 2 +- tests/object/tree/write.c | 6 +- tests/odb/alternates.c | 20 +- tests/odb/foreach.c | 7 +- tests/odb/freshen.c | 10 +- tests/odb/largefiles.c | 10 +- tests/online/clone.c | 46 +- tests/online/customcert.c | 10 +- tests/online/fetch.c | 6 +- tests/online/fetchhead.c | 8 +- tests/online/push.c | 43 +- tests/online/push_util.c | 24 +- tests/pack/filelimit.c | 18 +- tests/pack/indexer.c | 26 +- tests/pack/midx.c | 51 +- tests/pack/packbuilder.c | 10 +- tests/patch/parse.c | 12 +- tests/path/core.c | 14 +- tests/rebase/sign.c | 14 +- tests/rebase/submodule.c | 8 +- tests/refs/basic.c | 10 +- tests/refs/branches/create.c | 8 +- tests/refs/branches/delete.c | 20 +- tests/refs/branches/move.c | 25 +- tests/refs/branches/remote.c | 9 +- tests/refs/branches/upstreamname.c | 5 +- tests/refs/delete.c | 6 +- tests/refs/pack.c | 14 +- tests/refs/read.c | 6 +- tests/refs/ref_helpers.c | 7 +- tests/refs/reflog/messages.c | 8 +- tests/refs/reflog/reflog.c | 86 +-- tests/refs/reflog/reflog_helpers.c | 32 +- tests/refs/rename.c | 22 +- tests/refs/revparse.c | 21 +- tests/remote/fetch.c | 16 +- tests/repo/config.c | 12 +- tests/repo/discover.c | 26 +- tests/repo/env.c | 20 +- tests/repo/hashfile.c | 35 +- tests/repo/init.c | 70 +-- tests/repo/message.c | 14 +- tests/repo/open.c | 60 +- tests/repo/repo_helpers.c | 14 +- tests/repo/reservedname.c | 14 +- tests/repo/setters.c | 15 +- tests/repo/state.c | 11 +- tests/repo/template.c | 58 +- tests/reset/hard.c | 62 +- tests/reset/mixed.c | 12 +- tests/reset/soft.c | 18 +- tests/revert/bare.c | 1 - tests/revert/workdir.c | 11 +- tests/stash/apply.c | 8 +- tests/stash/save.c | 8 +- tests/status/renames.c | 11 +- tests/status/worktree.c | 84 +-- tests/str/basic.c | 50 ++ tests/{buf => str}/oom.c | 31 +- tests/{buf => str}/percent.c | 21 +- tests/{buf => str}/quote.c | 39 +- tests/str/splice.c | 92 +++ tests/stress/diff.c | 12 +- tests/submodule/add.c | 22 +- tests/submodule/escape.c | 12 +- tests/submodule/init.c | 18 +- tests/submodule/inject_option.c | 12 +- tests/submodule/lookup.c | 12 +- tests/submodule/modify.c | 6 +- tests/submodule/nosubs.c | 4 +- tests/submodule/open.c | 34 +- tests/submodule/repository_init.c | 4 +- tests/submodule/status.c | 6 +- tests/submodule/submodule_helpers.c | 39 +- tests/valgrind-supp-mac.txt | 6 +- tests/win32/forbidden.c | 1 - tests/win32/longpath.c | 21 +- tests/worktree/merge.c | 14 +- tests/worktree/open.c | 10 +- tests/worktree/refs.c | 6 +- tests/worktree/submodule.c | 6 +- tests/worktree/worktree.c | 102 ++-- 346 files changed, 6759 insertions(+), 6308 deletions(-) create mode 100644 src/buf.c create mode 100644 src/buf.h delete mode 100644 src/buffer.h rename src/{message.h => diff_stats.h} (55%) rename src/{buffer.c => str.c} (82%) create mode 100644 src/str.h delete mode 100644 tests/buf/basic.c delete mode 100644 tests/buf/splice.c create mode 100644 tests/core/buf.c rename tests/core/{buffer.c => gitstr.c} (55%) create mode 100644 tests/str/basic.c rename tests/{buf => str}/oom.c (61%) rename tests/{buf => str}/percent.c (71%) rename tests/{buf => str}/quote.c (74%) create mode 100644 tests/str/splice.c diff --git a/examples/diff.c b/examples/diff.c index 2305c86524f..a9fb5d4428a 100644 --- a/examples/diff.c +++ b/examples/diff.c @@ -344,7 +344,7 @@ static void parse_opts(struct diff_options *o, int argc, char *argv[]) static void diff_print_stats(git_diff *diff, struct diff_options *o) { git_diff_stats *stats; - git_buf b = GIT_BUF_INIT_CONST(NULL, 0); + git_buf b = GIT_BUF_INIT; git_diff_stats_format_t format = 0; check_lg2( diff --git a/fuzzers/commit_graph_fuzzer.c b/fuzzers/commit_graph_fuzzer.c index 39b52088279..05783a25936 100644 --- a/fuzzers/commit_graph_fuzzer.c +++ b/fuzzers/commit_graph_fuzzer.c @@ -11,8 +11,8 @@ #include "git2.h" -#include "buffer.h" #include "common.h" +#include "str.h" #include "futils.h" #include "hash.h" #include "commit_graph.h" @@ -33,7 +33,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { git_commit_graph_file file = {{0}}; git_commit_graph_entry e; - git_buf commit_graph_buf = GIT_BUF_INIT; + git_str commit_graph_buf = GIT_STR_INIT; unsigned char hash[GIT_HASH_SHA1_SIZE]; git_oid oid = {{0}}; bool append_hash = false; @@ -51,7 +51,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) size -= 4; if (append_hash) { - if (git_buf_init(&commit_graph_buf, size + GIT_HASH_SHA1_SIZE) < 0) + if (git_str_init(&commit_graph_buf, size + GIT_HASH_SHA1_SIZE) < 0) goto cleanup; if (git_hash_buf(hash, data, size, GIT_HASH_ALGORITHM_SHA1) < 0) { fprintf(stderr, "Failed to compute the SHA1 hash\n"); @@ -62,13 +62,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) memcpy(oid.id, hash, GIT_OID_RAWSZ); } else { - git_buf_attach_notowned(&commit_graph_buf, (char *)data, size); + git_str_attach_notowned(&commit_graph_buf, (char *)data, size); } if (git_commit_graph_file_parse( &file, - (const unsigned char *)git_buf_cstr(&commit_graph_buf), - git_buf_len(&commit_graph_buf)) + (const unsigned char *)git_str_cstr(&commit_graph_buf), + git_str_len(&commit_graph_buf)) < 0) goto cleanup; @@ -78,6 +78,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) cleanup: git_commit_graph_file_close(&file); - git_buf_dispose(&commit_graph_buf); + git_str_dispose(&commit_graph_buf); return 0; } diff --git a/fuzzers/midx_fuzzer.c b/fuzzers/midx_fuzzer.c index 9739f0a40a6..3cd609063fe 100644 --- a/fuzzers/midx_fuzzer.c +++ b/fuzzers/midx_fuzzer.c @@ -11,7 +11,6 @@ #include "git2.h" -#include "buffer.h" #include "common.h" #include "futils.h" #include "hash.h" @@ -33,7 +32,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { git_midx_file idx = {{0}}; git_midx_entry e; - git_buf midx_buf = GIT_BUF_INIT; + git_str midx_buf = GIT_STR_INIT; unsigned char hash[GIT_HASH_SHA1_SIZE]; git_oid oid = {{0}}; bool append_hash = false; @@ -51,7 +50,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) size -= 4; if (append_hash) { - if (git_buf_init(&midx_buf, size + GIT_HASH_SHA1_SIZE) < 0) + if (git_str_init(&midx_buf, size + GIT_HASH_SHA1_SIZE) < 0) goto cleanup; if (git_hash_buf(hash, data, size, GIT_HASH_ALGORITHM_SHA1) < 0) { fprintf(stderr, "Failed to compute the SHA1 hash\n"); @@ -62,10 +61,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) memcpy(oid.id, hash, GIT_OID_RAWSZ); } else { - git_buf_attach_notowned(&midx_buf, (char *)data, size); + git_str_attach_notowned(&midx_buf, (char *)data, size); } - if (git_midx_parse(&idx, (const unsigned char *)git_buf_cstr(&midx_buf), git_buf_len(&midx_buf)) < 0) + if (git_midx_parse(&idx, (const unsigned char *)git_str_cstr(&midx_buf), git_str_len(&midx_buf)) < 0) goto cleanup; /* Search for any oid, just to exercise that codepath. */ @@ -74,6 +73,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) cleanup: git_midx_close(&idx); - git_buf_dispose(&midx_buf); + git_str_dispose(&midx_buf); return 0; } diff --git a/fuzzers/packfile_fuzzer.c b/fuzzers/packfile_fuzzer.c index 50c11575524..f739b956376 100644 --- a/fuzzers/packfile_fuzzer.c +++ b/fuzzers/packfile_fuzzer.c @@ -12,7 +12,7 @@ #include "git2.h" #include "git2/sys/mempack.h" #include "common.h" -#include "buffer.h" +#include "str.h" static git_odb *odb = NULL; static git_odb_backend *mempack = NULL; @@ -53,7 +53,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { git_indexer_progress stats = {0, 0}; git_indexer *indexer = NULL; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_oid oid; bool append_hash = false; @@ -99,19 +99,19 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) if (git_indexer_commit(indexer, &stats) < 0) goto cleanup; - if (git_buf_printf(&path, "pack-%s.idx", git_oid_tostr_s(git_indexer_hash(indexer))) < 0) + if (git_str_printf(&path, "pack-%s.idx", git_oid_tostr_s(git_indexer_hash(indexer))) < 0) goto cleanup; - p_unlink(git_buf_cstr(&path)); + p_unlink(git_str_cstr(&path)); - git_buf_clear(&path); + git_str_clear(&path); - if (git_buf_printf(&path, "pack-%s.pack", git_oid_tostr_s(git_indexer_hash(indexer))) < 0) + if (git_str_printf(&path, "pack-%s.pack", git_oid_tostr_s(git_indexer_hash(indexer))) < 0) goto cleanup; - p_unlink(git_buf_cstr(&path)); + p_unlink(git_str_cstr(&path)); cleanup: git_mempack_reset(mempack); git_indexer_free(indexer); - git_buf_dispose(&path); + git_str_dispose(&path); return 0; } diff --git a/fuzzers/standalone_driver.c b/fuzzers/standalone_driver.c index 90e7013339c..88c8cfbda3d 100644 --- a/fuzzers/standalone_driver.c +++ b/fuzzers/standalone_driver.c @@ -16,7 +16,7 @@ extern int LLVMFuzzerInitialize(int *argc, char ***argv); static int run_one_file(const char *filename) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error = 0; if (git_futils_readbuffer(&buf, filename) < 0) { @@ -27,7 +27,7 @@ static int run_one_file(const char *filename) LLVMFuzzerTestOneInput((const unsigned char *)buf.ptr, buf.size); exit: - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } diff --git a/include/git2/buffer.h b/include/git2/buffer.h index 926f1332dfe..9fa97203457 100644 --- a/include/git2/buffer.h +++ b/include/git2/buffer.h @@ -23,110 +23,50 @@ GIT_BEGIN_DECL * * Sometimes libgit2 wants to return an allocated data buffer to the * caller and have the caller take responsibility for freeing that memory. - * This can be awkward if the caller does not have easy access to the same - * allocation functions that libgit2 is using. In those cases, libgit2 - * will fill in a `git_buf` and the caller can use `git_buf_dispose()` to - * release it when they are done. + * To make ownership clear in these cases, libgit2 uses `git_buf` to + * return this data. Callers should use `git_buf_dispose()` to release + * the memory when they are done. * - * A `git_buf` may also be used for the caller to pass in a reference to - * a block of memory they hold. In this case, libgit2 will not resize or - * free the memory, but will read from it as needed. - * - * Some APIs may occasionally do something slightly unusual with a buffer, - * such as setting `ptr` to a value that was passed in by the user. In - * those cases, the behavior will be clearly documented by the API. + * A `git_buf` contains a pointer to a NUL-terminated C string, and + * the length of the string (not including the NUL terminator). */ typedef struct { /** - * The buffer contents. - * - * `ptr` points to the start of the allocated memory. If it is NULL, - * then the `git_buf` is considered empty and libgit2 will feel free - * to overwrite it with new data. + * The buffer contents. `ptr` points to the start of the buffer + * being returned. The buffer's length (in bytes) is specified + * by the `size` member of the structure, and contains a NUL + * terminator at position `(size + 1)`. */ - char *ptr; + char *ptr; /** - * `asize` holds the known total amount of allocated memory if the `ptr` - * was allocated by libgit2. It may be larger than `size`. If `ptr` - * was not allocated by libgit2 and should not be resized and/or freed, - * then `asize` will be set to zero. + * This field is reserved and unused. */ - size_t asize; + size_t reserved; /** - * `size` holds the size (in bytes) of the data that is actually used. + * The length (in bytes) of the buffer pointed to by `ptr`, + * not including a NUL terminator. */ size_t size; } git_buf; /** - * Static initializer for git_buf from static buffer + * Use to initialize a `git_buf` before passing it to a function that + * will populate it. */ -#define GIT_BUF_INIT_CONST(STR,LEN) { (char *)(STR), 0, (size_t)(LEN) } +#define GIT_BUF_INIT { NULL, 0, 0 } /** * Free the memory referred to by the git_buf. * * Note that this does not free the `git_buf` itself, just the memory - * pointed to by `buffer->ptr`. This will not free the memory if it looks - * like it was not allocated internally, but it will clear the buffer back - * to the empty state. + * pointed to by `buffer->ptr`. * * @param buffer The buffer to deallocate */ GIT_EXTERN(void) git_buf_dispose(git_buf *buffer); -/** - * Resize the buffer allocation to make more space. - * - * This will attempt to grow the buffer to accommodate the target size. - * - * If the buffer refers to memory that was not allocated by libgit2 (i.e. - * the `asize` field is zero), then `ptr` will be replaced with a newly - * allocated block of data. Be careful so that memory allocated by the - * caller is not lost. As a special variant, if you pass `target_size` as - * 0 and the memory is not allocated by libgit2, this will allocate a new - * buffer of size `size` and copy the external data into it. - * - * Currently, this will never shrink a buffer, only expand it. - * - * If the allocation fails, this will return an error and the buffer will be - * marked as invalid for future operations, invaliding the contents. - * - * @param buffer The buffer to be resized; may or may not be allocated yet - * @param target_size The desired available size - * @return 0 on success, -1 on allocation failure - */ -GIT_EXTERN(int) git_buf_grow(git_buf *buffer, size_t target_size); - -/** - * Set buffer to a copy of some raw data. - * - * @param buffer The buffer to set - * @param data The data to copy into the buffer - * @param datalen The length of the data to copy into the buffer - * @return 0 on success, -1 on allocation failure - */ -GIT_EXTERN(int) git_buf_set( - git_buf *buffer, const void *data, size_t datalen); - -/** -* Check quickly if buffer looks like it contains binary data -* -* @param buf Buffer to check -* @return 1 if buffer looks like non-text data -*/ -GIT_EXTERN(int) git_buf_is_binary(const git_buf *buf); - -/** -* Check quickly if buffer contains a NUL byte -* -* @param buf Buffer to check -* @return 1 if buffer contains a NUL byte -*/ -GIT_EXTERN(int) git_buf_contains_nul(const git_buf *buf); - GIT_END_DECL /** @} */ diff --git a/src/apply.c b/src/apply.c index 7c65cd79db6..18304da4df7 100644 --- a/src/apply.c +++ b/src/apply.c @@ -265,7 +265,7 @@ static int apply_hunk( } static int apply_hunks( - git_buf *out, + git_str *out, const char *source, size_t source_len, git_patch *patch, @@ -286,7 +286,7 @@ static int apply_hunks( } git_vector_foreach(&image.lines, i, line) - git_buf_put(out, line->content, line->content_len); + git_str_put(out, line->content, line->content_len); done: patch_image_free(&image); @@ -295,24 +295,24 @@ static int apply_hunks( } static int apply_binary_delta( - git_buf *out, + git_str *out, const char *source, size_t source_len, git_diff_binary_file *binary_file) { - git_buf inflated = GIT_BUF_INIT; + git_str inflated = GIT_STR_INIT; int error = 0; /* no diff means identical contents */ if (binary_file->datalen == 0) - return git_buf_put(out, source, source_len); + return git_str_put(out, source, source_len); error = git_zstream_inflatebuf(&inflated, binary_file->data, binary_file->datalen); if (!error && inflated.size != binary_file->inflatedlen) { error = apply_err("inflated delta does not match expected length"); - git_buf_dispose(out); + git_str_dispose(out); } if (error < 0) @@ -330,7 +330,7 @@ static int apply_binary_delta( out->asize = data_len; } else if (binary_file->type == GIT_DIFF_BINARY_LITERAL) { - git_buf_swap(out, &inflated); + git_str_swap(out, &inflated); } else { error = apply_err("unknown binary delta type"); @@ -338,17 +338,17 @@ static int apply_binary_delta( } done: - git_buf_dispose(&inflated); + git_str_dispose(&inflated); return error; } static int apply_binary( - git_buf *out, + git_str *out, const char *source, size_t source_len, git_patch *patch) { - git_buf reverse = GIT_BUF_INIT; + git_str reverse = GIT_STR_INIT; int error = 0; if (!patch->binary.contains_data) { @@ -378,14 +378,14 @@ static int apply_binary( done: if (error < 0) - git_buf_dispose(out); + git_str_dispose(out); - git_buf_dispose(&reverse); + git_str_dispose(&reverse); return error; } int git_apply__patch( - git_buf *contents_out, + git_str *contents_out, char **filename_out, unsigned int *mode_out, const char *source, @@ -423,13 +423,13 @@ int git_apply__patch( else if (patch->hunks.size) error = apply_hunks(contents_out, source, source_len, patch, &ctx); else - error = git_buf_put(contents_out, source, source_len); + error = git_str_put(contents_out, source, source_len); if (error) goto done; if (patch->delta->status == GIT_DELTA_DELETED && - git_buf_len(contents_out) > 0) { + git_str_len(contents_out) > 0) { error = apply_err("removal patch leaves file contents"); goto done; } @@ -456,7 +456,7 @@ static int apply_one( const git_apply_options *opts) { git_patch *patch = NULL; - git_buf pre_contents = GIT_BUF_INIT, post_contents = GIT_BUF_INIT; + git_str pre_contents = GIT_STR_INIT, post_contents = GIT_STR_INIT; const git_diff_delta *delta; char *filename = NULL; unsigned int mode; @@ -579,8 +579,8 @@ static int apply_one( git_strmap_delete(removed_paths, delta->new_file.path); done: - git_buf_dispose(&pre_contents); - git_buf_dispose(&post_contents); + git_str_dispose(&pre_contents); + git_str_dispose(&post_contents); git__free(filename); git_patch_free(patch); diff --git a/src/apply.h b/src/apply.h index 11ec7563708..e990a71071c 100644 --- a/src/apply.h +++ b/src/apply.h @@ -11,10 +11,10 @@ #include "git2/patch.h" #include "git2/apply.h" -#include "buffer.h" +#include "str.h" extern int git_apply__patch( - git_buf *out, + git_str *out, char **filename, unsigned int *mode, const char *source, diff --git a/src/attr.c b/src/attr.c index 95b49e3de41..5849e701f60 100644 --- a/src/attr.c +++ b/src/attr.c @@ -338,7 +338,7 @@ GIT_INLINE(int) preload_attr_file( } static int system_attr_file( - git_buf *out, + git_str *out, git_attr_session *attr_session) { int error; @@ -366,11 +366,11 @@ static int system_attr_file( if (attr_session->sysdir.size == 0) return GIT_ENOTFOUND; - /* We can safely provide a git_buf with no allocation (asize == 0) to - * a consumer. This allows them to treat this as a regular `git_buf`, - * but their call to `git_buf_dispose` will not attempt to free it. + /* We can safely provide a git_str with no allocation (asize == 0) to + * a consumer. This allows them to treat this as a regular `git_str`, + * but their call to `git_str_dispose` will not attempt to free it. */ - git_buf_attach_notowned( + git_str_attach_notowned( out, attr_session->sysdir.ptr, attr_session->sysdir.size); return 0; } @@ -380,7 +380,7 @@ static int attr_setup( git_attr_session *attr_session, git_attr_options *opts) { - git_buf system = GIT_BUF_INIT, info = GIT_BUF_INIT; + git_str system = GIT_STR_INIT, info = GIT_STR_INIT; git_attr_file_source index_source = { GIT_ATTR_FILE_SOURCE_INDEX, NULL, GIT_ATTR_FILE, NULL }; git_attr_file_source head_source = { GIT_ATTR_FILE_SOURCE_HEAD, NULL, GIT_ATTR_FILE, NULL }; git_attr_file_source commit_source = { GIT_ATTR_FILE_SOURCE_COMMIT, NULL, GIT_ATTR_FILE, NULL }; @@ -411,7 +411,7 @@ static int attr_setup( git_repository_attr_cache(repo)->cfg_attr_file)) < 0) goto out; - if ((error = git_repository_item_path(&info, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || + if ((error = git_repository__item_path(&info, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || (error = preload_attr_file(repo, attr_session, info.ptr, GIT_ATTR_FILE_INREPO)) < 0) { if (error != GIT_ENOTFOUND) goto out; @@ -447,8 +447,8 @@ static int attr_setup( attr_session->init_setup = 1; out: - git_buf_dispose(&system); - git_buf_dispose(&info); + git_str_dispose(&system); + git_str_dispose(&info); return error; } @@ -625,7 +625,7 @@ static int collect_attr_files( git_vector *files) { int error = 0; - git_buf dir = GIT_BUF_INIT, attrfile = GIT_BUF_INIT; + git_str dir = GIT_STR_INIT, attrfile = GIT_STR_INIT; const char *workdir = git_repository_workdir(repo); attr_walk_up_info info = { NULL }; @@ -653,7 +653,7 @@ static int collect_attr_files( * - $GIT_PREFIX/etc/gitattributes */ - if ((error = git_repository_item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || + if ((error = git_repository__item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || (error = push_attr_file(repo, attr_session, files, attrfile.ptr, GIT_ATTR_FILE_INREPO)) < 0) { if (error != GIT_ENOTFOUND) goto cleanup; @@ -693,8 +693,8 @@ static int collect_attr_files( cleanup: if (error < 0) release_attr_files(files); - git_buf_dispose(&attrfile); - git_buf_dispose(&dir); + git_str_dispose(&attrfile); + git_str_dispose(&dir); return error; } diff --git a/src/attr_file.c b/src/attr_file.c index 71bd20a0f64..09f0ce1b8af 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -117,13 +117,13 @@ int git_attr_file__load( git_tree *tree = NULL; git_tree_entry *tree_entry = NULL; git_blob *blob = NULL; - git_buf content = GIT_BUF_INIT; + git_str content = GIT_STR_INIT; const char *content_str; git_attr_file *file; struct stat st; bool nonexistent = false; int bom_offset; - git_buf_bom_t bom; + git_str_bom_t bom; git_oid id; git_object_size_t blobsize; @@ -143,7 +143,7 @@ int git_attr_file__load( blobsize = git_blob_rawsize(blob); GIT_ERROR_CHECK_BLOBSIZE(blobsize); - git_buf_put(&content, git_blob_rawcontent(blob), (size_t)blobsize); + git_str_put(&content, git_blob_rawcontent(blob), (size_t)blobsize); break; } case GIT_ATTR_FILE_SOURCE_FILE: { @@ -198,7 +198,7 @@ int git_attr_file__load( blobsize = git_blob_rawsize(blob); GIT_ERROR_CHECK_BLOBSIZE(blobsize); - if ((error = git_buf_put(&content, + if ((error = git_str_put(&content, git_blob_rawcontent(blob), (size_t)blobsize)) < 0) goto cleanup; @@ -213,10 +213,10 @@ int git_attr_file__load( goto cleanup; /* advance over a UTF8 BOM */ - content_str = git_buf_cstr(&content); - bom_offset = git_buf_detect_bom(&bom, &content); + content_str = git_str_cstr(&content); + bom_offset = git_str_detect_bom(&bom, &content); - if (bom == GIT_BUF_BOM_UTF8) + if (bom == GIT_STR_BOM_UTF8) content_str += bom_offset; /* store the key of the attr_reader; don't bother with cache @@ -250,7 +250,7 @@ int git_attr_file__load( git_tree_entry_free(tree_entry); git_tree_free(tree); git_commit_free(commit); - git_buf_dispose(&content); + git_str_dispose(&content); return error; } @@ -435,7 +435,7 @@ int git_attr_file__lookup_one( int git_attr_file__load_standalone(git_attr_file **out, const char *path) { - git_buf content = GIT_BUF_INIT; + git_str content = GIT_STR_INIT; git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_FILE }; git_attr_file *file = NULL; int error; @@ -457,7 +457,7 @@ int git_attr_file__load_standalone(git_attr_file **out, const char *path) out: if (error < 0) git_attr_file__free(file); - git_buf_dispose(&content); + git_str_dispose(&content); return error; } @@ -558,7 +558,7 @@ int git_attr_path__init( ssize_t root; /* build full path as best we can */ - git_buf_init(&info->full, 0); + git_str_init(&info->full, 0); if (git_path_join_unrooted(&info->full, path, base, &root) < 0) return -1; @@ -605,7 +605,7 @@ int git_attr_path__init( void git_attr_path__free(git_attr_path *info) { - git_buf_dispose(&info->full); + git_str_dispose(&info->full); info->path = NULL; info->basename = NULL; } @@ -1020,8 +1020,8 @@ void git_attr_session__free(git_attr_session *session) if (!session) return; - git_buf_dispose(&session->sysdir); - git_buf_dispose(&session->tmp); + git_str_dispose(&session->sysdir); + git_str_dispose(&session->tmp); memset(session, 0, sizeof(git_attr_session)); } diff --git a/src/attr_file.h b/src/attr_file.h index d634e6da948..08630d1a6eb 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -13,7 +13,7 @@ #include "git2/attr.h" #include "vector.h" #include "pool.h" -#include "buffer.h" +#include "str.h" #include "futils.h" #define GIT_ATTR_FILE ".gitattributes" @@ -118,7 +118,7 @@ struct git_attr_file_entry { }; typedef struct { - git_buf full; + git_str full; char *path; char *basename; int is_dir; @@ -132,8 +132,8 @@ typedef struct { int key; unsigned int init_setup:1, init_sysdir:1; - git_buf sysdir; - git_buf tmp; + git_str sysdir; + git_str tmp; } git_attr_session; extern int git_attr_session__init(git_attr_session *attr_session, git_repository *repo); diff --git a/src/attrcache.c b/src/attrcache.c index 2b36b7a9c98..98d73cbc3ba 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -161,7 +161,7 @@ static int attr_cache_lookup( git_attr_file_source *source) { int error = 0; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; const char *wd = git_repository_workdir(repo); const char *filename; git_attr_cache *cache = git_repository_attr_cache(repo); @@ -170,9 +170,9 @@ static int attr_cache_lookup( /* join base and path as needed */ if (source->base != NULL && git_path_root(source->filename) < 0) { - git_buf *p = attr_session ? &attr_session->tmp : &path; + git_str *p = attr_session ? &attr_session->tmp : &path; - if (git_buf_joinpath(p, source->base, source->filename) < 0 || + if (git_str_joinpath(p, source->base, source->filename) < 0 || git_path_validate_workdir_buf(repo, p) < 0) return -1; @@ -203,7 +203,7 @@ static int attr_cache_lookup( *out_file = file; *out_entry = entry; - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -281,7 +281,7 @@ bool git_attr_cache__is_cached( static int attr_cache__lookup_path( char **out, git_config *cfg, const char *key, const char *fallback) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error; git_config_entry *entry = NULL; @@ -296,17 +296,17 @@ static int attr_cache__lookup_path( /* expand leading ~/ as needed */ if (cfgval && cfgval[0] == '~' && cfgval[1] == '/') { if (! (error = git_sysdir_expand_global_file(&buf, &cfgval[2]))) - *out = git_buf_detach(&buf); + *out = git_str_detach(&buf); } else if (cfgval) { *out = git__strdup(cfgval); } } else if (!git_sysdir_find_xdg_file(&buf, fallback)) { - *out = git_buf_detach(&buf); + *out = git_str_detach(&buf); } git_config_entry_free(entry); - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } diff --git a/src/blob.c b/src/blob.c index 09b5b5d9121..6f57d09e4ac 100644 --- a/src/blob.c +++ b/src/blob.c @@ -12,6 +12,7 @@ #include "git2/repository.h" #include "git2/odb_backend.h" +#include "buf.h" #include "filebuf.h" #include "filter.h" @@ -35,12 +36,12 @@ git_object_size_t git_blob_rawsize(const git_blob *blob) return (git_object_size_t)git_odb_object_size(blob->data.odb); } -int git_blob__getbuf(git_buf *buffer, git_blob *blob) +int git_blob__getbuf(git_str *buffer, git_blob *blob) { git_object_size_t size = git_blob_rawsize(blob); GIT_ERROR_CHECK_BLOBSIZE(size); - return git_buf_set(buffer, git_blob_rawcontent(blob), (size_t)size); + return git_str_set(buffer, git_blob_rawcontent(blob), (size_t)size); } void git_blob__free(void *_blob) @@ -142,9 +143,9 @@ static int write_file_filtered( git_repository* repo) { int error; - git_buf tgt = GIT_BUF_INIT; + git_str tgt = GIT_STR_INIT; - error = git_filter_list_apply_to_file(&tgt, fl, repo, full_path); + error = git_filter_list__apply_to_file(&tgt, fl, repo, full_path); /* Write the file to disk if it was properly filtered */ if (!error) { @@ -153,7 +154,7 @@ static int write_file_filtered( error = git_odb_write(id, odb, tgt.ptr, tgt.size, GIT_OBJECT_BLOB); } - git_buf_dispose(&tgt); + git_str_dispose(&tgt); return error; } @@ -193,7 +194,7 @@ int git_blob__create_from_paths( git_odb *odb = NULL; git_object_size_t size; mode_t mode; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; GIT_ASSERT_ARG(hint_path || !try_load_filters); @@ -261,7 +262,7 @@ int git_blob__create_from_paths( done: git_odb_free(odb); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -276,11 +277,11 @@ int git_blob_create_from_disk( git_oid *id, git_repository *repo, const char *path) { int error; - git_buf full_path = GIT_BUF_INIT; + git_str full_path = GIT_STR_INIT; const char *workdir, *hintpath = NULL; if ((error = git_path_prettify(&full_path, path, NULL)) < 0) { - git_buf_dispose(&full_path); + git_str_dispose(&full_path); return error; } @@ -290,9 +291,9 @@ int git_blob_create_from_disk( hintpath = full_path.ptr + strlen(workdir); error = git_blob__create_from_paths( - id, NULL, repo, git_buf_cstr(&full_path), hintpath, 0, !!hintpath); + id, NULL, repo, git_str_cstr(&full_path), hintpath, 0, !!hintpath); - git_buf_dispose(&full_path); + git_str_dispose(&full_path); return error; } @@ -330,7 +331,7 @@ static int blob_writestream_write(git_writestream *_stream, const char *buffer, int git_blob_create_from_stream(git_writestream **out, git_repository *repo, const char *hintpath) { int error; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; blob_writestream *stream; GIT_ASSERT_ARG(out); @@ -349,11 +350,11 @@ int git_blob_create_from_stream(git_writestream **out, git_repository *repo, con stream->parent.close = blob_writestream_close; stream->parent.free = blob_writestream_free; - if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0 - || (error = git_buf_joinpath(&path, path.ptr, "streamed")) < 0) + if ((error = git_repository__item_path(&path, repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0 + || (error = git_str_joinpath(&path, path.ptr, "streamed")) < 0) goto cleanup; - if ((error = git_filebuf_open_withsize(&stream->fbuf, git_buf_cstr(&path), GIT_FILEBUF_TEMPORARY, + if ((error = git_filebuf_open_withsize(&stream->fbuf, git_str_cstr(&path), GIT_FILEBUF_TEMPORARY, 0666, 2 * 1024 * 1024)) < 0) goto cleanup; @@ -363,7 +364,7 @@ int git_blob_create_from_stream(git_writestream **out, git_repository *repo, con if (error < 0) blob_writestream_free((git_writestream *) stream); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -391,16 +392,16 @@ int git_blob_create_from_stream_commit(git_oid *out, git_writestream *_stream) int git_blob_is_binary(const git_blob *blob) { - git_buf content = GIT_BUF_INIT; + git_str content = GIT_STR_INIT; git_object_size_t size; GIT_ASSERT_ARG(blob); size = git_blob_rawsize(blob); - git_buf_attach_notowned(&content, git_blob_rawcontent(blob), + git_str_attach_notowned(&content, git_blob_rawcontent(blob), (size_t)min(size, GIT_FILTER_BYTES_TO_CHECK_NUL)); - return git_buf_is_binary(&content); + return git_str_is_binary(&content); } int git_blob_filter_options_init( @@ -418,10 +419,10 @@ int git_blob_filter( const char *path, git_blob_filter_options *given_opts) { - int error = 0; - git_filter_list *fl = NULL; git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT; git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT; + git_filter_list *fl = NULL; + int error = 0; GIT_ASSERT_ARG(blob); GIT_ASSERT_ARG(path); @@ -430,9 +431,6 @@ int git_blob_filter( GIT_ERROR_CHECK_VERSION( given_opts, GIT_BLOB_FILTER_OPTIONS_VERSION, "git_blob_filter_options"); - if (git_buf_sanitize(out) < 0) - return -1; - if (given_opts != NULL) memcpy(&opts, given_opts, sizeof(git_blob_filter_options)); diff --git a/src/blob.h b/src/blob.h index e5770991eb7..9a5dda2254e 100644 --- a/src/blob.h +++ b/src/blob.h @@ -38,7 +38,7 @@ struct git_blob { void git_blob__free(void *blob); int git_blob__parse(void *blob, git_odb_object *obj); int git_blob__parse_raw(void *blob, const char *data, size_t size); -int git_blob__getbuf(git_buf *buffer, git_blob *blob); +int git_blob__getbuf(git_str *buffer, git_blob *blob); extern int git_blob__create_from_paths( git_oid *out_oid, diff --git a/src/branch.c b/src/branch.c index e6818a86df5..cf985f15364 100644 --- a/src/branch.c +++ b/src/branch.c @@ -7,6 +7,7 @@ #include "branch.h" +#include "buf.h" #include "commit.h" #include "tag.h" #include "config.h" @@ -27,11 +28,11 @@ static int retrieve_branch_reference( git_reference *branch = NULL; int error = 0; char *prefix; - git_buf ref_name = GIT_BUF_INIT; + git_str ref_name = GIT_STR_INIT; prefix = is_remote ? GIT_REFS_REMOTES_DIR : GIT_REFS_HEADS_DIR; - if ((error = git_buf_joinpath(&ref_name, prefix, branch_name)) < 0) + if ((error = git_str_joinpath(&ref_name, prefix, branch_name)) < 0) /* OOM */; else if ((error = git_reference_lookup(&branch, repo, ref_name.ptr)) < 0) git_error_set( @@ -40,7 +41,7 @@ static int retrieve_branch_reference( *branch_reference_out = branch; /* will be NULL on error */ - git_buf_dispose(&ref_name); + git_str_dispose(&ref_name); return error; } @@ -62,8 +63,8 @@ static int create_branch( { int is_unmovable_head = 0; git_reference *branch = NULL; - git_buf canonical_branch_name = GIT_BUF_INIT, - log_message = GIT_BUF_INIT; + git_str canonical_branch_name = GIT_STR_INIT, + log_message = GIT_STR_INIT; int error = -1; int bare = git_repository_is_bare(repository); @@ -96,22 +97,22 @@ static int create_branch( goto cleanup; } - if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0) + if (git_str_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0) goto cleanup; - if (git_buf_printf(&log_message, "branch: Created from %s", from) < 0) + if (git_str_printf(&log_message, "branch: Created from %s", from) < 0) goto cleanup; error = git_reference_create(&branch, repository, - git_buf_cstr(&canonical_branch_name), git_commit_id(commit), force, - git_buf_cstr(&log_message)); + git_str_cstr(&canonical_branch_name), git_commit_id(commit), force, + git_str_cstr(&log_message)); if (!error) *ref_out = branch; cleanup: - git_buf_dispose(&canonical_branch_name); - git_buf_dispose(&log_message); + git_str_dispose(&canonical_branch_name); + git_str_dispose(&log_message); return error; } @@ -174,7 +175,7 @@ int git_branch_is_checked_out(const git_reference *branch) int git_branch_delete(git_reference *branch) { int is_head; - git_buf config_section = GIT_BUF_INIT; + git_str config_section = GIT_STR_INIT; int error = -1; GIT_ASSERT_ARG(branch); @@ -200,18 +201,18 @@ int git_branch_delete(git_reference *branch) return -1; } - if (git_buf_join(&config_section, '.', "branch", + if (git_str_join(&config_section, '.', "branch", git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0) goto on_error; if (git_config_rename_section( - git_reference_owner(branch), git_buf_cstr(&config_section), NULL) < 0) + git_reference_owner(branch), git_str_cstr(&config_section), NULL) < 0) goto on_error; error = git_reference_delete(branch); on_error: - git_buf_dispose(&config_section); + git_str_dispose(&config_section); return error; } @@ -286,10 +287,10 @@ int git_branch_move( const char *new_branch_name, int force) { - git_buf new_reference_name = GIT_BUF_INIT, - old_config_section = GIT_BUF_INIT, - new_config_section = GIT_BUF_INIT, - log_message = GIT_BUF_INIT; + git_str new_reference_name = GIT_STR_INIT, + old_config_section = GIT_STR_INIT, + new_config_section = GIT_STR_INIT, + log_message = GIT_STR_INIT; int error; GIT_ASSERT_ARG(branch); @@ -298,35 +299,35 @@ int git_branch_move( if (!git_reference_is_branch(branch)) return not_a_local_branch(git_reference_name(branch)); - if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0) + if ((error = git_str_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0) goto done; - if ((error = git_buf_printf(&log_message, "branch: renamed %s to %s", - git_reference_name(branch), git_buf_cstr(&new_reference_name))) < 0) + if ((error = git_str_printf(&log_message, "branch: renamed %s to %s", + git_reference_name(branch), git_str_cstr(&new_reference_name))) < 0) goto done; /* first update ref then config so failure won't trash config */ error = git_reference_rename( - out, branch, git_buf_cstr(&new_reference_name), force, - git_buf_cstr(&log_message)); + out, branch, git_str_cstr(&new_reference_name), force, + git_str_cstr(&log_message)); if (error < 0) goto done; - git_buf_join(&old_config_section, '.', "branch", + git_str_join(&old_config_section, '.', "branch", git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)); - git_buf_join(&new_config_section, '.', "branch", new_branch_name); + git_str_join(&new_config_section, '.', "branch", new_branch_name); error = git_config_rename_section( git_reference_owner(branch), - git_buf_cstr(&old_config_section), - git_buf_cstr(&new_config_section)); + git_str_cstr(&old_config_section), + git_str_cstr(&new_config_section)); done: - git_buf_dispose(&new_reference_name); - git_buf_dispose(&old_config_section); - git_buf_dispose(&new_config_section); - git_buf_dispose(&log_message); + git_str_dispose(&new_reference_name); + git_str_dispose(&old_config_section); + git_str_dispose(&new_config_section); + git_str_dispose(&log_message); return error; } @@ -384,20 +385,20 @@ int git_branch_name( } static int retrieve_upstream_configuration( - git_buf *out, + git_str *out, const git_config *config, const char *canonical_branch_name, const char *format) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error; - if (git_buf_printf(&buf, format, + if (git_str_printf(&buf, format, canonical_branch_name + strlen(GIT_REFS_HEADS_DIR)) < 0) return -1; - error = git_config_get_string_buf(out, config, git_buf_cstr(&buf)); - git_buf_dispose(&buf); + error = git_config__get_string_buf(out, config, git_str_cstr(&buf)); + git_str_dispose(&buf); return error; } @@ -406,20 +407,26 @@ int git_branch_upstream_name( git_repository *repo, const char *refname) { - git_buf remote_name = GIT_BUF_INIT; - git_buf merge_name = GIT_BUF_INIT; - git_buf buf = GIT_BUF_INIT; + GIT_BUF_WRAP_PRIVATE(out, git_branch__upstream_name, repo, refname); +} + +int git_branch__upstream_name( + git_str *out, + git_repository *repo, + const char *refname) +{ + git_str remote_name = GIT_STR_INIT; + git_str merge_name = GIT_STR_INIT; + git_str buf = GIT_STR_INIT; int error = -1; git_remote *remote = NULL; const git_refspec *refspec; git_config *config; GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(refname); - if ((error = git_buf_sanitize(out)) < 0) - return error; - if (!git_reference__is_branch(refname)) return not_a_local_branch(refname); @@ -434,75 +441,109 @@ int git_branch_upstream_name( &merge_name, config, refname, "branch.%s.merge")) < 0) goto cleanup; - if (git_buf_len(&remote_name) == 0 || git_buf_len(&merge_name) == 0) { + if (git_str_len(&remote_name) == 0 || git_str_len(&merge_name) == 0) { git_error_set(GIT_ERROR_REFERENCE, "branch '%s' does not have an upstream", refname); error = GIT_ENOTFOUND; goto cleanup; } - if (strcmp(".", git_buf_cstr(&remote_name)) != 0) { - if ((error = git_remote_lookup(&remote, repo, git_buf_cstr(&remote_name))) < 0) + if (strcmp(".", git_str_cstr(&remote_name)) != 0) { + if ((error = git_remote_lookup(&remote, repo, git_str_cstr(&remote_name))) < 0) goto cleanup; - refspec = git_remote__matching_refspec(remote, git_buf_cstr(&merge_name)); + refspec = git_remote__matching_refspec(remote, git_str_cstr(&merge_name)); if (!refspec) { error = GIT_ENOTFOUND; goto cleanup; } - if (git_refspec_transform(&buf, refspec, git_buf_cstr(&merge_name)) < 0) + if (git_refspec__transform(&buf, refspec, git_str_cstr(&merge_name)) < 0) goto cleanup; } else - if (git_buf_set(&buf, git_buf_cstr(&merge_name), git_buf_len(&merge_name)) < 0) + if (git_str_set(&buf, git_str_cstr(&merge_name), git_str_len(&merge_name)) < 0) goto cleanup; - error = git_buf_set(out, git_buf_cstr(&buf), git_buf_len(&buf)); + git_str_swap(out, &buf); cleanup: git_config_free(config); git_remote_free(remote); - git_buf_dispose(&remote_name); - git_buf_dispose(&merge_name); - git_buf_dispose(&buf); + git_str_dispose(&remote_name); + git_str_dispose(&merge_name); + git_str_dispose(&buf); return error; } -static int git_branch_upstream_with_format(git_buf *buf, git_repository *repo, const char *refname, const char *format, const char *format_name) +static int git_branch_upstream_with_format( + git_str *out, + git_repository *repo, + const char *refname, + const char *format, + const char *format_name) { - int error; git_config *cfg; + int error; if (!git_reference__is_branch(refname)) return not_a_local_branch(refname); - if ((error = git_repository_config__weakptr(&cfg, repo)) < 0) - return error; - - if ((error = git_buf_sanitize(buf)) < 0 || - (error = retrieve_upstream_configuration(buf, cfg, refname, format)) < 0) + if ((error = git_repository_config__weakptr(&cfg, repo)) < 0 || + (error = retrieve_upstream_configuration(out, cfg, refname, format)) < 0) return error; - if (git_buf_len(buf) == 0) { + if (git_str_len(out) == 0) { git_error_set(GIT_ERROR_REFERENCE, "branch '%s' does not have an upstream %s", refname, format_name); error = GIT_ENOTFOUND; - git_buf_clear(buf); } return error; } -int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname) +int git_branch_upstream_remote( + git_buf *out, + git_repository *repo, + const char *refname) { - return git_branch_upstream_with_format(buf, repo, refname, "branch.%s.remote", "remote"); + GIT_BUF_WRAP_PRIVATE(out, git_branch__upstream_remote, repo, refname); } -int git_branch_upstream_merge(git_buf *buf, git_repository *repo, const char *refname) +int git_branch__upstream_remote( + git_str *out, + git_repository *repo, + const char *refname) { - return git_branch_upstream_with_format(buf, repo, refname, "branch.%s.merge", "merge"); + return git_branch_upstream_with_format(out, repo, refname, "branch.%s.remote", "remote"); } -int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refname) +int git_branch_upstream_merge( + git_buf *out, + git_repository *repo, + const char *refname) +{ + GIT_BUF_WRAP_PRIVATE(out, git_branch__upstream_merge, repo, refname); +} + +int git_branch__upstream_merge( + git_str *out, + git_repository *repo, + const char *refname) +{ + return git_branch_upstream_with_format(out, repo, refname, "branch.%s.merge", "merge"); +} + +int git_branch_remote_name( + git_buf *out, + git_repository *repo, + const char *refname) +{ + GIT_BUF_WRAP_PRIVATE(out, git_branch__remote_name, repo, refname); +} + +int git_branch__remote_name( + git_str *out, + git_repository *repo, + const char *refname) { git_strarray remote_list = {0}; size_t i; @@ -511,13 +552,10 @@ int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refna int error = 0; char *remote_name = NULL; - GIT_ASSERT_ARG(buf); + GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(refname); - if ((error = git_buf_sanitize(buf)) < 0) - return error; - /* Verify that this is a remote branch */ if (!git_reference__is_remote(refname)) { git_error_set(GIT_ERROR_INVALID, "reference '%s' is not a remote branch.", @@ -557,8 +595,8 @@ int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refna } if (remote_name) { - git_buf_clear(buf); - error = git_buf_puts(buf, remote_name); + git_str_clear(out); + error = git_str_puts(out, remote_name); } else { git_error_set(GIT_ERROR_REFERENCE, "could not determine remote for '%s'", refname); @@ -567,7 +605,7 @@ int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refna cleanup: if (error < 0) - git_buf_dispose(buf); + git_str_dispose(out); git_strarray_dispose(&remote_list); return error; @@ -578,49 +616,49 @@ int git_branch_upstream( const git_reference *branch) { int error; - git_buf tracking_name = GIT_BUF_INIT; + git_str tracking_name = GIT_STR_INIT; - if ((error = git_branch_upstream_name(&tracking_name, + if ((error = git_branch__upstream_name(&tracking_name, git_reference_owner(branch), git_reference_name(branch))) < 0) return error; error = git_reference_lookup( tracking_out, git_reference_owner(branch), - git_buf_cstr(&tracking_name)); + git_str_cstr(&tracking_name)); - git_buf_dispose(&tracking_name); + git_str_dispose(&tracking_name); return error; } static int unset_upstream(git_config *config, const char *shortname) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - if (git_buf_printf(&buf, "branch.%s.remote", shortname) < 0) + if (git_str_printf(&buf, "branch.%s.remote", shortname) < 0) return -1; - if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0) + if (git_config_delete_entry(config, git_str_cstr(&buf)) < 0) goto on_error; - git_buf_clear(&buf); - if (git_buf_printf(&buf, "branch.%s.merge", shortname) < 0) + git_str_clear(&buf); + if (git_str_printf(&buf, "branch.%s.merge", shortname) < 0) goto on_error; - if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0) + if (git_config_delete_entry(config, git_str_cstr(&buf)) < 0) goto on_error; - git_buf_dispose(&buf); + git_str_dispose(&buf); return 0; on_error: - git_buf_dispose(&buf); + git_str_dispose(&buf); return -1; } int git_branch_set_upstream(git_reference *branch, const char *branch_name) { - git_buf key = GIT_BUF_INIT, remote_name = GIT_BUF_INIT, merge_refspec = GIT_BUF_INIT; + git_str key = GIT_STR_INIT, remote_name = GIT_STR_INIT, merge_refspec = GIT_STR_INIT; git_reference *upstream; git_repository *repo; git_remote *remote = NULL; @@ -662,31 +700,31 @@ int git_branch_set_upstream(git_reference *branch, const char *branch_name) * name on the remote is and use that. */ if (local) - error = git_buf_puts(&remote_name, "."); + error = git_str_puts(&remote_name, "."); else - error = git_branch_remote_name(&remote_name, repo, git_reference_name(upstream)); + error = git_branch__remote_name(&remote_name, repo, git_reference_name(upstream)); if (error < 0) goto on_error; /* Update the upsteam branch config with the new name */ - if (git_buf_printf(&key, "branch.%s.remote", shortname) < 0) + if (git_str_printf(&key, "branch.%s.remote", shortname) < 0) goto on_error; - if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&remote_name)) < 0) + if (git_config_set_string(config, git_str_cstr(&key), git_str_cstr(&remote_name)) < 0) goto on_error; if (local) { /* A local branch uses the upstream refname directly */ - if (git_buf_puts(&merge_refspec, git_reference_name(upstream)) < 0) + if (git_str_puts(&merge_refspec, git_reference_name(upstream)) < 0) goto on_error; } else { /* We transform the upstream branch name according to the remote's refspecs */ - if (git_remote_lookup(&remote, repo, git_buf_cstr(&remote_name)) < 0) + if (git_remote_lookup(&remote, repo, git_str_cstr(&remote_name)) < 0) goto on_error; fetchspec = git_remote__matching_dst_refspec(remote, git_reference_name(upstream)); - if (!fetchspec || git_refspec_rtransform(&merge_refspec, fetchspec, git_reference_name(upstream)) < 0) + if (!fetchspec || git_refspec__rtransform(&merge_refspec, fetchspec, git_reference_name(upstream)) < 0) goto on_error; git_remote_free(remote); @@ -694,25 +732,25 @@ int git_branch_set_upstream(git_reference *branch, const char *branch_name) } /* Update the merge branch config with the refspec */ - git_buf_clear(&key); - if (git_buf_printf(&key, "branch.%s.merge", shortname) < 0) + git_str_clear(&key); + if (git_str_printf(&key, "branch.%s.merge", shortname) < 0) goto on_error; - if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&merge_refspec)) < 0) + if (git_config_set_string(config, git_str_cstr(&key), git_str_cstr(&merge_refspec)) < 0) goto on_error; git_reference_free(upstream); - git_buf_dispose(&key); - git_buf_dispose(&remote_name); - git_buf_dispose(&merge_refspec); + git_str_dispose(&key); + git_str_dispose(&remote_name); + git_str_dispose(&merge_refspec); return 0; on_error: git_reference_free(upstream); - git_buf_dispose(&key); - git_buf_dispose(&remote_name); - git_buf_dispose(&merge_refspec); + git_str_dispose(&key); + git_str_dispose(&remote_name); + git_str_dispose(&merge_refspec); git_remote_free(remote); return -1; @@ -749,7 +787,7 @@ int git_branch_is_head( int git_branch_name_is_valid(int *valid, const char *name) { - git_buf ref_name = GIT_BUF_INIT; + git_str ref_name = GIT_STR_INIT; int error = 0; GIT_ASSERT(valid); @@ -765,13 +803,13 @@ int git_branch_name_is_valid(int *valid, const char *name) if (!name || name[0] == '-' || !git__strcmp(name, "HEAD")) goto done; - if ((error = git_buf_puts(&ref_name, GIT_REFS_HEADS_DIR)) < 0 || - (error = git_buf_puts(&ref_name, name)) < 0) + if ((error = git_str_puts(&ref_name, GIT_REFS_HEADS_DIR)) < 0 || + (error = git_str_puts(&ref_name, name)) < 0) goto done; error = git_reference_name_is_valid(valid, ref_name.ptr); done: - git_buf_dispose(&ref_name); + git_str_dispose(&ref_name); return error; } diff --git a/src/branch.h b/src/branch.h index 5ae227c05aa..b4db42a0137 100644 --- a/src/branch.h +++ b/src/branch.h @@ -9,10 +9,22 @@ #include "common.h" -#include "buffer.h" +#include "str.h" -int git_branch_upstream__name( - git_buf *tracking_name, +int git_branch__remote_name( + git_str *out, + git_repository *repo, + const char *refname); +int git_branch__upstream_remote( + git_str *out, + git_repository *repo, + const char *refname); +int git_branch__upstream_merge( + git_str *out, + git_repository *repo, + const char *refname); +int git_branch__upstream_name( + git_str *tracking_name, git_repository *repo, const char *canonical_branch_name); diff --git a/src/buf.c b/src/buf.c new file mode 100644 index 00000000000..652f5dd52c7 --- /dev/null +++ b/src/buf.c @@ -0,0 +1,126 @@ +/* + * 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 "buf.h" +#include "common.h" + +int git_buf_sanitize(git_buf *buf) +{ + GIT_ASSERT_ARG(buf); + + if (buf->reserved > 0) + buf->ptr[0] = '\0'; + else + buf->ptr = git_str__initstr; + + buf->size = 0; + return 0; +} + +int git_buf_tostr(git_str *out, git_buf *buf) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(buf); + + if (git_buf_sanitize(buf) < 0) + return -1; + + out->ptr = buf->ptr; + out->asize = buf->reserved; + out->size = buf->size; + + buf->ptr = git_str__initstr; + buf->reserved = 0; + buf->size = 0; + + return 0; +} + +int git_buf_fromstr(git_buf *out, git_str *str) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(str); + + out->ptr = str->ptr; + out->reserved = str->asize; + out->size = str->size; + + str->ptr = git_str__initstr; + str->asize = 0; + str->size = 0; + + return 0; +} + +void git_buf_dispose(git_buf *buf) +{ + if (!buf) + return; + + if (buf->ptr != git_str__initstr) + git__free(buf->ptr); + + buf->ptr = git_str__initstr; + buf->reserved = 0; + buf->size = 0; +} + +#ifndef GIT_DEPRECATE_HARD +int git_buf_grow(git_buf *buffer, size_t target_size) +{ + char *newptr; + + if (buffer->reserved >= target_size) + return 0; + + if (buffer->ptr == git_str__initstr) + newptr = git__malloc(target_size); + else + newptr = git__realloc(buffer->ptr, target_size); + + if (!newptr) + return -1; + + buffer->ptr = newptr; + buffer->reserved = target_size; + return 0; +} + +int git_buf_set(git_buf *buffer, const void *data, size_t datalen) +{ + size_t alloclen; + + GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, datalen, 1); + + if (git_buf_grow(buffer, alloclen) < 0) + return -1; + + memmove(buffer->ptr, data, datalen); + buffer->size = datalen; + buffer->ptr[buffer->size] = '\0'; + + return 0; +} + +int git_buf_is_binary(const git_buf *buf) +{ + git_str str = GIT_STR_INIT_CONST(buf->ptr, buf->size); + return git_str_is_binary(&str); +} + +int git_buf_contains_nul(const git_buf *buf) +{ + git_str str = GIT_STR_INIT_CONST(buf->ptr, buf->size); + return git_str_contains_nul(&str); +} + +void git_buf_free(git_buf *buffer) +{ + git_buf_dispose(buffer); +} + +#endif diff --git a/src/buf.h b/src/buf.h new file mode 100644 index 00000000000..4bc7f270957 --- /dev/null +++ b/src/buf.h @@ -0,0 +1,50 @@ +/* + * 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_buf_h__ +#define INCLUDE_buf_h__ + +#include "git2/buffer.h" +#include "common.h" + +/* + * Adapts a private API that takes a `git_str` into a public API that + * takes a `git_buf`. + */ + +#define GIT_BUF_WRAP_PRIVATE(buf, fn, ...) \ + { \ + git_str str = GIT_STR_INIT; \ + int error; \ + if ((error = git_buf_tostr(&str, buf)) == 0 && \ + (error = fn(&str, __VA_ARGS__)) == 0) \ + error = git_buf_fromstr(buf, &str); \ + git_str_dispose(&str); \ + return error; \ +} + +/** + * "Sanitizes" a buffer from user input. This simply ensures that the + * `git_buf` has nice defaults if the user didn't set the members to + * anything, so that if we return early we don't leave it populated + * with nonsense. + */ +extern int git_buf_sanitize(git_buf *from_user); + +/** + * Populate a `git_str` from a `git_buf` for passing to libgit2 internal + * functions. Sanitizes the given `git_buf` before proceeding. The + * `git_buf` will no longer point to this memory. + */ +extern int git_buf_tostr(git_str *out, git_buf *buf); + +/** + * Populate a `git_buf` from a `git_str` for returning to a user. + * The `git_str` will no longer point to this memory. + */ +extern int git_buf_fromstr(git_buf *out, git_str *str); + +#endif diff --git a/src/buffer.h b/src/buffer.h deleted file mode 100644 index 75930e20944..00000000000 --- a/src/buffer.h +++ /dev/null @@ -1,374 +0,0 @@ -/* - * 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_buffer_h__ -#define INCLUDE_buffer_h__ - -#include "common.h" -#include "git2/strarray.h" -#include "git2/buffer.h" - -/* typedef struct { - * char *ptr; - * size_t asize, size; - * } git_buf; - */ - -typedef enum { - GIT_BUF_BOM_NONE = 0, - GIT_BUF_BOM_UTF8 = 1, - GIT_BUF_BOM_UTF16_LE = 2, - GIT_BUF_BOM_UTF16_BE = 3, - GIT_BUF_BOM_UTF32_LE = 4, - GIT_BUF_BOM_UTF32_BE = 5 -} git_buf_bom_t; - -typedef struct { - git_buf_bom_t bom; /* BOM found at head of text */ - unsigned int nul, cr, lf, crlf; /* NUL, CR, LF and CRLF counts */ - unsigned int printable, nonprintable; /* These are just approximations! */ -} git_buf_text_stats; - -extern char git_buf__initbuf[]; -extern char git_buf__oom[]; - -/* Use to initialize buffer structure when git_buf is on stack */ -#define GIT_BUF_INIT { git_buf__initbuf, 0, 0 } - -/** - * Static initializer for git_buf from static buffer - */ -#ifdef GIT_DEPRECATE_HARD -# define GIT_BUF_INIT_CONST(STR,LEN) { (char *)(STR), 0, (size_t)(LEN) } -#endif - -GIT_INLINE(bool) git_buf_is_allocated(const git_buf *buf) -{ - return (buf->ptr != NULL && buf->asize > 0); -} - -/** - * Initialize a git_buf structure. - * - * For the cases where GIT_BUF_INIT cannot be used to do static - * initialization. - */ -extern int git_buf_init(git_buf *buf, size_t initial_size); - -#ifdef GIT_DEPRECATE_HARD - -/** - * Resize the buffer allocation to make more space. - * - * This will attempt to grow the buffer to accommodate the target size. - * - * If the buffer refers to memory that was not allocated by libgit2 (i.e. - * the `asize` field is zero), then `ptr` will be replaced with a newly - * allocated block of data. Be careful so that memory allocated by the - * caller is not lost. As a special variant, if you pass `target_size` as - * 0 and the memory is not allocated by libgit2, this will allocate a new - * buffer of size `size` and copy the external data into it. - * - * Currently, this will never shrink a buffer, only expand it. - * - * If the allocation fails, this will return an error and the buffer will be - * marked as invalid for future operations, invaliding the contents. - * - * @param buffer The buffer to be resized; may or may not be allocated yet - * @param target_size The desired available size - * @return 0 on success, -1 on allocation failure - */ -int git_buf_grow(git_buf *buffer, size_t target_size); - -#endif - -/** - * Resize the buffer allocation to make more space. - * - * This will attempt to grow the buffer to accommodate the additional size. - * It is similar to `git_buf_grow`, but performs the new size calculation, - * checking for overflow. - * - * Like `git_buf_grow`, if this is a user-supplied buffer, this will allocate - * a new buffer. - */ -extern int git_buf_grow_by(git_buf *buffer, size_t additional_size); - -/** - * Attempt to grow the buffer to hold at least `target_size` bytes. - * - * If the allocation fails, this will return an error. If `mark_oom` is true, - * this will mark the buffer as invalid for future operations; if false, - * existing buffer content will be preserved, but calling code must handle - * that buffer was not expanded. If `preserve_external` is true, then any - * existing data pointed to be `ptr` even if `asize` is zero will be copied - * into the newly allocated buffer. - */ -extern int git_buf_try_grow( - git_buf *buf, size_t target_size, bool mark_oom); - -/** - * Sanitizes git_buf structures provided from user input. Users of the - * library, when providing git_buf's, may wish to provide a NULL ptr for - * ease of handling. The buffer routines, however, expect a non-NULL ptr - * always. This helper method simply handles NULL input, converting to a - * git_buf__initbuf. If a buffer with a non-NULL ptr is passed in, this method - * assures that the buffer is '\0'-terminated. - */ -extern int git_buf_sanitize(git_buf *buf); - -extern void git_buf_swap(git_buf *buf_a, git_buf *buf_b); -extern char *git_buf_detach(git_buf *buf); -extern int git_buf_attach(git_buf *buf, char *ptr, size_t asize); - -/* Populates a `git_buf` where the contents are not "owned" by the - * buffer, and calls to `git_buf_dispose` will not free the given buf. - */ -extern void git_buf_attach_notowned( - git_buf *buf, const char *ptr, size_t size); - -/** - * Test if there have been any reallocation failures with this git_buf. - * - * Any function that writes to a git_buf can fail due to memory allocation - * issues. If one fails, the git_buf will be marked with an OOM error and - * further calls to modify the buffer will fail. Check git_buf_oom() at the - * end of your sequence and it will be true if you ran out of memory at any - * point with that buffer. - * - * @return false if no error, true if allocation error - */ -GIT_INLINE(bool) git_buf_oom(const git_buf *buf) -{ - return (buf->ptr == git_buf__oom); -} - -/* - * Functions below that return int value error codes will return 0 on - * success or -1 on failure (which generally means an allocation failed). - * Using a git_buf where the allocation has failed with result in -1 from - * all further calls using that buffer. As a result, you can ignore the - * return code of these functions and call them in a series then just call - * git_buf_oom at the end. - */ - -#ifdef GIT_DEPRECATE_HARD -int git_buf_set(git_buf *buffer, const void *data, size_t datalen); -#endif - -int git_buf_sets(git_buf *buf, const char *string); -int git_buf_putc(git_buf *buf, char c); -int git_buf_putcn(git_buf *buf, char c, size_t len); -int git_buf_put(git_buf *buf, const char *data, size_t len); -int git_buf_puts(git_buf *buf, const char *string); -int git_buf_printf(git_buf *buf, const char *format, ...) GIT_FORMAT_PRINTF(2, 3); -int git_buf_vprintf(git_buf *buf, const char *format, va_list ap); -void git_buf_clear(git_buf *buf); -void git_buf_consume_bytes(git_buf *buf, size_t len); -void git_buf_consume(git_buf *buf, const char *end); -void git_buf_truncate(git_buf *buf, size_t len); -void git_buf_shorten(git_buf *buf, size_t amount); -void git_buf_truncate_at_char(git_buf *buf, char separator); -void git_buf_rtruncate_at_char(git_buf *path, char separator); - -/** General join with separator */ -int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...); -/** Fast join of two strings - first may legally point into `buf` data */ -int git_buf_join(git_buf *buf, char separator, const char *str_a, const char *str_b); -/** Fast join of three strings - cannot reference `buf` data */ -int git_buf_join3(git_buf *buf, char separator, const char *str_a, const char *str_b, const char *str_c); - -/** - * Join two strings as paths, inserting a slash between as needed. - * @return 0 on success, -1 on failure - */ -GIT_INLINE(int) git_buf_joinpath(git_buf *buf, const char *a, const char *b) -{ - return git_buf_join(buf, '/', a, b); -} - -GIT_INLINE(const char *) git_buf_cstr(const git_buf *buf) -{ - return buf->ptr; -} - -GIT_INLINE(size_t) git_buf_len(const git_buf *buf) -{ - return buf->size; -} - -int git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf); - -#define git_buf_PUTS(buf, str) git_buf_put(buf, str, sizeof(str) - 1) - -GIT_INLINE(ssize_t) git_buf_rfind_next(const git_buf *buf, char ch) -{ - ssize_t idx = (ssize_t)buf->size - 1; - while (idx >= 0 && buf->ptr[idx] == ch) idx--; - while (idx >= 0 && buf->ptr[idx] != ch) idx--; - return idx; -} - -GIT_INLINE(ssize_t) git_buf_rfind(const git_buf *buf, char ch) -{ - ssize_t idx = (ssize_t)buf->size - 1; - while (idx >= 0 && buf->ptr[idx] != ch) idx--; - return idx; -} - -GIT_INLINE(ssize_t) git_buf_find(const git_buf *buf, char ch) -{ - void *found = memchr(buf->ptr, ch, buf->size); - return found ? (ssize_t)((const char *)found - buf->ptr) : -1; -} - -/* Remove whitespace from the end of the buffer */ -void git_buf_rtrim(git_buf *buf); - -int git_buf_cmp(const git_buf *a, const git_buf *b); - -/* Quote and unquote a buffer as specified in - * http://marc.info/?l=git&m=112927316408690&w=2 - */ -int git_buf_quote(git_buf *buf); -int git_buf_unquote(git_buf *buf); - -/* Write data as base64 encoded in buffer */ -int git_buf_encode_base64(git_buf *buf, const char *data, size_t len); -/* Decode the given bas64 and write the result to the buffer */ -int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len); - -/* Write data as "base85" encoded in buffer */ -int git_buf_encode_base85(git_buf *buf, const char *data, size_t len); -/* Decode the given "base85" and write the result to the buffer */ -int git_buf_decode_base85(git_buf *buf, const char *base64, size_t len, size_t output_len); - -/* Decode the given percent-encoded string and write the result to the buffer */ -int git_buf_decode_percent(git_buf *buf, const char *str, size_t len); - -/* - * Insert, remove or replace a portion of the buffer. - * - * @param buf The buffer to work with - * - * @param where The location in the buffer where the transformation - * should be applied. - * - * @param nb_to_remove The number of chars to be removed. 0 to not - * remove any character in the buffer. - * - * @param data A pointer to the data which should be inserted. - * - * @param nb_to_insert The number of chars to be inserted. 0 to not - * insert any character from the buffer. - * - * @return 0 or an error code. - */ -int git_buf_splice( - git_buf *buf, - size_t where, - size_t nb_to_remove, - const char *data, - size_t nb_to_insert); - -/** - * Append string to buffer, prefixing each character from `esc_chars` with - * `esc_with` string. - * - * @param buf Buffer to append data to - * @param string String to escape and append - * @param esc_chars Characters to be escaped - * @param esc_with String to insert in from of each found character - * @return 0 on success, <0 on failure (probably allocation problem) - */ -extern int git_buf_puts_escaped( - git_buf *buf, - const char *string, - const char *esc_chars, - const char *esc_with); - -/** - * Append string escaping characters that are regex special - */ -GIT_INLINE(int) git_buf_puts_escape_regex(git_buf *buf, const char *string) -{ - return git_buf_puts_escaped(buf, string, "^.[]$()|*+?{}\\", "\\"); -} - -/** - * Unescape all characters in a buffer in place - * - * I.e. remove backslashes - */ -extern void git_buf_unescape(git_buf *buf); - -/** - * Replace all \r\n with \n. - * - * @return 0 on success, -1 on memory error - */ -extern int git_buf_crlf_to_lf(git_buf *tgt, const git_buf *src); - -/** - * Replace all \n with \r\n. Does not modify existing \r\n. - * - * @return 0 on success, -1 on memory error - */ -extern int git_buf_lf_to_crlf(git_buf *tgt, const git_buf *src); - -/** - * Fill buffer with the common prefix of a array of strings - * - * Buffer will be set to empty if there is no common prefix - */ -extern int git_buf_common_prefix(git_buf *buf, char *const *const strings, size_t count); - -/** - * Check if a buffer begins with a UTF BOM - * - * @param bom Set to the type of BOM detected or GIT_BOM_NONE - * @param buf Buffer in which to check the first bytes for a BOM - * @return Number of bytes of BOM data (or 0 if no BOM found) - */ -extern int git_buf_detect_bom(git_buf_bom_t *bom, const git_buf *buf); - -/** - * Gather stats for a piece of text - * - * Fill the `stats` structure with counts of unreadable characters, carriage - * returns, etc, so it can be used in heuristics. This automatically skips - * a trailing EOF (\032 character). Also it will look for a BOM at the - * start of the text and can be told to skip that as well. - * - * @param stats Structure to be filled in - * @param buf Text to process - * @param skip_bom Exclude leading BOM from stats if true - * @return Does the buffer heuristically look like binary data - */ -extern bool git_buf_gather_text_stats( - git_buf_text_stats *stats, const git_buf *buf, bool skip_bom); - -#ifdef GIT_DEPRECATE_HARD - -/** -* Check quickly if buffer looks like it contains binary data -* -* @param buf Buffer to check -* @return 1 if buffer looks like non-text data -*/ -int git_buf_is_binary(const git_buf *buf); - -/** -* Check quickly if buffer contains a NUL byte -* -* @param buf Buffer to check -* @return 1 if buffer contains a NUL byte -*/ -int git_buf_contains_nul(const git_buf *buf); - -#endif - -#endif diff --git a/src/checkout.c b/src/checkout.c index 3a171066b4e..b31918fc893 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -61,9 +61,9 @@ typedef struct { git_vector update_conflicts; git_vector *update_reuc; git_vector *update_names; - git_buf target_path; + git_str target_path; size_t target_len; - git_buf tmp; + git_str tmp; unsigned int strategy; int can_symlink; int respect_filemode; @@ -321,11 +321,11 @@ static int checkout_action_no_wd( } static int checkout_target_fullpath( - git_buf **out, checkout_data *data, const char *path) + git_str **out, checkout_data *data, const char *path) { - git_buf_truncate(&data->target_path, data->target_len); + git_str_truncate(&data->target_path, data->target_len); - if (path && git_buf_puts(&data->target_path, path) < 0) + if (path && git_str_puts(&data->target_path, path) < 0) return -1; if (git_path_validate_workdir_buf(data->repo, &data->target_path) < 0) @@ -339,7 +339,7 @@ static int checkout_target_fullpath( static bool wd_item_is_removable( checkout_data *data, const git_index_entry *wd) { - git_buf *full; + git_str *full; if (wd->mode != GIT_FILEMODE_TREE) return true; @@ -423,7 +423,7 @@ static int checkout_action_wd_only( /* copy the entry for issuing notification callback later */ git_index_entry saved_wd = *wd; - git_buf_sets(&data->tmp, wd->path); + git_str_sets(&data->tmp, wd->path); saved_wd.path = data->tmp.ptr; error = git_iterator_advance_over( @@ -476,7 +476,7 @@ static bool submodule_is_config_only( static bool checkout_is_empty_dir(checkout_data *data, const char *path) { - git_buf *fullpath; + git_str *fullpath; if (checkout_target_fullpath(&fullpath, data, path) < 0) return false; @@ -1584,7 +1584,7 @@ static int blob_content_to_link( git_blob *blob, const char *path) { - git_buf linktarget = GIT_BUF_INIT; + git_str linktarget = GIT_STR_INIT; int error; if ((error = mkpath2file(data, path, data->opts.dir_mode)) < 0) @@ -1594,10 +1594,10 @@ static int blob_content_to_link( return error; if (data->can_symlink) { - if ((error = p_symlink(git_buf_cstr(&linktarget), path)) < 0) + if ((error = p_symlink(git_str_cstr(&linktarget), path)) < 0) git_error_set(GIT_ERROR_OS, "could not create symlink %s", path); } else { - error = git_futils_fake_symlink(git_buf_cstr(&linktarget), path); + error = git_futils_fake_symlink(git_str_cstr(&linktarget), path); } if (!error) { @@ -1609,7 +1609,7 @@ static int blob_content_to_link( st->st_mode = GIT_FILEMODE_LINK; } - git_buf_dispose(&linktarget); + git_str_dispose(&linktarget); return error; } @@ -1636,7 +1636,7 @@ static int checkout_submodule_update_index( checkout_data *data, const git_diff_file *file) { - git_buf *fullpath; + git_str *fullpath; struct stat st; /* update the index unless prevented */ @@ -1772,7 +1772,7 @@ static int checkout_blob( checkout_data *data, const git_diff_file *file) { - git_buf *fullpath; + git_str *fullpath; struct stat st; int error = 0; @@ -1809,7 +1809,7 @@ static int checkout_remove_the_old( git_diff_delta *delta; const char *str; size_t i; - git_buf *fullpath; + git_str *fullpath; uint32_t flg = GIT_RMDIR_EMPTY_PARENTS | GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS; @@ -1927,40 +1927,40 @@ static int checkout_lookup_head_tree(git_tree **out, git_repository *repo) static int conflict_entry_name( - git_buf *out, + git_str *out, const char *side_name, const char *filename) { - if (git_buf_puts(out, side_name) < 0 || - git_buf_putc(out, ':') < 0 || - git_buf_puts(out, filename) < 0) + if (git_str_puts(out, side_name) < 0 || + git_str_putc(out, ':') < 0 || + git_str_puts(out, filename) < 0) return -1; return 0; } -static int checkout_path_suffixed(git_buf *path, const char *suffix) +static int checkout_path_suffixed(git_str *path, const char *suffix) { size_t path_len; int i = 0, error = 0; - if ((error = git_buf_putc(path, '~')) < 0 || (error = git_buf_puts(path, suffix)) < 0) + if ((error = git_str_putc(path, '~')) < 0 || (error = git_str_puts(path, suffix)) < 0) return -1; - path_len = git_buf_len(path); + path_len = git_str_len(path); - while (git_path_exists(git_buf_cstr(path)) && i < INT_MAX) { - git_buf_truncate(path, path_len); + while (git_path_exists(git_str_cstr(path)) && i < INT_MAX) { + git_str_truncate(path, path_len); - if ((error = git_buf_putc(path, '_')) < 0 || - (error = git_buf_printf(path, "%d", i)) < 0) + if ((error = git_str_putc(path, '_')) < 0 || + (error = git_str_printf(path, "%d", i)) < 0) return error; i++; } if (i == INT_MAX) { - git_buf_truncate(path, path_len); + git_str_truncate(path, path_len); git_error_set(GIT_ERROR_CHECKOUT, "could not write '%s': working directory file exists", path->ptr); return GIT_EEXISTS; @@ -1974,8 +1974,8 @@ static int checkout_write_entry( checkout_conflictdata *conflict, const git_index_entry *side) { - const char *hint_path, *suffix; - git_buf *fullpath; + const char *hint_path = NULL, *suffix; + git_str *fullpath; struct stat st; int error; @@ -2025,7 +2025,7 @@ static int checkout_write_entries( } static int checkout_merge_path( - git_buf *out, + git_str *out, checkout_data *data, checkout_conflictdata *conflict, git_merge_file_result *result) @@ -2033,7 +2033,7 @@ static int checkout_merge_path( const char *our_label_raw, *their_label_raw, *suffix; int error = 0; - if ((error = git_buf_joinpath(out, data->opts.target_directory, result->path)) < 0 || + if ((error = git_str_joinpath(out, data->opts.target_directory, result->path)) < 0 || (error = git_path_validate_workdir_buf(data->repo, out)) < 0) return error; @@ -2056,9 +2056,9 @@ static int checkout_write_merge( checkout_data *data, checkout_conflictdata *conflict) { - git_buf our_label = GIT_BUF_INIT, their_label = GIT_BUF_INIT, - path_suffixed = GIT_BUF_INIT, path_workdir = GIT_BUF_INIT, - in_data = GIT_BUF_INIT, out_data = GIT_BUF_INIT; + git_str our_label = GIT_STR_INIT, their_label = GIT_STR_INIT, + path_suffixed = GIT_STR_INIT, path_workdir = GIT_STR_INIT, + in_data = GIT_STR_INIT, out_data = GIT_STR_INIT; git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT; git_merge_file_result result = {0}; git_filebuf output = GIT_FILEBUF_INIT; @@ -2088,8 +2088,8 @@ static int checkout_write_merge( &their_label, opts.their_label, conflict->theirs->path)) < 0) goto done; - opts.our_label = git_buf_cstr(&our_label); - opts.their_label = git_buf_cstr(&their_label); + opts.our_label = git_str_cstr(&our_label); + opts.their_label = git_str_cstr(&their_label); } if ((error = git_merge_file_from_index(&result, data->repo, @@ -2106,7 +2106,7 @@ static int checkout_write_merge( goto done; if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0 && - (error = checkout_safe_for_update_only(data, git_buf_cstr(&path_workdir), result.mode)) <= 0) + (error = checkout_safe_for_update_only(data, git_str_cstr(&path_workdir), result.mode)) <= 0) goto done; if (!data->opts.disable_filters) { @@ -2127,7 +2127,7 @@ static int checkout_write_merge( } if ((error = mkpath2file(data, path_workdir.ptr, data->opts.dir_mode)) < 0 || - (error = git_filebuf_open(&output, git_buf_cstr(&path_workdir), GIT_FILEBUF_DO_NOT_BUFFER, result.mode)) < 0 || + (error = git_filebuf_open(&output, git_str_cstr(&path_workdir), GIT_FILEBUF_DO_NOT_BUFFER, result.mode)) < 0 || (error = git_filebuf_write(&output, out_data.ptr, out_data.size)) < 0 || (error = git_filebuf_commit(&output)) < 0) goto done; @@ -2135,13 +2135,13 @@ static int checkout_write_merge( done: git_filter_list_free(fl); - git_buf_dispose(&out_data); - git_buf_dispose(&our_label); - git_buf_dispose(&their_label); + git_str_dispose(&out_data); + git_str_dispose(&our_label); + git_str_dispose(&their_label); git_merge_file_result_free(&result); - git_buf_dispose(&path_workdir); - git_buf_dispose(&path_suffixed); + git_str_dispose(&path_workdir); + git_str_dispose(&path_suffixed); return error; } @@ -2321,8 +2321,8 @@ static void checkout_data_clear(checkout_data *data) git__free(data->pfx); data->pfx = NULL; - git_buf_dispose(&data->target_path); - git_buf_dispose(&data->tmp); + git_str_dispose(&data->target_path); + git_str_dispose(&data->tmp); git_index_free(data->index); data->index = NULL; @@ -2506,12 +2506,12 @@ static int checkout_data_init( (error = git_vector_init(&data->removes, 0, git__strcmp_cb)) < 0 || (error = git_vector_init(&data->remove_conflicts, 0, NULL)) < 0 || (error = git_vector_init(&data->update_conflicts, 0, NULL)) < 0 || - (error = git_buf_puts(&data->target_path, data->opts.target_directory)) < 0 || + (error = git_str_puts(&data->target_path, data->opts.target_directory)) < 0 || (error = git_path_to_dir(&data->target_path)) < 0 || (error = git_strmap_new(&data->mkdir_map)) < 0) goto cleanup; - data->target_len = git_buf_len(&data->target_path); + data->target_len = git_str_len(&data->target_path); git_attr_session__init(&data->attr_session, data->repo); @@ -2623,7 +2623,7 @@ int git_checkout_iterator( if (data.strategy & GIT_CHECKOUT_DRY_RUN) goto cleanup; - + data.total_steps = counts[CHECKOUT_ACTION__REMOVE] + counts[CHECKOUT_ACTION__REMOVE_CONFLICT] + counts[CHECKOUT_ACTION__UPDATE_BLOB] + diff --git a/src/cherrypick.c b/src/cherrypick.c index 4287956c9c3..9ec4962b99a 100644 --- a/src/cherrypick.c +++ b/src/cherrypick.c @@ -26,10 +26,10 @@ static int write_cherrypick_head( const char *commit_oidstr) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf file_path = GIT_BUF_INIT; + git_str file_path = GIT_STR_INIT; int error = 0; - if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_CHERRYPICK_HEAD_FILE)) >= 0 && + if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_CHERRYPICK_HEAD_FILE)) >= 0 && (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_CHERRYPICK_FILE_MODE)) >= 0 && (error = git_filebuf_printf(&file, "%s\n", commit_oidstr)) >= 0) error = git_filebuf_commit(&file); @@ -37,7 +37,7 @@ static int write_cherrypick_head( if (error < 0) git_filebuf_cleanup(&file); - git_buf_dispose(&file_path); + git_str_dispose(&file_path); return error; } @@ -47,10 +47,10 @@ static int write_merge_msg( const char *commit_msg) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf file_path = GIT_BUF_INIT; + git_str file_path = GIT_STR_INIT; int error = 0; - if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 || + if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 || (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_CHERRYPICK_FILE_MODE)) < 0 || (error = git_filebuf_printf(&file, "%s", commit_msg)) < 0) goto cleanup; @@ -61,7 +61,7 @@ static int write_merge_msg( if (error < 0) git_filebuf_cleanup(&file); - git_buf_dispose(&file_path); + git_str_dispose(&file_path); return error; } @@ -175,7 +175,7 @@ int git_cherrypick( git_commit *our_commit = NULL; char commit_oidstr[GIT_OID_HEXSZ + 1]; const char *commit_msg, *commit_summary; - git_buf their_label = GIT_BUF_INIT; + git_str their_label = GIT_STR_INIT; git_index *index = NULL; git_indexwriter indexwriter = GIT_INDEXWRITER_INIT; int error = 0; @@ -197,8 +197,8 @@ int git_cherrypick( git_oid_nfmt(commit_oidstr, sizeof(commit_oidstr), git_commit_id(commit)); if ((error = write_merge_msg(repo, commit_msg)) < 0 || - (error = git_buf_printf(&their_label, "%.7s... %s", commit_oidstr, commit_summary)) < 0 || - (error = cherrypick_normalize_opts(repo, &opts, given_opts, git_buf_cstr(&their_label))) < 0 || + (error = git_str_printf(&their_label, "%.7s... %s", commit_oidstr, commit_summary)) < 0 || + (error = cherrypick_normalize_opts(repo, &opts, given_opts, git_str_cstr(&their_label))) < 0 || (error = git_indexwriter_init_for_operation(&indexwriter, repo, &opts.checkout_opts.checkout_strategy)) < 0 || (error = write_cherrypick_head(repo, commit_oidstr)) < 0 || (error = git_repository_head(&our_ref, repo)) < 0 || @@ -220,7 +220,7 @@ int git_cherrypick( git_index_free(index); git_commit_free(our_commit); git_reference_free(our_ref); - git_buf_dispose(&their_label); + git_str_dispose(&their_label); return error; } diff --git a/src/clone.c b/src/clone.c index 752df3b92d8..cf4cc3c7f46 100644 --- a/src/clone.c +++ b/src/clone.c @@ -34,7 +34,7 @@ static int create_branch( { git_commit *head_obj = NULL; git_reference *branch_ref = NULL; - git_buf refname = GIT_BUF_INIT; + git_str refname = GIT_STR_INIT; int error; /* Find the target commit */ @@ -42,11 +42,11 @@ static int create_branch( return error; /* Create the new branch */ - if ((error = git_buf_printf(&refname, GIT_REFS_HEADS_DIR "%s", name)) < 0) + if ((error = git_str_printf(&refname, GIT_REFS_HEADS_DIR "%s", name)) < 0) return error; - error = git_reference_create(&branch_ref, repo, git_buf_cstr(&refname), target, 0, log_message); - git_buf_dispose(&refname); + error = git_reference_create(&branch_ref, repo, git_str_cstr(&refname), target, 0, log_message); + git_str_dispose(&refname); git_commit_free(head_obj); if (!error) @@ -64,29 +64,29 @@ static int setup_tracking_config( const char *merge_target) { git_config *cfg; - git_buf remote_key = GIT_BUF_INIT, merge_key = GIT_BUF_INIT; + git_str remote_key = GIT_STR_INIT, merge_key = GIT_STR_INIT; int error = -1; if (git_repository_config__weakptr(&cfg, repo) < 0) return -1; - if (git_buf_printf(&remote_key, "branch.%s.remote", branch_name) < 0) + if (git_str_printf(&remote_key, "branch.%s.remote", branch_name) < 0) goto cleanup; - if (git_buf_printf(&merge_key, "branch.%s.merge", branch_name) < 0) + if (git_str_printf(&merge_key, "branch.%s.merge", branch_name) < 0) goto cleanup; - if (git_config_set_string(cfg, git_buf_cstr(&remote_key), remote_name) < 0) + if (git_config_set_string(cfg, git_str_cstr(&remote_key), remote_name) < 0) goto cleanup; - if (git_config_set_string(cfg, git_buf_cstr(&merge_key), merge_target) < 0) + if (git_config_set_string(cfg, git_str_cstr(&merge_key), merge_target) < 0) goto cleanup; error = 0; cleanup: - git_buf_dispose(&remote_key); - git_buf_dispose(&merge_key); + git_str_dispose(&remote_key); + git_str_dispose(&merge_key); return error; } @@ -139,7 +139,7 @@ static int update_head_to_new_branch( static int update_head_to_default(git_repository *repo) { - git_buf initialbranch = GIT_BUF_INIT; + git_str initialbranch = GIT_STR_INIT; const char *branch_name; int error = 0; @@ -158,24 +158,24 @@ static int update_head_to_default(git_repository *repo) initialbranch.ptr); done: - git_buf_dispose(&initialbranch); + git_str_dispose(&initialbranch); return error; } static int update_remote_head( git_repository *repo, git_remote *remote, - git_buf *target, + git_str *target, const char *reflog_message) { git_refspec *refspec; git_reference *remote_head = NULL; - git_buf remote_head_name = GIT_BUF_INIT; - git_buf remote_branch_name = GIT_BUF_INIT; + git_str remote_head_name = GIT_STR_INIT; + git_str remote_branch_name = GIT_STR_INIT; int error; /* Determine the remote tracking ref name from the local branch */ - refspec = git_remote__matching_refspec(remote, git_buf_cstr(target)); + refspec = git_remote__matching_refspec(remote, git_str_cstr(target)); if (refspec == NULL) { git_error_set(GIT_ERROR_NET, "the remote's default branch does not fit the refspec configuration"); @@ -183,13 +183,13 @@ static int update_remote_head( goto cleanup; } - if ((error = git_refspec_transform( + if ((error = git_refspec__transform( &remote_branch_name, refspec, - git_buf_cstr(target))) < 0) + git_str_cstr(target))) < 0) goto cleanup; - if ((error = git_buf_printf(&remote_head_name, + if ((error = git_str_printf(&remote_head_name, "%s%s/%s", GIT_REFS_REMOTES_DIR, git_remote_name(remote), @@ -199,15 +199,15 @@ static int update_remote_head( error = git_reference_symbolic_create( &remote_head, repo, - git_buf_cstr(&remote_head_name), - git_buf_cstr(&remote_branch_name), + git_str_cstr(&remote_head_name), + git_str_cstr(&remote_branch_name), true, reflog_message); cleanup: git_reference_free(remote_head); - git_buf_dispose(&remote_branch_name); - git_buf_dispose(&remote_head_name); + git_str_dispose(&remote_branch_name); + git_str_dispose(&remote_head_name); return error; } @@ -220,7 +220,7 @@ static int update_head_to_remote( size_t refs_len; const git_remote_head *remote_head, **refs; const git_oid *remote_head_id; - git_buf branch = GIT_BUF_INIT; + git_str branch = GIT_STR_INIT; if ((error = git_remote_ls(&refs, &refs_len, remote)) < 0) return error; @@ -235,7 +235,7 @@ static int update_head_to_remote( remote_head_id = &remote_head->oid; - error = git_remote_default_branch(&branch, remote); + error = git_remote__default_branch(&branch, remote); if (error == GIT_ENOTFOUND) { error = git_repository_set_head_detached( repo, remote_head_id); @@ -248,11 +248,11 @@ static int update_head_to_remote( error = update_head_to_new_branch( repo, remote_head_id, - git_buf_cstr(&branch), + git_str_cstr(&branch), reflog_message); cleanup: - git_buf_dispose(&branch); + git_str_dispose(&branch); return error; } @@ -264,36 +264,36 @@ static int update_head_to_branch( const char *reflog_message) { int retcode; - git_buf remote_branch_name = GIT_BUF_INIT; + git_str remote_branch_name = GIT_STR_INIT; git_reference *remote_ref = NULL; - git_buf default_branch = GIT_BUF_INIT; + git_str default_branch = GIT_STR_INIT; GIT_ASSERT_ARG(remote); GIT_ASSERT_ARG(branch); - if ((retcode = git_buf_printf(&remote_branch_name, GIT_REFS_REMOTES_DIR "%s/%s", + if ((retcode = git_str_printf(&remote_branch_name, GIT_REFS_REMOTES_DIR "%s/%s", git_remote_name(remote), branch)) < 0 ) goto cleanup; - if ((retcode = git_reference_lookup(&remote_ref, repo, git_buf_cstr(&remote_branch_name))) < 0) + if ((retcode = git_reference_lookup(&remote_ref, repo, git_str_cstr(&remote_branch_name))) < 0) goto cleanup; if ((retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch, reflog_message)) < 0) goto cleanup; - if ((retcode = git_remote_default_branch(&default_branch, remote)) < 0) + if ((retcode = git_remote__default_branch(&default_branch, remote)) < 0) goto cleanup; - if (!git_remote__matching_refspec(remote, git_buf_cstr(&default_branch))) + if (!git_remote__matching_refspec(remote, git_str_cstr(&default_branch))) goto cleanup; retcode = update_remote_head(repo, remote, &default_branch, reflog_message); cleanup: git_reference_free(remote_ref); - git_buf_dispose(&remote_branch_name); - git_buf_dispose(&default_branch); + git_str_dispose(&remote_branch_name); + git_str_dispose(&default_branch); return retcode; } @@ -392,7 +392,7 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c 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; - git_buf reflog_message = GIT_BUF_INIT; + git_str reflog_message = GIT_STR_INIT; git_fetch_options fetch_opts; git_remote *remote; @@ -410,23 +410,23 @@ 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; 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_buf_cstr(&reflog_message))) != 0) + if ((error = git_remote_fetch(remote, NULL, &fetch_opts, git_str_cstr(&reflog_message))) != 0) goto cleanup; - error = checkout_branch(repo, remote, co_opts, branch, git_buf_cstr(&reflog_message)); + error = checkout_branch(repo, remote, co_opts, branch, git_str_cstr(&reflog_message)); cleanup: git_remote_free(remote); - git_buf_dispose(&reflog_message); + git_str_dispose(&reflog_message); return error; } int git_clone__should_clone_local(const char *url_or_path, git_clone_local_t local) { - git_buf fromurl = GIT_BUF_INIT; + git_str fromurl = GIT_STR_INIT; const char *path = url_or_path; bool is_url, is_local; @@ -446,7 +446,7 @@ int git_clone__should_clone_local(const char *url_or_path, git_clone_local_t loc git_path_isdir(path); done: - git_buf_dispose(&fromurl); + git_str_dispose(&fromurl); return is_local; } @@ -586,8 +586,8 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_ { int error, flags; git_repository *src; - git_buf src_odb = GIT_BUF_INIT, dst_odb = GIT_BUF_INIT, src_path = GIT_BUF_INIT; - git_buf reflog_message = GIT_BUF_INIT; + git_str src_odb = GIT_STR_INIT, dst_odb = GIT_STR_INIT, src_path = GIT_STR_INIT; + git_str reflog_message = GIT_STR_INIT; GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(remote); @@ -606,13 +606,13 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_ return error; /* Copy .git/objects/ from the source to the target */ - if ((error = git_repository_open(&src, git_buf_cstr(&src_path))) < 0) { - git_buf_dispose(&src_path); + if ((error = git_repository_open(&src, git_str_cstr(&src_path))) < 0) { + git_str_dispose(&src_path); return error; } - if (git_repository_item_path(&src_odb, src, GIT_REPOSITORY_ITEM_OBJECTS) < 0 - || git_repository_item_path(&dst_odb, repo, GIT_REPOSITORY_ITEM_OBJECTS) < 0) { + if (git_repository__item_path(&src_odb, src, GIT_REPOSITORY_ITEM_OBJECTS) < 0 || + git_repository__item_path(&dst_odb, repo, GIT_REPOSITORY_ITEM_OBJECTS) < 0) { error = -1; goto cleanup; } @@ -621,7 +621,7 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_ if (can_link(git_repository_path(src), git_repository_path(repo), link)) flags |= GIT_CPDIR_LINK_FILES; - error = git_futils_cp_r(git_buf_cstr(&src_odb), git_buf_cstr(&dst_odb), + error = git_futils_cp_r(git_str_cstr(&src_odb), git_str_cstr(&dst_odb), flags, GIT_OBJECT_DIR_MODE); /* @@ -631,25 +631,25 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_ */ if (error < 0 && link) { flags &= ~GIT_CPDIR_LINK_FILES; - error = git_futils_cp_r(git_buf_cstr(&src_odb), git_buf_cstr(&dst_odb), + error = git_futils_cp_r(git_str_cstr(&src_odb), git_str_cstr(&dst_odb), flags, GIT_OBJECT_DIR_MODE); } if (error < 0) goto cleanup; - 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_buf_cstr(&reflog_message))) != 0) + if ((error = git_remote_fetch(remote, NULL, fetch_opts, git_str_cstr(&reflog_message))) != 0) goto cleanup; - error = checkout_branch(repo, remote, co_opts, branch, git_buf_cstr(&reflog_message)); + error = checkout_branch(repo, remote, co_opts, branch, git_str_cstr(&reflog_message)); cleanup: - git_buf_dispose(&reflog_message); - git_buf_dispose(&src_path); - git_buf_dispose(&src_odb); - git_buf_dispose(&dst_odb); + git_str_dispose(&reflog_message); + git_str_dispose(&src_path); + git_str_dispose(&src_odb); + git_str_dispose(&dst_odb); git_repository_free(src); return error; } diff --git a/src/commit.c b/src/commit.c index 96259d5bb14..752d98b022f 100644 --- a/src/commit.c +++ b/src/commit.c @@ -14,10 +14,10 @@ #include "git2/mailmap.h" #include "git2/sys/commit.h" +#include "buf.h" #include "odb.h" #include "commit.h" #include "signature.h" -#include "message.h" #include "refs.h" #include "object.h" #include "array.h" @@ -42,7 +42,7 @@ void git_commit__free(void *_commit) } static int git_commit__create_buffer_internal( - git_buf *out, + git_str *out, const git_signature *author, const git_signature *committer, const char *message_encoding, @@ -67,17 +67,17 @@ static int git_commit__create_buffer_internal( git_signature__writebuf(out, "committer ", committer); if (message_encoding != NULL) - git_buf_printf(out, "encoding %s\n", message_encoding); + git_str_printf(out, "encoding %s\n", message_encoding); - git_buf_putc(out, '\n'); + git_str_putc(out, '\n'); - if (git_buf_puts(out, message) < 0) + if (git_str_puts(out, message) < 0) goto on_error; return 0; on_error: - git_buf_dispose(out); + git_str_dispose(out); return -1; } @@ -136,7 +136,7 @@ static int git_commit__create_internal( int error; git_odb *odb; git_reference *ref = NULL; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; const git_oid *current_id = NULL; git_array_oid_t parents = GIT_ARRAY_INIT; @@ -179,7 +179,7 @@ static int git_commit__create_internal( cleanup: git_array_clear(parents); git_reference_free(ref); - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -545,7 +545,7 @@ const char *git_commit_message(const git_commit *commit) const char *git_commit_summary(git_commit *commit) { - git_buf summary = GIT_BUF_INIT; + git_str summary = GIT_STR_INIT; const char *msg, *space; bool space_contains_newline = false; @@ -570,17 +570,17 @@ const char *git_commit_summary(git_commit *commit) /* process any recorded whitespace */ if (space) { if(space_contains_newline) - git_buf_putc(&summary, ' '); /* if the space contains a newline, collapse to ' ' */ + git_str_putc(&summary, ' '); /* if the space contains a newline, collapse to ' ' */ else - git_buf_put(&summary, space, (msg - space)); /* otherwise copy it */ + git_str_put(&summary, space, (msg - space)); /* otherwise copy it */ space = NULL; } /* copy the next character */ - git_buf_putc(&summary, next_character); + git_str_putc(&summary, next_character); } } - commit->summary = git_buf_detach(&summary); + commit->summary = git_str_detach(&summary); if (!commit->summary) commit->summary = git__strdup(""); } @@ -678,11 +678,22 @@ int git_commit_nth_gen_ancestor( return 0; } -int git_commit_header_field(git_buf *out, const git_commit *commit, const char *field) +int git_commit_header_field( + git_buf *out, + const git_commit *commit, + const char *field) +{ + GIT_BUF_WRAP_PRIVATE(out, git_commit__header_field, commit, field); +} + +int git_commit__header_field( + git_str *out, + const git_commit *commit, + const char *field) { const char *eol, *buf = commit->raw_header; - git_buf_clear(out); + git_str_clear(out); while ((eol = strchr(buf, '\n'))) { /* We can skip continuations here */ @@ -706,22 +717,22 @@ int git_commit_header_field(git_buf *out, const git_commit *commit, const char * buf++; /* skip the SP */ - git_buf_put(out, buf, eol - buf); - if (git_buf_oom(out)) + git_str_put(out, buf, eol - buf); + if (git_str_oom(out)) goto oom; /* If the next line starts with SP, it's multi-line, we must continue */ while (eol[1] == ' ') { - git_buf_putc(out, '\n'); + git_str_putc(out, '\n'); buf = eol + 2; eol = strchr(buf, '\n'); if (!eol) goto malformed; - git_buf_put(out, buf, eol - buf); + git_str_put(out, buf, eol - buf); } - if (git_buf_oom(out)) + if (git_str_oom(out)) goto oom; return 0; @@ -738,7 +749,35 @@ int git_commit_header_field(git_buf *out, const git_commit *commit, const char * return -1; } -int git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_repository *repo, git_oid *commit_id, const char *field) +int git_commit_extract_signature( + git_buf *signature_out, + git_buf *signed_data_out, + git_repository *repo, + git_oid *commit_id, + const char *field) +{ + git_str signature = GIT_STR_INIT, signed_data = GIT_STR_INIT; + int error; + + if ((error = git_buf_tostr(&signature, signature_out)) < 0 || + (error = git_buf_tostr(&signed_data, signed_data_out)) < 0 || + (error = git_commit__extract_signature(&signature, &signed_data, repo, commit_id, field)) < 0 || + (error = git_buf_fromstr(signature_out, &signature)) < 0 || + (error = git_buf_fromstr(signed_data_out, &signed_data)) < 0) + goto done; + +done: + git_str_dispose(&signature); + git_str_dispose(&signed_data); + return error; +} + +int git_commit__extract_signature( + git_str *signature, + git_str *signed_data, + git_repository *repo, + git_oid *commit_id, + const char *field) { git_odb_object *obj; git_odb *odb; @@ -746,8 +785,8 @@ int git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_r const char *h, *eol; int error; - git_buf_clear(signature); - git_buf_clear(signed_data); + git_str_clear(signature); + git_str_clear(signed_data); if (!field) field = "gpgsig"; @@ -769,7 +808,7 @@ int git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_r while ((h = strchr(buf, '\n')) && h[1] != '\0') { h++; if (git__prefixcmp(buf, field)) { - if (git_buf_put(signed_data, buf, h - buf) < 0) + if (git_str_put(signed_data, buf, h - buf) < 0) return -1; buf = h; @@ -788,25 +827,25 @@ int git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_r h++; /* skip the SP */ - git_buf_put(signature, h, eol - h); - if (git_buf_oom(signature)) + git_str_put(signature, h, eol - h); + if (git_str_oom(signature)) goto oom; /* If the next line starts with SP, it's multi-line, we must continue */ while (eol[1] == ' ') { - git_buf_putc(signature, '\n'); + git_str_putc(signature, '\n'); h = eol + 2; eol = strchr(h, '\n'); if (!eol) goto malformed; - git_buf_put(signature, h, eol - h); + git_str_put(signature, h, eol - h); } - if (git_buf_oom(signature)) + if (git_str_oom(signature)) goto oom; - error = git_buf_puts(signed_data, eol+1); + error = git_str_puts(signed_data, eol+1); git_odb_object_free(obj); return error; } @@ -826,12 +865,29 @@ int git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_r cleanup: git_odb_object_free(obj); - git_buf_clear(signature); - git_buf_clear(signed_data); + git_str_clear(signature); + git_str_clear(signed_data); return error; } -int git_commit_create_buffer(git_buf *out, +int git_commit_create_buffer( + git_buf *out, + git_repository *repo, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + size_t parent_count, + const git_commit *parents[]) +{ + GIT_BUF_WRAP_PRIVATE(out, git_commit__create_buffer, repo, + author, committer, message_encoding, message, + tree, parent_count, parents); +} + +int git_commit__create_buffer( + git_str *out, git_repository *repo, const git_signature *author, const git_signature *committer, @@ -866,7 +922,7 @@ int git_commit_create_buffer(git_buf *out, /** * Append to 'out' properly marking continuations when there's a newline in 'content' */ -static int format_header_field(git_buf *out, const char *field, const char *content) +static int format_header_field(git_str *out, const char *field, const char *content) { const char *lf; @@ -874,19 +930,19 @@ static int format_header_field(git_buf *out, const char *field, const char *cont GIT_ASSERT_ARG(field); GIT_ASSERT_ARG(content); - git_buf_puts(out, field); - git_buf_putc(out, ' '); + git_str_puts(out, field); + git_str_putc(out, ' '); while ((lf = strchr(content, '\n')) != NULL) { - git_buf_put(out, content, lf - content); - git_buf_puts(out, "\n "); + git_str_put(out, content, lf - content); + git_str_puts(out, "\n "); content = lf + 1; } - git_buf_puts(out, content); - git_buf_putc(out, '\n'); + git_str_puts(out, content); + git_str_putc(out, '\n'); - return git_buf_oom(out) ? -1 : 0; + return git_str_oom(out) ? -1 : 0; } static const git_oid *commit_parent_from_commit(size_t n, void *payload) @@ -908,7 +964,7 @@ int git_commit_create_with_signature( int error = 0; const char *field; const char *header_end; - git_buf commit = GIT_BUF_INIT; + git_str commit = GIT_STR_INIT; git_commit *parsed; git_array_oid_t parents = GIT_ARRAY_INIT; @@ -933,7 +989,7 @@ int git_commit_create_with_signature( /* The header ends after the first LF */ header_end++; - git_buf_put(&commit, commit_content, header_end - commit_content); + git_str_put(&commit, commit_content, header_end - commit_content); if (signature != NULL) { field = signature_field ? signature_field : "gpgsig"; @@ -942,9 +998,9 @@ int git_commit_create_with_signature( goto cleanup; } - git_buf_puts(&commit, header_end); + git_str_puts(&commit, header_end); - if (git_buf_oom(&commit)) + if (git_str_oom(&commit)) return -1; if ((error = git_repository_odb__weakptr(&odb, repo)) < 0) @@ -955,7 +1011,7 @@ int git_commit_create_with_signature( cleanup: git_commit__free(parsed); - git_buf_dispose(&commit); + git_str_dispose(&commit); return error; } diff --git a/src/commit.h b/src/commit.h index 318ce5cba4d..9378eab2d0c 100644 --- a/src/commit.h +++ b/src/commit.h @@ -33,6 +33,29 @@ struct git_commit { char *body; }; +int git_commit__header_field( + git_str *out, + const git_commit *commit, + const char *field); + +int git_commit__extract_signature( + git_str *signature, + git_str *signed_data, + git_repository *repo, + git_oid *commit_id, + const char *field); + +int git_commit__create_buffer( + git_str *out, + git_repository *repo, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + size_t parent_count, + const git_commit *parents[]); + void git_commit__free(void *commit); int git_commit__parse(void *commit, git_odb_object *obj); int git_commit__parse_raw(void *commit, const char *data, size_t size); diff --git a/src/commit_graph.c b/src/commit_graph.c index df760b5f8ca..f9a4bd2b270 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -8,6 +8,7 @@ #include "commit_graph.h" #include "array.h" +#include "buf.h" #include "filebuf.h" #include "futils.h" #include "hash.h" @@ -308,12 +309,12 @@ int git_commit_graph_new(git_commit_graph **cgraph_out, const char *objects_dir, cgraph = git__calloc(1, sizeof(git_commit_graph)); GIT_ERROR_CHECK_ALLOC(cgraph); - error = git_buf_joinpath(&cgraph->filename, objects_dir, "info/commit-graph"); + error = git_str_joinpath(&cgraph->filename, objects_dir, "info/commit-graph"); if (error < 0) goto error; if (open_file) { - error = git_commit_graph_file_open(&cgraph->file, git_buf_cstr(&cgraph->filename)); + error = git_commit_graph_file_open(&cgraph->file, git_str_cstr(&cgraph->filename)); if (error < 0) goto error; cgraph->checked = 1; @@ -387,7 +388,7 @@ int git_commit_graph_get_file(git_commit_graph_file **file_out, git_commit_graph cgraph->checked = 1; /* Best effort */ - error = git_commit_graph_file_open(&result, git_buf_cstr(&cgraph->filename)); + error = git_commit_graph_file_open(&result, git_str_cstr(&cgraph->filename)); if (error < 0) return error; @@ -407,7 +408,7 @@ void git_commit_graph_refresh(git_commit_graph *cgraph) return; if (cgraph->file - && git_commit_graph_file_needs_refresh(cgraph->file, git_buf_cstr(&cgraph->filename))) { + && git_commit_graph_file_needs_refresh(cgraph->file, git_str_cstr(&cgraph->filename))) { /* We just free the commit graph. The next time it is requested, it will be * re-loaded. */ git_commit_graph_file_free(cgraph->file); @@ -597,7 +598,7 @@ void git_commit_graph_free(git_commit_graph *cgraph) if (!cgraph) return; - git_buf_dispose(&cgraph->filename); + git_str_dispose(&cgraph->filename); git_commit_graph_file_free(cgraph->file); git__free(cgraph); } @@ -623,13 +624,13 @@ int git_commit_graph_writer_new(git_commit_graph_writer **out, const char *objec git_commit_graph_writer *w = git__calloc(1, sizeof(git_commit_graph_writer)); GIT_ERROR_CHECK_ALLOC(w); - if (git_buf_sets(&w->objects_info_dir, objects_info_dir) < 0) { + if (git_str_sets(&w->objects_info_dir, objects_info_dir) < 0) { git__free(w); return -1; } if (git_vector_init(&w->commits, 0, packed_commit__cmp) < 0) { - git_buf_dispose(&w->objects_info_dir); + git_str_dispose(&w->objects_info_dir); git__free(w); return -1; } @@ -649,7 +650,7 @@ void git_commit_graph_writer_free(git_commit_graph_writer *w) git_vector_foreach (&w->commits, i, packed_commit) packed_commit_free(packed_commit); git_vector_free(&w->commits); - git_buf_dispose(&w->objects_info_dir); + git_str_dispose(&w->objects_info_dir); git__free(w); } @@ -931,8 +932,8 @@ static int write_chunk_header( static int commit_graph_write_buf(const char *buf, size_t size, void *data) { - git_buf *b = (git_buf *)data; - return git_buf_put(b, buf, size); + git_str *b = (git_str *)data; + return git_str_put(b, buf, size); } struct commit_graph_write_hash_context { @@ -971,8 +972,8 @@ static int commit_graph_write( uint32_t extra_edge_list_count; uint32_t oid_fanout[256]; off64_t offset; - git_buf oid_lookup = GIT_BUF_INIT, commit_data = GIT_BUF_INIT, - extra_edge_list = GIT_BUF_INIT; + git_str oid_lookup = GIT_STR_INIT, commit_data = GIT_STR_INIT, + extra_edge_list = GIT_STR_INIT; git_oid cgraph_checksum = {{0}}; git_hash_ctx ctx; struct commit_graph_write_hash_context hash_cb_data = {0}; @@ -1011,7 +1012,7 @@ static int commit_graph_write( /* Fill the OID Lookup table. */ git_vector_foreach (&w->commits, i, packed_commit) { - error = git_buf_put(&oid_lookup, + error = git_str_put(&oid_lookup, (const char *)&packed_commit->sha1, sizeof(git_oid)); if (error < 0) goto cleanup; @@ -1026,7 +1027,7 @@ static int commit_graph_write( size_t *packed_index; unsigned int parentcount = (unsigned int)git_array_size(packed_commit->parents); - error = git_buf_put(&commit_data, + error = git_str_put(&commit_data, (const char *)&packed_commit->tree_oid, sizeof(git_oid)); if (error < 0) @@ -1038,7 +1039,7 @@ static int commit_graph_write( packed_index = git_array_get(packed_commit->parent_indices, 0); word = htonl((uint32_t)*packed_index); } - error = git_buf_put(&commit_data, (const char *)&word, sizeof(word)); + error = git_str_put(&commit_data, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; @@ -1050,7 +1051,7 @@ static int commit_graph_write( } else { word = htonl(0x80000000u | extra_edge_list_count); } - error = git_buf_put(&commit_data, (const char *)&word, sizeof(word)); + error = git_str_put(&commit_data, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; @@ -1061,7 +1062,7 @@ static int commit_graph_write( packed_commit->parent_indices, parent_i); word = htonl((uint32_t)(*packed_index | (parent_i + 1 == parentcount ? 0x80000000u : 0))); - error = git_buf_put(&extra_edge_list, + error = git_str_put(&extra_edge_list, (const char *)&word, sizeof(word)); if (error < 0) @@ -1075,18 +1076,18 @@ static int commit_graph_write( if (generation > GIT_COMMIT_GRAPH_GENERATION_NUMBER_MAX) generation = GIT_COMMIT_GRAPH_GENERATION_NUMBER_MAX; word = ntohl((uint32_t)((generation << 2) | ((commit_time >> 32ull) & 0x3ull))); - error = git_buf_put(&commit_data, (const char *)&word, sizeof(word)); + error = git_str_put(&commit_data, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; word = ntohl((uint32_t)(commit_time & 0xffffffffull)); - error = git_buf_put(&commit_data, (const char *)&word, sizeof(word)); + error = git_str_put(&commit_data, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; } /* Write the header. */ hdr.chunks = 3; - if (git_buf_len(&extra_edge_list) > 0) + if (git_str_len(&extra_edge_list) > 0) hdr.chunks++; error = write_cb((const char *)&hdr, sizeof(hdr), cb_data); if (error < 0) @@ -1101,17 +1102,17 @@ static int commit_graph_write( error = write_chunk_header(COMMIT_GRAPH_OID_LOOKUP_ID, offset, write_cb, cb_data); if (error < 0) goto cleanup; - offset += git_buf_len(&oid_lookup); + offset += git_str_len(&oid_lookup); error = write_chunk_header(COMMIT_GRAPH_COMMIT_DATA_ID, offset, write_cb, cb_data); if (error < 0) goto cleanup; - offset += git_buf_len(&commit_data); - if (git_buf_len(&extra_edge_list) > 0) { + offset += git_str_len(&commit_data); + if (git_str_len(&extra_edge_list) > 0) { error = write_chunk_header( COMMIT_GRAPH_EXTRA_EDGE_LIST_ID, offset, write_cb, cb_data); if (error < 0) goto cleanup; - offset += git_buf_len(&extra_edge_list); + offset += git_str_len(&extra_edge_list); } error = write_chunk_header(0, offset, write_cb, cb_data); if (error < 0) @@ -1121,13 +1122,13 @@ static int commit_graph_write( error = write_cb((const char *)oid_fanout, sizeof(oid_fanout), cb_data); if (error < 0) goto cleanup; - error = write_cb(git_buf_cstr(&oid_lookup), git_buf_len(&oid_lookup), cb_data); + error = write_cb(git_str_cstr(&oid_lookup), git_str_len(&oid_lookup), cb_data); if (error < 0) goto cleanup; - error = write_cb(git_buf_cstr(&commit_data), git_buf_len(&commit_data), cb_data); + error = write_cb(git_str_cstr(&commit_data), git_str_len(&commit_data), cb_data); if (error < 0) goto cleanup; - error = write_cb(git_buf_cstr(&extra_edge_list), git_buf_len(&extra_edge_list), cb_data); + error = write_cb(git_str_cstr(&extra_edge_list), git_str_len(&extra_edge_list), cb_data); if (error < 0) goto cleanup; @@ -1140,9 +1141,9 @@ static int commit_graph_write( goto cleanup; cleanup: - git_buf_dispose(&oid_lookup); - git_buf_dispose(&commit_data); - git_buf_dispose(&extra_edge_list); + git_str_dispose(&oid_lookup); + git_str_dispose(&commit_data); + git_str_dispose(&extra_edge_list); git_hash_ctx_cleanup(&ctx); return error; } @@ -1171,21 +1172,21 @@ int git_commit_graph_writer_commit( { int error; int filebuf_flags = GIT_FILEBUF_DO_NOT_BUFFER; - git_buf commit_graph_path = GIT_BUF_INIT; + git_str commit_graph_path = GIT_STR_INIT; git_filebuf output = GIT_FILEBUF_INIT; /* TODO: support options and fill in defaults. */ GIT_UNUSED(opts); - error = git_buf_joinpath( - &commit_graph_path, git_buf_cstr(&w->objects_info_dir), "commit-graph"); + error = git_str_joinpath( + &commit_graph_path, git_str_cstr(&w->objects_info_dir), "commit-graph"); if (error < 0) return error; if (git_repository__fsync_gitdir) filebuf_flags |= GIT_FILEBUF_FSYNC; - error = git_filebuf_open(&output, git_buf_cstr(&commit_graph_path), filebuf_flags, 0644); - git_buf_dispose(&commit_graph_path); + error = git_filebuf_open(&output, git_str_cstr(&commit_graph_path), filebuf_flags, 0644); + git_str_dispose(&commit_graph_path); if (error < 0) return error; @@ -1199,9 +1200,17 @@ int git_commit_graph_writer_commit( } int git_commit_graph_writer_dump( - git_buf *cgraph, - git_commit_graph_writer *w, - git_commit_graph_writer_options *opts) + git_buf *cgraph, + git_commit_graph_writer *w, + git_commit_graph_writer_options *opts) +{ + GIT_BUF_WRAP_PRIVATE(cgraph, git_commit_graph__writer_dump, w, opts); +} + +int git_commit_graph__writer_dump( + git_str *cgraph, + git_commit_graph_writer *w, + git_commit_graph_writer_options *opts) { /* TODO: support options. */ GIT_UNUSED(opts); diff --git a/src/commit_graph.h b/src/commit_graph.h index 9d0a827de0a..4d2be431c1e 100644 --- a/src/commit_graph.h +++ b/src/commit_graph.h @@ -92,7 +92,7 @@ typedef struct git_commit_graph_entry { /* A wrapper for git_commit_graph_file to enable lazy loading in the ODB. */ struct git_commit_graph { /* The path to the commit-graph file. Something like ".git/objects/info/commit-graph". */ - git_buf filename; + git_str filename; /* The underlying commit-graph file. */ git_commit_graph_file *file; @@ -127,12 +127,17 @@ struct git_commit_graph_writer { * The path of the `objects/info` directory where the `commit-graph` will be * stored. */ - git_buf objects_info_dir; + git_str objects_info_dir; /* The list of packed commits. */ git_vector commits; }; +int git_commit_graph__writer_dump( + git_str *cgraph, + git_commit_graph_writer *w, + git_commit_graph_writer_options *opts); + /* * Returns whether the git_commit_graph_file needs to be reloaded since the * contents of the commit-graph file have changed on disk. diff --git a/src/common.h b/src/common.h index 9bb1116b531..640f948067b 100644 --- a/src/common.h +++ b/src/common.h @@ -124,9 +124,9 @@ #define GIT_ERROR_CHECK_ALLOC(ptr) if (ptr == NULL) { return -1; } /** - * Check a buffer allocation result, returning -1 if it failed. + * Check a string buffer allocation result, returning -1 if it failed. */ -#define GIT_ERROR_CHECK_ALLOC_BUF(buf) if ((void *)(buf) == NULL || git_buf_oom(buf)) { return -1; } +#define GIT_ERROR_CHECK_ALLOC_STR(buf) if ((void *)(buf) == NULL || git_str_oom(buf)) { return -1; } /** * Check a return value and propagate result if non-zero. @@ -202,6 +202,9 @@ GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int v /* NOTE: other git_error functions are in the public errors.h header file */ +/* Forward declare git_str */ +typedef struct git_str git_str; + #include "util.h" #endif diff --git a/src/config.c b/src/config.c index 3251cd51fdb..9033a92c523 100644 --- a/src/config.c +++ b/src/config.c @@ -10,6 +10,7 @@ #include "git2/config.h" #include "git2/sys/config.h" +#include "buf.h" #include "config_backend.h" #include "regexp.h" #include "sysdir.h" @@ -848,7 +849,40 @@ static int is_readonly(const git_config *cfg) return 1; } -int git_config_get_path(git_buf *out, const git_config *cfg, const char *name) +static int git_config__parse_path(git_str *out, const char *value) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(value); + + if (value[0] == '~') { + if (value[1] != '\0' && value[1] != '/') { + git_error_set(GIT_ERROR_CONFIG, "retrieving a homedir by name is not supported"); + return -1; + } + + return git_sysdir_expand_global_file(out, value[1] ? &value[2] : NULL); + } + + return git_str_sets(out, value); +} + +int git_config_parse_path(git_buf *out, const char *value) +{ + GIT_BUF_WRAP_PRIVATE(out, git_config__parse_path, value); +} + +int git_config_get_path( + git_buf *out, + const git_config *cfg, + const char *name) +{ + GIT_BUF_WRAP_PRIVATE(out, git_config__get_path, cfg, name); +} + +int git_config__get_path( + git_str *out, + const git_config *cfg, + const char *name) { git_config_entry *entry; int error; @@ -856,7 +890,7 @@ int git_config_get_path(git_buf *out, const git_config *cfg, const char *name) if ((error = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0) return error; - error = git_config_parse_path(out, entry->value); + error = git_config__parse_path(out, entry->value); git_config_entry_free(entry); return error; @@ -883,19 +917,25 @@ int git_config_get_string( int git_config_get_string_buf( git_buf *out, const git_config *cfg, const char *name) +{ + GIT_BUF_WRAP_PRIVATE(out, git_config__get_string_buf, cfg, name); +} + +int git_config__get_string_buf( + git_str *out, const git_config *cfg, const char *name) { git_config_entry *entry; int ret; const char *str; - if ((ret = git_buf_sanitize(out)) < 0) - return ret; + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(cfg); ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS); str = !ret ? (entry->value ? entry->value : "") : NULL; if (str) - ret = git_buf_puts(out, str); + ret = git_str_puts(out, str); git_config_entry_free(entry); @@ -1087,101 +1127,112 @@ void git_config_iterator_free(git_config_iterator *iter) int git_config_find_global(git_buf *path) { - int error; - - if ((error = git_buf_sanitize(path)) < 0) - return error; + GIT_BUF_WRAP_PRIVATE(path, git_sysdir_find_global_file, GIT_CONFIG_FILENAME_GLOBAL); +} +int git_config__find_global(git_str *path) +{ return git_sysdir_find_global_file(path, GIT_CONFIG_FILENAME_GLOBAL); } int git_config_find_xdg(git_buf *path) { - int error; - - if ((error = git_buf_sanitize(path)) < 0) - return error; + GIT_BUF_WRAP_PRIVATE(path, git_sysdir_find_global_file, GIT_CONFIG_FILENAME_XDG); +} +int git_config__find_xdg(git_str *path) +{ return git_sysdir_find_xdg_file(path, GIT_CONFIG_FILENAME_XDG); } int git_config_find_system(git_buf *path) { - int error; - - if ((error = git_buf_sanitize(path)) < 0) - return error; + GIT_BUF_WRAP_PRIVATE(path, git_sysdir_find_global_file, GIT_CONFIG_FILENAME_SYSTEM); +} +int git_config__find_system(git_str *path) +{ return git_sysdir_find_system_file(path, GIT_CONFIG_FILENAME_SYSTEM); } int git_config_find_programdata(git_buf *path) +{ + git_str str = GIT_STR_INIT; + int error; + + if ((error = git_buf_tostr(&str, path)) == 0 && + (error = git_config__find_programdata(&str)) == 0) + error = git_buf_fromstr(path, &str); + + git_str_dispose(&str); + return error; +} + +int git_config__find_programdata(git_str *path) { int ret; - if ((ret = git_buf_sanitize(path)) < 0) - return ret; + ret = git_sysdir_find_programdata_file(path, GIT_CONFIG_FILENAME_PROGRAMDATA); - ret = git_sysdir_find_programdata_file(path, - GIT_CONFIG_FILENAME_PROGRAMDATA); if (ret != GIT_OK) return ret; return git_path_validate_system_file_ownership(path->ptr); } -int git_config__global_location(git_buf *buf) +int git_config__global_location(git_str *buf) { - const git_buf *paths; + const git_str *paths; const char *sep, *start; if (git_sysdir_get(&paths, GIT_SYSDIR_GLOBAL) < 0) return -1; /* no paths, so give up */ - if (!paths || !git_buf_len(paths)) + if (!paths || !git_str_len(paths)) return -1; /* find unescaped separator or end of string */ - for (sep = start = git_buf_cstr(paths); *sep; ++sep) { + for (sep = start = git_str_cstr(paths); *sep; ++sep) { if (*sep == GIT_PATH_LIST_SEPARATOR && (sep <= start || sep[-1] != '\\')) break; } - if (git_buf_set(buf, start, (size_t)(sep - start)) < 0) + if (git_str_set(buf, start, (size_t)(sep - start)) < 0) return -1; - return git_buf_joinpath(buf, buf->ptr, GIT_CONFIG_FILENAME_GLOBAL); + return git_str_joinpath(buf, buf->ptr, GIT_CONFIG_FILENAME_GLOBAL); } int git_config_open_default(git_config **out) { int error; git_config *cfg = NULL; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; if ((error = git_config_new(&cfg)) < 0) return error; - if (!git_config_find_global(&buf) || !git_config__global_location(&buf)) { + if (!git_config__find_global(&buf) || + !git_config__global_location(&buf)) { error = git_config_add_file_ondisk(cfg, buf.ptr, GIT_CONFIG_LEVEL_GLOBAL, NULL, 0); } - if (!error && !git_config_find_xdg(&buf)) + if (!error && !git_config__find_xdg(&buf)) error = git_config_add_file_ondisk(cfg, buf.ptr, GIT_CONFIG_LEVEL_XDG, NULL, 0); - if (!error && !git_config_find_system(&buf)) + if (!error && !git_config__find_system(&buf)) error = git_config_add_file_ondisk(cfg, buf.ptr, GIT_CONFIG_LEVEL_SYSTEM, NULL, 0); - if (!error && !git_config_find_programdata(&buf)) + if (!error && !git_config__find_programdata(&buf)) error = git_config_add_file_ondisk(cfg, buf.ptr, GIT_CONFIG_LEVEL_PROGRAMDATA, NULL, 0); - git_buf_dispose(&buf); + git_str_dispose(&buf); if (error) { git_config_free(cfg); @@ -1375,28 +1426,6 @@ int git_config_parse_int32(int32_t *out, const char *value) return -1; } -int git_config_parse_path(git_buf *out, const char *value) -{ - int error; - - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(value); - - if ((error = git_buf_sanitize(out)) < 0) - return error; - - if (value[0] == '~') { - if (value[1] != '\0' && value[1] != '/') { - git_error_set(GIT_ERROR_CONFIG, "retrieving a homedir by name is not supported"); - return -1; - } - - return git_sysdir_expand_global_file(out, value[1] ? &value[2] : NULL); - } - - return git_buf_sets(out, value); -} - static int normalize_section(char *start, char *end) { char *scan; @@ -1459,7 +1488,7 @@ int git_config__normalize_name(const char *in, char **out) struct rename_data { git_config *config; - git_buf *name; + git_str *name; size_t old_len; }; @@ -1469,15 +1498,15 @@ static int rename_config_entries_cb( { int error = 0; struct rename_data *data = (struct rename_data *)payload; - size_t base_len = git_buf_len(data->name); + size_t base_len = git_str_len(data->name); if (base_len > 0 && - !(error = git_buf_puts(data->name, entry->name + data->old_len))) + !(error = git_str_puts(data->name, entry->name + data->old_len))) { error = git_config_set_string( - data->config, git_buf_cstr(data->name), entry->value); + data->config, git_str_cstr(data->name), entry->value); - git_buf_truncate(data->name, base_len); + git_str_truncate(data->name, base_len); } if (!error) @@ -1492,13 +1521,13 @@ int git_config_rename_section( const char *new_section_name) { git_config *config; - git_buf pattern = GIT_BUF_INIT, replace = GIT_BUF_INIT; + git_str pattern = GIT_STR_INIT, replace = GIT_STR_INIT; int error = 0; struct rename_data data; - git_buf_puts_escape_regex(&pattern, old_section_name); + git_str_puts_escape_regex(&pattern, old_section_name); - if ((error = git_buf_puts(&pattern, "\\..+")) < 0) + if ((error = git_str_puts(&pattern, "\\..+")) < 0) goto cleanup; if ((error = git_repository_config__weakptr(&config, repo)) < 0) @@ -1508,7 +1537,7 @@ int git_config_rename_section( data.name = &replace; data.old_len = strlen(old_section_name) + 1; - if ((error = git_buf_join(&replace, '.', new_section_name, "")) < 0) + if ((error = git_str_join(&replace, '.', new_section_name, "")) < 0) goto cleanup; if (new_section_name != NULL && @@ -1520,11 +1549,11 @@ int git_config_rename_section( } error = git_config_foreach_match( - config, git_buf_cstr(&pattern), rename_config_entries_cb, &data); + config, git_str_cstr(&pattern), rename_config_entries_cb, &data); cleanup: - git_buf_dispose(&pattern); - git_buf_dispose(&replace); + git_str_dispose(&pattern); + git_str_dispose(&replace); return error; } diff --git a/src/config.h b/src/config.h index a1d8f7d2314..5dfc9da7165 100644 --- a/src/config.h +++ b/src/config.h @@ -27,7 +27,12 @@ struct git_config { git_vector backends; }; -extern int git_config__global_location(git_buf *buf); +extern int git_config__global_location(git_str *buf); + +extern int git_config__find_global(git_str *path); +extern int git_config__find_xdg(git_str *path); +extern int git_config__find_system(git_str *path); +extern int git_config__find_programdata(git_str *path); extern int git_config_rename_section( git_repository *repo, @@ -51,6 +56,14 @@ extern int git_config__update_entry( bool overwrite_existing, bool only_if_existing); +int git_config__get_path( + git_str *out, + const git_config *cfg, + const char *name); + +int git_config__get_string_buf( + git_str *out, const git_config *cfg, const char *name); + /* * Lookup functions that cannot fail. These functions look up a config * value and return a fallback value if the value is missing or if any diff --git a/src/config_file.c b/src/config_file.c index 2f83a407071..9c3d2ceb8fb 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -11,7 +11,7 @@ #include "git2/sys/config.h" #include "array.h" -#include "buffer.h" +#include "str.h" #include "config_backend.h" #include "config_entries.h" #include "config_parse.h" @@ -41,7 +41,7 @@ typedef struct { bool locked; git_filebuf locked_buf; - git_buf locked_content; + git_str locked_content; config_file file; } config_file_backend; @@ -131,7 +131,7 @@ static int config_file_open(git_config_backend *cfg, git_config_level_t level, c static int config_file_is_modified(int *modified, config_file *file) { config_file *include; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_oid hash; uint32_t i; int error = 0; @@ -159,7 +159,7 @@ static int config_file_is_modified(int *modified, config_file *file) } out: - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -486,7 +486,7 @@ static int config_file_unlock(git_config_backend *_cfg, int success) } git_filebuf_cleanup(&cfg->locked_buf); - git_buf_dispose(&cfg->locked_content); + git_str_dispose(&cfg->locked_content); cfg->locked = false; return error; @@ -523,7 +523,7 @@ int git_config_backend_from_file(git_config_backend **out, const char *path) return 0; } -static int included_path(git_buf *out, const char *dir, const char *path) +static int included_path(git_str *out, const char *dir, const char *path) { /* From the user's home */ if (path[0] == '~' && path[1] == '/') @@ -535,7 +535,7 @@ static int included_path(git_buf *out, const char *dir, const char *path) /* Escape the values to write them to the file */ static char *escape_value(const char *ptr) { - git_buf buf; + git_str buf; size_t len; const char *esc; @@ -545,29 +545,29 @@ static char *escape_value(const char *ptr) if (!len) return git__calloc(1, sizeof(char)); - if (git_buf_init(&buf, len) < 0) + if (git_str_init(&buf, len) < 0) return NULL; while (*ptr != '\0') { if ((esc = strchr(git_config_escaped, *ptr)) != NULL) { - git_buf_putc(&buf, '\\'); - git_buf_putc(&buf, git_config_escapes[esc - git_config_escaped]); + git_str_putc(&buf, '\\'); + git_str_putc(&buf, git_config_escapes[esc - git_config_escaped]); } else { - git_buf_putc(&buf, *ptr); + git_str_putc(&buf, *ptr); } ptr++; } - if (git_buf_oom(&buf)) + if (git_str_oom(&buf)) return NULL; - return git_buf_detach(&buf); + return git_str_detach(&buf); } static int parse_include(config_file_parse_data *parse_data, const char *file) { config_file *include; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; char *dir; int result; @@ -577,7 +577,7 @@ static int parse_include(config_file_parse_data *parse_data, const char *file) if ((result = git_path_dirname_r(&path, parse_data->file->path)) < 0) return result; - dir = git_buf_detach(&path); + dir = git_str_detach(&path); result = included_path(&path, dir, file); git__free(dir); @@ -588,7 +588,7 @@ static int parse_include(config_file_parse_data *parse_data, const char *file) GIT_ERROR_CHECK_ALLOC(include); memset(include, 0, sizeof(*include)); git_array_init(include->includes); - include->path = git_buf_detach(&path); + include->path = git_str_detach(&path); result = config_file_read(parse_data->entries, parse_data->repo, include, parse_data->level, parse_data->depth+1); @@ -608,38 +608,38 @@ static int do_match_gitdir( const char *condition, bool case_insensitive) { - git_buf pattern = GIT_BUF_INIT, gitdir = GIT_BUF_INIT; + git_str pattern = GIT_STR_INIT, gitdir = GIT_STR_INIT; int error; if (condition[0] == '.' && git_path_is_dirsep(condition[1])) { git_path_dirname_r(&pattern, cfg_file); - git_buf_joinpath(&pattern, pattern.ptr, condition + 2); + git_str_joinpath(&pattern, pattern.ptr, condition + 2); } else if (condition[0] == '~' && git_path_is_dirsep(condition[1])) git_sysdir_expand_global_file(&pattern, condition + 1); else if (!git_path_is_absolute(condition)) - git_buf_joinpath(&pattern, "**", condition); + git_str_joinpath(&pattern, "**", condition); else - git_buf_sets(&pattern, condition); + git_str_sets(&pattern, condition); if (git_path_is_dirsep(condition[strlen(condition) - 1])) - git_buf_puts(&pattern, "**"); + git_str_puts(&pattern, "**"); - if (git_buf_oom(&pattern)) { + if (git_str_oom(&pattern)) { error = -1; goto out; } - if ((error = git_repository_item_path(&gitdir, repo, GIT_REPOSITORY_ITEM_GITDIR)) < 0) + if ((error = git_repository__item_path(&gitdir, repo, GIT_REPOSITORY_ITEM_GITDIR)) < 0) goto out; if (git_path_is_dirsep(gitdir.ptr[gitdir.size - 1])) - git_buf_truncate(&gitdir, gitdir.size - 1); + git_str_truncate(&gitdir, gitdir.size - 1); *matches = wildmatch(pattern.ptr, gitdir.ptr, WM_PATHNAME | (case_insensitive ? WM_CASEFOLD : 0)) == WM_MATCH; out: - git_buf_dispose(&pattern); - git_buf_dispose(&gitdir); + git_str_dispose(&pattern); + git_str_dispose(&gitdir); return error; } @@ -667,7 +667,7 @@ static int conditional_match_onbranch( const char *cfg_file, const char *condition) { - git_buf reference = GIT_BUF_INIT, buf = GIT_BUF_INIT; + git_str reference = GIT_STR_INIT, buf = GIT_STR_INIT; int error; GIT_UNUSED(cfg_file); @@ -680,33 +680,33 @@ static int conditional_match_onbranch( * an endless recursion. */ - if ((error = git_buf_joinpath(&buf, git_repository_path(repo), GIT_HEAD_FILE)) < 0 || + if ((error = git_str_joinpath(&buf, git_repository_path(repo), GIT_HEAD_FILE)) < 0 || (error = git_futils_readbuffer(&reference, buf.ptr)) < 0) goto out; - git_buf_rtrim(&reference); + git_str_rtrim(&reference); if (git__strncmp(reference.ptr, GIT_SYMREF, strlen(GIT_SYMREF))) goto out; - git_buf_consume(&reference, reference.ptr + strlen(GIT_SYMREF)); + git_str_consume(&reference, reference.ptr + strlen(GIT_SYMREF)); if (git__strncmp(reference.ptr, GIT_REFS_HEADS_DIR, strlen(GIT_REFS_HEADS_DIR))) goto out; - git_buf_consume(&reference, reference.ptr + strlen(GIT_REFS_HEADS_DIR)); + git_str_consume(&reference, reference.ptr + strlen(GIT_REFS_HEADS_DIR)); /* * If the condition ends with a '/', then we should treat it as if * it had '**' appended. */ - if ((error = git_buf_sets(&buf, condition)) < 0) + if ((error = git_str_sets(&buf, condition)) < 0) goto out; if (git_path_is_dirsep(condition[strlen(condition) - 1]) && - (error = git_buf_puts(&buf, "**")) < 0) + (error = git_str_puts(&buf, "**")) < 0) goto out; *matches = wildmatch(buf.ptr, reference.ptr, WM_PATHNAME) == WM_MATCH; out: - git_buf_dispose(&reference); - git_buf_dispose(&buf); + git_str_dispose(&reference); + git_str_dispose(&buf); return error; @@ -763,7 +763,7 @@ static int read_on_variable( void *data) { config_file_parse_data *parse_data = (config_file_parse_data *)data; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_config_entry *entry; const char *c; int result = 0; @@ -777,19 +777,19 @@ static int read_on_variable( * here. Git appears to warn in most cases if it sees * un-namespaced config options. */ - git_buf_puts(&buf, current_section); - git_buf_putc(&buf, '.'); + git_str_puts(&buf, current_section); + git_str_putc(&buf, '.'); } for (c = var_name; *c; c++) - git_buf_putc(&buf, git__tolower(*c)); + git_str_putc(&buf, git__tolower(*c)); - if (git_buf_oom(&buf)) + if (git_str_oom(&buf)) return -1; entry = git__calloc(1, sizeof(git_config_entry)); GIT_ERROR_CHECK_ALLOC(entry); - entry->name = git_buf_detach(&buf); + entry->name = git_str_detach(&buf); entry->value = var_value ? git__strdup(var_value) : NULL; entry->level = parse_data->level; entry->include_depth = parse_data->depth; @@ -856,7 +856,7 @@ static int config_file_read( git_config_level_t level, int depth) { - git_buf contents = GIT_BUF_INIT; + git_str contents = GIT_STR_INIT; struct stat st; int error; @@ -877,36 +877,36 @@ static int config_file_read( goto out; out: - git_buf_dispose(&contents); + git_str_dispose(&contents); return error; } -static int write_section(git_buf *fbuf, const char *key) +static int write_section(git_str *fbuf, const char *key) { int result; const char *dot; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; /* All of this just for [section "subsection"] */ dot = strchr(key, '.'); - git_buf_putc(&buf, '['); + git_str_putc(&buf, '['); if (dot == NULL) { - git_buf_puts(&buf, key); + git_str_puts(&buf, key); } else { char *escaped; - git_buf_put(&buf, key, dot - key); + git_str_put(&buf, key, dot - key); escaped = escape_value(dot + 1); GIT_ERROR_CHECK_ALLOC(escaped); - git_buf_printf(&buf, " \"%s\"", escaped); + git_str_printf(&buf, " \"%s\"", escaped); git__free(escaped); } - git_buf_puts(&buf, "]\n"); + git_str_puts(&buf, "]\n"); - if (git_buf_oom(&buf)) + if (git_str_oom(&buf)) return -1; - result = git_buf_put(fbuf, git_buf_cstr(&buf), buf.size); - git_buf_dispose(&buf); + result = git_str_put(fbuf, git_str_cstr(&buf), buf.size); + git_str_dispose(&buf); return result; } @@ -930,8 +930,8 @@ static const char *quotes_for_value(const char *value) } struct write_data { - git_buf *buf; - git_buf buffered_comment; + git_str *buf; + git_str buffered_comment; unsigned int in_section : 1, preg_replaced : 1; const char *orig_section; @@ -942,12 +942,12 @@ struct write_data { const char *value; }; -static int write_line_to(git_buf *buf, const char *line, size_t line_len) +static int write_line_to(git_str *buf, const char *line, size_t line_len) { - int result = git_buf_put(buf, line, line_len); + int result = git_str_put(buf, line, line_len); if (!result && line_len && line[line_len-1] != '\n') - result = git_buf_printf(buf, "\n"); + result = git_str_printf(buf, "\n"); return result; } @@ -963,7 +963,7 @@ static int write_value(struct write_data *write_data) int result; q = quotes_for_value(write_data->value); - result = git_buf_printf(write_data->buf, + result = git_str_printf(write_data->buf, "\t%s = %s%s%s\n", write_data->orig_name, q, write_data->value, q); /* If we are updating a single name/value, we're done. Setting `value` @@ -1002,8 +1002,8 @@ static int write_on_section( * If there were comments just before this section, dump them as well. */ if (!result) { - result = git_buf_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size); - git_buf_clear(&write_data->buffered_comment); + result = git_str_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size); + git_str_clear(&write_data->buffered_comment); } if (!result) @@ -1031,10 +1031,10 @@ static int write_on_variable( /* * If there were comments just before this variable, let's dump them as well. */ - if ((error = git_buf_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size)) < 0) + if ((error = git_str_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size)) < 0) return error; - git_buf_clear(&write_data->buffered_comment); + git_str_clear(&write_data->buffered_comment); /* See if we are to update this name/value pair; first examine name */ if (write_data->in_section && @@ -1081,7 +1081,7 @@ static int write_on_eof( /* * If we've buffered comments when reaching EOF, make sure to dump them. */ - if ((result = git_buf_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size)) < 0) + if ((result = git_str_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size)) < 0) return result; /* If we are at the EOF and have not written our value (again, for a @@ -1108,7 +1108,7 @@ static int config_file_write(config_file_backend *cfg, const char *orig_key, con { char *orig_section = NULL, *section = NULL, *orig_name, *name, *ldot; - git_buf buf = GIT_BUF_INIT, contents = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT, contents = GIT_STR_INIT; git_config_parser parser = GIT_CONFIG_PARSER_INIT; git_filebuf file = GIT_FILEBUF_INIT; struct write_data write_data; @@ -1117,7 +1117,7 @@ static int config_file_write(config_file_backend *cfg, const char *orig_key, con memset(&write_data, 0, sizeof(write_data)); if (cfg->locked) { - error = git_buf_puts(&contents, git_buf_cstr(&cfg->locked_content) == NULL ? "" : git_buf_cstr(&cfg->locked_content)); + error = git_str_puts(&contents, git_str_cstr(&cfg->locked_content) == NULL ? "" : git_str_cstr(&cfg->locked_content)); } else { if ((error = git_filebuf_open(&file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS, GIT_CONFIG_FILE_MODE)) < 0) @@ -1157,10 +1157,10 @@ static int config_file_write(config_file_backend *cfg, const char *orig_key, con if (cfg->locked) { size_t len = buf.asize; /* Update our copy with the modified contents */ - git_buf_dispose(&cfg->locked_content); - git_buf_attach(&cfg->locked_content, git_buf_detach(&buf), len); + git_str_dispose(&cfg->locked_content); + git_str_attach(&cfg->locked_content, git_str_detach(&buf), len); } else { - git_filebuf_write(&file, git_buf_cstr(&buf), git_buf_len(&buf)); + git_filebuf_write(&file, git_str_cstr(&buf), git_str_len(&buf)); if ((error = git_filebuf_commit(&file)) < 0) goto done; @@ -1172,9 +1172,9 @@ static int config_file_write(config_file_backend *cfg, const char *orig_key, con done: git__free(section); git__free(orig_section); - git_buf_dispose(&write_data.buffered_comment); - git_buf_dispose(&buf); - git_buf_dispose(&contents); + git_str_dispose(&write_data.buffered_comment); + git_str_dispose(&buf); + git_str_dispose(&contents); git_filebuf_cleanup(&file); git_config_parser_dispose(&parser); diff --git a/src/config_mem.c b/src/config_mem.c index 5b573a995c9..560229cf534 100644 --- a/src/config_mem.c +++ b/src/config_mem.c @@ -14,7 +14,7 @@ typedef struct { git_config_backend parent; git_config_entries *entries; - git_buf cfg; + git_str cfg; } config_memory_backend; typedef struct { @@ -38,7 +38,7 @@ static int read_variable_cb( void *payload) { config_memory_parse_data *parse_data = (config_memory_parse_data *) payload; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_config_entry *entry; const char *c; int result; @@ -52,19 +52,19 @@ static int read_variable_cb( * here. Git appears to warn in most cases if it sees * un-namespaced config options. */ - git_buf_puts(&buf, current_section); - git_buf_putc(&buf, '.'); + git_str_puts(&buf, current_section); + git_str_putc(&buf, '.'); } for (c = var_name; *c; c++) - git_buf_putc(&buf, git__tolower(*c)); + git_str_putc(&buf, git__tolower(*c)); - if (git_buf_oom(&buf)) + if (git_str_oom(&buf)) return -1; entry = git__calloc(1, sizeof(git_config_entry)); GIT_ERROR_CHECK_ALLOC(entry); - entry->name = git_buf_detach(&buf); + entry->name = git_str_detach(&buf); entry->value = var_value ? git__strdup(var_value) : NULL; entry->level = parse_data->level; entry->include_depth = 0; @@ -178,7 +178,7 @@ static void config_memory_free(git_config_backend *_backend) return; git_config_entries_free(backend->entries); - git_buf_dispose(&backend->cfg); + git_str_dispose(&backend->cfg); git__free(backend); } @@ -194,7 +194,7 @@ int git_config_backend_from_string(git_config_backend **out, const char *cfg, si return -1; } - if (git_buf_set(&backend->cfg, cfg, len) < 0) { + if (git_str_set(&backend->cfg, cfg, len) < 0) { git_config_entries_free(backend->entries); git__free(backend); return -1; diff --git a/src/config_parse.c b/src/config_parse.c index 9f95e67d78c..3159cbef768 100644 --- a/src/config_parse.c +++ b/src/config_parse.c @@ -67,7 +67,7 @@ static int parse_subsection_header(git_config_parser *reader, const char *line, int c, rpos; const char *first_quote, *last_quote; const char *line_start = line; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; size_t quoted_len, alloc_len, base_name_len = strlen(base_name); /* Skip any additional whitespace before our section name */ @@ -97,8 +97,8 @@ static int parse_subsection_header(git_config_parser *reader, const char *line, GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, base_name_len, quoted_len); GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2); - if (git_buf_grow(&buf, alloc_len) < 0 || - git_buf_printf(&buf, "%s.", base_name) < 0) + if (git_str_grow(&buf, alloc_len) < 0 || + git_str_printf(&buf, "%s.", base_name) < 0) goto end_error; rpos = 0; @@ -132,25 +132,25 @@ static int parse_subsection_header(git_config_parser *reader, const char *line, break; } - git_buf_putc(&buf, (char)c); + git_str_putc(&buf, (char)c); c = line[++rpos]; } while (line + rpos < last_quote); end_parse: - if (git_buf_oom(&buf)) + if (git_str_oom(&buf)) goto end_error; if (line[rpos] != '"' || line[rpos + 1] != ']') { set_parse_error(reader, rpos, "unexpected text after closing quotes"); - git_buf_dispose(&buf); + git_str_dispose(&buf); return -1; } - *section_name = git_buf_detach(&buf); + *section_name = git_str_detach(&buf); return (int)(&line[rpos + 2] - line_start); /* rpos is at the closing quote */ end_error: - git_buf_dispose(&buf); + git_str_dispose(&buf); return -1; } @@ -227,11 +227,11 @@ static int parse_section_header(git_config_parser *reader, char **section_out) static int skip_bom(git_parse_ctx *parser) { - git_buf buf = GIT_BUF_INIT_CONST(parser->content, parser->content_len); - git_buf_bom_t bom; - int bom_offset = git_buf_detect_bom(&bom, &buf); + git_str buf = GIT_STR_INIT_CONST(parser->content, parser->content_len); + git_str_bom_t bom; + int bom_offset = git_str_detect_bom(&bom, &buf); - if (bom == GIT_BUF_BOM_UTF8) + if (bom == GIT_STR_BOM_UTF8) git_parse_advance_chars(parser, bom_offset); /* TODO: reference implementation is pretty stupid with BoM */ @@ -325,7 +325,7 @@ static int unescape_line( return 0; } -static int parse_multiline_variable(git_config_parser *reader, git_buf *value, int in_quotes) +static int parse_multiline_variable(git_config_parser *reader, git_str *value, int in_quotes) { int quote_count; bool multiline = true; @@ -358,7 +358,7 @@ static int parse_multiline_variable(git_config_parser *reader, git_buf *value, i goto out; /* Add this line to the multiline var */ - if ((error = git_buf_puts(value, proc_line)) < 0) + if ((error = git_str_puts(value, proc_line)) < 0) goto out; next: @@ -445,18 +445,18 @@ static int parse_variable(git_config_parser *reader, char **var_name, char **var goto out; if (multiline) { - git_buf multi_value = GIT_BUF_INIT; - git_buf_attach(&multi_value, value, 0); + git_str multi_value = GIT_STR_INIT; + git_str_attach(&multi_value, value, 0); value = NULL; if (parse_multiline_variable(reader, &multi_value, quote_count % 2) < 0 || - git_buf_oom(&multi_value)) { + git_str_oom(&multi_value)) { error = -1; - git_buf_dispose(&multi_value); + git_str_dispose(&multi_value); goto out; } - value = git_buf_detach(&multi_value); + value = git_str_detach(&multi_value); } } diff --git a/src/crlf.c b/src/crlf.c index 406f7140f21..7895ddec2a9 100644 --- a/src/crlf.c +++ b/src/crlf.c @@ -12,6 +12,7 @@ #include "git2/index.h" #include "git2/sys/filter.h" +#include "buf.h" #include "futils.h" #include "hash.h" #include "filter.h" @@ -152,7 +153,7 @@ static git_configmap_value output_eol(struct crlf_attrs *ca) GIT_INLINE(int) check_safecrlf( struct crlf_attrs *ca, const git_filter_source *src, - git_buf_text_stats *stats) + git_str_text_stats *stats) { const char *filename = git_filter_source_path(src); @@ -206,19 +207,19 @@ GIT_INLINE(int) check_safecrlf( static int crlf_apply_to_odb( struct crlf_attrs *ca, - git_buf *to, - const git_buf *from, + git_str *to, + const git_str *from, const git_filter_source *src) { - git_buf_text_stats stats; + git_str_text_stats stats; bool is_binary; int error; /* Binary attribute? Empty file? Nothing to do */ - if (ca->crlf_action == GIT_CRLF_BINARY || !git_buf_len(from)) + if (ca->crlf_action == GIT_CRLF_BINARY || from->size == 0) return GIT_PASSTHROUGH; - is_binary = git_buf_gather_text_stats(&stats, from, false); + is_binary = git_str_gather_text_stats(&stats, from, false); /* Heuristics to see if we can skip the conversion. * Straight from Core Git. @@ -246,22 +247,22 @@ static int crlf_apply_to_odb( return GIT_PASSTHROUGH; /* Actually drop the carriage returns */ - return git_buf_crlf_to_lf(to, from); + return git_str_crlf_to_lf(to, from); } static int crlf_apply_to_workdir( struct crlf_attrs *ca, - git_buf *to, - const git_buf *from) + git_str *to, + const git_str *from) { - git_buf_text_stats stats; + git_str_text_stats stats; bool is_binary; /* Empty file? Nothing to do. */ - if (git_buf_len(from) == 0 || output_eol(ca) != GIT_EOL_CRLF) + if (git_str_len(from) == 0 || output_eol(ca) != GIT_EOL_CRLF) return GIT_PASSTHROUGH; - is_binary = git_buf_gather_text_stats(&stats, from, false); + is_binary = git_str_gather_text_stats(&stats, from, false); /* If there are no LFs, or all LFs are part of a CRLF, nothing to do */ if (stats.lf == 0 || stats.lf == stats.crlf) @@ -280,7 +281,7 @@ static int crlf_apply_to_workdir( return GIT_PASSTHROUGH; } - return git_buf_lf_to_crlf(to, from); + return git_str_lf_to_crlf(to, from); } static int convert_attrs( @@ -368,22 +369,24 @@ static int crlf_check( static int crlf_apply( git_filter *self, void **payload, /* may be read and/or set */ - git_buf *to, - const git_buf *from, + git_str *to, + const git_str *from, const git_filter_source *src) { + int error = 0; + /* initialize payload in case `check` was bypassed */ if (!*payload) { - int error = crlf_check(self, payload, src, NULL); - - if (error < 0) + if ((error = crlf_check(self, payload, src, NULL)) < 0) return error; } if (git_filter_source_mode(src) == GIT_FILTER_SMUDGE) - return crlf_apply_to_workdir(*payload, to, from); + error = crlf_apply_to_workdir(*payload, to, from); else - return crlf_apply_to_odb(*payload, to, from, src); + error = crlf_apply_to_odb(*payload, to, from, src); + + return error; } static int crlf_stream( diff --git a/src/describe.c b/src/describe.c index 103d0da5c8d..1033eac500a 100644 --- a/src/describe.c +++ b/src/describe.c @@ -12,6 +12,7 @@ #include "git2/diff.h" #include "git2/status.h" +#include "buf.h" #include "commit.h" #include "commit_list.h" #include "oidmap.h" @@ -322,7 +323,7 @@ static unsigned long finish_depth_computation( return seen_commits; } -static int display_name(git_buf *buf, git_repository *repo, struct commit_name *n) +static int display_name(git_str *buf, git_repository *repo, struct commit_name *n) { if (n->prio == 2 && !n->tag) { if (git_tag_lookup(&n->tag, repo, &n->sha1) < 0) { @@ -346,9 +347,9 @@ static int display_name(git_buf *buf, git_repository *repo, struct commit_name * } if (n->tag) - git_buf_printf(buf, "%s", git_tag_name(n->tag)); + git_str_printf(buf, "%s", git_tag_name(n->tag)); else - git_buf_printf(buf, "%s", n->path); + git_str_printf(buf, "%s", n->path); return 0; } @@ -388,7 +389,7 @@ static int find_unique_abbrev_size( } static int show_suffix( - git_buf *buf, + git_str *buf, int depth, git_repository *repo, const git_oid *id, @@ -403,11 +404,11 @@ static int show_suffix( git_oid_fmt(hex_oid, id); - git_buf_printf(buf, "-%d-g", depth); + git_str_printf(buf, "-%d-g", depth); - git_buf_put(buf, hex_oid, size); + git_str_put(buf, hex_oid, size); - return git_buf_oom(buf) ? -1 : 0; + return git_str_oom(buf) ? -1 : 0; } #define MAX_CANDIDATES_TAGS FLAG_BITS - 1 @@ -769,7 +770,10 @@ static int normalize_format_options( return 0; } -int git_describe_format(git_buf *out, const git_describe_result *result, const git_describe_format_options *given) +static int git_describe__format( + git_str *out, + const git_describe_result *result, + const git_describe_format_options *given) { int error; git_repository *repo; @@ -782,10 +786,6 @@ int git_describe_format(git_buf *out, const git_describe_result *result, const g GIT_ERROR_CHECK_VERSION(given, GIT_DESCRIBE_FORMAT_OPTIONS_VERSION, "git_describe_format_options"); normalize_format_options(&opts, given); - if ((error = git_buf_sanitize(out)) < 0) - return error; - - if (opts.always_use_long_format && opts.abbreviated_size == 0) { git_error_set(GIT_ERROR_DESCRIBE, "cannot describe - " "'always_use_long_format' is incompatible with a zero" @@ -809,9 +809,9 @@ int git_describe_format(git_buf *out, const git_describe_result *result, const g } if (result->dirty && opts.dirty_suffix) - git_buf_puts(out, opts.dirty_suffix); + git_str_puts(out, opts.dirty_suffix); - return git_buf_oom(out) ? -1 : 0; + return git_str_oom(out) ? -1 : 0; } /* If we didn't find *any* tags, we fall back to the commit's id */ @@ -824,12 +824,12 @@ int git_describe_format(git_buf *out, const git_describe_result *result, const g return -1; git_oid_fmt(hex_oid, &result->commit_id); - git_buf_put(out, hex_oid, size); + git_str_put(out, hex_oid, size); if (result->dirty && opts.dirty_suffix) - git_buf_puts(out, opts.dirty_suffix); + git_str_puts(out, opts.dirty_suffix); - return git_buf_oom(out) ? -1 : 0; + return git_str_oom(out) ? -1 : 0; } /* Lastly, if we found a matching tag, we show that */ @@ -845,10 +845,18 @@ int git_describe_format(git_buf *out, const git_describe_result *result, const g } if (result->dirty && opts.dirty_suffix) { - git_buf_puts(out, opts.dirty_suffix); + git_str_puts(out, opts.dirty_suffix); } - return git_buf_oom(out) ? -1 : 0; + return git_str_oom(out) ? -1 : 0; +} + +int git_describe_format( + git_buf *out, + const git_describe_result *result, + const git_describe_format_options *given) +{ + GIT_BUF_WRAP_PRIVATE(out, git_describe__format, result, given); } void git_describe_result_free(git_describe_result *result) diff --git a/src/diff.c b/src/diff.c index 44b67ee0622..9840d6050da 100644 --- a/src/diff.c +++ b/src/diff.c @@ -8,6 +8,7 @@ #include "diff.h" #include "common.h" +#include "buf.h" #include "patch.h" #include "email.h" #include "commit.h" @@ -162,6 +163,7 @@ int git_diff_format_email( const git_diff_format_email_options *opts) { git_email_create_options email_create_opts = GIT_EMAIL_CREATE_OPTIONS_INIT; + git_str email = GIT_STR_INIT; int error; GIT_ASSERT_ARG(out); @@ -172,14 +174,29 @@ int git_diff_format_email( GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, "git_format_email_options"); + /* This is a `git_buf` special case; subsequent calls append. */ + email.ptr = out->ptr; + email.asize = out->reserved; + email.size = out->size; + + out->ptr = git_str__initstr; + out->reserved = 0; + out->size = 0; + if ((opts->flags & GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER) != 0) email_create_opts.subject_prefix = ""; - - error = git_email__append_from_diff(out, diff, opts->patch_no, + error = git_email__append_from_diff(&email, diff, opts->patch_no, opts->total_patches, opts->id, opts->summary, opts->body, opts->author, &email_create_opts); + if (error < 0) + goto done; + + error = git_buf_fromstr(out, &email); + +done: + git_str_dispose(&email); return error; } @@ -282,7 +299,7 @@ static int flush_hunk(git_oid *result, git_hash_ctx *ctx) return 0; } -static void strip_spaces(git_buf *buf) +static void strip_spaces(git_str *buf) { char *src = buf->ptr, *dst = buf->ptr; char c; @@ -295,7 +312,7 @@ static void strip_spaces(git_buf *buf) } } - git_buf_truncate(buf, len); + git_str_truncate(buf, len); } static int diff_patchid_print_callback_to_buf( @@ -305,7 +322,7 @@ static int diff_patchid_print_callback_to_buf( void *payload) { struct patch_id_args *args = (struct patch_id_args *) payload; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error = 0; if (line->origin == GIT_DIFF_LINE_CONTEXT_EOFNL || @@ -331,7 +348,7 @@ static int diff_patchid_print_callback_to_buf( args->first_file = 0; out: - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } diff --git a/src/diff.h b/src/diff.h index 69233b39fbf..4b033980912 100644 --- a/src/diff.h +++ b/src/diff.h @@ -14,9 +14,7 @@ #include "git2/sys/diff.h" #include "git2/oid.h" -#include #include "vector.h" -#include "buffer.h" #include "iterator.h" #include "repository.h" #include "pool.h" @@ -53,7 +51,7 @@ struct git_diff { }; extern int git_diff_delta__format_file_header( - git_buf *out, + git_str *out, const git_diff_delta *delta, const char *oldpfx, const char *newpfx, diff --git a/src/diff_driver.c b/src/diff_driver.c index a3892d35eea..f6b51d8bae6 100644 --- a/src/diff_driver.c +++ b/src/diff_driver.c @@ -90,7 +90,7 @@ static int diff_driver_add_patterns( int error = 0; const char *scan, *end; git_diff_driver_pattern *pat = NULL; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; for (scan = regex_str; scan; scan = end) { /* get pattern to fill in */ @@ -105,10 +105,10 @@ static int diff_driver_add_patterns( } if ((end = strchr(scan, '\n')) != NULL) { - error = git_buf_set(&buf, scan, end - scan); + error = git_str_set(&buf, scan, end - scan); end++; } else { - error = git_buf_sets(&buf, scan); + error = git_str_sets(&buf, scan); } if (error < 0) break; @@ -122,7 +122,7 @@ static int diff_driver_add_patterns( if (error && pat != NULL) (void)git_array_pop(drv->fn_patterns); /* release last item */ - git_buf_dispose(&buf); + git_str_dispose(&buf); /* We want to ignore bad patterns, so return success regardless */ return 0; @@ -237,7 +237,7 @@ static int git_diff_driver_load( git_diff_driver *drv; size_t namelen; git_config *cfg = NULL; - git_buf name = GIT_BUF_INIT; + git_str name = GIT_STR_INIT; git_config_entry *ce = NULL; bool found_driver = false; @@ -260,7 +260,7 @@ static int git_diff_driver_load( goto done; } - if ((error = git_buf_printf(&name, "diff.%s.binary", driver_name)) < 0) + if ((error = git_str_printf(&name, "diff.%s.binary", driver_name)) < 0) goto done; switch (git_config__get_bool_force(cfg, name.ptr, -1)) { @@ -281,8 +281,8 @@ static int git_diff_driver_load( /* TODO: warn if diff..command or diff..textconv are set */ - git_buf_truncate(&name, namelen + strlen("diff..")); - if ((error = git_buf_PUTS(&name, "xfuncname")) < 0) + git_str_truncate(&name, namelen + strlen("diff..")); + if ((error = git_str_PUTS(&name, "xfuncname")) < 0) goto done; if ((error = git_config_get_multivar_foreach( @@ -292,8 +292,8 @@ static int git_diff_driver_load( git_error_clear(); /* no diff..xfuncname, so just continue */ } - git_buf_truncate(&name, namelen + strlen("diff..")); - if ((error = git_buf_PUTS(&name, "funcname")) < 0) + git_str_truncate(&name, namelen + strlen("diff..")); + if ((error = git_str_PUTS(&name, "funcname")) < 0) goto done; if ((error = git_config_get_multivar_foreach( @@ -309,8 +309,8 @@ static int git_diff_driver_load( found_driver = true; } - git_buf_truncate(&name, namelen + strlen("diff..")); - if ((error = git_buf_PUTS(&name, "wordregex")) < 0) + git_str_truncate(&name, namelen + strlen("diff..")); + if ((error = git_str_PUTS(&name, "wordregex")) < 0) goto done; if ((error = git_config__lookup_entry(&ce, cfg, name.ptr, false)) < 0) @@ -340,7 +340,7 @@ static int git_diff_driver_load( done: git_config_entry_free(ce); - git_buf_dispose(&name); + git_str_dispose(&name); git_config_free(cfg); if (!*out) { @@ -420,11 +420,11 @@ void git_diff_driver_update_options( int git_diff_driver_content_is_binary( git_diff_driver *driver, const char *content, size_t content_len) { - git_buf search = GIT_BUF_INIT; + git_str search = GIT_STR_INIT; GIT_UNUSED(driver); - git_buf_attach_notowned(&search, content, + git_str_attach_notowned(&search, content, min(content_len, GIT_FILTER_BYTES_TO_CHECK_NUL)); /* TODO: provide encoding / binary detection callbacks that can @@ -432,15 +432,15 @@ int git_diff_driver_content_is_binary( * let's just use the simple NUL-byte detection that core git uses. */ - /* previously was: if (git_buf_is_binary(&search)) */ - if (git_buf_contains_nul(&search)) + /* previously was: if (git_str_is_binary(&search)) */ + if (git_str_contains_nul(&search)) return 1; return 0; } static int diff_context_line__simple( - git_diff_driver *driver, git_buf *line) + git_diff_driver *driver, git_str *line) { char firstch = line->ptr[0]; GIT_UNUSED(driver); @@ -448,7 +448,7 @@ static int diff_context_line__simple( } static int diff_context_line__pattern_match( - git_diff_driver *driver, git_buf *line) + git_diff_driver *driver, git_str *line) { size_t i, maxi = git_array_size(driver->fn_patterns); git_regmatch pmatch[2]; @@ -462,9 +462,9 @@ static int diff_context_line__pattern_match( /* use pmatch data to trim line data */ i = (pmatch[1].start >= 0) ? 1 : 0; - git_buf_consume(line, git_buf_cstr(line) + pmatch[i].start); - git_buf_truncate(line, pmatch[i].end - pmatch[i].start); - git_buf_rtrim(line); + git_str_consume(line, git_str_cstr(line) + pmatch[i].start); + git_str_truncate(line, pmatch[i].end - pmatch[i].start); + git_str_rtrim(line); return true; } @@ -482,9 +482,9 @@ static long diff_context_find( { git_diff_find_context_payload *ctxt = payload; - if (git_buf_set(&ctxt->line, line, (size_t)line_len) < 0) + if (git_str_set(&ctxt->line, line, (size_t)line_len) < 0) return -1; - git_buf_rtrim(&ctxt->line); + git_str_rtrim(&ctxt->line); if (!ctxt->line.size) return -1; @@ -511,14 +511,14 @@ void git_diff_find_context_init( payload_out->driver = driver; payload_out->match_line = (driver->type == DIFF_DRIVER_PATTERNLIST) ? diff_context_line__pattern_match : diff_context_line__simple; - git_buf_init(&payload_out->line, 0); + git_str_init(&payload_out->line, 0); } } void git_diff_find_context_clear(git_diff_find_context_payload *payload) { if (payload) { - git_buf_dispose(&payload->line); + git_str_dispose(&payload->line); payload->driver = NULL; } } diff --git a/src/diff_driver.h b/src/diff_driver.h index a03a67e676e..03711e89e8b 100644 --- a/src/diff_driver.h +++ b/src/diff_driver.h @@ -10,7 +10,7 @@ #include "common.h" #include "attr_file.h" -#include "buffer.h" +#include "str.h" typedef struct git_diff_driver_registry git_diff_driver_registry; @@ -34,12 +34,12 @@ typedef long (*git_diff_find_context_fn)( const char *, long, char *, long, void *); typedef int (*git_diff_find_context_line)( - git_diff_driver *, git_buf *); + git_diff_driver *, git_str *); typedef struct { git_diff_driver *driver; git_diff_find_context_line match_line; - git_buf line; + git_str line; } git_diff_find_context_payload; void git_diff_find_context_init( diff --git a/src/diff_file.c b/src/diff_file.c index eeaf4a5a274..78e332f2247 100644 --- a/src/diff_file.c +++ b/src/diff_file.c @@ -178,7 +178,7 @@ static int diff_file_content_commit_to_str( git_diff_file_content *fc, bool check_status) { char oid[GIT_OID_HEXSZ+1]; - git_buf content = GIT_BUF_INIT; + git_str content = GIT_STR_INIT; const char *status = ""; if (check_status) { @@ -217,11 +217,11 @@ static int diff_file_content_commit_to_str( } git_oid_tostr(oid, sizeof(oid), &fc->file->id); - if (git_buf_printf(&content, "Subproject commit %s%s\n", oid, status) < 0) + if (git_str_printf(&content, "Subproject commit %s%s\n", oid, status) < 0) return -1; - fc->map.len = git_buf_len(&content); - fc->map.data = git_buf_detach(&content); + fc->map.len = git_str_len(&content); + fc->map.data = git_str_detach(&content); fc->flags |= GIT_DIFF_FLAG__FREE_DATA; return 0; @@ -270,24 +270,24 @@ static int diff_file_content_load_blob( } static int diff_file_content_load_workdir_symlink_fake( - git_diff_file_content *fc, git_buf *path) + git_diff_file_content *fc, git_str *path) { - git_buf target = GIT_BUF_INIT; + git_str target = GIT_STR_INIT; int error; if ((error = git_futils_readbuffer(&target, path->ptr)) < 0) return error; - fc->map.len = git_buf_len(&target); - fc->map.data = git_buf_detach(&target); + fc->map.len = git_str_len(&target); + fc->map.data = git_str_detach(&target); fc->flags |= GIT_DIFF_FLAG__FREE_DATA; - git_buf_dispose(&target); + git_str_dispose(&target); return error; } static int diff_file_content_load_workdir_symlink( - git_diff_file_content *fc, git_buf *path) + git_diff_file_content *fc, git_str *path) { ssize_t alloc_len, read_len; int symlink_supported, error; @@ -309,7 +309,7 @@ static int diff_file_content_load_workdir_symlink( fc->flags |= GIT_DIFF_FLAG__FREE_DATA; - read_len = p_readlink(git_buf_cstr(path), fc->map.data, alloc_len); + read_len = p_readlink(git_str_cstr(path), fc->map.data, alloc_len); if (read_len < 0) { git_error_set(GIT_ERROR_OS, "failed to read symlink '%s'", fc->file->path); return -1; @@ -321,13 +321,13 @@ static int diff_file_content_load_workdir_symlink( static int diff_file_content_load_workdir_file( git_diff_file_content *fc, - git_buf *path, + git_str *path, git_diff_options *diff_opts) { int error = 0; git_filter_list *fl = NULL; - git_file fd = git_futils_open_ro(git_buf_cstr(path)); - git_buf raw = GIT_BUF_INIT; + git_file fd = git_futils_open_ro(git_str_cstr(path)); + git_str raw = GIT_STR_INIT; if (fd < 0) return fd; @@ -360,7 +360,7 @@ static int diff_file_content_load_workdir_file( } if (!(error = git_futils_readbuffer_fd(&raw, fd, (size_t)fc->file->size))) { - git_buf out = GIT_BUF_INIT; + git_str out = GIT_STR_INIT; error = git_filter_list__convert_buf(&out, fl, &raw); @@ -383,7 +383,7 @@ static int diff_file_content_load_workdir( git_diff_options *diff_opts) { int error = 0; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; if (fc->file->mode == GIT_FILEMODE_COMMIT) return diff_file_content_commit_to_str(fc, true); @@ -406,7 +406,7 @@ static int diff_file_content_load_workdir( fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; } - git_buf_dispose(&path); + git_str_dispose(&path); return error; } diff --git a/src/diff_generate.c b/src/diff_generate.c index aba9e52ba7f..dc690aa9b9e 100644 --- a/src/diff_generate.c +++ b/src/diff_generate.c @@ -586,7 +586,7 @@ int git_diff__oid_for_entry( const git_oid *update_match) { git_diff_generated *diff; - git_buf full_path = GIT_BUF_INIT; + git_str full_path = GIT_STR_INIT; git_index_entry entry = *src; git_filter_list *fl = NULL; int error = 0; @@ -606,7 +606,7 @@ int git_diff__oid_for_entry( if (p_stat(full_path.ptr, &st) < 0) { error = git_path_set_error(errno, entry.path, "stat"); - git_buf_dispose(&full_path); + git_str_dispose(&full_path); return error; } @@ -669,7 +669,7 @@ int git_diff__oid_for_entry( } } - git_buf_dispose(&full_path); + git_str_dispose(&full_path); return error; } @@ -1023,7 +1023,7 @@ static int handle_unmatched_new_item( /* do not advance into directories that contain a .git file */ if (recurse_into_dir && !contains_oitem) { - git_buf *full = NULL; + git_str *full = NULL; if (git_iterator_current_workdir_path(&full, info->new_iter) < 0) return -1; if (full && git_path_contains(full, DOT_GIT)) { diff --git a/src/diff_print.c b/src/diff_print.c index 062e267b00c..03d25b087a5 100644 --- a/src/diff_print.c +++ b/src/diff_print.c @@ -7,6 +7,7 @@ #include "common.h" +#include "buf.h" #include "diff.h" #include "diff_file.h" #include "patch_generate.h" @@ -21,7 +22,7 @@ typedef struct { git_diff_line_cb print_cb; void *payload; - git_buf *buf; + git_str *buf; git_diff_line line; const char *old_prefix; @@ -34,7 +35,7 @@ typedef struct { static int diff_print_info_init__common( diff_print_info *pi, - git_buf *out, + git_str *out, git_repository *repo, git_diff_format_t format, git_diff_line_cb cb, @@ -65,7 +66,7 @@ static int diff_print_info_init__common( static int diff_print_info_init_fromdiff( diff_print_info *pi, - git_buf *out, + git_str *out, git_diff *diff, git_diff_format_t format, git_diff_line_cb cb, @@ -89,7 +90,7 @@ static int diff_print_info_init_fromdiff( static int diff_print_info_init_frompatch( diff_print_info *pi, - git_buf *out, + git_str *out, git_patch *patch, git_diff_format_t format, git_diff_line_cb cb, @@ -142,7 +143,7 @@ static int diff_print_one_name_only( const git_diff_delta *delta, float progress, void *data) { diff_print_info *pi = data; - git_buf *out = pi->buf; + git_str *out = pi->buf; GIT_UNUSED(progress); @@ -150,15 +151,15 @@ static int diff_print_one_name_only( delta->status == GIT_DELTA_UNMODIFIED) return 0; - git_buf_clear(out); - git_buf_puts(out, delta->new_file.path); - git_buf_putc(out, '\n'); - if (git_buf_oom(out)) + git_str_clear(out); + git_str_puts(out, delta->new_file.path); + git_str_putc(out, '\n'); + if (git_str_oom(out)) return -1; pi->line.origin = GIT_DIFF_LINE_FILE_HDR; - pi->line.content = git_buf_cstr(out); - pi->line.content_len = git_buf_len(out); + pi->line.content = git_str_cstr(out); + pi->line.content_len = git_str_len(out); return pi->print_cb(delta, NULL, &pi->line, pi->payload); } @@ -167,7 +168,7 @@ static int diff_print_one_name_status( const git_diff_delta *delta, float progress, void *data) { diff_print_info *pi = data; - git_buf *out = pi->buf; + git_str *out = pi->buf; char old_suffix, new_suffix, code = git_diff_status_char(delta->status); int(*strcomp)(const char *, const char *) = pi->strcomp ? pi->strcomp : git__strcmp; @@ -180,26 +181,26 @@ static int diff_print_one_name_status( old_suffix = diff_pick_suffix(delta->old_file.mode); new_suffix = diff_pick_suffix(delta->new_file.mode); - git_buf_clear(out); + git_str_clear(out); if (delta->old_file.path != delta->new_file.path && strcomp(delta->old_file.path,delta->new_file.path) != 0) - git_buf_printf(out, "%c\t%s%c %s%c\n", code, + git_str_printf(out, "%c\t%s%c %s%c\n", code, delta->old_file.path, old_suffix, delta->new_file.path, new_suffix); else if (delta->old_file.mode != delta->new_file.mode && delta->old_file.mode != 0 && delta->new_file.mode != 0) - git_buf_printf(out, "%c\t%s%c %s%c\n", code, + git_str_printf(out, "%c\t%s%c %s%c\n", code, delta->old_file.path, old_suffix, delta->new_file.path, new_suffix); else if (old_suffix != ' ') - git_buf_printf(out, "%c\t%s%c\n", code, delta->old_file.path, old_suffix); + git_str_printf(out, "%c\t%s%c\n", code, delta->old_file.path, old_suffix); else - git_buf_printf(out, "%c\t%s\n", code, delta->old_file.path); - if (git_buf_oom(out)) + git_str_printf(out, "%c\t%s\n", code, delta->old_file.path); + if (git_str_oom(out)) return -1; pi->line.origin = GIT_DIFF_LINE_FILE_HDR; - pi->line.content = git_buf_cstr(out); - pi->line.content_len = git_buf_len(out); + pi->line.content = git_str_cstr(out); + pi->line.content_len = git_str_len(out); return pi->print_cb(delta, NULL, &pi->line, pi->payload); } @@ -208,7 +209,7 @@ static int diff_print_one_raw( const git_diff_delta *delta, float progress, void *data) { diff_print_info *pi = data; - git_buf *out = pi->buf; + git_str *out = pi->buf; int id_abbrev; char code = git_diff_status_char(delta->status); char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1]; @@ -218,7 +219,7 @@ static int diff_print_one_raw( if ((pi->flags & GIT_DIFF_SHOW_UNMODIFIED) == 0 && code == ' ') return 0; - git_buf_clear(out); + git_str_clear(out); id_abbrev = delta->old_file.mode ? delta->old_file.id_abbrev : delta->new_file.id_abbrev; @@ -233,43 +234,43 @@ static int diff_print_one_raw( git_oid_tostr(start_oid, pi->id_strlen + 1, &delta->old_file.id); git_oid_tostr(end_oid, pi->id_strlen + 1, &delta->new_file.id); - git_buf_printf( + git_str_printf( out, (pi->id_strlen <= GIT_OID_HEXSZ) ? ":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c", delta->old_file.mode, delta->new_file.mode, start_oid, end_oid, code); if (delta->similarity > 0) - git_buf_printf(out, "%03u", delta->similarity); + git_str_printf(out, "%03u", delta->similarity); if (delta->old_file.path != delta->new_file.path) - git_buf_printf( + git_str_printf( out, "\t%s %s\n", delta->old_file.path, delta->new_file.path); else - git_buf_printf( + git_str_printf( out, "\t%s\n", delta->old_file.path ? delta->old_file.path : delta->new_file.path); - if (git_buf_oom(out)) + if (git_str_oom(out)) return -1; pi->line.origin = GIT_DIFF_LINE_FILE_HDR; - pi->line.content = git_buf_cstr(out); - pi->line.content_len = git_buf_len(out); + pi->line.content = git_str_cstr(out); + pi->line.content_len = git_str_len(out); return pi->print_cb(delta, NULL, &pi->line, pi->payload); } static int diff_print_modes( - git_buf *out, const git_diff_delta *delta) + git_str *out, const git_diff_delta *delta) { - git_buf_printf(out, "old mode %o\n", delta->old_file.mode); - git_buf_printf(out, "new mode %o\n", delta->new_file.mode); + git_str_printf(out, "old mode %o\n", delta->old_file.mode); + git_str_printf(out, "new mode %o\n", delta->new_file.mode); - return git_buf_oom(out) ? -1 : 0; + return git_str_oom(out) ? -1 : 0; } static int diff_print_oid_range( - git_buf *out, const git_diff_delta *delta, int id_strlen, + git_str *out, const git_diff_delta *delta, int id_strlen, bool print_index) { char start_oid[GIT_OID_HEXSZ+1], end_oid[GIT_OID_HEXSZ+1]; @@ -295,34 +296,34 @@ static int diff_print_oid_range( if (delta->old_file.mode == delta->new_file.mode) { if (print_index) - git_buf_printf(out, "index %s..%s %o\n", + git_str_printf(out, "index %s..%s %o\n", start_oid, end_oid, delta->old_file.mode); } else { if (delta->old_file.mode == 0) - git_buf_printf(out, "new file mode %o\n", delta->new_file.mode); + git_str_printf(out, "new file mode %o\n", delta->new_file.mode); else if (delta->new_file.mode == 0) - git_buf_printf(out, "deleted file mode %o\n", delta->old_file.mode); + git_str_printf(out, "deleted file mode %o\n", delta->old_file.mode); else diff_print_modes(out, delta); if (print_index) - git_buf_printf(out, "index %s..%s\n", start_oid, end_oid); + git_str_printf(out, "index %s..%s\n", start_oid, end_oid); } - return git_buf_oom(out) ? -1 : 0; + return git_str_oom(out) ? -1 : 0; } static int diff_delta_format_path( - git_buf *out, const char *prefix, const char *filename) + git_str *out, const char *prefix, const char *filename) { - if (git_buf_joinpath(out, prefix, filename) < 0) + if (git_str_joinpath(out, prefix, filename) < 0) return -1; - return git_buf_quote(out); + return git_str_quote(out); } static int diff_delta_format_with_paths( - git_buf *out, + git_str *out, const git_diff_delta *delta, const char *template, const char *oldpath, @@ -334,14 +335,14 @@ static int diff_delta_format_with_paths( if (git_oid_is_zero(&delta->new_file.id)) newpath = "/dev/null"; - return git_buf_printf(out, template, oldpath, newpath); + return git_str_printf(out, template, oldpath, newpath); } static int diff_delta_format_similarity_header( - git_buf *out, + git_str *out, const git_diff_delta *delta) { - git_buf old_path = GIT_BUF_INIT, new_path = GIT_BUF_INIT; + git_str old_path = GIT_STR_INIT, new_path = GIT_STR_INIT; const char *type; int error = 0; @@ -357,13 +358,13 @@ static int diff_delta_format_similarity_header( else type = "copy"; - if ((error = git_buf_puts(&old_path, delta->old_file.path)) < 0 || - (error = git_buf_puts(&new_path, delta->new_file.path)) < 0 || - (error = git_buf_quote(&old_path)) < 0 || - (error = git_buf_quote(&new_path)) < 0) + if ((error = git_str_puts(&old_path, delta->old_file.path)) < 0 || + (error = git_str_puts(&new_path, delta->new_file.path)) < 0 || + (error = git_str_quote(&old_path)) < 0 || + (error = git_str_quote(&new_path)) < 0) goto done; - git_buf_printf(out, + git_str_printf(out, "similarity index %d%%\n" "%s from %s\n" "%s to %s\n", @@ -371,12 +372,12 @@ static int diff_delta_format_similarity_header( type, old_path.ptr, type, new_path.ptr); - if (git_buf_oom(out)) + if (git_str_oom(out)) error = -1; done: - git_buf_dispose(&old_path); - git_buf_dispose(&new_path); + git_str_dispose(&old_path); + git_str_dispose(&new_path); return error; } @@ -398,14 +399,14 @@ static bool delta_is_unchanged(const git_diff_delta *delta) } int git_diff_delta__format_file_header( - git_buf *out, + git_str *out, const git_diff_delta *delta, const char *oldpfx, const char *newpfx, int id_strlen, bool print_index) { - git_buf old_path = GIT_BUF_INIT, new_path = GIT_BUF_INIT; + git_str old_path = GIT_STR_INIT, new_path = GIT_STR_INIT; bool unchanged = delta_is_unchanged(delta); int error = 0; @@ -422,9 +423,9 @@ int git_diff_delta__format_file_header( &new_path, newpfx, delta->new_file.path)) < 0) goto done; - git_buf_clear(out); + git_str_clear(out); - git_buf_printf(out, "diff --git %s %s\n", + git_str_printf(out, "diff --git %s %s\n", old_path.ptr, new_path.ptr); if (unchanged && delta->old_file.mode != delta->new_file.mode) @@ -446,12 +447,12 @@ int git_diff_delta__format_file_header( "--- %s\n+++ %s\n", old_path.ptr, new_path.ptr); } - if (git_buf_oom(out)) + if (git_str_oom(out)) error = -1; done: - git_buf_dispose(&old_path); - git_buf_dispose(&new_path); + git_str_dispose(&old_path); + git_str_dispose(&new_path); return error; } @@ -467,7 +468,7 @@ static int format_binary( "delta" : "literal"; const char *scan, *end; - git_buf_printf(pi->buf, "%s %" PRIuZ "\n", typename, inflatedlen); + git_str_printf(pi->buf, "%s %" PRIuZ "\n", typename, inflatedlen); pi->line.num_lines++; for (scan = data, end = data + datalen; scan < end; ) { @@ -476,22 +477,22 @@ static int format_binary( chunk_len = 52; if (chunk_len <= 26) - git_buf_putc(pi->buf, (char)chunk_len + 'A' - 1); + git_str_putc(pi->buf, (char)chunk_len + 'A' - 1); else - git_buf_putc(pi->buf, (char)chunk_len - 26 + 'a' - 1); + git_str_putc(pi->buf, (char)chunk_len - 26 + 'a' - 1); - git_buf_encode_base85(pi->buf, scan, chunk_len); - git_buf_putc(pi->buf, '\n'); + git_str_encode_base85(pi->buf, scan, chunk_len); + git_str_putc(pi->buf, '\n'); - if (git_buf_oom(pi->buf)) + if (git_str_oom(pi->buf)) return -1; scan += chunk_len; pi->line.num_lines++; } - git_buf_putc(pi->buf, '\n'); + git_str_putc(pi->buf, '\n'); - if (git_buf_oom(pi->buf)) + if (git_str_oom(pi->buf)) return -1; return 0; @@ -501,7 +502,7 @@ static int diff_print_patch_file_binary_noshow( diff_print_info *pi, git_diff_delta *delta, const char *old_pfx, const char *new_pfx) { - git_buf old_path = GIT_BUF_INIT, new_path = GIT_BUF_INIT; + git_str old_path = GIT_STR_INIT, new_path = GIT_STR_INIT; int error; if ((error = diff_delta_format_path(&old_path, old_pfx, delta->old_file.path)) < 0 || @@ -513,8 +514,8 @@ static int diff_print_patch_file_binary_noshow( pi->line.num_lines = 1; done: - git_buf_dispose(&old_path); - git_buf_dispose(&new_path); + git_str_dispose(&old_path); + git_str_dispose(&new_path); return error; } @@ -534,7 +535,7 @@ static int diff_print_patch_file_binary( pi, delta, old_pfx, new_pfx); pre_binary_size = pi->buf->size; - git_buf_printf(pi->buf, "GIT binary patch\n"); + git_str_printf(pi->buf, "GIT binary patch\n"); pi->line.num_lines++; if ((error = format_binary(pi, binary->new_file.type, binary->new_file.data, @@ -543,7 +544,7 @@ static int diff_print_patch_file_binary( binary->old_file.datalen, binary->old_file.inflatedlen)) < 0) { if (error == GIT_EBUFS) { git_error_clear(); - git_buf_truncate(pi->buf, pre_binary_size); + git_str_truncate(pi->buf, pre_binary_size); return diff_print_patch_file_binary_noshow( pi, delta, old_pfx, new_pfx); @@ -589,8 +590,8 @@ static int diff_print_patch_file( return error; pi->line.origin = GIT_DIFF_LINE_FILE_HDR; - pi->line.content = git_buf_cstr(pi->buf); - pi->line.content_len = git_buf_len(pi->buf); + pi->line.content = git_str_cstr(pi->buf); + pi->line.content_len = git_str_len(pi->buf); return pi->print_cb(delta, NULL, &pi->line, pi->payload); } @@ -607,15 +608,15 @@ static int diff_print_patch_binary( pi->new_prefix ? pi->new_prefix : DIFF_NEW_PREFIX_DEFAULT; int error; - git_buf_clear(pi->buf); + git_str_clear(pi->buf); if ((error = diff_print_patch_file_binary( pi, (git_diff_delta *)delta, old_pfx, new_pfx, binary)) < 0) return error; pi->line.origin = GIT_DIFF_LINE_BINARY; - pi->line.content = git_buf_cstr(pi->buf); - pi->line.content_len = git_buf_len(pi->buf); + pi->line.content = git_str_cstr(pi->buf); + pi->line.content_len = git_str_len(pi->buf); return pi->print_cb(delta, NULL, &pi->line, pi->payload); } @@ -659,7 +660,7 @@ int git_diff_print( void *payload) { int error; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; diff_print_info pi; git_diff_file_cb print_file = NULL; git_diff_binary_cb print_binary = NULL; @@ -704,7 +705,7 @@ int git_diff_print( } out: - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -714,7 +715,7 @@ int git_diff_print_callback__to_buf( const git_diff_line *line, void *payload) { - git_buf *output = payload; + git_str *output = payload; GIT_UNUSED(delta); GIT_UNUSED(hunk); if (!output) { @@ -725,9 +726,9 @@ int git_diff_print_callback__to_buf( if (line->origin == GIT_DIFF_LINE_ADDITION || line->origin == GIT_DIFF_LINE_DELETION || line->origin == GIT_DIFF_LINE_CONTEXT) - git_buf_putc(output, line->origin); + git_str_putc(output, line->origin); - return git_buf_put(output, line->content, line->content_len); + return git_str_put(output, line->content, line->content_len); } int git_diff_print_callback__to_file_handle( @@ -761,18 +762,24 @@ int git_diff_print_callback__to_file_handle( return 0; } -/* print a git_diff to a git_buf */ +/* print a git_diff to a git_str */ int git_diff_to_buf(git_buf *out, git_diff *diff, git_diff_format_t format) { + git_str str = GIT_STR_INIT; int error; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(diff); - if ((error = git_buf_sanitize(out)) < 0) - return error; + if ((error = git_buf_tostr(&str, out)) < 0 || + (error = git_diff_print(diff, format, git_diff_print_callback__to_buf, &str)) < 0) + goto done; + + error = git_buf_fromstr(out, &str); - return git_diff_print(diff, format, git_diff_print_callback__to_buf, out); +done: + git_str_dispose(&str); + return error; } /* print a git_patch to an output callback */ @@ -781,7 +788,7 @@ int git_patch_print( git_diff_line_cb print_cb, void *payload) { - git_buf temp = GIT_BUF_INIT; + git_str temp = GIT_STR_INIT; diff_print_info pi; int error; @@ -799,20 +806,20 @@ int git_patch_print( } out: - git_buf_dispose(&temp); + git_str_dispose(&temp); return error; } -/* print a git_patch to a git_buf */ +/* print a git_patch to a git_str */ int git_patch_to_buf(git_buf *out, git_patch *patch) { - int error; + GIT_BUF_WRAP_PRIVATE(out, git_patch__to_buf, patch); +} +int git_patch__to_buf(git_str *out, git_patch *patch) +{ GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(patch); - if ((error = git_buf_sanitize(out)) < 0) - return error; - return git_patch_print(patch, git_diff_print_callback__to_buf, out); } diff --git a/src/diff_stats.c b/src/diff_stats.c index 41a25bf8aca..228f6f89291 100644 --- a/src/diff_stats.c +++ b/src/diff_stats.c @@ -5,8 +5,10 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "common.h" +#include "diff_stats.h" +#include "buf.h" +#include "common.h" #include "vector.h" #include "diff.h" #include "patch_generate.h" @@ -47,7 +49,7 @@ static int digits_for_value(size_t val) } static int diff_file_stats_full_to_buf( - git_buf *out, + git_str *out, const git_diff_delta *delta, const diff_file_stats *filestat, const git_diff_stats *stats, @@ -70,12 +72,12 @@ static int diff_file_stats_full_to_buf( if ((common_dirlen = git_path_common_dirlen(old_path, new_path)) && common_dirlen <= INT_MAX) { - error = git_buf_printf(out, " %.*s{%s"DIFF_RENAME_FILE_SEPARATOR"%s}", + error = git_str_printf(out, " %.*s{%s"DIFF_RENAME_FILE_SEPARATOR"%s}", (int) common_dirlen, old_path, old_path + common_dirlen, new_path + common_dirlen); } else { - error = git_buf_printf(out, " %s" DIFF_RENAME_FILE_SEPARATOR "%s", + error = git_str_printf(out, " %s" DIFF_RENAME_FILE_SEPARATOR "%s", old_path, new_path); } @@ -83,7 +85,7 @@ static int diff_file_stats_full_to_buf( goto on_error; } else { adddel_path = new_path ? new_path : old_path; - if (git_buf_printf(out, " %s", adddel_path) < 0) + if (git_str_printf(out, " %s", adddel_path) < 0) goto on_error; padding = stats->max_name - strlen(adddel_path); @@ -92,28 +94,28 @@ static int diff_file_stats_full_to_buf( padding += strlen(DIFF_RENAME_FILE_SEPARATOR); } - if (git_buf_putcn(out, ' ', padding) < 0 || - git_buf_puts(out, " | ") < 0) + if (git_str_putcn(out, ' ', padding) < 0 || + git_str_puts(out, " | ") < 0) goto on_error; if (delta->flags & GIT_DIFF_FLAG_BINARY) { - if (git_buf_printf(out, + if (git_str_printf(out, "Bin %" PRId64 " -> %" PRId64 " bytes", old_size, new_size) < 0) goto on_error; } else { - if (git_buf_printf(out, + if (git_str_printf(out, "%*" PRIuZ, stats->max_digits, filestat->insertions + filestat->deletions) < 0) goto on_error; if (filestat->insertions || filestat->deletions) { - if (git_buf_putc(out, ' ') < 0) + if (git_str_putc(out, ' ') < 0) goto on_error; if (!width) { - if (git_buf_putcn(out, '+', filestat->insertions) < 0 || - git_buf_putcn(out, '-', filestat->deletions) < 0) + if (git_str_putcn(out, '+', filestat->insertions) < 0 || + git_str_putcn(out, '-', filestat->deletions) < 0) goto on_error; } else { size_t total = filestat->insertions + filestat->deletions; @@ -122,21 +124,21 @@ static int diff_file_stats_full_to_buf( size_t plus = full * filestat->insertions / total; size_t minus = full - plus; - if (git_buf_putcn(out, '+', max(plus, 1)) < 0 || - git_buf_putcn(out, '-', max(minus, 1)) < 0) + if (git_str_putcn(out, '+', max(plus, 1)) < 0 || + git_str_putcn(out, '-', max(minus, 1)) < 0) goto on_error; } } } - git_buf_putc(out, '\n'); + git_str_putc(out, '\n'); on_error: - return (git_buf_oom(out) ? -1 : 0); + return (git_str_oom(out) ? -1 : 0); } static int diff_file_stats_number_to_buf( - git_buf *out, + git_str *out, const git_diff_delta *delta, const diff_file_stats *filestats) { @@ -144,29 +146,29 @@ static int diff_file_stats_number_to_buf( const char *path = delta->new_file.path; if (delta->flags & GIT_DIFF_FLAG_BINARY) - error = git_buf_printf(out, "%-8c" "%-8c" "%s\n", '-', '-', path); + error = git_str_printf(out, "%-8c" "%-8c" "%s\n", '-', '-', path); else - error = git_buf_printf(out, "%-8" PRIuZ "%-8" PRIuZ "%s\n", + error = git_str_printf(out, "%-8" PRIuZ "%-8" PRIuZ "%s\n", filestats->insertions, filestats->deletions, path); return error; } static int diff_file_stats_summary_to_buf( - git_buf *out, + git_str *out, const git_diff_delta *delta) { if (delta->old_file.mode != delta->new_file.mode) { if (delta->old_file.mode == 0) { - git_buf_printf(out, " create mode %06o %s\n", + git_str_printf(out, " create mode %06o %s\n", delta->new_file.mode, delta->new_file.path); } else if (delta->new_file.mode == 0) { - git_buf_printf(out, " delete mode %06o %s\n", + git_str_printf(out, " delete mode %06o %s\n", delta->old_file.mode, delta->old_file.path); } else { - git_buf_printf(out, " mode change %06o => %06o %s\n", + git_str_printf(out, " mode change %06o => %06o %s\n", delta->old_file.mode, delta->new_file.mode, delta->new_file.path); } } @@ -278,6 +280,15 @@ int git_diff_stats_to_buf( const git_diff_stats *stats, git_diff_stats_format_t format, size_t width) +{ + GIT_BUF_WRAP_PRIVATE(out, git_diff__stats_to_buf, stats, format, width); +} + +int git_diff__stats_to_buf( + git_str *out, + const git_diff_stats *stats, + git_diff_stats_format_t format, + size_t width) { int error = 0; size_t i; @@ -320,23 +331,23 @@ int git_diff_stats_to_buf( } if (format & GIT_DIFF_STATS_FULL || format & GIT_DIFF_STATS_SHORT) { - git_buf_printf( + git_str_printf( out, " %" PRIuZ " file%s changed", stats->files_changed, stats->files_changed != 1 ? "s" : ""); if (stats->insertions || stats->deletions == 0) - git_buf_printf( + git_str_printf( out, ", %" PRIuZ " insertion%s(+)", stats->insertions, stats->insertions != 1 ? "s" : ""); if (stats->deletions || stats->insertions == 0) - git_buf_printf( + git_str_printf( out, ", %" PRIuZ " deletion%s(-)", stats->deletions, stats->deletions != 1 ? "s" : ""); - git_buf_putc(out, '\n'); + git_str_putc(out, '\n'); - if (git_buf_oom(out)) + if (git_str_oom(out)) return -1; } diff --git a/src/message.h b/src/diff_stats.h similarity index 55% rename from src/message.h rename to src/diff_stats.h index 251727b2277..c71862b4e6d 100644 --- a/src/message.h +++ b/src/diff_stats.h @@ -4,14 +4,15 @@ * 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_message_h__ -#define INCLUDE_message_h__ +#ifndef INCLUDE_diff_stats_h__ +#define INCLUDE_diff_stats_h__ #include "common.h" -#include "git2/message.h" -#include "buffer.h" - -int git_message__prettify(git_buf *message_out, const char *message, int strip_comments); +int git_diff__stats_to_buf( + git_str *out, + const git_diff_stats *stats, + git_diff_stats_format_t format, + size_t width); #endif diff --git a/src/diff_tform.c b/src/diff_tform.c index 597e64e45eb..be55de6c3a0 100644 --- a/src/diff_tform.c +++ b/src/diff_tform.c @@ -444,7 +444,7 @@ typedef struct { git_iterator_t src; git_repository *repo; git_diff_file *file; - git_buf data; + git_str data; git_odb_object *odb_obj; git_blob *blob; } similarity_info; @@ -458,7 +458,7 @@ static int similarity_init( info->file = similarity_get_file(diff, file_idx); info->odb_obj = NULL; info->blob = NULL; - git_buf_init(&info->data, 0); + git_str_init(&info->data, 0); if (info->file->size > 0 || info->src == GIT_ITERATOR_WORKDIR) return 0; @@ -529,7 +529,7 @@ static void similarity_unload(similarity_info *info) if (info->blob) git_blob_free(info->blob); else - git_buf_dispose(&info->data); + git_str_dispose(&info->data); } #define FLAG_SET(opts,flag_name) (((opts)->flags & flag_name) != 0) diff --git a/src/email.c b/src/email.c index df63b6ec3b6..3459c054034 100644 --- a/src/email.c +++ b/src/email.c @@ -7,9 +7,11 @@ #include "email.h" -#include "buffer.h" #include "common.h" +#include "buf.h" #include "diff_generate.h" +#include "diff_stats.h" +#include "patch.h" #include "git2/email.h" #include "git2/patch.h" @@ -32,7 +34,7 @@ GIT_INLINE(int) include_prefix( } static int append_prefix( - git_buf *out, + git_str *out, size_t patch_idx, size_t patch_count, git_email_create_options *opts) @@ -40,16 +42,16 @@ static int append_prefix( const char *subject_prefix = opts->subject_prefix ? opts->subject_prefix : "PATCH"; - git_buf_putc(out, '['); + git_str_putc(out, '['); if (*subject_prefix) - git_buf_puts(out, subject_prefix); + git_str_puts(out, subject_prefix); if (opts->reroll_number) { if (*subject_prefix) - git_buf_putc(out, ' '); + git_str_putc(out, ' '); - git_buf_printf(out, "v%" PRIuZ, opts->reroll_number); + git_str_printf(out, "v%" PRIuZ, opts->reroll_number); } if ((opts->flags & GIT_EMAIL_CREATE_ALWAYS_NUMBER) != 0 || @@ -58,20 +60,20 @@ static int append_prefix( opts->start_number : 1; if (*subject_prefix || opts->reroll_number) - git_buf_putc(out, ' '); + git_str_putc(out, ' '); - git_buf_printf(out, "%" PRIuZ "/%" PRIuZ, + git_str_printf(out, "%" PRIuZ "/%" PRIuZ, patch_idx + (start_number - 1), patch_count + (start_number - 1)); } - git_buf_puts(out, "]"); + git_str_puts(out, "]"); - return git_buf_oom(out) ? -1 : 0; + return git_str_oom(out) ? -1 : 0; } static int append_subject( - git_buf *out, + git_str *out, size_t patch_idx, size_t patch_count, const char *summary, @@ -88,25 +90,25 @@ static int append_subject( summary_len = (nl - summary); } - if ((error = git_buf_puts(out, "Subject: ")) < 0) + if ((error = git_str_puts(out, "Subject: ")) < 0) return error; if (prefix && (error = append_prefix(out, patch_idx, patch_count, opts)) < 0) return error; - if (prefix && summary_len && (error = git_buf_putc(out, ' ')) < 0) + if (prefix && summary_len && (error = git_str_putc(out, ' ')) < 0) return error; if (summary_len && - (error = git_buf_put(out, summary, summary_len)) < 0) + (error = git_str_put(out, summary, summary_len)) < 0) return error; - return git_buf_putc(out, '\n'); + return git_str_putc(out, '\n'); } static int append_header( - git_buf *out, + git_str *out, size_t patch_idx, size_t patch_count, const git_oid *commit_id, @@ -119,20 +121,20 @@ static int append_header( int error; if ((error = git_oid_fmt(id, commit_id)) < 0 || - (error = git_buf_printf(out, "From %.*s %s\n", GIT_OID_HEXSZ, id, EMAIL_TIMESTAMP)) < 0 || - (error = git_buf_printf(out, "From: %s <%s>\n", author->name, author->email)) < 0 || + (error = git_str_printf(out, "From %.*s %s\n", GIT_OID_HEXSZ, id, EMAIL_TIMESTAMP)) < 0 || + (error = git_str_printf(out, "From: %s <%s>\n", author->name, author->email)) < 0 || (error = git__date_rfc2822_fmt(date, sizeof(date), &author->when)) < 0 || - (error = git_buf_printf(out, "Date: %s\n", date)) < 0 || + (error = git_str_printf(out, "Date: %s\n", date)) < 0 || (error = append_subject(out, patch_idx, patch_count, summary, opts)) < 0) return error; - if ((error = git_buf_putc(out, '\n')) < 0) + if ((error = git_str_putc(out, '\n')) < 0) return error; return 0; } -static int append_body(git_buf *out, const char *body) +static int append_body(git_str *out, const char *body) { size_t body_len; int error; @@ -142,16 +144,16 @@ static int append_body(git_buf *out, const char *body) body_len = strlen(body); - if ((error = git_buf_puts(out, body)) < 0) + if ((error = git_str_puts(out, body)) < 0) return error; if (body_len && body[body_len - 1] != '\n') - error = git_buf_putc(out, '\n'); + error = git_str_putc(out, '\n'); return error; } -static int append_diffstat(git_buf *out, git_diff *diff) +static int append_diffstat(git_str *out, git_diff *diff) { git_diff_stats *stats = NULL; unsigned int format_flags; @@ -160,14 +162,14 @@ static int append_diffstat(git_buf *out, git_diff *diff) format_flags = GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_INCLUDE_SUMMARY; if ((error = git_diff_get_stats(&stats, diff)) == 0 && - (error = git_diff_stats_to_buf(out, stats, format_flags, 0)) == 0) - error = git_buf_putc(out, '\n'); + (error = git_diff__stats_to_buf(out, stats, format_flags, 0)) == 0) + error = git_str_putc(out, '\n'); git_diff_stats_free(stats); return error; } -static int append_patches(git_buf *out, git_diff *diff) +static int append_patches(git_str *out, git_diff *diff) { size_t i, deltas; int error = 0; @@ -178,7 +180,7 @@ static int append_patches(git_buf *out, git_diff *diff) git_patch *patch = NULL; if ((error = git_patch_from_diff(&patch, diff, i)) >= 0) - error = git_patch_to_buf(out, patch); + error = git_patch__to_buf(out, patch); git_patch_free(patch); @@ -190,7 +192,7 @@ static int append_patches(git_buf *out, git_diff *diff) } int git_email__append_from_diff( - git_buf *out, + git_str *out, git_diff *diff, size_t patch_idx, size_t patch_count, @@ -216,14 +218,12 @@ int git_email__append_from_diff( if (given_opts) memcpy(&opts, given_opts, sizeof(git_email_create_options)); - git_buf_sanitize(out); - if ((error = append_header(out, patch_idx, patch_count, commit_id, summary, author, &opts)) == 0 && (error = append_body(out, body)) == 0 && - (error = git_buf_puts(out, "---\n")) == 0 && + (error = git_str_puts(out, "---\n")) == 0 && (error = append_diffstat(out, diff)) == 0 && (error = append_patches(out, diff)) == 0) - error = git_buf_puts(out, "--\nlibgit2 " LIBGIT2_VERSION "\n\n"); + error = git_str_puts(out, "--\nlibgit2 " LIBGIT2_VERSION "\n\n"); return error; } @@ -239,15 +239,19 @@ int git_email_create_from_diff( const git_signature *author, const git_email_create_options *given_opts) { + git_str email = GIT_STR_INIT; int error; - git_buf_sanitize(out); - git_buf_clear(out); + git_buf_tostr(&email, out); - error = git_email__append_from_diff(out, diff, patch_idx, + error = git_email__append_from_diff(&email, diff, patch_idx, patch_count, commit_id, summary, body, author, given_opts); + if (error == 0) + error = git_buf_fromstr(out, &email); + + git_str_dispose(&email); return error; } diff --git a/src/email.h b/src/email.h index 7aeb462abc1..083e56d5c45 100644 --- a/src/email.h +++ b/src/email.h @@ -12,7 +12,7 @@ #include "git2/email.h" extern int git_email__append_from_diff( - git_buf *out, + git_str *out, git_diff *diff, size_t patch_idx, size_t patch_count, diff --git a/src/errors.c b/src/errors.c index ce883b2dad1..3614b9ce5f5 100644 --- a/src/errors.c +++ b/src/errors.c @@ -9,7 +9,7 @@ #include "threadstate.h" #include "posix.h" -#include "buffer.h" +#include "str.h" #include "libgit2.h" /******************************************** @@ -29,7 +29,7 @@ static git_error g_git_uninitialized_error = { static void set_error_from_buffer(int error_class) { git_error *error = &GIT_THREADSTATE->error_t; - git_buf *buf = &GIT_THREADSTATE->error_buf; + git_str *buf = &GIT_THREADSTATE->error_buf; error->message = buf->ptr; error->klass = error_class; @@ -39,11 +39,11 @@ static void set_error_from_buffer(int error_class) static void set_error(int error_class, char *string) { - git_buf *buf = &GIT_THREADSTATE->error_buf; + git_str *buf = &GIT_THREADSTATE->error_buf; - git_buf_clear(buf); + git_str_clear(buf); if (string) { - git_buf_puts(buf, string); + git_str_puts(buf, string); git__free(string); } @@ -70,20 +70,20 @@ void git_error_vset(int error_class, const char *fmt, va_list ap) DWORD win32_error_code = (error_class == GIT_ERROR_OS) ? GetLastError() : 0; #endif int error_code = (error_class == GIT_ERROR_OS) ? errno : 0; - git_buf *buf = &GIT_THREADSTATE->error_buf; + git_str *buf = &GIT_THREADSTATE->error_buf; - git_buf_clear(buf); + git_str_clear(buf); if (fmt) { - git_buf_vprintf(buf, fmt, ap); + git_str_vprintf(buf, fmt, ap); if (error_class == GIT_ERROR_OS) - git_buf_PUTS(buf, ": "); + git_str_PUTS(buf, ": "); } if (error_class == GIT_ERROR_OS) { #ifdef GIT_WIN32 char * win32_error = git_win32_get_error_message(win32_error_code); if (win32_error) { - git_buf_puts(buf, win32_error); + git_str_puts(buf, win32_error); git__free(win32_error); SetLastError(0); @@ -91,26 +91,26 @@ void git_error_vset(int error_class, const char *fmt, va_list ap) else #endif if (error_code) - git_buf_puts(buf, strerror(error_code)); + git_str_puts(buf, strerror(error_code)); if (error_code) errno = 0; } - if (!git_buf_oom(buf)) + if (!git_str_oom(buf)) set_error_from_buffer(error_class); } int git_error_set_str(int error_class, const char *string) { - git_buf *buf = &GIT_THREADSTATE->error_buf; + git_str *buf = &GIT_THREADSTATE->error_buf; GIT_ASSERT_ARG(string); - git_buf_clear(buf); - git_buf_puts(buf, string); + git_str_clear(buf); + git_str_puts(buf, string); - if (git_buf_oom(buf)) + if (git_str_oom(buf)) return -1; set_error_from_buffer(error_class); @@ -142,7 +142,7 @@ const git_error *git_error_last(void) int git_error_state_capture(git_error_state *state, int error_code) { git_error *error = GIT_THREADSTATE->last_error; - git_buf *error_buf = &GIT_THREADSTATE->error_buf; + git_str *error_buf = &GIT_THREADSTATE->error_buf; memset(state, 0, sizeof(git_error_state)); @@ -158,7 +158,7 @@ int git_error_state_capture(git_error_state *state, int error_code) if (state->oom) state->error_msg.message = g_git_oom_error.message; else - state->error_msg.message = git_buf_detach(error_buf); + state->error_msg.message = git_str_detach(error_buf); } git_error_clear(); diff --git a/src/fetchhead.c b/src/fetchhead.c index 88c567e4847..6511124efce 100644 --- a/src/fetchhead.c +++ b/src/fetchhead.c @@ -10,7 +10,7 @@ #include "git2/types.h" #include "git2/oid.h" -#include "buffer.h" +#include "str.h" #include "futils.h" #include "filebuf.h" #include "refs.h" @@ -44,7 +44,7 @@ static char *sanitized_remote_url(const char *remote_url) int error; if (git_net_url_parse(&url, remote_url) == 0) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git__free(url.username); git__free(url.password); @@ -53,7 +53,7 @@ static char *sanitized_remote_url(const char *remote_url) if ((error = git_net_url_fmt(&buf, &url)) < 0) goto fallback; - sanitized = git_buf_detach(&buf); + sanitized = git_str_detach(&buf); } fallback: @@ -143,22 +143,22 @@ static int fetchhead_ref_write( int git_fetchhead_write(git_repository *repo, git_vector *fetchhead_refs) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; unsigned int i; git_fetchhead_ref *fetchhead_ref; GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(fetchhead_refs); - if (git_buf_joinpath(&path, repo->gitdir, GIT_FETCH_HEAD_FILE) < 0) + if (git_str_joinpath(&path, repo->gitdir, GIT_FETCH_HEAD_FILE) < 0) return -1; if (git_filebuf_open(&file, path.ptr, GIT_FILEBUF_APPEND, GIT_REFS_FILE_MODE) < 0) { - git_buf_dispose(&path); + git_str_dispose(&path); return -1; } - git_buf_dispose(&path); + git_str_dispose(&path); git_vector_sort(fetchhead_refs); @@ -171,7 +171,7 @@ int git_fetchhead_write(git_repository *repo, git_vector *fetchhead_refs) static int fetchhead_ref_parse( git_oid *oid, unsigned int *is_merge, - git_buf *ref_name, + git_str *ref_name, const char **remote_url, char *line, size_t line_num) @@ -259,12 +259,12 @@ static int fetchhead_ref_parse( *remote_url = desc; } - git_buf_clear(ref_name); + git_str_clear(ref_name); if (type) - git_buf_join(ref_name, '/', type, name); + git_str_join(ref_name, '/', type, name); else if(name) - git_buf_puts(ref_name, name); + git_str_puts(ref_name, name); return error; } @@ -273,7 +273,7 @@ int git_repository_fetchhead_foreach(git_repository *repo, git_repository_fetchhead_foreach_cb cb, void *payload) { - git_buf path = GIT_BUF_INIT, file = GIT_BUF_INIT, name = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, file = GIT_STR_INIT, name = GIT_STR_INIT; const char *ref_name; git_oid oid; const char *remote_url; @@ -285,10 +285,10 @@ int git_repository_fetchhead_foreach(git_repository *repo, GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(cb); - if (git_buf_joinpath(&path, repo->gitdir, GIT_FETCH_HEAD_FILE) < 0) + if (git_str_joinpath(&path, repo->gitdir, GIT_FETCH_HEAD_FILE) < 0) return -1; - if ((error = git_futils_readbuffer(&file, git_buf_cstr(&path))) < 0) + if ((error = git_futils_readbuffer(&file, git_str_cstr(&path))) < 0) goto done; buffer = file.ptr; @@ -300,8 +300,8 @@ int git_repository_fetchhead_foreach(git_repository *repo, &oid, &is_merge, &name, &remote_url, line, line_num)) < 0) goto done; - if (git_buf_len(&name) > 0) - ref_name = git_buf_cstr(&name); + if (git_str_len(&name) > 0) + ref_name = git_str_cstr(&name); else ref_name = NULL; @@ -319,9 +319,9 @@ int git_repository_fetchhead_foreach(git_repository *repo, } done: - git_buf_dispose(&file); - git_buf_dispose(&path); - git_buf_dispose(&name); + git_str_dispose(&file); + git_str_dispose(&path); + git_str_dispose(&name); return error; } diff --git a/src/filebuf.c b/src/filebuf.c index 4296b2226d3..10f8c581320 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -195,21 +195,21 @@ static int write_deflate(git_filebuf *file, void *source, size_t len) #define MAX_SYMLINK_DEPTH 5 -static int resolve_symlink(git_buf *out, const char *path) +static int resolve_symlink(git_str *out, const char *path) { int i, error, root; ssize_t ret; struct stat st; - git_buf curpath = GIT_BUF_INIT, target = GIT_BUF_INIT; + git_str curpath = GIT_STR_INIT, target = GIT_STR_INIT; - if ((error = git_buf_grow(&target, GIT_PATH_MAX + 1)) < 0 || - (error = git_buf_puts(&curpath, path)) < 0) + if ((error = git_str_grow(&target, GIT_PATH_MAX + 1)) < 0 || + (error = git_str_puts(&curpath, path)) < 0) return error; for (i = 0; i < MAX_SYMLINK_DEPTH; i++) { error = p_lstat(curpath.ptr, &st); if (error < 0 && errno == ENOENT) { - error = git_buf_puts(out, curpath.ptr); + error = git_str_puts(out, curpath.ptr); goto cleanup; } @@ -220,7 +220,7 @@ static int resolve_symlink(git_buf *out, const char *path) } if (!S_ISLNK(st.st_mode)) { - error = git_buf_puts(out, curpath.ptr); + error = git_str_puts(out, curpath.ptr); goto cleanup; } @@ -243,16 +243,16 @@ static int resolve_symlink(git_buf *out, const char *path) root = git_path_root(target.ptr); if (root >= 0) { - if ((error = git_buf_sets(&curpath, target.ptr)) < 0) + if ((error = git_str_sets(&curpath, target.ptr)) < 0) goto cleanup; } else { - git_buf dir = GIT_BUF_INIT; + git_str dir = GIT_STR_INIT; if ((error = git_path_dirname_r(&dir, curpath.ptr)) < 0) goto cleanup; - git_buf_swap(&curpath, &dir); - git_buf_dispose(&dir); + git_str_swap(&curpath, &dir); + git_str_dispose(&dir); if ((error = git_path_apply_relative(&curpath, target.ptr)) < 0) goto cleanup; @@ -263,8 +263,8 @@ static int resolve_symlink(git_buf *out, const char *path) error = -1; cleanup: - git_buf_dispose(&curpath); - git_buf_dispose(&target); + git_str_dispose(&curpath); + git_str_dispose(&target); return error; } @@ -332,13 +332,13 @@ int git_filebuf_open_withsize(git_filebuf *file, const char *path, int flags, mo /* If we are writing to a temp file */ if (flags & GIT_FILEBUF_TEMPORARY) { - git_buf tmp_path = GIT_BUF_INIT; + git_str tmp_path = GIT_STR_INIT; /* Open the file as temporary for locking */ file->fd = git_futils_mktmp(&tmp_path, path, mode); if (file->fd < 0) { - git_buf_dispose(&tmp_path); + git_str_dispose(&tmp_path); goto cleanup; } file->fd_is_open = true; @@ -346,17 +346,17 @@ int git_filebuf_open_withsize(git_filebuf *file, const char *path, int flags, mo /* No original path */ file->path_original = NULL; - file->path_lock = git_buf_detach(&tmp_path); + file->path_lock = git_str_detach(&tmp_path); GIT_ERROR_CHECK_ALLOC(file->path_lock); } else { - git_buf resolved_path = GIT_BUF_INIT; + git_str resolved_path = GIT_STR_INIT; if ((error = resolve_symlink(&resolved_path, path)) < 0) goto cleanup; /* Save the original path of the file */ path_len = resolved_path.size; - file->path_original = git_buf_detach(&resolved_path); + file->path_original = git_str_detach(&resolved_path); /* create the locking path by appending ".lock" to the original */ GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, path_len, GIT_FILELOCK_EXTLENGTH); diff --git a/src/filter.c b/src/filter.c index 73497cb3024..417d9cb8bbf 100644 --- a/src/filter.c +++ b/src/filter.c @@ -7,6 +7,7 @@ #include "filter.h" +#include "buf.h" #include "common.h" #include "futils.h" #include "hash.h" @@ -36,7 +37,7 @@ typedef struct { struct git_filter_list { git_array_t(git_filter_entry) filters; git_filter_source source; - git_buf *temp_buf; + git_str *temp_buf; char path[GIT_FLEX_ARRAY]; }; @@ -68,7 +69,7 @@ static void git_filter_global_shutdown(void); static int filter_def_scan_attrs( - git_buf *attrs, size_t *nattr, size_t *nmatch, const char *attr_str) + git_str *attrs, size_t *nattr, size_t *nmatch, const char *attr_str) { const char *start, *scan = attr_str; int has_eq; @@ -92,9 +93,9 @@ static int filter_def_scan_attrs( (*nmatch)++; if (has_eq) - git_buf_putc(attrs, '='); - git_buf_put(attrs, start, scan - start); - git_buf_putc(attrs, '\0'); + git_str_putc(attrs, '='); + git_str_put(attrs, start, scan - start); + git_str_putc(attrs, '\0'); } } @@ -152,7 +153,7 @@ static int filter_registry_insert( { git_filter_def *fdef; size_t nattr = 0, nmatch = 0, alloc_len; - git_buf attrs = GIT_BUF_INIT; + git_str attrs = GIT_STR_INIT; if (filter_def_scan_attrs(&attrs, &nattr, &nmatch, filter->attributes) < 0) return -1; @@ -171,7 +172,7 @@ static int filter_registry_insert( fdef->priority = priority; fdef->nattrs = nattr; fdef->nmatches = nmatch; - fdef->attrdata = git_buf_detach(&attrs); + fdef->attrdata = git_str_detach(&attrs); filter_def_set_attrs(fdef); @@ -710,7 +711,7 @@ size_t git_filter_list_length(const git_filter_list *fl) struct buf_stream { git_writestream parent; - git_buf *target; + git_str *target; bool complete; }; @@ -721,7 +722,7 @@ static int buf_stream_write( GIT_ASSERT_ARG(buf_stream); GIT_ASSERT(buf_stream->complete == 0); - return git_buf_put(buf_stream->target, buffer, len); + return git_str_put(buf_stream->target, buffer, len); } static int buf_stream_close(git_writestream *s) @@ -740,7 +741,7 @@ static void buf_stream_free(git_writestream *s) GIT_UNUSED(s); } -static void buf_stream_init(struct buf_stream *writer, git_buf *target) +static void buf_stream_init(struct buf_stream *writer, git_str *target) { memset(writer, 0, sizeof(struct buf_stream)); @@ -749,7 +750,7 @@ static void buf_stream_init(struct buf_stream *writer, git_buf *target) writer->parent.free = buf_stream_free; writer->target = target; - git_buf_clear(target); + git_str_clear(target); } int git_filter_list_apply_to_buffer( @@ -757,13 +758,19 @@ int git_filter_list_apply_to_buffer( git_filter_list *filters, const char *in, size_t in_len) +{ + GIT_BUF_WRAP_PRIVATE(out, git_filter_list__apply_to_buffer, filters, in, in_len); +} + +int git_filter_list__apply_to_buffer( + git_str *out, + git_filter_list *filters, + const char *in, + size_t in_len) { struct buf_stream writer; int error; - if ((error = git_buf_sanitize(out)) < 0) - return error; - buf_stream_init(&writer, out); if ((error = git_filter_list_stream_buffer(filters, @@ -775,23 +782,23 @@ int git_filter_list_apply_to_buffer( } int git_filter_list__convert_buf( - git_buf *out, + git_str *out, git_filter_list *filters, - git_buf *in) + git_str *in) { int error; if (!filters || git_filter_list_length(filters) == 0) { - git_buf_swap(out, in); - git_buf_dispose(in); + git_str_swap(out, in); + git_str_dispose(in); return 0; } - error = git_filter_list_apply_to_buffer(out, filters, + error = git_filter_list__apply_to_buffer(out, filters, in->ptr, in->size); if (!error) - git_buf_dispose(in); + git_str_dispose(in); return error; } @@ -801,6 +808,15 @@ int git_filter_list_apply_to_file( git_filter_list *filters, git_repository *repo, const char *path) +{ + GIT_BUF_WRAP_PRIVATE(out, git_filter_list__apply_to_file, filters, repo, path); +} + +int git_filter_list__apply_to_file( + git_str *out, + git_filter_list *filters, + git_repository *repo, + const char *path) { struct buf_stream writer; int error; @@ -815,7 +831,7 @@ int git_filter_list_apply_to_file( return error; } -static int buf_from_blob(git_buf *out, git_blob *blob) +static int buf_from_blob(git_str *out, git_blob *blob) { git_object_size_t rawsize = git_blob_rawsize(blob); @@ -824,7 +840,7 @@ static int buf_from_blob(git_buf *out, git_blob *blob) return -1; } - git_buf_attach_notowned(out, git_blob_rawcontent(blob), (size_t)rawsize); + git_str_attach_notowned(out, git_blob_rawcontent(blob), (size_t)rawsize); return 0; } @@ -832,6 +848,14 @@ int git_filter_list_apply_to_blob( git_buf *out, git_filter_list *filters, git_blob *blob) +{ + GIT_BUF_WRAP_PRIVATE(out, git_filter_list__apply_to_blob, filters, blob); +} + +int git_filter_list__apply_to_blob( + git_str *out, + git_filter_list *filters, + git_blob *blob) { struct buf_stream writer; int error; @@ -849,12 +873,13 @@ int git_filter_list_apply_to_blob( struct buffered_stream { git_writestream parent; git_filter *filter; - int (*write_fn)(git_filter *, void **, git_buf *, const git_buf *, const git_filter_source *); + int (*write_fn)(git_filter *, void **, git_str *, const git_str *, const git_filter_source *); + int (*legacy_write_fn)(git_filter *, void **, git_buf *, const git_buf *, const git_filter_source *); const git_filter_source *source; void **payload; - git_buf input; - git_buf temp_buf; - git_buf *output; + git_str input; + git_str temp_buf; + git_str *output; git_writestream *target; }; @@ -864,13 +889,13 @@ static int buffered_stream_write( struct buffered_stream *buffered_stream = (struct buffered_stream *)s; GIT_ASSERT_ARG(buffered_stream); - return git_buf_put(&buffered_stream->input, buffer, len); + return git_str_put(&buffered_stream->input, buffer, len); } static int buffered_stream_close(git_writestream *s) { struct buffered_stream *buffered_stream = (struct buffered_stream *)s; - git_buf *writebuf; + git_str *writebuf; git_error_state error_state = {0}; int error; @@ -886,9 +911,6 @@ static int buffered_stream_close(git_writestream *s) if (error == GIT_PASSTHROUGH) { writebuf = &buffered_stream->input; } else if (error == 0) { - if ((error = git_buf_sanitize(buffered_stream->output)) < 0) - return error; - writebuf = buffered_stream->output; } else { /* close stream before erroring out taking care @@ -911,8 +933,8 @@ static void buffered_stream_free(git_writestream *s) struct buffered_stream *buffered_stream = (struct buffered_stream *)s; if (buffered_stream) { - git_buf_dispose(&buffered_stream->input); - git_buf_dispose(&buffered_stream->temp_buf); + git_str_dispose(&buffered_stream->input); + git_str_dispose(&buffered_stream->temp_buf); git__free(buffered_stream); } } @@ -920,8 +942,8 @@ static void buffered_stream_free(git_writestream *s) int git_filter_buffered_stream_new( git_writestream **out, git_filter *filter, - int (*write_fn)(git_filter *, void **, git_buf *, const git_buf *, const git_filter_source *), - git_buf *temp_buf, + int (*write_fn)(git_filter *, void **, git_str *, const git_str *, const git_filter_source *), + git_str *temp_buf, void **payload, const git_filter_source *source, git_writestream *target) @@ -940,12 +962,43 @@ int git_filter_buffered_stream_new( buffered_stream->target = target; if (temp_buf) - git_buf_clear(temp_buf); + git_str_clear(temp_buf); *out = (git_writestream *)buffered_stream; return 0; } +#ifndef GIT_DEPRECATE_HARD +static int buffered_legacy_stream_new( + git_writestream **out, + git_filter *filter, + int (*legacy_write_fn)(git_filter *, void **, git_buf *, const git_buf *, const git_filter_source *), + git_str *temp_buf, + void **payload, + const git_filter_source *source, + git_writestream *target) +{ + struct buffered_stream *buffered_stream = git__calloc(1, sizeof(struct buffered_stream)); + GIT_ERROR_CHECK_ALLOC(buffered_stream); + + buffered_stream->parent.write = buffered_stream_write; + buffered_stream->parent.close = buffered_stream_close; + buffered_stream->parent.free = buffered_stream_free; + buffered_stream->filter = filter; + buffered_stream->legacy_write_fn = legacy_write_fn; + buffered_stream->output = temp_buf ? temp_buf : &buffered_stream->temp_buf; + buffered_stream->payload = payload; + buffered_stream->source = source; + buffered_stream->target = target; + + if (temp_buf) + git_str_clear(temp_buf); + + *out = (git_writestream *)buffered_stream; + return 0; +} +#endif + static int setup_stream( git_writestream **out, git_filter_entry *fe, @@ -961,7 +1014,7 @@ static int setup_stream( */ if (!fe->filter->stream) { /* Create a stream that proxies the one-shot apply */ - return git_filter_buffered_stream_new(out, + return buffered_legacy_stream_new(out, fe->filter, fe->filter->apply, filters->temp_buf, &fe->payload, &filters->source, last_stream); } @@ -1032,7 +1085,7 @@ int git_filter_list_stream_file( git_writestream *target) { char buf[FILTERIO_BUFSIZE]; - git_buf abspath = GIT_BUF_INIT; + git_str abspath = GIT_STR_INIT; const char *base = repo ? git_repository_workdir(repo) : NULL; git_vector filter_streams = GIT_VECTOR_INIT; git_writestream *stream_start; @@ -1067,7 +1120,7 @@ int git_filter_list_stream_file( if (fd >= 0) p_close(fd); filter_streams_free(&filter_streams); - git_buf_dispose(&abspath); + git_str_dispose(&abspath); return error; } @@ -1101,7 +1154,7 @@ int git_filter_list_stream_blob( git_blob *blob, git_writestream *target) { - git_buf in = GIT_BUF_INIT; + git_str in = GIT_STR_INIT; if (buf_from_blob(&in, blob) < 0) return -1; @@ -1125,22 +1178,12 @@ int git_filter_list_stream_data( git_buf *data, git_writestream *target) { - int error; - - if ((error = git_buf_sanitize(data)) < 0) - return error; - return git_filter_list_stream_buffer(filters, data->ptr, data->size, target); } int git_filter_list_apply_to_data( git_buf *tgt, git_filter_list *filters, git_buf *src) { - int error; - - if ((error = git_buf_sanitize(src)) < 0) - return error; - return git_filter_list_apply_to_buffer(tgt, filters, src->ptr, src->size); } diff --git a/src/filter.h b/src/filter.h index 241791276cd..58cb4b42407 100644 --- a/src/filter.h +++ b/src/filter.h @@ -19,7 +19,7 @@ typedef struct { git_filter_options options; git_attr_session *attr_session; - git_buf *temp_buf; + git_str *temp_buf; } git_filter_session; #define GIT_FILTER_SESSION_INIT {GIT_FILTER_OPTIONS_INIT, 0} @@ -36,14 +36,35 @@ extern int git_filter_list__load( git_filter_mode_t mode, git_filter_session *filter_session); +int git_filter_list__apply_to_buffer( + git_str *out, + git_filter_list *filters, + const char *in, + size_t in_len); +int git_filter_list__apply_to_file( + git_str *out, + git_filter_list *filters, + git_repository *repo, + const char *path); +int git_filter_list__apply_to_blob( + git_str *out, + git_filter_list *filters, + git_blob *blob); + /* * The given input buffer will be converted to the given output buffer. * The input buffer will be freed (_if_ it was allocated). */ extern int git_filter_list__convert_buf( - git_buf *out, + git_str *out, + git_filter_list *filters, + git_str *in); + +extern int git_filter_list__apply_to_file( + git_str *out, git_filter_list *filters, - git_buf *in); + git_repository *repo, + const char *path); /* * Available filters @@ -55,8 +76,8 @@ extern git_filter *git_ident_filter_new(void); extern int git_filter_buffered_stream_new( git_writestream **out, git_filter *filter, - int (*write_fn)(git_filter *, void **, git_buf *, const git_buf *, const git_filter_source *), - git_buf *temp_buf, + int (*write_fn)(git_filter *, void **, git_str *, const git_str *, const git_filter_source *), + git_str *temp_buf, void **payload, const git_filter_source *source, git_writestream *target); diff --git a/src/futils.c b/src/futils.c index d28b231ce70..9a15ceeb9a9 100644 --- a/src/futils.c +++ b/src/futils.c @@ -22,17 +22,17 @@ int git_futils_mkpath2file(const char *file_path, const mode_t mode) GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR); } -int git_futils_mktmp(git_buf *path_out, const char *filename, mode_t mode) +int git_futils_mktmp(git_str *path_out, const char *filename, mode_t mode) { int fd; mode_t mask; p_umask(mask = p_umask(0)); - git_buf_sets(path_out, filename); - git_buf_puts(path_out, "_git2_XXXXXX"); + git_str_sets(path_out, filename); + git_str_puts(path_out, "_git2_XXXXXX"); - if (git_buf_oom(path_out)) + if (git_str_oom(path_out)) return -1; if ((fd = p_mkstemp(path_out->ptr)) < 0) { @@ -145,12 +145,12 @@ mode_t git_futils_canonical_mode(mode_t raw_mode) return 0; } -int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len) +int git_futils_readbuffer_fd(git_str *buf, git_file fd, size_t len) { ssize_t read_size = 0; size_t alloc_len; - git_buf_clear(buf); + git_str_clear(buf); if (!git__is_ssizet(len)) { git_error_set(GIT_ERROR_INVALID, "read too large"); @@ -158,7 +158,7 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len) } GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, len, 1); - if (git_buf_grow(buf, alloc_len) < 0) + if (git_str_grow(buf, alloc_len) < 0) return -1; /* p_read loops internally to read len bytes */ @@ -166,7 +166,7 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len) if (read_size != (ssize_t)len) { git_error_set(GIT_ERROR_OS, "failed to read descriptor"); - git_buf_dispose(buf); + git_str_dispose(buf); return -1; } @@ -177,7 +177,7 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len) } int git_futils_readbuffer_updated( - git_buf *out, + git_str *out, const char *path, unsigned char checksum[GIT_HASH_SHA1_SIZE], int *updated) @@ -185,7 +185,7 @@ int git_futils_readbuffer_updated( int error; git_file fd; struct stat st; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; unsigned char checksum_new[GIT_HASH_SHA1_SIZE]; GIT_ASSERT_ARG(out); @@ -220,7 +220,7 @@ int git_futils_readbuffer_updated( if (checksum) { if ((error = git_hash_buf(checksum_new, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) { - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -228,7 +228,7 @@ int git_futils_readbuffer_updated( * If we were given a checksum, we only want to use it if it's different */ if (!memcmp(checksum, checksum_new, GIT_HASH_SHA1_SIZE)) { - git_buf_dispose(&buf); + git_str_dispose(&buf); if (updated) *updated = 0; @@ -244,19 +244,19 @@ int git_futils_readbuffer_updated( if (updated != NULL) *updated = 1; - git_buf_swap(out, &buf); - git_buf_dispose(&buf); + git_str_swap(out, &buf); + git_str_dispose(&buf); return 0; } -int git_futils_readbuffer(git_buf *buf, const char *path) +int git_futils_readbuffer(git_str *buf, const char *path) { return git_futils_readbuffer_updated(buf, path, NULL, NULL); } int git_futils_writebuffer( - const git_buf *buf, const char *path, int flags, mode_t mode) + const git_str *buf, const char *path, int flags, mode_t mode) { int fd, do_fsync = 0, error = 0; @@ -276,7 +276,7 @@ int git_futils_writebuffer( return fd; } - if ((error = p_write(fd, git_buf_cstr(buf), git_buf_len(buf))) < 0) { + if ((error = p_write(fd, git_str_cstr(buf), git_str_len(buf))) < 0) { git_error_set(GIT_ERROR_OS, "could not write to '%s'", path); (void)p_close(fd); return error; @@ -418,7 +418,7 @@ GIT_INLINE(int) mkdir_validate_mode( } GIT_INLINE(int) mkdir_canonicalize( - git_buf *path, + git_str *path, uint32_t flags) { ssize_t root_len; @@ -450,7 +450,7 @@ GIT_INLINE(int) mkdir_canonicalize( * the root), we don't have anything to do. */ if (path->size <= (size_t)root_len) - git_buf_clear(path); + git_str_clear(path); return 0; } @@ -460,16 +460,16 @@ int git_futils_mkdir( mode_t mode, uint32_t flags) { - git_buf make_path = GIT_BUF_INIT, parent_path = GIT_BUF_INIT; + git_str make_path = GIT_STR_INIT, parent_path = GIT_STR_INIT; const char *relative; struct git_futils_mkdir_options opts = { 0 }; struct stat st; size_t depth = 0; int len = 0, root_len, error; - if ((error = git_buf_puts(&make_path, path)) < 0 || + if ((error = git_str_puts(&make_path, path)) < 0 || (error = mkdir_canonicalize(&make_path, flags)) < 0 || - (error = git_buf_puts(&parent_path, make_path.ptr)) < 0 || + (error = git_str_puts(&parent_path, make_path.ptr)) < 0 || make_path.size == 0) goto done; @@ -541,8 +541,8 @@ int git_futils_mkdir( parent_path.size ? parent_path.ptr : NULL, mode, flags, &opts); done: - git_buf_dispose(&make_path); - git_buf_dispose(&parent_path); + git_str_dispose(&make_path); + git_str_dispose(&parent_path); return error; } @@ -558,7 +558,7 @@ int git_futils_mkdir_relative( uint32_t flags, struct git_futils_mkdir_options *opts) { - git_buf make_path = GIT_BUF_INIT; + git_str make_path = GIT_STR_INIT; ssize_t root = 0, min_root_len; char lastch = '/', *tail; struct stat st; @@ -578,7 +578,7 @@ int git_futils_mkdir_relative( /* if we are not supposed to make the whole path, reset root */ if ((flags & GIT_MKDIR_PATH) == 0) - root = git_buf_rfind(&make_path, '/'); + root = git_str_rfind(&make_path, '/'); /* advance root past drive name or network mount prefix */ min_root_len = git_path_root(make_path.ptr); @@ -673,7 +673,7 @@ int git_futils_mkdir_relative( } done: - git_buf_dispose(&make_path); + git_str_dispose(&make_path); return error; } @@ -697,13 +697,13 @@ static int futils__error_cannot_rmdir(const char *path, const char *filemsg) return -1; } -static int futils__rm_first_parent(git_buf *path, const char *ceiling) +static int futils__rm_first_parent(git_str *path, const char *ceiling) { int error = GIT_ENOTFOUND; struct stat st; while (error == GIT_ENOTFOUND) { - git_buf_rtruncate_at_char(path, '/'); + git_str_rtruncate_at_char(path, '/'); if (!path->size || git__prefixcmp(path->ptr, ceiling) != 0) error = 0; @@ -722,7 +722,7 @@ static int futils__rm_first_parent(git_buf *path, const char *ceiling) return error; } -static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path) +static int futils__rmdir_recurs_foreach(void *opaque, git_str *path) { int error = 0; futils__rmdir_data *data = opaque; @@ -810,7 +810,7 @@ int git_futils_rmdir_r( const char *path, const char *base, uint32_t flags) { int error; - git_buf fullpath = GIT_BUF_INIT; + git_str fullpath = GIT_STR_INIT; futils__rmdir_data data; /* build path and find "root" where we should start calling mkdir */ @@ -834,7 +834,7 @@ int git_futils_rmdir_r( error = 0; } - git_buf_dispose(&fullpath); + git_str_dispose(&fullpath); return error; } @@ -938,7 +938,7 @@ static int cp_link(const char *from, const char *to, size_t link_size) typedef struct { const char *to_root; - git_buf to; + git_str to; ssize_t from_prefix; uint32_t flags; uint32_t mkdir_flags; @@ -947,7 +947,7 @@ typedef struct { #define GIT_CPDIR__MKDIR_DONE_FOR_TO_ROOT (1u << 10) -static int _cp_r_mkdir(cp_r_info *info, git_buf *from) +static int _cp_r_mkdir(cp_r_info *info, git_str *from) { int error = 0; @@ -969,7 +969,7 @@ static int _cp_r_mkdir(cp_r_info *info, git_buf *from) return error; } -static int _cp_r_callback(void *ref, git_buf *from) +static int _cp_r_callback(void *ref, git_str *from) { int error = 0; cp_r_info *info = ref; @@ -980,7 +980,7 @@ static int _cp_r_callback(void *ref, git_buf *from) from->ptr[git_path_basename_offset(from)] == '.') return 0; - if ((error = git_buf_joinpath( + if ((error = git_str_joinpath( &info->to, info->to_root, from->ptr + info->from_prefix)) < 0) return error; @@ -1064,10 +1064,10 @@ int git_futils_cp_r( mode_t dirmode) { int error; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cp_r_info info; - if (git_buf_joinpath(&path, from, "") < 0) /* ensure trailing slash */ + if (git_str_joinpath(&path, from, "") < 0) /* ensure trailing slash */ return -1; memset(&info, 0, sizeof(info)); @@ -1075,7 +1075,7 @@ int git_futils_cp_r( info.flags = flags; info.dirmode = dirmode; info.from_prefix = path.size; - git_buf_init(&info.to, 0); + git_str_init(&info.to, 0); /* precalculate mkdir flags */ if ((flags & GIT_CPDIR_CREATE_EMPTY_DIRS) == 0) { @@ -1093,8 +1093,8 @@ int git_futils_cp_r( error = _cp_r_callback(&info, &path); - git_buf_dispose(&path); - git_buf_dispose(&info.to); + git_str_dispose(&path); + git_str_dispose(&info.to); return error; } diff --git a/src/futils.h b/src/futils.h index 373cc3042eb..eea69adde79 100644 --- a/src/futils.h +++ b/src/futils.h @@ -21,13 +21,13 @@ * * Read whole files into an in-memory buffer for processing */ -extern int git_futils_readbuffer(git_buf *obj, const char *path); +extern int git_futils_readbuffer(git_str *obj, const char *path); extern int git_futils_readbuffer_updated( - git_buf *obj, + git_str *obj, const char *path, unsigned char checksum[GIT_HASH_SHA1_SIZE], int *updated); -extern int git_futils_readbuffer_fd(git_buf *obj, git_file fd, size_t len); +extern int git_futils_readbuffer_fd(git_str *obj, git_file fd, size_t len); /* Additional constants for `git_futils_writebuffer`'s `open_flags`. We * support these internally and they will be removed before the `open` call. @@ -37,7 +37,7 @@ extern int git_futils_readbuffer_fd(git_buf *obj, git_file fd, size_t len); #endif extern int git_futils_writebuffer( - const git_buf *buf, const char *path, int open_flags, mode_t mode); + const git_str *buf, const char *path, int open_flags, mode_t mode); /** * File utils @@ -177,7 +177,7 @@ extern int git_futils_rmdir_r(const char *path, const char *base, uint32_t flags * Writes the filename into path_out. * @return On success, an open file descriptor, else an error code < 0. */ -extern int git_futils_mktmp(git_buf *path_out, const char *filename, mode_t mode); +extern int git_futils_mktmp(git_str *path_out, const char *filename, mode_t mode); /** * Move a file on the filesystem, create the diff --git a/src/hash.c b/src/hash.c index 222eadf4019..92e7ff2195f 100644 --- a/src/hash.c +++ b/src/hash.c @@ -101,7 +101,7 @@ int git_hash_buf( int git_hash_vec( unsigned char *out, - git_buf_vec *vec, + git_str_vec *vec, size_t n, git_hash_algorithm_t algorithm) { diff --git a/src/hash.h b/src/hash.h index ec91fa43a2a..10b14a904b9 100644 --- a/src/hash.h +++ b/src/hash.h @@ -16,7 +16,7 @@ typedef struct { void *data; size_t len; -} git_buf_vec; +} git_str_vec; typedef enum { GIT_HASH_ALGORITHM_NONE = 0, @@ -40,6 +40,6 @@ int git_hash_update(git_hash_ctx *c, const void *data, size_t len); int git_hash_final(unsigned char *out, git_hash_ctx *c); int git_hash_buf(unsigned char *out, const void *data, size_t len, git_hash_algorithm_t algorithm); -int git_hash_vec(unsigned char *out, git_buf_vec *vec, size_t n, git_hash_algorithm_t algorithm); +int git_hash_vec(unsigned char *out, git_str_vec *vec, size_t n, git_hash_algorithm_t algorithm); #endif diff --git a/src/ident.c b/src/ident.c index e5aab80ed1e..53095864ee9 100644 --- a/src/ident.c +++ b/src/ident.c @@ -9,7 +9,7 @@ #include "git2/sys/filter.h" #include "filter.h" -#include "buffer.h" +#include "str.h" static int ident_find_id( const char **id_start, const char **id_end, const char *start, size_t len) @@ -40,7 +40,7 @@ static int ident_find_id( } static int ident_insert_id( - git_buf *to, const git_buf *from, const git_filter_source *src) + git_str *to, const git_str *from, const git_filter_source *src) { char oid[GIT_OID_HEXSZ+1]; const char *id_start, *id_end, *from_end = from->ptr + from->size; @@ -60,20 +60,20 @@ static int ident_insert_id( 5 /* "$Id: " */ + GIT_OID_HEXSZ + 2 /* " $" */ + (size_t)(from_end - id_end); - if (git_buf_grow(to, need_size) < 0) + if (git_str_grow(to, need_size) < 0) return -1; - git_buf_set(to, from->ptr, (size_t)(id_start - from->ptr)); - git_buf_put(to, "$Id: ", 5); - git_buf_put(to, oid, GIT_OID_HEXSZ); - git_buf_put(to, " $", 2); - git_buf_put(to, id_end, (size_t)(from_end - id_end)); + git_str_set(to, from->ptr, (size_t)(id_start - from->ptr)); + git_str_put(to, "$Id: ", 5); + git_str_put(to, oid, GIT_OID_HEXSZ); + git_str_put(to, " $", 2); + git_str_put(to, id_end, (size_t)(from_end - id_end)); - return git_buf_oom(to) ? -1 : 0; + return git_str_oom(to) ? -1 : 0; } static int ident_remove_id( - git_buf *to, const git_buf *from) + git_str *to, const git_str *from) { const char *id_start, *id_end, *from_end = from->ptr + from->size; size_t need_size; @@ -84,27 +84,27 @@ static int ident_remove_id( need_size = (size_t)(id_start - from->ptr) + 4 /* "$Id$" */ + (size_t)(from_end - id_end); - if (git_buf_grow(to, need_size) < 0) + if (git_str_grow(to, need_size) < 0) return -1; - git_buf_set(to, from->ptr, (size_t)(id_start - from->ptr)); - git_buf_put(to, "$Id$", 4); - git_buf_put(to, id_end, (size_t)(from_end - id_end)); + git_str_set(to, from->ptr, (size_t)(id_start - from->ptr)); + git_str_put(to, "$Id$", 4); + git_str_put(to, id_end, (size_t)(from_end - id_end)); - return git_buf_oom(to) ? -1 : 0; + return git_str_oom(to) ? -1 : 0; } static int ident_apply( git_filter *self, void **payload, - git_buf *to, - const git_buf *from, + git_str *to, + const git_str *from, const git_filter_source *src) { GIT_UNUSED(self); GIT_UNUSED(payload); /* Don't filter binary files */ - if (git_buf_is_binary(from)) + if (git_str_is_binary(from)) return GIT_PASSTHROUGH; if (git_filter_source_mode(src) == GIT_FILTER_SMUDGE) diff --git a/src/ignore.c b/src/ignore.c index 9ead96ba67e..eb9fd8a9e97 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -105,7 +105,7 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match size_t i; git_attr_fnmatch *rule; char *path; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; *out = 0; @@ -115,12 +115,12 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match /* path of the file relative to the workdir, so we match the rules in subdirs */ if (match->containing_dir) { - git_buf_puts(&buf, match->containing_dir); + git_str_puts(&buf, match->containing_dir); } - if (git_buf_puts(&buf, match->pattern) < 0) + if (git_str_puts(&buf, match->pattern) < 0) return -1; - path = git_buf_detach(&buf); + path = git_str_detach(&buf); git_vector_foreach(rules, i, rule) { if (!(rule->flags & GIT_ATTR_FNMATCH_HASWILD)) { @@ -133,12 +133,12 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match continue; } - git_buf_clear(&buf); + git_str_clear(&buf); if (rule->containing_dir) - git_buf_puts(&buf, rule->containing_dir); - git_buf_puts(&buf, rule->pattern); + git_str_puts(&buf, rule->containing_dir); + git_str_puts(&buf, rule->pattern); - if (git_buf_oom(&buf)) + if (git_str_oom(&buf)) goto out; /* @@ -151,7 +151,7 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match effective_flags &= ~WM_PATHNAME; /* if we found a match, we want to keep this rule */ - if ((wildmatch(git_buf_cstr(&buf), path, effective_flags)) == WM_MATCH) { + if ((wildmatch(git_str_cstr(&buf), path, effective_flags)) == WM_MATCH) { *out = 1; error = 0; goto out; @@ -162,7 +162,7 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match out: git__free(path); - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -295,7 +295,7 @@ int git_ignore__for_path( { int error = 0; const char *workdir = git_repository_workdir(repo); - git_buf infopath = GIT_BUF_INIT; + git_str infopath = GIT_STR_INIT; GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(ignores); @@ -314,19 +314,19 @@ int git_ignore__for_path( /* given a unrooted path in a non-bare repo, resolve it */ if (workdir && git_path_root(path) < 0) { - git_buf local = GIT_BUF_INIT; + git_str local = GIT_STR_INIT; if ((error = git_path_dirname_r(&local, path)) < 0 || (error = git_path_resolve_relative(&local, 0)) < 0 || (error = git_path_to_dir(&local)) < 0 || - (error = git_buf_joinpath(&ignores->dir, workdir, local.ptr)) < 0 || + (error = git_str_joinpath(&ignores->dir, workdir, local.ptr)) < 0 || (error = git_path_validate_workdir_buf(repo, &ignores->dir)) < 0) { /* Nothing, we just want to stop on the first error */ } - git_buf_dispose(&local); + git_str_dispose(&local); } else { - if (!(error = git_buf_joinpath(&ignores->dir, path, ""))) + if (!(error = git_str_joinpath(&ignores->dir, path, ""))) error = git_path_validate_filesystem(ignores->dir.ptr, ignores->dir.size); } @@ -349,7 +349,7 @@ int git_ignore__for_path( } /* load .git/info/exclude if possible */ - if ((error = git_repository_item_path(&infopath, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || + if ((error = git_repository__item_path(&infopath, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || (error = push_ignore_file(ignores, &ignores->ign_global, infopath.ptr, GIT_IGNORE_FILE_INREPO)) < 0) { if (error != GIT_ENOTFOUND) goto cleanup; @@ -363,7 +363,7 @@ int git_ignore__for_path( git_repository_attr_cache(repo)->cfg_excl_file); cleanup: - git_buf_dispose(&infopath); + git_str_dispose(&infopath); if (error < 0) git_ignore__free(ignores); @@ -372,7 +372,7 @@ int git_ignore__for_path( int git_ignore__push_dir(git_ignores *ign, const char *dir) { - if (git_buf_joinpath(&ign->dir, ign->dir.ptr, dir) < 0) + if (git_str_joinpath(&ign->dir, ign->dir.ptr, dir) < 0) return -1; ign->depth++; @@ -409,7 +409,7 @@ int git_ignore__pop_dir(git_ignores *ign) } if (--ign->depth > 0) { - git_buf_rtruncate_at_char(&ign->dir, '/'); + git_str_rtruncate_at_char(&ign->dir, '/'); git_path_to_dir(&ign->dir); } @@ -435,7 +435,7 @@ void git_ignore__free(git_ignores *ignores) } git_vector_free(&ignores->ign_global); - git_buf_dispose(&ignores->dir); + git_str_dispose(&ignores->dir); } static bool ignore_lookup_in_rules( @@ -604,7 +604,7 @@ int git_ignore__check_pathspec_for_exact_ignores( size_t i; git_attr_fnmatch *match; int ignored; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; const char *filename; git_index *idx; @@ -645,7 +645,7 @@ int git_ignore__check_pathspec_for_exact_ignores( } git_index_free(idx); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } diff --git a/src/ignore.h b/src/ignore.h index 5895d3faac9..7991952589a 100644 --- a/src/ignore.h +++ b/src/ignore.h @@ -26,7 +26,7 @@ */ typedef struct { git_repository *repo; - git_buf dir; /* current directory reflected in ign_path */ + git_str dir; /* current directory reflected in ign_path */ git_attr_file *ign_internal; git_vector ign_path; git_vector ign_global; diff --git a/src/index.c b/src/index.c index 2e24fff6948..b8aa310d316 100644 --- a/src/index.c +++ b/src/index.c @@ -641,7 +641,7 @@ static int compare_checksum(git_index *index) int git_index_read(git_index *index, int force) { int error = 0, updated; - git_buf buffer = GIT_BUF_INIT; + git_str buffer = GIT_STR_INIT; git_futils_filestamp stamp = index->stamp; if (!index->index_file_path) @@ -687,7 +687,7 @@ int git_index_read(git_index *index, int force) index->dirty = 0; } - git_buf_dispose(&buffer); + git_str_dispose(&buffer); return error; } @@ -969,7 +969,7 @@ static int index_entry_init( { int error = 0; git_index_entry *entry = NULL; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; struct stat st; git_oid oid; git_repository *repo; @@ -992,7 +992,7 @@ static int index_entry_init( return -1; error = git_path_lstat(path.ptr, &st); - git_buf_dispose(&path); + git_str_dispose(&path); if (error < 0) return error; @@ -1525,7 +1525,7 @@ int git_index_add_from_buffer( static int add_repo_as_submodule(git_index_entry **out, git_index *index, const char *path) { git_repository *sub; - git_buf abspath = GIT_BUF_INIT; + git_str abspath = GIT_STR_INIT; git_repository *repo = INDEX_OWNER(index); git_reference *head; git_index_entry *entry; @@ -1556,7 +1556,7 @@ static int add_repo_as_submodule(git_index_entry **out, git_index *index, const git_reference_free(head); git_repository_free(sub); - git_buf_dispose(&abspath); + git_str_dispose(&abspath); *out = entry; return 0; @@ -1722,12 +1722,12 @@ int git_index_remove(git_index *index, const char *path, int stage) int git_index_remove_directory(git_index *index, const char *dir, int stage) { - git_buf pfx = GIT_BUF_INIT; + git_str pfx = GIT_STR_INIT; int error = 0; size_t pos; git_index_entry *entry; - if (!(error = git_buf_sets(&pfx, dir)) && + if (!(error = git_str_sets(&pfx, dir)) && !(error = git_path_to_dir(&pfx))) index_find(&pos, index, pfx.ptr, pfx.size, GIT_INDEX_STAGE_ANY); @@ -1746,7 +1746,7 @@ int git_index_remove_directory(git_index *index, const char *dir, int stage) /* removed entry at 'pos' so we don't need to increment */ } - git_buf_dispose(&pfx); + git_str_dispose(&pfx); return error; } @@ -2892,7 +2892,7 @@ static int write_entries(git_index *index, git_filebuf *file) return error; } -static int write_extension(git_filebuf *file, struct index_extension *header, git_buf *data) +static int write_extension(git_filebuf *file, struct index_extension *header, git_str *data) { struct index_extension ondisk; @@ -2904,30 +2904,30 @@ static int write_extension(git_filebuf *file, struct index_extension *header, gi return git_filebuf_write(file, data->ptr, data->size); } -static int create_name_extension_data(git_buf *name_buf, git_index_name_entry *conflict_name) +static int create_name_extension_data(git_str *name_buf, git_index_name_entry *conflict_name) { int error = 0; if (conflict_name->ancestor == NULL) - error = git_buf_put(name_buf, "\0", 1); + error = git_str_put(name_buf, "\0", 1); else - error = git_buf_put(name_buf, conflict_name->ancestor, strlen(conflict_name->ancestor) + 1); + error = git_str_put(name_buf, conflict_name->ancestor, strlen(conflict_name->ancestor) + 1); if (error != 0) goto on_error; if (conflict_name->ours == NULL) - error = git_buf_put(name_buf, "\0", 1); + error = git_str_put(name_buf, "\0", 1); else - error = git_buf_put(name_buf, conflict_name->ours, strlen(conflict_name->ours) + 1); + error = git_str_put(name_buf, conflict_name->ours, strlen(conflict_name->ours) + 1); if (error != 0) goto on_error; if (conflict_name->theirs == NULL) - error = git_buf_put(name_buf, "\0", 1); + error = git_str_put(name_buf, "\0", 1); else - error = git_buf_put(name_buf, conflict_name->theirs, strlen(conflict_name->theirs) + 1); + error = git_str_put(name_buf, conflict_name->theirs, strlen(conflict_name->theirs) + 1); on_error: return error; @@ -2935,7 +2935,7 @@ static int create_name_extension_data(git_buf *name_buf, git_index_name_entry *c static int write_name_extension(git_index *index, git_filebuf *file) { - git_buf name_buf = GIT_BUF_INIT; + git_str name_buf = GIT_STR_INIT; git_vector *out = &index->names; git_index_name_entry *conflict_name; struct index_extension extension; @@ -2953,28 +2953,28 @@ static int write_name_extension(git_index *index, git_filebuf *file) error = write_extension(file, &extension, &name_buf); - git_buf_dispose(&name_buf); + git_str_dispose(&name_buf); done: return error; } -static int create_reuc_extension_data(git_buf *reuc_buf, git_index_reuc_entry *reuc) +static int create_reuc_extension_data(git_str *reuc_buf, git_index_reuc_entry *reuc) { int i; int error = 0; - if ((error = git_buf_put(reuc_buf, reuc->path, strlen(reuc->path) + 1)) < 0) + if ((error = git_str_put(reuc_buf, reuc->path, strlen(reuc->path) + 1)) < 0) return error; for (i = 0; i < 3; i++) { - if ((error = git_buf_printf(reuc_buf, "%o", reuc->mode[i])) < 0 || - (error = git_buf_put(reuc_buf, "\0", 1)) < 0) + if ((error = git_str_printf(reuc_buf, "%o", reuc->mode[i])) < 0 || + (error = git_str_put(reuc_buf, "\0", 1)) < 0) return error; } for (i = 0; i < 3; i++) { - if (reuc->mode[i] && (error = git_buf_put(reuc_buf, (char *)&reuc->oid[i].id, GIT_OID_RAWSZ)) < 0) + if (reuc->mode[i] && (error = git_str_put(reuc_buf, (char *)&reuc->oid[i].id, GIT_OID_RAWSZ)) < 0) return error; } @@ -2983,7 +2983,7 @@ static int create_reuc_extension_data(git_buf *reuc_buf, git_index_reuc_entry *r static int write_reuc_extension(git_index *index, git_filebuf *file) { - git_buf reuc_buf = GIT_BUF_INIT; + git_str reuc_buf = GIT_STR_INIT; git_vector *out = &index->reuc; git_index_reuc_entry *reuc; struct index_extension extension; @@ -3001,7 +3001,7 @@ static int write_reuc_extension(git_index *index, git_filebuf *file) error = write_extension(file, &extension, &reuc_buf); - git_buf_dispose(&reuc_buf); + git_str_dispose(&reuc_buf); done: return error; @@ -3010,7 +3010,7 @@ static int write_reuc_extension(git_index *index, git_filebuf *file) static int write_tree_extension(git_index *index, git_filebuf *file) { struct index_extension extension; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error; if (index->tree == NULL) @@ -3025,7 +3025,7 @@ static int write_tree_extension(git_index *index, git_filebuf *file) error = write_extension(file, &extension, &buf); - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -3115,13 +3115,13 @@ static int read_tree_cb( { read_tree_data *data = payload; git_index_entry *entry = NULL, *old_entry; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; size_t pos; if (git_tree_entry__is_tree(tentry)) return 0; - if (git_buf_joinpath(&path, root, tentry->filename) < 0) + if (git_str_joinpath(&path, root, tentry->filename) < 0) return -1; if (index_entry_create(&entry, INDEX_OWNER(data->index), path.ptr, NULL, false) < 0) @@ -3143,7 +3143,7 @@ static int read_tree_cb( } index_entry_adjust_namemask(entry, path.size); - git_buf_dispose(&path); + git_str_dispose(&path); if (git_vector_insert(data->new_entries, entry) < 0) { index_entry_free(entry); @@ -3540,7 +3540,7 @@ static int index_apply_to_all( size_t i; git_pathspec ps; const char *match; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; GIT_ASSERT_ARG(index); @@ -3569,7 +3569,7 @@ static int index_apply_to_all( } /* index manipulation may alter entry, so don't depend on it */ - if ((error = git_buf_sets(&path, entry->path)) < 0) + if ((error = git_str_sets(&path, entry->path)) < 0) break; switch (action) { @@ -3598,7 +3598,7 @@ static int index_apply_to_all( } } - git_buf_dispose(&path); + git_str_dispose(&path); git_pathspec__clear(&ps); return error; diff --git a/src/indexer.c b/src/indexer.c index 16ed7bfae22..213ad7581a5 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -48,7 +48,7 @@ struct git_indexer { off64_t off; off64_t entry_start; git_object_t entry_type; - git_buf entry_data; + git_str entry_data; git_packfile_stream stream; size_t nr_objects; git_vector objects; @@ -137,7 +137,7 @@ int git_indexer_new( { git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT; git_indexer *idx; - git_buf path = GIT_BUF_INIT, tmp_path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, tmp_path = GIT_STR_INIT; static const char suff[] = "/pack"; int error, fd = -1; @@ -150,7 +150,7 @@ int git_indexer_new( idx->progress_cb = opts.progress_cb; idx->progress_payload = opts.progress_cb_payload; idx->mode = mode ? mode : GIT_PACK_FILE_MODE; - git_buf_init(&idx->entry_data, 0); + git_str_init(&idx->entry_data, 0); if ((error = git_hash_ctx_init(&idx->hash_ctx, GIT_HASH_ALGORITHM_SHA1)) < 0 || (error = git_hash_ctx_init(&idx->trailer, GIT_HASH_ALGORITHM_SHA1)) < 0 || @@ -162,17 +162,17 @@ int git_indexer_new( if (git_repository__fsync_gitdir) idx->do_fsync = 1; - error = git_buf_joinpath(&path, prefix, suff); + error = git_str_joinpath(&path, prefix, suff); if (error < 0) goto cleanup; - fd = git_futils_mktmp(&tmp_path, git_buf_cstr(&path), idx->mode); - git_buf_dispose(&path); + fd = git_futils_mktmp(&tmp_path, git_str_cstr(&path), idx->mode); + git_str_dispose(&path); if (fd < 0) goto cleanup; - error = git_packfile_alloc(&idx->pack, git_buf_cstr(&tmp_path)); - git_buf_dispose(&tmp_path); + error = git_packfile_alloc(&idx->pack, git_str_cstr(&tmp_path)); + git_str_dispose(&tmp_path); if (error < 0) goto cleanup; @@ -188,14 +188,14 @@ int git_indexer_new( if (fd != -1) p_close(fd); - if (git_buf_len(&tmp_path) > 0) - p_unlink(git_buf_cstr(&tmp_path)); + if (git_str_len(&tmp_path) > 0) + p_unlink(git_str_cstr(&tmp_path)); if (idx->pack != NULL) p_unlink(idx->pack->pack_name); - git_buf_dispose(&path); - git_buf_dispose(&tmp_path); + git_str_dispose(&path); + git_str_dispose(&tmp_path); git__free(idx); return -1; } @@ -245,7 +245,7 @@ static int hash_object_stream(git_indexer*idx, git_packfile_stream *stream) break; if (idx->do_verify) - git_buf_put(&idx->entry_data, idx->objbuf, read); + git_str_put(&idx->entry_data, idx->objbuf, read); git_hash_update(&idx->hash_ctx, idx->objbuf, read); } while (read > 0); @@ -730,7 +730,7 @@ static int read_stream_object(git_indexer *idx, git_indexer_progress *stats) git_mwindow_close(&w); idx->entry_start = entry_start; git_hash_init(&idx->hash_ctx); - git_buf_clear(&idx->entry_data); + git_str_clear(&idx->entry_data); if (type == GIT_OBJECT_REF_DELTA || type == GIT_OBJECT_OFS_DELTA) { error = advance_delta_offset(idx, type); @@ -876,7 +876,7 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_inde return error; } -static int index_path(git_buf *path, git_indexer *idx, const char *suffix) +static int index_path(git_str *path, git_indexer *idx, const char *suffix) { const char prefix[] = "pack-"; size_t slash = (size_t)path->size; @@ -885,17 +885,17 @@ static int index_path(git_buf *path, git_indexer *idx, const char *suffix) while (slash > 0 && path->ptr[slash - 1] != '/') slash--; - if (git_buf_grow(path, slash + 1 + strlen(prefix) + + if (git_str_grow(path, slash + 1 + strlen(prefix) + GIT_OID_HEXSZ + strlen(suffix) + 1) < 0) return -1; - git_buf_truncate(path, slash); - git_buf_puts(path, prefix); - git_oid_fmt(path->ptr + git_buf_len(path), &idx->hash); + git_str_truncate(path, slash); + git_str_puts(path, prefix); + git_oid_fmt(path->ptr + git_str_len(path), &idx->hash); path->size += GIT_OID_HEXSZ; - git_buf_puts(path, suffix); + git_str_puts(path, suffix); - return git_buf_oom(path) ? -1 : 0; + return git_str_oom(path) ? -1 : 0; } /** @@ -915,7 +915,7 @@ static int inject_object(git_indexer *idx, git_oid *id) struct git_pack_entry *pentry = NULL; git_oid foo = {{0}}; unsigned char hdr[64]; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; off64_t entry_start; const void *data; size_t len, hdr_len; @@ -956,7 +956,7 @@ static int inject_object(git_indexer *idx, git_oid *id) idx->pack->mwf.size += buf.size; entry->crc = htonl(crc32(entry->crc, (unsigned char *)buf.ptr, (uInt)buf.size)); - git_buf_dispose(&buf); + git_str_dispose(&buf); /* Write a fake trailer so the pack functions play ball */ @@ -1152,7 +1152,7 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) unsigned int i, long_offsets = 0, left; int error; struct git_pack_idx_header hdr; - git_buf filename = GIT_BUF_INIT; + git_str filename = GIT_STR_INIT; struct entry *entry; git_oid trailer_hash, file_hash; git_filebuf index_file = {0}; @@ -1226,10 +1226,10 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) * files with different contents have different names */ git_oid_cpy(&idx->hash, &trailer_hash); - git_buf_sets(&filename, idx->pack->pack_name); - git_buf_shorten(&filename, strlen("pack")); - git_buf_puts(&filename, "idx"); - if (git_buf_oom(&filename)) + git_str_sets(&filename, idx->pack->pack_name); + git_str_shorten(&filename, strlen("pack")); + git_str_puts(&filename, "idx"); + if (git_str_oom(&filename)) return -1; if (git_filebuf_open(&index_file, filename.ptr, @@ -1336,23 +1336,23 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) goto on_error; /* And don't forget to rename the packfile to its new place. */ - if (p_rename(idx->pack->pack_name, git_buf_cstr(&filename)) < 0) + if (p_rename(idx->pack->pack_name, git_str_cstr(&filename)) < 0) goto on_error; /* And fsync the parent directory if we're asked to. */ if (idx->do_fsync && - git_futils_fsync_parent(git_buf_cstr(&filename)) < 0) + git_futils_fsync_parent(git_str_cstr(&filename)) < 0) goto on_error; idx->pack_committed = 1; - git_buf_dispose(&filename); + git_str_dispose(&filename); return 0; on_error: git_mwindow_free_all(&idx->pack->mwf); git_filebuf_cleanup(&index_file); - git_buf_dispose(&filename); + git_str_dispose(&filename); return -1; } @@ -1389,7 +1389,7 @@ void git_indexer_free(git_indexer *idx) git_hash_ctx_cleanup(&idx->trailer); git_hash_ctx_cleanup(&idx->hash_ctx); - git_buf_dispose(&idx->entry_data); + git_str_dispose(&idx->entry_data); git_oidmap_free(idx->expected_oids); git__free(idx); } diff --git a/src/iterator.c b/src/iterator.c index ce9f305ef28..5549c636aa2 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -424,7 +424,7 @@ typedef struct { git_tree *tree; /* path to this particular frame (folder) */ - git_buf path; + git_str path; /* a sorted list of the entries for this frame (folder), these are * actually pointers to the iterator's entry pool. @@ -441,7 +441,7 @@ typedef struct { * parent path. */ git_vector similar_trees; - git_array_t(git_buf) similar_paths; + git_array_t(git_str) similar_paths; } tree_iterator_frame; typedef struct { @@ -450,7 +450,7 @@ typedef struct { git_array_t(tree_iterator_frame) frames; git_index_entry entry; - git_buf entry_path; + git_str entry_path; /* a pool of entries to reduce the number of allocations */ git_pool entry_pool; @@ -508,20 +508,20 @@ static int tree_iterator_entry_sort_icase(const void *ptr_a, const void *ptr_b) } static int tree_iterator_compute_path( - git_buf *out, + git_str *out, tree_iterator_entry *entry) { - git_buf_clear(out); + git_str_clear(out); if (entry->parent_path) - git_buf_joinpath(out, entry->parent_path, entry->tree_entry->filename); + git_str_joinpath(out, entry->parent_path, entry->tree_entry->filename); else - git_buf_puts(out, entry->tree_entry->filename); + git_str_puts(out, entry->tree_entry->filename); if (git_tree_entry__is_tree(entry->tree_entry)) - git_buf_putc(out, '/'); + git_str_putc(out, '/'); - if (git_buf_oom(out)) + if (git_str_oom(out)) return -1; return 0; @@ -601,7 +601,7 @@ GIT_INLINE(int) tree_iterator_frame_push_neighbors( tree_iterator_entry *entry, *new_entry; git_tree *tree = NULL; git_tree_entry *tree_entry; - git_buf *path; + git_str *path; size_t new_size, i; int error = 0; @@ -621,7 +621,7 @@ GIT_INLINE(int) tree_iterator_frame_push_neighbors( path = git_array_alloc(parent_frame->similar_paths); GIT_ERROR_CHECK_ALLOC(path); - memset(path, 0, sizeof(git_buf)); + memset(path, 0, sizeof(git_str)); if ((error = tree_iterator_compute_path(path, entry)) < 0) break; @@ -681,7 +681,7 @@ GIT_INLINE(int) tree_iterator_frame_push( static int tree_iterator_frame_pop(tree_iterator *iter) { tree_iterator_frame *frame; - git_buf *buf = NULL; + git_str *buf = NULL; git_tree *tree; size_t i; @@ -694,7 +694,7 @@ static int tree_iterator_frame_pop(tree_iterator *iter) do { buf = git_array_pop(frame->similar_paths); - git_buf_dispose(buf); + git_str_dispose(buf); } while (buf != NULL); git_array_clear(frame->similar_paths); @@ -704,7 +704,7 @@ static int tree_iterator_frame_pop(tree_iterator *iter) git_vector_free(&frame->similar_trees); - git_buf_dispose(&frame->path); + git_str_dispose(&frame->path); return 0; } @@ -892,7 +892,7 @@ static void tree_iterator_clear(tree_iterator *iter) git_array_clear(iter->frames); git_pool_clear(&iter->entry_pool); - git_buf_clear(&iter->entry_path); + git_str_clear(&iter->entry_path); iterator_clear(&iter->base); } @@ -925,7 +925,7 @@ static void tree_iterator_free(git_iterator *i) tree_iterator_clear(iter); git_tree_free(iter->root); - git_buf_dispose(&iter->entry_path); + git_str_dispose(&iter->entry_path); } int git_iterator_for_tree( @@ -1040,11 +1040,11 @@ typedef struct { /* info about the current entry */ git_index_entry entry; - git_buf current_path; + git_str current_path; int current_is_ignored; /* temporary buffer for advance_over */ - git_buf tmp_buf; + git_str tmp_buf; } filesystem_iterator; @@ -1266,7 +1266,7 @@ static int filesystem_iterator_entry_hash( filesystem_iterator *iter, filesystem_iterator_entry *entry) { - git_buf fullpath = GIT_BUF_INIT; + git_str fullpath = GIT_STR_INIT; int error; if (S_ISDIR(entry->st.st_mode)) { @@ -1278,11 +1278,11 @@ static int filesystem_iterator_entry_hash( return git_repository_hashfile(&entry->id, iter->base.repo, entry->path, GIT_OBJECT_BLOB, NULL); - if (!(error = git_buf_joinpath(&fullpath, iter->root, entry->path)) && + if (!(error = git_str_joinpath(&fullpath, iter->root, entry->path)) && !(error = git_path_validate_workdir_buf(iter->base.repo, &fullpath))) error = git_odb_hashfile(&entry->id, fullpath.ptr, GIT_OBJECT_BLOB); - git_buf_dispose(&fullpath); + git_str_dispose(&fullpath); return error; } @@ -1337,7 +1337,7 @@ static int filesystem_iterator_frame_push( { filesystem_iterator_frame *new_frame = NULL; git_path_diriter diriter = GIT_PATH_DIRITER_INIT; - git_buf root = GIT_BUF_INIT; + git_str root = GIT_STR_INIT; const char *path; filesystem_iterator_entry *entry; struct stat statbuf; @@ -1356,11 +1356,11 @@ static int filesystem_iterator_frame_push( memset(new_frame, 0, sizeof(filesystem_iterator_frame)); if (frame_entry) - git_buf_joinpath(&root, iter->root, frame_entry->path); + git_str_joinpath(&root, iter->root, frame_entry->path); else - git_buf_puts(&root, iter->root); + git_str_puts(&root, iter->root); - if (git_buf_oom(&root) || + if (git_str_oom(&root) || git_path_validate_workdir_buf(iter->base.repo, &root) < 0) { error = -1; goto done; @@ -1471,7 +1471,7 @@ static int filesystem_iterator_frame_push( if (error < 0) git_array_pop(iter->frames); - git_buf_dispose(&root); + git_str_dispose(&root); git_path_diriter_free(&diriter); return error; } @@ -1551,7 +1551,7 @@ static int filesystem_iterator_is_dir( const filesystem_iterator_entry *entry) { struct stat st; - git_buf fullpath = GIT_BUF_INIT; + git_str fullpath = GIT_STR_INIT; int error = 0; if (S_ISDIR(entry->st.st_mode)) { @@ -1564,7 +1564,7 @@ static int filesystem_iterator_is_dir( goto done; } - if ((error = git_buf_joinpath(&fullpath, iter->root, entry->path)) < 0 || + if ((error = git_str_joinpath(&fullpath, iter->root, entry->path)) < 0 || (error = git_path_validate_workdir_buf(iter->base.repo, &fullpath)) < 0 || (error = p_stat(fullpath.ptr, &st)) < 0) goto done; @@ -1572,7 +1572,7 @@ static int filesystem_iterator_is_dir( *is_dir = S_ISDIR(st.st_mode); done: - git_buf_dispose(&fullpath); + git_str_dispose(&fullpath); return error; } @@ -1673,7 +1673,7 @@ static int filesystem_iterator_advance_into( return filesystem_iterator_advance(out, i); } -int git_iterator_current_workdir_path(git_buf **out, git_iterator *i) +int git_iterator_current_workdir_path(git_str **out, git_iterator *i) { filesystem_iterator *iter = GIT_CONTAINER_OF(i, filesystem_iterator, base); const git_index_entry *entry; @@ -1684,10 +1684,10 @@ int git_iterator_current_workdir_path(git_buf **out, git_iterator *i) return 0; } - git_buf_truncate(&iter->current_path, iter->root_len); + git_str_truncate(&iter->current_path, iter->root_len); if (git_iterator_current(&entry, i) < 0 || - git_buf_puts(&iter->current_path, entry->path) < 0) + git_str_puts(&iter->current_path, entry->path) < 0) return -1; *out = &iter->current_path; @@ -1790,8 +1790,8 @@ static int filesystem_iterator_advance_over( return filesystem_iterator_advance(out, i); } - git_buf_clear(&iter->tmp_buf); - if ((error = git_buf_puts(&iter->tmp_buf, entry->path)) < 0) + git_str_clear(&iter->tmp_buf); + if ((error = git_str_puts(&iter->tmp_buf, entry->path)) < 0) return error; base = iter->tmp_buf.ptr; @@ -1858,7 +1858,7 @@ static void filesystem_iterator_clear(filesystem_iterator *iter) git_array_clear(iter->frames); git_ignore__free(&iter->ignores); - git_buf_dispose(&iter->tmp_buf); + git_str_dispose(&iter->tmp_buf); iterator_clear(&iter->base); } @@ -1892,7 +1892,7 @@ static void filesystem_iterator_free(git_iterator *i) { filesystem_iterator *iter = GIT_CONTAINER_OF(i, filesystem_iterator, base); git__free(iter->root); - git_buf_dispose(&iter->current_path); + git_str_dispose(&iter->current_path); git_tree_free(iter->tree); if (iter->index) git_index_snapshot_release(&iter->index_snapshot, iter->index); @@ -1946,7 +1946,7 @@ static int iterator_for_filesystem( iter->root[root_len] = '\0'; iter->root_len = root_len; - if ((error = git_buf_puts(&iter->current_path, iter->root)) < 0) + if ((error = git_str_puts(&iter->current_path, iter->root)) < 0) goto on_error; if ((error = iterator_init_common(&iter->base, repo, index, options)) < 0) @@ -2024,7 +2024,7 @@ typedef struct { /* the pseudotree entry */ git_index_entry tree_entry; - git_buf tree_buf; + git_str tree_buf; bool skip_tree; const git_index_entry *entry; @@ -2064,8 +2064,8 @@ static bool index_iterator_create_pseudotree( if ((dirsep = strchr(relative_path, '/')) == NULL) return false; - git_buf_clear(&iter->tree_buf); - git_buf_put(&iter->tree_buf, path, (dirsep - path) + 1); + git_str_clear(&iter->tree_buf); + git_str_put(&iter->tree_buf, path, (dirsep - path) + 1); iter->tree_entry.mode = GIT_FILEMODE_TREE; iter->tree_entry.path = iter->tree_buf.ptr; @@ -2230,7 +2230,7 @@ static void index_iterator_free(git_iterator *i) index_iterator *iter = GIT_CONTAINER_OF(i, index_iterator, base); git_index_snapshot_release(&iter->entries, iter->base.index); - git_buf_dispose(&iter->tree_buf); + git_str_dispose(&iter->tree_buf); } int git_iterator_for_index( diff --git a/src/iterator.h b/src/iterator.h index 30465df2f03..e55c1047ab3 100644 --- a/src/iterator.h +++ b/src/iterator.h @@ -11,7 +11,7 @@ #include "git2/index.h" #include "vector.h" -#include "buffer.h" +#include "str.h" #include "ignore.h" typedef struct git_iterator git_iterator; @@ -278,11 +278,11 @@ extern bool git_iterator_current_tree_is_ignored(git_iterator *iter); /** * Get full path of the current item from a workdir iterator. This will - * return NULL for a non-workdir iterator. The git_buf is still owned by + * return NULL for a non-workdir iterator. The git_str is still owned by * the iterator; this is exposed just for efficiency. */ extern int git_iterator_current_workdir_path( - git_buf **path, git_iterator *iter); + git_str **path, git_iterator *iter); /** * Retrieve the index stored in the iterator. diff --git a/src/libgit2.c b/src/libgit2.c index cc793b4587f..b3a72de18f9 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -9,6 +9,7 @@ #include #include "alloc.h" +#include "buf.h" #include "cache.h" #include "common.h" #include "filter.h" @@ -192,15 +193,17 @@ int git_libgit2_opts(int key, ...) { int sysdir = va_arg(ap, int); git_buf *out = va_arg(ap, git_buf *); - const git_buf *tmp; + git_str str = GIT_STR_INIT; + const git_str *tmp; int level; - if ((error = config_level_to_sysdir(&level, sysdir)) < 0 || - (error = git_buf_sanitize(out)) < 0 || - (error = git_sysdir_get(&tmp, level)) < 0) + if ((error = git_buf_tostr(&str, out)) < 0 || + (error = config_level_to_sysdir(&level, sysdir)) < 0 || + (error = git_sysdir_get(&tmp, level)) < 0 || + (error = git_str_put(&str, tmp->ptr, tmp->size)) < 0) break; - error = git_buf_sets(out, tmp->ptr); + error = git_buf_fromstr(out, &str); } break; @@ -237,13 +240,15 @@ int git_libgit2_opts(int key, ...) case GIT_OPT_GET_TEMPLATE_PATH: { git_buf *out = va_arg(ap, git_buf *); - const git_buf *tmp; + git_str str = GIT_STR_INIT; + const git_str *tmp; - if ((error = git_buf_sanitize(out)) < 0 || - (error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0) + if ((error = git_buf_tostr(&str, out)) < 0 || + (error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0 || + (error = git_str_put(&str, tmp->ptr, tmp->size)) < 0) break; - error = git_buf_sets(out, tmp->ptr); + error = git_buf_fromstr(out, &str); } break; @@ -306,9 +311,13 @@ int git_libgit2_opts(int key, ...) case GIT_OPT_GET_USER_AGENT: { git_buf *out = va_arg(ap, git_buf *); - if ((error = git_buf_sanitize(out)) < 0) + git_str str = GIT_STR_INIT; + + if ((error = git_buf_tostr(&str, out)) < 0 || + (error = git_str_puts(&str, git__user_agent)) < 0) break; - error = git_buf_sets(out, git__user_agent); + + error = git_buf_fromstr(out, &str); } break; diff --git a/src/mailmap.c b/src/mailmap.c index b69d55e2ee2..38ae0164589 100644 --- a/src/mailmap.c +++ b/src/mailmap.c @@ -8,6 +8,7 @@ #include "mailmap.h" #include "common.h" +#include "config.h" #include "path.h" #include "repository.h" #include "signature.h" @@ -90,21 +91,21 @@ static int advance_until( /* * Parse a single entry from a mailmap file. * - * The output git_bufs will be non-owning, and should be copied before being + * The output git_strs will be non-owning, and should be copied before being * persisted. */ static int parse_mailmap_entry( - git_buf *real_name, git_buf *real_email, - git_buf *replace_name, git_buf *replace_email, + git_str *real_name, git_str *real_email, + git_str *replace_name, git_str *replace_email, git_parse_ctx *ctx) { const char *start; size_t len; - git_buf_clear(real_name); - git_buf_clear(real_email); - git_buf_clear(replace_name); - git_buf_clear(replace_email); + git_str_clear(real_name); + git_str_clear(real_email); + git_str_clear(replace_name); + git_str_clear(replace_email); git_parse_advance_ws(ctx); if (is_eol(ctx)) @@ -114,8 +115,8 @@ static int parse_mailmap_entry( if (advance_until(&start, &len, ctx, '<') < 0) return -1; - git_buf_attach_notowned(real_name, start, len); - git_buf_rtrim(real_name); + git_str_attach_notowned(real_name, start, len); + git_str_rtrim(real_name); /* * If this is the last email in the line, this is the email to replace, @@ -126,19 +127,19 @@ static int parse_mailmap_entry( /* If we aren't at the end of the line, parse a second name and email */ if (!is_eol(ctx)) { - git_buf_attach_notowned(real_email, start, len); + git_str_attach_notowned(real_email, start, len); git_parse_advance_ws(ctx); if (advance_until(&start, &len, ctx, '<') < 0) return -1; - git_buf_attach_notowned(replace_name, start, len); - git_buf_rtrim(replace_name); + git_str_attach_notowned(replace_name, start, len); + git_str_rtrim(replace_name); if (advance_until(&start, &len, ctx, '>') < 0) return -1; } - git_buf_attach_notowned(replace_email, start, len); + git_str_attach_notowned(replace_email, start, len); if (!is_eol(ctx)) return -1; @@ -231,10 +232,10 @@ static int mailmap_add_buffer(git_mailmap *mm, const char *buf, size_t len) git_parse_ctx ctx; /* Scratch buffers containing the real parsed names & emails */ - git_buf real_name = GIT_BUF_INIT; - git_buf real_email = GIT_BUF_INIT; - git_buf replace_name = GIT_BUF_INIT; - git_buf replace_email = GIT_BUF_INIT; + git_str real_name = GIT_STR_INIT; + git_str real_email = GIT_STR_INIT; + git_str replace_name = GIT_STR_INIT; + git_str replace_email = GIT_STR_INIT; /* Buffers may not contain '\0's. */ if (memchr(buf, '\0', len) != NULL) @@ -263,10 +264,10 @@ static int mailmap_add_buffer(git_mailmap *mm, const char *buf, size_t len) } cleanup: - git_buf_dispose(&real_name); - git_buf_dispose(&real_email); - git_buf_dispose(&replace_name); - git_buf_dispose(&replace_email); + git_str_dispose(&real_name); + git_str_dispose(&real_email); + git_str_dispose(&replace_name); + git_str_dispose(&replace_email); return error; } @@ -289,7 +290,7 @@ static int mailmap_add_blob( { git_object *object = NULL; git_blob *blob = NULL; - git_buf content = GIT_BUF_INIT; + git_str content = GIT_STR_INIT; int error; GIT_ASSERT_ARG(mm); @@ -312,7 +313,7 @@ static int mailmap_add_blob( goto cleanup; cleanup: - git_buf_dispose(&content); + git_str_dispose(&content); git_blob_free(blob); git_object_free(object); return error; @@ -322,8 +323,8 @@ static int mailmap_add_file_ondisk( git_mailmap *mm, const char *path, git_repository *repo) { const char *base = repo ? git_repository_workdir(repo) : NULL; - git_buf fullpath = GIT_BUF_INIT; - git_buf content = GIT_BUF_INIT; + git_str fullpath = GIT_STR_INIT; + git_str content = GIT_STR_INIT; int error; error = git_path_join_unrooted(&fullpath, path, base, NULL); @@ -343,8 +344,8 @@ static int mailmap_add_file_ondisk( goto cleanup; cleanup: - git_buf_dispose(&fullpath); - git_buf_dispose(&content); + git_str_dispose(&fullpath); + git_str_dispose(&content); return error; } @@ -352,8 +353,8 @@ static int mailmap_add_file_ondisk( static void mailmap_add_from_repository(git_mailmap *mm, git_repository *repo) { git_config *config = NULL; - git_buf rev_buf = GIT_BUF_INIT; - git_buf path_buf = GIT_BUF_INIT; + git_str rev_buf = GIT_STR_INIT; + git_str path_buf = GIT_STR_INIT; const char *rev = NULL; const char *path = NULL; @@ -363,9 +364,9 @@ static void mailmap_add_from_repository(git_mailmap *mm, git_repository *repo) /* Try to load 'mailmap.file' and 'mailmap.blob' cfgs from the repo */ if (git_repository_config(&config, repo) == 0) { - if (git_config_get_string_buf(&rev_buf, config, MM_BLOB_CONFIG) == 0) + if (git_config__get_string_buf(&rev_buf, config, MM_BLOB_CONFIG) == 0) rev = rev_buf.ptr; - if (git_config_get_path(&path_buf, config, MM_FILE_CONFIG) == 0) + if (git_config__get_path(&path_buf, config, MM_FILE_CONFIG) == 0) path = path_buf.ptr; } @@ -387,8 +388,8 @@ static void mailmap_add_from_repository(git_mailmap *mm, git_repository *repo) if (path != NULL) mailmap_add_file_ondisk(mm, path, repo); - git_buf_dispose(&rev_buf); - git_buf_dispose(&path_buf); + git_str_dispose(&rev_buf); + git_str_dispose(&path_buf); git_config_free(config); } diff --git a/src/merge.c b/src/merge.c index d838e4ba92c..ae1d453ec11 100644 --- a/src/merge.c +++ b/src/merge.c @@ -8,7 +8,7 @@ #include "merge.h" #include "posix.h" -#include "buffer.h" +#include "str.h" #include "repository.h" #include "revwalk.h" #include "commit_list.h" @@ -591,7 +591,7 @@ int git_repository_mergehead_foreach( git_repository_mergehead_foreach_cb cb, void *payload) { - git_buf merge_head_path = GIT_BUF_INIT, merge_head_file = GIT_BUF_INIT; + git_str merge_head_path = GIT_STR_INIT, merge_head_file = GIT_STR_INIT; char *buffer, *line; size_t line_num = 1; git_oid oid; @@ -600,12 +600,12 @@ int git_repository_mergehead_foreach( GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(cb); - if ((error = git_buf_joinpath(&merge_head_path, repo->gitdir, + if ((error = git_str_joinpath(&merge_head_path, repo->gitdir, GIT_MERGE_HEAD_FILE)) < 0) return error; if ((error = git_futils_readbuffer(&merge_head_file, - git_buf_cstr(&merge_head_path))) < 0) + git_str_cstr(&merge_head_path))) < 0) goto cleanup; buffer = merge_head_file.ptr; @@ -635,8 +635,8 @@ int git_repository_mergehead_foreach( } cleanup: - git_buf_dispose(&merge_head_path); - git_buf_dispose(&merge_head_file); + git_str_dispose(&merge_head_path); + git_str_dispose(&merge_head_file); return error; } @@ -893,7 +893,7 @@ static int merge_conflict_invoke_driver( git_merge_driver_source *src) { git_index_entry *result; - git_buf buf = GIT_BUF_INIT; + git_buf buf = {0}; const char *path; uint32_t mode; git_odb *odb = NULL; @@ -2473,14 +2473,14 @@ static int write_merge_head( size_t heads_len) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf file_path = GIT_BUF_INIT; + git_str file_path = GIT_STR_INIT; size_t i; int error = 0; GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(heads); - if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_HEAD_FILE)) < 0 || + if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_MERGE_HEAD_FILE)) < 0 || (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0) goto cleanup; @@ -2495,7 +2495,7 @@ static int write_merge_head( if (error < 0) git_filebuf_cleanup(&file); - git_buf_dispose(&file_path); + git_str_dispose(&file_path); return error; } @@ -2503,12 +2503,12 @@ static int write_merge_head( static int write_merge_mode(git_repository *repo) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf file_path = GIT_BUF_INIT; + git_str file_path = GIT_STR_INIT; int error = 0; GIT_ASSERT_ARG(repo); - if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MODE_FILE)) < 0 || + if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_MERGE_MODE_FILE)) < 0 || (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0) goto cleanup; @@ -2521,7 +2521,7 @@ static int write_merge_mode(git_repository *repo) if (error < 0) git_filebuf_cleanup(&file); - git_buf_dispose(&file_path); + git_str_dispose(&file_path); return error; } @@ -2719,7 +2719,7 @@ static int write_merge_msg( size_t heads_len) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf file_path = GIT_BUF_INIT; + git_str file_path = GIT_STR_INIT; struct merge_msg_entry *entries; git_vector matching = GIT_VECTOR_INIT; size_t i; @@ -2740,7 +2740,7 @@ static int write_merge_msg( for (i = 0; i < heads_len; i++) entries[i].merge_head = heads[i]; - if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 || + if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 || (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0 || (error = git_filebuf_write(&file, "Merge ", 6)) < 0) goto cleanup; @@ -2822,7 +2822,7 @@ static int write_merge_msg( if (error < 0) git_filebuf_cleanup(&file); - git_buf_dispose(&file_path); + git_str_dispose(&file_path); git_vector_free(&matching); git__free(entries); @@ -3114,7 +3114,7 @@ int git_merge__append_conflicts_to_merge_msg( git_index *index) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf file_path = GIT_BUF_INIT; + git_str file_path = GIT_STR_INIT; const char *last = NULL; size_t i; int error; @@ -3122,7 +3122,7 @@ int git_merge__append_conflicts_to_merge_msg( if (!git_index_has_conflicts(index)) return 0; - if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 || + if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 || (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_APPEND, GIT_MERGE_FILE_MODE)) < 0) goto cleanup; @@ -3146,7 +3146,7 @@ int git_merge__append_conflicts_to_merge_msg( if (error < 0) git_filebuf_cleanup(&file); - git_buf_dispose(&file_path); + git_str_dispose(&file_path); return error; } diff --git a/src/merge_driver.c b/src/merge_driver.c index 17c386a143c..be4d3bf8a2a 100644 --- a/src/merge_driver.c +++ b/src/merge_driver.c @@ -110,7 +110,7 @@ int git_merge_driver__builtin_apply( merged_out->ptr = (char *)result.ptr; merged_out->size = result.len; - merged_out->asize = result.len; + merged_out->reserved = 0; result.ptr = NULL; done: diff --git a/src/message.c b/src/message.c index 327b984fc7c..ec0103a339f 100644 --- a/src/message.c +++ b/src/message.c @@ -5,7 +5,9 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "message.h" +#include "buf.h" + +#include "git2/message.h" static size_t line_length_without_trailing_spaces(const char *line, size_t len) { @@ -21,17 +23,17 @@ static size_t line_length_without_trailing_spaces(const char *line, size_t len) /* Greatly inspired from git.git "stripspace" */ /* see https://github.com/git/git/blob/497215d8811ac7b8955693ceaad0899ecd894ed2/builtin/stripspace.c#L4-67 */ -int git_message_prettify(git_buf *message_out, const char *message, int strip_comments, char comment_char) +static int git_message__prettify( + git_str *message_out, + const char *message, + int strip_comments, + char comment_char) { const size_t message_len = strlen(message); int consecutive_empty_lines = 0; size_t i, line_length, rtrimmed_line_length; char *next_newline; - int error; - - if ((error = git_buf_sanitize(message_out)) < 0) - return error; for (i = 0; i < strlen(message); i += line_length) { next_newline = memchr(message + i, '\n', message_len - i); @@ -53,12 +55,21 @@ int git_message_prettify(git_buf *message_out, const char *message, int strip_co } if (consecutive_empty_lines > 0 && message_out->size > 0) - git_buf_putc(message_out, '\n'); + git_str_putc(message_out, '\n'); consecutive_empty_lines = 0; - git_buf_put(message_out, message + i, rtrimmed_line_length); - git_buf_putc(message_out, '\n'); + git_str_put(message_out, message + i, rtrimmed_line_length); + git_str_putc(message_out, '\n'); } - return git_buf_oom(message_out) ? -1 : 0; + return git_str_oom(message_out) ? -1 : 0; +} + +int git_message_prettify( + git_buf *message_out, + const char *message, + int strip_comments, + char comment_char) +{ + GIT_BUF_WRAP_PRIVATE(message_out, git_message__prettify, message, strip_comments, comment_char); } diff --git a/src/midx.c b/src/midx.c index cd3c98cef3d..b8da989866b 100644 --- a/src/midx.c +++ b/src/midx.c @@ -8,7 +8,7 @@ #include "midx.h" #include "array.h" -#include "buffer.h" +#include "buf.h" #include "filebuf.h" #include "futils.h" #include "hash.h" @@ -16,6 +16,7 @@ #include "pack.h" #include "path.h" #include "repository.h" +#include "str.h" #define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */ #define MIDX_VERSION 1 @@ -313,7 +314,7 @@ int git_midx_open( idx = git__calloc(1, sizeof(git_midx_file)); GIT_ERROR_CHECK_ALLOC(idx); - error = git_buf_sets(&idx->filename, path); + error = git_str_sets(&idx->filename, path); if (error < 0) return error; @@ -477,7 +478,7 @@ void git_midx_free(git_midx_file *idx) if (!idx) return; - git_buf_dispose(&idx->filename); + git_str_dispose(&idx->filename); git_midx_close(idx); git__free(idx); } @@ -497,14 +498,14 @@ int git_midx_writer_new( git_midx_writer *w = git__calloc(1, sizeof(git_midx_writer)); GIT_ERROR_CHECK_ALLOC(w); - if (git_buf_sets(&w->pack_dir, pack_dir) < 0) { + if (git_str_sets(&w->pack_dir, pack_dir) < 0) { git__free(w); return -1; } git_path_squash_slashes(&w->pack_dir); if (git_vector_init(&w->packs, 0, packfile__cmp) < 0) { - git_buf_dispose(&w->pack_dir); + git_str_dispose(&w->pack_dir); git__free(w); return -1; } @@ -524,7 +525,7 @@ void git_midx_writer_free(git_midx_writer *w) git_vector_foreach (&w->packs, i, p) git_mwindow_put_pack(p); git_vector_free(&w->packs); - git_buf_dispose(&w->pack_dir); + git_str_dispose(&w->pack_dir); git__free(w); } @@ -532,16 +533,16 @@ int git_midx_writer_add( git_midx_writer *w, const char *idx_path) { - git_buf idx_path_buf = GIT_BUF_INIT; + git_str idx_path_buf = GIT_STR_INIT; int error; struct git_pack_file *p; - error = git_path_prettify(&idx_path_buf, idx_path, git_buf_cstr(&w->pack_dir)); + error = git_path_prettify(&idx_path_buf, idx_path, git_str_cstr(&w->pack_dir)); if (error < 0) return error; - error = git_mwindow_get_pack(&p, git_buf_cstr(&idx_path_buf)); - git_buf_dispose(&idx_path_buf); + error = git_mwindow_get_pack(&p, git_str_cstr(&idx_path_buf)); + git_str_dispose(&idx_path_buf); if (error < 0) return error; @@ -613,8 +614,8 @@ static int write_chunk_header(int chunk_id, off64_t offset, midx_write_cb write_ static int midx_write_buf(const char *buf, size_t size, void *data) { - git_buf *b = (git_buf *)data; - return git_buf_put(b, buf, size); + git_str *b = (git_str *)data; + return git_str_put(b, buf, size); } struct midx_write_hash_context { @@ -648,10 +649,10 @@ static int midx_write( uint32_t object_large_offsets_count; uint32_t oid_fanout[256]; off64_t offset; - git_buf packfile_names = GIT_BUF_INIT, - oid_lookup = GIT_BUF_INIT, - object_offsets = GIT_BUF_INIT, - object_large_offsets = GIT_BUF_INIT; + git_str packfile_names = GIT_STR_INIT, + oid_lookup = GIT_STR_INIT, + object_offsets = GIT_STR_INIT, + object_large_offsets = GIT_STR_INIT; git_oid idx_checksum = {{0}}; git_midx_entry *entry; object_entry_array_t object_entries_array = GIT_ARRAY_INIT; @@ -676,34 +677,34 @@ static int midx_write( git_vector_sort(&w->packs); git_vector_foreach (&w->packs, i, p) { - git_buf relative_index = GIT_BUF_INIT; + git_str relative_index = GIT_STR_INIT; struct object_entry_cb_state state = {0}; size_t path_len; state.pack_index = (uint32_t)i; state.object_entries_array = &object_entries_array; - error = git_buf_sets(&relative_index, p->pack_name); + error = git_str_sets(&relative_index, p->pack_name); if (error < 0) goto cleanup; - error = git_path_make_relative(&relative_index, git_buf_cstr(&w->pack_dir)); + error = git_path_make_relative(&relative_index, git_str_cstr(&w->pack_dir)); if (error < 0) { - git_buf_dispose(&relative_index); + git_str_dispose(&relative_index); goto cleanup; } - path_len = git_buf_len(&relative_index); - if (path_len <= strlen(".pack") || git__suffixcmp(git_buf_cstr(&relative_index), ".pack") != 0) { - git_buf_dispose(&relative_index); + path_len = git_str_len(&relative_index); + if (path_len <= strlen(".pack") || git__suffixcmp(git_str_cstr(&relative_index), ".pack") != 0) { + git_str_dispose(&relative_index); git_error_set(GIT_ERROR_INVALID, "invalid packfile name: '%s'", p->pack_name); error = -1; goto cleanup; } path_len -= strlen(".pack"); - git_buf_put(&packfile_names, git_buf_cstr(&relative_index), path_len); - git_buf_puts(&packfile_names, ".idx"); - git_buf_putc(&packfile_names, '\0'); - git_buf_dispose(&relative_index); + git_str_put(&packfile_names, git_str_cstr(&relative_index), path_len); + git_str_puts(&packfile_names, ".idx"); + git_str_putc(&packfile_names, '\0'); + git_str_dispose(&relative_index); error = git_pack_foreach_entry_offset(p, object_entry__cb, &state); if (error < 0) @@ -723,8 +724,8 @@ static int midx_write( git_vector_uniq(&object_entries, NULL); /* Pad the packfile names so it is a multiple of four. */ - while (git_buf_len(&packfile_names) & 3) - git_buf_putc(&packfile_names, '\0'); + while (git_str_len(&packfile_names) & 3) + git_str_putc(&packfile_names, '\0'); /* Fill the OID Fanout table. */ oid_fanout_count = 0; @@ -737,7 +738,7 @@ static int midx_write( /* Fill the OID Lookup table. */ git_vector_foreach (&object_entries, i, entry) { - error = git_buf_put(&oid_lookup, (const char *)&entry->sha1, sizeof(entry->sha1)); + error = git_str_put(&oid_lookup, (const char *)&entry->sha1, sizeof(entry->sha1)); if (error < 0) goto cleanup; } @@ -748,7 +749,7 @@ static int midx_write( uint32_t word; word = htonl((uint32_t)entry->pack_index); - error = git_buf_put(&object_offsets, (const char *)&word, sizeof(word)); + error = git_str_put(&object_offsets, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; if (entry->offset >= 0x80000000l) { @@ -759,7 +760,7 @@ static int midx_write( word = htonl((uint32_t)entry->offset & 0x7fffffffu); } - error = git_buf_put(&object_offsets, (const char *)&word, sizeof(word)); + error = git_str_put(&object_offsets, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; } @@ -767,7 +768,7 @@ static int midx_write( /* Write the header. */ hdr.packfiles = htonl((uint32_t)git_vector_length(&w->packs)); hdr.chunks = 4; - if (git_buf_len(&object_large_offsets) > 0) + if (git_str_len(&object_large_offsets) > 0) hdr.chunks++; error = write_cb((const char *)&hdr, sizeof(hdr), cb_data); if (error < 0) @@ -778,7 +779,7 @@ static int midx_write( error = write_chunk_header(MIDX_PACKFILE_NAMES_ID, offset, write_cb, cb_data); if (error < 0) goto cleanup; - offset += git_buf_len(&packfile_names); + offset += git_str_len(&packfile_names); error = write_chunk_header(MIDX_OID_FANOUT_ID, offset, write_cb, cb_data); if (error < 0) goto cleanup; @@ -786,35 +787,35 @@ static int midx_write( error = write_chunk_header(MIDX_OID_LOOKUP_ID, offset, write_cb, cb_data); if (error < 0) goto cleanup; - offset += git_buf_len(&oid_lookup); + offset += git_str_len(&oid_lookup); error = write_chunk_header(MIDX_OBJECT_OFFSETS_ID, offset, write_cb, cb_data); if (error < 0) goto cleanup; - offset += git_buf_len(&object_offsets); - if (git_buf_len(&object_large_offsets) > 0) { + offset += git_str_len(&object_offsets); + if (git_str_len(&object_large_offsets) > 0) { error = write_chunk_header(MIDX_OBJECT_LARGE_OFFSETS_ID, offset, write_cb, cb_data); if (error < 0) goto cleanup; - offset += git_buf_len(&object_large_offsets); + offset += git_str_len(&object_large_offsets); } error = write_chunk_header(0, offset, write_cb, cb_data); if (error < 0) goto cleanup; /* Write all the chunks. */ - error = write_cb(git_buf_cstr(&packfile_names), git_buf_len(&packfile_names), cb_data); + error = write_cb(git_str_cstr(&packfile_names), git_str_len(&packfile_names), cb_data); if (error < 0) goto cleanup; error = write_cb((const char *)oid_fanout, sizeof(oid_fanout), cb_data); if (error < 0) goto cleanup; - error = write_cb(git_buf_cstr(&oid_lookup), git_buf_len(&oid_lookup), cb_data); + error = write_cb(git_str_cstr(&oid_lookup), git_str_len(&oid_lookup), cb_data); if (error < 0) goto cleanup; - error = write_cb(git_buf_cstr(&object_offsets), git_buf_len(&object_offsets), cb_data); + error = write_cb(git_str_cstr(&object_offsets), git_str_len(&object_offsets), cb_data); if (error < 0) goto cleanup; - error = write_cb(git_buf_cstr(&object_large_offsets), git_buf_len(&object_large_offsets), cb_data); + error = write_cb(git_str_cstr(&object_large_offsets), git_str_len(&object_large_offsets), cb_data); if (error < 0) goto cleanup; @@ -829,10 +830,10 @@ static int midx_write( cleanup: git_array_clear(object_entries_array); git_vector_free(&object_entries); - git_buf_dispose(&packfile_names); - git_buf_dispose(&oid_lookup); - git_buf_dispose(&object_offsets); - git_buf_dispose(&object_large_offsets); + git_str_dispose(&packfile_names); + git_str_dispose(&oid_lookup); + git_str_dispose(&object_offsets); + git_str_dispose(&object_large_offsets); git_hash_ctx_cleanup(&ctx); return error; } @@ -848,17 +849,17 @@ int git_midx_writer_commit( { int error; int filebuf_flags = GIT_FILEBUF_DO_NOT_BUFFER; - git_buf midx_path = GIT_BUF_INIT; + git_str midx_path = GIT_STR_INIT; git_filebuf output = GIT_FILEBUF_INIT; - error = git_buf_joinpath(&midx_path, git_buf_cstr(&w->pack_dir), "multi-pack-index"); + error = git_str_joinpath(&midx_path, git_str_cstr(&w->pack_dir), "multi-pack-index"); if (error < 0) return error; if (git_repository__fsync_gitdir) filebuf_flags |= GIT_FILEBUF_FSYNC; - error = git_filebuf_open(&output, git_buf_cstr(&midx_path), filebuf_flags, 0644); - git_buf_dispose(&midx_path); + error = git_filebuf_open(&output, git_str_cstr(&midx_path), filebuf_flags, 0644); + git_str_dispose(&midx_path); if (error < 0) return error; @@ -875,5 +876,13 @@ int git_midx_writer_dump( git_buf *midx, git_midx_writer *w) { - return midx_write(w, midx_write_buf, midx); + git_str str = GIT_STR_INIT; + int error; + + if ((error = git_buf_tostr(&str, midx)) < 0 || + (error = midx_write(w, midx_write_buf, &str)) == 0) + error = git_buf_fromstr(midx, &str); + + git_str_dispose(&str); + return error; } diff --git a/src/midx.h b/src/midx.h index 4ce17ce73a8..ef3d534bc99 100644 --- a/src/midx.h +++ b/src/midx.h @@ -54,7 +54,7 @@ typedef struct git_midx_file { git_oid checksum; /* something like ".git/objects/pack/multi-pack-index". */ - git_buf filename; + git_str filename; } git_midx_file; /* @@ -77,7 +77,7 @@ struct git_midx_writer { * The path of the directory where the .pack/.idx files are stored. The * `multi-pack-index` file will be written to the same directory. */ - git_buf pack_dir; + git_str pack_dir; /* The list of `git_pack_file`s. */ git_vector packs; diff --git a/src/net.c b/src/net.c index 361e40e7b05..58792ee7df2 100644 --- a/src/net.c +++ b/src/net.c @@ -12,7 +12,7 @@ #include "git2/errors.h" #include "posix.h" -#include "buffer.h" +#include "str.h" #include "http_parser.h" #include "runtime.h" @@ -79,13 +79,13 @@ int git_net_url_parse(git_net_url *url, const char *given) { struct http_parser_url u = {0}; bool has_scheme, has_host, has_port, has_path, has_query, has_userinfo; - git_buf scheme = GIT_BUF_INIT, - host = GIT_BUF_INIT, - port = GIT_BUF_INIT, - path = GIT_BUF_INIT, - username = GIT_BUF_INIT, - password = GIT_BUF_INIT, - query = GIT_BUF_INIT; + git_str scheme = GIT_STR_INIT, + host = GIT_STR_INIT, + port = GIT_STR_INIT, + path = GIT_STR_INIT, + username = GIT_STR_INIT, + password = GIT_STR_INIT, + query = GIT_STR_INIT; int error = GIT_EINVALIDSPEC; if (http_parser_parse_url(given, strlen(given), false, &u)) { @@ -103,7 +103,7 @@ int git_net_url_parse(git_net_url *url, const char *given) if (has_scheme) { const char *url_scheme = given + u.field_data[UF_SCHEMA].off; size_t url_scheme_len = u.field_data[UF_SCHEMA].len; - git_buf_put(&scheme, url_scheme, url_scheme_len); + git_str_put(&scheme, url_scheme, url_scheme_len); git__strntolower(scheme.ptr, scheme.size); } else { git_error_set(GIT_ERROR_NET, "malformed URL '%s'", given); @@ -113,13 +113,13 @@ int git_net_url_parse(git_net_url *url, const char *given) if (has_host) { const char *url_host = given + u.field_data[UF_HOST].off; size_t url_host_len = u.field_data[UF_HOST].len; - git_buf_decode_percent(&host, url_host, url_host_len); + git_str_decode_percent(&host, url_host, url_host_len); } if (has_port) { const char *url_port = given + u.field_data[UF_PORT].off; size_t url_port_len = u.field_data[UF_PORT].len; - git_buf_put(&port, url_port, url_port_len); + git_str_put(&port, url_port, url_port_len); } else { const char *default_port = default_port_for_scheme(scheme.ptr); @@ -128,21 +128,21 @@ int git_net_url_parse(git_net_url *url, const char *given) goto done; } - git_buf_puts(&port, default_port); + git_str_puts(&port, default_port); } if (has_path) { const char *url_path = given + u.field_data[UF_PATH].off; size_t url_path_len = u.field_data[UF_PATH].len; - git_buf_put(&path, url_path, url_path_len); + git_str_put(&path, url_path, url_path_len); } else { - git_buf_puts(&path, "/"); + git_str_puts(&path, "/"); } if (has_query) { const char *url_query = given + u.field_data[UF_QUERY].off; size_t url_query_len = u.field_data[UF_QUERY].len; - git_buf_decode_percent(&query, url_query, url_query_len); + git_str_decode_percent(&query, url_query, url_query_len); } if (has_userinfo) { @@ -156,40 +156,40 @@ int git_net_url_parse(git_net_url *url, const char *given) const char *url_password = colon + 1; size_t url_password_len = url_userinfo_len - (url_username_len + 1); - git_buf_decode_percent(&username, url_username, url_username_len); - git_buf_decode_percent(&password, url_password, url_password_len); + git_str_decode_percent(&username, url_username, url_username_len); + git_str_decode_percent(&password, url_password, url_password_len); } else { - git_buf_decode_percent(&username, url_userinfo, url_userinfo_len); + git_str_decode_percent(&username, url_userinfo, url_userinfo_len); } } - if (git_buf_oom(&scheme) || - git_buf_oom(&host) || - git_buf_oom(&port) || - git_buf_oom(&path) || - git_buf_oom(&query) || - git_buf_oom(&username) || - git_buf_oom(&password)) + if (git_str_oom(&scheme) || + git_str_oom(&host) || + git_str_oom(&port) || + git_str_oom(&path) || + git_str_oom(&query) || + git_str_oom(&username) || + git_str_oom(&password)) return -1; - url->scheme = git_buf_detach(&scheme); - url->host = git_buf_detach(&host); - url->port = git_buf_detach(&port); - url->path = git_buf_detach(&path); - url->query = git_buf_detach(&query); - url->username = git_buf_detach(&username); - url->password = git_buf_detach(&password); + url->scheme = git_str_detach(&scheme); + url->host = git_str_detach(&host); + url->port = git_str_detach(&port); + url->path = git_str_detach(&path); + url->query = git_str_detach(&query); + url->username = git_str_detach(&username); + url->password = git_str_detach(&password); error = 0; done: - git_buf_dispose(&scheme); - git_buf_dispose(&host); - git_buf_dispose(&port); - git_buf_dispose(&path); - git_buf_dispose(&query); - git_buf_dispose(&username); - git_buf_dispose(&password); + git_str_dispose(&scheme); + git_str_dispose(&host); + git_str_dispose(&port); + git_str_dispose(&path); + git_str_dispose(&query); + git_str_dispose(&username); + git_str_dispose(&password); return error; } @@ -198,7 +198,7 @@ int git_net_url_joinpath( git_net_url *one, const char *two) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; const char *query; size_t one_len, two_len; @@ -226,14 +226,14 @@ int git_net_url_joinpath( two_len--; } - git_buf_put(&path, one->path, one_len); - git_buf_putc(&path, '/'); - git_buf_put(&path, two, two_len); + git_str_put(&path, one->path, one_len); + git_str_putc(&path, '/'); + git_str_put(&path, two, two_len); - if (git_buf_oom(&path)) + if (git_str_oom(&path)) return -1; - out->path = git_buf_detach(&path); + out->path = git_str_detach(&path); if (one->scheme) { out->scheme = git__strdup(one->scheme); @@ -399,53 +399,53 @@ void git_net_url_swap(git_net_url *a, git_net_url *b) memcpy(b, &tmp, sizeof(git_net_url)); } -int git_net_url_fmt(git_buf *buf, git_net_url *url) +int git_net_url_fmt(git_str *buf, git_net_url *url) { GIT_ASSERT_ARG(url); GIT_ASSERT_ARG(url->scheme); GIT_ASSERT_ARG(url->host); - git_buf_puts(buf, url->scheme); - git_buf_puts(buf, "://"); + git_str_puts(buf, url->scheme); + git_str_puts(buf, "://"); if (url->username) { - git_buf_puts(buf, url->username); + git_str_puts(buf, url->username); if (url->password) { - git_buf_puts(buf, ":"); - git_buf_puts(buf, url->password); + git_str_puts(buf, ":"); + git_str_puts(buf, url->password); } - git_buf_putc(buf, '@'); + git_str_putc(buf, '@'); } - git_buf_puts(buf, url->host); + git_str_puts(buf, url->host); if (url->port && !git_net_url_is_default_port(url)) { - git_buf_putc(buf, ':'); - git_buf_puts(buf, url->port); + git_str_putc(buf, ':'); + git_str_puts(buf, url->port); } - git_buf_puts(buf, url->path ? url->path : "/"); + git_str_puts(buf, url->path ? url->path : "/"); if (url->query) { - git_buf_putc(buf, '?'); - git_buf_puts(buf, url->query); + git_str_putc(buf, '?'); + git_str_puts(buf, url->query); } - return git_buf_oom(buf) ? -1 : 0; + return git_str_oom(buf) ? -1 : 0; } -int git_net_url_fmt_path(git_buf *buf, git_net_url *url) +int git_net_url_fmt_path(git_str *buf, git_net_url *url) { - git_buf_puts(buf, url->path ? url->path : "/"); + git_str_puts(buf, url->path ? url->path : "/"); if (url->query) { - git_buf_putc(buf, '?'); - git_buf_puts(buf, url->query); + git_str_putc(buf, '?'); + git_str_puts(buf, url->query); } - return git_buf_oom(buf) ? -1 : 0; + return git_str_oom(buf) ? -1 : 0; } static bool matches_pattern( diff --git a/src/net.h b/src/net.h index 322d0bda908..728add3d0ed 100644 --- a/src/net.h +++ b/src/net.h @@ -52,10 +52,10 @@ extern int git_net_url_apply_redirect( extern void git_net_url_swap(git_net_url *a, git_net_url *b); /** Places the URL into the given buffer. */ -extern int git_net_url_fmt(git_buf *out, git_net_url *url); +extern int git_net_url_fmt(git_str *out, git_net_url *url); /** Place the path and query string into the given buffer. */ -extern int git_net_url_fmt_path(git_buf *buf, git_net_url *url); +extern int git_net_url_fmt_path(git_str *buf, git_net_url *url); /** Determines if the url matches given pattern or pattern list */ extern bool git_net_url_matches_pattern( diff --git a/src/netops.c b/src/netops.c index a1ee2927cd9..0a27365b8ae 100644 --- a/src/netops.c +++ b/src/netops.c @@ -11,7 +11,7 @@ #include "git2/errors.h" #include "posix.h" -#include "buffer.h" +#include "str.h" #include "http_parser.h" #include "runtime.h" diff --git a/src/notes.c b/src/notes.c index 95db334fb83..d1a2b0f6429 100644 --- a/src/notes.c +++ b/src/notes.c @@ -7,7 +7,7 @@ #include "notes.h" -#include "git2.h" +#include "buf.h" #include "refs.h" #include "config.h" #include "iterator.h" @@ -407,7 +407,7 @@ static int note_remove( return error; } -static int note_get_default_ref(git_buf *out, git_repository *repo) +static int note_get_default_ref(git_str *out, git_repository *repo) { git_config *cfg; int error; @@ -415,25 +415,25 @@ static int note_get_default_ref(git_buf *out, git_repository *repo) if ((error = git_repository_config__weakptr(&cfg, repo)) < 0) return error; - error = git_config_get_string_buf(out, cfg, "core.notesref"); + error = git_config__get_string_buf(out, cfg, "core.notesref"); if (error == GIT_ENOTFOUND) - error = git_buf_puts(out, GIT_NOTES_DEFAULT_REF); + error = git_str_puts(out, GIT_NOTES_DEFAULT_REF); return error; } -static int normalize_namespace(git_buf *out, git_repository *repo, const char *notes_ref) +static int normalize_namespace(git_str *out, git_repository *repo, const char *notes_ref) { if (notes_ref) - return git_buf_puts(out, notes_ref); + return git_str_puts(out, notes_ref); return note_get_default_ref(out, repo); } static int retrieve_note_commit( git_commit **commit_out, - git_buf *notes_ref_out, + git_str *notes_ref_out, git_repository *repo, const char *notes_ref) { @@ -478,7 +478,7 @@ int git_note_read(git_note **out, git_repository *repo, const char *notes_ref_in, const git_oid *oid) { int error; - git_buf notes_ref = GIT_BUF_INIT; + git_str notes_ref = GIT_STR_INIT; git_commit *commit = NULL; error = retrieve_note_commit(&commit, ¬es_ref, repo, notes_ref_in); @@ -489,7 +489,7 @@ int git_note_read(git_note **out, git_repository *repo, error = git_note_commit_read(out, repo, commit, oid); cleanup: - git_buf_dispose(¬es_ref); + git_str_dispose(¬es_ref); git_commit_free(commit); return error; } @@ -536,7 +536,7 @@ int git_note_create( int allow_note_overwrite) { int error; - git_buf notes_ref = GIT_BUF_INIT; + git_str notes_ref = GIT_STR_INIT; git_commit *existing_notes_commit = NULL; git_reference *ref = NULL; git_oid notes_blob_oid, notes_commit_oid; @@ -562,7 +562,7 @@ int git_note_create( git_oid_cpy(out, ¬es_blob_oid); cleanup: - git_buf_dispose(¬es_ref); + git_str_dispose(¬es_ref); git_commit_free(existing_notes_commit); git_reference_free(ref); return error; @@ -598,7 +598,7 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in, const git_oid *oid) { int error; - git_buf notes_ref_target = GIT_BUF_INIT; + git_str notes_ref_target = GIT_STR_INIT; git_commit *existing_notes_commit = NULL; git_oid new_notes_commit; git_reference *notes_ref = NULL; @@ -618,7 +618,7 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in, &new_notes_commit, 1, NULL); cleanup: - git_buf_dispose(¬es_ref_target); + git_str_dispose(¬es_ref_target); git_reference_free(notes_ref); git_commit_free(existing_notes_commit); return error; @@ -626,16 +626,7 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in, int git_note_default_ref(git_buf *out, git_repository *repo) { - int error; - - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(repo); - - if ((error = git_buf_sanitize(out)) < 0 || - (error = note_get_default_ref(out, repo)) < 0) - git_buf_dispose(out); - - return error; + GIT_BUF_WRAP_PRIVATE(out, note_get_default_ref, repo); } const git_signature *git_note_committer(const git_note *note) @@ -679,12 +670,12 @@ static int process_entry_path( { int error = 0; size_t i = 0, j = 0, len; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - if ((error = git_buf_puts(&buf, entry_path)) < 0) + if ((error = git_str_puts(&buf, entry_path)) < 0) goto cleanup; - len = git_buf_len(&buf); + len = git_str_len(&buf); while (i < len) { if (buf.ptr[i] == '/') { @@ -715,7 +706,7 @@ static int process_entry_path( error = git_oid_fromstr(annotated_object_id, buf.ptr); cleanup: - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -780,7 +771,7 @@ int git_note_iterator_new( { int error; git_commit *commit = NULL; - git_buf notes_ref = GIT_BUF_INIT; + git_str notes_ref = GIT_STR_INIT; error = retrieve_note_commit(&commit, ¬es_ref, repo, notes_ref_in); if (error < 0) @@ -789,7 +780,7 @@ int git_note_iterator_new( error = git_note_commit_iterator_new(it, commit); cleanup: - git_buf_dispose(¬es_ref); + git_str_dispose(¬es_ref); git_commit_free(commit); return error; diff --git a/src/object.c b/src/object.c index 42e1e46bcc5..fb861e9e130 100644 --- a/src/object.c +++ b/src/object.c @@ -11,6 +11,7 @@ #include "repository.h" +#include "buf.h" #include "commit.h" #include "hash.h" #include "tree.h" @@ -491,7 +492,7 @@ int git_object_lookup_bypath( return error; } -int git_object_short_id(git_buf *out, const git_object *obj) +static int git_object__short_id(git_str *out, const git_object *obj) { git_repository *repo; int len = GIT_ABBREV_DEFAULT, error; @@ -501,9 +502,6 @@ int git_object_short_id(git_buf *out, const git_object *obj) GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(obj); - if ((error = git_buf_sanitize(out)) < 0) - return error; - repo = git_object_owner(obj); if ((error = git_repository__configmap_lookup(&len, repo, GIT_CONFIGMAP_ABBREV)) < 0) @@ -526,7 +524,7 @@ int git_object_short_id(git_buf *out, const git_object *obj) len++; } - if (!error && !(error = git_buf_grow(out, len + 1))) { + if (!error && !(error = git_str_grow(out, len + 1))) { git_oid_tostr(out->ptr, len + 1, &id); out->size = len; } @@ -536,6 +534,11 @@ int git_object_short_id(git_buf *out, const git_object *obj) return error; } +int git_object_short_id(git_buf *out, const git_object *obj) +{ + GIT_BUF_WRAP_PRIVATE(out, git_object__short_id, obj); +} + bool git_object__is_valid( git_repository *repo, const git_oid *id, git_object_t expected_type) { diff --git a/src/object.h b/src/object.h index 4b67936127e..66be57557e7 100644 --- a/src/object.h +++ b/src/object.h @@ -47,7 +47,7 @@ git_object_t git_object_stringn2type(const char *str, size_t len); int git_oid__parse(git_oid *oid, const char **buffer_out, const char *buffer_end, const char *header); -void git_oid__writebuf(git_buf *buf, const char *header, const git_oid *oid); +void git_oid__writebuf(git_str *buf, const char *header, const git_oid *oid); bool git_object__is_valid( git_repository *repo, const git_oid *id, git_object_t expected_type); diff --git a/src/odb.c b/src/odb.c index baa28734849..7bf57547405 100644 --- a/src/odb.c +++ b/src/odb.c @@ -109,7 +109,7 @@ int git_odb__format_object_header( int git_odb__hashobj(git_oid *id, git_rawobj *obj) { - git_buf_vec vec[2]; + git_str_vec vec[2]; char header[64]; size_t hdrlen; int error; @@ -248,7 +248,7 @@ int git_odb__hashfd_filtered( git_oid *out, git_file fd, size_t size, git_object_t type, git_filter_list *fl) { int error; - git_buf raw = GIT_BUF_INIT; + git_str raw = GIT_STR_INIT; if (!fl) return git_odb__hashfd(out, fd, size, type); @@ -258,14 +258,14 @@ int git_odb__hashfd_filtered( */ if (!(error = git_futils_readbuffer_fd(&raw, fd, size))) { - git_buf post = GIT_BUF_INIT; + git_str post = GIT_STR_INIT; error = git_filter_list__convert_buf(&post, fl, &raw); if (!error) error = git_odb_hash(out, post.ptr, post.size, type); - git_buf_dispose(&post); + git_str_dispose(&post); } return error; @@ -636,8 +636,8 @@ int git_odb__add_default_backends( static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth) { - git_buf alternates_path = GIT_BUF_INIT; - git_buf alternates_buf = GIT_BUF_INIT; + git_str alternates_path = GIT_STR_INIT; + git_str alternates_buf = GIT_STR_INIT; char *buffer; const char *alternate; int result = 0; @@ -646,16 +646,16 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_ if (alternate_depth > GIT_ALTERNATES_MAX_DEPTH) return 0; - if (git_buf_joinpath(&alternates_path, objects_dir, GIT_ALTERNATES_FILE) < 0) + if (git_str_joinpath(&alternates_path, objects_dir, GIT_ALTERNATES_FILE) < 0) return -1; if (git_path_exists(alternates_path.ptr) == false) { - git_buf_dispose(&alternates_path); + git_str_dispose(&alternates_path); return 0; } if (git_futils_readbuffer(&alternates_buf, alternates_path.ptr) < 0) { - git_buf_dispose(&alternates_path); + git_str_dispose(&alternates_path); return -1; } @@ -672,17 +672,17 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_ * the current repository. */ if (*alternate == '.' && !alternate_depth) { - if ((result = git_buf_joinpath(&alternates_path, objects_dir, alternate)) < 0) + if ((result = git_str_joinpath(&alternates_path, objects_dir, alternate)) < 0) break; - alternate = git_buf_cstr(&alternates_path); + alternate = git_str_cstr(&alternates_path); } if ((result = git_odb__add_default_backends(odb, alternate, true, alternate_depth + 1)) < 0) break; } - git_buf_dispose(&alternates_path); - git_buf_dispose(&alternates_buf); + git_str_dispose(&alternates_path); + git_str_dispose(&alternates_buf); return result; } @@ -1337,15 +1337,15 @@ static int read_prefix_1(git_odb_object **out, git_odb *db, data = raw.data; if (found && git_oid__cmp(&full_oid, &found_full_oid)) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - git_buf_printf(&buf, "multiple matches for prefix: %s", + git_str_printf(&buf, "multiple matches for prefix: %s", git_oid_tostr_s(&full_oid)); - git_buf_printf(&buf, " %s", + git_str_printf(&buf, " %s", git_oid_tostr_s(&found_full_oid)); error = git_odb__error_ambiguous(buf.ptr); - git_buf_dispose(&buf); + git_str_dispose(&buf); git_mutex_unlock(&db->lock); goto out; } diff --git a/src/odb_loose.c b/src/odb_loose.c index 1f8a0bb21b9..f0c3ac2c81c 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -76,17 +76,17 @@ typedef struct { ***********************************************************/ static int object_file_name( - git_buf *name, const loose_backend *be, const git_oid *id) + git_str *name, const loose_backend *be, const git_oid *id) { size_t alloclen; /* expand length for object root + 40 hex sha1 chars + 2 * '/' + '\0' */ GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, be->objects_dirlen, GIT_OID_HEXSZ); GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, alloclen, 3); - if (git_buf_grow(name, alloclen) < 0) + if (git_str_grow(name, alloclen) < 0) return -1; - git_buf_set(name, be->objects_dir, be->objects_dirlen); + git_str_set(name, be->objects_dir, be->objects_dirlen); git_path_to_dir(name); /* loose object filename: aa/aaa... (41 bytes) */ @@ -97,7 +97,7 @@ static int object_file_name( return 0; } -static int object_mkdir(const git_buf *name, const loose_backend *be) +static int object_mkdir(const git_str *name, const loose_backend *be) { return git_futils_mkdir_relative( name->ptr + be->objects_dirlen, be->objects_dir, be->object_dir_mode, @@ -222,9 +222,9 @@ static int is_zlib_compressed_data(unsigned char *data, size_t data_len) * of loose object data into packs. This format is no longer used, but * we must still read it. */ -static int read_loose_packlike(git_rawobj *out, git_buf *obj) +static int read_loose_packlike(git_rawobj *out, git_str *obj) { - git_buf body = GIT_BUF_INIT; + git_str body = GIT_STR_INIT; const unsigned char *obj_data; obj_hdr hdr; size_t obj_len, head_len, alloc_size; @@ -253,7 +253,7 @@ static int read_loose_packlike(git_rawobj *out, git_buf *obj) * allocate a buffer and inflate the data into it */ if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, hdr.size, 1) || - git_buf_init(&body, alloc_size) < 0) { + git_str_init(&body, alloc_size) < 0) { error = -1; goto done; } @@ -263,14 +263,14 @@ static int read_loose_packlike(git_rawobj *out, git_buf *obj) out->len = hdr.size; out->type = hdr.type; - out->data = git_buf_detach(&body); + out->data = git_str_detach(&body); done: - git_buf_dispose(&body); + git_str_dispose(&body); return error; } -static int read_loose_standard(git_rawobj *out, git_buf *obj) +static int read_loose_standard(git_rawobj *out, git_str *obj) { git_zstream zstream = GIT_ZSTREAM_INIT; unsigned char head[MAX_HEADER_LEN], *body = NULL; @@ -279,7 +279,7 @@ static int read_loose_standard(git_rawobj *out, git_buf *obj) int error; if ((error = git_zstream_init(&zstream, GIT_ZSTREAM_INFLATE)) < 0 || - (error = git_zstream_set_input(&zstream, git_buf_cstr(obj), git_buf_len(obj))) < 0) + (error = git_zstream_set_input(&zstream, git_str_cstr(obj), git_str_len(obj))) < 0) goto done; decompressed = sizeof(head); @@ -339,15 +339,15 @@ static int read_loose_standard(git_rawobj *out, git_buf *obj) return error; } -static int read_loose(git_rawobj *out, git_buf *loc) +static int read_loose(git_rawobj *out, git_str *loc) { int error; - git_buf obj = GIT_BUF_INIT; + git_str obj = GIT_STR_INIT; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(loc); - if (git_buf_oom(loc)) + if (git_str_oom(loc)) return -1; out->data = NULL; @@ -363,7 +363,7 @@ static int read_loose(git_rawobj *out, git_buf *loc) error = read_loose_standard(out, &obj); done: - git_buf_dispose(&obj); + git_str_dispose(&obj); return error; } @@ -406,7 +406,7 @@ static int read_header_loose_standard( return error; } -static int read_header_loose(git_rawobj *out, git_buf *loc) +static int read_header_loose(git_rawobj *out, git_str *loc) { unsigned char obj[1024]; ssize_t obj_len; @@ -415,7 +415,7 @@ static int read_header_loose(git_rawobj *out, git_buf *loc) GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(loc); - if (git_buf_oom(loc)) + if (git_str_oom(loc)) return -1; out->data = NULL; @@ -446,7 +446,7 @@ static int read_header_loose(git_rawobj *out, git_buf *loc) } static int locate_object( - git_buf *object_location, + git_str *object_location, loose_backend *backend, const git_oid *oid) { @@ -459,10 +459,10 @@ static int locate_object( } /* Explore an entry of a directory and see if it matches a short oid */ -static int fn_locate_object_short_oid(void *state, git_buf *pathbuf) { +static int fn_locate_object_short_oid(void *state, git_str *pathbuf) { loose_locate_object_state *sstate = (loose_locate_object_state *)state; - if (git_buf_len(pathbuf) - sstate->dir_len != GIT_OID_HEXSZ - 2) { + if (git_str_len(pathbuf) - sstate->dir_len != GIT_OID_HEXSZ - 2) { /* Entry cannot be an object. Continue to next entry */ return 0; } @@ -491,7 +491,7 @@ static int fn_locate_object_short_oid(void *state, git_buf *pathbuf) { /* Locate an object matching a given short oid */ static int locate_object_short_oid( - git_buf *object_location, + git_str *object_location, git_oid *res_oid, loose_backend *backend, const git_oid *short_oid, @@ -505,20 +505,20 @@ static int locate_object_short_oid( /* prealloc memory for OBJ_DIR/xx/xx..38x..xx */ GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ); GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 3); - if (git_buf_grow(object_location, alloc_len) < 0) + if (git_str_grow(object_location, alloc_len) < 0) return -1; - git_buf_set(object_location, objects_dir, dir_len); + git_str_set(object_location, objects_dir, dir_len); git_path_to_dir(object_location); /* save adjusted position at end of dir so it can be restored later */ - dir_len = git_buf_len(object_location); + dir_len = git_str_len(object_location); /* Convert raw oid to hex formatted oid */ git_oid_fmt((char *)state.short_oid, short_oid); /* Explore OBJ_DIR/xx/ where xx is the beginning of hex formatted short oid */ - if (git_buf_put(object_location, (char *)state.short_oid, 3) < 0) + if (git_str_put(object_location, (char *)state.short_oid, 3) < 0) return -1; object_location->ptr[object_location->size - 1] = '/'; @@ -527,7 +527,7 @@ static int locate_object_short_oid( return git_odb__error_notfound("no matching loose object for prefix", short_oid, len); - state.dir_len = git_buf_len(object_location); + state.dir_len = git_str_len(object_location); state.short_oid_len = len; state.found = 0; @@ -553,8 +553,8 @@ static int locate_object_short_oid( GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ); GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2); - git_buf_truncate(object_location, dir_len); - if (git_buf_grow(object_location, alloc_len) < 0) + git_str_truncate(object_location, dir_len); + if (git_str_grow(object_location, alloc_len) < 0) return -1; git_oid_pathfmt(object_location->ptr + dir_len, res_oid); @@ -583,7 +583,7 @@ static int locate_object_short_oid( static int loose_backend__read_header(size_t *len_p, git_object_t *type_p, git_odb_backend *backend, const git_oid *oid) { - git_buf object_path = GIT_BUF_INIT; + git_str object_path = GIT_STR_INIT; git_rawobj raw; int error; @@ -601,14 +601,14 @@ static int loose_backend__read_header(size_t *len_p, git_object_t *type_p, git_o *type_p = raw.type; } - git_buf_dispose(&object_path); + git_str_dispose(&object_path); return error; } static int loose_backend__read(void **buffer_p, size_t *len_p, git_object_t *type_p, git_odb_backend *backend, const git_oid *oid) { - git_buf object_path = GIT_BUF_INIT; + git_str object_path = GIT_STR_INIT; git_rawobj raw; int error = 0; @@ -624,7 +624,7 @@ static int loose_backend__read(void **buffer_p, size_t *len_p, git_object_t *typ *type_p = raw.type; } - git_buf_dispose(&object_path); + git_str_dispose(&object_path); return error; } @@ -648,7 +648,7 @@ static int loose_backend__read_prefix( if (!error) git_oid_cpy(out_oid, short_oid); } else { - git_buf object_path = GIT_BUF_INIT; + git_str object_path = GIT_STR_INIT; git_rawobj raw; GIT_ASSERT_ARG(backend && short_oid); @@ -662,7 +662,7 @@ static int loose_backend__read_prefix( *type_p = raw.type; } - git_buf_dispose(&object_path); + git_str_dispose(&object_path); } return error; @@ -670,7 +670,7 @@ static int loose_backend__read_prefix( static int loose_backend__exists(git_odb_backend *backend, const git_oid *oid) { - git_buf object_path = GIT_BUF_INIT; + git_str object_path = GIT_STR_INIT; int error; GIT_ASSERT_ARG(backend); @@ -678,7 +678,7 @@ static int loose_backend__exists(git_odb_backend *backend, const git_oid *oid) error = locate_object(&object_path, (loose_backend *)backend, oid); - git_buf_dispose(&object_path); + git_str_dispose(&object_path); return !error; } @@ -686,7 +686,7 @@ static int loose_backend__exists(git_odb_backend *backend, const git_oid *oid) static int loose_backend__exists_prefix( git_oid *out, git_odb_backend *backend, const git_oid *short_id, size_t len) { - git_buf object_path = GIT_BUF_INIT; + git_str object_path = GIT_STR_INIT; int error; GIT_ASSERT_ARG(backend); @@ -697,7 +697,7 @@ static int loose_backend__exists_prefix( error = locate_object_short_oid( &object_path, out, (loose_backend *)backend, short_id, len); - git_buf_dispose(&object_path); + git_str_dispose(&object_path); return error; } @@ -736,7 +736,7 @@ GIT_INLINE(int) filename_to_oid(git_oid *oid, const char *ptr) return 0; } -static int foreach_object_dir_cb(void *_state, git_buf *path) +static int foreach_object_dir_cb(void *_state, git_str *path) { git_oid oid; struct foreach_state *state = (struct foreach_state *) _state; @@ -748,12 +748,12 @@ static int foreach_object_dir_cb(void *_state, git_buf *path) state->cb(&oid, state->data), "git_odb_foreach"); } -static int foreach_cb(void *_state, git_buf *path) +static int foreach_cb(void *_state, git_str *path) { struct foreach_state *state = (struct foreach_state *) _state; /* non-dir is some stray file, ignore it */ - if (!git_path_isdir(git_buf_cstr(path))) + if (!git_path_isdir(git_str_cstr(path))) return 0; return git_path_direach(path, 0, foreach_object_dir_cb, state); @@ -763,7 +763,7 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb { char *objects_dir; int error; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; struct foreach_state state; loose_backend *backend = (loose_backend *) _backend; @@ -772,19 +772,19 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb objects_dir = backend->objects_dir; - git_buf_sets(&buf, objects_dir); + git_str_sets(&buf, objects_dir); git_path_to_dir(&buf); - if (git_buf_oom(&buf)) + if (git_str_oom(&buf)) return -1; memset(&state, 0, sizeof(state)); state.cb = cb; state.data = data; - state.dir_len = git_buf_len(&buf); + state.dir_len = git_str_len(&buf); error = git_path_direach(&buf, 0, foreach_cb, &state); - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -793,7 +793,7 @@ static int loose_backend__writestream_finalize(git_odb_stream *_stream, const gi { loose_writestream *stream = (loose_writestream *)_stream; loose_backend *backend = (loose_backend *)_stream->backend; - git_buf final_path = GIT_BUF_INIT; + git_str final_path = GIT_STR_INIT; int error = 0; if (object_file_name(&final_path, backend, oid) < 0 || @@ -803,7 +803,7 @@ static int loose_backend__writestream_finalize(git_odb_stream *_stream, const gi error = git_filebuf_commit_at( &stream->fbuf, final_path.ptr); - git_buf_dispose(&final_path); + git_str_dispose(&final_path); return error; } @@ -838,7 +838,7 @@ static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backe loose_backend *backend; loose_writestream *stream = NULL; char hdr[MAX_HEADER_LEN]; - git_buf tmp_path = GIT_BUF_INIT; + git_str tmp_path = GIT_STR_INIT; size_t hdrlen; int error; @@ -861,7 +861,7 @@ static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backe stream->stream.free = &loose_backend__writestream_free; stream->stream.mode = GIT_STREAM_WRONLY; - if (git_buf_joinpath(&tmp_path, backend->objects_dir, "tmp_object") < 0 || + if (git_str_joinpath(&tmp_path, backend->objects_dir, "tmp_object") < 0 || git_filebuf_open(&stream->fbuf, tmp_path.ptr, filebuf_flags(backend), backend->object_file_mode) < 0 || stream->stream.write((git_odb_stream *)stream, hdr, hdrlen) < 0) @@ -870,7 +870,7 @@ static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backe git__free(stream); stream = NULL; } - git_buf_dispose(&tmp_path); + git_str_dispose(&tmp_path); *stream_out = (git_odb_stream *)stream; return !stream ? -1 : 0; @@ -996,7 +996,7 @@ static int loose_backend__readstream( loose_backend *backend; loose_readstream *stream = NULL; git_hash_ctx *hash_ctx = NULL; - git_buf object_path = GIT_BUF_INIT; + git_str object_path = GIT_STR_INIT; obj_hdr hdr; int error = 0; @@ -1059,14 +1059,14 @@ static int loose_backend__readstream( } } - git_buf_dispose(&object_path); + git_str_dispose(&object_path); return error; } static int loose_backend__write(git_odb_backend *_backend, const git_oid *oid, const void *data, size_t len, git_object_t type) { int error = 0; - git_buf final_path = GIT_BUF_INIT; + git_str final_path = GIT_STR_INIT; char header[MAX_HEADER_LEN]; size_t header_len; git_filebuf fbuf = GIT_FILEBUF_INIT; @@ -1079,7 +1079,7 @@ static int loose_backend__write(git_odb_backend *_backend, const git_oid *oid, c header, sizeof(header), len, type)) < 0) goto cleanup; - if (git_buf_joinpath(&final_path, backend->objects_dir, "tmp_object") < 0 || + if (git_str_joinpath(&final_path, backend->objects_dir, "tmp_object") < 0 || git_filebuf_open(&fbuf, final_path.ptr, filebuf_flags(backend), backend->object_file_mode) < 0) { @@ -1098,7 +1098,7 @@ static int loose_backend__write(git_odb_backend *_backend, const git_oid *oid, c cleanup: if (error < 0) git_filebuf_cleanup(&fbuf); - git_buf_dispose(&final_path); + git_str_dispose(&final_path); return error; } @@ -1107,14 +1107,14 @@ static int loose_backend__freshen( const git_oid *oid) { loose_backend *backend = (loose_backend *)_backend; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error; if (object_file_name(&path, backend, oid) < 0) return -1; error = git_futils_touch(path.ptr, NULL); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } diff --git a/src/odb_mempack.c b/src/odb_mempack.c index d08356a8d44..6f27f45f870 100644 --- a/src/odb_mempack.c +++ b/src/odb_mempack.c @@ -7,18 +7,20 @@ #include "common.h" -#include "git2/object.h" -#include "git2/sys/odb_backend.h" -#include "git2/sys/mempack.h" +#include "buf.h" #include "futils.h" #include "hash.h" #include "odb.h" #include "array.h" #include "oidmap.h" +#include "pack-objects.h" #include "git2/odb_backend.h" +#include "git2/object.h" #include "git2/types.h" #include "git2/pack.h" +#include "git2/sys/odb_backend.h" +#include "git2/sys/mempack.h" struct memobject { git_oid oid; @@ -100,7 +102,10 @@ static int impl__read_header(size_t *len_p, git_object_t *type_p, git_odb_backen return 0; } -int git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *_backend) +static int git_mempack__dump( + git_str *pack, + git_repository *repo, + git_odb_backend *_backend) { struct memory_packer_db *db = (struct memory_packer_db *)_backend; git_packbuilder *packbuilder; @@ -120,13 +125,21 @@ int git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *_back goto cleanup; } - err = git_packbuilder_write_buf(pack, packbuilder); + err = git_packbuilder__write_buf(pack, packbuilder); cleanup: git_packbuilder_free(packbuilder); return err; } +int git_mempack_dump( + git_buf *pack, + git_repository *repo, + git_odb_backend *_backend) +{ + GIT_BUF_WRAP_PRIVATE(pack, git_mempack__dump, repo, _backend); +} + int git_mempack_reset(git_odb_backend *_backend) { struct memory_packer_db *db = (struct memory_packer_db *)_backend; diff --git a/src/odb_pack.c b/src/odb_pack.c index f4cb9a558b7..f2c47adbe2b 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -166,7 +166,7 @@ struct pack_writepack { static int packfile_sort__cb(const void *a_, const void *b_); -static int packfile_load__cb(void *_data, git_buf *path); +static int packfile_load__cb(void *_data, git_str *path); static int packfile_byname_search_cmp(const void *path, const void *pack_entry); @@ -195,10 +195,10 @@ static int pack_entry_find_prefix( static int packfile_byname_search_cmp(const void *path_, const void *p_) { - const git_buf *path = (const git_buf *)path_; + const git_str *path = (const git_str *)path_; const struct git_pack_file *p = (const struct git_pack_file *)p_; - return strncmp(p->pack_name, git_buf_cstr(path), git_buf_len(path)); + return strncmp(p->pack_name, git_str_cstr(path), git_str_len(path)); } static int packfile_sort__cb(const void *a_, const void *b_) @@ -231,20 +231,20 @@ static int packfile_sort__cb(const void *a_, const void *b_) } -static int packfile_load__cb(void *data, git_buf *path) +static int packfile_load__cb(void *data, git_str *path) { struct pack_backend *backend = data; struct git_pack_file *pack; - const char *path_str = git_buf_cstr(path); - git_buf index_prefix = GIT_BUF_INIT; - size_t cmp_len = git_buf_len(path); + const char *path_str = git_str_cstr(path); + git_str index_prefix = GIT_STR_INIT; + size_t cmp_len = git_str_len(path); int error; if (cmp_len <= strlen(".idx") || git__suffixcmp(path_str, ".idx") != 0) return 0; /* not an index */ cmp_len -= strlen(".idx"); - git_buf_attach_notowned(&index_prefix, path_str, cmp_len); + git_str_attach_notowned(&index_prefix, path_str, cmp_len); if (git_vector_search2(NULL, &backend->midx_packs, packfile_byname_search_cmp, &index_prefix) == 0) return 0; @@ -404,29 +404,29 @@ static int process_multi_pack_index_pack( int error; struct git_pack_file *pack; size_t found_position; - git_buf pack_path = GIT_BUF_INIT, index_prefix = GIT_BUF_INIT; + git_str pack_path = GIT_STR_INIT, index_prefix = GIT_STR_INIT; - error = git_buf_joinpath(&pack_path, backend->pack_folder, packfile_name); + error = git_str_joinpath(&pack_path, backend->pack_folder, packfile_name); if (error < 0) return error; /* This is ensured by midx_parse_packfile_name() */ - if (git_buf_len(&pack_path) <= strlen(".idx") || git__suffixcmp(git_buf_cstr(&pack_path), ".idx") != 0) + if (git_str_len(&pack_path) <= strlen(".idx") || git__suffixcmp(git_str_cstr(&pack_path), ".idx") != 0) return git_odb__error_notfound("midx file contained a non-index", NULL, 0); - git_buf_attach_notowned(&index_prefix, git_buf_cstr(&pack_path), git_buf_len(&pack_path) - strlen(".idx")); + git_str_attach_notowned(&index_prefix, git_str_cstr(&pack_path), git_str_len(&pack_path) - strlen(".idx")); if (git_vector_search2(&found_position, &backend->packs, packfile_byname_search_cmp, &index_prefix) == 0) { /* Pack was found in the packs list. Moving it to the midx_packs list. */ - git_buf_dispose(&pack_path); + git_str_dispose(&pack_path); git_vector_set(NULL, &backend->midx_packs, i, git_vector_get(&backend->packs, found_position)); git_vector_remove(&backend->packs, found_position); return 0; } /* Pack was not found. Allocate a new one. */ - error = git_mwindow_get_pack(&pack, git_buf_cstr(&pack_path)); - git_buf_dispose(&pack_path); + error = git_mwindow_get_pack(&pack, git_str_cstr(&pack_path)); + git_str_dispose(&pack_path); if (error < 0) return error; @@ -442,11 +442,11 @@ static int process_multi_pack_index_pack( static int refresh_multi_pack_index(struct pack_backend *backend) { int error; - git_buf midx_path = GIT_BUF_INIT; + git_str midx_path = GIT_STR_INIT; const char *packfile_name; size_t i; - error = git_buf_joinpath(&midx_path, backend->pack_folder, "multi-pack-index"); + error = git_str_joinpath(&midx_path, backend->pack_folder, "multi-pack-index"); if (error < 0) return error; @@ -457,19 +457,19 @@ static int refresh_multi_pack_index(struct pack_backend *backend) * refreshing the new multi-pack-index fails, or the file is deleted. */ if (backend->midx) { - if (!git_midx_needs_refresh(backend->midx, git_buf_cstr(&midx_path))) { - git_buf_dispose(&midx_path); + if (!git_midx_needs_refresh(backend->midx, git_str_cstr(&midx_path))) { + git_str_dispose(&midx_path); return 0; } error = remove_multi_pack_index(backend); if (error < 0) { - git_buf_dispose(&midx_path); + git_str_dispose(&midx_path); return error; } } - error = git_midx_open(&backend->midx, git_buf_cstr(&midx_path)); - git_buf_dispose(&midx_path); + error = git_midx_open(&backend->midx, git_str_cstr(&midx_path)); + git_str_dispose(&midx_path); if (error < 0) return error; @@ -505,7 +505,7 @@ static int pack_backend__refresh(git_odb_backend *backend_) { int error; struct stat st; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; struct pack_backend *backend = (struct pack_backend *)backend_; if (backend->pack_folder == NULL) @@ -523,10 +523,10 @@ static int pack_backend__refresh(git_odb_backend *backend_) } /* reload all packs */ - git_buf_sets(&path, backend->pack_folder); + git_str_sets(&path, backend->pack_folder); error = git_path_direach(&path, 0, packfile_load__cb, backend); - git_buf_dispose(&path); + git_str_dispose(&path); git_vector_sort(&backend->packs); return error; @@ -743,7 +743,7 @@ static int pack_backend__writepack(struct git_odb_writepack **out, } static int get_idx_path( - git_buf *idx_path, + git_str *idx_path, struct pack_backend *backend, struct git_pack_file *p) { @@ -753,11 +753,11 @@ static int get_idx_path( error = git_path_prettify(idx_path, p->pack_name, backend->pack_folder); if (error < 0) return error; - path_len = git_buf_len(idx_path); - if (path_len <= strlen(".pack") || git__suffixcmp(git_buf_cstr(idx_path), ".pack") != 0) + path_len = git_str_len(idx_path); + if (path_len <= strlen(".pack") || git__suffixcmp(git_str_cstr(idx_path), ".pack") != 0) return git_odb__error_notfound("packfile does not end in .pack", NULL, 0); path_len -= strlen(".pack"); - error = git_buf_splice(idx_path, path_len, strlen(".pack"), ".idx", strlen(".idx")); + error = git_str_splice(idx_path, path_len, strlen(".pack"), ".idx", strlen(".idx")); if (error < 0) return error; @@ -781,22 +781,22 @@ static int pack_backend__writemidx(git_odb_backend *_backend) return error; git_vector_foreach(&backend->midx_packs, i, p) { - git_buf idx_path = GIT_BUF_INIT; + git_str idx_path = GIT_STR_INIT; error = get_idx_path(&idx_path, backend, p); if (error < 0) goto cleanup; - error = git_midx_writer_add(w, git_buf_cstr(&idx_path)); - git_buf_dispose(&idx_path); + error = git_midx_writer_add(w, git_str_cstr(&idx_path)); + git_str_dispose(&idx_path); if (error < 0) goto cleanup; } git_vector_foreach(&backend->packs, i, p) { - git_buf idx_path = GIT_BUF_INIT; + git_str idx_path = GIT_STR_INIT; error = get_idx_path(&idx_path, backend, p); if (error < 0) goto cleanup; - error = git_midx_writer_add(w, git_buf_cstr(&idx_path)); - git_buf_dispose(&idx_path); + error = git_midx_writer_add(w, git_str_cstr(&idx_path)); + git_str_dispose(&idx_path); if (error < 0) goto cleanup; } @@ -896,15 +896,15 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir) { int error = 0; struct pack_backend *backend = NULL; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; if (pack_backend__alloc(&backend, 8) < 0) return -1; - if (!(error = git_buf_joinpath(&path, objects_dir, "pack")) && - git_path_isdir(git_buf_cstr(&path))) + if (!(error = git_str_joinpath(&path, objects_dir, "pack")) && + git_path_isdir(git_str_cstr(&path))) { - backend->pack_folder = git_buf_detach(&path); + backend->pack_folder = git_str_detach(&path); error = pack_backend__refresh((git_odb_backend *)backend); } @@ -915,7 +915,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir) *backend_out = (git_odb_backend *)backend; - git_buf_dispose(&path); + git_str_dispose(&path); return error; } diff --git a/src/oid.c b/src/oid.c index 893e2fc0fb0..dbc5a5a9092 100644 --- a/src/oid.c +++ b/src/oid.c @@ -162,14 +162,14 @@ int git_oid__parse( return 0; } -void git_oid__writebuf(git_buf *buf, const char *header, const git_oid *oid) +void git_oid__writebuf(git_str *buf, const char *header, const git_oid *oid) { char hex_oid[GIT_OID_HEXSZ]; git_oid_fmt(hex_oid, oid); - git_buf_puts(buf, header); - git_buf_put(buf, hex_oid, GIT_OID_HEXSZ); - git_buf_putc(buf, '\n'); + git_str_puts(buf, header); + git_str_put(buf, hex_oid, GIT_OID_HEXSZ); + git_str_putc(buf, '\n'); } int git_oid_fromraw(git_oid *out, const unsigned char *raw) diff --git a/src/pack-objects.c b/src/pack-objects.c index d89a4e78044..e5fc625a465 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -7,6 +7,7 @@ #include "pack-objects.h" +#include "buf.h" #include "zstream.h" #include "delta.h" #include "iterator.h" @@ -33,7 +34,7 @@ struct unpacked { struct tree_walk_context { git_packbuilder *pb; - git_buf buf; + git_str buf; }; struct pack_write_context { @@ -685,8 +686,8 @@ static int write_pack(git_packbuilder *pb, static int write_pack_buf(void *buf, size_t size, void *data) { - git_buf *b = (git_buf *)data; - return git_buf_put(b, buf, size); + git_str *b = (git_str *)data; + return git_str_put(b, buf, size); } static int type_size_sort(const void *_a, const void *_b) @@ -947,7 +948,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list, size_t *list_size, size_t window, size_t depth) { git_pobject *po; - git_buf zbuf = GIT_BUF_INIT; + git_str zbuf = GIT_STR_INIT; struct unpacked *array; size_t idx = 0, count = 0; size_t mem_usage = 0; @@ -1045,7 +1046,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list, memcpy(po->delta_data, zbuf.ptr, zbuf.size); po->z_delta_size = zbuf.size; - git_buf_clear(&zbuf); + git_str_clear(&zbuf); GIT_ASSERT(git_packbuilder__cache_lock(pb) == 0); pb->delta_cache_size -= po->delta_size; @@ -1093,7 +1094,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list, git__free(array[i].data); } git__free(array); - git_buf_dispose(&zbuf); + git_str_dispose(&zbuf); return error; } @@ -1360,18 +1361,18 @@ int git_packbuilder_foreach(git_packbuilder *pb, int (*cb)(void *buf, size_t siz return write_pack(pb, cb, payload); } -int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb) +int git_packbuilder__write_buf(git_str *buf, git_packbuilder *pb) { - int error; - - if ((error = git_buf_sanitize(buf)) < 0) - return error; - PREPARE_PACK; return write_pack(pb, &write_pack_buf, buf); } +int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb) +{ + GIT_BUF_WRAP_PRIVATE(buf, git_packbuilder__write_buf, pb); +} + static int write_cb(void *buf, size_t len, void *payload) { struct pack_write_context *ctx = payload; @@ -1386,7 +1387,7 @@ int git_packbuilder_write( void *progress_cb_payload) { int error = -1; - git_buf object_path = GIT_BUF_INIT; + git_str object_path = GIT_STR_INIT; git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT; git_indexer *indexer = NULL; git_indexer_progress stats; @@ -1396,11 +1397,11 @@ int git_packbuilder_write( PREPARE_PACK; if (path == NULL) { - if ((error = git_repository_item_path(&object_path, pb->repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0) + if ((error = git_repository__item_path(&object_path, pb->repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0) goto cleanup; - if ((error = git_buf_joinpath(&object_path, git_buf_cstr(&object_path), "pack")) < 0) + if ((error = git_str_joinpath(&object_path, git_str_cstr(&object_path), "pack")) < 0) goto cleanup; - path = git_buf_cstr(&object_path); + path = git_str_cstr(&object_path); } opts.progress_cb = progress_cb; @@ -1425,7 +1426,7 @@ int git_packbuilder_write( cleanup: git_indexer_free(indexer); - git_buf_dispose(&object_path); + git_str_dispose(&object_path); return error; } @@ -1447,10 +1448,10 @@ static int cb_tree_walk( if (git_tree_entry_type(entry) == GIT_OBJECT_COMMIT) return 0; - if (!(error = git_buf_sets(&ctx->buf, root)) && - !(error = git_buf_puts(&ctx->buf, git_tree_entry_name(entry)))) + if (!(error = git_str_sets(&ctx->buf, root)) && + !(error = git_str_puts(&ctx->buf, git_tree_entry_name(entry)))) error = git_packbuilder_insert( - ctx->pb, git_tree_entry_id(entry), git_buf_cstr(&ctx->buf)); + ctx->pb, git_tree_entry_id(entry), git_str_cstr(&ctx->buf)); return error; } @@ -1474,14 +1475,14 @@ int git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *oid) { int error; git_tree *tree = NULL; - struct tree_walk_context context = { pb, GIT_BUF_INIT }; + struct tree_walk_context context = { pb, GIT_STR_INIT }; if (!(error = git_tree_lookup(&tree, pb->repo, oid)) && !(error = git_packbuilder_insert(pb, oid, NULL))) error = git_tree_walk(tree, GIT_TREEWALK_PRE, cb_tree_walk, &context); git_tree_free(tree); - git_buf_dispose(&context.buf); + git_str_dispose(&context.buf); return error; } diff --git a/src/pack-objects.h b/src/pack-objects.h index 04514daa6e1..db2038b0a04 100644 --- a/src/pack-objects.h +++ b/src/pack-objects.h @@ -10,7 +10,7 @@ #include "common.h" -#include "buffer.h" +#include "str.h" #include "hash.h" #include "oidmap.h" #include "netops.h" @@ -96,6 +96,6 @@ struct git_packbuilder { bool done; }; -int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb); +int git_packbuilder__write_buf(git_str *buf, git_packbuilder *pb); #endif diff --git a/src/pack.c b/src/pack.c index aadf3f2be7c..e17d20f8c89 100644 --- a/src/pack.c +++ b/src/pack.c @@ -308,7 +308,7 @@ static int pack_index_open_locked(struct git_pack_file *p) { int error = 0; size_t name_len; - git_buf idx_name = GIT_BUF_INIT; + git_str idx_name = GIT_STR_INIT; if (p->index_version > -1) goto cleanup; @@ -317,12 +317,12 @@ static int pack_index_open_locked(struct git_pack_file *p) name_len = strlen(p->pack_name); GIT_ASSERT(name_len > strlen(".pack")); - if ((error = git_buf_init(&idx_name, name_len)) < 0) + if ((error = git_str_init(&idx_name, name_len)) < 0) goto cleanup; - git_buf_put(&idx_name, p->pack_name, name_len - strlen(".pack")); - git_buf_puts(&idx_name, ".idx"); - if (git_buf_oom(&idx_name)) { + git_str_put(&idx_name, p->pack_name, name_len - strlen(".pack")); + git_str_puts(&idx_name, ".idx"); + if (git_str_oom(&idx_name)) { error = -1; goto cleanup; } @@ -331,7 +331,7 @@ static int pack_index_open_locked(struct git_pack_file *p) error = pack_index_check_locked(idx_name.ptr, p); cleanup: - git_buf_dispose(&idx_name); + git_str_dispose(&idx_name); return error; } @@ -1156,17 +1156,17 @@ static int packfile_open_locked(struct git_pack_file *p) int git_packfile__name(char **out, const char *path) { size_t path_len; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; path_len = strlen(path); if (path_len < strlen(".idx")) return git_odb__error_notfound("invalid packfile path", NULL, 0); - if (git_buf_printf(&buf, "%.*s.pack", (int)(path_len - strlen(".idx")), path) < 0) + if (git_str_printf(&buf, "%.*s.pack", (int)(path_len - strlen(".idx")), path) < 0) return -1; - *out = git_buf_detach(&buf); + *out = git_str_detach(&buf); return 0; } diff --git a/src/patch.c b/src/patch.c index f02c928de25..a30546f3ce6 100644 --- a/src/patch.c +++ b/src/patch.c @@ -76,15 +76,15 @@ size_t git_patch_size( out += patch->header_size; if (include_file_headers) { - git_buf file_header = GIT_BUF_INIT; + git_str file_header = GIT_STR_INIT; if (git_diff_delta__format_file_header( &file_header, patch->delta, NULL, NULL, 0, true) < 0) git_error_clear(); else - out += git_buf_len(&file_header); + out += git_str_len(&file_header); - git_buf_dispose(&file_header); + git_str_dispose(&file_header); } return out; diff --git a/src/patch.h b/src/patch.h index 156d1310e79..1e1471ed613 100644 --- a/src/patch.h +++ b/src/patch.h @@ -63,6 +63,7 @@ typedef struct { #define GIT_PATCH_OPTIONS_INIT { 1 } +extern int git_patch__to_buf(git_str *out, git_patch *patch); extern void git_patch_free(git_patch *patch); #endif diff --git a/src/patch_generate.c b/src/patch_generate.c index 38cd714a980..6d115affebc 100644 --- a/src/patch_generate.c +++ b/src/patch_generate.c @@ -261,7 +261,7 @@ static int create_binary( const char *b_data, size_t b_datalen) { - git_buf deflate = GIT_BUF_INIT, delta = GIT_BUF_INIT; + git_str deflate = GIT_STR_INIT, delta = GIT_STR_INIT; size_t delta_data_len = 0; int error; @@ -302,18 +302,18 @@ static int create_binary( if (delta.size && delta.size < deflate.size) { *out_type = GIT_DIFF_BINARY_DELTA; *out_datalen = delta.size; - *out_data = git_buf_detach(&delta); + *out_data = git_str_detach(&delta); *out_inflatedlen = delta_data_len; } else { *out_type = GIT_DIFF_BINARY_LITERAL; *out_datalen = deflate.size; - *out_data = git_buf_detach(&deflate); + *out_data = git_str_detach(&deflate); *out_inflatedlen = b_datalen; } done: - git_buf_dispose(&deflate); - git_buf_dispose(&delta); + git_str_dispose(&deflate); + git_str_dispose(&delta); return error; } diff --git a/src/patch_parse.c b/src/patch_parse.c index 2cc5c599517..fce4bc9e469 100644 --- a/src/patch_parse.c +++ b/src/patch_parse.c @@ -65,19 +65,19 @@ static size_t header_path_len(git_patch_parse_ctx *ctx) return len; } -static int parse_header_path_buf(git_buf *path, git_patch_parse_ctx *ctx, size_t path_len) +static int parse_header_path_buf(git_str *path, git_patch_parse_ctx *ctx, size_t path_len) { int error; - if ((error = git_buf_put(path, ctx->parse_ctx.line, path_len)) < 0) + if ((error = git_str_put(path, ctx->parse_ctx.line, path_len)) < 0) return error; git_parse_advance_chars(&ctx->parse_ctx, path_len); - git_buf_rtrim(path); + git_str_rtrim(path); if (path->size > 0 && path->ptr[0] == '"' && - (error = git_buf_unquote(path)) < 0) + (error = git_str_unquote(path)) < 0) return error; git_path_squash_slashes(path); @@ -91,22 +91,22 @@ static int parse_header_path_buf(git_buf *path, git_patch_parse_ctx *ctx, size_t static int parse_header_path(char **out, git_patch_parse_ctx *ctx) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error; if ((error = parse_header_path_buf(&path, ctx, header_path_len(ctx))) < 0) goto out; - *out = git_buf_detach(&path); + *out = git_str_detach(&path); out: - git_buf_dispose(&path); + git_str_dispose(&path); return error; } static int parse_header_git_oldpath( git_patch_parsed *patch, git_patch_parse_ctx *ctx) { - git_buf old_path = GIT_BUF_INIT; + git_str old_path = GIT_STR_INIT; int error; if (patch->old_path) { @@ -118,17 +118,17 @@ static int parse_header_git_oldpath( if ((error = parse_header_path_buf(&old_path, ctx, ctx->parse_ctx.line_len - 1)) < 0) goto out; - patch->old_path = git_buf_detach(&old_path); + patch->old_path = git_str_detach(&old_path); out: - git_buf_dispose(&old_path); + git_str_dispose(&old_path); return error; } static int parse_header_git_newpath( git_patch_parsed *patch, git_patch_parse_ctx *ctx) { - git_buf new_path = GIT_BUF_INIT; + git_str new_path = GIT_STR_INIT; int error; if (patch->new_path) { @@ -139,10 +139,10 @@ static int parse_header_git_newpath( if ((error = parse_header_path_buf(&new_path, ctx, ctx->parse_ctx.line_len - 1)) < 0) goto out; - patch->new_path = git_buf_detach(&new_path); + patch->new_path = git_str_detach(&new_path); out: - git_buf_dispose(&new_path); + git_str_dispose(&new_path); return error; } @@ -257,7 +257,7 @@ static int parse_header_rename( char **out, git_patch_parse_ctx *ctx) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; if (parse_header_path_buf(&path, ctx, header_path_len(ctx)) < 0) return -1; @@ -265,7 +265,7 @@ static int parse_header_rename( /* Note: the `rename from` and `rename to` lines include the literal * filename. They do *not* include the prefix. (Who needs consistency?) */ - *out = git_buf_detach(&path); + *out = git_str_detach(&path); return 0; } @@ -766,7 +766,7 @@ static int parse_patch_binary_side( git_patch_parse_ctx *ctx) { git_diff_binary_t type = GIT_DIFF_BINARY_NONE; - git_buf base85 = GIT_BUF_INIT, decoded = GIT_BUF_INIT; + git_str base85 = GIT_STR_INIT, decoded = GIT_STR_INIT; int64_t len; int error = 0; @@ -815,7 +815,7 @@ static int parse_patch_binary_side( goto done; } - if ((error = git_buf_decode_base85( + if ((error = git_str_decode_base85( &decoded, ctx->parse_ctx.line, encoded_len, decoded_len)) < 0) goto done; @@ -835,11 +835,11 @@ static int parse_patch_binary_side( binary->type = type; binary->inflatedlen = (size_t)len; binary->datalen = decoded.size; - binary->data = git_buf_detach(&decoded); + binary->data = git_str_detach(&decoded); done: - git_buf_dispose(&base85); - git_buf_dispose(&decoded); + git_str_dispose(&base85); + git_str_dispose(&decoded); return error; } diff --git a/src/path.c b/src/path.c index c444b31a771..d8d33a1419f 100644 --- a/src/path.c +++ b/src/path.c @@ -93,7 +93,7 @@ static bool looks_like_network_computer_name(const char *path, int pos) * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -int git_path_basename_r(git_buf *buffer, const char *path) +int git_path_basename_r(git_str *buffer, const char *path) { const char *endp, *startp; int len, result; @@ -128,7 +128,7 @@ int git_path_basename_r(git_buf *buffer, const char *path) Exit: result = len; - if (buffer != NULL && git_buf_set(buffer, startp, len) < 0) + if (buffer != NULL && git_str_set(buffer, startp, len) < 0) return -1; return result; @@ -166,7 +166,7 @@ static int win32_prefix_length(const char *path, int len) * Based on the Android implementation, BSD licensed. * Check http://android.git.kernel.org/ */ -int git_path_dirname_r(git_buf *buffer, const char *path) +int git_path_dirname_r(git_str *buffer, const char *path) { const char *endp; int is_prefix = 0, len; @@ -225,9 +225,9 @@ int git_path_dirname_r(git_buf *buffer, const char *path) Exit: if (buffer) { - if (git_buf_set(buffer, path, len) < 0) + if (git_str_set(buffer, path, len) < 0) return -1; - if (is_prefix && git_buf_putc(buffer, '/') < 0) + if (is_prefix && git_str_putc(buffer, '/') < 0) return -1; } @@ -237,36 +237,36 @@ int git_path_dirname_r(git_buf *buffer, const char *path) char *git_path_dirname(const char *path) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; char *dirname; git_path_dirname_r(&buf, path); - dirname = git_buf_detach(&buf); - git_buf_dispose(&buf); /* avoid memleak if error occurs */ + dirname = git_str_detach(&buf); + git_str_dispose(&buf); /* avoid memleak if error occurs */ return dirname; } char *git_path_basename(const char *path) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; char *basename; git_path_basename_r(&buf, path); - basename = git_buf_detach(&buf); - git_buf_dispose(&buf); /* avoid memleak if error occurs */ + basename = git_str_detach(&buf); + git_str_dispose(&buf); /* avoid memleak if error occurs */ return basename; } -size_t git_path_basename_offset(git_buf *buffer) +size_t git_path_basename_offset(git_str *buffer) { ssize_t slash; if (!buffer || buffer->size <= 0) return 0; - slash = git_buf_rfind_next(buffer, '/'); + slash = git_str_rfind_next(buffer, '/'); if (slash >= 0 && buffer->ptr[slash] == '/') return (size_t)(slash + 1); @@ -304,7 +304,7 @@ int git_path_root(const char *path) return -1; /* Not a real error - signals that path is not rooted */ } -static void path_trim_slashes(git_buf *path) +static void path_trim_slashes(git_str *path) { int ceiling = git_path_root(path->ptr) + 1; @@ -321,7 +321,7 @@ static void path_trim_slashes(git_buf *path) } int git_path_join_unrooted( - git_buf *path_out, const char *path, const char *base, ssize_t *root_at) + git_str *path_out, const char *path, const char *base, ssize_t *root_at) { ssize_t root; @@ -331,12 +331,12 @@ int git_path_join_unrooted( root = (ssize_t)git_path_root(path); if (base != NULL && root < 0) { - if (git_buf_joinpath(path_out, base, path) < 0) + if (git_str_joinpath(path_out, base, path) < 0) return -1; root = (ssize_t)strlen(base); } else { - if (git_buf_sets(path_out, path) < 0) + if (git_str_sets(path_out, path) < 0) return -1; if (root < 0) @@ -351,7 +351,7 @@ int git_path_join_unrooted( return 0; } -void git_path_squash_slashes(git_buf *path) +void git_path_squash_slashes(git_str *path) { char *p, *q; @@ -370,7 +370,7 @@ void git_path_squash_slashes(git_buf *path) *p = '\0'; } -int git_path_prettify(git_buf *path_out, const char *path, const char *base) +int git_path_prettify(git_str *path_out, const char *path, const char *base) { char buf[GIT_PATH_MAX]; @@ -379,7 +379,7 @@ int git_path_prettify(git_buf *path_out, const char *path, const char *base) /* construct path if needed */ if (base != NULL && git_path_root(path) < 0) { - if (git_buf_joinpath(path_out, base, path) < 0) + if (git_str_joinpath(path_out, base, path) < 0) return -1; path = path_out->ptr; } @@ -389,28 +389,28 @@ int git_path_prettify(git_buf *path_out, const char *path, const char *base) int error = (errno == ENOENT || errno == ENOTDIR) ? GIT_ENOTFOUND : -1; git_error_set(GIT_ERROR_OS, "failed to resolve path '%s'", path); - git_buf_clear(path_out); + git_str_clear(path_out); return error; } - return git_buf_sets(path_out, buf); + return git_str_sets(path_out, buf); } -int git_path_prettify_dir(git_buf *path_out, const char *path, const char *base) +int git_path_prettify_dir(git_str *path_out, const char *path, const char *base) { int error = git_path_prettify(path_out, path, base); return (error < 0) ? error : git_path_to_dir(path_out); } -int git_path_to_dir(git_buf *path) +int git_path_to_dir(git_str *path) { if (path->asize > 0 && - git_buf_len(path) > 0 && - path->ptr[git_buf_len(path) - 1] != '/') - git_buf_putc(path, '/'); + git_str_len(path) > 0 && + path->ptr[git_str_len(path) - 1] != '/') + git_str_putc(path, '/'); - return git_buf_oom(path) ? -1 : 0; + return git_str_oom(path) ? -1 : 0; } void git_path_string_to_dir(char *path, size_t size) @@ -423,7 +423,7 @@ void git_path_string_to_dir(char *path, size_t size) } } -int git__percent_decode(git_buf *decoded_out, const char *input) +int git__percent_decode(git_str *decoded_out, const char *input) { int len, hi, lo, i; @@ -431,7 +431,7 @@ int git__percent_decode(git_buf *decoded_out, const char *input) GIT_ASSERT_ARG(input); len = (int)strlen(input); - git_buf_clear(decoded_out); + git_str_clear(decoded_out); for(i = 0; i < len; i++) { @@ -453,7 +453,7 @@ int git__percent_decode(git_buf *decoded_out, const char *input) i += 2; append: - if (git_buf_putc(decoded_out, c) < 0) + if (git_str_putc(decoded_out, c) < 0) return -1; } @@ -485,7 +485,7 @@ bool git_path_is_local_file_url(const char *file_url) return (local_file_url_prefixlen(file_url) > 0); } -int git_path_fromurl(git_buf *local_path_out, const char *file_url) +int git_path_fromurl(git_str *local_path_out, const char *file_url) { int offset; @@ -500,18 +500,18 @@ int git_path_fromurl(git_buf *local_path_out, const char *file_url) offset--; /* A *nix absolute path starts with a forward slash */ #endif - git_buf_clear(local_path_out); + git_str_clear(local_path_out); return git__percent_decode(local_path_out, file_url + offset); } int git_path_walk_up( - git_buf *path, + git_str *path, const char *ceiling, int (*cb)(void *data, const char *), void *data) { int error = 0; - git_buf iter; + git_str iter; ssize_t stop = 0, scan; char oldc = '\0'; @@ -522,9 +522,9 @@ int git_path_walk_up( if (git__prefixcmp(path->ptr, ceiling) == 0) stop = (ssize_t)strlen(ceiling); else - stop = git_buf_len(path); + stop = git_str_len(path); } - scan = git_buf_len(path); + scan = git_str_len(path); /* empty path: yield only once */ if (!scan) { @@ -535,7 +535,7 @@ int git_path_walk_up( } iter.ptr = path->ptr; - iter.size = git_buf_len(path); + iter.size = git_str_len(path); iter.asize = path->asize; while (scan >= stop) { @@ -547,7 +547,7 @@ int git_path_walk_up( break; } - scan = git_buf_rfind_next(&iter, '/'); + scan = git_str_rfind_next(&iter, '/'); if (scan >= 0) { scan++; oldc = iter.ptr[scan]; @@ -651,7 +651,7 @@ bool git_path_is_empty_dir(const char *path) #else -static int path_found_entry(void *payload, git_buf *path) +static int path_found_entry(void *payload, git_str *path) { GIT_UNUSED(payload); return !git_path_is_dot_or_dotdot(path->ptr); @@ -660,17 +660,17 @@ static int path_found_entry(void *payload, git_buf *path) bool git_path_is_empty_dir(const char *path) { int error; - git_buf dir = GIT_BUF_INIT; + git_str dir = GIT_STR_INIT; if (!git_path_isdir(path)) return false; - if ((error = git_buf_sets(&dir, path)) != 0) + if ((error = git_str_sets(&dir, path)) != 0) git_error_clear(); else error = git_path_direach(&dir, 0, path_found_entry, NULL); - git_buf_dispose(&dir); + git_str_dispose(&dir); return !error; } @@ -713,54 +713,54 @@ int git_path_lstat(const char *path, struct stat *st) } static bool _check_dir_contents( - git_buf *dir, + git_str *dir, const char *sub, bool (*predicate)(const char *)) { bool result; - size_t dir_size = git_buf_len(dir); + size_t dir_size = git_str_len(dir); size_t sub_size = strlen(sub); size_t alloc_size; /* leave base valid even if we could not make space for subdir */ if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) || GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) || - git_buf_try_grow(dir, alloc_size, false) < 0) + git_str_try_grow(dir, alloc_size, false) < 0) return false; /* save excursion */ - if (git_buf_joinpath(dir, dir->ptr, sub) < 0) + if (git_str_joinpath(dir, dir->ptr, sub) < 0) return false; result = predicate(dir->ptr); /* restore path */ - git_buf_truncate(dir, dir_size); + git_str_truncate(dir, dir_size); return result; } -bool git_path_contains(git_buf *dir, const char *item) +bool git_path_contains(git_str *dir, const char *item) { return _check_dir_contents(dir, item, &git_path_exists); } -bool git_path_contains_dir(git_buf *base, const char *subdir) +bool git_path_contains_dir(git_str *base, const char *subdir) { return _check_dir_contents(base, subdir, &git_path_isdir); } -bool git_path_contains_file(git_buf *base, const char *file) +bool git_path_contains_file(git_str *base, const char *file) { return _check_dir_contents(base, file, &git_path_isfile); } -int git_path_find_dir(git_buf *dir) +int git_path_find_dir(git_str *dir) { int error = 0; char buf[GIT_PATH_MAX]; if (p_realpath(dir->ptr, buf) != NULL) - error = git_buf_sets(dir, buf); + error = git_str_sets(dir, buf); /* call dirname if this is not a directory */ if (!error) /* && git_path_isdir(dir->ptr) == false) */ @@ -772,12 +772,12 @@ int git_path_find_dir(git_buf *dir) return error; } -int git_path_resolve_relative(git_buf *path, size_t ceiling) +int git_path_resolve_relative(git_str *path, size_t ceiling) { char *base, *to, *from, *next; size_t len; - GIT_ERROR_CHECK_ALLOC_BUF(path); + GIT_ERROR_CHECK_ALLOC_STR(path); if (ceiling > path->size) ceiling = path->size; @@ -851,9 +851,9 @@ int git_path_resolve_relative(git_buf *path, size_t ceiling) return 0; } -int git_path_apply_relative(git_buf *target, const char *relpath) +int git_path_apply_relative(git_str *target, const char *relpath) { - return git_buf_joinpath(target, git_buf_cstr(target), relpath) || + return git_str_joinpath(target, git_str_cstr(target), relpath) || git_path_resolve_relative(target, 0); } @@ -896,7 +896,7 @@ size_t git_path_common_dirlen(const char *one, const char *two) return dirsep ? (dirsep - one) + 1 : 0; } -int git_path_make_relative(git_buf *path, const char *parent) +int git_path_make_relative(git_str *path, const char *parent) { const char *p, *q, *p_dirsep, *q_dirsep; size_t plen = path->size, newlen, alloclen, depth = 1, i, offset; @@ -923,7 +923,7 @@ int git_path_make_relative(git_buf *path, const char *parent) else if (!*p && *q == '/') q++; else if (!*p && !*q) - return git_buf_clear(path), 0; + return git_str_clear(path), 0; else { p = p_dirsep + 1; q = q_dirsep + 1; @@ -932,7 +932,7 @@ int git_path_make_relative(git_buf *path, const char *parent) plen -= (p - path->ptr); if (!*q) - return git_buf_set(path, p, plen); + return git_str_set(path, p, plen); for (; (q = strchr(q, '/')) && *(q + 1); q++) depth++; @@ -944,7 +944,7 @@ int git_path_make_relative(git_buf *path, const char *parent) /* save the offset as we might realllocate the pointer */ offset = p - path->ptr; - if (git_buf_try_grow(path, alloclen, 1) < 0) + if (git_str_try_grow(path, alloclen, 1) < 0) return -1; p = path->ptr + offset; @@ -972,7 +972,7 @@ bool git_path_has_non_ascii(const char *path, size_t pathlen) int git_path_iconv_init_precompose(git_path_iconv_t *ic) { - git_buf_init(&ic->buf, 0); + git_str_init(&ic->buf, 0); ic->map = iconv_open(GIT_PATH_REPO_ENCODING, GIT_PATH_NATIVE_ENCODING); return 0; } @@ -982,7 +982,7 @@ void git_path_iconv_clear(git_path_iconv_t *ic) if (ic) { if (ic->map != (iconv_t)-1) iconv_close(ic->map); - git_buf_dispose(&ic->buf); + git_str_dispose(&ic->buf); } } @@ -996,11 +996,11 @@ int git_path_iconv(git_path_iconv_t *ic, const char **in, size_t *inlen) !git_path_has_non_ascii(*in, *inlen)) return 0; - git_buf_clear(&ic->buf); + git_str_clear(&ic->buf); while (1) { GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, wantlen, 1); - if (git_buf_grow(&ic->buf, alloclen) < 0) + if (git_str_grow(&ic->buf, alloclen) < 0) return -1; nfc = ic->buf.ptr + ic->buf.size; @@ -1054,7 +1054,7 @@ static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D.XXXXXX"; */ bool git_path_does_fs_decompose_unicode(const char *root) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int fd; bool found_decomposed = false; char tmp[6]; @@ -1063,7 +1063,7 @@ bool git_path_does_fs_decompose_unicode(const char *root) * using the decomposed name. If the lookup fails, then we will mark * that we should precompose unicode for this repository. */ - if (git_buf_joinpath(&path, root, nfc_file) < 0 || + if (git_str_joinpath(&path, root, nfc_file) < 0 || (fd = p_mkstemp(path.ptr)) < 0) goto done; p_close(fd); @@ -1072,21 +1072,21 @@ bool git_path_does_fs_decompose_unicode(const char *root) memcpy(tmp, path.ptr + path.size - sizeof(tmp), sizeof(tmp)); /* try to look up as NFD path */ - if (git_buf_joinpath(&path, root, nfd_file) < 0) + if (git_str_joinpath(&path, root, nfd_file) < 0) goto done; memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); found_decomposed = git_path_exists(path.ptr); /* remove temporary file (using original precomposed path) */ - if (git_buf_joinpath(&path, root, nfc_file) < 0) + if (git_str_joinpath(&path, root, nfc_file) < 0) goto done; memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); (void)p_unlink(path.ptr); done: - git_buf_dispose(&path); + git_str_dispose(&path); return found_decomposed; } @@ -1107,9 +1107,9 @@ typedef struct dirent path_dirent_data; #endif int git_path_direach( - git_buf *path, + git_str *path, uint32_t flags, - int (*fn)(void *, git_buf *), + int (*fn)(void *, git_str *), void *arg) { int error = 0; @@ -1126,7 +1126,7 @@ int git_path_direach( if (git_path_to_dir(path) < 0) return -1; - wd_len = git_buf_len(path); + wd_len = git_str_len(path); if ((dir = opendir(path->ptr)) == NULL) { git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path->ptr); @@ -1153,13 +1153,13 @@ int git_path_direach( break; #endif - if ((error = git_buf_put(path, de_path, de_len)) < 0) + if ((error = git_str_put(path, de_path, de_len)) < 0) break; git_error_clear(); error = fn(arg, path); - git_buf_truncate(path, wd_len); /* restore path */ + git_str_truncate(path, wd_len); /* restore path */ /* Only set our own error if the callback did not set one already */ if (error != 0) { @@ -1205,7 +1205,7 @@ int git_path_diriter_init( memset(diriter, 0, sizeof(git_path_diriter)); diriter->handle = INVALID_HANDLE_VALUE; - if (git_buf_puts(&diriter->path_utf8, path) < 0) + if (git_str_puts(&diriter->path_utf8, path) < 0) return -1; path_trim_slashes(&diriter->path_utf8); @@ -1261,15 +1261,15 @@ static int diriter_update_paths(git_path_diriter *diriter) diriter->current.cFileName, filename_len * sizeof(wchar_t)); diriter->path[path_len-1] = L'\0'; - git_buf_truncate(&diriter->path_utf8, diriter->parent_utf8_len); + git_str_truncate(&diriter->path_utf8, diriter->parent_utf8_len); if (diriter->parent_utf8_len > 0 && diriter->path_utf8.ptr[diriter->parent_utf8_len-1] != '/') - git_buf_putc(&diriter->path_utf8, '/'); + git_str_putc(&diriter->path_utf8, '/'); - git_buf_put_w(&diriter->path_utf8, diriter->current.cFileName, filename_len); + git_str_put_w(&diriter->path_utf8, diriter->current.cFileName, filename_len); - if (git_buf_oom(&diriter->path_utf8)) + if (git_str_oom(&diriter->path_utf8)) return -1; return 0; @@ -1339,7 +1339,7 @@ void git_path_diriter_free(git_path_diriter *diriter) if (diriter == NULL) return; - git_buf_dispose(&diriter->path_utf8); + git_str_dispose(&diriter->path_utf8); if (diriter->handle != INVALID_HANDLE_VALUE) { FindClose(diriter->handle); @@ -1359,7 +1359,7 @@ int git_path_diriter_init( memset(diriter, 0, sizeof(git_path_diriter)); - if (git_buf_puts(&diriter->path, path) < 0) + if (git_str_puts(&diriter->path, path) < 0) return -1; path_trim_slashes(&diriter->path); @@ -1370,7 +1370,7 @@ int git_path_diriter_init( } if ((diriter->dir = opendir(diriter->path.ptr)) == NULL) { - git_buf_dispose(&diriter->path); + git_str_dispose(&diriter->path); git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path); return -1; @@ -1419,15 +1419,15 @@ int git_path_diriter_next(git_path_diriter *diriter) return error; #endif - git_buf_truncate(&diriter->path, diriter->parent_len); + git_str_truncate(&diriter->path, diriter->parent_len); if (diriter->parent_len > 0 && diriter->path.ptr[diriter->parent_len-1] != '/') - git_buf_putc(&diriter->path, '/'); + git_str_putc(&diriter->path, '/'); - git_buf_put(&diriter->path, filename, filename_len); + git_str_put(&diriter->path, filename, filename_len); - if (git_buf_oom(&diriter->path)) + if (git_str_oom(&diriter->path)) return -1; return error; @@ -1484,7 +1484,7 @@ void git_path_diriter_free(git_path_diriter *diriter) git_path_iconv_clear(&diriter->ic); #endif - git_buf_dispose(&diriter->path); + git_str_dispose(&diriter->path); } #endif @@ -1527,12 +1527,12 @@ int git_path_dirload( return error; } -int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path) +int git_path_from_url_or_path(git_str *local_path_out, const char *url_or_path) { if (git_path_is_local_file_url(url_or_path)) return git_path_fromurl(local_path_out, url_or_path); else - return git_buf_sets(local_path_out, url_or_path); + return git_str_sets(local_path_out, url_or_path); } /* Reject paths like AUX or COM1, or those versions that end in a dot or @@ -1625,7 +1625,7 @@ static bool verify_dotgit_hfs(const char *path, size_t len) GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size_t len) { - git_buf *reserved = git_repository__reserved_names_win32; + git_str *reserved = git_repository__reserved_names_win32; size_t reserved_len = git_repository__reserved_names_win32_len; size_t start = 0, i; @@ -1633,7 +1633,7 @@ GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size git_repository__reserved_names(&reserved, &reserved_len, repo, true); for (i = 0; i < reserved_len; i++) { - git_buf *r = &reserved[i]; + git_str *r = &reserved[i]; if (len >= r->size && strncasecmp(path, r->ptr, r->size) == 0) { @@ -1943,17 +1943,17 @@ int git_path_validate_workdir_with_len( return 0; } -int git_path_validate_workdir_buf(git_repository *repo, git_buf *path) +int git_path_validate_workdir_buf(git_repository *repo, git_str *path) { return git_path_validate_workdir_with_len(repo, path->ptr, path->size); } -int git_path_normalize_slashes(git_buf *out, const char *path) +int git_path_normalize_slashes(git_str *out, const char *path) { int error; char *p; - if ((error = git_buf_puts(out, path)) < 0) + if ((error = git_str_puts(out, path)) < 0) return error; for (p = out->ptr; *p; p++) { @@ -2004,7 +2004,7 @@ extern int git_path_is_gitfile(const char *path, size_t pathlen, git_path_gitfil bool git_path_supports_symlinks(const char *dir) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; bool supported = false; struct stat st; int fd; @@ -2020,7 +2020,7 @@ bool git_path_supports_symlinks(const char *dir) done: if (path.size) (void)p_unlink(path.ptr); - git_buf_dispose(&path); + git_str_dispose(&path); return supported; } diff --git a/src/path.h b/src/path.h index de6ec8ff248..4074c342598 100644 --- a/src/path.h +++ b/src/path.h @@ -10,7 +10,7 @@ #include "common.h" #include "posix.h" -#include "buffer.h" +#include "str.h" #include "vector.h" #include "git2/sys/path.h" @@ -35,13 +35,13 @@ * The `git_path_dirname` implementation is thread safe. The returned * string must be manually free'd. * - * The `git_path_dirname_r` implementation writes the dirname to a `git_buf` + * The `git_path_dirname_r` implementation writes the dirname to a `git_str` * if the buffer pointer is not NULL. * It returns an error code < 0 if there is an allocation error, otherwise * the length of the dirname (which will be > 0). */ extern char *git_path_dirname(const char *path); -extern int git_path_dirname_r(git_buf *buffer, const char *path); +extern int git_path_dirname_r(git_str *buffer, const char *path); /* * This function returns the basename of the file, which is the last @@ -55,17 +55,17 @@ extern int git_path_dirname_r(git_buf *buffer, const char *path); * The `git_path_basename` implementation is thread safe. The returned * string must be manually free'd. * - * The `git_path_basename_r` implementation writes the basename to a `git_buf`. + * The `git_path_basename_r` implementation writes the basename to a `git_str`. * It returns an error code < 0 if there is an allocation error, otherwise * the length of the basename (which will be >= 0). */ extern char *git_path_basename(const char *path); -extern int git_path_basename_r(git_buf *buffer, const char *path); +extern int git_path_basename_r(git_str *buffer, const char *path); /* Return the offset of the start of the basename. Unlike the other * basename functions, this returns 0 if the path is empty. */ -extern size_t git_path_basename_offset(git_buf *buffer); +extern size_t git_path_basename_offset(git_str *buffer); /** * Find offset to root of path if path has one. @@ -80,7 +80,7 @@ extern int git_path_root(const char *path); /** * Ensure path has a trailing '/'. */ -extern int git_path_to_dir(git_buf *path); +extern int git_path_to_dir(git_str *path); /** * Ensure string has a trailing '/' if there is space for it. @@ -150,12 +150,12 @@ GIT_INLINE(int) git_path_at_end_of_segment(const char *p) return !*p || *p == '/'; } -extern int git__percent_decode(git_buf *decoded_out, const char *input); +extern int git__percent_decode(git_str *decoded_out, const char *input); /** * Extract path from file:// URL. */ -extern int git_path_fromurl(git_buf *local_path_out, const char *file_url); +extern int git_path_fromurl(git_str *local_path_out, const char *file_url); /** @@ -205,7 +205,7 @@ extern int git_path_lstat(const char *path, struct stat *st); * @param item Item that might be in the directory. * @return 0 if item exists in directory, <0 otherwise. */ -extern bool git_path_contains(git_buf *dir, const char *item); +extern bool git_path_contains(git_str *dir, const char *item); /** * Check if the given path contains the given subdirectory. @@ -214,7 +214,7 @@ extern bool git_path_contains(git_buf *dir, const char *item); * @param subdir Subdirectory name to look for in parent * @return true if subdirectory exists, false otherwise. */ -extern bool git_path_contains_dir(git_buf *parent, const char *subdir); +extern bool git_path_contains_dir(git_str *parent, const char *subdir); /** * Determine the common directory length between two paths, including @@ -237,7 +237,7 @@ extern size_t git_path_common_dirlen(const char *one, const char *two); * if there was not common root between the paths, * or <0. */ -extern int git_path_make_relative(git_buf *path, const char *parent); +extern int git_path_make_relative(git_str *path, const char *parent); /** * Check if the given path contains the given file. @@ -246,7 +246,7 @@ extern int git_path_make_relative(git_buf *path, const char *parent); * @param file File name to look for in parent * @return true if file exists, false otherwise. */ -extern bool git_path_contains_file(git_buf *dir, const char *file); +extern bool git_path_contains_file(git_str *dir, const char *file); /** * Prepend base to unrooted path or just copy path over. @@ -255,24 +255,24 @@ extern bool git_path_contains_file(git_buf *dir, const char *file); * is, either the end of the base directory prefix or the path root. */ extern int git_path_join_unrooted( - git_buf *path_out, const char *path, const char *base, ssize_t *root_at); + git_str *path_out, const char *path, const char *base, ssize_t *root_at); /** * Removes multiple occurrences of '/' in a row, squashing them into a * single '/'. */ -extern void git_path_squash_slashes(git_buf *path); +extern void git_path_squash_slashes(git_str *path); /** * Clean up path, prepending base if it is not already rooted. */ -extern int git_path_prettify(git_buf *path_out, const char *path, const char *base); +extern int git_path_prettify(git_str *path_out, const char *path, const char *base); /** * Clean up path, prepending base if it is not already rooted and * appending a slash. */ -extern int git_path_prettify_dir(git_buf *path_out, const char *path, const char *base); +extern int git_path_prettify_dir(git_str *path_out, const char *path, const char *base); /** * Get a directory from a path. @@ -283,7 +283,7 @@ extern int git_path_prettify_dir(git_buf *path_out, const char *path, const char * appends the trailing '/'. If the path does not exist, it is * treated like a regular filename. */ -extern int git_path_find_dir(git_buf *dir); +extern int git_path_find_dir(git_str *dir); /** * Resolve relative references within a path. @@ -295,7 +295,7 @@ extern int git_path_find_dir(git_buf *dir); * Additionally, this will recognize an "c:/" drive prefix or a "xyz://" URL * prefix and not touch that part of the path. */ -extern int git_path_resolve_relative(git_buf *path, size_t ceiling); +extern int git_path_resolve_relative(git_str *path, size_t ceiling); /** * Apply a relative path to base path. @@ -306,7 +306,7 @@ extern int git_path_resolve_relative(git_buf *path, size_t ceiling); * slash, "." will be eaten with no change, and ".." will remove a * segment from the base path. */ -extern int git_path_apply_relative(git_buf *target, const char *relpath); +extern int git_path_apply_relative(git_str *target, const char *relpath); enum { GIT_PATH_DIR_IGNORE_CASE = (1u << 0), @@ -328,9 +328,9 @@ enum { * @return 0 on success or error code from OS error or from callback */ extern int git_path_direach( - git_buf *pathbuf, + git_str *pathbuf, uint32_t flags, - int (*callback)(void *payload, git_buf *path), + int (*callback)(void *payload, git_str *path), void *payload); /** @@ -360,7 +360,7 @@ extern int git_path_cmp( * @param payload Passed to fn as the first ath. */ extern int git_path_walk_up( - git_buf *pathbuf, + git_str *pathbuf, const char *ceiling, int (*callback)(void *payload, const char *path), void *payload); @@ -429,10 +429,10 @@ extern bool git_path_has_non_ascii(const char *path, size_t pathlen); typedef struct { iconv_t map; - git_buf buf; + git_str buf; } git_path_iconv_t; -#define GIT_PATH_ICONV_INIT { (iconv_t)-1, GIT_BUF_INIT } +#define GIT_PATH_ICONV_INIT { (iconv_t)-1, GIT_STR_INIT } /* Init iconv data for converting decomposed UTF-8 to precomposed */ extern int git_path_iconv_init_precompose(git_path_iconv_t *ic); @@ -461,7 +461,7 @@ struct git_path_diriter git_win32_path path; size_t parent_len; - git_buf path_utf8; + git_str path_utf8; size_t parent_utf8_len; HANDLE handle; @@ -472,13 +472,13 @@ struct git_path_diriter unsigned int needs_next; }; -#define GIT_PATH_DIRITER_INIT { {0}, 0, GIT_BUF_INIT, 0, INVALID_HANDLE_VALUE } +#define GIT_PATH_DIRITER_INIT { {0}, 0, GIT_STR_INIT, 0, INVALID_HANDLE_VALUE } #else struct git_path_diriter { - git_buf path; + git_str path; size_t parent_len; unsigned int flags; @@ -490,7 +490,7 @@ struct git_path_diriter #endif }; -#define GIT_PATH_DIRITER_INIT { GIT_BUF_INIT } +#define GIT_PATH_DIRITER_INIT { GIT_STR_INIT } #endif @@ -584,7 +584,7 @@ extern int git_path_dirload( /* Used for paths to repositories on the filesystem */ extern bool git_path_is_local_file_url(const char *file_url); -extern int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path); +extern int git_path_from_url_or_path(git_str *local_path_out, const char *url_or_path); /* Flags to determine path validity in `git_path_isvalid` */ #define GIT_PATH_REJECT_TRAVERSAL (1 << 0) @@ -713,12 +713,12 @@ extern int git_path_validate_workdir_with_len( size_t path_len); extern int git_path_validate_workdir_buf( git_repository *repo, - git_buf *buf); + git_str *buf); /** * Convert any backslashes into slashes */ -int git_path_normalize_slashes(git_buf *out, const char *path); +int git_path_normalize_slashes(git_str *out, const char *path); bool git_path_supports_symlinks(const char *dir); diff --git a/src/pathspec.c b/src/pathspec.c index c6ad16571ec..3e44643c675 100644 --- a/src/pathspec.c +++ b/src/pathspec.c @@ -20,11 +20,11 @@ /* what is the common non-wildcard prefix for all items in the pathspec */ char *git_pathspec_prefix(const git_strarray *pathspec) { - git_buf prefix = GIT_BUF_INIT; + git_str prefix = GIT_STR_INIT; const char *scan; if (!pathspec || !pathspec->count || - git_buf_common_prefix(&prefix, pathspec->strings, pathspec->count) < 0) + git_str_common_prefix(&prefix, pathspec->strings, pathspec->count) < 0) return NULL; /* diff prefix will only be leading non-wildcards */ @@ -33,16 +33,16 @@ char *git_pathspec_prefix(const git_strarray *pathspec) (scan == prefix.ptr || (*(scan - 1) != '\\'))) break; } - git_buf_truncate(&prefix, scan - prefix.ptr); + git_str_truncate(&prefix, scan - prefix.ptr); if (prefix.size <= 0) { - git_buf_dispose(&prefix); + git_str_dispose(&prefix); return NULL; } - git_buf_unescape(&prefix); + git_str_unescape(&prefix); - return git_buf_detach(&prefix); + return git_str_detach(&prefix); } /* is there anything in the spec that needs to be filtered on */ diff --git a/src/pathspec.h b/src/pathspec.h index c4d1a83d3b6..bfdcd48a707 100644 --- a/src/pathspec.h +++ b/src/pathspec.h @@ -10,7 +10,7 @@ #include "common.h" #include "git2/pathspec.h" -#include "buffer.h" +#include "str.h" #include "vector.h" #include "pool.h" #include "array.h" diff --git a/src/push.c b/src/push.c index b724188f977..3bf7ba5d920 100644 --- a/src/push.c +++ b/src/push.c @@ -159,7 +159,7 @@ int git_push_add_refspec(git_push *push, const char *refspec) int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks) { - git_buf remote_ref_name = GIT_BUF_INIT; + git_str remote_ref_name = GIT_STR_INIT; size_t i, j; git_refspec *fetch_spec; push_spec *push_spec = NULL; @@ -180,9 +180,9 @@ int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks) continue; /* Clear the buffer which can be dirty from previous iteration */ - git_buf_clear(&remote_ref_name); + git_str_clear(&remote_ref_name); - if ((error = git_refspec_transform(&remote_ref_name, fetch_spec, status->ref)) < 0) + if ((error = git_refspec__transform(&remote_ref_name, fetch_spec, status->ref)) < 0) goto on_error; /* Find matching push ref spec */ @@ -197,7 +197,7 @@ int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks) /* Update the remote ref */ if (git_oid_is_zero(&push_spec->loid)) { - error = git_reference_lookup(&remote_ref, push->remote->repo, git_buf_cstr(&remote_ref_name)); + error = git_reference_lookup(&remote_ref, push->remote->repo, git_str_cstr(&remote_ref_name)); if (error >= 0) { error = git_reference_delete(remote_ref); @@ -205,7 +205,7 @@ int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks) } } else { error = git_reference_create(NULL, push->remote->repo, - git_buf_cstr(&remote_ref_name), &push_spec->loid, 1, + git_str_cstr(&remote_ref_name), &push_spec->loid, 1, "update by push"); } @@ -218,7 +218,7 @@ int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks) } if (fire_callback && callbacks && callbacks->update_tips) { - error = callbacks->update_tips(git_buf_cstr(&remote_ref_name), + error = callbacks->update_tips(git_str_cstr(&remote_ref_name), &push_spec->roid, &push_spec->loid, callbacks->payload); if (error < 0) @@ -229,7 +229,7 @@ int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks) error = 0; on_error: - git_buf_dispose(&remote_ref_name); + git_str_dispose(&remote_ref_name); return error; } diff --git a/src/reader.c b/src/reader.c index 48928940dbc..ba9775240d0 100644 --- a/src/reader.c +++ b/src/reader.c @@ -23,7 +23,7 @@ typedef struct { } tree_reader; static int tree_reader_read( - git_buf *out, + git_str *out, git_oid *out_id, git_filemode_t *out_filemode, git_reader *_reader, @@ -42,7 +42,7 @@ static int tree_reader_read( blobsize = git_blob_rawsize(blob); GIT_ERROR_CHECK_BLOBSIZE(blobsize); - if ((error = git_buf_set(out, git_blob_rawcontent(blob), (size_t)blobsize)) < 0) + if ((error = git_str_set(out, git_blob_rawcontent(blob), (size_t)blobsize)) < 0) goto done; if (out_id) @@ -83,14 +83,14 @@ typedef struct { } workdir_reader; static int workdir_reader_read( - git_buf *out, + git_str *out, git_oid *out_id, git_filemode_t *out_filemode, git_reader *_reader, const char *filename) { workdir_reader *reader = (workdir_reader *)_reader; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; struct stat st; git_filemode_t filemode; git_filter_list *filters = NULL; @@ -120,7 +120,7 @@ static int workdir_reader_read( GIT_FILTER_TO_ODB, GIT_FILTER_DEFAULT)) < 0) goto done; - if ((error = git_filter_list_apply_to_file(out, + if ((error = git_filter_list__apply_to_file(out, filters, reader->repo, path.ptr)) < 0) goto done; @@ -146,7 +146,7 @@ static int workdir_reader_read( done: git_filter_list_free(filters); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -186,7 +186,7 @@ typedef struct { } index_reader; static int index_reader_read( - git_buf *out, + git_str *out, git_oid *out_id, git_filemode_t *out_filemode, git_reader *_reader, @@ -247,7 +247,7 @@ int git_reader_for_index( /* generic */ int git_reader_read( - git_buf *out, + git_str *out, git_oid *out_id, git_filemode_t *out_filemode, git_reader *reader, diff --git a/src/reader.h b/src/reader.h index 18a6a1103d7..b58dc93f673 100644 --- a/src/reader.h +++ b/src/reader.h @@ -25,7 +25,7 @@ typedef struct git_reader git_reader; * reader after disposing the underlying object that it reads. */ struct git_reader { - int (*read)(git_buf *out, git_oid *out_oid, git_filemode_t *mode, git_reader *reader, const char *filename); + int (*read)(git_str *out, git_oid *out_oid, git_filemode_t *mode, git_reader *reader, const char *filename); }; /** @@ -91,7 +91,7 @@ extern int git_reader_for_workdir( * @param filename The filename to read from the reader */ extern int git_reader_read( - git_buf *out, + git_str *out, git_oid *out_id, git_filemode_t *out_filemode, git_reader *reader, diff --git a/src/rebase.c b/src/rebase.c index 4f10c296bdd..302fc81fc20 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -7,10 +7,11 @@ #include "common.h" -#include "buffer.h" +#include "str.h" #include "repository.h" #include "posix.h" #include "filebuf.h" +#include "commit.h" #include "merge.h" #include "array.h" #include "config.h" @@ -90,22 +91,22 @@ static int rebase_state_type( char **path_out, git_repository *repo) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_rebase_t type = GIT_REBASE_NONE; - if (git_buf_joinpath(&path, repo->gitdir, REBASE_APPLY_DIR) < 0) + if (git_str_joinpath(&path, repo->gitdir, REBASE_APPLY_DIR) < 0) return -1; - if (git_path_isdir(git_buf_cstr(&path))) { + if (git_path_isdir(git_str_cstr(&path))) { type = GIT_REBASE_APPLY; goto done; } - git_buf_clear(&path); - if (git_buf_joinpath(&path, repo->gitdir, REBASE_MERGE_DIR) < 0) + git_str_clear(&path); + if (git_str_joinpath(&path, repo->gitdir, REBASE_MERGE_DIR) < 0) return -1; - if (git_path_isdir(git_buf_cstr(&path))) { + if (git_path_isdir(git_str_cstr(&path))) { type = GIT_REBASE_MERGE; goto done; } @@ -114,36 +115,36 @@ static int rebase_state_type( *type_out = type; if (type != GIT_REBASE_NONE && path_out) - *path_out = git_buf_detach(&path); + *path_out = git_str_detach(&path); - git_buf_dispose(&path); + git_str_dispose(&path); return 0; } GIT_INLINE(int) rebase_readfile( - git_buf *out, - git_buf *state_path, + git_str *out, + git_str *state_path, const char *filename) { size_t state_path_len = state_path->size; int error; - git_buf_clear(out); + git_str_clear(out); - if ((error = git_buf_joinpath(state_path, state_path->ptr, filename)) < 0 || + if ((error = git_str_joinpath(state_path, state_path->ptr, filename)) < 0 || (error = git_futils_readbuffer(out, state_path->ptr)) < 0) goto done; - git_buf_rtrim(out); + git_str_rtrim(out); done: - git_buf_truncate(state_path, state_path_len); + git_str_truncate(state_path, state_path_len); return error; } GIT_INLINE(int) rebase_readint( - size_t *out, git_buf *asc_out, git_buf *state_path, const char *filename) + size_t *out, git_str *asc_out, git_str *state_path, const char *filename) { int32_t num; const char *eol; @@ -163,7 +164,7 @@ GIT_INLINE(int) rebase_readint( } GIT_INLINE(int) rebase_readoid( - git_oid *out, git_buf *str_out, git_buf *state_path, const char *filename) + git_oid *out, git_str *str_out, git_str *state_path, const char *filename) { int error; @@ -201,13 +202,13 @@ static git_rebase_operation *rebase_operation_alloc( static int rebase_open_merge(git_rebase *rebase) { - git_buf state_path = GIT_BUF_INIT, buf = GIT_BUF_INIT, cmt = GIT_BUF_INIT; + git_str state_path = GIT_STR_INIT, buf = GIT_STR_INIT, cmt = GIT_STR_INIT; git_oid id; git_rebase_operation *operation; size_t i, msgnum = 0, end; int error; - if ((error = git_buf_puts(&state_path, rebase->state_path)) < 0) + if ((error = git_str_puts(&state_path, rebase->state_path)) < 0) goto done; /* Read 'msgnum' if it exists (otherwise, let msgnum = 0) */ @@ -234,9 +235,9 @@ static int rebase_open_merge(git_rebase *rebase) GIT_ERROR_CHECK_ARRAY(rebase->operations); for (i = 0; i < end; i++) { - git_buf_clear(&cmt); + git_str_clear(&cmt); - if ((error = git_buf_printf(&cmt, "cmt.%" PRIuZ, (i+1))) < 0 || + if ((error = git_str_printf(&cmt, "cmt.%" PRIuZ, (i+1))) < 0 || (error = rebase_readoid(&id, &buf, &state_path, cmt.ptr)) < 0) goto done; @@ -248,12 +249,12 @@ static int rebase_open_merge(git_rebase *rebase) if ((error = rebase_readfile(&buf, &state_path, ONTO_NAME_FILE)) < 0) goto done; - rebase->onto_name = git_buf_detach(&buf); + rebase->onto_name = git_str_detach(&buf); done: - git_buf_dispose(&cmt); - git_buf_dispose(&state_path); - git_buf_dispose(&buf); + git_str_dispose(&cmt); + git_str_dispose(&state_path); + git_str_dispose(&buf); return error; } @@ -296,8 +297,8 @@ int git_rebase_open( const git_rebase_options *given_opts) { git_rebase *rebase; - git_buf path = GIT_BUF_INIT, orig_head_name = GIT_BUF_INIT, - orig_head_id = GIT_BUF_INIT, onto_id = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, orig_head_name = GIT_STR_INIT, + orig_head_id = GIT_STR_INIT, onto_id = GIT_STR_INIT; size_t state_path_len; int error; @@ -320,54 +321,54 @@ int git_rebase_open( goto done; } - if ((error = git_buf_puts(&path, rebase->state_path)) < 0) + if ((error = git_str_puts(&path, rebase->state_path)) < 0) goto done; - state_path_len = git_buf_len(&path); + state_path_len = git_str_len(&path); - if ((error = git_buf_joinpath(&path, path.ptr, HEAD_NAME_FILE)) < 0 || + if ((error = git_str_joinpath(&path, path.ptr, HEAD_NAME_FILE)) < 0 || (error = git_futils_readbuffer(&orig_head_name, path.ptr)) < 0) goto done; - git_buf_rtrim(&orig_head_name); + git_str_rtrim(&orig_head_name); if (strcmp(ORIG_DETACHED_HEAD, orig_head_name.ptr) == 0) rebase->head_detached = 1; - git_buf_truncate(&path, state_path_len); + git_str_truncate(&path, state_path_len); - if ((error = git_buf_joinpath(&path, path.ptr, ORIG_HEAD_FILE)) < 0) + if ((error = git_str_joinpath(&path, path.ptr, ORIG_HEAD_FILE)) < 0) goto done; if (!git_path_isfile(path.ptr)) { /* Previous versions of git.git used 'head' here; support that. */ - git_buf_truncate(&path, state_path_len); + git_str_truncate(&path, state_path_len); - if ((error = git_buf_joinpath(&path, path.ptr, HEAD_FILE)) < 0) + if ((error = git_str_joinpath(&path, path.ptr, HEAD_FILE)) < 0) goto done; } if ((error = git_futils_readbuffer(&orig_head_id, path.ptr)) < 0) goto done; - git_buf_rtrim(&orig_head_id); + git_str_rtrim(&orig_head_id); if ((error = git_oid_fromstr(&rebase->orig_head_id, orig_head_id.ptr)) < 0) goto done; - git_buf_truncate(&path, state_path_len); + git_str_truncate(&path, state_path_len); - if ((error = git_buf_joinpath(&path, path.ptr, ONTO_FILE)) < 0 || + if ((error = git_str_joinpath(&path, path.ptr, ONTO_FILE)) < 0 || (error = git_futils_readbuffer(&onto_id, path.ptr)) < 0) goto done; - git_buf_rtrim(&onto_id); + git_str_rtrim(&onto_id); if ((error = git_oid_fromstr(&rebase->onto_id, onto_id.ptr)) < 0) goto done; if (!rebase->head_detached) - rebase->orig_head_name = git_buf_detach(&orig_head_name); + rebase->orig_head_name = git_str_detach(&orig_head_name); switch (rebase->type) { case GIT_REBASE_INTERACTIVE: @@ -391,10 +392,10 @@ int git_rebase_open( else git_rebase_free(rebase); - git_buf_dispose(&path); - git_buf_dispose(&orig_head_name); - git_buf_dispose(&orig_head_id); - git_buf_dispose(&onto_id); + git_str_dispose(&path); + git_str_dispose(&orig_head_name); + git_str_dispose(&orig_head_id); + git_str_dispose(&onto_id); return error; } @@ -410,20 +411,20 @@ static int rebase_cleanup(git_rebase *rebase) static int rebase_setupfile(git_rebase *rebase, const char *filename, int flags, const char *fmt, ...) { - git_buf path = GIT_BUF_INIT, - contents = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, + contents = GIT_STR_INIT; va_list ap; int error; va_start(ap, fmt); - git_buf_vprintf(&contents, fmt, ap); + git_str_vprintf(&contents, fmt, ap); va_end(ap); - if ((error = git_buf_joinpath(&path, rebase->state_path, filename)) == 0) + if ((error = git_str_joinpath(&path, rebase->state_path, filename)) == 0) error = git_futils_writebuffer(&contents, path.ptr, flags, REBASE_FILE_MODE); - git_buf_dispose(&path); - git_buf_dispose(&contents); + git_str_dispose(&path); + git_str_dispose(&contents); return error; } @@ -440,7 +441,7 @@ static const char *rebase_onto_name(const git_annotated_commit *onto) static int rebase_setupfiles_merge(git_rebase *rebase) { - git_buf commit_filename = GIT_BUF_INIT; + git_str commit_filename = GIT_STR_INIT; char id_str[GIT_OID_HEXSZ]; git_rebase_operation *operation; size_t i; @@ -453,8 +454,8 @@ static int rebase_setupfiles_merge(git_rebase *rebase) for (i = 0; i < git_array_size(rebase->operations); i++) { operation = git_array_get(rebase->operations, i); - git_buf_clear(&commit_filename); - git_buf_printf(&commit_filename, CMT_FILE_FMT, i+1); + git_str_clear(&commit_filename); + git_str_printf(&commit_filename, CMT_FILE_FMT, i+1); git_oid_fmt(id_str, &operation->id); @@ -464,7 +465,7 @@ static int rebase_setupfiles_merge(git_rebase *rebase) } done: - git_buf_dispose(&commit_filename); + git_str_dispose(&commit_filename); return error; } @@ -626,16 +627,16 @@ static int rebase_init_merge( { git_reference *head_ref = NULL; git_commit *onto_commit = NULL; - git_buf reflog = GIT_BUF_INIT; - git_buf state_path = GIT_BUF_INIT; + git_str reflog = GIT_STR_INIT; + git_str state_path = GIT_STR_INIT; int error; GIT_UNUSED(upstream); - if ((error = git_buf_joinpath(&state_path, repo->gitdir, REBASE_MERGE_DIR)) < 0) + if ((error = git_str_joinpath(&state_path, repo->gitdir, REBASE_MERGE_DIR)) < 0) goto done; - rebase->state_path = git_buf_detach(&state_path); + rebase->state_path = git_str_detach(&state_path); GIT_ERROR_CHECK_ALLOC(rebase->state_path); if (branch->ref_name && strcmp(branch->ref_name, "HEAD")) { @@ -654,7 +655,7 @@ static int rebase_init_merge( git_oid_cpy(&rebase->onto_id, git_annotated_commit_id(onto)); if ((error = rebase_setupfiles(rebase)) < 0 || - (error = git_buf_printf(&reflog, + (error = git_str_printf(&reflog, "rebase: checkout %s", rebase_onto_name(onto))) < 0 || (error = git_commit_lookup( &onto_commit, repo, git_annotated_commit_id(onto))) < 0 || @@ -667,8 +668,8 @@ static int rebase_init_merge( done: git_reference_free(head_ref); git_commit_free(onto_commit); - git_buf_dispose(&reflog); - git_buf_dispose(&state_path); + git_str_dispose(&reflog); + git_str_dispose(&state_path); return error; } @@ -795,7 +796,7 @@ static int rebase_next_merge( git_rebase_operation **out, git_rebase *rebase) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_commit *current_commit = NULL, *parent_commit = NULL; git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL; git_index *index = NULL; @@ -848,7 +849,7 @@ static int rebase_next_merge( git_tree_free(parent_tree); git_commit_free(parent_commit); git_commit_free(current_commit); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -955,14 +956,14 @@ static int create_signed( size_t parent_count, const git_commit **parents) { - git_buf commit_content = GIT_BUF_INIT, - commit_signature = GIT_BUF_INIT, - signature_field = GIT_BUF_INIT; + git_str commit_content = GIT_STR_INIT; + git_buf commit_signature = { NULL, 0, 0 }, + signature_field = { NULL, 0, 0 }; int error; git_error_clear(); - if ((error = git_commit_create_buffer(&commit_content, + if ((error = git_commit__create_buffer(&commit_content, rebase->repo, author, committer, message_encoding, message, tree, parent_count, parents)) < 0) goto done; @@ -986,7 +987,7 @@ static int create_signed( done: git_buf_dispose(&commit_signature); git_buf_dispose(&signature_field); - git_buf_dispose(&commit_content); + git_str_dispose(&commit_content); return error; } #endif @@ -1216,13 +1217,13 @@ int git_rebase_abort(git_rebase *rebase) return error; } -static int notes_ref_lookup(git_buf *out, git_rebase *rebase) +static int notes_ref_lookup(git_str *out, git_rebase *rebase) { git_config *config = NULL; int do_rewrite, error; if (rebase->options.rewrite_notes_ref) { - git_buf_attach_notowned(out, + git_str_attach_notowned(out, rebase->options.rewrite_notes_ref, strlen(rebase->options.rewrite_notes_ref)); return 0; @@ -1239,7 +1240,7 @@ static int notes_ref_lookup(git_buf *out, git_rebase *rebase) } error = do_rewrite ? - git_config_get_string_buf(out, config, "notes.rewriteref") : + git_config__get_string_buf(out, config, "notes.rewriteref") : GIT_ENOTFOUND; done: @@ -1294,7 +1295,7 @@ static int rebase_copy_notes( git_rebase *rebase, const git_signature *committer) { - git_buf path = GIT_BUF_INIT, rewritten = GIT_BUF_INIT, notes_ref = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, rewritten = GIT_STR_INIT, notes_ref = GIT_STR_INIT; char *pair_list, *fromstr, *tostr, *end; git_oid from, to; unsigned int linenum = 1; @@ -1309,7 +1310,7 @@ static int rebase_copy_notes( goto done; } - if ((error = git_buf_joinpath(&path, rebase->state_path, REWRITTEN_FILE)) < 0 || + if ((error = git_str_joinpath(&path, rebase->state_path, REWRITTEN_FILE)) < 0 || (error = git_futils_readbuffer(&rewritten, path.ptr)) < 0) goto done; @@ -1349,9 +1350,9 @@ static int rebase_copy_notes( error = -1; done: - git_buf_dispose(&rewritten); - git_buf_dispose(&path); - git_buf_dispose(¬es_ref); + git_str_dispose(&rewritten); + git_str_dispose(&path); + git_str_dispose(¬es_ref); return error; } @@ -1360,16 +1361,16 @@ static int return_to_orig_head(git_rebase *rebase) { git_reference *terminal_ref = NULL, *branch_ref = NULL, *head_ref = NULL; git_commit *terminal_commit = NULL; - git_buf branch_msg = GIT_BUF_INIT, head_msg = GIT_BUF_INIT; + git_str branch_msg = GIT_STR_INIT, head_msg = GIT_STR_INIT; char onto[GIT_OID_HEXSZ]; int error = 0; git_oid_fmt(onto, &rebase->onto_id); - if ((error = git_buf_printf(&branch_msg, + if ((error = git_str_printf(&branch_msg, "rebase finished: %s onto %.*s", rebase->orig_head_name, GIT_OID_HEXSZ, onto)) == 0 && - (error = git_buf_printf(&head_msg, + (error = git_str_printf(&head_msg, "rebase finished: returning to %s", rebase->orig_head_name)) == 0 && (error = git_repository_head(&terminal_ref, rebase->repo)) == 0 && @@ -1383,8 +1384,8 @@ static int return_to_orig_head(git_rebase *rebase) rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1, head_msg.ptr); - git_buf_dispose(&head_msg); - git_buf_dispose(&branch_msg); + git_str_dispose(&head_msg); + git_str_dispose(&branch_msg); git_commit_free(terminal_commit); git_reference_free(head_ref); git_reference_free(branch_ref); diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 24cb22fb06f..37eb85ecc4d 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -69,11 +69,11 @@ typedef struct refdb_fs_backend { static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name); GIT_INLINE(int) loose_path( - git_buf *out, + git_str *out, const char *base, const char *refname) { - if (git_buf_joinpath(out, base, refname) < 0) + if (git_str_joinpath(out, base, refname) < 0) return -1; return git_path_validate_filesystem_with_suffix(out->ptr, out->size, @@ -81,7 +81,7 @@ GIT_INLINE(int) loose_path( } GIT_INLINE(int) reflog_path( - git_buf *out, + git_str *out, git_repository *repo, const char *refname) { @@ -91,7 +91,7 @@ GIT_INLINE(int) reflog_path( base = (strcmp(refname, GIT_HEAD_FILE) == 0) ? repo->gitdir : repo->commondir; - if ((error = git_buf_joinpath(out, base, GIT_REFLOG_DIR)) < 0) + if ((error = git_str_joinpath(out, base, GIT_REFLOG_DIR)) < 0) return error; return loose_path(out, out->ptr, refname); @@ -106,7 +106,7 @@ static int packref_cmp(const void *a_, const void *b_) static int packed_reload(refdb_fs_backend *backend) { int error; - git_buf packedrefs = GIT_BUF_INIT; + git_str packedrefs = GIT_STR_INIT; char *scan, *eof, *eol; if (!backend->gitpath) @@ -212,7 +212,7 @@ static int packed_reload(refdb_fs_backend *backend) } git_sortedcache_wunlock(backend->refcache); - git_buf_dispose(&packedrefs); + git_str_dispose(&packedrefs); return 0; @@ -221,17 +221,17 @@ static int packed_reload(refdb_fs_backend *backend) GIT_UNUSED(git_sortedcache_clear(backend->refcache, false)); git_sortedcache_wunlock(backend->refcache); - git_buf_dispose(&packedrefs); + git_str_dispose(&packedrefs); return -1; } static int loose_parse_oid( - git_oid *oid, const char *filename, git_buf *file_content) + git_oid *oid, const char *filename, git_str *file_content) { - const char *str = git_buf_cstr(file_content); + const char *str = git_str_cstr(file_content); - if (git_buf_len(file_content) < GIT_OID_HEXSZ) + if (git_str_len(file_content) < GIT_OID_HEXSZ) goto corrupted; /* we need to get 40 OID characters from the file */ @@ -248,13 +248,13 @@ static int loose_parse_oid( return -1; } -static int loose_readbuffer(git_buf *buf, const char *base, const char *path) +static int loose_readbuffer(git_str *buf, const char *base, const char *path) { int error; if ((error = loose_path(buf, base, path)) < 0 || (error = git_futils_readbuffer(buf, buf->ptr)) < 0) - git_buf_dispose(buf); + git_str_dispose(buf); return error; } @@ -262,7 +262,7 @@ static int loose_readbuffer(git_buf *buf, const char *base, const char *path) static int loose_lookup_to_packfile(refdb_fs_backend *backend, const char *name) { int error = 0; - git_buf ref_file = GIT_BUF_INIT; + git_str ref_file = GIT_STR_INIT; struct packref *ref = NULL; git_oid oid; @@ -275,7 +275,7 @@ static int loose_lookup_to_packfile(refdb_fs_backend *backend, const char *name) } /* skip symbolic refs */ - if (!git__prefixcmp(git_buf_cstr(&ref_file), GIT_SYMREF)) + if (!git__prefixcmp(git_str_cstr(&ref_file), GIT_SYMREF)) goto done; /* parse OID from file */ @@ -295,11 +295,11 @@ static int loose_lookup_to_packfile(refdb_fs_backend *backend, const char *name) git_sortedcache_wunlock(backend->refcache); done: - git_buf_dispose(&ref_file); + git_str_dispose(&ref_file); return error; } -static int _dirent_loose_load(void *payload, git_buf *full_path) +static int _dirent_loose_load(void *payload, git_str *full_path) { refdb_fs_backend *backend = payload; const char *file_path; @@ -333,9 +333,9 @@ static int _dirent_loose_load(void *payload, git_buf *full_path) static int packed_loadloose(refdb_fs_backend *backend) { int error; - git_buf refs_path = GIT_BUF_INIT; + git_str refs_path = GIT_STR_INIT; - if (git_buf_joinpath(&refs_path, backend->gitpath, GIT_REFS_DIR) < 0) + if (git_str_joinpath(&refs_path, backend->gitpath, GIT_REFS_DIR) < 0) return -1; /* @@ -346,7 +346,7 @@ static int packed_loadloose(refdb_fs_backend *backend) error = git_path_direach( &refs_path, backend->direach_flags, _dirent_loose_load, backend); - git_buf_dispose(&refs_path); + git_str_dispose(&refs_path); return error; } @@ -357,7 +357,7 @@ static int refdb_fs_backend__exists( const char *ref_name) { refdb_fs_backend *backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); - git_buf ref_path = GIT_BUF_INIT; + git_str ref_path = GIT_STR_INIT; int error; GIT_ASSERT_ARG(backend); @@ -381,18 +381,18 @@ static int refdb_fs_backend__exists( } out: - git_buf_dispose(&ref_path); + git_str_dispose(&ref_path); return error; } -static const char *loose_parse_symbolic(git_buf *file_content) +static const char *loose_parse_symbolic(git_str *file_content) { const unsigned int header_len = (unsigned int)strlen(GIT_SYMREF); const char *refname_start; refname_start = (const char *)file_content->ptr; - if (git_buf_len(file_content) < header_len + 1) { + if (git_str_len(file_content) < header_len + 1) { git_error_set(GIT_ERROR_REFERENCE, "corrupted loose reference file"); return NULL; } @@ -424,7 +424,7 @@ static int loose_lookup( refdb_fs_backend *backend, const char *ref_name) { - git_buf ref_file = GIT_BUF_INIT; + git_str ref_file = GIT_STR_INIT; int error = 0; const char *ref_dir; @@ -438,10 +438,10 @@ static int loose_lookup( if ((error = loose_readbuffer(&ref_file, ref_dir, ref_name)) < 0) /* cannot read loose ref file - gah */; - else if (git__prefixcmp(git_buf_cstr(&ref_file), GIT_SYMREF) == 0) { + else if (git__prefixcmp(git_str_cstr(&ref_file), GIT_SYMREF) == 0) { const char *target; - git_buf_rtrim(&ref_file); + git_str_rtrim(&ref_file); if (!(target = loose_parse_symbolic(&ref_file))) error = -1; @@ -455,7 +455,7 @@ static int loose_lookup( *out = git_reference__alloc(ref_name, &oid, NULL); } - git_buf_dispose(&ref_file); + git_str_dispose(&ref_file); return error; } @@ -542,7 +542,7 @@ static void refdb_fs_backend__iterator_free(git_reference_iterator *_iter) static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter) { int error = 0; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_iterator *fsit = NULL; git_iterator_options fsit_opts = GIT_ITERATOR_OPTIONS_INIT; const git_index_entry *entry = NULL; @@ -578,26 +578,26 @@ static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter) } } - if ((error = git_buf_puts(&path, backend->commonpath)) < 0 || - (error = git_buf_put(&path, ref_prefix, ref_prefix_len)) < 0) { - git_buf_dispose(&path); + if ((error = git_str_puts(&path, backend->commonpath)) < 0 || + (error = git_str_put(&path, ref_prefix, ref_prefix_len)) < 0) { + git_str_dispose(&path); return error; } if ((error = git_iterator_for_filesystem(&fsit, path.ptr, &fsit_opts)) < 0) { - git_buf_dispose(&path); + git_str_dispose(&path); return (iter->glob && error == GIT_ENOTFOUND)? 0 : error; } - error = git_buf_sets(&path, ref_prefix); + error = git_str_sets(&path, ref_prefix); while (!error && !git_iterator_advance(&entry, fsit)) { const char *ref_name; char *ref_dup; - git_buf_truncate(&path, ref_prefix_len); - git_buf_puts(&path, entry->path); - ref_name = git_buf_cstr(&path); + git_str_truncate(&path, ref_prefix_len); + git_str_puts(&path, entry->path); + ref_name = git_str_cstr(&path); if (git__suffixcmp(ref_name, ".lock") == 0 || (iter->glob && wildmatch(iter->glob, ref_name, 0) != 0)) @@ -611,7 +611,7 @@ static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter) } git_iterator_free(fsit); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -810,7 +810,7 @@ static int reference_path_available( static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *name) { int error, filebuf_flags; - git_buf ref_path = GIT_BUF_INIT; + git_str ref_path = GIT_STR_INIT; const char *basedir; GIT_ASSERT_ARG(file); @@ -845,7 +845,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char * if (error == GIT_EDIRECTORY) git_error_set(GIT_ERROR_REFERENCE, "cannot lock ref '%s', there are refs beneath that folder", name); - git_buf_dispose(&ref_path); + git_str_dispose(&ref_path); return error; } @@ -1013,7 +1013,7 @@ static int packed_remove_loose(refdb_fs_backend *backend) { size_t i; git_filebuf lock = GIT_FILEBUF_INIT; - git_buf ref_content = GIT_BUF_INIT; + git_str ref_content = GIT_STR_INIT; int error = 0; /* backend->refcache is already locked when this is called */ @@ -1034,7 +1034,7 @@ static int packed_remove_loose(refdb_fs_backend *backend) continue; if (error < 0) { - git_buf_dispose(&ref_content); + git_str_dispose(&ref_content); git_error_set(GIT_ERROR_REFERENCE, "failed to lock loose reference '%s'", ref->name); return error; } @@ -1065,7 +1065,7 @@ static int packed_remove_loose(refdb_fs_backend *backend) p_unlink(lock.path_original); } - git_buf_dispose(&ref_content); + git_str_dispose(&ref_content); git_filebuf_cleanup(&lock); return 0; } @@ -1333,32 +1333,32 @@ static int refdb_fs_backend__prune_refs( const char *ref_name, const char *prefix) { - git_buf relative_path = GIT_BUF_INIT; - git_buf base_path = GIT_BUF_INIT; + git_str relative_path = GIT_STR_INIT; + git_str base_path = GIT_STR_INIT; size_t commonlen; int error; GIT_ASSERT_ARG(backend); GIT_ASSERT_ARG(ref_name); - if ((error = git_buf_sets(&relative_path, ref_name)) < 0) + if ((error = git_str_sets(&relative_path, ref_name)) < 0) goto cleanup; git_path_squash_slashes(&relative_path); - if ((commonlen = git_path_common_dirlen("refs/heads/", git_buf_cstr(&relative_path))) == strlen("refs/heads/") || - (commonlen = git_path_common_dirlen("refs/tags/", git_buf_cstr(&relative_path))) == strlen("refs/tags/") || - (commonlen = git_path_common_dirlen("refs/remotes/", git_buf_cstr(&relative_path))) == strlen("refs/remotes/")) { + if ((commonlen = git_path_common_dirlen("refs/heads/", git_str_cstr(&relative_path))) == strlen("refs/heads/") || + (commonlen = git_path_common_dirlen("refs/tags/", git_str_cstr(&relative_path))) == strlen("refs/tags/") || + (commonlen = git_path_common_dirlen("refs/remotes/", git_str_cstr(&relative_path))) == strlen("refs/remotes/")) { - git_buf_truncate(&relative_path, commonlen); + git_str_truncate(&relative_path, commonlen); if (prefix) - error = git_buf_join3(&base_path, '/', + error = git_str_join3(&base_path, '/', backend->commonpath, prefix, - git_buf_cstr(&relative_path)); + git_str_cstr(&relative_path)); else - error = git_buf_joinpath(&base_path, + error = git_str_joinpath(&base_path, backend->commonpath, - git_buf_cstr(&relative_path)); + git_str_cstr(&relative_path)); if (!error) error = git_path_validate_filesystem(base_path.ptr, base_path.size); @@ -1367,7 +1367,7 @@ static int refdb_fs_backend__prune_refs( goto cleanup; error = git_futils_rmdir_r(ref_name + commonlen, - git_buf_cstr(&base_path), + git_str_cstr(&base_path), GIT_RMDIR_EMPTY_PARENTS | GIT_RMDIR_SKIP_ROOT); if (error == GIT_ENOTFOUND) @@ -1375,8 +1375,8 @@ static int refdb_fs_backend__prune_refs( } cleanup: - git_buf_dispose(&relative_path); - git_buf_dispose(&base_path); + git_str_dispose(&relative_path); + git_str_dispose(&base_path); return error; } @@ -1405,7 +1405,7 @@ static int refdb_fs_backend__delete( static int loose_delete(refdb_fs_backend *backend, const char *ref_name) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error = 0; if ((error = loose_path(&path, backend->commonpath, ref_name)) < 0) @@ -1417,7 +1417,7 @@ static int loose_delete(refdb_fs_backend *backend, const char *ref_name) else if (error != 0) error = -1; - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -1574,17 +1574,17 @@ static void refdb_fs_backend__free(git_refdb_backend *_backend) static char *setup_namespace(git_repository *repo, const char *in) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; char *parts, *start, *end, *out = NULL; if (!in) goto done; - git_buf_puts(&path, in); + git_str_puts(&path, in); /* if the repo is not namespaced, nothing else to do */ if (repo->namespace == NULL) { - out = git_buf_detach(&path); + out = git_str_detach(&path); goto done; } @@ -1599,23 +1599,23 @@ static char *setup_namespace(git_repository *repo, const char *in) * refs under refs/namespaces/foo/refs/namespaces/bar/ */ while ((start = git__strsep(&end, "/")) != NULL) - git_buf_printf(&path, "refs/namespaces/%s/", start); + git_str_printf(&path, "refs/namespaces/%s/", start); - git_buf_printf(&path, "refs/namespaces/%s/refs", end); + git_str_printf(&path, "refs/namespaces/%s/refs", end); git__free(parts); /* Make sure that the folder with the namespace exists */ - if (git_futils_mkdir_relative(git_buf_cstr(&path), in, 0777, + if (git_futils_mkdir_relative(git_str_cstr(&path), in, 0777, GIT_MKDIR_PATH, NULL) < 0) goto done; /* Return root of the namespaced gitpath, i.e. without the trailing 'refs' */ - git_buf_rtruncate_at_char(&path, '/'); - git_buf_putc(&path, '/'); - out = git_buf_detach(&path); + git_str_rtruncate_at_char(&path, '/'); + git_str_putc(&path, '/'); + out = git_str_detach(&path); done: - git_buf_dispose(&path); + git_str_dispose(&path); return out; } @@ -1716,7 +1716,7 @@ static int refdb_reflog_fs__ensure_log(git_refdb_backend *_backend, const char * { refdb_fs_backend *backend; git_repository *repo; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error; GIT_ASSERT_ARG(_backend && name); @@ -1727,8 +1727,8 @@ static int refdb_reflog_fs__ensure_log(git_refdb_backend *_backend, const char * if ((error = reflog_path(&path, repo, name)) < 0) return error; - error = create_new_reflog_file(git_buf_cstr(&path)); - git_buf_dispose(&path); + error = create_new_reflog_file(git_str_cstr(&path)); + git_str_dispose(&path); return error; } @@ -1736,15 +1736,15 @@ static int refdb_reflog_fs__ensure_log(git_refdb_backend *_backend, const char * static int has_reflog(git_repository *repo, const char *name) { int ret = 0; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; if (reflog_path(&path, repo, name) < 0) goto cleanup; - ret = git_path_isfile(git_buf_cstr(&path)); + ret = git_path_isfile(git_str_cstr(&path)); cleanup: - git_buf_dispose(&path); + git_str_dispose(&path); return ret; } @@ -1763,8 +1763,8 @@ static int refdb_reflog_fs__has_log(git_refdb_backend *_backend, const char *nam static int refdb_reflog_fs__read(git_reflog **out, git_refdb_backend *_backend, const char *name) { int error = -1; - git_buf log_path = GIT_BUF_INIT; - git_buf log_file = GIT_BUF_INIT; + git_str log_path = GIT_STR_INIT; + git_str log_file = GIT_STR_INIT; git_reflog *log = NULL; git_repository *repo; refdb_fs_backend *backend; @@ -1782,16 +1782,16 @@ static int refdb_reflog_fs__read(git_reflog **out, git_refdb_backend *_backend, if (reflog_path(&log_path, repo, name) < 0) goto cleanup; - error = git_futils_readbuffer(&log_file, git_buf_cstr(&log_path)); + error = git_futils_readbuffer(&log_file, git_str_cstr(&log_path)); if (error < 0 && error != GIT_ENOTFOUND) goto cleanup; if ((error == GIT_ENOTFOUND) && - ((error = create_new_reflog_file(git_buf_cstr(&log_path))) < 0)) + ((error = create_new_reflog_file(git_str_cstr(&log_path))) < 0)) goto cleanup; if ((error = reflog_parse(log, - git_buf_cstr(&log_file), git_buf_len(&log_file))) < 0) + git_str_cstr(&log_file), git_str_len(&log_file))) < 0) goto cleanup; *out = log; @@ -1801,14 +1801,14 @@ static int refdb_reflog_fs__read(git_reflog **out, git_refdb_backend *_backend, git_reflog_free(log); success: - git_buf_dispose(&log_file); - git_buf_dispose(&log_path); + git_str_dispose(&log_file); + git_str_dispose(&log_path); return error; } static int serialize_reflog_entry( - git_buf *buf, + git_str *buf, const git_oid *oid_old, const git_oid *oid_new, const git_signature *committer, @@ -1820,38 +1820,38 @@ static int serialize_reflog_entry( git_oid_tostr(raw_old, GIT_OID_HEXSZ+1, oid_old); git_oid_tostr(raw_new, GIT_OID_HEXSZ+1, oid_new); - git_buf_clear(buf); + git_str_clear(buf); - git_buf_puts(buf, raw_old); - git_buf_putc(buf, ' '); - git_buf_puts(buf, raw_new); + git_str_puts(buf, raw_old); + git_str_putc(buf, ' '); + git_str_puts(buf, raw_new); git_signature__writebuf(buf, " ", committer); /* drop trailing LF */ - git_buf_rtrim(buf); + git_str_rtrim(buf); if (msg) { size_t i; - git_buf_putc(buf, '\t'); - git_buf_puts(buf, msg); + git_str_putc(buf, '\t'); + git_str_puts(buf, msg); for (i = 0; i < buf->size - 2; i++) if (buf->ptr[i] == '\n') buf->ptr[i] = ' '; - git_buf_rtrim(buf); + git_str_rtrim(buf); } - git_buf_putc(buf, '\n'); + git_str_putc(buf, '\n'); - return git_buf_oom(buf); + return git_str_oom(buf); } static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char *refname) { git_repository *repo; - git_buf log_path = GIT_BUF_INIT; + git_str log_path = GIT_STR_INIT; int error; repo = backend->repo; @@ -1864,17 +1864,17 @@ static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char if (reflog_path(&log_path, repo, refname) < 0) return -1; - if (!git_path_isfile(git_buf_cstr(&log_path))) { + if (!git_path_isfile(git_str_cstr(&log_path))) { git_error_set(GIT_ERROR_INVALID, "log file for reference '%s' doesn't exist", refname); error = -1; goto cleanup; } - error = git_filebuf_open(file, git_buf_cstr(&log_path), 0, GIT_REFLOG_FILE_MODE); + error = git_filebuf_open(file, git_str_cstr(&log_path), 0, GIT_REFLOG_FILE_MODE); cleanup: - git_buf_dispose(&log_path); + git_str_dispose(&log_path); return error; } @@ -1885,7 +1885,7 @@ static int refdb_reflog_fs__write(git_refdb_backend *_backend, git_reflog *reflo unsigned int i; git_reflog_entry *entry; refdb_fs_backend *backend; - git_buf log = GIT_BUF_INIT; + git_str log = GIT_STR_INIT; git_filebuf fbuf = GIT_FILEBUF_INIT; GIT_ASSERT_ARG(_backend); @@ -1911,7 +1911,7 @@ static int refdb_reflog_fs__write(git_refdb_backend *_backend, git_reflog *reflo git_filebuf_cleanup(&fbuf); success: - git_buf_dispose(&log); + git_str_dispose(&log); return error; } @@ -1921,7 +1921,7 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co { int error, is_symbolic, open_flags; git_oid old_id = {{0}}, new_id = {{0}}; - git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT, path = GIT_STR_INIT; git_repository *repo = backend->repo; is_symbolic = ref->type == GIT_REFERENCE_SYMBOLIC; @@ -1965,7 +1965,7 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co if ((error = reflog_path(&path, repo, ref->name)) < 0) goto cleanup; - if (((error = git_futils_mkpath2file(git_buf_cstr(&path), 0777)) < 0) && + if (((error = git_futils_mkpath2file(git_str_cstr(&path), 0777)) < 0) && (error != GIT_EEXISTS)) { goto cleanup; } @@ -1973,11 +1973,11 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co /* If the new branch matches part of the namespace of a previously deleted branch, * there maybe an obsolete/unused directory (or directory hierarchy) in the way. */ - if (git_path_isdir(git_buf_cstr(&path))) { - if ((error = git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_SKIP_NONEMPTY)) < 0) { + if (git_path_isdir(git_str_cstr(&path))) { + if ((error = git_futils_rmdir_r(git_str_cstr(&path), NULL, GIT_RMDIR_SKIP_NONEMPTY)) < 0) { if (error == GIT_ENOTFOUND) error = 0; - } else if (git_path_isdir(git_buf_cstr(&path))) { + } else if (git_path_isdir(git_str_cstr(&path))) { git_error_set(GIT_ERROR_REFERENCE, "cannot create reflog at '%s', there are reflogs beneath that folder", ref->name); error = GIT_EDIRECTORY; @@ -1992,11 +1992,11 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co if (backend->fsync) open_flags |= O_FSYNC; - error = git_futils_writebuffer(&buf, git_buf_cstr(&path), open_flags, GIT_REFLOG_FILE_MODE); + error = git_futils_writebuffer(&buf, git_str_cstr(&path), open_flags, GIT_REFLOG_FILE_MODE); cleanup: - git_buf_dispose(&buf); - git_buf_dispose(&path); + git_str_dispose(&buf); + git_str_dispose(&path); return error; } @@ -2004,10 +2004,10 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_name, const char *new_name) { int error = 0, fd; - git_buf old_path = GIT_BUF_INIT; - git_buf new_path = GIT_BUF_INIT; - git_buf temp_path = GIT_BUF_INIT; - git_buf normalized = GIT_BUF_INIT; + git_str old_path = GIT_STR_INIT; + git_str new_path = GIT_STR_INIT; + git_str temp_path = GIT_STR_INIT; + git_str normalized = GIT_STR_INIT; git_repository *repo; refdb_fs_backend *backend; @@ -2022,16 +2022,16 @@ static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_ &normalized, new_name, GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL)) < 0) return error; - if (git_buf_joinpath(&temp_path, repo->gitdir, GIT_REFLOG_DIR) < 0) + if (git_str_joinpath(&temp_path, repo->gitdir, GIT_REFLOG_DIR) < 0) return -1; - if ((error = loose_path(&old_path, git_buf_cstr(&temp_path), old_name)) < 0) + if ((error = loose_path(&old_path, git_str_cstr(&temp_path), old_name)) < 0) return error; - if ((error = loose_path(&new_path, git_buf_cstr(&temp_path), git_buf_cstr(&normalized))) < 0) + if ((error = loose_path(&new_path, git_str_cstr(&temp_path), git_str_cstr(&normalized))) < 0) return error; - if (!git_path_exists(git_buf_cstr(&old_path))) { + if (!git_path_exists(git_str_cstr(&old_path))) { error = GIT_ENOTFOUND; goto cleanup; } @@ -2043,43 +2043,43 @@ static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_ * - a/b -> a/b/c * - a/b/c/d -> a/b/c */ - if ((error = loose_path(&temp_path, git_buf_cstr(&temp_path), "temp_reflog")) < 0) + if ((error = loose_path(&temp_path, git_str_cstr(&temp_path), "temp_reflog")) < 0) return error; - if ((fd = git_futils_mktmp(&temp_path, git_buf_cstr(&temp_path), GIT_REFLOG_FILE_MODE)) < 0) { + if ((fd = git_futils_mktmp(&temp_path, git_str_cstr(&temp_path), GIT_REFLOG_FILE_MODE)) < 0) { error = -1; goto cleanup; } p_close(fd); - if (p_rename(git_buf_cstr(&old_path), git_buf_cstr(&temp_path)) < 0) { + if (p_rename(git_str_cstr(&old_path), git_str_cstr(&temp_path)) < 0) { git_error_set(GIT_ERROR_OS, "failed to rename reflog for %s", new_name); error = -1; goto cleanup; } - if (git_path_isdir(git_buf_cstr(&new_path)) && - (git_futils_rmdir_r(git_buf_cstr(&new_path), NULL, GIT_RMDIR_SKIP_NONEMPTY) < 0)) { + if (git_path_isdir(git_str_cstr(&new_path)) && + (git_futils_rmdir_r(git_str_cstr(&new_path), NULL, GIT_RMDIR_SKIP_NONEMPTY) < 0)) { error = -1; goto cleanup; } - if (git_futils_mkpath2file(git_buf_cstr(&new_path), GIT_REFLOG_DIR_MODE) < 0) { + if (git_futils_mkpath2file(git_str_cstr(&new_path), GIT_REFLOG_DIR_MODE) < 0) { error = -1; goto cleanup; } - if (p_rename(git_buf_cstr(&temp_path), git_buf_cstr(&new_path)) < 0) { + if (p_rename(git_str_cstr(&temp_path), git_str_cstr(&new_path)) < 0) { git_error_set(GIT_ERROR_OS, "failed to rename reflog for %s", new_name); error = -1; } cleanup: - git_buf_dispose(&temp_path); - git_buf_dispose(&old_path); - git_buf_dispose(&new_path); - git_buf_dispose(&normalized); + git_str_dispose(&temp_path); + git_str_dispose(&old_path); + git_str_dispose(&new_path); + git_str_dispose(&normalized); return error; } @@ -2087,7 +2087,7 @@ static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_ static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name) { refdb_fs_backend *backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error; GIT_ASSERT_ARG(_backend); @@ -2105,7 +2105,7 @@ static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name error = refdb_fs_backend__prune_refs(backend, name, GIT_REFLOG_DIR); out: - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -2115,7 +2115,7 @@ int git_refdb_backend_fs( git_repository *repository) { int t = 0; - git_buf gitpath = GIT_BUF_INIT; + git_str gitpath = GIT_STR_INIT; refdb_fs_backend *backend; backend = git__calloc(1, sizeof(refdb_fs_backend)); @@ -2140,13 +2140,13 @@ int git_refdb_backend_fs( goto fail; } - if (git_buf_joinpath(&gitpath, backend->commonpath, GIT_PACKEDREFS_FILE) < 0 || + if (git_str_joinpath(&gitpath, backend->commonpath, GIT_PACKEDREFS_FILE) < 0 || git_sortedcache_new( &backend->refcache, offsetof(struct packref, name), - NULL, NULL, packref_cmp, git_buf_cstr(&gitpath)) < 0) + NULL, NULL, packref_cmp, git_str_cstr(&gitpath)) < 0) goto fail; - git_buf_dispose(&gitpath); + git_str_dispose(&gitpath); if (!git_repository__configmap_lookup(&t, backend->repo, GIT_CONFIGMAP_IGNORECASE) && t) { backend->iterator_flags |= GIT_ITERATOR_IGNORE_CASE; @@ -2182,7 +2182,7 @@ int git_refdb_backend_fs( return 0; fail: - git_buf_dispose(&gitpath); + git_str_dispose(&gitpath); git__free(backend->gitpath); git__free(backend->commonpath); git__free(backend); diff --git a/src/refs.c b/src/refs.c index 8acfa84a5a6..0ac455d2481 100644 --- a/src/refs.c +++ b/src/refs.c @@ -247,7 +247,7 @@ int git_reference_dwim(git_reference **out, git_repository *repo, const char *re int error = 0, i, valid; bool fallbackmode = true, foundvalid = false; git_reference *ref; - git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT; + git_str refnamebuf = GIT_STR_INIT, name = GIT_STR_INIT; static const char *formatters[] = { "%s", @@ -260,18 +260,18 @@ int git_reference_dwim(git_reference **out, git_repository *repo, const char *re }; if (*refname) - git_buf_puts(&name, refname); + git_str_puts(&name, refname); else { - git_buf_puts(&name, GIT_HEAD_FILE); + git_str_puts(&name, GIT_HEAD_FILE); fallbackmode = false; } for (i = 0; formatters[i] && (fallbackmode || i == 0); i++) { - git_buf_clear(&refnamebuf); + git_str_clear(&refnamebuf); - if ((error = git_buf_printf(&refnamebuf, formatters[i], git_buf_cstr(&name))) < 0 || - (error = git_reference_name_is_valid(&valid, git_buf_cstr(&refnamebuf))) < 0) + if ((error = git_str_printf(&refnamebuf, formatters[i], git_str_cstr(&name))) < 0 || + (error = git_reference_name_is_valid(&valid, git_str_cstr(&refnamebuf))) < 0) goto cleanup; if (!valid) { @@ -280,7 +280,7 @@ int git_reference_dwim(git_reference **out, git_repository *repo, const char *re } foundvalid = true; - error = git_reference_lookup_resolved(&ref, repo, git_buf_cstr(&refnamebuf), -1); + error = git_reference_lookup_resolved(&ref, repo, git_str_cstr(&refnamebuf), -1); if (!error) { *out = ref; @@ -296,14 +296,14 @@ int git_reference_dwim(git_reference **out, git_repository *repo, const char *re if (error && !foundvalid) { /* never found a valid reference name */ git_error_set(GIT_ERROR_REFERENCE, - "could not use '%s' as valid reference name", git_buf_cstr(&name)); + "could not use '%s' as valid reference name", git_str_cstr(&name)); } if (error == GIT_ENOTFOUND) git_error_set(GIT_ERROR_REFERENCE, "no reference found for shorthand '%s'", refname); - git_buf_dispose(&name); - git_buf_dispose(&refnamebuf); + git_str_dispose(&name); + git_str_dispose(&refnamebuf); return error; } @@ -891,7 +891,7 @@ static bool is_all_caps_and_underscore(const char *name, size_t len) /* Inspired from https://github.com/git/git/blob/f06d47e7e0d9db709ee204ed13a8a7486149f494/refs.c#L36-100 */ int git_reference__normalize_name( - git_buf *buf, + git_str *buf, const char *name, unsigned int flags) { @@ -914,7 +914,7 @@ int git_reference__normalize_name( goto cleanup; if (normalize) - git_buf_clear(buf); + git_str_clear(buf); #ifdef GIT_USE_ICONV if ((flags & GIT_REFERENCE_FORMAT__PRECOMPOSE_UNICODE) != 0) { @@ -927,9 +927,9 @@ int git_reference__normalize_name( #endif if (!validate) { - git_buf_sets(buf, current); + git_str_sets(buf, current); - error = git_buf_oom(buf) ? -1 : 0; + error = git_str_oom(buf) ? -1 : 0; goto cleanup; } @@ -949,13 +949,13 @@ int git_reference__normalize_name( process_flags &= ~GIT_REFERENCE_FORMAT_REFSPEC_PATTERN; if (normalize) { - size_t cur_len = git_buf_len(buf); + size_t cur_len = git_str_len(buf); - git_buf_joinpath(buf, git_buf_cstr(buf), current); - git_buf_truncate(buf, + git_str_joinpath(buf, git_str_cstr(buf), current); + git_str_truncate(buf, cur_len + segment_len + (segments_count ? 1 : 0)); - if (git_buf_oom(buf)) { + if (git_str_oom(buf)) { error = -1; goto cleanup; } @@ -1008,7 +1008,7 @@ int git_reference__normalize_name( "the given reference name '%s' is not valid", name); if (error && normalize) - git_buf_dispose(buf); + git_str_dispose(buf); #ifdef GIT_USE_ICONV git_path_iconv_clear(&ic); @@ -1023,13 +1023,13 @@ int git_reference_normalize_name( const char *name, unsigned int flags) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error; if ((error = git_reference__normalize_name(&buf, name, flags)) < 0) goto cleanup; - if (git_buf_len(&buf) > buffer_size - 1) { + if (git_str_len(&buf) > buffer_size - 1) { git_error_set( GIT_ERROR_REFERENCE, "the provided buffer is too short to hold the normalization of '%s'", name); @@ -1037,13 +1037,13 @@ int git_reference_normalize_name( goto cleanup; } - if ((error = git_buf_copy_cstr(buffer_out, buffer_size, &buf)) < 0) + if ((error = git_str_copy_cstr(buffer_out, buffer_size, &buf)) < 0) goto cleanup; error = 0; cleanup: - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -1143,12 +1143,12 @@ int git_reference__update_for_commit( { git_reference *ref_new = NULL; git_commit *commit = NULL; - git_buf reflog_msg = GIT_BUF_INIT; + git_str reflog_msg = GIT_STR_INIT; const git_signature *who; int error; if ((error = git_commit_lookup(&commit, repo, id)) < 0 || - (error = git_buf_printf(&reflog_msg, "%s%s: %s", + (error = git_str_printf(&reflog_msg, "%s%s: %s", operation ? operation : "commit", commit_type(commit), git_commit_summary(commit))) < 0) @@ -1161,15 +1161,15 @@ int git_reference__update_for_commit( return error; error = reference__create(&ref_new, repo, ref->name, id, NULL, 1, who, - git_buf_cstr(&reflog_msg), &ref->target.oid, NULL); + git_str_cstr(&reflog_msg), &ref->target.oid, NULL); } else error = git_reference__update_terminal( - repo, ref_name, id, who, git_buf_cstr(&reflog_msg)); + repo, ref_name, id, who, git_str_cstr(&reflog_msg)); done: git_reference_free(ref_new); - git_buf_dispose(&reflog_msg); + git_str_dispose(&reflog_msg); git_commit_free(commit); return error; } diff --git a/src/refs.h b/src/refs.h index 376a512f85d..cb888bf8f49 100644 --- a/src/refs.h +++ b/src/refs.h @@ -13,7 +13,7 @@ #include "git2/refs.h" #include "git2/refdb.h" #include "strmap.h" -#include "buffer.h" +#include "str.h" #include "oid.h" extern bool git_reference__enable_symbolic_ref_target_validation; @@ -83,7 +83,7 @@ struct git_reference { */ git_reference *git_reference__realloc(git_reference **ptr_to_ref, const char *name); -int git_reference__normalize_name(git_buf *buf, const char *name, unsigned int flags); +int git_reference__normalize_name(git_str *buf, const char *name, unsigned int flags); int git_reference__update_terminal(git_repository *repo, const char *ref_name, const git_oid *oid, const git_signature *sig, const char *log_message); int git_reference__name_is_valid(int *valid, const char *name, unsigned int flags); int git_reference__is_branch(const char *ref_name); diff --git a/src/refspec.c b/src/refspec.c index c72721a4373..f0a0c2bfb3e 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -7,8 +7,7 @@ #include "refspec.h" -#include "git2/errors.h" - +#include "buf.h" #include "refs.h" #include "util.h" #include "vector.h" @@ -243,16 +242,12 @@ int git_refspec_dst_matches(const git_refspec *refspec, const char *refname) } static int refspec_transform( - git_buf *out, const char *from, const char *to, const char *name) + git_str *out, const char *from, const char *to, const char *name) { const char *from_star, *to_star; size_t replacement_len, star_offset; - int error; - - if ((error = git_buf_sanitize(out)) < 0) - return error; - git_buf_clear(out); + git_str_clear(out); /* * There are two parts to each side of a refspec, the bit @@ -269,72 +264,72 @@ static int refspec_transform( star_offset = from_star - from; /* the first half is copied over */ - git_buf_put(out, to, to_star - to); + git_str_put(out, to, to_star - to); /* * Copy over the name, but exclude the trailing part in "from" starting * after the glob */ replacement_len = strlen(name + star_offset) - strlen(from_star + 1); - git_buf_put(out, name + star_offset, replacement_len); + git_str_put(out, name + star_offset, replacement_len); - return git_buf_puts(out, to_star + 1); + return git_str_puts(out, to_star + 1); } int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name) { - int error; + GIT_BUF_WRAP_PRIVATE(out, git_refspec__transform, spec, name); +} +int git_refspec__transform(git_str *out, const git_refspec *spec, const char *name) +{ GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(spec); GIT_ASSERT_ARG(name); - if ((error = git_buf_sanitize(out)) < 0) - return error; - if (!git_refspec_src_matches(spec, name)) { git_error_set(GIT_ERROR_INVALID, "ref '%s' doesn't match the source", name); return -1; } if (!spec->pattern) - return git_buf_puts(out, spec->dst ? spec->dst : ""); + return git_str_puts(out, spec->dst ? spec->dst : ""); return refspec_transform(out, spec->src, spec->dst, name); } int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name) { - int error; + GIT_BUF_WRAP_PRIVATE(out, git_refspec__rtransform, spec, name); +} +int git_refspec__rtransform(git_str *out, const git_refspec *spec, const char *name) +{ GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(spec); GIT_ASSERT_ARG(name); - if ((error = git_buf_sanitize(out)) < 0) - return error; - if (!git_refspec_dst_matches(spec, name)) { git_error_set(GIT_ERROR_INVALID, "ref '%s' doesn't match the destination", name); return -1; } if (!spec->pattern) - return git_buf_puts(out, spec->src); + return git_str_puts(out, spec->src); return refspec_transform(out, spec->dst, spec->src, name); } -int git_refspec__serialize(git_buf *out, const git_refspec *refspec) +int git_refspec__serialize(git_str *out, const git_refspec *refspec) { if (refspec->force) - git_buf_putc(out, '+'); + git_str_putc(out, '+'); - git_buf_printf(out, "%s:%s", + git_str_printf(out, "%s:%s", refspec->src != NULL ? refspec->src : "", refspec->dst != NULL ? refspec->dst : ""); - return git_buf_oom(out) == false; + return git_str_oom(out) == false; } int git_refspec_is_wildcard(const git_refspec *spec) @@ -354,7 +349,7 @@ git_direction git_refspec_direction(const git_refspec *spec) int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; size_t j, pos; git_remote_head key; git_refspec *cur; @@ -382,14 +377,14 @@ int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs) /* shorthand on the lhs */ if (git__prefixcmp(spec->src, GIT_REFS_DIR)) { for (j = 0; formatters[j]; j++) { - git_buf_clear(&buf); - git_buf_printf(&buf, formatters[j], spec->src); - GIT_ERROR_CHECK_ALLOC_BUF(&buf); + git_str_clear(&buf); + git_str_printf(&buf, formatters[j], spec->src); + GIT_ERROR_CHECK_ALLOC_STR(&buf); - key.name = (char *) git_buf_cstr(&buf); + key.name = (char *) git_str_cstr(&buf); if (!git_vector_search(&pos, refs, &key)) { /* we found something to match the shorthand, set src to that */ - cur->src = git_buf_detach(&buf); + cur->src = git_str_detach(&buf); } } } @@ -403,18 +398,18 @@ int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs) if (spec->dst && git__prefixcmp(spec->dst, GIT_REFS_DIR)) { /* if it starts with "remotes" then we just prepend "refs/" */ if (!git__prefixcmp(spec->dst, "remotes/")) { - git_buf_puts(&buf, GIT_REFS_DIR); + git_str_puts(&buf, GIT_REFS_DIR); } else { - git_buf_puts(&buf, GIT_REFS_HEADS_DIR); + git_str_puts(&buf, GIT_REFS_HEADS_DIR); } - git_buf_puts(&buf, spec->dst); - GIT_ERROR_CHECK_ALLOC_BUF(&buf); + git_str_puts(&buf, spec->dst); + GIT_ERROR_CHECK_ALLOC_STR(&buf); - cur->dst = git_buf_detach(&buf); + cur->dst = git_str_detach(&buf); } - git_buf_dispose(&buf); + git_str_dispose(&buf); if (cur->dst == NULL && spec->dst != NULL) { cur->dst = git__strdup(spec->dst); diff --git a/src/refspec.h b/src/refspec.h index 2b4111f0419..bf4f7fcfbbc 100644 --- a/src/refspec.h +++ b/src/refspec.h @@ -10,7 +10,7 @@ #include "common.h" #include "git2/refspec.h" -#include "buffer.h" +#include "str.h" #include "vector.h" struct git_refspec { @@ -25,6 +25,9 @@ struct git_refspec { #define GIT_REFSPEC_TAGS "refs/tags/*:refs/tags/*" +int git_refspec__transform(git_str *out, const git_refspec *spec, const char *name); +int git_refspec__rtransform(git_str *out, const git_refspec *spec, const char *name); + int git_refspec__parse( struct git_refspec *refspec, const char *str, @@ -32,7 +35,7 @@ int git_refspec__parse( void git_refspec__dispose(git_refspec *refspec); -int git_refspec__serialize(git_buf *out, const git_refspec *refspec); +int git_refspec__serialize(git_str *out, const git_refspec *refspec); /** * Determines if a refspec is a wildcard refspec. diff --git a/src/remote.c b/src/remote.c index 56d7e42db0b..bde4ce779c2 100644 --- a/src/remote.c +++ b/src/remote.c @@ -7,11 +7,8 @@ #include "remote.h" -#include "git2/config.h" -#include "git2/types.h" -#include "git2/oid.h" -#include "git2/net.h" - +#include "buf.h" +#include "branch.h" #include "config.h" #include "repository.h" #include "fetch.h" @@ -20,6 +17,11 @@ #include "fetchhead.h" #include "push.h" +#include "git2/config.h" +#include "git2/types.h" +#include "git2/oid.h" +#include "git2/net.h" + #define CONFIG_URL_FMT "remote.%s.url" #define CONFIG_PUSHURL_FMT "remote.%s.pushurl" #define CONFIG_FETCH_FMT "remote.%s.fetch" @@ -60,14 +62,14 @@ static int add_refspec(git_remote *remote, const char *string, bool is_fetch) static int download_tags_value(git_remote *remote, git_config *cfg) { git_config_entry *ce; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error; - if (git_buf_printf(&buf, "remote.%s.tagopt", remote->name) < 0) + if (git_str_printf(&buf, "remote.%s.tagopt", remote->name) < 0) return -1; - error = git_config__lookup_entry(&ce, cfg, git_buf_cstr(&buf), false); - git_buf_dispose(&buf); + error = git_config__lookup_entry(&ce, cfg, git_str_cstr(&buf), false); + git_str_dispose(&buf); if (!error && ce && ce->value) { if (!strcmp(ce->value, "--no-tags")) @@ -99,7 +101,7 @@ static int ensure_remote_name_is_valid(const char *name) static int write_add_refspec(git_repository *repo, const char *name, const char *refspec, bool fetch) { git_config *cfg; - git_buf var = GIT_BUF_INIT; + git_str var = GIT_STR_INIT; git_refspec spec; const char *fmt; int error; @@ -117,7 +119,7 @@ static int write_add_refspec(git_repository *repo, const char *name, const char git_refspec__dispose(&spec); - if ((error = git_buf_printf(&var, fmt, name)) < 0) + if ((error = git_str_printf(&var, fmt, name)) < 0) return error; /* @@ -130,11 +132,11 @@ static int write_add_refspec(git_repository *repo, const char *name, const char } cleanup: - git_buf_dispose(&var); + git_str_dispose(&var); return 0; } -static int canonicalize_url(git_buf *out, const char *in) +static int canonicalize_url(git_str *out, const char *in) { if (in == NULL || strlen(in) == 0) { git_error_set(GIT_ERROR_INVALID, "cannot set empty URL"); @@ -149,18 +151,18 @@ static int canonicalize_url(git_buf *out, const char *in) (git__isalpha(in[2]) || git__isdigit(in[2]))) { const char *c; for (c = in; *c; c++) - git_buf_putc(out, *c == '\\' ? '/' : *c); + git_str_putc(out, *c == '\\' ? '/' : *c); - return git_buf_oom(out) ? -1 : 0; + return git_str_oom(out) ? -1 : 0; } #endif - return git_buf_puts(out, in); + return git_str_puts(out, in); } -static int default_fetchspec_for_name(git_buf *buf, const char *name) +static int default_fetchspec_for_name(git_str *buf, const char *name) { - if (git_buf_printf(buf, "+refs/heads/*:refs/remotes/%s/*", name) < 0) + if (git_str_printf(buf, "+refs/heads/*:refs/remotes/%s/*", name) < 0) return -1; return 0; @@ -204,9 +206,9 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem { git_remote *remote = NULL; git_config *config_ro = NULL, *config_rw; - git_buf canonical_url = GIT_BUF_INIT; - git_buf var = GIT_BUF_INIT; - git_buf specbuf = GIT_BUF_INIT; + git_str canonical_url = GIT_STR_INIT; + git_str var = GIT_STR_INIT; + git_str specbuf = GIT_STR_INIT; const git_remote_create_options dummy_opts = GIT_REMOTE_CREATE_OPTIONS_INIT; int error = -1; @@ -254,7 +256,7 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem GIT_ERROR_CHECK_ALLOC(remote->name); if (opts->repository && - ((error = git_buf_printf(&var, CONFIG_URL_FMT, opts->name)) < 0 || + ((error = git_str_printf(&var, CONFIG_URL_FMT, opts->name)) < 0 || (error = git_repository_config__weakptr(&config_rw, opts->repository)) < 0 || (error = git_config_set_string(config_rw, var.ptr, canonical_url.ptr)) < 0)) goto on_error; @@ -269,7 +271,7 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem if ((error = default_fetchspec_for_name(&specbuf, opts->name)) < 0) goto on_error; - fetch = git_buf_cstr(&specbuf); + fetch = git_str_cstr(&specbuf); } if ((error = add_refspec(remote, fetch, true)) < 0) @@ -293,7 +295,7 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO; - git_buf_dispose(&var); + git_str_dispose(&var); *out = remote; error = 0; @@ -303,15 +305,15 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem git_remote_free(remote); git_config_free(config_ro); - git_buf_dispose(&specbuf); - git_buf_dispose(&canonical_url); - git_buf_dispose(&var); + git_str_dispose(&specbuf); + git_str_dispose(&canonical_url); + git_str_dispose(&var); return error; } int git_remote_create(git_remote **out, git_repository *repo, const char *name, const char *url) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error; git_remote_create_options opts = GIT_REMOTE_CREATE_OPTIONS_INIT; @@ -322,14 +324,14 @@ int git_remote_create(git_remote **out, git_repository *repo, const char *name, if (canonicalize_url(&buf, url) < 0) return GIT_ERROR; - git_buf_clear(&buf); + git_str_clear(&buf); opts.repository = repo; opts.name = name; error = git_remote_create_with_opts(out, url, &opts); - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -425,13 +427,13 @@ static int refspec_cb(const git_config_entry *entry, void *payload) } static int get_optional_config( - bool *found, git_config *config, git_buf *buf, + bool *found, git_config *config, git_str *buf, git_config_foreach_cb cb, void *payload) { int error = 0; - const char *key = git_buf_cstr(buf); + const char *key = git_str_cstr(buf); - if (git_buf_oom(buf)) + if (git_str_oom(buf)) return -1; if (cb != NULL) @@ -453,7 +455,7 @@ static int get_optional_config( int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) { git_remote *remote = NULL; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; const char *val; int error = 0; git_config *config; @@ -484,7 +486,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) goto cleanup; } - if ((error = git_buf_printf(&buf, "remote.%s.url", name)) < 0) + if ((error = git_str_printf(&buf, "remote.%s.url", name)) < 0) goto cleanup; if ((error = get_optional_config(&found, config, &buf, NULL, (void *)&val)) < 0) @@ -501,8 +503,8 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) } val = NULL; - git_buf_clear(&buf); - git_buf_printf(&buf, "remote.%s.pushurl", name); + git_str_clear(&buf); + git_str_printf(&buf, "remote.%s.pushurl", name); if ((error = get_optional_config(&found, config, &buf, NULL, (void *)&val)) < 0) goto cleanup; @@ -523,15 +525,15 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) data.remote = remote; data.fetch = true; - git_buf_clear(&buf); - git_buf_printf(&buf, "remote.%s.fetch", name); + git_str_clear(&buf); + git_str_printf(&buf, "remote.%s.fetch", name); if ((error = get_optional_config(NULL, config, &buf, refspec_cb, &data)) < 0) goto cleanup; data.fetch = false; - git_buf_clear(&buf); - git_buf_printf(&buf, "remote.%s.push", name); + git_str_clear(&buf); + git_str_printf(&buf, "remote.%s.push", name); if ((error = get_optional_config(NULL, config, &buf, refspec_cb, &data)) < 0) goto cleanup; @@ -550,7 +552,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) cleanup: git_config_free(config); - git_buf_dispose(&buf); + git_str_dispose(&buf); if (error < 0) git_remote_free(remote); @@ -560,12 +562,12 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error = 0; - git_buf_printf(&buf, "remote.%s.prune", name); + git_str_printf(&buf, "remote.%s.prune", name); - if ((error = git_config_get_bool(&remote->prune_refs, config, git_buf_cstr(&buf))) < 0) { + if ((error = git_config_get_bool(&remote->prune_refs, config, git_str_cstr(&buf))) < 0) { if (error == GIT_ENOTFOUND) { git_error_clear(); @@ -578,7 +580,7 @@ static int lookup_remote_prune_config(git_remote *remote, git_config *config, co } } - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -619,7 +621,7 @@ int git_remote_set_instance_url(git_remote *remote, const char *url) static int set_url(git_repository *repo, const char *remote, const char *pattern, const char *url) { git_config *cfg; - git_buf buf = GIT_BUF_INIT, canonical_url = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT, canonical_url = GIT_STR_INIT; int error; GIT_ASSERT_ARG(repo); @@ -631,7 +633,7 @@ static int set_url(git_repository *repo, const char *remote, const char *pattern if ((error = git_repository_config__weakptr(&cfg, repo)) < 0) return error; - if ((error = git_buf_printf(&buf, pattern, remote)) < 0) + if ((error = git_str_printf(&buf, pattern, remote)) < 0) return error; if (url) { @@ -644,8 +646,8 @@ static int set_url(git_repository *repo, const char *remote, const char *pattern } cleanup: - git_buf_dispose(&canonical_url); - git_buf_dispose(&buf); + git_str_dispose(&canonical_url); + git_str_dispose(&buf); return error; } @@ -683,7 +685,7 @@ int git_remote_set_pushurl(git_repository *repo, const char *remote, const char } static int resolve_url( - git_buf *resolved_url, + git_str *resolved_url, const char *url, int direction, const git_remote_callbacks *callbacks) @@ -692,27 +694,28 @@ static int resolve_url( GIT_UNUSED(direction); GIT_UNUSED(callbacks); #else - int status, error; + git_buf buf = GIT_BUF_INIT; + int error; if (callbacks && callbacks->resolve_url) { - git_buf_clear(resolved_url); - status = callbacks->resolve_url(resolved_url, url, direction, callbacks->payload); - if (status != GIT_PASSTHROUGH) { - git_error_set_after_callback_function(status, "git_resolve_url_cb"); + error = callbacks->resolve_url(&buf, url, direction, callbacks->payload); - if ((error = git_buf_sanitize(resolved_url)) < 0) - return error; + if (error != GIT_PASSTHROUGH) { + git_error_set_after_callback_function(error, "git_resolve_url_cb"); - return status; + git_str_set(resolved_url, buf.ptr, buf.size); + git_buf_dispose(&buf); + + return error; } } #endif - return git_buf_sets(resolved_url, url); + return git_str_sets(resolved_url, url); } int git_remote__urlfordirection( - git_buf *url_out, + git_str *url_out, struct git_remote *remote, int direction, const git_remote_callbacks *callbacks) @@ -767,7 +770,7 @@ static int set_transport_custom_headers(git_transport *t, const git_strarray *cu int git_remote__connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_remote_connection_opts *conn) { git_transport *t; - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; int flags = GIT_TRANSPORTFLAGS_NONE; int error; void *payload = NULL; @@ -811,7 +814,7 @@ int git_remote__connect(git_remote *remote, git_direction direction, const git_r remote->transport = t; - git_buf_dispose(&url); + git_str_dispose(&url); return 0; @@ -819,7 +822,7 @@ int git_remote__connect(git_remote *remote, git_direction direction, const git_r if (t) t->free(t); - git_buf_dispose(&url); + git_str_dispose(&url); if (t == remote->transport) remote->transport = NULL; @@ -885,7 +888,7 @@ static void url_config_trim(git_net_url *url) static int http_proxy_config(char **out, git_remote *remote, git_net_url *url) { git_config *cfg = NULL; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_net_url lookup_url = GIT_NET_URL_INIT; int error; @@ -902,19 +905,19 @@ static int http_proxy_config(char **out, git_remote *remote, git_net_url *url) /* remote..proxy config setting */ if (remote->name && remote->name[0]) { - git_buf_clear(&buf); + git_str_clear(&buf); - if ((error = git_buf_printf(&buf, "remote.%s.proxy", remote->name)) < 0 || + if ((error = git_str_printf(&buf, "remote.%s.proxy", remote->name)) < 0 || (error = lookup_config(out, cfg, buf.ptr)) != GIT_ENOTFOUND) goto done; } while (true) { - git_buf_clear(&buf); + git_str_clear(&buf); - if ((error = git_buf_puts(&buf, "http.")) < 0 || + if ((error = git_str_puts(&buf, "http.")) < 0 || (error = git_net_url_fmt(&buf, &lookup_url)) < 0 || - (error = git_buf_puts(&buf, ".proxy")) < 0 || + (error = git_str_puts(&buf, ".proxy")) < 0 || (error = lookup_config(out, cfg, buf.ptr)) != GIT_ENOTFOUND) goto done; @@ -924,20 +927,20 @@ static int http_proxy_config(char **out, git_remote *remote, git_net_url *url) url_config_trim(&lookup_url); } - git_buf_clear(&buf); + git_str_clear(&buf); error = lookup_config(out, cfg, "http.proxy"); done: git_config_free(cfg); - git_buf_dispose(&buf); + git_str_dispose(&buf); git_net_url_dispose(&lookup_url); return error; } static int http_proxy_env(char **out, git_remote *remote, git_net_url *url) { - git_buf proxy_env = GIT_BUF_INIT, no_proxy_env = GIT_BUF_INIT; + git_str proxy_env = GIT_STR_INIT, no_proxy_env = GIT_STR_INIT; bool use_ssl = (strcmp(url->scheme, "https") == 0); int error; @@ -963,13 +966,13 @@ static int http_proxy_env(char **out, git_remote *remote, git_net_url *url) goto done; if (!git_net_url_matches_pattern_list(url, no_proxy_env.ptr)) - *out = git_buf_detach(&proxy_env); + *out = git_str_detach(&proxy_env); else error = GIT_ENOTFOUND; done: - git_buf_dispose(&proxy_env); - git_buf_dispose(&no_proxy_env); + git_str_dispose(&proxy_env); + git_str_dispose(&no_proxy_env); return error; } @@ -1135,7 +1138,7 @@ int git_remote_fetch( int error, update_fetchhead = 1; git_remote_autotag_option_t tagopt = remote->download_tags; bool prune = false; - git_buf reflog_msg_buf = GIT_BUF_INIT; + git_str reflog_msg_buf = GIT_STR_INIT; const git_remote_callbacks *cbs = NULL; git_remote_connection_opts conn = GIT_REMOTE_CONNECTION_OPTIONS_INIT; @@ -1164,15 +1167,15 @@ int git_remote_fetch( /* Default reflog message */ if (reflog_message) - git_buf_sets(&reflog_msg_buf, reflog_message); + git_str_sets(&reflog_msg_buf, reflog_message); else { - git_buf_printf(&reflog_msg_buf, "fetch %s", + git_str_printf(&reflog_msg_buf, "fetch %s", remote->name ? remote->name : remote->url); } /* Create "remote/foo" branches for all remote branches */ - error = git_remote_update_tips(remote, cbs, update_fetchhead, tagopt, git_buf_cstr(&reflog_msg_buf)); - git_buf_dispose(&reflog_msg_buf); + error = git_remote_update_tips(remote, cbs, update_fetchhead, tagopt, git_str_cstr(&reflog_msg_buf)); + git_str_dispose(&reflog_msg_buf); if (error < 0) return error; @@ -1211,22 +1214,22 @@ static int remote_head_for_fetchspec_src(git_remote_head **out, git_vector *upda return 0; } -static int ref_to_update(int *update, git_buf *remote_name, git_remote *remote, git_refspec *spec, const char *ref_name) +static int ref_to_update(int *update, git_str *remote_name, git_remote *remote, git_refspec *spec, const char *ref_name) { int error = 0; git_repository *repo; - git_buf upstream_remote = GIT_BUF_INIT; - git_buf upstream_name = GIT_BUF_INIT; + git_str upstream_remote = GIT_STR_INIT; + git_str upstream_name = GIT_STR_INIT; repo = git_remote_owner(remote); if ((!git_reference__is_branch(ref_name)) || !git_remote_name(remote) || - (error = git_branch_upstream_remote(&upstream_remote, repo, ref_name) < 0) || - git__strcmp(git_remote_name(remote), git_buf_cstr(&upstream_remote)) || - (error = git_branch_upstream_name(&upstream_name, repo, ref_name)) < 0 || - !git_refspec_dst_matches(spec, git_buf_cstr(&upstream_name)) || - (error = git_refspec_rtransform(remote_name, spec, upstream_name.ptr)) < 0) { + (error = git_branch__upstream_remote(&upstream_remote, repo, ref_name) < 0) || + git__strcmp(git_remote_name(remote), git_str_cstr(&upstream_remote)) || + (error = git_branch__upstream_name(&upstream_name, repo, ref_name)) < 0 || + !git_refspec_dst_matches(spec, git_str_cstr(&upstream_name)) || + (error = git_refspec__rtransform(remote_name, spec, upstream_name.ptr)) < 0) { /* Not an error if there is no upstream */ if (error == GIT_ENOTFOUND) { git_error_clear(); @@ -1238,15 +1241,15 @@ static int ref_to_update(int *update, git_buf *remote_name, git_remote *remote, *update = 1; } - git_buf_dispose(&upstream_remote); - git_buf_dispose(&upstream_name); + git_str_dispose(&upstream_remote); + git_str_dispose(&upstream_name); return error; } static int remote_head_for_ref(git_remote_head **out, git_remote *remote, git_refspec *spec, git_vector *update_heads, git_reference *ref) { git_reference *resolved_ref = NULL; - git_buf remote_name = GIT_BUF_INIT; + git_str remote_name = GIT_STR_INIT; git_config *config = NULL; const char *ref_name; int error = 0, update; @@ -1281,10 +1284,10 @@ static int remote_head_for_ref(git_remote_head **out, git_remote *remote, git_re goto cleanup; if (update) - error = remote_head_for_fetchspec_src(out, update_heads, git_buf_cstr(&remote_name)); + error = remote_head_for_fetchspec_src(out, update_heads, git_str_cstr(&remote_name)); cleanup: - git_buf_dispose(&remote_name); + git_str_dispose(&remote_name); git_reference_free(resolved_ref); git_config_free(config); return error; @@ -1422,7 +1425,7 @@ int git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks) */ git_vector_foreach(&candidates, i, refname) { git_vector_foreach(&remote->active_refspecs, j, spec) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; size_t pos; char *src_name; git_remote_head key = {0}; @@ -1430,12 +1433,12 @@ int git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks) if (!git_refspec_dst_matches(spec, refname)) continue; - if ((error = git_refspec_rtransform(&buf, spec, refname)) < 0) + if ((error = git_refspec__rtransform(&buf, spec, refname)) < 0) goto cleanup; - key.name = (char *) git_buf_cstr(&buf); + key.name = (char *) git_str_cstr(&buf); error = git_vector_bsearch(&pos, &remote_refs, &key); - git_buf_dispose(&buf); + git_str_dispose(&buf); if (error < 0 && error != GIT_ENOTFOUND) goto cleanup; @@ -1508,7 +1511,7 @@ static int update_tips_for_spec( { int error = 0, autotag, valid; unsigned int i = 0; - git_buf refname = GIT_BUF_INIT; + git_str refname = GIT_STR_INIT; git_oid old; git_odb *odb; git_remote_head *head; @@ -1531,7 +1534,7 @@ static int update_tips_for_spec( for (; i < refs->length; ++i) { head = git_vector_get(refs, i); autotag = 0; - git_buf_clear(&refname); + git_str_clear(&refname); /* Ignore malformed ref names (which also saves us from tag^{} */ if (git_reference_name_is_valid(&valid, head->name) < 0) @@ -1547,8 +1550,8 @@ static int update_tips_for_spec( if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_AUTO) autotag = 1; - git_buf_clear(&refname); - if (git_buf_puts(&refname, head->name) < 0) + git_str_clear(&refname); + if (git_str_puts(&refname, head->name) < 0) goto on_error; } } @@ -1556,7 +1559,7 @@ static int update_tips_for_spec( /* If we didn't want to auto-follow the tag, check if the refspec matches */ if (!autotag && git_refspec_src_matches(spec, head->name)) { if (spec->dst) { - if (git_refspec_transform(&refname, spec, head->name) < 0) + if (git_refspec__transform(&refname, spec, head->name) < 0) goto on_error; } else { /* @@ -1571,7 +1574,7 @@ static int update_tips_for_spec( } /* If we still don't have a refname, we don't want it */ - if (git_buf_len(&refname) == 0) { + if (git_str_len(&refname) == 0) { continue; } @@ -1625,13 +1628,13 @@ static int update_tips_for_spec( git_vector_free(&update_heads); git_refspec__dispose(&tagspec); - git_buf_dispose(&refname); + git_str_dispose(&refname); return 0; on_error: git_vector_free(&update_heads); git_refspec__dispose(&tagspec); - git_buf_dispose(&refname); + git_str_dispose(&refname); return -1; } @@ -1704,7 +1707,7 @@ static int opportunistic_updates(const git_remote *remote, const git_remote_call git_refspec *spec; git_remote_head *head; git_reference *ref; - git_buf refname = GIT_BUF_INIT; + git_str refname = GIT_STR_INIT; int error = 0; i = j = k = 0; @@ -1719,8 +1722,8 @@ static int opportunistic_updates(const git_remote *remote, const git_remote_call * FETCH_HEAD */ - git_buf_clear(&refname); - if ((error = git_refspec_transform(&refname, spec, head->name)) < 0) + git_str_clear(&refname); + if ((error = git_refspec__transform(&refname, spec, head->name)) < 0) goto cleanup; error = git_reference_name_to_id(&old, remote->repo, refname.ptr); @@ -1749,20 +1752,20 @@ static int opportunistic_updates(const git_remote *remote, const git_remote_call error = 0; cleanup: - git_buf_dispose(&refname); + git_str_dispose(&refname); return error; } static int truncate_fetch_head(const char *gitdir) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error; - if ((error = git_buf_joinpath(&path, gitdir, GIT_FETCH_HEAD_FILE)) < 0) + if ((error = git_str_joinpath(&path, gitdir, GIT_FETCH_HEAD_FILE)) < 0) return error; error = git_futils_truncate(path.ptr, GIT_REFS_FILE_MODE); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -1943,7 +1946,7 @@ git_remote_autotag_option_t git_remote_autotag(const git_remote *remote) int git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_autotag_option_t value) { - git_buf var = GIT_BUF_INIT; + git_str var = GIT_STR_INIT; git_config *config; int error; @@ -1955,7 +1958,7 @@ int git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_ if ((error = git_repository_config__weakptr(&config, repo)) < 0) return error; - if ((error = git_buf_printf(&var, CONFIG_TAGOPT_FMT, remote))) + if ((error = git_str_printf(&var, CONFIG_TAGOPT_FMT, remote))) return error; switch (value) { @@ -1975,7 +1978,7 @@ int git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_ error = -1; } - git_buf_dispose(&var); + git_str_dispose(&var); return error; } @@ -1989,25 +1992,25 @@ static int rename_remote_config_section( const char *old_name, const char *new_name) { - git_buf old_section_name = GIT_BUF_INIT, - new_section_name = GIT_BUF_INIT; + git_str old_section_name = GIT_STR_INIT, + new_section_name = GIT_STR_INIT; int error = -1; - if (git_buf_printf(&old_section_name, "remote.%s", old_name) < 0) + if (git_str_printf(&old_section_name, "remote.%s", old_name) < 0) goto cleanup; if (new_name && - (git_buf_printf(&new_section_name, "remote.%s", new_name) < 0)) + (git_str_printf(&new_section_name, "remote.%s", new_name) < 0)) goto cleanup; error = git_config_rename_section( repo, - git_buf_cstr(&old_section_name), - new_name ? git_buf_cstr(&new_section_name) : NULL); + git_str_cstr(&old_section_name), + new_name ? git_str_cstr(&new_section_name) : NULL); cleanup: - git_buf_dispose(&old_section_name); - git_buf_dispose(&new_section_name); + git_str_dispose(&old_section_name); + git_str_dispose(&new_section_name); return error; } @@ -2056,27 +2059,27 @@ static int rename_one_remote_reference( { int error; git_reference *ref = NULL, *dummy = NULL; - git_buf namespace = GIT_BUF_INIT, old_namespace = GIT_BUF_INIT; - git_buf new_name = GIT_BUF_INIT; - git_buf log_message = GIT_BUF_INIT; + git_str namespace = GIT_STR_INIT, old_namespace = GIT_STR_INIT; + git_str new_name = GIT_STR_INIT; + git_str log_message = GIT_STR_INIT; size_t pfx_len; const char *target; - if ((error = git_buf_printf(&namespace, GIT_REFS_REMOTES_DIR "%s/", new_remote_name)) < 0) + if ((error = git_str_printf(&namespace, GIT_REFS_REMOTES_DIR "%s/", new_remote_name)) < 0) return error; pfx_len = strlen(GIT_REFS_REMOTES_DIR) + strlen(old_remote_name) + 1; - git_buf_puts(&new_name, namespace.ptr); - if ((error = git_buf_puts(&new_name, git_reference_name(reference_in) + pfx_len)) < 0) + git_str_puts(&new_name, namespace.ptr); + if ((error = git_str_puts(&new_name, git_reference_name(reference_in) + pfx_len)) < 0) goto cleanup; - if ((error = git_buf_printf(&log_message, + if ((error = git_str_printf(&log_message, "renamed remote %s to %s", old_remote_name, new_remote_name)) < 0) goto cleanup; - if ((error = git_reference_rename(&ref, reference_in, git_buf_cstr(&new_name), 1, - git_buf_cstr(&log_message))) < 0) + if ((error = git_reference_rename(&ref, reference_in, git_str_cstr(&new_name), 1, + git_str_cstr(&log_message))) < 0) goto cleanup; if (git_reference_type(ref) != GIT_REFERENCE_SYMBOLIC) @@ -2084,29 +2087,29 @@ static int rename_one_remote_reference( /* Handle refs like origin/HEAD -> origin/master */ target = git_reference_symbolic_target(ref); - if ((error = git_buf_printf(&old_namespace, GIT_REFS_REMOTES_DIR "%s/", old_remote_name)) < 0) + if ((error = git_str_printf(&old_namespace, GIT_REFS_REMOTES_DIR "%s/", old_remote_name)) < 0) goto cleanup; if (git__prefixcmp(target, old_namespace.ptr)) goto cleanup; - git_buf_clear(&new_name); - git_buf_puts(&new_name, namespace.ptr); - if ((error = git_buf_puts(&new_name, target + pfx_len)) < 0) + git_str_clear(&new_name); + git_str_puts(&new_name, namespace.ptr); + if ((error = git_str_puts(&new_name, target + pfx_len)) < 0) goto cleanup; - error = git_reference_symbolic_set_target(&dummy, ref, git_buf_cstr(&new_name), - git_buf_cstr(&log_message)); + error = git_reference_symbolic_set_target(&dummy, ref, git_str_cstr(&new_name), + git_str_cstr(&log_message)); git_reference_free(dummy); cleanup: git_reference_free(reference_in); git_reference_free(ref); - git_buf_dispose(&namespace); - git_buf_dispose(&old_namespace); - git_buf_dispose(&new_name); - git_buf_dispose(&log_message); + git_str_dispose(&namespace); + git_str_dispose(&old_namespace); + git_str_dispose(&new_name); + git_str_dispose(&log_message); return error; } @@ -2116,15 +2119,15 @@ static int rename_remote_references( const char *new_name) { int error; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_reference *ref; git_reference_iterator *iter; - if ((error = git_buf_printf(&buf, GIT_REFS_REMOTES_DIR "%s/*", old_name)) < 0) + if ((error = git_str_printf(&buf, GIT_REFS_REMOTES_DIR "%s/*", old_name)) < 0) return error; - error = git_reference_iterator_glob_new(&iter, repo, git_buf_cstr(&buf)); - git_buf_dispose(&buf); + error = git_reference_iterator_glob_new(&iter, repo, git_str_cstr(&buf)); + git_str_dispose(&buf); if (error < 0) return error; @@ -2142,7 +2145,7 @@ static int rename_remote_references( static int rename_fetch_refspecs(git_vector *problems, git_remote *remote, const char *new_name) { git_config *config; - git_buf base = GIT_BUF_INIT, var = GIT_BUF_INIT, val = GIT_BUF_INIT; + git_str base = GIT_STR_INIT, var = GIT_STR_INIT, val = GIT_STR_INIT; const git_refspec *spec; size_t i; int error = 0; @@ -2161,7 +2164,7 @@ static int rename_fetch_refspecs(git_vector *problems, git_remote *remote, const continue; /* Does the dst part of the refspec follow the expected format? */ - if (strcmp(git_buf_cstr(&base), spec->string)) { + if (strcmp(git_str_cstr(&base), spec->string)) { char *dup; dup = git__strdup(spec->string); @@ -2175,24 +2178,24 @@ static int rename_fetch_refspecs(git_vector *problems, git_remote *remote, const /* If we do want to move it to the new section */ - git_buf_clear(&val); - git_buf_clear(&var); + git_str_clear(&val); + git_str_clear(&var); if (default_fetchspec_for_name(&val, new_name) < 0 || - git_buf_printf(&var, "remote.%s.fetch", new_name) < 0) + git_str_printf(&var, "remote.%s.fetch", new_name) < 0) { error = -1; break; } if ((error = git_config_set_string( - config, git_buf_cstr(&var), git_buf_cstr(&val))) < 0) + config, git_str_cstr(&var), git_str_cstr(&val))) < 0) break; } - git_buf_dispose(&base); - git_buf_dispose(&var); - git_buf_dispose(&val); + git_str_dispose(&base); + git_str_dispose(&var); + git_str_dispose(&val); if (error < 0) { char *str; @@ -2247,7 +2250,7 @@ int git_remote_rename(git_strarray *out, git_repository *repo, const char *name, int git_remote_name_is_valid(int *valid, const char *remote_name) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_refspec refspec = {0}; int error; @@ -2258,10 +2261,10 @@ int git_remote_name_is_valid(int *valid, const char *remote_name) if (!remote_name || *remote_name == '\0') return 0; - if ((error = git_buf_printf(&buf, "refs/heads/test:refs/remotes/%s/test", remote_name)) < 0) + if ((error = git_str_printf(&buf, "refs/heads/test:refs/remotes/%s/test", remote_name)) < 0) goto done; - error = git_refspec__parse(&refspec, git_buf_cstr(&buf), true); + error = git_refspec__parse(&refspec, git_str_cstr(&buf), true); if (!error) *valid = 1; @@ -2269,7 +2272,7 @@ int git_remote_name_is_valid(int *valid, const char *remote_name) error = 0; done: - git_buf_dispose(&buf); + git_str_dispose(&buf); git_refspec__dispose(&refspec); return error; @@ -2401,7 +2404,7 @@ static int remove_branch_config_related_entries( git_config *config; git_config_entry *entry; git_config_iterator *iter; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; if ((error = git_repository_config__weakptr(&config, repo)) < 0) return error; @@ -2422,21 +2425,21 @@ static int remove_branch_config_related_entries( break; } - git_buf_clear(&buf); - if ((error = git_buf_printf(&buf, "branch.%.*s.merge", (int)branch_len, branch)) < 0) + git_str_clear(&buf); + if ((error = git_str_printf(&buf, "branch.%.*s.merge", (int)branch_len, branch)) < 0) break; - if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0) { + if ((error = git_config_delete_entry(config, git_str_cstr(&buf))) < 0) { if (error != GIT_ENOTFOUND) break; git_error_clear(); } - git_buf_clear(&buf); - if ((error = git_buf_printf(&buf, "branch.%.*s.remote", (int)branch_len, branch)) < 0) + git_str_clear(&buf); + if ((error = git_str_printf(&buf, "branch.%.*s.remote", (int)branch_len, branch)) < 0) break; - if ((error = git_config_delete_entry(config, git_buf_cstr(&buf))) < 0) { + if ((error = git_config_delete_entry(config, git_str_cstr(&buf))) < 0) { if (error != GIT_ENOTFOUND) break; git_error_clear(); @@ -2446,7 +2449,7 @@ static int remove_branch_config_related_entries( if (error == GIT_ITEROVER) error = 0; - git_buf_dispose(&buf); + git_str_dispose(&buf); git_config_iterator_free(iter); return error; } @@ -2540,12 +2543,17 @@ int git_remote_delete(git_repository *repo, const char *name) } int git_remote_default_branch(git_buf *out, git_remote *remote) +{ + GIT_BUF_WRAP_PRIVATE(out, git_remote__default_branch, remote); +} + +int git_remote__default_branch(git_str *out, git_remote *remote) { const git_remote_head **heads; const git_remote_head *guess = NULL; const git_oid *head_id; size_t heads_len, i; - git_buf local_default = GIT_BUF_INIT; + git_str local_default = GIT_STR_INIT; int error; GIT_ASSERT_ARG(out); @@ -2558,12 +2566,9 @@ int git_remote_default_branch(git_buf *out, git_remote *remote) goto done; } - if ((error = git_buf_sanitize(out)) < 0) - return error; - /* the first one must be HEAD so if that has the symref info, we're done */ if (heads[0]->symref_target) { - error = git_buf_puts(out, heads[0]->symref_target); + error = git_str_puts(out, heads[0]->symref_target); goto done; } @@ -2601,10 +2606,10 @@ int git_remote_default_branch(git_buf *out, git_remote *remote) goto done; } - error = git_buf_puts(out, guess->name); + error = git_str_puts(out, guess->name); done: - git_buf_dispose(&local_default); + git_str_dispose(&local_default); return error; } @@ -2720,7 +2725,7 @@ char *apply_insteadof(git_config *config, const char *url, int direction) char *replacement = NULL; const char *regexp; - git_buf result = GIT_BUF_INIT; + git_str result = GIT_STR_INIT; git_config_entry *entry; git_config_iterator *iter; @@ -2768,7 +2773,7 @@ char *apply_insteadof(git_config *config, const char *url, int direction) if (match_length == 0) return git__strdup(url); - git_buf_printf(&result, "%s%s", replacement, url + match_length); + git_str_printf(&result, "%s%s", replacement, url + match_length); git__free(replacement); diff --git a/src/remote.h b/src/remote.h index ce92db76aa5..77eefdf4088 100644 --- a/src/remote.h +++ b/src/remote.h @@ -46,10 +46,12 @@ typedef struct git_remote_connection_opts { int git_remote__connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_remote_connection_opts *conn); -int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int direction, const git_remote_callbacks *callbacks); +int git_remote__urlfordirection(git_str *url_out, struct git_remote *remote, int direction, const git_remote_callbacks *callbacks); int git_remote__http_proxy(char **out, git_remote *remote, git_net_url *url); git_refspec *git_remote__matching_refspec(git_remote *remote, const char *refname); git_refspec *git_remote__matching_dst_refspec(git_remote *remote, const char *refname); +int git_remote__default_branch(git_str *out, git_remote *remote); + #endif diff --git a/src/repository.c b/src/repository.c index 9b3e9c9e3b1..29684e463db 100644 --- a/src/repository.c +++ b/src/repository.c @@ -12,6 +12,7 @@ #include "git2/object.h" #include "git2/sys/repository.h" +#include "buf.h" #include "common.h" #include "commit.h" #include "tag.h" @@ -75,13 +76,13 @@ static int check_extensions(git_config *config, int version); #define GIT_REPO_VERSION 0 #define GIT_REPO_MAX_VERSION 1 -git_buf git_repository__reserved_names_win32[] = { +git_str git_repository__reserved_names_win32[] = { { DOT_GIT, 0, CONST_STRLEN(DOT_GIT) }, { GIT_DIR_SHORTNAME, 0, CONST_STRLEN(GIT_DIR_SHORTNAME) } }; size_t git_repository__reserved_names_win32_len = 2; -git_buf git_repository__reserved_names_posix[] = { +git_str git_repository__reserved_names_posix[] = { { DOT_GIT, 0, CONST_STRLEN(DOT_GIT) }, }; size_t git_repository__reserved_names_posix_len = 1; @@ -171,7 +172,7 @@ void git_repository_free(git_repository *repo) repo->diff_drivers = NULL; for (i = 0; i < repo->reserved_names.size; i++) - git_buf_dispose(git_array_get(repo->reserved_names, i)); + git_str_dispose(git_array_get(repo->reserved_names, i)); git_array_clear(repo->reserved_names); git__free(repo->gitlink); @@ -187,9 +188,9 @@ void git_repository_free(git_repository *repo) } /* Check if we have a separate commondir (e.g. we have a worktree) */ -static int lookup_commondir(bool *separate, git_buf *commondir, git_buf *repository_path) +static int lookup_commondir(bool *separate, git_str *commondir, git_str *repository_path) { - git_buf common_link = GIT_BUF_INIT; + git_str common_link = GIT_STR_INIT; int error; /* @@ -197,7 +198,7 @@ static int lookup_commondir(bool *separate, git_buf *commondir, git_buf *reposit * common path, but it needs a trailing slash. */ if (!git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) { - if ((error = git_buf_set(commondir, repository_path->ptr, repository_path->size)) == 0) + if ((error = git_str_set(commondir, repository_path->ptr, repository_path->size)) == 0) error = git_path_to_dir(commondir); *separate = false; @@ -206,19 +207,19 @@ static int lookup_commondir(bool *separate, git_buf *commondir, git_buf *reposit *separate = true; - if ((error = git_buf_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE)) < 0 || + if ((error = git_str_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE)) < 0 || (error = git_futils_readbuffer(&common_link, common_link.ptr)) < 0) goto done; - git_buf_rtrim(&common_link); + git_str_rtrim(&common_link); if (git_path_is_relative(common_link.ptr)) { - if ((error = git_buf_joinpath(commondir, repository_path->ptr, common_link.ptr)) < 0) + if ((error = git_str_joinpath(commondir, repository_path->ptr, common_link.ptr)) < 0) goto done; } else { - git_buf_swap(commondir, &common_link); + git_str_swap(commondir, &common_link); } - git_buf_dispose(&common_link); + git_str_dispose(&common_link); /* Make sure the commondir path always has a trailing slash */ error = git_path_prettify_dir(commondir, commondir->ptr, NULL); @@ -227,7 +228,7 @@ static int lookup_commondir(bool *separate, git_buf *commondir, git_buf *reposit return error; } -GIT_INLINE(int) validate_repo_path(git_buf *path) +GIT_INLINE(int) validate_repo_path(git_str *path) { /* * The longest static path in a repository (or commondir) is the @@ -248,7 +249,7 @@ GIT_INLINE(int) validate_repo_path(git_buf *path) * * Open a repository object from its path */ -static int is_valid_repository_path(bool *out, git_buf *repository_path, git_buf *common_path) +static int is_valid_repository_path(bool *out, git_str *repository_path, git_str *common_path) { bool separate_commondir = false; int error; @@ -333,12 +334,12 @@ static int load_config_data(git_repository *repo, const git_config *config) return 0; } -static int load_workdir(git_repository *repo, git_config *config, git_buf *parent_path) +static int load_workdir(git_repository *repo, git_config *config, git_str *parent_path) { int error; git_config_entry *ce; - git_buf worktree = GIT_BUF_INIT; - git_buf path = GIT_BUF_INIT; + git_str worktree = GIT_STR_INIT; + git_str path = GIT_STR_INIT; if (repo->is_bare) return 0; @@ -354,7 +355,7 @@ static int load_workdir(git_repository *repo, git_config *config, git_buf *paren goto cleanup; } - git_buf_attach(&worktree, gitlink, 0); + git_str_attach(&worktree, gitlink, 0); if ((git_path_dirname_r(&worktree, worktree.ptr)) < 0 || git_path_to_dir(&worktree) < 0) { @@ -362,17 +363,17 @@ static int load_workdir(git_repository *repo, git_config *config, git_buf *paren goto cleanup; } - repo->workdir = git_buf_detach(&worktree); + repo->workdir = git_str_detach(&worktree); } else if (ce && ce->value) { if ((error = git_path_prettify_dir( &worktree, ce->value, repo->gitdir)) < 0) goto cleanup; - repo->workdir = git_buf_detach(&worktree); + repo->workdir = git_str_detach(&worktree); } else if (parent_path && git_path_isdir(parent_path->ptr)) - repo->workdir = git_buf_detach(parent_path); + repo->workdir = git_str_detach(parent_path); else { if (git_path_dirname_r(&worktree, repo->gitdir) < 0 || git_path_to_dir(&worktree) < 0) { @@ -380,12 +381,12 @@ static int load_workdir(git_repository *repo, git_config *config, git_buf *paren goto cleanup; } - repo->workdir = git_buf_detach(&worktree); + repo->workdir = git_str_detach(&worktree); } GIT_ERROR_CHECK_ALLOC(repo->workdir); cleanup: - git_buf_dispose(&path); + git_str_dispose(&path); git_config_entry_free(ce); return error; } @@ -394,7 +395,7 @@ static int load_workdir(git_repository *repo, git_config *config, git_buf *paren * This function returns furthest offset into path where a ceiling dir * is found, so we can stop processing the path at that point. * - * Note: converting this to use git_bufs instead of GIT_PATH_MAX buffers on + * Note: converting this to use git_strs instead of GIT_PATH_MAX buffers on * the stack could remove directories name limits, but at the cost of doing * repeated malloc/frees inside the loop below, so let's not do it now. */ @@ -447,10 +448,10 @@ static size_t find_ceiling_dir_offset( * it points to. Before calling, set `path_out` to the base directory that * should be used if the contents of `file_path` are a relative path. */ -static int read_gitfile(git_buf *path_out, const char *file_path) +static int read_gitfile(git_str *path_out, const char *file_path) { int error = 0; - git_buf file = GIT_BUF_INIT; + git_str file = GIT_STR_INIT; size_t prefix_len = strlen(GIT_FILE_CONTENT_PREFIX); GIT_ASSERT_ARG(path_out); @@ -459,41 +460,41 @@ static int read_gitfile(git_buf *path_out, const char *file_path) if (git_futils_readbuffer(&file, file_path) < 0) return -1; - git_buf_rtrim(&file); + git_str_rtrim(&file); /* apparently on Windows, some people use backslashes in paths */ git_path_mkposix(file.ptr); - if (git_buf_len(&file) <= prefix_len || - memcmp(git_buf_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0) + if (git_str_len(&file) <= prefix_len || + memcmp(git_str_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0) { git_error_set(GIT_ERROR_REPOSITORY, "the `.git` file at '%s' is malformed", file_path); error = -1; } else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) { - const char *gitlink = git_buf_cstr(&file) + prefix_len; + const char *gitlink = git_str_cstr(&file) + prefix_len; while (*gitlink && git__isspace(*gitlink)) gitlink++; error = git_path_prettify_dir( - path_out, gitlink, git_buf_cstr(path_out)); + path_out, gitlink, git_str_cstr(path_out)); } - git_buf_dispose(&file); + git_str_dispose(&file); return error; } static int find_repo( - git_buf *gitdir_path, - git_buf *workdir_path, - git_buf *gitlink_path, - git_buf *commondir_path, + git_str *gitdir_path, + git_str *workdir_path, + git_str *gitlink_path, + git_str *commondir_path, const char *start_path, uint32_t flags, const char *ceiling_dirs) { - git_buf path = GIT_BUF_INIT; - git_buf repo_link = GIT_BUF_INIT; - git_buf common_link = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; + git_str repo_link = GIT_STR_INIT; + git_str common_link = GIT_STR_INIT; struct stat st; dev_t initial_device = 0; int min_iterations; @@ -501,7 +502,7 @@ static int find_repo( size_t ceiling_offset = 0; int error; - git_buf_clear(gitdir_path); + git_str_clear(gitdir_path); error = git_path_prettify(&path, start_path, NULL); if (error < 0) @@ -525,7 +526,7 @@ static int find_repo( for (;;) { if (!(flags & GIT_REPOSITORY_OPEN_NO_DOTGIT)) { if (!in_dot_git) { - if ((error = git_buf_joinpath(&path, path.ptr, DOT_GIT)) < 0) + if ((error = git_str_joinpath(&path, path.ptr, DOT_GIT)) < 0) goto out; } in_dot_git = !in_dot_git; @@ -545,14 +546,14 @@ static int find_repo( if (is_valid) { if ((error = git_path_to_dir(&path)) < 0 || - (error = git_buf_set(gitdir_path, path.ptr, path.size)) < 0) + (error = git_str_set(gitdir_path, path.ptr, path.size)) < 0) goto out; if (gitlink_path) - if ((error = git_buf_attach(gitlink_path, git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0)) < 0) + if ((error = git_str_attach(gitlink_path, git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0)) < 0) goto out; if (commondir_path) - git_buf_swap(&common_link, commondir_path); + git_str_swap(&common_link, commondir_path); break; } @@ -562,13 +563,13 @@ static int find_repo( goto out; if (is_valid) { - git_buf_swap(gitdir_path, &repo_link); + git_str_swap(gitdir_path, &repo_link); if (gitlink_path) - if ((error = git_buf_put(gitlink_path, path.ptr, path.size)) < 0) + if ((error = git_str_put(gitlink_path, path.ptr, path.size)) < 0) goto out; if (commondir_path) - git_buf_swap(&common_link, commondir_path); + git_str_swap(&common_link, commondir_path); } break; } @@ -592,8 +593,8 @@ static int find_repo( } if (workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) { - if (!git_buf_len(gitdir_path)) - git_buf_clear(workdir_path); + if (!git_str_len(gitdir_path)) + git_str_clear(workdir_path); else if ((error = git_path_dirname_r(workdir_path, path.ptr)) < 0 || (error = git_path_to_dir(workdir_path)) < 0) goto out; @@ -601,16 +602,16 @@ static int find_repo( /* If we didn't find the repository, and we don't have any other error * to report, report that. */ - if (!git_buf_len(gitdir_path)) { + if (!git_str_len(gitdir_path)) { git_error_set(GIT_ERROR_REPOSITORY, "could not find repository from '%s'", start_path); error = GIT_ENOTFOUND; goto out; } out: - git_buf_dispose(&path); - git_buf_dispose(&repo_link); - git_buf_dispose(&common_link); + git_str_dispose(&path); + git_str_dispose(&repo_link); + git_str_dispose(&common_link); return error; } @@ -618,7 +619,7 @@ int git_repository_open_bare( git_repository **repo_ptr, const char *bare_path) { - git_buf path = GIT_BUF_INIT, common_path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, common_path = GIT_STR_INIT; git_repository *repo = NULL; bool is_valid; int error; @@ -628,8 +629,8 @@ int git_repository_open_bare( return error; if (!is_valid) { - git_buf_dispose(&path); - git_buf_dispose(&common_path); + git_str_dispose(&path); + git_str_dispose(&common_path); git_error_set(GIT_ERROR_REPOSITORY, "path is not a repository: %s", bare_path); return GIT_ENOTFOUND; } @@ -637,9 +638,9 @@ int git_repository_open_bare( repo = repository_alloc(); GIT_ERROR_CHECK_ALLOC(repo); - repo->gitdir = git_buf_detach(&path); + repo->gitdir = git_str_detach(&path); GIT_ERROR_CHECK_ALLOC(repo->gitdir); - repo->commondir = git_buf_detach(&common_path); + repo->commondir = git_str_detach(&common_path); GIT_ERROR_CHECK_ALLOC(repo->commondir); /* of course we're bare! */ @@ -658,15 +659,15 @@ static int _git_repository_open_ext_from_env( git_repository *repo = NULL; git_index *index = NULL; git_odb *odb = NULL; - git_buf dir_buf = GIT_BUF_INIT; - git_buf ceiling_dirs_buf = GIT_BUF_INIT; - git_buf across_fs_buf = GIT_BUF_INIT; - git_buf index_file_buf = GIT_BUF_INIT; - git_buf namespace_buf = GIT_BUF_INIT; - git_buf object_dir_buf = GIT_BUF_INIT; - git_buf alts_buf = GIT_BUF_INIT; - git_buf work_tree_buf = GIT_BUF_INIT; - git_buf common_dir_buf = GIT_BUF_INIT; + git_str dir_buf = GIT_STR_INIT; + git_str ceiling_dirs_buf = GIT_STR_INIT; + git_str across_fs_buf = GIT_STR_INIT; + git_str index_file_buf = GIT_STR_INIT; + git_str namespace_buf = GIT_STR_INIT; + git_str object_dir_buf = GIT_STR_INIT; + git_str alts_buf = GIT_STR_INIT; + git_str work_tree_buf = GIT_STR_INIT; + git_str common_dir_buf = GIT_STR_INIT; const char *ceiling_dirs = NULL; unsigned flags = 0; int error; @@ -679,7 +680,7 @@ static int _git_repository_open_ext_from_env( } else if (error < 0) goto error; else { - start_path = git_buf_cstr(&dir_buf); + start_path = git_str_cstr(&dir_buf); flags |= GIT_REPOSITORY_OPEN_NO_SEARCH; flags |= GIT_REPOSITORY_OPEN_NO_DOTGIT; } @@ -691,7 +692,7 @@ static int _git_repository_open_ext_from_env( else if (error < 0) goto error; else - ceiling_dirs = git_buf_cstr(&ceiling_dirs_buf); + ceiling_dirs = git_str_cstr(&ceiling_dirs_buf); error = git__getenv(&across_fs_buf, "GIT_DISCOVERY_ACROSS_FILESYSTEM"); if (error == GIT_ENOTFOUND) @@ -700,7 +701,7 @@ static int _git_repository_open_ext_from_env( goto error; else { int across_fs = 0; - error = git_config_parse_bool(&across_fs, git_buf_cstr(&across_fs_buf)); + error = git_config_parse_bool(&across_fs, git_str_cstr(&across_fs_buf)); if (error < 0) goto error; if (across_fs) @@ -713,7 +714,7 @@ static int _git_repository_open_ext_from_env( else if (error < 0) goto error; else { - error = git_index_open(&index, git_buf_cstr(&index_file_buf)); + error = git_index_open(&index, git_str_cstr(&index_file_buf)); if (error < 0) goto error; } @@ -730,7 +731,7 @@ static int _git_repository_open_ext_from_env( else if (error < 0) goto error; else { - error = git_odb_open(&odb, git_buf_cstr(&object_dir_buf)); + error = git_odb_open(&odb, git_str_cstr(&object_dir_buf)); if (error < 0) goto error; } @@ -779,7 +780,7 @@ static int _git_repository_open_ext_from_env( goto error; } - end = git_buf_cstr(&alts_buf) + git_buf_len(&alts_buf); + end = git_str_cstr(&alts_buf) + git_str_len(&alts_buf); for (sep = alt = alts_buf.ptr; sep != end; alt = sep+1) { for (sep = alt; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++) ; @@ -791,8 +792,8 @@ static int _git_repository_open_ext_from_env( } } - if (git_buf_len(&namespace_buf)) { - error = git_repository_set_namespace(repo, git_buf_cstr(&namespace_buf)); + if (git_str_len(&namespace_buf)) { + error = git_repository_set_namespace(repo, git_str_cstr(&namespace_buf)); if (error < 0) goto error; } @@ -808,21 +809,21 @@ static int _git_repository_open_ext_from_env( success: git_odb_free(odb); git_index_free(index); - git_buf_dispose(&common_dir_buf); - git_buf_dispose(&work_tree_buf); - git_buf_dispose(&alts_buf); - git_buf_dispose(&object_dir_buf); - git_buf_dispose(&namespace_buf); - git_buf_dispose(&index_file_buf); - git_buf_dispose(&across_fs_buf); - git_buf_dispose(&ceiling_dirs_buf); - git_buf_dispose(&dir_buf); + git_str_dispose(&common_dir_buf); + git_str_dispose(&work_tree_buf); + git_str_dispose(&alts_buf); + git_str_dispose(&object_dir_buf); + git_str_dispose(&namespace_buf); + git_str_dispose(&index_file_buf); + git_str_dispose(&across_fs_buf); + git_str_dispose(&ceiling_dirs_buf); + git_str_dispose(&dir_buf); return error; } static int repo_is_worktree(unsigned *out, const git_repository *repo) { - git_buf gitdir_link = GIT_BUF_INIT; + git_str gitdir_link = GIT_STR_INIT; int error; /* Worktrees cannot have the same commondir and gitdir */ @@ -832,14 +833,14 @@ static int repo_is_worktree(unsigned *out, const git_repository *repo) return 0; } - if ((error = git_buf_joinpath(&gitdir_link, repo->gitdir, "gitdir")) < 0) + if ((error = git_str_joinpath(&gitdir_link, repo->gitdir, "gitdir")) < 0) return -1; /* A 'gitdir' file inside a git directory is currently * only used when the repository is a working tree. */ *out = !!git_path_exists(gitdir_link.ptr); - git_buf_dispose(&gitdir_link); + git_str_dispose(&gitdir_link); return error; } @@ -851,8 +852,8 @@ int git_repository_open_ext( { int error; unsigned is_worktree; - git_buf gitdir = GIT_BUF_INIT, workdir = GIT_BUF_INIT, - gitlink = GIT_BUF_INIT, commondir = GIT_BUF_INIT; + git_str gitdir = GIT_STR_INIT, workdir = GIT_STR_INIT, + gitlink = GIT_STR_INIT, commondir = GIT_STR_INIT; git_repository *repo = NULL; git_config *config = NULL; int version = 0; @@ -872,15 +873,15 @@ int git_repository_open_ext( repo = repository_alloc(); GIT_ERROR_CHECK_ALLOC(repo); - repo->gitdir = git_buf_detach(&gitdir); + repo->gitdir = git_str_detach(&gitdir); GIT_ERROR_CHECK_ALLOC(repo->gitdir); if (gitlink.size) { - repo->gitlink = git_buf_detach(&gitlink); + repo->gitlink = git_str_detach(&gitlink); GIT_ERROR_CHECK_ALLOC(repo->gitlink); } if (commondir.size) { - repo->commondir = git_buf_detach(&commondir); + repo->commondir = git_str_detach(&commondir); GIT_ERROR_CHECK_ALLOC(repo->commondir); } @@ -914,10 +915,10 @@ int git_repository_open_ext( } cleanup: - git_buf_dispose(&gitdir); - git_buf_dispose(&workdir); - git_buf_dispose(&gitlink); - git_buf_dispose(&commondir); + git_str_dispose(&gitdir); + git_str_dispose(&workdir); + git_str_dispose(&gitlink); + git_str_dispose(&commondir); git_config_free(config); if (error < 0) @@ -936,7 +937,7 @@ int git_repository_open(git_repository **repo_out, const char *path) int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *wt) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_repository *repo = NULL; size_t len; int err; @@ -952,7 +953,7 @@ int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *w goto out; } - if ((err = git_buf_set(&path, wt->gitlink_path, len - 4)) < 0) + if ((err = git_str_set(&path, wt->gitlink_path, len - 4)) < 0) goto out; if ((err = git_repository_open(&repo, path.ptr)) < 0) @@ -961,7 +962,7 @@ int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *w *repo_out = repo; out: - git_buf_dispose(&path); + git_str_dispose(&path); return err; } @@ -986,14 +987,10 @@ int git_repository_discover( const char *ceiling_dirs) { uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0; - int error; GIT_ASSERT_ARG(start_path); - if ((error = git_buf_sanitize(out)) < 0) - return error; - - return find_repo(out, NULL, NULL, NULL, start_path, flags, ceiling_dirs); + GIT_BUF_WRAP_PRIVATE(out, find_repo, NULL, NULL, NULL, start_path, flags, ceiling_dirs); } static int load_config( @@ -1005,7 +1002,7 @@ static int load_config( const char *programdata_path) { int error; - git_buf config_path = GIT_BUF_INIT; + git_str config_path = GIT_STR_INIT; git_config *cfg = NULL; GIT_ASSERT_ARG(out); @@ -1014,13 +1011,13 @@ static int load_config( return error; if (repo) { - if ((error = git_repository_item_path(&config_path, repo, GIT_REPOSITORY_ITEM_CONFIG)) == 0) + if ((error = git_repository__item_path(&config_path, repo, GIT_REPOSITORY_ITEM_CONFIG)) == 0) error = git_config_add_file_ondisk(cfg, config_path.ptr, GIT_CONFIG_LEVEL_LOCAL, repo, 0); if (error && error != GIT_ENOTFOUND) goto on_error; - git_buf_dispose(&config_path); + git_str_dispose(&config_path); } if (global_config_path != NULL && @@ -1053,15 +1050,15 @@ static int load_config( return 0; on_error: - git_buf_dispose(&config_path); + git_str_dispose(&config_path); git_config_free(cfg); *out = NULL; return error; } -static const char *path_unless_empty(git_buf *buf) +static const char *path_unless_empty(git_str *buf) { - return git_buf_len(buf) > 0 ? git_buf_cstr(buf) : NULL; + return git_str_len(buf) > 0 ? git_str_cstr(buf) : NULL; } int git_repository_config__weakptr(git_config **out, git_repository *repo) @@ -1069,19 +1066,19 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo) int error = 0; if (repo->_config == NULL) { - git_buf global_buf = GIT_BUF_INIT; - git_buf xdg_buf = GIT_BUF_INIT; - git_buf system_buf = GIT_BUF_INIT; - git_buf programdata_buf = GIT_BUF_INIT; + git_str global_buf = GIT_STR_INIT; + git_str xdg_buf = GIT_STR_INIT; + git_str system_buf = GIT_STR_INIT; + git_str programdata_buf = GIT_STR_INIT; git_config *config; - git_config_find_global(&global_buf); - git_config_find_xdg(&xdg_buf); - git_config_find_system(&system_buf); - git_config_find_programdata(&programdata_buf); + git_config__find_global(&global_buf); + git_config__find_xdg(&xdg_buf); + git_config__find_system(&system_buf); + git_config__find_programdata(&programdata_buf); /* If there is no global file, open a backend for it anyway */ - if (git_buf_len(&global_buf) == 0) + if (git_str_len(&global_buf) == 0) git_config__global_location(&global_buf); error = load_config( @@ -1099,10 +1096,10 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo) } } - git_buf_dispose(&global_buf); - git_buf_dispose(&xdg_buf); - git_buf_dispose(&system_buf); - git_buf_dispose(&programdata_buf); + git_str_dispose(&global_buf); + git_str_dispose(&xdg_buf); + git_str_dispose(&system_buf); + git_str_dispose(&programdata_buf); } *out = repo->_config; @@ -1147,10 +1144,10 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo) *out = git_atomic_load(repo->_odb); if (*out == NULL) { - git_buf odb_path = GIT_BUF_INIT; + git_str odb_path = GIT_STR_INIT; git_odb *odb; - if ((error = git_repository_item_path(&odb_path, repo, + if ((error = git_repository__item_path(&odb_path, repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0 || (error = git_odb_new(&odb)) < 0) return error; @@ -1168,7 +1165,7 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo) git_odb_free(odb); } - git_buf_dispose(&odb_path); + git_str_dispose(&odb_path); *out = git_atomic_load(repo->_odb); } @@ -1244,10 +1241,10 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo) GIT_ASSERT_ARG(repo); if (repo->_index == NULL) { - git_buf index_path = GIT_BUF_INIT; + git_str index_path = GIT_STR_INIT; git_index *index; - if ((error = git_buf_joinpath(&index_path, repo->gitdir, GIT_INDEX_FILE)) < 0) + if ((error = git_str_joinpath(&index_path, repo->gitdir, GIT_INDEX_FILE)) < 0) return error; error = git_index_open(&index, index_path.ptr); @@ -1263,7 +1260,7 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo) GIT_INDEX_CAPABILITY_FROM_OWNER); } - git_buf_dispose(&index_path); + git_str_dispose(&index_path); } *out = repo->_index; @@ -1311,7 +1308,7 @@ static int reserved_names_add8dot3(git_repository *repo, const char *path) const char *def_dot_git = DOT_GIT; size_t name_len, def_len = CONST_STRLEN(GIT_DIR_SHORTNAME); size_t def_dot_git_len = CONST_STRLEN(DOT_GIT); - git_buf *buf; + git_str *buf; if (!name) return 0; @@ -1327,17 +1324,17 @@ static int reserved_names_add8dot3(git_repository *repo, const char *path) if ((buf = git_array_alloc(repo->reserved_names)) == NULL) return -1; - git_buf_attach(buf, name, name_len); + git_str_attach(buf, name, name_len); return true; } bool git_repository__reserved_names( - git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs) + git_str **out, size_t *outlen, git_repository *repo, bool include_ntfs) { GIT_UNUSED(include_ntfs); if (repo->reserved_names.size == 0) { - git_buf *buf; + git_str *buf; size_t i; /* Add the static defaults */ @@ -1389,7 +1386,7 @@ bool git_repository__reserved_names( } #else bool git_repository__reserved_names( - git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs) + git_str **out, size_t *outlen, git_repository *repo, bool include_ntfs) { GIT_UNUSED(repo); @@ -1435,7 +1432,7 @@ static git_vector user_extensions = GIT_VECTOR_INIT; static int check_valid_extension(const git_config_entry *entry, void *payload) { - git_buf cfg = GIT_BUF_INIT; + git_str cfg = GIT_STR_INIT; bool reject; const char *extension; size_t i; @@ -1444,7 +1441,7 @@ static int check_valid_extension(const git_config_entry *entry, void *payload) GIT_UNUSED(payload); git_vector_foreach (&user_extensions, i, extension) { - git_buf_clear(&cfg); + git_str_clear(&cfg); /* * Users can specify that they don't want to support an @@ -1453,7 +1450,7 @@ static int check_valid_extension(const git_config_entry *entry, void *payload) if ((reject = (extension[0] == '!')) == true) extension = &extension[1]; - if ((error = git_buf_printf(&cfg, "extensions.%s", extension)) < 0) + if ((error = git_str_printf(&cfg, "extensions.%s", extension)) < 0) goto done; if (strcmp(entry->name, cfg.ptr) == 0) { @@ -1467,7 +1464,7 @@ static int check_valid_extension(const git_config_entry *entry, void *payload) for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) { extension = builtin_extensions[i]; - if ((error = git_buf_printf(&cfg, "extensions.%s", extension)) < 0) + if ((error = git_str_printf(&cfg, "extensions.%s", extension)) < 0) goto done; if (strcmp(entry->name, cfg.ptr) == 0) @@ -1479,7 +1476,7 @@ static int check_valid_extension(const git_config_entry *entry, void *payload) error = -1; done: - git_buf_dispose(&cfg); + git_str_dispose(&cfg); return error; } @@ -1557,12 +1554,12 @@ void git_repository__free_extensions(void) int git_repository_create_head(const char *git_dir, const char *ref_name) { - git_buf ref_path = GIT_BUF_INIT; + git_str ref_path = GIT_STR_INIT; git_filebuf ref = GIT_FILEBUF_INIT; const char *fmt; int error; - if ((error = git_buf_joinpath(&ref_path, git_dir, GIT_HEAD_FILE)) < 0 || + if ((error = git_str_joinpath(&ref_path, git_dir, GIT_HEAD_FILE)) < 0 || (error = git_filebuf_open(&ref, ref_path.ptr, 0, GIT_REFS_FILE_MODE)) < 0) goto out; @@ -1576,7 +1573,7 @@ int git_repository_create_head(const char *git_dir, const char *ref_name) goto out; out: - git_buf_dispose(&ref_path); + git_str_dispose(&ref_path); git_filebuf_cleanup(&ref); return error; } @@ -1599,23 +1596,23 @@ static bool is_chmod_supported(const char *file_path) static bool is_filesystem_case_insensitive(const char *gitdir_path) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int is_insensitive = -1; - if (!git_buf_joinpath(&path, gitdir_path, "CoNfIg")) - is_insensitive = git_path_exists(git_buf_cstr(&path)); + if (!git_str_joinpath(&path, gitdir_path, "CoNfIg")) + is_insensitive = git_path_exists(git_str_cstr(&path)); - git_buf_dispose(&path); + git_str_dispose(&path); return is_insensitive; } static bool are_symlinks_supported(const char *wd_path) { git_config *config = NULL; - git_buf global_buf = GIT_BUF_INIT; - git_buf xdg_buf = GIT_BUF_INIT; - git_buf system_buf = GIT_BUF_INIT; - git_buf programdata_buf = GIT_BUF_INIT; + git_str global_buf = GIT_STR_INIT; + git_str xdg_buf = GIT_STR_INIT; + git_str system_buf = GIT_STR_INIT; + git_str programdata_buf = GIT_STR_INIT; int symlinks = 0; /* @@ -1626,10 +1623,10 @@ static bool are_symlinks_supported(const char *wd_path) * _not_ set, then we do not test or enable symlink support. */ #ifdef GIT_WIN32 - git_config_find_global(&global_buf); - git_config_find_xdg(&xdg_buf); - git_config_find_system(&system_buf); - git_config_find_programdata(&programdata_buf); + git_config__find_global(&global_buf); + git_config__find_xdg(&xdg_buf); + git_config__find_system(&system_buf); + git_config__find_programdata(&programdata_buf); if (load_config(&config, NULL, path_unless_empty(&global_buf), @@ -1646,10 +1643,10 @@ static bool are_symlinks_supported(const char *wd_path) goto done; done: - git_buf_dispose(&global_buf); - git_buf_dispose(&xdg_buf); - git_buf_dispose(&system_buf); - git_buf_dispose(&programdata_buf); + git_str_dispose(&global_buf); + git_str_dispose(&xdg_buf); + git_str_dispose(&system_buf); + git_str_dispose(&programdata_buf); git_config_free(config); return symlinks != 0; } @@ -1673,7 +1670,7 @@ static int create_empty_file(const char *path, mode_t mode) static int repo_local_config( git_config **out, - git_buf *config_dir, + git_str *config_dir, git_repository *repo, const char *repo_dir) { @@ -1681,9 +1678,9 @@ static int repo_local_config( git_config *parent; const char *cfg_path; - if (git_buf_joinpath(config_dir, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0) + if (git_str_joinpath(config_dir, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0) return -1; - cfg_path = git_buf_cstr(config_dir); + cfg_path = git_str_cstr(config_dir); /* make LOCAL config if missing */ if (!git_path_isfile(cfg_path) && @@ -1759,7 +1756,7 @@ static int repo_init_config( uint32_t mode) { int error = 0; - git_buf cfg_path = GIT_BUF_INIT, worktree_path = GIT_BUF_INIT; + git_str cfg_path = GIT_STR_INIT, worktree_path = GIT_STR_INIT; git_config *config = NULL; bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0); bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0); @@ -1789,7 +1786,7 @@ static int repo_init_config( SET_REPO_CONFIG(bool, "core.logallrefupdates", true); if (!(flags & GIT_REPOSITORY_INIT__NATURAL_WD)) { - if ((error = git_buf_sets(&worktree_path, work_dir)) < 0) + if ((error = git_str_sets(&worktree_path, work_dir)) < 0) goto cleanup; if ((flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK)) @@ -1813,8 +1810,8 @@ static int repo_init_config( } cleanup: - git_buf_dispose(&cfg_path); - git_buf_dispose(&worktree_path); + git_str_dispose(&cfg_path); + git_str_dispose(&worktree_path); git_config_free(config); return error; @@ -1836,7 +1833,7 @@ static int repo_reinit_submodule_fs(git_submodule *sm, const char *n, void *p) int git_repository_reinit_filesystem(git_repository *repo, int recurse) { int error = 0; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_config *config = NULL; const char *repo_dir = git_repository_path(repo); @@ -1845,7 +1842,7 @@ int git_repository_reinit_filesystem(git_repository *repo, int recurse) config, path.ptr, repo_dir, git_repository_workdir(repo), true); git_config_free(config); - git_buf_dispose(&path); + git_str_dispose(&path); git_repository__configmap_lookup_cache_clear(repo); @@ -1863,10 +1860,10 @@ static int repo_write_template( bool hidden, const char *content) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int fd, error = 0, flags; - if (git_buf_joinpath(&path, git_dir, file) < 0) + if (git_str_joinpath(&path, git_dir, file) < 0) return -1; if (allow_overwrite) @@ -1874,7 +1871,7 @@ static int repo_write_template( else flags = O_WRONLY | O_CREAT | O_EXCL; - fd = p_open(git_buf_cstr(&path), flags, mode); + fd = p_open(git_str_cstr(&path), flags, mode); if (fd >= 0) { error = p_write(fd, content, strlen(content)); @@ -1893,7 +1890,7 @@ static int repo_write_template( GIT_UNUSED(hidden); #endif - git_buf_dispose(&path); + git_str_dispose(&path); if (error) git_error_set(GIT_ERROR_OS, @@ -1906,13 +1903,13 @@ static int repo_write_gitlink( const char *in_dir, const char *to_repo, bool use_relative_path) { int error; - git_buf buf = GIT_BUF_INIT; - git_buf path_to_repo = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; + git_str path_to_repo = GIT_STR_INIT; struct stat st; git_path_dirname_r(&buf, to_repo); git_path_to_dir(&buf); - if (git_buf_oom(&buf)) + if (git_str_oom(&buf)) return -1; /* don't write gitlink to natural workdir */ @@ -1923,7 +1920,7 @@ static int repo_write_gitlink( goto cleanup; } - if ((error = git_buf_joinpath(&buf, in_dir, DOT_GIT)) < 0) + if ((error = git_str_joinpath(&buf, in_dir, DOT_GIT)) < 0) goto cleanup; if (!p_stat(buf.ptr, &st) && !S_ISREG(st.st_mode)) { @@ -1933,22 +1930,22 @@ static int repo_write_gitlink( goto cleanup; } - git_buf_clear(&buf); + git_str_clear(&buf); - error = git_buf_sets(&path_to_repo, to_repo); + error = git_str_sets(&path_to_repo, to_repo); if (!error && use_relative_path) error = git_path_make_relative(&path_to_repo, in_dir); if (!error) - error = git_buf_join(&buf, ' ', GIT_FILE_CONTENT_PREFIX, path_to_repo.ptr); + error = git_str_join(&buf, ' ', GIT_FILE_CONTENT_PREFIX, path_to_repo.ptr); if (!error) error = repo_write_template(in_dir, true, DOT_GIT, 0666, true, buf.ptr); cleanup: - git_buf_dispose(&buf); - git_buf_dispose(&path_to_repo); + git_str_dispose(&buf); + git_str_dispose(&path_to_repo); return error; } @@ -2001,12 +1998,12 @@ static int repo_init_structure( git_config *cfg = NULL; const char *tdir = NULL; bool default_template = false; - git_buf template_buf = GIT_BUF_INIT; + git_str template_buf = GIT_STR_INIT; if (opts->template_path) tdir = opts->template_path; else if ((error = git_config_open_default(&cfg)) >= 0) { - if (!git_config_get_path(&template_buf, cfg, "init.templatedir")) + if (!git_config__get_path(&template_buf, cfg, "init.templatedir")) tdir = template_buf.ptr; git_error_clear(); } @@ -2032,7 +2029,7 @@ static int repo_init_structure( error = git_futils_cp_r(tdir, repo_dir, cpflags, dmode); } - git_buf_dispose(&template_buf); + git_str_dispose(&template_buf); git_config_free(cfg); if (error < 0) { @@ -2073,7 +2070,7 @@ static int repo_init_structure( return error; } -static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2) +static int mkdir_parent(git_str *buf, uint32_t mode, bool skip2) { /* When making parent directories during repository initialization * don't try to set gid or grant world write access @@ -2085,8 +2082,8 @@ static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2) } static int repo_init_directories( - git_buf *repo_path, - git_buf *wd_path, + git_str *repo_path, + git_str *wd_path, const char *given_repo, git_repository_init_options *opts) { @@ -2124,7 +2121,7 @@ static int repo_init_directories( git__suffixcmp(given_repo, "/" DOT_GIT) != 0 && git__suffixcmp(given_repo, "/" GIT_DIR) != 0; - if (git_buf_joinpath(repo_path, given_repo, add_dotgit ? GIT_DIR : "") < 0) + if (git_str_joinpath(repo_path, given_repo, add_dotgit ? GIT_DIR : "") < 0) return -1; has_dotgit = (git__suffixcmp(repo_path->ptr, "/" GIT_DIR) == 0); @@ -2150,7 +2147,7 @@ static int repo_init_directories( if (git_path_to_dir(wd_path) < 0) return -1; } else { - git_buf_clear(wd_path); + git_str_clear(wd_path); } natural_wd = @@ -2219,11 +2216,11 @@ static int repo_init_directories( static int repo_init_head(const char *repo_dir, const char *given) { git_config *cfg = NULL; - git_buf head_path = GIT_BUF_INIT, cfg_branch = GIT_BUF_INIT; + git_str head_path = GIT_STR_INIT, cfg_branch = GIT_STR_INIT; const char *initial_head = NULL; int error; - if ((error = git_buf_joinpath(&head_path, repo_dir, GIT_HEAD_FILE)) < 0) + if ((error = git_str_joinpath(&head_path, repo_dir, GIT_HEAD_FILE)) < 0) goto out; /* @@ -2236,7 +2233,7 @@ static int repo_init_head(const char *repo_dir, const char *given) if (given) { initial_head = given; } else if ((error = git_config_open_default(&cfg)) >= 0 && - (error = git_config_get_string_buf(&cfg_branch, cfg, "init.defaultbranch")) >= 0 && + (error = git_config__get_string_buf(&cfg_branch, cfg, "init.defaultbranch")) >= 0 && *cfg_branch.ptr) { initial_head = cfg_branch.ptr; } @@ -2248,8 +2245,8 @@ static int repo_init_head(const char *repo_dir, const char *given) out: git_config_free(cfg); - git_buf_dispose(&head_path); - git_buf_dispose(&cfg_branch); + git_str_dispose(&head_path); + git_str_dispose(&cfg_branch); return error; } @@ -2283,8 +2280,8 @@ int git_repository_init_ext( const char *given_repo, git_repository_init_options *opts) { - git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT, - common_path = GIT_BUF_INIT; + git_str repo_path = GIT_STR_INIT, wd_path = GIT_STR_INIT, + common_path = GIT_STR_INIT; const char *wd; bool is_valid; int error; @@ -2298,7 +2295,7 @@ int git_repository_init_ext( if ((error = repo_init_directories(&repo_path, &wd_path, given_repo, opts)) < 0) goto out; - wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_buf_cstr(&wd_path); + wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_str_cstr(&wd_path); if ((error = is_valid_repository_path(&is_valid, &repo_path, &common_path)) < 0) goto out; @@ -2332,9 +2329,9 @@ int git_repository_init_ext( goto out; out: - git_buf_dispose(&common_path); - git_buf_dispose(&repo_path); - git_buf_dispose(&wd_path); + git_str_dispose(&common_path); + git_str_dispose(&repo_path); + git_str_dispose(&wd_path); return error; } @@ -2522,7 +2519,7 @@ static int repo_contains_no_reference(git_repository *repo) return error; } -int git_repository_initialbranch(git_buf *out, git_repository *repo) +int git_repository_initialbranch(git_str *out, git_repository *repo) { git_config *config; git_config_entry *entry = NULL; @@ -2543,8 +2540,8 @@ int git_repository_initialbranch(git_buf *out, git_repository *repo) goto done; } - if ((error = git_buf_puts(out, GIT_REFS_HEADS_DIR)) < 0 || - (error = git_buf_puts(out, branch)) < 0 || + if ((error = git_str_puts(out, GIT_REFS_HEADS_DIR)) < 0 || + (error = git_str_puts(out, branch)) < 0 || (error = git_reference_name_is_valid(&valid, out->ptr)) < 0) goto done; @@ -2561,7 +2558,7 @@ int git_repository_initialbranch(git_buf *out, git_repository *repo) int git_repository_is_empty(git_repository *repo) { git_reference *head = NULL; - git_buf initialbranch = GIT_BUF_INIT; + git_str initialbranch = GIT_STR_INIT; int result = 0; if ((result = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0 || @@ -2574,7 +2571,7 @@ int git_repository_is_empty(git_repository *repo) done: git_reference_free(head); - git_buf_dispose(&initialbranch); + git_str_dispose(&initialbranch); return result; } @@ -2603,7 +2600,18 @@ static const char *resolved_parent_path(const git_repository *repo, git_reposito return parent; } -int git_repository_item_path(git_buf *out, const git_repository *repo, git_repository_item_t item) +int git_repository_item_path( + git_buf *out, + const git_repository *repo, + git_repository_item_t item) +{ + GIT_BUF_WRAP_PRIVATE(out, git_repository__item_path, repo, item); +} + +int git_repository__item_path( + git_str *out, + const git_repository *repo, + git_repository_item_t item) { const char *parent = resolved_parent_path(repo, items[item].parent, items[item].fallback); if (parent == NULL) { @@ -2611,11 +2619,11 @@ int git_repository_item_path(git_buf *out, const git_repository *repo, git_repos return GIT_ENOTFOUND; } - if (git_buf_sets(out, parent) < 0) + if (git_str_sets(out, parent) < 0) return -1; if (items[item].name) { - if (git_buf_joinpath(out, parent, items[item].name) < 0) + if (git_str_joinpath(out, parent, items[item].name) < 0) return -1; } @@ -2644,7 +2652,7 @@ const char *git_repository_workdir(const git_repository *repo) } int git_repository_workdir_path( - git_buf *out, git_repository *repo, const char *path) + git_str *out, git_repository *repo, const char *path) { int error; @@ -2653,7 +2661,7 @@ int git_repository_workdir_path( return GIT_EBAREREPO; } - if (!(error = git_buf_joinpath(out, repo->workdir, path))) + if (!(error = git_str_joinpath(out, repo->workdir, path))) error = git_path_validate_workdir_buf(repo, out); return error; @@ -2669,7 +2677,7 @@ int git_repository_set_workdir( git_repository *repo, const char *workdir, int update_gitlink) { int error = 0; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(workdir); @@ -2701,7 +2709,7 @@ int git_repository_set_workdir( if (!error) { char *old_workdir = repo->workdir; - repo->workdir = git_buf_detach(&path); + repo->workdir = git_str_detach(&path); repo->is_bare = 0; git__free(old_workdir); @@ -2770,13 +2778,13 @@ int git_repository_head_tree(git_tree **tree, git_repository *repo) int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf file_path = GIT_BUF_INIT; + git_str file_path = GIT_STR_INIT; char orig_head_str[GIT_OID_HEXSZ]; int error = 0; git_oid_fmt(orig_head_str, orig_head); - if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_ORIG_HEAD_FILE)) == 0 && + if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_ORIG_HEAD_FILE)) == 0 && (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) == 0 && (error = git_filebuf_printf(&file, "%.*s\n", GIT_OID_HEXSZ, orig_head_str)) == 0) error = git_filebuf_commit(&file); @@ -2784,46 +2792,48 @@ int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head if (error < 0) git_filebuf_cleanup(&file); - git_buf_dispose(&file_path); + git_str_dispose(&file_path); return error; } -int git_repository_message(git_buf *out, git_repository *repo) +static int git_repository__message(git_str *out, git_repository *repo) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; struct stat st; int error; - if ((error = git_buf_sanitize(out)) < 0) - return error; - - if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0) + if (git_str_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0) return -1; - if ((error = p_stat(git_buf_cstr(&path), &st)) < 0) { + if ((error = p_stat(git_str_cstr(&path), &st)) < 0) { if (errno == ENOENT) error = GIT_ENOTFOUND; git_error_set(GIT_ERROR_OS, "could not access message file"); } else { - error = git_futils_readbuffer(out, git_buf_cstr(&path)); + error = git_futils_readbuffer(out, git_str_cstr(&path)); } - git_buf_dispose(&path); + git_str_dispose(&path); return error; } +int git_repository_message(git_buf *out, git_repository *repo) +{ + GIT_BUF_WRAP_PRIVATE(out, git_repository__message, repo); +} + int git_repository_message_remove(git_repository *repo) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error; - if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0) + if (git_str_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0) return -1; - error = p_unlink(git_buf_cstr(&path)); - git_buf_dispose(&path); + error = p_unlink(git_str_cstr(&path)); + git_str_dispose(&path); return error; } @@ -2839,7 +2849,7 @@ int git_repository_hashfile( git_filter_list *fl = NULL; git_file fd = -1; uint64_t len; - git_buf full_path = GIT_BUF_INIT; + git_str full_path = GIT_STR_INIT; const char *workdir = git_repository_workdir(repo); /* as_path can be NULL */ @@ -2895,30 +2905,30 @@ int git_repository_hashfile( if (fd >= 0) p_close(fd); git_filter_list_free(fl); - git_buf_dispose(&full_path); + git_str_dispose(&full_path); return error; } -static int checkout_message(git_buf *out, git_reference *old, const char *new) +static int checkout_message(git_str *out, git_reference *old, const char *new) { - git_buf_puts(out, "checkout: moving from "); + git_str_puts(out, "checkout: moving from "); if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC) - git_buf_puts(out, git_reference__shorthand(git_reference_symbolic_target(old))); + git_str_puts(out, git_reference__shorthand(git_reference_symbolic_target(old))); else - git_buf_puts(out, git_oid_tostr_s(git_reference_target(old))); + git_str_puts(out, git_oid_tostr_s(git_reference_target(old))); - git_buf_puts(out, " to "); + git_str_puts(out, " to "); if (git_reference__is_branch(new) || git_reference__is_tag(new) || git_reference__is_remote(new)) - git_buf_puts(out, git_reference__shorthand(new)); + git_str_puts(out, git_reference__shorthand(new)); else - git_buf_puts(out, new); + git_str_puts(out, new); - if (git_buf_oom(out)) + if (git_str_oom(out)) return -1; return 0; @@ -2927,7 +2937,7 @@ static int checkout_message(git_buf *out, git_reference *old, const char *new) static int detach(git_repository *repo, const git_oid *id, const char *new) { int error; - git_buf log_message = GIT_BUF_INIT; + git_str log_message = GIT_STR_INIT; git_object *object = NULL, *peeled = NULL; git_reference *new_head = NULL, *current = NULL; @@ -2949,10 +2959,10 @@ static int detach(git_repository *repo, const git_oid *id, const char *new) if ((error = checkout_message(&log_message, current, new)) < 0) goto cleanup; - error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_buf_cstr(&log_message)); + error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_str_cstr(&log_message)); cleanup: - git_buf_dispose(&log_message); + git_str_dispose(&log_message); git_object_free(object); git_object_free(peeled); git_reference_free(current); @@ -2965,7 +2975,7 @@ int git_repository_set_head( const char *refname) { git_reference *ref = NULL, *current = NULL, *new_head = NULL; - git_buf log_message = GIT_BUF_INIT; + git_str log_message = GIT_STR_INIT; int error; GIT_ASSERT_ARG(repo); @@ -2992,18 +3002,18 @@ int git_repository_set_head( if (!error) { if (git_reference_is_branch(ref)) { error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, - git_reference_name(ref), true, git_buf_cstr(&log_message)); + git_reference_name(ref), true, git_str_cstr(&log_message)); } else { error = detach(repo, git_reference_target(ref), git_reference_is_tag(ref) || git_reference_is_remote(ref) ? refname : NULL); } } else if (git_reference__is_branch(refname)) { error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname, - true, git_buf_cstr(&log_message)); + true, git_str_cstr(&log_message)); } cleanup: - git_buf_dispose(&log_message); + git_str_dispose(&log_message); git_reference_free(current); git_reference_free(ref); git_reference_free(new_head); @@ -3031,7 +3041,7 @@ int git_repository_detach_head(git_repository *repo) { git_reference *old_head = NULL, *new_head = NULL, *current = NULL; git_object *object = NULL; - git_buf log_message = GIT_BUF_INIT; + git_str log_message = GIT_STR_INIT; int error; GIT_ASSERT_ARG(repo); @@ -3049,10 +3059,10 @@ int git_repository_detach_head(git_repository *repo) goto cleanup; error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head), - 1, git_buf_cstr(&log_message)); + 1, git_str_cstr(&log_message)); cleanup: - git_buf_dispose(&log_message); + git_str_dispose(&log_message); git_object_free(object); git_reference_free(old_head); git_reference_free(new_head); @@ -3066,12 +3076,12 @@ int git_repository_detach_head(git_repository *repo) */ int git_repository_state(git_repository *repo) { - git_buf repo_path = GIT_BUF_INIT; + git_str repo_path = GIT_STR_INIT; int state = GIT_REPOSITORY_STATE_NONE; GIT_ASSERT_ARG(repo); - if (git_buf_puts(&repo_path, repo->gitdir) < 0) + if (git_str_puts(&repo_path, repo->gitdir) < 0) return -1; if (git_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE)) @@ -3099,24 +3109,24 @@ int git_repository_state(git_repository *repo) } else if (git_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE)) state = GIT_REPOSITORY_STATE_BISECT; - git_buf_dispose(&repo_path); + git_str_dispose(&repo_path); return state; } int git_repository__cleanup_files( git_repository *repo, const char *files[], size_t files_len) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; size_t i; int error; for (error = 0, i = 0; !error && i < files_len; ++i) { const char *path; - if (git_buf_joinpath(&buf, repo->gitdir, files[i]) < 0) + if (git_str_joinpath(&buf, repo->gitdir, files[i]) < 0) return -1; - path = git_buf_cstr(&buf); + path = git_str_cstr(&buf); if (git_path_isfile(path)) { error = p_unlink(path); @@ -3125,10 +3135,10 @@ int git_repository__cleanup_files( GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS); } - git_buf_clear(&buf); + git_str_clear(&buf); } - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -3153,15 +3163,15 @@ int git_repository_state_cleanup(git_repository *repo) int git_repository_is_shallow(git_repository *repo) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; struct stat st; int error; - if ((error = git_buf_joinpath(&path, repo->gitdir, "shallow")) < 0) + if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0) return error; error = git_path_lstat(path.ptr, &st); - git_buf_dispose(&path); + git_str_dispose(&path); if (error == GIT_ENOTFOUND) { git_error_clear(); diff --git a/src/repository.h b/src/repository.h index cbc160140f3..1ea5a44f767 100644 --- a/src/repository.h +++ b/src/repository.h @@ -19,7 +19,7 @@ #include "array.h" #include "cache.h" #include "refs.h" -#include "buffer.h" +#include "str.h" #include "object.h" #include "attrcache.h" #include "submodule.h" @@ -148,7 +148,7 @@ struct git_repository { char *ident_name; char *ident_email; - git_array_t(git_buf) reserved_names; + git_array_t(git_str) reserved_names; unsigned is_bare:1; unsigned is_worktree:1; @@ -196,6 +196,8 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo); int git_repository__configmap_lookup(int *out, git_repository *repo, git_configmap_item item); void git_repository__configmap_lookup_cache_clear(git_repository *repo); +int git_repository__item_path(git_str *out, const git_repository *repo, git_repository_item_t item); + GIT_INLINE(int) git_repository__ensure_not_bare( git_repository *repo, const char *operation_name) @@ -216,10 +218,10 @@ int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head int git_repository__cleanup_files(git_repository *repo, const char *files[], size_t files_len); /* The default "reserved names" for a repository */ -extern git_buf git_repository__reserved_names_win32[]; +extern git_str git_repository__reserved_names_win32[]; extern size_t git_repository__reserved_names_win32_len; -extern git_buf git_repository__reserved_names_posix[]; +extern git_str git_repository__reserved_names_posix[]; extern size_t git_repository__reserved_names_posix_len; /* @@ -233,13 +235,13 @@ extern size_t git_repository__reserved_names_posix_len; * will still be populated with good defaults. */ bool git_repository__reserved_names( - git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs); + git_str **out, size_t *outlen, git_repository *repo, bool include_ntfs); /* * The default branch for the repository; the `init.defaultBranch` * configuration option, if set, or `master` if it is not. */ -int git_repository_initialbranch(git_buf *out, git_repository *repo); +int git_repository_initialbranch(git_str *out, git_repository *repo); /* * Given a relative `path`, this makes it absolute based on the @@ -247,7 +249,7 @@ int git_repository_initialbranch(git_buf *out, git_repository *repo); * to ensure that the path is not longer than MAX_PATH on Windows * (unless `core.longpaths` is set in the repo config). */ -int git_repository_workdir_path(git_buf *out, git_repository *repo, const char *path); +int git_repository_workdir_path(git_str *out, git_repository *repo, const char *path); int git_repository__extensions(char ***out, size_t *out_len); int git_repository__set_extensions(const char **extensions, size_t len); diff --git a/src/reset.c b/src/reset.c index f21a620c653..b8327fe5e0b 100644 --- a/src/reset.c +++ b/src/reset.c @@ -111,7 +111,7 @@ static int reset( git_tree *tree = NULL; int error = 0; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - git_buf log_message = GIT_BUF_INIT; + git_str log_message = GIT_STR_INIT; GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(target); @@ -144,7 +144,7 @@ static int reset( goto cleanup; } - if ((error = git_buf_printf(&log_message, "reset: moving to %s", to)) < 0) + if ((error = git_str_printf(&log_message, "reset: moving to %s", to)) < 0) return error; if (reset_type == GIT_RESET_HARD) { @@ -157,7 +157,7 @@ static int reset( /* move HEAD to the new target */ if ((error = git_reference__update_terminal(repo, GIT_HEAD_FILE, - git_object_id(commit), NULL, git_buf_cstr(&log_message))) < 0) + git_object_id(commit), NULL, git_str_cstr(&log_message))) < 0) goto cleanup; if (reset_type > GIT_RESET_SOFT) { @@ -177,7 +177,7 @@ static int reset( git_object_free(commit); git_index_free(index); git_tree_free(tree); - git_buf_dispose(&log_message); + git_str_dispose(&log_message); return error; } diff --git a/src/revert.c b/src/revert.c index 683f0d70d8b..d6ab6ae3ce4 100644 --- a/src/revert.c +++ b/src/revert.c @@ -25,10 +25,10 @@ static int write_revert_head( const char *commit_oidstr) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf file_path = GIT_BUF_INIT; + git_str file_path = GIT_STR_INIT; int error = 0; - if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_REVERT_HEAD_FILE)) >= 0 && + if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_REVERT_HEAD_FILE)) >= 0 && (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_REVERT_FILE_MODE)) >= 0 && (error = git_filebuf_printf(&file, "%s\n", commit_oidstr)) >= 0) error = git_filebuf_commit(&file); @@ -36,7 +36,7 @@ static int write_revert_head( if (error < 0) git_filebuf_cleanup(&file); - git_buf_dispose(&file_path); + git_str_dispose(&file_path); return error; } @@ -47,10 +47,10 @@ static int write_merge_msg( const char *commit_msgline) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf file_path = GIT_BUF_INIT; + git_str file_path = GIT_STR_INIT; int error = 0; - if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 || + if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 || (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_REVERT_FILE_MODE)) < 0 || (error = git_filebuf_printf(&file, "Revert \"%s\"\n\nThis reverts commit %s.\n", commit_msgline, commit_oidstr)) < 0) @@ -62,7 +62,7 @@ static int write_merge_msg( if (error < 0) git_filebuf_cleanup(&file); - git_buf_dispose(&file_path); + git_str_dispose(&file_path); return error; } @@ -178,7 +178,7 @@ int git_revert( git_commit *our_commit = NULL; char commit_oidstr[GIT_OID_HEXSZ + 1]; const char *commit_msg; - git_buf their_label = GIT_BUF_INIT; + git_str their_label = GIT_STR_INIT; git_index *index = NULL; git_indexwriter indexwriter = GIT_INDEXWRITER_INIT; int error; @@ -199,8 +199,8 @@ int git_revert( goto on_error; } - if ((error = git_buf_printf(&their_label, "parent of %.7s... %s", commit_oidstr, commit_msg)) < 0 || - (error = revert_normalize_opts(repo, &opts, given_opts, git_buf_cstr(&their_label))) < 0 || + if ((error = git_str_printf(&their_label, "parent of %.7s... %s", commit_oidstr, commit_msg)) < 0 || + (error = revert_normalize_opts(repo, &opts, given_opts, git_str_cstr(&their_label))) < 0 || (error = git_indexwriter_init_for_operation(&indexwriter, repo, &opts.checkout_opts.checkout_strategy)) < 0 || (error = write_revert_head(repo, commit_oidstr)) < 0 || (error = write_merge_msg(repo, commit_oidstr, commit_msg)) < 0 || @@ -223,7 +223,7 @@ int git_revert( git_index_free(index); git_commit_free(our_commit); git_reference_free(our_ref); - git_buf_dispose(&their_label); + git_str_dispose(&their_label); return error; } diff --git a/src/revparse.c b/src/revparse.c index b4d5d475938..cf39936a5b1 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -7,7 +7,7 @@ #include "common.h" -#include "buffer.h" +#include "str.h" #include "tree.h" #include "refdb.h" #include "regexp.h" @@ -145,7 +145,7 @@ static int retrieve_previously_checked_out_branch_or_revision(git_object **out, size_t i, numentries, cur; const git_reflog_entry *entry; const char *msg; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; cur = position; @@ -179,16 +179,16 @@ static int retrieve_previously_checked_out_branch_or_revision(git_object **out, if (cur > 0) continue; - if ((git_buf_put(&buf, msg+regexmatches[1].start, regexmatches[1].end - regexmatches[1].start)) < 0) + if ((git_str_put(&buf, msg+regexmatches[1].start, regexmatches[1].end - regexmatches[1].start)) < 0) goto cleanup; - if ((error = git_reference_dwim(base_ref, repo, git_buf_cstr(&buf))) == 0) + if ((error = git_reference_dwim(base_ref, repo, git_str_cstr(&buf))) == 0) goto cleanup; if (error < 0 && error != GIT_ENOTFOUND) goto cleanup; - error = maybe_abbrev(out, repo, git_buf_cstr(&buf)); + error = maybe_abbrev(out, repo, git_str_cstr(&buf)); goto cleanup; } @@ -197,7 +197,7 @@ static int retrieve_previously_checked_out_branch_or_revision(git_object **out, cleanup: git_reference_free(ref); - git_buf_dispose(&buf); + git_str_dispose(&buf); git_regexp_dispose(&preg); git_reflog_free(reflog); return error; @@ -314,12 +314,12 @@ static int handle_at_syntax(git_object **out, git_reference **ref, const char *s { bool is_numeric; int parsed = 0, error = -1; - git_buf identifier = GIT_BUF_INIT; + git_str identifier = GIT_STR_INIT; git_time_t timestamp; GIT_ASSERT(*out == NULL); - if (git_buf_put(&identifier, spec, identifier_len) < 0) + if (git_str_put(&identifier, spec, identifier_len) < 0) return -1; is_numeric = !try_parse_numeric(&parsed, curly_braces_content); @@ -331,15 +331,15 @@ static int handle_at_syntax(git_object **out, git_reference **ref, const char *s if (is_numeric) { if (parsed < 0) - error = retrieve_previously_checked_out_branch_or_revision(out, ref, repo, git_buf_cstr(&identifier), -parsed); + error = retrieve_previously_checked_out_branch_or_revision(out, ref, repo, git_str_cstr(&identifier), -parsed); else - error = retrieve_revobject_from_reflog(out, ref, repo, git_buf_cstr(&identifier), parsed); + error = retrieve_revobject_from_reflog(out, ref, repo, git_str_cstr(&identifier), parsed); goto cleanup; } if (!strcmp(curly_braces_content, "u") || !strcmp(curly_braces_content, "upstream")) { - error = retrieve_remote_tracking_reference(ref, git_buf_cstr(&identifier), repo); + error = retrieve_remote_tracking_reference(ref, git_str_cstr(&identifier), repo); goto cleanup; } @@ -347,10 +347,10 @@ static int handle_at_syntax(git_object **out, git_reference **ref, const char *s if (git__date_parse(×tamp, curly_braces_content) < 0) goto cleanup; - error = retrieve_revobject_from_reflog(out, ref, repo, git_buf_cstr(&identifier), (size_t)timestamp); + error = retrieve_revobject_from_reflog(out, ref, repo, git_str_cstr(&identifier), (size_t)timestamp); cleanup: - git_buf_dispose(&identifier); + git_str_dispose(&identifier); return error; } @@ -520,9 +520,9 @@ static int handle_caret_curly_syntax(git_object **out, git_object *obj, const ch return git_object_peel(out, obj, expected_type); } -static int extract_curly_braces_content(git_buf *buf, const char *spec, size_t *pos) +static int extract_curly_braces_content(git_str *buf, const char *spec, size_t *pos) { - git_buf_clear(buf); + git_str_clear(buf); GIT_ASSERT_ARG(spec[*pos] == '^' || spec[*pos] == '@'); @@ -537,7 +537,7 @@ static int extract_curly_braces_content(git_buf *buf, const char *spec, size_t * if (spec[*pos] == '\0') return GIT_EINVALIDSPEC; - if (git_buf_putc(buf, spec[(*pos)++]) < 0) + if (git_str_putc(buf, spec[(*pos)++]) < 0) return -1; } @@ -546,18 +546,18 @@ static int extract_curly_braces_content(git_buf *buf, const char *spec, size_t * return 0; } -static int extract_path(git_buf *buf, const char *spec, size_t *pos) +static int extract_path(git_str *buf, const char *spec, size_t *pos) { - git_buf_clear(buf); + git_str_clear(buf); GIT_ASSERT_ARG(spec[*pos] == ':'); (*pos)++; - if (git_buf_puts(buf, spec + *pos) < 0) + if (git_str_puts(buf, spec + *pos) < 0) return -1; - *pos += git_buf_len(buf); + *pos += git_str_len(buf); return 0; } @@ -610,7 +610,7 @@ static int object_from_reference(git_object **object, git_reference *reference) static int ensure_base_rev_loaded(git_object **object, git_reference **reference, const char *spec, size_t identifier_len, git_repository *repo, bool allow_empty_identifier) { int error; - git_buf identifier = GIT_BUF_INIT; + git_str identifier = GIT_STR_INIT; if (*object != NULL) return 0; @@ -621,11 +621,11 @@ static int ensure_base_rev_loaded(git_object **object, git_reference **reference if (!allow_empty_identifier && identifier_len == 0) return GIT_EINVALIDSPEC; - if (git_buf_put(&identifier, spec, identifier_len) < 0) + if (git_str_put(&identifier, spec, identifier_len) < 0) return -1; - error = revparse_lookup_object(object, reference, repo, git_buf_cstr(&identifier)); - git_buf_dispose(&identifier); + error = revparse_lookup_object(object, reference, repo, git_str_cstr(&identifier)); + git_str_dispose(&identifier); return error; } @@ -669,7 +669,7 @@ static int revparse( { size_t pos = 0, identifier_len = 0; int error = -1, n; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_reference *reference = NULL; git_object *base_rev = NULL; @@ -698,7 +698,7 @@ static int revparse( if ((error = extract_curly_braces_content(&buf, spec, &pos)) < 0) goto cleanup; - if ((error = handle_caret_curly_syntax(&temp_object, base_rev, git_buf_cstr(&buf))) < 0) + if ((error = handle_caret_curly_syntax(&temp_object, base_rev, git_str_cstr(&buf))) < 0) goto cleanup; git_object_free(base_rev); @@ -750,11 +750,11 @@ static int revparse( if ((error = ensure_base_rev_loaded(&base_rev, &reference, spec, identifier_len, repo, true)) < 0) goto cleanup; - if ((error = handle_colon_syntax(&temp_object, base_rev, git_buf_cstr(&buf))) < 0) + if ((error = handle_colon_syntax(&temp_object, base_rev, git_str_cstr(&buf))) < 0) goto cleanup; } else { - if (*git_buf_cstr(&buf) == '/') { - if ((error = handle_grep_syntax(&temp_object, repo, NULL, git_buf_cstr(&buf) + 1)) < 0) + if (*git_str_cstr(&buf) == '/') { + if ((error = handle_grep_syntax(&temp_object, repo, NULL, git_str_cstr(&buf) + 1)) < 0) goto cleanup; } else { @@ -783,7 +783,7 @@ static int revparse( if ((error = ensure_base_rev_is_not_known_yet(base_rev)) < 0) goto cleanup; - if ((error = handle_at_syntax(&temp_object, &reference, spec, identifier_len, repo, git_buf_cstr(&buf))) < 0) + if ((error = handle_at_syntax(&temp_object, &reference, spec, identifier_len, repo, git_str_cstr(&buf))) < 0) goto cleanup; if (temp_object != NULL) @@ -824,7 +824,7 @@ static int revparse( git_reference_free(reference); } - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } diff --git a/src/revwalk.c b/src/revwalk.c index a686a9f6fa9..e29e9c9b90e 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -131,7 +131,7 @@ int git_revwalk__push_glob(git_revwalk *walk, const char *glob, const git_revwal { git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT; int error = 0; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_reference *ref; git_reference_iterator *iter; size_t wildcard; @@ -144,15 +144,15 @@ int git_revwalk__push_glob(git_revwalk *walk, const char *glob, const git_revwal /* refs/ is implied if not given in the glob */ if (git__prefixcmp(glob, GIT_REFS_DIR) != 0) - git_buf_joinpath(&buf, GIT_REFS_DIR, glob); + git_str_joinpath(&buf, GIT_REFS_DIR, glob); else - git_buf_puts(&buf, glob); - GIT_ERROR_CHECK_ALLOC_BUF(&buf); + git_str_puts(&buf, glob); + GIT_ERROR_CHECK_ALLOC_STR(&buf); /* If no '?', '*' or '[' exist, we append '/ *' to the glob */ wildcard = strcspn(glob, "?*["); if (!glob[wildcard]) - git_buf_put(&buf, "/*", 2); + git_str_put(&buf, "/*", 2); if ((error = git_reference_iterator_glob_new(&iter, walk->repo, buf.ptr)) < 0) goto out; @@ -169,7 +169,7 @@ int git_revwalk__push_glob(git_revwalk *walk, const char *glob, const git_revwal if (error == GIT_ITEROVER) error = 0; out: - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } diff --git a/src/signature.c b/src/signature.c index 1efda212a0a..acd5fd72bad 100644 --- a/src/signature.c +++ b/src/signature.c @@ -299,7 +299,7 @@ int git_signature_from_buffer(git_signature **out, const char *buf) return error; } -void git_signature__writebuf(git_buf *buf, const char *header, const git_signature *sig) +void git_signature__writebuf(git_str *buf, const char *header, const git_signature *sig) { int offset, hours, mins; char sign; @@ -313,7 +313,7 @@ void git_signature__writebuf(git_buf *buf, const char *header, const git_signatu hours = offset / 60; mins = offset % 60; - git_buf_printf(buf, "%s%s <%s> %u %c%02d%02d\n", + git_str_printf(buf, "%s%s <%s> %u %c%02d%02d\n", header ? header : "", sig->name, sig->email, (unsigned)sig->when.time, sign, hours, mins); } diff --git a/src/signature.h b/src/signature.h index 40d7c54f9c2..5c8270954e7 100644 --- a/src/signature.h +++ b/src/signature.h @@ -15,7 +15,7 @@ #include int git_signature__parse(git_signature *sig, const char **buffer_out, const char *buffer_end, const char *header, char ender); -void git_signature__writebuf(git_buf *buf, const char *header, const git_signature *sig); +void git_signature__writebuf(git_str *buf, const char *header, const git_signature *sig); bool git_signature__equal(const git_signature *one, const git_signature *two); int git_signature__pdup(git_signature **dest, const git_signature *source, git_pool *pool); diff --git a/src/sortedcache.c b/src/sortedcache.c index ee6363f6d73..7ff900efe33 100644 --- a/src/sortedcache.c +++ b/src/sortedcache.c @@ -201,7 +201,7 @@ void git_sortedcache_runlock(git_sortedcache *sc) /* if the file has changed, lock cache and load file contents into buf; * returns <0 on error, >0 if file has not changed */ -int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf) +int git_sortedcache_lockandload(git_sortedcache *sc, git_str *buf) { int error, fd; struct stat st; diff --git a/src/sortedcache.h b/src/sortedcache.h index 0e1f63ceb00..ef260a093a5 100644 --- a/src/sortedcache.h +++ b/src/sortedcache.h @@ -121,7 +121,7 @@ void git_sortedcache_wunlock(git_sortedcache *sc); * @return 0 if up-to-date, 1 if out-of-date, <0 on error */ GIT_WARN_UNUSED_RESULT int git_sortedcache_lockandload( - git_sortedcache *sc, git_buf *buf); + git_sortedcache *sc, git_str *buf); /* Refresh file timestamp after write completes * You should already be holding the write lock when you call this. diff --git a/src/stash.c b/src/stash.c index 49ea26fdd52..5fc01ac36dd 100644 --- a/src/stash.c +++ b/src/stash.c @@ -9,7 +9,6 @@ #include "repository.h" #include "commit.h" -#include "message.h" #include "tree.h" #include "reflog.h" #include "blob.h" @@ -43,20 +42,20 @@ static int retrieve_head(git_reference **out, git_repository *repo) return error; } -static int append_abbreviated_oid(git_buf *out, const git_oid *b_commit) +static int append_abbreviated_oid(git_str *out, const git_oid *b_commit) { char *formatted_oid; formatted_oid = git_oid_allocfmt(b_commit); GIT_ERROR_CHECK_ALLOC(formatted_oid); - git_buf_put(out, formatted_oid, 7); + git_str_put(out, formatted_oid, 7); git__free(formatted_oid); - return git_buf_oom(out) ? -1 : 0; + return git_str_oom(out) ? -1 : 0; } -static int append_commit_description(git_buf *out, git_commit *commit) +static int append_commit_description(git_str *out, git_commit *commit) { const char *summary = git_commit_summary(commit); GIT_ERROR_CHECK_ALLOC(summary); @@ -64,16 +63,16 @@ static int append_commit_description(git_buf *out, git_commit *commit) if (append_abbreviated_oid(out, git_commit_id(commit)) < 0) return -1; - git_buf_putc(out, ' '); - git_buf_puts(out, summary); - git_buf_putc(out, '\n'); + git_str_putc(out, ' '); + git_str_puts(out, summary); + git_str_putc(out, '\n'); - return git_buf_oom(out) ? -1 : 0; + return git_str_oom(out) ? -1 : 0; } static int retrieve_base_commit_and_message( git_commit **b_commit, - git_buf *stash_message, + git_str *stash_message, git_repository *repo) { git_reference *head = NULL; @@ -83,9 +82,9 @@ static int retrieve_base_commit_and_message( return error; if (strcmp("HEAD", git_reference_name(head)) == 0) - error = git_buf_puts(stash_message, "(no branch): "); + error = git_str_puts(stash_message, "(no branch): "); else - error = git_buf_printf( + error = git_str_printf( stash_message, "%s: ", git_reference_name(head) + strlen(GIT_REFS_HEADS_DIR)); @@ -128,13 +127,13 @@ static int commit_index( { git_tree *i_tree = NULL; git_oid i_commit_oid; - git_buf msg = GIT_BUF_INIT; + git_str msg = GIT_STR_INIT; int error; if ((error = build_tree_from_index(&i_tree, repo, index)) < 0) goto cleanup; - if ((error = git_buf_printf(&msg, "index on %s\n", message)) < 0) + if ((error = git_str_printf(&msg, "index on %s\n", message)) < 0) goto cleanup; if ((error = git_commit_create( @@ -144,7 +143,7 @@ static int commit_index( stasher, stasher, NULL, - git_buf_cstr(&msg), + git_str_cstr(&msg), i_tree, 1, &parent)) < 0) @@ -154,7 +153,7 @@ static int commit_index( cleanup: git_tree_free(i_tree); - git_buf_dispose(&msg); + git_str_dispose(&msg); return error; } @@ -303,13 +302,13 @@ static int commit_untracked( { git_tree *u_tree = NULL; git_oid u_commit_oid; - git_buf msg = GIT_BUF_INIT; + git_str msg = GIT_STR_INIT; int error; if ((error = build_untracked_tree(&u_tree, repo, i_commit, flags)) < 0) goto cleanup; - if ((error = git_buf_printf(&msg, "untracked files on %s\n", message)) < 0) + if ((error = git_str_printf(&msg, "untracked files on %s\n", message)) < 0) goto cleanup; if ((error = git_commit_create( @@ -319,7 +318,7 @@ static int commit_untracked( stasher, stasher, NULL, - git_buf_cstr(&msg), + git_str_cstr(&msg), u_tree, 0, NULL)) < 0) @@ -329,7 +328,7 @@ static int commit_untracked( cleanup: git_tree_free(u_tree); - git_buf_dispose(&msg); + git_str_dispose(&msg); return error; } @@ -437,33 +436,33 @@ static int commit_worktree( return error; } -static int prepare_worktree_commit_message(git_buf *out, const char *user_message) +static int prepare_worktree_commit_message(git_str *out, const char *user_message) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error = 0; if (!user_message) { - git_buf_printf(&buf, "WIP on %s", git_buf_cstr(out)); + git_str_printf(&buf, "WIP on %s", git_str_cstr(out)); } else { const char *colon; - if ((colon = strchr(git_buf_cstr(out), ':')) == NULL) + if ((colon = strchr(git_str_cstr(out), ':')) == NULL) goto cleanup; - git_buf_puts(&buf, "On "); - git_buf_put(&buf, git_buf_cstr(out), colon - out->ptr); - git_buf_printf(&buf, ": %s\n", user_message); + git_str_puts(&buf, "On "); + git_str_put(&buf, git_str_cstr(out), colon - out->ptr); + git_str_printf(&buf, ": %s\n", user_message); } - if (git_buf_oom(&buf)) { + if (git_str_oom(&buf)) { error = -1; goto cleanup; } - git_buf_swap(out, &buf); + git_str_swap(out, &buf); cleanup: - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -543,7 +542,7 @@ int git_stash_save( { git_index *index = NULL; git_commit *b_commit = NULL, *i_commit = NULL, *u_commit = NULL; - git_buf msg = GIT_BUF_INIT; + git_str msg = GIT_STR_INIT; int error; GIT_ASSERT_ARG(out); @@ -563,24 +562,24 @@ int git_stash_save( goto cleanup; if ((error = commit_index(&i_commit, repo, index, stasher, - git_buf_cstr(&msg), b_commit)) < 0) + git_str_cstr(&msg), b_commit)) < 0) goto cleanup; if ((flags & (GIT_STASH_INCLUDE_UNTRACKED | GIT_STASH_INCLUDE_IGNORED)) && (error = commit_untracked(&u_commit, repo, stasher, - git_buf_cstr(&msg), i_commit, flags)) < 0) + git_str_cstr(&msg), i_commit, flags)) < 0) goto cleanup; if ((error = prepare_worktree_commit_message(&msg, message)) < 0) goto cleanup; - if ((error = commit_worktree(out, repo, stasher, git_buf_cstr(&msg), + if ((error = commit_worktree(out, repo, stasher, git_str_cstr(&msg), i_commit, b_commit, u_commit)) < 0) goto cleanup; - git_buf_rtrim(&msg); + git_str_rtrim(&msg); - if ((error = update_reflog(out, repo, git_buf_cstr(&msg))) < 0) + if ((error = update_reflog(out, repo, git_str_cstr(&msg))) < 0) goto cleanup; if ((error = reset_index_and_workdir(repo, (flags & GIT_STASH_KEEP_INDEX) ? i_commit : b_commit, @@ -589,7 +588,7 @@ int git_stash_save( cleanup: - git_buf_dispose(&msg); + git_str_dispose(&msg); git_commit_free(i_commit); git_commit_free(b_commit); git_commit_free(u_commit); diff --git a/src/buffer.c b/src/str.c similarity index 82% rename from src/buffer.c rename to src/str.c index fe087ea1116..7b50800c147 100644 --- a/src/buffer.c +++ b/src/str.c @@ -4,42 +4,42 @@ * 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 "buffer.h" + +#include "str.h" #include "posix.h" -#include "git2/buffer.h" #include -/* Used as default value for git_buf->ptr so that people can always - * assume ptr is non-NULL and zero terminated even for new git_bufs. +/* Used as default value for git_str->ptr so that people can always + * assume ptr is non-NULL and zero terminated even for new git_strs. */ -char git_buf__initbuf[1]; +char git_str__initstr[1]; -char git_buf__oom[1]; +char git_str__oom[1]; #define ENSURE_SIZE(b, d) \ - if ((b)->ptr == git_buf__oom || \ - ((d) > (b)->asize && git_buf_grow((b), (d)) < 0))\ + if ((b)->ptr == git_str__oom || \ + ((d) > (b)->asize && git_str_grow((b), (d)) < 0))\ return -1; -int git_buf_init(git_buf *buf, size_t initial_size) +int git_str_init(git_str *buf, size_t initial_size) { buf->asize = 0; buf->size = 0; - buf->ptr = git_buf__initbuf; + buf->ptr = git_str__initstr; ENSURE_SIZE(buf, initial_size); return 0; } -int git_buf_try_grow( - git_buf *buf, size_t target_size, bool mark_oom) +int git_str_try_grow( + git_str *buf, size_t target_size, bool mark_oom) { char *new_ptr; size_t new_size; - if (buf->ptr == git_buf__oom) + if (buf->ptr == git_str__oom) return -1; if (buf->asize == 0 && buf->size != 0) { @@ -74,9 +74,9 @@ int git_buf_try_grow( if (new_size < buf->size) { if (mark_oom) { - if (buf->ptr && buf->ptr != git_buf__initbuf) + if (buf->ptr && buf->ptr != git_str__initstr) git__free(buf->ptr); - buf->ptr = git_buf__oom; + buf->ptr = git_str__oom; } git_error_set_oom(); @@ -87,9 +87,9 @@ int git_buf_try_grow( if (!new_ptr) { if (mark_oom) { - if (buf->ptr && (buf->ptr != git_buf__initbuf)) + if (buf->ptr && (buf->ptr != git_str__initstr)) git__free(buf->ptr); - buf->ptr = git_buf__oom; + buf->ptr = git_str__oom; } return -1; } @@ -105,59 +105,46 @@ int git_buf_try_grow( return 0; } -int git_buf_grow(git_buf *buffer, size_t target_size) +int git_str_grow(git_str *buffer, size_t target_size) { - return git_buf_try_grow(buffer, target_size, true); + return git_str_try_grow(buffer, target_size, true); } -int git_buf_grow_by(git_buf *buffer, size_t additional_size) +int git_str_grow_by(git_str *buffer, size_t additional_size) { size_t newsize; if (GIT_ADD_SIZET_OVERFLOW(&newsize, buffer->size, additional_size)) { - buffer->ptr = git_buf__oom; + buffer->ptr = git_str__oom; return -1; } - return git_buf_try_grow(buffer, newsize, true); + return git_str_try_grow(buffer, newsize, true); } -void git_buf_dispose(git_buf *buf) +void git_str_dispose(git_str *buf) { if (!buf) return; - if (buf->asize > 0 && buf->ptr != NULL && buf->ptr != git_buf__oom) + if (buf->asize > 0 && buf->ptr != NULL && buf->ptr != git_str__oom) git__free(buf->ptr); - git_buf_init(buf, 0); + git_str_init(buf, 0); } #ifndef GIT_DEPRECATE_HARD -void git_buf_free(git_buf *buf) +void git_str_free(git_str *buf) { - git_buf_dispose(buf); + git_str_dispose(buf); } #endif -int git_buf_sanitize(git_buf *buf) -{ - if (buf->ptr == NULL) { - GIT_ASSERT_ARG(buf->size == 0 && buf->asize == 0); - - buf->ptr = git_buf__initbuf; - } else if (buf->asize > buf->size) { - buf->ptr[buf->size] = '\0'; - } - - return 0; -} - -void git_buf_clear(git_buf *buf) +void git_str_clear(git_str *buf) { buf->size = 0; if (!buf->ptr) { - buf->ptr = git_buf__initbuf; + buf->ptr = git_str__initstr; buf->asize = 0; } @@ -165,12 +152,12 @@ void git_buf_clear(git_buf *buf) buf->ptr[0] = '\0'; } -int git_buf_set(git_buf *buf, const void *data, size_t len) +int git_str_set(git_str *buf, const void *data, size_t len) { size_t alloclen; if (len == 0 || data == NULL) { - git_buf_clear(buf); + git_str_clear(buf); } else { if (data != buf->ptr) { GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, len, 1); @@ -186,12 +173,12 @@ int git_buf_set(git_buf *buf, const void *data, size_t len) return 0; } -int git_buf_sets(git_buf *buf, const char *string) +int git_str_sets(git_str *buf, const char *string) { - return git_buf_set(buf, string, string ? strlen(string) : 0); + return git_str_set(buf, string, string ? strlen(string) : 0); } -int git_buf_putc(git_buf *buf, char c) +int git_str_putc(git_str *buf, char c) { size_t new_size; GIT_ERROR_CHECK_ALLOC_ADD(&new_size, buf->size, 2); @@ -201,7 +188,7 @@ int git_buf_putc(git_buf *buf, char c) return 0; } -int git_buf_putcn(git_buf *buf, char c, size_t len) +int git_str_putcn(git_str *buf, char c, size_t len) { size_t new_size; GIT_ERROR_CHECK_ALLOC_ADD(&new_size, buf->size, len); @@ -213,7 +200,7 @@ int git_buf_putcn(git_buf *buf, char c, size_t len) return 0; } -int git_buf_put(git_buf *buf, const char *data, size_t len) +int git_str_put(git_str *buf, const char *data, size_t len) { if (len) { size_t new_size; @@ -230,17 +217,17 @@ int git_buf_put(git_buf *buf, const char *data, size_t len) return 0; } -int git_buf_puts(git_buf *buf, const char *string) +int git_str_puts(git_str *buf, const char *string) { GIT_ASSERT_ARG(string); - return git_buf_put(buf, string, strlen(string)); + return git_str_put(buf, string, strlen(string)); } static const char base64_encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -int git_buf_encode_base64(git_buf *buf, const char *data, size_t len) +int git_str_encode_base64(git_str *buf, const char *data, size_t len) { size_t extra = len % 3; uint8_t *write, a, b, c; @@ -302,7 +289,7 @@ static const int8_t base64_decode[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; -int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len) +int git_str_decode_base64(git_str *buf, const char *base64, size_t len) { size_t i; int8_t a, b, c, d; @@ -342,7 +329,7 @@ int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len) static const char base85_encode[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~"; -int git_buf_encode_base85(git_buf *buf, const char *data, size_t len) +int git_str_encode_base85(git_str *buf, const char *data, size_t len) { size_t blocks = (len / 4) + !!(len % 4), alloclen; @@ -401,8 +388,8 @@ static const int8_t base85_decode[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; -int git_buf_decode_base85( - git_buf *buf, +int git_str_decode_base85( + git_str *buf, const char *base85, size_t base85_len, size_t output_len) @@ -465,8 +452,8 @@ int git_buf_decode_base85( #define HEX_DECODE(c) ((c | 32) % 39 - 9) -int git_buf_decode_percent( - git_buf *buf, +int git_str_decode_percent( + git_str *buf, const char *str, size_t str_len) { @@ -493,7 +480,7 @@ int git_buf_decode_percent( return 0; } -int git_buf_vprintf(git_buf *buf, const char *format, va_list ap) +int git_str_vprintf(git_str *buf, const char *format, va_list ap) { size_t expected_size, new_size; int len; @@ -516,7 +503,7 @@ int git_buf_vprintf(git_buf *buf, const char *format, va_list ap) if (len < 0) { git__free(buf->ptr); - buf->ptr = git_buf__oom; + buf->ptr = git_str__oom; return -1; } @@ -533,19 +520,19 @@ int git_buf_vprintf(git_buf *buf, const char *format, va_list ap) return 0; } -int git_buf_printf(git_buf *buf, const char *format, ...) +int git_str_printf(git_str *buf, const char *format, ...) { int r; va_list ap; va_start(ap, format); - r = git_buf_vprintf(buf, format, ap); + r = git_str_vprintf(buf, format, ap); va_end(ap); return r; } -int git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf) +int git_str_copy_cstr(char *data, size_t datasize, const git_str *buf) { size_t copylen; @@ -567,12 +554,12 @@ int git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf) return 0; } -void git_buf_consume_bytes(git_buf *buf, size_t len) +void git_str_consume_bytes(git_str *buf, size_t len) { - git_buf_consume(buf, buf->ptr + len); + git_str_consume(buf, buf->ptr + len); } -void git_buf_consume(git_buf *buf, const char *end) +void git_str_consume(git_str *buf, const char *end) { if (end > buf->ptr && end <= buf->ptr + buf->size) { size_t consumed = end - buf->ptr; @@ -582,7 +569,7 @@ void git_buf_consume(git_buf *buf, const char *end) } } -void git_buf_truncate(git_buf *buf, size_t len) +void git_str_truncate(git_str *buf, size_t len) { if (len >= buf->size) return; @@ -592,49 +579,49 @@ void git_buf_truncate(git_buf *buf, size_t len) buf->ptr[buf->size] = '\0'; } -void git_buf_shorten(git_buf *buf, size_t amount) +void git_str_shorten(git_str *buf, size_t amount) { if (buf->size > amount) - git_buf_truncate(buf, buf->size - amount); + git_str_truncate(buf, buf->size - amount); else - git_buf_clear(buf); + git_str_clear(buf); } -void git_buf_truncate_at_char(git_buf *buf, char separator) +void git_str_truncate_at_char(git_str *buf, char separator) { - ssize_t idx = git_buf_find(buf, separator); + ssize_t idx = git_str_find(buf, separator); if (idx >= 0) - git_buf_truncate(buf, (size_t)idx); + git_str_truncate(buf, (size_t)idx); } -void git_buf_rtruncate_at_char(git_buf *buf, char separator) +void git_str_rtruncate_at_char(git_str *buf, char separator) { - ssize_t idx = git_buf_rfind_next(buf, separator); - git_buf_truncate(buf, idx < 0 ? 0 : (size_t)idx); + ssize_t idx = git_str_rfind_next(buf, separator); + git_str_truncate(buf, idx < 0 ? 0 : (size_t)idx); } -void git_buf_swap(git_buf *buf_a, git_buf *buf_b) +void git_str_swap(git_str *str_a, git_str *str_b) { - git_buf t = *buf_a; - *buf_a = *buf_b; - *buf_b = t; + git_str t = *str_a; + *str_a = *str_b; + *str_b = t; } -char *git_buf_detach(git_buf *buf) +char *git_str_detach(git_str *buf) { char *data = buf->ptr; - if (buf->asize == 0 || buf->ptr == git_buf__oom) + if (buf->asize == 0 || buf->ptr == git_str__oom) return NULL; - git_buf_init(buf, 0); + git_str_init(buf, 0); return data; } -int git_buf_attach(git_buf *buf, char *ptr, size_t asize) +int git_str_attach(git_str *buf, char *ptr, size_t asize) { - git_buf_dispose(buf); + git_str_dispose(buf); if (ptr) { buf->ptr = ptr; @@ -649,13 +636,13 @@ int git_buf_attach(git_buf *buf, char *ptr, size_t asize) return 0; } -void git_buf_attach_notowned(git_buf *buf, const char *ptr, size_t size) +void git_str_attach_notowned(git_str *buf, const char *ptr, size_t size) { - if (git_buf_is_allocated(buf)) - git_buf_dispose(buf); + if (git_str_is_allocated(buf)) + git_str_dispose(buf); if (!size) { - git_buf_init(buf, 0); + git_str_init(buf, 0); } else { buf->ptr = (char *)ptr; buf->asize = 0; @@ -663,7 +650,7 @@ void git_buf_attach_notowned(git_buf *buf, const char *ptr, size_t size) } } -int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...) +int git_str_join_n(git_str *buf, char separator, int nbuf, ...) { va_list ap; int i; @@ -698,7 +685,7 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...) return 0; GIT_ERROR_CHECK_ALLOC_ADD(&total_size, total_size, 1); - if (git_buf_grow_by(buf, total_size) < 0) + if (git_str_grow_by(buf, total_size) < 0) return -1; out = buf->ptr + buf->size; @@ -751,8 +738,8 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...) return 0; } -int git_buf_join( - git_buf *buf, +int git_str_join( + git_str *buf, char separator, const char *str_a, const char *str_b) @@ -800,8 +787,8 @@ int git_buf_join( return 0; } -int git_buf_join3( - git_buf *buf, +int git_str_join3( + git_str *buf, char separator, const char *str_a, const char *str_b, @@ -860,7 +847,7 @@ int git_buf_join3( return 0; } -void git_buf_rtrim(git_buf *buf) +void git_str_rtrim(git_str *buf) { while (buf->size > 0) { if (!git__isspace(buf->ptr[buf->size - 1])) @@ -873,15 +860,15 @@ void git_buf_rtrim(git_buf *buf) buf->ptr[buf->size] = '\0'; } -int git_buf_cmp(const git_buf *a, const git_buf *b) +int git_str_cmp(const git_str *a, const git_str *b) { int result = memcmp(a->ptr, b->ptr, min(a->size, b->size)); return (result != 0) ? result : (a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0; } -int git_buf_splice( - git_buf *buf, +int git_str_splice( + git_str *buf, size_t where, size_t nb_to_remove, const char *data, @@ -915,10 +902,10 @@ int git_buf_splice( } /* Quote per http://marc.info/?l=git&m=112927316408690&w=2 */ -int git_buf_quote(git_buf *buf) +int git_str_quote(git_str *buf) { const char whitespace[] = { 'a', 'b', 't', 'n', 'v', 'f', 'r' }; - git_buf quoted = GIT_BUF_INIT; + git_str quoted = GIT_STR_INIT; size_t i = 0; bool quote = false; int error = 0; @@ -938,55 +925,55 @@ int git_buf_quote(git_buf *buf) if (!quote) goto done; - git_buf_putc("ed, '"'); - git_buf_put("ed, buf->ptr, i); + git_str_putc("ed, '"'); + git_str_put("ed, buf->ptr, i); for (; i < buf->size; i++) { /* whitespace - use the map above, which is ordered by ascii value */ if (buf->ptr[i] >= '\a' && buf->ptr[i] <= '\r') { - git_buf_putc("ed, '\\'); - git_buf_putc("ed, whitespace[buf->ptr[i] - '\a']); + git_str_putc("ed, '\\'); + git_str_putc("ed, whitespace[buf->ptr[i] - '\a']); } /* double quote and backslash must be escaped */ else if (buf->ptr[i] == '"' || buf->ptr[i] == '\\') { - git_buf_putc("ed, '\\'); - git_buf_putc("ed, buf->ptr[i]); + git_str_putc("ed, '\\'); + git_str_putc("ed, buf->ptr[i]); } /* escape anything unprintable as octal */ else if (buf->ptr[i] != ' ' && (buf->ptr[i] < '!' || buf->ptr[i] > '~')) { - git_buf_printf("ed, "\\%03o", (unsigned char)buf->ptr[i]); + git_str_printf("ed, "\\%03o", (unsigned char)buf->ptr[i]); } /* yay, printable! */ else { - git_buf_putc("ed, buf->ptr[i]); + git_str_putc("ed, buf->ptr[i]); } } - git_buf_putc("ed, '"'); + git_str_putc("ed, '"'); - if (git_buf_oom("ed)) { + if (git_str_oom("ed)) { error = -1; goto done; } - git_buf_swap("ed, buf); + git_str_swap("ed, buf); done: - git_buf_dispose("ed); + git_str_dispose("ed); return error; } /* Unquote per http://marc.info/?l=git&m=112927316408690&w=2 */ -int git_buf_unquote(git_buf *buf) +int git_str_unquote(git_str *buf) { size_t i, j; char ch; - git_buf_rtrim(buf); + git_str_rtrim(buf); if (buf->size < 2 || buf->ptr[0] != '"' || buf->ptr[buf->size-1] != '"') goto invalid; @@ -1055,8 +1042,8 @@ int git_buf_unquote(git_buf *buf) return -1; } -int git_buf_puts_escaped( - git_buf *buf, +int git_str_puts_escaped( + git_str *buf, const char *string, const char *esc_chars, const char *esc_with) @@ -1079,7 +1066,7 @@ int git_buf_puts_escaped( } GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, total, 1); - if (git_buf_grow_by(buf, alloclen) < 0) + if (git_str_grow_by(buf, alloclen) < 0) return -1; for (scan = string; *scan; ) { @@ -1105,12 +1092,12 @@ int git_buf_puts_escaped( return 0; } -void git_buf_unescape(git_buf *buf) +void git_str_unescape(git_str *buf) { buf->size = git__unescape(buf->ptr); } -int git_buf_crlf_to_lf(git_buf *tgt, const git_buf *src) +int git_str_crlf_to_lf(git_str *tgt, const git_str *src) { const char *scan = src->ptr; const char *scan_end = src->ptr + src->size; @@ -1121,11 +1108,11 @@ int git_buf_crlf_to_lf(git_buf *tgt, const git_buf *src) GIT_ASSERT(tgt != src); if (!next) - return git_buf_set(tgt, src->ptr, src->size); + return git_str_set(tgt, src->ptr, src->size); /* reduce reallocs while in the loop */ GIT_ERROR_CHECK_ALLOC_ADD(&new_size, src->size, 1); - if (git_buf_grow(tgt, new_size) < 0) + if (git_str_grow(tgt, new_size) < 0) return -1; out = tgt->ptr; @@ -1157,7 +1144,7 @@ int git_buf_crlf_to_lf(git_buf *tgt, const git_buf *src) return 0; } -int git_buf_lf_to_crlf(git_buf *tgt, const git_buf *src) +int git_str_lf_to_crlf(git_str *tgt, const git_str *src) { const char *start = src->ptr; const char *end = start + src->size; @@ -1168,12 +1155,12 @@ int git_buf_lf_to_crlf(git_buf *tgt, const git_buf *src) GIT_ASSERT(tgt != src); if (!next) - return git_buf_set(tgt, src->ptr, src->size); + return git_str_set(tgt, src->ptr, src->size); /* attempt to reduce reallocs while in the loop */ GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, src->size, src->size >> 4); GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1); - if (git_buf_grow(tgt, alloclen) < 0) + if (git_str_grow(tgt, alloclen) < 0) return -1; tgt->size = 0; @@ -1185,7 +1172,7 @@ int git_buf_lf_to_crlf(git_buf *tgt, const git_buf *src) copylen--; GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, copylen, 3); - if (git_buf_grow_by(tgt, alloclen) < 0) + if (git_str_grow_by(tgt, alloclen) < 0) return -1; if (copylen) { @@ -1198,21 +1185,21 @@ int git_buf_lf_to_crlf(git_buf *tgt, const git_buf *src) } tgt->ptr[tgt->size] = '\0'; - return git_buf_put(tgt, scan, end - scan); + return git_str_put(tgt, scan, end - scan); } -int git_buf_common_prefix(git_buf *buf, char *const *const strings, size_t count) +int git_str_common_prefix(git_str *buf, char *const *const strings, size_t count) { size_t i; const char *str, *pfx; - git_buf_clear(buf); + git_str_clear(buf); if (!strings || !count) return 0; /* initialize common prefix to first string */ - if (git_buf_sets(buf, strings[0]) < 0) + if (git_str_sets(buf, strings[0]) < 0) return -1; /* go through the rest of the strings, truncating to shared prefix */ @@ -1223,7 +1210,7 @@ int git_buf_common_prefix(git_buf *buf, char *const *const strings, size_t count str++, pfx++) /* scanning */; - git_buf_truncate(buf, pfx - buf->ptr); + git_str_truncate(buf, pfx - buf->ptr); if (!buf->size) break; @@ -1232,15 +1219,15 @@ int git_buf_common_prefix(git_buf *buf, char *const *const strings, size_t count return 0; } -int git_buf_is_binary(const git_buf *buf) +int git_str_is_binary(const git_str *buf) { const char *scan = buf->ptr, *end = buf->ptr + buf->size; - git_buf_bom_t bom; + git_str_bom_t bom; int printable = 0, nonprintable = 0; - scan += git_buf_detect_bom(&bom, buf); + scan += git_str_detect_bom(&bom, buf); - if (bom > GIT_BUF_BOM_UTF8) + if (bom > GIT_STR_BOM_UTF8) return 1; while (scan < end) { @@ -1260,17 +1247,17 @@ int git_buf_is_binary(const git_buf *buf) return ((printable >> 7) < nonprintable); } -int git_buf_contains_nul(const git_buf *buf) +int git_str_contains_nul(const git_str *buf) { return (memchr(buf->ptr, '\0', buf->size) != NULL); } -int git_buf_detect_bom(git_buf_bom_t *bom, const git_buf *buf) +int git_str_detect_bom(git_str_bom_t *bom, const git_str *buf) { const char *ptr; size_t len; - *bom = GIT_BUF_BOM_NONE; + *bom = GIT_STR_BOM_NONE; /* need at least 2 bytes to look for any BOM */ if (buf->size < 2) return 0; @@ -1281,19 +1268,19 @@ int git_buf_detect_bom(git_buf_bom_t *bom, const git_buf *buf) switch (*ptr++) { case 0: if (len >= 4 && ptr[0] == 0 && ptr[1] == '\xFE' && ptr[2] == '\xFF') { - *bom = GIT_BUF_BOM_UTF32_BE; + *bom = GIT_STR_BOM_UTF32_BE; return 4; } break; case '\xEF': if (len >= 3 && ptr[0] == '\xBB' && ptr[1] == '\xBF') { - *bom = GIT_BUF_BOM_UTF8; + *bom = GIT_STR_BOM_UTF8; return 3; } break; case '\xFE': if (*ptr == '\xFF') { - *bom = GIT_BUF_BOM_UTF16_BE; + *bom = GIT_STR_BOM_UTF16_BE; return 2; } break; @@ -1301,10 +1288,10 @@ int git_buf_detect_bom(git_buf_bom_t *bom, const git_buf *buf) if (*ptr != '\xFE') break; if (len >= 4 && ptr[1] == 0 && ptr[2] == 0) { - *bom = GIT_BUF_BOM_UTF32_LE; + *bom = GIT_STR_BOM_UTF32_LE; return 4; } else { - *bom = GIT_BUF_BOM_UTF16_LE; + *bom = GIT_STR_BOM_UTF16_LE; return 2; } break; @@ -1315,8 +1302,8 @@ int git_buf_detect_bom(git_buf_bom_t *bom, const git_buf *buf) return 0; } -bool git_buf_gather_text_stats( - git_buf_text_stats *stats, const git_buf *buf, bool skip_bom) +bool git_str_gather_text_stats( + git_str_text_stats *stats, const git_str *buf, bool skip_bom) { const char *scan = buf->ptr, *end = buf->ptr + buf->size; int skip; @@ -1324,7 +1311,7 @@ bool git_buf_gather_text_stats( memset(stats, 0, sizeof(*stats)); /* BOM detection */ - skip = git_buf_detect_bom(&stats->bom, buf); + skip = git_str_detect_bom(&stats->bom, buf); if (skip_bom) scan += skip; diff --git a/src/str.h b/src/str.h new file mode 100644 index 00000000000..af7acc21f87 --- /dev/null +++ b/src/str.h @@ -0,0 +1,354 @@ +/* + * 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_str_h__ +#define INCLUDE_str_h__ + +#include "common.h" + +struct git_str { + char *ptr; + size_t asize; + size_t size; +}; + +typedef enum { + GIT_STR_BOM_NONE = 0, + GIT_STR_BOM_UTF8 = 1, + GIT_STR_BOM_UTF16_LE = 2, + GIT_STR_BOM_UTF16_BE = 3, + GIT_STR_BOM_UTF32_LE = 4, + GIT_STR_BOM_UTF32_BE = 5 +} git_str_bom_t; + +typedef struct { + git_str_bom_t bom; /* BOM found at head of text */ + unsigned int nul, cr, lf, crlf; /* NUL, CR, LF and CRLF counts */ + unsigned int printable, nonprintable; /* These are just approximations! */ +} git_str_text_stats; + +extern char git_str__initstr[]; +extern char git_str__oom[]; + +/* Use to initialize string buffer structure when git_str is on stack */ +#define GIT_STR_INIT { git_str__initstr, 0, 0 } + +/** + * Static initializer for git_str from static string buffer + */ +#define GIT_STR_INIT_CONST(str, len) { (char *)(str), 0, (size_t)(len) } + +GIT_INLINE(bool) git_str_is_allocated(const git_str *str) +{ + return (str->ptr != NULL && str->asize > 0); +} + +/** + * Initialize a git_str structure. + * + * For the cases where GIT_STR_INIT cannot be used to do static + * initialization. + */ +extern int git_str_init(git_str *str, size_t initial_size); + +extern void git_str_dispose(git_str *str); + +/** + * Resize the string buffer allocation to make more space. + * + * This will attempt to grow the string buffer to accommodate the target + * size. The bstring buffer's `ptr` will be replaced with a newly + * allocated block of data. Be careful so that memory allocated by the + * caller is not lost. As a special variant, if you pass `target_size` as + * 0 and the memory is not allocated by libgit2, this will allocate a new + * buffer of size `size` and copy the external data into it. + * + * Currently, this will never shrink a buffer, only expand it. + * + * If the allocation fails, this will return an error and the buffer will be + * marked as invalid for future operations, invaliding the contents. + * + * @param str The buffer to be resized; may or may not be allocated yet + * @param target_size The desired available size + * @return 0 on success, -1 on allocation failure + */ +int git_str_grow(git_str *str, size_t target_size); + +/** + * Resize the buffer allocation to make more space. + * + * This will attempt to grow the string buffer to accommodate the + * additional size. It is similar to `git_str_grow`, but performs the + * new size calculation, checking for overflow. + * + * Like `git_str_grow`, if this is a user-supplied string buffer, + * this will allocate a new string uffer. + */ +extern int git_str_grow_by(git_str *str, size_t additional_size); + +/** + * Attempt to grow the buffer to hold at least `target_size` bytes. + * + * If the allocation fails, this will return an error. If `mark_oom` is + * true, this will mark the string buffer as invalid for future + * operations; if false, existing string buffer content will be preserved, + * but calling code must handle that string buffer was not expanded. If + * `preserve_external` is true, then any existing data pointed to be + * `ptr` even if `asize` is zero will be copied into the newly allocated + * string buffer. + */ +extern int git_str_try_grow( + git_str *str, size_t target_size, bool mark_oom); + +extern void git_str_swap(git_str *str_a, git_str *str_b); +extern char *git_str_detach(git_str *str); +extern int git_str_attach(git_str *str, char *ptr, size_t asize); + +/* Populates a `git_str` where the contents are not "owned" by the string + * buffer, and calls to `git_str_dispose` will not free the given str. + */ +extern void git_str_attach_notowned( + git_str *str, const char *ptr, size_t size); + +/** + * Test if there have been any reallocation failures with this git_str. + * + * Any function that writes to a git_str can fail due to memory allocation + * issues. If one fails, the git_str will be marked with an OOM error and + * further calls to modify the string buffer will fail. Check + * git_str_oom() at the end of your sequence and it will be true if you + * ran out of memory at any point with that string buffer. + * + * @return false if no error, true if allocation error + */ +GIT_INLINE(bool) git_str_oom(const git_str *str) +{ + return (str->ptr == git_str__oom); +} + +/* + * Functions below that return int value error codes will return 0 on + * success or -1 on failure (which generally means an allocation failed). + * Using a git_str where the allocation has failed with result in -1 from + * all further calls using that string buffer. As a result, you can + * ignore the return code of these functions and call them in a series + * then just call git_str_oom at the end. + */ + +int git_str_set(git_str *str, const void *data, size_t datalen); + +int git_str_sets(git_str *str, const char *string); +int git_str_putc(git_str *str, char c); +int git_str_putcn(git_str *str, char c, size_t len); +int git_str_put(git_str *str, const char *data, size_t len); +int git_str_puts(git_str *str, const char *string); +int git_str_printf(git_str *str, const char *format, ...) GIT_FORMAT_PRINTF(2, 3); +int git_str_vprintf(git_str *str, const char *format, va_list ap); +void git_str_clear(git_str *str); +void git_str_consume_bytes(git_str *str, size_t len); +void git_str_consume(git_str *str, const char *end); +void git_str_truncate(git_str *str, size_t len); +void git_str_shorten(git_str *str, size_t amount); +void git_str_truncate_at_char(git_str *path, char separator); +void git_str_rtruncate_at_char(git_str *path, char separator); + +/** General join with separator */ +int git_str_join_n(git_str *str, char separator, int len, ...); +/** Fast join of two strings - first may legally point into `str` data */ +int git_str_join(git_str *str, char separator, const char *str_a, const char *str_b); +/** Fast join of three strings - cannot reference `str` data */ +int git_str_join3(git_str *str, char separator, const char *str_a, const char *str_b, const char *str_c); + +/** + * Join two strings as paths, inserting a slash between as needed. + * @return 0 on success, -1 on failure + */ +GIT_INLINE(int) git_str_joinpath(git_str *str, const char *a, const char *b) +{ + return git_str_join(str, '/', a, b); +} + +GIT_INLINE(const char *) git_str_cstr(const git_str *str) +{ + return str->ptr; +} + +GIT_INLINE(size_t) git_str_len(const git_str *str) +{ + return str->size; +} + +int git_str_copy_cstr(char *data, size_t datasize, const git_str *str); + +#define git_str_PUTS(str, cstr) git_str_put(str, cstr, sizeof(cstr) - 1) + +GIT_INLINE(ssize_t) git_str_rfind_next(const git_str *str, char ch) +{ + ssize_t idx = (ssize_t)str->size - 1; + while (idx >= 0 && str->ptr[idx] == ch) idx--; + while (idx >= 0 && str->ptr[idx] != ch) idx--; + return idx; +} + +GIT_INLINE(ssize_t) git_str_rfind(const git_str *str, char ch) +{ + ssize_t idx = (ssize_t)str->size - 1; + while (idx >= 0 && str->ptr[idx] != ch) idx--; + return idx; +} + +GIT_INLINE(ssize_t) git_str_find(const git_str *str, char ch) +{ + void *found = memchr(str->ptr, ch, str->size); + return found ? (ssize_t)((const char *)found - str->ptr) : -1; +} + +/* Remove whitespace from the end of the string buffer */ +void git_str_rtrim(git_str *str); + +int git_str_cmp(const git_str *a, const git_str *b); + +/* Quote and unquote a string buffer as specified in + * http://marc.info/?l=git&m=112927316408690&w=2 + */ +int git_str_quote(git_str *str); +int git_str_unquote(git_str *str); + +/* Write data as base64 encoded in string buffer */ +int git_str_encode_base64(git_str *str, const char *data, size_t len); +/* Decode the given bas64 and write the result to the string buffer */ +int git_str_decode_base64(git_str *str, const char *base64, size_t len); + +/* Write data as "base85" encoded in string buffer */ +int git_str_encode_base85(git_str *str, const char *data, size_t len); +/* Decode the given "base85" and write the result to the string buffer */ +int git_str_decode_base85(git_str *str, const char *base64, size_t len, size_t output_len); + +/* + * Decode the given percent-encoded string and write the result to the + * string buffer. + */ +int git_str_decode_percent(git_str *str, const char *encoded, size_t len); + +/* + * Insert, remove or replace a portion of the string buffer. + * + * @param str The string buffer to work with + * + * @param where The location in the string buffer where the transformation + * should be applied. + * + * @param nb_to_remove The number of chars to be removed. 0 to not + * remove any character in the string buffer. + * + * @param data A pointer to the data which should be inserted. + * + * @param nb_to_insert The number of chars to be inserted. 0 to not + * insert any character from the string buffer. + * + * @return 0 or an error code. + */ +int git_str_splice( + git_str *str, + size_t where, + size_t nb_to_remove, + const char *data, + size_t nb_to_insert); + +/** + * Append string to string buffer, prefixing each character from + * `esc_chars` with `esc_with` string. + * + * @param str String buffer to append data to + * @param string String to escape and append + * @param esc_chars Characters to be escaped + * @param esc_with String to insert in from of each found character + * @return 0 on success, <0 on failure (probably allocation problem) + */ +extern int git_str_puts_escaped( + git_str *str, + const char *string, + const char *esc_chars, + const char *esc_with); + +/** + * Append string escaping characters that are regex special + */ +GIT_INLINE(int) git_str_puts_escape_regex(git_str *str, const char *string) +{ + return git_str_puts_escaped(str, string, "^.[]$()|*+?{}\\", "\\"); +} + +/** + * Unescape all characters in a string buffer in place + * + * I.e. remove backslashes + */ +extern void git_str_unescape(git_str *str); + +/** + * Replace all \r\n with \n. + * + * @return 0 on success, -1 on memory error + */ +extern int git_str_crlf_to_lf(git_str *tgt, const git_str *src); + +/** + * Replace all \n with \r\n. Does not modify existing \r\n. + * + * @return 0 on success, -1 on memory error + */ +extern int git_str_lf_to_crlf(git_str *tgt, const git_str *src); + +/** + * Fill string buffer with the common prefix of a array of strings + * + * String buffer will be set to empty if there is no common prefix + */ +extern int git_str_common_prefix(git_str *buf, char *const *const strings, size_t count); + +/** + * Check if a string buffer begins with a UTF BOM + * + * @param bom Set to the type of BOM detected or GIT_BOM_NONE + * @param str String buffer in which to check the first bytes for a BOM + * @return Number of bytes of BOM data (or 0 if no BOM found) + */ +extern int git_str_detect_bom(git_str_bom_t *bom, const git_str *str); + +/** + * Gather stats for a piece of text + * + * Fill the `stats` structure with counts of unreadable characters, carriage + * returns, etc, so it can be used in heuristics. This automatically skips + * a trailing EOF (\032 character). Also it will look for a BOM at the + * start of the text and can be told to skip that as well. + * + * @param stats Structure to be filled in + * @param str Text to process + * @param skip_bom Exclude leading BOM from stats if true + * @return Does the string buffer heuristically look like binary data + */ +extern bool git_str_gather_text_stats( + git_str_text_stats *stats, const git_str *str, bool skip_bom); + +/** +* Check quickly if string buffer looks like it contains binary data +* +* @param str string buffer to check +* @return 1 if string buffer looks like non-text data +*/ +int git_str_is_binary(const git_str *str); + +/** +* Check quickly if buffer contains a NUL byte +* +* @param str string buffer to check +* @return 1 if string buffer contains a NUL byte +*/ +int git_str_contains_nul(const git_str *str); + +#endif diff --git a/src/submodule.c b/src/submodule.c index 7cbb9fa3a1a..b0f7294be8b 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -7,11 +7,8 @@ #include "submodule.h" -#include "git2/config.h" -#include "git2/sys/config.h" -#include "git2/types.h" -#include "git2/index.h" -#include "buffer.h" +#include "buf.h" +#include "branch.h" #include "vector.h" #include "posix.h" #include "config_backend.h" @@ -20,10 +17,16 @@ #include "tree.h" #include "iterator.h" #include "path.h" +#include "str.h" #include "index.h" #include "worktree.h" #include "clone.h" +#include "git2/config.h" +#include "git2/sys/config.h" +#include "git2/types.h" +#include "git2/index.h" + #define GIT_MODULES_FILE ".gitmodules" static git_configmap _sm_update_map[] = { @@ -63,8 +66,8 @@ enum { static int submodule_alloc(git_submodule **out, git_repository *repo, const char *name); static git_config_backend *open_gitmodules(git_repository *repo, int gitmod); static int gitmodules_snapshot(git_config **snap, git_repository *repo); -static int get_url_base(git_buf *url, git_repository *repo); -static int lookup_head_remote_key(git_buf *remote_key, git_repository *repo); +static int get_url_base(git_str *url, git_repository *repo); +static int lookup_head_remote_key(git_str *remote_key, git_repository *repo); static int lookup_default_remote(git_remote **remote, git_repository *repo); static int submodule_load_each(const git_config_entry *entry, void *payload); static int submodule_read_config(git_submodule *sm, git_config *cfg); @@ -79,11 +82,11 @@ static int submodule_cmp(const void *a, const void *b) return strcmp(((git_submodule *)a)->name, ((git_submodule *)b)->name); } -static int submodule_config_key_trunc_puts(git_buf *key, const char *suffix) +static int submodule_config_key_trunc_puts(git_str *key, const char *suffix) { - ssize_t idx = git_buf_rfind(key, '.'); - git_buf_truncate(key, (size_t)(idx + 1)); - return git_buf_puts(key, suffix); + ssize_t idx = git_str_rfind(key, '.'); + git_str_truncate(key, (size_t)(idx + 1)); + return git_str_puts(key, suffix); } /* @@ -128,7 +131,7 @@ static int is_path_occupied(bool *occupied, git_repository *repo, const char *pa { int error = 0; git_index *index; - git_buf dir = GIT_BUF_INIT; + git_str dir = GIT_STR_INIT; *occupied = false; if ((error = git_repository_index__weakptr(&index, repo)) < 0) @@ -143,7 +146,7 @@ static int is_path_occupied(bool *occupied, git_repository *repo, const char *pa goto out; } - if ((error = git_buf_sets(&dir, path)) < 0) + if ((error = git_str_sets(&dir, path)) < 0) goto out; if ((error = git_path_to_dir(&dir)) < 0) @@ -161,7 +164,7 @@ static int is_path_occupied(bool *occupied, git_repository *repo, const char *pa error = 0; out: - git_buf_dispose(&dir); + git_str_dispose(&dir); return error; } @@ -195,7 +198,7 @@ static int load_submodule_names(git_strmap **out, git_repository *repo, git_conf const char *key = "submodule\\..*\\.path"; git_config_iterator *iter = NULL; git_config_entry *entry; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_strmap *names; int isvalid, error; @@ -219,8 +222,8 @@ static int load_submodule_names(git_strmap **out, git_repository *repo, git_conf goto out; } - git_buf_clear(&buf); - git_buf_put(&buf, fdot + 1, ldot - fdot - 1); + git_str_clear(&buf); + git_str_put(&buf, fdot + 1, ldot - fdot - 1); isvalid = git_submodule_name_is_valid(repo, buf.ptr, 0); if (isvalid < 0) { error = isvalid; @@ -229,7 +232,7 @@ static int load_submodule_names(git_strmap **out, git_repository *repo, git_conf if (!isvalid) continue; - if ((error = git_strmap_set(names, git__strdup(entry->value), git_buf_detach(&buf))) < 0) { + if ((error = git_strmap_set(names, git__strdup(entry->value), git_str_detach(&buf))) < 0) { git_error_set(GIT_ERROR_NOMEMORY, "error inserting submodule into hash table"); error = -1; goto out; @@ -243,7 +246,7 @@ static int load_submodule_names(git_strmap **out, git_repository *repo, git_conf out: free_submodule_names(names); - git_buf_dispose(&buf); + git_str_dispose(&buf); git_config_iterator_free(iter); return error; } @@ -329,10 +332,10 @@ int git_submodule__lookup_with_cache( if (location == 0 || location == GIT_SUBMODULE_STATUS_IN_WD) { git_config_backend *mods; const char *pattern = "submodule\\..*\\.path"; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; fbp_data data = { NULL, NULL }; - git_buf_puts(&path, name); + git_str_puts(&path, name); while (path.ptr[path.size-1] == '/') { path.ptr[--path.size] = '\0'; } @@ -347,14 +350,14 @@ int git_submodule__lookup_with_cache( if (error < 0) { git_submodule_free(sm); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } if (data.name) { git__free(sm->name); sm->name = data.name; - sm->path = git_buf_detach(&path); + sm->path = git_str_detach(&path); /* Try to load again with the right name */ if ((error = git_submodule_reload(sm, false)) < 0) { @@ -363,7 +366,7 @@ int git_submodule__lookup_with_cache( } } - git_buf_dispose(&path); + git_str_dispose(&path); } if ((error = git_submodule_location(&location, sm)) < 0) { @@ -378,8 +381,8 @@ int git_submodule__lookup_with_cache( /* If it's not configured, we still check if there's a repo at the path */ if (git_repository_workdir(repo)) { - git_buf path = GIT_BUF_INIT; - if (git_buf_join3(&path, '/', + git_str path = GIT_STR_INIT; + if (git_str_join3(&path, '/', git_repository_workdir(repo), name, DOT_GIT) < 0 || git_path_validate_workdir_buf(NULL, &path) < 0) @@ -388,7 +391,7 @@ int git_submodule__lookup_with_cache( if (git_path_exists(path.ptr)) error = GIT_EEXISTS; - git_buf_dispose(&path); + git_str_dispose(&path); } submodule_set_lookup_error(error, name); @@ -405,7 +408,7 @@ int git_submodule__lookup_with_cache( int git_submodule_name_is_valid(git_repository *repo, const char *name, int flags) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error, isvalid; if (flags == 0) @@ -416,11 +419,11 @@ int git_submodule_name_is_valid(git_repository *repo, const char *name, int flag if ((error = git_path_normalize_slashes(&buf, name)) < 0) return error; } else { - git_buf_attach_notowned(&buf, name, strlen(name)); + git_str_attach_notowned(&buf, name, strlen(name)); } isvalid = git_path_validate(repo, buf.ptr, 0, flags); - git_buf_dispose(&buf); + git_str_dispose(&buf); return isvalid; } @@ -554,7 +557,7 @@ int git_submodule__map(git_repository *repo, git_strmap *map) int error = 0; git_index *idx = NULL; git_tree *head = NULL; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_submodule *sm; git_config *mods = NULL; bool has_workdir; @@ -613,7 +616,7 @@ int git_submodule__map(git_repository *repo, git_strmap *map) /* TODO: if we got an error, mark submodule config as invalid? */ git_index_free(idx); git_tree_free(head); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -682,7 +685,7 @@ static int submodule_repo_init( bool use_gitlink) { int error = 0; - git_buf workdir = GIT_BUF_INIT, repodir = GIT_BUF_INIT; + git_str workdir = GIT_STR_INIT, repodir = GIT_STR_INIT; git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT; git_repository *subrepo = NULL; @@ -701,10 +704,10 @@ static int submodule_repo_init( * Old style: sub-repo goes directly into repo//.git/ */ if (use_gitlink) { - error = git_repository_item_path(&repodir, parent_repo, GIT_REPOSITORY_ITEM_MODULES); + error = git_repository__item_path(&repodir, parent_repo, GIT_REPOSITORY_ITEM_MODULES); if (error < 0) goto cleanup; - error = git_buf_joinpath(&repodir, repodir.ptr, path); + error = git_str_joinpath(&repodir, repodir.ptr, path); if (error < 0) goto cleanup; @@ -718,14 +721,57 @@ static int submodule_repo_init( error = git_repository_init_ext(&subrepo, workdir.ptr, &initopt); cleanup: - git_buf_dispose(&workdir); - git_buf_dispose(&repodir); + git_str_dispose(&workdir); + git_str_dispose(&repodir); *out = subrepo; return error; } +static int git_submodule__resolve_url( + git_str *out, + git_repository *repo, + const char *url) +{ + int error = 0; + git_str normalized = GIT_STR_INIT; + + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(repo); + GIT_ASSERT_ARG(url); + + /* We do this in all platforms in case someone on Windows created the .gitmodules */ + if (strchr(url, '\\')) { + if ((error = git_path_normalize_slashes(&normalized, url)) < 0) + return error; + + url = normalized.ptr; + } + + + if (git_path_is_relative(url)) { + if (!(error = get_url_base(out, repo))) + error = git_path_apply_relative(out, url); + } else if (strchr(url, ':') != NULL || url[0] == '/') { + error = git_str_sets(out, url); + } else { + git_error_set(GIT_ERROR_SUBMODULE, "invalid format for submodule URL"); + error = -1; + } + + git_str_dispose(&normalized); + return error; +} + +int git_submodule_resolve_url( + git_buf *out, + git_repository *repo, + const char *url) +{ + GIT_BUF_WRAP_PRIVATE(out, git_submodule__resolve_url, repo, url); +} + int git_submodule_add_setup( git_submodule **out, git_repository *repo, @@ -736,7 +782,7 @@ int git_submodule_add_setup( int error = 0; git_config_backend *mods = NULL; git_submodule *sm = NULL; - git_buf name = GIT_BUF_INIT, real_url = GIT_BUF_INIT; + git_str name = GIT_STR_INIT, real_url = GIT_STR_INIT; git_repository *subrepo = NULL; bool path_occupied; @@ -781,7 +827,7 @@ int git_submodule_add_setup( return -1; } - if ((error = git_buf_printf(&name, "submodule.%s.path", path)) < 0 || + if ((error = git_str_printf(&name, "submodule.%s.path", path)) < 0 || (error = git_config_backend_set_string(mods, name.ptr, path)) < 0) goto cleanup; @@ -789,7 +835,7 @@ int git_submodule_add_setup( (error = git_config_backend_set_string(mods, name.ptr, url)) < 0) goto cleanup; - git_buf_clear(&name); + git_str_clear(&name); /* init submodule repository and add origin remote as needed */ @@ -804,7 +850,7 @@ int git_submodule_add_setup( git_path_contains(&name, DOT_GIT))) { /* resolve the actual URL to use */ - if ((error = git_submodule_resolve_url(&real_url, repo, url)) < 0) + if ((error = git_submodule__resolve_url(&real_url, repo, url)) < 0) goto cleanup; if ((error = submodule_repo_init(&subrepo, repo, path, real_url.ptr, use_gitlink)) < 0) @@ -826,8 +872,8 @@ int git_submodule_add_setup( git_config_backend_free(mods); git_repository_free(subrepo); - git_buf_dispose(&real_url); - git_buf_dispose(&name); + git_str_dispose(&real_url); + git_str_dispose(&name); return error; } @@ -841,13 +887,13 @@ int git_submodule_repo_init( git_repository *sub_repo = NULL; const char *configured_url; git_config *cfg = NULL; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(sm); /* get the configured remote url of the submodule */ - if ((error = git_buf_printf(&buf, "submodule.%s.url", sm->name)) < 0 || + if ((error = git_str_printf(&buf, "submodule.%s.url", sm->name)) < 0 || (error = git_repository_config_snapshot(&cfg, sm->repo)) < 0 || (error = git_config_get_string(&configured_url, cfg, buf.ptr)) < 0 || (error = submodule_repo_init(&sub_repo, sm->repo, sm->path, configured_url, use_gitlink)) < 0) @@ -857,7 +903,7 @@ int git_submodule_repo_init( done: git_config_free(cfg); - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -881,7 +927,7 @@ int git_submodule_clone(git_repository **out, git_submodule *submodule, const gi { int error; git_repository *clone; - git_buf rel_path = GIT_BUF_INIT; + git_str rel_path = GIT_STR_INIT; git_submodule_update_options sub_opts = GIT_SUBMODULE_UPDATE_OPTIONS_INIT; git_clone_options opts = GIT_CLONE_OPTIONS_INIT; @@ -903,7 +949,7 @@ int git_submodule_clone(git_repository **out, git_submodule *submodule, const gi if (error < 0) goto cleanup; - error = git_clone__submodule(&clone, git_submodule_url(submodule), git_buf_cstr(&rel_path), &opts); + error = git_clone__submodule(&clone, git_submodule_url(submodule), git_str_cstr(&rel_path), &opts); if (error < 0) goto cleanup; @@ -913,7 +959,7 @@ int git_submodule_clone(git_repository **out, git_submodule *submodule, const gi *out = clone; cleanup: - git_buf_dispose(&rel_path); + git_str_dispose(&rel_path); return error; } @@ -937,7 +983,7 @@ int git_submodule_add_to_index(git_submodule *sm, int write_index) int error; git_repository *sm_repo = NULL; git_index *index; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_commit *head; git_index_entry entry; struct stat st; @@ -997,7 +1043,7 @@ int git_submodule_add_to_index(git_submodule *sm, int write_index) cleanup: git_repository_free(sm_repo); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -1034,44 +1080,9 @@ const char *git_submodule_url(git_submodule *submodule) return submodule->url; } -int git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *url) -{ - int error = 0; - git_buf normalized = GIT_BUF_INIT; - - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(repo); - GIT_ASSERT_ARG(url); - - if ((error = git_buf_sanitize(out)) < 0) - return error; - - /* We do this in all platforms in case someone on Windows created the .gitmodules */ - if (strchr(url, '\\')) { - if ((error = git_path_normalize_slashes(&normalized, url)) < 0) - return error; - - url = normalized.ptr; - } - - - if (git_path_is_relative(url)) { - if (!(error = get_url_base(out, repo))) - error = git_path_apply_relative(out, url); - } else if (strchr(url, ':') != NULL || url[0] == '/') { - error = git_buf_sets(out, url); - } else { - git_error_set(GIT_ERROR_SUBMODULE, "invalid format for submodule URL"); - error = -1; - } - - git_buf_dispose(&normalized); - return error; -} - static int write_var(git_repository *repo, const char *name, const char *var, const char *val) { - git_buf key = GIT_BUF_INIT; + git_str key = GIT_STR_INIT; git_config_backend *mods; int error; @@ -1079,7 +1090,7 @@ static int write_var(git_repository *repo, const char *name, const char *var, co if (!mods) return -1; - if ((error = git_buf_printf(&key, "submodule.%s.%s", name, var)) < 0) + if ((error = git_str_printf(&key, "submodule.%s.%s", name, var)) < 0) goto cleanup; if (val) @@ -1087,7 +1098,7 @@ static int write_var(git_repository *repo, const char *name, const char *var, co else error = git_config_backend_delete(mods, key.ptr); - git_buf_dispose(&key); + git_str_dispose(&key); cleanup: git_config_backend_free(mods); @@ -1227,7 +1238,7 @@ static int submodule_repo_create( const char *path) { int error = 0; - git_buf workdir = GIT_BUF_INIT, repodir = GIT_BUF_INIT; + git_str workdir = GIT_STR_INIT, repodir = GIT_STR_INIT; git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT; git_repository *subrepo = NULL; @@ -1249,18 +1260,18 @@ static int submodule_repo_create( * /modules// with a gitlink in the * sub-repo workdir directory to that repository. */ - error = git_repository_item_path(&repodir, parent_repo, GIT_REPOSITORY_ITEM_MODULES); + error = git_repository__item_path(&repodir, parent_repo, GIT_REPOSITORY_ITEM_MODULES); if (error < 0) goto cleanup; - error = git_buf_joinpath(&repodir, repodir.ptr, path); + error = git_str_joinpath(&repodir, repodir.ptr, path); if (error < 0) goto cleanup; error = git_repository_init_ext(&subrepo, repodir.ptr, &initopt); cleanup: - git_buf_dispose(&workdir); - git_buf_dispose(&repodir); + git_str_dispose(&workdir); + git_str_dispose(&repodir); *out = subrepo; @@ -1309,7 +1320,7 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio git_repository *sub_repo = NULL; git_remote *remote = NULL; git_object *target_commit = NULL; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT; git_clone_options clone_options = GIT_CLONE_OPTIONS_INIT; @@ -1337,10 +1348,10 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio * info has been copied into .git/config */ if ((error = git_repository_config_snapshot(&config, sm->repo)) < 0 || - (error = git_buf_printf(&buf, "submodule.%s.url", git_submodule_name(sm))) < 0) + (error = git_str_printf(&buf, "submodule.%s.url", git_submodule_name(sm))) < 0) goto done; - if ((error = git_config_get_string(&submodule_url, config, git_buf_cstr(&buf))) < 0) { + if ((error = git_config_get_string(&submodule_url, config, git_str_cstr(&buf))) < 0) { /* * If the error is not "not found" or if it is "not found" and we are not * initializing the submodule, then return error. @@ -1362,7 +1373,7 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio config = NULL; if ((error = git_repository_config_snapshot(&config, sm->repo)) < 0 || - (error = git_config_get_string(&submodule_url, config, git_buf_cstr(&buf))) < 0) + (error = git_config_get_string(&submodule_url, config, git_str_cstr(&buf))) < 0) goto done; } @@ -1420,7 +1431,7 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio } done: - git_buf_dispose(&buf); + git_str_dispose(&buf); git_config_free(config); git_object_free(target_commit); git_remote_free(remote); @@ -1433,7 +1444,7 @@ int git_submodule_init(git_submodule *sm, int overwrite) { int error; const char *val; - git_buf key = GIT_BUF_INIT, effective_submodule_url = GIT_BUF_INIT; + git_str key = GIT_STR_INIT, effective_submodule_url = GIT_STR_INIT; git_config *cfg = NULL; if (!sm->url) { @@ -1447,8 +1458,8 @@ int git_submodule_init(git_submodule *sm, int overwrite) /* write "submodule.NAME.url" */ - if ((error = git_submodule_resolve_url(&effective_submodule_url, sm->repo, sm->url)) < 0 || - (error = git_buf_printf(&key, "submodule.%s.url", sm->name)) < 0 || + if ((error = git_submodule__resolve_url(&effective_submodule_url, sm->repo, sm->url)) < 0 || + (error = git_str_printf(&key, "submodule.%s.url", sm->name)) < 0 || (error = git_config__update_entry( cfg, key.ptr, effective_submodule_url.ptr, overwrite != 0, false)) < 0) goto cleanup; @@ -1458,7 +1469,7 @@ int git_submodule_init(git_submodule *sm, int overwrite) val = (sm->update == GIT_SUBMODULE_UPDATE_CHECKOUT) ? NULL : submodule_update_to_str(sm->update); - if ((error = git_buf_printf(&key, "submodule.%s.update", sm->name)) < 0 || + if ((error = git_str_printf(&key, "submodule.%s.update", sm->name)) < 0 || (error = git_config__update_entry( cfg, key.ptr, val, overwrite != 0, false)) < 0) goto cleanup; @@ -1467,15 +1478,15 @@ int git_submodule_init(git_submodule *sm, int overwrite) cleanup: git_config_free(cfg); - git_buf_dispose(&key); - git_buf_dispose(&effective_submodule_url); + git_str_dispose(&key); + git_str_dispose(&effective_submodule_url); return error; } int git_submodule_sync(git_submodule *sm) { - git_buf key = GIT_BUF_INIT, url = GIT_BUF_INIT, remote_name = GIT_BUF_INIT; + git_str key = GIT_STR_INIT, url = GIT_STR_INIT, remote_name = GIT_STR_INIT; git_repository *smrepo = NULL; git_config *cfg = NULL; int error = 0; @@ -1487,8 +1498,8 @@ int git_submodule_sync(git_submodule *sm) /* copy URL over to config only if it already exists */ if ((error = git_repository_config__weakptr(&cfg, sm->repo)) < 0 || - (error = git_buf_printf(&key, "submodule.%s.url", sm->name)) < 0 || - (error = git_submodule_resolve_url(&url, sm->repo, sm->url)) < 0 || + (error = git_str_printf(&key, "submodule.%s.url", sm->name)) < 0 || + (error = git_submodule__resolve_url(&url, sm->repo, sm->url)) < 0 || (error = git_config__update_entry(cfg, key.ptr, url.ptr, true, true)) < 0) goto out; @@ -1501,9 +1512,9 @@ int git_submodule_sync(git_submodule *sm) goto out; if (lookup_head_remote_key(&remote_name, smrepo) == 0) { - if ((error = git_buf_join3(&key, '.', "remote", remote_name.ptr, "url")) < 0) + if ((error = git_str_join3(&key, '.', "remote", remote_name.ptr, "url")) < 0) goto out; - } else if ((error = git_buf_sets(&key, "remote.origin.url")) < 0) { + } else if ((error = git_str_sets(&key, "remote.origin.url")) < 0) { goto out; } @@ -1512,9 +1523,9 @@ int git_submodule_sync(git_submodule *sm) out: git_repository_free(smrepo); - git_buf_dispose(&remote_name); - git_buf_dispose(&key); - git_buf_dispose(&url); + git_str_dispose(&remote_name); + git_str_dispose(&key); + git_str_dispose(&url); return error; } @@ -1522,7 +1533,7 @@ static int git_submodule__open( git_repository **subrepo, git_submodule *sm, bool bare) { int error; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; unsigned int flags = GIT_REPOSITORY_OPEN_NO_SEARCH; const char *wd; @@ -1535,7 +1546,7 @@ static int git_submodule__open( wd = git_repository_workdir(sm->repo); - if (git_buf_join3(&path, '/', wd, sm->path, DOT_GIT) < 0) + if (git_str_join3(&path, '/', wd, sm->path, DOT_GIT) < 0) return -1; sm->flags = sm->flags & @@ -1561,13 +1572,13 @@ static int git_submodule__open( sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED | GIT_SUBMODULE_STATUS_IN_WD; } else { - git_buf_rtruncate_at_char(&path, '/'); /* remove "/.git" */ + git_str_rtruncate_at_char(&path, '/'); /* remove "/.git" */ if (git_path_isdir(path.ptr)) sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED; } - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -1921,13 +1932,13 @@ static int submodule_parse_recurse(git_submodule_recurse_t *out, const char *val return 0; } -static int get_value(const char **out, git_config *cfg, git_buf *buf, const char *name, const char *field) +static int get_value(const char **out, git_config *cfg, git_str *buf, const char *name, const char *field) { int error; - git_buf_clear(buf); + git_str_clear(buf); - if ((error = git_buf_printf(buf, "submodule.%s.%s", name, field)) < 0 || + if ((error = git_str_printf(buf, "submodule.%s.%s", name, field)) < 0 || (error = git_config_get_string(out, cfg, buf->ptr)) < 0) return error; @@ -1944,7 +1955,7 @@ static bool looks_like_command_line_option(const char *s) static int submodule_read_config(git_submodule *sm, git_config *cfg) { - git_buf key = GIT_BUF_INIT; + git_str key = GIT_STR_INIT; const char *value; int error, in_config = 0; @@ -2025,7 +2036,7 @@ static int submodule_read_config(git_submodule *sm, git_config *cfg) error = 0; cleanup: - git_buf_dispose(&key); + git_str_dispose(&key); return error; } @@ -2034,7 +2045,7 @@ static int submodule_load_each(const git_config_entry *entry, void *payload) lfc_data *data = payload; const char *namestart, *property; git_strmap *map = data->map; - git_buf name = GIT_BUF_INIT; + git_str name = GIT_STR_INIT; git_submodule *sm; int error, isvalid; @@ -2049,7 +2060,7 @@ static int submodule_load_each(const git_config_entry *entry, void *payload) property++; - if ((error = git_buf_set(&name, namestart, property - namestart -1)) < 0) + if ((error = git_str_set(&name, namestart, property - namestart -1)) < 0) return error; isvalid = git_submodule_name_is_valid(data->repo, name.ptr, 0); @@ -2083,13 +2094,13 @@ static int submodule_load_each(const git_config_entry *entry, void *payload) error = 0; done: - git_buf_dispose(&name); + git_str_dispose(&name); return error; } static int submodule_load_from_wd_lite(git_submodule *sm) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; if (git_repository_workdir_path(&path, sm->repo, sm->path) < 0) return -1; @@ -2100,7 +2111,7 @@ static int submodule_load_from_wd_lite(git_submodule *sm) if (git_path_contains(&path, DOT_GIT)) sm->flags |= GIT_SUBMODULE_STATUS_IN_WD; - git_buf_dispose(&path); + git_str_dispose(&path); return 0; } @@ -2112,7 +2123,7 @@ static int submodule_load_from_wd_lite(git_submodule *sm) static int gitmodules_snapshot(git_config **snap, git_repository *repo) { git_config *mods = NULL; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error; if (git_repository_workdir(repo) == NULL) @@ -2123,7 +2134,7 @@ static int gitmodules_snapshot(git_config **snap, git_repository *repo) if ((error = git_config_open_ondisk(&mods, path.ptr)) < 0) goto cleanup; - git_buf_dispose(&path); + git_str_dispose(&path); if ((error = git_config_snapshot(snap, mods)) < 0) goto cleanup; @@ -2133,7 +2144,7 @@ static int gitmodules_snapshot(git_config **snap, git_repository *repo) cleanup: if (mods) git_config_free(mods); - git_buf_dispose(&path); + git_str_dispose(&path); return error; } @@ -2142,7 +2153,7 @@ static git_config_backend *open_gitmodules( git_repository *repo, int okay_to_create) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_config_backend *mods = NULL; if (git_repository_workdir(repo) != NULL) { @@ -2161,17 +2172,17 @@ static git_config_backend *open_gitmodules( } } - git_buf_dispose(&path); + git_str_dispose(&path); return mods; } /* Lookup name of remote of the local tracking branch HEAD points to */ -static int lookup_head_remote_key(git_buf *remote_name, git_repository *repo) +static int lookup_head_remote_key(git_str *remote_name, git_repository *repo) { int error; git_reference *head = NULL; - git_buf upstream_name = GIT_BUF_INIT; + git_str upstream_name = GIT_STR_INIT; /* lookup and dereference HEAD */ if ((error = git_repository_head(&head, repo)) < 0) @@ -2190,18 +2201,18 @@ static int lookup_head_remote_key(git_buf *remote_name, git_repository *repo) } /* lookup remote tracking branch of HEAD */ - if ((error = git_branch_upstream_name( + if ((error = git_branch__upstream_name( &upstream_name, repo, git_reference_name(head))) < 0) goto done; /* lookup remote of remote tracking branch */ - if ((error = git_branch_remote_name(remote_name, repo, upstream_name.ptr)) < 0) + if ((error = git_branch__remote_name(remote_name, repo, upstream_name.ptr)) < 0) goto done; done: - git_buf_dispose(&upstream_name); + git_str_dispose(&upstream_name); git_reference_free(head); return error; @@ -2211,13 +2222,13 @@ static int lookup_head_remote_key(git_buf *remote_name, git_repository *repo) static int lookup_head_remote(git_remote **remote, git_repository *repo) { int error; - git_buf remote_name = GIT_BUF_INIT; + git_str remote_name = GIT_STR_INIT; /* lookup remote of remote tracking branch name */ if (!(error = lookup_head_remote_key(&remote_name, repo))) error = git_remote_lookup(remote, repo, remote_name.ptr); - git_buf_dispose(&remote_name); + git_str_dispose(&remote_name); return error; } @@ -2240,14 +2251,14 @@ static int lookup_default_remote(git_remote **remote, git_repository *repo) return error; } -static int get_url_base(git_buf *url, git_repository *repo) +static int get_url_base(git_str *url, git_repository *repo) { int error; git_worktree *wt = NULL; git_remote *remote = NULL; if ((error = lookup_default_remote(&remote, repo)) == 0) { - error = git_buf_sets(url, git_remote_url(remote)); + error = git_str_sets(url, git_remote_url(remote)); goto out; } else if (error != GIT_ENOTFOUND) goto out; @@ -2258,9 +2269,9 @@ static int get_url_base(git_buf *url, git_repository *repo) if (git_repository_is_worktree(repo)) { if ((error = git_worktree_open_from_repository(&wt, repo)) < 0) goto out; - error = git_buf_sets(url, wt->parent_path); + error = git_str_sets(url, wt->parent_path); } else { - error = git_buf_sets(url, git_repository_workdir(repo)); + error = git_str_sets(url, git_repository_workdir(repo)); } out: diff --git a/src/sysdir.c b/src/sysdir.c index dcbd48bc394..457d7f8a8f5 100644 --- a/src/sysdir.c +++ b/src/sysdir.c @@ -8,7 +8,7 @@ #include "sysdir.h" #include "runtime.h" -#include "buffer.h" +#include "str.h" #include "path.h" #include #if GIT_WIN32 @@ -18,27 +18,27 @@ #include #endif -static int git_sysdir_guess_programdata_dirs(git_buf *out) +static int git_sysdir_guess_programdata_dirs(git_str *out) { #ifdef GIT_WIN32 return git_win32__find_programdata_dirs(out); #else - git_buf_clear(out); + git_str_clear(out); return 0; #endif } -static int git_sysdir_guess_system_dirs(git_buf *out) +static int git_sysdir_guess_system_dirs(git_str *out) { #ifdef GIT_WIN32 return git_win32__find_system_dirs(out, L"etc\\"); #else - return git_buf_sets(out, "/etc"); + return git_str_sets(out, "/etc"); #endif } #ifndef GIT_WIN32 -static int get_passwd_home(git_buf *out, uid_t uid) +static int get_passwd_home(git_str *out, uid_t uid) { struct passwd pwd, *pwdptr; char *buf = NULL; @@ -66,7 +66,7 @@ static int get_passwd_home(git_buf *out, uid_t uid) goto out; } - if ((error = git_buf_puts(out, pwdptr->pw_dir)) < 0) + if ((error = git_str_puts(out, pwdptr->pw_dir)) < 0) goto out; out: @@ -75,7 +75,7 @@ static int get_passwd_home(git_buf *out, uid_t uid) } #endif -static int git_sysdir_guess_global_dirs(git_buf *out) +static int git_sysdir_guess_global_dirs(git_str *out) { #ifdef GIT_WIN32 return git_win32__find_global_dirs(out); @@ -114,12 +114,12 @@ static int git_sysdir_guess_global_dirs(git_buf *out) #endif } -static int git_sysdir_guess_xdg_dirs(git_buf *out) +static int git_sysdir_guess_xdg_dirs(git_str *out) { #ifdef GIT_WIN32 return git_win32__find_xdg_dirs(out); #else - git_buf env = GIT_BUF_INIT; + git_str env = GIT_STR_INIT; int error; uid_t uid, euid; @@ -132,13 +132,13 @@ static int git_sysdir_guess_xdg_dirs(git_buf *out) */ if (uid == euid) { if ((error = git__getenv(&env, "XDG_CONFIG_HOME")) == 0) - error = git_buf_joinpath(out, env.ptr, "git"); + error = git_str_joinpath(out, env.ptr, "git"); if (error == GIT_ENOTFOUND && (error = git__getenv(&env, "HOME")) == 0) - error = git_buf_joinpath(out, env.ptr, ".config/git"); + error = git_str_joinpath(out, env.ptr, ".config/git"); } else { if ((error = get_passwd_home(&env, euid)) == 0) - error = git_buf_joinpath(out, env.ptr, ".config/git"); + error = git_str_joinpath(out, env.ptr, ".config/git"); } if (error == GIT_ENOTFOUND) { @@ -146,31 +146,31 @@ static int git_sysdir_guess_xdg_dirs(git_buf *out) error = 0; } - git_buf_dispose(&env); + git_str_dispose(&env); return error; #endif } -static int git_sysdir_guess_template_dirs(git_buf *out) +static int git_sysdir_guess_template_dirs(git_str *out) { #ifdef GIT_WIN32 return git_win32__find_system_dirs(out, L"share\\git-core\\templates"); #else - return git_buf_sets(out, "/usr/share/git-core/templates"); + return git_str_sets(out, "/usr/share/git-core/templates"); #endif } struct git_sysdir__dir { - git_buf buf; - int (*guess)(git_buf *out); + git_str buf; + int (*guess)(git_str *out); }; static struct git_sysdir__dir git_sysdir__dirs[] = { - { GIT_BUF_INIT, git_sysdir_guess_system_dirs }, - { GIT_BUF_INIT, git_sysdir_guess_global_dirs }, - { GIT_BUF_INIT, git_sysdir_guess_xdg_dirs }, - { GIT_BUF_INIT, git_sysdir_guess_programdata_dirs }, - { GIT_BUF_INIT, git_sysdir_guess_template_dirs }, + { GIT_STR_INIT, git_sysdir_guess_system_dirs }, + { GIT_STR_INIT, git_sysdir_guess_global_dirs }, + { GIT_STR_INIT, git_sysdir_guess_xdg_dirs }, + { GIT_STR_INIT, git_sysdir_guess_programdata_dirs }, + { GIT_STR_INIT, git_sysdir_guess_template_dirs }, }; static void git_sysdir_global_shutdown(void) @@ -178,7 +178,7 @@ static void git_sysdir_global_shutdown(void) size_t i; for (i = 0; i < ARRAY_SIZE(git_sysdir__dirs); ++i) - git_buf_dispose(&git_sysdir__dirs[i].buf); + git_str_dispose(&git_sysdir__dirs[i].buf); } int git_sysdir_global_init(void) @@ -202,7 +202,7 @@ static int git_sysdir_check_selector(git_sysdir_t which) } -int git_sysdir_get(const git_buf **out, git_sysdir_t which) +int git_sysdir_get(const git_str **out, git_sysdir_t which) { GIT_ASSERT_ARG(out); @@ -219,7 +219,7 @@ int git_sysdir_get(const git_buf **out, git_sysdir_t which) int git_sysdir_set(git_sysdir_t which, const char *search_path) { const char *expand_path = NULL; - git_buf merge = GIT_BUF_INIT; + git_str merge = GIT_STR_INIT; GIT_ERROR_CHECK_ERROR(git_sysdir_check_selector(which)); @@ -233,48 +233,48 @@ int git_sysdir_set(git_sysdir_t which, const char *search_path) /* if $PATH is not referenced, then just set the path */ if (!expand_path) { if (search_path) - git_buf_sets(&git_sysdir__dirs[which].buf, search_path); + git_str_sets(&git_sysdir__dirs[which].buf, search_path); goto done; } /* otherwise set to join(before $PATH, old value, after $PATH) */ if (expand_path > search_path) - git_buf_set(&merge, search_path, expand_path - search_path); + git_str_set(&merge, search_path, expand_path - search_path); - if (git_buf_len(&git_sysdir__dirs[which].buf)) - git_buf_join(&merge, GIT_PATH_LIST_SEPARATOR, + if (git_str_len(&git_sysdir__dirs[which].buf)) + git_str_join(&merge, GIT_PATH_LIST_SEPARATOR, merge.ptr, git_sysdir__dirs[which].buf.ptr); expand_path += strlen(PATH_MAGIC); if (*expand_path) - git_buf_join(&merge, GIT_PATH_LIST_SEPARATOR, merge.ptr, expand_path); + git_str_join(&merge, GIT_PATH_LIST_SEPARATOR, merge.ptr, expand_path); - git_buf_swap(&git_sysdir__dirs[which].buf, &merge); - git_buf_dispose(&merge); + git_str_swap(&git_sysdir__dirs[which].buf, &merge); + git_str_dispose(&merge); done: - if (git_buf_oom(&git_sysdir__dirs[which].buf)) + if (git_str_oom(&git_sysdir__dirs[which].buf)) return -1; return 0; } static int git_sysdir_find_in_dirlist( - git_buf *path, + git_str *path, const char *name, git_sysdir_t which, const char *label) { size_t len; const char *scan, *next = NULL; - const git_buf *syspath; + const git_str *syspath; GIT_ERROR_CHECK_ERROR(git_sysdir_get(&syspath, which)); - if (!syspath || !git_buf_len(syspath)) + if (!syspath || !git_str_len(syspath)) goto done; - for (scan = git_buf_cstr(syspath); scan; scan = next) { + for (scan = git_str_cstr(syspath); scan; scan = next) { /* find unescaped separator or end of string */ for (next = scan; *next; ++next) { if (*next == GIT_PATH_LIST_SEPARATOR && @@ -287,9 +287,9 @@ static int git_sysdir_find_in_dirlist( if (!len) continue; - GIT_ERROR_CHECK_ERROR(git_buf_set(path, scan, len)); + GIT_ERROR_CHECK_ERROR(git_str_set(path, scan, len)); if (name) - GIT_ERROR_CHECK_ERROR(git_buf_joinpath(path, path->ptr, name)); + GIT_ERROR_CHECK_ERROR(git_str_joinpath(path, path->ptr, name)); if (git_path_exists(path->ptr)) return 0; @@ -300,47 +300,47 @@ static int git_sysdir_find_in_dirlist( git_error_set(GIT_ERROR_OS, "the %s file '%s' doesn't exist", label, name); else git_error_set(GIT_ERROR_OS, "the %s directory doesn't exist", label); - git_buf_dispose(path); + git_str_dispose(path); return GIT_ENOTFOUND; } -int git_sysdir_find_system_file(git_buf *path, const char *filename) +int git_sysdir_find_system_file(git_str *path, const char *filename) { return git_sysdir_find_in_dirlist( path, filename, GIT_SYSDIR_SYSTEM, "system"); } -int git_sysdir_find_global_file(git_buf *path, const char *filename) +int git_sysdir_find_global_file(git_str *path, const char *filename) { return git_sysdir_find_in_dirlist( path, filename, GIT_SYSDIR_GLOBAL, "global"); } -int git_sysdir_find_xdg_file(git_buf *path, const char *filename) +int git_sysdir_find_xdg_file(git_str *path, const char *filename) { return git_sysdir_find_in_dirlist( path, filename, GIT_SYSDIR_XDG, "global/xdg"); } -int git_sysdir_find_programdata_file(git_buf *path, const char *filename) +int git_sysdir_find_programdata_file(git_str *path, const char *filename) { return git_sysdir_find_in_dirlist( path, filename, GIT_SYSDIR_PROGRAMDATA, "ProgramData"); } -int git_sysdir_find_template_dir(git_buf *path) +int git_sysdir_find_template_dir(git_str *path) { return git_sysdir_find_in_dirlist( path, NULL, GIT_SYSDIR_TEMPLATE, "template"); } -int git_sysdir_expand_global_file(git_buf *path, const char *filename) +int git_sysdir_expand_global_file(git_str *path, const char *filename) { int error; if ((error = git_sysdir_find_global_file(path, NULL)) == 0) { if (filename) - error = git_buf_joinpath(path, path->ptr, filename); + error = git_str_joinpath(path, path->ptr, filename); } return error; diff --git a/src/sysdir.h b/src/sysdir.h index cc5599e383a..d12bac9d9be 100644 --- a/src/sysdir.h +++ b/src/sysdir.h @@ -10,7 +10,7 @@ #include "common.h" #include "posix.h" -#include "buffer.h" +#include "str.h" /** * Find a "global" file (i.e. one in a user's home directory). @@ -19,7 +19,7 @@ * @param filename name of file to find in the home directory * @return 0 if found, GIT_ENOTFOUND if not found, or -1 on other OS error */ -extern int git_sysdir_find_global_file(git_buf *path, const char *filename); +extern int git_sysdir_find_global_file(git_str *path, const char *filename); /** * Find an "XDG" file (i.e. one in user's XDG config path). @@ -28,7 +28,7 @@ extern int git_sysdir_find_global_file(git_buf *path, const char *filename); * @param filename name of file to find in the home directory * @return 0 if found, GIT_ENOTFOUND if not found, or -1 on other OS error */ -extern int git_sysdir_find_xdg_file(git_buf *path, const char *filename); +extern int git_sysdir_find_xdg_file(git_str *path, const char *filename); /** * Find a "system" file (i.e. one shared for all users of the system). @@ -37,7 +37,7 @@ extern int git_sysdir_find_xdg_file(git_buf *path, const char *filename); * @param filename name of file to find in the home directory * @return 0 if found, GIT_ENOTFOUND if not found, or -1 on other OS error */ -extern int git_sysdir_find_system_file(git_buf *path, const char *filename); +extern int git_sysdir_find_system_file(git_str *path, const char *filename); /** * Find a "ProgramData" file (i.e. one in %PROGRAMDATA%) @@ -46,7 +46,7 @@ extern int git_sysdir_find_system_file(git_buf *path, const char *filename); * @param filename name of file to find in the ProgramData directory * @return 0 if found, GIT_ENOTFOUND if not found, or -1 on other OS error */ -extern int git_sysdir_find_programdata_file(git_buf *path, const char *filename); +extern int git_sysdir_find_programdata_file(git_str *path, const char *filename); /** * Find template directory. @@ -54,7 +54,7 @@ extern int git_sysdir_find_programdata_file(git_buf *path, const char *filename) * @param path buffer to write the full path into * @return 0 if found, GIT_ENOTFOUND if not found, or -1 on other OS error */ -extern int git_sysdir_find_template_dir(git_buf *path); +extern int git_sysdir_find_template_dir(git_str *path); /** * Expand the name of a "global" file (i.e. one in a user's home @@ -66,7 +66,7 @@ extern int git_sysdir_find_template_dir(git_buf *path); * @param filename name of file in the home directory * @return 0 on success or -1 on error */ -extern int git_sysdir_expand_global_file(git_buf *path, const char *filename); +extern int git_sysdir_expand_global_file(git_str *path, const char *filename); typedef enum { GIT_SYSDIR_SYSTEM = 0, @@ -87,11 +87,11 @@ extern int git_sysdir_global_init(void); /** * Get the search path for global/system/xdg files * - * @param out pointer to git_buf containing search path + * @param out pointer to git_str containing search path * @param which which list of paths to return * @return 0 on success, <0 on failure */ -extern int git_sysdir_get(const git_buf **out, git_sysdir_t which); +extern int git_sysdir_get(const git_str **out, git_sysdir_t which); /** * Set search paths for global/system/xdg files diff --git a/src/tag.c b/src/tag.c index ee91e509162..7a155147d1c 100644 --- a/src/tag.c +++ b/src/tag.c @@ -9,7 +9,6 @@ #include "commit.h" #include "signature.h" -#include "message.h" #include "wildmatch.h" #include "git2/object.h" #include "git2/repository.h" @@ -176,7 +175,7 @@ int git_tag__parse(void *_tag, git_odb_object *odb_obj) static int retrieve_tag_reference( git_reference **tag_reference_out, - git_buf *ref_name_out, + git_str *ref_name_out, git_repository *repo, const char *tag_name) { @@ -185,7 +184,7 @@ static int retrieve_tag_reference( *tag_reference_out = NULL; - if (git_buf_joinpath(ref_name_out, GIT_REFS_TAGS_DIR, tag_name) < 0) + if (git_str_joinpath(ref_name_out, GIT_REFS_TAGS_DIR, tag_name) < 0) return -1; error = git_reference_lookup(&tag_ref, repo, ref_name_out->ptr); @@ -199,11 +198,11 @@ static int retrieve_tag_reference( static int retrieve_tag_reference_oid( git_oid *oid, - git_buf *ref_name_out, + git_str *ref_name_out, git_repository *repo, const char *tag_name) { - if (git_buf_joinpath(ref_name_out, GIT_REFS_TAGS_DIR, tag_name) < 0) + if (git_str_joinpath(ref_name_out, GIT_REFS_TAGS_DIR, tag_name) < 0) return -1; return git_reference_name_to_id(oid, repo, ref_name_out->ptr); @@ -217,16 +216,16 @@ static int write_tag_annotation( const git_signature *tagger, const char *message) { - git_buf tag = GIT_BUF_INIT; + git_str tag = GIT_STR_INIT; git_odb *odb; git_oid__writebuf(&tag, "object ", git_object_id(target)); - git_buf_printf(&tag, "type %s\n", git_object_type2string(git_object_type(target))); - git_buf_printf(&tag, "tag %s\n", tag_name); + git_str_printf(&tag, "type %s\n", git_object_type2string(git_object_type(target))); + git_str_printf(&tag, "tag %s\n", tag_name); git_signature__writebuf(&tag, "tagger ", tagger); - git_buf_putc(&tag, '\n'); + git_str_putc(&tag, '\n'); - if (git_buf_puts(&tag, message) < 0) + if (git_str_puts(&tag, message) < 0) goto on_error; if (git_repository_odb__weakptr(&odb, repo) < 0) @@ -235,11 +234,11 @@ static int write_tag_annotation( if (git_odb_write(oid, odb, tag.ptr, tag.size, GIT_OBJECT_TAG) < 0) goto on_error; - git_buf_dispose(&tag); + git_str_dispose(&tag); return 0; on_error: - git_buf_dispose(&tag); + git_str_dispose(&tag); git_error_set(GIT_ERROR_OBJECT, "failed to create tag annotation"); return -1; } @@ -255,7 +254,7 @@ static int git_tag_create__internal( int create_tag_annotation) { git_reference *new_ref = NULL; - git_buf ref_name = GIT_BUF_INIT; + git_str ref_name = GIT_STR_INIT; int error; @@ -276,7 +275,7 @@ static int git_tag_create__internal( /** Ensure the tag name doesn't conflict with an already existing * reference unless overwriting has explicitly been requested **/ if (error == 0 && !allow_ref_overwrite) { - git_buf_dispose(&ref_name); + git_str_dispose(&ref_name); git_error_set(GIT_ERROR_TAG, "tag already exists"); return GIT_EEXISTS; } @@ -291,7 +290,7 @@ static int git_tag_create__internal( cleanup: git_reference_free(new_ref); - git_buf_dispose(&ref_name); + git_str_dispose(&ref_name); return error; } @@ -344,7 +343,7 @@ int git_tag_create_from_buffer(git_oid *oid, git_repository *repo, const char *b git_odb_object *target_obj; git_reference *new_ref = NULL; - git_buf ref_name = GIT_BUF_INIT; + git_str ref_name = GIT_STR_INIT; GIT_ASSERT_ARG(oid); GIT_ASSERT_ARG(buffer); @@ -395,7 +394,7 @@ int git_tag_create_from_buffer(git_oid *oid, git_repository *repo, const char *b git_odb_stream_free(stream); if (error < 0) { - git_buf_dispose(&ref_name); + git_str_dispose(&ref_name); return error; } @@ -403,7 +402,7 @@ int git_tag_create_from_buffer(git_oid *oid, git_repository *repo, const char *b &new_ref, repo, ref_name.ptr, oid, allow_ref_overwrite, NULL); git_reference_free(new_ref); - git_buf_dispose(&ref_name); + git_str_dispose(&ref_name); return error; @@ -418,12 +417,12 @@ int git_tag_create_from_buffer(git_oid *oid, git_repository *repo, const char *b int git_tag_delete(git_repository *repo, const char *tag_name) { git_reference *tag_ref; - git_buf ref_name = GIT_BUF_INIT; + git_str ref_name = GIT_STR_INIT; int error; error = retrieve_tag_reference(&tag_ref, &ref_name, repo, tag_name); - git_buf_dispose(&ref_name); + git_str_dispose(&ref_name); if (error < 0) return error; @@ -535,7 +534,7 @@ int git_tag_peel(git_object **tag_target, const git_tag *tag) int git_tag_name_is_valid(int *valid, const char *name) { - git_buf ref_name = GIT_BUF_INIT; + git_str ref_name = GIT_STR_INIT; int error = 0; GIT_ASSERT(valid); @@ -547,14 +546,14 @@ int git_tag_name_is_valid(int *valid, const char *name) if (!name || name[0] == '-') goto done; - if ((error = git_buf_puts(&ref_name, GIT_REFS_TAGS_DIR)) < 0 || - (error = git_buf_puts(&ref_name, name)) < 0) + if ((error = git_str_puts(&ref_name, GIT_REFS_TAGS_DIR)) < 0 || + (error = git_str_puts(&ref_name, name)) < 0) goto done; error = git_reference_name_is_valid(valid, ref_name.ptr); done: - git_buf_dispose(&ref_name); + git_str_dispose(&ref_name); return error; } diff --git a/src/threadstate.c b/src/threadstate.c index e2c08975fd9..f67cf082bb4 100644 --- a/src/threadstate.c +++ b/src/threadstate.c @@ -36,7 +36,7 @@ static void threadstate_dispose(git_threadstate *threadstate) if (!threadstate) return; - if (threadstate->error_t.message != git_buf__initbuf) + if (threadstate->error_t.message != git_str__initstr) git__free(threadstate->error_t.message); threadstate->error_t.message = NULL; } @@ -76,7 +76,7 @@ git_threadstate *git_threadstate_get(void) return threadstate; if ((threadstate = git__calloc(1, sizeof(git_threadstate))) == NULL || - git_buf_init(&threadstate->error_buf, 0) < 0) + git_str_init(&threadstate->error_buf, 0) < 0) return NULL; git_tlsdata_set(tls_key, threadstate); diff --git a/src/threadstate.h b/src/threadstate.h index 51810a9390f..c10f26b5947 100644 --- a/src/threadstate.h +++ b/src/threadstate.h @@ -12,7 +12,7 @@ typedef struct { git_error *last_error; git_error error_t; - git_buf error_buf; + git_str error_buf; char oid_fmt[GIT_OID_HEXSZ+1]; } git_threadstate; diff --git a/src/trace.c b/src/trace.c index efc7b01a2d8..c316bcacfa1 100644 --- a/src/trace.c +++ b/src/trace.c @@ -7,7 +7,7 @@ #include "trace.h" -#include "buffer.h" +#include "str.h" #include "runtime.h" #include "git2/trace.h" diff --git a/src/trace.h b/src/trace.h index a233aa2257c..eb20ec57b0f 100644 --- a/src/trace.h +++ b/src/trace.h @@ -10,7 +10,7 @@ #include "common.h" #include -#include "buffer.h" +#include "str.h" #ifdef GIT_TRACE @@ -27,13 +27,13 @@ GIT_INLINE(void) git_trace__write_fmt( va_list ap) { git_trace_cb callback = git_trace__data.callback; - git_buf message = GIT_BUF_INIT; + git_str message = GIT_STR_INIT; - git_buf_vprintf(&message, fmt, ap); + git_str_vprintf(&message, fmt, ap); - callback(level, git_buf_cstr(&message)); + callback(level, git_str_cstr(&message)); - git_buf_dispose(&message); + git_str_dispose(&message); } #define git_trace_level() (git_trace__data.level) diff --git a/src/transport.c b/src/transport.c index e128aa6c724..fa1d35fcef2 100644 --- a/src/transport.c +++ b/src/transport.c @@ -143,7 +143,7 @@ int git_transport_register( git_transport_cb cb, void *param) { - git_buf prefix = GIT_BUF_INIT; + git_str prefix = GIT_STR_INIT; transport_definition *d, *definition = NULL; size_t i; int error = 0; @@ -151,7 +151,7 @@ int git_transport_register( GIT_ASSERT_ARG(scheme); GIT_ASSERT_ARG(cb); - if ((error = git_buf_printf(&prefix, "%s://", scheme)) < 0) + if ((error = git_str_printf(&prefix, "%s://", scheme)) < 0) goto on_error; git_vector_foreach(&custom_transports, i, d) { @@ -164,7 +164,7 @@ int git_transport_register( definition = git__calloc(1, sizeof(transport_definition)); GIT_ERROR_CHECK_ALLOC(definition); - definition->prefix = git_buf_detach(&prefix); + definition->prefix = git_str_detach(&prefix); definition->fn = cb; definition->param = param; @@ -174,21 +174,21 @@ int git_transport_register( return 0; on_error: - git_buf_dispose(&prefix); + git_str_dispose(&prefix); git__free(definition); return error; } int git_transport_unregister(const char *scheme) { - git_buf prefix = GIT_BUF_INIT; + git_str prefix = GIT_STR_INIT; transport_definition *d; size_t i; int error = 0; GIT_ASSERT_ARG(scheme); - if ((error = git_buf_printf(&prefix, "%s://", scheme)) < 0) + if ((error = git_str_printf(&prefix, "%s://", scheme)) < 0) goto done; git_vector_foreach(&custom_transports, i, d) { @@ -210,7 +210,7 @@ int git_transport_unregister(const char *scheme) error = GIT_ENOTFOUND; done: - git_buf_dispose(&prefix); + git_str_dispose(&prefix); return error; } diff --git a/src/transports/auth.c b/src/transports/auth.c index 51763e35926..90b6b124f0e 100644 --- a/src/transports/auth.c +++ b/src/transports/auth.c @@ -7,17 +7,15 @@ #include "auth.h" -#include "git2.h" -#include "buffer.h" #include "git2/sys/credential.h" static int basic_next_token( - git_buf *out, + git_str *out, git_http_auth_context *ctx, git_credential *c) { git_credential_userpass_plaintext *cred; - git_buf raw = GIT_BUF_INIT; + git_str raw = GIT_STR_INIT; int error = GIT_EAUTH; GIT_UNUSED(ctx); @@ -29,11 +27,11 @@ static int basic_next_token( cred = (git_credential_userpass_plaintext *)c; - git_buf_printf(&raw, "%s:%s", cred->username, cred->password); + git_str_printf(&raw, "%s:%s", cred->username, cred->password); - if (git_buf_oom(&raw) || - git_buf_puts(out, "Basic ") < 0 || - git_buf_encode_base64(out, git_buf_cstr(&raw), raw.size) < 0) + if (git_str_oom(&raw) || + git_str_puts(out, "Basic ") < 0 || + git_str_encode_base64(out, git_str_cstr(&raw), raw.size) < 0) goto on_error; error = 0; @@ -42,7 +40,7 @@ static int basic_next_token( if (raw.size) git__memzero(raw.ptr, raw.size); - git_buf_dispose(&raw); + git_str_dispose(&raw); return error; } diff --git a/src/transports/auth.h b/src/transports/auth.h index 9caac4676fc..824d7198cfc 100644 --- a/src/transports/auth.h +++ b/src/transports/auth.h @@ -10,7 +10,6 @@ #include "common.h" -#include "git2.h" #include "netops.h" typedef enum { @@ -35,7 +34,7 @@ struct git_http_auth_context { int (*set_challenge)(git_http_auth_context *ctx, const char *challenge); /** Gets the next authentication token from the context */ - int (*next_token)(git_buf *out, git_http_auth_context *ctx, git_credential *cred); + int (*next_token)(git_str *out, git_http_auth_context *ctx, git_credential *cred); /** Examines if all tokens have been presented. */ int (*is_complete)(git_http_auth_context *ctx); diff --git a/src/transports/auth_negotiate.c b/src/transports/auth_negotiate.c index 31469933e74..6380504be7e 100644 --- a/src/transports/auth_negotiate.c +++ b/src/transports/auth_negotiate.c @@ -10,7 +10,6 @@ #if defined(GIT_GSSAPI) || defined(GIT_GSSFRAMEWORK) #include "git2.h" -#include "buffer.h" #include "auth.h" #include "git2/sys/credential.h" @@ -33,7 +32,7 @@ typedef struct { git_http_auth_context parent; unsigned configured : 1, complete : 1; - git_buf target; + git_str target; char *challenge; gss_ctx_id_t gss_context; gss_OID oid; @@ -87,14 +86,14 @@ static void negotiate_context_dispose(http_auth_negotiate_context *ctx) ctx->gss_context = GSS_C_NO_CONTEXT; } - git_buf_dispose(&ctx->target); + git_str_dispose(&ctx->target); git__free(ctx->challenge); ctx->challenge = NULL; } static int negotiate_next_token( - git_buf *buf, + git_str *buf, git_http_auth_context *c, git_credential *cred) { @@ -104,7 +103,7 @@ static int negotiate_next_token( input_token = GSS_C_EMPTY_BUFFER, output_token = GSS_C_EMPTY_BUFFER; gss_buffer_t input_token_ptr = GSS_C_NO_BUFFER; - git_buf input_buf = GIT_BUF_INIT; + git_str input_buf = GIT_STR_INIT; gss_name_t server = NULL; gss_OID mech; size_t challenge_len; @@ -142,7 +141,7 @@ static int negotiate_next_token( } if (challenge_len > 9) { - if (git_buf_decode_base64(&input_buf, + if (git_str_decode_base64(&input_buf, ctx->challenge + 10, challenge_len - 10) < 0) { git_error_set(GIT_ERROR_NET, "invalid negotiate challenge from server"); error = -1; @@ -192,16 +191,16 @@ static int negotiate_next_token( goto done; } - git_buf_puts(buf, "Negotiate "); - git_buf_encode_base64(buf, output_token.value, output_token.length); + git_str_puts(buf, "Negotiate "); + git_str_encode_base64(buf, output_token.value, output_token.length); - if (git_buf_oom(buf)) + if (git_str_oom(buf)) error = -1; done: gss_release_name(&status_minor, &server); gss_release_buffer(&status_minor, (gss_buffer_t) &output_token); - git_buf_dispose(&input_buf); + git_str_dispose(&input_buf); return error; } @@ -270,10 +269,10 @@ static int negotiate_init_context( return GIT_EAUTH; } - git_buf_puts(&ctx->target, "HTTP@"); - git_buf_puts(&ctx->target, url->host); + git_str_puts(&ctx->target, "HTTP@"); + git_str_puts(&ctx->target, url->host); - if (git_buf_oom(&ctx->target)) + if (git_str_oom(&ctx->target)) return -1; ctx->gss_context = GSS_C_NO_CONTEXT; diff --git a/src/transports/auth_ntlm.c b/src/transports/auth_ntlm.c index 742db75b3d3..f49ce101a56 100644 --- a/src/transports/auth_ntlm.c +++ b/src/transports/auth_ntlm.c @@ -5,11 +5,11 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "git2.h" +#include "auth_ntlm.h" + #include "common.h" -#include "buffer.h" +#include "str.h" #include "auth.h" -#include "auth_ntlm.h" #include "git2/sys/credential.h" #ifdef GIT_NTLM @@ -77,12 +77,12 @@ static int ntlm_set_credentials(http_auth_ntlm_context *ctx, git_credential *_cr } static int ntlm_next_token( - git_buf *buf, + git_str *buf, git_http_auth_context *c, git_credential *cred) { http_auth_ntlm_context *ctx = (http_auth_ntlm_context *)c; - git_buf input_buf = GIT_BUF_INIT; + git_str input_buf = GIT_STR_INIT; const unsigned char *msg; size_t challenge_len, msg_len; int error = GIT_EAUTH; @@ -129,7 +129,7 @@ static int ntlm_next_token( goto done; } - if (git_buf_decode_base64(&input_buf, + if (git_str_decode_base64(&input_buf, ctx->challenge + 5, challenge_len - 5) < 0) { git_error_set(GIT_ERROR_NET, "invalid NTLM challenge from server"); goto done; @@ -149,16 +149,16 @@ static int ntlm_next_token( } } - git_buf_puts(buf, "NTLM "); - git_buf_encode_base64(buf, (const char *)msg, msg_len); + git_str_puts(buf, "NTLM "); + git_str_encode_base64(buf, (const char *)msg, msg_len); - if (git_buf_oom(buf)) + if (git_str_oom(buf)) goto done; error = 0; done: - git_buf_dispose(&input_buf); + git_str_dispose(&input_buf); return error; } diff --git a/src/transports/auth_ntlm.h b/src/transports/auth_ntlm.h index a7cd6d795dd..40689498cae 100644 --- a/src/transports/auth_ntlm.h +++ b/src/transports/auth_ntlm.h @@ -8,7 +8,6 @@ #ifndef INCLUDE_transports_auth_ntlm_h__ #define INCLUDE_transports_auth_ntlm_h__ -#include "git2.h" #include "auth.h" /* NTLM requires a full request/challenge/response */ diff --git a/src/transports/git.c b/src/transports/git.c index 7c93155a8bf..591e2ab0352 100644 --- a/src/transports/git.c +++ b/src/transports/git.c @@ -7,12 +7,10 @@ #include "common.h" -#include "git2.h" -#include "buffer.h" #include "netops.h" -#include "git2/sys/transport.h" #include "stream.h" #include "streams/socket.h" +#include "git2/sys/transport.h" #define OWNING_SUBTRANSPORT(s) ((git_subtransport *)(s)->parent.subtransport) @@ -39,7 +37,7 @@ typedef struct { * * For example: 0035git-upload-pack /libgit2/libgit2\0host=github.com\0 */ -static int gen_proto(git_buf *request, const char *cmd, const char *url) +static int gen_proto(git_str *request, const char *cmd, const char *url) { char *delim, *repo; char host[] = "host="; @@ -61,13 +59,13 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url) len = 4 + strlen(cmd) + 1 + strlen(repo) + 1 + strlen(host) + (delim - url) + 1; - git_buf_grow(request, len); - git_buf_printf(request, "%04x%s %s%c%s", + git_str_grow(request, len); + git_str_printf(request, "%04x%s %s%c%s", (unsigned int)(len & 0x0FFFF), cmd, repo, 0, host); - git_buf_put(request, url, delim - url); - git_buf_putc(request, '\0'); + git_str_put(request, url, delim - url); + git_str_putc(request, '\0'); - if (git_buf_oom(request)) + if (git_str_oom(request)) return -1; return 0; @@ -75,7 +73,7 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url) static int send_command(git_proto_stream *s) { - git_buf request = GIT_BUF_INIT; + git_str request = GIT_STR_INIT; int error; if ((error = gen_proto(&request, s->cmd, s->url)) < 0) @@ -87,7 +85,7 @@ static int send_command(git_proto_stream *s) s->sent_command = 1; cleanup: - git_buf_dispose(&request); + git_str_dispose(&request); return error; } diff --git a/src/transports/http.c b/src/transports/http.c index 914335aba57..adcb1ac43cd 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -9,13 +9,10 @@ #ifndef GIT_WINHTTP -#include "git2.h" #include "http_parser.h" -#include "buffer.h" #include "net.h" #include "netops.h" #include "remote.h" -#include "git2/sys/credential.h" #include "smart.h" #include "auth.h" #include "http.h" @@ -25,6 +22,7 @@ #include "streams/tls.h" #include "streams/socket.h" #include "httpclient.h" +#include "git2/sys/credential.h" bool git_http__expect_continue = false; diff --git a/src/transports/http.h b/src/transports/http.h index 5c360b88387..8e8e7226ed2 100644 --- a/src/transports/http.h +++ b/src/transports/http.h @@ -8,7 +8,6 @@ #ifndef INCLUDE_transports_http_h__ #define INCLUDE_transports_http_h__ -#include "buffer.h" #include "settings.h" #include "httpclient.h" @@ -16,14 +15,14 @@ extern bool git_http__expect_continue; -GIT_INLINE(int) git_http__user_agent(git_buf *buf) +GIT_INLINE(int) git_http__user_agent(git_str *buf) { const char *ua = git_libgit2__user_agent(); if (!ua) ua = "libgit2 " LIBGIT2_VERSION; - return git_buf_printf(buf, "git/2.0 (%s)", ua); + return git_str_printf(buf, "git/2.0 (%s)", ua); } #endif diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index 5b8949a04dd..75782da82f9 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -84,8 +84,8 @@ typedef struct { git_http_response *response; /* Temporary buffers to avoid extra mallocs */ - git_buf parse_header_name; - git_buf parse_header_value; + git_str parse_header_name; + git_str parse_header_value; /* Parser state */ int error; @@ -120,8 +120,8 @@ struct git_http_client { request_chunked : 1; /* Temporary buffers to avoid extra mallocs */ - git_buf request_msg; - git_buf read_buf; + git_str request_msg; + git_str read_buf; /* A subset of information from the request */ size_t request_body_len, @@ -160,8 +160,8 @@ static int on_header_complete(http_parser *parser) git_http_client *client = ctx->client; git_http_response *response = ctx->response; - git_buf *name = &ctx->parse_header_name; - git_buf *value = &ctx->parse_header_value; + git_str *name = &ctx->parse_header_name; + git_str *value = &ctx->parse_header_value; if (!strcasecmp("Content-Type", name->ptr)) { if (response->content_type) { @@ -193,7 +193,7 @@ static int on_header_complete(http_parser *parser) } else if (!strcasecmp("Transfer-Encoding", name->ptr) && !strcasecmp("chunked", value->ptr)) { ctx->response->chunked = 1; - } else if (!strcasecmp("Proxy-Authenticate", git_buf_cstr(name))) { + } else if (!strcasecmp("Proxy-Authenticate", git_str_cstr(name))) { char *dup = git__strndup(value->ptr, value->size); GIT_ERROR_CHECK_ALLOC(dup); @@ -232,15 +232,15 @@ static int on_header_field(http_parser *parser, const char *str, size_t len) if (on_header_complete(parser) < 0) return ctx->parse_status = PARSE_STATUS_ERROR; - git_buf_clear(&ctx->parse_header_name); - git_buf_clear(&ctx->parse_header_value); + git_str_clear(&ctx->parse_header_name); + git_str_clear(&ctx->parse_header_value); /* Fall through */ case PARSE_HEADER_NONE: case PARSE_HEADER_NAME: ctx->parse_header_state = PARSE_HEADER_NAME; - if (git_buf_put(&ctx->parse_header_name, str, len) < 0) + if (git_str_put(&ctx->parse_header_name, str, len) < 0) return ctx->parse_status = PARSE_STATUS_ERROR; break; @@ -263,7 +263,7 @@ static int on_header_value(http_parser *parser, const char *str, size_t len) case PARSE_HEADER_VALUE: ctx->parse_header_state = PARSE_HEADER_VALUE; - if (git_buf_put(&ctx->parse_header_value, str, len) < 0) + if (git_str_put(&ctx->parse_header_value, str, len) < 0) return ctx->parse_status = PARSE_STATUS_ERROR; break; @@ -548,7 +548,7 @@ static void free_auth_context(git_http_server *server) } static int apply_credentials( - git_buf *buf, + git_str *buf, git_http_server *server, const char *header_name, git_credential *credentials) @@ -556,7 +556,7 @@ static int apply_credentials( git_http_auth_context *auth = server->auth_context; git_vector *challenges = &server->auth_challenges; const char *challenge; - git_buf token = GIT_BUF_INIT; + git_str token = GIT_STR_INIT; int error = 0; /* We've started a new request without creds; free the context. */ @@ -602,15 +602,15 @@ static int apply_credentials( } if (token.size > 0) - error = git_buf_printf(buf, "%s: %s\r\n", header_name, token.ptr); + error = git_str_printf(buf, "%s: %s\r\n", header_name, token.ptr); done: - git_buf_dispose(&token); + git_str_dispose(&token); return error; } GIT_INLINE(int) apply_server_credentials( - git_buf *buf, + git_str *buf, git_http_client *client, git_http_request *request) { @@ -621,7 +621,7 @@ GIT_INLINE(int) apply_server_credentials( } GIT_INLINE(int) apply_proxy_credentials( - git_buf *buf, + git_str *buf, git_http_client *client, git_http_request *request) { @@ -631,54 +631,54 @@ GIT_INLINE(int) apply_proxy_credentials( request->proxy_credentials); } -static int puts_host_and_port(git_buf *buf, git_net_url *url, bool force_port) +static int puts_host_and_port(git_str *buf, git_net_url *url, bool force_port) { bool ipv6 = git_net_url_is_ipv6(url); if (ipv6) - git_buf_putc(buf, '['); + git_str_putc(buf, '['); - git_buf_puts(buf, url->host); + git_str_puts(buf, url->host); if (ipv6) - git_buf_putc(buf, ']'); + git_str_putc(buf, ']'); if (force_port || !git_net_url_is_default_port(url)) { - git_buf_putc(buf, ':'); - git_buf_puts(buf, url->port); + git_str_putc(buf, ':'); + git_str_puts(buf, url->port); } - return git_buf_oom(buf) ? -1 : 0; + return git_str_oom(buf) ? -1 : 0; } static int generate_connect_request( git_http_client *client, git_http_request *request) { - git_buf *buf; + git_str *buf; int error; - git_buf_clear(&client->request_msg); + git_str_clear(&client->request_msg); buf = &client->request_msg; - git_buf_puts(buf, "CONNECT "); + git_str_puts(buf, "CONNECT "); puts_host_and_port(buf, &client->server.url, true); - git_buf_puts(buf, " HTTP/1.1\r\n"); + git_str_puts(buf, " HTTP/1.1\r\n"); - git_buf_puts(buf, "User-Agent: "); + git_str_puts(buf, "User-Agent: "); git_http__user_agent(buf); - git_buf_puts(buf, "\r\n"); + git_str_puts(buf, "\r\n"); - git_buf_puts(buf, "Host: "); + git_str_puts(buf, "Host: "); puts_host_and_port(buf, &client->server.url, true); - git_buf_puts(buf, "\r\n"); + git_str_puts(buf, "\r\n"); if ((error = apply_proxy_credentials(buf, client, request) < 0)) return -1; - git_buf_puts(buf, "\r\n"); + git_str_puts(buf, "\r\n"); - return git_buf_oom(buf) ? -1 : 0; + return git_str_oom(buf) ? -1 : 0; } static bool use_connect_proxy(git_http_client *client) @@ -690,53 +690,53 @@ static int generate_request( git_http_client *client, git_http_request *request) { - git_buf *buf; + git_str *buf; size_t i; int error; GIT_ASSERT_ARG(client); GIT_ASSERT_ARG(request); - git_buf_clear(&client->request_msg); + git_str_clear(&client->request_msg); buf = &client->request_msg; /* GET|POST path HTTP/1.1 */ - git_buf_puts(buf, name_for_method(request->method)); - git_buf_putc(buf, ' '); + git_str_puts(buf, name_for_method(request->method)); + git_str_putc(buf, ' '); if (request->proxy && strcmp(request->url->scheme, "https")) git_net_url_fmt(buf, request->url); else git_net_url_fmt_path(buf, request->url); - git_buf_puts(buf, " HTTP/1.1\r\n"); + git_str_puts(buf, " HTTP/1.1\r\n"); - git_buf_puts(buf, "User-Agent: "); + git_str_puts(buf, "User-Agent: "); git_http__user_agent(buf); - git_buf_puts(buf, "\r\n"); + git_str_puts(buf, "\r\n"); - git_buf_puts(buf, "Host: "); + git_str_puts(buf, "Host: "); puts_host_and_port(buf, request->url, false); - git_buf_puts(buf, "\r\n"); + git_str_puts(buf, "\r\n"); if (request->accept) - git_buf_printf(buf, "Accept: %s\r\n", request->accept); + git_str_printf(buf, "Accept: %s\r\n", request->accept); else - git_buf_puts(buf, "Accept: */*\r\n"); + git_str_puts(buf, "Accept: */*\r\n"); if (request->content_type) - git_buf_printf(buf, "Content-Type: %s\r\n", + git_str_printf(buf, "Content-Type: %s\r\n", request->content_type); if (request->chunked) - git_buf_puts(buf, "Transfer-Encoding: chunked\r\n"); + git_str_puts(buf, "Transfer-Encoding: chunked\r\n"); if (request->content_length > 0) - git_buf_printf(buf, "Content-Length: %"PRIuZ "\r\n", + git_str_printf(buf, "Content-Length: %"PRIuZ "\r\n", request->content_length); if (request->expect_continue) - git_buf_printf(buf, "Expect: 100-continue\r\n"); + git_str_printf(buf, "Expect: 100-continue\r\n"); if ((error = apply_server_credentials(buf, client, request)) < 0 || (!use_connect_proxy(client) && @@ -748,13 +748,13 @@ static int generate_request( const char *hdr = request->custom_headers->strings[i]; if (hdr) - git_buf_printf(buf, "%s\r\n", hdr); + git_str_printf(buf, "%s\r\n", hdr); } } - git_buf_puts(buf, "\r\n"); + git_str_puts(buf, "\r\n"); - if (git_buf_oom(buf)) + if (git_str_oom(buf)) return -1; return 0; @@ -1077,7 +1077,7 @@ GIT_INLINE(int) client_read(git_http_client *client) client->proxy.stream : client->server.stream; /* - * We use a git_buf for convenience, but statically allocate it and + * We use a git_str for convenience, but statically allocate it and * don't resize. Limit our consumption to INT_MAX since calling * functions use an int return type to return number of bytes read. */ @@ -1198,7 +1198,7 @@ GIT_INLINE(int) client_read_and_parse(git_http_client *client) return -1; } - git_buf_consume_bytes(&client->read_buf, parsed_len); + git_str_consume_bytes(&client->read_buf, parsed_len); return (int)parsed_len; } @@ -1235,7 +1235,7 @@ static void complete_response_body(git_http_client *client) } done: - git_buf_clear(&client->read_buf); + git_str_clear(&client->read_buf); } int git_http_client_send_request( @@ -1257,12 +1257,12 @@ int git_http_client_send_request( return 0; if (git_trace_level() >= GIT_TRACE_DEBUG) { - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; git_net_url_fmt(&url, request->url); git_trace(GIT_TRACE_DEBUG, "Sending %s request to %s", name_for_method(request->method), url.ptr ? url.ptr : ""); - git_buf_dispose(&url); + git_str_dispose(&url); } if ((error = http_client_connect(client, request)) < 0 || @@ -1314,7 +1314,7 @@ int git_http_client_send_body( size_t buffer_len) { git_http_server *server; - git_buf hdr = GIT_BUF_INIT; + git_str hdr = GIT_STR_INIT; int error; GIT_ASSERT_ARG(client); @@ -1341,7 +1341,7 @@ int git_http_client_send_body( client->request_body_remain -= buffer_len; } else { - if ((error = git_buf_printf(&hdr, "%" PRIxZ "\r\n", buffer_len)) < 0 || + if ((error = git_str_printf(&hdr, "%" PRIxZ "\r\n", buffer_len)) < 0 || (error = stream_write(server, hdr.ptr, hdr.size)) < 0 || (error = stream_write(server, buffer, buffer_len)) < 0 || (error = stream_write(server, "\r\n", 2)) < 0) @@ -1349,7 +1349,7 @@ int git_http_client_send_body( } done: - git_buf_dispose(&hdr); + git_str_dispose(&hdr); return error; } @@ -1422,8 +1422,8 @@ int git_http_client_read_response( GIT_ASSERT(client->state == READING_BODY || client->state == DONE); done: - git_buf_dispose(&parser_context.parse_header_name); - git_buf_dispose(&parser_context.parse_header_value); + git_str_dispose(&parser_context.parse_header_name); + git_str_dispose(&parser_context.parse_header_value); return error; } @@ -1531,7 +1531,7 @@ int git_http_client_new( client = git__calloc(1, sizeof(git_http_client)); GIT_ERROR_CHECK_ALLOC(client); - git_buf_init(&client->read_buf, GIT_READ_BUFFER_SIZE); + git_str_init(&client->read_buf, GIT_READ_BUFFER_SIZE); GIT_ERROR_CHECK_ALLOC(client->read_buf.ptr); if (opts) @@ -1560,7 +1560,7 @@ static void http_client_close(git_http_client *client) http_server_close(&client->server); http_server_close(&client->proxy); - git_buf_dispose(&client->request_msg); + git_str_dispose(&client->request_msg); client->state = 0; client->request_count = 0; @@ -1574,6 +1574,6 @@ void git_http_client_free(git_http_client *client) return; http_client_close(client); - git_buf_dispose(&client->read_buf); + git_str_dispose(&client->read_buf); git__free(client); } diff --git a/src/transports/local.c b/src/transports/local.c index bb31b134580..0656ea592df 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -7,6 +7,16 @@ #include "common.h" +#include "pack-objects.h" +#include "refs.h" +#include "posix.h" +#include "path.h" +#include "repository.h" +#include "odb.h" +#include "push.h" +#include "remote.h" +#include "proxy.h" + #include "git2/types.h" #include "git2/net.h" #include "git2/repository.h" @@ -19,17 +29,6 @@ #include "git2/commit.h" #include "git2/revparse.h" -#include "pack-objects.h" -#include "refs.h" -#include "posix.h" -#include "path.h" -#include "buffer.h" -#include "repository.h" -#include "odb.h" -#include "push.h" -#include "remote.h" -#include "proxy.h" - typedef struct { git_transport parent; git_remote *owner; @@ -71,7 +70,7 @@ static int add_ref(transport_local *t, const char *name) git_remote_head *head; git_oid obj_id; git_object *obj = NULL, *target = NULL; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error; if ((error = git_reference_lookup(&ref, t->repo, name)) < 0) @@ -132,11 +131,11 @@ static int add_ref(transport_local *t, const char *name) head = git__calloc(1, sizeof(git_remote_head)); GIT_ERROR_CHECK_ALLOC(head); - if (git_buf_join(&buf, 0, name, peeled) < 0) { + if (git_str_join(&buf, 0, name, peeled) < 0) { free_head(head); return -1; } - head->name = git_buf_detach(&buf); + head->name = git_str_detach(&buf); if (!(error = git_tag_peel(&target, (git_tag *)obj))) { git_oid_cpy(&head->oid, git_object_id(target)); @@ -210,7 +209,7 @@ static int local_connect( int error; transport_local *t = (transport_local *) transport; const char *path; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; GIT_UNUSED(cred_acquire_cb); GIT_UNUSED(cred_acquire_payload); @@ -228,14 +227,14 @@ static int local_connect( /* 'url' may be a url or path; convert to a path */ if ((error = git_path_from_url_or_path(&buf, url)) < 0) { - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } - path = git_buf_cstr(&buf); + path = git_str_cstr(&buf); error = git_repository_open(&repo, path); - git_buf_dispose(&buf); + git_str_dispose(&buf); if (error < 0) return -1; @@ -346,7 +345,7 @@ static int local_push( push_spec *spec; char *url = NULL; const char *path; - git_buf buf = GIT_BUF_INIT, odb_path = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT, odb_path = GIT_STR_INIT; int error; size_t j; @@ -354,14 +353,14 @@ static int local_push( /* 'push->remote->url' may be a url or path; convert to a path */ if ((error = git_path_from_url_or_path(&buf, push->remote->url)) < 0) { - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } - path = git_buf_cstr(&buf); + path = git_str_cstr(&buf); error = git_repository_open(&remote_repo, path); - git_buf_dispose(&buf); + git_str_dispose(&buf); if (error < 0) return error; @@ -378,12 +377,12 @@ static int local_push( goto on_error; } - if ((error = git_repository_item_path(&odb_path, remote_repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0 - || (error = git_buf_joinpath(&odb_path, odb_path.ptr, "pack")) < 0) + if ((error = git_repository__item_path(&odb_path, remote_repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0 + || (error = git_str_joinpath(&odb_path, odb_path.ptr, "pack")) < 0) goto on_error; error = git_packbuilder_write(push->pb, odb_path.ptr, 0, transfer_to_push_transfer, (void *) cbs); - git_buf_dispose(&odb_path); + git_str_dispose(&odb_path); if (error < 0) goto on_error; @@ -479,7 +478,7 @@ static const char *compressing_objects_fmt = "Compressing objects: %.0f%% (%d/%d static int local_counting(int stage, unsigned int current, unsigned int total, void *payload) { - git_buf progress_info = GIT_BUF_INIT; + git_str progress_info = GIT_STR_INIT; transport_local *t = payload; int error; @@ -487,22 +486,22 @@ static int local_counting(int stage, unsigned int current, unsigned int total, v return 0; if (stage == GIT_PACKBUILDER_ADDING_OBJECTS) { - git_buf_printf(&progress_info, counting_objects_fmt, current); + git_str_printf(&progress_info, counting_objects_fmt, current); } else if (stage == GIT_PACKBUILDER_DELTAFICATION) { float perc = (((float) current) / total) * 100; - git_buf_printf(&progress_info, compressing_objects_fmt, perc, current, total); + git_str_printf(&progress_info, compressing_objects_fmt, perc, current, total); if (current == total) - git_buf_printf(&progress_info, ", done\n"); + git_str_printf(&progress_info, ", done\n"); else - git_buf_putc(&progress_info, '\r'); + git_str_putc(&progress_info, '\r'); } - if (git_buf_oom(&progress_info)) + if (git_str_oom(&progress_info)) return -1; - error = t->progress_cb(git_buf_cstr(&progress_info), (int)git_buf_len(&progress_info), t->message_cb_payload); - git_buf_dispose(&progress_info); + error = t->progress_cb(git_str_cstr(&progress_info), (int)git_str_len(&progress_info), t->message_cb_payload); + git_str_dispose(&progress_info); return error; } @@ -545,7 +544,7 @@ static int local_download_pack( git_packbuilder *pack = NULL; git_odb_writepack *writepack = NULL; git_odb *odb = NULL; - git_buf progress_info = GIT_BUF_INIT; + git_str progress_info = GIT_STR_INIT; if ((error = git_revwalk_new(&walk, t->repo)) < 0) goto cleanup; @@ -584,11 +583,11 @@ static int local_download_pack( if ((error = git_packbuilder_insert_walk(pack, walk))) goto cleanup; - if ((error = git_buf_printf(&progress_info, counting_objects_fmt, git_packbuilder_object_count(pack))) < 0) + if ((error = git_str_printf(&progress_info, counting_objects_fmt, git_packbuilder_object_count(pack))) < 0) goto cleanup; if (t->progress_cb && - (error = t->progress_cb(git_buf_cstr(&progress_info), (int)git_buf_len(&progress_info), t->message_cb_payload)) < 0) + (error = t->progress_cb(git_str_cstr(&progress_info), (int)git_str_len(&progress_info), t->message_cb_payload)) < 0) goto cleanup; /* Walk the objects, building a packfile */ @@ -596,13 +595,13 @@ static int local_download_pack( goto cleanup; /* One last one with the newline */ - git_buf_clear(&progress_info); - git_buf_printf(&progress_info, counting_objects_fmt, git_packbuilder_object_count(pack)); - if ((error = git_buf_putc(&progress_info, '\n')) < 0) + git_str_clear(&progress_info); + git_str_printf(&progress_info, counting_objects_fmt, git_packbuilder_object_count(pack)); + if ((error = git_str_putc(&progress_info, '\n')) < 0) goto cleanup; if (t->progress_cb && - (error = t->progress_cb(git_buf_cstr(&progress_info), (int)git_buf_len(&progress_info), t->message_cb_payload)) < 0) + (error = t->progress_cb(git_str_cstr(&progress_info), (int)git_str_len(&progress_info), t->message_cb_payload)) < 0) goto cleanup; if ((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) != 0) @@ -627,7 +626,7 @@ static int local_download_pack( cleanup: if (writepack) writepack->free(writepack); - git_buf_dispose(&progress_info); + git_str_dispose(&progress_info); git_packbuilder_free(pack); git_revwalk_free(walk); return error; diff --git a/src/transports/smart.c b/src/transports/smart.c index 587f1435889..fe024de2fd5 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -164,20 +164,20 @@ int git_smart__update_heads(transport_smart *t, git_vector *symrefs) if (symrefs) { git_refspec *spec; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; size_t j; int error = 0; git_vector_foreach(symrefs, j, spec) { - git_buf_clear(&buf); + git_str_clear(&buf); if (git_refspec_src_matches(spec, ref->head.name) && - !(error = git_refspec_transform(&buf, spec, ref->head.name))) { + !(error = git_refspec__transform(&buf, spec, ref->head.name))) { git__free(ref->head.symref_target); - ref->head.symref_target = git_buf_detach(&buf); + ref->head.symref_target = git_str_detach(&buf); } } - git_buf_dispose(&buf); + git_str_dispose(&buf); if (error < 0) return error; diff --git a/src/transports/smart.h b/src/transports/smart.h index a05d4c9e3a2..225e64996c7 100644 --- a/src/transports/smart.h +++ b/src/transports/smart.h @@ -12,8 +12,8 @@ #include "git2.h" #include "vector.h" #include "netops.h" -#include "buffer.h" #include "push.h" +#include "str.h" #include "git2/sys/transport.h" #define GIT_SIDE_BAND_DATA 1 @@ -189,11 +189,11 @@ int git_smart__update_heads(transport_smart *t, git_vector *symrefs); /* smart_pkt.c */ int git_pkt_parse_line(git_pkt **head, const char **endptr, const char *line, size_t linelen); -int git_pkt_buffer_flush(git_buf *buf); +int git_pkt_buffer_flush(git_str *buf); int git_pkt_send_flush(GIT_SOCKET s); -int git_pkt_buffer_done(git_buf *buf); -int git_pkt_buffer_wants(const git_remote_head * const *refs, size_t count, transport_smart_caps *caps, git_buf *buf); -int git_pkt_buffer_have(git_oid *oid, git_buf *buf); +int git_pkt_buffer_done(git_str *buf); +int git_pkt_buffer_wants(const git_remote_head * const *refs, size_t count, transport_smart_caps *caps, git_str *buf); +int git_pkt_buffer_have(git_oid *oid, git_str *buf); void git_pkt_free(git_pkt *pkt); #endif diff --git a/src/transports/smart_pkt.c b/src/transports/smart_pkt.c index 56b680d281e..b42edd0d6e5 100644 --- a/src/transports/smart_pkt.c +++ b/src/transports/smart_pkt.c @@ -7,16 +7,16 @@ #include "common.h" -#include "git2/types.h" -#include "git2/errors.h" -#include "git2/refs.h" -#include "git2/revwalk.h" - #include "smart.h" #include "util.h" #include "netops.h" #include "posix.h" -#include "buffer.h" +#include "str.h" + +#include "git2/types.h" +#include "git2/errors.h" +#include "git2/refs.h" +#include "git2/revwalk.h" #include @@ -522,43 +522,43 @@ void git_pkt_free(git_pkt *pkt) git__free(pkt); } -int git_pkt_buffer_flush(git_buf *buf) +int git_pkt_buffer_flush(git_str *buf) { - return git_buf_put(buf, pkt_flush_str, strlen(pkt_flush_str)); + return git_str_put(buf, pkt_flush_str, strlen(pkt_flush_str)); } -static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_buf *buf) +static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_str *buf) { - git_buf str = GIT_BUF_INIT; + git_str str = GIT_STR_INIT; char oid[GIT_OID_HEXSZ +1] = {0}; size_t len; /* Prefer multi_ack_detailed */ if (caps->multi_ack_detailed) - git_buf_puts(&str, GIT_CAP_MULTI_ACK_DETAILED " "); + git_str_puts(&str, GIT_CAP_MULTI_ACK_DETAILED " "); else if (caps->multi_ack) - git_buf_puts(&str, GIT_CAP_MULTI_ACK " "); + git_str_puts(&str, GIT_CAP_MULTI_ACK " "); /* Prefer side-band-64k if the server supports both */ if (caps->side_band_64k) - git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND_64K); + git_str_printf(&str, "%s ", GIT_CAP_SIDE_BAND_64K); else if (caps->side_band) - git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND); + git_str_printf(&str, "%s ", GIT_CAP_SIDE_BAND); if (caps->include_tag) - git_buf_puts(&str, GIT_CAP_INCLUDE_TAG " "); + git_str_puts(&str, GIT_CAP_INCLUDE_TAG " "); if (caps->thin_pack) - git_buf_puts(&str, GIT_CAP_THIN_PACK " "); + git_str_puts(&str, GIT_CAP_THIN_PACK " "); if (caps->ofs_delta) - git_buf_puts(&str, GIT_CAP_OFS_DELTA " "); + git_str_puts(&str, GIT_CAP_OFS_DELTA " "); - if (git_buf_oom(&str)) + if (git_str_oom(&str)) return -1; len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + - git_buf_len(&str) + 1 /* LF */; + git_str_len(&str) + 1 /* LF */; if (len > 0xffff) { git_error_set(GIT_ERROR_NET, @@ -566,13 +566,13 @@ static int buffer_want_with_caps(const git_remote_head *head, transport_smart_ca return -1; } - git_buf_grow_by(buf, len); + git_str_grow_by(buf, len); git_oid_fmt(oid, &head->oid); - git_buf_printf(buf, - "%04xwant %s %s\n", (unsigned int)len, oid, git_buf_cstr(&str)); - git_buf_dispose(&str); + git_str_printf(buf, + "%04xwant %s %s\n", (unsigned int)len, oid, git_str_cstr(&str)); + git_str_dispose(&str); - GIT_ERROR_CHECK_ALLOC_BUF(buf); + GIT_ERROR_CHECK_ALLOC_STR(buf); return 0; } @@ -586,7 +586,7 @@ int git_pkt_buffer_wants( const git_remote_head * const *refs, size_t count, transport_smart_caps *caps, - git_buf *buf) + git_str *buf) { size_t i = 0; const git_remote_head *head; @@ -612,26 +612,26 @@ int git_pkt_buffer_wants( continue; git_oid_fmt(oid, &head->oid); - git_buf_put(buf, pkt_want_prefix, strlen(pkt_want_prefix)); - git_buf_put(buf, oid, GIT_OID_HEXSZ); - git_buf_putc(buf, '\n'); - if (git_buf_oom(buf)) + git_str_put(buf, pkt_want_prefix, strlen(pkt_want_prefix)); + git_str_put(buf, oid, GIT_OID_HEXSZ); + git_str_putc(buf, '\n'); + if (git_str_oom(buf)) return -1; } return git_pkt_buffer_flush(buf); } -int git_pkt_buffer_have(git_oid *oid, git_buf *buf) +int git_pkt_buffer_have(git_oid *oid, git_str *buf) { char oidhex[GIT_OID_HEXSZ + 1]; memset(oidhex, 0x0, sizeof(oidhex)); git_oid_fmt(oidhex, oid); - return git_buf_printf(buf, "%s%s\n", pkt_have_prefix, oidhex); + return git_str_printf(buf, "%s%s\n", pkt_have_prefix, oidhex); } -int git_pkt_buffer_done(git_buf *buf) +int git_pkt_buffer_done(git_str *buf) { - return git_buf_puts(buf, pkt_done_str); + return git_str_puts(buf, pkt_done_str); } diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 91de163e91f..a9a623cc7df 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -89,7 +89,7 @@ static int append_symref(const char **out, git_vector *symrefs, const char *ptr) { int error; const char *end; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_refspec *mapping = NULL; ptr += strlen(GIT_CAP_SYMREF); @@ -101,15 +101,15 @@ static int append_symref(const char **out, git_vector *symrefs, const char *ptr) !(end = strchr(ptr, '\0'))) goto on_invalid; - if ((error = git_buf_put(&buf, ptr, end - ptr)) < 0) + if ((error = git_str_put(&buf, ptr, end - ptr)) < 0) return error; /* symref mapping has refspec format */ mapping = git__calloc(1, sizeof(git_refspec)); GIT_ERROR_CHECK_ALLOC(mapping); - error = git_refspec__parse(mapping, git_buf_cstr(&buf), true); - git_buf_dispose(&buf); + error = git_refspec__parse(mapping, git_str_cstr(&buf), true); + git_str_dispose(&buf); /* if the error isn't OOM, then it's a parse error; let's use a nicer message */ if (error < 0) { @@ -310,7 +310,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c transport_smart *t = (transport_smart *)transport; git_revwalk__push_options opts = GIT_REVWALK__PUSH_OPTIONS_INIT; gitno_buffer *buf = &t->buffer; - git_buf data = GIT_BUF_INIT; + git_str data = GIT_STR_INIT; git_revwalk *walk = NULL; int error = -1; git_pkt_type pkt_type; @@ -354,7 +354,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c } git_pkt_buffer_flush(&data); - if (git_buf_oom(&data)) { + if (git_str_oom(&data)) { error = -1; goto on_error; } @@ -362,7 +362,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; - git_buf_clear(&data); + git_str_clear(&data); if (t->caps.multi_ack || t->caps.multi_ack_detailed) { if ((error = store_common(t)) < 0) goto on_error; @@ -397,7 +397,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c goto on_error; } - if (git_buf_oom(&data)) { + if (git_str_oom(&data)) { error = -1; goto on_error; } @@ -417,7 +417,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c goto on_error; } - if (git_buf_oom(&data)) { + if (git_str_oom(&data)) { error = -1; goto on_error; } @@ -434,7 +434,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; - git_buf_dispose(&data); + git_str_dispose(&data); git_revwalk_free(walk); /* Now let's eat up whatever the server gives us */ @@ -454,7 +454,7 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c on_error: git_revwalk_free(walk); - git_buf_dispose(&data); + git_str_dispose(&data); return error; } @@ -626,7 +626,7 @@ int git_smart__download_pack( return error; } -static int gen_pktline(git_buf *buf, git_push *push) +static int gen_pktline(git_str *buf, git_push *push) { push_spec *spec; size_t i, len; @@ -647,24 +647,24 @@ static int gen_pktline(git_buf *buf, git_push *push) git_oid_fmt(old_id, &spec->roid); git_oid_fmt(new_id, &spec->loid); - git_buf_printf(buf, "%04"PRIxZ"%s %s %s", len, old_id, new_id, spec->refspec.dst); + git_str_printf(buf, "%04"PRIxZ"%s %s %s", len, old_id, new_id, spec->refspec.dst); if (i == 0) { - git_buf_putc(buf, '\0'); + git_str_putc(buf, '\0'); /* Core git always starts their capabilities string with a space */ if (push->report_status) { - git_buf_putc(buf, ' '); - git_buf_printf(buf, GIT_CAP_REPORT_STATUS); + git_str_putc(buf, ' '); + git_str_printf(buf, GIT_CAP_REPORT_STATUS); } - git_buf_putc(buf, ' '); - git_buf_printf(buf, GIT_CAP_SIDE_BAND_64K); + git_str_putc(buf, ' '); + git_str_printf(buf, GIT_CAP_SIDE_BAND_64K); } - git_buf_putc(buf, '\n'); + git_str_putc(buf, '\n'); } - git_buf_puts(buf, "0000"); - return git_buf_oom(buf) ? -1 : 0; + git_str_puts(buf, "0000"); + return git_str_oom(buf) ? -1 : 0; } static int add_push_report_pkt(git_push *push, git_pkt *pkt) @@ -707,7 +707,7 @@ static int add_push_report_pkt(git_push *push, git_pkt *pkt) return 0; } -static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, git_buf *data_pkt_buf) +static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, git_str *data_pkt_buf) { git_pkt *pkt; const char *line, *line_end = NULL; @@ -718,7 +718,7 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, if (reading_from_buf) { /* We had an existing partial packet, so add the new * packet to the buffer and parse the whole thing */ - git_buf_put(data_pkt_buf, data_pkt->data, data_pkt->len); + git_str_put(data_pkt_buf, data_pkt->data, data_pkt->len); line = data_pkt_buf->ptr; line_len = data_pkt_buf->size; } @@ -734,7 +734,7 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, /* Buffer the data when the inner packet is split * across multiple sideband packets */ if (!reading_from_buf) - git_buf_put(data_pkt_buf, line, line_len); + git_str_put(data_pkt_buf, line, line_len); error = 0; goto done; } @@ -757,7 +757,7 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, done: if (reading_from_buf) - git_buf_consume(data_pkt_buf, line_end); + git_str_consume(data_pkt_buf, line_end); return error; } @@ -767,7 +767,7 @@ static int parse_report(transport_smart *transport, git_push *push) const char *line_end = NULL; gitno_buffer *buf = &transport->buffer; int error, recvd; - git_buf data_pkt_buf = GIT_BUF_INIT; + git_str data_pkt_buf = GIT_STR_INIT; for (;;) { if (buf->offset > 0) @@ -847,7 +847,7 @@ static int parse_report(transport_smart *transport, git_push *push) } } done: - git_buf_dispose(&data_pkt_buf); + git_str_dispose(&data_pkt_buf); return error; } @@ -991,7 +991,7 @@ int git_smart__push(git_transport *transport, git_push *push, const git_remote_c { transport_smart *t = (transport_smart *)transport; struct push_packbuilder_payload packbuilder_payload = {0}; - git_buf pktline = GIT_BUF_INIT; + git_str pktline = GIT_STR_INIT; int error = 0, need_pack = 0; push_spec *spec; unsigned int i; @@ -1036,7 +1036,7 @@ int git_smart__push(git_transport *transport, git_push *push, const git_remote_c if ((error = git_smart__get_push_stream(t, &packbuilder_payload.stream)) < 0 || (error = gen_pktline(&pktline, push)) < 0 || - (error = packbuilder_payload.stream->write(packbuilder_payload.stream, git_buf_cstr(&pktline), git_buf_len(&pktline))) < 0) + (error = packbuilder_payload.stream->write(packbuilder_payload.stream, git_str_cstr(&pktline), git_str_len(&pktline))) < 0) goto done; if (need_pack && @@ -1071,6 +1071,6 @@ int git_smart__push(git_transport *transport, git_push *push, const git_remote_c } done: - git_buf_dispose(&pktline); + git_str_dispose(&pktline); return error; } diff --git a/src/transports/ssh.c b/src/transports/ssh.c index 1b00be79cd6..e3bb5eef625 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -12,8 +12,6 @@ #endif #include "runtime.h" -#include "git2.h" -#include "buffer.h" #include "net.h" #include "netops.h" #include "smart.h" @@ -65,7 +63,7 @@ static void ssh_error(LIBSSH2_SESSION *session, const char *errmsg) * * For example: git-upload-pack '/libgit2/libgit2' */ -static int gen_proto(git_buf *request, const char *cmd, const char *url) +static int gen_proto(git_str *request, const char *cmd, const char *url) { const char *repo; int len; @@ -94,13 +92,13 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url) len = strlen(cmd) + 1 /* Space */ + 1 /* Quote */ + strlen(repo) + 1 /* Quote */ + 1; - git_buf_grow(request, len); - git_buf_puts(request, cmd); - git_buf_puts(request, " '"); - git_buf_decode_percent(request, repo, strlen(repo)); - git_buf_puts(request, "'"); + git_str_grow(request, len); + git_str_puts(request, cmd); + git_str_puts(request, " '"); + git_str_decode_percent(request, repo, strlen(repo)); + git_str_puts(request, "'"); - if (git_buf_oom(request)) + if (git_str_oom(request)) return -1; return 0; @@ -109,7 +107,7 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url) static int send_command(ssh_stream *s) { int error; - git_buf request = GIT_BUF_INIT; + git_str request = GIT_STR_INIT; error = gen_proto(&request, s->cmd, s->url); if (error < 0) @@ -124,7 +122,7 @@ static int send_command(ssh_stream *s) s->sent_command = 1; cleanup: - git_buf_dispose(&request); + git_str_dispose(&request); return error; } @@ -580,7 +578,7 @@ static int _git_ssh_setup_conn( case LIBSSH2_HOSTKEY_TYPE_DSS: cert.raw_type = GIT_CERT_SSH_RAW_TYPE_DSS; break; - + #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256 case LIBSSH2_HOSTKEY_TYPE_ECDSA_256: cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256; @@ -592,7 +590,7 @@ static int _git_ssh_setup_conn( cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521; break; #endif - + #ifdef LIBSSH2_HOSTKEY_TYPE_ED25519 case LIBSSH2_HOSTKEY_TYPE_ED25519: cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ED25519; diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index f4801a4516b..efbaf0298a7 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -11,8 +11,8 @@ #include "git2.h" #include "git2/transport.h" -#include "buffer.h" #include "posix.h" +#include "str.h" #include "netops.h" #include "smart.h" #include "remote.h" @@ -372,7 +372,7 @@ static int apply_credentials( static int winhttp_stream_connect(winhttp_stream *s) { winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; char *proxy_url = NULL; wchar_t ct[MAX_CONTENT_TYPE_LEN]; LPCWSTR types[] = { L"*/*", NULL }; @@ -391,13 +391,13 @@ static int winhttp_stream_connect(winhttp_stream *s) if ((git__suffixcmp(t->server.url.path, "/") == 0) && (git__prefixcmp(service_url, "/") == 0)) service_url++; /* Prepare URL */ - git_buf_printf(&buf, "%s%s", t->server.url.path, service_url); + git_str_printf(&buf, "%s%s", t->server.url.path, service_url); - if (git_buf_oom(&buf)) + if (git_str_oom(&buf)) return -1; /* Convert URL to wide characters */ - if (git__utf8_to_16_alloc(&s->request_uri, git_buf_cstr(&buf)) < 0) { + if (git__utf8_to_16_alloc(&s->request_uri, git_str_cstr(&buf)) < 0) { git_error_set(GIT_ERROR_OS, "failed to convert string to wide form"); goto on_error; } @@ -438,7 +438,7 @@ static int winhttp_stream_connect(winhttp_stream *s) } if (proxy_url) { - git_buf processed_url = GIT_BUF_INIT; + git_str processed_url = GIT_STR_INIT; WINHTTP_PROXY_INFO proxy_info; wchar_t *proxy_wide; @@ -453,28 +453,28 @@ static int winhttp_stream_connect(winhttp_stream *s) goto on_error; } - git_buf_puts(&processed_url, t->proxy.url.scheme); - git_buf_PUTS(&processed_url, "://"); + git_str_puts(&processed_url, t->proxy.url.scheme); + git_str_PUTS(&processed_url, "://"); if (git_net_url_is_ipv6(&t->proxy.url)) - git_buf_putc(&processed_url, '['); + git_str_putc(&processed_url, '['); - git_buf_puts(&processed_url, t->proxy.url.host); + git_str_puts(&processed_url, t->proxy.url.host); if (git_net_url_is_ipv6(&t->proxy.url)) - git_buf_putc(&processed_url, ']'); + git_str_putc(&processed_url, ']'); if (!git_net_url_is_default_port(&t->proxy.url)) - git_buf_printf(&processed_url, ":%s", t->proxy.url.port); + git_str_printf(&processed_url, ":%s", t->proxy.url.port); - if (git_buf_oom(&processed_url)) { + if (git_str_oom(&processed_url)) { error = -1; goto on_error; } /* Convert URL to wide characters */ error = git__utf8_to_16_alloc(&proxy_wide, processed_url.ptr); - git_buf_dispose(&processed_url); + git_str_dispose(&processed_url); if (error < 0) goto on_error; @@ -525,13 +525,13 @@ static int winhttp_stream_connect(winhttp_stream *s) if (post_verb == s->verb) { /* Send Content-Type and Accept headers -- only necessary on a POST */ - git_buf_clear(&buf); - if (git_buf_printf(&buf, + git_str_clear(&buf); + if (git_str_printf(&buf, "Content-Type: application/x-git-%s-request", s->service) < 0) goto on_error; - if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { + if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_str_cstr(&buf)) < 0) { git_error_set(GIT_ERROR_OS, "failed to convert content-type to wide characters"); goto on_error; } @@ -542,13 +542,13 @@ static int winhttp_stream_connect(winhttp_stream *s) goto on_error; } - git_buf_clear(&buf); - if (git_buf_printf(&buf, + git_str_clear(&buf); + if (git_str_printf(&buf, "Accept: application/x-git-%s-result", s->service) < 0) goto on_error; - if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { + if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_str_cstr(&buf)) < 0) { git_error_set(GIT_ERROR_OS, "failed to convert accept header to wide characters"); goto on_error; } @@ -562,9 +562,9 @@ static int winhttp_stream_connect(winhttp_stream *s) for (i = 0; i < t->owner->custom_headers.count; i++) { if (t->owner->custom_headers.strings[i]) { - git_buf_clear(&buf); - git_buf_puts(&buf, t->owner->custom_headers.strings[i]); - if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { + git_str_clear(&buf); + git_str_puts(&buf, t->owner->custom_headers.strings[i]); + if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_str_cstr(&buf)) < 0) { git_error_set(GIT_ERROR_OS, "failed to convert custom header to wide characters"); goto on_error; } @@ -597,7 +597,7 @@ static int winhttp_stream_connect(winhttp_stream *s) winhttp_stream_close(s); git__free(proxy_url); - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } @@ -646,23 +646,23 @@ static int parse_unauthorized_response( static int write_chunk(HINTERNET request, const char *buffer, size_t len) { DWORD bytes_written; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; /* Chunk header */ - git_buf_printf(&buf, "%"PRIXZ"\r\n", len); + git_str_printf(&buf, "%"PRIXZ"\r\n", len); - if (git_buf_oom(&buf)) + if (git_str_oom(&buf)) return -1; if (!WinHttpWriteData(request, - git_buf_cstr(&buf), (DWORD)git_buf_len(&buf), + git_str_cstr(&buf), (DWORD)git_str_len(&buf), &bytes_written)) { - git_buf_dispose(&buf); + git_str_dispose(&buf); git_error_set(GIT_ERROR_OS, "failed to write chunk header"); return -1; } - git_buf_dispose(&buf); + git_str_dispose(&buf); /* Chunk body */ if (!WinHttpWriteData(request, @@ -756,7 +756,7 @@ static int winhttp_connect( wchar_t *wide_host = NULL; int32_t port; wchar_t *wide_ua = NULL; - git_buf ipv6 = GIT_BUF_INIT, ua = GIT_BUF_INIT; + git_str ipv6 = GIT_STR_INIT, ua = GIT_STR_INIT; const char *host; int error = -1; int default_timeout = TIMEOUT_INFINITE; @@ -777,7 +777,7 @@ static int winhttp_connect( /* IPv6? Add braces around the host. */ if (git_net_url_is_ipv6(&t->server.url)) { - if (git_buf_printf(&ipv6, "[%s]", t->server.url.host) < 0) + if (git_str_printf(&ipv6, "[%s]", t->server.url.host) < 0) goto on_error; host = ipv6.ptr; @@ -795,7 +795,7 @@ static int winhttp_connect( if (git_http__user_agent(&ua) < 0) goto on_error; - if (git__utf8_to_16_alloc(&wide_ua, git_buf_cstr(&ua)) < 0) { + if (git__utf8_to_16_alloc(&wide_ua, git_str_cstr(&ua)) < 0) { git_error_set(GIT_ERROR_OS, "unable to convert host to wide characters"); goto on_error; } @@ -863,8 +863,8 @@ static int winhttp_connect( if (error < 0) winhttp_close_connection(t); - git_buf_dispose(&ua); - git_buf_dispose(&ipv6); + git_str_dispose(&ua); + git_str_dispose(&ipv6); git__free(wide_host); git__free(wide_ua); diff --git a/src/tree-cache.c b/src/tree-cache.c index 04d86fd3691..0977c92f331 100644 --- a/src/tree-cache.c +++ b/src/tree-cache.c @@ -256,22 +256,22 @@ int git_tree_cache_new(git_tree_cache **out, const char *name, git_pool *pool) return 0; } -static void write_tree(git_buf *out, git_tree_cache *tree) +static void write_tree(git_str *out, git_tree_cache *tree) { size_t i; - git_buf_printf(out, "%s%c%"PRIdZ" %"PRIuZ"\n", tree->name, 0, tree->entry_count, tree->children_count); + git_str_printf(out, "%s%c%"PRIdZ" %"PRIuZ"\n", tree->name, 0, tree->entry_count, tree->children_count); if (tree->entry_count != -1) - git_buf_put(out, (const char *) &tree->oid, GIT_OID_RAWSZ); + git_str_put(out, (const char *) &tree->oid, GIT_OID_RAWSZ); for (i = 0; i < tree->children_count; i++) write_tree(out, tree->children[i]); } -int git_tree_cache_write(git_buf *out, git_tree_cache *tree) +int git_tree_cache_write(git_str *out, git_tree_cache *tree) { write_tree(out, tree); - return git_buf_oom(out) ? -1 : 0; + return git_str_oom(out) ? -1 : 0; } diff --git a/src/tree-cache.h b/src/tree-cache.h index e02300e6e19..a27e3046614 100644 --- a/src/tree-cache.h +++ b/src/tree-cache.h @@ -11,7 +11,7 @@ #include "common.h" #include "pool.h" -#include "buffer.h" +#include "str.h" #include "git2/oid.h" typedef struct git_tree_cache { @@ -24,7 +24,7 @@ typedef struct git_tree_cache { char name[GIT_FLEX_ARRAY]; } git_tree_cache; -int git_tree_cache_write(git_buf *out, git_tree_cache *tree); +int git_tree_cache_write(git_str *out, git_tree_cache *tree); int git_tree_cache_read(git_tree_cache **tree, const char *buffer, size_t buffer_size, git_pool *pool); void git_tree_cache_invalidate_path(git_tree_cache *tree, const char *path); const git_tree_cache *git_tree_cache_get(const git_tree_cache *tree, const char *path); diff --git a/src/tree.c b/src/tree.c index b1df79eacfc..c1e39158dbf 100644 --- a/src/tree.c +++ b/src/tree.c @@ -495,7 +495,7 @@ static int check_entry(git_repository *repo, const char *filename, const git_oid static int git_treebuilder__write_with_buffer( git_oid *oid, git_treebuilder *bld, - git_buf *buf) + git_str *buf) { int error = 0; size_t i, entrycount; @@ -503,14 +503,14 @@ static int git_treebuilder__write_with_buffer( git_tree_entry *entry; git_vector entries = GIT_VECTOR_INIT; - git_buf_clear(buf); + git_str_clear(buf); entrycount = git_strmap_size(bld->map); if ((error = git_vector_init(&entries, entrycount, entry_sort_cmp)) < 0) goto out; if (buf->asize == 0 && - (error = git_buf_grow(buf, entrycount * 72)) < 0) + (error = git_str_grow(buf, entrycount * 72)) < 0) goto out; git_strmap_foreach_value(bld->map, entry, { @@ -523,11 +523,11 @@ static int git_treebuilder__write_with_buffer( for (i = 0; i < entries.length && !error; ++i) { entry = git_vector_get(&entries, i); - git_buf_printf(buf, "%o ", entry->attr); - git_buf_put(buf, entry->filename, entry->filename_len + 1); - git_buf_put(buf, (char *)entry->oid->id, GIT_OID_RAWSZ); + git_str_printf(buf, "%o ", entry->attr); + git_str_put(buf, entry->filename, entry->filename_len + 1); + git_str_put(buf, (char *)entry->oid->id, GIT_OID_RAWSZ); - if (git_buf_oom(buf)) { + if (git_str_oom(buf)) { error = -1; goto out; } @@ -575,7 +575,7 @@ static int write_tree( git_index *index, const char *dirname, size_t start, - git_buf *shared_buf) + git_str *shared_buf) { git_treebuilder *bld = NULL; size_t i, entries = git_index_entrycount(index); @@ -676,7 +676,7 @@ int git_tree__write_index( { int ret; git_tree *tree; - git_buf shared_buf = GIT_BUF_INIT; + git_str shared_buf = GIT_STR_INIT; bool old_ignore_case = false; GIT_ASSERT_ARG(oid); @@ -705,7 +705,7 @@ int git_tree__write_index( } ret = write_tree(oid, repo, index, "", 0, &shared_buf); - git_buf_dispose(&shared_buf); + git_str_dispose(&shared_buf); if (old_ignore_case) git_index__set_ignore_case(index, true); @@ -879,7 +879,7 @@ void git_treebuilder_free(git_treebuilder *bld) if (bld == NULL) return; - git_buf_dispose(&bld->write_cache); + git_str_dispose(&bld->write_cache); git_treebuilder_clear(bld); git_strmap_free(bld->map); git__free(bld); @@ -959,7 +959,7 @@ int git_tree_entry_bypath( static int tree_walk( const git_tree *tree, git_treewalk_cb callback, - git_buf *path, + git_str *path, void *payload, bool preorder) { @@ -982,17 +982,17 @@ static int tree_walk( if (git_tree_entry__is_tree(entry)) { git_tree *subtree; - size_t path_len = git_buf_len(path); + size_t path_len = git_str_len(path); error = git_tree_lookup(&subtree, tree->object.repo, entry->oid); if (error < 0) break; /* append the next entry to the path */ - git_buf_puts(path, entry->filename); - git_buf_putc(path, '/'); + git_str_puts(path, entry->filename); + git_str_putc(path, '/'); - if (git_buf_oom(path)) + if (git_str_oom(path)) error = -1; else error = tree_walk(subtree, callback, path, payload, preorder); @@ -1001,7 +1001,7 @@ static int tree_walk( if (error != 0) break; - git_buf_truncate(path, path_len); + git_str_truncate(path, path_len); } if (!preorder) { @@ -1024,7 +1024,7 @@ int git_tree_walk( void *payload) { int error = 0; - git_buf root_path = GIT_BUF_INIT; + git_str root_path = GIT_STR_INIT; if (mode != GIT_TREEWALK_POST && mode != GIT_TREEWALK_PRE) { git_error_set(GIT_ERROR_INVALID, "invalid walking mode for tree walk"); @@ -1034,7 +1034,7 @@ int git_tree_walk( error = tree_walk( tree, callback, &root_path, payload, (mode == GIT_TREEWALK_PRE)); - git_buf_dispose(&root_path); + git_str_dispose(&root_path); return error; } @@ -1080,19 +1080,19 @@ GIT_INLINE(size_t) count_slashes(const char *path) return count; } -static bool next_component(git_buf *out, const char *in) +static bool next_component(git_str *out, const char *in) { const char *slash = strchr(in, '/'); - git_buf_clear(out); + git_str_clear(out); if (slash) - git_buf_put(out, in, slash - in); + git_str_put(out, in, slash - in); return !!slash; } -static int create_popped_tree(tree_stack_entry *current, tree_stack_entry *popped, git_buf *component) +static int create_popped_tree(tree_stack_entry *current, tree_stack_entry *popped, git_str *component) { int error; git_oid new_tree; @@ -1116,8 +1116,8 @@ static int create_popped_tree(tree_stack_entry *current, tree_stack_entry *poppe } /* We've written out the tree, now we have to put the new value into its parent */ - git_buf_clear(component); - git_buf_puts(component, popped->name); + git_str_clear(component); + git_str_puts(component, popped->name); git__free(popped->name); GIT_ERROR_CHECK_ALLOC(component->ptr); @@ -1142,7 +1142,7 @@ int git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseli git_vector entries; int error; size_t i; - git_buf component = GIT_BUF_INIT; + git_str component = GIT_STR_INIT; if ((error = git_vector_init(&entries, nupdates, compare_entries)) < 0) return error; @@ -1300,7 +1300,7 @@ int git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseli } } - git_buf_dispose(&component); + git_str_dispose(&component); git_array_clear(stack); git_vector_free(&entries); return error; diff --git a/src/tree.h b/src/tree.h index 2f3027b5a27..6bd9ed65248 100644 --- a/src/tree.h +++ b/src/tree.h @@ -32,7 +32,7 @@ struct git_tree { struct git_treebuilder { git_repository *repo; git_strmap *map; - git_buf write_cache; + git_str write_cache; }; GIT_INLINE(bool) git_tree_entry__is_tree(const struct git_tree_entry *e) diff --git a/src/util.c b/src/util.c index 9b0c45ce825..2b1dadfe84c 100644 --- a/src/util.c +++ b/src/util.c @@ -735,13 +735,13 @@ void git__qsort_r( } #ifdef GIT_WIN32 -int git__getenv(git_buf *out, const char *name) +int git__getenv(git_str *out, const char *name) { wchar_t *wide_name = NULL, *wide_value = NULL; DWORD value_len; int error = -1; - git_buf_clear(out); + git_str_clear(out); if (git__utf8_to_16_alloc(&wide_name, name) < 0) return -1; @@ -754,7 +754,7 @@ int git__getenv(git_buf *out, const char *name) } if (value_len) - error = git_buf_put_w(out, wide_value, value_len); + error = git_str_put_w(out, wide_value, value_len); else if (GetLastError() == ERROR_SUCCESS || GetLastError() == ERROR_ENVVAR_NOT_FOUND) error = GIT_ENOTFOUND; else @@ -765,16 +765,16 @@ int git__getenv(git_buf *out, const char *name) return error; } #else -int git__getenv(git_buf *out, const char *name) +int git__getenv(git_str *out, const char *name) { const char *val = getenv(name); - git_buf_clear(out); + git_str_clear(out); if (!val) return GIT_ENOTFOUND; - return git_buf_puts(out, val); + return git_str_puts(out, val); } #endif diff --git a/src/util.h b/src/util.h index e8074fcb9da..30cdd0ddfe2 100644 --- a/src/util.h +++ b/src/util.h @@ -7,15 +7,11 @@ #ifndef INCLUDE_util_h__ #define INCLUDE_util_h__ -#include "common.h" - #ifndef GIT_WIN32 # include #endif -#include "git2/buffer.h" - -#include "buffer.h" +#include "str.h" #include "common.h" #include "strnlen.h" #include "thread.h" @@ -402,7 +398,7 @@ GIT_INLINE(double) git__timer(void) #endif -extern int git__getenv(git_buf *out, const char *name); +extern int git__getenv(git_str *out, const char *name); extern int git__online_cpus(void); diff --git a/src/win32/findfile.c b/src/win32/findfile.c index 40d2d518a18..caa79398ab5 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -34,7 +34,7 @@ static int git_win32__expand_path(_findfile_path *dest, const wchar_t *src) return 0; } -static int win32_path_to_8(git_buf *dest, const wchar_t *src) +static int win32_path_to_8(git_str *dest, const wchar_t *src) { git_win32_utf8_path utf8_path; @@ -46,7 +46,7 @@ static int win32_path_to_8(git_buf *dest, const wchar_t *src) /* Convert backslashes to forward slashes */ git_path_mkposix(utf8_path); - return git_buf_sets(dest, utf8_path); + return git_str_sets(dest, utf8_path); } static wchar_t *win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen) @@ -70,7 +70,7 @@ static wchar_t *win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen) return (path != base) ? path : NULL; } -static int win32_find_git_in_path(git_buf *buf, const wchar_t *gitexe, const wchar_t *subdir) +static int win32_find_git_in_path(git_str *buf, const wchar_t *gitexe, const wchar_t *subdir) { wchar_t *env = _wgetenv(L"PATH"), lastch; _findfile_path root; @@ -106,7 +106,7 @@ static int win32_find_git_in_path(git_buf *buf, const wchar_t *gitexe, const wch } static int win32_find_git_in_registry( - git_buf *buf, const HKEY hive, const wchar_t *key, const wchar_t *subdir) + git_str *buf, const HKEY hive, const wchar_t *key, const wchar_t *subdir) { HKEY hKey; int error = GIT_ENOTFOUND; @@ -141,12 +141,12 @@ static int win32_find_git_in_registry( } static int win32_find_existing_dirs( - git_buf *out, const wchar_t *tmpl[]) + git_str *out, const wchar_t *tmpl[]) { _findfile_path path16; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - git_buf_clear(out); + git_str_clear(out); for (; *tmpl != NULL; tmpl++) { if (!git_win32__expand_path(&path16, *tmpl) && @@ -156,43 +156,43 @@ static int win32_find_existing_dirs( win32_path_to_8(&buf, path16.path); if (buf.size) - git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); + git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); } } - git_buf_dispose(&buf); + git_str_dispose(&buf); - return (git_buf_oom(out) ? -1 : 0); + return (git_str_oom(out) ? -1 : 0); } -int git_win32__find_system_dirs(git_buf *out, const wchar_t *subdir) +int git_win32__find_system_dirs(git_str *out, const wchar_t *subdir) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; /* directories where git.exe & git.cmd are found */ if (!win32_find_git_in_path(&buf, L"git.exe", subdir) && buf.size) - git_buf_set(out, buf.ptr, buf.size); + git_str_set(out, buf.ptr, buf.size); else - git_buf_clear(out); + git_str_clear(out); if (!win32_find_git_in_path(&buf, L"git.cmd", subdir) && buf.size) - git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); + git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); /* directories where git is installed according to registry */ if (!win32_find_git_in_registry( &buf, HKEY_CURRENT_USER, REG_MSYSGIT_INSTALL_LOCAL, subdir) && buf.size) - git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); + git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); if (!win32_find_git_in_registry( &buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL, subdir) && buf.size) - git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); + git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); - git_buf_dispose(&buf); + git_str_dispose(&buf); - return (git_buf_oom(out) ? -1 : 0); + return (git_str_oom(out) ? -1 : 0); } -int git_win32__find_global_dirs(git_buf *out) +int git_win32__find_global_dirs(git_str *out) { static const wchar_t *global_tmpls[4] = { L"%HOME%\\", @@ -204,7 +204,7 @@ int git_win32__find_global_dirs(git_buf *out) return win32_find_existing_dirs(out, global_tmpls); } -int git_win32__find_xdg_dirs(git_buf *out) +int git_win32__find_xdg_dirs(git_str *out) { static const wchar_t *global_tmpls[7] = { L"%XDG_CONFIG_HOME%\\git", @@ -219,7 +219,7 @@ int git_win32__find_xdg_dirs(git_buf *out) return win32_find_existing_dirs(out, global_tmpls); } -int git_win32__find_programdata_dirs(git_buf *out) +int git_win32__find_programdata_dirs(git_str *out) { static const wchar_t *programdata_tmpls[2] = { L"%PROGRAMDATA%\\Git", diff --git a/src/win32/findfile.h b/src/win32/findfile.h index e7bcf948a5c..e11ccebc58c 100644 --- a/src/win32/findfile.h +++ b/src/win32/findfile.h @@ -10,10 +10,10 @@ #include "common.h" -extern int git_win32__find_system_dirs(git_buf *out, const wchar_t *subpath); -extern int git_win32__find_global_dirs(git_buf *out); -extern int git_win32__find_xdg_dirs(git_buf *out); -extern int git_win32__find_programdata_dirs(git_buf *out); +extern int git_win32__find_system_dirs(git_str *out, const wchar_t *subpath); +extern int git_win32__find_global_dirs(git_str *out); +extern int git_win32__find_xdg_dirs(git_str *out); +extern int git_win32__find_programdata_dirs(git_str *out); #endif diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index 8af07e6fa77..f26983d9792 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -14,7 +14,6 @@ #include "utf-conv.h" #include "repository.h" #include "reparse.h" -#include "buffer.h" #include #include #include @@ -415,7 +414,7 @@ int p_readlink(const char *path, char *buf, size_t bufsiz) static bool target_is_dir(const char *target, const char *path) { - git_buf resolved = GIT_BUF_INIT; + git_str resolved = GIT_STR_INIT; git_win32_path resolved_w; bool isdir = true; @@ -429,7 +428,7 @@ static bool target_is_dir(const char *target, const char *path) isdir = GetFileAttributesW(resolved_w) & FILE_ATTRIBUTE_DIRECTORY; out: - git_buf_dispose(&resolved); + git_str_dispose(&resolved); return isdir; } @@ -1003,7 +1002,7 @@ ssize_t p_pread(int fd, void *data, size_t size, off64_t offset) /* Fail if the final offset would have overflowed to match POSIX semantics. */ if (!git__is_ssizet(size) || git__add_int64_overflow(&final_offset, offset, (int64_t)size)) { errno = EINVAL; - return -1; + return -1; } /* @@ -1038,7 +1037,7 @@ ssize_t p_pwrite(int fd, const void *data, size_t size, off64_t offset) /* Fail if the final offset would have overflowed to match POSIX semantics. */ if (!git__is_ssizet(size) || git__add_int64_overflow(&final_offset, offset, (int64_t)size)) { errno = EINVAL; - return -1; + return -1; } /* diff --git a/src/win32/w32_buffer.c b/src/win32/w32_buffer.c index f270a1e6ac9..6fee8203c24 100644 --- a/src/win32/w32_buffer.c +++ b/src/win32/w32_buffer.c @@ -7,7 +7,6 @@ #include "w32_buffer.h" -#include "../buffer.h" #include "utf-conv.h" GIT_INLINE(int) handle_wc_error(void) @@ -20,7 +19,7 @@ GIT_INLINE(int) handle_wc_error(void) return -1; } -int git_buf_put_w(git_buf *buf, const wchar_t *string_w, size_t len_w) +int git_str_put_w(git_str *buf, const wchar_t *string_w, size_t len_w) { int utf8_len, utf8_write_len; size_t new_size; @@ -43,7 +42,7 @@ int git_buf_put_w(git_buf *buf, const wchar_t *string_w, size_t len_w) GIT_ERROR_CHECK_ALLOC_ADD(&new_size, buf->size, (size_t)utf8_len); GIT_ERROR_CHECK_ALLOC_ADD(&new_size, new_size, 1); - if (git_buf_grow(buf, new_size) < 0) + if (git_str_grow(buf, new_size) < 0) return -1; if ((utf8_write_len = WideCharToMultiByte( diff --git a/src/win32/w32_buffer.h b/src/win32/w32_buffer.h index 43298e4a78a..4227296d8f5 100644 --- a/src/win32/w32_buffer.h +++ b/src/win32/w32_buffer.h @@ -8,13 +8,12 @@ #define INCLUDE_win32_w32_buffer_h__ #include "common.h" - -#include "../buffer.h" +#include "str.h" /** * Convert a wide character string to UTF-8 and append the results to the * buffer. */ -int git_buf_put_w(git_buf *buf, const wchar_t *string_w, size_t len_w); +int git_str_put_w(git_str *buf, const wchar_t *string_w, size_t len_w); #endif diff --git a/src/worktree.c b/src/worktree.c index fe8db774305..92a0900b08b 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -7,32 +7,33 @@ #include "worktree.h" +#include "buf.h" +#include "repository.h" + #include "git2/branch.h" #include "git2/commit.h" #include "git2/worktree.h" -#include "repository.h" - static bool is_worktree_dir(const char *dir) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int error; - if (git_buf_sets(&buf, dir) < 0) + if (git_str_sets(&buf, dir) < 0) return -1; error = git_path_contains_file(&buf, "commondir") && git_path_contains_file(&buf, "gitdir") && git_path_contains_file(&buf, "HEAD"); - git_buf_dispose(&buf); + git_str_dispose(&buf); return error; } int git_worktree_list(git_strarray *wts, git_repository *repo) { git_vector worktrees = GIT_VECTOR_INIT; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; char *worktree; size_t i, len; int error; @@ -43,7 +44,7 @@ int git_worktree_list(git_strarray *wts, git_repository *repo) wts->count = 0; wts->strings = NULL; - if ((error = git_buf_joinpath(&path, repo->commondir, "worktrees/")) < 0) + if ((error = git_str_joinpath(&path, repo->commondir, "worktrees/")) < 0) goto exit; if (!git_path_exists(path.ptr) || git_path_is_empty_dir(path.ptr)) goto exit; @@ -53,8 +54,8 @@ int git_worktree_list(git_strarray *wts, git_repository *repo) len = path.size; git_vector_foreach(&worktrees, i, worktree) { - git_buf_truncate(&path, len); - git_buf_puts(&path, worktree); + git_str_truncate(&path, len); + git_str_puts(&path, worktree); if (!is_worktree_dir(path.ptr)) { git_vector_remove(&worktrees, i); @@ -65,68 +66,68 @@ int git_worktree_list(git_strarray *wts, git_repository *repo) wts->strings = (char **)git_vector_detach(&wts->count, NULL, &worktrees); exit: - git_buf_dispose(&path); + git_str_dispose(&path); return error; } char *git_worktree__read_link(const char *base, const char *file) { - git_buf path = GIT_BUF_INIT, buf = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, buf = GIT_STR_INIT; GIT_ASSERT_ARG_WITH_RETVAL(base, NULL); GIT_ASSERT_ARG_WITH_RETVAL(file, NULL); - if (git_buf_joinpath(&path, base, file) < 0) + if (git_str_joinpath(&path, base, file) < 0) goto err; if (git_futils_readbuffer(&buf, path.ptr) < 0) goto err; - git_buf_dispose(&path); + git_str_dispose(&path); - git_buf_rtrim(&buf); + git_str_rtrim(&buf); if (!git_path_is_relative(buf.ptr)) - return git_buf_detach(&buf); + return git_str_detach(&buf); - if (git_buf_sets(&path, base) < 0) + if (git_str_sets(&path, base) < 0) goto err; if (git_path_apply_relative(&path, buf.ptr) < 0) goto err; - git_buf_dispose(&buf); + git_str_dispose(&buf); - return git_buf_detach(&path); + return git_str_detach(&path); err: - git_buf_dispose(&buf); - git_buf_dispose(&path); + git_str_dispose(&buf); + git_str_dispose(&path); return NULL; } -static int write_wtfile(const char *base, const char *file, const git_buf *buf) +static int write_wtfile(const char *base, const char *file, const git_str *buf) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int err; GIT_ASSERT_ARG(base); GIT_ASSERT_ARG(file); GIT_ASSERT_ARG(buf); - if ((err = git_buf_joinpath(&path, base, file)) < 0) + if ((err = git_str_joinpath(&path, base, file)) < 0) goto out; if ((err = git_futils_writebuffer(buf, path.ptr, O_CREAT|O_EXCL|O_WRONLY, 0644)) < 0) goto out; out: - git_buf_dispose(&path); + git_str_dispose(&path); return err; } static int open_worktree_dir(git_worktree **out, const char *parent, const char *dir, const char *name) { - git_buf gitdir = GIT_BUF_INIT; + git_str gitdir = GIT_STR_INIT; git_worktree *wt = NULL; int error = 0; @@ -154,7 +155,7 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char if ((error = git_path_prettify_dir(&gitdir, dir, NULL)) < 0) goto out; - wt->gitdir_path = git_buf_detach(&gitdir); + wt->gitdir_path = git_str_detach(&gitdir); if ((error = git_worktree_is_locked(NULL, wt)) < 0) goto out; @@ -166,14 +167,14 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char out: if (error) git_worktree_free(wt); - git_buf_dispose(&gitdir); + git_str_dispose(&gitdir); return error; } int git_worktree_lookup(git_worktree **out, git_repository *repo, const char *name) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_worktree *wt = NULL; int error; @@ -182,14 +183,14 @@ int git_worktree_lookup(git_worktree **out, git_repository *repo, const char *na *out = NULL; - if ((error = git_buf_join3(&path, '/', repo->commondir, "worktrees", name)) < 0) + if ((error = git_str_join3(&path, '/', repo->commondir, "worktrees", name)) < 0) goto out; if ((error = (open_worktree_dir(out, git_repository_workdir(repo), path.ptr, name))) < 0) goto out; out: - git_buf_dispose(&path); + git_str_dispose(&path); if (error) git_worktree_free(wt); @@ -199,7 +200,7 @@ int git_worktree_lookup(git_worktree **out, git_repository *repo, const char *na int git_worktree_open_from_repository(git_worktree **out, git_repository *repo) { - git_buf parent = GIT_BUF_INIT; + git_str parent = GIT_STR_INIT; const char *gitdir, *commondir; char *name = NULL; int error = 0; @@ -224,7 +225,7 @@ int git_worktree_open_from_repository(git_worktree **out, git_repository *repo) out: git__free(name); - git_buf_dispose(&parent); + git_str_dispose(&parent); return error; } @@ -298,7 +299,7 @@ int git_worktree_add(git_worktree **out, git_repository *repo, const char *name, const char *worktree, const git_worktree_add_options *opts) { - git_buf gitdir = GIT_BUF_INIT, wddir = GIT_BUF_INIT, buf = GIT_BUF_INIT; + git_str gitdir = GIT_STR_INIT, wddir = GIT_STR_INIT, buf = GIT_STR_INIT; git_reference *ref = NULL, *head = NULL; git_commit *commit = NULL; git_repository *wt = NULL; @@ -334,12 +335,12 @@ int git_worktree_add(git_worktree **out, git_repository *repo, } /* Create gitdir directory ".git/worktrees/" */ - if ((err = git_buf_joinpath(&gitdir, repo->commondir, "worktrees")) < 0) + if ((err = git_str_joinpath(&gitdir, repo->commondir, "worktrees")) < 0) goto out; if (!git_path_exists(gitdir.ptr)) if ((err = git_futils_mkdir(gitdir.ptr, 0755, GIT_MKDIR_EXCL)) < 0) goto out; - if ((err = git_buf_joinpath(&gitdir, gitdir.ptr, name)) < 0) + if ((err = git_str_joinpath(&gitdir, gitdir.ptr, name)) < 0) goto out; if ((err = git_futils_mkdir(gitdir.ptr, 0755, GIT_MKDIR_EXCL)) < 0) goto out; @@ -355,7 +356,7 @@ int git_worktree_add(git_worktree **out, git_repository *repo, if (wtopts.lock) { int fd; - if ((err = git_buf_joinpath(&buf, gitdir.ptr, "locked")) < 0) + if ((err = git_str_joinpath(&buf, gitdir.ptr, "locked")) < 0) goto out; if ((fd = p_creat(buf.ptr, 0644)) < 0) { @@ -364,22 +365,22 @@ int git_worktree_add(git_worktree **out, git_repository *repo, } p_close(fd); - git_buf_clear(&buf); + git_str_clear(&buf); } /* Create worktree .git file */ - if ((err = git_buf_printf(&buf, "gitdir: %s\n", gitdir.ptr)) < 0) + if ((err = git_str_printf(&buf, "gitdir: %s\n", gitdir.ptr)) < 0) goto out; if ((err = write_wtfile(wddir.ptr, ".git", &buf)) < 0) goto out; /* Create gitdir files */ if ((err = git_path_prettify_dir(&buf, repo->commondir, NULL) < 0) - || (err = git_buf_putc(&buf, '\n')) < 0 + || (err = git_str_putc(&buf, '\n')) < 0 || (err = write_wtfile(gitdir.ptr, "commondir", &buf)) < 0) goto out; - if ((err = git_buf_joinpath(&buf, wddir.ptr, ".git")) < 0 - || (err = git_buf_putc(&buf, '\n')) < 0 + if ((err = git_str_joinpath(&buf, wddir.ptr, ".git")) < 0 + || (err = git_str_putc(&buf, '\n')) < 0 || (err = write_wtfile(gitdir.ptr, "gitdir", &buf)) < 0) goto out; @@ -412,9 +413,9 @@ int git_worktree_add(git_worktree **out, git_repository *repo, goto out; out: - git_buf_dispose(&gitdir); - git_buf_dispose(&wddir); - git_buf_dispose(&buf); + git_str_dispose(&gitdir); + git_str_dispose(&wddir); + git_str_dispose(&buf); git_reference_free(ref); git_reference_free(head); git_commit_free(commit); @@ -425,7 +426,7 @@ int git_worktree_add(git_worktree **out, git_repository *repo, int git_worktree_lock(git_worktree *wt, const char *reason) { - git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT, path = GIT_STR_INIT; int error; GIT_ASSERT_ARG(wt); @@ -437,11 +438,11 @@ int git_worktree_lock(git_worktree *wt, const char *reason) goto out; } - if ((error = git_buf_joinpath(&path, wt->gitdir_path, "locked")) < 0) + if ((error = git_str_joinpath(&path, wt->gitdir_path, "locked")) < 0) goto out; if (reason) - git_buf_attach_notowned(&buf, reason, strlen(reason)); + git_str_attach_notowned(&buf, reason, strlen(reason)); if ((error = git_futils_writebuffer(&buf, path.ptr, O_CREAT|O_EXCL|O_WRONLY, 0644)) < 0) goto out; @@ -449,14 +450,14 @@ int git_worktree_lock(git_worktree *wt, const char *reason) wt->locked = 1; out: - git_buf_dispose(&path); + git_str_dispose(&path); return error; } int git_worktree_unlock(git_worktree *wt) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error; GIT_ASSERT_ARG(wt); @@ -466,32 +467,32 @@ int git_worktree_unlock(git_worktree *wt) if (!error) return 1; - if (git_buf_joinpath(&path, wt->gitdir_path, "locked") < 0) + if (git_str_joinpath(&path, wt->gitdir_path, "locked") < 0) return -1; if (p_unlink(path.ptr) != 0) { - git_buf_dispose(&path); + git_str_dispose(&path); return -1; } wt->locked = 0; - git_buf_dispose(&path); + git_str_dispose(&path); return 0; } -int git_worktree_is_locked(git_buf *reason, const git_worktree *wt) +static int git_worktree__is_locked(git_str *reason, const git_worktree *wt) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int error, locked; GIT_ASSERT_ARG(wt); if (reason) - git_buf_clear(reason); + git_str_clear(reason); - if ((error = git_buf_joinpath(&path, wt->gitdir_path, "locked")) < 0) + if ((error = git_str_joinpath(&path, wt->gitdir_path, "locked")) < 0) goto out; locked = git_path_exists(path.ptr); if (locked && reason && @@ -500,8 +501,27 @@ int git_worktree_is_locked(git_buf *reason, const git_worktree *wt) error = locked; out: - git_buf_dispose(&path); + git_str_dispose(&path); + + return error; +} + +int git_worktree_is_locked(git_buf *reason, const git_worktree *wt) +{ + git_str str = GIT_STR_INIT; + int error = 0; + + if (reason && (error = git_buf_tostr(&str, reason)) < 0) + return error; + + error = git_worktree__is_locked(reason ? &str : NULL, wt); + + if (error >= 0 && reason) { + if (git_buf_fromstr(reason, &str) < 0) + error = -1; + } + git_str_dispose(&str); return error; } @@ -547,17 +567,17 @@ int git_worktree_is_prunable(git_worktree *wt, memcpy(&popts, opts, sizeof(popts)); if ((popts.flags & GIT_WORKTREE_PRUNE_LOCKED) == 0) { - git_buf reason = GIT_BUF_INIT; + git_str reason = GIT_STR_INIT; int error; - if ((error = git_worktree_is_locked(&reason, wt)) < 0) + if ((error = git_worktree__is_locked(&reason, wt)) < 0) return error; if (error) { if (!reason.size) - git_buf_attach_notowned(&reason, "no reason given", 15); + git_str_attach_notowned(&reason, "no reason given", 15); git_error_set(GIT_ERROR_WORKTREE, "not pruning locked working tree: '%s'", reason.ptr); - git_buf_dispose(&reason); + git_str_dispose(&reason); return 0; } } @@ -575,7 +595,7 @@ int git_worktree_prune(git_worktree *wt, git_worktree_prune_options *opts) { git_worktree_prune_options popts = GIT_WORKTREE_PRUNE_OPTIONS_INIT; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; char *wtpath; int err; @@ -592,7 +612,7 @@ int git_worktree_prune(git_worktree *wt, } /* Delete gitdir in parent repository */ - if ((err = git_buf_join3(&path, '/', wt->commondir_path, "worktrees", wt->name)) < 0) + if ((err = git_str_join3(&path, '/', wt->commondir_path, "worktrees", wt->name)) < 0) goto out; if (!git_path_exists(path.ptr)) { @@ -613,7 +633,7 @@ int git_worktree_prune(git_worktree *wt, if ((wtpath = git_path_dirname(wt->gitlink_path)) == NULL) goto out; - git_buf_attach(&path, wtpath, 0); + git_str_attach(&path, wtpath, 0); if (!git_path_exists(path.ptr)) { git_error_set(GIT_ERROR_WORKTREE, "working tree '%s' does not exist", path.ptr); @@ -624,7 +644,7 @@ int git_worktree_prune(git_worktree *wt, goto out; out: - git_buf_dispose(&path); + git_str_dispose(&path); return err; } diff --git a/src/zstream.c b/src/zstream.c index a5675676e90..cb8b125ed5b 100644 --- a/src/zstream.c +++ b/src/zstream.c @@ -9,7 +9,7 @@ #include -#include "buffer.h" +#include "str.h" #define ZSTREAM_BUFFER_SIZE (1024 * 1024) #define ZSTREAM_BUFFER_MIN_EXTRA 8 @@ -164,7 +164,7 @@ int git_zstream_get_output(void *out, size_t *out_len, git_zstream *zstream) return 0; } -static int zstream_buf(git_buf *out, const void *in, size_t in_len, git_zstream_t type) +static int zstream_buf(git_str *out, const void *in, size_t in_len, git_zstream_t type) { git_zstream zs = GIT_ZSTREAM_INIT; int error = 0; @@ -178,7 +178,7 @@ static int zstream_buf(git_buf *out, const void *in, size_t in_len, git_zstream_ while (!git_zstream_done(&zs)) { size_t step = git_zstream_suggest_output_len(&zs), written; - if ((error = git_buf_grow_by(out, step)) < 0) + if ((error = git_str_grow_by(out, step)) < 0) goto done; written = out->asize - out->size; @@ -199,12 +199,12 @@ static int zstream_buf(git_buf *out, const void *in, size_t in_len, git_zstream_ return error; } -int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len) +int git_zstream_deflatebuf(git_str *out, const void *in, size_t in_len) { return zstream_buf(out, in, in_len, GIT_ZSTREAM_DEFLATE); } -int git_zstream_inflatebuf(git_buf *out, const void *in, size_t in_len) +int git_zstream_inflatebuf(git_str *out, const void *in, size_t in_len) { return zstream_buf(out, in, in_len, GIT_ZSTREAM_INFLATE); } diff --git a/src/zstream.h b/src/zstream.h index db0cc477c38..3a59d9a369d 100644 --- a/src/zstream.h +++ b/src/zstream.h @@ -11,7 +11,7 @@ #include -#include "buffer.h" +#include "str.h" typedef enum { GIT_ZSTREAM_INFLATE, @@ -48,7 +48,7 @@ bool git_zstream_eos(git_zstream *zstream); void git_zstream_reset(git_zstream *zstream); -int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len); -int git_zstream_inflatebuf(git_buf *out, const void *in, size_t in_len); +int git_zstream_deflatebuf(git_str *out, const void *in, size_t in_len); +int git_zstream_inflatebuf(git_str *out, const void *in, size_t in_len); #endif diff --git a/tests/apply/fromdiff.c b/tests/apply/fromdiff.c index 69dfe0987a8..9da6ac92374 100644 --- a/tests/apply/fromdiff.c +++ b/tests/apply/fromdiff.c @@ -22,15 +22,15 @@ void test_apply_fromdiff__cleanup(void) } static int apply_gitbuf( - const git_buf *old, + const git_str *old, const char *oldname, - const git_buf *new, + const git_str *new, const char *newname, const char *patch_expected, const git_diff_options *diff_opts) { git_patch *patch; - git_buf result = GIT_BUF_INIT; + git_str result = GIT_STR_INIT; git_buf patchbuf = GIT_BUF_INIT; char *filename; unsigned int mode; @@ -62,7 +62,7 @@ static int apply_gitbuf( } git__free(filename); - git_buf_dispose(&result); + git_str_dispose(&result); git_buf_dispose(&patchbuf); git_patch_free(patch); @@ -77,7 +77,7 @@ static int apply_buf( const char *patch_expected, const git_diff_options *diff_opts) { - git_buf o = GIT_BUF_INIT, n = GIT_BUF_INIT, + git_str o = GIT_STR_INIT, n = GIT_STR_INIT, *optr = NULL, *nptr = NULL; if (old) { @@ -275,7 +275,7 @@ void test_apply_fromdiff__no_change(void) void test_apply_fromdiff__binary_add(void) { - git_buf newfile = GIT_BUF_INIT; + git_str newfile = GIT_STR_INIT; newfile.ptr = FILE_BINARY_DELTA_MODIFIED; newfile.size = FILE_BINARY_DELTA_MODIFIED_LEN; @@ -288,7 +288,7 @@ void test_apply_fromdiff__binary_add(void) void test_apply_fromdiff__binary_no_change(void) { - git_buf original = GIT_BUF_INIT; + git_str original = GIT_STR_INIT; original.ptr = FILE_BINARY_DELTA_ORIGINAL; original.size = FILE_BINARY_DELTA_ORIGINAL_LEN; @@ -301,7 +301,7 @@ void test_apply_fromdiff__binary_no_change(void) void test_apply_fromdiff__binary_change_delta(void) { - git_buf original = GIT_BUF_INIT, modified = GIT_BUF_INIT; + git_str original = GIT_STR_INIT, modified = GIT_STR_INIT; original.ptr = FILE_BINARY_DELTA_ORIGINAL; original.size = FILE_BINARY_DELTA_ORIGINAL_LEN; @@ -317,7 +317,7 @@ void test_apply_fromdiff__binary_change_delta(void) void test_apply_fromdiff__binary_change_literal(void) { - git_buf original = GIT_BUF_INIT, modified = GIT_BUF_INIT; + git_str original = GIT_STR_INIT, modified = GIT_STR_INIT; original.ptr = FILE_BINARY_LITERAL_ORIGINAL; original.size = FILE_BINARY_LITERAL_ORIGINAL_LEN; @@ -333,7 +333,7 @@ void test_apply_fromdiff__binary_change_literal(void) void test_apply_fromdiff__binary_delete(void) { - git_buf original = GIT_BUF_INIT; + git_str original = GIT_STR_INIT; original.ptr = FILE_BINARY_DELTA_MODIFIED; original.size = FILE_BINARY_DELTA_MODIFIED_LEN; @@ -346,7 +346,7 @@ void test_apply_fromdiff__binary_delete(void) void test_apply_fromdiff__patching_correctly_truncates_source(void) { - git_buf original = GIT_BUF_INIT, patched = GIT_BUF_INIT; + git_str original = GIT_STR_INIT, patched = GIT_STR_INIT; git_patch *patch; unsigned int mode; char *path; @@ -371,8 +371,8 @@ void test_apply_fromdiff__patching_correctly_truncates_source(void) cl_git_pass(git_apply__patch(&patched, &path, &mode, "foo\nbar\n", 7, patch, NULL)); - git_buf_dispose(&original); - git_buf_dispose(&patched); + git_str_dispose(&original); + git_str_dispose(&patched); git_patch_free(patch); git__free(path); } diff --git a/tests/apply/fromfile.c b/tests/apply/fromfile.c index ae519eab051..8cde623928a 100644 --- a/tests/apply/fromfile.c +++ b/tests/apply/fromfile.c @@ -30,8 +30,8 @@ static int apply_patchfile( unsigned int mode_expected) { git_patch *patch; - git_buf result = GIT_BUF_INIT; - git_buf patchbuf = GIT_BUF_INIT; + git_str result = GIT_STR_INIT; + git_str patchbuf = GIT_STR_INIT; char *filename; unsigned int mode; int error; @@ -50,8 +50,8 @@ static int apply_patchfile( } git__free(filename); - git_buf_dispose(&result); - git_buf_dispose(&patchbuf); + git_str_dispose(&result); + git_str_dispose(&patchbuf); git_patch_free(patch); return error; diff --git a/tests/apply/partial.c b/tests/apply/partial.c index 548faaadb14..fd4908d4b1d 100644 --- a/tests/apply/partial.c +++ b/tests/apply/partial.c @@ -83,8 +83,8 @@ static int apply_buf( void *payload) { git_patch *patch; - git_buf result = GIT_BUF_INIT; - git_buf patchbuf = GIT_BUF_INIT; + git_str result = GIT_STR_INIT; + git_str patchbuf = GIT_STR_INIT; git_apply_options opts = GIT_APPLY_OPTIONS_INIT; char *filename; unsigned int mode; @@ -103,8 +103,8 @@ static int apply_buf( } git__free(filename); - git_buf_dispose(&result); - git_buf_dispose(&patchbuf); + git_str_dispose(&result); + git_str_dispose(&patchbuf); git_patch_free(patch); return error; diff --git a/tests/attr/repo.c b/tests/attr/repo.c index eabc033eb97..e7b97529010 100644 --- a/tests/attr/repo.c +++ b/tests/attr/repo.c @@ -230,12 +230,12 @@ void test_attr_repo__manpage_example(void) static void add_to_workdir(const char *filename, const char *content) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&buf, "attr", filename)); - cl_git_rewritefile(git_buf_cstr(&buf), content); + cl_git_pass(git_str_joinpath(&buf, "attr", filename)); + cl_git_rewritefile(git_str_cstr(&buf), content); - git_buf_dispose(&buf); + git_str_dispose(&buf); } static void assert_proper_normalization(git_index *index, const char *filename, const char *expected_sha) @@ -311,12 +311,12 @@ void test_attr_repo__bare_repo_with_index(void) void test_attr_repo__sysdir(void) { - git_buf sysdir = GIT_BUF_INIT; + git_str sysdir = GIT_STR_INIT; const char *value; cl_git_pass(p_mkdir("system", 0777)); cl_git_rewritefile("system/gitattributes", "file merge=foo"); - cl_git_pass(git_buf_joinpath(&sysdir, clar_sandbox_path(), "system")); + cl_git_pass(git_str_joinpath(&sysdir, clar_sandbox_path(), "system")); cl_git_pass(git_sysdir_set(GIT_SYSDIR_SYSTEM, sysdir.ptr)); g_repo = cl_git_sandbox_reopen(); @@ -325,18 +325,18 @@ void test_attr_repo__sysdir(void) cl_git_pass(p_unlink("system/gitattributes")); cl_git_pass(p_rmdir("system")); - git_buf_dispose(&sysdir); + git_str_dispose(&sysdir); } void test_attr_repo__sysdir_with_session(void) { const char *values[2], *attrs[2] = { "foo", "bar" }; - git_buf sysdir = GIT_BUF_INIT; + git_str sysdir = GIT_STR_INIT; git_attr_session session; cl_git_pass(p_mkdir("system", 0777)); cl_git_rewritefile("system/gitattributes", "file foo=1 bar=2"); - cl_git_pass(git_buf_joinpath(&sysdir, clar_sandbox_path(), "system")); + cl_git_pass(git_str_joinpath(&sysdir, clar_sandbox_path(), "system")); cl_git_pass(git_sysdir_set(GIT_SYSDIR_SYSTEM, sysdir.ptr)); g_repo = cl_git_sandbox_reopen(); @@ -348,7 +348,7 @@ void test_attr_repo__sysdir_with_session(void) cl_git_pass(p_unlink("system/gitattributes")); cl_git_pass(p_rmdir("system")); - git_buf_dispose(&sysdir); + git_str_dispose(&sysdir); git_attr_session__free(&session); } @@ -371,11 +371,11 @@ void test_attr_repo__rewrite(void) void test_attr_repo__rewrite_sysdir(void) { - git_buf sysdir = GIT_BUF_INIT; + git_str sysdir = GIT_STR_INIT; const char *value; cl_git_pass(p_mkdir("system", 0777)); - cl_git_pass(git_buf_joinpath(&sysdir, clar_sandbox_path(), "system")); + cl_git_pass(git_str_joinpath(&sysdir, clar_sandbox_path(), "system")); cl_git_pass(git_sysdir_set(GIT_SYSDIR_SYSTEM, sysdir.ptr)); g_repo = cl_git_sandbox_reopen(); @@ -387,7 +387,7 @@ void test_attr_repo__rewrite_sysdir(void) cl_git_pass(git_attr_get(&value, g_repo, 0, "file", "foo")); cl_assert_equal_s(value, "second"); - git_buf_dispose(&sysdir); + git_str_dispose(&sysdir); } void test_attr_repo__unlink(void) diff --git a/tests/buf/basic.c b/tests/buf/basic.c deleted file mode 100644 index f90c4c6ed0d..00000000000 --- a/tests/buf/basic.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "clar_libgit2.h" -#include "buffer.h" - -static const char *test_string = "Have you seen that? Have you seeeen that??"; - -void test_buf_basic__resize(void) -{ - git_buf buf1 = GIT_BUF_INIT; - git_buf_puts(&buf1, test_string); - cl_assert(git_buf_oom(&buf1) == 0); - cl_assert_equal_s(git_buf_cstr(&buf1), test_string); - - git_buf_puts(&buf1, test_string); - cl_assert(strlen(git_buf_cstr(&buf1)) == strlen(test_string) * 2); - git_buf_dispose(&buf1); -} - -void test_buf_basic__resize_incremental(void) -{ - git_buf buf1 = GIT_BUF_INIT; - - /* Presently, asking for 6 bytes will round up to 8. */ - cl_git_pass(git_buf_puts(&buf1, "Hello")); - cl_assert_equal_i(5, buf1.size); - cl_assert_equal_i(8, buf1.asize); - - /* Ensure an additional byte does not realloc. */ - cl_git_pass(git_buf_grow_by(&buf1, 1)); - cl_assert_equal_i(5, buf1.size); - cl_assert_equal_i(8, buf1.asize); - - /* But requesting many does. */ - cl_git_pass(git_buf_grow_by(&buf1, 16)); - cl_assert_equal_i(5, buf1.size); - cl_assert(buf1.asize > 8); - - git_buf_dispose(&buf1); -} - -void test_buf_basic__printf(void) -{ - git_buf buf2 = GIT_BUF_INIT; - git_buf_printf(&buf2, "%s %s %d ", "shoop", "da", 23); - cl_assert(git_buf_oom(&buf2) == 0); - cl_assert_equal_s(git_buf_cstr(&buf2), "shoop da 23 "); - - git_buf_printf(&buf2, "%s %d", "woop", 42); - cl_assert(git_buf_oom(&buf2) == 0); - cl_assert_equal_s(git_buf_cstr(&buf2), "shoop da 23 woop 42"); - git_buf_dispose(&buf2); -} diff --git a/tests/buf/splice.c b/tests/buf/splice.c deleted file mode 100644 index 18c7c3f2bd0..00000000000 --- a/tests/buf/splice.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "clar_libgit2.h" -#include "buffer.h" - -static git_buf _buf; - -void test_buf_splice__initialize(void) { - git_buf_init(&_buf, 16); -} - -void test_buf_splice__cleanup(void) { - git_buf_dispose(&_buf); -} - -void test_buf_splice__preprend(void) -{ - git_buf_sets(&_buf, "world!"); - - cl_git_pass(git_buf_splice(&_buf, 0, 0, "Hello Dolly", strlen("Hello "))); - - cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf)); -} - -void test_buf_splice__append(void) -{ - git_buf_sets(&_buf, "Hello"); - - cl_git_pass(git_buf_splice(&_buf, git_buf_len(&_buf), 0, " world!", strlen(" world!"))); - - cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf)); -} - -void test_buf_splice__insert_at(void) -{ - git_buf_sets(&_buf, "Hell world!"); - - cl_git_pass(git_buf_splice(&_buf, strlen("Hell"), 0, "o", strlen("o"))); - - cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf)); -} - -void test_buf_splice__remove_at(void) -{ - git_buf_sets(&_buf, "Hello world of warcraft!"); - - cl_git_pass(git_buf_splice(&_buf, strlen("Hello world"), strlen(" of warcraft"), "", 0)); - - cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf)); -} - -void test_buf_splice__replace(void) -{ - git_buf_sets(&_buf, "Hell0 w0rld!"); - - cl_git_pass(git_buf_splice(&_buf, strlen("Hell"), strlen("0 w0"), "o wo", strlen("o wo"))); - - cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf)); -} - -void test_buf_splice__replace_with_longer(void) -{ - git_buf_sets(&_buf, "Hello you!"); - - cl_git_pass(git_buf_splice(&_buf, strlen("Hello "), strlen("you"), "world", strlen("world"))); - - cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf)); -} - -void test_buf_splice__replace_with_shorter(void) -{ - git_buf_sets(&_buf, "Brave new world!"); - - cl_git_pass(git_buf_splice(&_buf, 0, strlen("Brave new"), "Hello", strlen("Hello"))); - - cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf)); -} - -void test_buf_splice__truncate(void) -{ - git_buf_sets(&_buf, "Hello world!!"); - - cl_git_pass(git_buf_splice(&_buf, strlen("Hello world!"), strlen("!"), "", 0)); - - cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf)); -} - -void test_buf_splice__dont_do_anything(void) -{ - git_buf_sets(&_buf, "Hello world!"); - - cl_git_pass(git_buf_splice(&_buf, 3, 0, "Hello", 0)); - - cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf)); -} diff --git a/tests/checkout/checkout_helpers.c b/tests/checkout/checkout_helpers.c index 95af5d3964c..1e9c21bdc5c 100644 --- a/tests/checkout/checkout_helpers.c +++ b/tests/checkout/checkout_helpers.c @@ -7,16 +7,16 @@ void assert_on_branch(git_repository *repo, const char *branch) { git_reference *head; - git_buf bname = GIT_BUF_INIT; + git_str bname = GIT_STR_INIT; cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE)); cl_assert_(git_reference_type(head) == GIT_REFERENCE_SYMBOLIC, branch); - cl_git_pass(git_buf_joinpath(&bname, "refs/heads", branch)); + cl_git_pass(git_str_joinpath(&bname, "refs/heads", branch)); cl_assert_equal_s(bname.ptr, git_reference_symbolic_target(head)); git_reference_free(head); - git_buf_dispose(&bname); + git_str_dispose(&bname); } void reset_index_to_treeish(git_object *treeish) diff --git a/tests/checkout/checkout_helpers.h b/tests/checkout/checkout_helpers.h index 6058a196c70..879b48b06d7 100644 --- a/tests/checkout/checkout_helpers.h +++ b/tests/checkout/checkout_helpers.h @@ -1,4 +1,3 @@ -#include "buffer.h" #include "git2/object.h" #include "git2/repository.h" diff --git a/tests/checkout/conflict.c b/tests/checkout/conflict.c index dae3f295e94..3f5e7162d4a 100644 --- a/tests/checkout/conflict.c +++ b/tests/checkout/conflict.c @@ -85,14 +85,14 @@ void test_checkout_conflict__cleanup(void) static void create_index(struct checkout_index_entry *entries, size_t entries_len) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; size_t i; for (i = 0; i < entries_len; i++) { - git_buf_joinpath(&path, TEST_REPO_PATH, entries[i].path); + git_str_joinpath(&path, TEST_REPO_PATH, entries[i].path); if (entries[i].stage == 3 && (i == 0 || strcmp(entries[i-1].path, entries[i].path) != 0 || entries[i-1].stage != 2)) - p_unlink(git_buf_cstr(&path)); + p_unlink(git_str_cstr(&path)); cl_git_pass(git_index_remove_bypath(g_index, entries[i].path)); } @@ -110,7 +110,7 @@ static void create_index(struct checkout_index_entry *entries, size_t entries_le cl_git_pass(git_index_add(g_index, &entry)); } - git_buf_dispose(&path); + git_str_dispose(&path); } static void create_index_names(struct checkout_name_entry *entries, size_t entries_len) @@ -139,16 +139,16 @@ static void create_conflicting_index(void) static void ensure_workdir_contents(const char *path, const char *contents) { - git_buf fullpath = GIT_BUF_INIT, data_buf = GIT_BUF_INIT; + git_str fullpath = GIT_STR_INIT, data_buf = GIT_STR_INIT; cl_git_pass( - git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path)); + git_str_joinpath(&fullpath, git_repository_workdir(g_repo), path)); - cl_git_pass(git_futils_readbuffer(&data_buf, git_buf_cstr(&fullpath))); - cl_assert(strcmp(git_buf_cstr(&data_buf), contents) == 0); + cl_git_pass(git_futils_readbuffer(&data_buf, git_str_cstr(&fullpath))); + cl_assert(strcmp(git_str_cstr(&data_buf), contents) == 0); - git_buf_dispose(&fullpath); - git_buf_dispose(&data_buf); + git_str_dispose(&fullpath); + git_str_dispose(&data_buf); } static void ensure_workdir_oid(const char *path, const char *oid_str) @@ -166,16 +166,16 @@ static void ensure_workdir_mode(const char *path, int mode) GIT_UNUSED(path); GIT_UNUSED(mode); #else - git_buf fullpath = GIT_BUF_INIT; + git_str fullpath = GIT_STR_INIT; struct stat st; cl_git_pass( - git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path)); + git_str_joinpath(&fullpath, git_repository_workdir(g_repo), path)); - cl_git_pass(p_stat(git_buf_cstr(&fullpath), &st)); + cl_git_pass(p_stat(git_str_cstr(&fullpath), &st)); cl_assert_equal_i((mode & S_IRWXU), (st.st_mode & S_IRWXU)); - git_buf_dispose(&fullpath); + git_str_dispose(&fullpath); #endif } @@ -197,22 +197,22 @@ static void ensure_workdir_link( if (!symlinks) { ensure_workdir_contents(path, target); } else { - git_buf fullpath = GIT_BUF_INIT; + git_str fullpath = GIT_STR_INIT; char actual[1024]; struct stat st; int len; cl_git_pass( - git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path)); + git_str_joinpath(&fullpath, git_repository_workdir(g_repo), path)); - cl_git_pass(p_lstat(git_buf_cstr(&fullpath), &st)); + cl_git_pass(p_lstat(git_str_cstr(&fullpath), &st)); cl_assert(S_ISLNK(st.st_mode)); - cl_assert((len = p_readlink(git_buf_cstr(&fullpath), actual, 1024)) > 0); + cl_assert((len = p_readlink(git_str_cstr(&fullpath), actual, 1024)) > 0); actual[len] = '\0'; cl_assert(strcmp(actual, target) == 0); - git_buf_dispose(&fullpath); + git_str_dispose(&fullpath); } } diff --git a/tests/checkout/crlf.c b/tests/checkout/crlf.c index 4950201615c..eb4c61f39be 100644 --- a/tests/checkout/crlf.c +++ b/tests/checkout/crlf.c @@ -11,9 +11,9 @@ static git_repository *g_repo; static const char *systype; -static git_buf expected_fixture = GIT_BUF_INIT; +static git_str expected_fixture = GIT_STR_INIT; -static int unlink_file(void *payload, git_buf *path) +static int unlink_file(void *payload, git_str *path) { char *fn; @@ -30,7 +30,7 @@ static int unlink_file(void *payload, git_buf *path) void test_checkout_crlf__initialize(void) { - git_buf reponame = GIT_BUF_INIT; + git_str reponame = GIT_STR_INIT; g_repo = cl_git_sandbox_init("crlf"); @@ -38,7 +38,7 @@ void test_checkout_crlf__initialize(void) * remove the contents of the working directory so that we can * check out over it. */ - cl_git_pass(git_buf_puts(&reponame, "crlf")); + cl_git_pass(git_str_puts(&reponame, "crlf")); cl_git_pass(git_path_direach(&reponame, 0, unlink_file, NULL)); if (GIT_EOL_NATIVE == GIT_EOL_CRLF) @@ -46,7 +46,7 @@ void test_checkout_crlf__initialize(void) else systype = "posix"; - git_buf_dispose(&reponame); + git_str_dispose(&reponame); } void test_checkout_crlf__cleanup(void) @@ -55,7 +55,7 @@ void test_checkout_crlf__cleanup(void) if (expected_fixture.size) { cl_fixture_cleanup(expected_fixture.ptr); - git_buf_dispose(&expected_fixture); + git_str_dispose(&expected_fixture); } } @@ -66,11 +66,11 @@ struct compare_data const char *attrs; }; -static int compare_file(void *payload, git_buf *actual_path) +static int compare_file(void *payload, git_str *actual_path) { - git_buf expected_path = GIT_BUF_INIT; - git_buf actual_contents = GIT_BUF_INIT; - git_buf expected_contents = GIT_BUF_INIT; + git_str expected_path = GIT_STR_INIT; + git_str actual_contents = GIT_STR_INIT; + git_str expected_contents = GIT_STR_INIT; struct compare_data *cd = payload; bool failed = true; int cmp_git, cmp_gitattributes; @@ -85,7 +85,7 @@ static int compare_file(void *payload, git_buf *actual_path) goto done; } - cl_git_pass(git_buf_joinpath(&expected_path, cd->dirname, basename)); + cl_git_pass(git_str_joinpath(&expected_path, cd->dirname, basename)); if (!git_path_isfile(expected_path.ptr) || !git_path_isfile(actual_path->ptr)) @@ -105,61 +105,61 @@ static int compare_file(void *payload, git_buf *actual_path) done: if (failed) { - git_buf details = GIT_BUF_INIT; - git_buf_printf(&details, "filename=%s, system=%s, autocrlf=%s, attrs={%s}", + git_str details = GIT_STR_INIT; + git_str_printf(&details, "filename=%s, system=%s, autocrlf=%s, attrs={%s}", git_path_basename(actual_path->ptr), systype, cd->autocrlf, cd->attrs); clar__fail(__FILE__, __func__, __LINE__, "checked out contents did not match expected", details.ptr, 0); - git_buf_dispose(&details); + git_str_dispose(&details); } git__free(basename); - git_buf_dispose(&expected_contents); - git_buf_dispose(&actual_contents); - git_buf_dispose(&expected_path); + git_str_dispose(&expected_contents); + git_str_dispose(&actual_contents); + git_str_dispose(&expected_path); return 0; } static void test_checkout(const char *autocrlf, const char *attrs) { - git_buf attrbuf = GIT_BUF_INIT; - git_buf expected_dirname = GIT_BUF_INIT; - git_buf systype_and_direction = GIT_BUF_INIT; - git_buf sandboxname = GIT_BUF_INIT; - git_buf reponame = GIT_BUF_INIT; + git_str attrbuf = GIT_STR_INIT; + git_str expected_dirname = GIT_STR_INIT; + git_str systype_and_direction = GIT_STR_INIT; + git_str sandboxname = GIT_STR_INIT; + git_str reponame = GIT_STR_INIT; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; struct compare_data compare_data = { NULL, autocrlf, attrs }; const char *c; - cl_git_pass(git_buf_puts(&reponame, "crlf")); + cl_git_pass(git_str_puts(&reponame, "crlf")); - cl_git_pass(git_buf_puts(&systype_and_direction, systype)); - cl_git_pass(git_buf_puts(&systype_and_direction, "_to_workdir")); + cl_git_pass(git_str_puts(&systype_and_direction, systype)); + cl_git_pass(git_str_puts(&systype_and_direction, "_to_workdir")); - cl_git_pass(git_buf_puts(&sandboxname, "autocrlf_")); - cl_git_pass(git_buf_puts(&sandboxname, autocrlf)); + cl_git_pass(git_str_puts(&sandboxname, "autocrlf_")); + cl_git_pass(git_str_puts(&sandboxname, autocrlf)); if (*attrs) { - cl_git_pass(git_buf_puts(&sandboxname, ",")); + cl_git_pass(git_str_puts(&sandboxname, ",")); for (c = attrs; *c; c++) { if (*c == ' ') - cl_git_pass(git_buf_putc(&sandboxname, ',')); + cl_git_pass(git_str_putc(&sandboxname, ',')); else if (*c == '=') - cl_git_pass(git_buf_putc(&sandboxname, '_')); + cl_git_pass(git_str_putc(&sandboxname, '_')); else - cl_git_pass(git_buf_putc(&sandboxname, *c)); + cl_git_pass(git_str_putc(&sandboxname, *c)); } - cl_git_pass(git_buf_printf(&attrbuf, "* %s\n", attrs)); + cl_git_pass(git_str_printf(&attrbuf, "* %s\n", attrs)); cl_git_mkfile("crlf/.gitattributes", attrbuf.ptr); } cl_repo_set_string(g_repo, "core.autocrlf", autocrlf); - cl_git_pass(git_buf_joinpath(&expected_dirname, systype_and_direction.ptr, sandboxname.ptr)); - cl_git_pass(git_buf_joinpath(&expected_fixture, "crlf_data", expected_dirname.ptr)); + cl_git_pass(git_str_joinpath(&expected_dirname, systype_and_direction.ptr, sandboxname.ptr)); + cl_git_pass(git_str_joinpath(&expected_fixture, "crlf_data", expected_dirname.ptr)); cl_fixture_sandbox(expected_fixture.ptr); opts.checkout_strategy = GIT_CHECKOUT_FORCE; @@ -169,14 +169,14 @@ static void test_checkout(const char *autocrlf, const char *attrs) cl_git_pass(git_path_direach(&reponame, 0, compare_file, &compare_data)); cl_fixture_cleanup(expected_fixture.ptr); - git_buf_dispose(&expected_fixture); - - git_buf_dispose(&attrbuf); - git_buf_dispose(&expected_fixture); - git_buf_dispose(&expected_dirname); - git_buf_dispose(&sandboxname); - git_buf_dispose(&systype_and_direction); - git_buf_dispose(&reponame); + git_str_dispose(&expected_fixture); + + git_str_dispose(&attrbuf); + git_str_dispose(&expected_fixture); + git_str_dispose(&expected_dirname); + git_str_dispose(&sandboxname); + git_str_dispose(&systype_and_direction); + git_str_dispose(&reponame); } static void empty_workdir(const char *name) diff --git a/tests/checkout/icase.c b/tests/checkout/icase.c index 077d24cd3af..6c30765a369 100644 --- a/tests/checkout/icase.c +++ b/tests/checkout/icase.c @@ -46,7 +46,7 @@ void test_checkout_icase__cleanup(void) static char *get_filename(const char *in) { char *search_dirname, *search_filename, *filename = NULL; - git_buf out = GIT_BUF_INIT; + git_str out = GIT_STR_INIT; DIR *dir; struct dirent *de; @@ -57,8 +57,8 @@ static char *get_filename(const char *in) while ((de = readdir(dir))) { if (strcasecmp(de->d_name, search_filename) == 0) { - git_buf_join(&out, '/', search_dirname, de->d_name); - filename = git_buf_detach(&out); + git_str_join(&out, '/', search_dirname, de->d_name); + filename = git_str_detach(&out); break; } } @@ -67,7 +67,7 @@ static char *get_filename(const char *in) git__free(search_dirname); git__free(search_filename); - git_buf_dispose(&out); + git_str_dispose(&out); return filename; } diff --git a/tests/checkout/index.c b/tests/checkout/index.c index 5089753656d..13eecc9848f 100644 --- a/tests/checkout/index.c +++ b/tests/checkout/index.c @@ -8,7 +8,7 @@ #include "repo/repo_helpers.h" static git_repository *g_repo; -static git_buf g_global_path = GIT_BUF_INIT; +static git_str g_global_path = GIT_STR_INIT; void test_checkout_index__initialize(void) { @@ -33,7 +33,7 @@ void test_checkout_index__cleanup(void) { git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, g_global_path.ptr); - git_buf_dispose(&g_global_path); + git_str_dispose(&g_global_path); cl_git_sandbox_cleanup(); @@ -203,14 +203,14 @@ void test_checkout_index__honor_coreautocrlf_setting_set_to_true(void) static void populate_symlink_workdir(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_repository *repo; git_remote *origin; git_object *target; const char *url = git_repository_path(g_repo); - cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), "symlink.git")); + cl_git_pass(git_str_joinpath(&path, clar_sandbox_path(), "symlink.git")); cl_git_pass(git_repository_init(&repo, path.ptr, true)); cl_git_pass(git_repository_set_workdir(repo, "symlink", 1)); @@ -226,7 +226,7 @@ static void populate_symlink_workdir(void) git_object_free(target); git_repository_free(repo); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_checkout_index__honor_coresymlinks_default_true(void) @@ -808,7 +808,7 @@ void test_checkout_index__writes_conflict_file(void) { git_index *index; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - git_buf conflicting_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT; cl_git_pass(git_repository_index(&index, g_repo)); @@ -824,7 +824,7 @@ void test_checkout_index__writes_conflict_file(void) "=======\n" "this file is changed in branch and master\n" ">>>>>>> theirs\n") == 0); - git_buf_dispose(&conflicting_buf); + git_str_dispose(&conflicting_buf); git_index_free(index); } @@ -855,7 +855,7 @@ void test_checkout_index__conflicts_honor_coreautocrlf(void) #ifdef GIT_WIN32 git_index *index; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - git_buf conflicting_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT; cl_git_pass(p_unlink("./testrepo/.gitattributes")); cl_repo_set_bool(g_repo, "core.autocrlf", true); @@ -874,7 +874,7 @@ void test_checkout_index__conflicts_honor_coreautocrlf(void) "=======\r\n" "this file is changed in branch and master\r\n" ">>>>>>> theirs\r\n") == 0); - git_buf_dispose(&conflicting_buf); + git_str_dispose(&conflicting_buf); git_index_free(index); #endif diff --git a/tests/checkout/nasty.c b/tests/checkout/nasty.c index 611e850d392..a1b3164be60 100644 --- a/tests/checkout/nasty.c +++ b/tests/checkout/nasty.c @@ -3,7 +3,6 @@ #include "git2/checkout.h" #include "repository.h" -#include "buffer.h" #include "futils.h" static const char *repo_name = "nasty"; @@ -28,9 +27,9 @@ static void test_checkout_passes(const char *refname, const char *filename) git_oid commit_id; git_commit *commit; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&path, repo_name, filename)); + cl_git_pass(git_str_joinpath(&path, repo_name, filename)); cl_git_pass(git_reference_name_to_id(&commit_id, repo, refname)); cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); @@ -42,7 +41,7 @@ static void test_checkout_passes(const char *refname, const char *filename) cl_assert(!git_path_exists(path.ptr)); git_commit_free(commit); - git_buf_dispose(&path); + git_str_dispose(&path); } static void test_checkout_fails(const char *refname, const char *filename) @@ -50,9 +49,9 @@ static void test_checkout_fails(const char *refname, const char *filename) git_oid commit_id; git_commit *commit; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&path, repo_name, filename)); + cl_git_pass(git_str_joinpath(&path, repo_name, filename)); cl_git_pass(git_reference_name_to_id(&commit_id, repo, refname)); cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); @@ -63,7 +62,7 @@ static void test_checkout_fails(const char *refname, const char *filename) cl_assert(!git_path_exists(path.ptr)); git_commit_free(commit); - git_buf_dispose(&path); + git_str_dispose(&path); } /* A tree that contains ".git" as a tree, with a blob inside diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c index 3241a3eb767..cdfb456b77a 100644 --- a/tests/checkout/tree.c +++ b/tests/checkout/tree.c @@ -3,7 +3,6 @@ #include "git2/checkout.h" #include "repository.h" -#include "buffer.h" #include "futils.h" static git_repository *g_repo; @@ -519,7 +518,7 @@ void assert_conflict( git_index *index; git_object *hack_tree; git_reference *branch, *head; - git_buf file_path = GIT_BUF_INIT; + git_str file_path = GIT_STR_INIT; cl_git_pass(git_repository_index(&index, g_repo)); @@ -549,9 +548,9 @@ void assert_conflict( g_object = NULL; /* Create a conflicting file */ - cl_git_pass(git_buf_joinpath(&file_path, "./testrepo", entry_path)); - cl_git_mkfile(git_buf_cstr(&file_path), new_content); - git_buf_dispose(&file_path); + cl_git_pass(git_str_joinpath(&file_path, "./testrepo", entry_path)); + cl_git_mkfile(git_str_cstr(&file_path), new_content); + git_str_dispose(&file_path); /* Trying to checkout the original commit */ cl_git_pass(git_revparse_single(&g_object, g_repo, commit_sha)); @@ -1037,17 +1036,17 @@ void test_checkout_tree__filemode_preserved_in_index(void) mode_t read_filemode(const char *path) { - git_buf fullpath = GIT_BUF_INIT; + git_str fullpath = GIT_STR_INIT; struct stat st; mode_t result; - git_buf_joinpath(&fullpath, "testrepo", path); + git_str_joinpath(&fullpath, "testrepo", path); cl_must_pass(p_stat(fullpath.ptr, &st)); result = GIT_PERMS_IS_EXEC(st.st_mode) ? GIT_FILEMODE_BLOB_EXECUTABLE : GIT_FILEMODE_BLOB; - git_buf_dispose(&fullpath); + git_str_dispose(&fullpath); return result; } @@ -1317,7 +1316,7 @@ void test_checkout_tree__caches_attributes_during_checkout(void) git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_oid oid; git_object *obj = NULL; - git_buf ident1 = GIT_BUF_INIT, ident2 = GIT_BUF_INIT; + git_str ident1 = GIT_STR_INIT, ident2 = GIT_STR_INIT; char *ident_paths[] = { "ident1.txt", "ident2.txt" }; opts.progress_cb = update_attr_callback; @@ -1346,8 +1345,8 @@ void test_checkout_tree__caches_attributes_during_checkout(void) cl_assert_equal_strn(ident1.ptr, "# $Id: ", 7); cl_assert_equal_strn(ident2.ptr, "# $Id: ", 7); - git_buf_dispose(&ident1); - git_buf_dispose(&ident2); + git_str_dispose(&ident1); + git_str_dispose(&ident2); git_object_free(obj); } @@ -1679,6 +1678,6 @@ void test_checkout_tree__dry_run(void) /* check that notify callback was invoked */ cl_assert_equal_i(ct.n_updates, 2); - + git_object_free(obj); } diff --git a/tests/checkout/typechange.c b/tests/checkout/typechange.c index db3f02a5c9c..205ce657f9e 100644 --- a/tests/checkout/typechange.c +++ b/tests/checkout/typechange.c @@ -90,7 +90,7 @@ static void assert_workdir_matches_tree( git_object *obj; git_tree *tree; size_t i, max_i; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; if (!root) root = git_repository_workdir(repo); @@ -106,7 +106,7 @@ static void assert_workdir_matches_tree( const git_tree_entry *te = git_tree_entry_byindex(tree, i); cl_assert(te); - cl_git_pass(git_buf_joinpath(&path, root, git_tree_entry_name(te))); + cl_git_pass(git_str_joinpath(&path, root, git_tree_entry_name(te))); switch (git_tree_entry_type(te)) { case GIT_OBJECT_COMMIT: @@ -139,7 +139,7 @@ static void assert_workdir_matches_tree( } git_tree_free(tree); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_checkout_typechange__checkout_typechanges_safe(void) @@ -226,31 +226,31 @@ static void force_create_file(const char *file) static int make_submodule_dirty(git_submodule *sm, const char *name, void *payload) { - git_buf submodulepath = GIT_BUF_INIT; - git_buf dirtypath = GIT_BUF_INIT; + git_str submodulepath = GIT_STR_INIT; + git_str dirtypath = GIT_STR_INIT; git_repository *submodule_repo; GIT_UNUSED(name); GIT_UNUSED(payload); /* remove submodule directory in preparation for init and repo_init */ - cl_git_pass(git_buf_joinpath( + cl_git_pass(git_str_joinpath( &submodulepath, git_repository_workdir(g_repo), git_submodule_path(sm) )); - git_futils_rmdir_r(git_buf_cstr(&submodulepath), NULL, GIT_RMDIR_REMOVE_FILES); + git_futils_rmdir_r(git_str_cstr(&submodulepath), NULL, GIT_RMDIR_REMOVE_FILES); /* initialize submodule's repository */ cl_git_pass(git_submodule_repo_init(&submodule_repo, sm, 0)); /* create a file in the submodule workdir to make it dirty */ cl_git_pass( - git_buf_joinpath(&dirtypath, git_repository_workdir(submodule_repo), "dirty")); - force_create_file(git_buf_cstr(&dirtypath)); + git_str_joinpath(&dirtypath, git_repository_workdir(submodule_repo), "dirty")); + force_create_file(git_str_cstr(&dirtypath)); - git_buf_dispose(&dirtypath); - git_buf_dispose(&submodulepath); + git_str_dispose(&dirtypath); + git_str_dispose(&submodulepath); git_repository_free(submodule_repo); return 0; diff --git a/tests/cherrypick/bare.c b/tests/cherrypick/bare.c index 50e8d86006a..f90ce022602 100644 --- a/tests/cherrypick/bare.c +++ b/tests/cherrypick/bare.c @@ -1,7 +1,6 @@ #include "clar.h" #include "clar_libgit2.h" -#include "buffer.h" #include "futils.h" #include "git2/cherrypick.h" diff --git a/tests/cherrypick/workdir.c b/tests/cherrypick/workdir.c index 10e8c2d8b4f..f7765f2c277 100644 --- a/tests/cherrypick/workdir.c +++ b/tests/cherrypick/workdir.c @@ -1,7 +1,6 @@ #include "clar.h" #include "clar_libgit2.h" -#include "buffer.h" #include "futils.h" #include "git2/cherrypick.h" @@ -140,7 +139,7 @@ void test_cherrypick_workdir__conflicts(void) { git_commit *head = NULL, *commit = NULL; git_oid head_oid, cherry_oid; - git_buf conflicting_buf = GIT_BUF_INIT, mergemsg_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT, mergemsg_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { { 0100644, "242e7977ba73637822ffb265b46004b9b0e5153b", 0, "file1.txt" }, @@ -168,7 +167,7 @@ void test_cherrypick_workdir__conflicts(void) cl_git_pass(git_futils_readbuffer(&mergemsg_buf, TEST_REPO_PATH "/.git/MERGE_MSG")); - cl_assert(strcmp(git_buf_cstr(&mergemsg_buf), + cl_assert(strcmp(git_str_cstr(&mergemsg_buf), "Change all files\n" \ "\n" \ "Conflicts:\n" \ @@ -178,7 +177,7 @@ void test_cherrypick_workdir__conflicts(void) cl_git_pass(git_futils_readbuffer(&conflicting_buf, TEST_REPO_PATH "/file2.txt")); - cl_assert(strcmp(git_buf_cstr(&conflicting_buf), + cl_assert(strcmp(git_str_cstr(&conflicting_buf), "!File 2\n" \ "File 2\n" \ "File 2\n" \ @@ -204,7 +203,7 @@ void test_cherrypick_workdir__conflicts(void) cl_git_pass(git_futils_readbuffer(&conflicting_buf, TEST_REPO_PATH "/file3.txt")); - cl_assert(strcmp(git_buf_cstr(&conflicting_buf), + cl_assert(strcmp(git_str_cstr(&conflicting_buf), "!File 3\n" \ "File 3\n" \ "File 3\n" \ @@ -228,8 +227,8 @@ void test_cherrypick_workdir__conflicts(void) git_commit_free(commit); git_commit_free(head); - git_buf_dispose(&mergemsg_buf); - git_buf_dispose(&conflicting_buf); + git_str_dispose(&mergemsg_buf); + git_str_dispose(&conflicting_buf); } /* git reset --hard bafbf6912c09505ac60575cd43d3f2aba3bd84d8 @@ -324,7 +323,7 @@ void test_cherrypick_workdir__both_renamed(void) { git_commit *head, *commit; git_oid head_oid, cherry_oid; - git_buf mergemsg_buf = GIT_BUF_INIT; + git_str mergemsg_buf = GIT_STR_INIT; git_cherrypick_options opts = GIT_CHERRYPICK_OPTIONS_INIT; struct merge_index_entry merge_index_entries[] = { @@ -350,7 +349,7 @@ void test_cherrypick_workdir__both_renamed(void) cl_git_pass(git_futils_readbuffer(&mergemsg_buf, TEST_REPO_PATH "/.git/MERGE_MSG")); - cl_assert(strcmp(git_buf_cstr(&mergemsg_buf), + cl_assert(strcmp(git_str_cstr(&mergemsg_buf), "Renamed file3.txt -> file3.txt.renamed\n" \ "\n" \ "Conflicts:\n" \ @@ -358,7 +357,7 @@ void test_cherrypick_workdir__both_renamed(void) "\tfile3.txt.renamed\n" \ "\tfile3.txt.renamed_on_branch\n") == 0); - git_buf_dispose(&mergemsg_buf); + git_str_dispose(&mergemsg_buf); git_commit_free(commit); git_commit_free(head); } diff --git a/tests/clar_libgit2.c b/tests/clar_libgit2.c index c4550c32a8b..adea597e35e 100644 --- a/tests/clar_libgit2.c +++ b/tests/clar_libgit2.c @@ -68,7 +68,7 @@ void cl_git_rmfile(const char *filename) char *cl_getenv(const char *name) { - git_buf out = GIT_BUF_INIT; + git_str out = GIT_STR_INIT; int error = git__getenv(&out, name); cl_assert(error >= 0 || error == GIT_ENOTFOUND); @@ -83,7 +83,7 @@ char *cl_getenv(const char *name) return dup; } - return git_buf_detach(&out); + return git_str_detach(&out); } bool cl_is_env_set(const char *name) @@ -278,11 +278,11 @@ const char* cl_git_path_url(const char *path) static char url[4096 + 1]; const char *in_buf; - git_buf path_buf = GIT_BUF_INIT; - git_buf url_buf = GIT_BUF_INIT; + git_str path_buf = GIT_STR_INIT; + git_str url_buf = GIT_STR_INIT; cl_git_pass(git_path_prettify_dir(&path_buf, path, NULL)); - cl_git_pass(git_buf_puts(&url_buf, "file://")); + cl_git_pass(git_str_puts(&url_buf, "file://")); #ifdef GIT_WIN32 /* @@ -294,29 +294,29 @@ const char* cl_git_path_url(const char *path) * *nix: file:///usr/home/... * Windows: file:///C:/Users/... */ - cl_git_pass(git_buf_putc(&url_buf, '/')); + cl_git_pass(git_str_putc(&url_buf, '/')); #endif - in_buf = git_buf_cstr(&path_buf); + in_buf = git_str_cstr(&path_buf); /* * A very hacky Url encoding that only takes care of escaping the spaces */ while (*in_buf) { if (*in_buf == ' ') - cl_git_pass(git_buf_puts(&url_buf, "%20")); + cl_git_pass(git_str_puts(&url_buf, "%20")); else - cl_git_pass(git_buf_putc(&url_buf, *in_buf)); + cl_git_pass(git_str_putc(&url_buf, *in_buf)); in_buf++; } cl_assert(url_buf.size < sizeof(url) - 1); - strncpy(url, git_buf_cstr(&url_buf), sizeof(url) - 1); + strncpy(url, git_str_cstr(&url_buf), sizeof(url) - 1); url[sizeof(url) - 1] = '\0'; - git_buf_dispose(&url_buf); - git_buf_dispose(&path_buf); + git_str_dispose(&url_buf); + git_str_dispose(&path_buf); return url; } @@ -324,15 +324,15 @@ const char *cl_git_sandbox_path(int is_dir, ...) { const char *path = NULL; static char _temp[GIT_PATH_MAX]; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; va_list arg; - cl_git_pass(git_buf_sets(&buf, clar_sandbox_path())); + cl_git_pass(git_str_sets(&buf, clar_sandbox_path())); va_start(arg, is_dir); while ((path = va_arg(arg, const char *)) != NULL) { - cl_git_pass(git_buf_joinpath(&buf, buf.ptr, path)); + cl_git_pass(git_str_joinpath(&buf, buf.ptr, path)); } va_end(arg); @@ -341,10 +341,10 @@ const char *cl_git_sandbox_path(int is_dir, ...) git_path_to_dir(&buf); /* make sure we won't truncate */ - cl_assert(git_buf_len(&buf) < sizeof(_temp)); - git_buf_copy_cstr(_temp, sizeof(_temp), &buf); + cl_assert(git_str_len(&buf) < sizeof(_temp)); + git_str_copy_cstr(_temp, sizeof(_temp), &buf); - git_buf_dispose(&buf); + git_str_dispose(&buf); return _temp; } @@ -354,7 +354,7 @@ typedef struct { size_t filename_len; } remove_data; -static int remove_placeholders_recurs(void *_data, git_buf *path) +static int remove_placeholders_recurs(void *_data, git_str *path) { remove_data *data = (remove_data *)_data; size_t pathlen; @@ -380,12 +380,12 @@ int cl_git_remove_placeholders(const char *directory_path, const char *filename) { int error; remove_data data; - git_buf buffer = GIT_BUF_INIT; + git_str buffer = GIT_STR_INIT; if (git_path_isdir(directory_path) == false) return -1; - if (git_buf_sets(&buffer, directory_path) < 0) + if (git_str_sets(&buffer, directory_path) < 0) return -1; data.filename = filename; @@ -393,7 +393,7 @@ int cl_git_remove_placeholders(const char *directory_path, const char *filename) error = remove_placeholders_recurs(&data, &buffer); - git_buf_dispose(&buffer); + git_str_dispose(&buffer); return error; } @@ -548,30 +548,26 @@ void clar__assert_equal_file( (size_t)expected_bytes, (size_t)total_bytes); } -static char *_cl_restore_home = NULL; +static git_buf _cl_restore_home = GIT_BUF_INIT; void cl_fake_home_cleanup(void *payload) { - char *restore = _cl_restore_home; - _cl_restore_home = NULL; - GIT_UNUSED(payload); - if (restore) { + if (_cl_restore_home.ptr) { cl_git_pass(git_libgit2_opts( - GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, restore)); - git__free(restore); + GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, _cl_restore_home.ptr)); + git_buf_dispose(&_cl_restore_home); } } void cl_fake_home(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_git_pass(git_libgit2_opts( - GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &path)); + GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &_cl_restore_home)); - _cl_restore_home = git_buf_detach(&path); cl_set_cleanup(cl_fake_home_cleanup, NULL); if (!git_path_exists("home")) @@ -579,14 +575,14 @@ void cl_fake_home(void) cl_git_pass(git_path_prettify(&path, "home", NULL)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr)); - git_buf_dispose(&path); + git_str_dispose(&path); } void cl_sandbox_set_search_path_defaults(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; - git_buf_joinpath(&path, clar_sandbox_path(), "__config"); + git_str_joinpath(&path, clar_sandbox_path(), "__config"); if (!git_path_exists(path.ptr)) cl_must_pass(p_mkdir(path.ptr, 0777)); @@ -600,18 +596,18 @@ void cl_sandbox_set_search_path_defaults(void) git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_PROGRAMDATA, path.ptr); - git_buf_dispose(&path); + git_str_dispose(&path); } #ifdef GIT_WIN32 bool cl_sandbox_supports_8dot3(void) { - git_buf longpath = GIT_BUF_INIT; + git_str longpath = GIT_STR_INIT; char *shortname; bool supported; cl_git_pass( - git_buf_joinpath(&longpath, clar_sandbox_path(), "longer_than_8dot3")); + git_str_joinpath(&longpath, clar_sandbox_path(), "longer_than_8dot3")); cl_git_write2file(longpath.ptr, "", 0, O_RDWR|O_CREAT, 0666); shortname = git_win32_path_8dot3_name(longpath.ptr); @@ -619,7 +615,7 @@ bool cl_sandbox_supports_8dot3(void) supported = (shortname != NULL); git__free(shortname); - git_buf_dispose(&longpath); + git_str_dispose(&longpath); return supported; } diff --git a/tests/clar_libgit2_timer.c b/tests/clar_libgit2_timer.c index 737506da2c3..2330f9351d1 100644 --- a/tests/clar_libgit2_timer.c +++ b/tests/clar_libgit2_timer.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "clar_libgit2_timer.h" -#include "buffer.h" void cl_perf_timer__init(cl_perf_timer *t) { diff --git a/tests/clone/local.c b/tests/clone/local.c index b90ff310752..e0bd74df78a 100644 --- a/tests/clone/local.c +++ b/tests/clone/local.c @@ -2,42 +2,41 @@ #include "git2/clone.h" #include "clone.h" -#include "buffer.h" #include "path.h" #include "posix.h" #include "futils.h" -static int file_url(git_buf *buf, const char *host, const char *path) +static int file_url(git_str *buf, const char *host, const char *path) { if (path[0] == '/') path++; - git_buf_clear(buf); - return git_buf_printf(buf, "file://%s/%s", host, path); + git_str_clear(buf); + return git_str_printf(buf, "file://%s/%s", host, path); } #ifdef GIT_WIN32 -static int git_style_unc_path(git_buf *buf, const char *host, const char *path) +static int git_style_unc_path(git_str *buf, const char *host, const char *path) { - git_buf_clear(buf); + git_str_clear(buf); if (host) - git_buf_printf(buf, "//%s/", host); + git_str_printf(buf, "//%s/", host); if (path[0] == '/') path++; if (git__isalpha(path[0]) && path[1] == ':' && path[2] == '/') { - git_buf_printf(buf, "%c$/", path[0]); + git_str_printf(buf, "%c$/", path[0]); path += 3; } - git_buf_puts(buf, path); + git_str_puts(buf, path); - return git_buf_oom(buf) ? -1 : 0; + return git_str_oom(buf) ? -1 : 0; } -static int unc_path(git_buf *buf, const char *host, const char *path) +static int unc_path(git_str *buf, const char *host, const char *path) { char *c; @@ -54,7 +53,7 @@ static int unc_path(git_buf *buf, const char *host, const char *path) void test_clone_local__should_clone_local(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; /* we use a fixture path because it needs to exist for us to want to clone */ const char *path = cl_fixture("testrepo.git"); @@ -79,8 +78,8 @@ void test_clone_local__should_clone_local(void) /* Ensure that file:/// urls are percent decoded: .git == %2e%67%69%74 */ cl_git_pass(file_url(&buf, "", path)); - git_buf_shorten(&buf, 4); - cl_git_pass(git_buf_puts(&buf, "%2e%67%69%74")); + git_str_shorten(&buf, 4); + cl_git_pass(git_str_puts(&buf, "%2e%67%69%74")); cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO)); cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL)); cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS)); @@ -91,14 +90,14 @@ void test_clone_local__should_clone_local(void) cl_assert_equal_i(1, git_clone__should_clone_local(path, GIT_CLONE_LOCAL_NO_LINKS)); cl_assert_equal_i(0, git_clone__should_clone_local(path, GIT_CLONE_NO_LOCAL)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } void test_clone_local__hardlinks(void) { git_repository *repo; git_clone_options opts = GIT_CLONE_OPTIONS_INIT; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; struct stat st; /* @@ -117,21 +116,21 @@ void test_clone_local__hardlinks(void) cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone2.git", &opts)); #ifndef GIT_WIN32 - git_buf_clear(&buf); - cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125")); + git_str_clear(&buf); + cl_git_pass(git_str_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125")); cl_git_pass(p_stat(buf.ptr, &st)); cl_assert_equal_i(2, st.st_nlink); #endif git_repository_free(repo); - git_buf_clear(&buf); + git_str_clear(&buf); opts.local = GIT_CLONE_LOCAL_NO_LINKS; cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone3.git", &opts)); - git_buf_clear(&buf); - cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125")); + git_str_clear(&buf); + cl_git_pass(git_str_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125")); cl_git_pass(p_stat(buf.ptr, &st)); cl_assert_equal_i(1, st.st_nlink); @@ -142,14 +141,14 @@ void test_clone_local__hardlinks(void) cl_git_pass(git_clone(&repo, "./clone.git", "./clone4.git", NULL)); #ifndef GIT_WIN32 - git_buf_clear(&buf); - cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125")); + git_str_clear(&buf); + cl_git_pass(git_str_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125")); cl_git_pass(p_stat(buf.ptr, &st)); cl_assert_equal_i(3, st.st_nlink); #endif - git_buf_dispose(&buf); + git_str_dispose(&buf); git_repository_free(repo); cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES)); @@ -164,7 +163,7 @@ void test_clone_local__standard_unc_paths_are_written_git_style(void) git_repository *repo; git_remote *remote; git_clone_options opts = GIT_CLONE_OPTIONS_INIT; - git_buf unc = GIT_BUF_INIT, git_unc = GIT_BUF_INIT; + git_str unc = GIT_STR_INIT, git_unc = GIT_STR_INIT; /* we use a fixture path because it needs to exist for us to want to clone */ const char *path = cl_fixture("testrepo.git"); @@ -179,8 +178,8 @@ void test_clone_local__standard_unc_paths_are_written_git_style(void) git_remote_free(remote); git_repository_free(repo); - git_buf_dispose(&unc); - git_buf_dispose(&git_unc); + git_str_dispose(&unc); + git_str_dispose(&git_unc); cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES)); #endif @@ -192,7 +191,7 @@ void test_clone_local__git_style_unc_paths(void) git_repository *repo; git_remote *remote; git_clone_options opts = GIT_CLONE_OPTIONS_INIT; - git_buf git_unc = GIT_BUF_INIT; + git_str git_unc = GIT_STR_INIT; /* we use a fixture path because it needs to exist for us to want to clone */ const char *path = cl_fixture("testrepo.git"); @@ -206,7 +205,7 @@ void test_clone_local__git_style_unc_paths(void) git_remote_free(remote); git_repository_free(repo); - git_buf_dispose(&git_unc); + git_str_dispose(&git_unc); cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES)); #endif diff --git a/tests/clone/nonetwork.c b/tests/clone/nonetwork.c index ec12fee18a1..7625a218306 100644 --- a/tests/clone/nonetwork.c +++ b/tests/clone/nonetwork.c @@ -145,15 +145,15 @@ void test_clone_nonetwork__cope_with_already_existing_directory(void) void test_clone_nonetwork__can_prevent_the_checkout_of_a_standard_repo(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; g_options.checkout_opts.checkout_strategy = 0; cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); - cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&path))); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); + cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&path))); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_clone_nonetwork__can_checkout_given_branch(void) @@ -304,9 +304,9 @@ static void assert_correct_reflog(const char *name) { git_reflog *log; const git_reflog_entry *entry; - git_buf expected_message = GIT_BUF_INIT; + git_str expected_message = GIT_STR_INIT; - git_buf_printf(&expected_message, + git_str_printf(&expected_message, "clone: from %s", cl_git_fixture_url("testrepo.git")); cl_git_pass(git_reflog_read(&log, g_repo, name)); @@ -316,7 +316,7 @@ static void assert_correct_reflog(const char *name) git_reflog_free(log); - git_buf_dispose(&expected_message); + git_str_dispose(&expected_message); } void test_clone_nonetwork__clone_updates_reflog_properly(void) diff --git a/tests/commit/parse.c b/tests/commit/parse.c index f0a31de9a43..04366d7d277 100644 --- a/tests/commit/parse.c +++ b/tests/commit/parse.c @@ -445,15 +445,15 @@ cpxtDQQMGYFpXK/71stq\n\ cl_git_pass(git_commit_header_field(&buf, commit, "tree")); cl_assert_equal_s("6b79e22d69bf46e289df0345a14ca059dfc9bdf6", buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); cl_git_pass(git_commit_header_field(&buf, commit, "parent")); cl_assert_equal_s("34734e478d6cf50c27c9d69026d93974d052c454", buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); cl_git_pass(git_commit_header_field(&buf, commit, "gpgsig")); cl_assert_equal_s(gpgsig, buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); cl_git_fail_with(GIT_ENOTFOUND, git_commit_header_field(&buf, commit, "awesomeness")); cl_git_fail_with(GIT_ENOTFOUND, git_commit_header_field(&buf, commit, "par")); @@ -513,7 +513,6 @@ committer Some User 1454537944 -0700\n\ \n\ corrupt signature\n"; - cl_git_pass(git_repository_odb__weakptr(&odb, g_repo)); cl_git_pass(git_odb_write(&commit_id, odb, passing_commit_cases[4], strlen(passing_commit_cases[4]), GIT_OBJECT_COMMIT)); @@ -521,13 +520,16 @@ corrupt signature\n"; cl_assert_equal_s(gpgsig, signature.ptr); cl_assert_equal_s(data, signed_data.ptr); - git_buf_clear(&signature); - git_buf_clear(&signed_data); + git_buf_dispose(&signature); + git_buf_dispose(&signed_data); cl_git_pass(git_commit_extract_signature(&signature, &signed_data, g_repo, &commit_id, "gpgsig")); cl_assert_equal_s(gpgsig, signature.ptr); cl_assert_equal_s(data, signed_data.ptr); + git_buf_dispose(&signature); + git_buf_dispose(&signed_data); + /* Try to parse a tree */ cl_git_pass(git_oid_fromstr(&commit_id, "45dd856fdd4d89b884c340ba0e047752d9b085d6")); cl_git_fail_with(GIT_ENOTFOUND, git_commit_extract_signature(&signature, &signed_data, g_repo, &commit_id, NULL)); @@ -539,15 +541,11 @@ corrupt signature\n"; cl_assert_equal_i(GIT_ERROR_OBJECT, git_error_last()->klass); /* Parse the commit with a single-line signature */ - git_buf_clear(&signature); - git_buf_clear(&signed_data); cl_git_pass(git_odb_write(&commit_id, odb, oneline_signature, strlen(oneline_signature), GIT_OBJECT_COMMIT)); cl_git_pass(git_commit_extract_signature(&signature, &signed_data, g_repo, &commit_id, NULL)); cl_assert_equal_s("bad", signature.ptr); cl_assert_equal_s(oneline_data, signed_data.ptr); - git_buf_dispose(&signature); git_buf_dispose(&signed_data); - } diff --git a/tests/config/conditionals.c b/tests/config/conditionals.c index 5858782c18e..6249dbd794e 100644 --- a/tests/config/conditionals.c +++ b/tests/config/conditionals.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "futils.h" #include "repository.h" @@ -23,43 +22,46 @@ void test_config_conditionals__cleanup(void) static void assert_condition_includes(const char *keyword, const char *path, bool expected) { - git_buf buf = GIT_BUF_INIT; + git_buf value = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_config *cfg; - cl_git_pass(git_buf_printf(&buf, "[includeIf \"%s:%s\"]\n", keyword, path)); - cl_git_pass(git_buf_puts(&buf, "path = other\n")); + cl_git_pass(git_str_printf(&buf, "[includeIf \"%s:%s\"]\n", keyword, path)); + cl_git_pass(git_str_puts(&buf, "path = other\n")); cl_git_mkfile("empty_standard_repo/.git/config", buf.ptr); cl_git_mkfile("empty_standard_repo/.git/other", "[foo]\nbar=baz\n"); _repo = cl_git_sandbox_reopen(); + git_str_dispose(&buf); + cl_git_pass(git_repository_config(&cfg, _repo)); if (expected) { - git_buf_clear(&buf); - cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar")); - cl_assert_equal_s("baz", git_buf_cstr(&buf)); + cl_git_pass(git_config_get_string_buf(&value, cfg, "foo.bar")); + cl_assert_equal_s("baz", value.ptr); } else { cl_git_fail_with(GIT_ENOTFOUND, - git_config_get_string_buf(&buf, cfg, "foo.bar")); + git_config_get_string_buf(&value, cfg, "foo.bar")); } - git_buf_dispose(&buf); + git_str_dispose(&buf); + git_buf_dispose(&value); git_config_free(cfg); } -static char *sandbox_path(git_buf *buf, const char *suffix) +static char *sandbox_path(git_str *buf, const char *suffix) { char *path = p_realpath(clar_sandbox_path(), NULL); cl_assert(path); - cl_git_pass(git_buf_attach(buf, path, 0)); - cl_git_pass(git_buf_joinpath(buf, buf->ptr, suffix)); + cl_git_pass(git_str_attach(buf, path, 0)); + cl_git_pass(git_str_joinpath(buf, buf->ptr, suffix)); return buf->ptr; } void test_config_conditionals__gitdir(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; assert_condition_includes("gitdir", ROOT_PREFIX "/", true); assert_condition_includes("gitdir", "empty_stand", false); @@ -90,17 +92,17 @@ void test_config_conditionals__gitdir(void) assert_condition_includes("gitdir", sandbox_path(&path, "Empty_Standard_Repo"), false); assert_condition_includes("gitdir", sandbox_path(&path, "Empty_Standard_Repo/"), false); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_config_conditionals__gitdir_i(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; assert_condition_includes("gitdir/i", sandbox_path(&path, "empty_standard_repo/"), true); assert_condition_includes("gitdir/i", sandbox_path(&path, "EMPTY_STANDARD_REPO/"), true); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_config_conditionals__invalid_conditional_fails(void) diff --git a/tests/config/config_helpers.c b/tests/config/config_helpers.c index d92ff1a4ee8..ecdab5bf616 100644 --- a/tests/config/config_helpers.c +++ b/tests/config/config_helpers.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "config_helpers.h" #include "repository.h" -#include "buffer.h" void assert_config_entry_existence( git_repository *repo, @@ -13,7 +12,7 @@ void assert_config_entry_existence( int result; cl_git_pass(git_repository_config__weakptr(&config, repo)); - + result = git_config_get_entry(&entry, config, name); git_config_entry_free(entry); @@ -35,7 +34,7 @@ void assert_config_entry_value( cl_git_pass(git_config_get_string_buf(&buf, config, name)); - cl_assert_equal_s(expected_value, git_buf_cstr(&buf)); + cl_assert_equal_s(expected_value, buf.ptr); git_buf_dispose(&buf); } diff --git a/tests/config/configlevel.c b/tests/config/configlevel.c index 15c469fcb83..8422d32c944 100644 --- a/tests/config/configlevel.c +++ b/tests/config/configlevel.c @@ -22,7 +22,7 @@ void test_config_configlevel__adding_the_same_level_twice_returns_EEXISTS(void) void test_config_configlevel__can_replace_a_config_file_at_an_existing_level(void) { git_config *cfg; - git_buf buf = {0}; + git_buf buf = GIT_BUF_INIT; cl_git_pass(git_config_new(&cfg)); cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config18"), diff --git a/tests/config/global.c b/tests/config/global.c index ed47d02515a..d59c39fa2e2 100644 --- a/tests/config/global.c +++ b/tests/config/global.c @@ -1,10 +1,9 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "futils.h" void test_config_global__initialize(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_git_pass(git_futils_mkdir_r("home", 0777)); cl_git_pass(git_path_prettify(&path, "home", NULL)); @@ -21,7 +20,7 @@ void test_config_global__initialize(void) cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr)); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_config_global__cleanup(void) @@ -132,24 +131,25 @@ void test_config_global__open_programdata(void) { git_config *cfg; git_repository *repo; - git_buf config_path = GIT_BUF_INIT; + git_buf dir_path = GIT_BUF_INIT; + git_str config_path = GIT_STR_INIT; git_buf var_contents = GIT_BUF_INIT; if (cl_is_env_set("GITTEST_INVASIVE_FS_STRUCTURE")) cl_skip(); cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, - GIT_CONFIG_LEVEL_PROGRAMDATA, &config_path)); + GIT_CONFIG_LEVEL_PROGRAMDATA, &dir_path)); - if (!git_path_isdir(config_path.ptr)) - cl_git_pass(p_mkdir(config_path.ptr, 0777)); + if (!git_path_isdir(dir_path.ptr)) + cl_git_pass(p_mkdir(dir_path.ptr, 0777)); - cl_git_pass(git_buf_puts(&config_path, "/config")); + cl_git_pass(git_str_joinpath(&config_path, dir_path.ptr, "config")); cl_git_pass(git_config_open_ondisk(&cfg, config_path.ptr)); cl_git_pass(git_config_set_string(cfg, "programdata.var", "even higher level")); - git_buf_dispose(&config_path); + git_str_dispose(&config_path); git_config_free(cfg); git_config_open_default(&cfg); @@ -165,6 +165,7 @@ void test_config_global__open_programdata(void) cl_assert_equal_s("even higher level", var_contents.ptr); git_config_free(cfg); + git_buf_dispose(&dir_path); git_buf_dispose(&var_contents); git_repository_free(repo); cl_fixture_cleanup("./foo.git"); diff --git a/tests/config/include.c b/tests/config/include.c index b702d621140..9328f3cf649 100644 --- a/tests/config/include.c +++ b/tests/config/include.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "futils.h" static git_config *cfg; @@ -7,14 +6,14 @@ static git_buf buf; void test_config_include__initialize(void) { - cfg = NULL; - git_buf_init(&buf, 0); + cfg = NULL; + memset(&buf, 0, sizeof(git_buf)); } void test_config_include__cleanup(void) { - git_config_free(cfg); - git_buf_dispose(&buf); + git_config_free(cfg); + git_buf_dispose(&buf); } void test_config_include__relative(void) @@ -22,19 +21,21 @@ void test_config_include__relative(void) cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config-include"))); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar.baz")); - cl_assert_equal_s("huzzah", git_buf_cstr(&buf)); + cl_assert_equal_s("huzzah", buf.ptr); } void test_config_include__absolute(void) { - cl_git_pass(git_buf_printf(&buf, "[include]\npath = %s/config-included", cl_fixture("config"))); + git_str cfgdata = GIT_STR_INIT; + cl_git_pass(git_str_printf(&cfgdata, "[include]\npath = %s/config-included", cl_fixture("config"))); + + cl_git_mkfile("config-include-absolute", cfgdata.ptr); + git_str_dispose(&cfgdata); - cl_git_mkfile("config-include-absolute", git_buf_cstr(&buf)); - git_buf_dispose(&buf); cl_git_pass(git_config_open_ondisk(&cfg, "config-include-absolute")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar.baz")); - cl_assert_equal_s("huzzah", git_buf_cstr(&buf)); + cl_assert_equal_s("huzzah", buf.ptr); cl_git_pass(p_unlink("config-include-absolute")); } @@ -47,7 +48,7 @@ void test_config_include__homedir(void) cl_git_pass(git_config_open_ondisk(&cfg, "config-include-homedir")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar.baz")); - cl_assert_equal_s("huzzah", git_buf_cstr(&buf)); + cl_assert_equal_s("huzzah", buf.ptr); cl_sandbox_set_search_path_defaults(); @@ -66,10 +67,10 @@ void test_config_include__ordering(void) cl_git_pass(git_config_open_ondisk(&cfg, "including")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar.frotz")); - cl_assert_equal_s("hiya", git_buf_cstr(&buf)); - git_buf_clear(&buf); + cl_assert_equal_s("hiya", buf.ptr); + git_buf_dispose(&buf); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar.baz")); - cl_assert_equal_s("huzzah", git_buf_cstr(&buf)); + cl_assert_equal_s("huzzah", buf.ptr); cl_git_pass(p_unlink("included")); cl_git_pass(p_unlink("including")); @@ -92,7 +93,7 @@ void test_config_include__empty_path_sanely_handled(void) cl_git_mkfile("a", "[include]\npath"); cl_git_pass(git_config_open_ondisk(&cfg, "a")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "include.path")); - cl_assert_equal_s("", git_buf_cstr(&buf)); + cl_assert_equal_s("", buf.ptr); cl_git_pass(p_unlink("a")); } @@ -105,7 +106,7 @@ void test_config_include__missing(void) cl_git_pass(git_config_open_ondisk(&cfg, "including")); cl_assert(git_error_last() == NULL); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar")); - cl_assert_equal_s("baz", git_buf_cstr(&buf)); + cl_assert_equal_s("baz", buf.ptr); cl_git_pass(p_unlink("including")); } @@ -119,7 +120,7 @@ void test_config_include__missing_homedir(void) cl_git_pass(git_config_open_ondisk(&cfg, "including")); cl_assert(git_error_last() == NULL); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar")); - cl_assert_equal_s("baz", git_buf_cstr(&buf)); + cl_assert_equal_s("baz", buf.ptr); cl_sandbox_set_search_path_defaults(); cl_git_pass(p_unlink("including")); @@ -137,11 +138,11 @@ void test_config_include__depth2(void) cl_git_pass(git_config_open_ondisk(&cfg, "top-level")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar")); - cl_assert_equal_s("baz", git_buf_cstr(&buf)); + cl_assert_equal_s("baz", buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar2")); - cl_assert_equal_s("baz2", git_buf_cstr(&buf)); + cl_assert_equal_s("baz2", buf.ptr); cl_git_pass(p_unlink("top-level")); cl_git_pass(p_unlink("middle")); @@ -186,13 +187,13 @@ void test_config_include__rewriting_include_twice_refreshes_values(void) cl_git_pass(git_config_open_ondisk(&cfg, "top-level")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar")); - git_buf_clear(&buf); + git_buf_dispose(&buf); cl_git_mkfile("included", "[foo]\nother = value2"); cl_git_fail(git_config_get_string_buf(&buf, cfg, "foo.bar")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.other")); cl_assert_equal_s(buf.ptr, "value2"); - git_buf_clear(&buf); + git_buf_dispose(&buf); cl_git_mkfile("included", "[foo]\nanother = bar"); cl_git_fail(git_config_get_string_buf(&buf, cfg, "foo.other")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.another")); diff --git a/tests/config/new.c b/tests/config/new.c index 22c330f6f98..baca0533223 100644 --- a/tests/config/new.c +++ b/tests/config/new.c @@ -22,10 +22,10 @@ void test_config_new__write_new_config(void) cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_get_string_buf(&buf, config, "color.ui")); - cl_assert_equal_s("auto", git_buf_cstr(&buf)); - git_buf_clear(&buf); + cl_assert_equal_s("auto", buf.ptr); + git_buf_dispose(&buf); cl_git_pass(git_config_get_string_buf(&buf, config, "core.editor")); - cl_assert_equal_s("ed", git_buf_cstr(&buf)); + cl_assert_equal_s("ed", buf.ptr); git_buf_dispose(&buf); git_config_free(config); diff --git a/tests/config/read.c b/tests/config/read.c index 8d1bb8b0afa..77f8a126222 100644 --- a/tests/config/read.c +++ b/tests/config/read.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "path.h" static git_buf buf = GIT_BUF_INIT; @@ -36,11 +35,11 @@ void test_config_read__case_sensitive(void) cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config1"))); cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.that.other")); - cl_assert_equal_s("true", git_buf_cstr(&buf)); - git_buf_clear(&buf); + cl_assert_equal_s("true", buf.ptr); + git_buf_dispose(&buf); cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.That.other")); - cl_assert_equal_s("yes", git_buf_cstr(&buf)); + cl_assert_equal_s("yes", buf.ptr); cl_git_pass(git_config_get_bool(&i, cfg, "this.that.other")); cl_assert(i == 1); @@ -64,7 +63,7 @@ void test_config_read__multiline_value(void) cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config2"))); cl_git_pass(git_config_get_string_buf(&buf, cfg, "this.That.and")); - cl_assert_equal_s("one one one two two three three", git_buf_cstr(&buf)); + cl_assert_equal_s("one one one two two three three", buf.ptr); git_config_free(cfg); } @@ -84,7 +83,7 @@ void test_config_read__multiline_value_and_eof(void) cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "header.key1")); - cl_assert_equal_s("foo", git_buf_cstr(&buf)); + cl_assert_equal_s("foo", buf.ptr); git_config_free(cfg); } @@ -98,7 +97,7 @@ void test_config_read__multiline_eof(void) cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "header.key1")); - cl_assert_equal_s("", git_buf_cstr(&buf)); + cl_assert_equal_s("", buf.ptr); git_config_free(cfg); } @@ -113,7 +112,7 @@ void test_config_read__subsection_header(void) cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config3"))); cl_git_pass(git_config_get_string_buf(&buf, cfg, "section.subsection.var")); - cl_assert_equal_s("hello", git_buf_cstr(&buf)); + cl_assert_equal_s("hello", buf.ptr); /* The subsection is transformed to lower-case */ cl_must_fail(git_config_get_string_buf(&buf, cfg, "section.subSectIon.var")); @@ -131,14 +130,14 @@ void test_config_read__lone_variable(void) cl_git_fail(git_config_get_int32(&i, cfg, "some.section.variable")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.section.variable")); - cl_assert_equal_s("", git_buf_cstr(&buf)); - git_buf_clear(&buf); + cl_assert_equal_s("", buf.ptr); + git_buf_dispose(&buf); cl_git_pass(git_config_get_bool(&i, cfg, "some.section.variable")); cl_assert(i == 1); cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.section.variableeq")); - cl_assert_equal_s("", git_buf_cstr(&buf)); + cl_assert_equal_s("", buf.ptr); cl_git_pass(git_config_get_bool(&i, cfg, "some.section.variableeq")); cl_assert(i == 0); @@ -234,11 +233,11 @@ void test_config_read__prefixes(void) cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9"))); cl_git_pass(git_config_get_string_buf(&buf, cfg, "remote.ab.url")); - cl_assert_equal_s("http://example.com/git/ab", git_buf_cstr(&buf)); - git_buf_clear(&buf); + cl_assert_equal_s("http://example.com/git/ab", buf.ptr); + git_buf_dispose(&buf); cl_git_pass(git_config_get_string_buf(&buf, cfg, "remote.abba.url")); - cl_assert_equal_s("http://example.com/git/abba", git_buf_cstr(&buf)); + cl_assert_equal_s("http://example.com/git/abba", buf.ptr); git_config_free(cfg); } @@ -249,7 +248,7 @@ void test_config_read__escaping_quotes(void) cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config13"))); cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.editor")); - cl_assert_equal_s("\"C:/Program Files/Nonsense/bah.exe\" \"--some option\"", git_buf_cstr(&buf)); + cl_assert_equal_s("\"C:/Program Files/Nonsense/bah.exe\" \"--some option\"", buf.ptr); git_config_free(cfg); } @@ -446,11 +445,11 @@ void test_config_read__whitespace_not_required_around_assignment(void) cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config14"))); cl_git_pass(git_config_get_string_buf(&buf, cfg, "a.b")); - cl_assert_equal_s("c", git_buf_cstr(&buf)); - git_buf_clear(&buf); + cl_assert_equal_s("c", buf.ptr); + git_buf_dispose(&buf); cl_git_pass(git_config_get_string_buf(&buf, cfg, "d.e")); - cl_assert_equal_s("f", git_buf_cstr(&buf)); + cl_assert_equal_s("f", buf.ptr); git_config_free(cfg); } @@ -596,7 +595,7 @@ void test_config_read__simple_read_from_specific_level(void) cl_git_pass(git_config_get_bool(&i, cfg_specific, "core.boolglobal")); cl_assert_equal_b(true, i); cl_git_pass(git_config_get_string_buf(&buf, cfg_specific, "core.stringglobal")); - cl_assert_equal_s("I'm a global config value!", git_buf_cstr(&buf)); + cl_assert_equal_s("I'm a global config value!", buf.ptr); git_config_free(cfg_specific); git_config_free(cfg); @@ -692,7 +691,7 @@ void test_config_read__override_variable(void) cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.var")); - cl_assert_equal_s("two", git_buf_cstr(&buf)); + cl_assert_equal_s("two", buf.ptr); git_config_free(cfg); } @@ -702,8 +701,8 @@ void test_config_read__path(void) git_config *cfg; git_buf path = GIT_BUF_INIT; git_buf old_path = GIT_BUF_INIT; - git_buf home_path = GIT_BUF_INIT; - git_buf expected_path = GIT_BUF_INIT; + git_str home_path = GIT_STR_INIT; + git_str expected_path = GIT_STR_INIT; cl_git_pass(p_mkdir("fakehome", 0777)); cl_git_pass(git_path_prettify(&home_path, "fakehome", NULL)); @@ -725,7 +724,7 @@ void test_config_read__path(void) git_buf_dispose(&path); cl_git_mkfile("./testconfig", "[some]\n path = ~"); - cl_git_pass(git_buf_sets(&expected_path, home_path.ptr)); + cl_git_pass(git_str_sets(&expected_path, home_path.ptr)); cl_git_pass(git_config_get_path(&path, cfg, "some.path")); cl_assert_equal_s(expected_path.ptr, path.ptr); @@ -736,8 +735,8 @@ void test_config_read__path(void) cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, old_path.ptr)); git_buf_dispose(&old_path); - git_buf_dispose(&home_path); - git_buf_dispose(&expected_path); + git_str_dispose(&home_path); + git_str_dispose(&expected_path); git_config_free(cfg); } @@ -884,18 +883,18 @@ void test_config_read__single_line(void) cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.var")); cl_assert_equal_s(buf.ptr, "value"); - git_buf_clear(&buf); + git_buf_dispose(&buf); cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.OtheR.var")); cl_assert_equal_s(buf.ptr, "value"); git_config_free(cfg); cl_git_mkfile("./testconfig", "[some] var = value\n[some \"OtheR\"]var = value"); cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig")); - git_buf_clear(&buf); + git_buf_dispose(&buf); cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.var")); cl_assert_equal_s(buf.ptr, "value"); - git_buf_clear(&buf); + git_buf_dispose(&buf); cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.OtheR.var")); cl_assert_equal_s(buf.ptr, "value"); diff --git a/tests/config/stress.c b/tests/config/stress.c index 577452e8d14..7ec274b187a 100644 --- a/tests/config/stress.c +++ b/tests/config/stress.c @@ -41,9 +41,9 @@ void test_config_stress__dont_break_on_invalid_input(void) void assert_config_value(git_config *config, const char *key, const char *value) { - git_buf_clear(&buf); + git_buf_dispose(&buf); cl_git_pass(git_config_get_string_buf(&buf, config, key)); - cl_assert_equal_s(value, git_buf_cstr(&buf)); + cl_assert_equal_s(value, buf.ptr); } void test_config_stress__comments(void) diff --git a/tests/config/write.c b/tests/config/write.c index 78ed7f15b76..4ee83833f06 100644 --- a/tests/config/write.c +++ b/tests/config/write.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "futils.h" #include "git2/sys/config.h" #include "config.h" @@ -290,7 +289,7 @@ void test_config_write__write_subsection(void) cl_git_pass(git_config_open_ondisk(&cfg, "config9")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "my.own.var")); - cl_assert_equal_s("works", git_buf_cstr(&buf)); + cl_assert_equal_s("works", buf.ptr); git_buf_dispose(&buf); git_config_free(cfg); @@ -313,27 +312,27 @@ void test_config_write__value_containing_quotes(void) cl_git_pass(git_config_open_ondisk(&cfg, "config9")); cl_git_pass(git_config_set_string(cfg, "core.somevar", "this \"has\" quotes")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); - cl_assert_equal_s("this \"has\" quotes", git_buf_cstr(&buf)); - git_buf_clear(&buf); + cl_assert_equal_s("this \"has\" quotes", buf.ptr); + git_buf_dispose(&buf); git_config_free(cfg); cl_git_pass(git_config_open_ondisk(&cfg, "config9")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); - cl_assert_equal_s("this \"has\" quotes", git_buf_cstr(&buf)); - git_buf_clear(&buf); + cl_assert_equal_s("this \"has\" quotes", buf.ptr); + git_buf_dispose(&buf); git_config_free(cfg); /* The code path for values that already exist is different, check that one as well */ cl_git_pass(git_config_open_ondisk(&cfg, "config9")); cl_git_pass(git_config_set_string(cfg, "core.somevar", "this also \"has\" quotes")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); - cl_assert_equal_s("this also \"has\" quotes", git_buf_cstr(&buf)); - git_buf_clear(&buf); + cl_assert_equal_s("this also \"has\" quotes", buf.ptr); + git_buf_dispose(&buf); git_config_free(cfg); cl_git_pass(git_config_open_ondisk(&cfg, "config9")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); - cl_assert_equal_s("this also \"has\" quotes", git_buf_cstr(&buf)); + cl_assert_equal_s("this also \"has\" quotes", buf.ptr); git_buf_dispose(&buf); git_config_free(cfg); } @@ -346,13 +345,13 @@ void test_config_write__escape_value(void) cl_git_pass(git_config_open_ondisk(&cfg, "config9")); cl_git_pass(git_config_set_string(cfg, "core.somevar", "this \"has\" quotes and \t")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); - cl_assert_equal_s("this \"has\" quotes and \t", git_buf_cstr(&buf)); - git_buf_clear(&buf); + cl_assert_equal_s("this \"has\" quotes and \t", buf.ptr); + git_buf_dispose(&buf); git_config_free(cfg); cl_git_pass(git_config_open_ondisk(&cfg, "config9")); cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); - cl_assert_equal_s("this \"has\" quotes and \t", git_buf_cstr(&buf)); + cl_assert_equal_s("this \"has\" quotes and \t", buf.ptr); git_buf_dispose(&buf); git_config_free(cfg); } @@ -390,7 +389,7 @@ void test_config_write__add_value_at_specific_level(void) cl_git_pass(git_config_get_bool(&i, cfg, "core.boolglobal")); cl_assert_equal_b(true, i); cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.stringglobal")); - cl_assert_equal_s("I'm a global config value!", git_buf_cstr(&buf)); + cl_assert_equal_s("I'm a global config value!", buf.ptr); git_buf_dispose(&buf); git_config_free(cfg); @@ -553,7 +552,7 @@ void test_config_write__preserves_whitespace_and_comments(void) const char *file_name = "config-duplicate-header"; const char *n; git_config *cfg; - git_buf newfile = GIT_BUF_INIT; + git_str newfile = GIT_STR_INIT; /* This config can occur after removing and re-adding the origin remote */ const char *file_content = SECTION_FOO_WITH_COMMENT SECTION_BAR; @@ -580,7 +579,7 @@ void test_config_write__preserves_whitespace_and_comments(void) cl_assert_equal_s("[newsection]\n\tnewname = new_value\n", n); - git_buf_dispose(&newfile); + git_str_dispose(&newfile); git_config_free(cfg); } @@ -588,7 +587,7 @@ void test_config_write__preserves_entry_with_name_only(void) { const char *file_name = "config-empty-value"; git_config *cfg; - git_buf newfile = GIT_BUF_INIT; + git_str newfile = GIT_STR_INIT; /* Write the test config and make sure the expected entry exists */ cl_git_mkfile(file_name, "[section \"foo\"]\n\tname\n"); @@ -599,7 +598,7 @@ void test_config_write__preserves_entry_with_name_only(void) cl_git_pass(git_futils_readbuffer(&newfile, file_name)); cl_assert_equal_s("[section \"foo\"]\n\tname\n\tother = otherval\n[newsection]\n\tnewname = new_value\n", newfile.ptr); - git_buf_dispose(&newfile); + git_str_dispose(&newfile); git_config_free(cfg); } @@ -607,7 +606,7 @@ void test_config_write__to_empty_file(void) { git_config *cfg; const char *filename = "config-file"; - git_buf result = GIT_BUF_INIT; + git_str result = GIT_STR_INIT; cl_git_mkfile(filename, ""); cl_git_pass(git_config_open_ondisk(&cfg, filename)); @@ -617,14 +616,14 @@ void test_config_write__to_empty_file(void) cl_git_pass(git_futils_readbuffer(&result, "config-file")); cl_assert_equal_s("[section]\n\tname = value\n", result.ptr); - git_buf_dispose(&result); + git_str_dispose(&result); } void test_config_write__to_file_with_only_comment(void) { git_config *cfg; const char *filename = "config-file"; - git_buf result = GIT_BUF_INIT; + git_str result = GIT_STR_INIT; cl_git_mkfile(filename, "\n\n"); cl_git_pass(git_config_open_ondisk(&cfg, filename)); @@ -634,7 +633,7 @@ void test_config_write__to_file_with_only_comment(void) cl_git_pass(git_futils_readbuffer(&result, "config-file")); cl_assert_equal_s("\n\n[section]\n\tname = value\n", result.ptr); - git_buf_dispose(&result); + git_str_dispose(&result); } void test_config_write__locking(void) @@ -699,7 +698,7 @@ void test_config_write__repeated(void) { const char *filename = "config-repeated"; git_config *cfg; - git_buf result = GIT_BUF_INIT; + git_str result = GIT_STR_INIT; const char *expected = "[sample \"prefix\"]\n\ \tsetting1 = someValue1\n\ \tsetting2 = someValue2\n\ @@ -717,7 +716,7 @@ void test_config_write__repeated(void) cl_git_pass(git_futils_readbuffer(&result, filename)); cl_assert_equal_s(expected, result.ptr); - git_buf_dispose(&result); + git_str_dispose(&result); git_config_free(cfg); } @@ -726,7 +725,7 @@ void test_config_write__preserve_case(void) { const char *filename = "config-preserve-case"; git_config *cfg; - git_buf result = GIT_BUF_INIT; + git_str result = GIT_STR_INIT; const char *expected = "[sOMe]\n" \ "\tThInG = foo\n" \ "\tOtheR = thing\n"; @@ -740,7 +739,7 @@ void test_config_write__preserve_case(void) cl_git_pass(git_futils_readbuffer(&result, filename)); cl_assert_equal_s(expected, result.ptr); - git_buf_dispose(&result); + git_str_dispose(&result); git_config_free(cfg); } diff --git a/tests/core/buf.c b/tests/core/buf.c new file mode 100644 index 00000000000..3959fa883b6 --- /dev/null +++ b/tests/core/buf.c @@ -0,0 +1,54 @@ +#include "clar_libgit2.h" +#include "buf.h" + +void test_core_buf__sanitize(void) +{ + git_buf buf = { (char *)0x42, 0, 16 }; + + cl_git_pass(git_buf_sanitize(&buf)); + cl_assert_equal_s(buf.ptr, ""); + cl_assert_equal_i(buf.reserved, 0); + cl_assert_equal_i(buf.size, 0); + + git_buf_dispose(&buf); +} + +void test_core_buf__tostr(void) +{ + git_str str = GIT_STR_INIT; + git_buf buf = { (char *)0x42, 0, 16 }; + + cl_git_pass(git_buf_tostr(&str, &buf)); + + cl_assert_equal_s(buf.ptr, ""); + cl_assert_equal_i(buf.reserved, 0); + cl_assert_equal_i(buf.size, 0); + + cl_assert_equal_s(str.ptr, ""); + cl_assert_equal_i(str.asize, 0); + cl_assert_equal_i(str.size, 0); + + git_buf_dispose(&buf); + git_str_dispose(&str); +} + +void test_core_buf__fromstr(void) +{ + git_str str = GIT_STR_INIT; + git_buf buf = { (char *)0x42, 0, 16 }; + + cl_git_pass(git_buf_tostr(&str, &buf)); + cl_git_pass(git_str_puts(&str, "Hello, world.")); + cl_git_pass(git_buf_fromstr(&buf, &str)); + + cl_assert(buf.reserved > 14); + cl_assert_equal_i(buf.size, 13); + cl_assert_equal_s(buf.ptr, "Hello, world."); + + cl_assert_equal_s(str.ptr, ""); + cl_assert_equal_i(str.asize, 0); + cl_assert_equal_i(str.size, 0); + + git_buf_dispose(&buf); + git_str_dispose(&str); +} diff --git a/tests/core/dirent.c b/tests/core/dirent.c index 08e0b11cf16..ce93e0358e5 100644 --- a/tests/core/dirent.c +++ b/tests/core/dirent.c @@ -9,7 +9,7 @@ typedef struct name_data { typedef struct walk_data { char *sub; /* sub-directory name */ name_data *names; /* name state data */ - git_buf path; + git_str path; } walk_data; @@ -27,7 +27,7 @@ static void setup(walk_data *d) if (strcmp(d->sub, ".") != 0) cl_must_pass(p_mkdir(d->sub, 0777)); - cl_git_pass(git_buf_sets(&d->path, d->sub)); + cl_git_pass(git_str_sets(&d->path, d->sub)); state_loc = d; @@ -55,7 +55,7 @@ static void dirent_cleanup__cb(void *_d) cl_must_pass(p_rmdir(top_dir)); - git_buf_dispose(&d->path); + git_str_dispose(&d->path); } static void check_counts(walk_data *d) @@ -81,7 +81,7 @@ static int update_count(name_data *data, const char *name) return GIT_ERROR; } -static int one_entry(void *state, git_buf *path) +static int one_entry(void *state, git_str *path) { walk_data *d = (walk_data *) state; @@ -104,7 +104,7 @@ static name_data dot_names[] = { static walk_data dot = { ".", dot_names, - GIT_BUF_INIT + GIT_STR_INIT }; /* make sure that the '.' folder is not traversed */ @@ -128,7 +128,7 @@ static name_data sub_names[] = { static walk_data sub = { "sub", sub_names, - GIT_BUF_INIT + GIT_STR_INIT }; /* traverse a subfolder */ @@ -146,7 +146,7 @@ void test_core_dirent__traverse_subfolder(void) static walk_data sub_slash = { "sub/", sub_names, - GIT_BUF_INIT + GIT_STR_INIT }; /* traverse a slash-terminated subfolder */ @@ -167,7 +167,7 @@ static name_data empty_names[] = { static walk_data empty = { "empty", empty_names, - GIT_BUF_INIT + GIT_STR_INIT }; /* make sure that empty folders are not traversed */ @@ -195,7 +195,7 @@ static name_data odd_names[] = { static walk_data odd = { "odd", odd_names, - GIT_BUF_INIT + GIT_STR_INIT }; /* make sure that strange looking filenames ('..c') are traversed */ diff --git a/tests/core/env.c b/tests/core/env.c index 3c34b2c4da4..9a3f0ae76da 100644 --- a/tests/core/env.c +++ b/tests/core/env.c @@ -83,7 +83,7 @@ static void setenv_and_check(const char *name, const char *value) void test_core_env__0(void) { - git_buf path = GIT_BUF_INIT, found = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, found = GIT_STR_INIT; char testfile[16], tidx = '0'; char **val; const char *testname = "testfile"; @@ -110,9 +110,9 @@ void test_core_env__0(void) * accidentally make this test pass... */ testfile[testlen] = tidx++; - cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile)); + cl_git_pass(git_str_joinpath(&path, path.ptr, testfile)); cl_git_mkfile(path.ptr, "find me"); - git_buf_rtruncate_at_char(&path, '/'); + git_str_rtruncate_at_char(&path, '/'); cl_assert_equal_i( GIT_ENOTFOUND, git_sysdir_find_global_file(&found, testfile)); @@ -162,14 +162,14 @@ void test_core_env__0(void) (void)p_rmdir(*val); } - git_buf_dispose(&path); - git_buf_dispose(&found); + git_str_dispose(&path); + git_str_dispose(&found); } void test_core_env__1(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_assert_equal_i( GIT_ENOTFOUND, git_sysdir_find_global_file(&path, "nonexistentfile")); @@ -206,21 +206,21 @@ void test_core_env__1(void) GIT_ENOTFOUND, git_sysdir_find_system_file(&path, "nonexistentfile")); #endif - git_buf_dispose(&path); + git_str_dispose(&path); } static void check_global_searchpath( - const char *path, int position, const char *file, git_buf *temp) + const char *path, int position, const char *file, git_str *temp) { - git_buf out = GIT_BUF_INIT; + git_str out = GIT_STR_INIT; /* build and set new path */ if (position < 0) - cl_git_pass(git_buf_join(temp, GIT_PATH_LIST_SEPARATOR, path, "$PATH")); + cl_git_pass(git_str_join(temp, GIT_PATH_LIST_SEPARATOR, path, "$PATH")); else if (position > 0) - cl_git_pass(git_buf_join(temp, GIT_PATH_LIST_SEPARATOR, "$PATH", path)); + cl_git_pass(git_str_join(temp, GIT_PATH_LIST_SEPARATOR, "$PATH", path)); else - cl_git_pass(git_buf_sets(temp, path)); + cl_git_pass(git_str_sets(temp, path)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, temp->ptr)); @@ -245,12 +245,12 @@ static void check_global_searchpath( cl_assert_equal_i( GIT_ENOTFOUND, git_sysdir_find_global_file(temp, file)); - git_buf_dispose(&out); + git_str_dispose(&out); } void test_core_env__2(void) { - git_buf path = GIT_BUF_INIT, found = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, found = GIT_STR_INIT; char testfile[16], tidx = '0'; char **val; const char *testname = "alternate"; @@ -276,9 +276,9 @@ void test_core_env__2(void) * deleting files won't accidentally make a test pass. */ testfile[testlen] = tidx++; - cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile)); + cl_git_pass(git_str_joinpath(&path, path.ptr, testfile)); cl_git_mkfile(path.ptr, "find me"); - git_buf_rtruncate_at_char(&path, '/'); + git_str_rtruncate_at_char(&path, '/'); /* default should be NOTFOUND */ cl_assert_equal_i( @@ -290,32 +290,32 @@ void test_core_env__2(void) check_global_searchpath(path.ptr, 1, testfile, &found); /* cleanup */ - cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile)); + cl_git_pass(git_str_joinpath(&path, path.ptr, testfile)); (void)p_unlink(path.ptr); (void)p_rmdir(*val); } - git_buf_dispose(&path); - git_buf_dispose(&found); + git_str_dispose(&path); + git_str_dispose(&found); } void test_core_env__substitution(void) { - git_buf buf = GIT_BUF_INIT, expected = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT, expected = GIT_STR_INIT; /* Set it to something non-default so we have controllable values */ cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, "/tmp/a")); cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &buf)); cl_assert_equal_s("/tmp/a", buf.ptr); - git_buf_clear(&buf); - cl_git_pass(git_buf_join(&buf, GIT_PATH_LIST_SEPARATOR, "$PATH", "/tmp/b")); + git_str_clear(&buf); + cl_git_pass(git_str_join(&buf, GIT_PATH_LIST_SEPARATOR, "$PATH", "/tmp/b")); cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, buf.ptr)); cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &buf)); - cl_git_pass(git_buf_join(&expected, GIT_PATH_LIST_SEPARATOR, "/tmp/a", "/tmp/b")); + cl_git_pass(git_str_join(&expected, GIT_PATH_LIST_SEPARATOR, "/tmp/a", "/tmp/b")); cl_assert_equal_s(expected.ptr, buf.ptr); - git_buf_dispose(&expected); - git_buf_dispose(&buf); + git_str_dispose(&expected); + git_str_dispose(&buf); } diff --git a/tests/core/filebuf.c b/tests/core/filebuf.c index e527ce97cac..6f654f523e6 100644 --- a/tests/core/filebuf.c +++ b/tests/core/filebuf.c @@ -189,13 +189,13 @@ void test_core_filebuf__symlink_follow(void) void test_core_filebuf__symlink_follow_absolute_paths(void) { git_filebuf file = GIT_FILEBUF_INIT; - git_buf source = GIT_BUF_INIT, target = GIT_BUF_INIT; + git_str source = GIT_STR_INIT, target = GIT_STR_INIT; if (!git_path_supports_symlinks(clar_sandbox_path())) cl_skip(); - cl_git_pass(git_buf_joinpath(&source, clar_sandbox_path(), "linkdir/link")); - cl_git_pass(git_buf_joinpath(&target, clar_sandbox_path(), "linkdir/target")); + cl_git_pass(git_str_joinpath(&source, clar_sandbox_path(), "linkdir/link")); + cl_git_pass(git_str_joinpath(&target, clar_sandbox_path(), "linkdir/target")); cl_git_pass(p_mkdir("linkdir", 0777)); cl_git_pass(p_symlink(target.ptr, source.ptr)); @@ -208,8 +208,8 @@ void test_core_filebuf__symlink_follow_absolute_paths(void) cl_assert_equal_i(true, git_path_exists("linkdir/target")); git_filebuf_cleanup(&file); - git_buf_dispose(&source); - git_buf_dispose(&target); + git_str_dispose(&source); + git_str_dispose(&target); cl_git_pass(git_futils_rmdir_r("linkdir", NULL, GIT_RMDIR_REMOVE_FILES)); } diff --git a/tests/core/futils.c b/tests/core/futils.c index 2c8294c876f..d08043b6edd 100644 --- a/tests/core/futils.c +++ b/tests/core/futils.c @@ -14,27 +14,27 @@ void test_core_futils__cleanup(void) void test_core_futils__writebuffer(void) { - git_buf out = GIT_BUF_INIT, - append = GIT_BUF_INIT; + git_str out = GIT_STR_INIT, + append = GIT_STR_INIT; /* create a new file */ - git_buf_puts(&out, "hello!\n"); - git_buf_printf(&out, "this is a %s\n", "test"); + git_str_puts(&out, "hello!\n"); + git_str_printf(&out, "this is a %s\n", "test"); cl_git_pass(git_futils_writebuffer(&out, "futils/test-file", O_RDWR|O_CREAT, 0666)); cl_assert_equal_file(out.ptr, out.size, "futils/test-file"); /* append some more data */ - git_buf_puts(&append, "And some more!\n"); - git_buf_put(&out, append.ptr, append.size); + git_str_puts(&append, "And some more!\n"); + git_str_put(&out, append.ptr, append.size); cl_git_pass(git_futils_writebuffer(&append, "futils/test-file", O_RDWR|O_APPEND, 0666)); cl_assert_equal_file(out.ptr, out.size, "futils/test-file"); - git_buf_dispose(&out); - git_buf_dispose(&append); + git_str_dispose(&out); + git_str_dispose(&append); } void test_core_futils__write_hidden_file(void) @@ -42,17 +42,17 @@ void test_core_futils__write_hidden_file(void) #ifndef GIT_WIN32 cl_skip(); #else - git_buf out = GIT_BUF_INIT, append = GIT_BUF_INIT; + git_str out = GIT_STR_INIT, append = GIT_STR_INIT; bool hidden; - git_buf_puts(&out, "hidden file.\n"); + git_str_puts(&out, "hidden file.\n"); git_futils_writebuffer(&out, "futils/test-file", O_RDWR | O_CREAT, 0666); cl_git_pass(git_win32__set_hidden("futils/test-file", true)); /* append some more data */ - git_buf_puts(&append, "And some more!\n"); - git_buf_put(&out, append.ptr, append.size); + git_str_puts(&append, "And some more!\n"); + git_str_put(&out, append.ptr, append.size); cl_git_pass(git_futils_writebuffer(&append, "futils/test-file", O_RDWR | O_APPEND, 0666)); @@ -61,8 +61,8 @@ void test_core_futils__write_hidden_file(void) cl_git_pass(git_win32__hidden(&hidden, "futils/test-file")); cl_assert(hidden); - git_buf_dispose(&out); - git_buf_dispose(&append); + git_str_dispose(&out); + git_str_dispose(&append); #endif } diff --git a/tests/core/buffer.c b/tests/core/gitstr.c similarity index 55% rename from tests/core/buffer.c rename to tests/core/gitstr.c index 2af4a87126b..0a624e28c02 100644 --- a/tests/core/buffer.c +++ b/tests/core/gitstr.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "git2/sys/hashsig.h" #include "futils.h" @@ -13,205 +12,205 @@ const char *test_4096 = TESTSTR_4096; const char *test_8192 = TESTSTR_8192; /* test basic data concatenation */ -void test_core_buffer__0(void) +void test_core_gitstr__0(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; cl_assert(buf.size == 0); - git_buf_puts(&buf, test_string); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(test_string, git_buf_cstr(&buf)); + git_str_puts(&buf, test_string); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(test_string, git_str_cstr(&buf)); - git_buf_puts(&buf, test_string); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(test_string_x2, git_buf_cstr(&buf)); + git_str_puts(&buf, test_string); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(test_string_x2, git_str_cstr(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } -/* test git_buf_printf */ -void test_core_buffer__1(void) +/* test git_str_printf */ +void test_core_gitstr__1(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - git_buf_printf(&buf, "%s %s %d ", "shoop", "da", 23); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s("shoop da 23 ", git_buf_cstr(&buf)); + git_str_printf(&buf, "%s %s %d ", "shoop", "da", 23); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s("shoop da 23 ", git_str_cstr(&buf)); - git_buf_printf(&buf, "%s %d", "woop", 42); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s("shoop da 23 woop 42", git_buf_cstr(&buf)); + git_str_printf(&buf, "%s %d", "woop", 42); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s("shoop da 23 woop 42", git_str_cstr(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } /* more thorough test of concatenation options */ -void test_core_buffer__2(void) +void test_core_gitstr__2(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int i; char data[128]; cl_assert(buf.size == 0); /* this must be safe to do */ - git_buf_dispose(&buf); + git_str_dispose(&buf); cl_assert(buf.size == 0); cl_assert(buf.asize == 0); /* empty buffer should be empty string */ - cl_assert_equal_s("", git_buf_cstr(&buf)); + cl_assert_equal_s("", git_str_cstr(&buf)); cl_assert(buf.size == 0); - /* cl_assert(buf.asize == 0); -- should not assume what git_buf does */ + /* cl_assert(buf.asize == 0); -- should not assume what git_str does */ /* free should set us back to the beginning */ - git_buf_dispose(&buf); + git_str_dispose(&buf); cl_assert(buf.size == 0); cl_assert(buf.asize == 0); /* add letter */ - git_buf_putc(&buf, '+'); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s("+", git_buf_cstr(&buf)); + git_str_putc(&buf, '+'); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s("+", git_str_cstr(&buf)); /* add letter again */ - git_buf_putc(&buf, '+'); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s("++", git_buf_cstr(&buf)); + git_str_putc(&buf, '+'); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s("++", git_str_cstr(&buf)); /* let's try that a few times */ for (i = 0; i < 16; ++i) { - git_buf_putc(&buf, '+'); - cl_assert(git_buf_oom(&buf) == 0); + git_str_putc(&buf, '+'); + cl_assert(git_str_oom(&buf) == 0); } - cl_assert_equal_s("++++++++++++++++++", git_buf_cstr(&buf)); + cl_assert_equal_s("++++++++++++++++++", git_str_cstr(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); /* add data */ - git_buf_put(&buf, "xo", 2); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s("xo", git_buf_cstr(&buf)); + git_str_put(&buf, "xo", 2); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s("xo", git_str_cstr(&buf)); /* add letter again */ - git_buf_put(&buf, "xo", 2); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s("xoxo", git_buf_cstr(&buf)); + git_str_put(&buf, "xo", 2); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s("xoxo", git_str_cstr(&buf)); /* let's try that a few times */ for (i = 0; i < 16; ++i) { - git_buf_put(&buf, "xo", 2); - cl_assert(git_buf_oom(&buf) == 0); + git_str_put(&buf, "xo", 2); + cl_assert(git_str_oom(&buf) == 0); } cl_assert_equal_s("xoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxo", - git_buf_cstr(&buf)); + git_str_cstr(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); /* set to string */ - git_buf_sets(&buf, test_string); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(test_string, git_buf_cstr(&buf)); + git_str_sets(&buf, test_string); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(test_string, git_str_cstr(&buf)); /* append string */ - git_buf_puts(&buf, test_string); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(test_string_x2, git_buf_cstr(&buf)); + git_str_puts(&buf, test_string); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(test_string_x2, git_str_cstr(&buf)); /* set to string again (should overwrite - not append) */ - git_buf_sets(&buf, test_string); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(test_string, git_buf_cstr(&buf)); + git_str_sets(&buf, test_string); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(test_string, git_str_cstr(&buf)); /* test clear */ - git_buf_clear(&buf); - cl_assert_equal_s("", git_buf_cstr(&buf)); + git_str_clear(&buf); + cl_assert_equal_s("", git_str_cstr(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); /* test extracting data into buffer */ - git_buf_puts(&buf, REP4("0123456789")); - cl_assert(git_buf_oom(&buf) == 0); + git_str_puts(&buf, REP4("0123456789")); + cl_assert(git_str_oom(&buf) == 0); - git_buf_copy_cstr(data, sizeof(data), &buf); + git_str_copy_cstr(data, sizeof(data), &buf); cl_assert_equal_s(REP4("0123456789"), data); - git_buf_copy_cstr(data, 11, &buf); + git_str_copy_cstr(data, 11, &buf); cl_assert_equal_s("0123456789", data); - git_buf_copy_cstr(data, 3, &buf); + git_str_copy_cstr(data, 3, &buf); cl_assert_equal_s("01", data); - git_buf_copy_cstr(data, 1, &buf); + git_str_copy_cstr(data, 1, &buf); cl_assert_equal_s("", data); - git_buf_copy_cstr(data, sizeof(data), &buf); + git_str_copy_cstr(data, sizeof(data), &buf); cl_assert_equal_s(REP4("0123456789"), data); - git_buf_sets(&buf, REP256("x")); - git_buf_copy_cstr(data, sizeof(data), &buf); + git_str_sets(&buf, REP256("x")); + git_str_copy_cstr(data, sizeof(data), &buf); /* since sizeof(data) == 128, only 127 bytes should be copied */ cl_assert_equal_s(REP4(REP16("x")) REP16("x") REP16("x") REP16("x") "xxxxxxxxxxxxxxx", data); - git_buf_dispose(&buf); + git_str_dispose(&buf); - git_buf_copy_cstr(data, sizeof(data), &buf); + git_str_copy_cstr(data, sizeof(data), &buf); cl_assert_equal_s("", data); } /* let's do some tests with larger buffers to push our limits */ -void test_core_buffer__3(void) +void test_core_gitstr__3(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; /* set to string */ - git_buf_set(&buf, test_4096, 4096); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(test_4096, git_buf_cstr(&buf)); + git_str_set(&buf, test_4096, 4096); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(test_4096, git_str_cstr(&buf)); /* append string */ - git_buf_puts(&buf, test_4096); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(test_8192, git_buf_cstr(&buf)); + git_str_puts(&buf, test_4096); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(test_8192, git_str_cstr(&buf)); /* set to string again (should overwrite - not append) */ - git_buf_set(&buf, test_4096, 4096); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(test_4096, git_buf_cstr(&buf)); + git_str_set(&buf, test_4096, 4096); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(test_4096, git_str_cstr(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } /* let's try some producer/consumer tests */ -void test_core_buffer__4(void) +void test_core_gitstr__4(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int i; for (i = 0; i < 10; ++i) { - git_buf_puts(&buf, "1234"); /* add 4 */ - cl_assert(git_buf_oom(&buf) == 0); - git_buf_consume(&buf, buf.ptr + 2); /* eat the first two */ - cl_assert(strlen(git_buf_cstr(&buf)) == (size_t)((i + 1) * 2)); + git_str_puts(&buf, "1234"); /* add 4 */ + cl_assert(git_str_oom(&buf) == 0); + git_str_consume(&buf, buf.ptr + 2); /* eat the first two */ + cl_assert(strlen(git_str_cstr(&buf)) == (size_t)((i + 1) * 2)); } /* we have appended 1234 10x and removed the first 20 letters */ - cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf)); + cl_assert_equal_s("12341234123412341234", git_str_cstr(&buf)); - git_buf_consume(&buf, NULL); - cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf)); + git_str_consume(&buf, NULL); + cl_assert_equal_s("12341234123412341234", git_str_cstr(&buf)); - git_buf_consume(&buf, "invalid pointer"); - cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf)); + git_str_consume(&buf, "invalid pointer"); + cl_assert_equal_s("12341234123412341234", git_str_cstr(&buf)); - git_buf_consume(&buf, buf.ptr); - cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf)); + git_str_consume(&buf, buf.ptr); + cl_assert_equal_s("12341234123412341234", git_str_cstr(&buf)); - git_buf_consume(&buf, buf.ptr + 1); - cl_assert_equal_s("2341234123412341234", git_buf_cstr(&buf)); + git_str_consume(&buf, buf.ptr + 1); + cl_assert_equal_s("2341234123412341234", git_str_cstr(&buf)); - git_buf_consume(&buf, buf.ptr + buf.size); - cl_assert_equal_s("", git_buf_cstr(&buf)); + git_str_consume(&buf, buf.ptr + buf.size); + cl_assert_equal_s("", git_str_cstr(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } @@ -223,18 +222,18 @@ check_buf_append( size_t expected_size, size_t expected_asize) { - git_buf tgt = GIT_BUF_INIT; + git_str tgt = GIT_STR_INIT; - git_buf_sets(&tgt, data_a); - cl_assert(git_buf_oom(&tgt) == 0); - git_buf_puts(&tgt, data_b); - cl_assert(git_buf_oom(&tgt) == 0); - cl_assert_equal_s(expected_data, git_buf_cstr(&tgt)); + git_str_sets(&tgt, data_a); + cl_assert(git_str_oom(&tgt) == 0); + git_str_puts(&tgt, data_b); + cl_assert(git_str_oom(&tgt) == 0); + cl_assert_equal_s(expected_data, git_str_cstr(&tgt)); cl_assert_equal_i(tgt.size, expected_size); if (expected_asize > 0) cl_assert_equal_i(tgt.asize, expected_asize); - git_buf_dispose(&tgt); + git_str_dispose(&tgt); } static void @@ -248,37 +247,37 @@ check_buf_append_abc( const char* expected_abcab, const char* expected_abcabc) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - git_buf_sets(&buf, buf_a); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(buf_a, git_buf_cstr(&buf)); + git_str_sets(&buf, buf_a); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(buf_a, git_str_cstr(&buf)); - git_buf_puts(&buf, buf_b); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(expected_ab, git_buf_cstr(&buf)); + git_str_puts(&buf, buf_b); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(expected_ab, git_str_cstr(&buf)); - git_buf_puts(&buf, buf_c); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(expected_abc, git_buf_cstr(&buf)); + git_str_puts(&buf, buf_c); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(expected_abc, git_str_cstr(&buf)); - git_buf_puts(&buf, buf_a); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(expected_abca, git_buf_cstr(&buf)); + git_str_puts(&buf, buf_a); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(expected_abca, git_str_cstr(&buf)); - git_buf_puts(&buf, buf_b); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(expected_abcab, git_buf_cstr(&buf)); + git_str_puts(&buf, buf_b); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(expected_abcab, git_str_cstr(&buf)); - git_buf_puts(&buf, buf_c); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(expected_abcabc, git_buf_cstr(&buf)); + git_str_puts(&buf, buf_c); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(expected_abcabc, git_str_cstr(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } /* more variations on append tests */ -void test_core_buffer__5(void) +void test_core_gitstr__5(void) { check_buf_append("", "", "", 0, 0); check_buf_append("a", "", "a", 1, 0); @@ -321,70 +320,70 @@ void test_core_buffer__5(void) } /* test swap */ -void test_core_buffer__6(void) +void test_core_gitstr__6(void) { - git_buf a = GIT_BUF_INIT; - git_buf b = GIT_BUF_INIT; + git_str a = GIT_STR_INIT; + git_str b = GIT_STR_INIT; - git_buf_sets(&a, "foo"); - cl_assert(git_buf_oom(&a) == 0); - git_buf_sets(&b, "bar"); - cl_assert(git_buf_oom(&b) == 0); + git_str_sets(&a, "foo"); + cl_assert(git_str_oom(&a) == 0); + git_str_sets(&b, "bar"); + cl_assert(git_str_oom(&b) == 0); - cl_assert_equal_s("foo", git_buf_cstr(&a)); - cl_assert_equal_s("bar", git_buf_cstr(&b)); + cl_assert_equal_s("foo", git_str_cstr(&a)); + cl_assert_equal_s("bar", git_str_cstr(&b)); - git_buf_swap(&a, &b); + git_str_swap(&a, &b); - cl_assert_equal_s("bar", git_buf_cstr(&a)); - cl_assert_equal_s("foo", git_buf_cstr(&b)); + cl_assert_equal_s("bar", git_str_cstr(&a)); + cl_assert_equal_s("foo", git_str_cstr(&b)); - git_buf_dispose(&a); - git_buf_dispose(&b); + git_str_dispose(&a); + git_str_dispose(&b); } /* test detach/attach data */ -void test_core_buffer__7(void) +void test_core_gitstr__7(void) { const char *fun = "This is fun"; - git_buf a = GIT_BUF_INIT; + git_str a = GIT_STR_INIT; char *b = NULL; - git_buf_sets(&a, "foo"); - cl_assert(git_buf_oom(&a) == 0); - cl_assert_equal_s("foo", git_buf_cstr(&a)); + git_str_sets(&a, "foo"); + cl_assert(git_str_oom(&a) == 0); + cl_assert_equal_s("foo", git_str_cstr(&a)); - b = git_buf_detach(&a); + b = git_str_detach(&a); cl_assert_equal_s("foo", b); cl_assert_equal_s("", a.ptr); git__free(b); - b = git_buf_detach(&a); + b = git_str_detach(&a); cl_assert_equal_s(NULL, b); cl_assert_equal_s("", a.ptr); - git_buf_dispose(&a); + git_str_dispose(&a); b = git__strdup(fun); - git_buf_attach(&a, b, 0); + git_str_attach(&a, b, 0); cl_assert_equal_s(fun, a.ptr); cl_assert(a.size == strlen(fun)); cl_assert(a.asize == strlen(fun) + 1); - git_buf_dispose(&a); + git_str_dispose(&a); b = git__strdup(fun); - git_buf_attach(&a, b, strlen(fun) + 1); + git_str_attach(&a, b, strlen(fun) + 1); cl_assert_equal_s(fun, a.ptr); cl_assert(a.size == strlen(fun)); cl_assert(a.asize == strlen(fun) + 1); - git_buf_dispose(&a); + git_str_dispose(&a); } @@ -395,12 +394,12 @@ check_joinbuf_2( const char *expected) { char sep = '/'; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - git_buf_join(&buf, sep, a, b); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(expected, git_buf_cstr(&buf)); - git_buf_dispose(&buf); + git_str_join(&buf, sep, a, b); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(expected, git_str_cstr(&buf)); + git_str_dispose(&buf); } static void @@ -411,13 +410,13 @@ check_joinbuf_overlapped( const char *expected) { char sep = '/'; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - git_buf_sets(&buf, oldval); - git_buf_join(&buf, sep, buf.ptr + ofs_a, b); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(expected, git_buf_cstr(&buf)); - git_buf_dispose(&buf); + git_str_sets(&buf, oldval); + git_str_join(&buf, sep, buf.ptr + ofs_a, b); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(expected, git_str_cstr(&buf)); + git_str_dispose(&buf); } static void @@ -427,16 +426,16 @@ check_joinbuf_n_2( const char *expected) { char sep = '/'; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - git_buf_sets(&buf, a); - cl_assert(git_buf_oom(&buf) == 0); + git_str_sets(&buf, a); + cl_assert(git_str_oom(&buf) == 0); - git_buf_join_n(&buf, sep, 1, b); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(expected, git_buf_cstr(&buf)); + git_str_join_n(&buf, sep, 1, b); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(expected, git_str_cstr(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } static void @@ -448,31 +447,31 @@ check_joinbuf_n_4( const char *expected) { char sep = ';'; - git_buf buf = GIT_BUF_INIT; - git_buf_join_n(&buf, sep, 4, a, b, c, d); - cl_assert(git_buf_oom(&buf) == 0); - cl_assert_equal_s(expected, git_buf_cstr(&buf)); - git_buf_dispose(&buf); + git_str buf = GIT_STR_INIT; + git_str_join_n(&buf, sep, 4, a, b, c, d); + cl_assert(git_str_oom(&buf) == 0); + cl_assert_equal_s(expected, git_str_cstr(&buf)); + git_str_dispose(&buf); } /* test join */ -void test_core_buffer__8(void) +void test_core_gitstr__8(void) { - git_buf a = GIT_BUF_INIT; + git_str a = GIT_STR_INIT; - git_buf_join_n(&a, '/', 1, "foo"); - cl_assert(git_buf_oom(&a) == 0); - cl_assert_equal_s("foo", git_buf_cstr(&a)); + git_str_join_n(&a, '/', 1, "foo"); + cl_assert(git_str_oom(&a) == 0); + cl_assert_equal_s("foo", git_str_cstr(&a)); - git_buf_join_n(&a, '/', 1, "bar"); - cl_assert(git_buf_oom(&a) == 0); - cl_assert_equal_s("foo/bar", git_buf_cstr(&a)); + git_str_join_n(&a, '/', 1, "bar"); + cl_assert(git_str_oom(&a) == 0); + cl_assert_equal_s("foo/bar", git_str_cstr(&a)); - git_buf_join_n(&a, '/', 1, "baz"); - cl_assert(git_buf_oom(&a) == 0); - cl_assert_equal_s("foo/bar/baz", git_buf_cstr(&a)); + git_str_join_n(&a, '/', 1, "baz"); + cl_assert(git_str_oom(&a) == 0); + cl_assert_equal_s("foo/bar/baz", git_str_cstr(&a)); - git_buf_dispose(&a); + git_str_dispose(&a); check_joinbuf_2(NULL, "", ""); check_joinbuf_2(NULL, "a", "a"); @@ -537,9 +536,9 @@ void test_core_buffer__8(void) check_joinbuf_n_4(";abcd;", ";efgh;", ";ijkl;", ";mnop;", ";abcd;efgh;ijkl;mnop;"); } -void test_core_buffer__9(void) +void test_core_gitstr__9(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; /* just some exhaustive tests of various separator placement */ char *a[] = { "", "-", "a-", "-a", "-a-" }; @@ -570,68 +569,68 @@ void test_core_buffer__9(void) for (j = 0; j < sizeof(b) / sizeof(char*); ++j) { for (i = 0; i < sizeof(a) / sizeof(char*); ++i) { - git_buf_join(&buf, separator, a[i], b[j]); + git_str_join(&buf, separator, a[i], b[j]); cl_assert_equal_s(*expect, buf.ptr); expect++; } } } - git_buf_dispose(&buf); + git_str_dispose(&buf); } -void test_core_buffer__10(void) +void test_core_gitstr__10(void) { - git_buf a = GIT_BUF_INIT; + git_str a = GIT_STR_INIT; - cl_git_pass(git_buf_join_n(&a, '/', 1, "test")); + cl_git_pass(git_str_join_n(&a, '/', 1, "test")); cl_assert_equal_s(a.ptr, "test"); - cl_git_pass(git_buf_join_n(&a, '/', 1, "string")); + cl_git_pass(git_str_join_n(&a, '/', 1, "string")); cl_assert_equal_s(a.ptr, "test/string"); - git_buf_clear(&a); - cl_git_pass(git_buf_join_n(&a, '/', 3, "test", "string", "join")); + git_str_clear(&a); + cl_git_pass(git_str_join_n(&a, '/', 3, "test", "string", "join")); cl_assert_equal_s(a.ptr, "test/string/join"); - cl_git_pass(git_buf_join_n(&a, '/', 2, a.ptr, "more")); + cl_git_pass(git_str_join_n(&a, '/', 2, a.ptr, "more")); cl_assert_equal_s(a.ptr, "test/string/join/test/string/join/more"); - git_buf_dispose(&a); + git_str_dispose(&a); } -void test_core_buffer__join3(void) +void test_core_gitstr__join3(void) { - git_buf a = GIT_BUF_INIT; + git_str a = GIT_STR_INIT; - cl_git_pass(git_buf_join3(&a, '/', "test", "string", "join")); + cl_git_pass(git_str_join3(&a, '/', "test", "string", "join")); cl_assert_equal_s("test/string/join", a.ptr); - cl_git_pass(git_buf_join3(&a, '/', "test/", "string", "join")); + cl_git_pass(git_str_join3(&a, '/', "test/", "string", "join")); cl_assert_equal_s("test/string/join", a.ptr); - cl_git_pass(git_buf_join3(&a, '/', "test/", "/string", "join")); + cl_git_pass(git_str_join3(&a, '/', "test/", "/string", "join")); cl_assert_equal_s("test/string/join", a.ptr); - cl_git_pass(git_buf_join3(&a, '/', "test/", "/string/", "join")); + cl_git_pass(git_str_join3(&a, '/', "test/", "/string/", "join")); cl_assert_equal_s("test/string/join", a.ptr); - cl_git_pass(git_buf_join3(&a, '/', "test/", "/string/", "/join")); + cl_git_pass(git_str_join3(&a, '/', "test/", "/string/", "/join")); cl_assert_equal_s("test/string/join", a.ptr); - cl_git_pass(git_buf_join3(&a, '/', "", "string", "join")); + cl_git_pass(git_str_join3(&a, '/', "", "string", "join")); cl_assert_equal_s("string/join", a.ptr); - cl_git_pass(git_buf_join3(&a, '/', "", "string/", "join")); + cl_git_pass(git_str_join3(&a, '/', "", "string/", "join")); cl_assert_equal_s("string/join", a.ptr); - cl_git_pass(git_buf_join3(&a, '/', "", "string/", "/join")); + cl_git_pass(git_str_join3(&a, '/', "", "string/", "/join")); cl_assert_equal_s("string/join", a.ptr); - cl_git_pass(git_buf_join3(&a, '/', "string", "", "join")); + cl_git_pass(git_str_join3(&a, '/', "string", "", "join")); cl_assert_equal_s("string/join", a.ptr); - cl_git_pass(git_buf_join3(&a, '/', "string/", "", "join")); + cl_git_pass(git_str_join3(&a, '/', "string/", "", "join")); cl_assert_equal_s("string/join", a.ptr); - cl_git_pass(git_buf_join3(&a, '/', "string/", "", "/join")); + cl_git_pass(git_str_join3(&a, '/', "string/", "", "/join")); cl_assert_equal_s("string/join", a.ptr); - git_buf_dispose(&a); + git_str_dispose(&a); } -void test_core_buffer__11(void) +void test_core_gitstr__11(void) { - git_buf a = GIT_BUF_INIT; + git_str a = GIT_STR_INIT; char *t1[] = { "nothing", "in", "common" }; char *t2[] = { "something", "something else", "some other" }; char *t3[] = { "something", "some fun", "no fun" }; @@ -640,89 +639,89 @@ void test_core_buffer__11(void) char *t6[] = { "no", "nope", "" }; char *t7[] = { "", "doesn't matter" }; - cl_git_pass(git_buf_common_prefix(&a, t1, 3)); + cl_git_pass(git_str_common_prefix(&a, t1, 3)); cl_assert_equal_s(a.ptr, ""); - cl_git_pass(git_buf_common_prefix(&a, t2, 3)); + cl_git_pass(git_str_common_prefix(&a, t2, 3)); cl_assert_equal_s(a.ptr, "some"); - cl_git_pass(git_buf_common_prefix(&a, t3, 3)); + cl_git_pass(git_str_common_prefix(&a, t3, 3)); cl_assert_equal_s(a.ptr, ""); - cl_git_pass(git_buf_common_prefix(&a, t4, 3)); + cl_git_pass(git_str_common_prefix(&a, t4, 3)); cl_assert_equal_s(a.ptr, "happ"); - cl_git_pass(git_buf_common_prefix(&a, t5, 3)); + cl_git_pass(git_str_common_prefix(&a, t5, 3)); cl_assert_equal_s(a.ptr, "happ"); - cl_git_pass(git_buf_common_prefix(&a, t6, 3)); + cl_git_pass(git_str_common_prefix(&a, t6, 3)); cl_assert_equal_s(a.ptr, ""); - cl_git_pass(git_buf_common_prefix(&a, t7, 3)); + cl_git_pass(git_str_common_prefix(&a, t7, 3)); cl_assert_equal_s(a.ptr, ""); - git_buf_dispose(&a); + git_str_dispose(&a); } -void test_core_buffer__rfind_variants(void) +void test_core_gitstr__rfind_variants(void) { - git_buf a = GIT_BUF_INIT; + git_str a = GIT_STR_INIT; ssize_t len; - cl_git_pass(git_buf_sets(&a, "/this/is/it/")); + cl_git_pass(git_str_sets(&a, "/this/is/it/")); - len = (ssize_t)git_buf_len(&a); + len = (ssize_t)git_str_len(&a); - cl_assert(git_buf_rfind(&a, '/') == len - 1); - cl_assert(git_buf_rfind_next(&a, '/') == len - 4); + cl_assert(git_str_rfind(&a, '/') == len - 1); + cl_assert(git_str_rfind_next(&a, '/') == len - 4); - cl_assert(git_buf_rfind(&a, 'i') == len - 3); - cl_assert(git_buf_rfind_next(&a, 'i') == len - 3); + cl_assert(git_str_rfind(&a, 'i') == len - 3); + cl_assert(git_str_rfind_next(&a, 'i') == len - 3); - cl_assert(git_buf_rfind(&a, 'h') == 2); - cl_assert(git_buf_rfind_next(&a, 'h') == 2); + cl_assert(git_str_rfind(&a, 'h') == 2); + cl_assert(git_str_rfind_next(&a, 'h') == 2); - cl_assert(git_buf_rfind(&a, 'q') == -1); - cl_assert(git_buf_rfind_next(&a, 'q') == -1); + cl_assert(git_str_rfind(&a, 'q') == -1); + cl_assert(git_str_rfind_next(&a, 'q') == -1); - git_buf_dispose(&a); + git_str_dispose(&a); } -void test_core_buffer__puts_escaped(void) +void test_core_gitstr__puts_escaped(void) { - git_buf a = GIT_BUF_INIT; + git_str a = GIT_STR_INIT; - git_buf_clear(&a); - cl_git_pass(git_buf_puts_escaped(&a, "this is a test", "", "")); + git_str_clear(&a); + cl_git_pass(git_str_puts_escaped(&a, "this is a test", "", "")); cl_assert_equal_s("this is a test", a.ptr); - git_buf_clear(&a); - cl_git_pass(git_buf_puts_escaped(&a, "this is a test", "t", "\\")); + git_str_clear(&a); + cl_git_pass(git_str_puts_escaped(&a, "this is a test", "t", "\\")); cl_assert_equal_s("\\this is a \\tes\\t", a.ptr); - git_buf_clear(&a); - cl_git_pass(git_buf_puts_escaped(&a, "this is a test", "i ", "__")); + git_str_clear(&a); + cl_git_pass(git_str_puts_escaped(&a, "this is a test", "i ", "__")); cl_assert_equal_s("th__is__ __is__ a__ test", a.ptr); - git_buf_clear(&a); - cl_git_pass(git_buf_puts_escape_regex(&a, "^match\\s*[A-Z]+.*")); + git_str_clear(&a); + cl_git_pass(git_str_puts_escape_regex(&a, "^match\\s*[A-Z]+.*")); cl_assert_equal_s("\\^match\\\\s\\*\\[A-Z\\]\\+\\.\\*", a.ptr); - git_buf_dispose(&a); + git_str_dispose(&a); } static void assert_unescape(char *expected, char *to_unescape) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_sets(&buf, to_unescape)); - git_buf_unescape(&buf); + cl_git_pass(git_str_sets(&buf, to_unescape)); + git_str_unescape(&buf); cl_assert_equal_s(expected, buf.ptr); cl_assert_equal_sz(strlen(expected), buf.size); - git_buf_dispose(&buf); + git_str_dispose(&buf); } -void test_core_buffer__unescape(void) +void test_core_gitstr__unescape(void) { assert_unescape("Escaped\\", "Es\\ca\\ped\\"); assert_unescape("Es\\caped\\", "Es\\\\ca\\ped\\\\"); @@ -731,9 +730,9 @@ void test_core_buffer__unescape(void) assert_unescape("", ""); } -void test_core_buffer__encode_base64(void) +void test_core_gitstr__encode_base64(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; /* t h i s * 0x 74 68 69 73 @@ -742,100 +741,100 @@ void test_core_buffer__encode_base64(void) * 0x 1d 06 21 29 1c 30 * d G h p c w */ - cl_git_pass(git_buf_encode_base64(&buf, "this", 4)); + cl_git_pass(git_str_encode_base64(&buf, "this", 4)); cl_assert_equal_s("dGhpcw==", buf.ptr); - git_buf_clear(&buf); - cl_git_pass(git_buf_encode_base64(&buf, "this!", 5)); + git_str_clear(&buf); + cl_git_pass(git_str_encode_base64(&buf, "this!", 5)); cl_assert_equal_s("dGhpcyE=", buf.ptr); - git_buf_clear(&buf); - cl_git_pass(git_buf_encode_base64(&buf, "this!\n", 6)); + git_str_clear(&buf); + cl_git_pass(git_str_encode_base64(&buf, "this!\n", 6)); cl_assert_equal_s("dGhpcyEK", buf.ptr); - git_buf_dispose(&buf); + git_str_dispose(&buf); } -void test_core_buffer__decode_base64(void) +void test_core_gitstr__decode_base64(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_decode_base64(&buf, "dGhpcw==", 8)); + cl_git_pass(git_str_decode_base64(&buf, "dGhpcw==", 8)); cl_assert_equal_s("this", buf.ptr); - git_buf_clear(&buf); - cl_git_pass(git_buf_decode_base64(&buf, "dGhpcyE=", 8)); + git_str_clear(&buf); + cl_git_pass(git_str_decode_base64(&buf, "dGhpcyE=", 8)); cl_assert_equal_s("this!", buf.ptr); - git_buf_clear(&buf); - cl_git_pass(git_buf_decode_base64(&buf, "dGhpcyEK", 8)); + git_str_clear(&buf); + cl_git_pass(git_str_decode_base64(&buf, "dGhpcyEK", 8)); cl_assert_equal_s("this!\n", buf.ptr); - cl_git_fail(git_buf_decode_base64(&buf, "This is not a valid base64 string!!!", 36)); + cl_git_fail(git_str_decode_base64(&buf, "This is not a valid base64 string!!!", 36)); cl_assert_equal_s("this!\n", buf.ptr); - git_buf_dispose(&buf); + git_str_dispose(&buf); } -void test_core_buffer__encode_base85(void) +void test_core_gitstr__encode_base85(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_encode_base85(&buf, "this", 4)); + cl_git_pass(git_str_encode_base85(&buf, "this", 4)); cl_assert_equal_s("bZBXF", buf.ptr); - git_buf_clear(&buf); + git_str_clear(&buf); - cl_git_pass(git_buf_encode_base85(&buf, "two rnds", 8)); + cl_git_pass(git_str_encode_base85(&buf, "two rnds", 8)); cl_assert_equal_s("ba!tca&BaE", buf.ptr); - git_buf_clear(&buf); + git_str_clear(&buf); - cl_git_pass(git_buf_encode_base85(&buf, "this is base 85 encoded", + cl_git_pass(git_str_encode_base85(&buf, "this is base 85 encoded", strlen("this is base 85 encoded"))); cl_assert_equal_s("bZBXFAZc?TVqtS-AUHK3Wo~0{WMyOk", buf.ptr); - git_buf_clear(&buf); + git_str_clear(&buf); - git_buf_dispose(&buf); + git_str_dispose(&buf); } -void test_core_buffer__decode_base85(void) +void test_core_gitstr__decode_base85(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_decode_base85(&buf, "bZBXF", 5, 4)); + cl_git_pass(git_str_decode_base85(&buf, "bZBXF", 5, 4)); cl_assert_equal_sz(4, buf.size); cl_assert_equal_s("this", buf.ptr); - git_buf_clear(&buf); + git_str_clear(&buf); - cl_git_pass(git_buf_decode_base85(&buf, "ba!tca&BaE", 10, 8)); + cl_git_pass(git_str_decode_base85(&buf, "ba!tca&BaE", 10, 8)); cl_assert_equal_sz(8, buf.size); cl_assert_equal_s("two rnds", buf.ptr); - git_buf_clear(&buf); + git_str_clear(&buf); - cl_git_pass(git_buf_decode_base85(&buf, "bZBXFAZc?TVqtS-AUHK3Wo~0{WMyOk", 30, 23)); + cl_git_pass(git_str_decode_base85(&buf, "bZBXFAZc?TVqtS-AUHK3Wo~0{WMyOk", 30, 23)); cl_assert_equal_sz(23, buf.size); cl_assert_equal_s("this is base 85 encoded", buf.ptr); - git_buf_clear(&buf); + git_str_clear(&buf); - git_buf_dispose(&buf); + git_str_dispose(&buf); } -void test_core_buffer__decode_base85_fails_gracefully(void) +void test_core_gitstr__decode_base85_fails_gracefully(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - git_buf_puts(&buf, "foobar"); + git_str_puts(&buf, "foobar"); - cl_git_fail(git_buf_decode_base85(&buf, "invalid charsZZ", 15, 42)); - cl_git_fail(git_buf_decode_base85(&buf, "invalidchars__ ", 15, 42)); - cl_git_fail(git_buf_decode_base85(&buf, "overflowZZ~~~~~", 15, 42)); - cl_git_fail(git_buf_decode_base85(&buf, "truncated", 9, 42)); + cl_git_fail(git_str_decode_base85(&buf, "invalid charsZZ", 15, 42)); + cl_git_fail(git_str_decode_base85(&buf, "invalidchars__ ", 15, 42)); + cl_git_fail(git_str_decode_base85(&buf, "overflowZZ~~~~~", 15, 42)); + cl_git_fail(git_str_decode_base85(&buf, "truncated", 9, 42)); cl_assert_equal_sz(6, buf.size); cl_assert_equal_s("foobar", buf.ptr); - git_buf_dispose(&buf); + git_str_dispose(&buf); } -void test_core_buffer__classify_with_utf8(void) +void test_core_gitstr__classify_with_utf8(void) { char *data0 = "Simple text\n"; size_t data0len = 12; @@ -845,23 +844,23 @@ void test_core_buffer__classify_with_utf8(void) size_t data2len = 29; char *data3 = "\xef\xbb\xbfThis is UTF-8 with a BOM.\n"; size_t data3len = 20; - git_buf b; + git_str b; b.ptr = data0; b.size = b.asize = data0len; - cl_assert(!git_buf_is_binary(&b)); - cl_assert(!git_buf_contains_nul(&b)); + cl_assert(!git_str_is_binary(&b)); + cl_assert(!git_str_contains_nul(&b)); b.ptr = data1; b.size = b.asize = data1len; - cl_assert(!git_buf_is_binary(&b)); - cl_assert(!git_buf_contains_nul(&b)); + cl_assert(!git_str_is_binary(&b)); + cl_assert(!git_str_contains_nul(&b)); b.ptr = data2; b.size = b.asize = data2len; - cl_assert(git_buf_is_binary(&b)); - cl_assert(git_buf_contains_nul(&b)); + cl_assert(git_str_is_binary(&b)); + cl_assert(git_str_contains_nul(&b)); b.ptr = data3; b.size = b.asize = data3len; - cl_assert(!git_buf_is_binary(&b)); - cl_assert(!git_buf_contains_nul(&b)); + cl_assert(!git_str_is_binary(&b)); + cl_assert(!git_str_contains_nul(&b)); } #define SIMILARITY_TEST_DATA_1 \ @@ -871,15 +870,15 @@ void test_core_buffer__classify_with_utf8(void) "030\n031\n032\n033\n034\n035\n036\n037\n038\n039\n" \ "040\n041\n042\n043\n044\n045\n046\n047\n048\n049\n" -void test_core_buffer__similarity_metric(void) +void test_core_gitstr__similarity_metric(void) { git_hashsig *a, *b; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int sim; /* in the first case, we compare data to itself and expect 100% match */ - cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1)); + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); @@ -890,9 +889,9 @@ void test_core_buffer__similarity_metric(void) /* if we change just a single byte, how much does that change magnify? */ - cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1)); + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - cl_git_pass(git_buf_sets(&buf, + cl_git_pass(git_str_sets(&buf, "000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \ "010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \ "x020x\n021\n022\n023\n024\n025\n026\n027\n028\n029\n" \ @@ -910,9 +909,9 @@ void test_core_buffer__similarity_metric(void) /* let's try comparing data to a superset of itself */ - cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1)); + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1 + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1 "050\n051\n052\n053\n054\n055\n056\n057\n058\n059\n")); cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); @@ -926,9 +925,9 @@ void test_core_buffer__similarity_metric(void) /* what if we keep about half the original data and add half new */ - cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1)); + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - cl_git_pass(git_buf_sets(&buf, + cl_git_pass(git_str_sets(&buf, "000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \ "010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \ "020x\n021\n022\n023\n024\n" \ @@ -948,7 +947,7 @@ void test_core_buffer__similarity_metric(void) /* lastly, let's check that we can hash file content as well */ - cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1)); + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); cl_git_pass(git_futils_mkdir("scratch", 0755, GIT_MKDIR_PATH)); @@ -961,15 +960,15 @@ void test_core_buffer__similarity_metric(void) git_hashsig_free(a); git_hashsig_free(b); - git_buf_dispose(&buf); + git_str_dispose(&buf); git_futils_rmdir_r("scratch", NULL, GIT_RMDIR_REMOVE_FILES); } -void test_core_buffer__similarity_metric_whitespace(void) +void test_core_gitstr__similarity_metric_whitespace(void) { git_hashsig *a, *b; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int sim, i, j; git_hashsig_option_t opt; const char *tabbed = @@ -979,7 +978,7 @@ void test_core_buffer__similarity_metric_whitespace(void) "\n" " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\n" " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\n" - " git_buf_join(&buf, separator, a[i], b[j]);\n" + " git_str_join(&buf, separator, a[i], b[j]);\n" " cl_assert_equal_s(*expect, buf.ptr);\n" " expect++;\n" " }\n" @@ -992,7 +991,7 @@ void test_core_buffer__similarity_metric_whitespace(void) "\n" " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\n" " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\n" - " git_buf_join(&buf, separator, a[i], b[j]);\n" + " git_str_join(&buf, separator, a[i], b[j]);\n" " cl_assert_equal_s(*expect, buf.ptr);\n" " expect++;\n" " }\n" @@ -1005,7 +1004,7 @@ void test_core_buffer__similarity_metric_whitespace(void) "\r\n" " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\r\n" " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\r\n" - " git_buf_join(&buf, separator, a[i], b[j]);\r\n" + " git_str_join(&buf, separator, a[i], b[j]);\r\n" " cl_assert_equal_s(*expect, buf.ptr);\r\n" " expect++;\r\n" " }\r\n" @@ -1018,10 +1017,10 @@ void test_core_buffer__similarity_metric_whitespace(void) for (opt = GIT_HASHSIG_NORMAL; opt <= GIT_HASHSIG_SMART_WHITESPACE; ++opt) { for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { - cl_git_pass(git_buf_sets(&buf, text[i])); + cl_git_pass(git_str_sets(&buf, text[i])); cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, opt)); - cl_git_pass(git_buf_sets(&buf, text[j])); + cl_git_pass(git_str_sets(&buf, text[j])); cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, opt)); sim = git_hashsig_compare(a, b); @@ -1041,7 +1040,7 @@ void test_core_buffer__similarity_metric_whitespace(void) } } - git_buf_dispose(&buf); + git_str_dispose(&buf); } #include "../filter/crlf.h" @@ -1050,177 +1049,177 @@ void test_core_buffer__similarity_metric_whitespace(void) cl_assert_equal_s(expected, buf.ptr); \ cl_assert_equal_sz(strlen(expected), buf.size); } while (0) -void test_core_buffer__lf_and_crlf_conversions(void) +void test_core_gitstr__lf_and_crlf_conversions(void) { - git_buf src = GIT_BUF_INIT, tgt = GIT_BUF_INIT; + git_str src = GIT_STR_INIT, tgt = GIT_STR_INIT; /* LF source */ - git_buf_sets(&src, "lf\nlf\nlf\nlf\n"); + git_str_sets(&src, "lf\nlf\nlf\nlf\n"); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf("lf\r\nlf\r\nlf\r\nlf\r\n", tgt); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf(src.ptr, tgt); - git_buf_sets(&src, "\nlf\nlf\nlf\nlf\nlf"); + git_str_sets(&src, "\nlf\nlf\nlf\nlf\nlf"); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf("\r\nlf\r\nlf\r\nlf\r\nlf\r\nlf", tgt); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf(src.ptr, tgt); /* CRLF source */ - git_buf_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n"); + git_str_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n"); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf("crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n", tgt); - git_buf_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n"); + git_str_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n"); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf("crlf\ncrlf\ncrlf\ncrlf\n", tgt); - git_buf_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf"); + git_str_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf"); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf("\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf", tgt); - git_buf_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf"); + git_str_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf"); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf("\ncrlf\ncrlf\ncrlf\ncrlf\ncrlf", tgt); /* CRLF in LF text */ - git_buf_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n"); + git_str_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n"); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf("\r\nlf\r\nlf\r\ncrlf\r\nlf\r\nlf\r\ncrlf\r\n", tgt); - git_buf_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n"); + git_str_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n"); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf("\nlf\nlf\ncrlf\nlf\nlf\ncrlf\n", tgt); /* LF in CRLF text */ - git_buf_sets(&src, "\ncrlf\r\ncrlf\r\nlf\ncrlf\r\ncrlf"); + git_str_sets(&src, "\ncrlf\r\ncrlf\r\nlf\ncrlf\r\ncrlf"); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf("\r\ncrlf\r\ncrlf\r\nlf\r\ncrlf\r\ncrlf", tgt); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf("\ncrlf\ncrlf\nlf\ncrlf\ncrlf", tgt); /* bare CR test */ - git_buf_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r"); + git_str_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r"); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf("\rcrlf\r\nlf\r\nlf\r\ncr\rcrlf\r\nlf\r\ncr\r", tgt); - git_buf_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r"); + git_str_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r"); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf("\rcrlf\nlf\nlf\ncr\rcrlf\nlf\ncr\r", tgt); - git_buf_sets(&src, "\rcr\r"); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + git_str_sets(&src, "\rcr\r"); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf(src.ptr, tgt); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf("\rcr\r", tgt); - git_buf_dispose(&src); - git_buf_dispose(&tgt); + git_str_dispose(&src); + git_str_dispose(&tgt); /* blob correspondence tests */ - git_buf_sets(&src, ALL_CRLF_TEXT_RAW); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + git_str_sets(&src, ALL_CRLF_TEXT_RAW); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf(ALL_CRLF_TEXT_AS_CRLF, tgt); - git_buf_sets(&src, ALL_CRLF_TEXT_RAW); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + git_str_sets(&src, ALL_CRLF_TEXT_RAW); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf(ALL_CRLF_TEXT_AS_LF, tgt); - git_buf_dispose(&src); - git_buf_dispose(&tgt); + git_str_dispose(&src); + git_str_dispose(&tgt); - git_buf_sets(&src, ALL_LF_TEXT_RAW); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + git_str_sets(&src, ALL_LF_TEXT_RAW); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf(ALL_LF_TEXT_AS_CRLF, tgt); - git_buf_sets(&src, ALL_LF_TEXT_RAW); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + git_str_sets(&src, ALL_LF_TEXT_RAW); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf(ALL_LF_TEXT_AS_LF, tgt); - git_buf_dispose(&src); - git_buf_dispose(&tgt); + git_str_dispose(&src); + git_str_dispose(&tgt); - git_buf_sets(&src, MORE_CRLF_TEXT_RAW); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + git_str_sets(&src, MORE_CRLF_TEXT_RAW); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf(MORE_CRLF_TEXT_AS_CRLF, tgt); - git_buf_sets(&src, MORE_CRLF_TEXT_RAW); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + git_str_sets(&src, MORE_CRLF_TEXT_RAW); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf(MORE_CRLF_TEXT_AS_LF, tgt); - git_buf_dispose(&src); - git_buf_dispose(&tgt); + git_str_dispose(&src); + git_str_dispose(&tgt); - git_buf_sets(&src, MORE_LF_TEXT_RAW); - cl_git_pass(git_buf_lf_to_crlf(&tgt, &src)); + git_str_sets(&src, MORE_LF_TEXT_RAW); + cl_git_pass(git_str_lf_to_crlf(&tgt, &src)); check_buf(MORE_LF_TEXT_AS_CRLF, tgt); - git_buf_sets(&src, MORE_LF_TEXT_RAW); - cl_git_pass(git_buf_crlf_to_lf(&tgt, &src)); + git_str_sets(&src, MORE_LF_TEXT_RAW); + cl_git_pass(git_str_crlf_to_lf(&tgt, &src)); check_buf(MORE_LF_TEXT_AS_LF, tgt); - git_buf_dispose(&src); - git_buf_dispose(&tgt); + git_str_dispose(&src); + git_str_dispose(&tgt); } -void test_core_buffer__dont_grow_borrowed(void) +void test_core_gitstr__dont_grow_borrowed(void) { const char *somestring = "blah blah"; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - git_buf_attach_notowned(&buf, somestring, strlen(somestring) + 1); + git_str_attach_notowned(&buf, somestring, strlen(somestring) + 1); cl_assert_equal_p(somestring, buf.ptr); cl_assert_equal_i(0, buf.asize); cl_assert_equal_i(strlen(somestring) + 1, buf.size); - cl_git_fail_with(GIT_EINVALID, git_buf_grow(&buf, 1024)); + cl_git_fail_with(GIT_EINVALID, git_str_grow(&buf, 1024)); } -void test_core_buffer__dont_hit_infinite_loop_when_resizing(void) +void test_core_gitstr__dont_hit_infinite_loop_when_resizing(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_puts(&buf, "foobar")); + cl_git_pass(git_str_puts(&buf, "foobar")); /* * We do not care whether this succeeds or fails, which * would depend on platform-specific allocation * semantics. We only want to know that the function * actually returns. */ - (void)git_buf_try_grow(&buf, SIZE_MAX, true); + (void)git_str_try_grow(&buf, SIZE_MAX, true); - git_buf_dispose(&buf); + git_str_dispose(&buf); } -void test_core_buffer__avoid_printing_into_oom_buffer(void) +void test_core_gitstr__avoid_printing_into_oom_buffer(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; /* Emulate OOM situation with a previous allocation */ buf.asize = 8; - buf.ptr = git_buf__oom; + buf.ptr = git_str__oom; /* * Print the same string again. As the buffer still has * an `asize` of 8 due to the previous print, * `ENSURE_SIZE` would not try to reallocate the array at - * all. As it didn't explicitly check for `git_buf__oom` + * all. As it didn't explicitly check for `git_str__oom` * in earlier versions, this would've resulted in it - * returning successfully and thus `git_buf_puts` would - * just print into the `git_buf__oom` array. + * returning successfully and thus `git_str_puts` would + * just print into the `git_str__oom` array. */ - cl_git_fail(git_buf_puts(&buf, "foobar")); + cl_git_fail(git_str_puts(&buf, "foobar")); } diff --git a/tests/core/link.c b/tests/core/link.c index 0493edf1dd7..6ab79b2a869 100644 --- a/tests/core/link.c +++ b/tests/core/link.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "posix.h" -#include "buffer.h" #include "path.h" #ifdef GIT_WIN32 @@ -82,7 +81,7 @@ static void do_junction(const char *old, const char *new) { GIT_REPARSE_DATA_BUFFER *reparse_buf; HANDLE handle; - git_buf unparsed_buf = GIT_BUF_INIT; + git_str unparsed_buf = GIT_STR_INIT; wchar_t *subst_utf16, *print_utf16; DWORD ioctl_ret; int subst_utf16_len, subst_byte_len, print_utf16_len, print_byte_len, ret; @@ -93,14 +92,14 @@ static void do_junction(const char *old, const char *new) * backslashes instead of forward, and end in a trailing backslash. * eg: \??\C:\Foo\ */ - git_buf_puts(&unparsed_buf, "\\??\\"); + git_str_puts(&unparsed_buf, "\\??\\"); for (i = 0; i < strlen(old); i++) - git_buf_putc(&unparsed_buf, old[i] == '/' ? '\\' : old[i]); + git_str_putc(&unparsed_buf, old[i] == '/' ? '\\' : old[i]); - git_buf_putc(&unparsed_buf, '\\'); + git_str_putc(&unparsed_buf, '\\'); - subst_utf16_len = git__utf8_to_16(NULL, 0, git_buf_cstr(&unparsed_buf)); + subst_utf16_len = git__utf8_to_16(NULL, 0, git_str_cstr(&unparsed_buf)); subst_byte_len = subst_utf16_len * sizeof(WCHAR); print_utf16_len = subst_utf16_len - 4; @@ -127,11 +126,11 @@ static void do_junction(const char *old, const char *new) print_utf16 = subst_utf16 + subst_utf16_len + 1; ret = git__utf8_to_16(subst_utf16, subst_utf16_len + 1, - git_buf_cstr(&unparsed_buf)); + git_str_cstr(&unparsed_buf)); cl_assert_equal_i(subst_utf16_len, ret); ret = git__utf8_to_16(print_utf16, - print_utf16_len + 1, git_buf_cstr(&unparsed_buf) + 4); + print_utf16_len + 1, git_str_cstr(&unparsed_buf) + 4); cl_assert_equal_i(print_utf16_len, ret); reparse_buf->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; @@ -147,7 +146,7 @@ static void do_junction(const char *old, const char *new) CloseHandle(handle); LocalFree(reparse_buf); - git_buf_dispose(&unparsed_buf); + git_str_dispose(&unparsed_buf); } static void do_custom_reparse(const char *path) @@ -300,7 +299,7 @@ void test_core_link__stat_dangling_symlink_directory(void) void test_core_link__lstat_symlink(void) { - git_buf target_path = GIT_BUF_INIT; + git_str target_path = GIT_STR_INIT; struct stat st; if (!should_run()) @@ -309,10 +308,10 @@ void test_core_link__lstat_symlink(void) /* Windows always writes the canonical path as the link target, so * write the full path on all platforms. */ - git_buf_join(&target_path, '/', clar_sandbox_path(), "lstat_target"); + git_str_join(&target_path, '/', clar_sandbox_path(), "lstat_target"); cl_git_rewritefile("lstat_target", "This is the target of a symbolic link.\n"); - do_symlink(git_buf_cstr(&target_path), "lstat_symlink", 0); + do_symlink(git_str_cstr(&target_path), "lstat_symlink", 0); cl_must_pass(p_lstat("lstat_target", &st)); cl_assert(S_ISREG(st.st_mode)); @@ -320,32 +319,32 @@ void test_core_link__lstat_symlink(void) cl_must_pass(p_lstat("lstat_symlink", &st)); cl_assert(S_ISLNK(st.st_mode)); - cl_assert_equal_i(git_buf_len(&target_path), st.st_size); + cl_assert_equal_i(git_str_len(&target_path), st.st_size); - git_buf_dispose(&target_path); + git_str_dispose(&target_path); } void test_core_link__lstat_symlink_directory(void) { - git_buf target_path = GIT_BUF_INIT; + git_str target_path = GIT_STR_INIT; struct stat st; if (!should_run()) clar__skip(); - git_buf_join(&target_path, '/', clar_sandbox_path(), "lstat_dirtarget"); + git_str_join(&target_path, '/', clar_sandbox_path(), "lstat_dirtarget"); p_mkdir("lstat_dirtarget", 0777); - do_symlink(git_buf_cstr(&target_path), "lstat_dirlink", 1); + do_symlink(git_str_cstr(&target_path), "lstat_dirlink", 1); cl_must_pass(p_lstat("lstat_dirtarget", &st)); cl_assert(S_ISDIR(st.st_mode)); cl_must_pass(p_lstat("lstat_dirlink", &st)); cl_assert(S_ISLNK(st.st_mode)); - cl_assert_equal_i(git_buf_len(&target_path), st.st_size); + cl_assert_equal_i(git_str_len(&target_path), st.st_size); - git_buf_dispose(&target_path); + git_str_dispose(&target_path); } void test_core_link__lstat_dangling_symlink(void) @@ -383,13 +382,13 @@ void test_core_link__lstat_dangling_symlink_directory(void) void test_core_link__stat_junction(void) { #ifdef GIT_WIN32 - git_buf target_path = GIT_BUF_INIT; + git_str target_path = GIT_STR_INIT; struct stat st; - git_buf_join(&target_path, '/', clar_sandbox_path(), "stat_junctarget"); + git_str_join(&target_path, '/', clar_sandbox_path(), "stat_junctarget"); p_mkdir("stat_junctarget", 0777); - do_junction(git_buf_cstr(&target_path), "stat_junction"); + do_junction(git_str_cstr(&target_path), "stat_junction"); cl_must_pass(p_stat("stat_junctarget", &st)); cl_assert(S_ISDIR(st.st_mode)); @@ -397,40 +396,40 @@ void test_core_link__stat_junction(void) cl_must_pass(p_stat("stat_junction", &st)); cl_assert(S_ISDIR(st.st_mode)); - git_buf_dispose(&target_path); + git_str_dispose(&target_path); #endif } void test_core_link__stat_dangling_junction(void) { #ifdef GIT_WIN32 - git_buf target_path = GIT_BUF_INIT; + git_str target_path = GIT_STR_INIT; struct stat st; - git_buf_join(&target_path, '/', clar_sandbox_path(), "stat_nonexistent_junctarget"); + git_str_join(&target_path, '/', clar_sandbox_path(), "stat_nonexistent_junctarget"); p_mkdir("stat_nonexistent_junctarget", 0777); - do_junction(git_buf_cstr(&target_path), "stat_dangling_junction"); + do_junction(git_str_cstr(&target_path), "stat_dangling_junction"); RemoveDirectory("stat_nonexistent_junctarget"); cl_must_fail(p_stat("stat_nonexistent_junctarget", &st)); cl_must_fail(p_stat("stat_dangling_junction", &st)); - git_buf_dispose(&target_path); + git_str_dispose(&target_path); #endif } void test_core_link__lstat_junction(void) { #ifdef GIT_WIN32 - git_buf target_path = GIT_BUF_INIT; + git_str target_path = GIT_STR_INIT; struct stat st; - git_buf_join(&target_path, '/', clar_sandbox_path(), "lstat_junctarget"); + git_str_join(&target_path, '/', clar_sandbox_path(), "lstat_junctarget"); p_mkdir("lstat_junctarget", 0777); - do_junction(git_buf_cstr(&target_path), "lstat_junction"); + do_junction(git_str_cstr(&target_path), "lstat_junction"); cl_must_pass(p_lstat("lstat_junctarget", &st)); cl_assert(S_ISDIR(st.st_mode)); @@ -438,20 +437,20 @@ void test_core_link__lstat_junction(void) cl_must_pass(p_lstat("lstat_junction", &st)); cl_assert(S_ISLNK(st.st_mode)); - git_buf_dispose(&target_path); + git_str_dispose(&target_path); #endif } void test_core_link__lstat_dangling_junction(void) { #ifdef GIT_WIN32 - git_buf target_path = GIT_BUF_INIT; + git_str target_path = GIT_STR_INIT; struct stat st; - git_buf_join(&target_path, '/', clar_sandbox_path(), "lstat_nonexistent_junctarget"); + git_str_join(&target_path, '/', clar_sandbox_path(), "lstat_nonexistent_junctarget"); p_mkdir("lstat_nonexistent_junctarget", 0777); - do_junction(git_buf_cstr(&target_path), "lstat_dangling_junction"); + do_junction(git_str_cstr(&target_path), "lstat_dangling_junction"); RemoveDirectory("lstat_nonexistent_junctarget"); @@ -459,9 +458,9 @@ void test_core_link__lstat_dangling_junction(void) cl_must_pass(p_lstat("lstat_dangling_junction", &st)); cl_assert(S_ISLNK(st.st_mode)); - cl_assert_equal_i(git_buf_len(&target_path), st.st_size); + cl_assert_equal_i(git_str_len(&target_path), st.st_size); - git_buf_dispose(&target_path); + git_str_dispose(&target_path); #endif } @@ -554,79 +553,79 @@ void test_core_link__readlink_normal_file(void) void test_core_link__readlink_symlink(void) { - git_buf target_path = GIT_BUF_INIT; + git_str target_path = GIT_STR_INIT; int len; char buf[2048]; if (!should_run()) clar__skip(); - git_buf_join(&target_path, '/', clar_sandbox_path(), "readlink_target"); + git_str_join(&target_path, '/', clar_sandbox_path(), "readlink_target"); cl_git_rewritefile("readlink_target", "This is the target of a symlink\n"); - do_symlink(git_buf_cstr(&target_path), "readlink_link", 0); + do_symlink(git_str_cstr(&target_path), "readlink_link", 0); len = p_readlink("readlink_link", buf, 2048); cl_must_pass(len); buf[len] = 0; - cl_assert_equal_s(git_buf_cstr(&target_path), buf); + cl_assert_equal_s(git_str_cstr(&target_path), buf); - git_buf_dispose(&target_path); + git_str_dispose(&target_path); } void test_core_link__readlink_dangling(void) { - git_buf target_path = GIT_BUF_INIT; + git_str target_path = GIT_STR_INIT; int len; char buf[2048]; if (!should_run()) clar__skip(); - git_buf_join(&target_path, '/', clar_sandbox_path(), "readlink_nonexistent"); + git_str_join(&target_path, '/', clar_sandbox_path(), "readlink_nonexistent"); - do_symlink(git_buf_cstr(&target_path), "readlink_dangling", 0); + do_symlink(git_str_cstr(&target_path), "readlink_dangling", 0); len = p_readlink("readlink_dangling", buf, 2048); cl_must_pass(len); buf[len] = 0; - cl_assert_equal_s(git_buf_cstr(&target_path), buf); + cl_assert_equal_s(git_str_cstr(&target_path), buf); - git_buf_dispose(&target_path); + git_str_dispose(&target_path); } void test_core_link__readlink_multiple(void) { - git_buf target_path = GIT_BUF_INIT, - path3 = GIT_BUF_INIT, path2 = GIT_BUF_INIT, path1 = GIT_BUF_INIT; + git_str target_path = GIT_STR_INIT, + path3 = GIT_STR_INIT, path2 = GIT_STR_INIT, path1 = GIT_STR_INIT; int len; char buf[2048]; if (!should_run()) clar__skip(); - git_buf_join(&target_path, '/', clar_sandbox_path(), "readlink_final"); - git_buf_join(&path3, '/', clar_sandbox_path(), "readlink_3"); - git_buf_join(&path2, '/', clar_sandbox_path(), "readlink_2"); - git_buf_join(&path1, '/', clar_sandbox_path(), "readlink_1"); + git_str_join(&target_path, '/', clar_sandbox_path(), "readlink_final"); + git_str_join(&path3, '/', clar_sandbox_path(), "readlink_3"); + git_str_join(&path2, '/', clar_sandbox_path(), "readlink_2"); + git_str_join(&path1, '/', clar_sandbox_path(), "readlink_1"); - do_symlink(git_buf_cstr(&target_path), git_buf_cstr(&path3), 0); - do_symlink(git_buf_cstr(&path3), git_buf_cstr(&path2), 0); - do_symlink(git_buf_cstr(&path2), git_buf_cstr(&path1), 0); + do_symlink(git_str_cstr(&target_path), git_str_cstr(&path3), 0); + do_symlink(git_str_cstr(&path3), git_str_cstr(&path2), 0); + do_symlink(git_str_cstr(&path2), git_str_cstr(&path1), 0); len = p_readlink("readlink_1", buf, 2048); cl_must_pass(len); buf[len] = 0; - cl_assert_equal_s(git_buf_cstr(&path2), buf); + cl_assert_equal_s(git_str_cstr(&path2), buf); - git_buf_dispose(&path1); - git_buf_dispose(&path2); - git_buf_dispose(&path3); - git_buf_dispose(&target_path); + git_str_dispose(&path1); + git_str_dispose(&path2); + git_str_dispose(&path3); + git_str_dispose(&target_path); } diff --git a/tests/core/mkdir.c b/tests/core/mkdir.c index 3f04c2ad371..f0461ac1f27 100644 --- a/tests/core/mkdir.c +++ b/tests/core/mkdir.c @@ -15,41 +15,41 @@ static void cleanup_basic_dirs(void *ref) void test_core_mkdir__absolute(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_set_cleanup(cleanup_basic_dirs, NULL); - git_buf_joinpath(&path, clar_sandbox_path(), "d0"); + git_str_joinpath(&path, clar_sandbox_path(), "d0"); /* make a directory */ cl_assert(!git_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir(path.ptr, 0755, 0)); cl_assert(git_path_isdir(path.ptr)); - git_buf_joinpath(&path, path.ptr, "subdir"); + git_str_joinpath(&path, path.ptr, "subdir"); cl_assert(!git_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir(path.ptr, 0755, 0)); cl_assert(git_path_isdir(path.ptr)); /* ensure mkdir_r works for a single subdir */ - git_buf_joinpath(&path, path.ptr, "another"); + git_str_joinpath(&path, path.ptr, "another"); cl_assert(!git_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir_r(path.ptr, 0755)); cl_assert(git_path_isdir(path.ptr)); /* ensure mkdir_r works */ - git_buf_joinpath(&path, clar_sandbox_path(), "d1/foo/bar/asdf"); + git_str_joinpath(&path, clar_sandbox_path(), "d1/foo/bar/asdf"); cl_assert(!git_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir_r(path.ptr, 0755)); cl_assert(git_path_isdir(path.ptr)); /* ensure we don't imply recursive */ - git_buf_joinpath(&path, clar_sandbox_path(), "d2/foo/bar/asdf"); + git_str_joinpath(&path, clar_sandbox_path(), "d2/foo/bar/asdf"); cl_assert(!git_path_isdir(path.ptr)); cl_git_fail(git_futils_mkdir(path.ptr, 0755, 0)); cl_assert(!git_path_isdir(path.ptr)); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_core_mkdir__basic(void) @@ -230,7 +230,7 @@ void test_core_mkdir__chmods(void) void test_core_mkdir__keeps_parent_symlinks(void) { #ifndef GIT_WIN32 - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_set_cleanup(cleanup_basic_dirs, NULL); @@ -250,14 +250,14 @@ void test_core_mkdir__keeps_parent_symlinks(void) cl_must_pass(symlink("d0", "d2")); cl_assert(git_path_islink("d2")); - git_buf_joinpath(&path, clar_sandbox_path(), "d2/other/dir"); + git_str_joinpath(&path, clar_sandbox_path(), "d2/other/dir"); cl_git_pass(git_futils_mkdir(path.ptr, 0755, GIT_MKDIR_PATH|GIT_MKDIR_REMOVE_SYMLINKS)); cl_assert(git_path_islink("d2")); cl_assert(git_path_isdir("d2/other/dir")); cl_assert(git_path_isdir("d0/other/dir")); - git_buf_dispose(&path); + git_str_dispose(&path); #endif } diff --git a/tests/core/path.c b/tests/core/path.c index eac3573fea7..6decf23eaae 100644 --- a/tests/core/path.c +++ b/tests/core/path.c @@ -4,12 +4,12 @@ static void check_dirname(const char *A, const char *B) { - git_buf dir = GIT_BUF_INIT; + git_str dir = GIT_STR_INIT; char *dir2; cl_assert(git_path_dirname_r(&dir, A) >= 0); cl_assert_equal_s(B, dir.ptr); - git_buf_dispose(&dir); + git_str_dispose(&dir); cl_assert((dir2 = git_path_dirname(A)) != NULL); cl_assert_equal_s(B, dir2); @@ -19,12 +19,12 @@ check_dirname(const char *A, const char *B) static void check_basename(const char *A, const char *B) { - git_buf base = GIT_BUF_INIT; + git_str base = GIT_STR_INIT; char *base2; cl_assert(git_path_basename_r(&base, A) >= 0); cl_assert_equal_s(B, base.ptr); - git_buf_dispose(&base); + git_str_dispose(&base); cl_assert((base2 = git_path_basename(A)) != NULL); cl_assert_equal_s(B, base2); @@ -34,12 +34,12 @@ check_basename(const char *A, const char *B) static void check_joinpath(const char *path_a, const char *path_b, const char *expected_path) { - git_buf joined_path = GIT_BUF_INIT; + git_str joined_path = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&joined_path, path_a, path_b)); + cl_git_pass(git_str_joinpath(&joined_path, path_a, path_b)); cl_assert_equal_s(expected_path, joined_path.ptr); - git_buf_dispose(&joined_path); + git_str_dispose(&joined_path); } static void @@ -50,13 +50,13 @@ check_joinpath_n( const char *path_d, const char *expected_path) { - git_buf joined_path = GIT_BUF_INIT; + git_str joined_path = GIT_STR_INIT; - cl_git_pass(git_buf_join_n(&joined_path, '/', 4, + cl_git_pass(git_str_join_n(&joined_path, '/', 4, path_a, path_b, path_c, path_d)); cl_assert_equal_s(expected_path, joined_path.ptr); - git_buf_dispose(&joined_path); + git_str_dispose(&joined_path); } @@ -172,13 +172,13 @@ check_path_to_dir( const char* path, const char* expected) { - git_buf tgt = GIT_BUF_INIT; + git_str tgt = GIT_STR_INIT; - git_buf_sets(&tgt, path); + git_str_sets(&tgt, path); cl_git_pass(git_path_to_dir(&tgt)); cl_assert_equal_s(expected, tgt.ptr); - git_buf_dispose(&tgt); + git_str_dispose(&tgt); } static void @@ -231,46 +231,46 @@ void test_core_path__07_path_to_dir(void) /* join path to itself */ void test_core_path__08_self_join(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; size_t asize = 0; asize = path.asize; - cl_git_pass(git_buf_sets(&path, "/foo")); + cl_git_pass(git_str_sets(&path, "/foo")); cl_assert_equal_s(path.ptr, "/foo"); cl_assert(asize < path.asize); asize = path.asize; - cl_git_pass(git_buf_joinpath(&path, path.ptr, "this is a new string")); + cl_git_pass(git_str_joinpath(&path, path.ptr, "this is a new string")); cl_assert_equal_s(path.ptr, "/foo/this is a new string"); cl_assert(asize < path.asize); asize = path.asize; - cl_git_pass(git_buf_joinpath(&path, path.ptr, "/grow the buffer, grow the buffer, grow the buffer")); + cl_git_pass(git_str_joinpath(&path, path.ptr, "/grow the buffer, grow the buffer, grow the buffer")); cl_assert_equal_s(path.ptr, "/foo/this is a new string/grow the buffer, grow the buffer, grow the buffer"); cl_assert(asize < path.asize); - git_buf_dispose(&path); - cl_git_pass(git_buf_sets(&path, "/foo/bar")); + git_str_dispose(&path); + cl_git_pass(git_str_sets(&path, "/foo/bar")); - cl_git_pass(git_buf_joinpath(&path, path.ptr + 4, "baz")); + cl_git_pass(git_str_joinpath(&path, path.ptr + 4, "baz")); cl_assert_equal_s(path.ptr, "/bar/baz"); asize = path.asize; - cl_git_pass(git_buf_joinpath(&path, path.ptr + 4, "somethinglongenoughtorealloc")); + cl_git_pass(git_str_joinpath(&path, path.ptr + 4, "somethinglongenoughtorealloc")); cl_assert_equal_s(path.ptr, "/baz/somethinglongenoughtorealloc"); cl_assert(asize < path.asize); - git_buf_dispose(&path); + git_str_dispose(&path); } static void check_percent_decoding(const char *expected_result, const char *input) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; cl_git_pass(git__percent_decode(&buf, input)); - cl_assert_equal_s(expected_result, git_buf_cstr(&buf)); + cl_assert_equal_s(expected_result, git_str_cstr(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } void test_core_path__09_percent_decode(void) @@ -289,17 +289,17 @@ void test_core_path__09_percent_decode(void) static void check_fromurl(const char *expected_result, const char *input, int should_fail) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; assert(should_fail || expected_result); if (!should_fail) { cl_git_pass(git_path_fromurl(&buf, input)); - cl_assert_equal_s(expected_result, git_buf_cstr(&buf)); + cl_assert_equal_s(expected_result, git_str_cstr(&buf)); } else cl_git_fail(git_path_fromurl(&buf, input)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } #ifdef GIT_WIN32 @@ -353,7 +353,7 @@ static int check_one_walkup_step(void *ref, const char *path) void test_core_path__11_walkup(void) { - git_buf p = GIT_BUF_INIT; + git_str p = GIT_STR_INIT; char *expect[] = { /* 1 */ "/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL, @@ -398,7 +398,7 @@ void test_core_path__11_walkup(void) for (i = 0, j = 0; expect[i] != NULL; i++, j++) { - git_buf_sets(&p, expect[i]); + git_str_sets(&p, expect[i]); info.expect_idx = i; cl_git_pass( @@ -410,12 +410,12 @@ void test_core_path__11_walkup(void) i = info.expect_idx; } - git_buf_dispose(&p); + git_str_dispose(&p); } void test_core_path__11a_walkup_cancel(void) { - git_buf p = GIT_BUF_INIT; + git_str p = GIT_STR_INIT; int cancel[] = { 3, 2, 1, 0 }; char *expect[] = { "/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "[CANCEL]", NULL, @@ -432,7 +432,7 @@ void test_core_path__11a_walkup_cancel(void) for (i = 0, j = 0; expect[i] != NULL; i++, j++) { - git_buf_sets(&p, expect[i]); + git_str_sets(&p, expect[i]); info.cancel_after = cancel[j]; info.expect_idx = i; @@ -446,7 +446,7 @@ void test_core_path__11a_walkup_cancel(void) while (expect[i] != NULL) i++; } - git_buf_dispose(&p); + git_str_dispose(&p); } void test_core_path__12_offset_to_path_root(void) @@ -468,20 +468,20 @@ void test_core_path__12_offset_to_path_root(void) void test_core_path__13_cannot_prettify_a_non_existing_file(void) { - git_buf p = GIT_BUF_INIT; + git_str p = GIT_STR_INIT; cl_assert_equal_b(git_path_exists(NON_EXISTING_FILEPATH), false); cl_assert_equal_i(GIT_ENOTFOUND, git_path_prettify(&p, NON_EXISTING_FILEPATH, NULL)); cl_assert_equal_i(GIT_ENOTFOUND, git_path_prettify(&p, NON_EXISTING_FILEPATH "/so-do-i", NULL)); - git_buf_dispose(&p); + git_str_dispose(&p); } void test_core_path__14_apply_relative(void) { - git_buf p = GIT_BUF_INIT; + git_str p = GIT_STR_INIT; - cl_git_pass(git_buf_sets(&p, "/this/is/a/base")); + cl_git_pass(git_str_sets(&p, "/this/is/a/base")); cl_git_pass(git_path_apply_relative(&p, "../test")); cl_assert_equal_s("/this/is/a/test", p.ptr); @@ -501,7 +501,7 @@ void test_core_path__14_apply_relative(void) cl_git_fail(git_path_apply_relative(&p, "../../..")); - cl_git_pass(git_buf_sets(&p, "d:/another/test")); + cl_git_pass(git_str_sets(&p, "d:/another/test")); cl_git_pass(git_path_apply_relative(&p, "../..")); cl_assert_equal_s("d:/", p.ptr); @@ -510,7 +510,7 @@ void test_core_path__14_apply_relative(void) cl_assert_equal_s("d:/from/here/and/back/", p.ptr); - cl_git_pass(git_buf_sets(&p, "https://my.url.com/test.git")); + cl_git_pass(git_str_sets(&p, "https://my.url.com/test.git")); cl_git_pass(git_path_apply_relative(&p, "../another.git")); cl_assert_equal_s("https://my.url.com/another.git", p.ptr); @@ -525,7 +525,7 @@ void test_core_path__14_apply_relative(void) cl_assert_equal_s("https://", p.ptr); - cl_git_pass(git_buf_sets(&p, "../../this/is/relative")); + cl_git_pass(git_str_sets(&p, "../../this/is/relative")); cl_git_pass(git_path_apply_relative(&p, "../../preserves/the/prefix")); cl_assert_equal_s("../../this/preserves/the/prefix", p.ptr); @@ -535,20 +535,20 @@ void test_core_path__14_apply_relative(void) cl_git_pass(git_path_apply_relative(&p, "../there")); cl_assert_equal_s("../../there", p.ptr); - git_buf_dispose(&p); + git_str_dispose(&p); } static void assert_resolve_relative( - git_buf *buf, const char *expected, const char *path) + git_str *buf, const char *expected, const char *path) { - cl_git_pass(git_buf_sets(buf, path)); + cl_git_pass(git_str_sets(buf, path)); cl_git_pass(git_path_resolve_relative(buf, 0)); cl_assert_equal_s(expected, buf->ptr); } void test_core_path__15_resolve_relative(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; assert_resolve_relative(&buf, "", ""); assert_resolve_relative(&buf, "", "."); @@ -595,22 +595,22 @@ void test_core_path__15_resolve_relative(void) assert_resolve_relative(&buf, "../../path", "../../test//../././path"); assert_resolve_relative(&buf, "../d", "a/b/../../../c/../d"); - cl_git_pass(git_buf_sets(&buf, "/..")); + cl_git_pass(git_str_sets(&buf, "/..")); cl_git_fail(git_path_resolve_relative(&buf, 0)); - cl_git_pass(git_buf_sets(&buf, "/./..")); + cl_git_pass(git_str_sets(&buf, "/./..")); cl_git_fail(git_path_resolve_relative(&buf, 0)); - cl_git_pass(git_buf_sets(&buf, "/.//..")); + cl_git_pass(git_str_sets(&buf, "/.//..")); cl_git_fail(git_path_resolve_relative(&buf, 0)); - cl_git_pass(git_buf_sets(&buf, "/../.")); + cl_git_pass(git_str_sets(&buf, "/../.")); cl_git_fail(git_path_resolve_relative(&buf, 0)); - cl_git_pass(git_buf_sets(&buf, "/../.././../a")); + cl_git_pass(git_str_sets(&buf, "/../.././../a")); cl_git_fail(git_path_resolve_relative(&buf, 0)); - cl_git_pass(git_buf_sets(&buf, "////..")); + cl_git_pass(git_str_sets(&buf, "////..")); cl_git_fail(git_path_resolve_relative(&buf, 0)); /* things that start with Windows network paths */ @@ -619,7 +619,7 @@ void test_core_path__15_resolve_relative(void) assert_resolve_relative(&buf, "//a/", "//a/b/.."); assert_resolve_relative(&buf, "//a/b/c", "//a/Q/../b/x/y/../../c"); - cl_git_pass(git_buf_sets(&buf, "//a/b/../..")); + cl_git_pass(git_str_sets(&buf, "//a/b/../..")); cl_git_fail(git_path_resolve_relative(&buf, 0)); #else assert_resolve_relative(&buf, "/a/b/c", "//a/b/c"); @@ -628,7 +628,7 @@ void test_core_path__15_resolve_relative(void) assert_resolve_relative(&buf, "/", "//a/b/../.."); #endif - git_buf_dispose(&buf); + git_str_dispose(&buf); } #define assert_common_dirlen(i, p, q) \ diff --git a/tests/core/posix.c b/tests/core/posix.c index 1bb1e9c6b1d..247bd43f52b 100644 --- a/tests/core/posix.c +++ b/tests/core/posix.c @@ -168,7 +168,7 @@ void test_core_posix__unlink_removes_symlink(void) void test_core_posix__symlink_resolves_to_correct_type(void) { - git_buf contents = GIT_BUF_INIT; + git_str contents = GIT_STR_INIT; if (!git_path_supports_symlinks(clar_sandbox_path())) clar__skip(); @@ -187,12 +187,12 @@ void test_core_posix__symlink_resolves_to_correct_type(void) cl_must_pass(p_rmdir("dir")); cl_must_pass(p_rmdir("file")); - git_buf_dispose(&contents); + git_str_dispose(&contents); } void test_core_posix__relative_symlink(void) { - git_buf contents = GIT_BUF_INIT; + git_str contents = GIT_STR_INIT; if (!git_path_supports_symlinks(clar_sandbox_path())) clar__skip(); @@ -207,12 +207,12 @@ void test_core_posix__relative_symlink(void) cl_must_pass(p_unlink("dir/link")); cl_must_pass(p_rmdir("dir")); - git_buf_dispose(&contents); + git_str_dispose(&contents); } void test_core_posix__symlink_to_file_across_dirs(void) { - git_buf contents = GIT_BUF_INIT; + git_str contents = GIT_STR_INIT; if (!git_path_supports_symlinks(clar_sandbox_path())) clar__skip(); @@ -234,5 +234,5 @@ void test_core_posix__symlink_to_file_across_dirs(void) cl_must_pass(p_unlink("link")); cl_must_pass(p_rmdir("dir")); - git_buf_dispose(&contents); + git_str_dispose(&contents); } diff --git a/tests/core/rmdir.c b/tests/core/rmdir.c index b436b97e061..56ea320bea5 100644 --- a/tests/core/rmdir.c +++ b/tests/core/rmdir.c @@ -5,26 +5,26 @@ static const char *empty_tmp_dir = "test_gitfo_rmdir_recurs_test"; void test_core_rmdir__initialize(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_must_pass(p_mkdir(empty_tmp_dir, 0777)); - cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one")); + cl_git_pass(git_str_joinpath(&path, empty_tmp_dir, "/one")); cl_must_pass(p_mkdir(path.ptr, 0777)); - cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one/two_one")); + cl_git_pass(git_str_joinpath(&path, empty_tmp_dir, "/one/two_one")); cl_must_pass(p_mkdir(path.ptr, 0777)); - cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one/two_two")); + cl_git_pass(git_str_joinpath(&path, empty_tmp_dir, "/one/two_two")); cl_must_pass(p_mkdir(path.ptr, 0777)); - cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one/two_two/three")); + cl_git_pass(git_str_joinpath(&path, empty_tmp_dir, "/one/two_two/three")); cl_must_pass(p_mkdir(path.ptr, 0777)); - cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/two")); + cl_git_pass(git_str_joinpath(&path, empty_tmp_dir, "/two")); cl_must_pass(p_mkdir(path.ptr, 0777)); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_core_rmdir__cleanup(void) @@ -36,25 +36,25 @@ void test_core_rmdir__cleanup(void) /* make sure empty dir can be deleted recusively */ void test_core_rmdir__delete_recursive(void) { - git_buf path = GIT_BUF_INIT; - cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one")); - cl_assert(git_path_exists(git_buf_cstr(&path))); + git_str path = GIT_STR_INIT; + cl_git_pass(git_str_joinpath(&path, empty_tmp_dir, "/one")); + cl_assert(git_path_exists(git_str_cstr(&path))); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY)); - cl_assert(!git_path_exists(git_buf_cstr(&path))); + cl_assert(!git_path_exists(git_str_cstr(&path))); - git_buf_dispose(&path); + git_str_dispose(&path); } /* make sure non-empty dir cannot be deleted recusively */ void test_core_rmdir__fail_to_delete_non_empty_dir(void) { - git_buf file = GIT_BUF_INIT; + git_str file = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&file, empty_tmp_dir, "/two/file.txt")); + cl_git_pass(git_str_joinpath(&file, empty_tmp_dir, "/two/file.txt")); - cl_git_mkfile(git_buf_cstr(&file), "dummy"); + cl_git_mkfile(git_str_cstr(&file), "dummy"); cl_git_fail(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY)); @@ -63,7 +63,7 @@ void test_core_rmdir__fail_to_delete_non_empty_dir(void) cl_assert(!git_path_exists(empty_tmp_dir)); - git_buf_dispose(&file); + git_str_dispose(&file); } void test_core_rmdir__keep_base(void) @@ -74,47 +74,47 @@ void test_core_rmdir__keep_base(void) void test_core_rmdir__can_skip_non_empty_dir(void) { - git_buf file = GIT_BUF_INIT; + git_str file = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&file, empty_tmp_dir, "/two/file.txt")); + cl_git_pass(git_str_joinpath(&file, empty_tmp_dir, "/two/file.txt")); - cl_git_mkfile(git_buf_cstr(&file), "dummy"); + cl_git_mkfile(git_str_cstr(&file), "dummy"); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_SKIP_NONEMPTY)); - cl_assert(git_path_exists(git_buf_cstr(&file)) == true); + cl_assert(git_path_exists(git_str_cstr(&file)) == true); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_REMOVE_FILES)); cl_assert(git_path_exists(empty_tmp_dir) == false); - git_buf_dispose(&file); + git_str_dispose(&file); } void test_core_rmdir__can_remove_empty_parents(void) { - git_buf file = GIT_BUF_INIT; + git_str file = GIT_STR_INIT; cl_git_pass( - git_buf_joinpath(&file, empty_tmp_dir, "/one/two_two/three/file.txt")); - cl_git_mkfile(git_buf_cstr(&file), "dummy"); - cl_assert(git_path_isfile(git_buf_cstr(&file))); + git_str_joinpath(&file, empty_tmp_dir, "/one/two_two/three/file.txt")); + cl_git_mkfile(git_str_cstr(&file), "dummy"); + cl_assert(git_path_isfile(git_str_cstr(&file))); cl_git_pass(git_futils_rmdir_r("one/two_two/three/file.txt", empty_tmp_dir, GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_EMPTY_PARENTS)); - cl_assert(!git_path_exists(git_buf_cstr(&file))); + cl_assert(!git_path_exists(git_str_cstr(&file))); - git_buf_rtruncate_at_char(&file, '/'); /* three (only contained file.txt) */ - cl_assert(!git_path_exists(git_buf_cstr(&file))); + git_str_rtruncate_at_char(&file, '/'); /* three (only contained file.txt) */ + cl_assert(!git_path_exists(git_str_cstr(&file))); - git_buf_rtruncate_at_char(&file, '/'); /* two_two (only contained three) */ - cl_assert(!git_path_exists(git_buf_cstr(&file))); + git_str_rtruncate_at_char(&file, '/'); /* two_two (only contained three) */ + cl_assert(!git_path_exists(git_str_cstr(&file))); - git_buf_rtruncate_at_char(&file, '/'); /* one (contained two_one also) */ - cl_assert(git_path_exists(git_buf_cstr(&file))); + git_str_rtruncate_at_char(&file, '/'); /* one (contained two_one also) */ + cl_assert(git_path_exists(git_str_cstr(&file))); cl_assert(git_path_exists(empty_tmp_dir) == true); - git_buf_dispose(&file); + git_str_dispose(&file); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY)); } diff --git a/tests/core/sortedcache.c b/tests/core/sortedcache.c index d5bbcea19f2..cb4e34efaaf 100644 --- a/tests/core/sortedcache.c +++ b/tests/core/sortedcache.c @@ -241,7 +241,7 @@ void test_core_sortedcache__in_memory(void) static void sortedcache_test_reload(git_sortedcache *sc) { int count = 0; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; char *scan, *after; sortedcache_test_struct *item; @@ -266,7 +266,7 @@ static void sortedcache_test_reload(git_sortedcache *sc) git_sortedcache_wunlock(sc); - git_buf_dispose(&buf); + git_str_dispose(&buf); } void test_core_sortedcache__on_disk(void) diff --git a/tests/core/stat.c b/tests/core/stat.c index 7f5d6675340..56d141e9869 100644 --- a/tests/core/stat.c +++ b/tests/core/stat.c @@ -98,17 +98,17 @@ void test_core_stat__0(void) void test_core_stat__root(void) { const char *sandbox = clar_sandbox_path(); - git_buf root = GIT_BUF_INIT; + git_str root = GIT_STR_INIT; int root_len; struct stat st; root_len = git_path_root(sandbox); cl_assert(root_len >= 0); - git_buf_set(&root, sandbox, root_len+1); + git_str_set(&root, sandbox, root_len+1); cl_must_pass(p_stat(root.ptr, &st)); cl_assert(S_ISDIR(st.st_mode)); - git_buf_dispose(&root); + git_str_dispose(&root); } diff --git a/tests/core/useragent.c b/tests/core/useragent.c index 2ce935bf546..a4ece902fd9 100644 --- a/tests/core/useragent.c +++ b/tests/core/useragent.c @@ -4,7 +4,7 @@ void test_core_useragent__get(void) { const char *custom_name = "super duper git"; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; cl_assert_equal_p(NULL, git_libgit2__user_agent()); cl_git_pass(git_libgit2_opts(GIT_OPT_SET_USER_AGENT, custom_name)); @@ -13,5 +13,5 @@ void test_core_useragent__get(void) cl_git_pass(git_libgit2_opts(GIT_OPT_GET_USER_AGENT, &buf)); cl_assert_equal_s(custom_name, buf.ptr); - git_buf_dispose(&buf); + git_str_dispose(&buf); } diff --git a/tests/core/zstream.c b/tests/core/zstream.c index 3cbcea168d4..c22e81008b6 100644 --- a/tests/core/zstream.c +++ b/tests/core/zstream.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "zstream.h" static const char *data = "This is a test test test of This is a test"; @@ -60,7 +59,7 @@ void test_core_zstream__basic(void) void test_core_zstream__fails_on_trailing_garbage(void) { - git_buf deflated = GIT_BUF_INIT, inflated = GIT_BUF_INIT; + git_str deflated = GIT_STR_INIT, inflated = GIT_STR_INIT; char i = 0; /* compress a simple string */ @@ -68,29 +67,29 @@ void test_core_zstream__fails_on_trailing_garbage(void) /* append some garbage */ for (i = 0; i < 10; i++) { - git_buf_putc(&deflated, i); + git_str_putc(&deflated, i); } cl_git_fail(git_zstream_inflatebuf(&inflated, deflated.ptr, deflated.size)); - git_buf_dispose(&deflated); - git_buf_dispose(&inflated); + git_str_dispose(&deflated); + git_str_dispose(&inflated); } void test_core_zstream__buffer(void) { - git_buf out = GIT_BUF_INIT; + git_str out = GIT_STR_INIT; cl_git_pass(git_zstream_deflatebuf(&out, data, strlen(data) + 1)); assert_zlib_equal(data, strlen(data) + 1, out.ptr, out.size); - git_buf_dispose(&out); + git_str_dispose(&out); } #define BIG_STRING_PART "Big Data IS Big - Long Data IS Long - We need a buffer larger than 1024 x 1024 to make sure we trigger chunked compression - Big Big Data IS Bigger than Big - Long Long Data IS Longer than Long" -static void compress_and_decompress_input_various_ways(git_buf *input) +static void compress_and_decompress_input_various_ways(git_str *input) { - git_buf out1 = GIT_BUF_INIT, out2 = GIT_BUF_INIT; - git_buf inflated = GIT_BUF_INIT; + git_str out1 = GIT_STR_INIT, out2 = GIT_STR_INIT; + git_str inflated = GIT_STR_INIT; size_t i, fixed_size = max(input->size / 2, 256); char *fixed = git__malloc(fixed_size); cl_assert(fixed); @@ -119,7 +118,7 @@ static void compress_and_decompress_input_various_ways(git_buf *input) while (!git_zstream_done(&zs)) { size_t written = use_fixed_size; cl_git_pass(git_zstream_get_output(fixed, &written, &zs)); - cl_git_pass(git_buf_put(&out2, fixed, written)); + cl_git_pass(git_str_put(&out2, fixed, written)); } git_zstream_free(&zs); @@ -129,30 +128,30 @@ static void compress_and_decompress_input_various_ways(git_buf *input) cl_assert_equal_sz(out1.size, out2.size); cl_assert(!memcmp(out1.ptr, out2.ptr, out1.size)); - git_buf_dispose(&out2); + git_str_dispose(&out2); } cl_git_pass(git_zstream_inflatebuf(&inflated, out1.ptr, out1.size)); cl_assert_equal_i(input->size, inflated.size); cl_assert(memcmp(input->ptr, inflated.ptr, inflated.size) == 0); - git_buf_dispose(&out1); - git_buf_dispose(&inflated); + git_str_dispose(&out1); + git_str_dispose(&inflated); git__free(fixed); } void test_core_zstream__big_data(void) { - git_buf in = GIT_BUF_INIT; + git_str in = GIT_STR_INIT; size_t scan, target; for (target = 1024; target <= 1024 * 1024 * 4; target *= 8) { /* make a big string that's easy to compress */ - git_buf_clear(&in); + git_str_clear(&in); while (in.size < target) cl_git_pass( - git_buf_put(&in, BIG_STRING_PART, strlen(BIG_STRING_PART))); + git_str_put(&in, BIG_STRING_PART, strlen(BIG_STRING_PART))); compress_and_decompress_input_various_ways(&in); @@ -164,5 +163,5 @@ void test_core_zstream__big_data(void) compress_and_decompress_input_various_ways(&in); } - git_buf_dispose(&in); + git_str_dispose(&in); } diff --git a/tests/describe/describe.c b/tests/describe/describe.c index 26ca4efd825..ba67ca46b22 100644 --- a/tests/describe/describe.c +++ b/tests/describe/describe.c @@ -32,7 +32,7 @@ void test_describe_describe__describe_a_repo_with_no_refs(void) { git_repository *repo; git_describe_options opts = GIT_DESCRIBE_OPTIONS_INIT; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_object *object; git_describe_result *result = NULL; @@ -50,6 +50,6 @@ void test_describe_describe__describe_a_repo_with_no_refs(void) git_describe_result_free(result); git_object_free(object); - git_buf_dispose(&buf); + git_str_dispose(&buf); cl_git_sandbox_cleanup(); } diff --git a/tests/describe/describe_helpers.c b/tests/describe/describe_helpers.c index 80217dcf0c6..3df3b7c5966 100644 --- a/tests/describe/describe_helpers.c +++ b/tests/describe/describe_helpers.c @@ -18,7 +18,7 @@ void assert_describe( cl_git_pass(git_describe_commit(&result, object, opts)); cl_git_pass(git_describe_format(&label, result, fmt_opts)); - cl_must_pass(wildmatch(expected_output, git_buf_cstr(&label), 0)); + cl_must_pass(wildmatch(expected_output, label.ptr, 0)); git_describe_result_free(result); git_object_free(object); @@ -37,7 +37,7 @@ void assert_describe_workdir( cl_git_pass(git_describe_workdir(&result, repo, opts)); cl_git_pass(git_describe_format(&label, result, fmt_opts)); - cl_must_pass(wildmatch(expected_output, git_buf_cstr(&label), 0)); + cl_must_pass(wildmatch(expected_output, label.ptr, 0)); git_describe_result_free(result); git_buf_dispose(&label); diff --git a/tests/describe/describe_helpers.h b/tests/describe/describe_helpers.h index 16a0638e392..43e8c5e1932 100644 --- a/tests/describe/describe_helpers.h +++ b/tests/describe/describe_helpers.h @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" extern void assert_describe( const char *expected_output, diff --git a/tests/diff/binary.c b/tests/diff/binary.c index 7edf37b5129..24d2b22ef45 100644 --- a/tests/diff/binary.c +++ b/tests/diff/binary.c @@ -2,7 +2,6 @@ #include "git2/sys/diff.h" -#include "buffer.h" #include "delta.h" #include "filebuf.h" #include "repository.h" @@ -53,7 +52,7 @@ void test_patch( cl_assert_equal_s(expected, actual.ptr); - git_buf_clear(&actual); + git_buf_dispose(&actual); cl_git_pass(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, git_diff_print_callback__to_buf, &actual)); cl_assert_equal_s(expected, actual.ptr); @@ -197,7 +196,7 @@ void test_diff_binary__delete(void) void test_diff_binary__delta(void) { git_index *index; - git_buf contents = GIT_BUF_INIT; + git_str contents = GIT_STR_INIT; size_t i; git_diff_options opts = GIT_DIFF_OPTIONS_INIT; const char *expected = @@ -239,7 +238,7 @@ void test_diff_binary__delta(void) expected); git_index_free(index); - git_buf_dispose(&contents); + git_str_dispose(&contents); } void test_diff_binary__delta_append(void) @@ -283,7 +282,7 @@ void test_diff_binary__empty_for_no_diff(void) git_commit *commit; git_tree *tree; git_diff *diff; - git_buf actual = GIT_BUF_INIT; + git_str actual = GIT_STR_INIT; opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY; opts.id_abbrev = GIT_OID_HEXSZ; @@ -299,7 +298,7 @@ void test_diff_binary__empty_for_no_diff(void) cl_assert_equal_s("", actual.ptr); - git_buf_dispose(&actual); + git_str_dispose(&actual); git_diff_free(diff); git_commit_free(commit); git_tree_free(tree); @@ -359,24 +358,24 @@ static int print_cb( const git_diff_line *line, void *payload) { - git_buf *buf = (git_buf *)payload; + git_str *buf = (git_str *)payload; GIT_UNUSED(delta); if (hunk) - git_buf_put(buf, hunk->header, hunk->header_len); + git_str_put(buf, hunk->header, hunk->header_len); if (line) - git_buf_put(buf, line->content, line->content_len); + git_str_put(buf, line->content, line->content_len); - return git_buf_oom(buf) ? -1 : 0; + return git_str_oom(buf) ? -1 : 0; } void test_diff_binary__print_patch_from_diff(void) { git_index *index; git_diff *diff; - git_buf actual = GIT_BUF_INIT; + git_str actual = GIT_STR_INIT; git_diff_options opts = GIT_DIFF_OPTIONS_INIT; const char *expected = "diff --git a/untimely.txt b/untimely.txt\n" \ @@ -403,7 +402,7 @@ void test_diff_binary__print_patch_from_diff(void) cl_assert_equal_s(expected, actual.ptr); - git_buf_dispose(&actual); + git_str_dispose(&actual); git_diff_free(diff); git_index_free(index); } @@ -411,13 +410,13 @@ void test_diff_binary__print_patch_from_diff(void) struct diff_data { char *old_path; git_oid old_id; - git_buf old_binary_base85; + git_str old_binary_base85; size_t old_binary_inflatedlen; git_diff_binary_t old_binary_type; char *new_path; git_oid new_id; - git_buf new_binary_base85; + git_str new_binary_base85; size_t new_binary_inflatedlen; git_diff_binary_t new_binary_type; }; @@ -452,12 +451,12 @@ static int binary_cb( GIT_UNUSED(delta); - git_buf_encode_base85(&diff_data->old_binary_base85, + git_str_encode_base85(&diff_data->old_binary_base85, binary->old_file.data, binary->old_file.datalen); diff_data->old_binary_inflatedlen = binary->old_file.inflatedlen; diff_data->old_binary_type = binary->old_file.type; - git_buf_encode_base85(&diff_data->new_binary_base85, + git_str_encode_base85(&diff_data->new_binary_base85, binary->new_file.data, binary->new_file.datalen); diff_data->new_binary_inflatedlen = binary->new_file.inflatedlen; diff_data->new_binary_type = binary->new_file.type; @@ -541,6 +540,6 @@ void test_diff_binary__blob_to_blob(void) git__free(diff_data.old_path); git__free(diff_data.new_path); - git_buf_dispose(&diff_data.old_binary_base85); - git_buf_dispose(&diff_data.new_binary_base85); + git_str_dispose(&diff_data.old_binary_base85); + git_str_dispose(&diff_data.new_binary_base85); } diff --git a/tests/diff/blob.c b/tests/diff/blob.c index 50edf6bc061..9f71e4ea6e6 100644 --- a/tests/diff/blob.c +++ b/tests/diff/blob.c @@ -915,7 +915,7 @@ void test_diff_blob__using_path_and_attributes(void) "+More lines\n" "+And more\n" "+Go here\n", buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(p); cl_git_pass(git_patch_from_blob_and_buffer( @@ -925,7 +925,7 @@ void test_diff_blob__using_path_and_attributes(void) "diff --git a/zzz.binary b/zzz.binary\n" "index 45141a7..75b0dbb 100644\n" "Binary files a/zzz.binary and b/zzz.binary differ\n", buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(p); cl_git_pass(git_patch_from_blob_and_buffer( @@ -940,7 +940,7 @@ void test_diff_blob__using_path_and_attributes(void) "+More lines\n" "+And more\n" "+Go here\n", buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(p); cl_git_pass(git_patch_from_blob_and_buffer( @@ -955,7 +955,7 @@ void test_diff_blob__using_path_and_attributes(void) "+More lines\n" "+And more\n" "+Go here\n", buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(p); /* "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\n0123456789\n" @@ -971,7 +971,7 @@ void test_diff_blob__using_path_and_attributes(void) "diff --git a/zzz.normal b/zzz.normal\n" "index b435cd5..1604519 100644\n" "Binary files a/zzz.normal and b/zzz.normal differ\n", buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(p); cl_git_pass(git_patch_from_blob_and_buffer( @@ -985,7 +985,7 @@ void test_diff_blob__using_path_and_attributes(void) "@@ -3 +3 @@\n" "-0123456789\n" "+replace a line\n", buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(p); cl_git_pass(git_patch_from_blob_and_buffer( @@ -999,7 +999,7 @@ void test_diff_blob__using_path_and_attributes(void) "@@ -3 +3 @@\n" "-0123456789\n" "+replace a line\n", buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(p); cl_git_pass(git_patch_from_blob_and_buffer( @@ -1013,7 +1013,7 @@ void test_diff_blob__using_path_and_attributes(void) "@@ -3 +3 @@ 0123456789\n" "-0123456789\n" "+replace a line\n", buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(p); git_buf_dispose(&buf); diff --git a/tests/diff/drivers.c b/tests/diff/drivers.c index cace40967f8..ce24e9bc0b9 100644 --- a/tests/diff/drivers.c +++ b/tests/diff/drivers.c @@ -178,7 +178,8 @@ void test_diff_drivers__builtins(void) { git_diff *diff; git_patch *patch; - git_buf file = GIT_BUF_INIT, actual = GIT_BUF_INIT, expected = GIT_BUF_INIT; + git_str file = GIT_STR_INIT, expected = GIT_STR_INIT; + git_buf actual = GIT_BUF_INIT; git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_vector files = GIT_VECTOR_INIT; size_t i; @@ -205,15 +206,15 @@ void test_diff_drivers__builtins(void) cl_git_pass(git_patch_from_diff(&patch, diff, 0)); cl_git_pass(git_patch_to_buf(&actual, patch)); - git_buf_sets(&expected, "userdiff/expected/nodriver/diff."); - git_buf_puts(&expected, extension); + git_str_sets(&expected, "userdiff/expected/nodriver/diff."); + git_str_puts(&expected, extension); cl_git_pass(git_futils_readbuffer(&expected, expected.ptr)); overwrite_filemode(expected.ptr, &actual); cl_assert_equal_s(expected.ptr, actual.ptr); - git_buf_clear(&actual); + git_buf_dispose(&actual); git_patch_free(patch); git_diff_free(diff); @@ -230,24 +231,24 @@ void test_diff_drivers__builtins(void) cl_git_pass(git_patch_from_diff(&patch, diff, 0)); cl_git_pass(git_patch_to_buf(&actual, patch)); - git_buf_sets(&expected, "userdiff/expected/driver/diff."); - git_buf_puts(&expected, extension); + git_str_sets(&expected, "userdiff/expected/driver/diff."); + git_str_puts(&expected, extension); cl_git_pass(git_futils_readbuffer(&expected, expected.ptr)); overwrite_filemode(expected.ptr, &actual); cl_assert_equal_s(expected.ptr, actual.ptr); - git_buf_clear(&actual); + git_buf_dispose(&actual); git_patch_free(patch); git_diff_free(diff); git__free(path); } - git_buf_dispose(&file); git_buf_dispose(&actual); - git_buf_dispose(&expected); + git_str_dispose(&file); + git_str_dispose(&expected); git_vector_free(&files); } diff --git a/tests/diff/format_email.c b/tests/diff/format_email.c index ea7aa070fa2..612804c4288 100644 --- a/tests/diff/format_email.c +++ b/tests/diff/format_email.c @@ -1,7 +1,6 @@ #include "clar.h" #include "clar_libgit2.h" -#include "buffer.h" #include "commit.h" #include "diff.h" #include "diff_generate.h" @@ -41,12 +40,12 @@ static void assert_email_match( cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); cl_git_pass(git_diff_format_email(&buf, diff, opts)); - cl_assert_equal_s(expected, git_buf_cstr(&buf)); - git_buf_clear(&buf); + cl_assert_equal_s(expected, buf.ptr); + git_buf_dispose(&buf); cl_git_pass(git_diff_commit_as_email( &buf, repo, commit, 1, 1, opts->flags, NULL)); - cl_assert_equal_s(expected, git_buf_cstr(&buf)); + cl_assert_equal_s(expected, buf.ptr); git_diff_free(diff); git_commit_free(commit); @@ -258,7 +257,7 @@ void test_diff_format_email__multiple(void) cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); cl_git_pass(git_diff_format_email(&buf, diff, &opts)); - cl_assert_equal_s(email, git_buf_cstr(&buf)); + cl_assert_equal_s(email, buf.ptr); git_diff_free(diff); git_commit_free(commit); diff --git a/tests/diff/parse.c b/tests/diff/parse.c index 6b6e6645e45..d3a0c8de6d4 100644 --- a/tests/diff/parse.c +++ b/tests/diff/parse.c @@ -39,21 +39,21 @@ void test_diff_parse__nonpatches_fail_with_notfound(void) static void test_parse_invalid_diff(const char *invalid_diff) { git_diff *diff; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; /* throw some random (legitimate) diffs in with the given invalid * one. */ - git_buf_puts(&buf, PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE); - git_buf_puts(&buf, PATCH_BINARY_DELTA); - git_buf_puts(&buf, invalid_diff); - git_buf_puts(&buf, PATCH_ORIGINAL_TO_CHANGE_MIDDLE); - git_buf_puts(&buf, PATCH_BINARY_LITERAL); + git_str_puts(&buf, PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE); + git_str_puts(&buf, PATCH_BINARY_DELTA); + git_str_puts(&buf, invalid_diff); + git_str_puts(&buf, PATCH_ORIGINAL_TO_CHANGE_MIDDLE); + git_str_puts(&buf, PATCH_BINARY_LITERAL); cl_git_fail_with(GIT_ERROR, git_diff_from_buffer(&diff, buf.ptr, buf.size)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } void test_diff_parse__exact_rename(void) diff --git a/tests/diff/patch.c b/tests/diff/patch.c index d288bba58aa..8945afc26a8 100644 --- a/tests/diff/patch.c +++ b/tests/diff/patch.c @@ -208,7 +208,7 @@ void test_diff_patch__config_options(void) cl_git_pass(git_patch_to_buf(&buf, patch)); cl_assert_equal_s(expected1, buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(patch); git_diff_free(diff); @@ -219,7 +219,7 @@ void test_diff_patch__config_options(void) cl_git_pass(git_patch_to_buf(&buf, patch)); cl_assert_equal_s(expected2, buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(patch); git_diff_free(diff); @@ -233,7 +233,7 @@ void test_diff_patch__config_options(void) cl_git_pass(git_patch_to_buf(&buf, patch)); cl_assert_equal_s(expected3, buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(patch); git_diff_free(diff); @@ -247,7 +247,7 @@ void test_diff_patch__config_options(void) cl_git_pass(git_patch_to_buf(&buf, patch)); cl_assert_equal_s(expected4, buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(patch); git_diff_free(diff); @@ -267,7 +267,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) const git_diff_hunk *hunk; const git_diff_line *line; size_t hunklen; - git_buf old_content = GIT_BUF_INIT, actual = GIT_BUF_INIT; + git_str old_content = GIT_STR_INIT, actual = GIT_STR_INIT; const char *new_content = "The Song of Seven Cities\n------------------------\n\nI WAS Lord of Cities very sumptuously builded.\nSeven roaring Cities paid me tribute from afar.\nIvory their outposts were--the guardrooms of them gilded,\nAnd garrisoned with Amazons invincible in war.\n\nThis is some new text;\nNot as good as the old text;\nBut here it is.\n\nSo they warred and trafficked only yesterday, my Cities.\nTo-day there is no mark or mound of where my Cities stood.\nFor the River rose at midnight and it washed away my Cities.\nThey are evened with Atlantis and the towns before the Flood.\n\nRain on rain-gorged channels raised the water-levels round them,\nFreshet backed on freshet swelled and swept their world from sight,\nTill the emboldened floods linked arms and, flashing forward, drowned them--\nDrowned my Seven Cities and their peoples in one night!\n\nLow among the alders lie their derelict foundations,\nThe beams wherein they trusted and the plinths whereon they built--\nMy rulers and their treasure and their unborn populations,\nDead, destroyed, aborted, and defiled with mud and silt!\n\nAnother replacement;\nBreaking up the poem;\nGenerating some hunks.\n\nTo the sound of trumpets shall their seed restore my Cities\nWealthy and well-weaponed, that once more may I behold\nAll the world go softly when it walks before my Cities,\nAnd the horses and the chariots fleeing from them as of old!\n\n -- Rudyard Kipling\n"; g_repo = cl_git_sandbox_init("renames"); @@ -311,7 +311,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 0)); cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin); - cl_git_pass(git_buf_set(&actual, line->content, line->content_len)); + cl_git_pass(git_str_set(&actual, line->content, line->content_len)); cl_assert_equal_s("Ivory their outposts were--the guardrooms of them gilded,\n", actual.ptr); cl_assert_equal_i(6, line->old_lineno); cl_assert_equal_i(6, line->new_lineno); @@ -319,7 +319,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 3)); cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin); - cl_git_pass(git_buf_set(&actual, line->content, line->content_len)); + cl_git_pass(git_str_set(&actual, line->content, line->content_len)); cl_assert_equal_s("All the world went softly when it walked before my Cities--\n", actual.ptr); cl_assert_equal_i(9, line->old_lineno); cl_assert_equal_i(-1, line->new_lineno); @@ -327,7 +327,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 12)); cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin); - cl_git_pass(git_buf_set(&actual, line->content, line->content_len)); + cl_git_pass(git_str_set(&actual, line->content, line->content_len)); cl_assert_equal_s("This is some new text;\n", actual.ptr); cl_assert_equal_i(-1, line->old_lineno); cl_assert_equal_i(9, line->new_lineno); @@ -348,7 +348,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 0)); cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin); - cl_git_pass(git_buf_set(&actual, line->content, line->content_len)); + cl_git_pass(git_str_set(&actual, line->content, line->content_len)); cl_assert_equal_s("My rulers and their treasure and their unborn populations,\n", actual.ptr); cl_assert_equal_i(31, line->old_lineno); cl_assert_equal_i(25, line->new_lineno); @@ -356,7 +356,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 3)); cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin); - cl_git_pass(git_buf_set(&actual, line->content, line->content_len)); + cl_git_pass(git_str_set(&actual, line->content, line->content_len)); cl_assert_equal_s("The Daughters of the Palace whom they cherished in my Cities,\n", actual.ptr); cl_assert_equal_i(34, line->old_lineno); cl_assert_equal_i(-1, line->new_lineno); @@ -364,7 +364,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 12)); cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin); - cl_git_pass(git_buf_set(&actual, line->content, line->content_len)); + cl_git_pass(git_str_set(&actual, line->content, line->content_len)); cl_assert_equal_s("Another replacement;\n", actual.ptr); cl_assert_equal_i(-1, line->old_lineno); cl_assert_equal_i(28, line->new_lineno); @@ -375,7 +375,7 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) /* Let's check line numbers when there is no newline */ - git_buf_rtrim(&old_content); + git_str_rtrim(&old_content); cl_git_rewritefile("renames/songof7cities.txt", old_content.ptr); cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, head, &opt)); @@ -403,35 +403,35 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 1)); cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin); - cl_git_pass(git_buf_set(&actual, line->content, line->content_len)); + cl_git_pass(git_str_set(&actual, line->content, line->content_len)); cl_assert_equal_s("And the horses and the chariots fleeing from them as of old!\n", actual.ptr); cl_assert_equal_i(47, line->old_lineno); cl_assert_equal_i(47, line->new_lineno); cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 2)); cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin); - cl_git_pass(git_buf_set(&actual, line->content, line->content_len)); + cl_git_pass(git_str_set(&actual, line->content, line->content_len)); cl_assert_equal_s("\n", actual.ptr); cl_assert_equal_i(48, line->old_lineno); cl_assert_equal_i(48, line->new_lineno); cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 3)); cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin); - cl_git_pass(git_buf_set(&actual, line->content, line->content_len)); + cl_git_pass(git_str_set(&actual, line->content, line->content_len)); cl_assert_equal_s(" -- Rudyard Kipling\n", actual.ptr); cl_assert_equal_i(49, line->old_lineno); cl_assert_equal_i(-1, line->new_lineno); cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 4)); cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin); - cl_git_pass(git_buf_set(&actual, line->content, line->content_len)); + cl_git_pass(git_str_set(&actual, line->content, line->content_len)); cl_assert_equal_s(" -- Rudyard Kipling", actual.ptr); cl_assert_equal_i(-1, line->old_lineno); cl_assert_equal_i(49, line->new_lineno); cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 5)); cl_assert_equal_i(GIT_DIFF_LINE_DEL_EOFNL, (int)line->origin); - cl_git_pass(git_buf_set(&actual, line->content, line->content_len)); + cl_git_pass(git_str_set(&actual, line->content, line->content_len)); cl_assert_equal_s("\n\\ No newline at end of file\n", actual.ptr); cl_assert_equal_i(-1, line->old_lineno); cl_assert_equal_i(49, line->new_lineno); @@ -439,8 +439,8 @@ void test_diff_patch__hunks_have_correct_line_numbers(void) git_patch_free(patch); git_diff_free(diff); - git_buf_dispose(&actual); - git_buf_dispose(&old_content); + git_str_dispose(&actual); + git_str_dispose(&old_content); git_tree_free(head); } @@ -532,7 +532,7 @@ static void check_single_patch_stats( void test_diff_patch__line_counts_with_eofnl(void) { git_config *cfg; - git_buf content = GIT_BUF_INIT; + git_str content = GIT_STR_INIT; const char *end; git_index *index; const char *expected = @@ -565,15 +565,15 @@ void test_diff_patch__line_counts_with_eofnl(void) /* remove first line */ - end = git_buf_cstr(&content) + git_buf_find(&content, '\n') + 1; - git_buf_consume(&content, end); + end = git_str_cstr(&content) + git_str_find(&content, '\n') + 1; + git_str_consume(&content, end); cl_git_rewritefile("renames/songof7cities.txt", content.ptr); check_single_patch_stats(g_repo, 1, 0, 1, 3, NULL, NULL); /* remove trailing whitespace */ - git_buf_rtrim(&content); + git_str_rtrim(&content); cl_git_rewritefile("renames/songof7cities.txt", content.ptr); check_single_patch_stats(g_repo, 2, 1, 2, 6, NULL, NULL); @@ -585,7 +585,7 @@ void test_diff_patch__line_counts_with_eofnl(void) cl_git_pass(git_index_write(index)); git_index_free(index); - cl_git_pass(git_buf_putc(&content, '\n')); + cl_git_pass(git_str_putc(&content, '\n')); cl_git_rewritefile("renames/songof7cities.txt", content.ptr); check_single_patch_stats(g_repo, 1, 1, 1, 3, NULL, NULL); @@ -613,7 +613,7 @@ void test_diff_patch__line_counts_with_eofnl(void) check_single_patch_stats( g_repo, 1, 1, 1, 6, expected_sizes, expected); - git_buf_dispose(&content); + git_str_dispose(&content); } void test_diff_patch__can_strip_bad_utf8(void) diff --git a/tests/diff/rename.c b/tests/diff/rename.c index bd25d29aaba..d28a4d989ed 100644 --- a/tests/diff/rename.c +++ b/tests/diff/rename.c @@ -460,7 +460,7 @@ void test_diff_rename__working_directory_changes(void) git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT; git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT; diff_expects exp; - git_buf old_content = GIT_BUF_INIT, content = GIT_BUF_INIT;; + git_str old_content = GIT_STR_INIT, content = GIT_STR_INIT;; tree = resolve_commit_oid_to_tree(g_repo, sha0); diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED | GIT_DIFF_INCLUDE_UNTRACKED; @@ -514,7 +514,7 @@ void test_diff_rename__working_directory_changes(void) cl_git_pass( git_futils_readbuffer(&old_content, "renames/songof7cities.txt")); cl_git_pass( - git_buf_lf_to_crlf(&content, &old_content)); + git_str_lf_to_crlf(&content, &old_content)); cl_git_pass( git_futils_writebuffer(&content, "renames/songof7cities.txt", 0, 0)); @@ -576,7 +576,7 @@ void test_diff_rename__working_directory_changes(void) cl_git_pass(git_oid_fromstr(&id, blobsha)); cl_git_pass(git_blob_lookup(&blob, g_repo, &id)); - cl_git_pass(git_buf_set( + cl_git_pass(git_str_set( &content, git_blob_rawcontent(blob), (size_t)git_blob_rawsize(blob))); cl_git_rewritefile("renames/songof7cities.txt", content.ptr); git_blob_free(blob); @@ -604,8 +604,8 @@ void test_diff_rename__working_directory_changes(void) git_diff_free(diff); git_tree_free(tree); - git_buf_dispose(&content); - git_buf_dispose(&old_content); + git_str_dispose(&content); + git_str_dispose(&old_content); } void test_diff_rename__patch(void) @@ -666,7 +666,7 @@ void test_diff_rename__patch(void) void test_diff_rename__file_exchange(void) { - git_buf c1 = GIT_BUF_INIT, c2 = GIT_BUF_INIT; + git_str c1 = GIT_STR_INIT, c2 = GIT_STR_INIT; git_index *index; git_tree *tree; git_diff *diff; @@ -708,13 +708,13 @@ void test_diff_rename__file_exchange(void) git_tree_free(tree); git_index_free(index); - git_buf_dispose(&c1); - git_buf_dispose(&c2); + git_str_dispose(&c1); + git_str_dispose(&c2); } void test_diff_rename__file_exchange_three(void) { - git_buf c1 = GIT_BUF_INIT, c2 = GIT_BUF_INIT, c3 = GIT_BUF_INIT; + git_str c1 = GIT_STR_INIT, c2 = GIT_STR_INIT, c3 = GIT_STR_INIT; git_index *index; git_tree *tree; git_diff *diff; @@ -760,14 +760,14 @@ void test_diff_rename__file_exchange_three(void) git_tree_free(tree); git_index_free(index); - git_buf_dispose(&c1); - git_buf_dispose(&c2); - git_buf_dispose(&c3); + git_str_dispose(&c1); + git_str_dispose(&c2); + git_str_dispose(&c3); } void test_diff_rename__file_partial_exchange(void) { - git_buf c1 = GIT_BUF_INIT, c2 = GIT_BUF_INIT; + git_str c1 = GIT_STR_INIT, c2 = GIT_STR_INIT; git_index *index; git_tree *tree; git_diff *diff; @@ -779,7 +779,7 @@ void test_diff_rename__file_partial_exchange(void) cl_git_pass(git_futils_readbuffer(&c1, "renames/untimely.txt")); cl_git_pass(git_futils_writebuffer(&c1, "renames/songof7cities.txt", 0, 0)); for (i = 0; i < 100; ++i) - cl_git_pass(git_buf_puts(&c2, "this is not the content you are looking for\n")); + cl_git_pass(git_str_puts(&c2, "this is not the content you are looking for\n")); cl_git_pass(git_futils_writebuffer(&c2, "renames/untimely.txt", 0, 0)); cl_git_pass( @@ -813,13 +813,13 @@ void test_diff_rename__file_partial_exchange(void) git_tree_free(tree); git_index_free(index); - git_buf_dispose(&c1); - git_buf_dispose(&c2); + git_str_dispose(&c1); + git_str_dispose(&c2); } void test_diff_rename__rename_and_copy_from_same_source(void) { - git_buf c1 = GIT_BUF_INIT, c2 = GIT_BUF_INIT; + git_str c1 = GIT_STR_INIT, c2 = GIT_STR_INIT; git_index *index; git_tree *tree; git_diff *diff; @@ -831,9 +831,9 @@ void test_diff_rename__rename_and_copy_from_same_source(void) * and the second 2/3 of file into another new place */ cl_git_pass(git_futils_readbuffer(&c1, "renames/songof7cities.txt")); - cl_git_pass(git_buf_set(&c2, c1.ptr, c1.size)); - git_buf_truncate(&c1, c1.size * 2 / 3); - git_buf_consume(&c2, ((char *)c2.ptr) + (c2.size / 3)); + cl_git_pass(git_str_set(&c2, c1.ptr, c1.size)); + git_str_truncate(&c1, c1.size * 2 / 3); + git_str_consume(&c2, ((char *)c2.ptr) + (c2.size / 3)); cl_git_pass(git_futils_writebuffer(&c1, "renames/song_a.txt", 0, 0)); cl_git_pass(git_futils_writebuffer(&c2, "renames/song_b.txt", 0, 0)); @@ -870,13 +870,13 @@ void test_diff_rename__rename_and_copy_from_same_source(void) git_tree_free(tree); git_index_free(index); - git_buf_dispose(&c1); - git_buf_dispose(&c2); + git_str_dispose(&c1); + git_str_dispose(&c2); } void test_diff_rename__from_deleted_to_split(void) { - git_buf c1 = GIT_BUF_INIT; + git_str c1 = GIT_STR_INIT; git_index *index; git_tree *tree; git_diff *diff; @@ -924,7 +924,7 @@ void test_diff_rename__from_deleted_to_split(void) git_tree_free(tree); git_index_free(index); - git_buf_dispose(&c1); + git_str_dispose(&c1); } struct rename_expected @@ -967,7 +967,7 @@ void test_diff_rename__rejected_match_can_match_others(void) git_diff *diff; git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT; git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT; - git_buf one = GIT_BUF_INIT, two = GIT_BUF_INIT; + git_str one = GIT_STR_INIT, two = GIT_STR_INIT; unsigned int status[] = { GIT_DELTA_RENAMED, GIT_DELTA_RENAMED }; const char *sources[] = { "Class1.cs", "Class2.cs" }; const char *targets[] = { "ClassA.cs", "ClassB.cs" }; @@ -1024,25 +1024,25 @@ void test_diff_rename__rejected_match_can_match_others(void) git_index_free(index); git_reference_free(head); git_reference_free(selfsimilar); - git_buf_dispose(&one); - git_buf_dispose(&two); + git_str_dispose(&one); + git_str_dispose(&two); } static void write_similarity_file_two(const char *filename, size_t b_lines) { - git_buf contents = GIT_BUF_INIT; + git_str contents = GIT_STR_INIT; size_t i; for (i = 0; i < b_lines; i++) - git_buf_printf(&contents, "%02d - bbbbb\r\n", (int)(i+1)); + git_str_printf(&contents, "%02d - bbbbb\r\n", (int)(i+1)); for (i = b_lines; i < 50; i++) - git_buf_printf(&contents, "%02d - aaaaa%s", (int)(i+1), (i == 49 ? "" : "\r\n")); + git_str_printf(&contents, "%02d - aaaaa%s", (int)(i+1), (i == 49 ? "" : "\r\n")); cl_git_pass( git_futils_writebuffer(&contents, filename, O_RDWR|O_CREAT, 0777)); - git_buf_dispose(&contents); + git_str_dispose(&contents); } void test_diff_rename__rejected_match_can_match_others_two(void) @@ -1346,7 +1346,7 @@ void test_diff_rename__rewrite_on_single_file(void) void test_diff_rename__can_find_copy_to_split(void) { - git_buf c1 = GIT_BUF_INIT; + git_str c1 = GIT_STR_INIT; git_index *index; git_tree *tree; git_diff *diff; @@ -1390,12 +1390,12 @@ void test_diff_rename__can_find_copy_to_split(void) git_tree_free(tree); git_index_free(index); - git_buf_dispose(&c1); + git_str_dispose(&c1); } void test_diff_rename__can_delete_unmodified_deltas(void) { - git_buf c1 = GIT_BUF_INIT; + git_str c1 = GIT_STR_INIT; git_index *index; git_tree *tree; git_diff *diff; @@ -1438,7 +1438,7 @@ void test_diff_rename__can_delete_unmodified_deltas(void) git_tree_free(tree); git_index_free(index); - git_buf_dispose(&c1); + git_str_dispose(&c1); } void test_diff_rename__matches_config_behavior(void) diff --git a/tests/diff/stats.c b/tests/diff/stats.c index 54572672ca4..f69dba9b306 100644 --- a/tests/diff/stats.c +++ b/tests/diff/stats.c @@ -1,7 +1,6 @@ #include "clar.h" #include "clar_libgit2.h" -#include "buffer.h" #include "commit.h" #include "diff.h" #include "diff_generate.h" @@ -53,11 +52,11 @@ void test_diff_stats__stat(void) cl_assert_equal_sz(3, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); + cl_assert(strcmp(buf.ptr, stat) == 0); git_buf_dispose(&buf); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 80)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); + cl_assert(strcmp(buf.ptr, stat) == 0); git_buf_dispose(&buf); } @@ -77,7 +76,7 @@ void test_diff_stats__multiple_hunks(void) cl_assert_equal_sz(4, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -92,7 +91,7 @@ void test_diff_stats__numstat(void) &_stats, "cd471f0d8770371e1bc78bcbb38db4c7e4106bd2", false); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_NUMBER, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -110,7 +109,7 @@ void test_diff_stats__shortstat(void) cl_assert_equal_sz(3, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_SHORT, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -128,7 +127,7 @@ void test_diff_stats__shortstat_noinsertions(void) cl_assert_equal_sz(2, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_SHORT, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -146,7 +145,7 @@ void test_diff_stats__shortstat_nodeletions(void) cl_assert_equal_sz(0, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_SHORT, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -166,7 +165,7 @@ void test_diff_stats__rename(void) cl_assert_equal_sz(1, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -186,7 +185,7 @@ void test_diff_stats__rename_nochanges(void) cl_assert_equal_sz(0, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -206,7 +205,7 @@ void test_diff_stats__rename_and_modifiy(void) cl_assert_equal_sz(1, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -225,7 +224,7 @@ void test_diff_stats__rename_in_subdirectory(void) cl_assert_equal_sz(0, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -247,7 +246,7 @@ void test_diff_stats__rename_no_find(void) cl_assert_equal_sz(10, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -269,7 +268,7 @@ void test_diff_stats__rename_nochanges_no_find(void) cl_assert_equal_sz(13, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -290,7 +289,7 @@ void test_diff_stats__rename_and_modify_no_find(void) cl_assert_equal_sz(8, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -309,7 +308,7 @@ void test_diff_stats__binary(void) cl_assert_equal_sz(0, git_diff_stats_deletions(_stats)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -323,7 +322,7 @@ void test_diff_stats__binary_numstat(void) &_stats, "8d7523f6fcb2404257889abe0d96f093d9f524f9", false); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_NUMBER, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -339,7 +338,7 @@ void test_diff_stats__mode_change(void) &_stats, "7ade76dd34bba4733cf9878079f9fd4a456a9189", false); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_INCLUDE_SUMMARY, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); } @@ -372,7 +371,7 @@ void test_diff_stats__new_file(void) cl_git_pass(git_diff_from_buffer(&diff, input, strlen(input))); cl_git_pass(git_diff_get_stats(&_stats, diff)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_INCLUDE_SUMMARY, 0)); - cl_assert_equal_s(stat, git_buf_cstr(&buf)); + cl_assert_equal_s(stat, buf.ptr); git_buf_dispose(&buf); git_diff_free(diff); diff --git a/tests/diff/submodules.c b/tests/diff/submodules.c index 93223ef7d4b..0436ca5c8e8 100644 --- a/tests/diff/submodules.c +++ b/tests/diff/submodules.c @@ -15,7 +15,7 @@ void test_diff_submodules__cleanup(void) cl_git_sandbox_cleanup(); } -#define get_buf_ptr(buf) ((buf)->asize ? (buf)->ptr : NULL) +#define get_buf_ptr(buf) ((buf)->size ? (buf)->ptr : NULL) static void check_diff_patches_at_line( git_diff *diff, const char **expected, diff --git a/tests/diff/workdir.c b/tests/diff/workdir.c index 00c52ff1b4c..f7c74a29438 100644 --- a/tests/diff/workdir.c +++ b/tests/diff/workdir.c @@ -1663,7 +1663,7 @@ void test_diff_workdir__patience_diff(void) cl_git_pass(git_patch_to_buf(&buf, patch)); cl_assert_equal_s(expected_normal, buf.ptr); - git_buf_clear(&buf); + git_buf_dispose(&buf); git_patch_free(patch); git_diff_free(diff); @@ -1675,9 +1675,8 @@ void test_diff_workdir__patience_diff(void) cl_git_pass(git_patch_to_buf(&buf, patch)); cl_assert_equal_s(expected_patience, buf.ptr); - git_buf_clear(&buf); - git_buf_dispose(&buf); + git_patch_free(patch); git_diff_free(diff); } @@ -1754,7 +1753,7 @@ void test_diff_workdir__with_stale_index(void) git_index_free(idx); } -static int touch_file(void *payload, git_buf *path) +static int touch_file(void *payload, git_str *path) { struct stat st; struct p_timeval times[2]; @@ -1804,10 +1803,10 @@ void test_diff_workdir__can_update_index(void) /* touch all the files so stat times are different */ { - git_buf path = GIT_BUF_INIT; - cl_git_pass(git_buf_sets(&path, "status")); + git_str path = GIT_STR_INIT; + cl_git_pass(git_str_sets(&path, "status")); cl_git_pass(git_path_direach(&path, 0, touch_file, NULL)); - git_buf_dispose(&path); + git_str_dispose(&path); } opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED; @@ -1873,9 +1872,9 @@ void test_diff_workdir__binary_detection(void) { git_index *idx; git_diff *diff = NULL; - git_buf b = GIT_BUF_INIT; + git_str b = GIT_STR_INIT; int i; - git_buf data[10] = { + git_str data[10] = { { "1234567890", 0, 10 }, /* 0 - all ascii text control */ { "\xC3\x85\xC3\xBC\xE2\x80\xA0\x48\xC3\xB8\xCF\x80\xCE\xA9", 0, 14 }, /* 1 - UTF-8 multibyte text */ { "\xEF\xBB\xBF\xC3\x9C\xE2\xA4\x92\xC6\x92\x38\xC2\xA3\xE2\x82\xAC", 0, 16 }, /* 2 - UTF-8 with BOM */ @@ -1899,7 +1898,7 @@ void test_diff_workdir__binary_detection(void) * then we will try with test data in index and ASCII in workdir. */ - cl_git_pass(git_buf_sets(&b, "empty_standard_repo/0")); + cl_git_pass(git_str_sets(&b, "empty_standard_repo/0")); for (i = 0; i < 10; ++i) { b.ptr[b.size - 1] = '0' + i; cl_git_mkfile(b.ptr, "baseline"); @@ -1931,7 +1930,7 @@ void test_diff_workdir__binary_detection(void) git_diff_free(diff); - cl_git_pass(git_buf_sets(&b, "empty_standard_repo/0")); + cl_git_pass(git_str_sets(&b, "empty_standard_repo/0")); for (i = 0; i < 10; ++i) { b.ptr[b.size - 1] = '0' + i; cl_git_pass(git_index_add_bypath(idx, &b.ptr[b.size - 1])); @@ -1959,7 +1958,7 @@ void test_diff_workdir__binary_detection(void) git_diff_free(diff); git_index_free(idx); - git_buf_dispose(&b); + git_str_dispose(&b); } void test_diff_workdir__to_index_conflicted(void) { @@ -2006,7 +2005,7 @@ void test_diff_workdir__only_writes_index_when_necessary(void) git_reference *head; git_object *head_object; git_oid initial, first, second; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; struct stat st; struct p_timeval times[2]; @@ -2040,7 +2039,7 @@ void test_diff_workdir__only_writes_index_when_necessary(void) cl_assert(!git_oid_equal(&initial, &first)); /* touch all the files so stat times are different */ - cl_git_pass(git_buf_sets(&path, "status")); + cl_git_pass(git_str_sets(&path, "status")); cl_git_pass(git_path_direach(&path, 0, touch_file, NULL)); cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts)); @@ -2050,7 +2049,7 @@ void test_diff_workdir__only_writes_index_when_necessary(void) git_oid_cpy(&second, git_index_checksum(index)); cl_assert(!git_oid_equal(&first, &second)); - git_buf_dispose(&path); + git_str_dispose(&path); git_object_free(head_object); git_reference_free(head); git_index_free(index); diff --git a/tests/email/create.c b/tests/email/create.c index ccf79c2aa71..27a66558256 100644 --- a/tests/email/create.c +++ b/tests/email/create.c @@ -1,7 +1,6 @@ #include "clar.h" #include "clar_libgit2.h" -#include "buffer.h" #include "diff_generate.h" static git_repository *repo; @@ -43,7 +42,7 @@ static void assert_email_match( git_buf buf = GIT_BUF_INIT; email_for_commit(&buf, commit_id, opts); - cl_assert_equal_s(expected, git_buf_cstr(&buf)); + cl_assert_equal_s(expected, buf.ptr); git_buf_dispose(&buf); } @@ -54,15 +53,17 @@ static void assert_subject_match( git_email_create_options *opts) { git_buf buf = GIT_BUF_INIT; - const char *loc; + char *subject, *nl; email_for_commit(&buf, commit_id, opts); - cl_assert((loc = strstr(buf.ptr, "\nSubject: ")) != NULL); - git_buf_consume(&buf, (loc + 10)); - git_buf_truncate_at_char(&buf, '\n'); + cl_assert((subject = strstr(buf.ptr, "\nSubject: ")) != NULL); + subject += 10; - cl_assert_equal_s(expected, git_buf_cstr(&buf)); + if ((nl = strchr(subject, '\n')) != NULL) + *nl = '\0'; + + cl_assert_equal_s(expected, subject); git_buf_dispose(&buf); } @@ -327,7 +328,7 @@ void test_email_create__custom_summary_and_body(void) cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); cl_git_pass(git_email_create_from_diff(&buf, diff, 2, 4, &oid, summary, body, git_commit_author(commit), &opts)); - cl_assert_equal_s(expected, git_buf_cstr(&buf)); + cl_assert_equal_s(expected, buf.ptr); git_diff_free(diff); git_commit_free(commit); diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c index 6881af40a00..0de712be871 100644 --- a/tests/fetchhead/nonetwork.c +++ b/tests/fetchhead/nonetwork.c @@ -78,7 +78,7 @@ void test_fetchhead_nonetwork__write(void) { git_vector fetchhead_vector = GIT_VECTOR_INIT; git_fetchhead_ref *fetchhead_ref; - git_buf fetchhead_buf = GIT_BUF_INIT; + git_str fetchhead_buf = GIT_STR_INIT; int equals = 0; size_t i; @@ -94,7 +94,7 @@ void test_fetchhead_nonetwork__write(void) equals = (strcmp(fetchhead_buf.ptr, FETCH_HEAD_WILDCARD_DATA_LOCAL) == 0); - git_buf_dispose(&fetchhead_buf); + git_str_dispose(&fetchhead_buf); git_vector_foreach(&fetchhead_vector, i, fetchhead_ref) { git_fetchhead_ref_free(fetchhead_ref); @@ -431,7 +431,7 @@ int find_master_haacked(const char *ref_name, const char *remote_url, const git_ void test_fetchhead_nonetwork__create_when_refpecs_given(void) { git_remote *remote; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; char *refspec1 = "refs/heads/master"; char *refspec2 = "refs/heads/haacked"; char *refspecs[] = { refspec1, refspec2 }; @@ -443,7 +443,7 @@ void test_fetchhead_nonetwork__create_when_refpecs_given(void) cl_set_cleanup(&cleanup_repository, "./test1"); cl_git_pass(git_repository_init(&g_repo, "./test1", 0)); - cl_git_pass(git_buf_joinpath(&path, git_repository_path(g_repo), "FETCH_HEAD")); + cl_git_pass(git_str_joinpath(&path, git_repository_path(g_repo), "FETCH_HEAD")); cl_git_pass(git_remote_create(&remote, g_repo, "origin", cl_fixture("testrepo.git"))); cl_assert(!git_path_exists(path.ptr)); @@ -456,7 +456,7 @@ void test_fetchhead_nonetwork__create_when_refpecs_given(void) cl_assert(found_haacked); git_remote_free(remote); - git_buf_dispose(&path); + git_str_dispose(&path); } static bool count_refs_called; @@ -488,7 +488,7 @@ int count_refs(const char *ref_name, const char *remote_url, const git_oid *oid, void test_fetchhead_nonetwork__create_with_multiple_refspecs(void) { git_remote *remote; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_set_cleanup(&cleanup_repository, "./test1"); cl_git_pass(git_repository_init(&g_repo, "./test1", 0)); @@ -499,7 +499,7 @@ void test_fetchhead_nonetwork__create_with_multiple_refspecs(void) /* Pick up the new refspec */ cl_git_pass(git_remote_lookup(&remote, g_repo, "origin")); - cl_git_pass(git_buf_joinpath(&path, git_repository_path(g_repo), "FETCH_HEAD")); + cl_git_pass(git_str_joinpath(&path, git_repository_path(g_repo), "FETCH_HEAD")); cl_assert(!git_path_exists(path.ptr)); cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL)); cl_assert(git_path_exists(path.ptr)); @@ -520,7 +520,7 @@ void test_fetchhead_nonetwork__create_with_multiple_refspecs(void) } git_remote_free(remote); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_fetchhead_nonetwork__credentials_are_stripped(void) diff --git a/tests/filter/crlf.c b/tests/filter/crlf.c index bc9c7f28938..925ea58d2ec 100644 --- a/tests/filter/crlf.c +++ b/tests/filter/crlf.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "git2/sys/filter.h" -#include "buffer.h" static git_repository *g_repo = NULL; diff --git a/tests/filter/custom_helpers.c b/tests/filter/custom_helpers.c index ee3b6353b32..7aa3777e66b 100644 --- a/tests/filter/custom_helpers.c +++ b/tests/filter/custom_helpers.c @@ -8,8 +8,8 @@ int bitflip_filter_apply( git_filter *self, void **payload, - git_buf *to, - const git_buf *from, + git_str *to, + const git_str *from, const git_filter_source *source) { const unsigned char *src = (const unsigned char *)from->ptr; @@ -25,7 +25,7 @@ int bitflip_filter_apply( if (!from->size) return 0; - cl_git_pass(git_buf_grow(to, from->size)); + cl_git_pass(git_str_grow(to, from->size)); dst = (unsigned char *)to->ptr; @@ -70,8 +70,8 @@ git_filter *create_bitflip_filter(void) int reverse_filter_apply( git_filter *self, void **payload, - git_buf *to, - const git_buf *from, + git_str *to, + const git_str *from, const git_filter_source *source) { const unsigned char *src = (const unsigned char *)from->ptr; @@ -87,7 +87,7 @@ int reverse_filter_apply( if (!from->size) return 0; - cl_git_pass(git_buf_grow(to, from->size)); + cl_git_pass(git_str_grow(to, from->size)); dst = (unsigned char *)to->ptr + from->size - 1; diff --git a/tests/filter/custom_helpers.h b/tests/filter/custom_helpers.h index 537a51da226..0936c581b86 100644 --- a/tests/filter/custom_helpers.h +++ b/tests/filter/custom_helpers.h @@ -7,13 +7,13 @@ extern git_filter *create_erroneous_filter(const char *attr); extern int bitflip_filter_apply( git_filter *self, void **payload, - git_buf *to, - const git_buf *from, + git_str *to, + const git_str *from, const git_filter_source *source); extern int reverse_filter_apply( git_filter *self, void **payload, - git_buf *to, - const git_buf *from, + git_str *to, + const git_str *from, const git_filter_source *source); diff --git a/tests/filter/file.c b/tests/filter/file.c index 521c01c02e3..3b7ab19e280 100644 --- a/tests/filter/file.c +++ b/tests/filter/file.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/sys/filter.h" #include "crlf.h" -#include "buffer.h" static git_repository *g_repo = NULL; @@ -53,13 +52,13 @@ void test_filter_file__apply(void) struct buf_writestream { git_writestream base; - git_buf buf; + git_str buf; }; int buf_writestream_write(git_writestream *s, const char *buf, size_t len) { struct buf_writestream *stream = (struct buf_writestream *)s; - return git_buf_put(&stream->buf, buf, len); + return git_str_put(&stream->buf, buf, len); } int buf_writestream_close(git_writestream *s) @@ -71,7 +70,7 @@ int buf_writestream_close(git_writestream *s) void buf_writestream_free(git_writestream *s) { struct buf_writestream *stream = (struct buf_writestream *)s; - git_buf_dispose(&stream->buf); + git_str_dispose(&stream->buf); } void test_filter_file__apply_stream(void) diff --git a/tests/filter/query.c b/tests/filter/query.c index 6889d715bb3..429c1044324 100644 --- a/tests/filter/query.c +++ b/tests/filter/query.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/sys/filter.h" #include "crlf.h" -#include "buffer.h" static git_repository *g_repo = NULL; diff --git a/tests/filter/stream.c b/tests/filter/stream.c index b6a4c3ca1fa..0f85f9c4736 100644 --- a/tests/filter/stream.c +++ b/tests/filter/stream.c @@ -137,12 +137,12 @@ git_filter *create_compress_filter(void) static void writefile(const char *filename, size_t numchunks) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; char buf[CHUNKSIZE]; size_t i = 0, j = 0; int fd; - cl_git_pass(git_buf_joinpath(&path, "empty_standard_repo", filename)); + cl_git_pass(git_str_joinpath(&path, "empty_standard_repo", filename)); fd = p_open(path.ptr, O_RDWR|O_CREAT, 0666); cl_assert(fd >= 0); @@ -156,7 +156,7 @@ static void writefile(const char *filename, size_t numchunks) } p_close(fd); - git_buf_dispose(&path); + git_str_dispose(&path); } static void test_stream(size_t numchunks) diff --git a/tests/filter/systemattrs.c b/tests/filter/systemattrs.c index 4996b3b1ea2..b687b4b44cd 100644 --- a/tests/filter/systemattrs.c +++ b/tests/filter/systemattrs.c @@ -3,29 +3,33 @@ #include "path.h" static git_repository *g_repo = NULL; -static git_buf system_attr_path = GIT_BUF_INIT; +static git_str system_attr_path = GIT_STR_INIT; void test_filter_systemattrs__initialize(void) { + git_buf system_path = GIT_BUF_INIT; + g_repo = cl_git_sandbox_init("crlf"); cl_must_pass(p_unlink("crlf/.gitattributes")); cl_git_pass(git_libgit2_opts( - GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, &system_attr_path)); - cl_git_pass(git_buf_joinpath(&system_attr_path, - system_attr_path.ptr, "gitattributes")); + GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, &system_path)); + cl_git_pass(git_str_joinpath(&system_attr_path, + system_path.ptr, "gitattributes")); cl_git_mkfile(system_attr_path.ptr, "*.txt text\n" "*.bin binary\n" "*.crlf text eol=crlf\n" "*.lf text eol=lf\n"); + + git_buf_dispose(&system_path); } void test_filter_systemattrs__cleanup(void) { cl_must_pass(p_unlink(system_attr_path.ptr)); - git_buf_dispose(&system_attr_path); + git_str_dispose(&system_attr_path); cl_git_sandbox_cleanup(); } diff --git a/tests/filter/wildcard.c b/tests/filter/wildcard.c index 0c9c13b1e4c..ee61a8dba66 100644 --- a/tests/filter/wildcard.c +++ b/tests/filter/wildcard.c @@ -78,8 +78,8 @@ static int wildcard_filter_check( static int wildcard_filter_apply( git_filter *self, void **payload, - git_buf *to, - const git_buf *from, + git_str *to, + const git_str *from, const git_filter_source *source) { const char *filtername = *payload; diff --git a/tests/graph/commit_graph.c b/tests/graph/commit_graph.c index 5926dca6f32..83f53f1d405 100644 --- a/tests/graph/commit_graph.c +++ b/tests/graph/commit_graph.c @@ -12,12 +12,12 @@ void test_graph_commit_graph__parse(void) struct git_commit_graph_file *file; struct git_commit_graph_entry e, parent; git_oid id; - git_buf commit_graph_path = GIT_BUF_INIT; + git_str commit_graph_path = GIT_STR_INIT; cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); - cl_git_pass(git_buf_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph")); - cl_git_pass(git_commit_graph_file_open(&file, git_buf_cstr(&commit_graph_path))); - cl_assert_equal_i(git_commit_graph_file_needs_refresh(file, git_buf_cstr(&commit_graph_path)), 0); + cl_git_pass(git_str_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph")); + cl_git_pass(git_commit_graph_file_open(&file, git_str_cstr(&commit_graph_path))); + cl_assert_equal_i(git_commit_graph_file_needs_refresh(file, git_str_cstr(&commit_graph_path)), 0); cl_git_pass(git_oid_fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5")); cl_git_pass(git_commit_graph_entry_find(&e, file, &id, GIT_OID_HEXSZ)); @@ -47,7 +47,7 @@ void test_graph_commit_graph__parse(void) git_commit_graph_file_free(file); git_repository_free(repo); - git_buf_dispose(&commit_graph_path); + git_str_dispose(&commit_graph_path); } void test_graph_commit_graph__parse_octopus_merge(void) @@ -56,11 +56,11 @@ void test_graph_commit_graph__parse_octopus_merge(void) struct git_commit_graph_file *file; struct git_commit_graph_entry e, parent; git_oid id; - git_buf commit_graph_path = GIT_BUF_INIT; + git_str commit_graph_path = GIT_STR_INIT; cl_git_pass(git_repository_open(&repo, cl_fixture("merge-recursive/.gitted"))); - cl_git_pass(git_buf_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph")); - cl_git_pass(git_commit_graph_file_open(&file, git_buf_cstr(&commit_graph_path))); + cl_git_pass(git_str_joinpath(&commit_graph_path, git_repository_path(repo), "objects/info/commit-graph")); + cl_git_pass(git_commit_graph_file_open(&file, git_str_cstr(&commit_graph_path))); cl_git_pass(git_oid_fromstr(&id, "d71c24b3b113fd1d1909998c5bfe33b86a65ee03")); cl_git_pass(git_commit_graph_entry_find(&e, file, &id, GIT_OID_HEXSZ)); @@ -88,7 +88,7 @@ void test_graph_commit_graph__parse_octopus_merge(void) git_commit_graph_file_free(file); git_repository_free(repo); - git_buf_dispose(&commit_graph_path); + git_str_dispose(&commit_graph_path); } void test_graph_commit_graph__writer(void) @@ -97,12 +97,13 @@ void test_graph_commit_graph__writer(void) git_commit_graph_writer *w = NULL; git_revwalk *walk; git_commit_graph_writer_options opts = GIT_COMMIT_GRAPH_WRITER_OPTIONS_INIT; - git_buf cgraph = GIT_BUF_INIT, expected_cgraph = GIT_BUF_INIT, path = GIT_BUF_INIT; + git_buf cgraph = GIT_BUF_INIT; + git_str expected_cgraph = GIT_STR_INIT, path = GIT_STR_INIT; cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); - cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/info")); - cl_git_pass(git_commit_graph_writer_new(&w, git_buf_cstr(&path))); + cl_git_pass(git_str_joinpath(&path, git_repository_path(repo), "objects/info")); + cl_git_pass(git_commit_graph_writer_new(&w, git_str_cstr(&path))); /* This is equivalent to `git commit-graph write --reachable`. */ cl_git_pass(git_revwalk_new(&walk, repo)); @@ -111,15 +112,15 @@ void test_graph_commit_graph__writer(void) git_revwalk_free(walk); cl_git_pass(git_commit_graph_writer_dump(&cgraph, w, &opts)); - cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/info/commit-graph")); - cl_git_pass(git_futils_readbuffer(&expected_cgraph, git_buf_cstr(&path))); + cl_git_pass(git_str_joinpath(&path, git_repository_path(repo), "objects/info/commit-graph")); + cl_git_pass(git_futils_readbuffer(&expected_cgraph, git_str_cstr(&path))); - cl_assert_equal_i(git_buf_len(&cgraph), git_buf_len(&expected_cgraph)); - cl_assert_equal_i(memcmp(git_buf_cstr(&cgraph), git_buf_cstr(&expected_cgraph), git_buf_len(&cgraph)), 0); + cl_assert_equal_i(cgraph.size, git_str_len(&expected_cgraph)); + cl_assert_equal_i(memcmp(cgraph.ptr, git_str_cstr(&expected_cgraph), cgraph.size), 0); git_buf_dispose(&cgraph); - git_buf_dispose(&expected_cgraph); - git_buf_dispose(&path); + git_str_dispose(&expected_cgraph); + git_str_dispose(&path); git_commit_graph_writer_free(w); git_repository_free(repo); } diff --git a/tests/graph/reachable_from_any.c b/tests/graph/reachable_from_any.c index 5c84164998f..9693d7d67fe 100644 --- a/tests/graph/reachable_from_any.c +++ b/tests/graph/reachable_from_any.c @@ -200,12 +200,12 @@ void test_graph_reachable_from_any__exhaustive(void) descendants, n_descendants); if (actual_reachable != expected_reachable) { - git_buf error_message_buf = GIT_BUF_INIT; + git_str error_message_buf = GIT_STR_INIT; char parent_oidbuf[9] = {0}, child_oidbuf[9] = {0}; cl_git_pass(git_oid_nfmt( parent_oidbuf, 8, git_commit_id(parent_commit))); - git_buf_printf(&error_message_buf, + git_str_printf(&error_message_buf, "git_graph_reachable_from_any(\"%s\", %zu, " "{", parent_oidbuf, @@ -216,14 +216,14 @@ void test_graph_reachable_from_any__exhaustive(void) git_oid_nfmt(child_oidbuf, 8, &descendants[descendant_i])); - git_buf_printf(&error_message_buf, " \"%s\"", child_oidbuf); + git_str_printf(&error_message_buf, " \"%s\"", child_oidbuf); } - git_buf_printf(&error_message_buf, + git_str_printf(&error_message_buf, " }) = %d, expected = %d", actual_reachable, expected_reachable); cl_check_(actual_reachable == expected_reachable, - git_buf_cstr(&error_message_buf)); + git_str_cstr(&error_message_buf)); } } } diff --git a/tests/ignore/status.c b/tests/ignore/status.c index 83e821bdd8c..deb7175900e 100644 --- a/tests/ignore/status.c +++ b/tests/ignore/status.c @@ -610,12 +610,12 @@ void test_ignore_status__filenames_with_special_prefixes_do_not_interfere_with_s int i; for (i = 0; *(test_cases + i) != NULL; i++) { - git_buf file = GIT_BUF_INIT; + git_str file = GIT_STR_INIT; char *file_name = *(test_cases + i); git_repository *repo = cl_git_sandbox_init("empty_standard_repo"); - cl_git_pass(git_buf_joinpath(&file, "empty_standard_repo", file_name)); - cl_git_mkfile(git_buf_cstr(&file), "Please don't ignore me!"); + cl_git_pass(git_str_joinpath(&file, "empty_standard_repo", file_name)); + cl_git_mkfile(git_str_cstr(&file), "Please don't ignore me!"); memset(&st, 0, sizeof(st)); cl_git_pass(git_status_foreach(repo, cb_status__single, &st)); @@ -626,7 +626,7 @@ void test_ignore_status__filenames_with_special_prefixes_do_not_interfere_with_s cl_assert(st.status == GIT_STATUS_WT_NEW); cl_git_sandbox_cleanup(); - git_buf_dispose(&file); + git_str_dispose(&file); } } diff --git a/tests/index/crlf.c b/tests/index/crlf.c index 26c19d76d42..8d2a5fccefe 100644 --- a/tests/index/crlf.c +++ b/tests/index/crlf.c @@ -14,7 +14,7 @@ static git_repository *g_repo; static git_index *g_index; -static git_buf expected_fixture = GIT_BUF_INIT; +static git_str expected_fixture = GIT_STR_INIT; void test_index_crlf__initialize(void) { @@ -29,7 +29,7 @@ void test_index_crlf__cleanup(void) if (expected_fixture.size) { cl_fixture_cleanup(expected_fixture.ptr); - git_buf_dispose(&expected_fixture); + git_str_dispose(&expected_fixture); } } @@ -42,11 +42,11 @@ struct compare_data const char *attrs; }; -static int add_and_check_file(void *payload, git_buf *actual_path) +static int add_and_check_file(void *payload, git_str *actual_path) { - git_buf expected_path = GIT_BUF_INIT; - git_buf expected_path_fail = GIT_BUF_INIT; - git_buf expected_contents = GIT_BUF_INIT; + git_str expected_path = GIT_STR_INIT; + git_str expected_path_fail = GIT_STR_INIT; + git_str expected_contents = GIT_STR_INIT; struct compare_data *cd = payload; char *basename; const git_index_entry *entry; @@ -60,10 +60,10 @@ static int add_and_check_file(void *payload, git_buf *actual_path) goto done; } - cl_git_pass(git_buf_joinpath(&expected_path, cd->dirname, basename)); + cl_git_pass(git_str_joinpath(&expected_path, cd->dirname, basename)); - cl_git_pass(git_buf_puts(&expected_path_fail, expected_path.ptr)); - cl_git_pass(git_buf_puts(&expected_path_fail, ".fail")); + cl_git_pass(git_str_puts(&expected_path_fail, expected_path.ptr)); + cl_git_pass(git_str_puts(&expected_path_fail, ".fail")); if (git_path_isfile(expected_path.ptr)) { cl_git_pass(git_index_add_bypath(g_index, basename)); @@ -79,7 +79,7 @@ static int add_and_check_file(void *payload, git_buf *actual_path) git_blob_free(blob); } else if (git_path_isfile(expected_path_fail.ptr)) { cl_git_pass(git_futils_readbuffer(&expected_contents, expected_path_fail.ptr)); - git_buf_rtrim(&expected_contents); + git_str_rtrim(&expected_contents); if (git_index_add_bypath(g_index, basename) == 0 || git_error_last()->klass != GIT_ERROR_FILTER || @@ -93,18 +93,18 @@ static int add_and_check_file(void *payload, git_buf *actual_path) done: if (failed) { - git_buf details = GIT_BUF_INIT; - git_buf_printf(&details, "filename=%s, system=%s, autocrlf=%s, safecrlf=%s, attrs={%s}", + git_str details = GIT_STR_INIT; + git_str_printf(&details, "filename=%s, system=%s, autocrlf=%s, safecrlf=%s, attrs={%s}", basename, cd->systype, cd->autocrlf, cd->safecrlf, cd->attrs); clar__fail(__FILE__, __func__, __LINE__, "index contents did not match expected", details.ptr, 0); - git_buf_dispose(&details); + git_str_dispose(&details); } git__free(basename); - git_buf_dispose(&expected_contents); - git_buf_dispose(&expected_path); - git_buf_dispose(&expected_path_fail); + git_str_dispose(&expected_contents); + git_str_dispose(&expected_path); + git_str_dispose(&expected_path_fail); return 0; } @@ -118,34 +118,34 @@ static const char *system_type(void) static void test_add_index(const char *safecrlf, const char *autocrlf, const char *attrs) { - git_buf attrbuf = GIT_BUF_INIT; - git_buf expected_dirname = GIT_BUF_INIT; - git_buf sandboxname = GIT_BUF_INIT; - git_buf reponame = GIT_BUF_INIT; + git_str attrbuf = GIT_STR_INIT; + git_str expected_dirname = GIT_STR_INIT; + git_str sandboxname = GIT_STR_INIT; + git_str reponame = GIT_STR_INIT; struct compare_data compare_data = { system_type(), NULL, safecrlf, autocrlf, attrs }; const char *c; - git_buf_puts(&reponame, "crlf"); + git_str_puts(&reponame, "crlf"); - git_buf_puts(&sandboxname, "autocrlf_"); - git_buf_puts(&sandboxname, autocrlf); + git_str_puts(&sandboxname, "autocrlf_"); + git_str_puts(&sandboxname, autocrlf); - git_buf_puts(&sandboxname, ",safecrlf_"); - git_buf_puts(&sandboxname, safecrlf); + git_str_puts(&sandboxname, ",safecrlf_"); + git_str_puts(&sandboxname, safecrlf); if (*attrs) { - git_buf_puts(&sandboxname, ","); + git_str_puts(&sandboxname, ","); for (c = attrs; *c; c++) { if (*c == ' ') - git_buf_putc(&sandboxname, ','); + git_str_putc(&sandboxname, ','); else if (*c == '=') - git_buf_putc(&sandboxname, '_'); + git_str_putc(&sandboxname, '_'); else - git_buf_putc(&sandboxname, *c); + git_str_putc(&sandboxname, *c); } - git_buf_printf(&attrbuf, "* %s\n", attrs); + git_str_printf(&attrbuf, "* %s\n", attrs); cl_git_mkfile("crlf/.gitattributes", attrbuf.ptr); } @@ -154,23 +154,23 @@ static void test_add_index(const char *safecrlf, const char *autocrlf, const cha cl_git_pass(git_index_clear(g_index)); - git_buf_joinpath(&expected_dirname, "crlf_data", system_type()); - git_buf_puts(&expected_dirname, "_to_odb"); + git_str_joinpath(&expected_dirname, "crlf_data", system_type()); + git_str_puts(&expected_dirname, "_to_odb"); - git_buf_joinpath(&expected_fixture, expected_dirname.ptr, sandboxname.ptr); + git_str_joinpath(&expected_fixture, expected_dirname.ptr, sandboxname.ptr); cl_fixture_sandbox(expected_fixture.ptr); compare_data.dirname = sandboxname.ptr; cl_git_pass(git_path_direach(&reponame, 0, add_and_check_file, &compare_data)); cl_fixture_cleanup(expected_fixture.ptr); - git_buf_dispose(&expected_fixture); + git_str_dispose(&expected_fixture); - git_buf_dispose(&attrbuf); - git_buf_dispose(&expected_fixture); - git_buf_dispose(&expected_dirname); - git_buf_dispose(&sandboxname); - git_buf_dispose(&reponame); + git_str_dispose(&attrbuf); + git_str_dispose(&expected_fixture); + git_str_dispose(&expected_dirname); + git_str_dispose(&sandboxname); + git_str_dispose(&reponame); } static void set_up_workingdir(const char *name) @@ -196,16 +196,16 @@ static void set_up_workingdir(const char *name) git_path_dirload(&contents, cl_fixture("crlf"), 0, 0); git_vector_foreach(&contents, i, fn) { char *basename = git_path_basename(fn); - git_buf dest_filename = GIT_BUF_INIT; + git_str dest_filename = GIT_STR_INIT; if (strcmp(basename, ".gitted") && strcmp(basename, ".gitattributes")) { - git_buf_joinpath(&dest_filename, name, basename); + git_str_joinpath(&dest_filename, name, basename); cl_git_pass(git_futils_cp(fn, dest_filename.ptr, 0644)); } git__free(basename); - git_buf_dispose(&dest_filename); + git_str_dispose(&dest_filename); } git_vector_free_deep(&contents); } diff --git a/tests/index/filemodes.c b/tests/index/filemodes.c index 3d2bb4a0373..1ab8a9a7ff7 100644 --- a/tests/index/filemodes.c +++ b/tests/index/filemodes.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "posix.h" #include "index.h" @@ -36,10 +35,10 @@ void test_index_filemodes__read(void) static void replace_file_with_mode( const char *filename, const char *backup, unsigned int create_mode) { - git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, content = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&path, "filemodes", filename)); - cl_git_pass(git_buf_printf(&content, "%s as %08u (%d)", + cl_git_pass(git_str_joinpath(&path, "filemodes", filename)); + cl_git_pass(git_str_printf(&content, "%s as %08u (%d)", filename, create_mode, rand())); cl_git_pass(p_rename(path.ptr, backup)); @@ -47,8 +46,8 @@ static void replace_file_with_mode( path.ptr, content.ptr, content.size, O_WRONLY|O_CREAT|O_TRUNC, create_mode); - git_buf_dispose(&path); - git_buf_dispose(&content); + git_str_dispose(&path); + git_str_dispose(&content); } #define add_and_check_mode(I,F,X) add_and_check_mode_(I,F,X,__FILE__,__func__,__LINE__) diff --git a/tests/index/nsec.c b/tests/index/nsec.c index 6edcf030a75..3efd855a7e6 100644 --- a/tests/index/nsec.c +++ b/tests/index/nsec.c @@ -47,16 +47,16 @@ static bool try_create_file_with_nsec_timestamp(const char *path) */ static bool should_expect_nsecs(void) { - git_buf nsec_path = GIT_BUF_INIT; + git_str nsec_path = GIT_STR_INIT; bool expect; - git_buf_joinpath(&nsec_path, clar_sandbox_path(), "nsec_test"); + git_str_joinpath(&nsec_path, clar_sandbox_path(), "nsec_test"); expect = try_create_file_with_nsec_timestamp(nsec_path.ptr); cl_must_pass(p_unlink(nsec_path.ptr)); - git_buf_dispose(&nsec_path); + git_str_dispose(&nsec_path); return expect; } diff --git a/tests/index/racy.c b/tests/index/racy.c index b06f55de4cc..07b3b73d429 100644 --- a/tests/index/racy.c +++ b/tests/index/racy.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "../checkout/checkout_helpers.h" -#include "buffer.h" #include "index.h" #include "repository.h" @@ -24,9 +23,9 @@ void test_index_racy__diff(void) { git_index *index; git_diff *diff; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A")); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "A")); cl_git_mkfile(path.ptr, "A"); /* Put 'A' into the index */ @@ -46,21 +45,21 @@ void test_index_racy__diff(void) git_index_free(index); git_diff_free(diff); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_index_racy__write_index_just_after_file(void) { git_index *index; git_diff *diff; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; struct p_timeval times[2]; /* Make sure we do have a timestamp */ cl_git_pass(git_repository_index(&index, g_repo)); cl_git_pass(git_index_write(index)); - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A")); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "A")); cl_git_mkfile(path.ptr, "A"); /* Force the file's timestamp to be a second after we wrote the index */ times[0].tv_sec = index->stamp.mtime.tv_sec + 1; @@ -95,7 +94,7 @@ void test_index_racy__write_index_just_after_file(void) cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL)); cl_assert_equal_i(1, git_diff_num_deltas(diff)); - git_buf_dispose(&path); + git_str_dispose(&path); git_diff_free(diff); git_index_free(index); } @@ -103,7 +102,7 @@ void test_index_racy__write_index_just_after_file(void) static void setup_race(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_index *index; git_index_entry *entry; struct stat st; @@ -112,7 +111,7 @@ static void setup_race(void) cl_git_pass(git_repository_index__weakptr(&index, g_repo)); cl_git_pass(git_index_write(index)); - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A")); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "A")); cl_git_mkfile(path.ptr, "A"); cl_git_pass(git_index_add_bypath(index, "A")); @@ -129,7 +128,7 @@ static void setup_race(void) entry->mtime.seconds = (int32_t)st.st_mtime; entry->mtime.nanoseconds = (int32_t)st.st_mtime_nsec; - git_buf_dispose(&path); + git_str_dispose(&path); } void test_index_racy__smudges_index_entry_on_save(void) @@ -169,14 +168,14 @@ void test_index_racy__detects_diff_of_change_in_identical_timestamp(void) static void setup_uptodate_files(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_index *index; const git_index_entry *a_entry; git_index_entry new_entry = {{0}}; cl_git_pass(git_repository_index(&index, g_repo)); - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A")); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "A")); cl_git_mkfile(path.ptr, "A"); /* Put 'A' into the index */ @@ -196,7 +195,7 @@ static void setup_uptodate_files(void) cl_git_pass(git_index_add_from_buffer(index, &new_entry, "hello!\n", 7)); git_index_free(index); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_index_racy__adding_to_index_is_uptodate(void) diff --git a/tests/index/tests.c b/tests/index/tests.c index d9d8371dd50..9b28028e6cc 100644 --- a/tests/index/tests.c +++ b/tests/index/tests.c @@ -28,7 +28,7 @@ static struct test_entry test_entries[] = { /* Helpers */ static void copy_file(const char *src, const char *dst) { - git_buf source_buf = GIT_BUF_INIT; + git_str source_buf = GIT_STR_INIT; git_file dst_fd; cl_git_pass(git_futils_readbuffer(&source_buf, src)); @@ -40,28 +40,28 @@ static void copy_file(const char *src, const char *dst) cl_git_pass(p_write(dst_fd, source_buf.ptr, source_buf.size)); cleanup: - git_buf_dispose(&source_buf); + git_str_dispose(&source_buf); p_close(dst_fd); } static void files_are_equal(const char *a, const char *b) { - git_buf buf_a = GIT_BUF_INIT; - git_buf buf_b = GIT_BUF_INIT; + git_str buf_a = GIT_STR_INIT; + git_str buf_b = GIT_STR_INIT; int pass; if (git_futils_readbuffer(&buf_a, a) < 0) cl_assert(0); if (git_futils_readbuffer(&buf_b, b) < 0) { - git_buf_dispose(&buf_a); + git_str_dispose(&buf_a); cl_assert(0); } pass = (buf_a.size == buf_b.size && !memcmp(buf_a.ptr, buf_b.ptr, buf_a.size)); - git_buf_dispose(&buf_a); - git_buf_dispose(&buf_b); + git_str_dispose(&buf_a); + git_str_dispose(&buf_b); cl_assert(pass); } @@ -544,12 +544,12 @@ void test_index_tests__add_bypath_to_a_bare_repository_returns_EBAREPO(void) static void assert_add_bypath_fails(git_repository *repo, const char *fn) { git_index *index; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_git_pass(git_repository_index(&index, repo)); cl_assert(git_index_entrycount(index) == 0); - git_buf_joinpath(&path, "./invalid", fn); + git_str_joinpath(&path, "./invalid", fn); cl_git_mkfile(path.ptr, NULL); cl_git_fail(git_index_add_bypath(index, fn)); @@ -557,7 +557,7 @@ static void assert_add_bypath_fails(git_repository *repo, const char *fn) cl_assert(git_index_entrycount(index) == 0); - git_buf_dispose(&path); + git_str_dispose(&path); git_index_free(index); } @@ -592,7 +592,7 @@ void test_index_tests__cannot_add_invalid_filename(void) static void assert_add_fails(git_repository *repo, const char *fn) { git_index *index; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_index_entry entry = {{0}}; cl_git_pass(git_repository_index(&index, repo)); @@ -606,7 +606,7 @@ static void assert_add_fails(git_repository *repo, const char *fn) cl_assert(git_index_entrycount(index) == 0); - git_buf_dispose(&path); + git_str_dispose(&path); git_index_free(index); } @@ -659,7 +659,7 @@ static void assert_write_fails(git_repository *repo, const char *fn_orig) git_index *index; git_oid expected; const git_index_entry *entry; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; char *fn; cl_git_pass(git_repository_index(&index, repo)); @@ -673,7 +673,7 @@ static void assert_write_fails(git_repository *repo, const char *fn_orig) replace_char(fn, '/', '_'); replace_char(fn, ':', '!'); - git_buf_joinpath(&path, "./invalid", fn); + git_str_joinpath(&path, "./invalid", fn); cl_git_mkfile(path.ptr, NULL); @@ -691,7 +691,7 @@ static void assert_write_fails(git_repository *repo, const char *fn_orig) p_unlink(path.ptr); cl_git_pass(git_index_remove_all(index, NULL, NULL, NULL)); - git_buf_dispose(&path); + git_str_dispose(&path); git_index_free(index); git__free(fn); } diff --git a/tests/iterator/index.c b/tests/iterator/index.c index 25d8c29902e..69b795f5c80 100644 --- a/tests/iterator/index.c +++ b/tests/iterator/index.c @@ -279,12 +279,12 @@ static const char *expected_index_ci[] = { void test_iterator_index__case_folding(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; int fs_is_ci = 0; - cl_git_pass(git_buf_joinpath(&path, cl_fixture("icase"), ".gitted/CoNfIg")); + cl_git_pass(git_str_joinpath(&path, cl_fixture("icase"), ".gitted/CoNfIg")); fs_is_ci = git_path_exists(path.ptr); - git_buf_dispose(&path); + git_str_dispose(&path); index_iterator_test( "icase", NULL, NULL, 0, ARRAY_SIZE(expected_index_cs), @@ -978,22 +978,22 @@ void test_iterator_index__pathlist_with_directory(void) static void create_paths(git_index *index, const char *root, int depth) { - git_buf fullpath = GIT_BUF_INIT; + git_str fullpath = GIT_STR_INIT; git_index_entry entry; size_t root_len; int i; if (root) { - cl_git_pass(git_buf_puts(&fullpath, root)); - cl_git_pass(git_buf_putc(&fullpath, '/')); + cl_git_pass(git_str_puts(&fullpath, root)); + cl_git_pass(git_str_putc(&fullpath, '/')); } root_len = fullpath.size; for (i = 0; i < 8; i++) { bool file = (depth == 0 || (i % 2) == 0); - git_buf_truncate(&fullpath, root_len); - cl_git_pass(git_buf_printf(&fullpath, "item%d", i)); + git_str_truncate(&fullpath, root_len); + cl_git_pass(git_str_printf(&fullpath, "item%d", i)); if (file) { memset(&entry, 0, sizeof(git_index_entry)); @@ -1007,7 +1007,7 @@ static void create_paths(git_index *index, const char *root, int depth) } } - git_buf_dispose(&fullpath); + git_str_dispose(&fullpath); } void test_iterator_index__pathlist_for_deeply_nested_item(void) diff --git a/tests/iterator/tree.c b/tests/iterator/tree.c index f7fb9a7ee97..4145c8dea29 100644 --- a/tests/iterator/tree.c +++ b/tests/iterator/tree.c @@ -623,7 +623,7 @@ static void build_test_tree( const char *scan = fmt, *next; char type, delimiter; git_filemode_t mode = GIT_FILEMODE_BLOB; - git_buf name = GIT_BUF_INIT; + git_str name = GIT_STR_INIT; va_list arglist; cl_git_pass(git_treebuilder_new(&builder, repo, NULL)); /* start builder */ @@ -640,7 +640,7 @@ static void build_test_tree( delimiter = *scan++; /* read and skip delimiter */ for (next = scan; *next && *next != delimiter; ++next) /* seek end */; - cl_git_pass(git_buf_set(&name, scan, (size_t)(next - scan))); + cl_git_pass(git_str_set(&name, scan, (size_t)(next - scan))); for (scan = next; *scan && (*scan == delimiter || *scan == ','); ++scan) /* skip delimiter and optional comma */; @@ -653,7 +653,7 @@ static void build_test_tree( cl_git_pass(git_treebuilder_write(out, builder)); git_treebuilder_free(builder); - git_buf_dispose(&name); + git_str_dispose(&name); } void test_iterator_tree__case_conflicts_0(void) diff --git a/tests/iterator/workdir.c b/tests/iterator/workdir.c index 82ee363f9f7..7ca726c247d 100644 --- a/tests/iterator/workdir.c +++ b/tests/iterator/workdir.c @@ -643,7 +643,7 @@ void test_iterator_workdir__filesystem2(void) */ void test_iterator_workdir__filesystem_gunk(void) { - git_buf parent = GIT_BUF_INIT; + git_str parent = GIT_STR_INIT; git_iterator *i; int n; @@ -653,8 +653,8 @@ void test_iterator_workdir__filesystem_gunk(void) g_repo = cl_git_sandbox_init("testrepo"); for (n = 0; n < 100000; n++) { - git_buf_clear(&parent); - cl_git_pass(git_buf_printf(&parent, "%s/refs/heads/foo/%d/subdir", git_repository_path(g_repo), n)); + git_str_clear(&parent); + cl_git_pass(git_str_printf(&parent, "%s/refs/heads/foo/%d/subdir", git_repository_path(g_repo), n)); cl_git_pass(git_futils_mkdir(parent.ptr, 0775, GIT_MKDIR_PATH)); } @@ -667,7 +667,7 @@ void test_iterator_workdir__filesystem_gunk(void) expect_iterator_items(i, 17, NULL, 16, NULL); git_iterator_free(i); - git_buf_dispose(&parent); + git_str_dispose(&parent); } void test_iterator_workdir__skips_unreadable_dirs(void) @@ -1019,19 +1019,19 @@ void test_iterator_workdir__pathlist_with_dirs(void) static void create_paths(const char *root, int depth) { - git_buf fullpath = GIT_BUF_INIT; + git_str fullpath = GIT_STR_INIT; size_t root_len; int i; - cl_git_pass(git_buf_puts(&fullpath, root)); + cl_git_pass(git_str_puts(&fullpath, root)); cl_git_pass(git_path_to_dir(&fullpath)); root_len = fullpath.size; for (i = 0; i < 8; i++) { bool file = (depth == 0 || (i % 2) == 0); - git_buf_truncate(&fullpath, root_len); - cl_git_pass(git_buf_printf(&fullpath, "item%d", i)); + git_str_truncate(&fullpath, root_len); + cl_git_pass(git_str_printf(&fullpath, "item%d", i)); if (file) { cl_git_rewritefile(fullpath.ptr, "This is a file!\n"); @@ -1043,7 +1043,7 @@ static void create_paths(const char *root, int depth) } } - git_buf_dispose(&fullpath); + git_str_dispose(&fullpath); } void test_iterator_workdir__pathlist_for_deeply_nested_item(void) diff --git a/tests/mailmap/parsing.c b/tests/mailmap/parsing.c index ba3b3a2f6db..5ea470f34ac 100644 --- a/tests/mailmap/parsing.c +++ b/tests/mailmap/parsing.c @@ -103,15 +103,15 @@ void test_mailmap_parsing__string(void) void test_mailmap_parsing__windows_string(void) { - git_buf unixbuf = GIT_BUF_INIT; - git_buf winbuf = GIT_BUF_INIT; + git_str unixbuf = GIT_STR_INIT; + git_str winbuf = GIT_STR_INIT; /* Parse with windows-style line endings */ - git_buf_attach_notowned(&unixbuf, string_mailmap, strlen(string_mailmap)); - cl_git_pass(git_buf_lf_to_crlf(&winbuf, &unixbuf)); + git_str_attach_notowned(&unixbuf, string_mailmap, strlen(string_mailmap)); + cl_git_pass(git_str_lf_to_crlf(&winbuf, &unixbuf)); cl_git_pass(git_mailmap_from_buffer(&g_mailmap, winbuf.ptr, winbuf.size)); - git_buf_dispose(&winbuf); + git_str_dispose(&winbuf); /* We should have parsed all of the entries */ check_mailmap_entries(g_mailmap, entries, ARRAY_SIZE(entries)); diff --git a/tests/merge/analysis.c b/tests/merge/analysis.c index 1432a7d112f..8c61303e342 100644 --- a/tests/merge/analysis.c +++ b/tests/merge/analysis.c @@ -53,28 +53,28 @@ static void analysis_from_branch( const char *our_branchname, const char *their_branchname) { - git_buf our_refname = GIT_BUF_INIT; - git_buf their_refname = GIT_BUF_INIT; + git_str our_refname = GIT_STR_INIT; + git_str their_refname = GIT_STR_INIT; git_reference *our_ref; git_reference *their_ref; git_annotated_commit *their_head; if (our_branchname != NULL) { - cl_git_pass(git_buf_printf(&our_refname, "%s%s", GIT_REFS_HEADS_DIR, our_branchname)); - cl_git_pass(git_reference_lookup(&our_ref, repo, git_buf_cstr(&our_refname))); + cl_git_pass(git_str_printf(&our_refname, "%s%s", GIT_REFS_HEADS_DIR, our_branchname)); + cl_git_pass(git_reference_lookup(&our_ref, repo, git_str_cstr(&our_refname))); } else { cl_git_pass(git_reference_lookup(&our_ref, repo, GIT_HEAD_FILE)); } - cl_git_pass(git_buf_printf(&their_refname, "%s%s", GIT_REFS_HEADS_DIR, their_branchname)); + cl_git_pass(git_str_printf(&their_refname, "%s%s", GIT_REFS_HEADS_DIR, their_branchname)); - cl_git_pass(git_reference_lookup(&their_ref, repo, git_buf_cstr(&their_refname))); + cl_git_pass(git_reference_lookup(&their_ref, repo, git_str_cstr(&their_refname))); cl_git_pass(git_annotated_commit_from_ref(&their_head, repo, their_ref)); cl_git_pass(git_merge_analysis_for_ref(merge_analysis, merge_pref, repo, our_ref, (const git_annotated_commit **)&their_head, 1)); - git_buf_dispose(&our_refname); - git_buf_dispose(&their_refname); + git_str_dispose(&our_refname); + git_str_dispose(&their_refname); git_annotated_commit_free(their_head); git_reference_free(our_ref); git_reference_free(their_ref); @@ -120,15 +120,15 @@ void test_merge_analysis__unborn(void) { git_merge_analysis_t merge_analysis; git_merge_preference_t merge_pref; - git_buf master = GIT_BUF_INIT; + git_str master = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&master, git_repository_path(repo), "refs/heads/master")); - cl_must_pass(p_unlink(git_buf_cstr(&master))); + cl_git_pass(git_str_joinpath(&master, git_repository_path(repo), "refs/heads/master")); + cl_must_pass(p_unlink(git_str_cstr(&master))); analysis_from_branch(&merge_analysis, &merge_pref, NULL, NOFASTFORWARD_BRANCH); cl_assert_equal_i(GIT_MERGE_ANALYSIS_FASTFORWARD|GIT_MERGE_ANALYSIS_UNBORN, merge_analysis); - git_buf_dispose(&master); + git_str_dispose(&master); } void test_merge_analysis__fastforward_with_config_noff(void) diff --git a/tests/merge/driver.c b/tests/merge/driver.c index a3fececb462..b7d320cbbb8 100644 --- a/tests/merge/driver.c +++ b/tests/merge/driver.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/repository.h" #include "git2/merge.h" -#include "buffer.h" #include "merge.h" #define TEST_REPO_PATH "merge-resolve" @@ -71,14 +70,23 @@ static int test_driver_apply( const char *filter_name, const git_merge_driver_source *src) { + git_str str = GIT_STR_INIT; + int error; + GIT_UNUSED(s); GIT_UNUSED(src); *path_out = "applied.txt"; *mode_out = GIT_FILEMODE_BLOB; - return git_buf_printf(merged_out, "This is the `%s` driver.\n", + error = git_str_printf(&str, "This is the `%s` driver.\n", filter_name); + + merged_out->ptr = str.ptr; + merged_out->size = str.size; + merged_out->reserved = 0; + + return error; } static struct test_merge_driver test_driver_custom = { @@ -117,19 +125,19 @@ static void test_drivers_unregister(void) static void set_gitattributes_to(const char *driver) { - git_buf line = GIT_BUF_INIT; + git_str line = GIT_STR_INIT; if (driver && strcmp(driver, "")) - git_buf_printf(&line, "automergeable.txt merge=%s\n", driver); + git_str_printf(&line, "automergeable.txt merge=%s\n", driver); else if (driver) - git_buf_printf(&line, "automergeable.txt merge\n"); + git_str_printf(&line, "automergeable.txt merge\n"); else - git_buf_printf(&line, "automergeable.txt -merge\n"); + git_str_printf(&line, "automergeable.txt -merge\n"); - cl_assert(!git_buf_oom(&line)); + cl_assert(!git_str_oom(&line)); cl_git_mkfile(TEST_REPO_PATH "/.gitattributes", line.ptr); - git_buf_dispose(&line); + git_str_dispose(&line); } static void merge_branch(void) @@ -172,11 +180,11 @@ void test_merge_driver__shutdown_is_called(void) test_driver_custom.shutdown = 0; test_driver_wildcard.initialized = 0; test_driver_wildcard.shutdown = 0; - + /* run the merge with the custom driver */ set_gitattributes_to("custom"); merge_branch(); - + /* unregister the drivers, ensure their shutdown function is called */ test_drivers_unregister(); diff --git a/tests/merge/files.c b/tests/merge/files.c index 6877f984865..fbc54e11e50 100644 --- a/tests/merge/files.c +++ b/tests/merge/files.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/repository.h" #include "git2/merge.h" -#include "buffer.h" #include "merge.h" #include "merge_helpers.h" #include "conflict_data.h" diff --git a/tests/merge/merge_helpers.c b/tests/merge/merge_helpers.c index 27f355f3530..1eb423ef7c8 100644 --- a/tests/merge/merge_helpers.c +++ b/tests/merge/merge_helpers.c @@ -17,15 +17,15 @@ int merge_trees_from_branches( git_commit *our_commit, *their_commit, *ancestor_commit = NULL; git_tree *our_tree, *their_tree, *ancestor_tree = NULL; git_oid our_oid, their_oid, ancestor_oid; - git_buf branch_buf = GIT_BUF_INIT; + git_str branch_buf = GIT_STR_INIT; int error; - git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name); + git_str_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name); cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid)); - git_buf_clear(&branch_buf); - git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs_name); + git_str_clear(&branch_buf); + git_str_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs_name); cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid)); @@ -43,7 +43,7 @@ int merge_trees_from_branches( error = git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, opts); - git_buf_dispose(&branch_buf); + git_str_dispose(&branch_buf); git_tree_free(our_tree); git_tree_free(their_tree); git_tree_free(ancestor_tree); @@ -61,21 +61,21 @@ int merge_commits_from_branches( { git_commit *our_commit, *their_commit; git_oid our_oid, their_oid; - git_buf branch_buf = GIT_BUF_INIT; + git_str branch_buf = GIT_STR_INIT; int error; - git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name); + git_str_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name); cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid)); - git_buf_clear(&branch_buf); - git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs_name); + git_str_clear(&branch_buf); + git_str_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs_name); cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid)); error = git_merge_commits(index, repo, our_commit, their_commit, opts); - git_buf_dispose(&branch_buf); + git_str_dispose(&branch_buf); git_commit_free(our_commit); git_commit_free(their_commit); @@ -328,12 +328,12 @@ int merge_test_reuc(git_index *index, const struct merge_reuc_entry expected[], return 1; } -int dircount(void *payload, git_buf *pathbuf) +int dircount(void *payload, git_str *pathbuf) { size_t *entries = payload; - size_t len = git_buf_len(pathbuf); + size_t len = git_str_len(pathbuf); - if (len < 5 || strcmp(pathbuf->ptr + (git_buf_len(pathbuf) - 5), "/.git") != 0) + if (len < 5 || strcmp(pathbuf->ptr + (git_str_len(pathbuf) - 5), "/.git") != 0) (*entries)++; return 0; @@ -343,9 +343,9 @@ int merge_test_workdir(git_repository *repo, const struct merge_index_entry expe { size_t actual_len = 0, i; git_oid actual_oid, expected_oid; - git_buf wd = GIT_BUF_INIT; + git_str wd = GIT_STR_INIT; - git_buf_puts(&wd, repo->workdir); + git_str_puts(&wd, repo->workdir); git_path_direach(&wd, 0, dircount, &actual_len); if (actual_len != expected_len) @@ -359,7 +359,7 @@ int merge_test_workdir(git_repository *repo, const struct merge_index_entry expe return 0; } - git_buf_dispose(&wd); + git_str_dispose(&wd); return 1; } diff --git a/tests/merge/trees/automerge.c b/tests/merge/trees/automerge.c index dd26464fbee..3bf6c520844 100644 --- a/tests/merge/trees/automerge.c +++ b/tests/merge/trees/automerge.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/repository.h" #include "git2/merge.h" -#include "buffer.h" #include "merge.h" #include "futils.h" #include "../merge_helpers.h" diff --git a/tests/merge/trees/modeconflict.c b/tests/merge/trees/modeconflict.c index 32866ea6d36..a0521c4e855 100644 --- a/tests/merge/trees/modeconflict.c +++ b/tests/merge/trees/modeconflict.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/repository.h" #include "git2/merge.h" -#include "buffer.h" #include "merge.h" #include "../merge_helpers.h" #include "futils.h" diff --git a/tests/merge/trees/renames.c b/tests/merge/trees/renames.c index eef7bc96be0..26f6d33062a 100644 --- a/tests/merge/trees/renames.c +++ b/tests/merge/trees/renames.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/repository.h" #include "git2/merge.h" -#include "buffer.h" #include "merge.h" #include "../merge_helpers.h" #include "futils.h" @@ -279,7 +278,7 @@ void test_merge_trees_renames__cache_recomputation(void) { git_oid blob, binary, ancestor_oid, theirs_oid, ours_oid; git_merge_options opts = GIT_MERGE_OPTIONS_INIT; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_treebuilder *builder; git_tree *ancestor_tree, *their_tree, *our_tree; git_index *index; @@ -307,9 +306,9 @@ void test_merge_trees_renames__cache_recomputation(void) */ cl_git_pass(git_treebuilder_new(&builder, repo, NULL)); for (i = 0; i < 1000; i++) { - cl_git_pass(git_buf_printf(&path, "%"PRIuZ".txt", i)); + cl_git_pass(git_str_printf(&path, "%"PRIuZ".txt", i)); cl_git_pass(git_treebuilder_insert(NULL, builder, path.ptr, &blob, GIT_FILEMODE_BLOB)); - git_buf_clear(&path); + git_str_clear(&path); } cl_git_pass(git_treebuilder_insert(NULL, builder, "original.bin", &binary, GIT_FILEMODE_BLOB)); cl_git_pass(git_treebuilder_write(&ancestor_oid, builder)); @@ -344,7 +343,7 @@ void test_merge_trees_renames__cache_recomputation(void) cl_git_pass(git_merge_trees(&index, repo, ancestor_tree, our_tree, their_tree, &opts)); git_treebuilder_free(builder); - git_buf_dispose(&path); + git_str_dispose(&path); git_index_free(index); git_tree_free(ancestor_tree); git_tree_free(their_tree); diff --git a/tests/merge/trees/trivial.c b/tests/merge/trees/trivial.c index ac4f09f80f8..dce392c863e 100644 --- a/tests/merge/trees/trivial.c +++ b/tests/merge/trees/trivial.c @@ -30,15 +30,15 @@ static int merge_trivial(git_index **index, const char *ours, const char *theirs git_commit *our_commit, *their_commit, *ancestor_commit; git_tree *our_tree, *their_tree, *ancestor_tree; git_oid our_oid, their_oid, ancestor_oid; - git_buf branch_buf = GIT_BUF_INIT; + git_str branch_buf = GIT_STR_INIT; git_merge_options opts = GIT_MERGE_OPTIONS_INIT; - git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours); + git_str_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours); cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid)); - git_buf_clear(&branch_buf); - git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs); + git_str_clear(&branch_buf); + git_str_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs); cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid)); @@ -51,7 +51,7 @@ static int merge_trivial(git_index **index, const char *ours, const char *theirs cl_git_pass(git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, &opts)); - git_buf_dispose(&branch_buf); + git_str_dispose(&branch_buf); git_tree_free(our_tree); git_tree_free(their_tree); git_tree_free(ancestor_tree); diff --git a/tests/merge/trees/whitespace.c b/tests/merge/trees/whitespace.c index ce770349645..9917df506da 100644 --- a/tests/merge/trees/whitespace.c +++ b/tests/merge/trees/whitespace.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/repository.h" #include "git2/merge.h" -#include "buffer.h" #include "merge.h" #include "../merge_helpers.h" #include "futils.h" diff --git a/tests/merge/workdir/dirty.c b/tests/merge/workdir/dirty.c index 6044bca43b9..b9c2ad0330c 100644 --- a/tests/merge/workdir/dirty.c +++ b/tests/merge/workdir/dirty.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "git2/merge.h" -#include "buffer.h" #include "merge.h" #include "index.h" #include "../merge_helpers.h" @@ -109,29 +108,29 @@ static int merge_branch(void) static void write_files(char *files[]) { char *filename; - git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, content = GIT_STR_INIT; size_t i; for (i = 0, filename = files[i]; filename; filename = files[++i]) { - git_buf_clear(&path); - git_buf_clear(&content); + git_str_clear(&path); + git_str_clear(&content); - git_buf_printf(&path, "%s/%s", TEST_REPO_PATH, filename); - git_buf_printf(&content, "This is a dirty file in the working directory!\n\n" + git_str_printf(&path, "%s/%s", TEST_REPO_PATH, filename); + git_str_printf(&content, "This is a dirty file in the working directory!\n\n" "It will not be staged! Its filename is %s.\n", filename); cl_git_mkfile(path.ptr, content.ptr); } - git_buf_dispose(&path); - git_buf_dispose(&content); + git_str_dispose(&path); + git_str_dispose(&content); } static void hack_index(char *files[]) { char *filename; struct stat statbuf; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_index_entry *entry; struct p_timeval times[2]; time_t now; @@ -153,12 +152,12 @@ static void hack_index(char *files[]) times[1].tv_usec = 0; for (i = 0, filename = files[i]; filename; filename = files[++i]) { - git_buf_clear(&path); + git_str_clear(&path); cl_assert(entry = (git_index_entry *) git_index_get_bypath(repo_index, filename, 0)); - cl_git_pass(git_buf_printf(&path, "%s/%s", TEST_REPO_PATH, filename)); + cl_git_pass(git_str_printf(&path, "%s/%s", TEST_REPO_PATH, filename)); cl_git_pass(p_utimes(path.ptr, times)); cl_git_pass(p_stat(path.ptr, &statbuf)); @@ -178,7 +177,7 @@ static void hack_index(char *files[]) entry->file_size = (uint32_t)statbuf.st_size; } - git_buf_dispose(&path); + git_str_dispose(&path); } static void stage_random_files(char *files[]) @@ -196,7 +195,7 @@ static void stage_content(char *content[]) { git_reference *head; git_object *head_object; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; char *filename, *text; size_t i; @@ -208,9 +207,9 @@ static void stage_content(char *content[]) filename && text; filename = content[++i], text = content[++i]) { - git_buf_clear(&path); + git_str_clear(&path); - cl_git_pass(git_buf_printf(&path, "%s/%s", TEST_REPO_PATH, filename)); + cl_git_pass(git_str_printf(&path, "%s/%s", TEST_REPO_PATH, filename)); cl_git_mkfile(path.ptr, text); cl_git_pass(git_index_add_bypath(repo_index, filename)); @@ -218,7 +217,7 @@ static void stage_content(char *content[]) git_object_free(head_object); git_reference_free(head); - git_buf_dispose(&path); + git_str_dispose(&path); } static int merge_dirty_files(char *dirty_files[]) diff --git a/tests/merge/workdir/recursive.c b/tests/merge/workdir/recursive.c index e7dc267e49b..7669e1b1ac1 100644 --- a/tests/merge/workdir/recursive.c +++ b/tests/merge/workdir/recursive.c @@ -23,7 +23,7 @@ void test_merge_workdir_recursive__writes_conflict_with_virtual_base(void) { git_index *index; git_merge_options opts = GIT_MERGE_OPTIONS_INIT; - git_buf conflicting_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { { 0100644, "ffb36e513f5fdf8a6ba850a20142676a2ac4807d", 0, "asparagus.txt" }, @@ -46,7 +46,7 @@ void test_merge_workdir_recursive__writes_conflict_with_virtual_base(void) cl_assert_equal_s(CONFLICTING_RECURSIVE_F1_TO_F2, conflicting_buf.ptr); git_index_free(index); - git_buf_dispose(&conflicting_buf); + git_str_dispose(&conflicting_buf); } void test_merge_workdir_recursive__conflicting_merge_base_with_diff3(void) @@ -54,7 +54,7 @@ void test_merge_workdir_recursive__conflicting_merge_base_with_diff3(void) git_index *index; git_merge_options opts = GIT_MERGE_OPTIONS_INIT; git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; - git_buf conflicting_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { { 0100644, "ffb36e513f5fdf8a6ba850a20142676a2ac4807d", 0, "asparagus.txt" }, @@ -80,5 +80,5 @@ void test_merge_workdir_recursive__conflicting_merge_base_with_diff3(void) cl_assert_equal_s(CONFLICTING_RECURSIVE_H2_TO_H1_WITH_DIFF3, conflicting_buf.ptr); git_index_free(index); - git_buf_dispose(&conflicting_buf); + git_str_dispose(&conflicting_buf); } diff --git a/tests/merge/workdir/renames.c b/tests/merge/workdir/renames.c index e8cd333af80..1b5128cf1b7 100644 --- a/tests/merge/workdir/renames.c +++ b/tests/merge/workdir/renames.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/repository.h" #include "git2/merge.h" -#include "buffer.h" #include "merge.h" #include "../merge_helpers.h" #include "futils.h" diff --git a/tests/merge/workdir/setup.c b/tests/merge/workdir/setup.c index 0b85f271244..fe33e21f201 100644 --- a/tests/merge/workdir/setup.c +++ b/tests/merge/workdir/setup.c @@ -46,29 +46,29 @@ void test_merge_workdir_setup__cleanup(void) static bool test_file_contents(const char *filename, const char *expected) { - git_buf file_path_buf = GIT_BUF_INIT, file_buf = GIT_BUF_INIT; + git_str file_path_buf = GIT_STR_INIT, file_buf = GIT_STR_INIT; bool equals; - git_buf_joinpath(&file_path_buf, git_repository_path(repo), filename); + git_str_joinpath(&file_path_buf, git_repository_path(repo), filename); cl_git_pass(git_futils_readbuffer(&file_buf, file_path_buf.ptr)); equals = (strcmp(file_buf.ptr, expected) == 0); - git_buf_dispose(&file_path_buf); - git_buf_dispose(&file_buf); + git_str_dispose(&file_path_buf); + git_str_dispose(&file_buf); return equals; } static void write_file_contents(const char *filename, const char *output) { - git_buf file_path_buf = GIT_BUF_INIT; + git_str file_path_buf = GIT_STR_INIT; - git_buf_joinpath(&file_path_buf, git_repository_path(repo), + git_str_joinpath(&file_path_buf, git_repository_path(repo), filename); cl_git_rewritefile(file_path_buf.ptr, output); - git_buf_dispose(&file_path_buf); + git_str_dispose(&file_path_buf); } /* git merge --no-ff octo1 */ @@ -464,41 +464,41 @@ static int create_remote_tracking_branch(const char *branch_name, const char *oi { int error = 0; - git_buf remotes_path = GIT_BUF_INIT, - origin_path = GIT_BUF_INIT, - filename = GIT_BUF_INIT, - data = GIT_BUF_INIT; + git_str remotes_path = GIT_STR_INIT, + origin_path = GIT_STR_INIT, + filename = GIT_STR_INIT, + data = GIT_STR_INIT; - if ((error = git_buf_puts(&remotes_path, git_repository_path(repo))) < 0 || - (error = git_buf_puts(&remotes_path, GIT_REFS_REMOTES_DIR)) < 0) + if ((error = git_str_puts(&remotes_path, git_repository_path(repo))) < 0 || + (error = git_str_puts(&remotes_path, GIT_REFS_REMOTES_DIR)) < 0) goto done; - if (!git_path_exists(git_buf_cstr(&remotes_path)) && - (error = p_mkdir(git_buf_cstr(&remotes_path), 0777)) < 0) + if (!git_path_exists(git_str_cstr(&remotes_path)) && + (error = p_mkdir(git_str_cstr(&remotes_path), 0777)) < 0) goto done; - if ((error = git_buf_puts(&origin_path, git_buf_cstr(&remotes_path))) < 0 || - (error = git_buf_puts(&origin_path, "origin")) < 0) + if ((error = git_str_puts(&origin_path, git_str_cstr(&remotes_path))) < 0 || + (error = git_str_puts(&origin_path, "origin")) < 0) goto done; - if (!git_path_exists(git_buf_cstr(&origin_path)) && - (error = p_mkdir(git_buf_cstr(&origin_path), 0777)) < 0) + if (!git_path_exists(git_str_cstr(&origin_path)) && + (error = p_mkdir(git_str_cstr(&origin_path), 0777)) < 0) goto done; - if ((error = git_buf_puts(&filename, git_buf_cstr(&origin_path))) < 0 || - (error = git_buf_puts(&filename, "/")) < 0 || - (error = git_buf_puts(&filename, branch_name)) < 0 || - (error = git_buf_puts(&data, oid_str)) < 0 || - (error = git_buf_puts(&data, "\n")) < 0) + if ((error = git_str_puts(&filename, git_str_cstr(&origin_path))) < 0 || + (error = git_str_puts(&filename, "/")) < 0 || + (error = git_str_puts(&filename, branch_name)) < 0 || + (error = git_str_puts(&data, oid_str)) < 0 || + (error = git_str_puts(&data, "\n")) < 0) goto done; - cl_git_rewritefile(git_buf_cstr(&filename), git_buf_cstr(&data)); + cl_git_rewritefile(git_str_cstr(&filename), git_str_cstr(&data)); done: - git_buf_dispose(&remotes_path); - git_buf_dispose(&origin_path); - git_buf_dispose(&filename); - git_buf_dispose(&data); + git_str_dispose(&remotes_path); + git_str_dispose(&origin_path); + git_str_dispose(&filename); + git_str_dispose(&data); return error; } diff --git a/tests/merge/workdir/simple.c b/tests/merge/workdir/simple.c index 6b4e174921a..6c4cf7e3cb5 100644 --- a/tests/merge/workdir/simple.c +++ b/tests/merge/workdir/simple.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/repository.h" #include "git2/merge.h" -#include "buffer.h" #include "merge.h" #include "../merge_helpers.h" #include "../conflict_data.h" @@ -126,7 +125,7 @@ void test_merge_workdir_simple__automerge(void) { git_index *index; const git_index_entry *entry; - git_buf automergeable_buf = GIT_BUF_INIT; + git_str automergeable_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { ADDED_IN_MASTER_INDEX_ENTRY, @@ -155,7 +154,7 @@ void test_merge_workdir_simple__automerge(void) cl_git_pass(git_futils_readbuffer(&automergeable_buf, TEST_REPO_PATH "/automergeable.txt")); cl_assert(strcmp(automergeable_buf.ptr, AUTOMERGEABLE_MERGED_FILE) == 0); - git_buf_dispose(&automergeable_buf); + git_str_dispose(&automergeable_buf); cl_assert(merge_test_index(repo_index, merge_index_entries, 8)); cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3)); @@ -202,7 +201,7 @@ void test_merge_workdir_simple__automerge_crlf(void) #ifdef GIT_WIN32 git_index *index; const git_index_entry *entry; - git_buf automergeable_buf = GIT_BUF_INIT; + git_str automergeable_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { ADDED_IN_MASTER_INDEX_ENTRY, @@ -230,7 +229,7 @@ void test_merge_workdir_simple__automerge_crlf(void) cl_git_pass(git_futils_readbuffer(&automergeable_buf, TEST_REPO_PATH "/automergeable.txt")); cl_assert(strcmp(automergeable_buf.ptr, AUTOMERGEABLE_MERGED_FILE_CRLF) == 0); - git_buf_dispose(&automergeable_buf); + git_str_dispose(&automergeable_buf); cl_assert(merge_test_index(repo_index, merge_index_entries, 8)); cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3)); @@ -246,7 +245,7 @@ void test_merge_workdir_simple__automerge_crlf(void) void test_merge_workdir_simple__mergefile(void) { - git_buf conflicting_buf = GIT_BUF_INIT, mergemsg_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT, mergemsg_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { ADDED_IN_MASTER_INDEX_ENTRY, @@ -276,13 +275,13 @@ void test_merge_workdir_simple__mergefile(void) cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_MERGE_FILE) == 0); cl_git_pass(git_futils_readbuffer(&mergemsg_buf, TEST_REPO_PATH "/.git/MERGE_MSG")); - cl_assert(strcmp(git_buf_cstr(&mergemsg_buf), + cl_assert(strcmp(git_str_cstr(&mergemsg_buf), "Merge commit '7cb63eed597130ba4abb87b3e544b85021905520'\n" \ "\n" \ "Conflicts:\n" \ "\tconflicting.txt\n") == 0); - git_buf_dispose(&conflicting_buf); - git_buf_dispose(&mergemsg_buf); + git_str_dispose(&conflicting_buf); + git_str_dispose(&mergemsg_buf); cl_assert(merge_test_index(repo_index, merge_index_entries, 8)); cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3)); @@ -290,7 +289,7 @@ void test_merge_workdir_simple__mergefile(void) void test_merge_workdir_simple__diff3(void) { - git_buf conflicting_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { ADDED_IN_MASTER_INDEX_ENTRY, @@ -318,7 +317,7 @@ void test_merge_workdir_simple__diff3(void) cl_git_pass(git_futils_readbuffer(&conflicting_buf, TEST_REPO_PATH "/conflicting.txt")); cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_DIFF3_FILE) == 0); - git_buf_dispose(&conflicting_buf); + git_str_dispose(&conflicting_buf); cl_assert(merge_test_index(repo_index, merge_index_entries, 8)); cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3)); @@ -326,7 +325,7 @@ void test_merge_workdir_simple__diff3(void) void test_merge_workdir_simple__union(void) { - git_buf conflicting_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { ADDED_IN_MASTER_INDEX_ENTRY, @@ -353,7 +352,7 @@ void test_merge_workdir_simple__union(void) cl_git_pass(git_futils_readbuffer(&conflicting_buf, TEST_REPO_PATH "/conflicting.txt")); cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_UNION_FILE) == 0); - git_buf_dispose(&conflicting_buf); + git_str_dispose(&conflicting_buf); cl_assert(merge_test_index(repo_index, merge_index_entries, 6)); cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 4)); @@ -361,7 +360,7 @@ void test_merge_workdir_simple__union(void) void test_merge_workdir_simple__gitattributes_union(void) { - git_buf conflicting_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { ADDED_IN_MASTER_INDEX_ENTRY, @@ -389,7 +388,7 @@ void test_merge_workdir_simple__gitattributes_union(void) cl_git_pass(git_futils_readbuffer(&conflicting_buf, TEST_REPO_PATH "/conflicting.txt")); cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_UNION_FILE) == 0); - git_buf_dispose(&conflicting_buf); + git_str_dispose(&conflicting_buf); cl_assert(merge_test_index(repo_index, merge_index_entries, 6)); cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 4)); @@ -398,7 +397,7 @@ void test_merge_workdir_simple__gitattributes_union(void) void test_merge_workdir_simple__diff3_from_config(void) { git_config *config; - git_buf conflicting_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { ADDED_IN_MASTER_INDEX_ENTRY, @@ -429,7 +428,7 @@ void test_merge_workdir_simple__diff3_from_config(void) cl_git_pass(git_futils_readbuffer(&conflicting_buf, TEST_REPO_PATH "/conflicting.txt")); cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_DIFF3_FILE) == 0); - git_buf_dispose(&conflicting_buf); + git_str_dispose(&conflicting_buf); cl_assert(merge_test_index(repo_index, merge_index_entries, 8)); cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3)); @@ -440,7 +439,7 @@ void test_merge_workdir_simple__diff3_from_config(void) void test_merge_workdir_simple__merge_overrides_config(void) { git_config *config; - git_buf conflicting_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { ADDED_IN_MASTER_INDEX_ENTRY, @@ -471,7 +470,7 @@ void test_merge_workdir_simple__merge_overrides_config(void) cl_git_pass(git_futils_readbuffer(&conflicting_buf, TEST_REPO_PATH "/conflicting.txt")); cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_MERGE_FILE) == 0); - git_buf_dispose(&conflicting_buf); + git_str_dispose(&conflicting_buf); cl_assert(merge_test_index(repo_index, merge_index_entries, 8)); cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3)); diff --git a/tests/merge/workdir/submodules.c b/tests/merge/workdir/submodules.c index 35280e61e8d..5117be78958 100644 --- a/tests/merge/workdir/submodules.c +++ b/tests/merge/workdir/submodules.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/repository.h" #include "git2/merge.h" -#include "buffer.h" #include "merge.h" #include "../merge_helpers.h" diff --git a/tests/merge/workdir/trivial.c b/tests/merge/workdir/trivial.c index c5bb7030ef3..fe83748516f 100644 --- a/tests/merge/workdir/trivial.c +++ b/tests/merge/workdir/trivial.c @@ -30,26 +30,26 @@ void test_merge_workdir_trivial__cleanup(void) static int merge_trivial(const char *ours, const char *theirs) { - git_buf branch_buf = GIT_BUF_INIT; + git_str branch_buf = GIT_STR_INIT; git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; git_reference *our_ref, *their_ref; git_annotated_commit *their_heads[1]; checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE; - git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours); + git_str_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours); cl_git_pass(git_reference_symbolic_create(&our_ref, repo, "HEAD", branch_buf.ptr, 1, NULL)); cl_git_pass(git_checkout_head(repo, &checkout_opts)); - git_buf_clear(&branch_buf); - git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs); + git_str_clear(&branch_buf); + git_str_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs); cl_git_pass(git_reference_lookup(&their_ref, repo, branch_buf.ptr)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, their_ref)); cl_git_pass(git_merge(repo, (const git_annotated_commit **)their_heads, 1, NULL, NULL)); - git_buf_dispose(&branch_buf); + git_str_dispose(&branch_buf); git_reference_free(our_ref); git_reference_free(their_ref); git_annotated_commit_free(their_heads[0]); diff --git a/tests/message/trailer.c b/tests/message/trailer.c index 9cc83de7256..919e10a499c 100644 --- a/tests/message/trailer.c +++ b/tests/message/trailer.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "message.h" static void assert_trailers(const char *message, git_message_trailer *trailers) { diff --git a/tests/network/fetchlocal.c b/tests/network/fetchlocal.c index 13f03100b36..302d1544cfb 100644 --- a/tests/network/fetchlocal.c +++ b/tests/network/fetchlocal.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "path.h" #include "remote.h" diff --git a/tests/network/remote/defaultbranch.c b/tests/network/remote/defaultbranch.c index b0417f76484..a7c0d81f6ca 100644 --- a/tests/network/remote/defaultbranch.c +++ b/tests/network/remote/defaultbranch.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "refspec.h" #include "remote.h" diff --git a/tests/network/remote/local.c b/tests/network/remote/local.c index 16cce6777d7..f174044d732 100644 --- a/tests/network/remote/local.c +++ b/tests/network/remote/local.c @@ -1,11 +1,10 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "path.h" #include "posix.h" #include "git2/sys/repository.h" static git_repository *repo; -static git_buf file_path_buf = GIT_BUF_INIT; +static git_str file_path_buf = GIT_STR_INIT; static git_remote *remote; static char *push_refspec_strings[] = { @@ -25,7 +24,7 @@ void test_network_remote_local__initialize(void) void test_network_remote_local__cleanup(void) { - git_buf_dispose(&file_path_buf); + git_str_dispose(&file_path_buf); git_remote_free(remote); remote = NULL; @@ -38,9 +37,9 @@ void test_network_remote_local__cleanup(void) static void connect_to_local_repository(const char *local_repository) { - git_buf_sets(&file_path_buf, cl_git_path_url(local_repository)); + git_str_sets(&file_path_buf, cl_git_path_url(local_repository)); - cl_git_pass(git_remote_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf))); + cl_git_pass(git_remote_create_anonymous(&remote, repo, git_str_cstr(&file_path_buf))); cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL)); } @@ -70,9 +69,9 @@ void test_network_remote_local__retrieve_advertised_before_connect(void) const git_remote_head **refs; size_t refs_len = 0; - git_buf_sets(&file_path_buf, cl_git_path_url(cl_fixture("testrepo.git"))); + git_str_sets(&file_path_buf, cl_git_path_url(cl_fixture("testrepo.git"))); - cl_git_pass(git_remote_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf))); + cl_git_pass(git_remote_create_anonymous(&remote, repo, git_str_cstr(&file_path_buf))); cl_git_fail(git_remote_ls(&refs, &refs_len, remote)); } @@ -472,10 +471,10 @@ void test_network_remote_local__anonymous_remote_inmemory_repo(void) git_repository *inmemory; git_remote *remote; - git_buf_sets(&file_path_buf, cl_git_path_url(cl_fixture("testrepo.git"))); + git_str_sets(&file_path_buf, cl_git_path_url(cl_fixture("testrepo.git"))); cl_git_pass(git_repository_new(&inmemory)); - cl_git_pass(git_remote_create_anonymous(&remote, inmemory, git_buf_cstr(&file_path_buf))); + cl_git_pass(git_remote_create_anonymous(&remote, inmemory, git_str_cstr(&file_path_buf))); cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL)); cl_assert(git_remote_connected(remote)); git_remote_disconnect(remote); diff --git a/tests/network/remote/remotes.c b/tests/network/remote/remotes.c index ed6a890751f..79c4f39fa21 100644 --- a/tests/network/remote/remotes.c +++ b/tests/network/remote/remotes.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "config/config_helpers.h" -#include "buffer.h" #include "refspec.h" #include "remote.h" @@ -28,7 +27,7 @@ void test_network_remote_remotes__cleanup(void) void test_network_remote_remotes__parsing(void) { - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; git_remote *_remote2 = NULL; cl_assert_equal_s(git_remote_name(_remote), "test"); @@ -53,7 +52,7 @@ void test_network_remote_remotes__parsing(void) cl_assert_equal_s(url.ptr, "git://github.com/libgit2/pushlibgit2"); git_remote_free(_remote2); - git_buf_dispose(&url); + git_str_dispose(&url); } static int remote_ready_callback(git_remote *remote, int direction, void *payload) @@ -79,7 +78,7 @@ static int remote_ready_callback(git_remote *remote, int direction, void *payloa void test_network_remote_remotes__remote_ready(void) { - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; callbacks.remote_ready = remote_ready_callback; @@ -95,29 +94,31 @@ void test_network_remote_remotes__remote_ready(void) cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, &callbacks)); cl_assert_equal_s(url.ptr, "push_url"); - git_buf_dispose(&url); + git_str_dispose(&url); } #ifndef GIT_DEPRECATE_HARD static int urlresolve_callback(git_buf *url_resolved, const char *url, int direction, void *payload) { + int error = -1; + cl_assert(strcmp(url, "git://github.com/libgit2/libgit2") == 0); cl_assert(strcmp(payload, "payload") == 0); cl_assert(url_resolved->size == 0); if (direction == GIT_DIRECTION_PUSH) - git_buf_sets(url_resolved, "pushresolve"); + error = git_buf_set(url_resolved, "pushresolve", strlen("pushresolve") + 1); if (direction == GIT_DIRECTION_FETCH) - git_buf_sets(url_resolved, "fetchresolve"); + error = git_buf_set(url_resolved, "fetchresolve", strlen("fetchresolve") + 1); - return GIT_OK; + return error; } #endif void test_network_remote_remotes__urlresolve(void) { #ifndef GIT_DEPRECATE_HARD - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; callbacks.resolve_url = urlresolve_callback; @@ -133,7 +134,7 @@ void test_network_remote_remotes__urlresolve(void) cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, &callbacks)); cl_assert_equal_s(url.ptr, "pushresolve"); - git_buf_dispose(&url); + git_str_dispose(&url); #endif } @@ -151,7 +152,7 @@ static int urlresolve_passthrough_callback(git_buf *url_resolved, const char *ur void test_network_remote_remotes__urlresolve_passthrough(void) { #ifndef GIT_DEPRECATE_HARD - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; const char *orig_url = "git://github.com/libgit2/libgit2"; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; @@ -167,13 +168,13 @@ void test_network_remote_remotes__urlresolve_passthrough(void) cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, &callbacks)); cl_assert_equal_s(url.ptr, orig_url); - git_buf_dispose(&url); + git_str_dispose(&url); #endif } void test_network_remote_remotes__instance_url(void) { - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; const char *orig_url = "git://github.com/libgit2/libgit2"; cl_assert_equal_s(git_remote_name(_remote), "test"); @@ -181,11 +182,11 @@ void test_network_remote_remotes__instance_url(void) cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, NULL)); cl_assert_equal_s(url.ptr, orig_url); - git_buf_clear(&url); + git_str_clear(&url); cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, NULL)); cl_assert_equal_s(url.ptr, orig_url); - git_buf_clear(&url); + git_str_clear(&url); /* Setting the instance url updates the fetch and push URLs */ git_remote_set_instance_url(_remote, "https://github.com/new/remote/url"); @@ -194,11 +195,11 @@ void test_network_remote_remotes__instance_url(void) cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, NULL)); cl_assert_equal_s(url.ptr, "https://github.com/new/remote/url"); - git_buf_clear(&url); + git_str_clear(&url); cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, NULL)); cl_assert_equal_s(url.ptr, "https://github.com/new/remote/url"); - git_buf_clear(&url); + git_str_clear(&url); /* Setting the instance push url updates only the push URL */ git_remote_set_instance_pushurl(_remote, "https://github.com/new/push/url"); @@ -207,13 +208,13 @@ void test_network_remote_remotes__instance_url(void) cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, NULL)); cl_assert_equal_s(url.ptr, "https://github.com/new/remote/url"); - git_buf_clear(&url); + git_str_clear(&url); cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, NULL)); cl_assert_equal_s(url.ptr, "https://github.com/new/push/url"); - git_buf_clear(&url); + git_str_clear(&url); - git_buf_dispose(&url); + git_str_dispose(&url); } void test_network_remote_remotes__pushurl(void) diff --git a/tests/notes/notes.c b/tests/notes/notes.c index af968679079..dd9ad1e4b13 100644 --- a/tests/notes/notes.c +++ b/tests/notes/notes.c @@ -1,7 +1,5 @@ #include "clar_libgit2.h" -#include "buffer.h" - static git_repository *_repo; static git_signature *_sig; @@ -282,7 +280,7 @@ void test_notes_notes__inserting_a_note_without_passing_a_namespace_uses_the_def create_note(¬e_oid, NULL, "08b041783f40edfe12bb406c9c9a8a040177c125", "hello world\n"); cl_git_pass(git_note_read(¬e, _repo, NULL, &target_oid)); - cl_git_pass(git_note_read(&default_namespace_note, _repo, git_buf_cstr(&default_ref), &target_oid)); + cl_git_pass(git_note_read(&default_namespace_note, _repo, default_ref.ptr, &target_oid)); assert_note_equal(note, "hello world\n", ¬e_oid); assert_note_equal(default_namespace_note, "hello world\n", ¬e_oid); diff --git a/tests/notes/notesref.c b/tests/notes/notesref.c index 3bcb05f20f5..6ba324c76b1 100644 --- a/tests/notes/notesref.c +++ b/tests/notes/notesref.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "notes.h" -#include "buffer.h" static git_repository *_repo; static git_note *_note; @@ -57,7 +56,7 @@ void test_notes_notesref__config_corenotesref(void) cl_git_pass(git_note_default_ref(&default_ref, _repo)); cl_assert_equal_s("refs/notes/mydefaultnotesref", default_ref.ptr); - git_buf_clear(&default_ref); + git_buf_dispose(&default_ref); cl_git_pass(git_config_delete_entry(_cfg, "core.notesRef")); diff --git a/tests/object/blob/filter.c b/tests/object/blob/filter.c index a8e3d3097b8..00b553e7123 100644 --- a/tests/object/blob/filter.c +++ b/tests/object/blob/filter.c @@ -24,7 +24,7 @@ static off64_t g_crlf_raw_len[CRLF_NUM_TEST_OBJECTS] = { static git_oid g_crlf_oids[CRLF_NUM_TEST_OBJECTS]; -static git_buf g_crlf_filtered[CRLF_NUM_TEST_OBJECTS] = { +static git_str g_crlf_filtered[CRLF_NUM_TEST_OBJECTS] = { { "", 0, 0 }, { "foo\nbar\n", 0, 8 }, { "foo\rbar\r", 0, 8 }, @@ -36,16 +36,16 @@ static git_buf g_crlf_filtered[CRLF_NUM_TEST_OBJECTS] = { { "\xFE\xFF\x00T\x00h\x00i\x00s\x00!", 0, 12 } }; -static git_buf_text_stats g_crlf_filtered_stats[CRLF_NUM_TEST_OBJECTS] = { +static git_str_text_stats g_crlf_filtered_stats[CRLF_NUM_TEST_OBJECTS] = { { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 2, 0, 6, 0 }, { 0, 0, 2, 0, 0, 6, 0 }, { 0, 0, 2, 2, 2, 6, 0 }, { 0, 0, 4, 4, 1, 31, 0 }, { 0, 1, 1, 2, 1, 9, 5 }, - { GIT_BUF_BOM_UTF8, 0, 0, 1, 0, 16, 0 }, - { GIT_BUF_BOM_UTF8, 0, 2, 2, 2, 27, 0 }, - { GIT_BUF_BOM_UTF16_BE, 5, 0, 0, 0, 7, 5 }, + { GIT_STR_BOM_UTF8, 0, 0, 1, 0, 16, 0 }, + { GIT_STR_BOM_UTF8, 0, 2, 2, 2, 27, 0 }, + { GIT_STR_BOM_UTF16_BE, 5, 0, 0, 0, 7, 5 }, }; void test_object_blob_filter__initialize(void) @@ -90,19 +90,19 @@ void test_object_blob_filter__stats(void) { int i; git_blob *blob; - git_buf buf = GIT_BUF_INIT; - git_buf_text_stats stats; + git_str buf = GIT_STR_INIT; + git_str_text_stats stats; for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) { cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i])); cl_git_pass(git_blob__getbuf(&buf, blob)); - git_buf_gather_text_stats(&stats, &buf, false); + git_str_gather_text_stats(&stats, &buf, false); cl_assert_equal_i( 0, memcmp(&g_crlf_filtered_stats[i], &stats, sizeof(stats))); git_blob_free(blob); } - git_buf_dispose(&buf); + git_str_dispose(&buf); } void test_object_blob_filter__to_odb(void) diff --git a/tests/object/blob/fromstream.c b/tests/object/blob/fromstream.c index df229f98f9d..60ff3991b9e 100644 --- a/tests/object/blob/fromstream.c +++ b/tests/object/blob/fromstream.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "posix.h" #include "path.h" #include "futils.h" @@ -48,15 +47,15 @@ void test_object_blob_fromstream__multiple_write(void) static void write_attributes(git_repository *repo) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&buf, git_repository_path(repo), "info")); - cl_git_pass(git_buf_joinpath(&buf, git_buf_cstr(&buf), "attributes")); + cl_git_pass(git_str_joinpath(&buf, git_repository_path(repo), "info")); + cl_git_pass(git_str_joinpath(&buf, git_str_cstr(&buf), "attributes")); - cl_git_pass(git_futils_mkpath2file(git_buf_cstr(&buf), 0777)); - cl_git_rewritefile(git_buf_cstr(&buf), GITATTR); + cl_git_pass(git_futils_mkpath2file(git_str_cstr(&buf), 0777)); + cl_git_rewritefile(git_str_cstr(&buf), GITATTR); - git_buf_dispose(&buf); + git_str_dispose(&buf); } static void assert_named_chunked_blob(const char *expected_sha, const char *fake_name) diff --git a/tests/object/blob/write.c b/tests/object/blob/write.c index 9a18d7cd410..802467498ed 100644 --- a/tests/object/blob/write.c +++ b/tests/object/blob/write.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "posix.h" #include "path.h" #include "futils.h" @@ -38,32 +37,32 @@ void test_object_blob_write__can_create_a_blob_in_a_standard_repo_from_a_file_lo void test_object_blob_write__can_create_a_blob_in_a_standard_repo_from_a_absolute_filepath_pointing_outside_of_the_working_directory(void) { - git_buf full_path = GIT_BUF_INIT; + git_str full_path = GIT_STR_INIT; repo = cl_git_sandbox_init(WORKDIR); cl_must_pass(p_mkdir(ELSEWHERE, 0777)); cl_must_pass(git_path_prettify_dir(&full_path, ELSEWHERE, NULL)); - cl_must_pass(git_buf_puts(&full_path, "test.txt")); + cl_must_pass(git_str_puts(&full_path, "test.txt")); - assert_blob_creation(ELSEWHERE "/test.txt", git_buf_cstr(&full_path), &git_blob_create_from_disk); + assert_blob_creation(ELSEWHERE "/test.txt", git_str_cstr(&full_path), &git_blob_create_from_disk); - git_buf_dispose(&full_path); + git_str_dispose(&full_path); cl_must_pass(git_futils_rmdir_r(ELSEWHERE, NULL, GIT_RMDIR_REMOVE_FILES)); } void test_object_blob_write__can_create_a_blob_in_a_bare_repo_from_a_absolute_filepath(void) { - git_buf full_path = GIT_BUF_INIT; + git_str full_path = GIT_STR_INIT; repo = cl_git_sandbox_init(BARE_REPO); cl_must_pass(p_mkdir(ELSEWHERE, 0777)); cl_must_pass(git_path_prettify_dir(&full_path, ELSEWHERE, NULL)); - cl_must_pass(git_buf_puts(&full_path, "test.txt")); + cl_must_pass(git_str_puts(&full_path, "test.txt")); - assert_blob_creation(ELSEWHERE "/test.txt", git_buf_cstr(&full_path), &git_blob_create_from_disk); + assert_blob_creation(ELSEWHERE "/test.txt", git_str_cstr(&full_path), &git_blob_create_from_disk); - git_buf_dispose(&full_path); + git_str_dispose(&full_path); cl_must_pass(git_futils_rmdir_r(ELSEWHERE, NULL, GIT_RMDIR_REMOVE_FILES)); } diff --git a/tests/object/commit/commitstagedfile.c b/tests/object/commit/commitstagedfile.c index f7ff05c01da..7322a4e8602 100644 --- a/tests/object/commit/commitstagedfile.c +++ b/tests/object/commit/commitstagedfile.c @@ -25,7 +25,7 @@ void test_object_commit_commitstagedfile__generate_predictable_object_ids(void) git_oid expected_blob_oid, tree_oid, expected_tree_oid, commit_oid, expected_commit_oid; git_signature *signature; git_tree *tree; - git_buf buffer; + git_buf buffer = GIT_BUF_INIT; /* * The test below replicates the following git scenario @@ -111,7 +111,6 @@ void test_object_commit_commitstagedfile__generate_predictable_object_ids(void) cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); cl_git_pass(git_tree_lookup(&tree, repo, &tree_oid)); - memset(&buffer, 0, sizeof(git_buf)); cl_git_pass(git_message_prettify(&buffer, "Initial commit", 0, '#')); cl_git_pass(git_commit_create_v( diff --git a/tests/object/lookup.c b/tests/object/lookup.c index 2458537fc20..a7b1ceeb4ed 100644 --- a/tests/object/lookup.c +++ b/tests/object/lookup.c @@ -66,13 +66,13 @@ void test_object_lookup__lookup_corrupt_object_returns_error(void) { const char *commit = "8e73b769e97678d684b809b163bebdae2911720f", *file = "objects/8e/73b769e97678d684b809b163bebdae2911720f"; - git_buf path = GIT_BUF_INIT, contents = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, contents = GIT_STR_INIT; git_oid oid; git_object *object; size_t i; cl_git_pass(git_oid_fromstr(&oid, commit)); - cl_git_pass(git_buf_joinpath(&path, git_repository_path(g_repo), file)); + cl_git_pass(git_str_joinpath(&path, git_repository_path(g_repo), file)); cl_git_pass(git_futils_readbuffer(&contents, path.ptr)); /* Corrupt and try to read the object */ @@ -88,8 +88,8 @@ void test_object_lookup__lookup_corrupt_object_returns_error(void) cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT)); git_object_free(object); - git_buf_dispose(&path); - git_buf_dispose(&contents); + git_str_dispose(&path); + git_str_dispose(&contents); } void test_object_lookup__lookup_object_with_wrong_hash_returns_error(void) @@ -97,15 +97,15 @@ void test_object_lookup__lookup_object_with_wrong_hash_returns_error(void) const char *oldloose = "objects/8e/73b769e97678d684b809b163bebdae2911720f", *newloose = "objects/8e/73b769e97678d684b809b163bebdae2911720e", *commit = "8e73b769e97678d684b809b163bebdae2911720e"; - git_buf oldpath = GIT_BUF_INIT, newpath = GIT_BUF_INIT; + git_str oldpath = GIT_STR_INIT, newpath = GIT_STR_INIT; git_object *object; git_oid oid; cl_git_pass(git_oid_fromstr(&oid, commit)); /* Copy object to another location with wrong hash */ - cl_git_pass(git_buf_joinpath(&oldpath, git_repository_path(g_repo), oldloose)); - cl_git_pass(git_buf_joinpath(&newpath, git_repository_path(g_repo), newloose)); + cl_git_pass(git_str_joinpath(&oldpath, git_repository_path(g_repo), oldloose)); + cl_git_pass(git_str_joinpath(&newpath, git_repository_path(g_repo), newloose)); cl_git_pass(git_futils_cp(oldpath.ptr, newpath.ptr, 0644)); /* Verify that lookup fails due to a hashsum mismatch */ @@ -117,6 +117,6 @@ void test_object_lookup__lookup_object_with_wrong_hash_returns_error(void) cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 1)); git_object_free(object); - git_buf_dispose(&oldpath); - git_buf_dispose(&newpath); + git_str_dispose(&oldpath); + git_str_dispose(&newpath); } diff --git a/tests/object/message.c b/tests/object/message.c index bc005340bbb..d87c8ef7060 100644 --- a/tests/object/message.c +++ b/tests/object/message.c @@ -1,13 +1,11 @@ #include "clar_libgit2.h" -#include "buffer.h" -#include "message.h" static void assert_message_prettifying(char *expected_output, char *input, int strip_comments) { git_buf prettified_message = GIT_BUF_INIT; git_message_prettify(&prettified_message, input, strip_comments, '#'); - cl_assert_equal_s(expected_output, git_buf_cstr(&prettified_message)); + cl_assert_equal_s(expected_output, prettified_message.ptr); git_buf_dispose(&prettified_message); } diff --git a/tests/object/raw/hash.c b/tests/object/raw/hash.c index 3be1f83b39b..5a3e818552a 100644 --- a/tests/object/raw/hash.c +++ b/tests/object/raw/hash.c @@ -56,7 +56,7 @@ void test_object_raw_hash__hash_buffer_in_single_call(void) void test_object_raw_hash__hash_vector(void) { git_oid id1, id2; - git_buf_vec vec[2]; + git_str_vec vec[2]; cl_git_pass(git_oid_fromstr(&id1, hello_id)); diff --git a/tests/object/tree/write.c b/tests/object/tree/write.c index 1bc5a50a02b..a4ceb35b684 100644 --- a/tests/object/tree/write.c +++ b/tests/object/tree/write.c @@ -394,12 +394,12 @@ void test_object_tree_write__cruel_paths(void) for (i = 0; i < count; ++i) { for (j = 0; j < count; ++j) { - git_buf b = GIT_BUF_INIT; - cl_git_pass(git_buf_joinpath(&b, the_paths[i], the_paths[j])); + git_str b = GIT_STR_INIT; + cl_git_pass(git_str_joinpath(&b, the_paths[i], the_paths[j])); cl_git_pass(git_tree_entry_bypath(&te, tree, b.ptr)); cl_assert_equal_s(the_paths[j], git_tree_entry_name(te)); git_tree_entry_free(te); - git_buf_dispose(&b); + git_str_dispose(&b); } } diff --git a/tests/odb/alternates.c b/tests/odb/alternates.c index f65a44bb542..e36010b7507 100644 --- a/tests/odb/alternates.c +++ b/tests/odb/alternates.c @@ -2,7 +2,7 @@ #include "odb.h" #include "filebuf.h" -static git_buf destpath, filepath; +static git_str destpath, filepath; static const char *paths[] = { "A.git", "B.git", "C.git", "D.git", "E.git", "F.git", "G.git" }; @@ -13,8 +13,8 @@ void test_odb_alternates__cleanup(void) { size_t i; - git_buf_dispose(&destpath); - git_buf_dispose(&filepath); + git_str_dispose(&destpath); + git_str_dispose(&filepath); for (i = 0; i < ARRAY_SIZE(paths); i++) cl_fixture_cleanup(paths[i]); @@ -22,18 +22,18 @@ void test_odb_alternates__cleanup(void) static void init_linked_repo(const char *path, const char *alternate) { - git_buf_clear(&destpath); - git_buf_clear(&filepath); + git_str_clear(&destpath); + git_str_clear(&filepath); cl_git_pass(git_repository_init(&repo, path, 1)); cl_git_pass(git_path_prettify(&destpath, alternate, NULL)); - cl_git_pass(git_buf_joinpath(&destpath, destpath.ptr, "objects")); - cl_git_pass(git_buf_joinpath(&filepath, git_repository_path(repo), "objects/info")); + cl_git_pass(git_str_joinpath(&destpath, destpath.ptr, "objects")); + cl_git_pass(git_str_joinpath(&filepath, git_repository_path(repo), "objects/info")); cl_git_pass(git_futils_mkdir(filepath.ptr, 0755, GIT_MKDIR_PATH)); - cl_git_pass(git_buf_joinpath(&filepath, filepath.ptr , "alternates")); + cl_git_pass(git_str_joinpath(&filepath, filepath.ptr , "alternates")); - cl_git_pass(git_filebuf_open(&file, git_buf_cstr(&filepath), 0, 0666)); - git_filebuf_printf(&file, "%s\n", git_buf_cstr(&destpath)); + cl_git_pass(git_filebuf_open(&file, git_str_cstr(&filepath), 0, 0666)); + git_filebuf_printf(&file, "%s\n", git_str_cstr(&destpath)); cl_git_pass(git_filebuf_commit(&file)); git_repository_free(repo); diff --git a/tests/odb/foreach.c b/tests/odb/foreach.c index 02112380b80..c2a44836338 100644 --- a/tests/odb/foreach.c +++ b/tests/odb/foreach.c @@ -2,7 +2,6 @@ #include "odb.h" #include "git2/odb_backend.h" #include "pack.h" -#include "buffer.h" static git_odb *_odb; static git_repository *_repo; @@ -121,15 +120,15 @@ void test_odb_foreach__files_in_objects_dir(void) { git_repository *repo; git_odb *odb; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; int nobj = 0; cl_fixture_sandbox("testrepo.git"); cl_git_pass(git_repository_open(&repo, "testrepo.git")); - cl_git_pass(git_buf_joinpath(&buf, git_repository_path(repo), "objects/somefile")); + cl_git_pass(git_str_joinpath(&buf, git_repository_path(repo), "objects/somefile")); cl_git_mkfile(buf.ptr, ""); - git_buf_dispose(&buf); + git_str_dispose(&buf); cl_git_pass(git_repository_odb(&odb, repo)); cl_git_pass(git_odb_foreach(odb, foreach_cb, &nobj)); diff --git a/tests/odb/freshen.c b/tests/odb/freshen.c index 1ecd92a8d27..2396e37746c 100644 --- a/tests/odb/freshen.c +++ b/tests/odb/freshen.c @@ -19,7 +19,7 @@ void test_odb_freshen__cleanup(void) static void set_time_wayback(struct stat *out, const char *fn) { - git_buf fullpath = GIT_BUF_INIT; + git_str fullpath = GIT_STR_INIT; struct p_timeval old[2]; old[0].tv_sec = 1234567890; @@ -27,11 +27,11 @@ static void set_time_wayback(struct stat *out, const char *fn) old[1].tv_sec = 1234567890; old[1].tv_usec = 0; - git_buf_joinpath(&fullpath, "testrepo.git/objects", fn); + git_str_joinpath(&fullpath, "testrepo.git/objects", fn); - cl_must_pass(p_utimes(git_buf_cstr(&fullpath), old)); - cl_must_pass(p_lstat(git_buf_cstr(&fullpath), out)); - git_buf_dispose(&fullpath); + cl_must_pass(p_utimes(git_str_cstr(&fullpath), old)); + cl_must_pass(p_lstat(git_str_cstr(&fullpath), out)); + git_str_dispose(&fullpath); } #define LOOSE_STR "my new file\n" diff --git a/tests/odb/largefiles.c b/tests/odb/largefiles.c index ff82291b301..acc786ee4cc 100644 --- a/tests/odb/largefiles.c +++ b/tests/odb/largefiles.c @@ -23,11 +23,11 @@ void test_odb_largefiles__cleanup(void) static void writefile(git_oid *oid) { static git_odb_stream *stream; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; size_t i; for (i = 0; i < 3041; i++) - cl_git_pass(git_buf_puts(&buf, "Hello, world.\n")); + cl_git_pass(git_str_puts(&buf, "Hello, world.\n")); cl_git_pass(git_odb_open_wstream(&stream, odb, LARGEFILE_SIZE, GIT_OBJECT_BLOB)); for (i = 0; i < 126103; i++) @@ -36,13 +36,13 @@ static void writefile(git_oid *oid) cl_git_pass(git_odb_stream_finalize_write(oid, stream)); git_odb_stream_free(stream); - git_buf_dispose(&buf); + git_str_dispose(&buf); } void test_odb_largefiles__write_from_memory(void) { git_oid expected, oid; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; size_t i; #ifndef GIT_ARCH_64 @@ -55,7 +55,7 @@ void test_odb_largefiles__write_from_memory(void) cl_skip(); for (i = 0; i < (3041*126103); i++) - cl_git_pass(git_buf_puts(&buf, "Hello, world.\n")); + cl_git_pass(git_str_puts(&buf, "Hello, world.\n")); git_oid_fromstr(&expected, "3fb56989cca483b21ba7cb0a6edb229d10e1c26c"); cl_git_pass(git_odb_write(&oid, odb, buf.ptr, buf.size, GIT_OBJECT_BLOB)); diff --git a/tests/online/clone.c b/tests/online/clone.c index 7d43c6a098f..c55cf9f951f 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -180,7 +180,7 @@ static int fetch_progress(const git_indexer_progress *stats, void *payload) void test_online_clone__can_checkout_a_cloned_repo(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_reference *head, *remote_head; bool checkout_progress_cb_was_called = false, fetch_progress_cb_was_called = false; @@ -193,8 +193,8 @@ void test_online_clone__can_checkout_a_cloned_repo(void) cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); - cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&path))); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); + cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&path))); cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(head)); @@ -209,7 +209,7 @@ void test_online_clone__can_checkout_a_cloned_repo(void) git_reference_free(remote_head); git_reference_free(head); - git_buf_dispose(&path); + git_str_dispose(&path); } static int remote_mirror_cb(git_remote **out, git_repository *repo, @@ -406,16 +406,16 @@ void test_online_clone__credentials(void) void test_online_clone__credentials_via_custom_headers(void) { const char *creds = "libgit3:libgit3"; - git_buf auth = GIT_BUF_INIT; + git_str auth = GIT_STR_INIT; - cl_git_pass(git_buf_puts(&auth, "Authorization: Basic ")); - cl_git_pass(git_buf_encode_base64(&auth, creds, strlen(creds))); + cl_git_pass(git_str_puts(&auth, "Authorization: Basic ")); + cl_git_pass(git_str_encode_base64(&auth, creds, strlen(creds))); g_options.fetch_opts.custom_headers.count = 1; g_options.fetch_opts.custom_headers.strings = &auth.ptr; cl_git_pass(git_clone(&g_repo, "https://bitbucket.org/libgit2/testgitrepository.git", "./foo", &g_options)); - git_buf_dispose(&auth); + git_str_dispose(&auth); } void test_online_clone__bitbucket_style(void) @@ -807,12 +807,12 @@ static int proxy_cert_cb(git_cert *cert, int valid, const char *host, void *payl void test_online_clone__proxy_credentials_request(void) { - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) cl_skip(); - cl_git_pass(git_buf_printf(&url, "%s://%s/", + cl_git_pass(git_str_printf(&url, "%s://%s/", _remote_proxy_scheme ? _remote_proxy_scheme : "http", _remote_proxy_host)); @@ -824,17 +824,17 @@ void test_online_clone__proxy_credentials_request(void) cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); cl_assert(called_proxy_creds); - git_buf_dispose(&url); + git_str_dispose(&url); } void test_online_clone__proxy_credentials_in_url(void) { - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) cl_skip(); - cl_git_pass(git_buf_printf(&url, "%s://%s:%s@%s/", + cl_git_pass(git_str_printf(&url, "%s://%s:%s@%s/", _remote_proxy_scheme ? _remote_proxy_scheme : "http", _remote_proxy_user, _remote_proxy_pass, _remote_proxy_host)); @@ -845,12 +845,12 @@ void test_online_clone__proxy_credentials_in_url(void) cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); cl_assert(called_proxy_creds == 0); - git_buf_dispose(&url); + git_str_dispose(&url); } void test_online_clone__proxy_credentials_in_environment(void) { - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) cl_skip(); @@ -863,7 +863,7 @@ void test_online_clone__proxy_credentials_in_environment(void) g_options.fetch_opts.proxy_opts.type = GIT_PROXY_AUTO; g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb; - cl_git_pass(git_buf_printf(&url, "%s://%s:%s@%s/", + cl_git_pass(git_str_printf(&url, "%s://%s:%s@%s/", _remote_proxy_scheme ? _remote_proxy_scheme : "http", _remote_proxy_user, _remote_proxy_pass, _remote_proxy_host)); @@ -873,17 +873,17 @@ void test_online_clone__proxy_credentials_in_environment(void) cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); - git_buf_dispose(&url); + git_str_dispose(&url); } void test_online_clone__proxy_credentials_in_url_https(void) { - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) cl_skip(); - cl_git_pass(git_buf_printf(&url, "%s://%s:%s@%s/", + cl_git_pass(git_str_printf(&url, "%s://%s:%s@%s/", _remote_proxy_scheme ? _remote_proxy_scheme : "http", _remote_proxy_user, _remote_proxy_pass, _remote_proxy_host)); @@ -895,7 +895,7 @@ void test_online_clone__proxy_credentials_in_url_https(void) cl_git_pass(git_clone(&g_repo, "https://github.com/libgit2/TestGitRepository", "./foo", &g_options)); cl_assert(called_proxy_creds == 0); - git_buf_dispose(&url); + git_str_dispose(&url); } void test_online_clone__proxy_auto_not_detected(void) @@ -907,12 +907,12 @@ void test_online_clone__proxy_auto_not_detected(void) void test_online_clone__proxy_cred_callback_after_failed_url_creds(void) { - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) cl_skip(); - cl_git_pass(git_buf_printf(&url, "%s://invalid_user_name:INVALID_pass_WORD@%s/", + cl_git_pass(git_str_printf(&url, "%s://invalid_user_name:INVALID_pass_WORD@%s/", _remote_proxy_scheme ? _remote_proxy_scheme : "http", _remote_proxy_host)); @@ -924,7 +924,7 @@ void test_online_clone__proxy_cred_callback_after_failed_url_creds(void) cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options)); cl_assert(called_proxy_creds); - git_buf_dispose(&url); + git_str_dispose(&url); } void test_online_clone__azurerepos(void) diff --git a/tests/online/customcert.c b/tests/online/customcert.c index c7a0de1a18e..098212b148e 100644 --- a/tests/online/customcert.c +++ b/tests/online/customcert.c @@ -28,22 +28,22 @@ void test_online_customcert__initialize(void) g_repo = NULL; if (!initialized) { - git_buf path = GIT_BUF_INIT, file = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, file = GIT_STR_INIT; char cwd[GIT_PATH_MAX]; cl_fixture_sandbox(CUSTOM_CERT_ONE_PATH); cl_fixture_sandbox(CUSTOM_CERT_TWO_FILE); cl_must_pass(p_getcwd(cwd, GIT_PATH_MAX)); - cl_git_pass(git_buf_joinpath(&path, cwd, CUSTOM_CERT_ONE_PATH)); - cl_git_pass(git_buf_joinpath(&file, cwd, CUSTOM_CERT_TWO_FILE)); + cl_git_pass(git_str_joinpath(&path, cwd, CUSTOM_CERT_ONE_PATH)); + cl_git_pass(git_str_joinpath(&file, cwd, CUSTOM_CERT_TWO_FILE)); cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, file.ptr, path.ptr)); initialized = true; - git_buf_dispose(&file); - git_buf_dispose(&path); + git_str_dispose(&file); + git_str_dispose(&path); } #endif } diff --git a/tests/online/fetch.c b/tests/online/fetch.c index 67dfd69ed62..9142910154d 100644 --- a/tests/online/fetch.c +++ b/tests/online/fetch.c @@ -226,13 +226,13 @@ void test_online_fetch__twice(void) void test_online_fetch__proxy(void) { git_remote *remote; - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; git_fetch_options fetch_opts; if (!_remote_proxy_host || !_remote_proxy_user || !_remote_proxy_pass) cl_skip(); - cl_git_pass(git_buf_printf(&url, "%s://%s:%s@%s/", + cl_git_pass(git_str_printf(&url, "%s://%s:%s@%s/", _remote_proxy_scheme ? _remote_proxy_scheme : "http", _remote_proxy_user, _remote_proxy_pass, _remote_proxy_host)); @@ -245,5 +245,5 @@ void test_online_fetch__proxy(void) cl_git_pass(git_remote_fetch(remote, NULL, &fetch_opts, NULL)); git_remote_free(remote); - git_buf_dispose(&url); + git_str_dispose(&url); } diff --git a/tests/online/fetchhead.c b/tests/online/fetchhead.c index b6199313818..30cce3a90ee 100644 --- a/tests/online/fetchhead.c +++ b/tests/online/fetchhead.c @@ -52,7 +52,7 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet { git_remote *remote; git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT; - git_buf fetchhead_buf = GIT_BUF_INIT; + git_str fetchhead_buf = GIT_STR_INIT; int equals = 0; git_strarray array, *active_refs = NULL; @@ -72,7 +72,7 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet equals = (strcmp(fetchhead_buf.ptr, expected_fetchhead) == 0); - git_buf_dispose(&fetchhead_buf); + git_str_dispose(&fetchhead_buf); cl_assert(equals); } @@ -157,7 +157,7 @@ void test_online_fetchhead__colon_only_dst_refspec_creates_no_branch(void) void test_online_fetchhead__creds_get_stripped(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_remote *remote; cl_git_pass(git_repository_init(&g_repo, "./foo", 0)); @@ -169,5 +169,5 @@ void test_online_fetchhead__creds_get_stripped(void) "49322bb17d3acc9146f98c97d078513228bbf3c0\t\thttps://github.com/libgit2/TestGitRepository\n"); git_remote_free(remote); - git_buf_dispose(&buf); + git_str_dispose(&buf); } diff --git a/tests/online/push.c b/tests/online/push.c index c82b606cb9a..51adc3930ca 100644 --- a/tests/online/push.c +++ b/tests/online/push.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "posix.h" #include "vector.h" #include "../submodule/submodule_helpers.h" @@ -129,28 +128,28 @@ static void do_verify_push_status(record_callbacks_data *data, const push_status } if (failed) { - git_buf msg = GIT_BUF_INIT; + git_str msg = GIT_STR_INIT; - git_buf_puts(&msg, "Expected and actual push statuses differ:\nEXPECTED:\n"); + git_str_puts(&msg, "Expected and actual push statuses differ:\nEXPECTED:\n"); for(i = 0; i < expected_len; i++) { - git_buf_printf(&msg, "%s: %s\n", + git_str_printf(&msg, "%s: %s\n", expected[i].ref, expected[i].success ? "success" : "failed"); } - git_buf_puts(&msg, "\nACTUAL:\n"); + git_str_puts(&msg, "\nACTUAL:\n"); git_vector_foreach(actual, i, iter) { if (iter->success) - git_buf_printf(&msg, "%s: success\n", iter->ref); + git_str_printf(&msg, "%s: success\n", iter->ref); else - git_buf_printf(&msg, "%s: failed with message: %s", iter->ref, iter->msg); + git_str_printf(&msg, "%s: failed with message: %s", iter->ref, iter->msg); } - cl_fail(git_buf_cstr(&msg)); + cl_fail(git_str_cstr(&msg)); - git_buf_dispose(&msg); + git_str_dispose(&msg); } git_vector_foreach(actual, i, iter) { @@ -192,7 +191,7 @@ static void verify_tracking_branches(git_remote *remote, expected_ref expected_r { git_refspec *fetch_spec; size_t i, j; - git_buf msg = GIT_BUF_INIT; + git_str msg = GIT_STR_INIT; git_buf ref_name = GIT_BUF_INIT; git_vector actual_refs = GIT_VECTOR_INIT; git_branch_iterator *iter; @@ -230,12 +229,12 @@ static void verify_tracking_branches(git_remote *remote, expected_ref expected_r /* Find matching remote branch */ git_vector_foreach(&actual_refs, j, actual_ref) { - if (!strcmp(git_buf_cstr(&ref_name), actual_ref)) + if (!strcmp(ref_name.ptr, actual_ref)) break; } if (j == actual_refs.length) { - git_buf_printf(&msg, "Did not find expected tracking branch '%s'.", git_buf_cstr(&ref_name)); + git_str_printf(&msg, "Did not find expected tracking branch '%s'.", ref_name.ptr); failed = 1; goto failed; } @@ -244,7 +243,7 @@ static void verify_tracking_branches(git_remote *remote, expected_ref expected_r cl_git_pass(git_reference_name_to_id(&oid, remote->repo, actual_ref)); if (git_oid_cmp(expected_refs[i].oid, &oid) != 0) { - git_buf_puts(&msg, "Tracking branch commit does not match expected ID."); + git_str_puts(&msg, "Tracking branch commit does not match expected ID."); failed = 1; goto failed; } @@ -255,27 +254,27 @@ static void verify_tracking_branches(git_remote *remote, expected_ref expected_r /* Make sure there are no extra branches */ if (actual_refs.length > 0) { - git_buf_puts(&msg, "Unexpected remote tracking branches exist."); + git_str_puts(&msg, "Unexpected remote tracking branches exist."); failed = 1; goto failed; } failed: if (failed) - cl_fail(git_buf_cstr(&msg)); + cl_fail(git_str_cstr(&msg)); git_vector_foreach(&actual_refs, i, actual_ref) git__free(actual_ref); git_vector_free(&actual_refs); - git_buf_dispose(&msg); + git_str_dispose(&msg); git_buf_dispose(&ref_name); } static void verify_update_tips_callback(git_remote *remote, expected_ref expected_refs[], size_t expected_refs_len) { git_refspec *fetch_spec; - git_buf msg = GIT_BUF_INIT; + git_str msg = GIT_STR_INIT; git_buf ref_name = GIT_BUF_INIT; updated_tip *tip = NULL; size_t i, j; @@ -293,18 +292,18 @@ static void verify_update_tips_callback(git_remote *remote, expected_ref expecte /* Find matching update_tip entry */ git_vector_foreach(&_record_cbs_data.updated_tips, j, tip) { - if (!strcmp(git_buf_cstr(&ref_name), tip->name)) + if (!strcmp(ref_name.ptr, tip->name)) break; } if (j == _record_cbs_data.updated_tips.length) { - git_buf_printf(&msg, "Did not find expected updated tip entry for branch '%s'.", git_buf_cstr(&ref_name)); + git_str_printf(&msg, "Did not find expected updated tip entry for branch '%s'.", ref_name.ptr); failed = 1; goto failed; } if (git_oid_cmp(expected_refs[i].oid, &tip->new_oid) != 0) { - git_buf_printf(&msg, "Updated tip ID does not match expected ID"); + git_str_printf(&msg, "Updated tip ID does not match expected ID"); failed = 1; goto failed; } @@ -312,10 +311,10 @@ static void verify_update_tips_callback(git_remote *remote, expected_ref expecte failed: if (failed) - cl_fail(git_buf_cstr(&msg)); + cl_fail(git_str_cstr(&msg)); git_buf_dispose(&ref_name); - git_buf_dispose(&msg); + git_str_dispose(&msg); } void test_online_push__initialize(void) diff --git a/tests/online/push_util.c b/tests/online/push_util.c index b39f7811421..94e310f3d83 100644 --- a/tests/online/push_util.c +++ b/tests/online/push_util.c @@ -1,6 +1,4 @@ - #include "clar_libgit2.h" -#include "buffer.h" #include "vector.h" #include "push_util.h" @@ -57,7 +55,7 @@ int record_update_tips_cb(const char *refname, const git_oid *a, const git_oid * int create_deletion_refspecs(git_vector *out, const git_remote_head **heads, size_t heads_len) { - git_buf del_spec = GIT_BUF_INIT; + git_str del_spec = GIT_STR_INIT; int valid; size_t i; @@ -70,9 +68,9 @@ int create_deletion_refspecs(git_vector *out, const git_remote_head **heads, siz /* Create a refspec that deletes a branch in the remote */ if (strcmp(head->name, "refs/heads/master")) { - cl_git_pass(git_buf_putc(&del_spec, ':')); - cl_git_pass(git_buf_puts(&del_spec, head->name)); - cl_git_pass(git_vector_insert(out, git_buf_detach(&del_spec))); + cl_git_pass(git_str_putc(&del_spec, ':')); + cl_git_pass(git_str_puts(&del_spec, head->name)); + cl_git_pass(git_vector_insert(out, git_str_detach(&del_spec))); } } @@ -88,7 +86,7 @@ int record_ref_cb(git_remote_head *head, void *payload) void verify_remote_refs(const git_remote_head *actual_refs[], size_t actual_refs_len, const expected_ref expected_refs[], size_t expected_refs_len) { size_t i, j = 0; - git_buf msg = GIT_BUF_INIT; + git_str msg = GIT_STR_INIT; const git_remote_head *actual; char *oid_str; bool master_present = false; @@ -120,24 +118,24 @@ void verify_remote_refs(const git_remote_head *actual_refs[], size_t actual_refs return; failed: - git_buf_puts(&msg, "Expected and actual refs differ:\nEXPECTED:\n"); + git_str_puts(&msg, "Expected and actual refs differ:\nEXPECTED:\n"); for(i = 0; i < expected_refs_len; i++) { oid_str = git_oid_tostr_s(expected_refs[i].oid); - cl_git_pass(git_buf_printf(&msg, "%s = %s\n", expected_refs[i].name, oid_str)); + cl_git_pass(git_str_printf(&msg, "%s = %s\n", expected_refs[i].name, oid_str)); } - git_buf_puts(&msg, "\nACTUAL:\n"); + git_str_puts(&msg, "\nACTUAL:\n"); for (i = 0; i < actual_refs_len; i++) { actual = actual_refs[i]; if (master_present && !strcmp(actual->name, "refs/heads/master")) continue; oid_str = git_oid_tostr_s(&actual->oid); - cl_git_pass(git_buf_printf(&msg, "%s = %s\n", actual->name, oid_str)); + cl_git_pass(git_str_printf(&msg, "%s = %s\n", actual->name, oid_str)); } - cl_fail(git_buf_cstr(&msg)); + cl_fail(git_str_cstr(&msg)); - git_buf_dispose(&msg); + git_str_dispose(&msg); } diff --git a/tests/pack/filelimit.c b/tests/pack/filelimit.c index 5e0b77e9bd2..2b7bf6e9542 100644 --- a/tests/pack/filelimit.c +++ b/tests/pack/filelimit.c @@ -34,12 +34,12 @@ void test_pack_filelimit__initialize_unlimited(void) void test_pack_filelimit__cleanup(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_git_pass(git_libgit2_opts(GIT_OPT_SET_MWINDOW_FILE_LIMIT, original_mwindow_file_limit)); - cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), "repo.git")); + cl_git_pass(git_str_joinpath(&path, clar_sandbox_path(), "repo.git")); cl_fixture_cleanup(path.ptr); - git_buf_dispose(&path); + git_str_dispose(&path); } /* @@ -54,7 +54,7 @@ void create_packfile_commit( size_t commit_index, size_t commit_count) { - git_buf file_contents = GIT_BUF_INIT; + git_str file_contents = GIT_STR_INIT; git_treebuilder *treebuilder; git_packbuilder *packbuilder; git_signature *s; @@ -67,7 +67,7 @@ void create_packfile_commit( cl_git_pass(git_blob_create_from_buffer(&oid, repo, "", 0)); cl_git_pass(git_treebuilder_insert(NULL, treebuilder, "README.md", &oid, 0100644)); - cl_git_pass(git_buf_printf(&file_contents, "Commit %zd/%zd", commit_index, commit_count)); + cl_git_pass(git_str_printf(&file_contents, "Commit %zd/%zd", commit_index, commit_count)); cl_git_pass(git_blob_create_from_buffer(&oid, repo, file_contents.ptr, file_contents.size)); cl_git_pass(git_treebuilder_insert(NULL, treebuilder, "file.txt", &oid, 0100644)); @@ -82,7 +82,7 @@ void create_packfile_commit( cl_git_pass(git_oid_cpy(out_commit_id, &commit_id)); - git_buf_dispose(&file_contents); + git_str_dispose(&file_contents); git_treebuilder_free(treebuilder); git_packbuilder_free(packbuilder); git_signature_free(s); @@ -90,7 +90,7 @@ void create_packfile_commit( void test_pack_filelimit__open_repo_with_multiple_packfiles(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_mwindow_ctl *ctl = &git_mwindow__mem_ctl; git_repository *repo; git_revwalk *walk; @@ -103,7 +103,7 @@ void test_pack_filelimit__open_repo_with_multiple_packfiles(void) * Create a repository and populate it with 16 commits, each in its own * packfile. */ - cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), "repo.git")); + cl_git_pass(git_str_joinpath(&path, clar_sandbox_path(), "repo.git")); cl_git_pass(git_repository_init(&repo, path.ptr, true)); for (i = 0; i < commit_count; ++i) { create_packfile_commit(repo, &id, parent_id, i + 1, commit_count); @@ -130,7 +130,7 @@ void test_pack_filelimit__open_repo_with_multiple_packfiles(void) cl_assert_equal_i(expected_open_mwindow_files, open_windows); - git_buf_dispose(&path); + git_str_dispose(&path); git_revwalk_free(walk); git_repository_free(repo); } diff --git a/tests/pack/indexer.c b/tests/pack/indexer.c index 422c3def4e4..5958bc4baa9 100644 --- a/tests/pack/indexer.c +++ b/tests/pack/indexer.c @@ -279,10 +279,10 @@ void test_pack_indexer__out_of_order_with_connectivity_checks(void) git_indexer_free(idx); } -static int find_tmp_file_recurs(void *opaque, git_buf *path) +static int find_tmp_file_recurs(void *opaque, git_str *path) { int error = 0; - git_buf *first_tmp_file = opaque; + git_str *first_tmp_file = opaque; struct stat st; if ((error = p_lstat_posixly(path->ptr, &st)) < 0) @@ -292,8 +292,8 @@ static int find_tmp_file_recurs(void *opaque, git_buf *path) return git_path_direach(path, 0, find_tmp_file_recurs, opaque); /* This is the template that's used in git_futils_mktmp. */ - if (strstr(git_buf_cstr(path), "_git2_") != NULL) - return git_buf_sets(first_tmp_file, git_buf_cstr(path)); + if (strstr(git_str_cstr(path), "_git2_") != NULL) + return git_str_sets(first_tmp_file, git_str_cstr(path)); return 0; } @@ -301,21 +301,21 @@ static int find_tmp_file_recurs(void *opaque, git_buf *path) void test_pack_indexer__no_tmp_files(void) { git_indexer *idx = NULL; - git_buf path = GIT_BUF_INIT; - git_buf first_tmp_file = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; + git_str first_tmp_file = GIT_STR_INIT; /* Precondition: there are no temporary files. */ - cl_git_pass(git_buf_sets(&path, clar_sandbox_path())); + cl_git_pass(git_str_sets(&path, clar_sandbox_path())); cl_git_pass(find_tmp_file_recurs(&first_tmp_file, &path)); - git_buf_dispose(&path); - cl_assert(git_buf_len(&first_tmp_file) == 0); + git_str_dispose(&path); + cl_assert(git_str_len(&first_tmp_file) == 0); cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL)); git_indexer_free(idx); - cl_git_pass(git_buf_sets(&path, clar_sandbox_path())); + cl_git_pass(git_str_sets(&path, clar_sandbox_path())); cl_git_pass(find_tmp_file_recurs(&first_tmp_file, &path)); - git_buf_dispose(&path); - cl_assert(git_buf_len(&first_tmp_file) == 0); - git_buf_dispose(&first_tmp_file); + git_str_dispose(&path); + cl_assert(git_str_len(&first_tmp_file) == 0); + git_str_dispose(&first_tmp_file); } diff --git a/tests/pack/midx.c b/tests/pack/midx.c index d5b91d28ba3..9dd949363e6 100644 --- a/tests/pack/midx.c +++ b/tests/pack/midx.c @@ -12,12 +12,12 @@ void test_pack_midx__parse(void) struct git_midx_file *idx; struct git_midx_entry e; git_oid id; - git_buf midx_path = GIT_BUF_INIT; + git_str midx_path = GIT_STR_INIT; cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); - cl_git_pass(git_buf_joinpath(&midx_path, git_repository_path(repo), "objects/pack/multi-pack-index")); - cl_git_pass(git_midx_open(&idx, git_buf_cstr(&midx_path))); - cl_assert_equal_i(git_midx_needs_refresh(idx, git_buf_cstr(&midx_path)), 0); + cl_git_pass(git_str_joinpath(&midx_path, git_repository_path(repo), "objects/pack/multi-pack-index")); + cl_git_pass(git_midx_open(&idx, git_str_cstr(&midx_path))); + cl_assert_equal_i(git_midx_needs_refresh(idx, git_str_cstr(&midx_path)), 0); cl_git_pass(git_oid_fromstr(&id, "5001298e0c09ad9c34e4249bc5801c75e9754fa5")); cl_git_pass(git_midx_entry_find(&e, idx, &id, GIT_OID_HEXSZ)); @@ -28,7 +28,7 @@ void test_pack_midx__parse(void) git_midx_free(idx); git_repository_free(repo); - git_buf_dispose(&midx_path); + git_str_dispose(&midx_path); } void test_pack_midx__lookup(void) @@ -51,27 +51,28 @@ void test_pack_midx__writer(void) { git_repository *repo; git_midx_writer *w = NULL; - git_buf midx = GIT_BUF_INIT, expected_midx = GIT_BUF_INIT, path = GIT_BUF_INIT; + git_buf midx = GIT_BUF_INIT; + git_str expected_midx = GIT_STR_INIT, path = GIT_STR_INIT; cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); - cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/pack")); - cl_git_pass(git_midx_writer_new(&w, git_buf_cstr(&path))); + cl_git_pass(git_str_joinpath(&path, git_repository_path(repo), "objects/pack")); + cl_git_pass(git_midx_writer_new(&w, git_str_cstr(&path))); cl_git_pass(git_midx_writer_add(w, "pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx")); cl_git_pass(git_midx_writer_add(w, "pack-d85f5d483273108c9d8dd0e4728ccf0b2982423a.idx")); cl_git_pass(git_midx_writer_add(w, "pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx")); cl_git_pass(git_midx_writer_dump(&midx, w)); - cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "objects/pack/multi-pack-index")); - cl_git_pass(git_futils_readbuffer(&expected_midx, git_buf_cstr(&path))); + cl_git_pass(git_str_joinpath(&path, git_repository_path(repo), "objects/pack/multi-pack-index")); + cl_git_pass(git_futils_readbuffer(&expected_midx, git_str_cstr(&path))); - cl_assert_equal_i(git_buf_len(&midx), git_buf_len(&expected_midx)); - cl_assert_equal_strn(git_buf_cstr(&midx), git_buf_cstr(&expected_midx), git_buf_len(&midx)); + cl_assert_equal_i(midx.size, git_str_len(&expected_midx)); + cl_assert_equal_strn(midx.ptr, git_str_cstr(&expected_midx), midx.size); git_buf_dispose(&midx); - git_buf_dispose(&expected_midx); - git_buf_dispose(&path); + git_str_dispose(&expected_midx); + git_str_dispose(&path); git_midx_writer_free(w); git_repository_free(repo); } @@ -81,30 +82,30 @@ void test_pack_midx__odb_create(void) git_repository *repo; git_odb *odb; git_clone_options opts = GIT_CLONE_OPTIONS_INIT; - git_buf midx = GIT_BUF_INIT, expected_midx = GIT_BUF_INIT, midx_path = GIT_BUF_INIT; + git_str midx = GIT_STR_INIT, expected_midx = GIT_STR_INIT, midx_path = GIT_STR_INIT; struct stat st; opts.bare = true; opts.local = GIT_CLONE_LOCAL; cl_git_pass(git_clone(&repo, cl_fixture("testrepo/.gitted"), "./clone.git", &opts)); - cl_git_pass(git_buf_joinpath(&midx_path, git_repository_path(repo), "objects/pack/multi-pack-index")); - cl_git_fail(p_stat(git_buf_cstr(&midx_path), &st)); + cl_git_pass(git_str_joinpath(&midx_path, git_repository_path(repo), "objects/pack/multi-pack-index")); + cl_git_fail(p_stat(git_str_cstr(&midx_path), &st)); cl_git_pass(git_repository_odb(&odb, repo)); cl_git_pass(git_odb_write_multi_pack_index(odb)); git_odb_free(odb); - cl_git_pass(p_stat(git_buf_cstr(&midx_path), &st)); + cl_git_pass(p_stat(git_str_cstr(&midx_path), &st)); cl_git_pass(git_futils_readbuffer(&expected_midx, cl_fixture("testrepo.git/objects/pack/multi-pack-index"))); - cl_git_pass(git_futils_readbuffer(&midx, git_buf_cstr(&midx_path))); - cl_assert_equal_i(git_buf_len(&midx), git_buf_len(&expected_midx)); - cl_assert_equal_strn(git_buf_cstr(&midx), git_buf_cstr(&expected_midx), git_buf_len(&midx)); + cl_git_pass(git_futils_readbuffer(&midx, git_str_cstr(&midx_path))); + cl_assert_equal_i(git_str_len(&midx), git_str_len(&expected_midx)); + cl_assert_equal_strn(git_str_cstr(&midx), git_str_cstr(&expected_midx), git_str_len(&midx)); git_repository_free(repo); - git_buf_dispose(&midx); - git_buf_dispose(&midx_path); - git_buf_dispose(&expected_midx); + git_str_dispose(&midx); + git_str_dispose(&midx_path); + git_str_dispose(&expected_midx); cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES)); -} \ No newline at end of file +} diff --git a/tests/pack/packbuilder.c b/tests/pack/packbuilder.c index 5d93ede06fe..b4c655c5e21 100644 --- a/tests/pack/packbuilder.c +++ b/tests/pack/packbuilder.c @@ -96,7 +96,7 @@ static int feed_indexer(void *ptr, size_t len, void *payload) void test_pack_packbuilder__create_pack(void) { git_indexer_progress stats; - git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT, path = GIT_STR_INIT; git_hash_ctx ctx; git_oid hash; char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0'; @@ -108,7 +108,7 @@ void test_pack_packbuilder__create_pack(void) cl_git_pass(git_indexer_commit(_indexer, &stats)); git_oid_fmt(hex, git_indexer_hash(_indexer)); - git_buf_printf(&path, "pack-%s.pack", hex); + git_str_printf(&path, "pack-%s.pack", hex); /* * By default, packfiles are created with only one thread. @@ -124,15 +124,15 @@ void test_pack_packbuilder__create_pack(void) * */ - cl_git_pass(git_futils_readbuffer(&buf, git_buf_cstr(&path))); + cl_git_pass(git_futils_readbuffer(&buf, git_str_cstr(&path))); cl_git_pass(git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1)); cl_git_pass(git_hash_update(&ctx, buf.ptr, buf.size)); cl_git_pass(git_hash_final(hash.id, &ctx)); git_hash_ctx_cleanup(&ctx); - git_buf_dispose(&path); - git_buf_dispose(&buf); + git_str_dispose(&path); + git_str_dispose(&buf); git_oid_fmt(hex, &hash); diff --git a/tests/patch/parse.c b/tests/patch/parse.c index 3f89eb51af9..a3c4c6730b4 100644 --- a/tests/patch/parse.c +++ b/tests/patch/parse.c @@ -27,13 +27,14 @@ static void ensure_patch_validity(git_patch *patch) cl_assert_equal_i(0, delta->new_file.size); } -static void ensure_identical_patch_inout(const char *content) { +static void ensure_identical_patch_inout(const char *content) +{ git_buf buf = GIT_BUF_INIT; git_patch *patch; cl_git_pass(git_patch_from_buffer(&patch, content, strlen(content), NULL)); cl_git_pass(git_patch_to_buf(&buf, patch)); - cl_assert_equal_strn(git_buf_cstr(&buf), content, strlen(content)); + cl_assert_equal_strn(buf.ptr, content, strlen(content)); git_patch_free(patch); git_buf_dispose(&buf); @@ -131,12 +132,13 @@ void test_patch_parse__files_with_whitespaces_succeeds(void) void test_patch_parse__lifetime_of_patch_does_not_depend_on_buffer(void) { - git_buf diff = GIT_BUF_INIT, rendered = GIT_BUF_INIT; + git_str diff = GIT_STR_INIT; + git_buf rendered = GIT_BUF_INIT; git_patch *patch; - cl_git_pass(git_buf_sets(&diff, PATCH_ORIGINAL_TO_CHANGE_MIDDLE)); + cl_git_pass(git_str_sets(&diff, PATCH_ORIGINAL_TO_CHANGE_MIDDLE)); cl_git_pass(git_patch_from_buffer(&patch, diff.ptr, diff.size, NULL)); - git_buf_dispose(&diff); + git_str_dispose(&diff); cl_git_pass(git_patch_to_buf(&rendered, patch)); cl_assert_equal_s(PATCH_ORIGINAL_TO_CHANGE_MIDDLE, rendered.ptr); diff --git a/tests/path/core.c b/tests/path/core.c index c875a862ce7..1d606693357 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -12,11 +12,11 @@ static void test_make_relative( const char *parent, int expected_status) { - git_buf buf = GIT_BUF_INIT; - git_buf_puts(&buf, path); + git_str buf = GIT_STR_INIT; + git_str_puts(&buf, path); cl_assert_equal_i(expected_status, git_path_make_relative(&buf, parent)); cl_assert_equal_s(expected_path, buf.ptr); - git_buf_dispose(&buf); + git_str_dispose(&buf); } void test_path_core__make_relative(void) @@ -373,19 +373,19 @@ static void test_join_unrooted( const char *path, const char *base) { - git_buf result = GIT_BUF_INIT; + git_str result = GIT_STR_INIT; ssize_t root_at; cl_git_pass(git_path_join_unrooted(&result, path, base, &root_at)); cl_assert_equal_s(expected_result, result.ptr); cl_assert_equal_i(expected_rootlen, root_at); - git_buf_dispose(&result); + git_str_dispose(&result); } void test_path_core__join_unrooted(void) { - git_buf out = GIT_BUF_INIT; + git_str out = GIT_STR_INIT; test_join_unrooted("foo", 0, "foo", NULL); test_join_unrooted("foo/bar", 0, "foo/bar", NULL); @@ -421,7 +421,7 @@ void test_path_core__join_unrooted(void) /* Trailing slash in the base is ignored */ test_join_unrooted("c:/foo/bar/foobar", 6, "c:/foo/bar/foobar", "c:/foo/"); - git_buf_dispose(&out); + git_str_dispose(&out); } void test_path_core__join_unrooted_respects_funny_windows_roots(void) diff --git a/tests/rebase/sign.c b/tests/rebase/sign.c index 06c18937aa1..dc99407dd87 100644 --- a/tests/rebase/sign.c +++ b/tests/rebase/sign.c @@ -263,8 +263,8 @@ int signing_cb_passthrough( const char *commit_content, void *payload) { - cl_assert_equal_b(false, git_buf_is_allocated(signature)); - cl_assert_equal_b(false, git_buf_is_allocated(signature_field)); + cl_assert_equal_i(0, signature->size); + cl_assert_equal_i(0, signature_field->size); cl_assert_equal_s(expected_commit_content, commit_content); cl_assert_equal_p(NULL, payload); return GIT_PASSTHROUGH; @@ -342,8 +342,8 @@ cttVRsdOoego+fiy08eFE+aJIeYiINRGhqOBTsuqG4jIdpdKxPE=\n\ =KbsY\n\ -----END PGP SIGNATURE-----"; - cl_assert_equal_b(false, git_buf_is_allocated(signature)); - cl_assert_equal_b(false, git_buf_is_allocated(signature_field)); + cl_assert_equal_i(0, signature->size); + cl_assert_equal_i(0, signature_field->size); cl_assert_equal_s(expected_commit_content, commit_content); cl_assert_equal_p(NULL, payload); @@ -426,8 +426,10 @@ int signing_cb_magic_field( const char *signature_content = "magic word: pretty please"; const char *signature_field_content = "magicsig"; - cl_assert_equal_b(false, git_buf_is_allocated(signature)); - cl_assert_equal_b(false, git_buf_is_allocated(signature_field)); + cl_assert_equal_p(NULL, signature->ptr); + cl_assert_equal_i(0, signature->size); + cl_assert_equal_p(NULL, signature_field->ptr); + cl_assert_equal_i(0, signature_field->size); cl_assert_equal_s(expected_commit_content, commit_content); cl_assert_equal_p(NULL, payload); diff --git a/tests/rebase/submodule.c b/tests/rebase/submodule.c index a28b3f4b2a1..0b3c2d5b58c 100644 --- a/tests/rebase/submodule.c +++ b/tests/rebase/submodule.c @@ -65,7 +65,7 @@ void test_rebase_submodule__init_untracked(void) git_rebase *rebase; git_reference *branch_ref, *upstream_ref; git_annotated_commit *branch_head, *upstream_head; - git_buf untracked_path = GIT_BUF_INIT; + git_str untracked_path = GIT_STR_INIT; FILE *fp; git_submodule *submodule; @@ -78,11 +78,11 @@ void test_rebase_submodule__init_untracked(void) cl_git_pass(git_submodule_lookup(&submodule, repo, "my-submodule")); cl_git_pass(git_submodule_update(submodule, 1, NULL)); - git_buf_printf(&untracked_path, "%s/my-submodule/untracked", git_repository_workdir(repo)); - fp = fopen(git_buf_cstr(&untracked_path), "w"); + git_str_printf(&untracked_path, "%s/my-submodule/untracked", git_repository_workdir(repo)); + fp = fopen(git_str_cstr(&untracked_path), "w"); fprintf(fp, "An untracked file in a submodule should not block a rebase\n"); fclose(fp); - git_buf_dispose(&untracked_path); + git_str_dispose(&untracked_path); cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL)); diff --git a/tests/refs/basic.c b/tests/refs/basic.c index 9e4c2296484..32742f9ccd8 100644 --- a/tests/refs/basic.c +++ b/tests/refs/basic.c @@ -49,7 +49,7 @@ void test_refs_basic__longpaths(void) const char *base; size_t base_len, extra_len; ssize_t remain_len, i; - git_buf refname = GIT_BUF_INIT; + git_str refname = GIT_STR_INIT; git_reference *one = NULL, *two = NULL; git_oid id; @@ -62,10 +62,10 @@ void test_refs_basic__longpaths(void) remain_len = (ssize_t)MAX_PATH - (base_len + extra_len); cl_assert(remain_len > 0); - cl_git_pass(git_buf_puts(&refname, "refs/heads/")); + cl_git_pass(git_str_puts(&refname, "refs/heads/")); for (i = 0; i < remain_len; i++) { - cl_git_pass(git_buf_putc(&refname, 'a')); + cl_git_pass(git_str_putc(&refname, 'a')); } /* @@ -75,11 +75,11 @@ void test_refs_basic__longpaths(void) cl_git_pass(git_reference_create(&one, g_repo, refname.ptr, &id, 0, NULL)); /* Adding one more character gives us a path that is too long. */ - cl_git_pass(git_buf_putc(&refname, 'z')); + cl_git_pass(git_str_putc(&refname, 'z')); cl_git_fail(git_reference_create(&two, g_repo, refname.ptr, &id, 0, NULL)); git_reference_free(one); git_reference_free(two); - git_buf_dispose(&refname); + git_str_dispose(&refname); #endif } diff --git a/tests/refs/branches/create.c b/tests/refs/branches/create.c index 70ffad88d24..7a49ad54896 100644 --- a/tests/refs/branches/create.c +++ b/tests/refs/branches/create.c @@ -120,19 +120,19 @@ static void assert_branch_matches_name( const char *expected, const char *lookup_as) { git_reference *ref; - git_buf b = GIT_BUF_INIT; + git_str b = GIT_STR_INIT; cl_git_pass(git_branch_lookup(&ref, repo, lookup_as, GIT_BRANCH_LOCAL)); - cl_git_pass(git_buf_sets(&b, "refs/heads/")); - cl_git_pass(git_buf_puts(&b, expected)); + cl_git_pass(git_str_sets(&b, "refs/heads/")); + cl_git_pass(git_str_puts(&b, expected)); cl_assert_equal_s(b.ptr, git_reference_name(ref)); cl_git_pass( git_oid_cmp(git_reference_target(ref), git_commit_id(target))); git_reference_free(ref); - git_buf_dispose(&b); + git_str_dispose(&b); } void test_refs_branches_create__can_create_branch_with_unicode(void) diff --git a/tests/refs/branches/delete.c b/tests/refs/branches/delete.c index 6093c788658..aad5c090fc3 100644 --- a/tests/refs/branches/delete.c +++ b/tests/refs/branches/delete.c @@ -153,8 +153,8 @@ void test_refs_branches_delete__removes_empty_folders(void) git_oid oidzero = {{0}}; git_signature *sig; - git_buf ref_folder = GIT_BUF_INIT; - git_buf reflog_folder = GIT_BUF_INIT; + git_str ref_folder = GIT_STR_INIT; + git_str reflog_folder = GIT_STR_INIT; /* Create a new branch with a nested name */ cl_git_pass(git_oid_fromstr(&commit_id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")); @@ -170,19 +170,19 @@ void test_refs_branches_delete__removes_empty_folders(void) git_signature_free(sig); git_reflog_free(log); - cl_git_pass(git_buf_joinpath(&ref_folder, commondir, "refs/heads/some/deep")); - cl_git_pass(git_buf_join3(&reflog_folder, '/', commondir, GIT_REFLOG_DIR, "refs/heads/some/deep")); + cl_git_pass(git_str_joinpath(&ref_folder, commondir, "refs/heads/some/deep")); + cl_git_pass(git_str_join3(&reflog_folder, '/', commondir, GIT_REFLOG_DIR, "refs/heads/some/deep")); - cl_assert(git_path_exists(git_buf_cstr(&ref_folder)) == true); - cl_assert(git_path_exists(git_buf_cstr(&reflog_folder)) == true); + cl_assert(git_path_exists(git_str_cstr(&ref_folder)) == true); + cl_assert(git_path_exists(git_str_cstr(&reflog_folder)) == true); cl_git_pass(git_branch_delete(branch)); - cl_assert(git_path_exists(git_buf_cstr(&ref_folder)) == false); - cl_assert(git_path_exists(git_buf_cstr(&reflog_folder)) == false); + cl_assert(git_path_exists(git_str_cstr(&ref_folder)) == false); + cl_assert(git_path_exists(git_str_cstr(&reflog_folder)) == false); git_reference_free(branch); - git_buf_dispose(&ref_folder); - git_buf_dispose(&reflog_folder); + git_str_dispose(&ref_folder); + git_str_dispose(&reflog_folder); } diff --git a/tests/refs/branches/move.c b/tests/refs/branches/move.c index 2cba9dfd3a3..46a5082d2fd 100644 --- a/tests/refs/branches/move.c +++ b/tests/refs/branches/move.c @@ -67,16 +67,14 @@ void test_refs_branches_move__can_not_move_a_branch_if_its_destination_name_coll { git_reference *original_ref, *new_ref; git_config *config; - git_buf buf = GIT_BUF_INIT; - char *original_remote, *original_merge; + git_buf original_remote = GIT_BUF_INIT, + original_merge = GIT_BUF_INIT; const char *str; cl_git_pass(git_repository_config_snapshot(&config, repo)); - cl_git_pass(git_config_get_string_buf(&buf, config, "branch.master.remote")); - original_remote = git_buf_detach(&buf); - cl_git_pass(git_config_get_string_buf(&buf, config, "branch.master.merge")); - original_merge = git_buf_detach(&buf); + cl_git_pass(git_config_get_string_buf(&original_remote, config, "branch.master.remote")); + cl_git_pass(git_config_get_string_buf(&original_merge, config, "branch.master.merge")); git_config_free(config); cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2")); @@ -88,9 +86,9 @@ void test_refs_branches_move__can_not_move_a_branch_if_its_destination_name_coll cl_git_pass(git_repository_config_snapshot(&config, repo)); cl_git_pass(git_config_get_string(&str, config, "branch.master.remote")); - cl_assert_equal_s(original_remote, str); + cl_assert_equal_s(original_remote.ptr, str); cl_git_pass(git_config_get_string(&str, config, "branch.master.merge")); - cl_assert_equal_s(original_merge, str); + cl_assert_equal_s(original_merge.ptr, str); git_config_free(config); cl_assert_equal_i(GIT_EEXISTS, @@ -100,9 +98,9 @@ void test_refs_branches_move__can_not_move_a_branch_if_its_destination_name_coll cl_git_pass(git_repository_config_snapshot(&config, repo)); cl_git_pass(git_config_get_string(&str, config, "branch.master.remote")); - cl_assert_equal_s(original_remote, str); + cl_assert_equal_s(original_remote.ptr, str); cl_git_pass(git_config_get_string(&str, config, "branch.master.merge")); - cl_assert_equal_s(original_merge, str); + cl_assert_equal_s(original_merge.ptr, str); git_config_free(config); git_reference_free(original_ref); @@ -115,11 +113,12 @@ void test_refs_branches_move__can_not_move_a_branch_if_its_destination_name_coll cl_git_pass(git_repository_config_snapshot(&config, repo)); cl_git_pass(git_config_get_string(&str, config, "branch.master.remote")); - cl_assert_equal_s(original_remote, str); + cl_assert_equal_s(original_remote.ptr, str); cl_git_pass(git_config_get_string(&str, config, "branch.master.merge")); - cl_assert_equal_s(original_merge, str); + cl_assert_equal_s(original_merge.ptr, str); - git__free(original_remote); git__free(original_merge); + git_buf_dispose(&original_remote); + git_buf_dispose(&original_merge); git_reference_free(original_ref); git_config_free(config); } diff --git a/tests/refs/branches/remote.c b/tests/refs/branches/remote.c index 27a3b0c4497..e2bd3485a80 100644 --- a/tests/refs/branches/remote.c +++ b/tests/refs/branches/remote.c @@ -32,10 +32,9 @@ void test_refs_branches_remote__can_get_remote_for_branch(void) void test_refs_branches_remote__no_matching_remote_returns_error(void) { const char *unknown = "refs/remotes/nonexistent/master"; - git_buf buf; + git_buf buf = GIT_BUF_INIT; git_error_clear(); - memset(&buf, 0, sizeof(git_buf)); cl_git_fail_with(git_branch_remote_name(&buf, g_repo, unknown), GIT_ENOTFOUND); cl_assert(git_error_last() != NULL); } @@ -43,10 +42,9 @@ void test_refs_branches_remote__no_matching_remote_returns_error(void) void test_refs_branches_remote__local_remote_returns_error(void) { const char *local = "refs/heads/master"; - git_buf buf; + git_buf buf = GIT_BUF_INIT; git_error_clear(); - memset(&buf, 0, sizeof(git_buf)); cl_git_fail_with(git_branch_remote_name(&buf, g_repo, local), GIT_ERROR); cl_assert(git_error_last() != NULL); } @@ -54,7 +52,7 @@ void test_refs_branches_remote__local_remote_returns_error(void) void test_refs_branches_remote__ambiguous_remote_returns_error(void) { git_remote *remote; - git_buf buf; + git_buf buf = GIT_BUF_INIT; /* Create the remote */ cl_git_pass(git_remote_create_with_fetchspec(&remote, g_repo, "addtest", "http://github.com/libgit2/libgit2", "refs/heads/*:refs/remotes/test/*")); @@ -62,7 +60,6 @@ void test_refs_branches_remote__ambiguous_remote_returns_error(void) git_remote_free(remote); git_error_clear(); - memset(&buf, 0, sizeof(git_buf)); cl_git_fail_with(git_branch_remote_name(&buf, g_repo, remote_tracking_branch_name), GIT_EAMBIGUOUS); cl_assert(git_error_last() != NULL); } diff --git a/tests/refs/branches/upstreamname.c b/tests/refs/branches/upstreamname.c index 2eb639738ae..5bae154d23c 100644 --- a/tests/refs/branches/upstreamname.c +++ b/tests/refs/branches/upstreamname.c @@ -8,7 +8,6 @@ void test_refs_branches_upstreamname__initialize(void) { cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); - git_buf_init(&upstream_name, 0); } void test_refs_branches_upstreamname__cleanup(void) @@ -24,7 +23,7 @@ void test_refs_branches_upstreamname__can_retrieve_the_remote_tracking_reference cl_git_pass(git_branch_upstream_name( &upstream_name, repo, "refs/heads/master")); - cl_assert_equal_s("refs/remotes/test/master", git_buf_cstr(&upstream_name)); + cl_assert_equal_s("refs/remotes/test/master", upstream_name.ptr); } void test_refs_branches_upstreamname__can_retrieve_the_local_upstream_reference_name_of_a_local_branch(void) @@ -32,5 +31,5 @@ void test_refs_branches_upstreamname__can_retrieve_the_local_upstream_reference_ cl_git_pass(git_branch_upstream_name( &upstream_name, repo, "refs/heads/track-local")); - cl_assert_equal_s("refs/heads/master", git_buf_cstr(&upstream_name)); + cl_assert_equal_s("refs/heads/master", upstream_name.ptr); } diff --git a/tests/refs/delete.c b/tests/refs/delete.c index 3e99a7959b7..c76d126eb15 100644 --- a/tests/refs/delete.c +++ b/tests/refs/delete.c @@ -29,10 +29,10 @@ void test_refs_delete__packed_loose(void) { /* deleting a ref which is both packed and loose should remove both tracks in the filesystem */ git_reference *looked_up_ref, *another_looked_up_ref; - git_buf temp_path = GIT_BUF_INIT; + git_str temp_path = GIT_STR_INIT; /* Ensure the loose reference exists on the file system */ - cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name)); + cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name)); cl_assert(git_path_exists(temp_path.ptr)); /* Lookup the reference */ @@ -52,7 +52,7 @@ void test_refs_delete__packed_loose(void) cl_assert(!git_path_exists(temp_path.ptr)); git_reference_free(another_looked_up_ref); - git_buf_dispose(&temp_path); + git_str_dispose(&temp_path); } void test_refs_delete__packed_only(void) diff --git a/tests/refs/pack.c b/tests/refs/pack.c index 676fb175986..125b1adb0a5 100644 --- a/tests/refs/pack.c +++ b/tests/refs/pack.c @@ -33,11 +33,11 @@ static void packall(void) void test_refs_pack__empty(void) { /* create a packfile for an empty folder */ - git_buf temp_path = GIT_BUF_INIT; + git_str temp_path = GIT_STR_INIT; - cl_git_pass(git_buf_join_n(&temp_path, '/', 3, git_repository_path(g_repo), GIT_REFS_HEADS_DIR, "empty_dir")); + cl_git_pass(git_str_join_n(&temp_path, '/', 3, git_repository_path(g_repo), GIT_REFS_HEADS_DIR, "empty_dir")); cl_git_pass(git_futils_mkdir_r(temp_path.ptr, GIT_REFS_DIR_MODE)); - git_buf_dispose(&temp_path); + git_str_dispose(&temp_path); packall(); } @@ -46,7 +46,7 @@ void test_refs_pack__loose(void) { /* create a packfile from all the loose refs in a repo */ git_reference *reference; - git_buf temp_path = GIT_BUF_INIT; + git_str temp_path = GIT_STR_INIT; /* Ensure a known loose ref can be looked up */ cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name)); @@ -62,7 +62,7 @@ void test_refs_pack__loose(void) packall(); /* Ensure the packed-refs file exists */ - cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), GIT_PACKEDREFS_FILE)); + cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), GIT_PACKEDREFS_FILE)); cl_assert(git_path_exists(temp_path.ptr)); /* Ensure the known ref can still be looked up but is now packed */ @@ -71,11 +71,11 @@ void test_refs_pack__loose(void) cl_assert_equal_s(reference->name, loose_tag_ref_name); /* Ensure the known ref has been removed from the loose folder structure */ - cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), loose_tag_ref_name)); + cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), loose_tag_ref_name)); cl_assert(!git_path_exists(temp_path.ptr)); git_reference_free(reference); - git_buf_dispose(&temp_path); + git_str_dispose(&temp_path); } void test_refs_pack__symbolic(void) diff --git a/tests/refs/read.c b/tests/refs/read.c index 1bbc3876649..a622c770b80 100644 --- a/tests/refs/read.c +++ b/tests/refs/read.c @@ -31,7 +31,7 @@ void test_refs_read__loose_tag(void) /* lookup a loose tag reference */ git_reference *reference; git_object *object; - git_buf ref_name_from_tag_name = GIT_BUF_INIT; + git_str ref_name_from_tag_name = GIT_STR_INIT; cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name)); cl_assert(git_reference_type(reference) & GIT_REFERENCE_DIRECT); @@ -43,9 +43,9 @@ void test_refs_read__loose_tag(void) cl_assert(git_object_type(object) == GIT_OBJECT_TAG); /* Ensure the name of the tag matches the name of the reference */ - cl_git_pass(git_buf_joinpath(&ref_name_from_tag_name, GIT_REFS_TAGS_DIR, git_tag_name((git_tag *)object))); + cl_git_pass(git_str_joinpath(&ref_name_from_tag_name, GIT_REFS_TAGS_DIR, git_tag_name((git_tag *)object))); cl_assert_equal_s(ref_name_from_tag_name.ptr, loose_tag_ref_name); - git_buf_dispose(&ref_name_from_tag_name); + git_str_dispose(&ref_name_from_tag_name); git_object_free(object); diff --git a/tests/refs/ref_helpers.c b/tests/refs/ref_helpers.c index 42b49216cd9..e55364c6e62 100644 --- a/tests/refs/ref_helpers.c +++ b/tests/refs/ref_helpers.c @@ -2,24 +2,23 @@ #include "git2/refs.h" #include "common.h" #include "util.h" -#include "buffer.h" #include "path.h" int reference_is_packed(git_reference *ref) { - git_buf ref_path = GIT_BUF_INIT; + git_str ref_path = GIT_STR_INIT; int packed; assert(ref); - if (git_buf_joinpath(&ref_path, + if (git_str_joinpath(&ref_path, git_repository_path(git_reference_owner(ref)), git_reference_name(ref)) < 0) return -1; packed = !git_path_isfile(ref_path.ptr); - git_buf_dispose(&ref_path); + git_str_dispose(&ref_path); return packed; } diff --git a/tests/refs/reflog/messages.c b/tests/refs/reflog/messages.c index 53b8c6f3ed1..ed183d2f2ca 100644 --- a/tests/refs/reflog/messages.c +++ b/tests/refs/reflog/messages.c @@ -338,7 +338,7 @@ void test_refs_reflog_messages__updating_a_direct_reference(void) void test_refs_reflog_messages__creating_branches_default_messages(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_annotated_commit *annotated; git_object *obj; git_commit *target; @@ -350,11 +350,11 @@ void test_refs_reflog_messages__creating_branches_default_messages(void) cl_git_pass(git_branch_create(&branch1, g_repo, NEW_BRANCH_NAME, target, false)); - cl_git_pass(git_buf_printf(&buf, "branch: Created from %s", git_oid_tostr_s(git_commit_id(target)))); + cl_git_pass(git_str_printf(&buf, "branch: Created from %s", git_oid_tostr_s(git_commit_id(target)))); cl_reflog_check_entry(g_repo, "refs/heads/" NEW_BRANCH_NAME, 0, GIT_OID_HEX_ZERO, git_oid_tostr_s(git_commit_id(target)), - g_email, git_buf_cstr(&buf)); + g_email, git_str_cstr(&buf)); cl_git_pass(git_reference_remove(g_repo, "refs/heads/" NEW_BRANCH_NAME)); @@ -367,7 +367,7 @@ void test_refs_reflog_messages__creating_branches_default_messages(void) g_email, "branch: Created from e90810b8df3"); git_annotated_commit_free(annotated); - git_buf_dispose(&buf); + git_str_dispose(&buf); git_commit_free(target); git_reference_free(branch1); git_reference_free(branch2); diff --git a/tests/refs/reflog/reflog.c b/tests/refs/reflog/reflog.c index 5cefc3227ec..5bb6138dff4 100644 --- a/tests/refs/reflog/reflog.c +++ b/tests/refs/reflog/reflog.c @@ -100,60 +100,60 @@ void test_refs_reflog_reflog__append_then_read(void) void test_refs_reflog_reflog__renaming_the_reference_moves_the_reflog(void) { git_reference *master, *new_master; - git_buf master_log_path = GIT_BUF_INIT, moved_log_path = GIT_BUF_INIT; + git_str master_log_path = GIT_STR_INIT, moved_log_path = GIT_STR_INIT; - git_buf_joinpath(&master_log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); - git_buf_puts(&moved_log_path, git_buf_cstr(&master_log_path)); - git_buf_joinpath(&master_log_path, git_buf_cstr(&master_log_path), "refs/heads/master"); - git_buf_joinpath(&moved_log_path, git_buf_cstr(&moved_log_path), "refs/moved"); + git_str_joinpath(&master_log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); + git_str_puts(&moved_log_path, git_str_cstr(&master_log_path)); + git_str_joinpath(&master_log_path, git_str_cstr(&master_log_path), "refs/heads/master"); + git_str_joinpath(&moved_log_path, git_str_cstr(&moved_log_path), "refs/moved"); - cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&master_log_path))); - cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&moved_log_path))); + cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&master_log_path))); + cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&moved_log_path))); cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master")); cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0, NULL)); git_reference_free(master); - cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&master_log_path))); - cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&moved_log_path))); + cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&master_log_path))); + cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&moved_log_path))); git_reference_free(new_master); - git_buf_dispose(&moved_log_path); - git_buf_dispose(&master_log_path); + git_str_dispose(&moved_log_path); + git_str_dispose(&master_log_path); } void test_refs_reflog_reflog__deleting_the_reference_deletes_the_reflog(void) { git_reference *master; - git_buf master_log_path = GIT_BUF_INIT; + git_str master_log_path = GIT_STR_INIT; - git_buf_joinpath(&master_log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); - git_buf_joinpath(&master_log_path, git_buf_cstr(&master_log_path), "refs/heads/master"); + git_str_joinpath(&master_log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); + git_str_joinpath(&master_log_path, git_str_cstr(&master_log_path), "refs/heads/master"); - cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&master_log_path))); + cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&master_log_path))); cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master")); cl_git_pass(git_reference_delete(master)); git_reference_free(master); - cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&master_log_path))); - git_buf_dispose(&master_log_path); + cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&master_log_path))); + git_str_dispose(&master_log_path); } void test_refs_reflog_reflog__removes_empty_reflog_dir(void) { git_reference *ref; - git_buf log_path = GIT_BUF_INIT; + git_str log_path = GIT_STR_INIT; git_oid id; /* Create a new branch pointing at the HEAD */ git_oid_fromstr(&id, current_master_tip); cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/new-dir/new-head", &id, 0, NULL)); - git_buf_joinpath(&log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); - git_buf_joinpath(&log_path, git_buf_cstr(&log_path), "refs/heads/new-dir/new-head"); + git_str_joinpath(&log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); + git_str_joinpath(&log_path, git_str_cstr(&log_path), "refs/heads/new-dir/new-head"); - cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&log_path))); + cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&log_path))); cl_git_pass(git_reference_delete(ref)); git_reference_free(ref); @@ -163,13 +163,13 @@ void test_refs_reflog_reflog__removes_empty_reflog_dir(void) cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/new-dir", &id, 0, NULL)); git_reference_free(ref); - git_buf_dispose(&log_path); + git_str_dispose(&log_path); } void test_refs_reflog_reflog__fails_gracefully_on_nonempty_reflog_dir(void) { git_reference *ref; - git_buf log_path = GIT_BUF_INIT; + git_str log_path = GIT_STR_INIT; git_oid id; /* Create a new branch pointing at the HEAD */ @@ -177,10 +177,10 @@ void test_refs_reflog_reflog__fails_gracefully_on_nonempty_reflog_dir(void) cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/new-dir/new-head", &id, 0, NULL)); git_reference_free(ref); - git_buf_joinpath(&log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); - git_buf_joinpath(&log_path, git_buf_cstr(&log_path), "refs/heads/new-dir/new-head"); + git_str_joinpath(&log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); + git_str_joinpath(&log_path, git_str_cstr(&log_path), "refs/heads/new-dir/new-head"); - cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&log_path))); + cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&log_path))); /* delete the ref manually, leave the reflog */ cl_must_pass(p_unlink("testrepo.git/refs/heads/new-dir/new-head")); @@ -190,7 +190,7 @@ void test_refs_reflog_reflog__fails_gracefully_on_nonempty_reflog_dir(void) cl_git_fail_with(GIT_EDIRECTORY, git_reference_create(&ref, g_repo, "refs/heads/new-dir", &id, 0, NULL)); git_reference_free(ref); - git_buf_dispose(&log_path); + git_str_dispose(&log_path); } static void assert_has_reflog(bool expected_result, const char *name) @@ -209,17 +209,17 @@ void test_refs_reflog_reflog__reading_the_reflog_from_a_reference_with_no_log_re { git_reflog *reflog; const char *refname = "refs/heads/subtrees"; - git_buf subtrees_log_path = GIT_BUF_INIT; + git_str subtrees_log_path = GIT_STR_INIT; - git_buf_join_n(&subtrees_log_path, '/', 3, git_repository_path(g_repo), GIT_REFLOG_DIR, refname); - cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&subtrees_log_path))); + git_str_join_n(&subtrees_log_path, '/', 3, git_repository_path(g_repo), GIT_REFLOG_DIR, refname); + cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&subtrees_log_path))); cl_git_pass(git_reflog_read(&reflog, g_repo, refname)); cl_assert_equal_i(0, (int)git_reflog_entrycount(reflog)); git_reflog_free(reflog); - git_buf_dispose(&subtrees_log_path); + git_str_dispose(&subtrees_log_path); } void test_refs_reflog_reflog__reading_a_reflog_with_invalid_format_succeeds(void) @@ -231,7 +231,7 @@ void test_refs_reflog_reflog__reading_a_reflog_with_invalid_format_succeeds(void const git_reflog_entry *entry; git_reference *ref; git_oid id; - git_buf logpath = GIT_BUF_INIT, logcontents = GIT_BUF_INIT; + git_str logpath = GIT_STR_INIT, logcontents = GIT_STR_INIT; char *star; /* Create a new branch. */ @@ -242,18 +242,18 @@ void test_refs_reflog_reflog__reading_a_reflog_with_invalid_format_succeeds(void * Corrupt the branch reflog by introducing a newline inside the reflog message. * We do this by replacing '*' with '\n' */ - cl_git_pass(git_buf_join_n(&logpath, '/', 3, git_repository_path(g_repo), GIT_REFLOG_DIR, refname)); - cl_git_pass(git_futils_readbuffer(&logcontents, git_buf_cstr(&logpath))); - cl_assert((star = strchr(git_buf_cstr(&logcontents), '*')) != NULL); + cl_git_pass(git_str_join_n(&logpath, '/', 3, git_repository_path(g_repo), GIT_REFLOG_DIR, refname)); + cl_git_pass(git_futils_readbuffer(&logcontents, git_str_cstr(&logpath))); + cl_assert((star = strchr(git_str_cstr(&logcontents), '*')) != NULL); *star = '\n'; - cl_git_rewritefile(git_buf_cstr(&logpath), git_buf_cstr(&logcontents)); + cl_git_rewritefile(git_str_cstr(&logpath), git_str_cstr(&logcontents)); /* * Confirm that the file was rewritten successfully * and now contains a '\n' in the expected location */ - cl_git_pass(git_futils_readbuffer(&logcontents, git_buf_cstr(&logpath))); - cl_assert(strstr(git_buf_cstr(&logcontents), "Reflog\nmessage") != NULL); + cl_git_pass(git_futils_readbuffer(&logcontents, git_str_cstr(&logpath))); + cl_assert(strstr(git_str_cstr(&logcontents), "Reflog\nmessage") != NULL); cl_git_pass(git_reflog_read(&reflog, g_repo, refname)); cl_assert(entry = git_reflog_entry_byindex(reflog, 0)); @@ -261,14 +261,14 @@ void test_refs_reflog_reflog__reading_a_reflog_with_invalid_format_succeeds(void git_reference_free(ref); git_reflog_free(reflog); - git_buf_dispose(&logpath); - git_buf_dispose(&logcontents); + git_str_dispose(&logpath); + git_str_dispose(&logcontents); } void test_refs_reflog_reflog__cannot_write_a_moved_reflog(void) { git_reference *master, *new_master; - git_buf master_log_path = GIT_BUF_INIT, moved_log_path = GIT_BUF_INIT; + git_str master_log_path = GIT_STR_INIT, moved_log_path = GIT_STR_INIT; git_reflog *reflog; cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master")); @@ -283,8 +283,8 @@ void test_refs_reflog_reflog__cannot_write_a_moved_reflog(void) git_reflog_free(reflog); git_reference_free(new_master); - git_buf_dispose(&moved_log_path); - git_buf_dispose(&master_log_path); + git_str_dispose(&moved_log_path); + git_str_dispose(&master_log_path); } void test_refs_reflog_reflog__renaming_with_an_invalid_name_returns_EINVALIDSPEC(void) diff --git a/tests/refs/reflog/reflog_helpers.c b/tests/refs/reflog/reflog_helpers.c index aecb78b02bd..22619a4e3b6 100644 --- a/tests/refs/reflog/reflog_helpers.c +++ b/tests/refs/reflog/reflog_helpers.c @@ -3,7 +3,7 @@ #include "repository.h" #include "reflog.h" -static int reflog_entry_tostr(git_buf *out, const git_reflog_entry *entry) +static int reflog_entry_tostr(git_str *out, const git_reflog_entry *entry) { char old_oid[GIT_OID_HEXSZ], new_oid[GIT_OID_HEXSZ]; @@ -12,7 +12,7 @@ static int reflog_entry_tostr(git_buf *out, const git_reflog_entry *entry) git_oid_tostr((char *)&old_oid, GIT_OID_HEXSZ, git_reflog_entry_id_old(entry)); git_oid_tostr((char *)&new_oid, GIT_OID_HEXSZ, git_reflog_entry_id_new(entry)); - return git_buf_printf(out, "%s %s %s %s", old_oid, new_oid, "somesig", git_reflog_entry_message(entry)); + return git_str_printf(out, "%s %s %s %s", old_oid, new_oid, "somesig", git_reflog_entry_message(entry)); } size_t reflog_entrycount(git_repository *repo, const char *name) @@ -34,7 +34,7 @@ void cl_reflog_check_entry_(git_repository *repo, const char *reflog, size_t idx { git_reflog *log; const git_reflog_entry *entry; - git_buf result = GIT_BUF_INIT; + git_str result = GIT_STR_INIT; cl_git_pass(git_reflog_read(&log, repo, reflog)); entry = git_reflog_entry_byindex(log, idx); @@ -47,7 +47,7 @@ void cl_reflog_check_entry_(git_repository *repo, const char *reflog, size_t idx if (git_oid_cmp(git_object_id(obj), git_reflog_entry_id_old(entry)) != 0) { git_oid__writebuf(&result, "\tOld OID: \"", git_object_id(obj)); git_oid__writebuf(&result, "\" != \"", git_reflog_entry_id_old(entry)); - git_buf_puts(&result, "\"\n"); + git_str_puts(&result, "\"\n"); } git_object_free(obj); } else { @@ -56,7 +56,7 @@ void cl_reflog_check_entry_(git_repository *repo, const char *reflog, size_t idx if (git_oid_cmp(oid, git_reflog_entry_id_old(entry)) != 0) { git_oid__writebuf(&result, "\tOld OID: \"", oid); git_oid__writebuf(&result, "\" != \"", git_reflog_entry_id_old(entry)); - git_buf_puts(&result, "\"\n"); + git_str_puts(&result, "\"\n"); } git__free(oid); } @@ -67,7 +67,7 @@ void cl_reflog_check_entry_(git_repository *repo, const char *reflog, size_t idx if (git_oid_cmp(git_object_id(obj), git_reflog_entry_id_new(entry)) != 0) { git_oid__writebuf(&result, "\tNew OID: \"", git_object_id(obj)); git_oid__writebuf(&result, "\" != \"", git_reflog_entry_id_new(entry)); - git_buf_puts(&result, "\"\n"); + git_str_puts(&result, "\"\n"); } git_object_free(obj); } else { @@ -76,26 +76,26 @@ void cl_reflog_check_entry_(git_repository *repo, const char *reflog, size_t idx if (git_oid_cmp(oid, git_reflog_entry_id_new(entry)) != 0) { git_oid__writebuf(&result, "\tNew OID: \"", oid); git_oid__writebuf(&result, "\" != \"", git_reflog_entry_id_new(entry)); - git_buf_puts(&result, "\"\n"); + git_str_puts(&result, "\"\n"); } git__free(oid); } } if (email && strcmp(email, git_reflog_entry_committer(entry)->email) != 0) - git_buf_printf(&result, "\tEmail: \"%s\" != \"%s\"\n", email, git_reflog_entry_committer(entry)->email); + git_str_printf(&result, "\tEmail: \"%s\" != \"%s\"\n", email, git_reflog_entry_committer(entry)->email); if (message) { const char *entry_msg = git_reflog_entry_message(entry); if (entry_msg == NULL) entry_msg = ""; if (entry_msg && strcmp(message, entry_msg) != 0) - git_buf_printf(&result, "\tMessage: \"%s\" != \"%s\"\n", message, entry_msg); + git_str_printf(&result, "\tMessage: \"%s\" != \"%s\"\n", message, entry_msg); } - if (git_buf_len(&result) != 0) - clar__fail(file, func, line, "Reflog entry mismatch", git_buf_cstr(&result), 1); + if (git_str_len(&result) != 0) + clar__fail(file, func, line, "Reflog entry mismatch", git_str_cstr(&result), 1); - git_buf_dispose(&result); + git_str_dispose(&result); git_reflog_free(log); } @@ -103,17 +103,17 @@ void reflog_print(git_repository *repo, const char *reflog_name) { git_reflog *reflog; size_t idx; - git_buf out = GIT_BUF_INIT; + git_str out = GIT_STR_INIT; git_reflog_read(&reflog, repo, reflog_name); for (idx = 0; idx < git_reflog_entrycount(reflog); idx++) { const git_reflog_entry *entry = git_reflog_entry_byindex(reflog, idx); reflog_entry_tostr(&out, entry); - git_buf_putc(&out, '\n'); + git_str_putc(&out, '\n'); } - fprintf(stderr, "%s", git_buf_cstr(&out)); - git_buf_dispose(&out); + fprintf(stderr, "%s", git_str_cstr(&out)); + git_str_dispose(&out); git_reflog_free(reflog); } diff --git a/tests/refs/rename.c b/tests/refs/rename.c index b1b75cd6474..fa732234a72 100644 --- a/tests/refs/rename.c +++ b/tests/refs/rename.c @@ -36,11 +36,11 @@ void test_refs_rename__loose(void) { /* rename a loose reference */ git_reference *looked_up_ref, *new_ref, *another_looked_up_ref; - git_buf temp_path = GIT_BUF_INIT; + git_str temp_path = GIT_STR_INIT; const char *new_name = "refs/tags/Nemo/knows/refs.kung-fu"; /* Ensure the ref doesn't exist on the file system */ - cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), new_name)); + cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), new_name)); cl_assert(!git_path_exists(temp_path.ptr)); /* Retrieval of the reference to rename */ @@ -66,23 +66,23 @@ void test_refs_rename__loose(void) cl_assert(reference_is_packed(new_ref) == 0); /* ...and the ref can be found in the file system */ - cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), new_name)); + cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), new_name)); cl_assert(git_path_exists(temp_path.ptr)); git_reference_free(new_ref); git_reference_free(another_looked_up_ref); - git_buf_dispose(&temp_path); + git_str_dispose(&temp_path); } void test_refs_rename__packed(void) { /* rename a packed reference (should make it loose) */ git_reference *looked_up_ref, *new_ref, *another_looked_up_ref; - git_buf temp_path = GIT_BUF_INIT; + git_str temp_path = GIT_STR_INIT; const char *brand_new_name = "refs/heads/brand_new_name"; /* Ensure the ref doesn't exist on the file system */ - cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), packed_head_name)); + cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), packed_head_name)); cl_assert(!git_path_exists(temp_path.ptr)); /* The reference can however be looked-up... */ @@ -108,23 +108,23 @@ void test_refs_rename__packed(void) cl_assert(reference_is_packed(new_ref) == 0); /* ...and the ref now happily lives in the file system */ - cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), brand_new_name)); + cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), brand_new_name)); cl_assert(git_path_exists(temp_path.ptr)); git_reference_free(new_ref); git_reference_free(another_looked_up_ref); - git_buf_dispose(&temp_path); + git_str_dispose(&temp_path); } void test_refs_rename__packed_doesnt_pack_others(void) { /* renaming a packed reference does not pack another reference which happens to be in both loose and pack state */ git_reference *looked_up_ref, *another_looked_up_ref, *renamed_ref; - git_buf temp_path = GIT_BUF_INIT; + git_str temp_path = GIT_STR_INIT; const char *brand_new_name = "refs/heads/brand_new_name"; /* Ensure the other reference exists on the file system */ - cl_git_pass(git_buf_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name)); + cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name)); cl_assert(git_path_exists(temp_path.ptr)); /* Lookup the other reference */ @@ -155,7 +155,7 @@ void test_refs_rename__packed_doesnt_pack_others(void) git_reference_free(renamed_ref); git_reference_free(another_looked_up_ref); - git_buf_dispose(&temp_path); + git_str_dispose(&temp_path); } void test_refs_rename__name_collision(void) diff --git a/tests/refs/revparse.c b/tests/refs/revparse.c index bc6e0a4c411..9c960702ae6 100644 --- a/tests/refs/revparse.c +++ b/tests/refs/revparse.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/revparse.h" -#include "buffer.h" #include "refs.h" #include "path.h" @@ -292,7 +291,7 @@ void test_refs_revparse__upstream(void) void test_refs_revparse__ordinal(void) { assert_invalid_single_spec("master@{-2}"); - + /* TODO: make the test below actually fail * cl_git_fail(git_revparse_single(&g_obj, g_repo, "master@{1a}")); */ @@ -326,19 +325,19 @@ void test_refs_revparse__previous_head(void) static void create_fake_stash_reference_and_reflog(git_repository *repo) { git_reference *master, *new_master; - git_buf log_path = GIT_BUF_INIT; + git_str log_path = GIT_STR_INIT; - git_buf_joinpath(&log_path, git_repository_path(repo), "logs/refs/fakestash"); + git_str_joinpath(&log_path, git_repository_path(repo), "logs/refs/fakestash"); - cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&log_path))); + cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&log_path))); cl_git_pass(git_reference_lookup(&master, repo, "refs/heads/master")); cl_git_pass(git_reference_rename(&new_master, master, "refs/fakestash", 0, NULL)); git_reference_free(master); - cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&log_path))); + cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&log_path))); - git_buf_dispose(&log_path); + git_str_dispose(&log_path); git_reference_free(new_master); } @@ -555,7 +554,7 @@ void test_refs_revparse__a_too_short_objectid_returns_EAMBIGUOUS(void) /* * $ echo "aabqhq" | git hash-object -t blob --stdin * dea509d0b3cb8ee0650f6ca210bc83f4678851ba - * + * * $ echo "aaazvc" | git hash-object -t blob --stdin * dea509d097ce692e167dfc6a48a7a280cc5e877e */ @@ -569,11 +568,11 @@ void test_refs_revparse__a_not_precise_enough_objectid_returns_EAMBIGUOUS(void) cl_git_mkfile("testrepo/one.txt", "aabqhq\n"); cl_git_mkfile("testrepo/two.txt", "aaazvc\n"); - + cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_add_bypath(index, "one.txt")); cl_git_pass(git_index_add_bypath(index, "two.txt")); - + cl_git_fail_with(git_revparse_single(&obj, repo, "dea509d0"), GIT_EAMBIGUOUS); cl_git_pass(git_revparse_single(&obj, repo, "dea509d09")); @@ -588,7 +587,7 @@ void test_refs_revparse__issue_994(void) git_repository *repo; git_reference *head, *with_at; git_object *target; - + repo = cl_git_sandbox_init("testrepo.git"); cl_assert_equal_i(GIT_ENOTFOUND, diff --git a/tests/remote/fetch.c b/tests/remote/fetch.c index 7e825ca16ca..209c42993b1 100644 --- a/tests/remote/fetch.c +++ b/tests/remote/fetch.c @@ -15,24 +15,24 @@ static char *NON_FORCE_FETCHSPEC = "refs/heads/main:refs/remotes/repo1/main"; void test_remote_fetch__initialize(void) { git_config *c; - git_buf repo1_path_buf = GIT_BUF_INIT; - git_buf repo2_path_buf = GIT_BUF_INIT; + git_str repo1_path_buf = GIT_STR_INIT; + git_str repo2_path_buf = GIT_STR_INIT; const char *sandbox = clar_sandbox_path(); - cl_git_pass(git_buf_joinpath(&repo1_path_buf, sandbox, "fetchtest_repo1")); - repo1_path = git_buf_detach(&repo1_path_buf); + cl_git_pass(git_str_joinpath(&repo1_path_buf, sandbox, "fetchtest_repo1")); + repo1_path = git_str_detach(&repo1_path_buf); cl_git_pass(git_repository_init(&repo1, repo1_path, true)); - cl_git_pass(git_buf_joinpath(&repo2_path_buf, sandbox, "fetchtest_repo2")); - repo2_path = git_buf_detach(&repo2_path_buf); + cl_git_pass(git_str_joinpath(&repo2_path_buf, sandbox, "fetchtest_repo2")); + repo2_path = git_str_detach(&repo2_path_buf); cl_git_pass(git_repository_init(&repo2, repo2_path, true)); cl_git_pass(git_repository_config(&c, repo1)); cl_git_pass(git_config_set_string(c, "user.email", "some@email")); cl_git_pass(git_config_set_string(c, "user.name", "some@name")); git_config_free(c); - git_buf_dispose(&repo1_path_buf); - git_buf_dispose(&repo2_path_buf); + git_str_dispose(&repo1_path_buf); + git_str_dispose(&repo2_path_buf); } void test_remote_fetch__cleanup(void) { diff --git a/tests/repo/config.c b/tests/repo/config.c index 6ca31f550a7..0b9daac98c7 100644 --- a/tests/repo/config.c +++ b/tests/repo/config.c @@ -3,7 +3,7 @@ #include "futils.h" #include -static git_buf path = GIT_BUF_INIT; +static git_str path = GIT_STR_INIT; void test_repo_config__initialize(void) { @@ -11,7 +11,7 @@ void test_repo_config__initialize(void) cl_git_pass(cl_rename( "empty_standard_repo/.gitted", "empty_standard_repo/.git")); - git_buf_clear(&path); + git_str_clear(&path); cl_must_pass(p_mkdir("alternate", 0777)); cl_git_pass(git_path_prettify(&path, "alternate", NULL)); @@ -21,7 +21,7 @@ void test_repo_config__cleanup(void) { cl_sandbox_set_search_path_defaults(); - git_buf_dispose(&path); + git_str_dispose(&path); cl_git_pass( git_futils_rmdir_r("alternate", NULL, GIT_RMDIR_REMOVE_FILES)); @@ -60,7 +60,7 @@ void test_repo_config__can_open_missing_global_with_separators(void) git_repository *repo; git_config *config, *global; - cl_git_pass(git_buf_printf( + cl_git_pass(git_str_printf( &path, "%c%s", GIT_PATH_LIST_SEPARATOR, "dummy")); cl_git_pass(git_libgit2_opts( @@ -70,7 +70,7 @@ void test_repo_config__can_open_missing_global_with_separators(void) cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr)); - git_buf_dispose(&path); + git_str_dispose(&path); cl_git_pass(git_repository_open(&repo, "empty_standard_repo")); cl_git_pass(git_repository_config(&config, repo)); @@ -115,7 +115,7 @@ void test_repo_config__read_with_no_configs_at_all(void) cl_sandbox_set_search_path_defaults(); cl_must_pass(p_mkdir("alternate/1", 0777)); - cl_git_pass(git_buf_joinpath(&path, path.ptr, "1")); + cl_git_pass(git_str_joinpath(&path, path.ptr, "1")); cl_git_rewritefile("alternate/1/gitconfig", "[core]\n\tabbrev = 10\n"); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr)); diff --git a/tests/repo/discover.c b/tests/repo/discover.c index c026eefc310..2a24f1b2928 100644 --- a/tests/repo/discover.c +++ b/tests/repo/discover.c @@ -28,16 +28,17 @@ static void ensure_repository_discover(const char *start_path, const char *ceiling_dirs, const char *expected_path) { - git_buf found_path = GIT_BUF_INIT, resolved = GIT_BUF_INIT; + git_buf found_path = GIT_BUF_INIT; + git_str resolved = GIT_STR_INIT; - git_buf_attach(&resolved, p_realpath(expected_path, NULL), 0); + git_str_attach(&resolved, p_realpath(expected_path, NULL), 0); cl_assert(resolved.size > 0); cl_git_pass(git_path_to_dir(&resolved)); cl_git_pass(git_repository_discover(&found_path, start_path, 1, ceiling_dirs)); cl_assert_equal_s(found_path.ptr, resolved.ptr); - git_buf_dispose(&resolved); + git_str_dispose(&resolved); git_buf_dispose(&found_path); } @@ -59,24 +60,24 @@ static void write_file(const char *path, const char *content) } /*no check is performed on ceiling_dirs length, so be sure it's long enough */ -static void append_ceiling_dir(git_buf *ceiling_dirs, const char *path) +static void append_ceiling_dir(git_str *ceiling_dirs, const char *path) { - git_buf pretty_path = GIT_BUF_INIT; + git_str pretty_path = GIT_STR_INIT; char ceiling_separator[2] = { GIT_PATH_LIST_SEPARATOR, '\0' }; cl_git_pass(git_path_prettify_dir(&pretty_path, path, NULL)); if (ceiling_dirs->size > 0) - git_buf_puts(ceiling_dirs, ceiling_separator); + git_str_puts(ceiling_dirs, ceiling_separator); - git_buf_puts(ceiling_dirs, pretty_path.ptr); + git_str_puts(ceiling_dirs, pretty_path.ptr); - git_buf_dispose(&pretty_path); - cl_assert(git_buf_oom(ceiling_dirs) == 0); + git_str_dispose(&pretty_path); + cl_assert(git_str_oom(ceiling_dirs) == 0); } static git_buf discovered; -static git_buf ceiling_dirs; +static git_str ceiling_dirs; void test_repo_discover__initialize(void) { @@ -84,8 +85,7 @@ void test_repo_discover__initialize(void) const mode_t mode = 0777; git_futils_mkdir_r(DISCOVER_FOLDER, mode); - git_buf_init(&discovered, 0); - git_buf_init(&ceiling_dirs, 0); + git_str_init(&ceiling_dirs, 0); append_ceiling_dir(&ceiling_dirs, TEMP_REPO_FOLDER); cl_git_pass(git_repository_init(&repo, DISCOVER_FOLDER, 1)); @@ -115,7 +115,7 @@ void test_repo_discover__initialize(void) void test_repo_discover__cleanup(void) { git_buf_dispose(&discovered); - git_buf_dispose(&ceiling_dirs); + git_str_dispose(&ceiling_dirs); cl_git_pass(git_futils_rmdir_r(TEMP_REPO_FOLDER, NULL, GIT_RMDIR_REMOVE_FILES)); } diff --git a/tests/repo/env.c b/tests/repo/env.c index 43defc168a3..4bd45d1a632 100644 --- a/tests/repo/env.c +++ b/tests/repo/env.c @@ -38,14 +38,14 @@ static int GIT_FORMAT_PRINTF(2, 3) cl_setenv_printf(const char *name, const char { int ret; va_list args; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; va_start(args, fmt); - cl_git_pass(git_buf_vprintf(&buf, fmt, args)); + cl_git_pass(git_str_vprintf(&buf, fmt, args)); va_end(args); - ret = cl_setenv(name, git_buf_cstr(&buf)); - git_buf_dispose(&buf); + ret = cl_setenv(name, git_str_cstr(&buf)); + git_str_dispose(&buf); return ret; } @@ -80,12 +80,12 @@ static void env_cd_( void (*passfail_)(const char *, const char *, const char *, int), const char *file, const char *func, int line) { - git_buf cwd_buf = GIT_BUF_INIT; + git_str cwd_buf = GIT_STR_INIT; cl_git_pass(git_path_prettify_dir(&cwd_buf, ".", NULL)); cl_must_pass(p_chdir(path)); passfail_(NULL, file, func, line); - cl_must_pass(p_chdir(git_buf_cstr(&cwd_buf))); - git_buf_dispose(&cwd_buf); + cl_must_pass(p_chdir(git_str_cstr(&cwd_buf))); + git_str_dispose(&cwd_buf); } #define env_cd_pass(path) env_cd_((path), env_pass_, __FILE__, __func__, __LINE__) #define env_cd_fail(path) env_cd_((path), env_fail_, __FILE__, __func__, __LINE__) @@ -128,7 +128,7 @@ static void env_check_objects_(bool a, bool t, bool p, const char *file, const c void test_repo_env__open(void) { git_repository *repo = NULL; - git_buf repo_dir_buf = GIT_BUF_INIT; + git_str repo_dir_buf = GIT_STR_INIT; const char *repo_dir = NULL; git_index *index = NULL; const char *t_obj = "testrepo.git/objects"; @@ -142,7 +142,7 @@ void test_repo_env__open(void) cl_git_pass(p_rename("attr/.gitted", "attr/.git")); cl_git_pass(git_path_prettify_dir(&repo_dir_buf, "attr", NULL)); - repo_dir = git_buf_cstr(&repo_dir_buf); + repo_dir = git_str_cstr(&repo_dir_buf); /* GIT_DIR that doesn't exist */ cl_setenv("GIT_DIR", "does-not-exist"); @@ -271,7 +271,7 @@ void test_repo_env__open(void) cl_fixture_cleanup("testrepo.git"); cl_fixture_cleanup("attr"); - git_buf_dispose(&repo_dir_buf); + git_str_dispose(&repo_dir_buf); clear_git_env(); } diff --git a/tests/repo/hashfile.c b/tests/repo/hashfile.c index bffb51bb56b..e23bb77f98a 100644 --- a/tests/repo/hashfile.c +++ b/tests/repo/hashfile.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" static git_repository *_repo; @@ -18,14 +17,14 @@ void test_repo_hashfile__cleanup(void) void test_repo_hashfile__simple(void) { git_oid a, b; - git_buf full = GIT_BUF_INIT; + git_str full = GIT_STR_INIT; /* hash with repo relative path */ cl_git_pass(git_odb_hashfile(&a, "status/current_file", GIT_OBJECT_BLOB)); cl_git_pass(git_repository_hashfile(&b, _repo, "current_file", GIT_OBJECT_BLOB, NULL)); cl_assert_equal_oid(&a, &b); - cl_git_pass(git_buf_joinpath(&full, git_repository_workdir(_repo), "current_file")); + cl_git_pass(git_str_joinpath(&full, git_repository_workdir(_repo), "current_file")); /* hash with full path */ cl_git_pass(git_odb_hashfile(&a, full.ptr, GIT_OBJECT_BLOB)); @@ -36,20 +35,20 @@ void test_repo_hashfile__simple(void) cl_git_fail(git_odb_hashfile(&a, full.ptr, GIT_OBJECT_ANY)); cl_git_fail(git_repository_hashfile(&b, _repo, full.ptr, GIT_OBJECT_OFS_DELTA, NULL)); - git_buf_dispose(&full); + git_str_dispose(&full); } void test_repo_hashfile__filtered_in_workdir(void) { - git_buf root = GIT_BUF_INIT, txt = GIT_BUF_INIT, bin = GIT_BUF_INIT; + git_str root = GIT_STR_INIT, txt = GIT_STR_INIT, bin = GIT_STR_INIT; char cwd[GIT_PATH_MAX]; git_oid a, b; cl_must_pass(p_getcwd(cwd, GIT_PATH_MAX)); cl_must_pass(p_mkdir("absolute", 0777)); - cl_git_pass(git_buf_joinpath(&root, cwd, "status")); - cl_git_pass(git_buf_joinpath(&txt, root.ptr, "testfile.txt")); - cl_git_pass(git_buf_joinpath(&bin, root.ptr, "testfile.bin")); + cl_git_pass(git_str_joinpath(&root, cwd, "status")); + cl_git_pass(git_str_joinpath(&txt, root.ptr, "testfile.txt")); + cl_git_pass(git_str_joinpath(&bin, root.ptr, "testfile.bin")); cl_repo_set_bool(_repo, "core.autocrlf", true); @@ -120,22 +119,22 @@ void test_repo_hashfile__filtered_in_workdir(void) cl_git_fail(git_odb_hashfile(&a, "status/testfile.txt", 0)); cl_git_fail(git_repository_hashfile(&b, _repo, "testfile.txt", GIT_OBJECT_ANY, NULL)); - git_buf_dispose(&txt); - git_buf_dispose(&bin); - git_buf_dispose(&root); + git_str_dispose(&txt); + git_str_dispose(&bin); + git_str_dispose(&root); } void test_repo_hashfile__filtered_outside_workdir(void) { - git_buf root = GIT_BUF_INIT, txt = GIT_BUF_INIT, bin = GIT_BUF_INIT; + git_str root = GIT_STR_INIT, txt = GIT_STR_INIT, bin = GIT_STR_INIT; char cwd[GIT_PATH_MAX]; git_oid a, b; cl_must_pass(p_getcwd(cwd, GIT_PATH_MAX)); cl_must_pass(p_mkdir("absolute", 0777)); - cl_git_pass(git_buf_joinpath(&root, cwd, "absolute")); - cl_git_pass(git_buf_joinpath(&txt, root.ptr, "testfile.txt")); - cl_git_pass(git_buf_joinpath(&bin, root.ptr, "testfile.bin")); + cl_git_pass(git_str_joinpath(&root, cwd, "absolute")); + cl_git_pass(git_str_joinpath(&txt, root.ptr, "testfile.txt")); + cl_git_pass(git_str_joinpath(&bin, root.ptr, "testfile.bin")); cl_repo_set_bool(_repo, "core.autocrlf", true); cl_git_append2file("status/.gitattributes", "*.txt text\n*.bin binary\n\n"); @@ -166,7 +165,7 @@ void test_repo_hashfile__filtered_outside_workdir(void) cl_git_pass(git_repository_hashfile(&b, _repo, bin.ptr, GIT_OBJECT_BLOB, NULL)); cl_assert_equal_oid(&a, &b); - git_buf_dispose(&txt); - git_buf_dispose(&bin); - git_buf_dispose(&root); + git_str_dispose(&txt); + git_str_dispose(&bin); + git_str_dispose(&root); } diff --git a/tests/repo/init.c b/tests/repo/init.c index 1aa326f7f01..b41608cca6c 100644 --- a/tests/repo/init.c +++ b/tests/repo/init.c @@ -12,7 +12,7 @@ enum repo_mode { }; static git_repository *g_repo = NULL; -static git_buf g_global_path = GIT_BUF_INIT; +static git_str g_global_path = GIT_STR_INIT; void test_repo_init__initialize(void) { @@ -26,7 +26,7 @@ void test_repo_init__cleanup(void) { git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, g_global_path.ptr); - git_buf_dispose(&g_global_path); + git_str_dispose(&g_global_path); cl_fixture_cleanup("tmp_global_path"); } @@ -100,16 +100,16 @@ void test_repo_init__bare_repo_noslash(void) void test_repo_init__bare_repo_escaping_current_workdir(void) { - git_buf path_repository = GIT_BUF_INIT; - git_buf path_current_workdir = GIT_BUF_INIT; + git_str path_repository = GIT_STR_INIT; + git_str path_current_workdir = GIT_STR_INIT; cl_git_pass(git_path_prettify_dir(&path_current_workdir, ".", NULL)); - cl_git_pass(git_buf_joinpath(&path_repository, git_buf_cstr(&path_current_workdir), "a/b/c")); - cl_git_pass(git_futils_mkdir_r(git_buf_cstr(&path_repository), GIT_DIR_MODE)); + cl_git_pass(git_str_joinpath(&path_repository, git_str_cstr(&path_current_workdir), "a/b/c")); + cl_git_pass(git_futils_mkdir_r(git_str_cstr(&path_repository), GIT_DIR_MODE)); /* Change the current working directory */ - cl_git_pass(chdir(git_buf_cstr(&path_repository))); + cl_git_pass(chdir(git_str_cstr(&path_repository))); /* Initialize a bare repo with a relative path escaping out of the current working directory */ cl_git_pass(git_repository_init(&g_repo, "../d/e.git", 1)); @@ -121,10 +121,10 @@ void test_repo_init__bare_repo_escaping_current_workdir(void) /* Open a bare repo with a relative path escaping out of the current working directory */ cl_git_pass(git_repository_open(&g_repo, "../d/e.git")); - cl_git_pass(chdir(git_buf_cstr(&path_current_workdir))); + cl_git_pass(chdir(git_str_cstr(&path_current_workdir))); - git_buf_dispose(&path_current_workdir); - git_buf_dispose(&path_repository); + git_str_dispose(&path_current_workdir); + git_str_dispose(&path_repository); cleanup_repository("a"); } @@ -168,26 +168,26 @@ void test_repo_init__reinit_too_recent_bare_repo(void) void test_repo_init__additional_templates(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_set_cleanup(&cleanup_repository, "tester"); ensure_repository_init("tester", 0, "tester/.git/", "tester/"); cl_git_pass( - git_buf_joinpath(&path, git_repository_path(g_repo), "description")); - cl_assert(git_path_isfile(git_buf_cstr(&path))); + git_str_joinpath(&path, git_repository_path(g_repo), "description")); + cl_assert(git_path_isfile(git_str_cstr(&path))); cl_git_pass( - git_buf_joinpath(&path, git_repository_path(g_repo), "info/exclude")); - cl_assert(git_path_isfile(git_buf_cstr(&path))); + git_str_joinpath(&path, git_repository_path(g_repo), "info/exclude")); + cl_assert(git_path_isfile(git_str_cstr(&path))); cl_git_pass( - git_buf_joinpath(&path, git_repository_path(g_repo), "hooks")); - cl_assert(git_path_isdir(git_buf_cstr(&path))); + git_str_joinpath(&path, git_repository_path(g_repo), "hooks")); + cl_assert(git_path_isdir(git_str_cstr(&path))); /* won't confirm specific contents of hooks dir since it may vary */ - git_buf_dispose(&path); + git_str_dispose(&path); } static void assert_config_entry_on_init_bytype( @@ -447,7 +447,7 @@ void test_repo_init__extended_1(void) void test_repo_init__relative_gitdir(void) { git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; - git_buf dot_git_content = GIT_BUF_INIT; + git_str dot_git_content = GIT_STR_INIT; opts.workdir_path = "../c_wd"; opts.flags = @@ -472,18 +472,18 @@ void test_repo_init__relative_gitdir(void) cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git")); cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content.ptr); - git_buf_dispose(&dot_git_content); + git_str_dispose(&dot_git_content); cleanup_repository("root"); } void test_repo_init__relative_gitdir_2(void) { git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; - git_buf dot_git_content = GIT_BUF_INIT; - git_buf full_path = GIT_BUF_INIT; + git_str dot_git_content = GIT_STR_INIT; + git_str full_path = GIT_STR_INIT; cl_git_pass(git_path_prettify(&full_path, ".", NULL)); - cl_git_pass(git_buf_joinpath(&full_path, full_path.ptr, "root/b/c_wd")); + cl_git_pass(git_str_joinpath(&full_path, full_path.ptr, "root/b/c_wd")); opts.workdir_path = full_path.ptr; opts.flags = @@ -493,7 +493,7 @@ void test_repo_init__relative_gitdir_2(void) /* make the directory first, then it should succeed */ cl_git_pass(git_repository_init_ext(&g_repo, "root/b/my_repository", &opts)); - git_buf_dispose(&full_path); + git_str_dispose(&full_path); cl_assert(!git__suffixcmp(git_repository_workdir(g_repo), "root/b/c_wd/")); cl_assert(!git__suffixcmp(git_repository_path(g_repo), "root/b/my_repository/")); @@ -509,7 +509,7 @@ void test_repo_init__relative_gitdir_2(void) cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git")); cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content.ptr); - git_buf_dispose(&dot_git_content); + git_str_dispose(&dot_git_content); cleanup_repository("root"); } @@ -598,7 +598,7 @@ void test_repo_init__at_filesystem_root(void) { git_repository *repo; const char *sandbox = clar_sandbox_path(); - git_buf root = GIT_BUF_INIT; + git_str root = GIT_STR_INIT; int root_len; if (!cl_is_env_set("GITTEST_INVASIVE_FS_STRUCTURE")) @@ -607,8 +607,8 @@ void test_repo_init__at_filesystem_root(void) root_len = git_path_root(sandbox); cl_assert(root_len >= 0); - git_buf_put(&root, sandbox, root_len+1); - git_buf_joinpath(&root, root.ptr, "libgit2_test_dir"); + git_str_put(&root, sandbox, root_len+1); + git_str_joinpath(&root, root.ptr, "libgit2_test_dir"); cl_assert(!git_path_exists(root.ptr)); @@ -616,7 +616,7 @@ void test_repo_init__at_filesystem_root(void) cl_assert(git_path_isdir(root.ptr)); cl_git_pass(git_futils_rmdir_r(root.ptr, NULL, GIT_RMDIR_REMOVE_FILES)); - git_buf_dispose(&root); + git_str_dispose(&root); git_repository_free(repo); } @@ -710,29 +710,29 @@ void test_repo_init__longpath(void) #ifdef GIT_WIN32 size_t padding = CONST_STRLEN("objects/pack/pack-.pack.lock") + GIT_OID_HEXSZ; size_t max, i; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_repository *one = NULL, *two = NULL; /* * Files within repositories need to fit within MAX_PATH; * that means a repo path must be at most (MAX_PATH - 18). */ - cl_git_pass(git_buf_puts(&path, clar_sandbox_path())); - cl_git_pass(git_buf_putc(&path, '/')); + cl_git_pass(git_str_puts(&path, clar_sandbox_path())); + cl_git_pass(git_str_putc(&path, '/')); max = ((MAX_PATH) - path.size) - padding; for (i = 0; i < max - 1; i++) - cl_git_pass(git_buf_putc(&path, 'a')); + cl_git_pass(git_str_putc(&path, 'a')); cl_git_pass(git_repository_init(&one, path.ptr, 1)); /* Paths longer than this are rejected */ - cl_git_pass(git_buf_putc(&path, 'z')); + cl_git_pass(git_str_putc(&path, 'z')); cl_git_fail(git_repository_init(&two, path.ptr, 1)); git_repository_free(one); git_repository_free(two); - git_buf_dispose(&path); + git_str_dispose(&path); #endif } diff --git a/tests/repo/message.c b/tests/repo/message.c index 14577c8f0e8..6241f48f95f 100644 --- a/tests/repo/message.c +++ b/tests/repo/message.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "refs.h" #include "posix.h" @@ -23,17 +22,18 @@ void test_repo_message__none(void) void test_repo_message__message(void) { - git_buf path = GIT_BUF_INIT, actual = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; + git_buf actual = GIT_BUF_INIT; const char expected[] = "Test\n\nThis is a test of the emergency broadcast system\n"; - cl_git_pass(git_buf_joinpath(&path, git_repository_path(_repo), "MERGE_MSG")); - cl_git_mkfile(git_buf_cstr(&path), expected); + cl_git_pass(git_str_joinpath(&path, git_repository_path(_repo), "MERGE_MSG")); + cl_git_mkfile(git_str_cstr(&path), expected); cl_git_pass(git_repository_message(&actual, _repo)); - cl_assert_equal_s(expected, git_buf_cstr(&actual)); + cl_assert_equal_s(expected, actual.ptr); git_buf_dispose(&actual); - cl_git_pass(p_unlink(git_buf_cstr(&path))); + cl_git_pass(p_unlink(git_str_cstr(&path))); cl_assert_equal_i(GIT_ENOTFOUND, git_repository_message(&actual, _repo)); - git_buf_dispose(&path); + git_str_dispose(&path); } diff --git a/tests/repo/open.c b/tests/repo/open.c index bd60c12c29b..6558805c886 100644 --- a/tests/repo/open.c +++ b/tests/repo/open.c @@ -105,12 +105,12 @@ void test_repo_open__check_if_repository(void) static void make_gitlink_dir(const char *dir, const char *linktext) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_git_pass(git_futils_mkdir(dir, 0777, GIT_MKDIR_VERIFY_DIR)); - cl_git_pass(git_buf_joinpath(&path, dir, ".git")); + cl_git_pass(git_str_joinpath(&path, dir, ".git")); cl_git_rewritefile(path.ptr, linktext); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_repo_open__gitlinked(void) @@ -136,7 +136,7 @@ void test_repo_open__gitlinked(void) void test_repo_open__with_symlinked_config(void) { #ifndef GIT_WIN32 - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_repository *repo; git_config *cfg; int32_t value; @@ -157,9 +157,9 @@ void test_repo_open__with_symlinked_config(void) git_config_free(cfg); git_repository_free(repo); - cl_git_pass(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES)); + cl_git_pass(git_futils_rmdir_r(git_str_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES)); cl_sandbox_set_search_path_defaults(); - git_buf_dispose(&path); + git_str_dispose(&path); #endif } @@ -173,7 +173,7 @@ void test_repo_open__from_git_new_workdir(void) */ git_repository *repo2; - git_buf link_tgt = GIT_BUF_INIT, link = GIT_BUF_INIT, body = GIT_BUF_INIT; + git_str link_tgt = GIT_STR_INIT, link = GIT_STR_INIT, body = GIT_STR_INIT; const char **scan; int link_fd; static const char *links[] = { @@ -190,19 +190,19 @@ void test_repo_open__from_git_new_workdir(void) cl_git_pass(p_mkdir("alternate/.git", 0777)); for (scan = links; *scan != NULL; scan++) { - git_buf_joinpath(&link_tgt, "empty_standard_repo/.git", *scan); + git_str_joinpath(&link_tgt, "empty_standard_repo/.git", *scan); if (git_path_exists(link_tgt.ptr)) { - git_buf_joinpath(&link_tgt, "../../empty_standard_repo/.git", *scan); - git_buf_joinpath(&link, "alternate/.git", *scan); + git_str_joinpath(&link_tgt, "../../empty_standard_repo/.git", *scan); + git_str_joinpath(&link, "alternate/.git", *scan); if (strchr(*scan, '/')) git_futils_mkpath2file(link.ptr, 0777); cl_assert_(symlink(link_tgt.ptr, link.ptr) == 0, strerror(errno)); } } for (scan = copies; *scan != NULL; scan++) { - git_buf_joinpath(&link_tgt, "empty_standard_repo/.git", *scan); + git_str_joinpath(&link_tgt, "empty_standard_repo/.git", *scan); if (git_path_exists(link_tgt.ptr)) { - git_buf_joinpath(&link, "alternate/.git", *scan); + git_str_joinpath(&link, "alternate/.git", *scan); cl_git_pass(git_futils_readbuffer(&body, link_tgt.ptr)); cl_assert((link_fd = git_futils_creat_withpath(link.ptr, 0777, 0666)) >= 0); @@ -211,9 +211,9 @@ void test_repo_open__from_git_new_workdir(void) } } - git_buf_dispose(&link_tgt); - git_buf_dispose(&link); - git_buf_dispose(&body); + git_str_dispose(&link_tgt); + git_str_dispose(&link); + git_str_dispose(&body); cl_git_pass(git_repository_open(&repo2, "alternate")); @@ -233,10 +233,10 @@ void test_repo_open__from_git_new_workdir(void) void test_repo_open__failures(void) { git_repository *base, *repo; - git_buf ceiling = GIT_BUF_INIT; + git_str ceiling = GIT_STR_INIT; base = cl_git_sandbox_init("attr"); - cl_git_pass(git_buf_sets(&ceiling, git_repository_workdir(base))); + cl_git_pass(git_str_sets(&ceiling, git_repository_workdir(base))); /* fail with no searching */ cl_git_fail(git_repository_open(&repo, "attr/sub")); @@ -245,7 +245,7 @@ void test_repo_open__failures(void) /* fail with ceiling too low */ cl_git_fail(git_repository_open_ext(&repo, "attr/sub", 0, ceiling.ptr)); - cl_git_pass(git_buf_joinpath(&ceiling, ceiling.ptr, "sub")); + cl_git_pass(git_str_joinpath(&ceiling, ceiling.ptr, "sub")); cl_git_fail(git_repository_open_ext(&repo, "attr/sub/sub", 0, ceiling.ptr)); /* fail with no repo */ @@ -260,7 +260,7 @@ void test_repo_open__failures(void) GIT_REPOSITORY_OPEN_NO_SEARCH | GIT_REPOSITORY_OPEN_NO_DOTGIT, NULL)); - git_buf_dispose(&ceiling); + git_str_dispose(&ceiling); } void test_repo_open__bad_gitlinks(void) @@ -291,7 +291,7 @@ void test_repo_open__bad_gitlinks(void) } #ifdef GIT_WIN32 -static void unposix_path(git_buf *path) +static void unposix_path(git_str *path) { char *src, *tgt; @@ -318,44 +318,44 @@ void test_repo_open__win32_path(void) { #ifdef GIT_WIN32 git_repository *repo = cl_git_sandbox_init("empty_standard_repo"), *repo2; - git_buf winpath = GIT_BUF_INIT; + git_str winpath = GIT_STR_INIT; static const char *repo_path = "empty_standard_repo/.git/"; static const char *repo_wd = "empty_standard_repo/"; cl_assert(git__suffixcmp(git_repository_path(repo), repo_path) == 0); cl_assert(git__suffixcmp(git_repository_workdir(repo), repo_wd) == 0); - cl_git_pass(git_buf_sets(&winpath, git_repository_path(repo))); + cl_git_pass(git_str_sets(&winpath, git_repository_path(repo))); unposix_path(&winpath); cl_git_pass(git_repository_open(&repo2, winpath.ptr)); cl_assert(git__suffixcmp(git_repository_path(repo2), repo_path) == 0); cl_assert(git__suffixcmp(git_repository_workdir(repo2), repo_wd) == 0); git_repository_free(repo2); - cl_git_pass(git_buf_sets(&winpath, git_repository_path(repo))); - git_buf_truncate(&winpath, winpath.size - 1); /* remove trailing '/' */ + cl_git_pass(git_str_sets(&winpath, git_repository_path(repo))); + git_str_truncate(&winpath, winpath.size - 1); /* remove trailing '/' */ unposix_path(&winpath); cl_git_pass(git_repository_open(&repo2, winpath.ptr)); cl_assert(git__suffixcmp(git_repository_path(repo2), repo_path) == 0); cl_assert(git__suffixcmp(git_repository_workdir(repo2), repo_wd) == 0); git_repository_free(repo2); - cl_git_pass(git_buf_sets(&winpath, git_repository_workdir(repo))); + cl_git_pass(git_str_sets(&winpath, git_repository_workdir(repo))); unposix_path(&winpath); cl_git_pass(git_repository_open(&repo2, winpath.ptr)); cl_assert(git__suffixcmp(git_repository_path(repo2), repo_path) == 0); cl_assert(git__suffixcmp(git_repository_workdir(repo2), repo_wd) == 0); git_repository_free(repo2); - cl_git_pass(git_buf_sets(&winpath, git_repository_workdir(repo))); - git_buf_truncate(&winpath, winpath.size - 1); /* remove trailing '/' */ + cl_git_pass(git_str_sets(&winpath, git_repository_workdir(repo))); + git_str_truncate(&winpath, winpath.size - 1); /* remove trailing '/' */ unposix_path(&winpath); cl_git_pass(git_repository_open(&repo2, winpath.ptr)); cl_assert(git__suffixcmp(git_repository_path(repo2), repo_path) == 0); cl_assert(git__suffixcmp(git_repository_workdir(repo2), repo_wd) == 0); git_repository_free(repo2); - git_buf_dispose(&winpath); + git_str_dispose(&winpath); #endif } @@ -367,7 +367,7 @@ void test_repo_open__opening_a_non_existing_repository_returns_ENOTFOUND(void) void test_repo_open__no_config(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_repository *repo; git_config *config; @@ -389,7 +389,7 @@ void test_repo_open__no_config(void) cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr)); - git_buf_dispose(&path); + git_str_dispose(&path); cl_git_pass(git_repository_open(&repo, "empty_standard_repo")); cl_git_pass(git_repository_config(&config, repo)); diff --git a/tests/repo/repo_helpers.c b/tests/repo/repo_helpers.c index b22f3f6bac4..1efde70a50d 100644 --- a/tests/repo/repo_helpers.c +++ b/tests/repo/repo_helpers.c @@ -13,25 +13,25 @@ void make_head_unborn(git_repository* repo, const char *target) void delete_head(git_repository* repo) { - git_buf head_path = GIT_BUF_INIT; + git_str head_path = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&head_path, git_repository_path(repo), GIT_HEAD_FILE)); - cl_git_pass(p_unlink(git_buf_cstr(&head_path))); + cl_git_pass(git_str_joinpath(&head_path, git_repository_path(repo), GIT_HEAD_FILE)); + cl_git_pass(p_unlink(git_str_cstr(&head_path))); - git_buf_dispose(&head_path); + git_str_dispose(&head_path); } void create_tmp_global_config(const char *dirname, const char *key, const char *val) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_config *config; cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, dirname)); cl_must_pass(p_mkdir(dirname, 0777)); - cl_git_pass(git_buf_joinpath(&path, dirname, ".gitconfig")); + cl_git_pass(git_str_joinpath(&path, dirname, ".gitconfig")); cl_git_pass(git_config_open_ondisk(&config, path.ptr)); cl_git_pass(git_config_set_string(config, key, val)); git_config_free(config); - git_buf_dispose(&path); + git_str_dispose(&path); } diff --git a/tests/repo/reservedname.c b/tests/repo/reservedname.c index 8e024bcbb72..245d8625ac7 100644 --- a/tests/repo/reservedname.c +++ b/tests/repo/reservedname.c @@ -10,7 +10,7 @@ void test_repo_reservedname__cleanup(void) void test_repo_reservedname__includes_shortname_on_win32(void) { git_repository *repo; - git_buf *reserved; + git_str *reserved; size_t reserved_len; repo = cl_git_sandbox_init("nasty"); @@ -29,7 +29,7 @@ void test_repo_reservedname__includes_shortname_on_win32(void) void test_repo_reservedname__includes_shortname_when_requested(void) { git_repository *repo; - git_buf *reserved; + git_str *reserved; size_t reserved_len; repo = cl_git_sandbox_init("nasty"); @@ -47,7 +47,7 @@ void test_repo_reservedname__custom_shortname_recognized(void) { #ifdef GIT_WIN32 git_repository *repo; - git_buf *reserved; + git_str *reserved; size_t reserved_len; if (!cl_sandbox_supports_8dot3()) @@ -83,7 +83,7 @@ void test_repo_reservedname__submodule_pointer(void) #ifdef GIT_WIN32 git_repository *super_repo, *sub_repo; git_submodule *sub; - git_buf *sub_reserved; + git_str *sub_reserved; size_t sub_reserved_len; if (!cl_sandbox_supports_8dot3()) @@ -117,16 +117,16 @@ void test_repo_reservedname__submodule_pointer_during_create(void) git_repository *repo; git_submodule *sm; git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT; - git_buf url = GIT_BUF_INIT; + git_str url = GIT_STR_INIT; repo = setup_fixture_super(); - cl_git_pass(git_buf_joinpath(&url, clar_sandbox_path(), "sub.git")); + cl_git_pass(git_str_joinpath(&url, clar_sandbox_path(), "sub.git")); cl_repo_set_string(repo, "submodule.sub.url", url.ptr); cl_git_pass(git_submodule_lookup(&sm, repo, "sub")); cl_git_pass(git_submodule_update(sm, 1, &update_options)); git_submodule_free(sm); - git_buf_dispose(&url); + git_str_dispose(&url); } diff --git a/tests/repo/setters.c b/tests/repo/setters.c index 1fac627f66b..2c33db0dbf8 100644 --- a/tests/repo/setters.c +++ b/tests/repo/setters.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "git2/sys/repository.h" -#include "buffer.h" #include "posix.h" #include "util.h" #include "path.h" @@ -47,20 +46,20 @@ void test_repo_setters__setting_a_workdir_creates_a_gitlink(void) { git_config *cfg; git_buf buf = GIT_BUF_INIT; - git_buf content = GIT_BUF_INIT; + git_str content = GIT_STR_INIT; cl_git_pass(git_repository_set_workdir(repo, "./new_workdir", true)); cl_assert(git_path_isfile("./new_workdir/.git")); cl_git_pass(git_futils_readbuffer(&content, "./new_workdir/.git")); - cl_assert(git__prefixcmp(git_buf_cstr(&content), "gitdir: ") == 0); - cl_assert(git__suffixcmp(git_buf_cstr(&content), "testrepo.git/") == 0); - git_buf_dispose(&content); + cl_assert(git__prefixcmp(git_str_cstr(&content), "gitdir: ") == 0); + cl_assert(git__suffixcmp(git_str_cstr(&content), "testrepo.git/") == 0); + git_str_dispose(&content); cl_git_pass(git_repository_config(&cfg, repo)); cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.worktree")); - cl_assert(git__suffixcmp(git_buf_cstr(&buf), "new_workdir/") == 0); + cl_assert(git__suffixcmp(buf.ptr, "new_workdir/") == 0); git_buf_dispose(&buf); git_config_free(cfg); @@ -81,7 +80,7 @@ void test_repo_setters__setting_a_new_index_on_a_repo_which_has_already_loaded_o git_index_free(new_index); - /* + /* * Ensure the cleanup method won't try to free the repo as it's already been taken care of */ repo = NULL; @@ -102,7 +101,7 @@ void test_repo_setters__setting_a_new_odb_on_a_repo_which_already_loaded_one_pro git_odb_free(new_odb); - /* + /* * Ensure the cleanup method won't try to free the repo as it's already been taken care of */ repo = NULL; diff --git a/tests/repo/state.c b/tests/repo/state.c index afb361787fb..92b272dcee9 100644 --- a/tests/repo/state.c +++ b/tests/repo/state.c @@ -1,11 +1,10 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "refs.h" #include "posix.h" #include "futils.h" static git_repository *_repo; -static git_buf _path; +static git_str _path; void test_repo_state__initialize(void) { @@ -15,14 +14,14 @@ void test_repo_state__initialize(void) void test_repo_state__cleanup(void) { cl_git_sandbox_cleanup(); - git_buf_dispose(&_path); + git_str_dispose(&_path); } static void setup_simple_state(const char *filename) { - cl_git_pass(git_buf_joinpath(&_path, git_repository_path(_repo), filename)); - git_futils_mkpath2file(git_buf_cstr(&_path), 0777); - cl_git_mkfile(git_buf_cstr(&_path), "dummy"); + cl_git_pass(git_str_joinpath(&_path, git_repository_path(_repo), filename)); + git_futils_mkpath2file(git_str_cstr(&_path), 0777); + cl_git_mkfile(git_str_cstr(&_path), "dummy"); } static void assert_repo_state(git_repository_state_t state) diff --git a/tests/repo/template.c b/tests/repo/template.c index 3513190ac20..6f369c6d6e7 100644 --- a/tests/repo/template.c +++ b/tests/repo/template.c @@ -7,7 +7,7 @@ static git_repository *_repo = NULL; static mode_t g_umask = 0; -static git_buf _global_path = GIT_BUF_INIT; +static git_str _global_path = GIT_STR_INIT; static const char *fixture_repo; static const char *fixture_templates; @@ -27,7 +27,7 @@ void test_repo_template__cleanup(void) { git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, _global_path.ptr); - git_buf_dispose(&_global_path); + git_str_dispose(&_global_path); cl_fixture_cleanup("tmp_global_path"); @@ -51,14 +51,14 @@ static void assert_hooks_match( const char *hook_path, bool core_filemode) { - git_buf expected = GIT_BUF_INIT; - git_buf actual = GIT_BUF_INIT; + git_str expected = GIT_STR_INIT; + git_str actual = GIT_STR_INIT; struct stat expected_st, st; - cl_git_pass(git_buf_joinpath(&expected, template_dir, hook_path)); + cl_git_pass(git_str_joinpath(&expected, template_dir, hook_path)); cl_git_pass(git_path_lstat(expected.ptr, &expected_st)); - cl_git_pass(git_buf_joinpath(&actual, repo_dir, hook_path)); + cl_git_pass(git_str_joinpath(&actual, repo_dir, hook_path)); cl_git_pass(git_path_lstat(actual.ptr, &st)); cl_assert(expected_st.st_size == st.st_size); @@ -76,20 +76,20 @@ static void assert_hooks_match( cl_assert_equal_i_fmt(expected_mode, st.st_mode, "%07o"); } - git_buf_dispose(&expected); - git_buf_dispose(&actual); + git_str_dispose(&expected); + git_str_dispose(&actual); } static void assert_mode_seems_okay( const char *base, const char *path, git_filemode_t expect_mode, bool expect_setgid, bool core_filemode) { - git_buf full = GIT_BUF_INIT; + git_str full = GIT_STR_INIT; struct stat st; - cl_git_pass(git_buf_joinpath(&full, base, path)); + cl_git_pass(git_str_joinpath(&full, base, path)); cl_git_pass(git_path_lstat(full.ptr, &st)); - git_buf_dispose(&full); + git_str_dispose(&full); if (!core_filemode) { CLEAR_FOR_CORE_FILEMODE(expect_mode); @@ -115,7 +115,7 @@ static void setup_repo(const char *name, git_repository_init_options *opts) static void setup_templates(const char *name, bool setup_globally) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_fixture_sandbox("template"); if (strcmp(name, "template")) @@ -127,40 +127,40 @@ static void setup_templates(const char *name, bool setup_globally) * Create a symlink from link.sample to update.sample if the filesystem * supports it. */ - cl_git_pass(git_buf_join3(&path, '/', name, "hooks", "link.sample")); + cl_git_pass(git_str_join3(&path, '/', name, "hooks", "link.sample")); #ifdef GIT_WIN32 cl_git_mkfile(path.ptr, "#!/bin/sh\necho hello, world\n"); #else cl_must_pass(p_symlink("update.sample", path.ptr)); #endif - git_buf_clear(&path); + git_str_clear(&path); /* Create a file starting with a dot */ - cl_git_pass(git_buf_join3(&path, '/', name, "hooks", ".dotfile")); + cl_git_pass(git_str_join3(&path, '/', name, "hooks", ".dotfile")); cl_git_mkfile(path.ptr, "something\n"); - git_buf_clear(&path); + git_str_clear(&path); if (setup_globally) { - cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), name)); + cl_git_pass(git_str_joinpath(&path, clar_sandbox_path(), name)); create_tmp_global_config("tmp_global_path", "init.templatedir", path.ptr); } - git_buf_dispose(&path); + git_str_dispose(&path); } static void validate_templates(git_repository *repo, const char *template_path) { - git_buf path = GIT_BUF_INIT, expected = GIT_BUF_INIT, actual = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, expected = GIT_STR_INIT, actual = GIT_STR_INIT; int filemode; - cl_git_pass(git_buf_joinpath(&path, template_path, "description")); + cl_git_pass(git_str_joinpath(&path, template_path, "description")); cl_git_pass(git_futils_readbuffer(&expected, path.ptr)); - git_buf_clear(&path); + git_str_clear(&path); - cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "description")); + cl_git_pass(git_str_joinpath(&path, git_repository_path(repo), "description")); cl_git_pass(git_futils_readbuffer(&actual, path.ptr)); cl_assert_equal_s(expected.ptr, actual.ptr); @@ -177,9 +177,9 @@ static void validate_templates(git_repository *repo, const char *template_path) template_path, git_repository_path(repo), "hooks/.dotfile", filemode); - git_buf_dispose(&expected); - git_buf_dispose(&actual); - git_buf_dispose(&path); + git_str_dispose(&expected); + git_str_dispose(&actual); + git_str_dispose(&path); } void test_repo_template__external_templates_specified_in_options(void) @@ -252,7 +252,7 @@ void test_repo_template__extended_with_template_and_shared_mode(void) void test_repo_template__templated_head_is_used(void) { git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; - git_buf head = GIT_BUF_INIT; + git_str head = GIT_STR_INIT; opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; @@ -263,13 +263,13 @@ void test_repo_template__templated_head_is_used(void) cl_git_pass(git_futils_readbuffer(&head, "repo/.git/HEAD")); cl_assert_equal_s("foobar\n", head.ptr); - git_buf_dispose(&head); + git_str_dispose(&head); } void test_repo_template__initial_head_option_overrides_template_head(void) { git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; - git_buf head = GIT_BUF_INIT; + git_str head = GIT_STR_INIT; opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; opts.initial_head = "manual"; @@ -281,7 +281,7 @@ void test_repo_template__initial_head_option_overrides_template_head(void) cl_git_pass(git_futils_readbuffer(&head, "repo/.git/HEAD")); cl_assert_equal_s("ref: refs/heads/manual\n", head.ptr); - git_buf_dispose(&head); + git_str_dispose(&head); } void test_repo_template__empty_template_path(void) diff --git a/tests/reset/hard.c b/tests/reset/hard.c index 1ea1d13fbbb..36e8f14707e 100644 --- a/tests/reset/hard.c +++ b/tests/reset/hard.c @@ -40,7 +40,7 @@ static int strequal_ignore_eol(const char *exp, const char *str) void test_reset_hard__resetting_reverts_modified_files(void) { - git_buf path = GIT_BUF_INIT, content = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, content = GIT_STR_INIT; int i; static const char *files[4] = { "current_file", @@ -64,7 +64,7 @@ void test_reset_hard__resetting_reverts_modified_files(void) cl_assert(wd); for (i = 0; i < 4; ++i) { - cl_git_pass(git_buf_joinpath(&path, wd, files[i])); + cl_git_pass(git_str_joinpath(&path, wd, files[i])); cl_git_pass(git_futils_readbuffer(&content, path.ptr)); cl_assert_equal_s(before[i], content.ptr); } @@ -74,7 +74,7 @@ void test_reset_hard__resetting_reverts_modified_files(void) cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL)); for (i = 0; i < 4; ++i) { - cl_git_pass(git_buf_joinpath(&path, wd, files[i])); + cl_git_pass(git_str_joinpath(&path, wd, files[i])); if (after[i]) { cl_git_pass(git_futils_readbuffer(&content, path.ptr)); cl_assert(strequal_ignore_eol(after[i], content.ptr)); @@ -83,8 +83,8 @@ void test_reset_hard__resetting_reverts_modified_files(void) } } - git_buf_dispose(&content); - git_buf_dispose(&path); + git_str_dispose(&content); + git_str_dispose(&path); } void test_reset_hard__cannot_reset_in_a_bare_repository(void) @@ -165,42 +165,42 @@ void test_reset_hard__resetting_reverts_unmerged(void) void test_reset_hard__cleans_up_merge(void) { - git_buf merge_head_path = GIT_BUF_INIT, - merge_msg_path = GIT_BUF_INIT, - merge_mode_path = GIT_BUF_INIT, - orig_head_path = GIT_BUF_INIT; + git_str merge_head_path = GIT_STR_INIT, + merge_msg_path = GIT_STR_INIT, + merge_mode_path = GIT_STR_INIT, + orig_head_path = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD")); - cl_git_mkfile(git_buf_cstr(&merge_head_path), "beefbeefbeefbeefbeefbeefbeefbeefbeefbeef\n"); + cl_git_pass(git_str_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD")); + cl_git_mkfile(git_str_cstr(&merge_head_path), "beefbeefbeefbeefbeefbeefbeefbeefbeefbeef\n"); - cl_git_pass(git_buf_joinpath(&merge_msg_path, git_repository_path(repo), "MERGE_MSG")); - cl_git_mkfile(git_buf_cstr(&merge_msg_path), "Merge commit 0017bd4ab1ec30440b17bae1680cff124ab5f1f6\n"); + cl_git_pass(git_str_joinpath(&merge_msg_path, git_repository_path(repo), "MERGE_MSG")); + cl_git_mkfile(git_str_cstr(&merge_msg_path), "Merge commit 0017bd4ab1ec30440b17bae1680cff124ab5f1f6\n"); - cl_git_pass(git_buf_joinpath(&merge_mode_path, git_repository_path(repo), "MERGE_MODE")); - cl_git_mkfile(git_buf_cstr(&merge_mode_path), ""); + cl_git_pass(git_str_joinpath(&merge_mode_path, git_repository_path(repo), "MERGE_MODE")); + cl_git_mkfile(git_str_cstr(&merge_mode_path), ""); - cl_git_pass(git_buf_joinpath(&orig_head_path, git_repository_path(repo), "ORIG_HEAD")); - cl_git_mkfile(git_buf_cstr(&orig_head_path), "0017bd4ab1ec30440b17bae1680cff124ab5f1f6"); + cl_git_pass(git_str_joinpath(&orig_head_path, git_repository_path(repo), "ORIG_HEAD")); + cl_git_mkfile(git_str_cstr(&orig_head_path), "0017bd4ab1ec30440b17bae1680cff124ab5f1f6"); cl_git_pass(git_revparse_single(&target, repo, "0017bd4")); cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL)); - cl_assert(!git_path_exists(git_buf_cstr(&merge_head_path))); - cl_assert(!git_path_exists(git_buf_cstr(&merge_msg_path))); - cl_assert(!git_path_exists(git_buf_cstr(&merge_mode_path))); + cl_assert(!git_path_exists(git_str_cstr(&merge_head_path))); + cl_assert(!git_path_exists(git_str_cstr(&merge_msg_path))); + cl_assert(!git_path_exists(git_str_cstr(&merge_mode_path))); - cl_assert(git_path_exists(git_buf_cstr(&orig_head_path))); - cl_git_pass(p_unlink(git_buf_cstr(&orig_head_path))); + cl_assert(git_path_exists(git_str_cstr(&orig_head_path))); + cl_git_pass(p_unlink(git_str_cstr(&orig_head_path))); - git_buf_dispose(&merge_head_path); - git_buf_dispose(&merge_msg_path); - git_buf_dispose(&merge_mode_path); - git_buf_dispose(&orig_head_path); + git_str_dispose(&merge_head_path); + git_str_dispose(&merge_msg_path); + git_str_dispose(&merge_mode_path); + git_str_dispose(&orig_head_path); } void test_reset_hard__reflog_is_correct(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_annotated_commit *annotated; const char *exp_msg = "commit: Add a file which name should appear before the " "\"subdir/\" folder while being dealt with by the treewalker"; @@ -218,12 +218,12 @@ void test_reset_hard__reflog_is_correct(void) /* Moved branch, expect id in message */ cl_git_pass(git_revparse_single(&target, repo, "HEAD~^{commit}")); - cl_git_pass(git_buf_printf(&buf, "reset: moving to %s", git_oid_tostr_s(git_object_id(target)))); + cl_git_pass(git_str_printf(&buf, "reset: moving to %s", git_oid_tostr_s(git_object_id(target)))); cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL)); - reflog_check(repo, "HEAD", 4, NULL, git_buf_cstr(&buf)); - reflog_check(repo, "refs/heads/master", 4, NULL, git_buf_cstr(&buf)); + reflog_check(repo, "HEAD", 4, NULL, git_str_cstr(&buf)); + reflog_check(repo, "refs/heads/master", 4, NULL, git_str_cstr(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); /* Moved branch, expect revspec in message */ exp_msg = "reset: moving to HEAD~^{commit}"; diff --git a/tests/reset/mixed.c b/tests/reset/mixed.c index 9928c687121..4a78d4c3767 100644 --- a/tests/reset/mixed.c +++ b/tests/reset/mixed.c @@ -50,7 +50,7 @@ void test_reset_mixed__resetting_refreshes_the_index_to_the_commit_tree(void) void test_reset_mixed__reflog_is_correct(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; git_annotated_commit *annotated; const char *exp_msg = "commit: Updating test data so we can test inter-hunk-context"; @@ -68,12 +68,12 @@ void test_reset_mixed__reflog_is_correct(void) /* Moved branch, expect id in message */ cl_git_pass(git_revparse_single(&target, repo, "HEAD~^{commit}")); - git_buf_clear(&buf); - cl_git_pass(git_buf_printf(&buf, "reset: moving to %s", git_oid_tostr_s(git_object_id(target)))); + git_str_clear(&buf); + cl_git_pass(git_str_printf(&buf, "reset: moving to %s", git_oid_tostr_s(git_object_id(target)))); cl_git_pass(git_reset(repo, target, GIT_RESET_MIXED, NULL)); - reflog_check(repo, "HEAD", 10, NULL, git_buf_cstr(&buf)); - reflog_check(repo, "refs/heads/master", 10, NULL, git_buf_cstr(&buf)); - git_buf_dispose(&buf); + reflog_check(repo, "HEAD", 10, NULL, git_str_cstr(&buf)); + reflog_check(repo, "refs/heads/master", 10, NULL, git_str_cstr(&buf)); + git_str_dispose(&buf); /* Moved branch, expect revspec in message */ exp_msg = "reset: moving to HEAD~^{commit}"; diff --git a/tests/reset/soft.c b/tests/reset/soft.c index d9cfb0553e5..aca0834f25a 100644 --- a/tests/reset/soft.c +++ b/tests/reset/soft.c @@ -116,33 +116,33 @@ void test_reset_soft__resetting_against_an_unborn_head_repo_makes_the_head_no_lo void test_reset_soft__fails_when_merging(void) { - git_buf merge_head_path = GIT_BUF_INIT; + git_str merge_head_path = GIT_STR_INIT; cl_git_pass(git_repository_detach_head(repo)); - cl_git_pass(git_buf_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD")); - cl_git_mkfile(git_buf_cstr(&merge_head_path), "beefbeefbeefbeefbeefbeefbeefbeefbeefbeef\n"); + cl_git_pass(git_str_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD")); + cl_git_mkfile(git_str_cstr(&merge_head_path), "beefbeefbeefbeefbeefbeefbeefbeefbeefbeef\n"); cl_git_pass(git_revparse_single(&target, repo, KNOWN_COMMIT_IN_BARE_REPO)); cl_assert_equal_i(GIT_EUNMERGED, git_reset(repo, target, GIT_RESET_SOFT, NULL)); - cl_git_pass(p_unlink(git_buf_cstr(&merge_head_path))); + cl_git_pass(p_unlink(git_str_cstr(&merge_head_path))); - git_buf_dispose(&merge_head_path); + git_str_dispose(&merge_head_path); } void test_reset_soft__fails_when_index_contains_conflicts_independently_of_MERGE_HEAD_file_existence(void) { git_index *index; git_reference *head; - git_buf merge_head_path = GIT_BUF_INIT; + git_str merge_head_path = GIT_STR_INIT; cl_git_sandbox_cleanup(); repo = cl_git_sandbox_init("mergedrepo"); - cl_git_pass(git_buf_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD")); - cl_git_pass(p_unlink(git_buf_cstr(&merge_head_path))); - git_buf_dispose(&merge_head_path); + cl_git_pass(git_str_joinpath(&merge_head_path, git_repository_path(repo), "MERGE_HEAD")); + cl_git_pass(p_unlink(git_str_cstr(&merge_head_path))); + git_str_dispose(&merge_head_path); cl_git_pass(git_repository_index(&index, repo)); cl_assert_equal_i(true, git_index_has_conflicts(index)); diff --git a/tests/revert/bare.c b/tests/revert/bare.c index 03cffbf3e92..9261cfe861f 100644 --- a/tests/revert/bare.c +++ b/tests/revert/bare.c @@ -1,7 +1,6 @@ #include "clar.h" #include "clar_libgit2.h" -#include "buffer.h" #include "futils.h" #include "git2/revert.h" diff --git a/tests/revert/workdir.c b/tests/revert/workdir.c index 2ad059d99bb..36824044b3b 100644 --- a/tests/revert/workdir.c +++ b/tests/revert/workdir.c @@ -1,7 +1,6 @@ #include "clar.h" #include "clar_libgit2.h" -#include "buffer.h" #include "futils.h" #include "git2/revert.h" @@ -66,7 +65,7 @@ void test_revert_workdir__conflicts(void) git_reference *head_ref; git_commit *head, *commit; git_oid revert_oid; - git_buf conflicting_buf = GIT_BUF_INIT, mergemsg_buf = GIT_BUF_INIT; + git_str conflicting_buf = GIT_STR_INIT, mergemsg_buf = GIT_STR_INIT; struct merge_index_entry merge_index_entries[] = { { 0100644, "7731926a337c4eaba1e2187d90ebfa0a93659382", 1, "file1.txt" }, @@ -126,8 +125,8 @@ void test_revert_workdir__conflicts(void) git_commit_free(commit); git_commit_free(head); git_reference_free(head_ref); - git_buf_dispose(&mergemsg_buf); - git_buf_dispose(&conflicting_buf); + git_str_dispose(&mergemsg_buf); + git_str_dispose(&conflicting_buf); } /* git reset --hard 39467716290f6df775a91cdb9a4eb39295018145 @@ -308,7 +307,7 @@ void test_revert_workdir__again_after_edit(void) */ void test_revert_workdir__again_after_edit_two(void) { - git_buf diff_buf = GIT_BUF_INIT; + git_str diff_buf = GIT_STR_INIT; git_config *config; git_oid head_commit_oid, revert_commit_oid; git_commit *head_commit, *revert_commit; @@ -350,7 +349,7 @@ void test_revert_workdir__again_after_edit_two(void) git_commit_free(revert_commit); git_commit_free(head_commit); git_config_free(config); - git_buf_dispose(&diff_buf); + git_str_dispose(&diff_buf); } /* git reset --hard 72333f47d4e83616630ff3b0ffe4c0faebcc3c45 diff --git a/tests/stash/apply.c b/tests/stash/apply.c index 5eb59545ea2..c3d1ef0c29f 100644 --- a/tests/stash/apply.c +++ b/tests/stash/apply.c @@ -70,7 +70,7 @@ void test_stash_apply__cleanup(void) void test_stash_apply__with_default(void) { - git_buf where = GIT_BUF_INIT; + git_str where = GIT_STR_INIT; cl_git_pass(git_stash_apply(repo, 0, NULL)); @@ -85,7 +85,7 @@ void test_stash_apply__with_default(void) cl_git_pass(git_futils_readbuffer(&where, "stash/where")); cl_assert_equal_s("....\n", where.ptr); - git_buf_dispose(&where); + git_str_dispose(&where); } void test_stash_apply__with_existing_file(void) @@ -114,7 +114,7 @@ void test_stash_apply__merges_new_file(void) void test_stash_apply__with_reinstate_index(void) { - git_buf where = GIT_BUF_INIT; + git_str where = GIT_STR_INIT; git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT; opts.flags = GIT_STASH_APPLY_REINSTATE_INDEX; @@ -132,7 +132,7 @@ void test_stash_apply__with_reinstate_index(void) cl_git_pass(git_futils_readbuffer(&where, "stash/where")); cl_assert_equal_s("....\n", where.ptr); - git_buf_dispose(&where); + git_str_dispose(&where); } void test_stash_apply__conflict_index_with_default(void) diff --git a/tests/stash/save.c b/tests/stash/save.c index d568567d5f9..1fbcf0957a3 100644 --- a/tests/stash/save.c +++ b/tests/stash/save.c @@ -201,12 +201,12 @@ void test_stash_save__untracked_regression(void) const char *paths[] = {"what", "where", "how", "why"}; git_reference *head; git_commit *head_commit; - git_buf untracked_dir; + git_str untracked_dir; const char* workdir = git_repository_workdir(repo); - git_buf_init(&untracked_dir, 0); - git_buf_printf(&untracked_dir, "%sz", workdir); + git_str_init(&untracked_dir, 0); + git_str_printf(&untracked_dir, "%sz", workdir); cl_assert(!p_mkdir(untracked_dir.ptr, 0777)); @@ -227,7 +227,7 @@ void test_stash_save__untracked_regression(void) git_reference_free(head); git_commit_free(head_commit); - git_buf_dispose(&untracked_dir); + git_str_dispose(&untracked_dir); } #define MESSAGE "Look Ma! I'm on TV!" diff --git a/tests/status/renames.c b/tests/status/renames.c index 7deec980f6f..e69dbcce009 100644 --- a/tests/status/renames.c +++ b/tests/status/renames.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "path.h" #include "posix.h" #include "status_helpers.h" @@ -23,11 +22,11 @@ void test_status_renames__cleanup(void) static void _rename_helper( git_repository *repo, const char *from, const char *to, const char *extra) { - git_buf oldpath = GIT_BUF_INIT, newpath = GIT_BUF_INIT; + git_str oldpath = GIT_STR_INIT, newpath = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath( + cl_git_pass(git_str_joinpath( &oldpath, git_repository_workdir(repo), from)); - cl_git_pass(git_buf_joinpath( + cl_git_pass(git_str_joinpath( &newpath, git_repository_workdir(repo), to)); cl_git_pass(p_rename(oldpath.ptr, newpath.ptr)); @@ -35,8 +34,8 @@ static void _rename_helper( if (extra) cl_git_append2file(newpath.ptr, extra); - git_buf_dispose(&oldpath); - git_buf_dispose(&newpath); + git_str_dispose(&oldpath); + git_str_dispose(&newpath); } #define rename_file(R,O,N) _rename_helper((R), (O), (N), NULL) diff --git a/tests/status/worktree.c b/tests/status/worktree.c index d9fce44046a..4ab04094a13 100644 --- a/tests/status/worktree.c +++ b/tests/status/worktree.c @@ -100,9 +100,9 @@ void test_status_worktree__empty_repository(void) cl_assert_equal_i(0, count); } -static int remove_file_cb(void *data, git_buf *file) +static int remove_file_cb(void *data, git_str *file) { - const char *filename = git_buf_cstr(file); + const char *filename = git_str_cstr(file); GIT_UNUSED(data); @@ -112,7 +112,7 @@ static int remove_file_cb(void *data, git_buf *file) if (git_path_isdir(filename)) cl_git_pass(git_futils_rmdir_r(filename, NULL, GIT_RMDIR_REMOVE_FILES)); else - cl_git_pass(p_unlink(git_buf_cstr(file))); + cl_git_pass(p_unlink(git_str_cstr(file))); return 0; } @@ -122,12 +122,12 @@ void test_status_worktree__purged_worktree(void) { status_entry_counts counts; git_repository *repo = cl_git_sandbox_init("status"); - git_buf workdir = GIT_BUF_INIT; + git_str workdir = GIT_STR_INIT; /* first purge the contents of the worktree */ - cl_git_pass(git_buf_sets(&workdir, git_repository_workdir(repo))); + cl_git_pass(git_str_sets(&workdir, git_repository_workdir(repo))); cl_git_pass(git_path_direach(&workdir, 0, remove_file_cb, NULL)); - git_buf_dispose(&workdir); + git_str_dispose(&workdir); /* now get status */ memset(&counts, 0x0, sizeof(status_entry_counts)); @@ -369,78 +369,78 @@ static int cb_status__check_592(const char *p, unsigned int s, void *payload) void test_status_worktree__issue_592(void) { git_repository *repo; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; repo = cl_git_sandbox_init("issue_592"); - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "l.txt")); - cl_git_pass(p_unlink(git_buf_cstr(&path))); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(repo), "l.txt")); + cl_git_pass(p_unlink(git_str_cstr(&path))); cl_assert(!git_path_exists("issue_592/l.txt")); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "l.txt")); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_status_worktree__issue_592_2(void) { git_repository *repo; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; repo = cl_git_sandbox_init("issue_592"); - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "c/a.txt")); - cl_git_pass(p_unlink(git_buf_cstr(&path))); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(repo), "c/a.txt")); + cl_git_pass(p_unlink(git_str_cstr(&path))); cl_assert(!git_path_exists("issue_592/c/a.txt")); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt")); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_status_worktree__issue_592_3(void) { git_repository *repo; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; repo = cl_git_sandbox_init("issue_592"); - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "c")); - cl_git_pass(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES)); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(repo), "c")); + cl_git_pass(git_futils_rmdir_r(git_str_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES)); cl_assert(!git_path_exists("issue_592/c/a.txt")); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt")); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_status_worktree__issue_592_4(void) { git_repository *repo; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; repo = cl_git_sandbox_init("issue_592"); - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "t/b.txt")); - cl_git_pass(p_unlink(git_buf_cstr(&path))); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(repo), "t/b.txt")); + cl_git_pass(p_unlink(git_str_cstr(&path))); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "t/b.txt")); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_status_worktree__issue_592_5(void) { git_repository *repo; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; repo = cl_git_sandbox_init("issue_592"); - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "t")); - cl_git_pass(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES)); - cl_git_pass(p_mkdir(git_buf_cstr(&path), 0777)); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(repo), "t")); + cl_git_pass(git_futils_rmdir_r(git_str_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES)); + cl_git_pass(p_mkdir(git_str_cstr(&path), 0777)); cl_git_pass(git_status_foreach(repo, cb_status__check_592, NULL)); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_status_worktree__issue_592_ignores_0(void) @@ -610,8 +610,8 @@ void test_status_worktree__filemode_non755(void) git_repository *repo = cl_git_sandbox_init("filemodes"); status_entry_counts counts; git_status_options opts = GIT_STATUS_OPTIONS_INIT; - git_buf executable_path = GIT_BUF_INIT; - git_buf nonexecutable_path = GIT_BUF_INIT; + git_str executable_path = GIT_STR_INIT; + git_str nonexecutable_path = GIT_STR_INIT; if (!cl_is_chmod_supported()) return; @@ -620,14 +620,14 @@ void test_status_worktree__filemode_non755(void) GIT_STATUS_OPT_INCLUDE_IGNORED | GIT_STATUS_OPT_INCLUDE_UNMODIFIED; - git_buf_joinpath(&executable_path, git_repository_workdir(repo), "exec_on"); - cl_must_pass(p_chmod(git_buf_cstr(&executable_path), 0744)); - git_buf_dispose(&executable_path); + git_str_joinpath(&executable_path, git_repository_workdir(repo), "exec_on"); + cl_must_pass(p_chmod(git_str_cstr(&executable_path), 0744)); + git_str_dispose(&executable_path); - git_buf_joinpath(&nonexecutable_path, git_repository_workdir(repo), "exec_off"); + git_str_joinpath(&nonexecutable_path, git_repository_workdir(repo), "exec_off"); - cl_must_pass(p_chmod(git_buf_cstr(&nonexecutable_path), 0655)); - git_buf_dispose(&nonexecutable_path); + cl_must_pass(p_chmod(git_str_cstr(&nonexecutable_path), 0655)); + git_str_dispose(&nonexecutable_path); memset(&counts, 0, sizeof(counts)); counts.expected_entry_count = filemode_count; @@ -789,7 +789,7 @@ static void assert_ignore_case( int expected_camel_cased_file_status) { unsigned int status; - git_buf lower_case_path = GIT_BUF_INIT, camel_case_path = GIT_BUF_INIT; + git_str lower_case_path = GIT_STR_INIT, camel_case_path = GIT_STR_INIT; git_repository *repo, *repo2; repo = cl_git_sandbox_init("empty_standard_repo"); @@ -797,10 +797,10 @@ static void assert_ignore_case( cl_repo_set_bool(repo, "core.ignorecase", should_ignore_case); - cl_git_pass(git_buf_joinpath(&lower_case_path, + cl_git_pass(git_str_joinpath(&lower_case_path, git_repository_workdir(repo), "plop")); - cl_git_mkfile(git_buf_cstr(&lower_case_path), ""); + cl_git_mkfile(git_str_cstr(&lower_case_path), ""); stage_and_commit(repo, "plop"); @@ -809,10 +809,10 @@ static void assert_ignore_case( cl_git_pass(git_status_file(&status, repo2, "plop")); cl_assert_equal_i(GIT_STATUS_CURRENT, status); - cl_git_pass(git_buf_joinpath(&camel_case_path, + cl_git_pass(git_str_joinpath(&camel_case_path, git_repository_workdir(repo), "Plop")); - cl_git_pass(p_rename(git_buf_cstr(&lower_case_path), git_buf_cstr(&camel_case_path))); + cl_git_pass(p_rename(git_str_cstr(&lower_case_path), git_str_cstr(&camel_case_path))); cl_git_pass(git_status_file(&status, repo2, "plop")); cl_assert_equal_i(expected_lower_cased_file_status, status); @@ -821,8 +821,8 @@ static void assert_ignore_case( cl_assert_equal_i(expected_camel_cased_file_status, status); git_repository_free(repo2); - git_buf_dispose(&lower_case_path); - git_buf_dispose(&camel_case_path); + git_str_dispose(&lower_case_path); + git_str_dispose(&camel_case_path); } void test_status_worktree__file_status_honors_core_ignorecase_true(void) diff --git a/tests/str/basic.c b/tests/str/basic.c new file mode 100644 index 00000000000..5d2556805ca --- /dev/null +++ b/tests/str/basic.c @@ -0,0 +1,50 @@ +#include "clar_libgit2.h" + +static const char *test_string = "Have you seen that? Have you seeeen that??"; + +void test_str_basic__resize(void) +{ + git_str buf1 = GIT_STR_INIT; + git_str_puts(&buf1, test_string); + cl_assert(git_str_oom(&buf1) == 0); + cl_assert_equal_s(git_str_cstr(&buf1), test_string); + + git_str_puts(&buf1, test_string); + cl_assert(strlen(git_str_cstr(&buf1)) == strlen(test_string) * 2); + git_str_dispose(&buf1); +} + +void test_str_basic__resize_incremental(void) +{ + git_str buf1 = GIT_STR_INIT; + + /* Presently, asking for 6 bytes will round up to 8. */ + cl_git_pass(git_str_puts(&buf1, "Hello")); + cl_assert_equal_i(5, buf1.size); + cl_assert_equal_i(8, buf1.asize); + + /* Ensure an additional byte does not realloc. */ + cl_git_pass(git_str_grow_by(&buf1, 1)); + cl_assert_equal_i(5, buf1.size); + cl_assert_equal_i(8, buf1.asize); + + /* But requesting many does. */ + cl_git_pass(git_str_grow_by(&buf1, 16)); + cl_assert_equal_i(5, buf1.size); + cl_assert(buf1.asize > 8); + + git_str_dispose(&buf1); +} + +void test_str_basic__printf(void) +{ + git_str buf2 = GIT_STR_INIT; + git_str_printf(&buf2, "%s %s %d ", "shoop", "da", 23); + cl_assert(git_str_oom(&buf2) == 0); + cl_assert_equal_s(git_str_cstr(&buf2), "shoop da 23 "); + + git_str_printf(&buf2, "%s %d", "woop", 42); + cl_assert(git_str_oom(&buf2) == 0); + cl_assert_equal_s(git_str_cstr(&buf2), "shoop da 23 woop 42"); + git_str_dispose(&buf2); +} diff --git a/tests/buf/oom.c b/tests/str/oom.c similarity index 61% rename from tests/buf/oom.c rename to tests/str/oom.c index 726234ef89e..3d59ead0197 100644 --- a/tests/buf/oom.c +++ b/tests/str/oom.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" /* Override default allocators with ones that will fail predictably. */ @@ -18,7 +17,7 @@ static void *oom_realloc(void *p, size_t n, const char *file, int line) return (n > 100) ? NULL : std_alloc.grealloc(p, n, file, line); } -void test_buf_oom__initialize(void) +void test_str_oom__initialize(void) { git_stdalloc_init_allocator(&std_alloc); git_stdalloc_init_allocator(&oom_alloc); @@ -29,31 +28,31 @@ void test_buf_oom__initialize(void) cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ALLOCATOR, &oom_alloc)); } -void test_buf_oom__cleanup(void) +void test_str_oom__cleanup(void) { cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ALLOCATOR, NULL)); } -void test_buf_oom__grow(void) +void test_str_oom__grow(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_grow(&buf, 42)); - cl_assert(!git_buf_oom(&buf)); + cl_git_pass(git_str_grow(&buf, 42)); + cl_assert(!git_str_oom(&buf)); - cl_assert(git_buf_grow(&buf, 101) == -1); - cl_assert(git_buf_oom(&buf)); + cl_assert(git_str_grow(&buf, 101) == -1); + cl_assert(git_str_oom(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } -void test_buf_oom__grow_by(void) +void test_str_oom__grow_by(void) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_grow_by(&buf, 42)); - cl_assert(!git_buf_oom(&buf)); + cl_git_pass(git_str_grow_by(&buf, 42)); + cl_assert(!git_str_oom(&buf)); - cl_assert(git_buf_grow_by(&buf, 101) == -1); - cl_assert(git_buf_oom(&buf)); + cl_assert(git_str_grow_by(&buf, 101) == -1); + cl_assert(git_str_oom(&buf)); } diff --git a/tests/buf/percent.c b/tests/str/percent.c similarity index 71% rename from tests/buf/percent.c rename to tests/str/percent.c index 8c47b833de0..3393890756c 100644 --- a/tests/buf/percent.c +++ b/tests/str/percent.c @@ -1,28 +1,27 @@ #include "clar_libgit2.h" -#include "buffer.h" static void expect_decode_pass(const char *expected, const char *encoded) { - git_buf in = GIT_BUF_INIT, out = GIT_BUF_INIT; + git_str in = GIT_STR_INIT, out = GIT_STR_INIT; /* * ensure that we only read the given length of the input buffer * by putting garbage at the end. this will ensure that we do * not, eg, rely on nul-termination or walk off the end of the buf. */ - cl_git_pass(git_buf_puts(&in, encoded)); - cl_git_pass(git_buf_PUTS(&in, "TRAILER")); + cl_git_pass(git_str_puts(&in, encoded)); + cl_git_pass(git_str_PUTS(&in, "TRAILER")); - cl_git_pass(git_buf_decode_percent(&out, in.ptr, strlen(encoded))); + cl_git_pass(git_str_decode_percent(&out, in.ptr, strlen(encoded))); - cl_assert_equal_s(expected, git_buf_cstr(&out)); - cl_assert_equal_i(strlen(expected), git_buf_len(&out)); + cl_assert_equal_s(expected, git_str_cstr(&out)); + cl_assert_equal_i(strlen(expected), git_str_len(&out)); - git_buf_dispose(&in); - git_buf_dispose(&out); + git_str_dispose(&in); + git_str_dispose(&out); } -void test_buf_percent__decode_succeeds(void) +void test_str_percent__decode_succeeds(void) { expect_decode_pass("", ""); expect_decode_pass(" ", "%20"); @@ -37,7 +36,7 @@ void test_buf_percent__decode_succeeds(void) expect_decode_pass("foo bar ", "foo%20bar%20"); } -void test_buf_percent__ignores_invalid(void) +void test_str_percent__ignores_invalid(void) { expect_decode_pass("githu%%.com", "githu%%.com"); expect_decode_pass("github.co%2", "github.co%2"); diff --git a/tests/buf/quote.c b/tests/str/quote.c similarity index 74% rename from tests/buf/quote.c rename to tests/str/quote.c index 8867ae7d618..2c654624765 100644 --- a/tests/buf/quote.c +++ b/tests/str/quote.c @@ -1,20 +1,19 @@ #include "clar_libgit2.h" -#include "buffer.h" static void expect_quote_pass(const char *expected, const char *str) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_puts(&buf, str)); - cl_git_pass(git_buf_quote(&buf)); + cl_git_pass(git_str_puts(&buf, str)); + cl_git_pass(git_str_quote(&buf)); - cl_assert_equal_s(expected, git_buf_cstr(&buf)); - cl_assert_equal_i(strlen(expected), git_buf_len(&buf)); + cl_assert_equal_s(expected, git_str_cstr(&buf)); + cl_assert_equal_i(strlen(expected), git_str_len(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } -void test_buf_quote__quote_succeeds(void) +void test_str_quote__quote_succeeds(void) { expect_quote_pass("", ""); expect_quote_pass("foo", "foo"); @@ -30,28 +29,28 @@ void test_buf_quote__quote_succeeds(void) static void expect_unquote_pass(const char *expected, const char *quoted) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_puts(&buf, quoted)); - cl_git_pass(git_buf_unquote(&buf)); + cl_git_pass(git_str_puts(&buf, quoted)); + cl_git_pass(git_str_unquote(&buf)); - cl_assert_equal_s(expected, git_buf_cstr(&buf)); - cl_assert_equal_i(strlen(expected), git_buf_len(&buf)); + cl_assert_equal_s(expected, git_str_cstr(&buf)); + cl_assert_equal_i(strlen(expected), git_str_len(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } static void expect_unquote_fail(const char *quoted) { - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_puts(&buf, quoted)); - cl_git_fail(git_buf_unquote(&buf)); + cl_git_pass(git_str_puts(&buf, quoted)); + cl_git_fail(git_str_unquote(&buf)); - git_buf_dispose(&buf); + git_str_dispose(&buf); } -void test_buf_quote__unquote_succeeds(void) +void test_str_quote__unquote_succeeds(void) { expect_unquote_pass("", "\"\""); expect_unquote_pass(" ", "\" \""); @@ -68,7 +67,7 @@ void test_buf_quote__unquote_succeeds(void) expect_unquote_pass("0xff: \377", "\"0xff: \\377\""); } -void test_buf_quote__unquote_fails(void) +void test_str_quote__unquote_fails(void) { expect_unquote_fail("no quotes at all"); expect_unquote_fail("\"no trailing quote"); diff --git a/tests/str/splice.c b/tests/str/splice.c new file mode 100644 index 00000000000..14e844e2fc7 --- /dev/null +++ b/tests/str/splice.c @@ -0,0 +1,92 @@ +#include "clar_libgit2.h" + +static git_str _buf; + +void test_str_splice__initialize(void) { + git_str_init(&_buf, 16); +} + +void test_str_splice__cleanup(void) { + git_str_dispose(&_buf); +} + +void test_str_splice__preprend(void) +{ + git_str_sets(&_buf, "world!"); + + cl_git_pass(git_str_splice(&_buf, 0, 0, "Hello Dolly", strlen("Hello "))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__append(void) +{ + git_str_sets(&_buf, "Hello"); + + cl_git_pass(git_str_splice(&_buf, git_str_len(&_buf), 0, " world!", strlen(" world!"))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__insert_at(void) +{ + git_str_sets(&_buf, "Hell world!"); + + cl_git_pass(git_str_splice(&_buf, strlen("Hell"), 0, "o", strlen("o"))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__remove_at(void) +{ + git_str_sets(&_buf, "Hello world of warcraft!"); + + cl_git_pass(git_str_splice(&_buf, strlen("Hello world"), strlen(" of warcraft"), "", 0)); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__replace(void) +{ + git_str_sets(&_buf, "Hell0 w0rld!"); + + cl_git_pass(git_str_splice(&_buf, strlen("Hell"), strlen("0 w0"), "o wo", strlen("o wo"))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__replace_with_longer(void) +{ + git_str_sets(&_buf, "Hello you!"); + + cl_git_pass(git_str_splice(&_buf, strlen("Hello "), strlen("you"), "world", strlen("world"))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__replace_with_shorter(void) +{ + git_str_sets(&_buf, "Brave new world!"); + + cl_git_pass(git_str_splice(&_buf, 0, strlen("Brave new"), "Hello", strlen("Hello"))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__truncate(void) +{ + git_str_sets(&_buf, "Hello world!!"); + + cl_git_pass(git_str_splice(&_buf, strlen("Hello world!"), strlen("!"), "", 0)); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__dont_do_anything(void) +{ + git_str_sets(&_buf, "Hello world!"); + + cl_git_pass(git_str_splice(&_buf, 3, 0, "Hello", 0)); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} diff --git a/tests/stress/diff.c b/tests/stress/diff.c index 2ea0d407611..aecf08bbe33 100644 --- a/tests/stress/diff.c +++ b/tests/stress/diff.c @@ -90,7 +90,7 @@ void test_stress_diff__rename_big_files(void) git_index *index; char tmp[64]; int i, j; - git_buf b = GIT_BUF_INIT; + git_str b = GIT_STR_INIT; g_repo = cl_git_sandbox_init("renames"); @@ -99,7 +99,7 @@ void test_stress_diff__rename_big_files(void) for (i = 0; i < 100; i += 1) { p_snprintf(tmp, sizeof(tmp), "renames/newfile%03d", i); for (j = i * 256; j > 0; --j) - git_buf_printf(&b, "more content %d\n", i); + git_str_printf(&b, "more content %d\n", i); cl_git_mkfile(tmp, b.ptr); } @@ -108,7 +108,7 @@ void test_stress_diff__rename_big_files(void) cl_git_pass(git_index_add_bypath(index, tmp + strlen("renames/"))); } - git_buf_dispose(&b); + git_str_dispose(&b); git_index_free(index); test_with_many(100); @@ -119,13 +119,13 @@ void test_stress_diff__rename_many_files(void) git_index *index; char tmp[64]; int i; - git_buf b = GIT_BUF_INIT; + git_str b = GIT_STR_INIT; g_repo = cl_git_sandbox_init("renames"); cl_git_pass(git_repository_index(&index, g_repo)); - git_buf_printf(&b, "%08d\n" ANOTHER_POEM "%08d\n" ANOTHER_POEM ANOTHER_POEM, 0, 0); + git_str_printf(&b, "%08d\n" ANOTHER_POEM "%08d\n" ANOTHER_POEM ANOTHER_POEM, 0, 0); for (i = 0; i < 2500; i += 1) { p_snprintf(tmp, sizeof(tmp), "renames/newfile%03d", i); @@ -133,7 +133,7 @@ void test_stress_diff__rename_many_files(void) b.ptr[8] = '\n'; cl_git_mkfile(tmp, b.ptr); } - git_buf_dispose(&b); + git_str_dispose(&b); for (i = 0; i < 2500; i += 1) { p_snprintf(tmp, sizeof(tmp), "renames/newfile%03d", i); diff --git a/tests/submodule/add.c b/tests/submodule/add.c index fc458f82621..b564123dd58 100644 --- a/tests/submodule/add.c +++ b/tests/submodule/add.c @@ -17,20 +17,20 @@ void test_submodule_add__cleanup(void) static void assert_submodule_url(const char* name, const char *url) { - git_buf key = GIT_BUF_INIT; + git_str key = GIT_STR_INIT; - cl_git_pass(git_buf_printf(&key, "submodule.%s.url", name)); - assert_config_entry_value(g_repo, git_buf_cstr(&key), url); + cl_git_pass(git_str_printf(&key, "submodule.%s.url", name)); + assert_config_entry_value(g_repo, git_str_cstr(&key), url); - git_buf_dispose(&key); + git_str_dispose(&key); } void test_submodule_add__url_absolute(void) { git_submodule *sm; git_repository *repo; - git_buf dot_git_content = GIT_BUF_INIT; + git_str dot_git_content = GIT_STR_INIT; g_repo = setup_fixture_submod2(); @@ -63,7 +63,7 @@ void test_submodule_add__url_absolute(void) cl_assert_equal_s("gitdir: ../.git/modules/sm_libgit2/", dot_git_content.ptr); git_repository_free(repo); - git_buf_dispose(&dot_git_content); + git_str_dispose(&dot_git_content); /* add a submodule not using a gitlink */ @@ -151,11 +151,11 @@ void test_submodule_add__path_exists_in_index(void) { git_index *index; git_submodule *sm; - git_buf filename = GIT_BUF_INIT; + git_str filename = GIT_STR_INIT; g_repo = cl_git_sandbox_init("testrepo"); - cl_git_pass(git_buf_joinpath(&filename, "subdirectory", "test.txt")); + cl_git_pass(git_str_joinpath(&filename, "subdirectory", "test.txt")); cl_git_pass(git_repository_index__weakptr(&index, g_repo)); @@ -164,14 +164,14 @@ void test_submodule_add__path_exists_in_index(void) cl_git_fail_with(git_submodule_add_setup(&sm, g_repo, "./", "subdirectory", 1), GIT_EEXISTS); git_submodule_free(sm); - git_buf_dispose(&filename); + git_str_dispose(&filename); } void test_submodule_add__file_exists_in_index(void) { git_index *index; git_submodule *sm; - git_buf name = GIT_BUF_INIT; + git_str name = GIT_STR_INIT; g_repo = cl_git_sandbox_init("testrepo"); @@ -182,7 +182,7 @@ void test_submodule_add__file_exists_in_index(void) cl_git_fail_with(git_submodule_add_setup(&sm, g_repo, "./", "subdirectory", 1), GIT_EEXISTS); git_submodule_free(sm); - git_buf_dispose(&name); + git_str_dispose(&name); } void test_submodule_add__submodule_clone(void) diff --git a/tests/submodule/escape.c b/tests/submodule/escape.c index 08eb7680972..bcd52b510b0 100644 --- a/tests/submodule/escape.c +++ b/tests/submodule/escape.c @@ -33,17 +33,17 @@ void test_submodule_escape__from_gitdir(void) { int foundit; git_submodule *sm; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; unsigned int sm_location; g_repo = setup_fixture_submodule_simple(); - cl_git_pass(git_buf_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules")); + cl_git_pass(git_str_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules")); cl_git_rewritefile(buf.ptr, "[submodule \"" EVIL_SM_NAME "\"]\n" " path = testrepo\n" " url = ../testrepo.git\n"); - git_buf_dispose(&buf); + git_str_dispose(&buf); /* Find it all the different ways we know about it */ foundit = 0; @@ -67,17 +67,17 @@ void test_submodule_escape__from_gitdir_windows(void) { int foundit; git_submodule *sm; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; unsigned int sm_location; g_repo = setup_fixture_submodule_simple(); - cl_git_pass(git_buf_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules")); + cl_git_pass(git_str_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules")); cl_git_rewritefile(buf.ptr, "[submodule \"" EVIL_SM_NAME_WINDOWS "\"]\n" " path = testrepo\n" " url = ../testrepo.git\n"); - git_buf_dispose(&buf); + git_str_dispose(&buf); /* Find it all the different ways we know about it */ foundit = 0; diff --git a/tests/submodule/init.c b/tests/submodule/init.c index a1d870b9e74..bf865a9e81d 100644 --- a/tests/submodule/init.c +++ b/tests/submodule/init.c @@ -15,13 +15,13 @@ void test_submodule_init__absolute_url(void) { git_submodule *sm; git_config *cfg; - git_buf absolute_url = GIT_BUF_INIT; + git_str absolute_url = GIT_STR_INIT; const char *config_url; g_repo = setup_fixture_submodule_simple(); cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); - cl_git_pass(git_buf_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); + cl_git_pass(git_str_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); /* write the absolute url to the .gitmodules file*/ cl_git_pass(git_submodule_set_url(g_repo, "testrepo", absolute_url.ptr)); @@ -39,7 +39,7 @@ void test_submodule_init__absolute_url(void) cl_git_pass(git_config_get_string(&config_url, cfg, "submodule.testrepo.url")); cl_assert_equal_s(absolute_url.ptr, config_url); - git_buf_dispose(&absolute_url); + git_str_dispose(&absolute_url); git_config_free(cfg); git_submodule_free(sm); } @@ -48,13 +48,13 @@ void test_submodule_init__relative_url(void) { git_submodule *sm; git_config *cfg; - git_buf absolute_url = GIT_BUF_INIT; + git_str absolute_url = GIT_STR_INIT; const char *config_url; g_repo = setup_fixture_submodule_simple(); cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); - cl_git_pass(git_buf_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); + cl_git_pass(git_str_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo")); @@ -69,7 +69,7 @@ void test_submodule_init__relative_url(void) cl_git_pass(git_config_get_string(&config_url, cfg, "submodule.testrepo.url")); cl_assert_equal_s(absolute_url.ptr, config_url); - git_buf_dispose(&absolute_url); + git_str_dispose(&absolute_url); git_config_free(cfg); git_submodule_free(sm); } @@ -78,7 +78,7 @@ void test_submodule_init__relative_url_detached_head(void) { git_submodule *sm; git_config *cfg; - git_buf absolute_url = GIT_BUF_INIT; + git_str absolute_url = GIT_STR_INIT; const char *config_url; git_reference *head_ref = NULL; git_object *head_commit = NULL; @@ -92,7 +92,7 @@ void test_submodule_init__relative_url_detached_head(void) cl_git_pass(git_repository_set_head_detached(g_repo, git_commit_id((git_commit *)head_commit))); cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); - cl_git_pass(git_buf_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); + cl_git_pass(git_str_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo")); @@ -107,7 +107,7 @@ void test_submodule_init__relative_url_detached_head(void) cl_git_pass(git_config_get_string(&config_url, cfg, "submodule.testrepo.url")); cl_assert_equal_s(absolute_url.ptr, config_url); - git_buf_dispose(&absolute_url); + git_str_dispose(&absolute_url); git_config_free(cfg); git_object_free(head_commit); git_reference_free(head_ref); diff --git a/tests/submodule/inject_option.c b/tests/submodule/inject_option.c index cfc02acff53..e28ff848901 100644 --- a/tests/submodule/inject_option.c +++ b/tests/submodule/inject_option.c @@ -33,14 +33,14 @@ void test_submodule_inject_option__url(void) { int foundit; git_submodule *sm; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules")); + cl_git_pass(git_str_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules")); cl_git_rewritefile(buf.ptr, "[submodule \"naughty\"]\n" " path = testrepo\n" " url = -u./payload\n"); - git_buf_dispose(&buf); + git_str_dispose(&buf); /* We do want to find it, but with the appropriate field empty */ foundit = 0; @@ -58,14 +58,14 @@ void test_submodule_inject_option__path(void) { int foundit; git_submodule *sm; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules")); + cl_git_pass(git_str_joinpath(&buf, git_repository_workdir(g_repo), ".gitmodules")); cl_git_rewritefile(buf.ptr, "[submodule \"naughty\"]\n" " path = --something\n" " url = blah.git\n"); - git_buf_dispose(&buf); + git_str_dispose(&buf); /* We do want to find it, but with the appropriate field empty */ foundit = 0; diff --git a/tests/submodule/lookup.c b/tests/submodule/lookup.c index f49ebb4bdc6..acfdc838c26 100644 --- a/tests/submodule/lookup.c +++ b/tests/submodule/lookup.c @@ -255,7 +255,7 @@ static void add_submodule_with_commit(const char *name) git_submodule *sm; git_repository *smrepo; git_index *idx; - git_buf p = GIT_BUF_INIT; + git_str p = GIT_STR_INIT; cl_git_pass(git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", name, 1)); @@ -265,9 +265,9 @@ static void add_submodule_with_commit(const char *name) cl_git_pass(git_submodule_open(&smrepo, sm)); cl_git_pass(git_repository_index(&idx, smrepo)); - cl_git_pass(git_buf_joinpath(&p, git_repository_workdir(smrepo), "file")); + cl_git_pass(git_str_joinpath(&p, git_repository_workdir(smrepo), "file")); cl_git_mkfile(p.ptr, "new file"); - git_buf_dispose(&p); + git_str_dispose(&p); cl_git_pass(git_index_add_bypath(idx, "file")); cl_git_pass(git_index_write(idx)); @@ -284,7 +284,7 @@ static void add_submodule_with_commit(const char *name) void test_submodule_lookup__just_added(void) { git_submodule *sm; - git_buf snap1 = GIT_BUF_INIT, snap2 = GIT_BUF_INIT; + git_str snap1 = GIT_STR_INIT, snap2 = GIT_STR_INIT; git_reference *original_head = NULL; refute_submodule_exists(g_repo, "sm_just_added", GIT_ENOTFOUND); @@ -333,7 +333,7 @@ void test_submodule_lookup__just_added(void) baseline_tests(); cl_git_rewritefile("submod2/.gitmodules", snap2.ptr); - git_buf_dispose(&snap2); + git_str_dispose(&snap2); refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND); @@ -344,7 +344,7 @@ void test_submodule_lookup__just_added(void) baseline_tests(); cl_git_rewritefile("submod2/.gitmodules", snap1.ptr); - git_buf_dispose(&snap1); + git_str_dispose(&snap1); refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND); refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND); diff --git a/tests/submodule/modify.c b/tests/submodule/modify.c index 654f677e606..fd3b0f80bbf 100644 --- a/tests/submodule/modify.c +++ b/tests/submodule/modify.c @@ -213,7 +213,7 @@ void test_submodule_modify__set_url(void) void test_submodule_modify__set_relative_url(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_repository *repo; git_submodule *sm; @@ -222,12 +222,12 @@ void test_submodule_modify__set_relative_url(void) cl_git_pass(git_submodule_sync(sm)); cl_git_pass(git_submodule_open(&repo, sm)); - cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), "relative-url")); + cl_git_pass(git_str_joinpath(&path, clar_sandbox_path(), "relative-url")); assert_config_entry_value(g_repo, "submodule."SM1".url", path.ptr); assert_config_entry_value(repo, "remote.origin.url", path.ptr); git_repository_free(repo); git_submodule_free(sm); - git_buf_dispose(&path); + git_str_dispose(&path); } diff --git a/tests/submodule/nosubs.c b/tests/submodule/nosubs.c index e47ee39836e..e82230e87c2 100644 --- a/tests/submodule/nosubs.c +++ b/tests/submodule/nosubs.c @@ -69,7 +69,7 @@ void test_submodule_nosubs__add_and_delete(void) { git_repository *repo = cl_git_sandbox_init("status"); git_submodule *sm; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; cl_git_fail(git_submodule_lookup(NULL, repo, "libgit2")); cl_git_fail(git_submodule_lookup(NULL, repo, "submodules/libgit2")); @@ -85,7 +85,7 @@ void test_submodule_nosubs__add_and_delete(void) cl_git_pass(git_futils_readbuffer(&buf, "status/.gitmodules")); cl_assert(strstr(buf.ptr, "[submodule \"submodules/libgit2\"]") != NULL); cl_assert(strstr(buf.ptr, "path = submodules/libgit2") != NULL); - git_buf_dispose(&buf); + git_str_dispose(&buf); /* lookup */ diff --git a/tests/submodule/open.c b/tests/submodule/open.c index a8a5dccc34e..4f31feedf9d 100644 --- a/tests/submodule/open.c +++ b/tests/submodule/open.c @@ -23,33 +23,33 @@ void test_submodule_open__cleanup(void) static void assert_sm_valid(git_repository *parent, git_repository *child, const char *sm_name) { - git_buf expected = GIT_BUF_INIT, actual = GIT_BUF_INIT; + git_str expected = GIT_STR_INIT, actual = GIT_STR_INIT; /* assert working directory */ - cl_git_pass(git_buf_joinpath(&expected, git_repository_workdir(parent), sm_name)); + cl_git_pass(git_str_joinpath(&expected, git_repository_workdir(parent), sm_name)); cl_git_pass(git_path_prettify_dir(&expected, expected.ptr, NULL)); - cl_git_pass(git_buf_sets(&actual, git_repository_workdir(child))); + cl_git_pass(git_str_sets(&actual, git_repository_workdir(child))); cl_git_pass(git_path_prettify_dir(&actual, actual.ptr, NULL)); cl_assert_equal_s(expected.ptr, actual.ptr); - git_buf_clear(&expected); - git_buf_clear(&actual); + git_str_clear(&expected); + git_str_clear(&actual); /* assert common directory */ - cl_git_pass(git_buf_joinpath(&expected, git_repository_commondir(parent), "modules")); - cl_git_pass(git_buf_joinpath(&expected, expected.ptr, sm_name)); + cl_git_pass(git_str_joinpath(&expected, git_repository_commondir(parent), "modules")); + cl_git_pass(git_str_joinpath(&expected, expected.ptr, sm_name)); cl_git_pass(git_path_prettify_dir(&expected, expected.ptr, NULL)); - cl_git_pass(git_buf_sets(&actual, git_repository_commondir(child))); + cl_git_pass(git_str_sets(&actual, git_repository_commondir(child))); cl_git_pass(git_path_prettify_dir(&actual, actual.ptr, NULL)); cl_assert_equal_s(expected.ptr, actual.ptr); /* assert git directory */ - cl_git_pass(git_buf_sets(&actual, git_repository_path(child))); + cl_git_pass(git_str_sets(&actual, git_repository_path(child))); cl_git_pass(git_path_prettify_dir(&actual, actual.ptr, NULL)); cl_assert_equal_s(expected.ptr, actual.ptr); - git_buf_dispose(&expected); - git_buf_dispose(&actual); + git_str_dispose(&expected); + git_str_dispose(&actual); } void test_submodule_open__opening_via_lookup_succeeds(void) @@ -61,18 +61,18 @@ void test_submodule_open__opening_via_lookup_succeeds(void) void test_submodule_open__direct_open_succeeds(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_parent), "sm_unchanged")); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_parent), "sm_unchanged")); cl_git_pass(git_repository_open(&g_child, path.ptr)); assert_sm_valid(g_parent, g_child, "sm_unchanged"); - git_buf_dispose(&path); + git_str_dispose(&path); } void test_submodule_open__direct_open_succeeds_for_broken_sm_with_gitdir(void) { - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; /* * This is actually not a valid submodule, but we @@ -82,9 +82,9 @@ void test_submodule_open__direct_open_succeeds_for_broken_sm_with_gitdir(void) * add a test for this. */ cl_git_mkfile("submod2/.git/modules/sm_unchanged/gitdir", ".git"); - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_parent), "sm_unchanged")); + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_parent), "sm_unchanged")); cl_git_pass(git_repository_open(&g_child, path.ptr)); assert_sm_valid(g_parent, g_child, "sm_unchanged"); - git_buf_dispose(&path); + git_str_dispose(&path); } diff --git a/tests/submodule/repository_init.c b/tests/submodule/repository_init.c index 9962af311ef..3927afc2e06 100644 --- a/tests/submodule/repository_init.c +++ b/tests/submodule/repository_init.c @@ -11,7 +11,7 @@ void test_submodule_repository_init__basic(void) { git_submodule *sm; git_repository *repo; - git_buf dot_git_content = GIT_BUF_INIT; + git_str dot_git_content = GIT_STR_INIT; g_repo = setup_fixture_submod2(); @@ -34,5 +34,5 @@ void test_submodule_repository_init__basic(void) git_submodule_free(sm); git_repository_free(repo); - git_buf_dispose(&dot_git_content); + git_str_dispose(&dot_git_content); } diff --git a/tests/submodule/status.c b/tests/submodule/status.c index 06595cc9aa2..1d41337b7c3 100644 --- a/tests/submodule/status.c +++ b/tests/submodule/status.c @@ -31,10 +31,10 @@ void test_submodule_status__unchanged(void) static void rm_submodule(const char *name) { - git_buf path = GIT_BUF_INIT; - cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), name)); + git_str path = GIT_STR_INIT; + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), name)); cl_git_pass(git_futils_rmdir_r(path.ptr, NULL, GIT_RMDIR_REMOVE_FILES)); - git_buf_dispose(&path); + git_str_dispose(&path); } static void add_submodule_to_index(const char *name) diff --git a/tests/submodule/submodule_helpers.c b/tests/submodule/submodule_helpers.c index 1d4759616d0..95d20a009ac 100644 --- a/tests/submodule/submodule_helpers.c +++ b/tests/submodule/submodule_helpers.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "buffer.h" #include "path.h" #include "util.h" #include "posix.h" @@ -12,12 +11,12 @@ */ void rewrite_gitmodules(const char *workdir) { - git_buf in_f = GIT_BUF_INIT, out_f = GIT_BUF_INIT, path = GIT_BUF_INIT; + git_str in_f = GIT_STR_INIT, out_f = GIT_STR_INIT, path = GIT_STR_INIT; FILE *in, *out; char line[256]; - cl_git_pass(git_buf_joinpath(&in_f, workdir, "gitmodules")); - cl_git_pass(git_buf_joinpath(&out_f, workdir, ".gitmodules")); + cl_git_pass(git_str_joinpath(&in_f, workdir, "gitmodules")); + cl_git_pass(git_str_joinpath(&out_f, workdir, ".gitmodules")); cl_assert((in = fopen(in_f.ptr, "rb")) != NULL); cl_assert((out = fopen(out_f.ptr, "wb")) != NULL); @@ -32,16 +31,16 @@ void rewrite_gitmodules(const char *workdir) scan += strlen("path ="); while (*scan == ' ') scan++; - git_buf_joinpath(&path, workdir, scan); - git_buf_rtrim(&path); - git_buf_joinpath(&path, path.ptr, ".gitted"); + git_str_joinpath(&path, workdir, scan); + git_str_rtrim(&path); + git_str_joinpath(&path, path.ptr, ".gitted"); - if (!git_buf_oom(&path) && p_access(path.ptr, F_OK) == 0) { - git_buf_joinpath(&out_f, workdir, scan); - git_buf_rtrim(&out_f); - git_buf_joinpath(&out_f, out_f.ptr, ".git"); + if (!git_str_oom(&path) && p_access(path.ptr, F_OK) == 0) { + git_str_joinpath(&out_f, workdir, scan); + git_str_rtrim(&out_f); + git_str_joinpath(&out_f, out_f.ptr, ".git"); - if (!git_buf_oom(&out_f)) + if (!git_str_oom(&out_f)) p_rename(path.ptr, out_f.ptr); } } @@ -57,18 +56,18 @@ void rewrite_gitmodules(const char *workdir) while (*scan == ' ') scan++; if (*scan == '.') { - git_buf_joinpath(&path, workdir, scan); - git_buf_rtrim(&path); + git_str_joinpath(&path, workdir, scan); + git_str_rtrim(&path); } else if (!*scan || *scan == '\n') { - git_buf_joinpath(&path, workdir, "../testrepo.git"); + git_str_joinpath(&path, workdir, "../testrepo.git"); } else { fputs(line, out); continue; } git_path_prettify(&path, path.ptr, NULL); - git_buf_putc(&path, '\n'); - cl_assert(!git_buf_oom(&path)); + git_str_putc(&path, '\n'); + cl_assert(!git_str_oom(&path)); fwrite(line, scan - line, sizeof(char), out); fputs(path.ptr, out); @@ -79,9 +78,9 @@ void rewrite_gitmodules(const char *workdir) cl_must_pass(p_unlink(in_f.ptr)); - git_buf_dispose(&in_f); - git_buf_dispose(&out_f); - git_buf_dispose(&path); + git_str_dispose(&in_f); + git_str_dispose(&out_f); + git_str_dispose(&path); } static void cleanup_fixture_submodules(void *payload) diff --git a/tests/valgrind-supp-mac.txt b/tests/valgrind-supp-mac.txt index a104199e27a..3298abee659 100644 --- a/tests/valgrind-supp-mac.txt +++ b/tests/valgrind-supp-mac.txt @@ -3,9 +3,9 @@ Memcheck:Leak ... fun:git__realloc - fun:git_buf_try_grow - fun:git_buf_grow - fun:git_buf_vprintf + fun:git_str_try_grow + fun:git_str_grow + fun:git_str_vprintf fun:git_error_set } { diff --git a/tests/win32/forbidden.c b/tests/win32/forbidden.c index e02f411792b..5c007987b16 100644 --- a/tests/win32/forbidden.c +++ b/tests/win32/forbidden.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "repository.h" -#include "buffer.h" #include "submodule.h" static const char *repo_name = "win32-forbidden"; diff --git a/tests/win32/longpath.c b/tests/win32/longpath.c index f8b8c4b0ae8..4be86db5a61 100644 --- a/tests/win32/longpath.c +++ b/tests/win32/longpath.c @@ -2,11 +2,10 @@ #include "git2/clone.h" #include "clone.h" -#include "buffer.h" #include "futils.h" #include "repository.h" -static git_buf path = GIT_BUF_INIT; +static git_str path = GIT_STR_INIT; #define LONG_FILENAME "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt" @@ -18,20 +17,20 @@ void test_win32_longpath__initialize(void) size_t remain = MAX_PATH - base_len; size_t i; - git_buf_clear(&path); - git_buf_puts(&path, base); - git_buf_putc(&path, '/'); + git_str_clear(&path); + git_str_puts(&path, base); + git_str_putc(&path, '/'); cl_assert(remain < (MAX_PATH - 5)); for (i = 0; i < (remain - 5); i++) - git_buf_putc(&path, 'a'); + git_str_putc(&path, 'a'); #endif } void test_win32_longpath__cleanup(void) { - git_buf_dispose(&path); + git_str_dispose(&path); cl_git_sandbox_cleanup(); } @@ -49,7 +48,7 @@ void test_win32_longpath__workdir_path_validated(void) { #ifdef GIT_WIN32 git_repository *repo = cl_git_sandbox_init("testrepo"); - git_buf out = GIT_BUF_INIT; + git_str out = GIT_STR_INIT; cl_git_pass(git_repository_workdir_path(&out, repo, "a.txt")); @@ -60,7 +59,7 @@ void test_win32_longpath__workdir_path_validated(void) cl_repo_set_bool(repo, "core.longpaths", true); cl_git_pass(git_repository_workdir_path(&out, repo, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt")); cl_git_pass(git_repository_workdir_path(&out, repo, LONG_FILENAME)); - git_buf_dispose(&out); + git_str_dispose(&out); #endif } @@ -68,7 +67,7 @@ void test_win32_longpath__workdir_path_validated(void) static void assert_longpath_status_and_add(git_repository *repo, const char *wddata, const char *repodata) { git_index *index; git_blob *blob; - git_buf out = GIT_BUF_INIT; + git_str out = GIT_STR_INIT; const git_index_entry *entry; unsigned int status_flags; @@ -91,7 +90,7 @@ static void assert_longpath_status_and_add(git_repository *repo, const char *wdd git_blob_free(blob); git_index_free(index); - git_buf_dispose(&out); + git_str_dispose(&out); } #endif diff --git a/tests/worktree/merge.c b/tests/worktree/merge.c index 2a1206032c8..8bb95d1f706 100644 --- a/tests/worktree/merge.c +++ b/tests/worktree/merge.c @@ -57,7 +57,7 @@ void test_worktree_merge__merge_setup(void) { git_reference *ours_ref, *theirs_ref; git_annotated_commit *ours, *theirs; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; unsigned i; cl_git_pass(git_reference_lookup(&ours_ref, fixture.worktree, MASTER_BRANCH)); @@ -70,13 +70,13 @@ void test_worktree_merge__merge_setup(void) ours, (const git_annotated_commit **)&theirs, 1)); for (i = 0; i < ARRAY_SIZE(merge_files); i++) { - cl_git_pass(git_buf_joinpath(&path, + cl_git_pass(git_str_joinpath(&path, fixture.worktree->gitdir, merge_files[i])); cl_assert(git_path_exists(path.ptr)); } - git_buf_dispose(&path); + git_str_dispose(&path); git_reference_free(ours_ref); git_reference_free(theirs_ref); git_annotated_commit_free(ours); @@ -85,7 +85,7 @@ void test_worktree_merge__merge_setup(void) void test_worktree_merge__merge_conflict(void) { - git_buf path = GIT_BUF_INIT, buf = GIT_BUF_INIT; + git_str path = GIT_STR_INIT, buf = GIT_STR_INIT; git_reference *theirs_ref; git_annotated_commit *theirs; git_index *index; @@ -111,11 +111,11 @@ void test_worktree_merge__merge_conflict(void) git_annotated_commit_free(theirs); git_index_free(index); - cl_git_pass(git_buf_joinpath(&path, fixture.worktree->workdir, "branch_file.txt")); + cl_git_pass(git_str_joinpath(&path, fixture.worktree->workdir, "branch_file.txt")); cl_git_pass(git_futils_readbuffer(&buf, path.ptr)); cl_assert_equal_s(buf.ptr, CONFLICT_BRANCH_FILE_TXT); - git_buf_dispose(&path); - git_buf_dispose(&buf); + git_str_dispose(&path); + git_str_dispose(&buf); } diff --git a/tests/worktree/open.c b/tests/worktree/open.c index 52d47334c11..0c3fdc173f2 100644 --- a/tests/worktree/open.c +++ b/tests/worktree/open.c @@ -55,17 +55,17 @@ void test_worktree_open__repository_through_gitlink(void) void test_worktree_open__repository_through_gitdir(void) { - git_buf gitdir_path = GIT_BUF_INIT; + git_str gitdir_path = GIT_STR_INIT; git_repository *wt; - cl_git_pass(git_buf_joinpath(&gitdir_path, COMMON_REPO, ".git")); - cl_git_pass(git_buf_joinpath(&gitdir_path, gitdir_path.ptr, "worktrees")); - cl_git_pass(git_buf_joinpath(&gitdir_path, gitdir_path.ptr, "testrepo-worktree")); + cl_git_pass(git_str_joinpath(&gitdir_path, COMMON_REPO, ".git")); + cl_git_pass(git_str_joinpath(&gitdir_path, gitdir_path.ptr, "worktrees")); + cl_git_pass(git_str_joinpath(&gitdir_path, gitdir_path.ptr, "testrepo-worktree")); cl_git_pass(git_repository_open(&wt, gitdir_path.ptr)); assert_worktree_valid(wt, COMMON_REPO, WORKTREE_REPO); - git_buf_dispose(&gitdir_path); + git_str_dispose(&gitdir_path); git_repository_free(wt); } diff --git a/tests/worktree/refs.c b/tests/worktree/refs.c index 27dc667eaa8..5ae17ca1919 100644 --- a/tests/worktree/refs.c +++ b/tests/worktree/refs.c @@ -177,9 +177,9 @@ void test_worktree_refs__creating_refs_uses_commondir(void) { git_reference *head, *branch, *lookup; git_commit *commit; - git_buf refpath = GIT_BUF_INIT; + git_str refpath = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&refpath, + cl_git_pass(git_str_joinpath(&refpath, git_repository_commondir(fixture.worktree), "refs/heads/testbranch")); cl_assert(!git_path_exists(refpath.ptr)); @@ -194,5 +194,5 @@ void test_worktree_refs__creating_refs_uses_commondir(void) git_reference_free(branch); git_reference_free(head); git_commit_free(commit); - git_buf_dispose(&refpath); + git_str_dispose(&refpath); } diff --git a/tests/worktree/submodule.c b/tests/worktree/submodule.c index 2e62c039c41..4c6c657d385 100644 --- a/tests/worktree/submodule.c +++ b/tests/worktree/submodule.c @@ -61,14 +61,14 @@ void test_worktree_submodule__open_discovered_submodule_worktree(void) void test_worktree_submodule__resolve_relative_url(void) { - git_buf wt_path = GIT_BUF_INIT; + git_str wt_path = GIT_STR_INIT; git_buf sm_relative_path = GIT_BUF_INIT, wt_relative_path = GIT_BUF_INIT; git_repository *repo; git_worktree *wt; cl_git_pass(git_futils_mkdir("subdir", 0755, GIT_MKDIR_PATH)); cl_git_pass(git_path_prettify_dir(&wt_path, "subdir", NULL)); - cl_git_pass(git_buf_joinpath(&wt_path, wt_path.ptr, "wt")); + cl_git_pass(git_str_joinpath(&wt_path, wt_path.ptr, "wt")); /* Open child repository, which is a submodule */ cl_git_pass(git_repository_open(&child.repo, WORKTREE_CHILD)); @@ -86,7 +86,7 @@ void test_worktree_submodule__resolve_relative_url(void) git_worktree_free(wt); git_repository_free(repo); - git_buf_dispose(&wt_path); + git_str_dispose(&wt_path); git_buf_dispose(&sm_relative_path); git_buf_dispose(&wt_relative_path); } diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index 9b87bfae64f..a9a50fbf149 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -40,11 +40,11 @@ void test_worktree_worktree__list_with_invalid_worktree_dirs(void) { "gitdir", "HEAD" }, { "HEAD", "commondir" }, }; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_strarray wts; size_t i, j, len; - cl_git_pass(git_buf_joinpath(&path, + cl_git_pass(git_str_joinpath(&path, fixture.repo->commondir, "worktrees/invalid")); cl_git_pass(p_mkdir(path.ptr, 0755)); @@ -54,8 +54,8 @@ void test_worktree_worktree__list_with_invalid_worktree_dirs(void) for (i = 0; i < ARRAY_SIZE(filesets); i++) { for (j = 0; j < ARRAY_SIZE(filesets[i]); j++) { - git_buf_truncate(&path, len); - cl_git_pass(git_buf_joinpath(&path, path.ptr, filesets[i][j])); + git_str_truncate(&path, len); + cl_git_pass(git_str_joinpath(&path, path.ptr, filesets[i][j])); cl_git_pass(p_close(p_creat(path.ptr, 0644))); } @@ -65,13 +65,13 @@ void test_worktree_worktree__list_with_invalid_worktree_dirs(void) git_strarray_dispose(&wts); for (j = 0; j < ARRAY_SIZE(filesets[i]); j++) { - git_buf_truncate(&path, len); - cl_git_pass(git_buf_joinpath(&path, path.ptr, filesets[i][j])); + git_str_truncate(&path, len); + cl_git_pass(git_str_joinpath(&path, path.ptr, filesets[i][j])); p_unlink(path.ptr); } } - git_buf_dispose(&path); + git_str_dispose(&path); } void test_worktree_worktree__list_in_worktree_repo(void) @@ -100,11 +100,11 @@ void test_worktree_worktree__list_without_worktrees(void) void test_worktree_worktree__lookup(void) { git_worktree *wt; - git_buf gitdir_path = GIT_BUF_INIT; + git_str gitdir_path = GIT_STR_INIT; cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); - cl_git_pass(git_buf_joinpath(&gitdir_path, fixture.repo->commondir, "worktrees/testrepo-worktree/")); + cl_git_pass(git_str_joinpath(&gitdir_path, fixture.repo->commondir, "worktrees/testrepo-worktree/")); cl_assert_equal_s(wt->gitdir_path, gitdir_path.ptr); cl_assert_equal_s(wt->parent_path, fixture.repo->workdir); @@ -112,7 +112,7 @@ void test_worktree_worktree__lookup(void) cl_assert_equal_s(wt->commondir_path, fixture.repo->gitdir); cl_assert_equal_s(wt->commondir_path, fixture.repo->commondir); - git_buf_dispose(&gitdir_path); + git_str_dispose(&gitdir_path); git_worktree_free(wt); } @@ -143,10 +143,10 @@ void test_worktree_worktree__open_invalid_commondir(void) { git_worktree *wt; git_repository *repo; - git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT, path = GIT_STR_INIT; - cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/commondir")); - cl_git_pass(git_buf_joinpath(&path, + cl_git_pass(git_str_sets(&buf, "/path/to/nonexistent/commondir")); + cl_git_pass(git_str_joinpath(&path, fixture.repo->commondir, "worktrees/testrepo-worktree/commondir")); cl_git_pass(git_futils_writebuffer(&buf, path.ptr, O_RDWR, 0644)); @@ -154,8 +154,8 @@ void test_worktree_worktree__open_invalid_commondir(void) cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_git_fail(git_repository_open_from_worktree(&repo, wt)); - git_buf_dispose(&buf); - git_buf_dispose(&path); + git_str_dispose(&buf); + git_str_dispose(&path); git_worktree_free(wt); } @@ -163,10 +163,10 @@ void test_worktree_worktree__open_invalid_gitdir(void) { git_worktree *wt; git_repository *repo; - git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT, path = GIT_STR_INIT; - cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/gitdir")); - cl_git_pass(git_buf_joinpath(&path, + cl_git_pass(git_str_sets(&buf, "/path/to/nonexistent/gitdir")); + cl_git_pass(git_str_joinpath(&path, fixture.repo->commondir, "worktrees/testrepo-worktree/gitdir")); cl_git_pass(git_futils_writebuffer(&buf, path.ptr, O_RDWR, 0644)); @@ -174,8 +174,8 @@ void test_worktree_worktree__open_invalid_gitdir(void) cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_git_fail(git_repository_open_from_worktree(&repo, wt)); - git_buf_dispose(&buf); - git_buf_dispose(&path); + git_str_dispose(&buf); + git_str_dispose(&path); git_worktree_free(wt); } @@ -183,16 +183,16 @@ void test_worktree_worktree__open_invalid_parent(void) { git_worktree *wt; git_repository *repo; - git_buf buf = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_buf_sets(&buf, "/path/to/nonexistent/gitdir")); + cl_git_pass(git_str_sets(&buf, "/path/to/nonexistent/gitdir")); cl_git_pass(git_futils_writebuffer(&buf, fixture.worktree->gitlink, O_RDWR, 0644)); cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_git_fail(git_repository_open_from_worktree(&repo, wt)); - git_buf_dispose(&buf); + git_str_dispose(&buf); git_worktree_free(wt); } @@ -201,9 +201,9 @@ void test_worktree_worktree__init(void) git_worktree *wt; git_repository *repo; git_reference *branch; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-new")); + cl_git_pass(git_str_joinpath(&path, fixture.repo->workdir, "../worktree-new")); cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-new", path.ptr, NULL)); /* Open and verify created repo */ @@ -211,7 +211,7 @@ void test_worktree_worktree__init(void) cl_assert(git__suffixcmp(git_repository_workdir(repo), "worktree-new/") == 0); cl_git_pass(git_branch_lookup(&branch, repo, "worktree-new", GIT_BRANCH_LOCAL)); - git_buf_dispose(&path); + git_str_dispose(&path); git_worktree_free(wt); git_reference_free(branch); git_repository_free(repo); @@ -222,12 +222,12 @@ void test_worktree_worktree__add_locked(void) git_worktree *wt; git_repository *repo; git_reference *branch; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_worktree_add_options opts = GIT_WORKTREE_ADD_OPTIONS_INIT; opts.lock = 1; - cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-locked")); + cl_git_pass(git_str_joinpath(&path, fixture.repo->workdir, "../worktree-locked")); cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-locked", path.ptr, &opts)); /* Open and verify created repo */ @@ -236,7 +236,7 @@ void test_worktree_worktree__add_locked(void) cl_assert(git__suffixcmp(git_repository_workdir(repo), "worktree-locked/") == 0); cl_git_pass(git_branch_lookup(&branch, repo, "worktree-locked", GIT_BRANCH_LOCAL)); - git_buf_dispose(&path); + git_str_dispose(&path); git_worktree_free(wt); git_reference_free(branch); git_repository_free(repo); @@ -247,16 +247,16 @@ void test_worktree_worktree__init_existing_branch(void) git_reference *head, *branch; git_commit *commit; git_worktree *wt; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cl_git_pass(git_repository_head(&head, fixture.repo)); cl_git_pass(git_commit_lookup(&commit, fixture.repo, &head->target.oid)); cl_git_pass(git_branch_create(&branch, fixture.repo, "worktree-new", commit, false)); - cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-new")); + cl_git_pass(git_str_joinpath(&path, fixture.repo->workdir, "../worktree-new")); cl_git_fail(git_worktree_add(&wt, fixture.repo, "worktree-new", path.ptr, NULL)); - git_buf_dispose(&path); + git_str_dispose(&path); git_commit_free(commit); git_reference_free(head); git_reference_free(branch); @@ -268,7 +268,7 @@ void test_worktree_worktree__add_with_explicit_branch(void) git_commit *commit; git_worktree *wt; git_repository *wtrepo; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_worktree_add_options opts = GIT_WORKTREE_ADD_OPTIONS_INIT; cl_git_pass(git_repository_head(&head, fixture.repo)); @@ -277,13 +277,13 @@ void test_worktree_worktree__add_with_explicit_branch(void) opts.ref = branch; - cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-with-different-name")); + cl_git_pass(git_str_joinpath(&path, fixture.repo->workdir, "../worktree-with-different-name")); cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-with-different-name", path.ptr, &opts)); cl_git_pass(git_repository_open_from_worktree(&wtrepo, wt)); cl_git_pass(git_repository_head(&wthead, wtrepo)); cl_assert_equal_s(git_reference_name(wthead), "refs/heads/worktree-with-ref"); - git_buf_dispose(&path); + git_str_dispose(&path); git_commit_free(commit); git_reference_free(head); git_reference_free(branch); @@ -296,15 +296,15 @@ void test_worktree_worktree__add_with_explicit_branch(void) void test_worktree_worktree__init_existing_worktree(void) { git_worktree *wt; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-new")); + cl_git_pass(git_str_joinpath(&path, fixture.repo->workdir, "../worktree-new")); cl_git_fail(git_worktree_add(&wt, fixture.repo, "testrepo-worktree", path.ptr, NULL)); cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_assert_equal_s(wt->gitlink_path, fixture.worktree->gitlink); - git_buf_dispose(&path); + git_str_dispose(&path); git_worktree_free(wt); } @@ -312,42 +312,42 @@ void test_worktree_worktree__init_existing_path(void) { const char *wtfiles[] = { "HEAD", "commondir", "gitdir", "index" }; git_worktree *wt; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; unsigned i; /* Delete files to verify they have not been created by * the init call */ for (i = 0; i < ARRAY_SIZE(wtfiles); i++) { - cl_git_pass(git_buf_joinpath(&path, + cl_git_pass(git_str_joinpath(&path, fixture.worktree->gitdir, wtfiles[i])); cl_git_pass(p_unlink(path.ptr)); } - cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../testrepo-worktree")); + cl_git_pass(git_str_joinpath(&path, fixture.repo->workdir, "../testrepo-worktree")); cl_git_fail(git_worktree_add(&wt, fixture.repo, "worktree-new", path.ptr, NULL)); /* Verify files have not been re-created */ for (i = 0; i < ARRAY_SIZE(wtfiles); i++) { - cl_git_pass(git_buf_joinpath(&path, + cl_git_pass(git_str_joinpath(&path, fixture.worktree->gitdir, wtfiles[i])); cl_assert(!git_path_exists(path.ptr)); } - git_buf_dispose(&path); + git_str_dispose(&path); } void test_worktree_worktree__init_submodule(void) { git_repository *repo, *sm, *wt; git_worktree *worktree; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; cleanup_fixture_worktree(&fixture); repo = setup_fixture_submod2(); - cl_git_pass(git_buf_joinpath(&path, repo->workdir, "sm_unchanged")); + cl_git_pass(git_str_joinpath(&path, repo->workdir, "sm_unchanged")); cl_git_pass(git_repository_open(&sm, path.ptr)); - cl_git_pass(git_buf_joinpath(&path, repo->workdir, "../worktree/")); + cl_git_pass(git_str_joinpath(&path, repo->workdir, "../worktree/")); cl_git_pass(git_worktree_add(&worktree, sm, "repo-worktree", path.ptr, NULL)); cl_git_pass(git_repository_open_from_worktree(&wt, worktree)); @@ -356,10 +356,10 @@ void test_worktree_worktree__init_submodule(void) cl_git_pass(git_path_prettify_dir(&path, sm->commondir, NULL)); cl_assert_equal_s(sm->commondir, wt->commondir); - cl_git_pass(git_buf_joinpath(&path, sm->gitdir, "worktrees/repo-worktree/")); + cl_git_pass(git_str_joinpath(&path, sm->gitdir, "worktrees/repo-worktree/")); cl_assert_equal_s(path.ptr, wt->gitdir); - git_buf_dispose(&path); + git_str_dispose(&path); git_worktree_free(worktree); git_repository_free(sm); git_repository_free(wt); @@ -388,13 +388,13 @@ void test_worktree_worktree__name(void) void test_worktree_worktree__path(void) { git_worktree *wt; - git_buf expected_path = GIT_BUF_INIT; + git_str expected_path = GIT_STR_INIT; - cl_git_pass(git_buf_joinpath(&expected_path, clar_sandbox_path(), "testrepo-worktree")); + cl_git_pass(git_str_joinpath(&expected_path, clar_sandbox_path(), "testrepo-worktree")); cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_assert_equal_s(git_worktree_path(wt), expected_path.ptr); - git_buf_dispose(&expected_path); + git_str_dispose(&expected_path); git_worktree_free(wt); } From 4e14d4c6a6d4629601cc7e1659df85eeb450df10 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 26 Sep 2021 22:06:49 -0400 Subject: [PATCH 0576/1616] cmake: BUILD_CLAR is now BUILD_TESTS Nobody knows what CLAR is. The test building option should be `BUILD_TESTS`. --- CMakeLists.txt | 6 +++--- README.md | 2 +- docs/fuzzing.md | 2 +- fuzzers/corpora/objects/blob | 4 ++-- tests/CMakeLists.txt | 20 ++++++++++---------- tests/README.md | 4 ++-- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dccec3109a..81ef04f2a69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,7 @@ INCLUDE(EnableWarnings) OPTION(SONAME "Set the (SO)VERSION of the target" ON) OPTION(BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON) OPTION(THREADSAFE "Build libgit2 as threadsafe" ON) -OPTION(BUILD_CLAR "Build Tests using the Clar suite" ON) +OPTION(BUILD_TESTS "Build Tests using the Clar suite" ON) OPTION(BUILD_EXAMPLES "Build library usage example apps" OFF) OPTION(BUILD_FUZZERS "Build the fuzz targets" OFF) OPTION(ENABLE_TRACE "Enables tracing support" ON) @@ -281,7 +281,7 @@ IF (NOT MSVC) ENDIF() ENDIF () -IF (BUILD_CLAR) +IF (BUILD_TESTS) ENABLE_TESTING() ADD_SUBDIRECTORY(tests) ENDIF () @@ -295,7 +295,7 @@ IF(BUILD_FUZZERS) IF(BUILD_EXAMPLES) MESSAGE(FATAL_ERROR "Cannot build the fuzzer targets and the examples together") ENDIF() - IF(BUILD_CLAR) + IF(BUILD_TESTS) MESSAGE(FATAL_ERROR "Cannot build the fuzzer targets and the tests together") ENDIF() ENDIF() diff --git a/README.md b/README.md index 0cbde525b5a..ea1c8e29f79 100644 --- a/README.md +++ b/README.md @@ -278,7 +278,7 @@ The following CMake variables are declared: - `CMAKE_INSTALL_LIBDIR`: Where to install libraries to. - `CMAKE_INSTALL_INCLUDEDIR`: Where to install headers to. - `BUILD_SHARED_LIBS`: Build libgit2 as a Shared Library (defaults to ON) -- `BUILD_CLAR`: Build [Clar](https://github.com/vmg/clar)-based test suite (defaults to ON) +- `BUILD_TESTS`: Build the unit and integration test suites (defaults to ON) - `THREADSAFE`: Build libgit2 with threading support (defaults to ON) To list all build options and their current value, you can do the diff --git a/docs/fuzzing.md b/docs/fuzzing.md index 25b32cb0474..2bf4ccca915 100644 --- a/docs/fuzzing.md +++ b/docs/fuzzing.md @@ -19,7 +19,7 @@ automated fuzz testing. libFuzzer only works with clang. and [`leak`/`address,leak`](https://clang.llvm.org/docs/LeakSanitizer.html). 3. Create the cmake build environment and configure the build with the sanitizer chosen: `CC=/usr/bin/clang-6.0 CFLAGS="-fsanitize=address" cmake - -DBUILD_CLAR=OFF -DBUILD_FUZZERS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo ..`. + -DBUILD_TESTS=OFF -DBUILD_FUZZERS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo ..`. Note that building the fuzzer targets is incompatible with the tests and examples. 4. Build libgit2: `cmake --build .` diff --git a/fuzzers/corpora/objects/blob b/fuzzers/corpora/objects/blob index 9fe99d8d568..2031037b15b 100644 --- a/fuzzers/corpora/objects/blob +++ b/fuzzers/corpora/objects/blob @@ -64,7 +64,7 @@ slack channel once you've registered. If you have questions about the library, please be sure to check out the [API documentation](http://libgit2.github.com/libgit2/). If you still have -questions, reach out to us on Slack or post a question on +questions, reach out to us on Slack or post a question on [StackOverflow](http://stackoverflow.com/questions/tagged/libgit2) (with the `libgit2` tag). **Reporting Bugs** @@ -229,7 +229,7 @@ The following CMake variables are declared: - `LIB_INSTALL_DIR`: Where to install libraries to. - `INCLUDE_INSTALL_DIR`: Where to install headers to. - `BUILD_SHARED_LIBS`: Build libgit2 as a Shared Library (defaults to ON) -- `BUILD_CLAR`: Build [Clar](https://github.com/vmg/clar)-based test suite (defaults to ON) +- `BUILD_TESTS`: Build [Clar](https://github.com/vmg/clar)-based test suite (defaults to ON) - `THREADSAFE`: Build libgit2 with threading support (defaults to ON) - `STDCALL`: Build libgit2 as `stdcall`. Turn off for `cdecl` (Windows; defaults to ON) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 49999f4815e..74423fbd7e7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,7 +3,7 @@ FIND_PACKAGE(PythonInterp) IF(NOT PYTHONINTERP_FOUND) MESSAGE(FATAL_ERROR "Could not find a python interpeter, which is needed to build the tests. " - "Make sure python is available, or pass -DBUILD_CLAR=OFF to skip building the tests") + "Make sure python is available, or pass -DBUILD_TESTS=OFF to skip building the tests") ENDIF() SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/resources/") @@ -39,26 +39,26 @@ SET_SOURCE_FILES_PROPERTIES( INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES}) INCLUDE_DIRECTORIES(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) -ADD_EXECUTABLE(libgit2_clar ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS}) +ADD_EXECUTABLE(libgit2_tests ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS}) -SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES C_STANDARD 90) -SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) +SET_TARGET_PROPERTIES(libgit2_tests PROPERTIES C_STANDARD 90) +SET_TARGET_PROPERTIES(libgit2_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) -TARGET_INCLUDE_DIRECTORIES(libgit2_clar PRIVATE ../src PUBLIC ../include) -TARGET_LINK_LIBRARIES(libgit2_clar ${LIBGIT2_LIBS}) -IDE_SPLIT_SOURCES(libgit2_clar) +TARGET_INCLUDE_DIRECTORIES(libgit2_tests PRIVATE ../src PUBLIC ../include) +TARGET_LINK_LIBRARIES(libgit2_tests ${LIBGIT2_LIBS}) +IDE_SPLIT_SOURCES(libgit2_tests) IF (MSVC_IDE) # Precompiled headers - SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") + SET_TARGET_PROPERTIES(libgit2_tests PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") SET_SOURCE_FILES_PROPERTIES("precompiled.c" COMPILE_FLAGS "/Ycprecompiled.h") ENDIF () FUNCTION(ADD_CLAR_TEST name) IF (NOT USE_LEAK_CHECKER STREQUAL "OFF") - ADD_TEST(${name} "${libgit2_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${libgit2_BINARY_DIR}/libgit2_clar" ${ARGN}) + ADD_TEST(${name} "${libgit2_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${libgit2_BINARY_DIR}/libgit2_tests" ${ARGN}) ELSE() - ADD_TEST(${name} "${libgit2_BINARY_DIR}/libgit2_clar" ${ARGN}) + ADD_TEST(${name} "${libgit2_BINARY_DIR}/libgit2_tests" ${ARGN}) ENDIF() ENDFUNCTION(ADD_CLAR_TEST) diff --git a/tests/README.md b/tests/README.md index b1d70d3bc93..7684a6e64eb 100644 --- a/tests/README.md +++ b/tests/README.md @@ -11,7 +11,7 @@ https://github.com/vmg/clar * Make sure you actually build the tests by setting: - cmake -DBUILD_CLAR=ON build/ + cmake -DBUILD_TESTS=ON build/ * Test: @@ -32,7 +32,7 @@ These are automatically run as part of CI, but if you want to check locally: Uses [`valgrind`](http://www.valgrind.org/): ```console -$ cmake -DBUILD_CLAR=ON -DVALGRIND=ON .. +$ cmake -DBUILD_TESTS=ON -DVALGRIND=ON .. $ cmake --build . $ valgrind --leak-check=full --show-reachable=yes --num-callers=50 --suppressions=../libgit2_clar.supp \ ./libgit2_clar From cb6240bc751f78abfcc24de2339bc49b6aeefa87 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Sun, 17 Oct 2021 23:36:56 -0300 Subject: [PATCH 0577/1616] Fix a long long that crept past --- src/commit_graph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commit_graph.c b/src/commit_graph.c index f9a4bd2b270..397bee5e213 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -1075,7 +1075,7 @@ static int commit_graph_write( commit_time = (uint64_t)packed_commit->commit_time; if (generation > GIT_COMMIT_GRAPH_GENERATION_NUMBER_MAX) generation = GIT_COMMIT_GRAPH_GENERATION_NUMBER_MAX; - word = ntohl((uint32_t)((generation << 2) | ((commit_time >> 32ull) & 0x3ull))); + word = ntohl((uint32_t)((generation << 2) | ((commit_time >> UINT64_C(32)) & UINT64_C(0x3)))); error = git_str_put(&commit_data, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; From 7f5b0f0c1ad9d26163bb92fc4f0d36227ba3e68f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 26 Sep 2021 21:50:19 -0400 Subject: [PATCH 0578/1616] cmake: allow ENABLE_REPRODUCIBLE_BUILDS on macOS macOS may support ENABLE_REPRODUCIBLE_BUILDS, allow users to opt-in to it. (Especially since ENABLE_REPRODUCIBLE_BUILDS is not the default.) --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 81ef04f2a69..42cc169abd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,9 +64,7 @@ IF (UNIX) ELSE() OPTION(USE_NTLMCLIENT "Enable NTLM support on Unix." ON ) ENDIF() -ENDIF() -IF (UNIX AND NOT APPLE) OPTION(ENABLE_REPRODUCIBLE_BUILDS "Enable reproducible builds" OFF) ENDIF() From 780faa41c482aab60d08159e3301cb6b945ac496 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 26 Sep 2021 21:51:16 -0400 Subject: [PATCH 0579/1616] cmake: allow USE_ICONV on any Unix --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 42cc169abd1..229ba96830d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,9 +66,7 @@ IF (UNIX) ENDIF() OPTION(ENABLE_REPRODUCIBLE_BUILDS "Enable reproducible builds" OFF) -ENDIF() -IF (APPLE) OPTION(USE_ICONV "Link with and use iconv library" ON) ENDIF() From 8507bf81ea5cf11a99566f449e6b3af68bd02430 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 26 Sep 2021 21:54:08 -0400 Subject: [PATCH 0580/1616] trace: always enabled There's no need to make tracing opt-in; it should always be included. --- CMakeLists.txt | 1 - src/CMakeLists.txt | 6 ------ src/features.h.in | 1 - src/trace.c | 13 ------------- src/trace.h | 17 ----------------- 5 files changed, 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 229ba96830d..cab0cb268b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,6 @@ OPTION(THREADSAFE "Build libgit2 as threadsafe" ON) OPTION(BUILD_TESTS "Build Tests using the Clar suite" ON) OPTION(BUILD_EXAMPLES "Build library usage example apps" OFF) OPTION(BUILD_FUZZERS "Build the fuzz targets" OFF) -OPTION(ENABLE_TRACE "Enables tracing support" ON) OPTION(LIBGIT2_FILENAME "Name of the produced binary" OFF) OPTION(USE_SSH "Link with libssh2 to enable SSH support" ON) OPTION(USE_HTTPS "Enable HTTPS support. Can be set to a specific backend" ON) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fdb367335b4..b3d620c45ef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,12 +37,6 @@ SET(LIBGIT2_LIBS "") enable_warnings(missing-declarations) -# Enable tracing -IF(ENABLE_TRACE) - SET(GIT_TRACE 1) -ENDIF() -ADD_FEATURE_INFO(tracing GIT_TRACE "tracing support") - IF (HAVE_FUTIMENS) SET(GIT_USE_FUTIMENS 1) ENDIF () diff --git a/src/features.h.in b/src/features.h.in index 202cef49ecb..a40b6085e8f 100644 --- a/src/features.h.in +++ b/src/features.h.in @@ -5,7 +5,6 @@ #cmakedefine GIT_DEBUG_STRICT_ALLOC 1 #cmakedefine GIT_DEBUG_STRICT_OPEN 1 -#cmakedefine GIT_TRACE 1 #cmakedefine GIT_THREADS 1 #cmakedefine GIT_WIN32_LEAKCHECK 1 diff --git a/src/trace.c b/src/trace.c index c316bcacfa1..b0c56c4dc66 100644 --- a/src/trace.c +++ b/src/trace.c @@ -11,15 +11,10 @@ #include "runtime.h" #include "git2/trace.h" -#ifdef GIT_TRACE - struct git_trace_data git_trace__data = {0}; -#endif - int git_trace_set(git_trace_level_t level, git_trace_cb callback) { -#ifdef GIT_TRACE GIT_ASSERT_ARG(level == 0 || callback != NULL); git_trace__data.level = level; @@ -27,12 +22,4 @@ int git_trace_set(git_trace_level_t level, git_trace_cb callback) GIT_MEMORY_BARRIER; return 0; -#else - GIT_UNUSED(level); - GIT_UNUSED(callback); - - git_error_set(GIT_ERROR_INVALID, - "this version of libgit2 was not built with tracing."); - return -1; -#endif } diff --git a/src/trace.h b/src/trace.h index eb20ec57b0f..239928dcbce 100644 --- a/src/trace.h +++ b/src/trace.h @@ -12,8 +12,6 @@ #include #include "str.h" -#ifdef GIT_TRACE - struct git_trace_data { git_trace_level_t level; git_trace_cb callback; @@ -50,19 +48,4 @@ GIT_INLINE(void) git_trace(git_trace_level_t level, const char *fmt, ...) } } -#else - -GIT_INLINE(void) git_trace__null( - git_trace_level_t level, - const char *fmt, ...) -{ - GIT_UNUSED(level); - GIT_UNUSED(fmt); -} - -#define git_trace_level() ((git_trace_level_t)0) -#define git_trace git_trace__null - -#endif - #endif From e1be28c7cc6a352078ef8ce9ce8234a5f9a0a27a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 26 Sep 2021 22:02:04 -0400 Subject: [PATCH 0581/1616] cmake: remove unused STDCALL option The `STDCALL` option was removed; remove the (unreachable) error message. --- CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cab0cb268b0..fa226452419 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,10 +97,6 @@ ENDIF() # Platform specific compilation flags IF (MSVC) - IF (STDCALL) - MESSAGE(FATAL_ERROR "The STDCALL option is no longer supported; libgit2 is now always built as a cdecl library. If you're using PInvoke, please add the CallingConventions.Cdecl attribute for support.") - ENDIF() - ADD_DEFINITIONS(-D_SCL_SECURE_NO_WARNINGS) ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE) ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_DEPRECATE) From 52693ab44efe33d9340038c3936b9e75a70fe7bb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 26 Sep 2021 23:11:13 -0400 Subject: [PATCH 0582/1616] cmake: stylistic refactoring Ensure that we always use lowercase function names, and that we do not have spaces preceding open parentheses, for consistency. --- CMakeLists.txt | 395 +++++++++++---------- deps/chromium-zlib/CMakeLists.txt | 12 +- deps/ntlmclient/CMakeLists.txt | 62 ++-- deps/pcre/CMakeLists.txt | 176 ++++----- deps/winhttp/CMakeLists.txt | 24 +- examples/CMakeLists.txt | 22 +- fuzzers/CMakeLists.txt | 38 +- src/CMakeLists.txt | 568 +++++++++++++++--------------- tests/CMakeLists.txt | 98 +++--- 9 files changed, 704 insertions(+), 691 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fa226452419..f7b2e71ca1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,133 +1,141 @@ # CMake build script for the libgit2 project -# -# Building (out of source build): -# > mkdir build && cd build -# > cmake .. [-DSETTINGS=VALUE] -# > cmake --build . -# -# Testing: -# > ctest -V -# -# Install: -# > cmake --build . --target install +# See `README.md` for build instructions. -CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1) +cmake_minimum_required(VERSION 3.5.1) project(libgit2 VERSION "1.3.0" LANGUAGES C) # Add find modules to the path set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${libgit2_SOURCE_DIR}/cmake/") -INCLUDE(CheckLibraryExists) -INCLUDE(CheckFunctionExists) -INCLUDE(CheckSymbolExists) -INCLUDE(CheckStructHasMember) -INCLUDE(CheckPrototypeDefinition) # Added in CMake 3.0 -INCLUDE(AddCFlagIfSupported) -INCLUDE(FindPkgLibraries) -INCLUDE(FindThreads) -INCLUDE(FindStatNsec) -INCLUDE(Findfutimens) -INCLUDE(GNUInstallDirs) -INCLUDE(IdeSplitSources) -INCLUDE(FeatureSummary) -INCLUDE(EnableWarnings) +# Modules + +include(CheckLibraryExists) +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CheckStructHasMember) +include(CheckPrototypeDefinition) +include(AddCFlagIfSupported) +include(FindPkgLibraries) +include(FindThreads) +include(FindStatNsec) +include(Findfutimens) +include(GNUInstallDirs) +include(IdeSplitSources) +include(FeatureSummary) +include(EnableWarnings) +# # Build options # -OPTION(SONAME "Set the (SO)VERSION of the target" ON) -OPTION(BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON) -OPTION(THREADSAFE "Build libgit2 as threadsafe" ON) -OPTION(BUILD_TESTS "Build Tests using the Clar suite" ON) -OPTION(BUILD_EXAMPLES "Build library usage example apps" OFF) -OPTION(BUILD_FUZZERS "Build the fuzz targets" OFF) -OPTION(LIBGIT2_FILENAME "Name of the produced binary" OFF) -OPTION(USE_SSH "Link with libssh2 to enable SSH support" ON) -OPTION(USE_HTTPS "Enable HTTPS support. Can be set to a specific backend" ON) -OPTION(USE_SHA1 "Enable SHA1. Can be set to CollisionDetection(ON)/HTTPS/Generic" ON) -OPTION(USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF) -OPTION(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)" OFF) -OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF) -OPTION(DEBUG_POOL "Enable debug pool allocator" OFF) -OPTION(DEBUG_STRICT_ALLOC "Enable strict allocator behavior" OFF) -OPTION(DEBUG_STRICT_OPEN "Enable path validation in open" OFF) -OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF) -OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib. Can be set to one of Bundled(ON)/Chromium. The Chromium option requires a x86_64 processor with SSE4.2 and CLMUL" OFF) - SET(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.") -OPTION(DEPRECATE_HARD "Do not include deprecated functions in the library" OFF) - SET(REGEX_BACKEND "" CACHE STRING "Regular expression implementation. One of regcomp_l, pcre2, pcre, regcomp, or builtin.") - -IF (UNIX) - IF (NOT USE_HTTPS) - OPTION(USE_NTLMCLIENT "Enable NTLM support on Unix." OFF ) - ELSE() - OPTION(USE_NTLMCLIENT "Enable NTLM support on Unix." ON ) - ENDIF() - - OPTION(ENABLE_REPRODUCIBLE_BUILDS "Enable reproducible builds" OFF) - - OPTION(USE_ICONV "Link with and use iconv library" ON) -ENDIF() - -IF(MSVC) + +# Optional subsystems +option(THREADSAFE "Build libgit2 as threadsafe" ON) +option(BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON) +option(BUILD_TESTS "Build Tests using the Clar suite" ON) +option(BUILD_EXAMPLES "Build library usage example apps" OFF) +option(BUILD_FUZZERS "Build the fuzz targets" OFF) + +# Backend selection +option(USE_SSH "Link with libssh2 to enable SSH support" ON) +option(USE_HTTPS "Enable HTTPS support. Can be set to a specific backend" ON) +option(USE_SHA1 "Enable SHA1. Can be set to CollisionDetection(ON)/HTTPS/Generic" ON) +option(USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF) + set(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.") + set(REGEX_BACKEND "" CACHE STRING "Regular expression implementation. One of regcomp_l, pcre2, pcre, regcomp, or builtin.") +option(USE_BUNDLED_ZLIB "Use the bundled version of zlib. Can be set to one of Bundled(ON)/Chromium. The Chromium option requires a x86_64 processor with SSE4.2 and CLMUL" OFF) + +# Debugging options +option(USE_LEAK_CHECKER "Run tests with leak checker" OFF) +option(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)" OFF) +option(DEBUG_POOL "Enable debug pool allocator" OFF) +option(DEBUG_STRICT_ALLOC "Enable strict allocator behavior" OFF) +option(DEBUG_STRICT_OPEN "Enable path validation in open" OFF) + +# Output options +option(SONAME "Set the (SO)VERSION of the target" ON) +option(LIBGIT2_FILENAME "Name of the produced binary" OFF) +option(DEPRECATE_HARD "Do not include deprecated functions in the library" OFF) + +# Compilation options +option(ENABLE_WERROR "Enable compilation with -Werror" OFF) + +if(UNIX) + # NTLM client requires crypto libraries from the system HTTPS stack + if(NOT USE_HTTPS) + option(USE_NTLMCLIENT "Enable NTLM support on Unix." OFF) + else() + option(USE_NTLMCLIENT "Enable NTLM support on Unix." ON) + endif() + + option(ENABLE_REPRODUCIBLE_BUILDS "Enable reproducible builds" OFF) +endif() + +if(APPLE) + option(USE_ICONV "Link with and use iconv library" ON) +endif() + +if(MSVC) # This option must match the settings used in your program, in particular if you # are linking statically - OPTION(STATIC_CRT "Link the static CRT libraries" ON) + option(STATIC_CRT "Link the static CRT libraries" ON) # If you want to embed a copy of libssh2 into libgit2, pass a # path to libssh2 - OPTION(EMBED_SSH_PATH "Path to libssh2 to embed (Windows)" OFF) -ENDIF() + option(EMBED_SSH_PATH "Path to libssh2 to embed (Windows)" OFF) + # Enable leak checking using the debugging C runtime. + option(WIN32_LEAKCHECK "Enable leak reporting via crtdbg" OFF) +endif() -IF(WIN32) +if(WIN32) # By default, libgit2 is built with WinHTTP. To use the built-in # HTTP transport, invoke CMake with the "-DWINHTTP=OFF" argument. - OPTION(WINHTTP "Use Win32 WinHTTP routines" ON) -ENDIF() + option(WINHTTP "Use Win32 WinHTTP routines" ON) +endif() -IF(MSVC) - # Enable leak checking using the debugging C runtime. - OPTION(WIN32_LEAKCHECK "Enable leak reporting via crtdbg" OFF) -ENDIF() -IF (DEPRECATE_HARD) - ADD_DEFINITIONS(-DGIT_DEPRECATE_HARD) -ENDIF() +# +# Compiler / linker flags +# + +if(DEPRECATE_HARD) + add_definitions(-DGIT_DEPRECATE_HARD) +endif() # Platform specific compilation flags -IF (MSVC) - ADD_DEFINITIONS(-D_SCL_SECURE_NO_WARNINGS) - ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE) - ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_DEPRECATE) +if(MSVC) + add_definitions(-D_SCL_SECURE_NO_WARNINGS) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) - STRING(REPLACE "/Zm1000" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + string(REPLACE "/Zm1000" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") # /GF - String pooling # /MP - Parallel build - SET(CMAKE_C_FLAGS "/GF /MP /nologo ${CMAKE_C_FLAGS}") + set(CMAKE_C_FLAGS "/GF /MP /nologo ${CMAKE_C_FLAGS}") # /Gd - explicitly set cdecl calling convention - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gd") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gd") - IF (NOT (MSVC_VERSION LESS 1900)) + if(NOT (MSVC_VERSION LESS 1900)) # /guard:cf - Enable Control Flow Guard - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /guard:cf") - ENDIF() - - IF (STATIC_CRT) - SET(CRT_FLAG_DEBUG "/MTd") - SET(CRT_FLAG_RELEASE "/MT") - ELSE() - SET(CRT_FLAG_DEBUG "/MDd") - SET(CRT_FLAG_RELEASE "/MD") - ENDIF() - - IF (WIN32_LEAKCHECK) - SET(GIT_WIN32_LEAKCHECK 1) - SET(CRT_FLAG_DEBUG "${CRT_FLAG_DEBUG}") - SET(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} Dbghelp.lib") - ENDIF() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /guard:cf") + endif() + + if(STATIC_CRT) + set(CRT_FLAG_DEBUG "/MTd") + set(CRT_FLAG_RELEASE "/MT") + else() + set(CRT_FLAG_DEBUG "/MDd") + set(CRT_FLAG_RELEASE "/MD") + endif() + + if(WIN32_LEAKCHECK) + set(GIT_WIN32_LEAKCHECK 1) + set(CRT_FLAG_DEBUG "${CRT_FLAG_DEBUG}") + set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} Dbghelp.lib") + endif() # /Zi - Create debugging information # /Od - Disable optimization @@ -135,7 +143,7 @@ IF (MSVC) # /MTd - Statically link the multithreaded debug version of the CRT # /MDd - Dynamically link the multithreaded debug version of the CRT # /RTC1 - Run time checks - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Zi /Od /D_DEBUG /RTC1 ${CRT_FLAG_DEBUG}") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Zi /Od /D_DEBUG /RTC1 ${CRT_FLAG_DEBUG}") # /DNDEBUG - Disables asserts # /MT - Statically link the multithreaded release version of the CRT @@ -144,76 +152,80 @@ IF (MSVC) # /Oy - Enable frame pointer omission (FPO) (otherwise CMake will automatically turn it off) # /GL - Link time code generation (whole program optimization) # /Gy - Function-level linking - SET(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /Oy /GL /Gy ${CRT_FLAG_RELEASE}") + set(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /Oy /GL /Gy ${CRT_FLAG_RELEASE}") # /Oy- - Disable frame pointer omission (FPO) - SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/DNDEBUG /Zi /O2 /Oy- /GL /Gy ${CRT_FLAG_RELEASE}") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "/DNDEBUG /Zi /O2 /Oy- /GL /Gy ${CRT_FLAG_RELEASE}") # /O1 - Optimize for size - SET(CMAKE_C_FLAGS_MINSIZEREL "/DNDEBUG /O1 /Oy /GL /Gy ${CRT_FLAG_RELEASE}") + set(CMAKE_C_FLAGS_MINSIZEREL "/DNDEBUG /O1 /Oy /GL /Gy ${CRT_FLAG_RELEASE}") # /IGNORE:4221 - Ignore empty compilation units - SET(CMAKE_STATIC_LINKER_FLAGS "/IGNORE:4221") + set(CMAKE_STATIC_LINKER_FLAGS "/IGNORE:4221") # /DYNAMICBASE - Address space load randomization (ASLR) # /NXCOMPAT - Data execution prevention (DEP) # /LARGEADDRESSAWARE - >2GB user address space on x86 # /VERSION - Embed version information in PE header - SET(CMAKE_EXE_LINKER_FLAGS "/DYNAMICBASE /NXCOMPAT /LARGEADDRESSAWARE /VERSION:${libgit2_VERSION_MAJOR}.${libgit2_VERSION_MINOR}") + set(CMAKE_EXE_LINKER_FLAGS "/DYNAMICBASE /NXCOMPAT /LARGEADDRESSAWARE /VERSION:${libgit2_VERSION_MAJOR}.${libgit2_VERSION_MINOR}") - IF (NOT (MSVC_VERSION LESS 1900)) + if(NOT (MSVC_VERSION LESS 1900)) # /GUARD:CF - Enable Control Flow Guard - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /GUARD:CF") - ENDIF() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /GUARD:CF") + endif() # /DEBUG - Create a PDB # /LTCG - Link time code generation (whole program optimization) # /OPT:REF /OPT:ICF - Fold out duplicate code at link step # /INCREMENTAL:NO - Required to use /LTCG # /DEBUGTYPE:cv,fixup - Additional data embedded in the PDB (requires /INCREMENTAL:NO, so not on for Debug) - SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG") - SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO") - SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG /RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO /DEBUGTYPE:cv,fixup") - SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO") + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO") + set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG /RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO /DEBUGTYPE:cv,fixup") + set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO") # Same linker settings for DLL as EXE - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") - SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") - SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") - SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}") - SET(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}") -ELSE () - IF (ENABLE_REPRODUCIBLE_BUILDS) - SET(CMAKE_C_ARCHIVE_CREATE " Dqc ") - SET(CMAKE_C_ARCHIVE_APPEND " Dq ") - SET(CMAKE_C_ARCHIVE_FINISH " -D ") - ENDIF() - - SET(CMAKE_C_FLAGS "-D_GNU_SOURCE ${CMAKE_C_FLAGS}") - - ENABLE_WARNINGS(all) - ENABLE_WARNINGS(extra) - - IF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - SET(CMAKE_C_FLAGS "-D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS ${CMAKE_C_FLAGS}") - ENDIF() - - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -O0") - - IF (MINGW OR MSYS) # MinGW and MSYS always do PIC and complain if we tell them to - STRING(REGEX REPLACE "-fPIC" "" CMAKE_SHARED_LIBRARY_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}") - ELSEIF (BUILD_SHARED_LIBS) - ADD_C_FLAG_IF_SUPPORTED(-fvisibility=hidden) - - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") - ENDIF () - - IF (MINGW) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") + set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") + set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}") + set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}") +else() + if(ENABLE_REPRODUCIBLE_BUILDS) + set(CMAKE_C_ARCHIVE_CREATE " Dqc ") + set(CMAKE_C_ARCHIVE_APPEND " Dq ") + set(CMAKE_C_ARCHIVE_FINISH " -D ") + endif() + + if(NOT BUILD_SHARED_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + endif() + + set(CMAKE_C_FLAGS "-D_GNU_SOURCE ${CMAKE_C_FLAGS}") + + enable_warnings(all) + enable_warnings(extra) + + if(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") + set(CMAKE_C_FLAGS "-D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS ${CMAKE_C_FLAGS}") + endif() + + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -O0") + + if(MINGW OR MSYS) # MinGW and MSYS always do PIC and complain if we tell them to + string(REGEX REPLACE "-fPIC" "" CMAKE_SHARED_LIBRARY_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}") + elseif(BUILD_SHARED_LIBS) + add_c_flag_IF_SUPPORTED(-fvisibility=hidden) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + endif() + + if(MINGW) # MinGW >= 3.14 uses the C99-style stdio functions # automatically, but forks like mingw-w64 still want # us to define this in order to use them - ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO=1) - ENDIF () + add_definitions(-D__USE_MINGW_ANSI_STDIO=1) + endif() enable_warnings(documentation) disable_warnings(documentation-deprecated-sync) @@ -238,60 +250,59 @@ ELSE () enable_warnings(format) enable_warnings(format-security) endif() -ENDIF() +endif() # Ensure that MinGW provides the correct header files. -IF (WIN32 AND NOT CYGWIN) - ADD_DEFINITIONS(-DWIN32 -D_WIN32_WINNT=0x0600) -ENDIF() +if(WIN32 AND NOT CYGWIN) + add_definitions(-DWIN32 -D_WIN32_WINNT=0x0600) +endif() -IF( NOT CMAKE_CONFIGURATION_TYPES ) +if(NOT CMAKE_CONFIGURATION_TYPES) # Build Debug by default - IF (NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) - ENDIF () -ELSE() + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) + endif() +else() # Using a multi-configuration generator eg MSVC or Xcode # that uses CMAKE_CONFIGURATION_TYPES and not CMAKE_BUILD_TYPE -ENDIF() +endif() IF(BUILD_FUZZERS AND NOT USE_STANDALONE_FUZZERS) # The actual sanitizer link target will be added when linking the fuzz # targets. - SET(CMAKE_REQUIRED_FLAGS "-fsanitize=fuzzer-no-link") - ADD_C_FLAG(-fsanitize=fuzzer-no-link) - UNSET(CMAKE_REQUIRED_FLAGS) -ENDIF () - -ADD_SUBDIRECTORY(src) - -# Tests -IF (NOT MSVC) - IF (NOT BUILD_SHARED_LIBS) - SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - ENDIF() -ENDIF () - -IF (BUILD_TESTS) - ENABLE_TESTING() - ADD_SUBDIRECTORY(tests) -ENDIF () - -IF (BUILD_EXAMPLES) - ADD_SUBDIRECTORY(examples) -ENDIF () - -IF(BUILD_FUZZERS) - IF(NOT USE_STANDALONE_FUZZERS) - IF(BUILD_EXAMPLES) - MESSAGE(FATAL_ERROR "Cannot build the fuzzer targets and the examples together") - ENDIF() - IF(BUILD_TESTS) - MESSAGE(FATAL_ERROR "Cannot build the fuzzer targets and the tests together") - ENDIF() - ENDIF() - ADD_SUBDIRECTORY(fuzzers) -ENDIF() - -FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:") -FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:") + set(CMAKE_REQUIRED_FLAGS "-fsanitize=fuzzer-no-link") + add_c_flag(-fsanitize=fuzzer-no-link) + unset(CMAKE_REQUIRED_FLAGS) +endif() + +# +# Subdirectories +# + +add_subdirectory(src) + +if(BUILD_TESTS) + enable_testing() + add_subdirectory(tests) +endif() + +if(BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + +if(BUILD_FUZZERS) + if(NOT USE_STANDALONE_FUZZERS) + if(BUILD_EXAMPLES) + message(FATAL_ERROR "Cannot build the fuzzer targets and the examples together") + endif() + if(BUILD_TESTS) + message(FATAL_ERROR "Cannot build the fuzzer targets and the tests together") + endif() + endif() + add_subdirectory(fuzzers) +endif() + +# Summary + +feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:") +feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:") diff --git a/deps/chromium-zlib/CMakeLists.txt b/deps/chromium-zlib/CMakeLists.txt index bbb35d4e6fc..55d67948dbe 100644 --- a/deps/chromium-zlib/CMakeLists.txt +++ b/deps/chromium-zlib/CMakeLists.txt @@ -4,18 +4,18 @@ # TODO: The Chromium build file (in deps/chromium-zlib/zlib/BUILD.gn) supports # more platforms (like ARM with NEON), more can be enabled as needed. -CMAKE_MINIMUM_REQUIRED(VERSION 3.11) +cmake_minimum_required(VERSION 3.11) include(FetchContent) include(FindGit) # Ensure that the git binary is present to download the sources. find_package(Git) -IF(NOT Git_FOUND) +if(NOT Git_FOUND) message(FATAL_ERROR "git is required to download the Chromium zlib sources") -ENDIF() +endif() -FetchContent_Populate(chromium_zlib_src +fetchcontent_populate(chromium_zlib_src GIT_REPOSITORY https://chromium.googlesource.com/chromium/src/third_party/zlib.git GIT_TAG 2c183c9f93a328bfb3121284da13cf89a0f7e64a QUIET @@ -31,8 +31,8 @@ disable_warnings(missing-declarations) # -O3 is also set by the Chromium configuration and has been deemed safe enough # for them. -SET(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -g -DNDEBUG") -SET(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -g -DNDEBUG") +set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") # Common definitions. add_definitions( diff --git a/deps/ntlmclient/CMakeLists.txt b/deps/ntlmclient/CMakeLists.txt index 3e0d2c817b8..9c5e23d6002 100644 --- a/deps/ntlmclient/CMakeLists.txt +++ b/deps/ntlmclient/CMakeLists.txt @@ -1,37 +1,37 @@ -FILE(GLOB SRC_NTLMCLIENT "ntlm.c" "ntlm.h" "util.c" "util.h") -LIST(SORT SRC_NTLMCLIENT) +file(GLOB SRC_NTLMCLIENT "ntlm.c" "ntlm.h" "util.c" "util.h") +list(SORT SRC_NTLMCLIENT) -ADD_DEFINITIONS(-DNTLM_STATIC=1) +add_definitions(-DNTLM_STATIC=1) -DISABLE_WARNINGS(implicit-fallthrough) +disable_warnings(implicit-fallthrough) -IF(USE_ICONV) - ADD_DEFINITIONS(-DUNICODE_ICONV=1) - FILE(GLOB SRC_NTLMCLIENT_UNICODE "unicode_iconv.c" "unicode_iconv.h") -ELSE() - ADD_DEFINITIONS(-DUNICODE_BUILTIN=1) - FILE(GLOB SRC_NTLMCLIENT_UNICODE "unicode_builtin.c" "unicode_builtin.h") -ENDIF() +if(USE_ICONV) + add_definitions(-DUNICODE_ICONV=1) + file(GLOB SRC_NTLMCLIENT_UNICODE "unicode_iconv.c" "unicode_iconv.h") +else() + add_definitions(-DUNICODE_BUILTIN=1) + file(GLOB SRC_NTLMCLIENT_UNICODE "unicode_builtin.c" "unicode_builtin.h") +endif() -IF(USE_HTTPS STREQUAL "SecureTransport") - ADD_DEFINITIONS(-DCRYPT_COMMONCRYPTO) - SET(SRC_NTLMCLIENT_CRYPTO "crypt_commoncrypto.c" "crypt_commoncrypto.h") +if(USE_HTTPS STREQUAL "SecureTransport") + add_definitions(-DCRYPT_COMMONCRYPTO) + set(SRC_NTLMCLIENT_CRYPTO "crypt_commoncrypto.c" "crypt_commoncrypto.h") # CC_MD4 has been deprecated in macOS 10.15. - SET_SOURCE_FILES_PROPERTIES("crypt_commoncrypto.c" COMPILE_FLAGS "-Wno-deprecated") -ELSEIF(USE_HTTPS STREQUAL "OpenSSL") - ADD_DEFINITIONS(-DCRYPT_OPENSSL) - INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) - SET(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c" "crypt_openssl.h") -ELSEIF(USE_HTTPS STREQUAL "OpenSSL-Dynamic") - ADD_DEFINITIONS(-DCRYPT_OPENSSL) - ADD_DEFINITIONS(-DCRYPT_OPENSSL_DYNAMIC) - SET(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c" "crypt_openssl.h") -ELSEIF(USE_HTTPS STREQUAL "mbedTLS") - ADD_DEFINITIONS(-DCRYPT_MBEDTLS) - INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIR}) - SET(SRC_NTLMCLIENT_CRYPTO "crypt_mbedtls.c" "crypt_mbedtls.h") -ELSE() - MESSAGE(FATAL_ERROR "Unable to use libgit2's HTTPS backend (${USE_HTTPS}) for NTLM crypto") -ENDIF() + set_source_files_properties("crypt_commoncrypto.c" COMPILE_FLAGS "-Wno-deprecated") +elseif(USE_HTTPS STREQUAL "OpenSSL") + add_definitions(-DCRYPT_OPENSSL) + include_directories(${OPENSSL_INCLUDE_DIR}) + set(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c" "crypt_openssl.h") +elseif(USE_HTTPS STREQUAL "OpenSSL-Dynamic") + add_definitions(-DCRYPT_OPENSSL) + add_definitions(-DCRYPT_OPENSSL_DYNAMIC) + set(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c" "crypt_openssl.h") +elseif(USE_HTTPS STREQUAL "mbedTLS") + add_definitions(-DCRYPT_MBEDTLS) + include_directories(${MBEDTLS_INCLUDE_DIR}) + set(SRC_NTLMCLIENT_CRYPTO "crypt_mbedtls.c" "crypt_mbedtls.h") +else() + message(FATAL_ERROR "Unable to use libgit2's HTTPS backend (${USE_HTTPS}) for NTLM crypto") +endif() -ADD_LIBRARY(ntlmclient OBJECT ${SRC_NTLMCLIENT} ${SRC_NTLMCLIENT_UNICODE} ${SRC_NTLMCLIENT_CRYPTO}) +add_library(ntlmclient OBJECT ${SRC_NTLMCLIENT} ${SRC_NTLMCLIENT_UNICODE} ${SRC_NTLMCLIENT_CRYPTO}) diff --git a/deps/pcre/CMakeLists.txt b/deps/pcre/CMakeLists.txt index aff2d751bff..431dda01a02 100644 --- a/deps/pcre/CMakeLists.txt +++ b/deps/pcre/CMakeLists.txt @@ -1,95 +1,95 @@ -INCLUDE(CheckIncludeFile) -INCLUDE(CheckFunctionExists) -INCLUDE(CheckTypeSize) - -CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H) -CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H) -CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H) -CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H) -CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H) -CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) -CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H) - -CHECK_FUNCTION_EXISTS(bcopy HAVE_BCOPY) -CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE) -CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR) -CHECK_FUNCTION_EXISTS(strtoll HAVE_STRTOLL) -CHECK_FUNCTION_EXISTS(strtoq HAVE_STRTOQ) -CHECK_FUNCTION_EXISTS(_strtoi64 HAVE__STRTOI64) - -CHECK_TYPE_SIZE("long long" LONG_LONG) -CHECK_TYPE_SIZE("unsigned long long" UNSIGNED_LONG_LONG) - -DISABLE_WARNINGS(unused-function) -DISABLE_WARNINGS(implicit-fallthrough) +include(CheckIncludeFile) +include(CheckFunctionExists) +include(CheckTypeSize) + +check_include_file(dirent.h HAVE_DIRENT_H) +check_include_file(stdint.h HAVE_STDINT_H) +check_include_file(inttypes.h HAVE_INTTYPES_H) +check_include_file(sys/stat.h HAVE_SYS_STAT_H) +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +check_include_file(unistd.h HAVE_UNISTD_H) +check_include_file(windows.h HAVE_WINDOWS_H) + +check_function_exists(bcopy HAVE_BCOPY) +check_function_exists(memmove HAVE_MEMMOVE) +check_function_exists(strerror HAVE_STRERROR) +check_function_exists(strtoll HAVE_STRTOLL) +check_function_exists(strtoq HAVE_STRTOQ) +check_function_exists(_strtoi64 HAVE__STRTOI64) + +check_type_size("long long" LONG_LONG) +check_type_size("unsigned long long" UNSIGNED_LONG_LONG) + +disable_warnings(unused-function) +disable_warnings(implicit-fallthrough) # User-configurable options -SET(SUPPORT_PCRE8 1) -SET(PCRE_LINK_SIZE "2") -SET(PCRE_PARENS_NEST_LIMIT "250") -SET(PCRE_MATCH_LIMIT "10000000") -SET(PCRE_MATCH_LIMIT_RECURSION "MATCH_LIMIT") -SET(PCRE_NEWLINE "LF") -SET(NO_RECURSE 1) -SET(PCRE_POSIX_MALLOC_THRESHOLD "10") -SET(BSR_ANYCRLF 0) - -IF (MINGW) - OPTION(NON_STANDARD_LIB_PREFIX - "ON=Shared libraries built in mingw will be named pcre.dll, etc., instead of libpcre.dll, etc." - OFF) - - OPTION(NON_STANDARD_LIB_SUFFIX - "ON=Shared libraries built in mingw will be named libpcre-0.dll, etc., instead of libpcre.dll, etc." - OFF) -ENDIF(MINGW) +set(SUPPORT_PCRE8 1) +set(PCRE_LINK_SIZE "2") +set(PCRE_PARENS_NEST_LIMIT "250") +set(PCRE_MATCH_LIMIT "10000000") +set(PCRE_MATCH_LIMIT_RECURSION "MATCH_LIMIT") +set(PCRE_NEWLINE "LF") +set(NO_RECURSE 1) +set(PCRE_POSIX_MALLOC_THRESHOLD "10") +set(BSR_ANYCRLF 0) + +if(MINGW) + option(NON_STANDARD_LIB_PREFIX + "ON=Shared libraries built in mingw will be named pcre.dll, etc., instead of libpcre.dll, etc." + OFF) + + option(NON_STANDARD_LIB_SUFFIX + "ON=Shared libraries built in mingw will be named libpcre-0.dll, etc., instead of libpcre.dll, etc." + OFF) +endif(MINGW) # Prepare build configuration -SET(pcre_have_long_long 0) -SET(pcre_have_ulong_long 0) - -IF(HAVE_LONG_LONG) - SET(pcre_have_long_long 1) -ENDIF(HAVE_LONG_LONG) - -IF(HAVE_UNSIGNED_LONG_LONG) - SET(pcre_have_ulong_long 1) -ENDIF(HAVE_UNSIGNED_LONG_LONG) - -SET(NEWLINE "") - -IF(PCRE_NEWLINE STREQUAL "LF") - SET(NEWLINE "10") -ENDIF(PCRE_NEWLINE STREQUAL "LF") -IF(PCRE_NEWLINE STREQUAL "CR") - SET(NEWLINE "13") -ENDIF(PCRE_NEWLINE STREQUAL "CR") -IF(PCRE_NEWLINE STREQUAL "CRLF") - SET(NEWLINE "3338") -ENDIF(PCRE_NEWLINE STREQUAL "CRLF") -IF(PCRE_NEWLINE STREQUAL "ANY") - SET(NEWLINE "-1") -ENDIF(PCRE_NEWLINE STREQUAL "ANY") -IF(PCRE_NEWLINE STREQUAL "ANYCRLF") - SET(NEWLINE "-2") -ENDIF(PCRE_NEWLINE STREQUAL "ANYCRLF") - -IF(NEWLINE STREQUAL "") - MESSAGE(FATAL_ERROR "The PCRE_NEWLINE variable must be set to one of the following values: \"LF\", \"CR\", \"CRLF\", \"ANY\", \"ANYCRLF\".") -ENDIF(NEWLINE STREQUAL "") +set(pcre_have_long_long 0) +set(pcre_have_ulong_long 0) + +if(HAVE_LONG_LONG) + set(pcre_have_long_long 1) +endif(HAVE_LONG_LONG) + +if(HAVE_UNSIGNED_LONG_LONG) + set(pcre_have_ulong_long 1) +endif(HAVE_UNSIGNED_LONG_LONG) + +set(NEWLINE "") + +if(PCRE_NEWLINE STREQUAL "LF") + set(NEWLINE "10") +endif(PCRE_NEWLINE STREQUAL "LF") +if(PCRE_NEWLINE STREQUAL "CR") + set(NEWLINE "13") +endif(PCRE_NEWLINE STREQUAL "CR") +if(PCRE_NEWLINE STREQUAL "CRLF") + set(NEWLINE "3338") +endif(PCRE_NEWLINE STREQUAL "CRLF") +if(PCRE_NEWLINE STREQUAL "ANY") + set(NEWLINE "-1") +endif(PCRE_NEWLINE STREQUAL "ANY") +if(PCRE_NEWLINE STREQUAL "ANYCRLF") + set(NEWLINE "-2") +endif(PCRE_NEWLINE STREQUAL "ANYCRLF") + +if(NEWLINE STREQUAL "") + message(FATAL_ERROR "The PCRE_NEWLINE variable must be set to one of the following values: \"LF\", \"CR\", \"CRLF\", \"ANY\", \"ANYCRLF\".") +endif(NEWLINE STREQUAL "") # Output files -CONFIGURE_FILE(config.h.in +configure_file(config.h.in ${PROJECT_BINARY_DIR}/src/pcre/config.h @ONLY) # Source code -SET(PCRE_HEADERS ${PROJECT_BINARY_DIR}/src/pcre/config.h) +set(PCRE_HEADERS ${PROJECT_BINARY_DIR}/src/pcre/config.h) -SET(PCRE_SOURCES +set(PCRE_SOURCES pcre_byte_order.c pcre_chartables.c pcre_compile.c @@ -113,28 +113,28 @@ SET(PCRE_SOURCES pcre_xclass.c ) -SET(PCREPOSIX_HEADERS pcreposix.h) +set(PCREPOSIX_HEADERS pcreposix.h) -SET(PCREPOSIX_SOURCES pcreposix.c) +set(PCREPOSIX_SOURCES pcreposix.c) # Fix static compilation with MSVC: https://bugs.exim.org/show_bug.cgi?id=1681 # This code was taken from the CMake wiki, not from WebM. # Build setup -ADD_DEFINITIONS(-DHAVE_CONFIG_H) +add_definitions(-DHAVE_CONFIG_H) -IF(MSVC) - ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS) -ENDIF(MSVC) +if(MSVC) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS) +endif(MSVC) -SET(CMAKE_INCLUDE_CURRENT_DIR 1) +set(CMAKE_INCLUDE_CURRENT_DIR 1) -SET(targets) +set(targets) # Libraries # pcre -INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}/src/pcre) -ADD_LIBRARY(pcre OBJECT ${PCRE_HEADERS} ${PCRE_SOURCES} ${PCREPOSIX_SOURCES}) +include_directories(${PROJECT_BINARY_DIR}/src/pcre) +add_library(pcre OBJECT ${PCRE_HEADERS} ${PCRE_SOURCES} ${PCREPOSIX_SOURCES}) # end CMakeLists.txt diff --git a/deps/winhttp/CMakeLists.txt b/deps/winhttp/CMakeLists.txt index 148ac3ebc95..0ad2ac5f0ea 100644 --- a/deps/winhttp/CMakeLists.txt +++ b/deps/winhttp/CMakeLists.txt @@ -1,26 +1,26 @@ -FIND_PROGRAM(DLLTOOL dlltool CMAKE_FIND_ROOT_PATH_BOTH) -IF (NOT DLLTOOL) - MESSAGE(FATAL_ERROR "Could not find dlltool command") -ENDIF () +find_program(DLLTOOL dlltool CMAKE_FIND_ROOT_PATH_BOTH) +if(NOT DLLTOOL) + message(FATAL_ERROR "Could not find dlltool command") +endif() -SET(LIBWINHTTP_PATH "${libgit2_BINARY_DIR}/deps/winhttp") -SET(LIBWINHTTP_PATH ${LIBWINHTTP_PATH} PARENT_SCOPE) -FILE(MAKE_DIRECTORY ${LIBWINHTTP_PATH}) +set(LIBWINHTTP_PATH "${libgit2_BINARY_DIR}/deps/winhttp") +set(LIBWINHTTP_PATH ${LIBWINHTTP_PATH} PARENT_SCOPE) +file(MAKE_DIRECTORY ${LIBWINHTTP_PATH}) -IF (CMAKE_SIZEOF_VOID_P EQUAL 8) +if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(WINHTTP_DEF "winhttp64.def") -ELSE() +else() set(WINHTTP_DEF "winhttp.def") -ENDIF() +endif() -ADD_CUSTOM_COMMAND( +add_custom_command( OUTPUT ${LIBWINHTTP_PATH}/libwinhttp.a COMMAND ${DLLTOOL} -d ${WINHTTP_DEF} -k -D winhttp.dll -l libwinhttp.a DEPENDS ${WINHTTP_DEF} WORKING_DIRECTORY ${LIBWINHTTP_PATH} ) -SET_SOURCE_FILES_PROPERTIES( +set_source_files_properties( ${CMAKE_CURRENT_SOURCE_DIR}/src/transports/winhttp.c PROPERTIES OBJECT_DEPENDS ${LIBWINHTTP_PATH}/libwinhttp.a ) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 8cc72b35e4f..a7970a6d098 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,15 +1,15 @@ -INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES}) -INCLUDE_DIRECTORIES(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) +include_directories(${LIBGIT2_INCLUDES}) +include_directories(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) -FILE(GLOB LG2_SOURCES *.c *.h) -ADD_EXECUTABLE(lg2 ${LG2_SOURCES}) -SET_TARGET_PROPERTIES(lg2 PROPERTIES C_STANDARD 90) +file(GLOB LG2_SOURCES *.c *.h) +add_executable(lg2 ${LG2_SOURCES}) +set_target_properties(lg2 PROPERTIES C_STANDARD 90) # Ensure that we do not use deprecated functions internally -ADD_DEFINITIONS(-DGIT_DEPRECATE_HARD) +add_definitions(-DGIT_DEPRECATE_HARD) -IF(WIN32 OR ANDROID) - TARGET_LINK_LIBRARIES(lg2 git2) -ELSE() - TARGET_LINK_LIBRARIES(lg2 git2 pthread) -ENDIF() +if(WIN32 OR ANDROID) + target_link_libraries(lg2 git2) +else() + target_link_libraries(lg2 git2 pthread) +endif() diff --git a/fuzzers/CMakeLists.txt b/fuzzers/CMakeLists.txt index 59eca24d007..8cc61b7519a 100644 --- a/fuzzers/CMakeLists.txt +++ b/fuzzers/CMakeLists.txt @@ -1,23 +1,23 @@ -LINK_DIRECTORIES(${LIBGIT2_LIBDIRS}) -INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES}) -INCLUDE_DIRECTORIES(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) +link_directories(${LIBGIT2_LIBDIRS}) +include_directories(${LIBGIT2_INCLUDES}) +include_directories(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) -IF(BUILD_FUZZERS AND NOT USE_STANDALONE_FUZZERS) - ADD_C_FLAG(-fsanitize=fuzzer) -ENDIF () +if(BUILD_FUZZERS AND NOT USE_STANDALONE_FUZZERS) + add_c_flag(-fsanitize=fuzzer) +endif() -FILE(GLOB SRC_FUZZ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *_fuzzer.c) -FOREACH(fuzz_target_src ${SRC_FUZZ}) - STRING(REPLACE ".c" "" fuzz_target_name ${fuzz_target_src}) - STRING(REPLACE "_fuzzer" "" fuzz_name ${fuzz_target_name}) +file(GLOB SRC_FUZZ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *_fuzzer.c) +foreach(fuzz_target_src ${SRC_FUZZ}) + string(REPLACE ".c" "" fuzz_target_name ${fuzz_target_src}) + string(REPLACE "_fuzzer" "" fuzz_name ${fuzz_target_name}) - SET(${fuzz_target_name}_SOURCES ${fuzz_target_src} ${LIBGIT2_OBJECTS}) - IF(USE_STANDALONE_FUZZERS) - LIST(APPEND ${fuzz_target_name}_SOURCES "standalone_driver.c") - ENDIF() - ADD_EXECUTABLE(${fuzz_target_name} ${${fuzz_target_name}_SOURCES}) - SET_TARGET_PROPERTIES(${fuzz_target_name} PROPERTIES C_STANDARD 90) - TARGET_LINK_LIBRARIES(${fuzz_target_name} ${LIBGIT2_LIBS}) + set(${fuzz_target_name}_SOURCES ${fuzz_target_src} ${LIBGIT2_OBJECTS}) + if(USE_STANDALONE_FUZZERS) + list(APPEND ${fuzz_target_name}_SOURCES "standalone_driver.c") + endif() + add_executable(${fuzz_target_name} ${${fuzz_target_name}_SOURCES}) + set_target_properties(${fuzz_target_name} PROPERTIES C_STANDARD 90) + target_link_libraries(${fuzz_target_name} ${LIBGIT2_LIBS}) - ADD_TEST(${fuzz_target_name} "${CMAKE_CURRENT_BINARY_DIR}/${fuzz_target_name}" "${CMAKE_CURRENT_SOURCE_DIR}/corpora/${fuzz_name}") -ENDFOREACH() + add_test(${fuzz_target_name} "${CMAKE_CURRENT_BINARY_DIR}/${fuzz_target_name}" "${CMAKE_CURRENT_SOURCE_DIR}/corpora/${fuzz_name}") +endforeach() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b3d620c45ef..9812fc0e441 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,89 +1,91 @@ add_library(git2internal OBJECT) set_target_properties(git2internal PROPERTIES C_STANDARD 90) -IF(DEBUG_POOL) - SET(GIT_DEBUG_POOL 1) -ENDIF() -ADD_FEATURE_INFO(debugpool GIT_DEBUG_POOL "debug pool allocator") -IF(DEBUG_STRICT_ALLOC) - SET(GIT_DEBUG_STRICT_ALLOC 1) -ENDIF() -ADD_FEATURE_INFO(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators") +if(DEBUG_POOL) + set(GIT_DEBUG_POOL 1) +endif() +add_feature_info(debugpool GIT_DEBUG_POOL "debug pool allocator") + +if(DEBUG_STRICT_ALLOC) + set(GIT_DEBUG_STRICT_ALLOC 1) +endif() +add_feature_info(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators") + +if(DEBUG_STRICT_OPEN) + set(GIT_DEBUG_STRICT_OPEN 1) +endif() +add_feature_info(debugopen GIT_DEBUG_STRICT_OPEN "path validation in open") -IF(DEBUG_STRICT_OPEN) - SET(GIT_DEBUG_STRICT_OPEN 1) -ENDIF() -ADD_FEATURE_INFO(debugopen GIT_DEBUG_STRICT_OPEN "path validation in open") -INCLUDE(PkgBuildConfig) -INCLUDE(SanitizeBool) +include(PkgBuildConfig) +include(SanitizeBool) # This variable will contain the libraries we need to put into # libgit2.pc's Requires.private. That is, what we're linking to or # what someone who's statically linking us needs to link to. -SET(LIBGIT2_PC_REQUIRES "") +set(LIBGIT2_PC_REQUIRES "") # This will be set later if we use the system's http-parser library or # use iconv (OSX) and will be written to the Libs.private field in the # pc file. -SET(LIBGIT2_PC_LIBS "") +set(LIBGIT2_PC_LIBS "") -SET(LIBGIT2_INCLUDES +set(LIBGIT2_INCLUDES "${CMAKE_CURRENT_BINARY_DIR}" "${libgit2_SOURCE_DIR}/src" "${libgit2_SOURCE_DIR}/include") -SET(LIBGIT2_SYSTEM_INCLUDES "") -SET(LIBGIT2_LIBS "") +set(LIBGIT2_SYSTEM_INCLUDES "") +set(LIBGIT2_LIBS "") enable_warnings(missing-declarations) -IF (HAVE_FUTIMENS) - SET(GIT_USE_FUTIMENS 1) -ENDIF () -ADD_FEATURE_INFO(futimens GIT_USE_FUTIMENS "futimens support") +if(HAVE_FUTIMENS) + set(GIT_USE_FUTIMENS 1) +endif () +add_feature_info(futimens GIT_USE_FUTIMENS "futimens support") -CHECK_PROTOTYPE_DEFINITION(qsort_r +check_prototype_definition(qsort_r "void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, int (*compar)(void *, const void *, const void *))" "" "stdlib.h" HAVE_QSORT_R_BSD) -IF (HAVE_QSORT_R_BSD) +if(HAVE_QSORT_R_BSD) target_compile_definitions(git2internal PRIVATE HAVE_QSORT_R_BSD) -ENDIF() +endif() -CHECK_PROTOTYPE_DEFINITION(qsort_r +check_prototype_definition(qsort_r "void qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *arg)" "" "stdlib.h" HAVE_QSORT_R_GNU) -IF (HAVE_QSORT_R_GNU) +if(HAVE_QSORT_R_GNU) target_compile_definitions(git2internal PRIVATE HAVE_QSORT_R_GNU) -ENDIF() +endif() -CHECK_FUNCTION_EXISTS(qsort_s HAVE_QSORT_S) -IF (HAVE_QSORT_S) +check_function_exists(qsort_s HAVE_QSORT_S) +if(HAVE_QSORT_S) target_compile_definitions(git2internal PRIVATE HAVE_QSORT_S) -ENDIF () +endif() # Find required dependencies -IF(WIN32) - LIST(APPEND LIBGIT2_LIBS ws2_32) -ELSEIF(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - LIST(APPEND LIBGIT2_LIBS socket nsl) - LIST(APPEND LIBGIT2_PC_LIBS "-lsocket" "-lnsl") -ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Haiku") - LIST(APPEND LIBGIT2_LIBS network) - LIST(APPEND LIBGIT2_PC_LIBS "-lnetwork") -ENDIF() - -CHECK_LIBRARY_EXISTS(rt clock_gettime "time.h" NEED_LIBRT) -IF(NEED_LIBRT) - LIST(APPEND LIBGIT2_LIBS rt) - LIST(APPEND LIBGIT2_PC_LIBS "-lrt") -ENDIF() - -IF(THREADSAFE) - LIST(APPEND LIBGIT2_LIBS ${CMAKE_THREAD_LIBS_INIT}) - LIST(APPEND LIBGIT2_PC_LIBS ${CMAKE_THREAD_LIBS_INIT}) -ENDIF() -ADD_FEATURE_INFO(threadsafe THREADSAFE "threadsafe support") +if(WIN32) + list(APPEND LIBGIT2_LIBS ws2_32) +elseif(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") + list(APPEND LIBGIT2_LIBS socket nsl) + list(APPEND LIBGIT2_PC_LIBS "-lsocket" "-lnsl") +elseif(CMAKE_SYSTEM_NAME MATCHES "Haiku") + list(APPEND LIBGIT2_LIBS network) + list(APPEND LIBGIT2_PC_LIBS "-lnetwork") +endif() + +check_library_exists(rt clock_gettime "time.h" NEED_LIBRT) +if(NEED_LIBRT) + list(APPEND LIBGIT2_LIBS rt) + list(APPEND LIBGIT2_PC_LIBS "-lrt") +endif() + +if(THREADSAFE) + list(APPEND LIBGIT2_LIBS ${CMAKE_THREAD_LIBS_INIT}) + list(APPEND LIBGIT2_PC_LIBS ${CMAKE_THREAD_LIBS_INIT}) +endif() +add_feature_info(threadsafe THREADSAFE "threadsafe support") if(WIN32 AND EMBED_SSH_PATH) @@ -96,204 +98,204 @@ if(WIN32 AND EMBED_SSH_PATH) set(GIT_SSH 1) endif() -IF (WIN32 AND WINHTTP) - SET(GIT_WINHTTP 1) +if(WIN32 AND WINHTTP) + set(GIT_WINHTTP 1) # Since MinGW does not come with headers or an import library for winhttp, # we have to include a private header and generate our own import library - IF (MINGW) - ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/winhttp" "${libgit2_BINARY_DIR}/deps/winhttp") - LIST(APPEND LIBGIT2_LIBS winhttp) - LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/winhttp") - ELSE() - LIST(APPEND LIBGIT2_LIBS "winhttp") - LIST(APPEND LIBGIT2_PC_LIBS "-lwinhttp") - ENDIF () - - LIST(APPEND LIBGIT2_LIBS "rpcrt4" "crypt32" "ole32") - LIST(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32") -ENDIF() + if(MINGW) + add_subdirectory("${libgit2_SOURCE_DIR}/deps/winhttp" "${libgit2_BINARY_DIR}/deps/winhttp") + list(APPEND LIBGIT2_LIBS winhttp) + list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/winhttp") + else() + list(APPEND LIBGIT2_LIBS "winhttp") + list(APPEND LIBGIT2_PC_LIBS "-lwinhttp") + endif() + + list(APPEND LIBGIT2_LIBS "rpcrt4" "crypt32" "ole32") + list(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32") +endif() include(SelectHTTPSBackend) include(SelectHashes) target_sources(git2internal PRIVATE ${SRC_SHA1}) # Specify regular expression implementation -FIND_PACKAGE(PCRE) - -IF(REGEX_BACKEND STREQUAL "") - CHECK_SYMBOL_EXISTS(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L) - - IF(HAVE_REGCOMP_L) - SET(REGEX_BACKEND "regcomp_l") - ELSEIF(PCRE_FOUND) - SET(REGEX_BACKEND "pcre") - ELSE() - SET(REGEX_BACKEND "builtin") - ENDIF() -ENDIF() - -IF(REGEX_BACKEND STREQUAL "regcomp_l") - ADD_FEATURE_INFO(regex ON "using system regcomp_l") - SET(GIT_REGEX_REGCOMP_L 1) -ELSEIF(REGEX_BACKEND STREQUAL "pcre2") - FIND_PACKAGE(PCRE2) - - IF(NOT PCRE2_FOUND) +find_package(PCRE) + +if(REGEX_BACKEND STREQUAL "") + check_symbol_exists(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L) + + if(HAVE_REGCOMP_L) + set(REGEX_BACKEND "regcomp_l") + elseif(PCRE_FOUND) + set(REGEX_BACKEND "pcre") + else() + set(REGEX_BACKEND "builtin") + endif() +endif() + +if(REGEX_BACKEND STREQUAL "regcomp_l") + add_feature_info(regex ON "using system regcomp_l") + set(GIT_REGEX_REGCOMP_L 1) +elseif(REGEX_BACKEND STREQUAL "pcre2") + find_package(PCRE2) + + if(NOT PCRE2_FOUND) MESSAGE(FATAL_ERROR "PCRE2 support was requested but not found") - ENDIF() - - ADD_FEATURE_INFO(regex ON "using system PCRE2") - SET(GIT_REGEX_PCRE2 1) - - LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE2_INCLUDE_DIRS}) - LIST(APPEND LIBGIT2_LIBS ${PCRE2_LIBRARIES}) - LIST(APPEND LIBGIT2_PC_REQUIRES "libpcre2-8") -ELSEIF(REGEX_BACKEND STREQUAL "pcre") - ADD_FEATURE_INFO(regex ON "using system PCRE") - SET(GIT_REGEX_PCRE 1) - - LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE_INCLUDE_DIRS}) - LIST(APPEND LIBGIT2_LIBS ${PCRE_LIBRARIES}) - LIST(APPEND LIBGIT2_PC_REQUIRES "libpcre") -ELSEIF(REGEX_BACKEND STREQUAL "regcomp") - ADD_FEATURE_INFO(regex ON "using system regcomp") - SET(GIT_REGEX_REGCOMP 1) -ELSEIF(REGEX_BACKEND STREQUAL "builtin") - ADD_FEATURE_INFO(regex ON "using bundled PCRE") - SET(GIT_REGEX_BUILTIN 1) - - ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/pcre" "${libgit2_BINARY_DIR}/deps/pcre") - LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/pcre") - LIST(APPEND LIBGIT2_OBJECTS $) -ELSE() - MESSAGE(FATAL_ERROR "The REGEX_BACKEND option provided is not supported") -ENDIF() + endif() + + add_feature_info(regex ON "using system PCRE2") + set(GIT_REGEX_PCRE2 1) + + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE2_INCLUDE_DIRS}) + list(APPEND LIBGIT2_LIBS ${PCRE2_LIBRARIES}) + list(APPEND LIBGIT2_PC_REQUIRES "libpcre2-8") +elseif(REGEX_BACKEND STREQUAL "pcre") + add_feature_info(regex ON "using system PCRE") + set(GIT_REGEX_PCRE 1) + + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE_INCLUDE_DIRS}) + list(APPEND LIBGIT2_LIBS ${PCRE_LIBRARIES}) + list(APPEND LIBGIT2_PC_REQUIRES "libpcre") +elseif(REGEX_BACKEND STREQUAL "regcomp") + add_feature_info(regex ON "using system regcomp") + set(GIT_REGEX_REGCOMP 1) +elseif(REGEX_BACKEND STREQUAL "builtin") + add_feature_info(regex ON "using bundled PCRE") + set(GIT_REGEX_BUILTIN 1) + + add_subdirectory("${libgit2_SOURCE_DIR}/deps/pcre" "${libgit2_BINARY_DIR}/deps/pcre") + list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/pcre") + list(APPEND LIBGIT2_OBJECTS $) +else() + message(FATAL_ERROR "The REGEX_BACKEND option provided is not supported") +endif() # Optional external dependency: http-parser -IF(USE_HTTP_PARSER STREQUAL "system") - FIND_PACKAGE(HTTP_Parser) - - IF (HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2) - LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${HTTP_PARSER_INCLUDE_DIRS}) - LIST(APPEND LIBGIT2_LIBS ${HTTP_PARSER_LIBRARIES}) - LIST(APPEND LIBGIT2_PC_LIBS "-lhttp_parser") - ADD_FEATURE_INFO(http-parser ON "http-parser support (system)") - ELSE() - MESSAGE(FATAL_ERROR "http-parser support was requested but not found") - ENDIF() -ELSE() - MESSAGE(STATUS "http-parser version 2 was not found or disabled; using bundled 3rd-party sources.") - ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/http-parser" "${libgit2_BINARY_DIR}/deps/http-parser") - LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/http-parser") - LIST(APPEND LIBGIT2_OBJECTS "$") - ADD_FEATURE_INFO(http-parser ON "http-parser support (bundled)") -ENDIF() +if(USE_HTTP_PARSER STREQUAL "system") + find_package(HTTP_Parser) + + if(HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${HTTP_PARSER_INCLUDE_DIRS}) + list(APPEND LIBGIT2_LIBS ${HTTP_PARSER_LIBRARIES}) + list(APPEND LIBGIT2_PC_LIBS "-lhttp_parser") + add_feature_info(http-parser ON "http-parser support (system)") + else() + message(FATAL_ERROR "http-parser support was requested but not found") + endif() +else() + message(STATUS "http-parser version 2 was not found or disabled; using bundled 3rd-party sources.") + add_subdirectory("${libgit2_SOURCE_DIR}/deps/http-parser" "${libgit2_BINARY_DIR}/deps/http-parser") + list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/http-parser") + list(APPEND LIBGIT2_OBJECTS "$") + add_feature_info(http-parser ON "http-parser support (bundled)") +endif() # Optional external dependency: zlib SanitizeBool(USE_BUNDLED_ZLIB) -IF(USE_BUNDLED_ZLIB STREQUAL ON) - SET(USE_BUNDLED_ZLIB "Bundled") -ENDIF() - -IF(USE_BUNDLED_ZLIB STREQUAL "OFF") - FIND_PACKAGE(ZLIB) - IF(ZLIB_FOUND) - LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${ZLIB_INCLUDE_DIRS}) - LIST(APPEND LIBGIT2_LIBS ${ZLIB_LIBRARIES}) - IF(APPLE OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - LIST(APPEND LIBGIT2_PC_LIBS "-lz") - ELSE() - LIST(APPEND LIBGIT2_PC_REQUIRES "zlib") - ENDIF() - ADD_FEATURE_INFO(zlib ON "using system zlib") - ELSE() - MESSAGE(STATUS "zlib was not found; using bundled 3rd-party sources." ) - ENDIF() -ENDIF() -IF(USE_BUNDLED_ZLIB STREQUAL "Chromium") - ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/chromium-zlib" "${libgit2_BINARY_DIR}/deps/chromium-zlib") - LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/chromium-zlib") - LIST(APPEND LIBGIT2_OBJECTS $) - ADD_FEATURE_INFO(zlib ON "using (Chromium) bundled zlib") -ELSEIF(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND) - ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib") - LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib") - LIST(APPEND LIBGIT2_OBJECTS $) - ADD_FEATURE_INFO(zlib ON "using bundled zlib") -ENDIF() +if(USE_BUNDLED_ZLIB STREQUAL ON) + set(USE_BUNDLED_ZLIB "Bundled") +endif() + +if(USE_BUNDLED_ZLIB STREQUAL "OFF") + find_package(ZLIB) + if(ZLIB_FOUND) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ZLIB_INCLUDE_DIRS}) + list(APPEND LIBGIT2_LIBS ${ZLIB_LIBRARIES}) + if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + list(APPEND LIBGIT2_PC_LIBS "-lz") + else() + list(APPEND LIBGIT2_PC_REQUIRES "zlib") + endif() + add_feature_info(zlib ON "using system zlib") + else() + message(STATUS "zlib was not found; using bundled 3rd-party sources." ) + endif() +endif() +if(USE_BUNDLED_ZLIB STREQUAL "Chromium") + add_subdirectory("${libgit2_SOURCE_DIR}/deps/chromium-zlib" "${libgit2_BINARY_DIR}/deps/chromium-zlib") + list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/chromium-zlib") + list(APPEND LIBGIT2_OBJECTS $) + add_feature_info(zlib ON "using (Chromium) bundled zlib") +elseif(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND) + add_subdirectory("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib") + list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib") + list(APPEND LIBGIT2_OBJECTS $) + add_feature_info(zlib ON "using bundled zlib") +endif() # Optional external dependency: libssh2 -IF (USE_SSH) - FIND_PKGLIBRARIES(LIBSSH2 libssh2) - IF (NOT LIBSSH2_FOUND) - FIND_PACKAGE(LibSSH2) - SET(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR}) - GET_FILENAME_COMPONENT(LIBSSH2_LIBRARY_DIRS "${LIBSSH2_LIBRARY}" DIRECTORY) - SET(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY}) - SET(LIBSSH2_LDFLAGS "-lssh2") - ENDIF() -ENDIF() -IF (LIBSSH2_FOUND) - SET(GIT_SSH 1) - LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${LIBSSH2_INCLUDE_DIRS}) - LIST(APPEND LIBGIT2_LIBS ${LIBSSH2_LIBRARIES}) - LIST(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS}) - - CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS) - IF (HAVE_LIBSSH2_MEMORY_CREDENTIALS) - SET(GIT_SSH_MEMORY_CREDENTIALS 1) - ENDIF() -ELSE() - MESSAGE(STATUS "LIBSSH2 not found. Set CMAKE_PREFIX_PATH if it is installed outside of the default search path.") -ENDIF() -ADD_FEATURE_INFO(SSH GIT_SSH "SSH transport support") +if(USE_SSH) + find_pkglibraries(LIBSSH2 libssh2) + if(NOT LIBSSH2_FOUND) + find_package(LibSSH2) + set(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR}) + get_filename_component(LIBSSH2_LIBRARY_DIRS "${LIBSSH2_LIBRARY}" DIRECTORY) + set(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY}) + set(LIBSSH2_LDFLAGS "-lssh2") + endif() +endif() +if(LIBSSH2_FOUND) + set(GIT_SSH 1) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${LIBSSH2_INCLUDE_DIRS}) + list(APPEND LIBGIT2_LIBS ${LIBSSH2_LIBRARIES}) + list(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS}) + + check_library_exists("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS) + if(HAVE_LIBSSH2_MEMORY_CREDENTIALS) + set(GIT_SSH_MEMORY_CREDENTIALS 1) + endif() +else() + message(STATUS "LIBSSH2 not found. Set CMAKE_PREFIX_PATH if it is installed outside of the default search path.") +endif() +add_feature_info(SSH GIT_SSH "SSH transport support") # Optional external dependency: ntlmclient -IF (USE_NTLMCLIENT) - SET(GIT_NTLM 1) - ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/ntlmclient" "${libgit2_BINARY_DIR}/deps/ntlmclient") - LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/ntlmclient") - LIST(APPEND LIBGIT2_OBJECTS "$") -ENDIF() -ADD_FEATURE_INFO(ntlmclient GIT_NTLM "NTLM authentication support for Unix") +if(USE_NTLMCLIENT) + set(GIT_NTLM 1) + add_subdirectory("${libgit2_SOURCE_DIR}/deps/ntlmclient" "${libgit2_BINARY_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_OBJECTS "$") +endif() +add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix") # Optional external dependency: GSSAPI -INCLUDE(SelectGSSAPI) +include(SelectGSSAPI) # Optional external dependency: iconv -IF (USE_ICONV) - FIND_PACKAGE(Iconv) -ENDIF() -IF (ICONV_FOUND) - SET(GIT_USE_ICONV 1) - LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${ICONV_INCLUDE_DIR}) - LIST(APPEND LIBGIT2_LIBS ${ICONV_LIBRARIES}) - LIST(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES}) -ENDIF() -ADD_FEATURE_INFO(iconv GIT_USE_ICONV "iconv encoding conversion support") - - -IF (THREADSAFE) - IF (NOT WIN32) - FIND_PACKAGE(Threads REQUIRED) - ENDIF() - - SET(GIT_THREADS 1) -ENDIF() - -IF (USE_NSEC) - SET(GIT_USE_NSEC 1) -ENDIF() - -IF (HAVE_STRUCT_STAT_ST_MTIM) - SET(GIT_USE_STAT_MTIM 1) -ELSEIF (HAVE_STRUCT_STAT_ST_MTIMESPEC) - SET(GIT_USE_STAT_MTIMESPEC 1) -ELSEIF (HAVE_STRUCT_STAT_ST_MTIME_NSEC) - SET(GIT_USE_STAT_MTIME_NSEC 1) -ENDIF() +if(USE_ICONV) + find_package(Iconv) +endif() +if(ICONV_FOUND) + set(GIT_USE_ICONV 1) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ICONV_INCLUDE_DIR}) + list(APPEND LIBGIT2_LIBS ${ICONV_LIBRARIES}) + list(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES}) +endif() +add_feature_info(iconv GIT_USE_ICONV "iconv encoding conversion support") + + +if(THREADSAFE) + if(NOT WIN32) + find_package(Threads REQUIRED) + endif() + + set(GIT_THREADS 1) +endif() + +if(USE_NSEC) + set(GIT_USE_NSEC 1) +endif() + +if(HAVE_STRUCT_STAT_ST_MTIM) + set(GIT_USE_STAT_MTIM 1) +elseif(HAVE_STRUCT_STAT_ST_MTIMESPEC) + set(GIT_USE_STAT_MTIMESPEC 1) +elseif(HAVE_STRUCT_STAT_ST_MTIME_NSEC) + set(GIT_USE_STAT_MTIME_NSEC 1) +endif() target_compile_definitions(git2internal PRIVATE _FILE_OFFSET_BITS=64) @@ -307,7 +309,7 @@ target_sources(git2internal PRIVATE ${SRC_H}) # On Windows use specific platform sources if(WIN32 AND NOT CYGWIN) - SET(WIN_RC "win32/git2.rc") + set(WIN_RC "win32/git2.rc") file(GLOB SRC_OS win32/*.c win32/*.h) list(SORT SRC_OS) @@ -320,9 +322,9 @@ else() target_sources(git2internal PRIVATE ${SRC_OS}) endif() -IF (USE_LEAK_CHECKER STREQUAL "valgrind") +if(USE_LEAK_CHECKER STREQUAL "valgrind") target_compile_definitions(git2internal PRIVATE VALGRIND) -ENDIF() +endif() file(GLOB SRC_GIT2 *.c *.h allocators/*.c allocators/*.h @@ -332,65 +334,65 @@ file(GLOB SRC_GIT2 *.c *.h list(SORT SRC_GIT2) target_sources(git2internal PRIVATE ${SRC_GIT2}) -IF(APPLE) +if(APPLE) # The old Secure Transport API has been deprecated in macOS 10.15. - SET_SOURCE_FILES_PROPERTIES(streams/stransport.c PROPERTIES COMPILE_FLAGS -Wno-deprecated) -ENDIF() + set_source_files_properties(streams/stransport.c PROPERTIES COMPILE_FLAGS -Wno-deprecated) +endif() # the xdiff dependency is not (yet) warning-free, disable warnings as # errors for the xdiff sources until we've sorted them out -IF(MSVC) - SET_SOURCE_FILES_PROPERTIES(xdiff/xdiffi.c PROPERTIES COMPILE_FLAGS -WX-) - SET_SOURCE_FILES_PROPERTIES(xdiff/xutils.c PROPERTIES COMPILE_FLAGS -WX-) -ENDIF() +if(MSVC) + set_source_files_properties(xdiff/xdiffi.c PROPERTIES COMPILE_FLAGS -WX-) + set_source_files_properties(xdiff/xutils.c PROPERTIES COMPILE_FLAGS -WX-) +endif() # Determine architecture of the machine -IF (CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(GIT_ARCH_64 1) -ELSEIF (CMAKE_SIZEOF_VOID_P EQUAL 4) - SET(GIT_ARCH_32 1) -ELSEIF (CMAKE_SIZEOF_VOID_P) - MESSAGE(FATAL_ERROR "Unsupported architecture (pointer size is ${CMAKE_SIZEOF_VOID_P} bytes)") -ELSE() - MESSAGE(FATAL_ERROR "Unsupported architecture (CMAKE_SIZEOF_VOID_P is unset)") -ENDIF() - -CONFIGURE_FILE(features.h.in git2/sys/features.h) - -IDE_SPLIT_SOURCES(git2internal) -LIST(APPEND LIBGIT2_OBJECTS $) - -TARGET_INCLUDE_DIRECTORIES(git2internal PRIVATE ${LIBGIT2_INCLUDES} PUBLIC ${libgit2_SOURCE_DIR}/include) -TARGET_INCLUDE_DIRECTORIES(git2internal SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) - -SET(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE) -SET(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE) -SET(LIBGIT2_SYSTEM_INCLUDES ${LIBGIT2_SYSTEM_INCLUDES} PARENT_SCOPE) -SET(LIBGIT2_LIBS ${LIBGIT2_LIBS} PARENT_SCOPE) - -IF(XCODE_VERSION) +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(GIT_ARCH_64 1) +elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(GIT_ARCH_32 1) +elseif(CMAKE_SIZEOF_VOID_P) + message(FATAL_ERROR "Unsupported architecture (pointer size is ${CMAKE_SIZEOF_VOID_P} bytes)") +else() + message(FATAL_ERROR "Unsupported architecture (CMAKE_SIZEOF_VOID_P is unset)") +endif() + +configure_file(features.h.in git2/sys/features.h) + +ide_split_sources(git2internal) +list(APPEND LIBGIT2_OBJECTS $) + +target_include_directories(git2internal PRIVATE ${LIBGIT2_INCLUDES} PUBLIC ${libgit2_SOURCE_DIR}/include) +target_include_directories(git2internal SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) + +set(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE) +set(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE) +set(LIBGIT2_SYSTEM_INCLUDES ${LIBGIT2_SYSTEM_INCLUDES} PARENT_SCOPE) +set(LIBGIT2_LIBS ${LIBGIT2_LIBS} PARENT_SCOPE) + +if(XCODE_VERSION) # This is required for Xcode to actually link the libgit2 library # when using only object libraries. - FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.c "") - LIST(APPEND LIBGIT2_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/dummy.c) -ENDIF() + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.c "") + list(APPEND LIBGIT2_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/dummy.c) +endif() # Compile and link libgit2 -ADD_LIBRARY(git2 ${WIN_RC} ${LIBGIT2_OBJECTS}) -TARGET_LINK_LIBRARIES(git2 ${LIBGIT2_LIBS}) +add_library(git2 ${WIN_RC} ${LIBGIT2_OBJECTS}) +target_link_libraries(git2 ${LIBGIT2_LIBS}) -SET_TARGET_PROPERTIES(git2 PROPERTIES C_STANDARD 90) -SET_TARGET_PROPERTIES(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) -SET_TARGET_PROPERTIES(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) -SET_TARGET_PROPERTIES(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) +set_target_properties(git2 PROPERTIES C_STANDARD 90) +set_target_properties(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) +set_target_properties(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) +set_target_properties(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) # Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240) # Win64+MSVC+static libs = linker error -IF(MSVC AND GIT_ARCH_64 AND NOT BUILD_SHARED_LIBS) - SET_TARGET_PROPERTIES(git2 PROPERTIES STATIC_LIBRARY_FLAGS "/MACHINE:x64") -ENDIF() +if(MSVC AND GIT_ARCH_64 AND NOT BUILD_SHARED_LIBS) + set_target_properties(git2 PROPERTIES STATIC_LIBRARY_FLAGS "/MACHINE:x64") +endif() -IDE_SPLIT_SOURCES(git2) +ide_split_sources(git2) if(SONAME) set_target_properties(git2 PROPERTIES VERSION ${libgit2_VERSION}) @@ -403,7 +405,7 @@ if(SONAME) endif() endif() -PKG_BUILD_CONFIG(NAME libgit2 +pkg_build_config(NAME libgit2 VERSION ${libgit2_VERSION} DESCRIPTION "The git library, take 2" LIBS_SELF git2 @@ -411,17 +413,17 @@ PKG_BUILD_CONFIG(NAME libgit2 REQUIRES ${LIBGIT2_PC_REQUIRES} ) -IF (MSVC_IDE) - # Precompiled headers - SET_TARGET_PROPERTIES(git2 PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") - SET_SOURCE_FILES_PROPERTIES(win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h") -ENDIF () +if(MSVC_IDE) + # Precompiled headers + set_target_properties(git2 PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") + set_source_files_properties(win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h") +endif() # Install -INSTALL(TARGETS git2 +install(TARGETS git2 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) -INSTALL(DIRECTORY ${libgit2_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -INSTALL(FILES ${libgit2_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(DIRECTORY ${libgit2_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(FILES ${libgit2_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 74423fbd7e7..b85cd6ed363 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,73 +1,73 @@ -SET(Python_ADDITIONAL_VERSIONS 3 2.7) -FIND_PACKAGE(PythonInterp) +set(Python_ADDITIONAL_VERSIONS 3 2.7) +find_package(PythonInterp) -IF(NOT PYTHONINTERP_FOUND) - MESSAGE(FATAL_ERROR "Could not find a python interpeter, which is needed to build the tests. " - "Make sure python is available, or pass -DBUILD_TESTS=OFF to skip building the tests") +if(NOT PYTHONINTERP_FOUND) + message(FATAL_ERROR "Could not find a python interpeter, which is needed to build the tests. " + "Make sure python is available, or pass -DBUILD_TESTS=OFF to skip building the tests") ENDIF() -SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/resources/") -SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}") -ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\") -ADD_DEFINITIONS(-DCLAR_TMPDIR=\"libgit2_tests\") -ADD_DEFINITIONS(-DCLAR_WIN32_LONGPATHS) -ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64) +set(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/resources/") +set(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}") +add_definitions(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\") +add_definitions(-DCLAR_TMPDIR=\"libgit2_tests\") +add_definitions(-DCLAR_WIN32_LONGPATHS) +add_definitions(-D_FILE_OFFSET_BITS=64) # Ensure that we do not use deprecated functions internally -ADD_DEFINITIONS(-DGIT_DEPRECATE_HARD) +add_definitions(-DGIT_DEPRECATE_HARD) -INCLUDE_DIRECTORIES(${CLAR_PATH} ${libgit2_BINARY_DIR}/src) -FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h) -SET(SRC_CLAR "main.c" "clar_libgit2.c" "clar_libgit2_trace.c" "clar_libgit2_timer.c" "clar.c") +include_directories(${CLAR_PATH} ${libgit2_BINARY_DIR}/src) +file(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h) +set(SRC_CLAR "main.c" "clar_libgit2.c" "clar_libgit2_trace.c" "clar_libgit2_timer.c" "clar.c") -IF(MSVC_IDE) - LIST(APPEND SRC_CLAR "precompiled.c") -ENDIF() +if(MSVC_IDE) + list(APPEND SRC_CLAR "precompiled.c") +endif() -ADD_CUSTOM_COMMAND( +add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clar.suite COMMAND ${PYTHON_EXECUTABLE} generate.py -o "${CMAKE_CURRENT_BINARY_DIR}" -f -xonline -xstress -xperf . DEPENDS ${SRC_TEST} WORKING_DIRECTORY ${CLAR_PATH} ) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) -SET_SOURCE_FILES_PROPERTIES( +set_source_files_properties( ${CLAR_PATH}/clar.c PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clar.suite) -INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES}) -INCLUDE_DIRECTORIES(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) +include_directories(${LIBGIT2_INCLUDES}) +include_directories(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) -ADD_EXECUTABLE(libgit2_tests ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS}) +add_executable(libgit2_tests ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS}) -SET_TARGET_PROPERTIES(libgit2_tests PROPERTIES C_STANDARD 90) -SET_TARGET_PROPERTIES(libgit2_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) +set_target_properties(libgit2_tests PROPERTIES C_STANDARD 90) +set_target_properties(libgit2_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) -TARGET_INCLUDE_DIRECTORIES(libgit2_tests PRIVATE ../src PUBLIC ../include) -TARGET_LINK_LIBRARIES(libgit2_tests ${LIBGIT2_LIBS}) -IDE_SPLIT_SOURCES(libgit2_tests) +target_include_directories(libgit2_tests PRIVATE ../src PUBLIC ../include) +target_link_libraries(libgit2_tests ${LIBGIT2_LIBS}) +ide_split_sources(libgit2_tests) -IF (MSVC_IDE) +if(MSVC_IDE) # Precompiled headers - SET_TARGET_PROPERTIES(libgit2_tests PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") - SET_SOURCE_FILES_PROPERTIES("precompiled.c" COMPILE_FLAGS "/Ycprecompiled.h") -ENDIF () + set_target_properties(libgit2_tests PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") + set_source_files_properties("precompiled.c" COMPILE_FLAGS "/Ycprecompiled.h") +endif() -FUNCTION(ADD_CLAR_TEST name) - IF (NOT USE_LEAK_CHECKER STREQUAL "OFF") - ADD_TEST(${name} "${libgit2_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${libgit2_BINARY_DIR}/libgit2_tests" ${ARGN}) - ELSE() - ADD_TEST(${name} "${libgit2_BINARY_DIR}/libgit2_tests" ${ARGN}) - ENDIF() -ENDFUNCTION(ADD_CLAR_TEST) +function(ADD_CLAR_TEST name) + if(NOT USE_LEAK_CHECKER STREQUAL "OFF") + add_test(${name} "${libgit2_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${libgit2_BINARY_DIR}/libgit2_tests" ${ARGN}) + else() + add_test(${name} "${libgit2_BINARY_DIR}/libgit2_tests" ${ARGN}) + endif() +endfunction(ADD_CLAR_TEST) -ADD_CLAR_TEST(offline -v -xonline) -ADD_CLAR_TEST(invasive -v -score::ftruncate -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root) -ADD_CLAR_TEST(online -v -sonline -xonline::customcert) -ADD_CLAR_TEST(online_customcert -v -sonline::customcert) -ADD_CLAR_TEST(gitdaemon -v -sonline::push) -ADD_CLAR_TEST(ssh -v -sonline::push -sonline::clone::ssh_cert -sonline::clone::ssh_with_paths -sonline::clone::path_whitespace_ssh) -ADD_CLAR_TEST(proxy -v -sonline::clone::proxy) -ADD_CLAR_TEST(auth_clone -v -sonline::clone::cred) -ADD_CLAR_TEST(auth_clone_and_push -v -sonline::clone::push -sonline::push) +add_clar_test(offline -v -xonline) +add_clar_test(invasive -v -score::ftruncate -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root) +add_clar_test(online -v -sonline -xonline::customcert) +add_clar_test(online_customcert -v -sonline::customcert) +add_clar_test(gitdaemon -v -sonline::push) +add_clar_test(ssh -v -sonline::push -sonline::clone::ssh_cert -sonline::clone::ssh_with_paths -sonline::clone::path_whitespace_ssh) +add_clar_test(proxy -v -sonline::clone::proxy) +add_clar_test(auth_clone -v -sonline::clone::cred) +add_clar_test(auth_clone_and_push -v -sonline::clone::push -sonline::push) From b029713ae13bfc9edd08d4d7f9570d7b8e0bb0ec Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Mon, 18 Oct 2021 23:30:49 -0300 Subject: [PATCH 0583/1616] Also correct this long long constant I missed this because I searched for digits before ULL, otherwise it would match terms like "null" or "fully". --- src/commit_graph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commit_graph.c b/src/commit_graph.c index 397bee5e213..82b3901b3c7 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -1079,7 +1079,7 @@ static int commit_graph_write( error = git_str_put(&commit_data, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; - word = ntohl((uint32_t)(commit_time & 0xffffffffull)); + word = ntohl((uint32_t)(commit_time & UINT64_C(0xffffffff))); error = git_str_put(&commit_data, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; From 017f38f17cc51ab1e949a14713da6ab2ec66648b Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Mon, 18 Oct 2021 23:32:47 -0300 Subject: [PATCH 0584/1616] Fix long long constants in macro in ntlmclient This should be propagated to upstream. --- deps/ntlmclient/ntlm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deps/ntlmclient/ntlm.c b/deps/ntlmclient/ntlm.c index 3393be915d5..ad4de5de56e 100644 --- a/deps/ntlmclient/ntlm.c +++ b/deps/ntlmclient/ntlm.c @@ -930,10 +930,10 @@ const char *ntlm_client_target_domain_dns(ntlm_client *ntlm) } #define EVEN_PARITY(a) \ - (!!((a) & 0x01ll) ^ !!((a) & 0x02ll) ^ \ - !!((a) & 0x04ll) ^ !!((a) & 0x08ll) ^ \ - !!((a) & 0x10ll) ^ !!((a) & 0x20ll) ^ \ - !!((a) & 0x40ll) ^ !!((a) & 0x80ll)) + (!!((a) & INT64_C(0x01)) ^ !!((a) & INT64_C(0x02)) ^ \ + !!((a) & INT64_C(0x04)) ^ !!((a) & INT64_C(0x08)) ^ \ + !!((a) & INT64_C(0x10)) ^ !!((a) & INT64_C(0x20)) ^ \ + !!((a) & INT64_C(0x40)) ^ !!((a) & INT64_C(0x80))) static void generate_odd_parity(ntlm_des_block *block) { From 49ebc8a7551c32b3ea67d7d191b20be3e8905a8f Mon Sep 17 00:00:00 2001 From: Yoichi Nakayama Date: Fri, 22 Oct 2021 00:08:52 +0900 Subject: [PATCH 0585/1616] Add a branch with a empty reflog into testrepo.git --- tests/fetchhead/nonetwork.c | 2 +- tests/network/fetchlocal.c | 24 +++++++++---------- tests/network/remote/local.c | 6 ++--- tests/refs/branches/iterator.c | 4 ++-- tests/refs/foreachglob.c | 6 ++--- tests/refs/iterator.c | 2 ++ .../logs/refs/heads/with-empty-log | 0 .../testrepo.git/refs/heads/with-empty-log | 1 + 8 files changed, 24 insertions(+), 21 deletions(-) create mode 100644 tests/resources/testrepo.git/logs/refs/heads/with-empty-log create mode 100644 tests/resources/testrepo.git/refs/heads/with-empty-log diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c index 0de712be871..d1f09a817c0 100644 --- a/tests/fetchhead/nonetwork.c +++ b/tests/fetchhead/nonetwork.c @@ -508,7 +508,7 @@ void test_fetchhead_nonetwork__create_with_multiple_refspecs(void) int i; struct prefix_count prefix_counts[] = { {"refs/notes/", 0, 1}, - {"refs/heads/", 0, 12}, + {"refs/heads/", 0, 13}, {"refs/tags/", 0, 7}, {NULL, 0, 0}, }; diff --git a/tests/network/fetchlocal.c b/tests/network/fetchlocal.c index 302d1544cfb..2aa9fd5f1f6 100644 --- a/tests/network/fetchlocal.c +++ b/tests/network/fetchlocal.c @@ -45,7 +45,7 @@ void test_network_fetchlocal__complete(void) cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(19, (int)refnames.count); + cl_assert_equal_i(20, (int)refnames.count); cl_assert(callcount > 0); git_strarray_dispose(&refnames); @@ -74,7 +74,7 @@ void test_network_fetchlocal__prune(void) cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(19, (int)refnames.count); + cl_assert_equal_i(20, (int)refnames.count); cl_assert(callcount > 0); git_strarray_dispose(&refnames); git_remote_free(origin); @@ -88,7 +88,7 @@ void test_network_fetchlocal__prune(void) cl_git_pass(git_remote_prune(origin, &options.callbacks)); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(18, (int)refnames.count); + cl_assert_equal_i(19, (int)refnames.count); git_strarray_dispose(&refnames); git_remote_free(origin); @@ -101,7 +101,7 @@ void test_network_fetchlocal__prune(void) cl_git_pass(git_remote_prune(origin, &options.callbacks)); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(17, (int)refnames.count); + cl_assert_equal_i(18, (int)refnames.count); git_strarray_dispose(&refnames); git_remote_free(origin); @@ -166,7 +166,7 @@ void test_network_fetchlocal__prune_overlapping(void) assert_ref_exists(repo, "refs/remotes/origin/master"); assert_ref_exists(repo, "refs/remotes/origin/pr/42"); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(20, (int)refnames.count); + cl_assert_equal_i(21, (int)refnames.count); git_strarray_dispose(&refnames); cl_git_pass(git_config_delete_multivar(config, "remote.origin.fetch", "refs")); @@ -181,7 +181,7 @@ void test_network_fetchlocal__prune_overlapping(void) assert_ref_exists(repo, "refs/remotes/origin/master"); assert_ref_exists(repo, "refs/remotes/origin/pr/42"); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(20, (int)refnames.count); + cl_assert_equal_i(21, (int)refnames.count); git_strarray_dispose(&refnames); cl_git_pass(git_config_delete_multivar(config, "remote.origin.fetch", "refs")); @@ -221,7 +221,7 @@ void test_network_fetchlocal__fetchprune(void) cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(19, (int)refnames.count); + cl_assert_equal_i(20, (int)refnames.count); cl_assert(callcount > 0); git_strarray_dispose(&refnames); git_remote_free(origin); @@ -235,7 +235,7 @@ void test_network_fetchlocal__fetchprune(void) cl_git_pass(git_remote_prune(origin, &options.callbacks)); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(18, (int)refnames.count); + cl_assert_equal_i(19, (int)refnames.count); git_strarray_dispose(&refnames); git_remote_free(origin); @@ -251,7 +251,7 @@ void test_network_fetchlocal__fetchprune(void) cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(17, (int)refnames.count); + cl_assert_equal_i(18, (int)refnames.count); git_strarray_dispose(&refnames); git_remote_free(origin); @@ -335,7 +335,7 @@ void test_network_fetchlocal__partial(void) git_strarray_dispose(&refnames); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(20, (int)refnames.count); /* 18 remote + 1 local */ + cl_assert_equal_i(21, (int)refnames.count); /* 18 remote + 1 local */ cl_assert(callcount > 0); git_strarray_dispose(&refnames); @@ -418,7 +418,7 @@ void test_network_fetchlocal__multi_remotes(void) cl_git_pass(git_remote_fetch(test, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(33, (int)refnames.count); + cl_assert_equal_i(35, (int)refnames.count); git_strarray_dispose(&refnames); cl_git_pass(git_remote_set_url(repo, "test_with_pushurl", cl_git_fixture_url("testrepo.git"))); @@ -426,7 +426,7 @@ void test_network_fetchlocal__multi_remotes(void) cl_git_pass(git_remote_fetch(test2, NULL, &options, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); - cl_assert_equal_i(45, (int)refnames.count); + cl_assert_equal_i(48, (int)refnames.count); git_strarray_dispose(&refnames); git_remote_free(test); diff --git a/tests/network/remote/local.c b/tests/network/remote/local.c index f174044d732..2007f3776a1 100644 --- a/tests/network/remote/local.c +++ b/tests/network/remote/local.c @@ -61,7 +61,7 @@ void test_network_remote_local__retrieve_advertised_references(void) cl_git_pass(git_remote_ls(&refs, &refs_len, remote)); - cl_assert_equal_i(refs_len, 29); + cl_assert_equal_i(refs_len, 30); } void test_network_remote_local__retrieve_advertised_before_connect(void) @@ -85,7 +85,7 @@ void test_network_remote_local__retrieve_advertised_references_after_disconnect( cl_git_pass(git_remote_ls(&refs, &refs_len, remote)); - cl_assert_equal_i(refs_len, 29); + cl_assert_equal_i(refs_len, 30); } void test_network_remote_local__retrieve_advertised_references_from_spaced_repository(void) @@ -100,7 +100,7 @@ void test_network_remote_local__retrieve_advertised_references_from_spaced_repos cl_git_pass(git_remote_ls(&refs, &refs_len, remote)); - cl_assert_equal_i(refs_len, 29); + cl_assert_equal_i(refs_len, 30); git_remote_free(remote); /* Disconnect from the "spaced repo" before the cleanup */ remote = NULL; diff --git a/tests/refs/branches/iterator.c b/tests/refs/branches/iterator.c index ca366c9f3c1..e086681e554 100644 --- a/tests/refs/branches/iterator.c +++ b/tests/refs/branches/iterator.c @@ -48,7 +48,7 @@ static void assert_retrieval(unsigned int flags, unsigned int expected_count) void test_refs_branches_iterator__retrieve_all_branches(void) { - assert_retrieval(GIT_BRANCH_ALL, 14); + assert_retrieval(GIT_BRANCH_ALL, 15); } void test_refs_branches_iterator__retrieve_remote_branches(void) @@ -58,7 +58,7 @@ void test_refs_branches_iterator__retrieve_remote_branches(void) void test_refs_branches_iterator__retrieve_local_branches(void) { - assert_retrieval(GIT_BRANCH_LOCAL, 12); + assert_retrieval(GIT_BRANCH_LOCAL, 13); } struct expectations { diff --git a/tests/refs/foreachglob.c b/tests/refs/foreachglob.c index 3ff18a27a3b..b208a95a2b7 100644 --- a/tests/refs/foreachglob.c +++ b/tests/refs/foreachglob.c @@ -48,8 +48,8 @@ static void assert_retrieval(const char *glob, int expected_count) void test_refs_foreachglob__retrieve_all_refs(void) { - /* 12 heads (including one packed head) + 1 note + 2 remotes + 7 tags + 1 blob */ - assert_retrieval("*", 23); + /* 13 heads (including one packed head) + 1 note + 2 remotes + 7 tags + 1 blob */ + assert_retrieval("*", 24); } void test_refs_foreachglob__retrieve_remote_branches(void) @@ -59,7 +59,7 @@ void test_refs_foreachglob__retrieve_remote_branches(void) void test_refs_foreachglob__retrieve_local_branches(void) { - assert_retrieval("refs/heads/*", 12); + assert_retrieval("refs/heads/*", 13); } void test_refs_foreachglob__retrieve_nonexistant(void) diff --git a/tests/refs/iterator.c b/tests/refs/iterator.c index 8d52755c241..a4f9e62ec81 100644 --- a/tests/refs/iterator.c +++ b/tests/refs/iterator.c @@ -28,6 +28,7 @@ static const char *refnames[] = { "refs/heads/test", "refs/heads/track-local", "refs/heads/trailing", + "refs/heads/with-empty-log", "refs/notes/fanout", "refs/remotes/test/master", "refs/tags/annotated_tag_to_blob", @@ -58,6 +59,7 @@ static const char *refnames_with_symlink[] = { "refs/heads/test", "refs/heads/track-local", "refs/heads/trailing", + "refs/heads/with-empty-log", "refs/notes/fanout", "refs/remotes/test/master", "refs/tags/annotated_tag_to_blob", diff --git a/tests/resources/testrepo.git/logs/refs/heads/with-empty-log b/tests/resources/testrepo.git/logs/refs/heads/with-empty-log new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/resources/testrepo.git/refs/heads/with-empty-log b/tests/resources/testrepo.git/refs/heads/with-empty-log new file mode 100644 index 00000000000..dae4cb2b0d3 --- /dev/null +++ b/tests/resources/testrepo.git/refs/heads/with-empty-log @@ -0,0 +1 @@ +8496071c1b46c854b31185ea97743be6a8774479 From 776a6a8e5f8e258d31aded73c0ce38df6ac7bdc4 Mon Sep 17 00:00:00 2001 From: Yoichi Nakayama Date: Fri, 22 Oct 2021 00:09:39 +0900 Subject: [PATCH 0586/1616] Return the oldest reflog entry on revparse when older time is given For better compatibility with git command which returns the oldest log entry with a warning message. --- src/revparse.c | 10 +++++++--- tests/refs/revparse.c | 17 ++++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/revparse.c b/src/revparse.c index cf39936a5b1..8be22d6dd8f 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -207,7 +207,7 @@ static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, size_t ide { git_reflog *reflog; size_t numentries; - const git_reflog_entry *entry; + const git_reflog_entry *entry = NULL; bool search_by_pos = (identifier <= 100000000); if (git_reflog_read(&reflog, git_reference_owner(ref), git_reference_name(ref)) < 0) @@ -236,8 +236,12 @@ static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, size_t ide break; } - if (i == numentries) - goto notfound; + if (i == numentries) { + if (entry == NULL) + goto notfound; + + git_oid_cpy(oid, git_reflog_entry_id_new(entry)); + } } git_reflog_free(reflog); diff --git a/tests/refs/revparse.c b/tests/refs/revparse.c index 9c960702ae6..d6ec802e84a 100644 --- a/tests/refs/revparse.c +++ b/tests/refs/revparse.c @@ -399,7 +399,7 @@ void test_refs_revparse__date(void) * a65fedf HEAD@{1335806603 -0900}: commit: * be3563a HEAD@{1335806563 -0700}: clone: from /Users/ben/src/libgit2/tests/resour */ - test_object("HEAD@{10 years ago}", NULL); + test_object("HEAD@{10 years ago}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); test_object("HEAD@{1 second}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); test_object("HEAD@{1 second ago}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); @@ -417,11 +417,12 @@ void test_refs_revparse__date(void) /* - * $ git reflog -1 "master@{2012-04-30 17:22:42 +0000}" - * warning: Log for 'master' only goes back to Mon, 30 Apr 2012 09:22:43 -0800. + * $ git rev-parse "master@{2012-04-30 17:22:42 +0000}" + * warning: log for 'master' only goes back to Mon, 30 Apr 2012 09:22:43 -0800 + * be3563ae3f795b2b4353bcce3a527ad0a4f7f644 */ - test_object("master@{2012-04-30 17:22:42 +0000}", NULL); - test_object("master@{2012-04-30 09:22:42 -0800}", NULL); + test_object("master@{2012-04-30 17:22:42 +0000}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + test_object("master@{2012-04-30 09:22:42 -0800}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); /* * $ git reflog -1 "master@{2012-04-30 17:22:43 +0000}" @@ -451,6 +452,12 @@ void test_refs_revparse__date(void) */ test_object("master@{1335806603}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); test_object("master@{1335806602}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + + /* + * $ git rev-parse "with-empty-log@{2 days ago}" -- + * fatal: log for refs/heads/with-empty-log is empty + */ + test_object("with-empty-log@{2 days ago}", NULL); } void test_refs_revparse__colon(void) From 6c0d5366d9a9d24c76c1ca444a592111a1b2bdc3 Mon Sep 17 00:00:00 2001 From: Yoichi Nakayama Date: Fri, 22 Oct 2021 07:54:12 +0900 Subject: [PATCH 0587/1616] Cause error when date parsing is failed --- src/date.c | 4 ++-- src/revparse.c | 4 +++- tests/date/date.c | 7 +++++++ tests/refs/revparse.c | 13 +++++++++++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/date.c b/src/date.c index 2297ee66cf3..af6694e3057 100644 --- a/src/date.c +++ b/src/date.c @@ -853,7 +853,7 @@ static git_time_t approxidate_str(const char *date, } pending_number(&tm, &number); if (!touched) - *error_ret = 1; + *error_ret = -1; return update_tm(&tm, &now, 0); } @@ -872,7 +872,7 @@ int git__date_parse(git_time_t *out, const char *date) return -1; *out = approxidate_str(date, time_sec, &error_ret); - return error_ret; + return error_ret; } int git__date_rfc2822_fmt(char *out, size_t len, const git_time *date) diff --git a/src/revparse.c b/src/revparse.c index 8be22d6dd8f..2815bcfc492 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -348,8 +348,10 @@ static int handle_at_syntax(git_object **out, git_reference **ref, const char *s goto cleanup; } - if (git__date_parse(×tamp, curly_braces_content) < 0) + if (git__date_parse(×tamp, curly_braces_content) < 0) { + error = GIT_EINVALIDSPEC; goto cleanup; + } error = retrieve_revobject_from_reflog(out, ref, repo, git_str_cstr(&identifier), (size_t)timestamp); diff --git a/tests/date/date.c b/tests/date/date.c index 88881d1e137..ae787c0d3ed 100644 --- a/tests/date/date.c +++ b/tests/date/date.c @@ -13,3 +13,10 @@ void test_date_date__overflow(void) cl_assert(d2038 < d2039); #endif } + +void test_date_date__invalid_date(void) +{ + git_time_t d; + cl_git_fail(git__date_parse(&d, "")); + cl_git_fail(git__date_parse(&d, "NEITHER_INTEGER_NOR_DATETIME")); +} diff --git a/tests/refs/revparse.c b/tests/refs/revparse.c index d6ec802e84a..8d3a7e057b7 100644 --- a/tests/refs/revparse.c +++ b/tests/refs/revparse.c @@ -460,6 +460,19 @@ void test_refs_revparse__date(void) test_object("with-empty-log@{2 days ago}", NULL); } +void test_refs_revparse__invalid_date(void) +{ + /* + * $ git rev-parse HEAD@{} -- + * fatal: bad revision 'HEAD@{}' + * + * $ git rev-parse HEAD@{NEITHER_INTEGER_NOR_DATETIME} -- + * fatal: bad revision 'HEAD@{NEITHER_INTEGER_NOR_DATETIME}' + */ + test_object("HEAD@{}", NULL); + test_object("HEAD@{NEITHER_INTEGER_NOR_DATETIME}", NULL); +} + void test_refs_revparse__colon(void) { assert_invalid_single_spec(":/"); From 540b02f3b97baf2bc1d62210a23d522b5d73e5eb Mon Sep 17 00:00:00 2001 From: Yoichi Nakayama Date: Fri, 22 Oct 2021 23:21:22 +0900 Subject: [PATCH 0588/1616] Add TODO comment for emit a warning --- src/revparse.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/revparse.c b/src/revparse.c index 2815bcfc492..61e836aa87d 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -240,6 +240,9 @@ static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, size_t ide if (entry == NULL) goto notfound; + /* + * TODO: emit a warning (log for 'branch' only goes back to ...) + */ git_oid_cpy(oid, git_reflog_entry_id_new(entry)); } } From f66e7f36ffba13e5eac5bac965f128c39642c174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BChl?= Date: Thu, 28 Oct 2021 10:25:09 +0200 Subject: [PATCH 0589/1616] libgit2_clar is now libgit2_tests in #6083 the test runner was renamed to libgit2_tests, but not all references to the old name were updated. this change changes all of them to use the new name. --- .vscode/launch.json | 4 ++-- .vscode/tasks.json | 4 ++-- README.md | 6 +++--- cmake/IdeSplitSources.cmake | 2 +- docs/contributing.md | 8 ++++---- fuzzers/corpora/objects/blob | 6 +++--- tests/README.md | 8 ++++---- tests/core/init.c | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index d47d93aab10..62d4ec949b1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/build/libgit2_clar", + "program": "${workspaceFolder}/build/libgit2_tests", "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", @@ -24,4 +24,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 64142d3410d..24b4d745b31 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -16,7 +16,7 @@ { "label": "Run Tests", "type": "shell", - "command": "build/libgit2_clar -v", + "command": "build/libgit2_tests -v", "group": "test", "presentation": { "reveal": "always", @@ -24,4 +24,4 @@ } } ] - } \ No newline at end of file + } diff --git a/README.md b/README.md index ea1c8e29f79..2a365df302d 100644 --- a/README.md +++ b/README.md @@ -236,18 +236,18 @@ Once built, you can run the tests from the `build` directory with the command Alternatively you can run the test suite directly using, - $ ./libgit2_clar + $ ./libgit2_tests Invoking the test suite directly is useful because it allows you to execute individual tests, or groups of tests using the `-s` flag. For example, to run the index tests: - $ ./libgit2_clar -sindex + $ ./libgit2_tests -sindex To run a single test named `index::racy::diff`, which corresponds to the test function [`test_index_racy__diff`](https://github.com/libgit2/libgit2/blob/main/tests/index/racy.c#L23): - $ ./libgit2_clar -sindex::racy::diff + $ ./libgit2_tests -sindex::racy::diff The test suite will print a `.` for every passing test, and an `F` for any failing test. An `S` indicates that a test was skipped because it is not diff --git a/cmake/IdeSplitSources.cmake b/cmake/IdeSplitSources.cmake index e2e09b4ce15..396f18eb4a1 100644 --- a/cmake/IdeSplitSources.cmake +++ b/cmake/IdeSplitSources.cmake @@ -1,6 +1,6 @@ # This function splits the sources files up into their appropriate # subdirectories. This is especially useful for IDEs like Xcode and -# Visual Studio, so that you can navigate into the libgit2_clar project, +# Visual Studio, so that you can navigate into the libgit2_tests project, # and see the folders within the tests folder (instead of just seeing all # source and tests in a single folder.) FUNCTION(IDE_SPLIT_SOURCES target) diff --git a/docs/contributing.md b/docs/contributing.md index f3e559c9d81..03e0017093b 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -120,15 +120,15 @@ In addition to new tests, please ensure that your changes do not cause any other test failures. Running the entire test suite is helpful before you submit a pull request. When you build libgit2, the test suite will also be built. You can run most of the tests by simply running -the resultant `libgit2_clar` binary. If you want to run a specific +the resultant `libgit2_tests` binary. If you want to run a specific unit test, you can name it with the `-s` option. For example: - libgit2_clar -sstatus::worktree::long_filenames + libgit2_tests -sstatus::worktree::long_filenames Or you can run an entire class of tests. For example, to run all the worktree status tests: - libgit2_clar -sstatus::worktree + libgit2_tests -sstatus::worktree The default test run is fairly exhaustive, but it will exclude some unit tests by default: in particular, those that talk to network @@ -136,7 +136,7 @@ servers and the tests that manipulate the filesystem in onerous ways (and may need to have special privileges to run). To run the network tests: - libgit2_clar -ionline + libgit2_tests -ionline In addition, various tests may be enabled by environment variables, like the ones that write exceptionally large repositories or manipulate diff --git a/fuzzers/corpora/objects/blob b/fuzzers/corpora/objects/blob index 2031037b15b..b09444c80cf 100644 --- a/fuzzers/corpora/objects/blob +++ b/fuzzers/corpora/objects/blob @@ -187,18 +187,18 @@ Once built, you can run the tests from the `build` directory with the command Alternatively you can run the test suite directly using, - $ ./libgit2_clar + $ ./libgit2_tests Invoking the test suite directly is useful because it allows you to execute individual tests, or groups of tests using the `-s` flag. For example, to run the index tests: - $ ./libgit2_clar -sindex + $ ./libgit2_tests -sindex To run a single test named `index::racy::diff`, which corresponds to the test function (`test_index_racy__diff`)[https://github.com/libgit2/libgit2/blob/master/tests/index/racy.c#L23]: - $ ./libgit2_clar -sindex::racy::diff + $ ./libgit2_tests -sindex::racy::diff The test suite will print a `.` for every passing test, and an `F` for any failing test. An `S` indicates that a test was skipped because it is not diff --git a/tests/README.md b/tests/README.md index 7684a6e64eb..4369a8f3381 100644 --- a/tests/README.md +++ b/tests/README.md @@ -15,7 +15,7 @@ https://github.com/vmg/clar * Test: - ./build/libgit2_clar + ./build/libgit2_tests * Make sure everything is fine. @@ -34,8 +34,8 @@ Uses [`valgrind`](http://www.valgrind.org/): ```console $ cmake -DBUILD_TESTS=ON -DVALGRIND=ON .. $ cmake --build . -$ valgrind --leak-check=full --show-reachable=yes --num-callers=50 --suppressions=../libgit2_clar.supp \ - ./libgit2_clar +$ valgrind --leak-check=full --show-reachable=yes --num-callers=50 --suppressions=../libgit2_tests.supp \ + ./libgit2_tests ``` #### macOS @@ -44,5 +44,5 @@ Uses [`leaks`](https://developer.apple.com/library/archive/documentation/Perform ```console $ MallocStackLogging=1 MallocScribble=1 MallocLogFile=/dev/null CLAR_AT_EXIT="leaks -quiet \$PPID" \ - ./libgit2_clar + ./libgit2_tests ``` diff --git a/tests/core/init.c b/tests/core/init.c index a8cbd930b60..eba77ef522f 100644 --- a/tests/core/init.c +++ b/tests/core/init.c @@ -2,7 +2,7 @@ void test_core_init__returns_count(void) { - /* libgit2_clar initializes us first, so we have an existing + /* libgit2_tests initializes us first, so we have an existing * initialization. */ cl_assert_equal_i(2, git_libgit2_init()); From 3993e9aebc7d293e9aec420800c581f7f234def7 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 8 Nov 2021 14:00:09 +0100 Subject: [PATCH 0590/1616] Update documentation for ODB backend refresh logic Commit b1a6c316a6070fac4ab1ec5792979838f7145c39 moved auto-refresh into the pack backend, and added a comment accordingly. Commit 43820f204ea32503b4083e3b6b83f30a0a0031c9 moved auto-refresh back *out* of backends into the ODB layer, but didn't update the comment. --- include/git2/sys/odb_backend.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/include/git2/sys/odb_backend.h b/include/git2/sys/odb_backend.h index 9ae0ed9b3ed..8598f94e561 100644 --- a/include/git2/sys/odb_backend.h +++ b/include/git2/sys/odb_backend.h @@ -69,11 +69,8 @@ struct git_odb_backend { * If the backend implements a refreshing mechanism, it should be exposed * through this endpoint. Each call to `git_odb_refresh()` will invoke it. * - * However, the backend implementation should try to stay up-to-date as much - * as possible by itself as libgit2 will not automatically invoke - * `git_odb_refresh()`. For instance, a potential strategy for the backend - * implementation to achieve this could be to internally invoke this - * endpoint on failed lookups (ie. `exists()`, `read()`, `read_header()`). + * The odb layer will automatically call this when needed on failed + * lookups (ie. `exists()`, `read()`, `read_header()`). */ int GIT_CALLBACK(refresh)(git_odb_backend *); From 81662d432c585df651a9f733670ac577f6b555a5 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 8 Nov 2021 14:48:45 +0100 Subject: [PATCH 0591/1616] Support checking for object existence without refresh Looking up a non-existent object currently always invokes `git_odb_refresh`. If looking up a large batch of objects, many of which may legitimately not exist, this will repeatedly refresh the ODB to no avail. Add a `git_odb_exists_ext` that accepts flags controlling the ODB lookup, and add a flag to suppress the refresh. This allows the user to control if and when they refresh (for instance, refreshing once before starting the batch). --- include/git2/odb.h | 22 ++++++++++++++++++++++ src/odb.c | 7 ++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/include/git2/odb.h b/include/git2/odb.h index dd484553ff2..6c86cd625b2 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -22,6 +22,17 @@ */ GIT_BEGIN_DECL +/** Flags controlling the behavior of ODB lookup operations */ +typedef enum { + /** + * Don't call `git_odb_refresh` if the lookup fails. Useful when doing + * a batch of lookup operations for objects that may legitimately not + * exist. When using this flag, you may wish to manually call + * `git_odb_refresh` before processing a batch of objects. + */ + GIT_ODB_LOOKUP_NO_REFRESH = (1 << 0), +} git_odb_lookup_flags_t; + /** * Function type for callbacks from git_odb_foreach. */ @@ -155,6 +166,17 @@ GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_object_t *type_out, git */ GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id); +/** + * Determine if the given object can be found in the object database, with + * extended options. + * + * @param db database to be searched for the given object. + * @param id the object to search for. + * @param flags flags affecting the lookup (see `git_odb_lookup_flags_t`) + * @return 1 if the object was found, 0 otherwise + */ +GIT_EXTERN(int) git_odb_exists_ext(git_odb *db, const git_oid *id, unsigned int flags); + /** * Determine if an object can be found in the object database by an * abbreviated object ID. diff --git a/src/odb.c b/src/odb.c index 7bf57547405..79328672b6d 100644 --- a/src/odb.c +++ b/src/odb.c @@ -882,6 +882,11 @@ int git_odb__freshen(git_odb *db, const git_oid *id) } int git_odb_exists(git_odb *db, const git_oid *id) +{ + return git_odb_exists_ext(db, id, 0); +} + +int git_odb_exists_ext(git_odb *db, const git_oid *id, unsigned int flags) { git_odb_object *object; @@ -899,7 +904,7 @@ int git_odb_exists(git_odb *db, const git_oid *id) if (odb_exists_1(db, id, false)) return 1; - if (!git_odb_refresh(db)) + if (!(flags & GIT_ODB_LOOKUP_NO_REFRESH) && !git_odb_refresh(db)) return odb_exists_1(db, id, true); /* Failed to refresh, hence not found */ From 94cb060c37269485470fb11b7b7207ccf4f9b784 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 8 Nov 2021 14:54:09 +0100 Subject: [PATCH 0592/1616] Add tests for ODB refresh Add optional refreshing in the fake backend, and count the number of refresh calls if enabled. --- tests/odb/backend/backend_helpers.c | 17 ++- tests/odb/backend/backend_helpers.h | 4 +- tests/odb/backend/multiple.c | 4 +- tests/odb/backend/nonrefreshing.c | 2 +- tests/odb/backend/refreshing.c | 176 ++++++++++++++++++++++++++++ tests/odb/backend/simple.c | 2 +- 6 files changed, 198 insertions(+), 7 deletions(-) create mode 100644 tests/odb/backend/refreshing.c diff --git a/tests/odb/backend/backend_helpers.c b/tests/odb/backend/backend_helpers.c index 139d2fc72a0..54279924299 100644 --- a/tests/odb/backend/backend_helpers.c +++ b/tests/odb/backend/backend_helpers.c @@ -123,6 +123,18 @@ static int fake_backend__read_prefix( return 0; } +static int fake_backend__refresh(git_odb_backend *backend) +{ + fake_backend *fake; + + fake = (fake_backend *)backend; + + fake->refresh_calls++; + + return 0; +} + + static void fake_backend__free(git_odb_backend *_backend) { fake_backend *backend; @@ -134,7 +146,8 @@ static void fake_backend__free(git_odb_backend *_backend) int build_fake_backend( git_odb_backend **out, - const fake_object *objects) + const fake_object *objects, + bool support_refresh) { fake_backend *backend; @@ -143,12 +156,12 @@ int build_fake_backend( backend->parent.version = GIT_ODB_BACKEND_VERSION; - backend->parent.refresh = NULL; backend->objects = objects; backend->parent.read = fake_backend__read; backend->parent.read_prefix = fake_backend__read_prefix; backend->parent.read_header = fake_backend__read_header; + backend->parent.refresh = support_refresh ? fake_backend__refresh : NULL; backend->parent.exists = fake_backend__exists; backend->parent.exists_prefix = fake_backend__exists_prefix; backend->parent.free = &fake_backend__free; diff --git a/tests/odb/backend/backend_helpers.h b/tests/odb/backend/backend_helpers.h index 5c393c0a536..32d7a8bf03b 100644 --- a/tests/odb/backend/backend_helpers.h +++ b/tests/odb/backend/backend_helpers.h @@ -13,10 +13,12 @@ typedef struct { int read_calls; int read_header_calls; int read_prefix_calls; + int refresh_calls; const fake_object *objects; } fake_backend; int build_fake_backend( git_odb_backend **out, - const fake_object *objects); + const fake_object *objects, + bool support_refresh); diff --git a/tests/odb/backend/multiple.c b/tests/odb/backend/multiple.c index 1c6068df350..5f1eacd52b3 100644 --- a/tests/odb/backend/multiple.c +++ b/tests/odb/backend/multiple.c @@ -29,10 +29,10 @@ void test_odb_backend_multiple__initialize(void) _obj = NULL; _repo = cl_git_sandbox_init("testrepo.git"); - cl_git_pass(build_fake_backend(&backend, _objects_filled)); + cl_git_pass(build_fake_backend(&backend, _objects_filled, false)); _fake_filled = (fake_backend *)backend; - cl_git_pass(build_fake_backend(&backend, _objects_empty)); + cl_git_pass(build_fake_backend(&backend, _objects_empty, false)); _fake_empty = (fake_backend *)backend; } diff --git a/tests/odb/backend/nonrefreshing.c b/tests/odb/backend/nonrefreshing.c index ede48ade66e..2db10efbcea 100644 --- a/tests/odb/backend/nonrefreshing.c +++ b/tests/odb/backend/nonrefreshing.c @@ -23,7 +23,7 @@ static void setup_repository_and_backend(void) _repo = cl_git_sandbox_init("testrepo.git"); - cl_git_pass(build_fake_backend(&backend, _objects)); + cl_git_pass(build_fake_backend(&backend, _objects, false)); cl_git_pass(git_repository_odb__weakptr(&odb, _repo)); cl_git_pass(git_odb_add_backend(odb, backend, 10)); diff --git a/tests/odb/backend/refreshing.c b/tests/odb/backend/refreshing.c new file mode 100644 index 00000000000..9e49298a888 --- /dev/null +++ b/tests/odb/backend/refreshing.c @@ -0,0 +1,176 @@ +#include "clar_libgit2.h" +#include "repository.h" +#include "backend_helpers.h" + +static git_repository *_repo; +static fake_backend *_fake; + +#define NONEXISTING_HASH "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" +#define EXISTING_HASH "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391" + +static const fake_object _objects[] = { + { EXISTING_HASH, "" }, + { NULL, NULL } +}; + +static git_oid _nonexisting_oid; +static git_oid _existing_oid; + +static void setup_repository_and_backend(void) +{ + git_odb *odb = NULL; + git_odb_backend *backend = NULL; + + _repo = cl_git_sandbox_init("testrepo.git"); + + cl_git_pass(build_fake_backend(&backend, _objects, true)); + + cl_git_pass(git_repository_odb__weakptr(&odb, _repo)); + cl_git_pass(git_odb_add_backend(odb, backend, 10)); + + _fake = (fake_backend *)backend; +} + +void test_odb_backend_refreshing__initialize(void) +{ + git_oid_fromstr(&_nonexisting_oid, NONEXISTING_HASH); + git_oid_fromstr(&_existing_oid, EXISTING_HASH); + setup_repository_and_backend(); +} + +void test_odb_backend_refreshing__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_odb_backend_refreshing__exists_is_invoked_twice_on_failure(void) +{ + git_odb *odb; + + cl_git_pass(git_repository_odb__weakptr(&odb, _repo)); + cl_assert_equal_b(false, git_odb_exists(odb, &_nonexisting_oid)); + + cl_assert_equal_i(2, _fake->exists_calls); + cl_assert_equal_i(1, _fake->refresh_calls); +} + +void test_odb_backend_refreshing__read_is_invoked_twice_on_failure(void) +{ + git_object *obj; + + cl_git_fail_with( + git_object_lookup(&obj, _repo, &_nonexisting_oid, GIT_OBJECT_ANY), + GIT_ENOTFOUND); + + cl_assert_equal_i(2, _fake->read_calls); + cl_assert_equal_i(1, _fake->refresh_calls); +} + +void test_odb_backend_refreshing__readprefix_is_invoked_twice_on_failure(void) +{ + git_object *obj; + + cl_git_fail_with( + git_object_lookup_prefix(&obj, _repo, &_nonexisting_oid, 7, GIT_OBJECT_ANY), + GIT_ENOTFOUND); + + cl_assert_equal_i(2, _fake->read_prefix_calls); + cl_assert_equal_i(1, _fake->refresh_calls); +} + +void test_odb_backend_refreshing__readheader_is_invoked_twice_on_failure(void) +{ + git_odb *odb; + size_t len; + git_object_t type; + + cl_git_pass(git_repository_odb__weakptr(&odb, _repo)); + + cl_git_fail_with( + git_odb_read_header(&len, &type, odb, &_nonexisting_oid), + GIT_ENOTFOUND); + + cl_assert_equal_i(2, _fake->read_header_calls); + cl_assert_equal_i(1, _fake->refresh_calls); +} + +void test_odb_backend_refreshing__exists_is_invoked_once_on_success(void) +{ + git_odb *odb; + + cl_git_pass(git_repository_odb__weakptr(&odb, _repo)); + cl_assert_equal_b(true, git_odb_exists(odb, &_existing_oid)); + + cl_assert_equal_i(1, _fake->exists_calls); + cl_assert_equal_i(0, _fake->refresh_calls); +} + +void test_odb_backend_refreshing__read_is_invoked_once_on_success(void) +{ + git_object *obj; + + cl_git_pass(git_object_lookup(&obj, _repo, &_existing_oid, GIT_OBJECT_ANY)); + + cl_assert_equal_i(1, _fake->read_calls); + cl_assert_equal_i(0, _fake->refresh_calls); + + git_object_free(obj); +} + +void test_odb_backend_refreshing__readprefix_is_invoked_once_on_success(void) +{ + git_object *obj; + + cl_git_pass(git_object_lookup_prefix(&obj, _repo, &_existing_oid, 7, GIT_OBJECT_ANY)); + + cl_assert_equal_i(1, _fake->read_prefix_calls); + cl_assert_equal_i(0, _fake->refresh_calls); + + git_object_free(obj); +} + +void test_odb_backend_refreshing__readheader_is_invoked_once_on_success(void) +{ + git_odb *odb; + size_t len; + git_object_t type; + + cl_git_pass(git_repository_odb__weakptr(&odb, _repo)); + + cl_git_pass(git_odb_read_header(&len, &type, odb, &_existing_oid)); + + cl_assert_equal_i(1, _fake->read_header_calls); + cl_assert_equal_i(0, _fake->refresh_calls); +} + +void test_odb_backend_refreshing__read_is_invoked_twice_when_revparsing_a_full_oid(void) +{ + git_object *obj; + + cl_git_fail_with( + git_revparse_single(&obj, _repo, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"), + GIT_ENOTFOUND); + + cl_assert_equal_i(2, _fake->read_calls); + cl_assert_equal_i(1, _fake->refresh_calls); +} + +void test_odb_backend_refreshing__refresh_is_invoked(void) +{ + git_odb *odb; + + cl_git_pass(git_repository_odb__weakptr(&odb, _repo)); + cl_assert_equal_i(0, git_odb_refresh(odb)); + + cl_assert_equal_i(1, _fake->refresh_calls); +} + +void test_odb_backend_refreshing__refresh_suppressed_with_no_refresh(void) +{ + git_odb *odb; + + cl_git_pass(git_repository_odb__weakptr(&odb, _repo)); + cl_assert_equal_b(false, git_odb_exists_ext(odb, &_nonexisting_oid, GIT_ODB_LOOKUP_NO_REFRESH)); + + cl_assert_equal_i(0, _fake->refresh_calls); +} diff --git a/tests/odb/backend/simple.c b/tests/odb/backend/simple.c index 484dcba5a5a..6c9293ac0d8 100644 --- a/tests/odb/backend/simple.c +++ b/tests/odb/backend/simple.c @@ -13,7 +13,7 @@ static void setup_backend(const fake_object *objs) { git_odb_backend *backend; - cl_git_pass(build_fake_backend(&backend, objs)); + cl_git_pass(build_fake_backend(&backend, objs, false)); cl_git_pass(git_repository_odb__weakptr(&_odb, _repo)); cl_git_pass(git_odb_add_backend(_odb, backend, 10)); From f45ff6c92d8d27ff0c3eb007267eadb4aeeaf16f Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 8 Nov 2021 17:33:35 +0100 Subject: [PATCH 0593/1616] Omit trailing comma on enum To accommodate less capable compilers. Co-authored-by: Peter Pettersson <85582231+boretrk@users.noreply.github.com> --- include/git2/odb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/odb.h b/include/git2/odb.h index 6c86cd625b2..0691aa4d075 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -30,7 +30,7 @@ typedef enum { * exist. When using this flag, you may wish to manually call * `git_odb_refresh` before processing a batch of objects. */ - GIT_ODB_LOOKUP_NO_REFRESH = (1 << 0), + GIT_ODB_LOOKUP_NO_REFRESH = (1 << 0) } git_odb_lookup_flags_t; /** From 51f6f15d710c39c6844ceef58efea6db93c46d61 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 9 Nov 2021 09:03:06 -0500 Subject: [PATCH 0594/1616] ci: only update docs on push Only update the documentation on a `push`. We were previously updating the documentation only when not in a `pull_request`, which meant that we would push documentation updates in manual build triggers. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 572f025444a..e805b1bb891 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -300,4 +300,4 @@ jobs: - name: Push documentation branch working-directory: source run: git push origin gh-pages - if: github.event_name != 'pull_request' && github.repository == 'libgit2/libgit2' + if: github.event_name == 'push' && github.repository == 'libgit2/libgit2' From 95117d4744cf5a66f2bcde7991a925e9852d9b1e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 31 Oct 2021 09:45:46 -0400 Subject: [PATCH 0595/1616] path: separate git-specific path functions from util Introduce `git_fs_path`, which operates on generic filesystem paths. `git_path` will be kept for only git-specific path functionality (for example, checking for `.git` in a path). --- fuzzers/standalone_driver.c | 2 +- src/attr.c | 8 +- src/attr_file.c | 6 +- src/attrcache.c | 8 +- src/blob.c | 4 +- src/checkout.c | 25 +- src/clone.c | 16 +- src/config.c | 2 +- src/config_file.c | 22 +- src/diff_generate.c | 4 +- src/diff_stats.c | 2 +- src/diff_tform.c | 4 +- src/filebuf.c | 14 +- src/filter.c | 4 +- src/fs_path.c | 1839 ++++++++++++++++++++++++++ src/fs_path.h | 728 +++++++++++ src/futils.c | 50 +- src/futils.h | 2 +- src/ignore.c | 22 +- src/index.c | 9 +- src/iterator.c | 29 +- src/mailmap.c | 6 +- src/merge.c | 2 +- src/midx.c | 8 +- src/odb.c | 4 +- src/odb_loose.c | 20 +- src/odb_pack.c | 6 +- src/pack.c | 2 +- src/patch_parse.c | 4 +- src/path.c | 1867 +-------------------------- src/path.h | 723 +---------- src/posix.c | 6 +- src/rebase.c | 8 +- src/refdb_fs.c | 43 +- src/refs.c | 8 +- src/repository.c | 118 +- src/submodule.c | 37 +- src/sysdir.c | 4 +- src/transport.c | 6 +- src/transports/local.c | 6 +- src/tree.c | 11 +- src/win32/findfile.c | 2 +- src/win32/path_w32.c | 14 +- src/win32/posix_w32.c | 10 +- src/worktree.c | 48 +- tests/attr/repo.c | 2 +- tests/checkout/conflict.c | 24 +- tests/checkout/crlf.c | 18 +- tests/checkout/head.c | 24 +- tests/checkout/icase.c | 22 +- tests/checkout/index.c | 62 +- tests/checkout/nasty.c | 6 +- tests/checkout/tree.c | 192 +-- tests/checkout/typechange.c | 34 +- tests/cherrypick/workdir.c | 18 +- tests/clar_libgit2.c | 20 +- tests/clone/nonetwork.c | 16 +- tests/config/global.c | 8 +- tests/config/read.c | 8 +- tests/config/readonly.c | 10 +- tests/config/stress.c | 6 +- tests/core/copy.c | 80 +- tests/core/dirent.c | 48 +- tests/core/env.c | 6 +- tests/core/filebuf.c | 24 +- tests/core/futils.c | 6 +- tests/core/iconv.c | 20 +- tests/core/mkdir.c | 108 +- tests/core/path.c | 98 +- tests/core/posix.c | 12 +- tests/core/rmdir.c | 26 +- tests/core/stat.c | 2 +- tests/diff/drivers.c | 2 +- tests/diff/workdir.c | 10 +- tests/fetchhead/nonetwork.c | 8 +- tests/ignore/path.c | 4 +- tests/index/crlf.c | 16 +- tests/index/tests.c | 4 +- tests/iterator/index.c | 2 +- tests/iterator/workdir.c | 2 +- tests/merge/merge_helpers.c | 2 +- tests/merge/workdir/setup.c | 178 +-- tests/merge/workdir/simple.c | 2 +- tests/object/blob/write.c | 4 +- tests/object/raw/write.c | 4 +- tests/odb/alternates.c | 2 +- tests/odb/emptyobjects.c | 2 +- tests/online/clone.c | 6 +- tests/online/customcert.c | 4 +- tests/pack/indexer.c | 2 +- tests/pack/packbuilder.c | 4 +- tests/path/core.c | 384 +++--- tests/path/dotgit.c | 86 ++ tests/refs/branches/create.c | 2 +- tests/refs/branches/delete.c | 8 +- tests/refs/delete.c | 4 +- tests/refs/pack.c | 4 +- tests/refs/ref_helpers.c | 2 +- tests/refs/reflog/reflog.c | 18 +- tests/refs/rename.c | 12 +- tests/refs/revparse.c | 4 +- tests/repo/config.c | 22 +- tests/repo/discover.c | 6 +- tests/repo/env.c | 10 +- tests/repo/init.c | 26 +- tests/repo/open.c | 10 +- tests/repo/setters.c | 2 +- tests/repo/template.c | 6 +- tests/reset/hard.c | 12 +- tests/revert/workdir.c | 10 +- tests/stash/drop.c | 14 +- tests/stash/save.c | 20 +- tests/status/submodules.c | 12 +- tests/status/worktree.c | 10 +- tests/submodule/add.c | 16 +- tests/submodule/init.c | 6 +- tests/submodule/open.c | 10 +- tests/submodule/repository_init.c | 8 +- tests/submodule/submodule_helpers.c | 2 +- tests/worktree/merge.c | 2 +- tests/worktree/refs.c | 4 +- tests/worktree/submodule.c | 2 +- tests/worktree/worktree.c | 14 +- 123 files changed, 3894 insertions(+), 3775 deletions(-) create mode 100644 src/fs_path.c create mode 100644 src/fs_path.h diff --git a/fuzzers/standalone_driver.c b/fuzzers/standalone_driver.c index 88c8cfbda3d..c29102e6524 100644 --- a/fuzzers/standalone_driver.c +++ b/fuzzers/standalone_driver.c @@ -52,7 +52,7 @@ int main(int argc, char **argv) fprintf(stderr, "Running %s against %s\n", argv[0], argv[1]); LLVMFuzzerInitialize(&argc, &argv); - if (git_path_dirload(&corpus_files, argv[1], 0, 0x0) < 0) { + if (git_fs_path_dirload(&corpus_files, argv[1], 0, 0x0) < 0) { fprintf(stderr, "Failed to scan corpus directory '%s': %s\n", argv[1], git_error_last()->message); error = -1; diff --git a/src/attr.c b/src/attr.c index 5849e701f60..409c30b01ea 100644 --- a/src/attr.c +++ b/src/attr.c @@ -629,7 +629,7 @@ static int collect_attr_files( const char *workdir = git_repository_workdir(repo); attr_walk_up_info info = { NULL }; - GIT_ASSERT(!git_path_is_absolute(path)); + GIT_ASSERT(!git_fs_path_is_absolute(path)); if ((error = attr_setup(repo, attr_session, opts)) < 0) return error; @@ -637,10 +637,10 @@ static int collect_attr_files( /* Resolve path in a non-bare repo */ if (workdir != NULL) { if (!(error = git_repository_workdir_path(&dir, repo, path))) - error = git_path_find_dir(&dir); + error = git_fs_path_find_dir(&dir); } else { - error = git_path_dirname_r(&dir, path); + error = git_fs_path_dirname_r(&dir, path); } if (error < 0) @@ -670,7 +670,7 @@ static int collect_attr_files( if (!strcmp(dir.ptr, ".")) error = push_one_attr(&info, ""); else - error = git_path_walk_up(&dir, workdir, push_one_attr, &info); + error = git_fs_path_walk_up(&dir, workdir, push_one_attr, &info); if (error < 0) goto cleanup; diff --git a/src/attr_file.c b/src/attr_file.c index 09f0ce1b8af..0eb881a9b92 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -345,7 +345,7 @@ int git_attr_file__parse_buffer( int error = 0; /* If subdir file path, convert context for file paths */ - if (attrs->entry && git_path_root(attrs->entry->path) < 0 && + if (attrs->entry && git_fs_path_root(attrs->entry->path) < 0 && !git__suffixcmp(attrs->entry->path, "/" GIT_ATTR_FILE)) context = attrs->entry->path; @@ -560,7 +560,7 @@ int git_attr_path__init( /* build full path as best we can */ git_str_init(&info->full, 0); - if (git_path_join_unrooted(&info->full, path, base, &root) < 0) + if (git_fs_path_join_unrooted(&info->full, path, base, &root) < 0) return -1; info->path = info->full.ptr + root; @@ -596,7 +596,7 @@ int git_attr_path__init( case GIT_DIR_FLAG_UNKNOWN: default: - info->is_dir = (int)git_path_isdir(info->full.ptr); + info->is_dir = (int)git_fs_path_isdir(info->full.ptr); break; } diff --git a/src/attrcache.c b/src/attrcache.c index 98d73cbc3ba..15c7fab485a 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -47,7 +47,7 @@ int git_attr_cache__alloc_file_entry( size_t cachesize = sizeof(git_attr_file_entry) + pathlen + 1; git_attr_file_entry *ce; - if (base != NULL && git_path_root(path) < 0) { + if (base != NULL && git_fs_path_root(path) < 0) { baselen = strlen(base); cachesize += baselen; @@ -66,7 +66,7 @@ int git_attr_cache__alloc_file_entry( } memcpy(&ce->fullpath[baselen], path, pathlen); - if (git_path_validate_workdir_with_len(repo, ce->fullpath, pathlen + baselen) < 0) + if (git_fs_path_validate_workdir_with_len(repo, ce->fullpath, pathlen + baselen) < 0) return -1; ce->path = &ce->fullpath[baselen]; @@ -169,11 +169,11 @@ static int attr_cache_lookup( git_attr_file *file = NULL; /* join base and path as needed */ - if (source->base != NULL && git_path_root(source->filename) < 0) { + if (source->base != NULL && git_fs_path_root(source->filename) < 0) { git_str *p = attr_session ? &attr_session->tmp : &path; if (git_str_joinpath(p, source->base, source->filename) < 0 || - git_path_validate_workdir_buf(repo, p) < 0) + git_fs_path_validate_workdir_buf(repo, p) < 0) return -1; filename = p->ptr; diff --git a/src/blob.c b/src/blob.c index 6f57d09e4ac..65841ab03da 100644 --- a/src/blob.c +++ b/src/blob.c @@ -205,7 +205,7 @@ int git_blob__create_from_paths( content_path = path.ptr; } - if ((error = git_path_lstat(content_path, &st)) < 0 || + if ((error = git_fs_path_lstat(content_path, &st)) < 0 || (error = git_repository_odb(&odb, repo)) < 0) goto done; @@ -280,7 +280,7 @@ int git_blob_create_from_disk( git_str full_path = GIT_STR_INIT; const char *workdir, *hintpath = NULL; - if ((error = git_path_prettify(&full_path, path, NULL)) < 0) { + if ((error = git_fs_path_prettify(&full_path, path, NULL)) < 0) { git_str_dispose(&full_path); return error; } diff --git a/src/checkout.c b/src/checkout.c index b31918fc893..96ba4da386b 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -27,10 +27,11 @@ #include "diff_generate.h" #include "pathspec.h" #include "diff_xdiff.h" -#include "path.h" +#include "fs_path.h" #include "attr.h" #include "pool.h" #include "strmap.h" +#include "path.h" /* See docs/checkout-internals.md for more information */ @@ -328,7 +329,7 @@ static int checkout_target_fullpath( if (path && git_str_puts(&data->target_path, path) < 0) return -1; - if (git_path_validate_workdir_buf(data->repo, &data->target_path) < 0) + if (git_fs_path_validate_workdir_buf(data->repo, &data->target_path) < 0) return -1; *out = &data->target_path; @@ -347,7 +348,7 @@ static bool wd_item_is_removable( if (checkout_target_fullpath(&full, data, wd->path) < 0) return false; - return !full || !git_path_contains(full, DOT_GIT); + return !full || !git_fs_path_contains(full, DOT_GIT); } static int checkout_queue_remove(checkout_data *data, const char *path) @@ -481,7 +482,7 @@ static bool checkout_is_empty_dir(checkout_data *data, const char *path) if (checkout_target_fullpath(&fullpath, data, path) < 0) return false; - return git_path_is_empty_dir(fullpath->ptr); + return git_fs_path_is_empty_dir(fullpath->ptr); } static int checkout_action_with_wd( @@ -1201,12 +1202,12 @@ static int checkout_conflicts_mark_directoryfile( goto done; } - prefixed = git_path_equal_or_prefixed(path, entry->path, NULL); + prefixed = git_fs_path_equal_or_prefixed(path, entry->path, NULL); - if (prefixed == GIT_PATH_EQUAL) + if (prefixed == GIT_FS_PATH_EQUAL) continue; - if (prefixed == GIT_PATH_PREFIX) + if (prefixed == GIT_FS_PATH_PREFIX) conflict->directoryfile = 1; break; @@ -1949,7 +1950,7 @@ static int checkout_path_suffixed(git_str *path, const char *suffix) path_len = git_str_len(path); - while (git_path_exists(git_str_cstr(path)) && i < INT_MAX) { + while (git_fs_path_exists(git_str_cstr(path)) && i < INT_MAX) { git_str_truncate(path, path_len); if ((error = git_str_putc(path, '_')) < 0 || @@ -2034,7 +2035,7 @@ static int checkout_merge_path( int error = 0; if ((error = git_str_joinpath(out, data->opts.target_directory, result->path)) < 0 || - (error = git_path_validate_workdir_buf(data->repo, out)) < 0) + (error = git_fs_path_validate_workdir_buf(data->repo, out)) < 0) return error; /* Most conflicts simply use the filename in the index */ @@ -2337,10 +2338,10 @@ static int validate_target_directory(checkout_data *data) { int error; - if ((error = git_path_validate_workdir(data->repo, data->opts.target_directory)) < 0) + if ((error = git_fs_path_validate_workdir(data->repo, data->opts.target_directory)) < 0) return error; - if (git_path_isdir(data->opts.target_directory)) + if (git_fs_path_isdir(data->opts.target_directory)) return 0; error = checkout_mkdir(data, data->opts.target_directory, NULL, @@ -2507,7 +2508,7 @@ static int checkout_data_init( (error = git_vector_init(&data->remove_conflicts, 0, NULL)) < 0 || (error = git_vector_init(&data->update_conflicts, 0, NULL)) < 0 || (error = git_str_puts(&data->target_path, data->opts.target_directory)) < 0 || - (error = git_path_to_dir(&data->target_path)) < 0 || + (error = git_fs_path_to_dir(&data->target_path)) < 0 || (error = git_strmap_new(&data->mkdir_map)) < 0) goto cleanup; diff --git a/src/clone.c b/src/clone.c index cf4cc3c7f46..1843875f8e5 100644 --- a/src/clone.c +++ b/src/clone.c @@ -19,7 +19,7 @@ #include "remote.h" #include "futils.h" #include "refs.h" -#include "path.h" +#include "fs_path.h" #include "repository.h" #include "odb.h" @@ -333,7 +333,7 @@ static int create_and_configure_origin( void *payload = options->remote_cb_payload; /* If the path exists and is a dir, the url should be the absolute path */ - if (git_path_root(url) < 0 && git_path_exists(url) && git_path_isdir(url)) { + if (git_fs_path_root(url) < 0 && git_fs_path_exists(url) && git_fs_path_isdir(url)) { if (p_realpath(url, buf) == NULL) return -1; @@ -433,8 +433,8 @@ int git_clone__should_clone_local(const char *url_or_path, git_clone_local_t loc if (local == GIT_CLONE_NO_LOCAL) return 0; - if ((is_url = git_path_is_local_file_url(url_or_path)) != 0) { - if (git_path_fromurl(&fromurl, url_or_path) < 0) { + if ((is_url = git_fs_path_is_local_file_url(url_or_path)) != 0) { + if (git_fs_path_fromurl(&fromurl, url_or_path) < 0) { is_local = -1; goto done; } @@ -443,7 +443,7 @@ int git_clone__should_clone_local(const char *url_or_path, git_clone_local_t loc } is_local = (!is_url || local != GIT_CLONE_LOCAL_AUTO) && - git_path_isdir(path); + git_fs_path_isdir(path); done: git_str_dispose(&fromurl); @@ -474,14 +474,14 @@ static int git__clone( GIT_ERROR_CHECK_VERSION(&options, GIT_CLONE_OPTIONS_VERSION, "git_clone_options"); /* Only clone to a new directory or an empty directory */ - if (git_path_exists(local_path) && !use_existing && !git_path_is_empty_dir(local_path)) { + if (git_fs_path_exists(local_path) && !use_existing && !git_fs_path_is_empty_dir(local_path)) { git_error_set(GIT_ERROR_INVALID, "'%s' exists and is not an empty directory", local_path); return GIT_EEXISTS; } /* Only remove the root directory on failure if we create it */ - if (git_path_exists(local_path)) + if (git_fs_path_exists(local_path)) rmdir_flags |= GIT_RMDIR_SKIP_ROOT; if (options.repository_cb) @@ -602,7 +602,7 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_ * repo, if it's not rooted, the path should be relative to * the repository's worktree/gitdir. */ - if ((error = git_path_from_url_or_path(&src_path, git_remote_url(remote))) < 0) + if ((error = git_fs_path_from_url_or_path(&src_path, git_remote_url(remote))) < 0) return error; /* Copy .git/objects/ from the source to the target */ diff --git a/src/config.c b/src/config.c index 9033a92c523..88da34c5e48 100644 --- a/src/config.c +++ b/src/config.c @@ -1177,7 +1177,7 @@ int git_config__find_programdata(git_str *path) if (ret != GIT_OK) return ret; - return git_path_validate_system_file_ownership(path->ptr); + return git_fs_path_validate_system_file_ownership(path->ptr); } int git_config__global_location(git_str *buf) diff --git a/src/config_file.c b/src/config_file.c index 9c3d2ceb8fb..11b444094cf 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -108,7 +108,7 @@ static int config_file_open(git_config_backend *cfg, git_config_level_t level, c if ((res = git_config_entries_new(&b->entries)) < 0) return res; - if (!git_path_exists(b->file.path)) + if (!git_fs_path_exists(b->file.path)) return 0; /* @@ -529,7 +529,7 @@ static int included_path(git_str *out, const char *dir, const char *path) if (path[0] == '~' && path[1] == '/') return git_sysdir_expand_global_file(out, &path[1]); - return git_path_join_unrooted(out, path, dir, NULL); + return git_fs_path_join_unrooted(out, path, dir, NULL); } /* Escape the values to write them to the file */ @@ -574,7 +574,7 @@ static int parse_include(config_file_parse_data *parse_data, const char *file) if (!file) return 0; - if ((result = git_path_dirname_r(&path, parse_data->file->path)) < 0) + if ((result = git_fs_path_dirname_r(&path, parse_data->file->path)) < 0) return result; dir = git_str_detach(&path); @@ -611,17 +611,17 @@ static int do_match_gitdir( git_str pattern = GIT_STR_INIT, gitdir = GIT_STR_INIT; int error; - if (condition[0] == '.' && git_path_is_dirsep(condition[1])) { - git_path_dirname_r(&pattern, cfg_file); + if (condition[0] == '.' && git_fs_path_is_dirsep(condition[1])) { + git_fs_path_dirname_r(&pattern, cfg_file); git_str_joinpath(&pattern, pattern.ptr, condition + 2); - } else if (condition[0] == '~' && git_path_is_dirsep(condition[1])) + } else if (condition[0] == '~' && git_fs_path_is_dirsep(condition[1])) git_sysdir_expand_global_file(&pattern, condition + 1); - else if (!git_path_is_absolute(condition)) + else if (!git_fs_path_is_absolute(condition)) git_str_joinpath(&pattern, "**", condition); else git_str_sets(&pattern, condition); - if (git_path_is_dirsep(condition[strlen(condition) - 1])) + if (git_fs_path_is_dirsep(condition[strlen(condition) - 1])) git_str_puts(&pattern, "**"); if (git_str_oom(&pattern)) { @@ -632,7 +632,7 @@ static int do_match_gitdir( if ((error = git_repository__item_path(&gitdir, repo, GIT_REPOSITORY_ITEM_GITDIR)) < 0) goto out; - if (git_path_is_dirsep(gitdir.ptr[gitdir.size - 1])) + if (git_fs_path_is_dirsep(gitdir.ptr[gitdir.size - 1])) git_str_truncate(&gitdir, gitdir.size - 1); *matches = wildmatch(pattern.ptr, gitdir.ptr, @@ -699,7 +699,7 @@ static int conditional_match_onbranch( */ if ((error = git_str_sets(&buf, condition)) < 0) goto out; - if (git_path_is_dirsep(condition[strlen(condition) - 1]) && + if (git_fs_path_is_dirsep(condition[strlen(condition) - 1]) && (error = git_str_puts(&buf, "**")) < 0) goto out; @@ -861,7 +861,7 @@ static int config_file_read( int error; if (p_stat(file->path, &st) < 0) { - error = git_path_set_error(errno, file->path, "stat"); + error = git_fs_path_set_error(errno, file->path, "stat"); goto out; } diff --git a/src/diff_generate.c b/src/diff_generate.c index dc690aa9b9e..dca16d51a4e 100644 --- a/src/diff_generate.c +++ b/src/diff_generate.c @@ -605,7 +605,7 @@ int git_diff__oid_for_entry( diff->base.perf.stat_calls++; if (p_stat(full_path.ptr, &st) < 0) { - error = git_path_set_error(errno, entry.path, "stat"); + error = git_fs_path_set_error(errno, entry.path, "stat"); git_str_dispose(&full_path); return error; } @@ -1026,7 +1026,7 @@ static int handle_unmatched_new_item( git_str *full = NULL; if (git_iterator_current_workdir_path(&full, info->new_iter) < 0) return -1; - if (full && git_path_contains(full, DOT_GIT)) { + if (full && git_fs_path_contains(full, DOT_GIT)) { /* TODO: warning if not a valid git repository */ recurse_into_dir = false; } diff --git a/src/diff_stats.c b/src/diff_stats.c index 228f6f89291..259939844a5 100644 --- a/src/diff_stats.c +++ b/src/diff_stats.c @@ -70,7 +70,7 @@ static int diff_file_stats_full_to_buf( padding = stats->max_name - strlen(old_path) - strlen(new_path); - if ((common_dirlen = git_path_common_dirlen(old_path, new_path)) && + if ((common_dirlen = git_fs_path_common_dirlen(old_path, new_path)) && common_dirlen <= INT_MAX) { error = git_str_printf(out, " %.*s{%s"DIFF_RENAME_FILE_SEPARATOR"%s}", (int) common_dirlen, old_path, diff --git a/src/diff_tform.c b/src/diff_tform.c index be55de6c3a0..d14134071bc 100644 --- a/src/diff_tform.c +++ b/src/diff_tform.c @@ -13,7 +13,7 @@ #include "diff.h" #include "diff_generate.h" -#include "path.h" +#include "fs_path.h" #include "futils.h" #include "config.h" @@ -481,7 +481,7 @@ static int similarity_sig( return error; /* if path is not a regular file, just skip this item */ - if (!git_path_isfile(info->data.ptr)) + if (!git_fs_path_isfile(info->data.ptr)) return 0; /* TODO: apply wd-to-odb filters to file data if necessary */ diff --git a/src/filebuf.c b/src/filebuf.c index 10f8c581320..f0bd0004f12 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -43,7 +43,7 @@ static int verify_last_error(git_filebuf *file) static int lock_file(git_filebuf *file, int flags, mode_t mode) { - if (git_path_exists(file->path_lock) == true) { + if (git_fs_path_exists(file->path_lock) == true) { git_error_clear(); /* actual OS error code just confuses */ git_error_set(GIT_ERROR_OS, "failed to lock file '%s' for writing", file->path_lock); @@ -63,7 +63,7 @@ static int lock_file(git_filebuf *file, int flags, mode_t mode) file->fd_is_open = true; - if ((flags & GIT_FILEBUF_APPEND) && git_path_exists(file->path_original) == true) { + if ((flags & GIT_FILEBUF_APPEND) && git_fs_path_exists(file->path_original) == true) { git_file source; char buffer[FILEIO_BUFSIZE]; ssize_t read_bytes; @@ -103,7 +103,7 @@ void git_filebuf_cleanup(git_filebuf *file) if (file->fd_is_open && file->fd >= 0) p_close(file->fd); - if (file->created_lock && !file->did_rename && file->path_lock && git_path_exists(file->path_lock)) + if (file->created_lock && !file->did_rename && file->path_lock && git_fs_path_exists(file->path_lock)) p_unlink(file->path_lock); if (file->compute_digest) { @@ -241,20 +241,20 @@ static int resolve_symlink(git_str *out, const char *path) target.ptr[ret] = '\0'; target.size = ret; - root = git_path_root(target.ptr); + root = git_fs_path_root(target.ptr); if (root >= 0) { if ((error = git_str_sets(&curpath, target.ptr)) < 0) goto cleanup; } else { git_str dir = GIT_STR_INIT; - if ((error = git_path_dirname_r(&dir, curpath.ptr)) < 0) + if ((error = git_fs_path_dirname_r(&dir, curpath.ptr)) < 0) goto cleanup; git_str_swap(&curpath, &dir); git_str_dispose(&dir); - if ((error = git_path_apply_relative(&curpath, target.ptr)) < 0) + if ((error = git_fs_path_apply_relative(&curpath, target.ptr)) < 0) goto cleanup; } } @@ -366,7 +366,7 @@ int git_filebuf_open_withsize(git_filebuf *file, const char *path, int flags, mo memcpy(file->path_lock, file->path_original, path_len); memcpy(file->path_lock + path_len, GIT_FILELOCK_EXTENSION, GIT_FILELOCK_EXTLENGTH); - if (git_path_isdir(file->path_original)) { + if (git_fs_path_isdir(file->path_original)) { git_error_set(GIT_ERROR_FILESYSTEM, "path '%s' is a directory", file->path_original); error = GIT_EDIRECTORY; goto cleanup; diff --git a/src/filter.c b/src/filter.c index 417d9cb8bbf..95029603303 100644 --- a/src/filter.c +++ b/src/filter.c @@ -1094,8 +1094,8 @@ int git_filter_list_stream_file( if ((error = stream_list_init( &stream_start, &filter_streams, filters, target)) < 0 || - (error = git_path_join_unrooted(&abspath, path, base, NULL)) < 0 || - (error = git_path_validate_workdir_buf(repo, &abspath)) < 0) + (error = git_fs_path_join_unrooted(&abspath, path, base, NULL)) < 0 || + (error = git_fs_path_validate_workdir_buf(repo, &abspath)) < 0) goto done; initialized = 1; diff --git a/src/fs_path.c b/src/fs_path.c new file mode 100644 index 00000000000..e180d586622 --- /dev/null +++ b/src/fs_path.c @@ -0,0 +1,1839 @@ +/* + * 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 "fs_path.h" + +#include "posix.h" +#include "repository.h" +#ifdef GIT_WIN32 +#include "win32/posix.h" +#include "win32/w32_buffer.h" +#include "win32/w32_util.h" +#include "win32/version.h" +#include +#else +#include +#endif +#include +#include + +static int dos_drive_prefix_length(const char *path) +{ + int i; + + /* + * Does it start with an ASCII letter (i.e. highest bit not set), + * followed by a colon? + */ + if (!(0x80 & (unsigned char)*path)) + return *path && path[1] == ':' ? 2 : 0; + + /* + * While drive letters must be letters of the English alphabet, it is + * possible to assign virtually _any_ Unicode character via `subst` as + * a drive letter to "virtual drives". Even `1`, or `ä`. Or fun stuff + * like this: + * + * subst Ö: %USERPROFILE%\Desktop + */ + for (i = 1; i < 4 && (0x80 & (unsigned char)path[i]); i++) + ; /* skip first UTF-8 character */ + return path[i] == ':' ? i + 1 : 0; +} + +#ifdef GIT_WIN32 +static bool looks_like_network_computer_name(const char *path, int pos) +{ + if (pos < 3) + return false; + + if (path[0] != '/' || path[1] != '/') + return false; + + while (pos-- > 2) { + if (path[pos] == '/') + return false; + } + + return true; +} +#endif + +/* + * Based on the Android implementation, BSD licensed. + * http://android.git.kernel.org/ + * + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +int git_fs_path_basename_r(git_str *buffer, const char *path) +{ + const char *endp, *startp; + int len, result; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + startp = "."; + len = 1; + goto Exit; + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* All slashes becomes "/" */ + if (endp == path && *endp == '/') { + startp = "/"; + len = 1; + goto Exit; + } + + /* Find the start of the base */ + startp = endp; + while (startp > path && *(startp - 1) != '/') + startp--; + + /* Cast is safe because max path < max int */ + len = (int)(endp - startp + 1); + +Exit: + result = len; + + if (buffer != NULL && git_str_set(buffer, startp, len) < 0) + return -1; + + return result; +} + +/* + * Determine if the path is a Windows prefix and, if so, returns + * its actual lentgh. If it is not a prefix, returns -1. + */ +static int win32_prefix_length(const char *path, int len) +{ +#ifndef GIT_WIN32 + GIT_UNUSED(path); + GIT_UNUSED(len); +#else + /* + * Mimic unix behavior where '/.git' returns '/': 'C:/.git' + * will return 'C:/' here + */ + if (dos_drive_prefix_length(path) == len) + return len; + + /* + * Similarly checks if we're dealing with a network computer name + * '//computername/.git' will return '//computername/' + */ + if (looks_like_network_computer_name(path, len)) + return len; +#endif + + return -1; +} + +/* + * Based on the Android implementation, BSD licensed. + * Check http://android.git.kernel.org/ + */ +int git_fs_path_dirname_r(git_str *buffer, const char *path) +{ + const char *endp; + int is_prefix = 0, len; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + path = "."; + len = 1; + goto Exit; + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + if (endp - path + 1 > INT_MAX) { + git_error_set(GIT_ERROR_INVALID, "path too long"); + len = -1; + goto Exit; + } + + if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) { + is_prefix = 1; + goto Exit; + } + + /* Find the start of the dir */ + while (endp > path && *endp != '/') + endp--; + + /* Either the dir is "/" or there are no slashes */ + if (endp == path) { + path = (*endp == '/') ? "/" : "."; + len = 1; + goto Exit; + } + + do { + endp--; + } while (endp > path && *endp == '/'); + + if (endp - path + 1 > INT_MAX) { + git_error_set(GIT_ERROR_INVALID, "path too long"); + len = -1; + goto Exit; + } + + if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) { + is_prefix = 1; + goto Exit; + } + + /* Cast is safe because max path < max int */ + len = (int)(endp - path + 1); + +Exit: + if (buffer) { + if (git_str_set(buffer, path, len) < 0) + return -1; + if (is_prefix && git_str_putc(buffer, '/') < 0) + return -1; + } + + return len; +} + + +char *git_fs_path_dirname(const char *path) +{ + git_str buf = GIT_STR_INIT; + char *dirname; + + git_fs_path_dirname_r(&buf, path); + dirname = git_str_detach(&buf); + git_str_dispose(&buf); /* avoid memleak if error occurs */ + + return dirname; +} + +char *git_fs_path_basename(const char *path) +{ + git_str buf = GIT_STR_INIT; + char *basename; + + git_fs_path_basename_r(&buf, path); + basename = git_str_detach(&buf); + git_str_dispose(&buf); /* avoid memleak if error occurs */ + + return basename; +} + +size_t git_fs_path_basename_offset(git_str *buffer) +{ + ssize_t slash; + + if (!buffer || buffer->size <= 0) + return 0; + + slash = git_str_rfind_next(buffer, '/'); + + if (slash >= 0 && buffer->ptr[slash] == '/') + return (size_t)(slash + 1); + + return 0; +} + +int git_fs_path_root(const char *path) +{ + int offset = 0, prefix_len; + + /* Does the root of the path look like a windows drive ? */ + if ((prefix_len = dos_drive_prefix_length(path))) + offset += prefix_len; + +#ifdef GIT_WIN32 + /* Are we dealing with a windows network path? */ + else if ((path[0] == '/' && path[1] == '/' && path[2] != '/') || + (path[0] == '\\' && path[1] == '\\' && path[2] != '\\')) + { + offset += 2; + + /* Skip the computer name segment */ + while (path[offset] && path[offset] != '/' && path[offset] != '\\') + offset++; + } + + if (path[offset] == '\\') + return offset; +#endif + + if (path[offset] == '/') + return offset; + + return -1; /* Not a real error - signals that path is not rooted */ +} + +static void path_trim_slashes(git_str *path) +{ + int ceiling = git_fs_path_root(path->ptr) + 1; + + if (ceiling < 0) + return; + + while (path->size > (size_t)ceiling) { + if (path->ptr[path->size-1] != '/') + break; + + path->ptr[path->size-1] = '\0'; + path->size--; + } +} + +int git_fs_path_join_unrooted( + git_str *path_out, const char *path, const char *base, ssize_t *root_at) +{ + ssize_t root; + + GIT_ASSERT_ARG(path_out); + GIT_ASSERT_ARG(path); + + root = (ssize_t)git_fs_path_root(path); + + if (base != NULL && root < 0) { + if (git_str_joinpath(path_out, base, path) < 0) + return -1; + + root = (ssize_t)strlen(base); + } else { + if (git_str_sets(path_out, path) < 0) + return -1; + + if (root < 0) + root = 0; + else if (base) + git_fs_path_equal_or_prefixed(base, path, &root); + } + + if (root_at) + *root_at = root; + + return 0; +} + +void git_fs_path_squash_slashes(git_str *path) +{ + char *p, *q; + + if (path->size == 0) + return; + + for (p = path->ptr, q = path->ptr; *q; p++, q++) { + *p = *q; + + while (*q == '/' && *(q+1) == '/') { + path->size--; + q++; + } + } + + *p = '\0'; +} + +int git_fs_path_prettify(git_str *path_out, const char *path, const char *base) +{ + char buf[GIT_PATH_MAX]; + + GIT_ASSERT_ARG(path_out); + GIT_ASSERT_ARG(path); + + /* construct path if needed */ + if (base != NULL && git_fs_path_root(path) < 0) { + if (git_str_joinpath(path_out, base, path) < 0) + return -1; + path = path_out->ptr; + } + + if (p_realpath(path, buf) == NULL) { + /* git_error_set resets the errno when dealing with a GIT_ERROR_OS kind of error */ + int error = (errno == ENOENT || errno == ENOTDIR) ? GIT_ENOTFOUND : -1; + git_error_set(GIT_ERROR_OS, "failed to resolve path '%s'", path); + + git_str_clear(path_out); + + return error; + } + + return git_str_sets(path_out, buf); +} + +int git_fs_path_prettify_dir(git_str *path_out, const char *path, const char *base) +{ + int error = git_fs_path_prettify(path_out, path, base); + return (error < 0) ? error : git_fs_path_to_dir(path_out); +} + +int git_fs_path_to_dir(git_str *path) +{ + if (path->asize > 0 && + git_str_len(path) > 0 && + path->ptr[git_str_len(path) - 1] != '/') + git_str_putc(path, '/'); + + return git_str_oom(path) ? -1 : 0; +} + +void git_fs_path_string_to_dir(char *path, size_t size) +{ + size_t end = strlen(path); + + if (end && path[end - 1] != '/' && end < size) { + path[end] = '/'; + path[end + 1] = '\0'; + } +} + +int git__percent_decode(git_str *decoded_out, const char *input) +{ + int len, hi, lo, i; + + GIT_ASSERT_ARG(decoded_out); + GIT_ASSERT_ARG(input); + + len = (int)strlen(input); + git_str_clear(decoded_out); + + for(i = 0; i < len; i++) + { + char c = input[i]; + + if (c != '%') + goto append; + + if (i >= len - 2) + goto append; + + hi = git__fromhex(input[i + 1]); + lo = git__fromhex(input[i + 2]); + + if (hi < 0 || lo < 0) + goto append; + + c = (char)(hi << 4 | lo); + i += 2; + +append: + if (git_str_putc(decoded_out, c) < 0) + return -1; + } + + return 0; +} + +static int error_invalid_local_file_uri(const char *uri) +{ + git_error_set(GIT_ERROR_CONFIG, "'%s' is not a valid local file URI", uri); + return -1; +} + +static int local_file_url_prefixlen(const char *file_url) +{ + int len = -1; + + if (git__prefixcmp(file_url, "file://") == 0) { + if (file_url[7] == '/') + len = 8; + else if (git__prefixcmp(file_url + 7, "localhost/") == 0) + len = 17; + } + + return len; +} + +bool git_fs_path_is_local_file_url(const char *file_url) +{ + return (local_file_url_prefixlen(file_url) > 0); +} + +int git_fs_path_fromurl(git_str *local_path_out, const char *file_url) +{ + int offset; + + GIT_ASSERT_ARG(local_path_out); + GIT_ASSERT_ARG(file_url); + + if ((offset = local_file_url_prefixlen(file_url)) < 0 || + file_url[offset] == '\0' || file_url[offset] == '/') + return error_invalid_local_file_uri(file_url); + +#ifndef GIT_WIN32 + offset--; /* A *nix absolute path starts with a forward slash */ +#endif + + git_str_clear(local_path_out); + return git__percent_decode(local_path_out, file_url + offset); +} + +int git_fs_path_walk_up( + git_str *path, + const char *ceiling, + int (*cb)(void *data, const char *), + void *data) +{ + int error = 0; + git_str iter; + ssize_t stop = 0, scan; + char oldc = '\0'; + + GIT_ASSERT_ARG(path); + GIT_ASSERT_ARG(cb); + + if (ceiling != NULL) { + if (git__prefixcmp(path->ptr, ceiling) == 0) + stop = (ssize_t)strlen(ceiling); + else + stop = git_str_len(path); + } + scan = git_str_len(path); + + /* empty path: yield only once */ + if (!scan) { + error = cb(data, ""); + if (error) + git_error_set_after_callback(error); + return error; + } + + iter.ptr = path->ptr; + iter.size = git_str_len(path); + iter.asize = path->asize; + + while (scan >= stop) { + error = cb(data, iter.ptr); + iter.ptr[scan] = oldc; + + if (error) { + git_error_set_after_callback(error); + break; + } + + scan = git_str_rfind_next(&iter, '/'); + if (scan >= 0) { + scan++; + oldc = iter.ptr[scan]; + iter.size = scan; + iter.ptr[scan] = '\0'; + } + } + + if (scan >= 0) + iter.ptr[scan] = oldc; + + /* relative path: yield for the last component */ + if (!error && stop == 0 && iter.ptr[0] != '/') { + error = cb(data, ""); + if (error) + git_error_set_after_callback(error); + } + + return error; +} + +bool git_fs_path_exists(const char *path) +{ + GIT_ASSERT_ARG_WITH_RETVAL(path, false); + return p_access(path, F_OK) == 0; +} + +bool git_fs_path_isdir(const char *path) +{ + struct stat st; + if (p_stat(path, &st) < 0) + return false; + + return S_ISDIR(st.st_mode) != 0; +} + +bool git_fs_path_isfile(const char *path) +{ + struct stat st; + + GIT_ASSERT_ARG_WITH_RETVAL(path, false); + if (p_stat(path, &st) < 0) + return false; + + return S_ISREG(st.st_mode) != 0; +} + +bool git_fs_path_islink(const char *path) +{ + struct stat st; + + GIT_ASSERT_ARG_WITH_RETVAL(path, false); + if (p_lstat(path, &st) < 0) + return false; + + return S_ISLNK(st.st_mode) != 0; +} + +#ifdef GIT_WIN32 + +bool git_fs_path_is_empty_dir(const char *path) +{ + git_win32_path filter_w; + bool empty = false; + + if (git_win32__findfirstfile_filter(filter_w, path)) { + WIN32_FIND_DATAW findData; + HANDLE hFind = FindFirstFileW(filter_w, &findData); + + /* FindFirstFile will fail if there are no children to the given + * path, which can happen if the given path is a file (and obviously + * has no children) or if the given path is an empty mount point. + * (Most directories have at least directory entries '.' and '..', + * but ridiculously another volume mounted in another drive letter's + * path space do not, and thus have nothing to enumerate.) If + * FindFirstFile fails, check if this is a directory-like thing + * (a mount point). + */ + if (hFind == INVALID_HANDLE_VALUE) + return git_fs_path_isdir(path); + + /* If the find handle was created successfully, then it's a directory */ + empty = true; + + do { + /* Allow the enumeration to return . and .. and still be considered + * empty. In the special case of drive roots (i.e. C:\) where . and + * .. do not occur, we can still consider the path to be an empty + * directory if there's nothing there. */ + if (!git_fs_path_is_dot_or_dotdotW(findData.cFileName)) { + empty = false; + break; + } + } while (FindNextFileW(hFind, &findData)); + + FindClose(hFind); + } + + return empty; +} + +#else + +static int path_found_entry(void *payload, git_str *path) +{ + GIT_UNUSED(payload); + return !git_fs_path_is_dot_or_dotdot(path->ptr); +} + +bool git_fs_path_is_empty_dir(const char *path) +{ + int error; + git_str dir = GIT_STR_INIT; + + if (!git_fs_path_isdir(path)) + return false; + + if ((error = git_str_sets(&dir, path)) != 0) + git_error_clear(); + else + error = git_fs_path_direach(&dir, 0, path_found_entry, NULL); + + git_str_dispose(&dir); + + return !error; +} + +#endif + +int git_fs_path_set_error(int errno_value, const char *path, const char *action) +{ + switch (errno_value) { + case ENOENT: + case ENOTDIR: + git_error_set(GIT_ERROR_OS, "could not find '%s' to %s", path, action); + return GIT_ENOTFOUND; + + case EINVAL: + case ENAMETOOLONG: + git_error_set(GIT_ERROR_OS, "invalid path for filesystem '%s'", path); + return GIT_EINVALIDSPEC; + + case EEXIST: + git_error_set(GIT_ERROR_OS, "failed %s - '%s' already exists", action, path); + return GIT_EEXISTS; + + case EACCES: + git_error_set(GIT_ERROR_OS, "failed %s - '%s' is locked", action, path); + return GIT_ELOCKED; + + default: + git_error_set(GIT_ERROR_OS, "could not %s '%s'", action, path); + return -1; + } +} + +int git_fs_path_lstat(const char *path, struct stat *st) +{ + if (p_lstat(path, st) == 0) + return 0; + + return git_fs_path_set_error(errno, path, "stat"); +} + +static bool _check_dir_contents( + git_str *dir, + const char *sub, + bool (*predicate)(const char *)) +{ + bool result; + size_t dir_size = git_str_len(dir); + size_t sub_size = strlen(sub); + size_t alloc_size; + + /* leave base valid even if we could not make space for subdir */ + if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) || + GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) || + git_str_try_grow(dir, alloc_size, false) < 0) + return false; + + /* save excursion */ + if (git_str_joinpath(dir, dir->ptr, sub) < 0) + return false; + + result = predicate(dir->ptr); + + /* restore path */ + git_str_truncate(dir, dir_size); + return result; +} + +bool git_fs_path_contains(git_str *dir, const char *item) +{ + return _check_dir_contents(dir, item, &git_fs_path_exists); +} + +bool git_fs_path_contains_dir(git_str *base, const char *subdir) +{ + return _check_dir_contents(base, subdir, &git_fs_path_isdir); +} + +bool git_fs_path_contains_file(git_str *base, const char *file) +{ + return _check_dir_contents(base, file, &git_fs_path_isfile); +} + +int git_fs_path_find_dir(git_str *dir) +{ + int error = 0; + char buf[GIT_PATH_MAX]; + + if (p_realpath(dir->ptr, buf) != NULL) + error = git_str_sets(dir, buf); + + /* call dirname if this is not a directory */ + if (!error) /* && git_fs_path_isdir(dir->ptr) == false) */ + error = (git_fs_path_dirname_r(dir, dir->ptr) < 0) ? -1 : 0; + + if (!error) + error = git_fs_path_to_dir(dir); + + return error; +} + +int git_fs_path_resolve_relative(git_str *path, size_t ceiling) +{ + char *base, *to, *from, *next; + size_t len; + + GIT_ERROR_CHECK_ALLOC_STR(path); + + if (ceiling > path->size) + ceiling = path->size; + + /* recognize drive prefixes, etc. that should not be backed over */ + if (ceiling == 0) + ceiling = git_fs_path_root(path->ptr) + 1; + + /* recognize URL prefixes that should not be backed over */ + if (ceiling == 0) { + for (next = path->ptr; *next && git__isalpha(*next); ++next); + if (next[0] == ':' && next[1] == '/' && next[2] == '/') + ceiling = (next + 3) - path->ptr; + } + + base = to = from = path->ptr + ceiling; + + while (*from) { + for (next = from; *next && *next != '/'; ++next); + + len = next - from; + + if (len == 1 && from[0] == '.') + /* do nothing with singleton dot */; + + else if (len == 2 && from[0] == '.' && from[1] == '.') { + /* error out if trying to up one from a hard base */ + if (to == base && ceiling != 0) { + git_error_set(GIT_ERROR_INVALID, + "cannot strip root component off url"); + return -1; + } + + /* no more path segments to strip, + * use '../' as a new base path */ + if (to == base) { + if (*next == '/') + len++; + + if (to != from) + memmove(to, from, len); + + to += len; + /* this is now the base, can't back up from a + * relative prefix */ + base = to; + } else { + /* back up a path segment */ + while (to > base && to[-1] == '/') to--; + while (to > base && to[-1] != '/') to--; + } + } else { + if (*next == '/' && *from != '/') + len++; + + if (to != from) + memmove(to, from, len); + + to += len; + } + + from += len; + + while (*from == '/') from++; + } + + *to = '\0'; + + path->size = to - path->ptr; + + return 0; +} + +int git_fs_path_apply_relative(git_str *target, const char *relpath) +{ + return git_str_joinpath(target, git_str_cstr(target), relpath) || + git_fs_path_resolve_relative(target, 0); +} + +int git_fs_path_cmp( + const char *name1, size_t len1, int isdir1, + const char *name2, size_t len2, int isdir2, + int (*compare)(const char *, const char *, size_t)) +{ + unsigned char c1, c2; + size_t len = len1 < len2 ? len1 : len2; + int cmp; + + cmp = compare(name1, name2, len); + if (cmp) + return cmp; + + c1 = name1[len]; + c2 = name2[len]; + + if (c1 == '\0' && isdir1) + c1 = '/'; + + if (c2 == '\0' && isdir2) + c2 = '/'; + + return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0; +} + +size_t git_fs_path_common_dirlen(const char *one, const char *two) +{ + const char *p, *q, *dirsep = NULL; + + for (p = one, q = two; *p && *q; p++, q++) { + if (*p == '/' && *q == '/') + dirsep = p; + else if (*p != *q) + break; + } + + return dirsep ? (dirsep - one) + 1 : 0; +} + +int git_fs_path_make_relative(git_str *path, const char *parent) +{ + const char *p, *q, *p_dirsep, *q_dirsep; + size_t plen = path->size, newlen, alloclen, depth = 1, i, offset; + + for (p_dirsep = p = path->ptr, q_dirsep = q = parent; *p && *q; p++, q++) { + if (*p == '/' && *q == '/') { + p_dirsep = p; + q_dirsep = q; + } + else if (*p != *q) + break; + } + + /* need at least 1 common path segment */ + if ((p_dirsep == path->ptr || q_dirsep == parent) && + (*p_dirsep != '/' || *q_dirsep != '/')) { + git_error_set(GIT_ERROR_INVALID, + "%s is not a parent of %s", parent, path->ptr); + return GIT_ENOTFOUND; + } + + if (*p == '/' && !*q) + p++; + else if (!*p && *q == '/') + q++; + else if (!*p && !*q) + return git_str_clear(path), 0; + else { + p = p_dirsep + 1; + q = q_dirsep + 1; + } + + plen -= (p - path->ptr); + + if (!*q) + return git_str_set(path, p, plen); + + for (; (q = strchr(q, '/')) && *(q + 1); q++) + depth++; + + GIT_ERROR_CHECK_ALLOC_MULTIPLY(&newlen, depth, 3); + GIT_ERROR_CHECK_ALLOC_ADD(&newlen, newlen, plen); + + GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, newlen, 1); + + /* save the offset as we might realllocate the pointer */ + offset = p - path->ptr; + if (git_str_try_grow(path, alloclen, 1) < 0) + return -1; + p = path->ptr + offset; + + memmove(path->ptr + (depth * 3), p, plen + 1); + + for (i = 0; i < depth; i++) + memcpy(path->ptr + (i * 3), "../", 3); + + path->size = newlen; + return 0; +} + +bool git_fs_path_has_non_ascii(const char *path, size_t pathlen) +{ + const uint8_t *scan = (const uint8_t *)path, *end; + + for (end = scan + pathlen; scan < end; ++scan) + if (*scan & 0x80) + return true; + + return false; +} + +#ifdef GIT_USE_ICONV + +int git_fs_path_iconv_init_precompose(git_fs_path_iconv_t *ic) +{ + git_str_init(&ic->buf, 0); + ic->map = iconv_open(GIT_PATH_REPO_ENCODING, GIT_PATH_NATIVE_ENCODING); + return 0; +} + +void git_fs_path_iconv_clear(git_fs_path_iconv_t *ic) +{ + if (ic) { + if (ic->map != (iconv_t)-1) + iconv_close(ic->map); + git_str_dispose(&ic->buf); + } +} + +int git_fs_path_iconv(git_fs_path_iconv_t *ic, const char **in, size_t *inlen) +{ + char *nfd = (char*)*in, *nfc; + size_t nfdlen = *inlen, nfclen, wantlen = nfdlen, alloclen, rv; + int retry = 1; + + if (!ic || ic->map == (iconv_t)-1 || + !git_fs_path_has_non_ascii(*in, *inlen)) + return 0; + + git_str_clear(&ic->buf); + + while (1) { + GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, wantlen, 1); + if (git_str_grow(&ic->buf, alloclen) < 0) + return -1; + + nfc = ic->buf.ptr + ic->buf.size; + nfclen = ic->buf.asize - ic->buf.size; + + rv = iconv(ic->map, &nfd, &nfdlen, &nfc, &nfclen); + + ic->buf.size = (nfc - ic->buf.ptr); + + if (rv != (size_t)-1) + break; + + /* if we cannot convert the data (probably because iconv thinks + * it is not valid UTF-8 source data), then use original data + */ + if (errno != E2BIG) + return 0; + + /* make space for 2x the remaining data to be converted + * (with per retry overhead to avoid infinite loops) + */ + wantlen = ic->buf.size + max(nfclen, nfdlen) * 2 + (size_t)(retry * 4); + + if (retry++ > 4) + goto fail; + } + + ic->buf.ptr[ic->buf.size] = '\0'; + + *in = ic->buf.ptr; + *inlen = ic->buf.size; + + return 0; + +fail: + git_error_set(GIT_ERROR_OS, "unable to convert unicode path data"); + return -1; +} + +static const char *nfc_file = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D.XXXXXX"; +static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D.XXXXXX"; + +/* Check if the platform is decomposing unicode data for us. We will + * emulate core Git and prefer to use precomposed unicode data internally + * on these platforms, composing the decomposed unicode on the fly. + * + * This mainly happens on the Mac where HDFS stores filenames as + * decomposed unicode. Even on VFAT and SAMBA file systems, the Mac will + * return decomposed unicode from readdir() even when the actual + * filesystem is storing precomposed unicode. + */ +bool git_fs_path_does_decompose_unicode(const char *root) +{ + git_str path = GIT_STR_INIT; + int fd; + bool found_decomposed = false; + char tmp[6]; + + /* Create a file using a precomposed path and then try to find it + * using the decomposed name. If the lookup fails, then we will mark + * that we should precompose unicode for this repository. + */ + if (git_str_joinpath(&path, root, nfc_file) < 0 || + (fd = p_mkstemp(path.ptr)) < 0) + goto done; + p_close(fd); + + /* record trailing digits generated by mkstemp */ + memcpy(tmp, path.ptr + path.size - sizeof(tmp), sizeof(tmp)); + + /* try to look up as NFD path */ + if (git_str_joinpath(&path, root, nfd_file) < 0) + goto done; + memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); + + found_decomposed = git_fs_path_exists(path.ptr); + + /* remove temporary file (using original precomposed path) */ + if (git_str_joinpath(&path, root, nfc_file) < 0) + goto done; + memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); + + (void)p_unlink(path.ptr); + +done: + git_str_dispose(&path); + return found_decomposed; +} + +#else + +bool git_fs_path_does_decompose_unicode(const char *root) +{ + GIT_UNUSED(root); + return false; +} + +#endif + +#if defined(__sun) || defined(__GNU__) +typedef char path_dirent_data[sizeof(struct dirent) + FILENAME_MAX + 1]; +#else +typedef struct dirent path_dirent_data; +#endif + +int git_fs_path_direach( + git_str *path, + uint32_t flags, + int (*fn)(void *, git_str *), + void *arg) +{ + int error = 0; + ssize_t wd_len; + DIR *dir; + struct dirent *de; + +#ifdef GIT_USE_ICONV + git_fs_path_iconv_t ic = GIT_PATH_ICONV_INIT; +#endif + + GIT_UNUSED(flags); + + if (git_fs_path_to_dir(path) < 0) + return -1; + + wd_len = git_str_len(path); + + if ((dir = opendir(path->ptr)) == NULL) { + git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path->ptr); + if (errno == ENOENT) + return GIT_ENOTFOUND; + + return -1; + } + +#ifdef GIT_USE_ICONV + if ((flags & GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE) != 0) + (void)git_fs_path_iconv_init_precompose(&ic); +#endif + + while ((de = readdir(dir)) != NULL) { + const char *de_path = de->d_name; + size_t de_len = strlen(de_path); + + if (git_fs_path_is_dot_or_dotdot(de_path)) + continue; + +#ifdef GIT_USE_ICONV + if ((error = git_fs_path_iconv(&ic, &de_path, &de_len)) < 0) + break; +#endif + + if ((error = git_str_put(path, de_path, de_len)) < 0) + break; + + git_error_clear(); + error = fn(arg, path); + + git_str_truncate(path, wd_len); /* restore path */ + + /* Only set our own error if the callback did not set one already */ + if (error != 0) { + if (!git_error_last()) + git_error_set_after_callback(error); + + break; + } + } + + closedir(dir); + +#ifdef GIT_USE_ICONV + git_fs_path_iconv_clear(&ic); +#endif + + return error; +} + +#if defined(GIT_WIN32) && !defined(__MINGW32__) + +/* Using _FIND_FIRST_EX_LARGE_FETCH may increase performance in Windows 7 + * and better. + */ +#ifndef FIND_FIRST_EX_LARGE_FETCH +# define FIND_FIRST_EX_LARGE_FETCH 2 +#endif + +int git_fs_path_diriter_init( + git_fs_path_diriter *diriter, + const char *path, + unsigned int flags) +{ + git_win32_path path_filter; + + static int is_win7_or_later = -1; + if (is_win7_or_later < 0) + is_win7_or_later = git_has_win32_version(6, 1, 0); + + GIT_ASSERT_ARG(diriter); + GIT_ASSERT_ARG(path); + + memset(diriter, 0, sizeof(git_fs_path_diriter)); + diriter->handle = INVALID_HANDLE_VALUE; + + if (git_str_puts(&diriter->path_utf8, path) < 0) + return -1; + + path_trim_slashes(&diriter->path_utf8); + + if (diriter->path_utf8.size == 0) { + git_error_set(GIT_ERROR_FILESYSTEM, "could not open directory '%s'", path); + return -1; + } + + if ((diriter->parent_len = git_win32_path_from_utf8(diriter->path, diriter->path_utf8.ptr)) < 0 || + !git_win32__findfirstfile_filter(path_filter, diriter->path_utf8.ptr)) { + git_error_set(GIT_ERROR_OS, "could not parse the directory path '%s'", path); + return -1; + } + + diriter->handle = FindFirstFileExW( + path_filter, + is_win7_or_later ? FindExInfoBasic : FindExInfoStandard, + &diriter->current, + FindExSearchNameMatch, + NULL, + is_win7_or_later ? FIND_FIRST_EX_LARGE_FETCH : 0); + + if (diriter->handle == INVALID_HANDLE_VALUE) { + git_error_set(GIT_ERROR_OS, "could not open directory '%s'", path); + return -1; + } + + diriter->parent_utf8_len = diriter->path_utf8.size; + diriter->flags = flags; + return 0; +} + +static int diriter_update_paths(git_fs_path_diriter *diriter) +{ + size_t filename_len, path_len; + + filename_len = wcslen(diriter->current.cFileName); + + if (GIT_ADD_SIZET_OVERFLOW(&path_len, diriter->parent_len, filename_len) || + GIT_ADD_SIZET_OVERFLOW(&path_len, path_len, 2)) + return -1; + + if (path_len > GIT_WIN_PATH_UTF16) { + git_error_set(GIT_ERROR_FILESYSTEM, + "invalid path '%.*ls\\%ls' (path too long)", + diriter->parent_len, diriter->path, diriter->current.cFileName); + return -1; + } + + diriter->path[diriter->parent_len] = L'\\'; + memcpy(&diriter->path[diriter->parent_len+1], + diriter->current.cFileName, filename_len * sizeof(wchar_t)); + diriter->path[path_len-1] = L'\0'; + + git_str_truncate(&diriter->path_utf8, diriter->parent_utf8_len); + + if (diriter->parent_utf8_len > 0 && + diriter->path_utf8.ptr[diriter->parent_utf8_len-1] != '/') + git_str_putc(&diriter->path_utf8, '/'); + + git_str_put_w(&diriter->path_utf8, diriter->current.cFileName, filename_len); + + if (git_str_oom(&diriter->path_utf8)) + return -1; + + return 0; +} + +int git_fs_path_diriter_next(git_fs_path_diriter *diriter) +{ + bool skip_dot = !(diriter->flags & GIT_FS_PATH_DIR_INCLUDE_DOT_AND_DOTDOT); + + do { + /* Our first time through, we already have the data from + * FindFirstFileW. Use it, otherwise get the next file. + */ + if (!diriter->needs_next) + diriter->needs_next = 1; + else if (!FindNextFileW(diriter->handle, &diriter->current)) + return GIT_ITEROVER; + } while (skip_dot && git_fs_path_is_dot_or_dotdotW(diriter->current.cFileName)); + + if (diriter_update_paths(diriter) < 0) + return -1; + + return 0; +} + +int git_fs_path_diriter_filename( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); + GIT_ASSERT(diriter->path_utf8.size > diriter->parent_utf8_len); + + *out = &diriter->path_utf8.ptr[diriter->parent_utf8_len+1]; + *out_len = diriter->path_utf8.size - diriter->parent_utf8_len - 1; + return 0; +} + +int git_fs_path_diriter_fullpath( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); + + *out = diriter->path_utf8.ptr; + *out_len = diriter->path_utf8.size; + return 0; +} + +int git_fs_path_diriter_stat(struct stat *out, git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(diriter); + + return git_win32__file_attribute_to_stat(out, + (WIN32_FILE_ATTRIBUTE_DATA *)&diriter->current, + diriter->path); +} + +void git_fs_path_diriter_free(git_fs_path_diriter *diriter) +{ + if (diriter == NULL) + return; + + git_str_dispose(&diriter->path_utf8); + + if (diriter->handle != INVALID_HANDLE_VALUE) { + FindClose(diriter->handle); + diriter->handle = INVALID_HANDLE_VALUE; + } +} + +#else + +int git_fs_path_diriter_init( + git_fs_path_diriter *diriter, + const char *path, + unsigned int flags) +{ + GIT_ASSERT_ARG(diriter); + GIT_ASSERT_ARG(path); + + memset(diriter, 0, sizeof(git_fs_path_diriter)); + + if (git_str_puts(&diriter->path, path) < 0) + return -1; + + path_trim_slashes(&diriter->path); + + if (diriter->path.size == 0) { + git_error_set(GIT_ERROR_FILESYSTEM, "could not open directory '%s'", path); + return -1; + } + + if ((diriter->dir = opendir(diriter->path.ptr)) == NULL) { + git_str_dispose(&diriter->path); + + git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path); + return -1; + } + +#ifdef GIT_USE_ICONV + if ((flags & GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE) != 0) + (void)git_fs_path_iconv_init_precompose(&diriter->ic); +#endif + + diriter->parent_len = diriter->path.size; + diriter->flags = flags; + + return 0; +} + +int git_fs_path_diriter_next(git_fs_path_diriter *diriter) +{ + struct dirent *de; + const char *filename; + size_t filename_len; + bool skip_dot = !(diriter->flags & GIT_FS_PATH_DIR_INCLUDE_DOT_AND_DOTDOT); + int error = 0; + + GIT_ASSERT_ARG(diriter); + + errno = 0; + + do { + if ((de = readdir(diriter->dir)) == NULL) { + if (!errno) + return GIT_ITEROVER; + + git_error_set(GIT_ERROR_OS, + "could not read directory '%s'", diriter->path.ptr); + return -1; + } + } while (skip_dot && git_fs_path_is_dot_or_dotdot(de->d_name)); + + filename = de->d_name; + filename_len = strlen(filename); + +#ifdef GIT_USE_ICONV + if ((diriter->flags & GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE) != 0 && + (error = git_fs_path_iconv(&diriter->ic, &filename, &filename_len)) < 0) + return error; +#endif + + git_str_truncate(&diriter->path, diriter->parent_len); + + if (diriter->parent_len > 0 && + diriter->path.ptr[diriter->parent_len-1] != '/') + git_str_putc(&diriter->path, '/'); + + git_str_put(&diriter->path, filename, filename_len); + + if (git_str_oom(&diriter->path)) + return -1; + + return error; +} + +int git_fs_path_diriter_filename( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); + GIT_ASSERT(diriter->path.size > diriter->parent_len); + + *out = &diriter->path.ptr[diriter->parent_len+1]; + *out_len = diriter->path.size - diriter->parent_len - 1; + return 0; +} + +int git_fs_path_diriter_fullpath( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); + + *out = diriter->path.ptr; + *out_len = diriter->path.size; + return 0; +} + +int git_fs_path_diriter_stat(struct stat *out, git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(diriter); + + return git_fs_path_lstat(diriter->path.ptr, out); +} + +void git_fs_path_diriter_free(git_fs_path_diriter *diriter) +{ + if (diriter == NULL) + return; + + if (diriter->dir) { + closedir(diriter->dir); + diriter->dir = NULL; + } + +#ifdef GIT_USE_ICONV + git_fs_path_iconv_clear(&diriter->ic); +#endif + + git_str_dispose(&diriter->path); +} + +#endif + +int git_fs_path_dirload( + git_vector *contents, + const char *path, + size_t prefix_len, + uint32_t flags) +{ + git_fs_path_diriter iter = GIT_FS_PATH_DIRITER_INIT; + const char *name; + size_t name_len; + char *dup; + int error; + + GIT_ASSERT_ARG(contents); + GIT_ASSERT_ARG(path); + + if ((error = git_fs_path_diriter_init(&iter, path, flags)) < 0) + return error; + + while ((error = git_fs_path_diriter_next(&iter)) == 0) { + if ((error = git_fs_path_diriter_fullpath(&name, &name_len, &iter)) < 0) + break; + + GIT_ASSERT(name_len > prefix_len); + + dup = git__strndup(name + prefix_len, name_len - prefix_len); + GIT_ERROR_CHECK_ALLOC(dup); + + if ((error = git_vector_insert(contents, dup)) < 0) + break; + } + + if (error == GIT_ITEROVER) + error = 0; + + git_fs_path_diriter_free(&iter); + return error; +} + +int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url_or_path) +{ + if (git_fs_path_is_local_file_url(url_or_path)) + return git_fs_path_fromurl(local_path_out, url_or_path); + else + return git_str_sets(local_path_out, url_or_path); +} + +/* Reject paths like AUX or COM1, or those versions that end in a dot or + * colon. ("AUX." or "AUX:") + */ +GIT_INLINE(bool) validate_dospath( + const char *component, + size_t len, + const char dospath[3], + bool trailing_num) +{ + size_t last = trailing_num ? 4 : 3; + + if (len < last || git__strncasecmp(component, dospath, 3) != 0) + return true; + + if (trailing_num && (component[3] < '1' || component[3] > '9')) + return true; + + return (len > last && + component[last] != '.' && + component[last] != ':'); +} + +GIT_INLINE(bool) validate_char(unsigned char c, unsigned int flags) +{ + if ((flags & GIT_FS_PATH_REJECT_BACKSLASH) && c == '\\') + return false; + + if ((flags & GIT_FS_PATH_REJECT_SLASH) && c == '/') + return false; + + if (flags & GIT_FS_PATH_REJECT_NT_CHARS) { + if (c < 32) + return false; + + switch (c) { + case '<': + case '>': + case ':': + case '"': + case '|': + case '?': + case '*': + return false; + } + } + + return true; +} + +/* + * We fundamentally don't like some paths when dealing with user-inputted + * strings (to avoid escaping a sandbox): we don't want dot or dot-dot + * anywhere, we want to avoid writing weird paths on Windows that can't + * be handled by tools that use the non-\\?\ APIs, we don't want slashes + * or double slashes at the end of paths that can make them ambiguous. + * + * For checkout, we don't want to recurse into ".git" either. + */ +static bool validate_component( + const char *component, + size_t len, + unsigned int flags) +{ + if (len == 0) + return false; + + if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) && + len == 1 && component[0] == '.') + return false; + + if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) && + len == 2 && component[0] == '.' && component[1] == '.') + return false; + + if ((flags & GIT_FS_PATH_REJECT_TRAILING_DOT) && + component[len - 1] == '.') + return false; + + if ((flags & GIT_FS_PATH_REJECT_TRAILING_SPACE) && + component[len - 1] == ' ') + return false; + + if ((flags & GIT_FS_PATH_REJECT_TRAILING_COLON) && + component[len - 1] == ':') + return false; + + if (flags & GIT_FS_PATH_REJECT_DOS_PATHS) { + if (!validate_dospath(component, len, "CON", false) || + !validate_dospath(component, len, "PRN", false) || + !validate_dospath(component, len, "AUX", false) || + !validate_dospath(component, len, "NUL", false) || + !validate_dospath(component, len, "COM", true) || + !validate_dospath(component, len, "LPT", true)) + return false; + } + + return true; +} + +bool git_fs_path_validate_ext( + const char *path, + unsigned int flags, + bool (*validate_char_cb)(char ch, void *payload), + bool (*validate_component_cb)(const char *component, size_t len, void *payload), + void *payload) +{ + const char *start, *c; + + for (start = c = path; *c; c++) { + if (!validate_char(*c, flags)) + return false; + + if (validate_char_cb && !validate_char_cb(*c, payload)) + return false; + + if (*c != '/') + continue; + + if (!validate_component(start, (c - start), flags)) + return false; + + if (validate_component_cb && + !validate_component_cb(start, (c - start), payload)) + return false; + + start = c + 1; + } + + if (!validate_component(start, (c - start), flags)) + return false; + + if (validate_component_cb && + !validate_component_cb(start, (c - start), payload)) + return false; + + return true; +} + +bool git_fs_path_validate(const char *path, unsigned int flags) +{ + return git_fs_path_validate_ext(path, flags, NULL, NULL, NULL); +} + +#ifdef GIT_WIN32 +GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) +{ + int longpaths = 0; + + if (repo && + git_repository__configmap_lookup(&longpaths, repo, GIT_CONFIGMAP_LONGPATHS) < 0) + longpaths = 0; + + return (longpaths == 0); +} + +#else + +GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) +{ + GIT_UNUSED(repo); + + return false; +} +#endif + +int git_fs_path_validate_workdir(git_repository *repo, const char *path) +{ + if (should_validate_longpaths(repo)) + return git_fs_path_validate_filesystem(path, strlen(path)); + + return 0; +} + +int git_fs_path_validate_workdir_with_len( + git_repository *repo, + const char *path, + size_t path_len) +{ + if (should_validate_longpaths(repo)) + return git_fs_path_validate_filesystem(path, path_len); + + return 0; +} + +int git_fs_path_validate_workdir_buf(git_repository *repo, git_str *path) +{ + return git_fs_path_validate_workdir_with_len(repo, path->ptr, path->size); +} + +int git_fs_path_normalize_slashes(git_str *out, const char *path) +{ + int error; + char *p; + + if ((error = git_str_puts(out, path)) < 0) + return error; + + for (p = out->ptr; *p; p++) { + if (*p == '\\') + *p = '/'; + } + + return 0; +} + +bool git_fs_path_supports_symlinks(const char *dir) +{ + git_str path = GIT_STR_INIT; + bool supported = false; + struct stat st; + int fd; + + if ((fd = git_futils_mktmp(&path, dir, 0666)) < 0 || + p_close(fd) < 0 || + p_unlink(path.ptr) < 0 || + p_symlink("testing", path.ptr) < 0 || + p_lstat(path.ptr, &st) < 0) + goto done; + + supported = (S_ISLNK(st.st_mode) != 0); +done: + if (path.size) + (void)p_unlink(path.ptr); + git_str_dispose(&path); + return supported; +} + +int git_fs_path_validate_system_file_ownership(const char *path) +{ +#ifndef GIT_WIN32 + GIT_UNUSED(path); + return GIT_OK; +#else + git_win32_path buf; + PSID owner_sid; + PSECURITY_DESCRIPTOR descriptor = NULL; + HANDLE token; + TOKEN_USER *info = NULL; + DWORD err, len; + int ret; + + if (git_win32_path_from_utf8(buf, path) < 0) + return -1; + + err = GetNamedSecurityInfoW(buf, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION, + &owner_sid, NULL, NULL, NULL, &descriptor); + + if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) { + ret = GIT_ENOTFOUND; + goto cleanup; + } + + if (err != ERROR_SUCCESS) { + git_error_set(GIT_ERROR_OS, "failed to get security information"); + ret = GIT_ERROR; + goto cleanup; + } + + if (!IsValidSid(owner_sid)) { + git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is unknown"); + ret = GIT_ERROR; + goto cleanup; + } + + if (IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) || + IsWellKnownSid(owner_sid, WinLocalSystemSid)) { + ret = GIT_OK; + goto cleanup; + } + + /* Obtain current user's SID */ + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) && + !GetTokenInformation(token, TokenUser, NULL, 0, &len)) { + info = git__malloc(len); + GIT_ERROR_CHECK_ALLOC(info); + if (!GetTokenInformation(token, TokenUser, info, len, &len)) { + git__free(info); + info = NULL; + } + } + + /* + * If the file is owned by the same account that is running the current + * process, it's okay to read from that file. + */ + if (info && EqualSid(owner_sid, info->User.Sid)) + ret = GIT_OK; + else { + git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is not valid"); + ret = GIT_ERROR; + } + git__free(info); + +cleanup: + if (descriptor) + LocalFree(descriptor); + + return ret; +#endif +} diff --git a/src/fs_path.h b/src/fs_path.h new file mode 100644 index 00000000000..a60a37d9838 --- /dev/null +++ b/src/fs_path.h @@ -0,0 +1,728 @@ +/* + * 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_fs_path_h__ +#define INCLUDE_fs_path_h__ + +#include "common.h" + +#include "posix.h" +#include "str.h" +#include "vector.h" + +#include "git2/sys/path.h" + +/** + * Path manipulation utils + * + * These are path utilities that munge paths without actually + * looking at the real filesystem. + */ + +/* + * The dirname() function shall take a pointer to a character string + * that contains a pathname, and return a pointer to a string that is a + * pathname of the parent directory of that file. Trailing '/' characters + * in the path are not counted as part of the path. + * + * If path does not contain a '/', then dirname() shall return a pointer to + * the string ".". If path is a null pointer or points to an empty string, + * dirname() shall return a pointer to the string "." . + * + * The `git_fs_path_dirname` implementation is thread safe. The returned + * string must be manually free'd. + * + * The `git_fs_path_dirname_r` implementation writes the dirname to a `git_str` + * if the buffer pointer is not NULL. + * It returns an error code < 0 if there is an allocation error, otherwise + * the length of the dirname (which will be > 0). + */ +extern char *git_fs_path_dirname(const char *path); +extern int git_fs_path_dirname_r(git_str *buffer, const char *path); + +/* + * This function returns the basename of the file, which is the last + * part of its full name given by fname, with the drive letter and + * leading directories stripped off. For example, the basename of + * c:/foo/bar/file.ext is file.ext, and the basename of a:foo is foo. + * + * Trailing slashes and backslashes are significant: the basename of + * c:/foo/bar/ is an empty string after the rightmost slash. + * + * The `git_fs_path_basename` implementation is thread safe. The returned + * string must be manually free'd. + * + * The `git_fs_path_basename_r` implementation writes the basename to a `git_str`. + * It returns an error code < 0 if there is an allocation error, otherwise + * the length of the basename (which will be >= 0). + */ +extern char *git_fs_path_basename(const char *path); +extern int git_fs_path_basename_r(git_str *buffer, const char *path); + +/* Return the offset of the start of the basename. Unlike the other + * basename functions, this returns 0 if the path is empty. + */ +extern size_t git_fs_path_basename_offset(git_str *buffer); + +/** + * Find offset to root of path if path has one. + * + * This will return a number >= 0 which is the offset to the start of the + * path, if the path is rooted (i.e. "/rooted/path" returns 0 and + * "c:/windows/rooted/path" returns 2). If the path is not rooted, this + * returns -1. + */ +extern int git_fs_path_root(const char *path); + +/** + * Ensure path has a trailing '/'. + */ +extern int git_fs_path_to_dir(git_str *path); + +/** + * Ensure string has a trailing '/' if there is space for it. + */ +extern void git_fs_path_string_to_dir(char *path, size_t size); + +/** + * Taken from git.git; returns nonzero if the given path is "." or "..". + */ +GIT_INLINE(int) git_fs_path_is_dot_or_dotdot(const char *name) +{ + return (name[0] == '.' && + (name[1] == '\0' || + (name[1] == '.' && name[2] == '\0'))); +} + +#ifdef GIT_WIN32 +GIT_INLINE(int) git_fs_path_is_dot_or_dotdotW(const wchar_t *name) +{ + return (name[0] == L'.' && + (name[1] == L'\0' || + (name[1] == L'.' && name[2] == L'\0'))); +} + +#define git_fs_path_is_absolute(p) \ + (git__isalpha((p)[0]) && (p)[1] == ':' && ((p)[2] == '\\' || (p)[2] == '/')) + +#define git_fs_path_is_dirsep(p) \ + ((p) == '/' || (p) == '\\') + +/** + * Convert backslashes in path to forward slashes. + */ +GIT_INLINE(void) git_fs_path_mkposix(char *path) +{ + while (*path) { + if (*path == '\\') + *path = '/'; + + path++; + } +} +#else +# define git_fs_path_mkposix(p) /* blank */ + +#define git_fs_path_is_absolute(p) \ + ((p)[0] == '/') + +#define git_fs_path_is_dirsep(p) \ + ((p) == '/') + +#endif + +/** + * Check if string is a relative path (i.e. starts with "./" or "../") + */ +GIT_INLINE(int) git_fs_path_is_relative(const char *p) +{ + return (p[0] == '.' && (p[1] == '/' || (p[1] == '.' && p[2] == '/'))); +} + +/** + * Check if string is at end of path segment (i.e. looking at '/' or '\0') + */ +GIT_INLINE(int) git_fs_path_at_end_of_segment(const char *p) +{ + return !*p || *p == '/'; +} + +extern int git__percent_decode(git_str *decoded_out, const char *input); + +/** + * Extract path from file:// URL. + */ +extern int git_fs_path_fromurl(git_str *local_path_out, const char *file_url); + + +/** + * Path filesystem utils + * + * These are path utilities that actually access the filesystem. + */ + +/** + * Check if a file exists and can be accessed. + * @return true or false + */ +extern bool git_fs_path_exists(const char *path); + +/** + * Check if the given path points to a directory. + * @return true or false + */ +extern bool git_fs_path_isdir(const char *path); + +/** + * Check if the given path points to a regular file. + * @return true or false + */ +extern bool git_fs_path_isfile(const char *path); + +/** + * Check if the given path points to a symbolic link. + * @return true or false + */ +extern bool git_fs_path_islink(const char *path); + +/** + * Check if the given path is a directory, and is empty. + */ +extern bool git_fs_path_is_empty_dir(const char *path); + +/** + * Stat a file and/or link and set error if needed. + */ +extern int git_fs_path_lstat(const char *path, struct stat *st); + +/** + * Check if the parent directory contains the item. + * + * @param dir Directory to check. + * @param item Item that might be in the directory. + * @return 0 if item exists in directory, <0 otherwise. + */ +extern bool git_fs_path_contains(git_str *dir, const char *item); + +/** + * Check if the given path contains the given subdirectory. + * + * @param parent Directory path that might contain subdir + * @param subdir Subdirectory name to look for in parent + * @return true if subdirectory exists, false otherwise. + */ +extern bool git_fs_path_contains_dir(git_str *parent, const char *subdir); + +/** + * Determine the common directory length between two paths, including + * the final path separator. For example, given paths 'a/b/c/1.txt + * and 'a/b/c/d/2.txt', the common directory is 'a/b/c/', and this + * will return the length of the string 'a/b/c/', which is 6. + * + * @param one The first path + * @param two The second path + * @return The length of the common directory + */ +extern size_t git_fs_path_common_dirlen(const char *one, const char *two); + +/** + * Make the path relative to the given parent path. + * + * @param path The path to make relative + * @param parent The parent path to make path relative to + * @return 0 if path was made relative, GIT_ENOTFOUND + * if there was not common root between the paths, + * or <0. + */ +extern int git_fs_path_make_relative(git_str *path, const char *parent); + +/** + * Check if the given path contains the given file. + * + * @param dir Directory path that might contain file + * @param file File name to look for in parent + * @return true if file exists, false otherwise. + */ +extern bool git_fs_path_contains_file(git_str *dir, const char *file); + +/** + * Prepend base to unrooted path or just copy path over. + * + * This will optionally return the index into the path where the "root" + * is, either the end of the base directory prefix or the path root. + */ +extern int git_fs_path_join_unrooted( + git_str *path_out, const char *path, const char *base, ssize_t *root_at); + +/** + * Removes multiple occurrences of '/' in a row, squashing them into a + * single '/'. + */ +extern void git_fs_path_squash_slashes(git_str *path); + +/** + * Clean up path, prepending base if it is not already rooted. + */ +extern int git_fs_path_prettify(git_str *path_out, const char *path, const char *base); + +/** + * Clean up path, prepending base if it is not already rooted and + * appending a slash. + */ +extern int git_fs_path_prettify_dir(git_str *path_out, const char *path, const char *base); + +/** + * Get a directory from a path. + * + * If path is a directory, this acts like `git_fs_path_prettify_dir` + * (cleaning up path and appending a '/'). If path is a normal file, + * this prettifies it, then removed the filename a la dirname and + * appends the trailing '/'. If the path does not exist, it is + * treated like a regular filename. + */ +extern int git_fs_path_find_dir(git_str *dir); + +/** + * Resolve relative references within a path. + * + * This eliminates "./" and "../" relative references inside a path, + * as well as condensing multiple slashes into single ones. It will + * not touch the path before the "ceiling" length. + * + * Additionally, this will recognize an "c:/" drive prefix or a "xyz://" URL + * prefix and not touch that part of the path. + */ +extern int git_fs_path_resolve_relative(git_str *path, size_t ceiling); + +/** + * Apply a relative path to base path. + * + * Note that the base path could be a filename or a URL and this + * should still work. The relative path is walked segment by segment + * with three rules: series of slashes will be condensed to a single + * slash, "." will be eaten with no change, and ".." will remove a + * segment from the base path. + */ +extern int git_fs_path_apply_relative(git_str *target, const char *relpath); + +enum { + GIT_FS_PATH_DIR_IGNORE_CASE = (1u << 0), + GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE = (1u << 1), + GIT_FS_PATH_DIR_INCLUDE_DOT_AND_DOTDOT = (1u << 2), +}; + +/** + * Walk each directory entry, except '.' and '..', calling fn(state). + * + * @param pathbuf Buffer the function reads the initial directory + * path from, and updates with each successive entry's name. + * @param flags Combination of GIT_FS_PATH_DIR flags. + * @param callback Callback for each entry. Passed the `payload` and each + * successive path inside the directory as a full path. This may + * safely append text to the pathbuf if needed. Return non-zero to + * cancel iteration (and return value will be propagated back). + * @param payload Passed to callback as first argument. + * @return 0 on success or error code from OS error or from callback + */ +extern int git_fs_path_direach( + git_str *pathbuf, + uint32_t flags, + int (*callback)(void *payload, git_str *path), + void *payload); + +/** + * Sort function to order two paths + */ +extern int git_fs_path_cmp( + const char *name1, size_t len1, int isdir1, + const char *name2, size_t len2, int isdir2, + int (*compare)(const char *, const char *, size_t)); + +/** + * Invoke callback up path directory by directory until the ceiling is + * reached (inclusive of a final call at the root_path). + * + * Returning anything other than 0 from the callback function + * will stop the iteration and propagate the error to the caller. + * + * @param pathbuf Buffer the function reads the directory from and + * and updates with each successive name. + * @param ceiling Prefix of path at which to stop walking up. If NULL, + * this will walk all the way up to the root. If not a prefix of + * pathbuf, the callback will be invoked a single time on the + * original input path. + * @param callback Function to invoke on each path. Passed the `payload` + * and the buffer containing the current path. The path should not + * be modified in any way. Return non-zero to stop iteration. + * @param payload Passed to fn as the first ath. + */ +extern int git_fs_path_walk_up( + git_str *pathbuf, + const char *ceiling, + int (*callback)(void *payload, const char *path), + void *payload); + + +enum { + GIT_FS_PATH_NOTEQUAL = 0, + GIT_FS_PATH_EQUAL = 1, + GIT_FS_PATH_PREFIX = 2 +}; + +/* + * Determines if a path is equal to or potentially a child of another. + * @param parent The possible parent + * @param child The possible child + */ +GIT_INLINE(int) git_fs_path_equal_or_prefixed( + const char *parent, + const char *child, + ssize_t *prefixlen) +{ + const char *p = parent, *c = child; + int lastslash = 0; + + while (*p && *c) { + lastslash = (*p == '/'); + + if (*p++ != *c++) + return GIT_FS_PATH_NOTEQUAL; + } + + if (*p != '\0') + return GIT_FS_PATH_NOTEQUAL; + + if (*c == '\0') { + if (prefixlen) + *prefixlen = p - parent; + + return GIT_FS_PATH_EQUAL; + } + + if (*c == '/' || lastslash) { + if (prefixlen) + *prefixlen = (p - parent) - lastslash; + + return GIT_FS_PATH_PREFIX; + } + + return GIT_FS_PATH_NOTEQUAL; +} + +/* translate errno to libgit2 error code and set error message */ +extern int git_fs_path_set_error( + int errno_value, const char *path, const char *action); + +/* check if non-ascii characters are present in filename */ +extern bool git_fs_path_has_non_ascii(const char *path, size_t pathlen); + +#define GIT_PATH_REPO_ENCODING "UTF-8" + +#ifdef __APPLE__ +#define GIT_PATH_NATIVE_ENCODING "UTF-8-MAC" +#else +#define GIT_PATH_NATIVE_ENCODING "UTF-8" +#endif + +#ifdef GIT_USE_ICONV + +#include + +typedef struct { + iconv_t map; + git_str buf; +} git_fs_path_iconv_t; + +#define GIT_PATH_ICONV_INIT { (iconv_t)-1, GIT_STR_INIT } + +/* Init iconv data for converting decomposed UTF-8 to precomposed */ +extern int git_fs_path_iconv_init_precompose(git_fs_path_iconv_t *ic); + +/* Clear allocated iconv data */ +extern void git_fs_path_iconv_clear(git_fs_path_iconv_t *ic); + +/* + * Rewrite `in` buffer using iconv map if necessary, replacing `in` + * pointer internal iconv buffer if rewrite happened. The `in` pointer + * will be left unchanged if no rewrite was needed. + */ +extern int git_fs_path_iconv(git_fs_path_iconv_t *ic, const char **in, size_t *inlen); + +#endif /* GIT_USE_ICONV */ + +extern bool git_fs_path_does_decompose_unicode(const char *root); + + +typedef struct git_fs_path_diriter git_fs_path_diriter; + +#if defined(GIT_WIN32) && !defined(__MINGW32__) + +struct git_fs_path_diriter +{ + git_win32_path path; + size_t parent_len; + + git_str path_utf8; + size_t parent_utf8_len; + + HANDLE handle; + + unsigned int flags; + + WIN32_FIND_DATAW current; + unsigned int needs_next; +}; + +#define GIT_FS_PATH_DIRITER_INIT { {0}, 0, GIT_STR_INIT, 0, INVALID_HANDLE_VALUE } + +#else + +struct git_fs_path_diriter +{ + git_str path; + size_t parent_len; + + unsigned int flags; + + DIR *dir; + +#ifdef GIT_USE_ICONV + git_fs_path_iconv_t ic; +#endif +}; + +#define GIT_FS_PATH_DIRITER_INIT { GIT_STR_INIT } + +#endif + +/** + * Initialize a directory iterator. + * + * @param diriter Pointer to a diriter structure that will be setup. + * @param path The path that will be iterated over + * @param flags Directory reader flags + * @return 0 or an error code + */ +extern int git_fs_path_diriter_init( + git_fs_path_diriter *diriter, + const char *path, + unsigned int flags); + +/** + * Advance the directory iterator. Will return GIT_ITEROVER when + * the iteration has completed successfully. + * + * @param diriter The directory iterator + * @return 0, GIT_ITEROVER, or an error code + */ +extern int git_fs_path_diriter_next(git_fs_path_diriter *diriter); + +/** + * Returns the file name of the current item in the iterator. + * + * @param out Pointer to store the path in + * @param out_len Pointer to store the length of the path in + * @param diriter The directory iterator + * @return 0 or an error code + */ +extern int git_fs_path_diriter_filename( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter); + +/** + * Returns the full path of the current item in the iterator; that + * is the current filename plus the path of the directory that the + * iterator was constructed with. + * + * @param out Pointer to store the path in + * @param out_len Pointer to store the length of the path in + * @param diriter The directory iterator + * @return 0 or an error code + */ +extern int git_fs_path_diriter_fullpath( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter); + +/** + * Performs an `lstat` on the current item in the iterator. + * + * @param out Pointer to store the stat data in + * @param diriter The directory iterator + * @return 0 or an error code + */ +extern int git_fs_path_diriter_stat(struct stat *out, git_fs_path_diriter *diriter); + +/** + * Closes the directory iterator. + * + * @param diriter The directory iterator + */ +extern void git_fs_path_diriter_free(git_fs_path_diriter *diriter); + +/** + * Load all directory entries (except '.' and '..') into a vector. + * + * For cases where `git_fs_path_direach()` is not appropriate, this + * allows you to load the filenames in a directory into a vector + * of strings. That vector can then be sorted, iterated, or whatever. + * Remember to free alloc of the allocated strings when you are done. + * + * @param contents Vector to fill with directory entry names. + * @param path The directory to read from. + * @param prefix_len When inserting entries, the trailing part of path + * will be prefixed after this length. I.e. given path "/a/b" and + * prefix_len 3, the entries will look like "b/e1", "b/e2", etc. + * @param flags Combination of GIT_FS_PATH_DIR flags. + */ +extern int git_fs_path_dirload( + git_vector *contents, + const char *path, + size_t prefix_len, + uint32_t flags); + + +/* Used for paths to repositories on the filesystem */ +extern bool git_fs_path_is_local_file_url(const char *file_url); +extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url_or_path); + +/* Flags to determine path validity in `git_fs_path_isvalid` */ +#define GIT_FS_PATH_REJECT_TRAVERSAL (1 << 0) +#define GIT_FS_PATH_REJECT_SLASH (1 << 2) +#define GIT_FS_PATH_REJECT_BACKSLASH (1 << 3) +#define GIT_FS_PATH_REJECT_TRAILING_DOT (1 << 4) +#define GIT_FS_PATH_REJECT_TRAILING_SPACE (1 << 5) +#define GIT_FS_PATH_REJECT_TRAILING_COLON (1 << 6) +#define GIT_FS_PATH_REJECT_DOS_PATHS (1 << 7) +#define GIT_FS_PATH_REJECT_NT_CHARS (1 << 8) + +#define GIT_FS_PATH_REJECT_MAX (1 << 8) + +/* Default path safety for writing files to disk: since we use the + * Win32 "File Namespace" APIs ("\\?\") we need to protect from + * paths that the normal Win32 APIs would not write. + */ +#ifdef GIT_WIN32 +# define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ + GIT_FS_PATH_REJECT_TRAVERSAL | \ + GIT_FS_PATH_REJECT_BACKSLASH | \ + GIT_FS_PATH_REJECT_TRAILING_DOT | \ + GIT_FS_PATH_REJECT_TRAILING_SPACE | \ + GIT_FS_PATH_REJECT_TRAILING_COLON | \ + GIT_FS_PATH_REJECT_DOS_PATHS | \ + GIT_FS_PATH_REJECT_NT_CHARS +#else +# define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ + GIT_FS_PATH_REJECT_TRAVERSAL +#endif + +/** + * Validate a filesystem path. This ensures that the given path is legal + * and does not contain any "unsafe" components like path traversal ('.' + * or '..'), characters that are inappropriate for lesser filesystems + * (trailing ' ' or ':' characters), or filenames ("component names") + * that are not supported ('AUX', 'COM1"). + */ +extern bool git_fs_path_validate(const char *path, unsigned int flags); + +/** + * Validate a filesystem path; with custom callbacks per-character and + * per-path component. + */ +extern bool git_fs_path_validate_ext( + const char *path, + unsigned int flags, + bool (*validate_char_cb)(char ch, void *payload), + bool (*validate_component_cb)(const char *component, size_t len, void *payload), + void *payload); + +/** + * Validate an on-disk path, taking into account that it will have a + * suffix appended (eg, `.lock`). + */ +GIT_INLINE(int) git_fs_path_validate_filesystem_with_suffix( + const char *path, + size_t path_len, + size_t suffix_len) +{ +#ifdef GIT_WIN32 + size_t path_chars, total_chars; + + path_chars = git_utf8_char_length(path, path_len); + + if (GIT_ADD_SIZET_OVERFLOW(&total_chars, path_chars, suffix_len) || + total_chars > MAX_PATH) { + git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%s'", path); + return -1; + } + return 0; +#else + GIT_UNUSED(path); + GIT_UNUSED(path_len); + GIT_UNUSED(suffix_len); + return 0; +#endif +} + +/** + * Validate an path on the filesystem. This ensures that the given + * path is valid for the operating system/platform; for example, this + * will ensure that the given absolute path is smaller than MAX_PATH on + * Windows. + * + * For paths within the working directory, you should use ensure that + * `core.longpaths` is obeyed. Use `git_fs_path_validate_workdir`. + */ +GIT_INLINE(int) git_fs_path_validate_filesystem( + const char *path, + size_t path_len) +{ + return git_fs_path_validate_filesystem_with_suffix(path, path_len, 0); +} + +/** + * Validate a path relative to the repo's worktree. This ensures that + * the given working tree path is valid for the operating system/platform. + * This will ensure that an absolute path is smaller than MAX_PATH on + * Windows, while keeping `core.longpaths` configuration settings in mind. + * + * This should be checked by mechamisms like `git_checkout` after + * contructing on-disk paths and before trying to write them. + * + * If the repository is null, no repository configuration is applied. + */ +extern int git_fs_path_validate_workdir( + git_repository *repo, + const char *path); +extern int git_fs_path_validate_workdir_with_len( + git_repository *repo, + const char *path, + size_t path_len); +extern int git_fs_path_validate_workdir_buf( + git_repository *repo, + git_str *buf); + +/** + * Convert any backslashes into slashes + */ +int git_fs_path_normalize_slashes(git_str *out, const char *path); + +bool git_fs_path_supports_symlinks(const char *dir); + +/** + * Validate a system file's ownership + * + * Verify that the file in question is owned by an administrator or system + * account, or at least by the current user. + * + * This function returns 0 if successful. If the file is not owned by any of + * these, or any other if there have been problems determining the file + * ownership, it returns -1. + */ +int git_fs_path_validate_system_file_ownership(const char *path); + +#endif diff --git a/src/futils.c b/src/futils.c index 9a15ceeb9a9..7ec1009bd67 100644 --- a/src/futils.c +++ b/src/futils.c @@ -99,7 +99,7 @@ int git_futils_open_ro(const char *path) { int fd = p_open(path, O_RDONLY); if (fd < 0) - return git_path_set_error(errno, path, "open"); + return git_fs_path_set_error(errno, path, "open"); return fd; } @@ -107,7 +107,7 @@ int git_futils_truncate(const char *path, int mode) { int fd = p_open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode); if (fd < 0) - return git_path_set_error(errno, path, "open"); + return git_fs_path_set_error(errno, path, "open"); close(fd); return 0; @@ -195,7 +195,7 @@ int git_futils_readbuffer_updated( *updated = 0; if (p_stat(path, &st) < 0) - return git_path_set_error(errno, path, "stat"); + return git_fs_path_set_error(errno, path, "stat"); if (S_ISDIR(st.st_mode)) { @@ -429,7 +429,7 @@ GIT_INLINE(int) mkdir_canonicalize( } /* Trim trailing slashes (except the root) */ - if ((root_len = git_path_root(path->ptr)) < 0) + if ((root_len = git_fs_path_root(path->ptr)) < 0) root_len = 0; else root_len++; @@ -439,11 +439,11 @@ GIT_INLINE(int) mkdir_canonicalize( /* if we are not supposed to made the last element, truncate it */ if ((flags & GIT_MKDIR_SKIP_LAST2) != 0) { - git_path_dirname_r(path, path->ptr); + git_fs_path_dirname_r(path, path->ptr); flags |= GIT_MKDIR_SKIP_LAST; } if ((flags & GIT_MKDIR_SKIP_LAST) != 0) { - git_path_dirname_r(path, path->ptr); + git_fs_path_dirname_r(path, path->ptr); } /* We were either given the root path (or trimmed it to @@ -473,7 +473,7 @@ int git_futils_mkdir( make_path.size == 0) goto done; - root_len = git_path_root(make_path.ptr); + root_len = git_fs_path_root(make_path.ptr); /* find the first parent directory that exists. this will be used * as the base to dirname_relative. @@ -492,7 +492,7 @@ int git_futils_mkdir( depth++; /* examine the parent of the current path */ - if ((len = git_path_dirname_r(&parent_path, parent_path.ptr)) < 0) { + if ((len = git_fs_path_dirname_r(&parent_path, parent_path.ptr)) < 0) { error = len; goto done; } @@ -569,7 +569,7 @@ int git_futils_mkdir_relative( opts = &empty_opts; /* build path and find "root" where we should start calling mkdir */ - if (git_path_join_unrooted(&make_path, relative_path, base, &root) < 0) + if (git_fs_path_join_unrooted(&make_path, relative_path, base, &root) < 0) return -1; if ((error = mkdir_canonicalize(&make_path, flags)) < 0 || @@ -581,7 +581,7 @@ int git_futils_mkdir_relative( root = git_str_rfind(&make_path, '/'); /* advance root past drive name or network mount prefix */ - min_root_len = git_path_root(make_path.ptr); + min_root_len = git_fs_path_root(make_path.ptr); if (root < min_root_len) root = min_root_len; while (root >= 0 && make_path.ptr[root] == '/') @@ -744,13 +744,13 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_str *path) path->ptr, "parent is not directory"); } else - error = git_path_set_error(errno, path->ptr, "rmdir"); + error = git_fs_path_set_error(errno, path->ptr, "rmdir"); } else if (S_ISDIR(st.st_mode)) { data->depth++; - error = git_path_direach(path, 0, futils__rmdir_recurs_foreach, data); + error = git_fs_path_direach(path, 0, futils__rmdir_recurs_foreach, data); data->depth--; @@ -765,13 +765,13 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_str *path) (errno == ENOTEMPTY || errno == EEXIST || errno == EBUSY)) error = 0; else - error = git_path_set_error(errno, path->ptr, "rmdir"); + error = git_fs_path_set_error(errno, path->ptr, "rmdir"); } } else if ((data->flags & GIT_RMDIR_REMOVE_FILES) != 0) { if (p_unlink(path->ptr) < 0) - error = git_path_set_error(errno, path->ptr, "remove"); + error = git_fs_path_set_error(errno, path->ptr, "remove"); } else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0) @@ -795,11 +795,11 @@ static int futils__rmdir_empty_parent(void *opaque, const char *path) /* do nothing */ } else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0 && en == EBUSY) { - error = git_path_set_error(errno, path, "rmdir"); + error = git_fs_path_set_error(errno, path, "rmdir"); } else if (en == ENOTEMPTY || en == EEXIST || en == EBUSY) { error = GIT_ITEROVER; } else { - error = git_path_set_error(errno, path, "rmdir"); + error = git_fs_path_set_error(errno, path, "rmdir"); } } @@ -814,7 +814,7 @@ int git_futils_rmdir_r( futils__rmdir_data data; /* build path and find "root" where we should start calling mkdir */ - if (git_path_join_unrooted(&fullpath, path, base, NULL) < 0) + if (git_fs_path_join_unrooted(&fullpath, path, base, NULL) < 0) return -1; memset(&data, 0, sizeof(data)); @@ -826,7 +826,7 @@ int git_futils_rmdir_r( /* remove now-empty parents if requested */ if (!error && (flags & GIT_RMDIR_EMPTY_PARENTS) != 0) - error = git_path_walk_up( + error = git_fs_path_walk_up( &fullpath, base, futils__rmdir_empty_parent, &data); if (error == GIT_ITEROVER) { @@ -887,7 +887,7 @@ int git_futils_cp(const char *from, const char *to, mode_t filemode) if ((ofd = p_open(to, O_WRONLY | O_CREAT | O_EXCL, filemode)) < 0) { p_close(ifd); - return git_path_set_error(errno, to, "open for writing"); + return git_fs_path_set_error(errno, to, "open for writing"); } return cp_by_fd(ifd, ofd, true); @@ -903,7 +903,7 @@ int git_futils_touch(const char *path, time_t *when) ret = p_utimes(path, times); - return (ret < 0) ? git_path_set_error(errno, path, "touch") : 0; + return (ret < 0) ? git_fs_path_set_error(errno, path, "touch") : 0; } static int cp_link(const char *from, const char *to, size_t link_size) @@ -977,14 +977,14 @@ static int _cp_r_callback(void *ref, git_str *from) bool exists = false; if ((info->flags & GIT_CPDIR_COPY_DOTFILES) == 0 && - from->ptr[git_path_basename_offset(from)] == '.') + from->ptr[git_fs_path_basename_offset(from)] == '.') return 0; if ((error = git_str_joinpath( &info->to, info->to_root, from->ptr + info->from_prefix)) < 0) return error; - if (!(error = git_path_lstat(info->to.ptr, &to_st))) + if (!(error = git_fs_path_lstat(info->to.ptr, &to_st))) exists = true; else if (error != GIT_ENOTFOUND) return error; @@ -993,7 +993,7 @@ static int _cp_r_callback(void *ref, git_str *from) error = 0; } - if ((error = git_path_lstat(from->ptr, &from_st)) < 0) + if ((error = git_fs_path_lstat(from->ptr, &from_st)) < 0) return error; if (S_ISDIR(from_st.st_mode)) { @@ -1009,7 +1009,7 @@ static int _cp_r_callback(void *ref, git_str *from) /* recurse onto target directory */ if (!error && (!exists || S_ISDIR(to_st.st_mode))) - error = git_path_direach(from, 0, _cp_r_callback, info); + error = git_fs_path_direach(from, 0, _cp_r_callback, info); if (oldmode != 0) info->dirmode = oldmode; @@ -1182,7 +1182,7 @@ int git_futils_fsync_parent(const char *path) char *parent; int error; - if ((parent = git_path_dirname(path)) == NULL) + if ((parent = git_fs_path_dirname(path)) == NULL) return -1; error = git_futils_fsync_dir(parent); diff --git a/src/futils.h b/src/futils.h index eea69adde79..22098addfe3 100644 --- a/src/futils.h +++ b/src/futils.h @@ -11,7 +11,7 @@ #include "map.h" #include "posix.h" -#include "path.h" +#include "fs_path.h" #include "pool.h" #include "strmap.h" #include "hash.h" diff --git a/src/ignore.c b/src/ignore.c index eb9fd8a9e97..e7d8b799f5d 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -10,7 +10,7 @@ #include "git2/ignore.h" #include "common.h" #include "attrcache.h" -#include "path.h" +#include "fs_path.h" #include "config.h" #include "wildmatch.h" @@ -181,7 +181,7 @@ static int parse_ignore_file( /* if subdir file path, convert context for file paths */ if (attrs->entry && - git_path_root(attrs->entry->path) < 0 && + git_fs_path_root(attrs->entry->path) < 0 && !git__suffixcmp(attrs->entry->path, "/" GIT_IGNORE_FILE)) context = attrs->entry->path; @@ -313,21 +313,21 @@ int git_ignore__for_path( goto cleanup; /* given a unrooted path in a non-bare repo, resolve it */ - if (workdir && git_path_root(path) < 0) { + if (workdir && git_fs_path_root(path) < 0) { git_str local = GIT_STR_INIT; - if ((error = git_path_dirname_r(&local, path)) < 0 || - (error = git_path_resolve_relative(&local, 0)) < 0 || - (error = git_path_to_dir(&local)) < 0 || + if ((error = git_fs_path_dirname_r(&local, path)) < 0 || + (error = git_fs_path_resolve_relative(&local, 0)) < 0 || + (error = git_fs_path_to_dir(&local)) < 0 || (error = git_str_joinpath(&ignores->dir, workdir, local.ptr)) < 0 || - (error = git_path_validate_workdir_buf(repo, &ignores->dir)) < 0) { + (error = git_fs_path_validate_workdir_buf(repo, &ignores->dir)) < 0) { /* Nothing, we just want to stop on the first error */ } git_str_dispose(&local); } else { if (!(error = git_str_joinpath(&ignores->dir, path, ""))) - error = git_path_validate_filesystem(ignores->dir.ptr, ignores->dir.size); + error = git_fs_path_validate_filesystem(ignores->dir.ptr, ignores->dir.size); } if (error < 0) @@ -342,7 +342,7 @@ int git_ignore__for_path( /* load .gitignore up the path */ if (workdir != NULL) { - error = git_path_walk_up( + error = git_fs_path_walk_up( &ignores->dir, workdir, push_one_ignore, ignores); if (error < 0) goto cleanup; @@ -410,7 +410,7 @@ int git_ignore__pop_dir(git_ignores *ign) if (--ign->depth > 0) { git_str_rtruncate_at_char(&ign->dir, '/'); - git_path_to_dir(&ign->dir); + git_fs_path_to_dir(&ign->dir); } return 0; @@ -629,7 +629,7 @@ int git_ignore__check_pathspec_for_exact_ignores( break; /* is there a file on disk that matches this exactly? */ - if (!git_path_isfile(path.ptr)) + if (!git_fs_path_isfile(path.ptr)) continue; /* is that file ignored? */ diff --git a/src/index.c b/src/index.c index b8aa310d316..448852f29b1 100644 --- a/src/index.c +++ b/src/index.c @@ -20,6 +20,7 @@ #include "idxmap.h" #include "diff.h" #include "varint.h" +#include "path.h" #include "git2/odb.h" #include "git2/oid.h" @@ -420,7 +421,7 @@ int git_index_open(git_index **index_out, const char *index_path) goto fail; /* Check if index file is stored on disk already */ - if (git_path_exists(index->index_file_path) == true) + if (git_fs_path_exists(index->index_file_path) == true) index->on_disk = 1; } @@ -648,7 +649,7 @@ int git_index_read(git_index *index, int force) return create_index_error(-1, "failed to read index: The index is in-memory only"); - index->on_disk = git_path_exists(index->index_file_path); + index->on_disk = git_fs_path_exists(index->index_file_path); if (!index->on_disk) { if (force && (error = git_index_clear(index)) < 0) @@ -991,7 +992,7 @@ static int index_entry_init( if (git_repository_workdir_path(&path, repo, rel_path) < 0) return -1; - error = git_path_lstat(path.ptr, &st); + error = git_fs_path_lstat(path.ptr, &st); git_str_dispose(&path); if (error < 0) @@ -1728,7 +1729,7 @@ int git_index_remove_directory(git_index *index, const char *dir, int stage) git_index_entry *entry; if (!(error = git_str_sets(&pfx, dir)) && - !(error = git_path_to_dir(&pfx))) + !(error = git_fs_path_to_dir(&pfx))) index_find(&pos, index, pfx.ptr, pfx.size, GIT_INDEX_STAGE_ANY); while (!error) { diff --git a/src/iterator.c b/src/iterator.c index 5549c636aa2..a627e0f887b 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -472,7 +472,7 @@ GIT_INLINE(tree_iterator_frame *) tree_iterator_current_frame( GIT_INLINE(int) tree_entry_cmp( const git_tree_entry *a, const git_tree_entry *b, bool icase) { - return git_path_cmp( + return git_fs_path_cmp( a->filename, a->filename_len, a->attr == GIT_FILEMODE_TREE, b->filename, b->filename_len, b->attr == GIT_FILEMODE_TREE, icase ? git__strncasecmp : git__strncmp); @@ -1279,7 +1279,7 @@ static int filesystem_iterator_entry_hash( iter->base.repo, entry->path, GIT_OBJECT_BLOB, NULL); if (!(error = git_str_joinpath(&fullpath, iter->root, entry->path)) && - !(error = git_path_validate_workdir_buf(iter->base.repo, &fullpath))) + !(error = git_fs_path_validate_workdir_buf(iter->base.repo, &fullpath))) error = git_odb_hashfile(&entry->id, fullpath.ptr, GIT_OBJECT_BLOB); git_str_dispose(&fullpath); @@ -1336,7 +1336,7 @@ static int filesystem_iterator_frame_push( filesystem_iterator_entry *frame_entry) { filesystem_iterator_frame *new_frame = NULL; - git_path_diriter diriter = GIT_PATH_DIRITER_INIT; + git_fs_path_diriter diriter = GIT_FS_PATH_DIRITER_INIT; git_str root = GIT_STR_INIT; const char *path; filesystem_iterator_entry *entry; @@ -1361,7 +1361,7 @@ static int filesystem_iterator_frame_push( git_str_puts(&root, iter->root); if (git_str_oom(&root) || - git_path_validate_workdir_buf(iter->base.repo, &root) < 0) { + git_fs_path_validate_workdir_buf(iter->base.repo, &root) < 0) { error = -1; goto done; } @@ -1369,7 +1369,7 @@ static int filesystem_iterator_frame_push( new_frame->path_len = frame_entry ? frame_entry->path_len : 0; /* Any error here is equivalent to the dir not existing, skip over it */ - if ((error = git_path_diriter_init( + if ((error = git_fs_path_diriter_init( &diriter, root.ptr, iter->dirload_flags)) < 0) { error = GIT_ENOTFOUND; goto done; @@ -1387,12 +1387,12 @@ static int filesystem_iterator_frame_push( /* check if this directory is ignored */ filesystem_iterator_frame_push_ignores(iter, frame_entry, new_frame); - while ((error = git_path_diriter_next(&diriter)) == 0) { + while ((error = git_fs_path_diriter_next(&diriter)) == 0) { iterator_pathlist_search_t pathlist_match = ITERATOR_PATHLIST_FULL; bool dir_expected = false; - if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0 || - (error = git_path_validate_workdir_with_len(iter->base.repo, path, path_len)) < 0) + if ((error = git_fs_path_diriter_fullpath(&path, &path_len, &diriter)) < 0 || + (error = git_fs_path_validate_workdir_with_len(iter->base.repo, path, path_len)) < 0) goto done; GIT_ASSERT(path_len > iter->root_len); @@ -1414,7 +1414,7 @@ static int filesystem_iterator_frame_push( * we have an index, we can just copy the data out of it. */ - if ((error = git_path_diriter_stat(&statbuf, &diriter)) < 0) { + if ((error = git_fs_path_diriter_stat(&statbuf, &diriter)) < 0) { /* file was removed between readdir and lstat */ if (error == GIT_ENOTFOUND) continue; @@ -1472,7 +1472,7 @@ static int filesystem_iterator_frame_push( git_array_pop(iter->frames); git_str_dispose(&root); - git_path_diriter_free(&diriter); + git_fs_path_diriter_free(&diriter); return error; } @@ -1565,7 +1565,7 @@ static int filesystem_iterator_is_dir( } if ((error = git_str_joinpath(&fullpath, iter->root, entry->path)) < 0 || - (error = git_path_validate_workdir_buf(iter->base.repo, &fullpath)) < 0 || + (error = git_fs_path_validate_workdir_buf(iter->base.repo, &fullpath)) < 0 || (error = p_stat(fullpath.ptr, &st)) < 0) goto done; @@ -1961,9 +1961,10 @@ static int iterator_for_filesystem( iter->index = index; iter->dirload_flags = - (iterator__ignore_case(&iter->base) ? GIT_PATH_DIR_IGNORE_CASE : 0) | + (iterator__ignore_case(&iter->base) ? + GIT_FS_PATH_DIR_IGNORE_CASE : 0) | (iterator__flag(&iter->base, PRECOMPOSE_UNICODE) ? - GIT_PATH_DIR_PRECOMPOSE_UNICODE : 0); + GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE : 0); if ((error = filesystem_iterator_init(iter)) < 0) goto on_error; @@ -2058,7 +2059,7 @@ static bool index_iterator_create_pseudotree( prev_path = iter->entry ? iter->entry->path : ""; /* determine if the new path is in a different directory from the old */ - common_len = git_path_common_dirlen(prev_path, path); + common_len = git_fs_path_common_dirlen(prev_path, path); relative_path = path + common_len; if ((dirsep = strchr(relative_path, '/')) == NULL) diff --git a/src/mailmap.c b/src/mailmap.c index 38ae0164589..4fbb1ae779a 100644 --- a/src/mailmap.c +++ b/src/mailmap.c @@ -9,7 +9,7 @@ #include "common.h" #include "config.h" -#include "path.h" +#include "fs_path.h" #include "repository.h" #include "signature.h" #include "git2/config.h" @@ -327,11 +327,11 @@ static int mailmap_add_file_ondisk( git_str content = GIT_STR_INIT; int error; - error = git_path_join_unrooted(&fullpath, path, base, NULL); + error = git_fs_path_join_unrooted(&fullpath, path, base, NULL); if (error < 0) goto cleanup; - error = git_path_validate_workdir_buf(repo, &fullpath); + error = git_fs_path_validate_workdir_buf(repo, &fullpath); if (error < 0) goto cleanup; diff --git a/src/merge.c b/src/merge.c index ae1d453ec11..ec7e5bfd106 100644 --- a/src/merge.c +++ b/src/merge.c @@ -12,7 +12,7 @@ #include "repository.h" #include "revwalk.h" #include "commit_list.h" -#include "path.h" +#include "fs_path.h" #include "refs.h" #include "object.h" #include "iterator.h" diff --git a/src/midx.c b/src/midx.c index b8da989866b..d4f9bd5a04a 100644 --- a/src/midx.c +++ b/src/midx.c @@ -14,7 +14,7 @@ #include "hash.h" #include "odb.h" #include "pack.h" -#include "path.h" +#include "fs_path.h" #include "repository.h" #include "str.h" @@ -502,7 +502,7 @@ int git_midx_writer_new( git__free(w); return -1; } - git_path_squash_slashes(&w->pack_dir); + git_fs_path_squash_slashes(&w->pack_dir); if (git_vector_init(&w->packs, 0, packfile__cmp) < 0) { git_str_dispose(&w->pack_dir); @@ -537,7 +537,7 @@ int git_midx_writer_add( int error; struct git_pack_file *p; - error = git_path_prettify(&idx_path_buf, idx_path, git_str_cstr(&w->pack_dir)); + error = git_fs_path_prettify(&idx_path_buf, idx_path, git_str_cstr(&w->pack_dir)); if (error < 0) return error; @@ -687,7 +687,7 @@ static int midx_write( error = git_str_sets(&relative_index, p->pack_name); if (error < 0) goto cleanup; - error = git_path_make_relative(&relative_index, git_str_cstr(&w->pack_dir)); + error = git_fs_path_make_relative(&relative_index, git_str_cstr(&w->pack_dir)); if (error < 0) { git_str_dispose(&relative_index); goto cleanup; diff --git a/src/odb.c b/src/odb.c index 7bf57547405..5bc69c3f6fa 100644 --- a/src/odb.c +++ b/src/odb.c @@ -277,7 +277,7 @@ int git_odb__hashlink(git_oid *out, const char *path) int size; int result; - if (git_path_lstat(path, &st) < 0) + if (git_fs_path_lstat(path, &st) < 0) return -1; if (!git__is_int(st.st_size) || (int)st.st_size < 0) { @@ -649,7 +649,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_ if (git_str_joinpath(&alternates_path, objects_dir, GIT_ALTERNATES_FILE) < 0) return -1; - if (git_path_exists(alternates_path.ptr) == false) { + if (git_fs_path_exists(alternates_path.ptr) == false) { git_str_dispose(&alternates_path); return 0; } diff --git a/src/odb_loose.c b/src/odb_loose.c index f0c3ac2c81c..463e24fa52b 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -87,7 +87,7 @@ static int object_file_name( return -1; git_str_set(name, be->objects_dir, be->objects_dirlen); - git_path_to_dir(name); + git_fs_path_to_dir(name); /* loose object filename: aa/aaa... (41 bytes) */ git_oid_pathfmt(name->ptr + name->size, id); @@ -452,7 +452,7 @@ static int locate_object( { int error = object_file_name(object_location, backend, oid); - if (!error && !git_path_exists(object_location->ptr)) + if (!error && !git_fs_path_exists(object_location->ptr)) return GIT_ENOTFOUND; return error; @@ -467,7 +467,7 @@ static int fn_locate_object_short_oid(void *state, git_str *pathbuf) { return 0; } - if (git_path_isdir(pathbuf->ptr) == false) { + if (git_fs_path_isdir(pathbuf->ptr) == false) { /* We are already in the directory matching the 2 first hex characters, * compare the first ncmp characters of the oids */ if (!memcmp(sstate->short_oid + 2, @@ -509,7 +509,7 @@ static int locate_object_short_oid( return -1; git_str_set(object_location, objects_dir, dir_len); - git_path_to_dir(object_location); + git_fs_path_to_dir(object_location); /* save adjusted position at end of dir so it can be restored later */ dir_len = git_str_len(object_location); @@ -523,7 +523,7 @@ static int locate_object_short_oid( object_location->ptr[object_location->size - 1] = '/'; /* Check that directory exists */ - if (git_path_isdir(object_location->ptr) == false) + if (git_fs_path_isdir(object_location->ptr) == false) return git_odb__error_notfound("no matching loose object for prefix", short_oid, len); @@ -532,7 +532,7 @@ static int locate_object_short_oid( state.found = 0; /* Explore directory to find a unique object matching short_oid */ - error = git_path_direach( + error = git_fs_path_direach( object_location, 0, fn_locate_object_short_oid, &state); if (error < 0 && error != GIT_EAMBIGUOUS) return error; @@ -753,10 +753,10 @@ static int foreach_cb(void *_state, git_str *path) struct foreach_state *state = (struct foreach_state *) _state; /* non-dir is some stray file, ignore it */ - if (!git_path_isdir(git_str_cstr(path))) + if (!git_fs_path_isdir(git_str_cstr(path))) return 0; - return git_path_direach(path, 0, foreach_object_dir_cb, state); + return git_fs_path_direach(path, 0, foreach_object_dir_cb, state); } static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb cb, void *data) @@ -773,7 +773,7 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb objects_dir = backend->objects_dir; git_str_sets(&buf, objects_dir); - git_path_to_dir(&buf); + git_fs_path_to_dir(&buf); if (git_str_oom(&buf)) return -1; @@ -782,7 +782,7 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb state.data = data; state.dir_len = git_str_len(&buf); - error = git_path_direach(&buf, 0, foreach_cb, &state); + error = git_fs_path_direach(&buf, 0, foreach_cb, &state); git_str_dispose(&buf); diff --git a/src/odb_pack.c b/src/odb_pack.c index f2c47adbe2b..5b752102947 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -524,7 +524,7 @@ static int pack_backend__refresh(git_odb_backend *backend_) /* reload all packs */ git_str_sets(&path, backend->pack_folder); - error = git_path_direach(&path, 0, packfile_load__cb, backend); + error = git_fs_path_direach(&path, 0, packfile_load__cb, backend); git_str_dispose(&path); git_vector_sort(&backend->packs); @@ -750,7 +750,7 @@ static int get_idx_path( size_t path_len; int error; - error = git_path_prettify(idx_path, p->pack_name, backend->pack_folder); + error = git_fs_path_prettify(idx_path, p->pack_name, backend->pack_folder); if (error < 0) return error; path_len = git_str_len(idx_path); @@ -902,7 +902,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir) return -1; if (!(error = git_str_joinpath(&path, objects_dir, "pack")) && - git_path_isdir(git_str_cstr(&path))) + git_fs_path_isdir(git_str_cstr(&path))) { backend->pack_folder = git_str_detach(&path); error = pack_backend__refresh((git_odb_backend *)backend); diff --git a/src/pack.c b/src/pack.c index e17d20f8c89..5c0cba7e892 100644 --- a/src/pack.c +++ b/src/pack.c @@ -1198,7 +1198,7 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path) if (!git_disable_pack_keep_file_checks) { memcpy(p->pack_name + root_len, ".keep", sizeof(".keep")); - if (git_path_exists(p->pack_name) == true) + if (git_fs_path_exists(p->pack_name) == true) p->pack_keep = 1; } diff --git a/src/patch_parse.c b/src/patch_parse.c index fce4bc9e469..891cf79a3a1 100644 --- a/src/patch_parse.c +++ b/src/patch_parse.c @@ -10,7 +10,7 @@ #include "git2/patch.h" #include "patch.h" #include "diff_parse.h" -#include "path.h" +#include "fs_path.h" typedef struct { git_patch base; @@ -80,7 +80,7 @@ static int parse_header_path_buf(git_str *path, git_patch_parse_ctx *ctx, size_t (error = git_str_unquote(path)) < 0) return error; - git_path_squash_slashes(path); + git_fs_path_squash_slashes(path); if (!path->size) return git_parse_err("patch contains empty path at line %"PRIuZ, diff --git a/src/path.c b/src/path.c index d8d33a1419f..d34125128b8 100644 --- a/src/path.c +++ b/src/path.c @@ -7,1555 +7,14 @@ #include "path.h" -#include "posix.h" #include "repository.h" -#ifdef GIT_WIN32 -#include "win32/posix.h" -#include "win32/w32_buffer.h" -#include "win32/w32_util.h" -#include "win32/version.h" -#include -#else -#include -#endif -#include -#include - -static int dos_drive_prefix_length(const char *path) -{ - int i; - - /* - * Does it start with an ASCII letter (i.e. highest bit not set), - * followed by a colon? - */ - if (!(0x80 & (unsigned char)*path)) - return *path && path[1] == ':' ? 2 : 0; - - /* - * While drive letters must be letters of the English alphabet, it is - * possible to assign virtually _any_ Unicode character via `subst` as - * a drive letter to "virtual drives". Even `1`, or `ä`. Or fun stuff - * like this: - * - * subst Ö: %USERPROFILE%\Desktop - */ - for (i = 1; i < 4 && (0x80 & (unsigned char)path[i]); i++) - ; /* skip first UTF-8 character */ - return path[i] == ':' ? i + 1 : 0; -} - -#ifdef GIT_WIN32 -static bool looks_like_network_computer_name(const char *path, int pos) -{ - if (pos < 3) - return false; - - if (path[0] != '/' || path[1] != '/') - return false; - - while (pos-- > 2) { - if (path[pos] == '/') - return false; - } - - return true; -} -#endif - -/* - * Based on the Android implementation, BSD licensed. - * http://android.git.kernel.org/ - * - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -int git_path_basename_r(git_str *buffer, const char *path) -{ - const char *endp, *startp; - int len, result; - - /* Empty or NULL string gets treated as "." */ - if (path == NULL || *path == '\0') { - startp = "."; - len = 1; - goto Exit; - } - - /* Strip trailing slashes */ - endp = path + strlen(path) - 1; - while (endp > path && *endp == '/') - endp--; - - /* All slashes becomes "/" */ - if (endp == path && *endp == '/') { - startp = "/"; - len = 1; - goto Exit; - } - - /* Find the start of the base */ - startp = endp; - while (startp > path && *(startp - 1) != '/') - startp--; - - /* Cast is safe because max path < max int */ - len = (int)(endp - startp + 1); - -Exit: - result = len; - - if (buffer != NULL && git_str_set(buffer, startp, len) < 0) - return -1; - - return result; -} - -/* - * Determine if the path is a Windows prefix and, if so, returns - * its actual lentgh. If it is not a prefix, returns -1. - */ -static int win32_prefix_length(const char *path, int len) -{ -#ifndef GIT_WIN32 - GIT_UNUSED(path); - GIT_UNUSED(len); -#else - /* - * Mimic unix behavior where '/.git' returns '/': 'C:/.git' - * will return 'C:/' here - */ - if (dos_drive_prefix_length(path) == len) - return len; - - /* - * Similarly checks if we're dealing with a network computer name - * '//computername/.git' will return '//computername/' - */ - if (looks_like_network_computer_name(path, len)) - return len; -#endif - - return -1; -} - -/* - * Based on the Android implementation, BSD licensed. - * Check http://android.git.kernel.org/ - */ -int git_path_dirname_r(git_str *buffer, const char *path) -{ - const char *endp; - int is_prefix = 0, len; - - /* Empty or NULL string gets treated as "." */ - if (path == NULL || *path == '\0') { - path = "."; - len = 1; - goto Exit; - } - - /* Strip trailing slashes */ - endp = path + strlen(path) - 1; - while (endp > path && *endp == '/') - endp--; - - if (endp - path + 1 > INT_MAX) { - git_error_set(GIT_ERROR_INVALID, "path too long"); - len = -1; - goto Exit; - } - - if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) { - is_prefix = 1; - goto Exit; - } - - /* Find the start of the dir */ - while (endp > path && *endp != '/') - endp--; - - /* Either the dir is "/" or there are no slashes */ - if (endp == path) { - path = (*endp == '/') ? "/" : "."; - len = 1; - goto Exit; - } - - do { - endp--; - } while (endp > path && *endp == '/'); - - if (endp - path + 1 > INT_MAX) { - git_error_set(GIT_ERROR_INVALID, "path too long"); - len = -1; - goto Exit; - } - - if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) { - is_prefix = 1; - goto Exit; - } - - /* Cast is safe because max path < max int */ - len = (int)(endp - path + 1); - -Exit: - if (buffer) { - if (git_str_set(buffer, path, len) < 0) - return -1; - if (is_prefix && git_str_putc(buffer, '/') < 0) - return -1; - } - - return len; -} - - -char *git_path_dirname(const char *path) -{ - git_str buf = GIT_STR_INIT; - char *dirname; - - git_path_dirname_r(&buf, path); - dirname = git_str_detach(&buf); - git_str_dispose(&buf); /* avoid memleak if error occurs */ - - return dirname; -} - -char *git_path_basename(const char *path) -{ - git_str buf = GIT_STR_INIT; - char *basename; - - git_path_basename_r(&buf, path); - basename = git_str_detach(&buf); - git_str_dispose(&buf); /* avoid memleak if error occurs */ - - return basename; -} - -size_t git_path_basename_offset(git_str *buffer) -{ - ssize_t slash; - - if (!buffer || buffer->size <= 0) - return 0; - - slash = git_str_rfind_next(buffer, '/'); - - if (slash >= 0 && buffer->ptr[slash] == '/') - return (size_t)(slash + 1); - - return 0; -} - -int git_path_root(const char *path) -{ - int offset = 0, prefix_len; - - /* Does the root of the path look like a windows drive ? */ - if ((prefix_len = dos_drive_prefix_length(path))) - offset += prefix_len; - -#ifdef GIT_WIN32 - /* Are we dealing with a windows network path? */ - else if ((path[0] == '/' && path[1] == '/' && path[2] != '/') || - (path[0] == '\\' && path[1] == '\\' && path[2] != '\\')) - { - offset += 2; - - /* Skip the computer name segment */ - while (path[offset] && path[offset] != '/' && path[offset] != '\\') - offset++; - } - - if (path[offset] == '\\') - return offset; -#endif - - if (path[offset] == '/') - return offset; - - return -1; /* Not a real error - signals that path is not rooted */ -} - -static void path_trim_slashes(git_str *path) -{ - int ceiling = git_path_root(path->ptr) + 1; - - if (ceiling < 0) - return; - - while (path->size > (size_t)ceiling) { - if (path->ptr[path->size-1] != '/') - break; - - path->ptr[path->size-1] = '\0'; - path->size--; - } -} - -int git_path_join_unrooted( - git_str *path_out, const char *path, const char *base, ssize_t *root_at) -{ - ssize_t root; - - GIT_ASSERT_ARG(path_out); - GIT_ASSERT_ARG(path); - - root = (ssize_t)git_path_root(path); - - if (base != NULL && root < 0) { - if (git_str_joinpath(path_out, base, path) < 0) - return -1; - - root = (ssize_t)strlen(base); - } else { - if (git_str_sets(path_out, path) < 0) - return -1; - - if (root < 0) - root = 0; - else if (base) - git_path_equal_or_prefixed(base, path, &root); - } - - if (root_at) - *root_at = root; - - return 0; -} - -void git_path_squash_slashes(git_str *path) -{ - char *p, *q; - - if (path->size == 0) - return; - - for (p = path->ptr, q = path->ptr; *q; p++, q++) { - *p = *q; - - while (*q == '/' && *(q+1) == '/') { - path->size--; - q++; - } - } - - *p = '\0'; -} - -int git_path_prettify(git_str *path_out, const char *path, const char *base) -{ - char buf[GIT_PATH_MAX]; - - GIT_ASSERT_ARG(path_out); - GIT_ASSERT_ARG(path); - - /* construct path if needed */ - if (base != NULL && git_path_root(path) < 0) { - if (git_str_joinpath(path_out, base, path) < 0) - return -1; - path = path_out->ptr; - } - - if (p_realpath(path, buf) == NULL) { - /* git_error_set resets the errno when dealing with a GIT_ERROR_OS kind of error */ - int error = (errno == ENOENT || errno == ENOTDIR) ? GIT_ENOTFOUND : -1; - git_error_set(GIT_ERROR_OS, "failed to resolve path '%s'", path); - - git_str_clear(path_out); - - return error; - } - - return git_str_sets(path_out, buf); -} - -int git_path_prettify_dir(git_str *path_out, const char *path, const char *base) -{ - int error = git_path_prettify(path_out, path, base); - return (error < 0) ? error : git_path_to_dir(path_out); -} - -int git_path_to_dir(git_str *path) -{ - if (path->asize > 0 && - git_str_len(path) > 0 && - path->ptr[git_str_len(path) - 1] != '/') - git_str_putc(path, '/'); - - return git_str_oom(path) ? -1 : 0; -} - -void git_path_string_to_dir(char *path, size_t size) -{ - size_t end = strlen(path); - - if (end && path[end - 1] != '/' && end < size) { - path[end] = '/'; - path[end + 1] = '\0'; - } -} - -int git__percent_decode(git_str *decoded_out, const char *input) -{ - int len, hi, lo, i; - - GIT_ASSERT_ARG(decoded_out); - GIT_ASSERT_ARG(input); - - len = (int)strlen(input); - git_str_clear(decoded_out); - - for(i = 0; i < len; i++) - { - char c = input[i]; - - if (c != '%') - goto append; - - if (i >= len - 2) - goto append; - - hi = git__fromhex(input[i + 1]); - lo = git__fromhex(input[i + 2]); - - if (hi < 0 || lo < 0) - goto append; - - c = (char)(hi << 4 | lo); - i += 2; - -append: - if (git_str_putc(decoded_out, c) < 0) - return -1; - } - - return 0; -} - -static int error_invalid_local_file_uri(const char *uri) -{ - git_error_set(GIT_ERROR_CONFIG, "'%s' is not a valid local file URI", uri); - return -1; -} - -static int local_file_url_prefixlen(const char *file_url) -{ - int len = -1; - - if (git__prefixcmp(file_url, "file://") == 0) { - if (file_url[7] == '/') - len = 8; - else if (git__prefixcmp(file_url + 7, "localhost/") == 0) - len = 17; - } - - return len; -} - -bool git_path_is_local_file_url(const char *file_url) -{ - return (local_file_url_prefixlen(file_url) > 0); -} - -int git_path_fromurl(git_str *local_path_out, const char *file_url) -{ - int offset; - - GIT_ASSERT_ARG(local_path_out); - GIT_ASSERT_ARG(file_url); - - if ((offset = local_file_url_prefixlen(file_url)) < 0 || - file_url[offset] == '\0' || file_url[offset] == '/') - return error_invalid_local_file_uri(file_url); - -#ifndef GIT_WIN32 - offset--; /* A *nix absolute path starts with a forward slash */ -#endif - - git_str_clear(local_path_out); - return git__percent_decode(local_path_out, file_url + offset); -} - -int git_path_walk_up( - git_str *path, - const char *ceiling, - int (*cb)(void *data, const char *), - void *data) -{ - int error = 0; - git_str iter; - ssize_t stop = 0, scan; - char oldc = '\0'; - - GIT_ASSERT_ARG(path); - GIT_ASSERT_ARG(cb); - - if (ceiling != NULL) { - if (git__prefixcmp(path->ptr, ceiling) == 0) - stop = (ssize_t)strlen(ceiling); - else - stop = git_str_len(path); - } - scan = git_str_len(path); - - /* empty path: yield only once */ - if (!scan) { - error = cb(data, ""); - if (error) - git_error_set_after_callback(error); - return error; - } - - iter.ptr = path->ptr; - iter.size = git_str_len(path); - iter.asize = path->asize; - - while (scan >= stop) { - error = cb(data, iter.ptr); - iter.ptr[scan] = oldc; - - if (error) { - git_error_set_after_callback(error); - break; - } - - scan = git_str_rfind_next(&iter, '/'); - if (scan >= 0) { - scan++; - oldc = iter.ptr[scan]; - iter.size = scan; - iter.ptr[scan] = '\0'; - } - } - - if (scan >= 0) - iter.ptr[scan] = oldc; - - /* relative path: yield for the last component */ - if (!error && stop == 0 && iter.ptr[0] != '/') { - error = cb(data, ""); - if (error) - git_error_set_after_callback(error); - } - - return error; -} - -bool git_path_exists(const char *path) -{ - GIT_ASSERT_ARG_WITH_RETVAL(path, false); - return p_access(path, F_OK) == 0; -} - -bool git_path_isdir(const char *path) -{ - struct stat st; - if (p_stat(path, &st) < 0) - return false; - - return S_ISDIR(st.st_mode) != 0; -} - -bool git_path_isfile(const char *path) -{ - struct stat st; - - GIT_ASSERT_ARG_WITH_RETVAL(path, false); - if (p_stat(path, &st) < 0) - return false; - - return S_ISREG(st.st_mode) != 0; -} - -bool git_path_islink(const char *path) -{ - struct stat st; - - GIT_ASSERT_ARG_WITH_RETVAL(path, false); - if (p_lstat(path, &st) < 0) - return false; - - return S_ISLNK(st.st_mode) != 0; -} - -#ifdef GIT_WIN32 - -bool git_path_is_empty_dir(const char *path) -{ - git_win32_path filter_w; - bool empty = false; - - if (git_win32__findfirstfile_filter(filter_w, path)) { - WIN32_FIND_DATAW findData; - HANDLE hFind = FindFirstFileW(filter_w, &findData); - - /* FindFirstFile will fail if there are no children to the given - * path, which can happen if the given path is a file (and obviously - * has no children) or if the given path is an empty mount point. - * (Most directories have at least directory entries '.' and '..', - * but ridiculously another volume mounted in another drive letter's - * path space do not, and thus have nothing to enumerate.) If - * FindFirstFile fails, check if this is a directory-like thing - * (a mount point). - */ - if (hFind == INVALID_HANDLE_VALUE) - return git_path_isdir(path); - - /* If the find handle was created successfully, then it's a directory */ - empty = true; - - do { - /* Allow the enumeration to return . and .. and still be considered - * empty. In the special case of drive roots (i.e. C:\) where . and - * .. do not occur, we can still consider the path to be an empty - * directory if there's nothing there. */ - if (!git_path_is_dot_or_dotdotW(findData.cFileName)) { - empty = false; - break; - } - } while (FindNextFileW(hFind, &findData)); - - FindClose(hFind); - } - - return empty; -} - -#else - -static int path_found_entry(void *payload, git_str *path) -{ - GIT_UNUSED(payload); - return !git_path_is_dot_or_dotdot(path->ptr); -} - -bool git_path_is_empty_dir(const char *path) -{ - int error; - git_str dir = GIT_STR_INIT; - - if (!git_path_isdir(path)) - return false; - - if ((error = git_str_sets(&dir, path)) != 0) - git_error_clear(); - else - error = git_path_direach(&dir, 0, path_found_entry, NULL); - - git_str_dispose(&dir); - - return !error; -} - -#endif - -int git_path_set_error(int errno_value, const char *path, const char *action) -{ - switch (errno_value) { - case ENOENT: - case ENOTDIR: - git_error_set(GIT_ERROR_OS, "could not find '%s' to %s", path, action); - return GIT_ENOTFOUND; - - case EINVAL: - case ENAMETOOLONG: - git_error_set(GIT_ERROR_OS, "invalid path for filesystem '%s'", path); - return GIT_EINVALIDSPEC; - - case EEXIST: - git_error_set(GIT_ERROR_OS, "failed %s - '%s' already exists", action, path); - return GIT_EEXISTS; - - case EACCES: - git_error_set(GIT_ERROR_OS, "failed %s - '%s' is locked", action, path); - return GIT_ELOCKED; - - default: - git_error_set(GIT_ERROR_OS, "could not %s '%s'", action, path); - return -1; - } -} - -int git_path_lstat(const char *path, struct stat *st) -{ - if (p_lstat(path, st) == 0) - return 0; - - return git_path_set_error(errno, path, "stat"); -} - -static bool _check_dir_contents( - git_str *dir, - const char *sub, - bool (*predicate)(const char *)) -{ - bool result; - size_t dir_size = git_str_len(dir); - size_t sub_size = strlen(sub); - size_t alloc_size; - - /* leave base valid even if we could not make space for subdir */ - if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) || - GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) || - git_str_try_grow(dir, alloc_size, false) < 0) - return false; - - /* save excursion */ - if (git_str_joinpath(dir, dir->ptr, sub) < 0) - return false; - - result = predicate(dir->ptr); - - /* restore path */ - git_str_truncate(dir, dir_size); - return result; -} - -bool git_path_contains(git_str *dir, const char *item) -{ - return _check_dir_contents(dir, item, &git_path_exists); -} - -bool git_path_contains_dir(git_str *base, const char *subdir) -{ - return _check_dir_contents(base, subdir, &git_path_isdir); -} - -bool git_path_contains_file(git_str *base, const char *file) -{ - return _check_dir_contents(base, file, &git_path_isfile); -} - -int git_path_find_dir(git_str *dir) -{ - int error = 0; - char buf[GIT_PATH_MAX]; - - if (p_realpath(dir->ptr, buf) != NULL) - error = git_str_sets(dir, buf); - - /* call dirname if this is not a directory */ - if (!error) /* && git_path_isdir(dir->ptr) == false) */ - error = (git_path_dirname_r(dir, dir->ptr) < 0) ? -1 : 0; - - if (!error) - error = git_path_to_dir(dir); - - return error; -} - -int git_path_resolve_relative(git_str *path, size_t ceiling) -{ - char *base, *to, *from, *next; - size_t len; - - GIT_ERROR_CHECK_ALLOC_STR(path); - - if (ceiling > path->size) - ceiling = path->size; - - /* recognize drive prefixes, etc. that should not be backed over */ - if (ceiling == 0) - ceiling = git_path_root(path->ptr) + 1; - - /* recognize URL prefixes that should not be backed over */ - if (ceiling == 0) { - for (next = path->ptr; *next && git__isalpha(*next); ++next); - if (next[0] == ':' && next[1] == '/' && next[2] == '/') - ceiling = (next + 3) - path->ptr; - } - - base = to = from = path->ptr + ceiling; - - while (*from) { - for (next = from; *next && *next != '/'; ++next); - - len = next - from; - - if (len == 1 && from[0] == '.') - /* do nothing with singleton dot */; - - else if (len == 2 && from[0] == '.' && from[1] == '.') { - /* error out if trying to up one from a hard base */ - if (to == base && ceiling != 0) { - git_error_set(GIT_ERROR_INVALID, - "cannot strip root component off url"); - return -1; - } - - /* no more path segments to strip, - * use '../' as a new base path */ - if (to == base) { - if (*next == '/') - len++; - - if (to != from) - memmove(to, from, len); - - to += len; - /* this is now the base, can't back up from a - * relative prefix */ - base = to; - } else { - /* back up a path segment */ - while (to > base && to[-1] == '/') to--; - while (to > base && to[-1] != '/') to--; - } - } else { - if (*next == '/' && *from != '/') - len++; - - if (to != from) - memmove(to, from, len); - - to += len; - } - - from += len; - - while (*from == '/') from++; - } - - *to = '\0'; - - path->size = to - path->ptr; - - return 0; -} - -int git_path_apply_relative(git_str *target, const char *relpath) -{ - return git_str_joinpath(target, git_str_cstr(target), relpath) || - git_path_resolve_relative(target, 0); -} - -int git_path_cmp( - const char *name1, size_t len1, int isdir1, - const char *name2, size_t len2, int isdir2, - int (*compare)(const char *, const char *, size_t)) -{ - unsigned char c1, c2; - size_t len = len1 < len2 ? len1 : len2; - int cmp; - - cmp = compare(name1, name2, len); - if (cmp) - return cmp; - - c1 = name1[len]; - c2 = name2[len]; - - if (c1 == '\0' && isdir1) - c1 = '/'; - - if (c2 == '\0' && isdir2) - c2 = '/'; - - return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0; -} - -size_t git_path_common_dirlen(const char *one, const char *two) -{ - const char *p, *q, *dirsep = NULL; - - for (p = one, q = two; *p && *q; p++, q++) { - if (*p == '/' && *q == '/') - dirsep = p; - else if (*p != *q) - break; - } - - return dirsep ? (dirsep - one) + 1 : 0; -} - -int git_path_make_relative(git_str *path, const char *parent) -{ - const char *p, *q, *p_dirsep, *q_dirsep; - size_t plen = path->size, newlen, alloclen, depth = 1, i, offset; - - for (p_dirsep = p = path->ptr, q_dirsep = q = parent; *p && *q; p++, q++) { - if (*p == '/' && *q == '/') { - p_dirsep = p; - q_dirsep = q; - } - else if (*p != *q) - break; - } - - /* need at least 1 common path segment */ - if ((p_dirsep == path->ptr || q_dirsep == parent) && - (*p_dirsep != '/' || *q_dirsep != '/')) { - git_error_set(GIT_ERROR_INVALID, - "%s is not a parent of %s", parent, path->ptr); - return GIT_ENOTFOUND; - } - - if (*p == '/' && !*q) - p++; - else if (!*p && *q == '/') - q++; - else if (!*p && !*q) - return git_str_clear(path), 0; - else { - p = p_dirsep + 1; - q = q_dirsep + 1; - } - - plen -= (p - path->ptr); - - if (!*q) - return git_str_set(path, p, plen); - - for (; (q = strchr(q, '/')) && *(q + 1); q++) - depth++; - - GIT_ERROR_CHECK_ALLOC_MULTIPLY(&newlen, depth, 3); - GIT_ERROR_CHECK_ALLOC_ADD(&newlen, newlen, plen); - - GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, newlen, 1); - - /* save the offset as we might realllocate the pointer */ - offset = p - path->ptr; - if (git_str_try_grow(path, alloclen, 1) < 0) - return -1; - p = path->ptr + offset; - - memmove(path->ptr + (depth * 3), p, plen + 1); - - for (i = 0; i < depth; i++) - memcpy(path->ptr + (i * 3), "../", 3); - - path->size = newlen; - return 0; -} - -bool git_path_has_non_ascii(const char *path, size_t pathlen) -{ - const uint8_t *scan = (const uint8_t *)path, *end; - - for (end = scan + pathlen; scan < end; ++scan) - if (*scan & 0x80) - return true; - - return false; -} - -#ifdef GIT_USE_ICONV - -int git_path_iconv_init_precompose(git_path_iconv_t *ic) -{ - git_str_init(&ic->buf, 0); - ic->map = iconv_open(GIT_PATH_REPO_ENCODING, GIT_PATH_NATIVE_ENCODING); - return 0; -} - -void git_path_iconv_clear(git_path_iconv_t *ic) -{ - if (ic) { - if (ic->map != (iconv_t)-1) - iconv_close(ic->map); - git_str_dispose(&ic->buf); - } -} - -int git_path_iconv(git_path_iconv_t *ic, const char **in, size_t *inlen) -{ - char *nfd = (char*)*in, *nfc; - size_t nfdlen = *inlen, nfclen, wantlen = nfdlen, alloclen, rv; - int retry = 1; - - if (!ic || ic->map == (iconv_t)-1 || - !git_path_has_non_ascii(*in, *inlen)) - return 0; - - git_str_clear(&ic->buf); - - while (1) { - GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, wantlen, 1); - if (git_str_grow(&ic->buf, alloclen) < 0) - return -1; - - nfc = ic->buf.ptr + ic->buf.size; - nfclen = ic->buf.asize - ic->buf.size; - - rv = iconv(ic->map, &nfd, &nfdlen, &nfc, &nfclen); - - ic->buf.size = (nfc - ic->buf.ptr); - - if (rv != (size_t)-1) - break; - - /* if we cannot convert the data (probably because iconv thinks - * it is not valid UTF-8 source data), then use original data - */ - if (errno != E2BIG) - return 0; - - /* make space for 2x the remaining data to be converted - * (with per retry overhead to avoid infinite loops) - */ - wantlen = ic->buf.size + max(nfclen, nfdlen) * 2 + (size_t)(retry * 4); - - if (retry++ > 4) - goto fail; - } - - ic->buf.ptr[ic->buf.size] = '\0'; - - *in = ic->buf.ptr; - *inlen = ic->buf.size; - - return 0; - -fail: - git_error_set(GIT_ERROR_OS, "unable to convert unicode path data"); - return -1; -} - -static const char *nfc_file = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D.XXXXXX"; -static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D.XXXXXX"; - -/* Check if the platform is decomposing unicode data for us. We will - * emulate core Git and prefer to use precomposed unicode data internally - * on these platforms, composing the decomposed unicode on the fly. - * - * This mainly happens on the Mac where HDFS stores filenames as - * decomposed unicode. Even on VFAT and SAMBA file systems, the Mac will - * return decomposed unicode from readdir() even when the actual - * filesystem is storing precomposed unicode. - */ -bool git_path_does_fs_decompose_unicode(const char *root) -{ - git_str path = GIT_STR_INIT; - int fd; - bool found_decomposed = false; - char tmp[6]; - - /* Create a file using a precomposed path and then try to find it - * using the decomposed name. If the lookup fails, then we will mark - * that we should precompose unicode for this repository. - */ - if (git_str_joinpath(&path, root, nfc_file) < 0 || - (fd = p_mkstemp(path.ptr)) < 0) - goto done; - p_close(fd); - - /* record trailing digits generated by mkstemp */ - memcpy(tmp, path.ptr + path.size - sizeof(tmp), sizeof(tmp)); - - /* try to look up as NFD path */ - if (git_str_joinpath(&path, root, nfd_file) < 0) - goto done; - memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); - - found_decomposed = git_path_exists(path.ptr); - - /* remove temporary file (using original precomposed path) */ - if (git_str_joinpath(&path, root, nfc_file) < 0) - goto done; - memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); - - (void)p_unlink(path.ptr); - -done: - git_str_dispose(&path); - return found_decomposed; -} - -#else - -bool git_path_does_fs_decompose_unicode(const char *root) -{ - GIT_UNUSED(root); - return false; -} - -#endif - -#if defined(__sun) || defined(__GNU__) -typedef char path_dirent_data[sizeof(struct dirent) + FILENAME_MAX + 1]; -#else -typedef struct dirent path_dirent_data; -#endif - -int git_path_direach( - git_str *path, - uint32_t flags, - int (*fn)(void *, git_str *), - void *arg) -{ - int error = 0; - ssize_t wd_len; - DIR *dir; - struct dirent *de; - -#ifdef GIT_USE_ICONV - git_path_iconv_t ic = GIT_PATH_ICONV_INIT; -#endif - - GIT_UNUSED(flags); - - if (git_path_to_dir(path) < 0) - return -1; - - wd_len = git_str_len(path); - - if ((dir = opendir(path->ptr)) == NULL) { - git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path->ptr); - if (errno == ENOENT) - return GIT_ENOTFOUND; - - return -1; - } - -#ifdef GIT_USE_ICONV - if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0) - (void)git_path_iconv_init_precompose(&ic); -#endif - - while ((de = readdir(dir)) != NULL) { - const char *de_path = de->d_name; - size_t de_len = strlen(de_path); - - if (git_path_is_dot_or_dotdot(de_path)) - continue; - -#ifdef GIT_USE_ICONV - if ((error = git_path_iconv(&ic, &de_path, &de_len)) < 0) - break; -#endif - - if ((error = git_str_put(path, de_path, de_len)) < 0) - break; - - git_error_clear(); - error = fn(arg, path); - - git_str_truncate(path, wd_len); /* restore path */ - - /* Only set our own error if the callback did not set one already */ - if (error != 0) { - if (!git_error_last()) - git_error_set_after_callback(error); - - break; - } - } - - closedir(dir); - -#ifdef GIT_USE_ICONV - git_path_iconv_clear(&ic); -#endif - - return error; -} - -#if defined(GIT_WIN32) && !defined(__MINGW32__) - -/* Using _FIND_FIRST_EX_LARGE_FETCH may increase performance in Windows 7 - * and better. - */ -#ifndef FIND_FIRST_EX_LARGE_FETCH -# define FIND_FIRST_EX_LARGE_FETCH 2 -#endif - -int git_path_diriter_init( - git_path_diriter *diriter, - const char *path, - unsigned int flags) -{ - git_win32_path path_filter; +#include "fs_path.h" - static int is_win7_or_later = -1; - if (is_win7_or_later < 0) - is_win7_or_later = git_has_win32_version(6, 1, 0); - - GIT_ASSERT_ARG(diriter); - GIT_ASSERT_ARG(path); - - memset(diriter, 0, sizeof(git_path_diriter)); - diriter->handle = INVALID_HANDLE_VALUE; - - if (git_str_puts(&diriter->path_utf8, path) < 0) - return -1; - - path_trim_slashes(&diriter->path_utf8); - - if (diriter->path_utf8.size == 0) { - git_error_set(GIT_ERROR_FILESYSTEM, "could not open directory '%s'", path); - return -1; - } - - if ((diriter->parent_len = git_win32_path_from_utf8(diriter->path, diriter->path_utf8.ptr)) < 0 || - !git_win32__findfirstfile_filter(path_filter, diriter->path_utf8.ptr)) { - git_error_set(GIT_ERROR_OS, "could not parse the directory path '%s'", path); - return -1; - } - - diriter->handle = FindFirstFileExW( - path_filter, - is_win7_or_later ? FindExInfoBasic : FindExInfoStandard, - &diriter->current, - FindExSearchNameMatch, - NULL, - is_win7_or_later ? FIND_FIRST_EX_LARGE_FETCH : 0); - - if (diriter->handle == INVALID_HANDLE_VALUE) { - git_error_set(GIT_ERROR_OS, "could not open directory '%s'", path); - return -1; - } - - diriter->parent_utf8_len = diriter->path_utf8.size; - diriter->flags = flags; - return 0; -} - -static int diriter_update_paths(git_path_diriter *diriter) -{ - size_t filename_len, path_len; - - filename_len = wcslen(diriter->current.cFileName); - - if (GIT_ADD_SIZET_OVERFLOW(&path_len, diriter->parent_len, filename_len) || - GIT_ADD_SIZET_OVERFLOW(&path_len, path_len, 2)) - return -1; - - if (path_len > GIT_WIN_PATH_UTF16) { - git_error_set(GIT_ERROR_FILESYSTEM, - "invalid path '%.*ls\\%ls' (path too long)", - diriter->parent_len, diriter->path, diriter->current.cFileName); - return -1; - } - - diriter->path[diriter->parent_len] = L'\\'; - memcpy(&diriter->path[diriter->parent_len+1], - diriter->current.cFileName, filename_len * sizeof(wchar_t)); - diriter->path[path_len-1] = L'\0'; - - git_str_truncate(&diriter->path_utf8, diriter->parent_utf8_len); - - if (diriter->parent_utf8_len > 0 && - diriter->path_utf8.ptr[diriter->parent_utf8_len-1] != '/') - git_str_putc(&diriter->path_utf8, '/'); - - git_str_put_w(&diriter->path_utf8, diriter->current.cFileName, filename_len); - - if (git_str_oom(&diriter->path_utf8)) - return -1; - - return 0; -} - -int git_path_diriter_next(git_path_diriter *diriter) -{ - bool skip_dot = !(diriter->flags & GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT); - - do { - /* Our first time through, we already have the data from - * FindFirstFileW. Use it, otherwise get the next file. - */ - if (!diriter->needs_next) - diriter->needs_next = 1; - else if (!FindNextFileW(diriter->handle, &diriter->current)) - return GIT_ITEROVER; - } while (skip_dot && git_path_is_dot_or_dotdotW(diriter->current.cFileName)); - - if (diriter_update_paths(diriter) < 0) - return -1; - - return 0; -} - -int git_path_diriter_filename( - const char **out, - size_t *out_len, - git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(out_len); - GIT_ASSERT_ARG(diriter); - GIT_ASSERT(diriter->path_utf8.size > diriter->parent_utf8_len); - - *out = &diriter->path_utf8.ptr[diriter->parent_utf8_len+1]; - *out_len = diriter->path_utf8.size - diriter->parent_utf8_len - 1; - return 0; -} - -int git_path_diriter_fullpath( - const char **out, - size_t *out_len, - git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(out_len); - GIT_ASSERT_ARG(diriter); - - *out = diriter->path_utf8.ptr; - *out_len = diriter->path_utf8.size; - return 0; -} - -int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(diriter); - - return git_win32__file_attribute_to_stat(out, - (WIN32_FILE_ATTRIBUTE_DATA *)&diriter->current, - diriter->path); -} - -void git_path_diriter_free(git_path_diriter *diriter) -{ - if (diriter == NULL) - return; - - git_str_dispose(&diriter->path_utf8); - - if (diriter->handle != INVALID_HANDLE_VALUE) { - FindClose(diriter->handle); - diriter->handle = INVALID_HANDLE_VALUE; - } -} - -#else - -int git_path_diriter_init( - git_path_diriter *diriter, - const char *path, - unsigned int flags) -{ - GIT_ASSERT_ARG(diriter); - GIT_ASSERT_ARG(path); - - memset(diriter, 0, sizeof(git_path_diriter)); - - if (git_str_puts(&diriter->path, path) < 0) - return -1; - - path_trim_slashes(&diriter->path); - - if (diriter->path.size == 0) { - git_error_set(GIT_ERROR_FILESYSTEM, "could not open directory '%s'", path); - return -1; - } - - if ((diriter->dir = opendir(diriter->path.ptr)) == NULL) { - git_str_dispose(&diriter->path); - - git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path); - return -1; - } - -#ifdef GIT_USE_ICONV - if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0) - (void)git_path_iconv_init_precompose(&diriter->ic); -#endif - - diriter->parent_len = diriter->path.size; - diriter->flags = flags; - - return 0; -} - -int git_path_diriter_next(git_path_diriter *diriter) -{ - struct dirent *de; - const char *filename; - size_t filename_len; - bool skip_dot = !(diriter->flags & GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT); - int error = 0; - - GIT_ASSERT_ARG(diriter); - - errno = 0; - - do { - if ((de = readdir(diriter->dir)) == NULL) { - if (!errno) - return GIT_ITEROVER; - - git_error_set(GIT_ERROR_OS, - "could not read directory '%s'", diriter->path.ptr); - return -1; - } - } while (skip_dot && git_path_is_dot_or_dotdot(de->d_name)); - - filename = de->d_name; - filename_len = strlen(filename); - -#ifdef GIT_USE_ICONV - if ((diriter->flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0 && - (error = git_path_iconv(&diriter->ic, &filename, &filename_len)) < 0) - return error; -#endif - - git_str_truncate(&diriter->path, diriter->parent_len); - - if (diriter->parent_len > 0 && - diriter->path.ptr[diriter->parent_len-1] != '/') - git_str_putc(&diriter->path, '/'); - - git_str_put(&diriter->path, filename, filename_len); - - if (git_str_oom(&diriter->path)) - return -1; - - return error; -} - -int git_path_diriter_filename( - const char **out, - size_t *out_len, - git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(out_len); - GIT_ASSERT_ARG(diriter); - GIT_ASSERT(diriter->path.size > diriter->parent_len); - - *out = &diriter->path.ptr[diriter->parent_len+1]; - *out_len = diriter->path.size - diriter->parent_len - 1; - return 0; -} - -int git_path_diriter_fullpath( - const char **out, - size_t *out_len, - git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(out_len); - GIT_ASSERT_ARG(diriter); - - *out = diriter->path.ptr; - *out_len = diriter->path.size; - return 0; -} - -int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(diriter); - - return git_path_lstat(diriter->path.ptr, out); -} - -void git_path_diriter_free(git_path_diriter *diriter) -{ - if (diriter == NULL) - return; - - if (diriter->dir) { - closedir(diriter->dir); - diriter->dir = NULL; - } - -#ifdef GIT_USE_ICONV - git_path_iconv_clear(&diriter->ic); -#endif - - git_str_dispose(&diriter->path); -} - -#endif - -int git_path_dirload( - git_vector *contents, - const char *path, - size_t prefix_len, - uint32_t flags) -{ - git_path_diriter iter = GIT_PATH_DIRITER_INIT; - const char *name; - size_t name_len; - char *dup; - int error; - - GIT_ASSERT_ARG(contents); - GIT_ASSERT_ARG(path); - - if ((error = git_path_diriter_init(&iter, path, flags)) < 0) - return error; - - while ((error = git_path_diriter_next(&iter)) == 0) { - if ((error = git_path_diriter_fullpath(&name, &name_len, &iter)) < 0) - break; - - GIT_ASSERT(name_len > prefix_len); - - dup = git__strndup(name + prefix_len, name_len - prefix_len); - GIT_ERROR_CHECK_ALLOC(dup); - - if ((error = git_vector_insert(contents, dup)) < 0) - break; - } - - if (error == GIT_ITEROVER) - error = 0; - - git_path_diriter_free(&iter); - return error; -} - -int git_path_from_url_or_path(git_str *local_path_out, const char *url_or_path) -{ - if (git_path_is_local_file_url(url_or_path)) - return git_path_fromurl(local_path_out, url_or_path); - else - return git_str_sets(local_path_out, url_or_path); -} - -/* Reject paths like AUX or COM1, or those versions that end in a dot or - * colon. ("AUX." or "AUX:") - */ -GIT_INLINE(bool) verify_dospath( - const char *component, - size_t len, - const char dospath[3], - bool trailing_num) -{ - size_t last = trailing_num ? 4 : 3; - - if (len < last || git__strncasecmp(component, dospath, 3) != 0) - return true; - - if (trailing_num && (component[3] < '1' || component[3] > '9')) - return true; - - return (len > last && - component[last] != '.' && - component[last] != ':'); -} +typedef struct { + git_repository *repo; + uint16_t file_mode; + unsigned int flags; +} repository_path_validate_data; static int32_t next_hfs_char(const char **in, size_t *len) { @@ -1598,7 +57,11 @@ static int32_t next_hfs_char(const char **in, size_t *len) return 0; /* NULL byte -- end of string */ } -static bool verify_dotgit_hfs_generic(const char *path, size_t len, const char *needle, size_t needle_len) +static bool validate_dotgit_hfs_generic( + const char *path, + size_t len, + const char *needle, + size_t needle_len) { size_t i; char c; @@ -1618,12 +81,15 @@ static bool verify_dotgit_hfs_generic(const char *path, size_t len, const char * return false; } -static bool verify_dotgit_hfs(const char *path, size_t len) +static bool validate_dotgit_hfs(const char *path, size_t len) { - return verify_dotgit_hfs_generic(path, len, "git", CONST_STRLEN("git")); + return validate_dotgit_hfs_generic(path, len, "git", CONST_STRLEN("git")); } -GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size_t len) +GIT_INLINE(bool) validate_dotgit_ntfs( + git_repository *repo, + const char *path, + size_t len) { git_str *reserved = git_repository__reserved_names_win32; size_t reserved_len = git_repository__reserved_names_win32_len; @@ -1685,7 +151,12 @@ GIT_INLINE(bool) ntfs_end_of_filename(const char *path) return true; } -GIT_INLINE(bool) verify_dotgit_ntfs_generic(const char *name, size_t len, const char *dotgit_name, size_t dotgit_len, const char *shortname_pfix) +GIT_INLINE(bool) validate_dotgit_ntfs_generic( + const char *name, + size_t len, + const char *dotgit_name, + size_t dotgit_len, + const char *shortname_pfix) { int i, saw_tilde; @@ -1722,33 +193,6 @@ GIT_INLINE(bool) verify_dotgit_ntfs_generic(const char *name, size_t len, const return !ntfs_end_of_filename(name + i); } -GIT_INLINE(bool) verify_char(unsigned char c, unsigned int flags) -{ - if ((flags & GIT_PATH_REJECT_BACKSLASH) && c == '\\') - return false; - - if ((flags & GIT_PATH_REJECT_SLASH) && c == '/') - return false; - - if (flags & GIT_PATH_REJECT_NT_CHARS) { - if (c < 32) - return false; - - switch (c) { - case '<': - case '>': - case ':': - case '"': - case '|': - case '?': - case '*': - return false; - } - } - - return true; -} - /* * Return the length of the common prefix between str and prefix, comparing them * case-insensitively (must be ASCII to match). @@ -1757,7 +201,7 @@ GIT_INLINE(size_t) common_prefix_icase(const char *str, size_t len, const char * { size_t count = 0; - while (len >0 && tolower(*str) == tolower(*prefix)) { + while (len > 0 && tolower(*str) == tolower(*prefix)) { count++; str++; prefix++; @@ -1767,72 +211,37 @@ GIT_INLINE(size_t) common_prefix_icase(const char *str, size_t len, const char * return count; } -/* - * We fundamentally don't like some paths when dealing with user-inputted - * strings (in checkout or ref names): we don't want dot or dot-dot - * anywhere, we want to avoid writing weird paths on Windows that can't - * be handled by tools that use the non-\\?\ APIs, we don't want slashes - * or double slashes at the end of paths that can make them ambiguous. - * - * For checkout, we don't want to recurse into ".git" either. - */ -static bool verify_component( - git_repository *repo, +static bool validate_repo_component( const char *component, size_t len, - uint16_t mode, - unsigned int flags) + void *payload) { - if (len == 0) - return false; - - if ((flags & GIT_PATH_REJECT_TRAVERSAL) && - len == 1 && component[0] == '.') - return false; - - if ((flags & GIT_PATH_REJECT_TRAVERSAL) && - len == 2 && component[0] == '.' && component[1] == '.') - return false; - - if ((flags & GIT_PATH_REJECT_TRAILING_DOT) && component[len-1] == '.') - return false; - - if ((flags & GIT_PATH_REJECT_TRAILING_SPACE) && component[len-1] == ' ') - return false; - - if ((flags & GIT_PATH_REJECT_TRAILING_COLON) && component[len-1] == ':') - return false; + repository_path_validate_data *data = (repository_path_validate_data *)payload; - if (flags & GIT_PATH_REJECT_DOS_PATHS) { - if (!verify_dospath(component, len, "CON", false) || - !verify_dospath(component, len, "PRN", false) || - !verify_dospath(component, len, "AUX", false) || - !verify_dospath(component, len, "NUL", false) || - !verify_dospath(component, len, "COM", true) || - !verify_dospath(component, len, "LPT", true)) + if (data->flags & GIT_PATH_REJECT_DOT_GIT_HFS) { + if (!validate_dotgit_hfs(component, len)) return false; - } - if (flags & GIT_PATH_REJECT_DOT_GIT_HFS) { - if (!verify_dotgit_hfs(component, len)) - return false; - if (S_ISLNK(mode) && git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS)) + if (S_ISLNK(data->file_mode) && + git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS)) return false; } - if (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) { - if (!verify_dotgit_ntfs(repo, component, len)) + if (data->flags & GIT_PATH_REJECT_DOT_GIT_NTFS) { + if (!validate_dotgit_ntfs(data->repo, component, len)) return false; - if (S_ISLNK(mode) && git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_NTFS)) + + if (S_ISLNK(data->file_mode) && + git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_NTFS)) return false; } /* don't bother rerunning the `.git` test if we ran the HFS or NTFS * specific tests, they would have already rejected `.git`. */ - if ((flags & GIT_PATH_REJECT_DOT_GIT_HFS) == 0 && - (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 && - (flags & GIT_PATH_REJECT_DOT_GIT_LITERAL)) { + if ((data->flags & GIT_PATH_REJECT_DOT_GIT_HFS) == 0 && + (data->flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 && + (data->flags & GIT_PATH_REJECT_DOT_GIT_LITERAL)) { if (len >= 4 && component[0] == '.' && (component[1] == 'g' || component[1] == 'G') && @@ -1841,10 +250,11 @@ static bool verify_component( if (len == 4) return false; - if (S_ISLNK(mode) && common_prefix_icase(component, len, ".gitmodules") == len) + if (S_ISLNK(data->file_mode) && + common_prefix_icase(component, len, ".gitmodules") == len) return false; } - } + } return true; } @@ -1878,90 +288,20 @@ GIT_INLINE(unsigned int) dotgit_flags( bool git_path_validate( git_repository *repo, const char *path, - uint16_t mode, + uint16_t file_mode, unsigned int flags) { - const char *start, *c; + repository_path_validate_data data = {0}; /* Upgrade the ".git" checks based on platform */ if ((flags & GIT_PATH_REJECT_DOT_GIT)) flags = dotgit_flags(repo, flags); - for (start = c = path; *c; c++) { - if (!verify_char(*c, flags)) - return false; - - if (*c == '/') { - if (!verify_component(repo, start, (c - start), mode, flags)) - return false; - - start = c+1; - } - } - - return verify_component(repo, start, (c - start), mode, flags); -} - -#ifdef GIT_WIN32 -GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) -{ - int longpaths = 0; - - if (repo && - git_repository__configmap_lookup(&longpaths, repo, GIT_CONFIGMAP_LONGPATHS) < 0) - longpaths = 0; - - return (longpaths == 0); -} - -#else - -GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) -{ - GIT_UNUSED(repo); - - return false; -} -#endif - -int git_path_validate_workdir(git_repository *repo, const char *path) -{ - if (should_validate_longpaths(repo)) - return git_path_validate_filesystem(path, strlen(path)); - - return 0; -} - -int git_path_validate_workdir_with_len( - git_repository *repo, - const char *path, - size_t path_len) -{ - if (should_validate_longpaths(repo)) - return git_path_validate_filesystem(path, path_len); - - return 0; -} - -int git_path_validate_workdir_buf(git_repository *repo, git_str *path) -{ - return git_path_validate_workdir_with_len(repo, path->ptr, path->size); -} - -int git_path_normalize_slashes(git_str *out, const char *path) -{ - int error; - char *p; - - if ((error = git_str_puts(out, path)) < 0) - return error; - - for (p = out->ptr; *p; p++) { - if (*p == '\\') - *p = '/'; - } + data.repo = repo; + data.file_mode = file_mode; + data.flags = flags; - return 0; + return git_fs_path_validate_ext(path, flags, NULL, validate_repo_component, &data); } static const struct { @@ -1974,7 +314,11 @@ static const struct { { "gitattributes", "gi7d29", CONST_STRLEN("gitattributes") } }; -extern int git_path_is_gitfile(const char *path, size_t pathlen, git_path_gitfile gitfile, git_path_fs fs) +extern int git_path_is_gitfile( + const char *path, + size_t pathlen, + git_path_gitfile gitfile, + git_path_fs fs) { const char *file, *hash; size_t filelen; @@ -1990,112 +334,15 @@ extern int git_path_is_gitfile(const char *path, size_t pathlen, git_path_gitfil switch (fs) { case GIT_PATH_FS_GENERIC: - return !verify_dotgit_ntfs_generic(path, pathlen, file, filelen, hash) || - !verify_dotgit_hfs_generic(path, pathlen, file, filelen); + return !validate_dotgit_ntfs_generic(path, pathlen, file, filelen, hash) || + !validate_dotgit_hfs_generic(path, pathlen, file, filelen); case GIT_PATH_FS_NTFS: - return !verify_dotgit_ntfs_generic(path, pathlen, file, filelen, hash); + return !validate_dotgit_ntfs_generic(path, pathlen, file, filelen, hash); case GIT_PATH_FS_HFS: - return !verify_dotgit_hfs_generic(path, pathlen, file, filelen); + return !validate_dotgit_hfs_generic(path, pathlen, file, filelen); default: git_error_set(GIT_ERROR_OS, "invalid filesystem for path validation"); return -1; } } -bool git_path_supports_symlinks(const char *dir) -{ - git_str path = GIT_STR_INIT; - bool supported = false; - struct stat st; - int fd; - - if ((fd = git_futils_mktmp(&path, dir, 0666)) < 0 || - p_close(fd) < 0 || - p_unlink(path.ptr) < 0 || - p_symlink("testing", path.ptr) < 0 || - p_lstat(path.ptr, &st) < 0) - goto done; - - supported = (S_ISLNK(st.st_mode) != 0); -done: - if (path.size) - (void)p_unlink(path.ptr); - git_str_dispose(&path); - return supported; -} - -int git_path_validate_system_file_ownership(const char *path) -{ -#ifndef GIT_WIN32 - GIT_UNUSED(path); - return GIT_OK; -#else - git_win32_path buf; - PSID owner_sid; - PSECURITY_DESCRIPTOR descriptor = NULL; - HANDLE token; - TOKEN_USER *info = NULL; - DWORD err, len; - int ret; - - if (git_win32_path_from_utf8(buf, path) < 0) - return -1; - - err = GetNamedSecurityInfoW(buf, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION, - &owner_sid, NULL, NULL, NULL, &descriptor); - - if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) { - ret = GIT_ENOTFOUND; - goto cleanup; - } - - if (err != ERROR_SUCCESS) { - git_error_set(GIT_ERROR_OS, "failed to get security information"); - ret = GIT_ERROR; - goto cleanup; - } - - if (!IsValidSid(owner_sid)) { - git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is unknown"); - ret = GIT_ERROR; - goto cleanup; - } - - if (IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) || - IsWellKnownSid(owner_sid, WinLocalSystemSid)) { - ret = GIT_OK; - goto cleanup; - } - - /* Obtain current user's SID */ - if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) && - !GetTokenInformation(token, TokenUser, NULL, 0, &len)) { - info = git__malloc(len); - GIT_ERROR_CHECK_ALLOC(info); - if (!GetTokenInformation(token, TokenUser, info, len, &len)) { - git__free(info); - info = NULL; - } - } - - /* - * If the file is owned by the same account that is running the current - * process, it's okay to read from that file. - */ - if (info && EqualSid(owner_sid, info->User.Sid)) - ret = GIT_OK; - else { - git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is not valid"); - ret = GIT_ERROR; - } - git__free(info); - -cleanup: - if (descriptor) - LocalFree(descriptor); - - return ret; -#endif -} diff --git a/src/path.h b/src/path.h index 4074c342598..ca220d12114 100644 --- a/src/path.h +++ b/src/path.h @@ -9,729 +9,26 @@ #include "common.h" -#include "posix.h" -#include "str.h" -#include "vector.h" +#include "fs_path.h" +#include -#include "git2/sys/path.h" +#define GIT_PATH_REJECT_DOT_GIT (GIT_FS_PATH_REJECT_MAX << 1) +#define GIT_PATH_REJECT_DOT_GIT_LITERAL (GIT_FS_PATH_REJECT_MAX << 2) +#define GIT_PATH_REJECT_DOT_GIT_HFS (GIT_FS_PATH_REJECT_MAX << 3) +#define GIT_PATH_REJECT_DOT_GIT_NTFS (GIT_FS_PATH_REJECT_MAX << 4) -/** - * Path manipulation utils - * - * These are path utilities that munge paths without actually - * looking at the real filesystem. - */ - -/* - * The dirname() function shall take a pointer to a character string - * that contains a pathname, and return a pointer to a string that is a - * pathname of the parent directory of that file. Trailing '/' characters - * in the path are not counted as part of the path. - * - * If path does not contain a '/', then dirname() shall return a pointer to - * the string ".". If path is a null pointer or points to an empty string, - * dirname() shall return a pointer to the string "." . - * - * The `git_path_dirname` implementation is thread safe. The returned - * string must be manually free'd. - * - * The `git_path_dirname_r` implementation writes the dirname to a `git_str` - * if the buffer pointer is not NULL. - * It returns an error code < 0 if there is an allocation error, otherwise - * the length of the dirname (which will be > 0). - */ -extern char *git_path_dirname(const char *path); -extern int git_path_dirname_r(git_str *buffer, const char *path); - -/* - * This function returns the basename of the file, which is the last - * part of its full name given by fname, with the drive letter and - * leading directories stripped off. For example, the basename of - * c:/foo/bar/file.ext is file.ext, and the basename of a:foo is foo. - * - * Trailing slashes and backslashes are significant: the basename of - * c:/foo/bar/ is an empty string after the rightmost slash. - * - * The `git_path_basename` implementation is thread safe. The returned - * string must be manually free'd. - * - * The `git_path_basename_r` implementation writes the basename to a `git_str`. - * It returns an error code < 0 if there is an allocation error, otherwise - * the length of the basename (which will be >= 0). - */ -extern char *git_path_basename(const char *path); -extern int git_path_basename_r(git_str *buffer, const char *path); - -/* Return the offset of the start of the basename. Unlike the other - * basename functions, this returns 0 if the path is empty. - */ -extern size_t git_path_basename_offset(git_str *buffer); - -/** - * Find offset to root of path if path has one. - * - * This will return a number >= 0 which is the offset to the start of the - * path, if the path is rooted (i.e. "/rooted/path" returns 0 and - * "c:/windows/rooted/path" returns 2). If the path is not rooted, this - * returns -1. - */ -extern int git_path_root(const char *path); - -/** - * Ensure path has a trailing '/'. - */ -extern int git_path_to_dir(git_str *path); - -/** - * Ensure string has a trailing '/' if there is space for it. - */ -extern void git_path_string_to_dir(char *path, size_t size); - -/** - * Taken from git.git; returns nonzero if the given path is "." or "..". - */ -GIT_INLINE(int) git_path_is_dot_or_dotdot(const char *name) -{ - return (name[0] == '.' && - (name[1] == '\0' || - (name[1] == '.' && name[2] == '\0'))); -} - -#ifdef GIT_WIN32 -GIT_INLINE(int) git_path_is_dot_or_dotdotW(const wchar_t *name) -{ - return (name[0] == L'.' && - (name[1] == L'\0' || - (name[1] == L'.' && name[2] == L'\0'))); -} - -#define git_path_is_absolute(p) \ - (git__isalpha((p)[0]) && (p)[1] == ':' && ((p)[2] == '\\' || (p)[2] == '/')) - -#define git_path_is_dirsep(p) \ - ((p) == '/' || (p) == '\\') - -/** - * Convert backslashes in path to forward slashes. - */ -GIT_INLINE(void) git_path_mkposix(char *path) -{ - while (*path) { - if (*path == '\\') - *path = '/'; - - path++; - } -} -#else -# define git_path_mkposix(p) /* blank */ - -#define git_path_is_absolute(p) \ - ((p)[0] == '/') - -#define git_path_is_dirsep(p) \ - ((p) == '/') - -#endif - -/** - * Check if string is a relative path (i.e. starts with "./" or "../") - */ -GIT_INLINE(int) git_path_is_relative(const char *p) -{ - return (p[0] == '.' && (p[1] == '/' || (p[1] == '.' && p[2] == '/'))); -} - -/** - * Check if string is at end of path segment (i.e. looking at '/' or '\0') - */ -GIT_INLINE(int) git_path_at_end_of_segment(const char *p) -{ - return !*p || *p == '/'; -} - -extern int git__percent_decode(git_str *decoded_out, const char *input); - -/** - * Extract path from file:// URL. - */ -extern int git_path_fromurl(git_str *local_path_out, const char *file_url); - - -/** - * Path filesystem utils - * - * These are path utilities that actually access the filesystem. - */ - -/** - * Check if a file exists and can be accessed. - * @return true or false - */ -extern bool git_path_exists(const char *path); - -/** - * Check if the given path points to a directory. - * @return true or false - */ -extern bool git_path_isdir(const char *path); - -/** - * Check if the given path points to a regular file. - * @return true or false - */ -extern bool git_path_isfile(const char *path); - -/** - * Check if the given path points to a symbolic link. - * @return true or false - */ -extern bool git_path_islink(const char *path); - -/** - * Check if the given path is a directory, and is empty. - */ -extern bool git_path_is_empty_dir(const char *path); - -/** - * Stat a file and/or link and set error if needed. - */ -extern int git_path_lstat(const char *path, struct stat *st); - -/** - * Check if the parent directory contains the item. - * - * @param dir Directory to check. - * @param item Item that might be in the directory. - * @return 0 if item exists in directory, <0 otherwise. - */ -extern bool git_path_contains(git_str *dir, const char *item); - -/** - * Check if the given path contains the given subdirectory. - * - * @param parent Directory path that might contain subdir - * @param subdir Subdirectory name to look for in parent - * @return true if subdirectory exists, false otherwise. - */ -extern bool git_path_contains_dir(git_str *parent, const char *subdir); - -/** - * Determine the common directory length between two paths, including - * the final path separator. For example, given paths 'a/b/c/1.txt - * and 'a/b/c/d/2.txt', the common directory is 'a/b/c/', and this - * will return the length of the string 'a/b/c/', which is 6. - * - * @param one The first path - * @param two The second path - * @return The length of the common directory - */ -extern size_t git_path_common_dirlen(const char *one, const char *two); - -/** - * Make the path relative to the given parent path. - * - * @param path The path to make relative - * @param parent The parent path to make path relative to - * @return 0 if path was made relative, GIT_ENOTFOUND - * if there was not common root between the paths, - * or <0. - */ -extern int git_path_make_relative(git_str *path, const char *parent); - -/** - * Check if the given path contains the given file. - * - * @param dir Directory path that might contain file - * @param file File name to look for in parent - * @return true if file exists, false otherwise. - */ -extern bool git_path_contains_file(git_str *dir, const char *file); - -/** - * Prepend base to unrooted path or just copy path over. - * - * This will optionally return the index into the path where the "root" - * is, either the end of the base directory prefix or the path root. - */ -extern int git_path_join_unrooted( - git_str *path_out, const char *path, const char *base, ssize_t *root_at); - -/** - * Removes multiple occurrences of '/' in a row, squashing them into a - * single '/'. - */ -extern void git_path_squash_slashes(git_str *path); - -/** - * Clean up path, prepending base if it is not already rooted. - */ -extern int git_path_prettify(git_str *path_out, const char *path, const char *base); - -/** - * Clean up path, prepending base if it is not already rooted and - * appending a slash. - */ -extern int git_path_prettify_dir(git_str *path_out, const char *path, const char *base); - -/** - * Get a directory from a path. - * - * If path is a directory, this acts like `git_path_prettify_dir` - * (cleaning up path and appending a '/'). If path is a normal file, - * this prettifies it, then removed the filename a la dirname and - * appends the trailing '/'. If the path does not exist, it is - * treated like a regular filename. - */ -extern int git_path_find_dir(git_str *dir); - -/** - * Resolve relative references within a path. - * - * This eliminates "./" and "../" relative references inside a path, - * as well as condensing multiple slashes into single ones. It will - * not touch the path before the "ceiling" length. - * - * Additionally, this will recognize an "c:/" drive prefix or a "xyz://" URL - * prefix and not touch that part of the path. - */ -extern int git_path_resolve_relative(git_str *path, size_t ceiling); - -/** - * Apply a relative path to base path. - * - * Note that the base path could be a filename or a URL and this - * should still work. The relative path is walked segment by segment - * with three rules: series of slashes will be condensed to a single - * slash, "." will be eaten with no change, and ".." will remove a - * segment from the base path. - */ -extern int git_path_apply_relative(git_str *target, const char *relpath); - -enum { - GIT_PATH_DIR_IGNORE_CASE = (1u << 0), - GIT_PATH_DIR_PRECOMPOSE_UNICODE = (1u << 1), - GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT = (1u << 2), -}; - -/** - * Walk each directory entry, except '.' and '..', calling fn(state). - * - * @param pathbuf Buffer the function reads the initial directory - * path from, and updates with each successive entry's name. - * @param flags Combination of GIT_PATH_DIR flags. - * @param callback Callback for each entry. Passed the `payload` and each - * successive path inside the directory as a full path. This may - * safely append text to the pathbuf if needed. Return non-zero to - * cancel iteration (and return value will be propagated back). - * @param payload Passed to callback as first argument. - * @return 0 on success or error code from OS error or from callback - */ -extern int git_path_direach( - git_str *pathbuf, - uint32_t flags, - int (*callback)(void *payload, git_str *path), - void *payload); - -/** - * Sort function to order two paths - */ -extern int git_path_cmp( - const char *name1, size_t len1, int isdir1, - const char *name2, size_t len2, int isdir2, - int (*compare)(const char *, const char *, size_t)); - -/** - * Invoke callback up path directory by directory until the ceiling is - * reached (inclusive of a final call at the root_path). - * - * Returning anything other than 0 from the callback function - * will stop the iteration and propagate the error to the caller. - * - * @param pathbuf Buffer the function reads the directory from and - * and updates with each successive name. - * @param ceiling Prefix of path at which to stop walking up. If NULL, - * this will walk all the way up to the root. If not a prefix of - * pathbuf, the callback will be invoked a single time on the - * original input path. - * @param callback Function to invoke on each path. Passed the `payload` - * and the buffer containing the current path. The path should not - * be modified in any way. Return non-zero to stop iteration. - * @param payload Passed to fn as the first ath. - */ -extern int git_path_walk_up( - git_str *pathbuf, - const char *ceiling, - int (*callback)(void *payload, const char *path), - void *payload); - - -enum { GIT_PATH_NOTEQUAL = 0, GIT_PATH_EQUAL = 1, GIT_PATH_PREFIX = 2 }; - -/* - * Determines if a path is equal to or potentially a child of another. - * @param parent The possible parent - * @param child The possible child - */ -GIT_INLINE(int) git_path_equal_or_prefixed( - const char *parent, - const char *child, - ssize_t *prefixlen) -{ - const char *p = parent, *c = child; - int lastslash = 0; - - while (*p && *c) { - lastslash = (*p == '/'); - - if (*p++ != *c++) - return GIT_PATH_NOTEQUAL; - } - - if (*p != '\0') - return GIT_PATH_NOTEQUAL; - - if (*c == '\0') { - if (prefixlen) - *prefixlen = p - parent; - - return GIT_PATH_EQUAL; - } - - if (*c == '/' || lastslash) { - if (prefixlen) - *prefixlen = (p - parent) - lastslash; - - return GIT_PATH_PREFIX; - } - - return GIT_PATH_NOTEQUAL; -} - -/* translate errno to libgit2 error code and set error message */ -extern int git_path_set_error( - int errno_value, const char *path, const char *action); - -/* check if non-ascii characters are present in filename */ -extern bool git_path_has_non_ascii(const char *path, size_t pathlen); - -#define GIT_PATH_REPO_ENCODING "UTF-8" - -#ifdef __APPLE__ -#define GIT_PATH_NATIVE_ENCODING "UTF-8-MAC" -#else -#define GIT_PATH_NATIVE_ENCODING "UTF-8" -#endif - -#ifdef GIT_USE_ICONV - -#include - -typedef struct { - iconv_t map; - git_str buf; -} git_path_iconv_t; - -#define GIT_PATH_ICONV_INIT { (iconv_t)-1, GIT_STR_INIT } - -/* Init iconv data for converting decomposed UTF-8 to precomposed */ -extern int git_path_iconv_init_precompose(git_path_iconv_t *ic); - -/* Clear allocated iconv data */ -extern void git_path_iconv_clear(git_path_iconv_t *ic); - -/* - * Rewrite `in` buffer using iconv map if necessary, replacing `in` - * pointer internal iconv buffer if rewrite happened. The `in` pointer - * will be left unchanged if no rewrite was needed. - */ -extern int git_path_iconv(git_path_iconv_t *ic, const char **in, size_t *inlen); - -#endif /* GIT_USE_ICONV */ - -extern bool git_path_does_fs_decompose_unicode(const char *root); - - -typedef struct git_path_diriter git_path_diriter; - -#if defined(GIT_WIN32) && !defined(__MINGW32__) - -struct git_path_diriter -{ - git_win32_path path; - size_t parent_len; - - git_str path_utf8; - size_t parent_utf8_len; - - HANDLE handle; - - unsigned int flags; - - WIN32_FIND_DATAW current; - unsigned int needs_next; -}; - -#define GIT_PATH_DIRITER_INIT { {0}, 0, GIT_STR_INIT, 0, INVALID_HANDLE_VALUE } - -#else - -struct git_path_diriter -{ - git_str path; - size_t parent_len; - - unsigned int flags; - - DIR *dir; - -#ifdef GIT_USE_ICONV - git_path_iconv_t ic; -#endif -}; - -#define GIT_PATH_DIRITER_INIT { GIT_STR_INIT } - -#endif - -/** - * Initialize a directory iterator. - * - * @param diriter Pointer to a diriter structure that will be setup. - * @param path The path that will be iterated over - * @param flags Directory reader flags - * @return 0 or an error code - */ -extern int git_path_diriter_init( - git_path_diriter *diriter, - const char *path, - unsigned int flags); - -/** - * Advance the directory iterator. Will return GIT_ITEROVER when - * the iteration has completed successfully. - * - * @param diriter The directory iterator - * @return 0, GIT_ITEROVER, or an error code - */ -extern int git_path_diriter_next(git_path_diriter *diriter); - -/** - * Returns the file name of the current item in the iterator. - * - * @param out Pointer to store the path in - * @param out_len Pointer to store the length of the path in - * @param diriter The directory iterator - * @return 0 or an error code - */ -extern int git_path_diriter_filename( - const char **out, - size_t *out_len, - git_path_diriter *diriter); - -/** - * Returns the full path of the current item in the iterator; that - * is the current filename plus the path of the directory that the - * iterator was constructed with. - * - * @param out Pointer to store the path in - * @param out_len Pointer to store the length of the path in - * @param diriter The directory iterator - * @return 0 or an error code - */ -extern int git_path_diriter_fullpath( - const char **out, - size_t *out_len, - git_path_diriter *diriter); - -/** - * Performs an `lstat` on the current item in the iterator. - * - * @param out Pointer to store the stat data in - * @param diriter The directory iterator - * @return 0 or an error code - */ -extern int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter); - -/** - * Closes the directory iterator. - * - * @param diriter The directory iterator - */ -extern void git_path_diriter_free(git_path_diriter *diriter); - -/** - * Load all directory entries (except '.' and '..') into a vector. - * - * For cases where `git_path_direach()` is not appropriate, this - * allows you to load the filenames in a directory into a vector - * of strings. That vector can then be sorted, iterated, or whatever. - * Remember to free alloc of the allocated strings when you are done. - * - * @param contents Vector to fill with directory entry names. - * @param path The directory to read from. - * @param prefix_len When inserting entries, the trailing part of path - * will be prefixed after this length. I.e. given path "/a/b" and - * prefix_len 3, the entries will look like "b/e1", "b/e2", etc. - * @param flags Combination of GIT_PATH_DIR flags. - */ -extern int git_path_dirload( - git_vector *contents, - const char *path, - size_t prefix_len, - uint32_t flags); - - -/* Used for paths to repositories on the filesystem */ -extern bool git_path_is_local_file_url(const char *file_url); -extern int git_path_from_url_or_path(git_str *local_path_out, const char *url_or_path); - -/* Flags to determine path validity in `git_path_isvalid` */ -#define GIT_PATH_REJECT_TRAVERSAL (1 << 0) -#define GIT_PATH_REJECT_DOT_GIT (1 << 1) -#define GIT_PATH_REJECT_SLASH (1 << 2) -#define GIT_PATH_REJECT_BACKSLASH (1 << 3) -#define GIT_PATH_REJECT_TRAILING_DOT (1 << 4) -#define GIT_PATH_REJECT_TRAILING_SPACE (1 << 5) -#define GIT_PATH_REJECT_TRAILING_COLON (1 << 6) -#define GIT_PATH_REJECT_DOS_PATHS (1 << 7) -#define GIT_PATH_REJECT_NT_CHARS (1 << 8) -#define GIT_PATH_REJECT_DOT_GIT_LITERAL (1 << 9) -#define GIT_PATH_REJECT_DOT_GIT_HFS (1 << 10) -#define GIT_PATH_REJECT_DOT_GIT_NTFS (1 << 11) - -/* Default path safety for writing files to disk: since we use the - * Win32 "File Namespace" APIs ("\\?\") we need to protect from - * paths that the normal Win32 APIs would not write. - */ -#ifdef GIT_WIN32 -# define GIT_PATH_REJECT_FILESYSTEM_DEFAULTS \ - GIT_PATH_REJECT_TRAVERSAL | \ - GIT_PATH_REJECT_BACKSLASH | \ - GIT_PATH_REJECT_TRAILING_DOT | \ - GIT_PATH_REJECT_TRAILING_SPACE | \ - GIT_PATH_REJECT_TRAILING_COLON | \ - GIT_PATH_REJECT_DOS_PATHS | \ - GIT_PATH_REJECT_NT_CHARS -#else -# define GIT_PATH_REJECT_FILESYSTEM_DEFAULTS \ - GIT_PATH_REJECT_TRAVERSAL -#endif - - /* Paths that should never be written into the working directory. */ +/* Paths that should never be written into the working directory. */ #define GIT_PATH_REJECT_WORKDIR_DEFAULTS \ - GIT_PATH_REJECT_FILESYSTEM_DEFAULTS | GIT_PATH_REJECT_DOT_GIT + GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS | GIT_PATH_REJECT_DOT_GIT /* Paths that should never be written to the index. */ #define GIT_PATH_REJECT_INDEX_DEFAULTS \ - GIT_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT + GIT_FS_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT -/** - * Validate a "bare" git path. This ensures that the given path is legal - * to place in the index or a tree. This should be checked by mechanisms - * like `git_index_add` and `git_treebuilder_insert` when taking user - * data, and by `git_checkout` before constructing on-disk paths. - * - * This will ensure that a git path does not contain any "unsafe" components, - * a '.' or '..' component, or a component that is ".git" (in any case). - * - * (Note: if you take or construct an on-disk path -- a workdir path, - * a path to a git repository or a reference name that could be a loose - * ref -- you should _also_ validate that with `git_path_validate_workdir`.) - * - * `repo` is optional. If specified, it will be used to determine the short - * path name to reject (if `GIT_PATH_REJECT_DOS_SHORTNAME` is specified), - * in addition to the default of "git~1". - */ extern bool git_path_validate( git_repository *repo, const char *path, - uint16_t mode, + uint16_t file_mode, unsigned int flags); -/** - * Validate an on-disk path, taking into account that it will have a - * suffix appended (eg, `.lock`). - */ -GIT_INLINE(int) git_path_validate_filesystem_with_suffix( - const char *path, - size_t path_len, - size_t suffix_len) -{ -#ifdef GIT_WIN32 - size_t path_chars, total_chars; - - path_chars = git_utf8_char_length(path, path_len); - - if (GIT_ADD_SIZET_OVERFLOW(&total_chars, path_chars, suffix_len) || - total_chars > MAX_PATH) { - git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%s'", path); - return -1; - } - return 0; -#else - GIT_UNUSED(path); - GIT_UNUSED(path_len); - GIT_UNUSED(suffix_len); - return 0; -#endif -} - -/** - * Validate an path on the filesystem. This ensures that the given - * path is valid for the operating system/platform; for example, this - * will ensure that the given absolute path is smaller than MAX_PATH on - * Windows. - * - * For paths within the working directory, you should use ensure that - * `core.longpaths` is obeyed. Use `git_path_validate_workdir`. - */ -GIT_INLINE(int) git_path_validate_filesystem( - const char *path, - size_t path_len) -{ - return git_path_validate_filesystem_with_suffix(path, path_len, 0); -} - -/** - * Validate a path relative to the repo's worktree. This ensures that - * the given working tree path is valid for the operating system/platform. - * This will ensure that an absolute path is smaller than MAX_PATH on - * Windows, while keeping `core.longpaths` configuration settings in mind. - * - * This should be checked by mechamisms like `git_checkout` after - * contructing on-disk paths and before trying to write them. - * - * If the repository is null, no repository configuration is applied. - */ -extern int git_path_validate_workdir( - git_repository *repo, - const char *path); -extern int git_path_validate_workdir_with_len( - git_repository *repo, - const char *path, - size_t path_len); -extern int git_path_validate_workdir_buf( - git_repository *repo, - git_str *buf); - -/** - * Convert any backslashes into slashes - */ -int git_path_normalize_slashes(git_str *out, const char *path); - -bool git_path_supports_symlinks(const char *dir); - -/** - * Validate a system file's ownership - * - * Verify that the file in question is owned by an administrator or system - * account, or at least by the current user. - * - * This function returns 0 if successful. If the file is not owned by any of - * these, or any other if there have been problems determining the file - * ownership, it returns -1. - */ -int git_path_validate_system_file_ownership(const char *path); - #endif diff --git a/src/posix.c b/src/posix.c index c40134824a4..b1f85dc9412 100644 --- a/src/posix.c +++ b/src/posix.c @@ -7,7 +7,7 @@ #include "posix.h" -#include "path.h" +#include "fs_path.h" #include #include @@ -144,8 +144,8 @@ int p_getcwd(char *buffer_out, size_t size) if (cwd_buffer == NULL) return -1; - git_path_mkposix(buffer_out); - git_path_string_to_dir(buffer_out, size); /* append trailing slash */ + git_fs_path_mkposix(buffer_out); + git_fs_path_string_to_dir(buffer_out, size); /* append trailing slash */ return 0; } diff --git a/src/rebase.c b/src/rebase.c index 302fc81fc20..26b03b38c8a 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -97,7 +97,7 @@ static int rebase_state_type( if (git_str_joinpath(&path, repo->gitdir, REBASE_APPLY_DIR) < 0) return -1; - if (git_path_isdir(git_str_cstr(&path))) { + if (git_fs_path_isdir(git_str_cstr(&path))) { type = GIT_REBASE_APPLY; goto done; } @@ -106,7 +106,7 @@ static int rebase_state_type( if (git_str_joinpath(&path, repo->gitdir, REBASE_MERGE_DIR) < 0) return -1; - if (git_path_isdir(git_str_cstr(&path))) { + if (git_fs_path_isdir(git_str_cstr(&path))) { type = GIT_REBASE_MERGE; goto done; } @@ -340,7 +340,7 @@ int git_rebase_open( if ((error = git_str_joinpath(&path, path.ptr, ORIG_HEAD_FILE)) < 0) goto done; - if (!git_path_isfile(path.ptr)) { + if (!git_fs_path_isfile(path.ptr)) { /* Previous versions of git.git used 'head' here; support that. */ git_str_truncate(&path, state_path_len); @@ -404,7 +404,7 @@ static int rebase_cleanup(git_rebase *rebase) if (!rebase || rebase->inmemory) return 0; - return git_path_isdir(rebase->state_path) ? + return git_fs_path_isdir(rebase->state_path) ? git_futils_rmdir_r(rebase->state_path, NULL, GIT_RMDIR_REMOVE_FILES) : 0; } diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 37eb85ecc4d..39dc16e9d8f 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -18,6 +18,7 @@ #include "sortedcache.h" #include "signature.h" #include "wildmatch.h" +#include "path.h" #include #include @@ -76,7 +77,7 @@ GIT_INLINE(int) loose_path( if (git_str_joinpath(out, base, refname) < 0) return -1; - return git_path_validate_filesystem_with_suffix(out->ptr, out->size, + return git_fs_path_validate_filesystem_with_suffix(out->ptr, out->size, CONST_STRLEN(".lock")); } @@ -307,8 +308,8 @@ static int _dirent_loose_load(void *payload, git_str *full_path) if (git__suffixcmp(full_path->ptr, ".lock") == 0) return 0; - if (git_path_isdir(full_path->ptr)) { - int error = git_path_direach( + if (git_fs_path_isdir(full_path->ptr)) { + int error = git_fs_path_direach( full_path, backend->direach_flags, _dirent_loose_load, backend); /* Race with the filesystem, ignore it */ if (error == GIT_ENOTFOUND) { @@ -343,7 +344,7 @@ static int packed_loadloose(refdb_fs_backend *backend) * This will overwrite any old packed entries with their * updated loose versions */ - error = git_path_direach( + error = git_fs_path_direach( &refs_path, backend->direach_flags, _dirent_loose_load, backend); git_str_dispose(&refs_path); @@ -367,7 +368,7 @@ static int refdb_fs_backend__exists( if ((error = loose_path(&ref_path, backend->gitpath, ref_name)) < 0) goto out; - if (git_path_isfile(ref_path.ptr)) { + if (git_fs_path_isfile(ref_path.ptr)) { *exists = 1; goto out; } @@ -817,7 +818,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char * GIT_ASSERT_ARG(backend); GIT_ASSERT_ARG(name); - if (!git_path_validate(backend->repo, name, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) { + if (!git_path_validate(backend->repo, name, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { git_error_set(GIT_ERROR_INVALID, "invalid reference name '%s'", name); return GIT_EINVALIDSPEC; } @@ -1344,10 +1345,10 @@ static int refdb_fs_backend__prune_refs( if ((error = git_str_sets(&relative_path, ref_name)) < 0) goto cleanup; - git_path_squash_slashes(&relative_path); - if ((commonlen = git_path_common_dirlen("refs/heads/", git_str_cstr(&relative_path))) == strlen("refs/heads/") || - (commonlen = git_path_common_dirlen("refs/tags/", git_str_cstr(&relative_path))) == strlen("refs/tags/") || - (commonlen = git_path_common_dirlen("refs/remotes/", git_str_cstr(&relative_path))) == strlen("refs/remotes/")) { + git_fs_path_squash_slashes(&relative_path); + if ((commonlen = git_fs_path_common_dirlen("refs/heads/", git_str_cstr(&relative_path))) == strlen("refs/heads/") || + (commonlen = git_fs_path_common_dirlen("refs/tags/", git_str_cstr(&relative_path))) == strlen("refs/tags/") || + (commonlen = git_fs_path_common_dirlen("refs/remotes/", git_str_cstr(&relative_path))) == strlen("refs/remotes/")) { git_str_truncate(&relative_path, commonlen); @@ -1361,7 +1362,7 @@ static int refdb_fs_backend__prune_refs( git_str_cstr(&relative_path)); if (!error) - error = git_path_validate_filesystem(base_path.ptr, base_path.size); + error = git_fs_path_validate_filesystem(base_path.ptr, base_path.size); if (error < 0) goto cleanup; @@ -1741,7 +1742,7 @@ static int has_reflog(git_repository *repo, const char *name) if (reflog_path(&path, repo, name) < 0) goto cleanup; - ret = git_path_isfile(git_str_cstr(&path)); + ret = git_fs_path_isfile(git_str_cstr(&path)); cleanup: git_str_dispose(&path); @@ -1856,7 +1857,7 @@ static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char repo = backend->repo; - if (!git_path_validate(backend->repo, refname, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) { + if (!git_path_validate(backend->repo, refname, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { git_error_set(GIT_ERROR_INVALID, "invalid reference name '%s'", refname); return GIT_EINVALIDSPEC; } @@ -1864,7 +1865,7 @@ static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char if (reflog_path(&log_path, repo, refname) < 0) return -1; - if (!git_path_isfile(git_str_cstr(&log_path))) { + if (!git_fs_path_isfile(git_str_cstr(&log_path))) { git_error_set(GIT_ERROR_INVALID, "log file for reference '%s' doesn't exist", refname); error = -1; @@ -1973,11 +1974,11 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co /* If the new branch matches part of the namespace of a previously deleted branch, * there maybe an obsolete/unused directory (or directory hierarchy) in the way. */ - if (git_path_isdir(git_str_cstr(&path))) { + if (git_fs_path_isdir(git_str_cstr(&path))) { if ((error = git_futils_rmdir_r(git_str_cstr(&path), NULL, GIT_RMDIR_SKIP_NONEMPTY)) < 0) { if (error == GIT_ENOTFOUND) error = 0; - } else if (git_path_isdir(git_str_cstr(&path))) { + } else if (git_fs_path_isdir(git_str_cstr(&path))) { git_error_set(GIT_ERROR_REFERENCE, "cannot create reflog at '%s', there are reflogs beneath that folder", ref->name); error = GIT_EDIRECTORY; @@ -2031,7 +2032,7 @@ static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_ if ((error = loose_path(&new_path, git_str_cstr(&temp_path), git_str_cstr(&normalized))) < 0) return error; - if (!git_path_exists(git_str_cstr(&old_path))) { + if (!git_fs_path_exists(git_str_cstr(&old_path))) { error = GIT_ENOTFOUND; goto cleanup; } @@ -2059,7 +2060,7 @@ static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_ goto cleanup; } - if (git_path_isdir(git_str_cstr(&new_path)) && + if (git_fs_path_isdir(git_str_cstr(&new_path)) && (git_futils_rmdir_r(git_str_cstr(&new_path), NULL, GIT_RMDIR_SKIP_NONEMPTY) < 0)) { error = -1; goto cleanup; @@ -2096,7 +2097,7 @@ static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name if ((error = reflog_path(&path, backend->repo, name)) < 0) goto out; - if (!git_path_exists(path.ptr)) + if (!git_fs_path_exists(path.ptr)) goto out; if ((error = p_unlink(path.ptr)) < 0) @@ -2150,11 +2151,11 @@ int git_refdb_backend_fs( if (!git_repository__configmap_lookup(&t, backend->repo, GIT_CONFIGMAP_IGNORECASE) && t) { backend->iterator_flags |= GIT_ITERATOR_IGNORE_CASE; - backend->direach_flags |= GIT_PATH_DIR_IGNORE_CASE; + backend->direach_flags |= GIT_FS_PATH_DIR_IGNORE_CASE; } if (!git_repository__configmap_lookup(&t, backend->repo, GIT_CONFIGMAP_PRECOMPOSE) && t) { backend->iterator_flags |= GIT_ITERATOR_PRECOMPOSE_UNICODE; - backend->direach_flags |= GIT_PATH_DIR_PRECOMPOSE_UNICODE; + backend->direach_flags |= GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE; } if ((!git_repository__configmap_lookup(&t, backend->repo, GIT_CONFIGMAP_FSYNCOBJECTFILES) && t) || git_repository__fsync_gitdir) diff --git a/src/refs.c b/src/refs.c index 0ac455d2481..5c875b95b23 100644 --- a/src/refs.c +++ b/src/refs.c @@ -902,7 +902,7 @@ int git_reference__normalize_name( bool validate = (flags & GIT_REFERENCE_FORMAT__VALIDATION_DISABLE) == 0; #ifdef GIT_USE_ICONV - git_path_iconv_t ic = GIT_PATH_ICONV_INIT; + git_fs_path_iconv_t ic = GIT_PATH_ICONV_INIT; #endif GIT_ASSERT_ARG(name); @@ -919,8 +919,8 @@ int git_reference__normalize_name( #ifdef GIT_USE_ICONV if ((flags & GIT_REFERENCE_FORMAT__PRECOMPOSE_UNICODE) != 0) { size_t namelen = strlen(current); - if ((error = git_path_iconv_init_precompose(&ic)) < 0 || - (error = git_path_iconv(&ic, ¤t, &namelen)) < 0) + if ((error = git_fs_path_iconv_init_precompose(&ic)) < 0 || + (error = git_fs_path_iconv(&ic, ¤t, &namelen)) < 0) goto cleanup; error = GIT_EINVALIDSPEC; } @@ -1011,7 +1011,7 @@ int git_reference__normalize_name( git_str_dispose(buf); #ifdef GIT_USE_ICONV - git_path_iconv_clear(&ic); + git_fs_path_iconv_clear(&ic); #endif return error; diff --git a/src/repository.c b/src/repository.c index 29684e463db..2f7ae9b3d6f 100644 --- a/src/repository.c +++ b/src/repository.c @@ -197,9 +197,9 @@ static int lookup_commondir(bool *separate, git_str *commondir, git_str *reposit * If there's no commondir file, the repository path is the * common path, but it needs a trailing slash. */ - if (!git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) { + if (!git_fs_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) { if ((error = git_str_set(commondir, repository_path->ptr, repository_path->size)) == 0) - error = git_path_to_dir(commondir); + error = git_fs_path_to_dir(commondir); *separate = false; goto done; @@ -212,7 +212,7 @@ static int lookup_commondir(bool *separate, git_str *commondir, git_str *reposit goto done; git_str_rtrim(&common_link); - if (git_path_is_relative(common_link.ptr)) { + if (git_fs_path_is_relative(common_link.ptr)) { if ((error = git_str_joinpath(commondir, repository_path->ptr, common_link.ptr)) < 0) goto done; } else { @@ -222,7 +222,7 @@ static int lookup_commondir(bool *separate, git_str *commondir, git_str *reposit git_str_dispose(&common_link); /* Make sure the commondir path always has a trailing slash */ - error = git_path_prettify_dir(commondir, commondir->ptr, NULL); + error = git_fs_path_prettify_dir(commondir, commondir->ptr, NULL); done: return error; @@ -240,7 +240,7 @@ GIT_INLINE(int) validate_repo_path(git_str *path) CONST_STRLEN("objects/pack/pack-.pack.lock") + GIT_OID_HEXSZ; - return git_path_validate_filesystem_with_suffix( + return git_fs_path_validate_filesystem_with_suffix( path->ptr, path->size, suffix_len); } @@ -260,13 +260,13 @@ static int is_valid_repository_path(bool *out, git_str *repository_path, git_str return error; /* Ensure HEAD file exists */ - if (git_path_contains_file(repository_path, GIT_HEAD_FILE) == false) + if (git_fs_path_contains_file(repository_path, GIT_HEAD_FILE) == false) return 0; /* Check files in common dir */ - if (git_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false) + if (git_fs_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false) return 0; - if (git_path_contains_dir(common_path, GIT_REFS_DIR) == false) + if (git_fs_path_contains_dir(common_path, GIT_REFS_DIR) == false) return 0; /* Ensure the repo (and commondir) are valid paths */ @@ -357,8 +357,8 @@ static int load_workdir(git_repository *repo, git_config *config, git_str *paren git_str_attach(&worktree, gitlink, 0); - if ((git_path_dirname_r(&worktree, worktree.ptr)) < 0 || - git_path_to_dir(&worktree) < 0) { + if ((git_fs_path_dirname_r(&worktree, worktree.ptr)) < 0 || + git_fs_path_to_dir(&worktree) < 0) { error = -1; goto cleanup; } @@ -366,17 +366,17 @@ static int load_workdir(git_repository *repo, git_config *config, git_str *paren repo->workdir = git_str_detach(&worktree); } else if (ce && ce->value) { - if ((error = git_path_prettify_dir( + if ((error = git_fs_path_prettify_dir( &worktree, ce->value, repo->gitdir)) < 0) goto cleanup; repo->workdir = git_str_detach(&worktree); } - else if (parent_path && git_path_isdir(parent_path->ptr)) + else if (parent_path && git_fs_path_isdir(parent_path->ptr)) repo->workdir = git_str_detach(parent_path); else { - if (git_path_dirname_r(&worktree, repo->gitdir) < 0 || - git_path_to_dir(&worktree) < 0) { + if (git_fs_path_dirname_r(&worktree, repo->gitdir) < 0 || + git_fs_path_to_dir(&worktree) < 0) { error = -1; goto cleanup; } @@ -410,7 +410,7 @@ static size_t find_ceiling_dir_offset( GIT_ASSERT_ARG(path); - min_len = (size_t)(git_path_root(path) + 1); + min_len = (size_t)(git_fs_path_root(path) + 1); if (ceiling_directories == NULL || min_len == 0) return min_len; @@ -419,7 +419,7 @@ static size_t find_ceiling_dir_offset( for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++); len = sep - ceil; - if (len == 0 || len >= sizeof(buf) || git_path_root(ceil) == -1) + if (len == 0 || len >= sizeof(buf) || git_fs_path_root(ceil) == -1) continue; strncpy(buf, ceil, len); @@ -462,7 +462,7 @@ static int read_gitfile(git_str *path_out, const char *file_path) git_str_rtrim(&file); /* apparently on Windows, some people use backslashes in paths */ - git_path_mkposix(file.ptr); + git_fs_path_mkposix(file.ptr); if (git_str_len(&file) <= prefix_len || memcmp(git_str_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0) @@ -471,11 +471,11 @@ static int read_gitfile(git_str *path_out, const char *file_path) "the `.git` file at '%s' is malformed", file_path); error = -1; } - else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) { + else if ((error = git_fs_path_dirname_r(path_out, file_path)) >= 0) { const char *gitlink = git_str_cstr(&file) + prefix_len; while (*gitlink && git__isspace(*gitlink)) gitlink++; - error = git_path_prettify_dir( + error = git_fs_path_prettify_dir( path_out, gitlink, git_str_cstr(path_out)); } @@ -504,7 +504,7 @@ static int find_repo( git_str_clear(gitdir_path); - error = git_path_prettify(&path, start_path, NULL); + error = git_fs_path_prettify(&path, start_path, NULL); if (error < 0) return error; @@ -545,7 +545,7 @@ static int find_repo( goto out; if (is_valid) { - if ((error = git_path_to_dir(&path)) < 0 || + if ((error = git_fs_path_to_dir(&path)) < 0 || (error = git_str_set(gitdir_path, path.ptr, path.size)) < 0) goto out; @@ -578,7 +578,7 @@ static int find_repo( /* Move up one directory. If we're in_dot_git, we'll search the * parent itself next. If we're !in_dot_git, we'll search .git * in the parent directory next (added at the top of the loop). */ - if ((error = git_path_dirname_r(&path, path.ptr)) < 0) + if ((error = git_fs_path_dirname_r(&path, path.ptr)) < 0) goto out; /* Once we've checked the directory (and .git if applicable), @@ -595,8 +595,8 @@ static int find_repo( if (workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) { if (!git_str_len(gitdir_path)) git_str_clear(workdir_path); - else if ((error = git_path_dirname_r(workdir_path, path.ptr)) < 0 || - (error = git_path_to_dir(workdir_path)) < 0) + else if ((error = git_fs_path_dirname_r(workdir_path, path.ptr)) < 0 || + (error = git_fs_path_to_dir(workdir_path)) < 0) goto out; } @@ -624,7 +624,7 @@ int git_repository_open_bare( bool is_valid; int error; - if ((error = git_path_prettify_dir(&path, bare_path, NULL)) < 0 || + if ((error = git_fs_path_prettify_dir(&path, bare_path, NULL)) < 0 || (error = is_valid_repository_path(&is_valid, &path, &common_path)) < 0) return error; @@ -838,7 +838,7 @@ static int repo_is_worktree(unsigned *out, const git_repository *repo) /* A 'gitdir' file inside a git directory is currently * only used when the repository is a working tree. */ - *out = !!git_path_exists(gitdir_link.ptr); + *out = !!git_fs_path_exists(gitdir_link.ptr); git_str_dispose(&gitdir_link); return error; @@ -1600,7 +1600,7 @@ static bool is_filesystem_case_insensitive(const char *gitdir_path) int is_insensitive = -1; if (!git_str_joinpath(&path, gitdir_path, "CoNfIg")) - is_insensitive = git_path_exists(git_str_cstr(&path)); + is_insensitive = git_fs_path_exists(git_str_cstr(&path)); git_str_dispose(&path); return is_insensitive; @@ -1639,7 +1639,7 @@ static bool are_symlinks_supported(const char *wd_path) goto done; #endif - if (!(symlinks = git_path_supports_symlinks(wd_path))) + if (!(symlinks = git_fs_path_supports_symlinks(wd_path))) goto done; done: @@ -1683,7 +1683,7 @@ static int repo_local_config( cfg_path = git_str_cstr(config_dir); /* make LOCAL config if missing */ - if (!git_path_isfile(cfg_path) && + if (!git_fs_path_isfile(cfg_path) && (error = create_empty_file(cfg_path, GIT_CONFIG_FILE_MODE)) < 0) return error; @@ -1741,7 +1741,7 @@ static int repo_init_fs_configs( #ifdef GIT_USE_ICONV if ((error = git_config_set_bool( cfg, "core.precomposeunicode", - git_path_does_fs_decompose_unicode(work_dir))) < 0) + git_fs_path_does_decompose_unicode(work_dir))) < 0) return error; /* on non-iconv platforms, don't even set core.precomposeunicode */ #endif @@ -1790,7 +1790,7 @@ static int repo_init_config( goto cleanup; if ((flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK)) - if ((error = git_path_make_relative(&worktree_path, repo_dir)) < 0) + if ((error = git_fs_path_make_relative(&worktree_path, repo_dir)) < 0) goto cleanup; SET_REPO_CONFIG(string, "core.worktree", worktree_path.ptr); @@ -1907,8 +1907,8 @@ static int repo_write_gitlink( git_str path_to_repo = GIT_STR_INIT; struct stat st; - git_path_dirname_r(&buf, to_repo); - git_path_to_dir(&buf); + git_fs_path_dirname_r(&buf, to_repo); + git_fs_path_to_dir(&buf); if (git_str_oom(&buf)) return -1; @@ -1935,7 +1935,7 @@ static int repo_write_gitlink( error = git_str_sets(&path_to_repo, to_repo); if (!error && use_relative_path) - error = git_path_make_relative(&path_to_repo, in_dir); + error = git_fs_path_make_relative(&path_to_repo, in_dir); if (!error) error = git_str_join(&buf, ' ', GIT_FILE_CONTENT_PREFIX, path_to_repo.ptr); @@ -2132,11 +2132,11 @@ static int repo_init_directories( if (!is_bare) { if (opts->workdir_path) { - if (git_path_join_unrooted( + if (git_fs_path_join_unrooted( wd_path, opts->workdir_path, repo_path->ptr, NULL) < 0) return -1; } else if (has_dotgit) { - if (git_path_dirname_r(wd_path, repo_path->ptr) < 0) + if (git_fs_path_dirname_r(wd_path, repo_path->ptr) < 0) return -1; } else { git_error_set(GIT_ERROR_REPOSITORY, "cannot pick working directory" @@ -2144,7 +2144,7 @@ static int repo_init_directories( return -1; } - if (git_path_to_dir(wd_path) < 0) + if (git_fs_path_to_dir(wd_path) < 0) return -1; } else { git_str_clear(wd_path); @@ -2204,10 +2204,10 @@ static int repo_init_directories( /* prettify both directories now that they are created */ if (!error) { - error = git_path_prettify_dir(repo_path, repo_path->ptr, NULL); + error = git_fs_path_prettify_dir(repo_path, repo_path->ptr, NULL); if (!error && wd_path->size > 0) - error = git_path_prettify_dir(wd_path, wd_path->ptr, NULL); + error = git_fs_path_prettify_dir(wd_path, wd_path->ptr, NULL); } return error; @@ -2227,7 +2227,7 @@ static int repo_init_head(const char *repo_dir, const char *given) * A template may have set a HEAD; use that unless it's been * overridden by the caller's given initial head setting. */ - if (git_path_exists(head_path.ptr) && !given) + if (git_fs_path_exists(head_path.ptr) && !given) goto out; if (given) { @@ -2628,7 +2628,7 @@ int git_repository__item_path( } if (items[item].directory) { - if (git_path_to_dir(out) < 0) + if (git_fs_path_to_dir(out) < 0) return -1; } @@ -2662,7 +2662,7 @@ int git_repository_workdir_path( } if (!(error = git_str_joinpath(out, repo->workdir, path))) - error = git_path_validate_workdir_buf(repo, out); + error = git_fs_path_validate_workdir_buf(repo, out); return error; } @@ -2682,7 +2682,7 @@ int git_repository_set_workdir( GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(workdir); - if (git_path_prettify_dir(&path, workdir, NULL) < 0) + if (git_fs_path_prettify_dir(&path, workdir, NULL) < 0) return -1; if (repo->workdir && strcmp(repo->workdir, path.ptr) == 0) @@ -2857,8 +2857,8 @@ int git_repository_hashfile( GIT_ASSERT_ARG(path); GIT_ASSERT_ARG(repo); - if ((error = git_path_join_unrooted(&full_path, path, workdir, NULL)) < 0 || - (error = git_path_validate_workdir_buf(repo, &full_path)) < 0) + if ((error = git_fs_path_join_unrooted(&full_path, path, workdir, NULL)) < 0 || + (error = git_fs_path_validate_workdir_buf(repo, &full_path)) < 0) return error; /* @@ -3084,29 +3084,29 @@ int git_repository_state(git_repository *repo) if (git_str_puts(&repo_path, repo->gitdir) < 0) return -1; - if (git_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE)) + if (git_fs_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE)) state = GIT_REPOSITORY_STATE_REBASE_INTERACTIVE; - else if (git_path_contains_dir(&repo_path, GIT_REBASE_MERGE_DIR)) + else if (git_fs_path_contains_dir(&repo_path, GIT_REBASE_MERGE_DIR)) state = GIT_REPOSITORY_STATE_REBASE_MERGE; - else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_REBASING_FILE)) + else if (git_fs_path_contains_file(&repo_path, GIT_REBASE_APPLY_REBASING_FILE)) state = GIT_REPOSITORY_STATE_REBASE; - else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_APPLYING_FILE)) + else if (git_fs_path_contains_file(&repo_path, GIT_REBASE_APPLY_APPLYING_FILE)) state = GIT_REPOSITORY_STATE_APPLY_MAILBOX; - else if (git_path_contains_dir(&repo_path, GIT_REBASE_APPLY_DIR)) + else if (git_fs_path_contains_dir(&repo_path, GIT_REBASE_APPLY_DIR)) state = GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE; - else if (git_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE)) + else if (git_fs_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE)) state = GIT_REPOSITORY_STATE_MERGE; - else if (git_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE)) { + else if (git_fs_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE)) { state = GIT_REPOSITORY_STATE_REVERT; - if (git_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) { + if (git_fs_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) { state = GIT_REPOSITORY_STATE_REVERT_SEQUENCE; } - } else if (git_path_contains_file(&repo_path, GIT_CHERRYPICK_HEAD_FILE)) { + } else if (git_fs_path_contains_file(&repo_path, GIT_CHERRYPICK_HEAD_FILE)) { state = GIT_REPOSITORY_STATE_CHERRYPICK; - if (git_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) { + if (git_fs_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) { state = GIT_REPOSITORY_STATE_CHERRYPICK_SEQUENCE; } - } else if (git_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE)) + } else if (git_fs_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE)) state = GIT_REPOSITORY_STATE_BISECT; git_str_dispose(&repo_path); @@ -3128,9 +3128,9 @@ int git_repository__cleanup_files( path = git_str_cstr(&buf); - if (git_path_isfile(path)) { + if (git_fs_path_isfile(path)) { error = p_unlink(path); - } else if (git_path_isdir(path)) { + } else if (git_fs_path_isdir(path)) { error = git_futils_rmdir_r(path, NULL, GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS); } @@ -3170,7 +3170,7 @@ int git_repository_is_shallow(git_repository *repo) if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0) return error; - error = git_path_lstat(path.ptr, &st); + error = git_fs_path_lstat(path.ptr, &st); git_str_dispose(&path); if (error == GIT_ENOTFOUND) { diff --git a/src/submodule.c b/src/submodule.c index b0f7294be8b..727b6c6e471 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -16,11 +16,12 @@ #include "repository.h" #include "tree.h" #include "iterator.h" -#include "path.h" +#include "fs_path.h" #include "str.h" #include "index.h" #include "worktree.h" #include "clone.h" +#include "path.h" #include "git2/config.h" #include "git2/sys/config.h" @@ -149,7 +150,7 @@ static int is_path_occupied(bool *occupied, git_repository *repo, const char *pa if ((error = git_str_sets(&dir, path)) < 0) goto out; - if ((error = git_path_to_dir(&dir)) < 0) + if ((error = git_fs_path_to_dir(&dir)) < 0) goto out; if ((error = git_index_find_prefix(NULL, index, dir.ptr)) != GIT_ENOTFOUND) { @@ -385,10 +386,10 @@ int git_submodule__lookup_with_cache( if (git_str_join3(&path, '/', git_repository_workdir(repo), name, DOT_GIT) < 0 || - git_path_validate_workdir_buf(NULL, &path) < 0) + git_fs_path_validate_workdir_buf(NULL, &path) < 0) return -1; - if (git_path_exists(path.ptr)) + if (git_fs_path_exists(path.ptr)) error = GIT_EEXISTS; git_str_dispose(&path); @@ -412,17 +413,17 @@ int git_submodule_name_is_valid(git_repository *repo, const char *name, int flag int error, isvalid; if (flags == 0) - flags = GIT_PATH_REJECT_FILESYSTEM_DEFAULTS; + flags = GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS; /* Avoid allocating a new string if we can avoid it */ if (strchr(name, '\\') != NULL) { - if ((error = git_path_normalize_slashes(&buf, name)) < 0) + if ((error = git_fs_path_normalize_slashes(&buf, name)) < 0) return error; } else { git_str_attach_notowned(&buf, name, strlen(name)); } - isvalid = git_path_validate(repo, buf.ptr, 0, flags); + isvalid = git_path_validate(repo, buf.ptr, 0, flags); git_str_dispose(&buf); return isvalid; @@ -743,16 +744,16 @@ static int git_submodule__resolve_url( /* We do this in all platforms in case someone on Windows created the .gitmodules */ if (strchr(url, '\\')) { - if ((error = git_path_normalize_slashes(&normalized, url)) < 0) + if ((error = git_fs_path_normalize_slashes(&normalized, url)) < 0) return error; url = normalized.ptr; } - if (git_path_is_relative(url)) { + if (git_fs_path_is_relative(url)) { if (!(error = get_url_base(out, repo))) - error = git_path_apply_relative(out, url); + error = git_fs_path_apply_relative(out, url); } else if (strchr(url, ':') != NULL || url[0] == '/') { error = git_str_sets(out, url); } else { @@ -805,7 +806,7 @@ int git_submodule_add_setup( if (git__prefixcmp(path, git_repository_workdir(repo)) == 0) path += strlen(git_repository_workdir(repo)); - if (git_path_root(path) >= 0) { + if (git_fs_path_root(path) >= 0) { git_error_set(GIT_ERROR_SUBMODULE, "submodule path must be a relative path"); error = -1; goto cleanup; @@ -846,8 +847,8 @@ int git_submodule_add_setup( /* if the repo does not already exist, then init a new repo and add it. * Otherwise, just add the existing repo. */ - if (!(git_path_exists(name.ptr) && - git_path_contains(&name, DOT_GIT))) { + if (!(git_fs_path_exists(name.ptr) && + git_fs_path_contains(&name, DOT_GIT))) { /* resolve the actual URL to use */ if ((error = git_submodule__resolve_url(&real_url, repo, url)) < 0) @@ -1568,13 +1569,13 @@ static int git_submodule__open( sm->flags |= GIT_SUBMODULE_STATUS__WD_OID_VALID; else git_error_clear(); - } else if (git_path_exists(path.ptr)) { + } else if (git_fs_path_exists(path.ptr)) { sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED | GIT_SUBMODULE_STATUS_IN_WD; } else { git_str_rtruncate_at_char(&path, '/'); /* remove "/.git" */ - if (git_path_isdir(path.ptr)) + if (git_fs_path_isdir(path.ptr)) sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED; } @@ -2105,10 +2106,10 @@ static int submodule_load_from_wd_lite(git_submodule *sm) if (git_repository_workdir_path(&path, sm->repo, sm->path) < 0) return -1; - if (git_path_isdir(path.ptr)) + if (git_fs_path_isdir(path.ptr)) sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED; - if (git_path_contains(&path, DOT_GIT)) + if (git_fs_path_contains(&path, DOT_GIT)) sm->flags |= GIT_SUBMODULE_STATUS_IN_WD; git_str_dispose(&path); @@ -2160,7 +2161,7 @@ static git_config_backend *open_gitmodules( if (git_repository_workdir_path(&path, repo, GIT_MODULES_FILE) != 0) return NULL; - if (okay_to_create || git_path_isfile(path.ptr)) { + if (okay_to_create || git_fs_path_isfile(path.ptr)) { /* git_config_backend_from_file should only fail if OOM */ if (git_config_backend_from_file(&mods, path.ptr) < 0) mods = NULL; diff --git a/src/sysdir.c b/src/sysdir.c index 457d7f8a8f5..84d212e01f1 100644 --- a/src/sysdir.c +++ b/src/sysdir.c @@ -9,7 +9,7 @@ #include "runtime.h" #include "str.h" -#include "path.h" +#include "fs_path.h" #include #if GIT_WIN32 #include "win32/findfile.h" @@ -291,7 +291,7 @@ static int git_sysdir_find_in_dirlist( if (name) GIT_ERROR_CHECK_ERROR(git_str_joinpath(path, path->ptr, name)); - if (git_path_exists(path->ptr)) + if (git_fs_path_exists(path->ptr)) return 0; } diff --git a/src/transport.c b/src/transport.c index fa1d35fcef2..640ccacaee3 100644 --- a/src/transport.c +++ b/src/transport.c @@ -12,7 +12,7 @@ #include "git2/net.h" #include "git2/transport.h" #include "git2/sys/transport.h" -#include "path.h" +#include "fs_path.h" typedef struct transport_definition { char *prefix; @@ -82,7 +82,7 @@ static int transport_find_fn( * to a directory and if so assume local path, else assume SSH */ /* Check to see if the path points to a file on the local file system */ - if (!definition && git_path_exists(url) && git_path_isdir(url)) + if (!definition && git_fs_path_exists(url) && git_fs_path_isdir(url)) definition = &local_transport_definition; #endif @@ -98,7 +98,7 @@ static int transport_find_fn( #ifndef GIT_WIN32 /* Check to see if the path points to a file on the local file system */ - if (!definition && git_path_exists(url) && git_path_isdir(url)) + if (!definition && git_fs_path_exists(url) && git_fs_path_isdir(url)) definition = &local_transport_definition; #endif diff --git a/src/transports/local.c b/src/transports/local.c index 0656ea592df..0983914b1af 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -10,7 +10,7 @@ #include "pack-objects.h" #include "refs.h" #include "posix.h" -#include "path.h" +#include "fs_path.h" #include "repository.h" #include "odb.h" #include "push.h" @@ -226,7 +226,7 @@ static int local_connect( t->flags = flags; /* 'url' may be a url or path; convert to a path */ - if ((error = git_path_from_url_or_path(&buf, url)) < 0) { + if ((error = git_fs_path_from_url_or_path(&buf, url)) < 0) { git_str_dispose(&buf); return error; } @@ -352,7 +352,7 @@ static int local_push( GIT_UNUSED(cbs); /* 'push->remote->url' may be a url or path; convert to a path */ - if ((error = git_path_from_url_or_path(&buf, push->remote->url)) < 0) { + if ((error = git_fs_path_from_url_or_path(&buf, push->remote->url)) < 0) { git_str_dispose(&buf); return error; } diff --git a/src/tree.c b/src/tree.c index c1e39158dbf..256e720809d 100644 --- a/src/tree.c +++ b/src/tree.c @@ -13,6 +13,7 @@ #include "futils.h" #include "tree-cache.h" #include "index.h" +#include "path.h" #define DEFAULT_TREE_SIZE 16 #define MAX_FILEMODE_BYTES 6 @@ -55,7 +56,7 @@ static int valid_entry_name(git_repository *repo, const char *filename) { return *filename != '\0' && git_path_validate(repo, filename, 0, - GIT_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT | GIT_PATH_REJECT_SLASH); + GIT_FS_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT | GIT_FS_PATH_REJECT_SLASH); } static int entry_sort_cmp(const void *a, const void *b) @@ -63,7 +64,7 @@ static int entry_sort_cmp(const void *a, const void *b) const git_tree_entry *e1 = (const git_tree_entry *)a; const git_tree_entry *e2 = (const git_tree_entry *)b; - return git_path_cmp( + return git_fs_path_cmp( e1->filename, e1->filename_len, git_tree_entry__is_tree(e1), e2->filename, e2->filename_len, git_tree_entry__is_tree(e2), git__strncmp); @@ -1171,7 +1172,7 @@ int git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseli /* Figure out how much we need to change from the previous tree */ if (last_update) - common_prefix = git_path_common_dirlen(last_update->path, update->path); + common_prefix = git_fs_path_common_dirlen(last_update->path, update->path); /* * The entries are sorted, so when we find we're no @@ -1233,7 +1234,7 @@ int git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseli { /* Make sure we're replacing something of the same type */ tree_stack_entry *last = git_array_last(stack); - char *basename = git_path_basename(update->path); + char *basename = git_fs_path_basename(update->path); const git_tree_entry *e = git_treebuilder_get(last->bld, basename); if (e && git_tree_entry_type(e) != git_object__type_from_filemode(update->filemode)) { git__free(basename); @@ -1252,7 +1253,7 @@ int git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseli case GIT_TREE_UPDATE_REMOVE: { tree_stack_entry *last = git_array_last(stack); - char *basename = git_path_basename(update->path); + char *basename = git_fs_path_basename(update->path); error = git_treebuilder_remove(last->bld, basename); git__free(basename); break; diff --git a/src/win32/findfile.c b/src/win32/findfile.c index caa79398ab5..7578d960e39 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -44,7 +44,7 @@ static int win32_path_to_8(git_str *dest, const wchar_t *src) } /* Convert backslashes to forward slashes */ - git_path_mkposix(utf8_path); + git_fs_path_mkposix(utf8_path); return git_str_sets(dest, utf8_path); } diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c index e6640c85ed4..1f765f1deef 100644 --- a/src/win32/path_w32.c +++ b/src/win32/path_w32.c @@ -57,7 +57,7 @@ static wchar_t *path__skip_server(wchar_t *path) wchar_t *c; for (c = path; *c; c++) { - if (git_path_is_dirsep(*c)) + if (git_fs_path_is_dirsep(*c)) return c + 1; } @@ -71,9 +71,9 @@ static wchar_t *path__skip_prefix(wchar_t *path) if (wcsncmp(path, L"UNC\\", 4) == 0) path = path__skip_server(path + 4); - else if (git_path_is_absolute(path)) + else if (git_fs_path_is_absolute(path)) path += PATH__ABSOLUTE_LEN; - } else if (git_path_is_absolute(path)) { + } else if (git_fs_path_is_absolute(path)) { path += PATH__ABSOLUTE_LEN; } else if (path__is_unc(path)) { path = path__skip_server(path + 2); @@ -204,7 +204,7 @@ int git_win32_path_from_utf8(git_win32_path out, const char *src) dest += PATH__NT_NAMESPACE_LEN; /* See if this is an absolute path (beginning with a drive letter) */ - if (git_path_is_absolute(src)) { + if (git_fs_path_is_absolute(src)) { if (git__utf8_to_16(dest, GIT_WIN_PATH_MAX, src) < 0) goto on_error; } @@ -228,7 +228,7 @@ int git_win32_path_from_utf8(git_win32_path out, const char *src) if (path__cwd(dest, GIT_WIN_PATH_MAX) < 0) goto on_error; - if (!git_path_is_absolute(dest)) { + if (!git_fs_path_is_absolute(dest)) { errno = ENOENT; goto on_error; } @@ -266,7 +266,7 @@ int git_win32_path_relative_from_utf8(git_win32_path out, const char *src) int len; /* Handle absolute paths */ - if (git_path_is_absolute(src) || + if (git_fs_path_is_absolute(src) || path__is_nt_namespace(src) || path__is_unc(src) || path__startswith_slash(src)) { @@ -305,7 +305,7 @@ int git_win32_path_to_utf8(git_win32_utf8_path dest, const wchar_t *src) if ((len = git__utf16_to_8(out, GIT_WIN_PATH_UTF8, src)) < 0) return len; - git_path_mkposix(dest); + git_fs_path_mkposix(dest); return len; } diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index f26983d9792..398287f9e89 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -418,10 +418,10 @@ static bool target_is_dir(const char *target, const char *path) git_win32_path resolved_w; bool isdir = true; - if (git_path_is_absolute(target)) + if (git_fs_path_is_absolute(target)) git_win32_path_from_utf8(resolved_w, target); - else if (git_path_dirname_r(&resolved, path) < 0 || - git_path_apply_relative(&resolved, target) < 0 || + else if (git_fs_path_dirname_r(&resolved, path) < 0 || + git_fs_path_apply_relative(&resolved, target) < 0 || git_win32_path_from_utf8(resolved_w, resolved.ptr) < 0) goto out; @@ -661,7 +661,7 @@ int p_getcwd(char *buffer_out, size_t size) return -1; } - git_path_mkposix(buffer_out); + git_fs_path_mkposix(buffer_out); return 0; } @@ -821,7 +821,7 @@ char *p_realpath(const char *orig_path, char *buffer) if (git_win32_path_to_utf8(buffer, buffer_w) < 0) return NULL; - git_path_mkposix(buffer); + git_fs_path_mkposix(buffer); return buffer; } diff --git a/src/worktree.c b/src/worktree.c index 92a0900b08b..f0fc6d752bb 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -22,9 +22,9 @@ static bool is_worktree_dir(const char *dir) if (git_str_sets(&buf, dir) < 0) return -1; - error = git_path_contains_file(&buf, "commondir") - && git_path_contains_file(&buf, "gitdir") - && git_path_contains_file(&buf, "HEAD"); + error = git_fs_path_contains_file(&buf, "commondir") + && git_fs_path_contains_file(&buf, "gitdir") + && git_fs_path_contains_file(&buf, "HEAD"); git_str_dispose(&buf); return error; @@ -46,9 +46,9 @@ int git_worktree_list(git_strarray *wts, git_repository *repo) if ((error = git_str_joinpath(&path, repo->commondir, "worktrees/")) < 0) goto exit; - if (!git_path_exists(path.ptr) || git_path_is_empty_dir(path.ptr)) + if (!git_fs_path_exists(path.ptr) || git_fs_path_is_empty_dir(path.ptr)) goto exit; - if ((error = git_path_dirload(&worktrees, path.ptr, path.size, 0x0)) < 0) + if ((error = git_fs_path_dirload(&worktrees, path.ptr, path.size, 0x0)) < 0) goto exit; len = path.size; @@ -86,12 +86,12 @@ char *git_worktree__read_link(const char *base, const char *file) git_str_rtrim(&buf); - if (!git_path_is_relative(buf.ptr)) + if (!git_fs_path_is_relative(buf.ptr)) return git_str_detach(&buf); if (git_str_sets(&path, base) < 0) goto err; - if (git_path_apply_relative(&path, buf.ptr) < 0) + if (git_fs_path_apply_relative(&path, buf.ptr) < 0) goto err; git_str_dispose(&buf); @@ -136,7 +136,7 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char goto out; } - if ((error = git_path_validate_workdir(NULL, dir)) < 0) + if ((error = git_fs_path_validate_workdir(NULL, dir)) < 0) goto out; if ((wt = git__calloc(1, sizeof(*wt))) == NULL) { @@ -148,12 +148,12 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char (wt->commondir_path = git_worktree__read_link(dir, "commondir")) == NULL || (wt->gitlink_path = git_worktree__read_link(dir, "gitdir")) == NULL || (parent && (wt->parent_path = git__strdup(parent)) == NULL) || - (wt->worktree_path = git_path_dirname(wt->gitlink_path)) == NULL) { + (wt->worktree_path = git_fs_path_dirname(wt->gitlink_path)) == NULL) { error = -1; goto out; } - if ((error = git_path_prettify_dir(&gitdir, dir, NULL)) < 0) + if ((error = git_fs_path_prettify_dir(&gitdir, dir, NULL)) < 0) goto out; wt->gitdir_path = git_str_detach(&gitdir); @@ -214,11 +214,11 @@ int git_worktree_open_from_repository(git_worktree **out, git_repository *repo) gitdir = git_repository_path(repo); commondir = git_repository_commondir(repo); - if ((error = git_path_prettify_dir(&parent, "..", commondir)) < 0) + if ((error = git_fs_path_prettify_dir(&parent, "..", commondir)) < 0) goto out; /* The name is defined by the last component in '.git/worktree/%s' */ - name = git_path_basename(gitdir); + name = git_fs_path_basename(gitdir); if ((error = open_worktree_dir(out, parent.ptr, gitdir, name)) < 0) goto out; @@ -255,21 +255,21 @@ int git_worktree_validate(const git_worktree *wt) return GIT_ERROR; } - if (wt->parent_path && !git_path_exists(wt->parent_path)) { + if (wt->parent_path && !git_fs_path_exists(wt->parent_path)) { git_error_set(GIT_ERROR_WORKTREE, "worktree parent directory ('%s') does not exist ", wt->parent_path); return GIT_ERROR; } - if (!git_path_exists(wt->commondir_path)) { + if (!git_fs_path_exists(wt->commondir_path)) { git_error_set(GIT_ERROR_WORKTREE, "worktree common directory ('%s') does not exist ", wt->commondir_path); return GIT_ERROR; } - if (!git_path_exists(wt->worktree_path)) { + if (!git_fs_path_exists(wt->worktree_path)) { git_error_set(GIT_ERROR_WORKTREE, "worktree directory '%s' does not exist", wt->worktree_path); @@ -337,20 +337,20 @@ int git_worktree_add(git_worktree **out, git_repository *repo, /* Create gitdir directory ".git/worktrees/" */ if ((err = git_str_joinpath(&gitdir, repo->commondir, "worktrees")) < 0) goto out; - if (!git_path_exists(gitdir.ptr)) + if (!git_fs_path_exists(gitdir.ptr)) if ((err = git_futils_mkdir(gitdir.ptr, 0755, GIT_MKDIR_EXCL)) < 0) goto out; if ((err = git_str_joinpath(&gitdir, gitdir.ptr, name)) < 0) goto out; if ((err = git_futils_mkdir(gitdir.ptr, 0755, GIT_MKDIR_EXCL)) < 0) goto out; - if ((err = git_path_prettify_dir(&gitdir, gitdir.ptr, NULL)) < 0) + if ((err = git_fs_path_prettify_dir(&gitdir, gitdir.ptr, NULL)) < 0) goto out; /* Create worktree work dir */ if ((err = git_futils_mkdir(worktree, 0755, GIT_MKDIR_EXCL)) < 0) goto out; - if ((err = git_path_prettify_dir(&wddir, worktree, NULL)) < 0) + if ((err = git_fs_path_prettify_dir(&wddir, worktree, NULL)) < 0) goto out; if (wtopts.lock) { @@ -375,7 +375,7 @@ int git_worktree_add(git_worktree **out, git_repository *repo, goto out; /* Create gitdir files */ - if ((err = git_path_prettify_dir(&buf, repo->commondir, NULL) < 0) + if ((err = git_fs_path_prettify_dir(&buf, repo->commondir, NULL) < 0) || (err = git_str_putc(&buf, '\n')) < 0 || (err = write_wtfile(gitdir.ptr, "commondir", &buf)) < 0) goto out; @@ -494,7 +494,7 @@ static int git_worktree__is_locked(git_str *reason, const git_worktree *wt) if ((error = git_str_joinpath(&path, wt->gitdir_path, "locked")) < 0) goto out; - locked = git_path_exists(path.ptr); + locked = git_fs_path_exists(path.ptr); if (locked && reason && (error = git_futils_readbuffer(reason, path.ptr)) < 0) goto out; @@ -614,7 +614,7 @@ int git_worktree_prune(git_worktree *wt, /* Delete gitdir in parent repository */ if ((err = git_str_join3(&path, '/', wt->commondir_path, "worktrees", wt->name)) < 0) goto out; - if (!git_path_exists(path.ptr)) + if (!git_fs_path_exists(path.ptr)) { git_error_set(GIT_ERROR_WORKTREE, "worktree gitdir '%s' does not exist", path.ptr); err = -1; @@ -626,15 +626,15 @@ int git_worktree_prune(git_worktree *wt, /* Skip deletion of the actual working tree if it does * not exist or deletion was not requested */ if ((popts.flags & GIT_WORKTREE_PRUNE_WORKING_TREE) == 0 || - !git_path_exists(wt->gitlink_path)) + !git_fs_path_exists(wt->gitlink_path)) { goto out; } - if ((wtpath = git_path_dirname(wt->gitlink_path)) == NULL) + if ((wtpath = git_fs_path_dirname(wt->gitlink_path)) == NULL) goto out; git_str_attach(&path, wtpath, 0); - if (!git_path_exists(path.ptr)) + if (!git_fs_path_exists(path.ptr)) { git_error_set(GIT_ERROR_WORKTREE, "working tree '%s' does not exist", path.ptr); err = -1; diff --git a/tests/attr/repo.c b/tests/attr/repo.c index e7b97529010..abd2381541d 100644 --- a/tests/attr/repo.c +++ b/tests/attr/repo.c @@ -283,7 +283,7 @@ void test_attr_repo__bare_repo_with_index(void) git_index_free(index); cl_must_pass(p_unlink("attr/.gitattributes")); - cl_assert(!git_path_exists("attr/.gitattributes")); + cl_assert(!git_fs_path_exists("attr/.gitattributes")); cl_git_pass(git_repository_set_bare(g_repo)); diff --git a/tests/checkout/conflict.c b/tests/checkout/conflict.c index 3f5e7162d4a..4a9e4b9fa9b 100644 --- a/tests/checkout/conflict.c +++ b/tests/checkout/conflict.c @@ -227,7 +227,7 @@ void test_checkout_conflict__ignored(void) cl_git_pass(git_checkout_index(g_repo, g_index, &opts)); - cl_assert(!git_path_exists(TEST_REPO_PATH "/conflicting.txt")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/conflicting.txt")); } void test_checkout_conflict__ours(void) @@ -1030,15 +1030,15 @@ void test_checkout_conflict__update_only(void) ensure_workdir_contents("automergeable.txt", AUTOMERGEABLE_MERGED_FILE); ensure_workdir("directory_file-two/file", 0100644, CONFLICTING_OURS_OID); - cl_assert(!git_path_exists("merge-resolve/modify-delete")); - cl_assert(!git_path_exists("merge-resolve/test-one.txt")); - cl_assert(!git_path_exists("merge-resolve/test-one-side-one.txt")); - cl_assert(!git_path_exists("merge-resolve/test-one-side-two.txt")); - cl_assert(!git_path_exists("merge-resolve/test-one.txt~ours")); - cl_assert(!git_path_exists("merge-resolve/test-one.txt~theirs")); - cl_assert(!git_path_exists("merge-resolve/directory_file-one/file")); - cl_assert(!git_path_exists("merge-resolve/directory_file-one~ours")); - cl_assert(!git_path_exists("merge-resolve/directory_file-two~theirs")); + cl_assert(!git_fs_path_exists("merge-resolve/modify-delete")); + cl_assert(!git_fs_path_exists("merge-resolve/test-one.txt")); + cl_assert(!git_fs_path_exists("merge-resolve/test-one-side-one.txt")); + cl_assert(!git_fs_path_exists("merge-resolve/test-one-side-two.txt")); + cl_assert(!git_fs_path_exists("merge-resolve/test-one.txt~ours")); + cl_assert(!git_fs_path_exists("merge-resolve/test-one.txt~theirs")); + cl_assert(!git_fs_path_exists("merge-resolve/directory_file-one/file")); + cl_assert(!git_fs_path_exists("merge-resolve/directory_file-one~ours")); + cl_assert(!git_fs_path_exists("merge-resolve/directory_file-two~theirs")); } void test_checkout_conflict__path_filters(void) @@ -1076,9 +1076,9 @@ void test_checkout_conflict__path_filters(void) cl_git_pass(git_checkout_index(g_repo, g_index, &opts)); ensure_workdir_contents("conflicting-1.txt", CONFLICTING_DIFF3_FILE); - cl_assert(!git_path_exists("merge-resolve/conflicting-2.txt")); + cl_assert(!git_fs_path_exists("merge-resolve/conflicting-2.txt")); ensure_workdir_contents("conflicting-3.txt", AUTOMERGEABLE_MERGED_FILE); - cl_assert(!git_path_exists("merge-resolve/conflicting-4.txt")); + cl_assert(!git_fs_path_exists("merge-resolve/conflicting-4.txt")); } static void collect_progress( diff --git a/tests/checkout/crlf.c b/tests/checkout/crlf.c index eb4c61f39be..8fd16a00444 100644 --- a/tests/checkout/crlf.c +++ b/tests/checkout/crlf.c @@ -17,7 +17,7 @@ static int unlink_file(void *payload, git_str *path) { char *fn; - cl_assert(fn = git_path_basename(path->ptr)); + cl_assert(fn = git_fs_path_basename(path->ptr)); GIT_UNUSED(payload); @@ -39,7 +39,7 @@ void test_checkout_crlf__initialize(void) * check out over it. */ cl_git_pass(git_str_puts(&reponame, "crlf")); - cl_git_pass(git_path_direach(&reponame, 0, unlink_file, NULL)); + cl_git_pass(git_fs_path_direach(&reponame, 0, unlink_file, NULL)); if (GIT_EOL_NATIVE == GIT_EOL_CRLF) systype = "windows"; @@ -76,7 +76,7 @@ static int compare_file(void *payload, git_str *actual_path) int cmp_git, cmp_gitattributes; char *basename; - basename = git_path_basename(actual_path->ptr); + basename = git_fs_path_basename(actual_path->ptr); cmp_git = strcmp(basename, ".git"); cmp_gitattributes = strcmp(basename, ".gitattributes"); @@ -87,8 +87,8 @@ static int compare_file(void *payload, git_str *actual_path) cl_git_pass(git_str_joinpath(&expected_path, cd->dirname, basename)); - if (!git_path_isfile(expected_path.ptr) || - !git_path_isfile(actual_path->ptr)) + if (!git_fs_path_isfile(expected_path.ptr) || + !git_fs_path_isfile(actual_path->ptr)) goto done; if (git_futils_readbuffer(&actual_contents, actual_path->ptr) < 0 || @@ -107,7 +107,7 @@ static int compare_file(void *payload, git_str *actual_path) if (failed) { git_str details = GIT_STR_INIT; git_str_printf(&details, "filename=%s, system=%s, autocrlf=%s, attrs={%s}", - git_path_basename(actual_path->ptr), systype, cd->autocrlf, cd->attrs); + git_fs_path_basename(actual_path->ptr), systype, cd->autocrlf, cd->attrs); clar__fail(__FILE__, __func__, __LINE__, "checked out contents did not match expected", details.ptr, 0); git_str_dispose(&details); @@ -166,7 +166,7 @@ static void test_checkout(const char *autocrlf, const char *attrs) cl_git_pass(git_checkout_head(g_repo, &opts)); compare_data.dirname = sandboxname.ptr; - cl_git_pass(git_path_direach(&reponame, 0, compare_file, &compare_data)); + cl_git_pass(git_fs_path_direach(&reponame, 0, compare_file, &compare_data)); cl_fixture_cleanup(expected_fixture.ptr); git_str_dispose(&expected_fixture); @@ -187,9 +187,9 @@ static void empty_workdir(const char *name) size_t i; const char *fn; - cl_git_pass(git_path_dirload(&contents, name, 0, 0)); + cl_git_pass(git_fs_path_dirload(&contents, name, 0, 0)); git_vector_foreach(&contents, i, fn) { - cl_assert(basename = git_path_basename(fn)); + cl_assert(basename = git_fs_path_basename(fn)); cmp = strncasecmp(basename, ".git", 4); git__free(basename); diff --git a/tests/checkout/head.c b/tests/checkout/head.c index 5b3a034e77a..3b0bf472996 100644 --- a/tests/checkout/head.c +++ b/tests/checkout/head.c @@ -43,7 +43,7 @@ void test_checkout_head__with_index_only_tree(void) cl_git_pass(git_index_add_bypath(index, "newdir/newfile.txt")); cl_git_pass(git_index_write(index)); - cl_assert(git_path_isfile("testrepo/newdir/newfile.txt")); + cl_assert(git_fs_path_isfile("testrepo/newdir/newfile.txt")); cl_assert(git_index_get_bypath(index, "newdir/newfile.txt", 0) != NULL); git_index_free(index); @@ -55,7 +55,7 @@ void test_checkout_head__with_index_only_tree(void) cl_git_pass(git_repository_index(&index, g_repo)); - cl_assert(!git_path_isfile("testrepo/newdir/newfile.txt")); + cl_assert(!git_fs_path_isfile("testrepo/newdir/newfile.txt")); cl_assert(git_index_get_bypath(index, "newdir/newfile.txt", 0) == NULL); git_index_free(index); @@ -79,8 +79,8 @@ void test_checkout_head__do_not_remove_untracked_file(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isfile("testrepo/tracked/tracked")); - cl_assert(git_path_isfile("testrepo/tracked/untracked")); + cl_assert(!git_fs_path_isfile("testrepo/tracked/tracked")); + cl_assert(git_fs_path_isfile("testrepo/tracked/untracked")); } void test_checkout_head__do_not_remove_untracked_file_in_subdir(void) @@ -104,9 +104,9 @@ void test_checkout_head__do_not_remove_untracked_file_in_subdir(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isfile("testrepo/tracked/tracked")); - cl_assert(!git_path_isfile("testrepo/tracked/subdir/tracked")); - cl_assert(git_path_isfile("testrepo/tracked/subdir/untracked")); + cl_assert(!git_fs_path_isfile("testrepo/tracked/tracked")); + cl_assert(!git_fs_path_isfile("testrepo/tracked/subdir/tracked")); + cl_assert(git_fs_path_isfile("testrepo/tracked/subdir/untracked")); } void test_checkout_head__do_remove_untracked_paths(void) @@ -131,8 +131,8 @@ void test_checkout_head__do_remove_untracked_paths(void) opts.paths.count = 1; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(git_path_isfile("testrepo/tracked/tracked")); - cl_assert(!git_path_isfile("testrepo/tracked/untracked")); + cl_assert(git_fs_path_isfile("testrepo/tracked/tracked")); + cl_assert(!git_fs_path_isfile("testrepo/tracked/untracked")); } void test_checkout_head__do_remove_tracked_subdir(void) @@ -158,9 +158,9 @@ void test_checkout_head__do_remove_tracked_subdir(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isdir("testrepo/subdir/tracked")); - cl_assert(!git_path_isfile("testrepo/subdir/tracked-file")); - cl_assert(git_path_isfile("testrepo/subdir/untracked-file")); + cl_assert(!git_fs_path_isdir("testrepo/subdir/tracked")); + cl_assert(!git_fs_path_isfile("testrepo/subdir/tracked-file")); + cl_assert(git_fs_path_isfile("testrepo/subdir/untracked-file")); } void test_checkout_head__typechange_workdir(void) diff --git a/tests/checkout/icase.c b/tests/checkout/icase.c index 6c30765a369..d77c7abd514 100644 --- a/tests/checkout/icase.c +++ b/tests/checkout/icase.c @@ -50,8 +50,8 @@ static char *get_filename(const char *in) DIR *dir; struct dirent *de; - cl_assert(search_dirname = git_path_dirname(in)); - cl_assert(search_filename = git_path_basename(in)); + cl_assert(search_dirname = git_fs_path_dirname(in)); + cl_assert(search_filename = git_fs_path_basename(in)); cl_assert(dir = opendir(search_dirname)); @@ -134,7 +134,7 @@ void test_checkout_icase__refuses_to_overwrite_links_for_files(void) cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts)); - cl_assert(!git_path_exists("tmp")); + cl_assert(!git_fs_path_exists("tmp")); assert_name_is("testrepo/BRANCH_FILE.txt"); } @@ -146,7 +146,7 @@ void test_checkout_icase__overwrites_links_for_files_when_forced(void) cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts)); - cl_assert(!git_path_exists("tmp")); + cl_assert(!git_fs_path_exists("tmp")); assert_name_is("testrepo/new.txt"); } @@ -159,7 +159,7 @@ void test_checkout_icase__overwrites_empty_folders_for_files(void) cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts)); assert_name_is("testrepo/new.txt"); - cl_assert(!git_path_isdir("testrepo/new.txt")); + cl_assert(!git_fs_path_isdir("testrepo/new.txt")); } void test_checkout_icase__refuses_to_overwrite_populated_folders_for_files(void) @@ -173,7 +173,7 @@ void test_checkout_icase__refuses_to_overwrite_populated_folders_for_files(void) cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts)); assert_name_is("testrepo/BRANCH_FILE.txt"); - cl_assert(git_path_isdir("testrepo/BRANCH_FILE.txt")); + cl_assert(git_fs_path_isdir("testrepo/BRANCH_FILE.txt")); } void test_checkout_icase__overwrites_folders_for_files_when_forced(void) @@ -187,7 +187,7 @@ void test_checkout_icase__overwrites_folders_for_files_when_forced(void) cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts)); assert_name_is("testrepo/new.txt"); - cl_assert(!git_path_isdir("testrepo/new.txt")); + cl_assert(!git_fs_path_isdir("testrepo/new.txt")); } void test_checkout_icase__refuses_to_overwrite_files_for_folders(void) @@ -199,7 +199,7 @@ void test_checkout_icase__refuses_to_overwrite_files_for_folders(void) cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts)); assert_name_is("testrepo/A"); - cl_assert(!git_path_isdir("testrepo/A")); + cl_assert(!git_fs_path_isdir("testrepo/A")); } void test_checkout_icase__overwrites_files_for_folders_when_forced(void) @@ -211,7 +211,7 @@ void test_checkout_icase__overwrites_files_for_folders_when_forced(void) cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts)); assert_name_is("testrepo/a"); - cl_assert(git_path_isdir("testrepo/a")); + cl_assert(git_fs_path_isdir("testrepo/a")); } void test_checkout_icase__refuses_to_overwrite_links_for_folders(void) @@ -222,7 +222,7 @@ void test_checkout_icase__refuses_to_overwrite_links_for_folders(void) cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts)); - cl_assert(!git_path_exists("b.txt")); + cl_assert(!git_fs_path_exists("b.txt")); assert_name_is("testrepo/A"); } @@ -234,7 +234,7 @@ void test_checkout_icase__overwrites_links_for_folders_when_forced(void) cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts)); - cl_assert(!git_path_exists("b.txt")); + cl_assert(!git_fs_path_exists("b.txt")); assert_name_is("testrepo/a"); } diff --git a/tests/checkout/index.c b/tests/checkout/index.c index 13eecc9848f..6a80d22c58f 100644 --- a/tests/checkout/index.c +++ b/tests/checkout/index.c @@ -56,9 +56,9 @@ void test_checkout_index__can_create_missing_files(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - cl_assert_equal_i(false, git_path_isfile("./testrepo/README")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; @@ -77,7 +77,7 @@ void test_checkout_index__can_remove_untracked_files(void) cl_git_mkfile("./testrepo/dir/one", "one\n"); cl_git_mkfile("./testrepo/dir/subdir/two", "two\n"); - cl_assert_equal_i(true, git_path_isdir("./testrepo/dir/subdir/subsubdir")); + cl_assert_equal_i(true, git_fs_path_isdir("./testrepo/dir/subdir/subsubdir")); opts.checkout_strategy = GIT_CHECKOUT_SAFE | @@ -86,7 +86,7 @@ void test_checkout_index__can_remove_untracked_files(void) cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); - cl_assert_equal_i(false, git_path_isdir("./testrepo/dir")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/dir")); } void test_checkout_index__can_disable_pathspec_match(void) @@ -152,15 +152,15 @@ void test_checkout_index__honor_the_specified_pathspecs(void) opts.paths.strings = entries; opts.paths.count = 1; - cl_assert_equal_i(false, git_path_isfile("./testrepo/README")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); - cl_assert_equal_i(false, git_path_isfile("./testrepo/README")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n"); check_file_contents("./testrepo/new.txt", "my new file\n"); } @@ -236,7 +236,7 @@ void test_checkout_index__honor_coresymlinks_default_true(void) cl_must_pass(p_mkdir("symlink", 0777)); - if (!git_path_supports_symlinks("symlink/test")) + if (!git_fs_path_supports_symlinks("symlink/test")) cl_skip(); #ifdef GIT_WIN32 @@ -269,7 +269,7 @@ void test_checkout_index__honor_coresymlinks_default_false(void) * supports symlinks. Bail entirely on POSIX platforms that * do support symlinks. */ - if (git_path_supports_symlinks("symlink/test")) + if (git_fs_path_supports_symlinks("symlink/test")) cl_skip(); #endif @@ -281,7 +281,7 @@ void test_checkout_index__coresymlinks_set_to_true_fails_when_unsupported(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - if (git_path_supports_symlinks("testrepo/test")) { + if (git_fs_path_supports_symlinks("testrepo/test")) { cl_skip(); } @@ -297,7 +297,7 @@ void test_checkout_index__honor_coresymlinks_setting_set_to_true(void) char link_data[GIT_PATH_MAX]; size_t link_size = GIT_PATH_MAX; - if (!git_path_supports_symlinks("testrepo/test")) { + if (!git_fs_path_supports_symlinks("testrepo/test")) { cl_skip(); } @@ -578,8 +578,8 @@ void test_checkout_index__can_overcome_name_clashes(void) cl_git_pass(p_mkdir("./testrepo/path0", 0777)); cl_git_mkfile("./testrepo/path0/file0", "content\r\n"); - cl_assert(git_path_isfile("./testrepo/path1")); - cl_assert(git_path_isfile("./testrepo/path0/file0")); + cl_assert(git_fs_path_isfile("./testrepo/path1")); + cl_assert(git_fs_path_isfile("./testrepo/path0/file0")); opts.checkout_strategy = GIT_CHECKOUT_SAFE | @@ -587,14 +587,14 @@ void test_checkout_index__can_overcome_name_clashes(void) GIT_CHECKOUT_ALLOW_CONFLICTS; cl_git_pass(git_checkout_index(g_repo, index, &opts)); - cl_assert(git_path_isfile("./testrepo/path1")); - cl_assert(git_path_isfile("./testrepo/path0/file0")); + cl_assert(git_fs_path_isfile("./testrepo/path1")); + cl_assert(git_fs_path_isfile("./testrepo/path0/file0")); opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_index(g_repo, index, &opts)); - cl_assert(git_path_isfile("./testrepo/path0")); - cl_assert(git_path_isfile("./testrepo/path1/file1")); + cl_assert(git_fs_path_isfile("./testrepo/path0")); + cl_assert(git_fs_path_isfile("./testrepo/path1/file1")); git_index_free(index); } @@ -622,9 +622,9 @@ void test_checkout_index__can_update_prefixed_files(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - cl_assert_equal_i(false, git_path_isfile("./testrepo/README")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); cl_git_mkfile("./testrepo/READ", "content\n"); cl_git_mkfile("./testrepo/README.after", "content\n"); @@ -647,10 +647,10 @@ void test_checkout_index__can_update_prefixed_files(void) check_file_contents_nocr("./testrepo/branch_file.txt", "hi\nbye!\n"); check_file_contents_nocr("./testrepo/new.txt", "my new file\n"); - cl_assert(!git_path_exists("testrepo/READ")); - cl_assert(!git_path_exists("testrepo/README.after")); - cl_assert(!git_path_exists("testrepo/branch_file")); - cl_assert(!git_path_exists("testrepo/branch_file.txt.after")); + cl_assert(!git_fs_path_exists("testrepo/READ")); + cl_assert(!git_fs_path_exists("testrepo/README.after")); + cl_assert(!git_fs_path_exists("testrepo/branch_file")); + cl_assert(!git_fs_path_exists("testrepo/branch_file.txt.after")); } void test_checkout_index__can_checkout_a_newly_initialized_repository(void) @@ -688,7 +688,7 @@ void test_checkout_index__target_directory(void) opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; opts.target_directory = "alternative"; - cl_assert(!git_path_isdir("alternative")); + cl_assert(!git_fs_path_isdir("alternative")); opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL; opts.notify_cb = checkout_count_callback; @@ -741,7 +741,7 @@ void test_checkout_index__target_directory_from_bare(void) cl_git_fail(git_checkout_index(g_repo, NULL, &opts)); opts.target_directory = "alternative"; - cl_assert(!git_path_isdir("alternative")); + cl_assert(!git_fs_path_isdir("alternative")); cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); @@ -765,9 +765,9 @@ void test_checkout_index__can_get_repo_from_index(void) git_index *index; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - cl_assert_equal_i(false, git_path_isfile("./testrepo/README")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; diff --git a/tests/checkout/nasty.c b/tests/checkout/nasty.c index a1b3164be60..732f1d5e8bd 100644 --- a/tests/checkout/nasty.c +++ b/tests/checkout/nasty.c @@ -38,7 +38,7 @@ static void test_checkout_passes(const char *refname, const char *filename) GIT_CHECKOUT_DONT_UPDATE_INDEX; cl_git_pass(git_checkout_tree(repo, (const git_object *)commit, &opts)); - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); git_commit_free(commit); git_str_dispose(&path); @@ -59,7 +59,7 @@ static void test_checkout_fails(const char *refname, const char *filename) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_fail(git_checkout_tree(repo, (const git_object *)commit, &opts)); - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); git_commit_free(commit); git_str_dispose(&path); @@ -246,7 +246,7 @@ void test_checkout_nasty__only_looks_like_a_git_shortname(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_tree(repo, (const git_object *)commit, &opts)); - cl_assert(git_path_exists("nasty/git~3/foobar")); + cl_assert(git_fs_path_exists("nasty/git~3/foobar")); git_commit_free(commit); #endif diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c index cdfb456b77a..2f54f4e3e89 100644 --- a/tests/checkout/tree.c +++ b/tests/checkout/tree.c @@ -34,7 +34,7 @@ void test_checkout_tree__cleanup(void) cl_git_sandbox_cleanup(); - if (git_path_isdir("alternative")) + if (git_fs_path_isdir("alternative")) git_futils_rmdir_r("alternative", NULL, GIT_RMDIR_REMOVE_FILES); } @@ -54,17 +54,17 @@ void test_checkout_tree__can_checkout_a_subdirectory_from_a_commit(void) cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees")); - cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/")); cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt")); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/fgh/1.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/fgh/1.txt")); } void test_checkout_tree__can_checkout_and_remove_directory(void) { - cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/")); /* Checkout brach "subtrees" and update HEAD, so that HEAD matches the * current working tree @@ -74,9 +74,9 @@ void test_checkout_tree__can_checkout_and_remove_directory(void) cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); - cl_assert_equal_i(true, git_path_isdir("./testrepo/ab/")); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt")); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/fgh/1.txt")); + cl_assert_equal_i(true, git_fs_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/fgh/1.txt")); git_object_free(g_object); g_object = NULL; @@ -90,7 +90,7 @@ void test_checkout_tree__can_checkout_and_remove_directory(void) cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master")); /* This directory should no longer exist */ - cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/")); } void test_checkout_tree__can_checkout_a_subdirectory_from_a_subtree(void) @@ -102,12 +102,12 @@ void test_checkout_tree__can_checkout_a_subdirectory_from_a_subtree(void) cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees:ab")); - cl_assert_equal_i(false, git_path_isdir("./testrepo/de/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/de/")); cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert_equal_i(true, git_path_isfile("./testrepo/de/2.txt")); - cl_assert_equal_i(true, git_path_isfile("./testrepo/de/fgh/1.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/de/2.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/de/fgh/1.txt")); } static void progress(const char *path, size_t cur, size_t tot, void *payload) @@ -149,7 +149,7 @@ void test_checkout_tree__doesnt_write_unrequested_files_to_worktree(void) */ opts.checkout_strategy = GIT_CHECKOUT_NONE; git_checkout_tree(g_repo, (git_object*)p_chomped_commit, &opts); - cl_assert_equal_i(false, git_path_isfile("testrepo/readme.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("testrepo/readme.txt")); git_commit_free(p_master_commit); git_commit_free(p_chomped_commit); @@ -174,12 +174,12 @@ void test_checkout_tree__can_switch_branches(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); - cl_assert(git_path_isfile("testrepo/README")); - cl_assert(git_path_isfile("testrepo/branch_file.txt")); - cl_assert(git_path_isfile("testrepo/new.txt")); - cl_assert(git_path_isfile("testrepo/a/b.txt")); + cl_assert(git_fs_path_isfile("testrepo/README")); + cl_assert(git_fs_path_isfile("testrepo/branch_file.txt")); + cl_assert(git_fs_path_isfile("testrepo/new.txt")); + cl_assert(git_fs_path_isfile("testrepo/a/b.txt")); - cl_assert(!git_path_isdir("testrepo/ab")); + cl_assert(!git_fs_path_isdir("testrepo/ab")); assert_on_branch(g_repo, "dir"); @@ -194,15 +194,15 @@ void test_checkout_tree__can_switch_branches(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); - cl_assert(git_path_isfile("testrepo/README")); - cl_assert(git_path_isfile("testrepo/branch_file.txt")); - cl_assert(git_path_isfile("testrepo/new.txt")); - cl_assert(git_path_isfile("testrepo/ab/4.txt")); - cl_assert(git_path_isfile("testrepo/ab/c/3.txt")); - cl_assert(git_path_isfile("testrepo/ab/de/2.txt")); - cl_assert(git_path_isfile("testrepo/ab/de/fgh/1.txt")); + cl_assert(git_fs_path_isfile("testrepo/README")); + cl_assert(git_fs_path_isfile("testrepo/branch_file.txt")); + cl_assert(git_fs_path_isfile("testrepo/new.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/c/3.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/de/2.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/de/fgh/1.txt")); - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); assert_on_branch(g_repo, "subtrees"); @@ -216,11 +216,11 @@ void test_checkout_tree__can_remove_untracked(void) opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_REMOVE_UNTRACKED; cl_git_mkfile("testrepo/untracked_file", "as you wish"); - cl_assert(git_path_isfile("testrepo/untracked_file")); + cl_assert(git_fs_path_isfile("testrepo/untracked_file")); cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isfile("testrepo/untracked_file")); + cl_assert(!git_fs_path_isfile("testrepo/untracked_file")); } void test_checkout_tree__can_remove_ignored(void) @@ -237,11 +237,11 @@ void test_checkout_tree__can_remove_ignored(void) cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "ignored_file")); cl_assert_equal_i(1, ignored); - cl_assert(git_path_isfile("testrepo/ignored_file")); + cl_assert(git_fs_path_isfile("testrepo/ignored_file")); cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isfile("testrepo/ignored_file")); + cl_assert(!git_fs_path_isfile("testrepo/ignored_file")); } static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir) @@ -264,12 +264,12 @@ static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); - cl_assert(git_path_isfile("testrepo/README")); - cl_assert(git_path_isfile("testrepo/branch_file.txt")); - cl_assert(git_path_isfile("testrepo/new.txt")); - cl_assert(git_path_isfile("testrepo/a/b.txt")); + cl_assert(git_fs_path_isfile("testrepo/README")); + cl_assert(git_fs_path_isfile("testrepo/branch_file.txt")); + cl_assert(git_fs_path_isfile("testrepo/new.txt")); + cl_assert(git_fs_path_isfile("testrepo/a/b.txt")); - cl_assert(!git_path_isdir("testrepo/ab")); + cl_assert(!git_fs_path_isdir("testrepo/ab")); assert_on_branch(g_repo, "dir"); @@ -285,12 +285,12 @@ static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir) cl_git_mkfile("testrepo/ab/4.txt/file2.txt", "foo bar foo"); cl_git_mkfile("testrepo/ab/4.txt/file3.txt", "inky blinky pinky clyde"); - cl_assert(git_path_isdir("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isdir("testrepo/ab/4.txt")); } else { cl_must_pass(p_mkdir("testrepo/ab", 0777)); cl_git_mkfile("testrepo/ab/4.txt", "as you wish"); - cl_assert(git_path_isfile("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/4.txt")); } cl_git_pass(git_ignore_add_rule(g_repo, "ab/4.txt\n")); @@ -324,7 +324,7 @@ void test_checkout_tree__can_overwrite_ignored_by_default(void) cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); - cl_assert(git_path_isfile("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/4.txt")); assert_on_branch(g_repo, "subtrees"); } @@ -345,7 +345,7 @@ void test_checkout_tree__can_overwrite_ignored_folder_by_default(void) cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); - cl_assert(git_path_isfile("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/4.txt")); assert_on_branch(g_repo, "subtrees"); @@ -364,7 +364,7 @@ void test_checkout_tree__can_update_only(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n"); @@ -384,7 +384,7 @@ void test_checkout_tree__can_update_only(void) * the test_checkout_tree__can_switch_branches test), but with * UPDATE_ONLY it will not have been created. */ - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); /* but this file still should have been updated */ check_file_contents_nocr("testrepo/branch_file.txt", "hi\n"); @@ -410,10 +410,10 @@ void test_checkout_tree__can_checkout_with_pattern(void) git_object_free(g_object); g_object = NULL; - cl_assert(git_path_exists("testrepo/README")); - cl_assert(!git_path_exists("testrepo/branch_file.txt")); - cl_assert(!git_path_exists("testrepo/link_to_new.txt")); - cl_assert(!git_path_exists("testrepo/new.txt")); + cl_assert(git_fs_path_exists("testrepo/README")); + cl_assert(!git_fs_path_exists("testrepo/branch_file.txt")); + cl_assert(!git_fs_path_exists("testrepo/link_to_new.txt")); + cl_assert(!git_fs_path_exists("testrepo/new.txt")); /* now to a narrow patterned checkout */ @@ -425,10 +425,10 @@ void test_checkout_tree__can_checkout_with_pattern(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert(git_path_exists("testrepo/README")); - cl_assert(!git_path_exists("testrepo/branch_file.txt")); - cl_assert(git_path_exists("testrepo/link_to_new.txt")); - cl_assert(git_path_exists("testrepo/new.txt")); + cl_assert(git_fs_path_exists("testrepo/README")); + cl_assert(!git_fs_path_exists("testrepo/branch_file.txt")); + cl_assert(git_fs_path_exists("testrepo/link_to_new.txt")); + cl_assert(git_fs_path_exists("testrepo/new.txt")); } void test_checkout_tree__pathlist_checkout_ignores_non_matches(void) @@ -445,10 +445,10 @@ void test_checkout_tree__pathlist_checkout_ignores_non_matches(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master")); - cl_assert(git_path_exists("testrepo/README")); - cl_assert(git_path_exists("testrepo/branch_file.txt")); - cl_assert(git_path_exists("testrepo/link_to_new.txt")); - cl_assert(git_path_exists("testrepo/new.txt")); + cl_assert(git_fs_path_exists("testrepo/README")); + cl_assert(git_fs_path_exists("testrepo/branch_file.txt")); + cl_assert(git_fs_path_exists("testrepo/link_to_new.txt")); + cl_assert(git_fs_path_exists("testrepo/new.txt")); git_object_free(g_object); cl_git_pass(git_revparse_single(&g_object, g_repo, "8496071c1b46c854b31185ea97743be6a8774479")); @@ -460,10 +460,10 @@ void test_checkout_tree__pathlist_checkout_ignores_non_matches(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert(git_path_exists("testrepo/README")); - cl_assert(!git_path_exists("testrepo/branch_file.txt")); - cl_assert(!git_path_exists("testrepo/link_to_new.txt")); - cl_assert(git_path_exists("testrepo/new.txt")); + cl_assert(git_fs_path_exists("testrepo/README")); + cl_assert(!git_fs_path_exists("testrepo/branch_file.txt")); + cl_assert(!git_fs_path_exists("testrepo/link_to_new.txt")); + cl_assert(git_fs_path_exists("testrepo/new.txt")); } void test_checkout_tree__can_disable_pattern_match(void) @@ -484,7 +484,7 @@ void test_checkout_tree__can_disable_pattern_match(void) git_object_free(g_object); g_object = NULL; - cl_assert(!git_path_isfile("testrepo/branch_file.txt")); + cl_assert(!git_fs_path_isfile("testrepo/branch_file.txt")); /* now to a narrow patterned checkout, but disable pattern */ @@ -498,7 +498,7 @@ void test_checkout_tree__can_disable_pattern_match(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert(!git_path_isfile("testrepo/branch_file.txt")); + cl_assert(!git_fs_path_isfile("testrepo/branch_file.txt")); /* let's try that again, but allow the pattern match */ @@ -506,7 +506,7 @@ void test_checkout_tree__can_disable_pattern_match(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert(git_path_isfile("testrepo/branch_file.txt")); + cl_assert(git_fs_path_isfile("testrepo/branch_file.txt")); } void assert_conflict( @@ -623,7 +623,7 @@ void test_checkout_tree__donot_update_deleted_file_by_default(void) cl_git_pass(git_index_remove_bypath(index ,"branch_file.txt")); cl_git_pass(git_index_write(index)); - cl_assert(!git_path_exists("testrepo/branch_file.txt")); + cl_assert(!git_fs_path_exists("testrepo/branch_file.txt")); cl_git_pass(git_oid_fromstr(&new_id, "099fabac3a9ea935598528c27f866e34089c2eff")); cl_git_pass(git_commit_lookup(&new_commit, g_repo, &new_id)); @@ -686,16 +686,16 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void) opts.notify_payload = &ca; opts.checkout_strategy = GIT_CHECKOUT_FORCE; - cl_assert(!git_path_exists("testrepo/new.txt")); + cl_assert(!git_fs_path_exists("testrepo/new.txt")); cl_git_fail_with(git_checkout_tree(g_repo, obj, &opts), -5555); - cl_assert(!git_path_exists("testrepo/new.txt")); + cl_assert(!git_fs_path_exists("testrepo/new.txt")); /* on case-insensitive FS = a/b.txt, branch_file.txt, new.txt */ /* on case-sensitive FS = README, then above */ - if (git_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */ + if (git_fs_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */ cl_assert_equal_i(3, ca.count); else cl_assert_equal_i(4, ca.count); @@ -707,9 +707,9 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void) cl_git_fail_with(git_checkout_tree(g_repo, obj, &opts), 123); - cl_assert(!git_path_exists("testrepo/new.txt")); + cl_assert(!git_fs_path_exists("testrepo/new.txt")); - if (git_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */ + if (git_fs_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */ cl_assert_equal_i(4, ca.count); else cl_assert_equal_i(1, ca.count); @@ -799,7 +799,7 @@ void test_checkout_tree__can_write_to_empty_dirs(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); - cl_assert(git_path_isfile("testrepo/a/b.txt")); + cl_assert(git_fs_path_isfile("testrepo/a/b.txt")); git_object_free(obj); } @@ -818,7 +818,7 @@ void test_checkout_tree__fails_when_dir_in_use(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); - cl_assert(git_path_isfile("testrepo/a/b.txt")); + cl_assert(git_fs_path_isfile("testrepo/a/b.txt")); git_object_free(obj); @@ -831,7 +831,7 @@ void test_checkout_tree__fails_when_dir_in_use(void) cl_git_pass(p_chdir("../..")); - cl_assert(git_path_is_empty_dir("testrepo/a")); + cl_assert(git_fs_path_is_empty_dir("testrepo/a")); git_object_free(obj); #endif @@ -852,7 +852,7 @@ void test_checkout_tree__can_continue_when_dir_in_use(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); - cl_assert(git_path_isfile("testrepo/a/b.txt")); + cl_assert(git_fs_path_isfile("testrepo/a/b.txt")); git_object_free(obj); @@ -865,7 +865,7 @@ void test_checkout_tree__can_continue_when_dir_in_use(void) cl_git_pass(p_chdir("../..")); - cl_assert(git_path_is_empty_dir("testrepo/a")); + cl_assert(git_fs_path_is_empty_dir("testrepo/a")); git_object_free(obj); #endif @@ -896,7 +896,7 @@ void test_checkout_tree__target_directory_from_bare(void) cl_git_fail(git_checkout_tree(g_repo, g_object, &opts)); opts.target_directory = "alternative"; - cl_assert(!git_path_isdir("alternative")); + cl_assert(!git_fs_path_isdir("alternative")); cl_git_pass(git_checkout_tree(g_repo, g_object, &opts)); @@ -923,12 +923,12 @@ void test_checkout_tree__extremely_long_file_name(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); sprintf(path, "testrepo/%s.txt", longname); - cl_assert(git_path_exists(path)); + cl_assert(git_fs_path_exists(path)); git_object_free(g_object); cl_git_pass(git_revparse_single(&g_object, g_repo, "master")); cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert(!git_path_exists(path)); + cl_assert(!git_fs_path_exists(path)); } static void create_conflict(const char *path) @@ -1138,7 +1138,7 @@ void test_checkout_tree__removes_conflicts(void) cl_assert_equal_p(NULL, git_index_get_bypath(index, "other.txt", 2)); cl_assert_equal_p(NULL, git_index_get_bypath(index, "other.txt", 3)); - cl_assert(!git_path_exists("testrepo/other.txt")); + cl_assert(!git_fs_path_exists("testrepo/other.txt")); git_commit_free(commit); git_index_free(index); @@ -1183,7 +1183,7 @@ void test_checkout_tree__removes_conflicts_only_by_pathscope(void) cl_assert(git_index_get_bypath(index, "other.txt", 2) != NULL); cl_assert(git_index_get_bypath(index, "other.txt", 3) != NULL); - cl_assert(git_path_exists("testrepo/other.txt")); + cl_assert(git_fs_path_exists("testrepo/other.txt")); git_commit_free(commit); git_index_free(index); @@ -1214,8 +1214,8 @@ void test_checkout_tree__case_changing_rename(void) cl_git_pass(git_checkout_tree(g_repo, (git_object *)dir_commit, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); - cl_assert(git_path_isfile("testrepo/README")); - case_sensitive = !git_path_isfile("testrepo/readme"); + cl_assert(git_fs_path_isfile("testrepo/README")); + case_sensitive = !git_fs_path_isfile("testrepo/readme"); cl_assert(index_entry = git_index_get_bypath(index, "README", 0)); cl_assert_equal_s("README", index_entry->path); @@ -1235,9 +1235,9 @@ void test_checkout_tree__case_changing_rename(void) cl_git_pass(git_commit_create(&commit_id, g_repo, "refs/heads/dir", signature, signature, NULL, "case-changing rename", tree, 1, (const git_commit **)&dir_commit)); - cl_assert(git_path_isfile("testrepo/readme")); + cl_assert(git_fs_path_isfile("testrepo/readme")); if (case_sensitive) - cl_assert(!git_path_isfile("testrepo/README")); + cl_assert(!git_fs_path_isfile("testrepo/README")); cl_assert(index_entry = git_index_get_bypath(index, "readme", 0)); cl_assert_equal_s("readme", index_entry->path); @@ -1253,9 +1253,9 @@ void test_checkout_tree__case_changing_rename(void) assert_on_branch(g_repo, "master"); - cl_assert(git_path_isfile("testrepo/README")); + cl_assert(git_fs_path_isfile("testrepo/README")); if (case_sensitive) - cl_assert(!git_path_isfile("testrepo/readme")); + cl_assert(!git_fs_path_isfile("testrepo/readme")); cl_assert(index_entry = git_index_get_bypath(index, "README", 0)); cl_assert_equal_s("README", index_entry->path); @@ -1366,13 +1366,13 @@ void test_checkout_tree__can_not_update_index(void) cl_git_pass(git_reset(g_repo, head, GIT_RESET_HARD, &g_opts)); - cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/")); cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees")); cl_git_pass(git_checkout_tree(g_repo, g_object, &opts)); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt")); cl_git_pass(git_status_file(&status, g_repo, "ab/de/2.txt")); cl_assert_equal_i(GIT_STATUS_WT_NEW, status); @@ -1403,13 +1403,13 @@ void test_checkout_tree__can_update_but_not_write_index(void) cl_git_pass(git_reset(g_repo, head, GIT_RESET_HARD, &g_opts)); - cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/")); cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees")); cl_git_pass(git_checkout_tree(g_repo, g_object, &opts)); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt")); cl_git_pass(git_status_file(&status, g_repo, "ab/de/2.txt")); cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status); @@ -1450,15 +1450,15 @@ void test_checkout_tree__safe_proceeds_if_no_index(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); - cl_assert(git_path_isfile("testrepo/README")); - cl_assert(git_path_isfile("testrepo/branch_file.txt")); - cl_assert(git_path_isfile("testrepo/new.txt")); - cl_assert(git_path_isfile("testrepo/ab/4.txt")); - cl_assert(git_path_isfile("testrepo/ab/c/3.txt")); - cl_assert(git_path_isfile("testrepo/ab/de/2.txt")); - cl_assert(git_path_isfile("testrepo/ab/de/fgh/1.txt")); + cl_assert(git_fs_path_isfile("testrepo/README")); + cl_assert(git_fs_path_isfile("testrepo/branch_file.txt")); + cl_assert(git_fs_path_isfile("testrepo/new.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/c/3.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/de/2.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/de/fgh/1.txt")); - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); assert_on_branch(g_repo, "subtrees"); @@ -1650,7 +1650,7 @@ void test_checkout_tree__dry_run(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n"); @@ -1673,7 +1673,7 @@ void test_checkout_tree__dry_run(void) /* these normally would have been created and updated, but with * DRY_RUN they will be unchanged. */ - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n"); /* check that notify callback was invoked */ diff --git a/tests/checkout/typechange.c b/tests/checkout/typechange.c index 205ce657f9e..b888843f03f 100644 --- a/tests/checkout/typechange.c +++ b/tests/checkout/typechange.c @@ -76,12 +76,12 @@ void test_checkout_typechange__cleanup(void) static void assert_file_exists(const char *path) { - cl_assert_(git_path_isfile(path), path); + cl_assert_(git_fs_path_isfile(path), path); } static void assert_dir_exists(const char *path) { - cl_assert_(git_path_isdir(path), path); + cl_assert_(git_fs_path_isdir(path), path); } static void assert_workdir_matches_tree( @@ -126,7 +126,7 @@ static void assert_workdir_matches_tree( /* because of cross-platform, don't confirm exec bit yet */ break; case GIT_FILEMODE_LINK: - cl_assert_(git_path_exists(path.ptr), path.ptr); + cl_assert_(git_fs_path_exists(path.ptr), path.ptr); /* because of cross-platform, don't confirm link yet */ break; default: @@ -163,19 +163,19 @@ void test_checkout_typechange__checkout_typechanges_safe(void) git_object_free(obj); if (!g_typechange_empty[i]) { - cl_assert(git_path_isdir("typechanges")); - cl_assert(git_path_exists("typechanges/a")); - cl_assert(git_path_exists("typechanges/b")); - cl_assert(git_path_exists("typechanges/c")); - cl_assert(git_path_exists("typechanges/d")); - cl_assert(git_path_exists("typechanges/e")); + cl_assert(git_fs_path_isdir("typechanges")); + cl_assert(git_fs_path_exists("typechanges/a")); + cl_assert(git_fs_path_exists("typechanges/b")); + cl_assert(git_fs_path_exists("typechanges/c")); + cl_assert(git_fs_path_exists("typechanges/d")); + cl_assert(git_fs_path_exists("typechanges/e")); } else { - cl_assert(git_path_isdir("typechanges")); - cl_assert(!git_path_exists("typechanges/a")); - cl_assert(!git_path_exists("typechanges/b")); - cl_assert(!git_path_exists("typechanges/c")); - cl_assert(!git_path_exists("typechanges/d")); - cl_assert(!git_path_exists("typechanges/e")); + cl_assert(git_fs_path_isdir("typechanges")); + cl_assert(!git_fs_path_exists("typechanges/a")); + cl_assert(!git_fs_path_exists("typechanges/b")); + cl_assert(!git_fs_path_exists("typechanges/c")); + cl_assert(!git_fs_path_exists("typechanges/d")); + cl_assert(!git_fs_path_exists("typechanges/e")); } } } @@ -293,12 +293,12 @@ void test_checkout_typechange__checkout_with_conflicts(void) GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED; memset(&cts, 0, sizeof(cts)); - cl_assert(git_path_exists("typechanges/untracked")); + cl_assert(git_fs_path_exists("typechanges/untracked")); cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_assert_equal_i(0, cts.conflicts); - cl_assert(!git_path_exists("typechanges/untracked")); + cl_assert(!git_fs_path_exists("typechanges/untracked")); cl_git_pass( git_repository_set_head_detached(g_repo, git_object_id(obj))); diff --git a/tests/cherrypick/workdir.c b/tests/cherrypick/workdir.c index f7765f2c277..868b9d5ff94 100644 --- a/tests/cherrypick/workdir.c +++ b/tests/cherrypick/workdir.c @@ -71,8 +71,8 @@ void test_cherrypick_workdir__automerge(void) cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, NULL)); - cl_assert(git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); - cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); cl_git_pass(git_index_write_tree(&cherrypicked_tree_oid, repo_index)); cl_git_pass(git_tree_lookup(&cherrypicked_tree, repo, &cherrypicked_tree_oid)); @@ -114,7 +114,7 @@ void test_cherrypick_workdir__empty_result(void) /* Create an untracked file that should not conflict */ cl_git_mkfile(TEST_REPO_PATH "/file4.txt", ""); - cl_assert(git_path_exists(TEST_REPO_PATH "/file4.txt")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/file4.txt")); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); @@ -160,8 +160,8 @@ void test_cherrypick_workdir__conflicts(void) cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, NULL)); - cl_assert(git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); - cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); cl_assert(merge_test_index(repo_index, merge_index_entries, 7)); @@ -373,8 +373,8 @@ void test_cherrypick_workdir__nonmerge_fails_mainline_specified(void) opts.mainline = 1; cl_must_fail(git_cherrypick(repo, commit, &opts)); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); git_reference_free(head); git_commit_free(commit); @@ -396,8 +396,8 @@ void test_cherrypick_workdir__merge_fails_without_mainline_specified(void) cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_must_fail(git_cherrypick(repo, commit, NULL)); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); git_commit_free(commit); git_commit_free(head); diff --git a/tests/clar_libgit2.c b/tests/clar_libgit2.c index adea597e35e..55a09d11135 100644 --- a/tests/clar_libgit2.c +++ b/tests/clar_libgit2.c @@ -1,6 +1,6 @@ #include "clar_libgit2.h" #include "posix.h" -#include "path.h" +#include "fs_path.h" #include "git2/sys/repository.h" void cl_git_report_failure( @@ -281,7 +281,7 @@ const char* cl_git_path_url(const char *path) git_str path_buf = GIT_STR_INIT; git_str url_buf = GIT_STR_INIT; - cl_git_pass(git_path_prettify_dir(&path_buf, path, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&path_buf, path, NULL)); cl_git_pass(git_str_puts(&url_buf, "file://")); #ifdef GIT_WIN32 @@ -336,9 +336,9 @@ const char *cl_git_sandbox_path(int is_dir, ...) } va_end(arg); - cl_git_pass(git_path_prettify(&buf, buf.ptr, NULL)); + cl_git_pass(git_fs_path_prettify(&buf, buf.ptr, NULL)); if (is_dir) - git_path_to_dir(&buf); + git_fs_path_to_dir(&buf); /* make sure we won't truncate */ cl_assert(git_str_len(&buf) < sizeof(_temp)); @@ -359,8 +359,8 @@ static int remove_placeholders_recurs(void *_data, git_str *path) remove_data *data = (remove_data *)_data; size_t pathlen; - if (git_path_isdir(path->ptr) == true) - return git_path_direach(path, 0, remove_placeholders_recurs, data); + if (git_fs_path_isdir(path->ptr) == true) + return git_fs_path_direach(path, 0, remove_placeholders_recurs, data); pathlen = path->size; @@ -382,7 +382,7 @@ int cl_git_remove_placeholders(const char *directory_path, const char *filename) remove_data data; git_str buffer = GIT_STR_INIT; - if (git_path_isdir(directory_path) == false) + if (git_fs_path_isdir(directory_path) == false) return -1; if (git_str_sets(&buffer, directory_path) < 0) @@ -570,9 +570,9 @@ void cl_fake_home(void) cl_set_cleanup(cl_fake_home_cleanup, NULL); - if (!git_path_exists("home")) + if (!git_fs_path_exists("home")) cl_must_pass(p_mkdir("home", 0777)); - cl_git_pass(git_path_prettify(&path, "home", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "home", NULL)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr)); git_str_dispose(&path); @@ -584,7 +584,7 @@ void cl_sandbox_set_search_path_defaults(void) git_str_joinpath(&path, clar_sandbox_path(), "__config"); - if (!git_path_exists(path.ptr)) + if (!git_fs_path_exists(path.ptr)) cl_must_pass(p_mkdir(path.ptr, 0777)); git_libgit2_opts( diff --git a/tests/clone/nonetwork.c b/tests/clone/nonetwork.c index 7625a218306..c3515b53f24 100644 --- a/tests/clone/nonetwork.c +++ b/tests/clone/nonetwork.c @@ -51,10 +51,10 @@ void test_clone_nonetwork__bad_urls(void) { /* Clone should clean up the mess if the URL isn't a git repository */ cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options)); - cl_assert(!git_path_exists("./foo")); + cl_assert(!git_fs_path_exists("./foo")); g_options.bare = true; cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options)); - cl_assert(!git_path_exists("./foo")); + cl_assert(!git_fs_path_exists("./foo")); cl_git_fail(git_clone(&g_repo, "git://example.com:asdf", "./foo", &g_options)); cl_git_fail(git_clone(&g_repo, "https://example.com:asdf/foo", "./foo", &g_options)); @@ -70,12 +70,12 @@ void test_clone_nonetwork__do_not_clean_existing_directory(void) * Should clean up entries it creates. */ p_mkdir("./foo", GIT_DIR_MODE); cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options)); - cl_assert(git_path_is_empty_dir("./foo")); + cl_assert(git_fs_path_is_empty_dir("./foo")); /* Try again with a bare repository. */ g_options.bare = true; cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options)); - cl_assert(git_path_is_empty_dir("./foo")); + cl_assert(git_fs_path_is_empty_dir("./foo")); } void test_clone_nonetwork__local(void) @@ -151,7 +151,7 @@ void test_clone_nonetwork__can_prevent_the_checkout_of_a_standard_repo(void) cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&path))); git_str_dispose(&path); } @@ -168,7 +168,7 @@ void test_clone_nonetwork__can_checkout_given_branch(void) cl_git_pass(git_repository_head(&g_ref, g_repo)); cl_assert_equal_s(git_reference_name(g_ref), "refs/heads/test"); - cl_assert(git_path_exists("foo/readme.txt")); + cl_assert(git_fs_path_exists("foo/readme.txt")); cl_git_pass(git_reference_lookup(&remote_head, g_repo, "refs/remotes/origin/HEAD")); cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(remote_head)); @@ -196,7 +196,7 @@ void test_clone_nonetwork__can_cancel_clone_in_fetch(void) -54321); cl_assert(!g_repo); - cl_assert(!git_path_exists("foo/readme.txt")); + cl_assert(!git_fs_path_exists("foo/readme.txt")); } static int clone_cancel_checkout_cb( @@ -227,7 +227,7 @@ void test_clone_nonetwork__can_cancel_clone_in_checkout(void) -12345); cl_assert(!g_repo); - cl_assert(!git_path_exists("foo/readme.txt")); + cl_assert(!git_fs_path_exists("foo/readme.txt")); } void test_clone_nonetwork__can_detached_head(void) diff --git a/tests/config/global.c b/tests/config/global.c index d59c39fa2e2..5aba4eec69e 100644 --- a/tests/config/global.c +++ b/tests/config/global.c @@ -6,17 +6,17 @@ void test_config_global__initialize(void) git_str path = GIT_STR_INIT; cl_git_pass(git_futils_mkdir_r("home", 0777)); - cl_git_pass(git_path_prettify(&path, "home", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "home", NULL)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr)); cl_git_pass(git_futils_mkdir_r("xdg/git", 0777)); - cl_git_pass(git_path_prettify(&path, "xdg/git", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "xdg/git", NULL)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr)); cl_git_pass(git_futils_mkdir_r("etc", 0777)); - cl_git_pass(git_path_prettify(&path, "etc", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "etc", NULL)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr)); @@ -141,7 +141,7 @@ void test_config_global__open_programdata(void) cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_PROGRAMDATA, &dir_path)); - if (!git_path_isdir(dir_path.ptr)) + if (!git_fs_path_isdir(dir_path.ptr)) cl_git_pass(p_mkdir(dir_path.ptr, 0777)); cl_git_pass(git_str_joinpath(&config_path, dir_path.ptr, "config")); diff --git a/tests/config/read.c b/tests/config/read.c index 77f8a126222..3c96f851955 100644 --- a/tests/config/read.c +++ b/tests/config/read.c @@ -1,5 +1,5 @@ #include "clar_libgit2.h" -#include "path.h" +#include "fs_path.h" static git_buf buf = GIT_BUF_INIT; @@ -705,11 +705,11 @@ void test_config_read__path(void) git_str expected_path = GIT_STR_INIT; cl_git_pass(p_mkdir("fakehome", 0777)); - cl_git_pass(git_path_prettify(&home_path, "fakehome", NULL)); + cl_git_pass(git_fs_path_prettify(&home_path, "fakehome", NULL)); cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &old_path)); cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, home_path.ptr)); cl_git_mkfile("./testconfig", "[some]\n path = ~/somefile"); - cl_git_pass(git_path_join_unrooted(&expected_path, "somefile", home_path.ptr, NULL)); + cl_git_pass(git_fs_path_join_unrooted(&expected_path, "somefile", home_path.ptr, NULL)); cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig")); cl_git_pass(git_config_get_path(&path, cfg, "some.path")); @@ -717,7 +717,7 @@ void test_config_read__path(void) git_buf_dispose(&path); cl_git_mkfile("./testconfig", "[some]\n path = ~/"); - cl_git_pass(git_path_join_unrooted(&expected_path, "", home_path.ptr, NULL)); + cl_git_pass(git_fs_path_join_unrooted(&expected_path, "", home_path.ptr, NULL)); cl_git_pass(git_config_get_path(&path, cfg, "some.path")); cl_assert_equal_s(expected_path.ptr, path.ptr); diff --git a/tests/config/readonly.c b/tests/config/readonly.c index 5d544b8cb4a..a8901e394c0 100644 --- a/tests/config/readonly.c +++ b/tests/config/readonly.c @@ -25,7 +25,7 @@ void test_config_readonly__writing_to_readonly_fails(void) cl_git_pass(git_config_add_backend(cfg, backend, GIT_CONFIG_LEVEL_GLOBAL, NULL, 0)); cl_git_fail_with(GIT_ENOTFOUND, git_config_set_string(cfg, "foo.bar", "baz")); - cl_assert(!git_path_exists("global")); + cl_assert(!git_fs_path_exists("global")); } void test_config_readonly__writing_to_cfg_with_rw_precedence_succeeds(void) @@ -41,8 +41,8 @@ void test_config_readonly__writing_to_cfg_with_rw_precedence_succeeds(void) cl_git_pass(git_config_set_string(cfg, "foo.bar", "baz")); - cl_assert(git_path_exists("local")); - cl_assert(!git_path_exists("global")); + cl_assert(git_fs_path_exists("local")); + cl_assert(!git_fs_path_exists("global")); cl_git_pass(p_unlink("local")); } @@ -59,7 +59,7 @@ void test_config_readonly__writing_to_cfg_with_ro_precedence_succeeds(void) cl_git_pass(git_config_set_string(cfg, "foo.bar", "baz")); - cl_assert(!git_path_exists("local")); - cl_assert(git_path_exists("global")); + cl_assert(!git_fs_path_exists("local")); + cl_assert(git_fs_path_exists("global")); cl_git_pass(p_unlink("global")); } diff --git a/tests/config/stress.c b/tests/config/stress.c index 7ec274b187a..c823284ff29 100644 --- a/tests/config/stress.c +++ b/tests/config/stress.c @@ -30,7 +30,7 @@ void test_config_stress__dont_break_on_invalid_input(void) { git_config *config; - cl_assert(git_path_exists(TEST_CONFIG)); + cl_assert(git_fs_path_exists(TEST_CONFIG)); cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_get_string_buf(&buf, config, "color.ui")); @@ -72,7 +72,7 @@ void test_config_stress__escape_subsection_names(void) { git_config *config; - cl_assert(git_path_exists("git-test-config")); + cl_assert(git_fs_path_exists("git-test-config")); cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_set_string(config, "some.sec\\tion.other", "foo")); @@ -90,7 +90,7 @@ void test_config_stress__trailing_backslash(void) git_config *config; const char *path = "C:\\iam\\some\\windows\\path\\"; - cl_assert(git_path_exists("git-test-config")); + cl_assert(git_fs_path_exists("git-test-config")); cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_set_string(config, "windows.path", path)); git_config_free(config); diff --git a/tests/core/copy.c b/tests/core/copy.c index d3127480835..2b90fb6bfdf 100644 --- a/tests/core/copy.c +++ b/tests/core/copy.c @@ -12,7 +12,7 @@ void test_core_copy__file(void) cl_git_pass(git_futils_cp("copy_me", "copy_me_two", 0664)); - cl_git_pass(git_path_lstat("copy_me_two", &st)); + cl_git_pass(git_fs_path_lstat("copy_me_two", &st)); cl_assert(S_ISREG(st.st_mode)); cl_assert(strlen(content) == (size_t)st.st_size); @@ -27,7 +27,7 @@ void test_core_copy__file_in_dir(void) cl_git_pass(git_futils_mkdir("an_dir/in_a_dir", 0775, GIT_MKDIR_PATH)); cl_git_mkfile("an_dir/in_a_dir/copy_me", content); - cl_assert(git_path_isdir("an_dir")); + cl_assert(git_fs_path_isdir("an_dir")); cl_git_pass(git_futils_mkpath2file ("an_dir/second_dir/and_more/copy_me_two", 0775)); @@ -37,12 +37,12 @@ void test_core_copy__file_in_dir(void) "an_dir/second_dir/and_more/copy_me_two", 0664)); - cl_git_pass(git_path_lstat("an_dir/second_dir/and_more/copy_me_two", &st)); + cl_git_pass(git_fs_path_lstat("an_dir/second_dir/and_more/copy_me_two", &st)); cl_assert(S_ISREG(st.st_mode)); cl_assert(strlen(content) == (size_t)st.st_size); cl_git_pass(git_futils_rmdir_r("an_dir", NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(!git_path_isdir("an_dir")); + cl_assert(!git_fs_path_isdir("an_dir")); } void assert_hard_link(const char *path) @@ -50,7 +50,7 @@ void assert_hard_link(const char *path) /* we assert this by checking that there's more than one link to the file */ struct stat st; - cl_assert(git_path_isfile(path)); + cl_assert(git_fs_path_isfile(path)); cl_git_pass(p_stat(path, &st)); cl_assert(st.st_nlink > 1); } @@ -74,73 +74,73 @@ void test_core_copy__tree(void) cl_assert(p_symlink("../../b/f2", "src/c/d/l1") == 0); #endif - cl_assert(git_path_isdir("src")); - cl_assert(git_path_isdir("src/b")); - cl_assert(git_path_isdir("src/c/d")); - cl_assert(git_path_isfile("src/c/d/f4")); + cl_assert(git_fs_path_isdir("src")); + cl_assert(git_fs_path_isdir("src/b")); + cl_assert(git_fs_path_isdir("src/c/d")); + cl_assert(git_fs_path_isfile("src/c/d/f4")); /* copy with no empty dirs, yes links, no dotfiles, no overwrite */ cl_git_pass( git_futils_cp_r("src", "t1", GIT_CPDIR_COPY_SYMLINKS, 0) ); - cl_assert(git_path_isdir("t1")); - cl_assert(git_path_isdir("t1/b")); - cl_assert(git_path_isdir("t1/c")); - cl_assert(git_path_isdir("t1/c/d")); - cl_assert(!git_path_isdir("t1/c/e")); + cl_assert(git_fs_path_isdir("t1")); + cl_assert(git_fs_path_isdir("t1/b")); + cl_assert(git_fs_path_isdir("t1/c")); + cl_assert(git_fs_path_isdir("t1/c/d")); + cl_assert(!git_fs_path_isdir("t1/c/e")); - cl_assert(git_path_isfile("t1/f1")); - cl_assert(git_path_isfile("t1/b/f2")); - cl_assert(git_path_isfile("t1/c/f3")); - cl_assert(git_path_isfile("t1/c/d/f4")); - cl_assert(!git_path_isfile("t1/c/d/.f5")); + cl_assert(git_fs_path_isfile("t1/f1")); + cl_assert(git_fs_path_isfile("t1/b/f2")); + cl_assert(git_fs_path_isfile("t1/c/f3")); + cl_assert(git_fs_path_isfile("t1/c/d/f4")); + cl_assert(!git_fs_path_isfile("t1/c/d/.f5")); - cl_git_pass(git_path_lstat("t1/c/f3", &st)); + cl_git_pass(git_fs_path_lstat("t1/c/f3", &st)); cl_assert(S_ISREG(st.st_mode)); cl_assert(strlen(content) == (size_t)st.st_size); #ifndef GIT_WIN32 - cl_git_pass(git_path_lstat("t1/c/d/l1", &st)); + cl_git_pass(git_fs_path_lstat("t1/c/d/l1", &st)); cl_assert(S_ISLNK(st.st_mode)); #endif cl_git_pass(git_futils_rmdir_r("t1", NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(!git_path_isdir("t1")); + cl_assert(!git_fs_path_isdir("t1")); /* copy with empty dirs, no links, yes dotfiles, no overwrite */ cl_git_pass( git_futils_cp_r("src", "t2", GIT_CPDIR_CREATE_EMPTY_DIRS | GIT_CPDIR_COPY_DOTFILES, 0) ); - cl_assert(git_path_isdir("t2")); - cl_assert(git_path_isdir("t2/b")); - cl_assert(git_path_isdir("t2/c")); - cl_assert(git_path_isdir("t2/c/d")); - cl_assert(git_path_isdir("t2/c/e")); + cl_assert(git_fs_path_isdir("t2")); + cl_assert(git_fs_path_isdir("t2/b")); + cl_assert(git_fs_path_isdir("t2/c")); + cl_assert(git_fs_path_isdir("t2/c/d")); + cl_assert(git_fs_path_isdir("t2/c/e")); - cl_assert(git_path_isfile("t2/f1")); - cl_assert(git_path_isfile("t2/b/f2")); - cl_assert(git_path_isfile("t2/c/f3")); - cl_assert(git_path_isfile("t2/c/d/f4")); - cl_assert(git_path_isfile("t2/c/d/.f5")); + cl_assert(git_fs_path_isfile("t2/f1")); + cl_assert(git_fs_path_isfile("t2/b/f2")); + cl_assert(git_fs_path_isfile("t2/c/f3")); + cl_assert(git_fs_path_isfile("t2/c/d/f4")); + cl_assert(git_fs_path_isfile("t2/c/d/.f5")); #ifndef GIT_WIN32 - cl_git_fail(git_path_lstat("t2/c/d/l1", &st)); + cl_git_fail(git_fs_path_lstat("t2/c/d/l1", &st)); #endif cl_git_pass(git_futils_rmdir_r("t2", NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(!git_path_isdir("t2")); + cl_assert(!git_fs_path_isdir("t2")); #ifndef GIT_WIN32 cl_git_pass(git_futils_cp_r("src", "t3", GIT_CPDIR_CREATE_EMPTY_DIRS | GIT_CPDIR_LINK_FILES, 0)); - cl_assert(git_path_isdir("t3")); + cl_assert(git_fs_path_isdir("t3")); - cl_assert(git_path_isdir("t3")); - cl_assert(git_path_isdir("t3/b")); - cl_assert(git_path_isdir("t3/c")); - cl_assert(git_path_isdir("t3/c/d")); - cl_assert(git_path_isdir("t3/c/e")); + cl_assert(git_fs_path_isdir("t3")); + cl_assert(git_fs_path_isdir("t3/b")); + cl_assert(git_fs_path_isdir("t3/c")); + cl_assert(git_fs_path_isdir("t3/c/d")); + cl_assert(git_fs_path_isdir("t3/c/e")); assert_hard_link("t3/f1"); assert_hard_link("t3/b/f2"); diff --git a/tests/core/dirent.c b/tests/core/dirent.c index ce93e0358e5..2419ec7ab92 100644 --- a/tests/core/dirent.c +++ b/tests/core/dirent.c @@ -113,7 +113,7 @@ void test_core_dirent__dont_traverse_dot(void) cl_set_cleanup(&dirent_cleanup__cb, &dot); setup(&dot); - cl_git_pass(git_path_direach(&dot.path, 0, one_entry, &dot)); + cl_git_pass(git_fs_path_direach(&dot.path, 0, one_entry, &dot)); check_counts(&dot); } @@ -137,7 +137,7 @@ void test_core_dirent__traverse_subfolder(void) cl_set_cleanup(&dirent_cleanup__cb, &sub); setup(&sub); - cl_git_pass(git_path_direach(&sub.path, 0, one_entry, &sub)); + cl_git_pass(git_fs_path_direach(&sub.path, 0, one_entry, &sub)); check_counts(&sub); } @@ -155,7 +155,7 @@ void test_core_dirent__traverse_slash_terminated_folder(void) cl_set_cleanup(&dirent_cleanup__cb, &sub_slash); setup(&sub_slash); - cl_git_pass(git_path_direach(&sub_slash.path, 0, one_entry, &sub_slash)); + cl_git_pass(git_fs_path_direach(&sub_slash.path, 0, one_entry, &sub_slash)); check_counts(&sub_slash); } @@ -176,12 +176,12 @@ void test_core_dirent__dont_traverse_empty_folders(void) cl_set_cleanup(&dirent_cleanup__cb, &empty); setup(&empty); - cl_git_pass(git_path_direach(&empty.path, 0, one_entry, &empty)); + cl_git_pass(git_fs_path_direach(&empty.path, 0, one_entry, &empty)); check_counts(&empty); /* make sure callback not called */ - cl_assert(git_path_is_empty_dir(empty.path.ptr)); + cl_assert(git_fs_path_is_empty_dir(empty.path.ptr)); } static name_data odd_names[] = { @@ -204,7 +204,7 @@ void test_core_dirent__traverse_weird_filenames(void) cl_set_cleanup(&dirent_cleanup__cb, &odd); setup(&odd); - cl_git_pass(git_path_direach(&odd.path, 0, one_entry, &odd)); + cl_git_pass(git_fs_path_direach(&odd.path, 0, one_entry, &odd)); check_counts(&odd); } @@ -224,30 +224,30 @@ void test_core_dirent__length_limits(void) void test_core_dirent__empty_dir(void) { cl_must_pass(p_mkdir("empty_dir", 0777)); - cl_assert(git_path_is_empty_dir("empty_dir")); + cl_assert(git_fs_path_is_empty_dir("empty_dir")); cl_git_mkfile("empty_dir/content", "whatever\n"); - cl_assert(!git_path_is_empty_dir("empty_dir")); - cl_assert(!git_path_is_empty_dir("empty_dir/content")); + cl_assert(!git_fs_path_is_empty_dir("empty_dir")); + cl_assert(!git_fs_path_is_empty_dir("empty_dir/content")); cl_must_pass(p_unlink("empty_dir/content")); cl_must_pass(p_mkdir("empty_dir/content", 0777)); - cl_assert(!git_path_is_empty_dir("empty_dir")); - cl_assert(git_path_is_empty_dir("empty_dir/content")); + cl_assert(!git_fs_path_is_empty_dir("empty_dir")); + cl_assert(git_fs_path_is_empty_dir("empty_dir/content")); cl_must_pass(p_rmdir("empty_dir/content")); cl_must_pass(p_rmdir("empty_dir")); } -static void handle_next(git_path_diriter *diriter, walk_data *walk) +static void handle_next(git_fs_path_diriter *diriter, walk_data *walk) { const char *fullpath, *filename; size_t fullpath_len, filename_len; - cl_git_pass(git_path_diriter_fullpath(&fullpath, &fullpath_len, diriter)); - cl_git_pass(git_path_diriter_filename(&filename, &filename_len, diriter)); + cl_git_pass(git_fs_path_diriter_fullpath(&fullpath, &fullpath_len, diriter)); + cl_git_pass(git_fs_path_diriter_filename(&filename, &filename_len, diriter)); cl_assert_equal_strn(fullpath, "sub/", 4); cl_assert_equal_s(fullpath+4, filename); @@ -258,42 +258,42 @@ static void handle_next(git_path_diriter *diriter, walk_data *walk) /* test directory iterator */ void test_core_dirent__diriter_with_fullname(void) { - git_path_diriter diriter = GIT_PATH_DIRITER_INIT; + git_fs_path_diriter diriter = GIT_FS_PATH_DIRITER_INIT; int error; cl_set_cleanup(&dirent_cleanup__cb, &sub); setup(&sub); - cl_git_pass(git_path_diriter_init(&diriter, sub.path.ptr, 0)); + cl_git_pass(git_fs_path_diriter_init(&diriter, sub.path.ptr, 0)); - while ((error = git_path_diriter_next(&diriter)) == 0) + while ((error = git_fs_path_diriter_next(&diriter)) == 0) handle_next(&diriter, &sub); cl_assert_equal_i(error, GIT_ITEROVER); - git_path_diriter_free(&diriter); + git_fs_path_diriter_free(&diriter); check_counts(&sub); } void test_core_dirent__diriter_at_directory_root(void) { - git_path_diriter diriter = GIT_PATH_DIRITER_INIT; + git_fs_path_diriter diriter = GIT_FS_PATH_DIRITER_INIT; const char *sandbox_path, *path; char *root_path; size_t path_len; int root_offset, error; sandbox_path = clar_sandbox_path(); - cl_assert((root_offset = git_path_root(sandbox_path)) >= 0); + cl_assert((root_offset = git_fs_path_root(sandbox_path)) >= 0); cl_assert(root_path = git__calloc(1, root_offset + 2)); strncpy(root_path, sandbox_path, root_offset + 1); - cl_git_pass(git_path_diriter_init(&diriter, root_path, 0)); + cl_git_pass(git_fs_path_diriter_init(&diriter, root_path, 0)); - while ((error = git_path_diriter_next(&diriter)) == 0) { - cl_git_pass(git_path_diriter_fullpath(&path, &path_len, &diriter)); + while ((error = git_fs_path_diriter_next(&diriter)) == 0) { + cl_git_pass(git_fs_path_diriter_fullpath(&path, &path_len, &diriter)); cl_assert(path_len > (size_t)(root_offset + 1)); cl_assert(path[root_offset+1] != '/'); @@ -301,6 +301,6 @@ void test_core_dirent__diriter_at_directory_root(void) cl_assert_equal_i(error, GIT_ITEROVER); - git_path_diriter_free(&diriter); + git_fs_path_diriter_free(&diriter); git__free(root_path); } diff --git a/tests/core/env.c b/tests/core/env.c index 9a3f0ae76da..88c5c6aa3be 100644 --- a/tests/core/env.c +++ b/tests/core/env.c @@ -103,7 +103,7 @@ void test_core_env__0(void) continue; } - cl_git_pass(git_path_prettify(&path, *val, NULL)); + cl_git_pass(git_fs_path_prettify(&path, *val, NULL)); /* vary testfile name in each directory so accidentally leaving * an environment variable set from a previous iteration won't @@ -137,7 +137,7 @@ void test_core_env__0(void) cl_git_pass(git_sysdir_find_global_file(&found, testfile)); { - int root = git_path_root(path.ptr); + int root = git_fs_path_root(path.ptr); char old; if (root >= 0) { @@ -270,7 +270,7 @@ void test_core_env__2(void) continue; } - cl_git_pass(git_path_prettify(&path, *val, NULL)); + cl_git_pass(git_fs_path_prettify(&path, *val, NULL)); /* vary testfile name so any sloppiness is resetting variables or * deleting files won't accidentally make a test pass. diff --git a/tests/core/filebuf.c b/tests/core/filebuf.c index 6f654f523e6..6f40c24569f 100644 --- a/tests/core/filebuf.c +++ b/tests/core/filebuf.c @@ -14,7 +14,7 @@ void test_core_filebuf__0(void) cl_must_pass(p_close(fd)); cl_git_fail(git_filebuf_open(&file, test, 0, 0666)); - cl_assert(git_path_exists(testlock)); + cl_assert(git_fs_path_exists(testlock)); cl_must_pass(p_unlink(testlock)); } @@ -142,14 +142,14 @@ void test_core_filebuf__rename_error(void) cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks")); - cl_assert_equal_i(true, git_path_exists(test_lock)); + cl_assert_equal_i(true, git_fs_path_exists(test_lock)); cl_git_fail(git_filebuf_commit(&file)); p_close(fd); git_filebuf_cleanup(&file); - cl_assert_equal_i(false, git_path_exists(test_lock)); + cl_assert_equal_i(false, git_fs_path_exists(test_lock)); } void test_core_filebuf__symlink_follow(void) @@ -157,7 +157,7 @@ void test_core_filebuf__symlink_follow(void) git_filebuf file = GIT_FILEBUF_INIT; const char *dir = "linkdir", *source = "linkdir/link"; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) cl_skip(); cl_git_pass(p_mkdir(dir, 0777)); @@ -166,10 +166,10 @@ void test_core_filebuf__symlink_follow(void) cl_git_pass(git_filebuf_open(&file, source, 0, 0666)); cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks")); - cl_assert_equal_i(true, git_path_exists("linkdir/target.lock")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target.lock")); cl_git_pass(git_filebuf_commit(&file)); - cl_assert_equal_i(true, git_path_exists("linkdir/target")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target")); git_filebuf_cleanup(&file); @@ -177,10 +177,10 @@ void test_core_filebuf__symlink_follow(void) cl_git_pass(git_filebuf_open(&file, source, 0, 0666)); cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks")); - cl_assert_equal_i(true, git_path_exists("linkdir/target.lock")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target.lock")); cl_git_pass(git_filebuf_commit(&file)); - cl_assert_equal_i(true, git_path_exists("linkdir/target")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target")); git_filebuf_cleanup(&file); cl_git_pass(git_futils_rmdir_r(dir, NULL, GIT_RMDIR_REMOVE_FILES)); @@ -191,7 +191,7 @@ void test_core_filebuf__symlink_follow_absolute_paths(void) git_filebuf file = GIT_FILEBUF_INIT; git_str source = GIT_STR_INIT, target = GIT_STR_INIT; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) cl_skip(); cl_git_pass(git_str_joinpath(&source, clar_sandbox_path(), "linkdir/link")); @@ -202,10 +202,10 @@ void test_core_filebuf__symlink_follow_absolute_paths(void) cl_git_pass(git_filebuf_open(&file, source.ptr, 0, 0666)); cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks")); - cl_assert_equal_i(true, git_path_exists("linkdir/target.lock")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target.lock")); cl_git_pass(git_filebuf_commit(&file)); - cl_assert_equal_i(true, git_path_exists("linkdir/target")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target")); git_filebuf_cleanup(&file); git_str_dispose(&source); @@ -219,7 +219,7 @@ void test_core_filebuf__symlink_depth(void) git_filebuf file = GIT_FILEBUF_INIT; const char *dir = "linkdir", *source = "linkdir/link"; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) cl_skip(); cl_git_pass(p_mkdir(dir, 0777)); diff --git a/tests/core/futils.c b/tests/core/futils.c index d08043b6edd..b87ea183bea 100644 --- a/tests/core/futils.c +++ b/tests/core/futils.c @@ -68,7 +68,7 @@ void test_core_futils__write_hidden_file(void) void test_core_futils__recursive_rmdir_keeps_symlink_targets(void) { - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) cl_skip(); cl_git_pass(git_futils_mkdir_r("a/b", 0777)); @@ -80,8 +80,8 @@ void test_core_futils__recursive_rmdir_keeps_symlink_targets(void) cl_git_pass(git_futils_rmdir_r("a", NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(git_path_exists("dir-target")); - cl_assert(git_path_exists("file-target")); + cl_assert(git_fs_path_exists("dir-target")); + cl_assert(git_fs_path_exists("file-target")); cl_must_pass(p_unlink("dir-target/file")); cl_must_pass(p_rmdir("dir-target")); diff --git a/tests/core/iconv.c b/tests/core/iconv.c index 498094bdbb8..af1b4eabf48 100644 --- a/tests/core/iconv.c +++ b/tests/core/iconv.c @@ -1,8 +1,8 @@ #include "clar_libgit2.h" -#include "path.h" +#include "fs_path.h" #ifdef GIT_USE_ICONV -static git_path_iconv_t ic; +static git_fs_path_iconv_t ic; static char *nfc = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D"; static char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"; #endif @@ -10,14 +10,14 @@ static char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"; void test_core_iconv__initialize(void) { #ifdef GIT_USE_ICONV - cl_git_pass(git_path_iconv_init_precompose(&ic)); + cl_git_pass(git_fs_path_iconv_init_precompose(&ic)); #endif } void test_core_iconv__cleanup(void) { #ifdef GIT_USE_ICONV - git_path_iconv_clear(&ic); + git_fs_path_iconv_clear(&ic); #endif } @@ -27,7 +27,7 @@ void test_core_iconv__unchanged(void) const char *data = "Ascii data", *original = data; size_t datalen = strlen(data); - cl_git_pass(git_path_iconv(&ic, &data, &datalen)); + cl_git_pass(git_fs_path_iconv(&ic, &data, &datalen)); GIT_UNUSED(datalen); /* There are no high bits set, so this should leave data untouched */ @@ -42,7 +42,7 @@ void test_core_iconv__decomposed_to_precomposed(void) size_t datalen, nfdlen = strlen(nfd); datalen = nfdlen; - cl_git_pass(git_path_iconv(&ic, &data, &datalen)); + cl_git_pass(git_fs_path_iconv(&ic, &data, &datalen)); GIT_UNUSED(datalen); /* The decomposed nfd string should be transformed to the nfc form @@ -50,13 +50,13 @@ void test_core_iconv__decomposed_to_precomposed(void) */ cl_assert_equal_s(nfc, data); - /* should be able to do it multiple times with the same git_path_iconv_t */ + /* should be able to do it multiple times with the same git_fs_path_iconv_t */ data = nfd; datalen = nfdlen; - cl_git_pass(git_path_iconv(&ic, &data, &datalen)); + cl_git_pass(git_fs_path_iconv(&ic, &data, &datalen)); cl_assert_equal_s(nfc, data); data = nfd; datalen = nfdlen; - cl_git_pass(git_path_iconv(&ic, &data, &datalen)); + cl_git_pass(git_fs_path_iconv(&ic, &data, &datalen)); cl_assert_equal_s(nfc, data); #endif } @@ -67,7 +67,7 @@ void test_core_iconv__precomposed_is_unmodified(void) const char *data = nfc; size_t datalen = strlen(nfc); - cl_git_pass(git_path_iconv(&ic, &data, &datalen)); + cl_git_pass(git_fs_path_iconv(&ic, &data, &datalen)); GIT_UNUSED(datalen); /* data is already in precomposed form, so even though some bytes have diff --git a/tests/core/mkdir.c b/tests/core/mkdir.c index f0461ac1f27..8d4b9afd67b 100644 --- a/tests/core/mkdir.c +++ b/tests/core/mkdir.c @@ -22,32 +22,32 @@ void test_core_mkdir__absolute(void) git_str_joinpath(&path, clar_sandbox_path(), "d0"); /* make a directory */ - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir(path.ptr, 0755, 0)); - cl_assert(git_path_isdir(path.ptr)); + cl_assert(git_fs_path_isdir(path.ptr)); git_str_joinpath(&path, path.ptr, "subdir"); - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir(path.ptr, 0755, 0)); - cl_assert(git_path_isdir(path.ptr)); + cl_assert(git_fs_path_isdir(path.ptr)); /* ensure mkdir_r works for a single subdir */ git_str_joinpath(&path, path.ptr, "another"); - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir_r(path.ptr, 0755)); - cl_assert(git_path_isdir(path.ptr)); + cl_assert(git_fs_path_isdir(path.ptr)); /* ensure mkdir_r works */ git_str_joinpath(&path, clar_sandbox_path(), "d1/foo/bar/asdf"); - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir_r(path.ptr, 0755)); - cl_assert(git_path_isdir(path.ptr)); + cl_assert(git_fs_path_isdir(path.ptr)); /* ensure we don't imply recursive */ git_str_joinpath(&path, clar_sandbox_path(), "d2/foo/bar/asdf"); - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); cl_git_fail(git_futils_mkdir(path.ptr, 0755, 0)); - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); git_str_dispose(&path); } @@ -57,39 +57,39 @@ void test_core_mkdir__basic(void) cl_set_cleanup(cleanup_basic_dirs, NULL); /* make a directory */ - cl_assert(!git_path_isdir("d0")); + cl_assert(!git_fs_path_isdir("d0")); cl_git_pass(git_futils_mkdir("d0", 0755, 0)); - cl_assert(git_path_isdir("d0")); + cl_assert(git_fs_path_isdir("d0")); /* make a path */ - cl_assert(!git_path_isdir("d1")); + cl_assert(!git_fs_path_isdir("d1")); cl_git_pass(git_futils_mkdir("d1/d1.1/d1.2", 0755, GIT_MKDIR_PATH)); - cl_assert(git_path_isdir("d1")); - cl_assert(git_path_isdir("d1/d1.1")); - cl_assert(git_path_isdir("d1/d1.1/d1.2")); + cl_assert(git_fs_path_isdir("d1")); + cl_assert(git_fs_path_isdir("d1/d1.1")); + cl_assert(git_fs_path_isdir("d1/d1.1/d1.2")); /* make a dir exclusively */ - cl_assert(!git_path_isdir("d2")); + cl_assert(!git_fs_path_isdir("d2")); cl_git_pass(git_futils_mkdir("d2", 0755, GIT_MKDIR_EXCL)); - cl_assert(git_path_isdir("d2")); + cl_assert(git_fs_path_isdir("d2")); /* make exclusive failure */ cl_git_fail(git_futils_mkdir("d2", 0755, GIT_MKDIR_EXCL)); /* make a path exclusively */ - cl_assert(!git_path_isdir("d3")); + cl_assert(!git_fs_path_isdir("d3")); cl_git_pass(git_futils_mkdir("d3/d3.1/d3.2", 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL)); - cl_assert(git_path_isdir("d3")); - cl_assert(git_path_isdir("d3/d3.1/d3.2")); + cl_assert(git_fs_path_isdir("d3")); + cl_assert(git_fs_path_isdir("d3/d3.1/d3.2")); /* make exclusive path failure */ cl_git_fail(git_futils_mkdir("d3/d3.1/d3.2", 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL)); /* ??? Should EXCL only apply to the last item in the path? */ /* path with trailing slash? */ - cl_assert(!git_path_isdir("d4")); + cl_assert(!git_fs_path_isdir("d4")); cl_git_pass(git_futils_mkdir("d4/d4.1/", 0755, GIT_MKDIR_PATH)); - cl_assert(git_path_isdir("d4/d4.1")); + cl_assert(git_fs_path_isdir("d4/d4.1")); } static void cleanup_basedir(void *ref) @@ -107,10 +107,10 @@ void test_core_mkdir__with_base(void) cl_git_pass(git_futils_mkdir(BASEDIR, 0755, GIT_MKDIR_PATH)); cl_git_pass(git_futils_mkdir_relative("a", BASEDIR, 0755, 0, NULL)); - cl_assert(git_path_isdir(BASEDIR "/a")); + cl_assert(git_fs_path_isdir(BASEDIR "/a")); cl_git_pass(git_futils_mkdir_relative("b/b1/b2", BASEDIR, 0755, GIT_MKDIR_PATH, NULL)); - cl_assert(git_path_isdir(BASEDIR "/b/b1/b2")); + cl_assert(git_fs_path_isdir(BASEDIR "/b/b1/b2")); /* exclusive with existing base */ cl_git_pass(git_futils_mkdir_relative("c/c1/c2", BASEDIR, 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL, NULL)); @@ -126,7 +126,7 @@ void test_core_mkdir__with_base(void) /* path with shorter base and existing dirs */ cl_git_pass(git_futils_mkdir_relative("dir/here/d/", "base", 0755, GIT_MKDIR_PATH, NULL)); - cl_assert(git_path_isdir("base/dir/here/d")); + cl_assert(git_fs_path_isdir("base/dir/here/d")); /* fail: path with shorter base and existing dirs */ cl_git_fail(git_futils_mkdir_relative("dir/here/e/", "base", 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL, NULL)); @@ -179,51 +179,51 @@ void test_core_mkdir__chmods(void) cl_git_pass(git_futils_mkdir_relative("mode/is/important", "r", 0777, GIT_MKDIR_PATH, NULL)); - cl_git_pass(git_path_lstat("r/mode", &st)); + cl_git_pass(git_fs_path_lstat("r/mode", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode/is", &st)); + cl_git_pass(git_fs_path_lstat("r/mode/is", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode/is/important", &st)); + cl_git_pass(git_fs_path_lstat("r/mode/is/important", &st)); check_mode(0755, st.st_mode); cl_git_pass(git_futils_mkdir_relative("mode2/is2/important2", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD, NULL)); - cl_git_pass(git_path_lstat("r/mode2", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode2/is2", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2/is2", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode2/is2/important2", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2/is2/important2", &st)); check_mode(0777, st.st_mode); cl_git_pass(git_futils_mkdir_relative("mode3/is3/important3", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD_PATH, NULL)); - cl_git_pass(git_path_lstat("r/mode3", &st)); + cl_git_pass(git_fs_path_lstat("r/mode3", &st)); check_mode(0777, st.st_mode); - cl_git_pass(git_path_lstat("r/mode3/is3", &st)); + cl_git_pass(git_fs_path_lstat("r/mode3/is3", &st)); check_mode(0777, st.st_mode); - cl_git_pass(git_path_lstat("r/mode3/is3/important3", &st)); + cl_git_pass(git_fs_path_lstat("r/mode3/is3/important3", &st)); check_mode(0777, st.st_mode); /* test that we chmod existing dir */ cl_git_pass(git_futils_mkdir_relative("mode/is/important", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD, NULL)); - cl_git_pass(git_path_lstat("r/mode", &st)); + cl_git_pass(git_fs_path_lstat("r/mode", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode/is", &st)); + cl_git_pass(git_fs_path_lstat("r/mode/is", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode/is/important", &st)); + cl_git_pass(git_fs_path_lstat("r/mode/is/important", &st)); check_mode(0777, st.st_mode); /* test that we chmod even existing dirs if CHMOD_PATH is set */ cl_git_pass(git_futils_mkdir_relative("mode2/is2/important2.1", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD_PATH, NULL)); - cl_git_pass(git_path_lstat("r/mode2", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2", &st)); check_mode(0777, st.st_mode); - cl_git_pass(git_path_lstat("r/mode2/is2", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2/is2", &st)); check_mode(0777, st.st_mode); - cl_git_pass(git_path_lstat("r/mode2/is2/important2.1", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2/is2/important2.1", &st)); check_mode(0777, st.st_mode); } @@ -235,27 +235,27 @@ void test_core_mkdir__keeps_parent_symlinks(void) cl_set_cleanup(cleanup_basic_dirs, NULL); /* make a directory */ - cl_assert(!git_path_isdir("d0")); + cl_assert(!git_fs_path_isdir("d0")); cl_git_pass(git_futils_mkdir("d0", 0755, 0)); - cl_assert(git_path_isdir("d0")); + cl_assert(git_fs_path_isdir("d0")); cl_must_pass(symlink("d0", "d1")); - cl_assert(git_path_islink("d1")); + cl_assert(git_fs_path_islink("d1")); cl_git_pass(git_futils_mkdir("d1/foo/bar", 0755, GIT_MKDIR_PATH|GIT_MKDIR_REMOVE_SYMLINKS)); - cl_assert(git_path_islink("d1")); - cl_assert(git_path_isdir("d1/foo/bar")); - cl_assert(git_path_isdir("d0/foo/bar")); + cl_assert(git_fs_path_islink("d1")); + cl_assert(git_fs_path_isdir("d1/foo/bar")); + cl_assert(git_fs_path_isdir("d0/foo/bar")); cl_must_pass(symlink("d0", "d2")); - cl_assert(git_path_islink("d2")); + cl_assert(git_fs_path_islink("d2")); git_str_joinpath(&path, clar_sandbox_path(), "d2/other/dir"); cl_git_pass(git_futils_mkdir(path.ptr, 0755, GIT_MKDIR_PATH|GIT_MKDIR_REMOVE_SYMLINKS)); - cl_assert(git_path_islink("d2")); - cl_assert(git_path_isdir("d2/other/dir")); - cl_assert(git_path_isdir("d0/other/dir")); + cl_assert(git_fs_path_islink("d2")); + cl_assert(git_fs_path_isdir("d2/other/dir")); + cl_assert(git_fs_path_isdir("d0/other/dir")); git_str_dispose(&path); #endif @@ -276,16 +276,16 @@ void test_core_mkdir__mkdir_path_inside_unwriteable_parent(void) cl_git_pass(git_futils_mkdir("r", 0777, 0)); cl_git_pass(git_futils_mkdir_relative("mode/is/important", "r", 0777, GIT_MKDIR_PATH, NULL)); - cl_git_pass(git_path_lstat("r/mode", &st)); + cl_git_pass(git_fs_path_lstat("r/mode", &st)); check_mode(0755, st.st_mode); cl_must_pass(p_chmod("r/mode", 0111)); - cl_git_pass(git_path_lstat("r/mode", &st)); + cl_git_pass(git_fs_path_lstat("r/mode", &st)); check_mode(0111, st.st_mode); cl_git_pass( git_futils_mkdir_relative("mode/is/okay/inside", "r", 0777, GIT_MKDIR_PATH, NULL)); - cl_git_pass(git_path_lstat("r/mode/is/okay/inside", &st)); + cl_git_pass(git_fs_path_lstat("r/mode/is/okay/inside", &st)); check_mode(0755, st.st_mode); cl_must_pass(p_chmod("r/mode", 0777)); diff --git a/tests/core/path.c b/tests/core/path.c index 6decf23eaae..563dcd2a3ff 100644 --- a/tests/core/path.c +++ b/tests/core/path.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "futils.h" +#include "fs_path.h" static void check_dirname(const char *A, const char *B) @@ -7,11 +8,11 @@ check_dirname(const char *A, const char *B) git_str dir = GIT_STR_INIT; char *dir2; - cl_assert(git_path_dirname_r(&dir, A) >= 0); + cl_assert(git_fs_path_dirname_r(&dir, A) >= 0); cl_assert_equal_s(B, dir.ptr); git_str_dispose(&dir); - cl_assert((dir2 = git_path_dirname(A)) != NULL); + cl_assert((dir2 = git_fs_path_dirname(A)) != NULL); cl_assert_equal_s(B, dir2); git__free(dir2); } @@ -22,11 +23,11 @@ check_basename(const char *A, const char *B) git_str base = GIT_STR_INIT; char *base2; - cl_assert(git_path_basename_r(&base, A) >= 0); + cl_assert(git_fs_path_basename_r(&base, A) >= 0); cl_assert_equal_s(B, base.ptr); git_str_dispose(&base); - cl_assert((base2 = git_path_basename(A)) != NULL); + cl_assert((base2 = git_fs_path_basename(A)) != NULL); cl_assert_equal_s(B, base2); git__free(base2); } @@ -175,7 +176,7 @@ check_path_to_dir( git_str tgt = GIT_STR_INIT; git_str_sets(&tgt, path); - cl_git_pass(git_path_to_dir(&tgt)); + cl_git_pass(git_fs_path_to_dir(&tgt)); cl_assert_equal_s(expected, tgt.ptr); git_str_dispose(&tgt); @@ -193,7 +194,7 @@ check_string_to_dir( strncpy(buf, path, len + 2); - git_path_string_to_dir(buf, maxlen); + git_fs_path_string_to_dir(buf, maxlen); cl_assert_equal_s(expected, buf); @@ -294,10 +295,10 @@ static void check_fromurl(const char *expected_result, const char *input, int sh assert(should_fail || expected_result); if (!should_fail) { - cl_git_pass(git_path_fromurl(&buf, input)); + cl_git_pass(git_fs_path_fromurl(&buf, input)); cl_assert_equal_s(expected_result, git_str_cstr(&buf)); } else - cl_git_fail(git_path_fromurl(&buf, input)); + cl_git_fail(git_fs_path_fromurl(&buf, input)); git_str_dispose(&buf); } @@ -402,7 +403,7 @@ void test_core_path__11_walkup(void) info.expect_idx = i; cl_git_pass( - git_path_walk_up(&p, root[j], check_one_walkup_step, &info) + git_fs_path_walk_up(&p, root[j], check_one_walkup_step, &info) ); cl_assert_equal_s(p.ptr, expect[i]); @@ -439,7 +440,7 @@ void test_core_path__11a_walkup_cancel(void) cl_assert_equal_i( CANCEL_VALUE, - git_path_walk_up(&p, root[j], check_one_walkup_step, &info) + git_fs_path_walk_up(&p, root[j], check_one_walkup_step, &info) ); /* skip to next run of expectations */ @@ -451,16 +452,16 @@ void test_core_path__11a_walkup_cancel(void) void test_core_path__12_offset_to_path_root(void) { - cl_assert(git_path_root("non/rooted/path") == -1); - cl_assert(git_path_root("/rooted/path") == 0); + cl_assert(git_fs_path_root("non/rooted/path") == -1); + cl_assert(git_fs_path_root("/rooted/path") == 0); #ifdef GIT_WIN32 /* Windows specific tests */ - cl_assert(git_path_root("C:non/rooted/path") == -1); - cl_assert(git_path_root("C:/rooted/path") == 2); - cl_assert(git_path_root("//computername/sharefolder/resource") == 14); - cl_assert(git_path_root("//computername/sharefolder") == 14); - cl_assert(git_path_root("//computername") == -1); + cl_assert(git_fs_path_root("C:non/rooted/path") == -1); + cl_assert(git_fs_path_root("C:/rooted/path") == 2); + cl_assert(git_fs_path_root("//computername/sharefolder/resource") == 14); + cl_assert(git_fs_path_root("//computername/sharefolder") == 14); + cl_assert(git_fs_path_root("//computername") == -1); #endif } @@ -470,9 +471,9 @@ void test_core_path__13_cannot_prettify_a_non_existing_file(void) { git_str p = GIT_STR_INIT; - cl_assert_equal_b(git_path_exists(NON_EXISTING_FILEPATH), false); - cl_assert_equal_i(GIT_ENOTFOUND, git_path_prettify(&p, NON_EXISTING_FILEPATH, NULL)); - cl_assert_equal_i(GIT_ENOTFOUND, git_path_prettify(&p, NON_EXISTING_FILEPATH "/so-do-i", NULL)); + cl_assert_equal_b(git_fs_path_exists(NON_EXISTING_FILEPATH), false); + cl_assert_equal_i(GIT_ENOTFOUND, git_fs_path_prettify(&p, NON_EXISTING_FILEPATH, NULL)); + cl_assert_equal_i(GIT_ENOTFOUND, git_fs_path_prettify(&p, NON_EXISTING_FILEPATH "/so-do-i", NULL)); git_str_dispose(&p); } @@ -483,57 +484,57 @@ void test_core_path__14_apply_relative(void) cl_git_pass(git_str_sets(&p, "/this/is/a/base")); - cl_git_pass(git_path_apply_relative(&p, "../test")); + cl_git_pass(git_fs_path_apply_relative(&p, "../test")); cl_assert_equal_s("/this/is/a/test", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../../the/./end")); + cl_git_pass(git_fs_path_apply_relative(&p, "../../the/./end")); cl_assert_equal_s("/this/is/the/end", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "./of/this/../the/string")); + cl_git_pass(git_fs_path_apply_relative(&p, "./of/this/../the/string")); cl_assert_equal_s("/this/is/the/end/of/the/string", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../../../../../..")); + cl_git_pass(git_fs_path_apply_relative(&p, "../../../../../..")); cl_assert_equal_s("/this/", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../")); + cl_git_pass(git_fs_path_apply_relative(&p, "../")); cl_assert_equal_s("/", p.ptr); - cl_git_fail(git_path_apply_relative(&p, "../../..")); + cl_git_fail(git_fs_path_apply_relative(&p, "../../..")); cl_git_pass(git_str_sets(&p, "d:/another/test")); - cl_git_pass(git_path_apply_relative(&p, "../..")); + cl_git_pass(git_fs_path_apply_relative(&p, "../..")); cl_assert_equal_s("d:/", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "from/here/to/../and/./back/.")); + cl_git_pass(git_fs_path_apply_relative(&p, "from/here/to/../and/./back/.")); cl_assert_equal_s("d:/from/here/and/back/", p.ptr); cl_git_pass(git_str_sets(&p, "https://my.url.com/test.git")); - cl_git_pass(git_path_apply_relative(&p, "../another.git")); + cl_git_pass(git_fs_path_apply_relative(&p, "../another.git")); cl_assert_equal_s("https://my.url.com/another.git", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../full/path/url.patch")); + cl_git_pass(git_fs_path_apply_relative(&p, "../full/path/url.patch")); cl_assert_equal_s("https://my.url.com/full/path/url.patch", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "..")); + cl_git_pass(git_fs_path_apply_relative(&p, "..")); cl_assert_equal_s("https://my.url.com/full/path/", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../../../")); + cl_git_pass(git_fs_path_apply_relative(&p, "../../../")); cl_assert_equal_s("https://", p.ptr); cl_git_pass(git_str_sets(&p, "../../this/is/relative")); - cl_git_pass(git_path_apply_relative(&p, "../../preserves/the/prefix")); + cl_git_pass(git_fs_path_apply_relative(&p, "../../preserves/the/prefix")); cl_assert_equal_s("../../this/preserves/the/prefix", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../../../../that")); + cl_git_pass(git_fs_path_apply_relative(&p, "../../../../that")); cl_assert_equal_s("../../that", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../there")); + cl_git_pass(git_fs_path_apply_relative(&p, "../there")); cl_assert_equal_s("../../there", p.ptr); git_str_dispose(&p); } @@ -542,7 +543,7 @@ static void assert_resolve_relative( git_str *buf, const char *expected, const char *path) { cl_git_pass(git_str_sets(buf, path)); - cl_git_pass(git_path_resolve_relative(buf, 0)); + cl_git_pass(git_fs_path_resolve_relative(buf, 0)); cl_assert_equal_s(expected, buf->ptr); } @@ -596,22 +597,22 @@ void test_core_path__15_resolve_relative(void) assert_resolve_relative(&buf, "../d", "a/b/../../../c/../d"); cl_git_pass(git_str_sets(&buf, "/..")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); cl_git_pass(git_str_sets(&buf, "/./..")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); cl_git_pass(git_str_sets(&buf, "/.//..")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); cl_git_pass(git_str_sets(&buf, "/../.")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); cl_git_pass(git_str_sets(&buf, "/../.././../a")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); cl_git_pass(git_str_sets(&buf, "////..")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); /* things that start with Windows network paths */ #ifdef GIT_WIN32 @@ -620,7 +621,7 @@ void test_core_path__15_resolve_relative(void) assert_resolve_relative(&buf, "//a/b/c", "//a/Q/../b/x/y/../../c"); cl_git_pass(git_str_sets(&buf, "//a/b/../..")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); #else assert_resolve_relative(&buf, "/a/b/c", "//a/b/c"); assert_resolve_relative(&buf, "/a/", "//a/b/.."); @@ -632,7 +633,7 @@ void test_core_path__15_resolve_relative(void) } #define assert_common_dirlen(i, p, q) \ - cl_assert_equal_i((i), git_path_common_dirlen((p), (q))); + cl_assert_equal_i((i), git_fs_path_common_dirlen((p), (q))); void test_core_path__16_resolve_relative(void) { @@ -650,12 +651,3 @@ void test_core_path__16_resolve_relative(void) assert_common_dirlen(6, "a/b/c/foo.txt", "a/b/c/d/e/bar.txt"); assert_common_dirlen(7, "/a/b/c/foo.txt", "/a/b/c/d/e/bar.txt"); } - -void test_core_path__git_path_is_file(void) -{ - cl_git_fail(git_path_is_gitfile("blob", 4, -1, GIT_PATH_FS_HFS)); - cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITIGNORE, GIT_PATH_FS_HFS)); - cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS)); - cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITATTRIBUTES, GIT_PATH_FS_HFS)); - cl_git_fail(git_path_is_gitfile("blob", 4, 3, GIT_PATH_FS_HFS)); -} diff --git a/tests/core/posix.c b/tests/core/posix.c index 247bd43f52b..cba312913f4 100644 --- a/tests/core/posix.c +++ b/tests/core/posix.c @@ -147,7 +147,7 @@ void test_core_posix__utimes(void) void test_core_posix__unlink_removes_symlink(void) { - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) clar__skip(); cl_git_mkfile("file", "Dummy file."); @@ -159,8 +159,8 @@ void test_core_posix__unlink_removes_symlink(void) cl_must_pass(p_unlink("file-symlink")); cl_must_pass(p_unlink("dir-symlink")); - cl_assert(git_path_exists("file")); - cl_assert(git_path_exists("dir")); + cl_assert(git_fs_path_exists("file")); + cl_assert(git_fs_path_exists("dir")); cl_must_pass(p_unlink("file")); cl_must_pass(p_rmdir("dir")); @@ -170,7 +170,7 @@ void test_core_posix__symlink_resolves_to_correct_type(void) { git_str contents = GIT_STR_INIT; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) clar__skip(); cl_must_pass(git_futils_mkdir("dir", 0777, 0)); @@ -194,7 +194,7 @@ void test_core_posix__relative_symlink(void) { git_str contents = GIT_STR_INIT; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) clar__skip(); cl_must_pass(git_futils_mkdir("dir", 0777, 0)); @@ -214,7 +214,7 @@ void test_core_posix__symlink_to_file_across_dirs(void) { git_str contents = GIT_STR_INIT; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) clar__skip(); /* diff --git a/tests/core/rmdir.c b/tests/core/rmdir.c index 56ea320bea5..8e5bd5878f2 100644 --- a/tests/core/rmdir.c +++ b/tests/core/rmdir.c @@ -29,7 +29,7 @@ void test_core_rmdir__initialize(void) void test_core_rmdir__cleanup(void) { - if (git_path_exists(empty_tmp_dir)) + if (git_fs_path_exists(empty_tmp_dir)) cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_REMOVE_FILES)); } @@ -38,11 +38,11 @@ void test_core_rmdir__delete_recursive(void) { git_str path = GIT_STR_INIT; cl_git_pass(git_str_joinpath(&path, empty_tmp_dir, "/one")); - cl_assert(git_path_exists(git_str_cstr(&path))); + cl_assert(git_fs_path_exists(git_str_cstr(&path))); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY)); - cl_assert(!git_path_exists(git_str_cstr(&path))); + cl_assert(!git_fs_path_exists(git_str_cstr(&path))); git_str_dispose(&path); } @@ -61,7 +61,7 @@ void test_core_rmdir__fail_to_delete_non_empty_dir(void) cl_must_pass(p_unlink(file.ptr)); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY)); - cl_assert(!git_path_exists(empty_tmp_dir)); + cl_assert(!git_fs_path_exists(empty_tmp_dir)); git_str_dispose(&file); } @@ -69,7 +69,7 @@ void test_core_rmdir__fail_to_delete_non_empty_dir(void) void test_core_rmdir__keep_base(void) { cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_SKIP_ROOT)); - cl_assert(git_path_exists(empty_tmp_dir)); + cl_assert(git_fs_path_exists(empty_tmp_dir)); } void test_core_rmdir__can_skip_non_empty_dir(void) @@ -81,10 +81,10 @@ void test_core_rmdir__can_skip_non_empty_dir(void) cl_git_mkfile(git_str_cstr(&file), "dummy"); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_SKIP_NONEMPTY)); - cl_assert(git_path_exists(git_str_cstr(&file)) == true); + cl_assert(git_fs_path_exists(git_str_cstr(&file)) == true); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(git_path_exists(empty_tmp_dir) == false); + cl_assert(git_fs_path_exists(empty_tmp_dir) == false); git_str_dispose(&file); } @@ -96,23 +96,23 @@ void test_core_rmdir__can_remove_empty_parents(void) cl_git_pass( git_str_joinpath(&file, empty_tmp_dir, "/one/two_two/three/file.txt")); cl_git_mkfile(git_str_cstr(&file), "dummy"); - cl_assert(git_path_isfile(git_str_cstr(&file))); + cl_assert(git_fs_path_isfile(git_str_cstr(&file))); cl_git_pass(git_futils_rmdir_r("one/two_two/three/file.txt", empty_tmp_dir, GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_EMPTY_PARENTS)); - cl_assert(!git_path_exists(git_str_cstr(&file))); + cl_assert(!git_fs_path_exists(git_str_cstr(&file))); git_str_rtruncate_at_char(&file, '/'); /* three (only contained file.txt) */ - cl_assert(!git_path_exists(git_str_cstr(&file))); + cl_assert(!git_fs_path_exists(git_str_cstr(&file))); git_str_rtruncate_at_char(&file, '/'); /* two_two (only contained three) */ - cl_assert(!git_path_exists(git_str_cstr(&file))); + cl_assert(!git_fs_path_exists(git_str_cstr(&file))); git_str_rtruncate_at_char(&file, '/'); /* one (contained two_one also) */ - cl_assert(git_path_exists(git_str_cstr(&file))); + cl_assert(git_fs_path_exists(git_str_cstr(&file))); - cl_assert(git_path_exists(empty_tmp_dir) == true); + cl_assert(git_fs_path_exists(empty_tmp_dir) == true); git_str_dispose(&file); diff --git a/tests/core/stat.c b/tests/core/stat.c index 56d141e9869..022380ba66a 100644 --- a/tests/core/stat.c +++ b/tests/core/stat.c @@ -102,7 +102,7 @@ void test_core_stat__root(void) int root_len; struct stat st; - root_len = git_path_root(sandbox); + root_len = git_fs_path_root(sandbox); cl_assert(root_len >= 0); git_str_set(&root, sandbox, root_len+1); diff --git a/tests/diff/drivers.c b/tests/diff/drivers.c index ce24e9bc0b9..304a54b56dc 100644 --- a/tests/diff/drivers.c +++ b/tests/diff/drivers.c @@ -187,7 +187,7 @@ void test_diff_drivers__builtins(void) g_repo = cl_git_sandbox_init("userdiff"); - cl_git_pass(git_path_dirload(&files, "userdiff/files", 9, 0)); + cl_git_pass(git_fs_path_dirload(&files, "userdiff/files", 9, 0)); opts.interhunk_lines = 1; opts.context_lines = 1; diff --git a/tests/diff/workdir.c b/tests/diff/workdir.c index f7c74a29438..444fc2f9791 100644 --- a/tests/diff/workdir.c +++ b/tests/diff/workdir.c @@ -1252,7 +1252,7 @@ void test_diff_workdir__can_diff_empty_file(void) /* empty contents of file */ cl_git_rewritefile("attr_index/README.txt", ""); - cl_git_pass(git_path_lstat("attr_index/README.txt", &st)); + cl_git_pass(git_fs_path_lstat("attr_index/README.txt", &st)); cl_assert_equal_i(0, (int)st.st_size); cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &opts)); @@ -1265,7 +1265,7 @@ void test_diff_workdir__can_diff_empty_file(void) /* remove a file altogether */ cl_git_pass(p_unlink("attr_index/README.txt")); - cl_assert(!git_path_exists("attr_index/README.txt")); + cl_assert(!git_fs_path_exists("attr_index/README.txt")); cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &opts)); cl_assert_equal_i(3, (int)git_diff_num_deltas(diff)); @@ -1759,7 +1759,7 @@ static int touch_file(void *payload, git_str *path) struct p_timeval times[2]; GIT_UNUSED(payload); - if (git_path_isdir(path->ptr)) + if (git_fs_path_isdir(path->ptr)) return 0; cl_must_pass(p_stat(path->ptr, &st)); @@ -1805,7 +1805,7 @@ void test_diff_workdir__can_update_index(void) { git_str path = GIT_STR_INIT; cl_git_pass(git_str_sets(&path, "status")); - cl_git_pass(git_path_direach(&path, 0, touch_file, NULL)); + cl_git_pass(git_fs_path_direach(&path, 0, touch_file, NULL)); git_str_dispose(&path); } @@ -2040,7 +2040,7 @@ void test_diff_workdir__only_writes_index_when_necessary(void) /* touch all the files so stat times are different */ cl_git_pass(git_str_sets(&path, "status")); - cl_git_pass(git_path_direach(&path, 0, touch_file, NULL)); + cl_git_pass(git_fs_path_direach(&path, 0, touch_file, NULL)); cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts)); git_diff_free(diff); diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c index 0de712be871..334755cc348 100644 --- a/tests/fetchhead/nonetwork.c +++ b/tests/fetchhead/nonetwork.c @@ -446,9 +446,9 @@ void test_fetchhead_nonetwork__create_when_refpecs_given(void) cl_git_pass(git_str_joinpath(&path, git_repository_path(g_repo), "FETCH_HEAD")); cl_git_pass(git_remote_create(&remote, g_repo, "origin", cl_fixture("testrepo.git"))); - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); cl_git_pass(git_remote_fetch(remote, &specs, NULL, NULL)); - cl_assert(git_path_exists(path.ptr)); + cl_assert(git_fs_path_exists(path.ptr)); cl_git_pass(git_repository_fetchhead_foreach(g_repo, find_master_haacked, NULL)); cl_assert(find_master_haacked_called); @@ -500,9 +500,9 @@ void test_fetchhead_nonetwork__create_with_multiple_refspecs(void) cl_git_pass(git_remote_lookup(&remote, g_repo, "origin")); cl_git_pass(git_str_joinpath(&path, git_repository_path(g_repo), "FETCH_HEAD")); - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL)); - cl_assert(git_path_exists(path.ptr)); + cl_assert(git_fs_path_exists(path.ptr)); { int i; diff --git a/tests/ignore/path.c b/tests/ignore/path.c index d55bdc5dd23..a574d1d799d 100644 --- a/tests/ignore/path.c +++ b/tests/ignore/path.c @@ -257,7 +257,7 @@ void test_ignore_path__skip_gitignore_directory(void) { cl_git_rewritefile("attr/.git/info/exclude", "/NewFolder\n/NewFolder/NewFolder"); cl_must_pass(p_unlink("attr/.gitignore")); - cl_assert(!git_path_exists("attr/.gitignore")); + cl_assert(!git_fs_path_exists("attr/.gitignore")); p_mkdir("attr/.gitignore", 0777); cl_git_mkfile("attr/.gitignore/garbage.txt", "new_file\n"); @@ -270,7 +270,7 @@ void test_ignore_path__skip_gitignore_directory(void) void test_ignore_path__subdirectory_gitignore(void) { cl_must_pass(p_unlink("attr/.gitignore")); - cl_assert(!git_path_exists("attr/.gitignore")); + cl_assert(!git_fs_path_exists("attr/.gitignore")); cl_git_mkfile( "attr/.gitignore", "file1\n"); diff --git a/tests/index/crlf.c b/tests/index/crlf.c index 8d2a5fccefe..7520c23a33b 100644 --- a/tests/index/crlf.c +++ b/tests/index/crlf.c @@ -53,7 +53,7 @@ static int add_and_check_file(void *payload, git_str *actual_path) git_blob *blob; bool failed = true; - basename = git_path_basename(actual_path->ptr); + basename = git_fs_path_basename(actual_path->ptr); if (!strcmp(basename, ".git") || !strcmp(basename, ".gitattributes")) { failed = false; @@ -65,7 +65,7 @@ static int add_and_check_file(void *payload, git_str *actual_path) cl_git_pass(git_str_puts(&expected_path_fail, expected_path.ptr)); cl_git_pass(git_str_puts(&expected_path_fail, ".fail")); - if (git_path_isfile(expected_path.ptr)) { + if (git_fs_path_isfile(expected_path.ptr)) { cl_git_pass(git_index_add_bypath(g_index, basename)); cl_assert(entry = git_index_get_bypath(g_index, basename, 0)); @@ -77,7 +77,7 @@ static int add_and_check_file(void *payload, git_str *actual_path) goto done; git_blob_free(blob); - } else if (git_path_isfile(expected_path_fail.ptr)) { + } else if (git_fs_path_isfile(expected_path_fail.ptr)) { cl_git_pass(git_futils_readbuffer(&expected_contents, expected_path_fail.ptr)); git_str_rtrim(&expected_contents); @@ -161,7 +161,7 @@ static void test_add_index(const char *safecrlf, const char *autocrlf, const cha cl_fixture_sandbox(expected_fixture.ptr); compare_data.dirname = sandboxname.ptr; - cl_git_pass(git_path_direach(&reponame, 0, add_and_check_file, &compare_data)); + cl_git_pass(git_fs_path_direach(&reponame, 0, add_and_check_file, &compare_data)); cl_fixture_cleanup(expected_fixture.ptr); git_str_dispose(&expected_fixture); @@ -179,9 +179,9 @@ static void set_up_workingdir(const char *name) size_t i; const char *fn; - git_path_dirload(&contents, name, 0, 0); + git_fs_path_dirload(&contents, name, 0, 0); git_vector_foreach(&contents, i, fn) { - char *basename = git_path_basename(fn); + char *basename = git_fs_path_basename(fn); bool skip = strncasecmp(basename, ".git", 4) == 0 && strlen(basename) == 4; git__free(basename); @@ -193,9 +193,9 @@ static void set_up_workingdir(const char *name) git_vector_free_deep(&contents); /* copy input files */ - git_path_dirload(&contents, cl_fixture("crlf"), 0, 0); + git_fs_path_dirload(&contents, cl_fixture("crlf"), 0, 0); git_vector_foreach(&contents, i, fn) { - char *basename = git_path_basename(fn); + char *basename = git_fs_path_basename(fn); git_str dest_filename = GIT_STR_INIT; if (strcmp(basename, ".gitted") && diff --git a/tests/index/tests.c b/tests/index/tests.c index 9b28028e6cc..b6715574edf 100644 --- a/tests/index/tests.c +++ b/tests/index/tests.c @@ -571,9 +571,9 @@ void test_index_tests__cannot_add_invalid_filename(void) cl_must_pass(p_mkdir("./invalid/subdir", 0777)); /* cl_git_mkfile() needs the dir to exist */ - if (!git_path_exists("./invalid/.GIT")) + if (!git_fs_path_exists("./invalid/.GIT")) cl_must_pass(p_mkdir("./invalid/.GIT", 0777)); - if (!git_path_exists("./invalid/.GiT")) + if (!git_fs_path_exists("./invalid/.GiT")) cl_must_pass(p_mkdir("./invalid/.GiT", 0777)); assert_add_bypath_fails(repo, ".git/hello"); diff --git a/tests/iterator/index.c b/tests/iterator/index.c index 69b795f5c80..7218b4f758d 100644 --- a/tests/iterator/index.c +++ b/tests/iterator/index.c @@ -283,7 +283,7 @@ void test_iterator_index__case_folding(void) int fs_is_ci = 0; cl_git_pass(git_str_joinpath(&path, cl_fixture("icase"), ".gitted/CoNfIg")); - fs_is_ci = git_path_exists(path.ptr); + fs_is_ci = git_fs_path_exists(path.ptr); git_str_dispose(&path); index_iterator_test( diff --git a/tests/iterator/workdir.c b/tests/iterator/workdir.c index 7ca726c247d..86b847cab66 100644 --- a/tests/iterator/workdir.c +++ b/tests/iterator/workdir.c @@ -1024,7 +1024,7 @@ static void create_paths(const char *root, int depth) int i; cl_git_pass(git_str_puts(&fullpath, root)); - cl_git_pass(git_path_to_dir(&fullpath)); + cl_git_pass(git_fs_path_to_dir(&fullpath)); root_len = fullpath.size; diff --git a/tests/merge/merge_helpers.c b/tests/merge/merge_helpers.c index 1eb423ef7c8..73a1d852de2 100644 --- a/tests/merge/merge_helpers.c +++ b/tests/merge/merge_helpers.c @@ -346,7 +346,7 @@ int merge_test_workdir(git_repository *repo, const struct merge_index_entry expe git_str wd = GIT_STR_INIT; git_str_puts(&wd, repo->workdir); - git_path_direach(&wd, 0, dircount, &actual_len); + git_fs_path_direach(&wd, 0, dircount, &actual_len); if (actual_len != expected_len) return 0; diff --git a/tests/merge/workdir/setup.c b/tests/merge/workdir/setup.c index fe33e21f201..3db2d074fb9 100644 --- a/tests/merge/workdir/setup.c +++ b/tests/merge/workdir/setup.c @@ -48,15 +48,15 @@ static bool test_file_contents(const char *filename, const char *expected) { git_str file_path_buf = GIT_STR_INIT, file_buf = GIT_STR_INIT; bool equals; - + git_str_joinpath(&file_path_buf, git_repository_path(repo), filename); - + cl_git_pass(git_futils_readbuffer(&file_buf, file_path_buf.ptr)); equals = (strcmp(file_buf.ptr, expected) == 0); git_str_dispose(&file_path_buf); git_str_dispose(&file_buf); - + return equals; } @@ -77,13 +77,13 @@ void test_merge_workdir_setup__one_branch(void) git_oid our_oid; git_reference *octo1_ref; git_annotated_commit *our_head, *their_heads[1]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1)); cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n")); @@ -92,7 +92,7 @@ void test_merge_workdir_setup__one_branch(void) cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "'\n")); git_reference_free(octo1_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); } @@ -103,10 +103,10 @@ void test_merge_workdir_setup__one_oid(void) git_oid our_oid; git_oid octo1_oid; git_annotated_commit *our_head, *their_heads[1]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid)); @@ -128,10 +128,10 @@ void test_merge_workdir_setup__two_branches(void) git_reference *octo1_ref; git_reference *octo2_ref; git_annotated_commit *our_head, *their_heads[2]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); @@ -139,15 +139,15 @@ void test_merge_workdir_setup__two_branches(void) cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO2_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -161,13 +161,13 @@ void test_merge_workdir_setup__three_branches(void) git_reference *octo2_ref; git_reference *octo3_ref; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - + cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); @@ -180,7 +180,7 @@ void test_merge_workdir_setup__three_branches(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "', '" OCTO2_BRANCH "' and '" OCTO3_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); git_reference_free(octo3_ref); @@ -199,13 +199,13 @@ void test_merge_workdir_setup__three_oids(void) git_oid octo2_oid; git_oid octo3_oid; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid)); - + cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo2_oid)); @@ -218,7 +218,7 @@ void test_merge_workdir_setup__three_oids(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; commit '" OCTO2_OID "'; commit '" OCTO3_OID "'\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -232,7 +232,7 @@ void test_merge_workdir_setup__branches_and_oids_1(void) git_reference *octo1_ref; git_oid octo2_oid; git_annotated_commit *our_head, *their_heads[2]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -248,7 +248,7 @@ void test_merge_workdir_setup__branches_and_oids_1(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "'; commit '" OCTO2_OID "'\n")); - + git_reference_free(octo1_ref); git_annotated_commit_free(our_head); @@ -271,23 +271,23 @@ void test_merge_workdir_setup__branches_and_oids_2(void) cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - + cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo2_oid)); cl_git_pass(git_reference_lookup(&octo3_ref, repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[2], repo, octo3_ref)); - + cl_git_pass(git_oid_fromstr(&octo4_oid, OCTO4_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[3], repo, &octo4_oid)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4)); cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n" OCTO4_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO3_BRANCH "'; commit '" OCTO2_OID "'; commit '" OCTO4_OID "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo3_ref); @@ -307,7 +307,7 @@ void test_merge_workdir_setup__branches_and_oids_3(void) git_oid octo3_oid; git_reference *octo4_ref; git_annotated_commit *our_head, *their_heads[4]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -319,17 +319,17 @@ void test_merge_workdir_setup__branches_and_oids_3(void) cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo3_oid)); - + cl_git_pass(git_reference_lookup(&octo4_ref, repo, GIT_REFS_HEADS_DIR OCTO4_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[3], repo, octo4_ref)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4)); cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n" OCTO4_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; branches '" OCTO2_BRANCH "' and '" OCTO4_BRANCH "'; commit '" OCTO3_OID "'\n")); - + git_reference_free(octo2_ref); git_reference_free(octo4_ref); @@ -350,19 +350,19 @@ void test_merge_workdir_setup__branches_and_oids_4(void) git_reference *octo4_ref; git_reference *octo5_ref; git_annotated_commit *our_head, *their_heads[5]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid)); - + cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); - + cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo3_oid)); - + cl_git_pass(git_reference_lookup(&octo4_ref, repo, GIT_REFS_HEADS_DIR OCTO4_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[3], repo, octo4_ref)); @@ -375,7 +375,7 @@ void test_merge_workdir_setup__branches_and_oids_4(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; branches '" OCTO2_BRANCH "', '" OCTO4_BRANCH "' and '" OCTO5_BRANCH "'; commit '" OCTO3_OID "'\n")); - + git_reference_free(octo2_ref); git_reference_free(octo4_ref); git_reference_free(octo5_ref); @@ -396,30 +396,30 @@ void test_merge_workdir_setup__three_same_branches(void) git_reference *octo1_2_ref; git_reference *octo1_3_ref; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_1_ref)); - + cl_git_pass(git_reference_lookup(&octo1_2_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo1_2_ref)); - + cl_git_pass(git_reference_lookup(&octo1_3_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[2], repo, octo1_3_ref)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3)); cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO1_OID "\n" OCTO1_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "', '" OCTO1_BRANCH "' and '" OCTO1_BRANCH "'\n")); - + git_reference_free(octo1_1_ref); git_reference_free(octo1_2_ref); git_reference_free(octo1_3_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -434,26 +434,26 @@ void test_merge_workdir_setup__three_same_oids(void) git_oid octo1_2_oid; git_oid octo1_3_oid; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_oid_fromstr(&octo1_1_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_1_oid)); - + cl_git_pass(git_oid_fromstr(&octo1_2_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo1_2_oid)); - + cl_git_pass(git_oid_fromstr(&octo1_3_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo1_3_oid)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO1_OID "\n" OCTO1_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; commit '" OCTO1_OID "'; commit '" OCTO1_OID "'\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -473,7 +473,7 @@ static int create_remote_tracking_branch(const char *branch_name, const char *oi (error = git_str_puts(&remotes_path, GIT_REFS_REMOTES_DIR)) < 0) goto done; - if (!git_path_exists(git_str_cstr(&remotes_path)) && + if (!git_fs_path_exists(git_str_cstr(&remotes_path)) && (error = p_mkdir(git_str_cstr(&remotes_path), 0777)) < 0) goto done; @@ -481,7 +481,7 @@ static int create_remote_tracking_branch(const char *branch_name, const char *oi (error = git_str_puts(&origin_path, "origin")) < 0) goto done; - if (!git_path_exists(git_str_cstr(&origin_path)) && + if (!git_fs_path_exists(git_str_cstr(&origin_path)) && (error = p_mkdir(git_str_cstr(&origin_path), 0777)) < 0) goto done; @@ -514,10 +514,10 @@ void test_merge_workdir_setup__remote_tracking_one_branch(void) cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1)); cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n")); @@ -526,7 +526,7 @@ void test_merge_workdir_setup__remote_tracking_one_branch(void) cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge remote-tracking branch 'refs/remotes/origin/" OCTO1_BRANCH "'\n")); git_reference_free(octo1_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); } @@ -544,7 +544,7 @@ void test_merge_workdir_setup__remote_tracking_two_branches(void) cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); @@ -552,15 +552,15 @@ void test_merge_workdir_setup__remote_tracking_two_branches(void) cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge remote-tracking branches 'refs/remotes/origin/" OCTO1_BRANCH "' and 'refs/remotes/origin/" OCTO2_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -578,13 +578,13 @@ void test_merge_workdir_setup__remote_tracking_three_branches(void) cl_git_pass(create_remote_tracking_branch(OCTO1_BRANCH, OCTO1_OID)); cl_git_pass(create_remote_tracking_branch(OCTO2_BRANCH, OCTO2_OID)); cl_git_pass(create_remote_tracking_branch(OCTO3_BRANCH, OCTO3_OID)); - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - + cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO2_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); @@ -597,7 +597,7 @@ void test_merge_workdir_setup__remote_tracking_three_branches(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge remote-tracking branches 'refs/remotes/origin/" OCTO1_BRANCH "', 'refs/remotes/origin/" OCTO2_BRANCH "' and 'refs/remotes/origin/" OCTO3_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); git_reference_free(octo3_ref); @@ -628,15 +628,15 @@ void test_merge_workdir_setup__normal_branch_and_remote_tracking_branch(void) cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "', remote-tracking branch 'refs/remotes/origin/" OCTO2_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -654,7 +654,7 @@ void test_merge_workdir_setup__remote_tracking_branch_and_normal_branch(void) cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); @@ -662,15 +662,15 @@ void test_merge_workdir_setup__remote_tracking_branch_and_normal_branch(void) cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO2_BRANCH "', remote-tracking branch 'refs/remotes/origin/" OCTO1_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -691,7 +691,7 @@ void test_merge_workdir_setup__two_remote_tracking_branch_and_two_normal_branche cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); @@ -705,17 +705,17 @@ void test_merge_workdir_setup__two_remote_tracking_branch_and_two_normal_branche cl_git_pass(git_annotated_commit_from_ref(&their_heads[3], repo, octo4_ref)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n" OCTO4_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO3_BRANCH "', remote-tracking branches 'refs/remotes/origin/" OCTO2_BRANCH "' and 'refs/remotes/origin/" OCTO4_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); git_reference_free(octo3_ref); git_reference_free(octo4_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -735,14 +735,14 @@ void test_merge_workdir_setup__pull_one(void) cl_git_pass(git_oid_fromstr(&octo1_1_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.url/repo.git", &octo1_1_oid)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch 'octo1' of http://remote.url/repo.git\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); } @@ -754,7 +754,7 @@ void test_merge_workdir_setup__pull_two(void) git_oid octo1_oid; git_oid octo2_oid; git_annotated_commit *our_head, *their_heads[2]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -770,7 +770,7 @@ void test_merge_workdir_setup__pull_two(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO2_BRANCH "' of http://remote.url/repo.git\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -784,7 +784,7 @@ void test_merge_workdir_setup__pull_three(void) git_oid octo2_oid; git_oid octo3_oid; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -803,7 +803,7 @@ void test_merge_workdir_setup__pull_three(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "', '" OCTO2_BRANCH "' and '" OCTO3_BRANCH "' of http://remote.url/repo.git\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -817,7 +817,7 @@ void test_merge_workdir_setup__three_remotes(void) git_oid octo2_oid; git_oid octo3_oid; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -836,7 +836,7 @@ void test_merge_workdir_setup__three_remotes(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "' of http://remote.first/repo.git, branch '" OCTO2_BRANCH "' of http://remote.second/repo.git, branch '" OCTO3_BRANCH "' of http://remote.third/repo.git\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -851,7 +851,7 @@ void test_merge_workdir_setup__two_remotes(void) git_oid octo3_oid; git_oid octo4_oid; git_annotated_commit *our_head, *their_heads[4]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -873,7 +873,7 @@ void test_merge_workdir_setup__two_remotes(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO3_BRANCH "' of http://remote.first/repo.git, branches '" OCTO2_BRANCH "' and '" OCTO4_BRANCH "' of http://remote.second/repo.git\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -1036,9 +1036,9 @@ void test_merge_workdir_setup__removed_after_failure(void) cl_git_fail(git_merge( repo, (const git_annotated_commit **)&their_heads[0], 1, NULL, NULL)); - cl_assert(!git_path_exists("merge-resolve/.git/" GIT_MERGE_HEAD_FILE)); - cl_assert(!git_path_exists("merge-resolve/.git/" GIT_MERGE_MODE_FILE)); - cl_assert(!git_path_exists("merge-resolve/.git/" GIT_MERGE_MSG_FILE)); + cl_assert(!git_fs_path_exists("merge-resolve/.git/" GIT_MERGE_HEAD_FILE)); + cl_assert(!git_fs_path_exists("merge-resolve/.git/" GIT_MERGE_MODE_FILE)); + cl_assert(!git_fs_path_exists("merge-resolve/.git/" GIT_MERGE_MSG_FILE)); git_reference_free(octo1_ref); @@ -1061,7 +1061,7 @@ void test_merge_workdir_setup__unlocked_after_success(void) cl_git_pass(git_merge( repo, (const git_annotated_commit **)&their_heads[0], 1, NULL, NULL)); - cl_assert(!git_path_exists("merge-resolve/.git/index.lock")); + cl_assert(!git_fs_path_exists("merge-resolve/.git/index.lock")); git_reference_free(octo1_ref); @@ -1087,7 +1087,7 @@ void test_merge_workdir_setup__unlocked_after_conflict(void) cl_git_fail(git_merge( repo, (const git_annotated_commit **)&their_heads[0], 1, NULL, NULL)); - cl_assert(!git_path_exists("merge-resolve/.git/index.lock")); + cl_assert(!git_fs_path_exists("merge-resolve/.git/index.lock")); git_reference_free(octo1_ref); diff --git a/tests/merge/workdir/simple.c b/tests/merge/workdir/simple.c index 6c4cf7e3cb5..f51ff09a7aa 100644 --- a/tests/merge/workdir/simple.c +++ b/tests/merge/workdir/simple.c @@ -504,7 +504,7 @@ void test_merge_workdir_simple__checkout_ours(void) cl_assert(merge_test_index(repo_index, merge_index_entries, 8)); cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3)); - cl_assert(git_path_exists(TEST_REPO_PATH "/conflicting.txt")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/conflicting.txt")); } void test_merge_workdir_simple__favor_ours(void) diff --git a/tests/object/blob/write.c b/tests/object/blob/write.c index 802467498ed..422258d632c 100644 --- a/tests/object/blob/write.c +++ b/tests/object/blob/write.c @@ -42,7 +42,7 @@ void test_object_blob_write__can_create_a_blob_in_a_standard_repo_from_a_absolut repo = cl_git_sandbox_init(WORKDIR); cl_must_pass(p_mkdir(ELSEWHERE, 0777)); - cl_must_pass(git_path_prettify_dir(&full_path, ELSEWHERE, NULL)); + cl_must_pass(git_fs_path_prettify_dir(&full_path, ELSEWHERE, NULL)); cl_must_pass(git_str_puts(&full_path, "test.txt")); assert_blob_creation(ELSEWHERE "/test.txt", git_str_cstr(&full_path), &git_blob_create_from_disk); @@ -58,7 +58,7 @@ void test_object_blob_write__can_create_a_blob_in_a_bare_repo_from_a_absolute_fi repo = cl_git_sandbox_init(BARE_REPO); cl_must_pass(p_mkdir(ELSEWHERE, 0777)); - cl_must_pass(git_path_prettify_dir(&full_path, ELSEWHERE, NULL)); + cl_must_pass(git_fs_path_prettify_dir(&full_path, ELSEWHERE, NULL)); cl_must_pass(git_str_puts(&full_path, "test.txt")); assert_blob_creation(ELSEWHERE "/test.txt", git_str_cstr(&full_path), &git_blob_create_from_disk); diff --git a/tests/object/raw/write.c b/tests/object/raw/write.c index 9bc12768079..40e05f3577d 100644 --- a/tests/object/raw/write.c +++ b/tests/object/raw/write.c @@ -39,8 +39,8 @@ static void streaming_write(git_oid *oid, git_odb *odb, git_rawobj *raw) static void check_object_files(object_data *d) { - cl_assert(git_path_exists(d->dir)); - cl_assert(git_path_exists(d->file)); + cl_assert(git_fs_path_exists(d->dir)); + cl_assert(git_fs_path_exists(d->file)); } static void cmp_objects(git_rawobj *o1, git_rawobj *o2) diff --git a/tests/odb/alternates.c b/tests/odb/alternates.c index e36010b7507..6c00fda2fa4 100644 --- a/tests/odb/alternates.c +++ b/tests/odb/alternates.c @@ -26,7 +26,7 @@ static void init_linked_repo(const char *path, const char *alternate) git_str_clear(&filepath); cl_git_pass(git_repository_init(&repo, path, 1)); - cl_git_pass(git_path_prettify(&destpath, alternate, NULL)); + cl_git_pass(git_fs_path_prettify(&destpath, alternate, NULL)); cl_git_pass(git_str_joinpath(&destpath, destpath.ptr, "objects")); cl_git_pass(git_str_joinpath(&filepath, git_repository_path(repo), "objects/info")); cl_git_pass(git_futils_mkdir(filepath.ptr, 0755, GIT_MKDIR_PATH)); diff --git a/tests/odb/emptyobjects.c b/tests/odb/emptyobjects.c index 89b22ad4aed..e3ec62d3ff8 100644 --- a/tests/odb/emptyobjects.c +++ b/tests/odb/emptyobjects.c @@ -28,7 +28,7 @@ void test_odb_emptyobjects__blob_notfound(void) cl_git_fail_with(GIT_ENOTFOUND, git_blob_lookup(&blob, g_repo, &id)); cl_git_pass(git_odb_write(&written_id, g_odb, "", 0, GIT_OBJECT_BLOB)); - cl_assert(git_path_exists(TEST_REPO_PATH "/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391")); } void test_odb_emptyobjects__read_tree(void) diff --git a/tests/online/clone.c b/tests/online/clone.c index c55cf9f951f..ba88dff9c54 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -194,7 +194,7 @@ void test_online_clone__can_checkout_a_cloned_repo(void) cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&path))); cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(head)); @@ -930,11 +930,11 @@ void test_online_clone__proxy_cred_callback_after_failed_url_creds(void) void test_online_clone__azurerepos(void) { cl_git_pass(git_clone(&g_repo, "https://libgit2@dev.azure.com/libgit2/test/_git/test", "./foo", &g_options)); - cl_assert(git_path_exists("./foo/master.txt")); + cl_assert(git_fs_path_exists("./foo/master.txt")); } void test_online_clone__path_whitespace(void) { cl_git_pass(git_clone(&g_repo, "https://libgit2@dev.azure.com/libgit2/test/_git/spaces%20in%20the%20name", "./foo", &g_options)); - cl_assert(git_path_exists("./foo/master.txt")); + cl_assert(git_fs_path_exists("./foo/master.txt")); } diff --git a/tests/online/customcert.c b/tests/online/customcert.c index 098212b148e..7932a9e68f3 100644 --- a/tests/online/customcert.c +++ b/tests/online/customcert.c @@ -66,7 +66,7 @@ void test_online_customcert__file(void) { #if (GIT_OPENSSL || GIT_MBEDTLS) cl_git_pass(git_clone(&g_repo, CUSTOM_CERT_ONE_URL, "./cloned", NULL)); - cl_assert(git_path_exists("./cloned/master.txt")); + cl_assert(git_fs_path_exists("./cloned/master.txt")); #endif } @@ -74,6 +74,6 @@ void test_online_customcert__path(void) { #if (GIT_OPENSSL || GIT_MBEDTLS) cl_git_pass(git_clone(&g_repo, CUSTOM_CERT_TWO_URL, "./cloned", NULL)); - cl_assert(git_path_exists("./cloned/master.txt")); + cl_assert(git_fs_path_exists("./cloned/master.txt")); #endif } diff --git a/tests/pack/indexer.c b/tests/pack/indexer.c index 5958bc4baa9..954bee9532b 100644 --- a/tests/pack/indexer.c +++ b/tests/pack/indexer.c @@ -289,7 +289,7 @@ static int find_tmp_file_recurs(void *opaque, git_str *path) return error; if (S_ISDIR(st.st_mode)) - return git_path_direach(path, 0, find_tmp_file_recurs, opaque); + return git_fs_path_direach(path, 0, find_tmp_file_recurs, opaque); /* This is the template that's used in git_futils_mktmp. */ if (strstr(git_str_cstr(path), "_git2_") != NULL) diff --git a/tests/pack/packbuilder.c b/tests/pack/packbuilder.c index b4c655c5e21..5b1f7b9e9f3 100644 --- a/tests/pack/packbuilder.c +++ b/tests/pack/packbuilder.c @@ -156,8 +156,8 @@ void test_pack_packbuilder__write_default_path(void) seed_packbuilder(); cl_git_pass(git_packbuilder_write(_packbuilder, NULL, 0, NULL, NULL)); - cl_assert(git_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.idx")); - cl_assert(git_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack")); + cl_assert(git_fs_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.idx")); + cl_assert(git_fs_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack")); } static void test_write_pack_permission(mode_t given, mode_t expected) diff --git a/tests/path/core.c b/tests/path/core.c index 1d606693357..8576b471e5f 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -1,5 +1,5 @@ #include "clar_libgit2.h" -#include "path.h" +#include "fs_path.h" void test_path_core__cleanup(void) { @@ -14,7 +14,7 @@ static void test_make_relative( { git_str buf = GIT_STR_INIT; git_str_puts(&buf, path); - cl_assert_equal_i(expected_status, git_path_make_relative(&buf, parent)); + cl_assert_equal_i(expected_status, git_fs_path_make_relative(&buf, parent)); cl_assert_equal_s(expected_path, buf.ptr); git_str_dispose(&buf); } @@ -59,284 +59,208 @@ void test_path_core__make_relative(void) void test_path_core__isvalid_standard(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/file.txt", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/.file", 0, 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar/file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar/.file", 0)); } void test_path_core__isvalid_empty_dir_component(void) { - cl_assert_equal_b(false, git_path_validate(NULL, "foo//bar", 0, 0)); + cl_assert_equal_b(false, git_fs_path_validate("foo//bar", 0)); /* leading slash */ - cl_assert_equal_b(false, git_path_validate(NULL, "/", 0, 0)); - cl_assert_equal_b(false, git_path_validate(NULL, "/foo", 0, 0)); - cl_assert_equal_b(false, git_path_validate(NULL, "/foo/bar", 0, 0)); + cl_assert_equal_b(false, git_fs_path_validate("/", 0)); + cl_assert_equal_b(false, git_fs_path_validate("/foo", 0)); + cl_assert_equal_b(false, git_fs_path_validate("/foo/bar", 0)); /* trailing slash */ - cl_assert_equal_b(false, git_path_validate(NULL, "foo/", 0, 0)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar/", 0, 0)); + cl_assert_equal_b(false, git_fs_path_validate("foo/", 0)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar/", 0)); } void test_path_core__isvalid_dot_and_dotdot(void) { - cl_assert_equal_b(true, git_path_validate(NULL, ".", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "./foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "./foo", 0, 0)); - - cl_assert_equal_b(true, git_path_validate(NULL, "..", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "../foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/..", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "../foo", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, ".", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL)); - - cl_assert_equal_b(false, git_path_validate(NULL, "..", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/..", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL)); -} - -void test_path_core__isvalid_dot_git(void) -{ - cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git/foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.GIT/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/.Git", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - - cl_assert_equal_b(true, git_path_validate(NULL, "!git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/!git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "!git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".tig", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.tig", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".tig/bar", 0, 0)); + cl_assert_equal_b(true, git_fs_path_validate(".", 0)); + cl_assert_equal_b(true, git_fs_path_validate("./foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/.", 0)); + cl_assert_equal_b(true, git_fs_path_validate("./foo", 0)); + + cl_assert_equal_b(true, git_fs_path_validate("..", 0)); + cl_assert_equal_b(true, git_fs_path_validate("../foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/..", 0)); + cl_assert_equal_b(true, git_fs_path_validate("../foo", 0)); + + cl_assert_equal_b(false, git_fs_path_validate(".", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("foo/.", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + + cl_assert_equal_b(false, git_fs_path_validate("..", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("foo/..", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); } void test_path_core__isvalid_backslash(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "foo\\file.txt", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar\\file.txt", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar\\", 0, 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo\\file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar\\file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar\\", 0)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar\\", 0, GIT_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_validate("foo\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar\\", GIT_FS_PATH_REJECT_BACKSLASH)); } void test_path_core__isvalid_trailing_dot(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "foo.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo...", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo./bar", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "foo.", 0, GIT_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo...", 0, GIT_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar.", 0, GIT_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo./bar", 0, GIT_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(true, git_fs_path_validate("foo.", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo...", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar.", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo./bar", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("foo.", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_validate("foo...", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar.", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_validate("foo./bar", GIT_FS_PATH_REJECT_TRAILING_DOT)); } void test_path_core__isvalid_trailing_space(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "foo ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, " ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo /bar", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_validate(NULL, " ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo /bar", 0, GIT_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(true, git_fs_path_validate("foo ", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo ", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar ", 0)); + cl_assert_equal_b(true, git_fs_path_validate(" ", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo /bar", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_validate("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_validate(" ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_validate("foo /bar", GIT_FS_PATH_REJECT_TRAILING_SPACE)); } void test_path_core__isvalid_trailing_colon(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "foo:", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar:", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ":", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo:/bar", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "foo:", 0, GIT_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar:", 0, GIT_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_path_validate(NULL, ":", 0, GIT_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo:/bar", 0, GIT_PATH_REJECT_TRAILING_COLON)); -} - -void test_path_core__isvalid_dotgit_ntfs(void) -{ - cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git.. .", 0, 0)); - - cl_assert_equal_b(true, git_path_validate(NULL, "git~1", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1 ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1.. .", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - - cl_assert_equal_b(false, git_path_validate(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(true, git_fs_path_validate("foo:", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar:", 0)); + cl_assert_equal_b(true, git_fs_path_validate(":", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo:/bar", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("foo:", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar:", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_validate(":", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_validate("foo:/bar", GIT_FS_PATH_REJECT_TRAILING_COLON)); } void test_path_core__isvalid_dos_paths(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "aux", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux:", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux.asdf", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux.asdf\\zippy", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux:asdf\\foobar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "con", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "prn", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "nul", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "aux", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "aux.", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "aux:", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "aux.asdf", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "aux.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "aux:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "con", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "prn", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "nul", 0, GIT_PATH_REJECT_DOS_PATHS)); - - cl_assert_equal_b(true, git_path_validate(NULL, "aux1", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux1", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "auxn", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux\\foo", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("aux", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux.", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux:", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux.asdf", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux.asdf\\zippy", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux:asdf\\foobar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("con", 0)); + cl_assert_equal_b(true, git_fs_path_validate("prn", 0)); + cl_assert_equal_b(true, git_fs_path_validate("nul", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("aux", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("aux.", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("aux:", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("aux.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("aux.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("aux:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("con", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("prn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("nul", GIT_FS_PATH_REJECT_DOS_PATHS)); + + cl_assert_equal_b(true, git_fs_path_validate("aux1", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux1", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("auxn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("aux\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); } void test_path_core__isvalid_dos_paths_withnum(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "com1", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1:", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1.asdf", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1.asdf\\zippy", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1:asdf\\foobar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1\\foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "lpt1", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "com1", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1.", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1:", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1.asdf", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1/foo", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "lpt1", 0, GIT_PATH_REJECT_DOS_PATHS)); - - cl_assert_equal_b(true, git_path_validate(NULL, "com0", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com0", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "com10", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com10", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "comn", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1\\foo", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "lpt0", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "lpt10", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "lptn", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("com1", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1.", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1:", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1.asdf", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1.asdf\\zippy", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1:asdf\\foobar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1\\foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("lpt1", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("com1", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1.", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1:", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1/foo", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("lpt1", GIT_FS_PATH_REJECT_DOS_PATHS)); + + cl_assert_equal_b(true, git_fs_path_validate("com0", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com0", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("com10", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com10", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("comn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("com1\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("lpt0", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("lpt10", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("lptn", GIT_FS_PATH_REJECT_DOS_PATHS)); } void test_path_core__isvalid_nt_chars(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "asdf\001foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf\037bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdffoo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf:foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf\"bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf|foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf?bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf*bar", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "asdf\001foo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdf\037bar", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdffoo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdf:foo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdf\"bar", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdf|foo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdf?bar", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdf*bar", 0, GIT_PATH_REJECT_NT_CHARS)); -} - -void test_path_core__isvalid_dotgit_with_hfs_ignorables(void) -{ - cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(true, git_path_validate(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_fs_path_validate("asdf\001foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf\037bar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdffoo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf:foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf\"bar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf|foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf?bar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf*bar", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("asdf\001foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf\037bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdffoo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf:foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf\"bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf|foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf?bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf*bar", GIT_FS_PATH_REJECT_NT_CHARS)); } void test_path_core__validate_workdir(void) { - cl_must_pass(git_path_validate_workdir(NULL, "/foo/bar")); - cl_must_pass(git_path_validate_workdir(NULL, "C:\\Foo\\Bar")); - cl_must_pass(git_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); - cl_must_pass(git_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); - cl_must_pass(git_path_validate_workdir(NULL, "\\\\?\\UNC\\server\\C$\\folder")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "/foo/bar")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\Foo\\Bar")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\UNC\\server\\C$\\folder")); #ifdef GIT_WIN32 /* * In the absense of a repo configuration, 259 character paths * succeed. >= 260 character paths fail. */ - cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); - cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\260.txt")); - cl_must_fail(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\longer_than_260.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\260.txt")); + cl_must_fail(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\longer_than_260.txt")); /* count characters, not bytes */ - cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); - cl_must_fail(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_fail(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); #else - cl_must_pass(git_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/ok.txt")); - cl_must_pass(git_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/260.txt")); - cl_must_pass(git_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); - cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); - cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/ok.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/260.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); #endif } @@ -352,15 +276,15 @@ void test_path_core__validate_workdir_with_core_longpath(void) cl_git_pass(git_repository_config(&config, repo)); /* fail by default */ - cl_must_fail(git_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_fail(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); /* set core.longpaths explicitly on */ cl_git_pass(git_config_set_bool(config, "core.longpaths", 1)); - cl_must_pass(git_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_pass(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); /* set core.longpaths explicitly off */ cl_git_pass(git_config_set_bool(config, "core.longpaths", 0)); - cl_must_fail(git_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_fail(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); git_config_free(config); git_repository_free(repo); @@ -376,7 +300,7 @@ static void test_join_unrooted( git_str result = GIT_STR_INIT; ssize_t root_at; - cl_git_pass(git_path_join_unrooted(&result, path, base, &root_at)); + cl_git_pass(git_fs_path_join_unrooted(&result, path, base, &root_at)); cl_assert_equal_s(expected_result, result.ptr); cl_assert_equal_i(expected_rootlen, root_at); diff --git a/tests/path/dotgit.c b/tests/path/dotgit.c index 2f9fcae4fc8..5b3a311379b 100644 --- a/tests/path/dotgit.c +++ b/tests/path/dotgit.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" + #include "path.h" static char *gitmodules_altnames[] = { @@ -118,3 +119,88 @@ void test_path_dotgit__dotgit_modules_symlink(void) cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules . .::$DATA", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); } + +void test_core_path__git_fs_path_is_file(void) +{ + cl_git_fail(git_path_is_gitfile("blob", 4, -1, GIT_PATH_FS_HFS)); + cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITIGNORE, GIT_PATH_FS_HFS)); + cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS)); + cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITATTRIBUTES, GIT_PATH_FS_HFS)); + cl_git_fail(git_path_is_gitfile("blob", 4, 3, GIT_PATH_FS_HFS)); +} + +void test_path_dotgit__isvalid_dot_git(void) +{ + cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git/foo", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git/bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.GIT/bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/.Git", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + + cl_assert_equal_b(true, git_path_validate(NULL, "!git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/!git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "!git/bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".tig", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.tig", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".tig/bar", 0, 0)); +} + +void test_path_dotgit__isvalid_dotgit_ntfs(void) +{ + cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git ", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git.", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git.. .", 0, 0)); + + cl_assert_equal_b(true, git_path_validate(NULL, "git~1", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "git~1 ", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "git~1.", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "git~1.. .", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + + cl_assert_equal_b(false, git_path_validate(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); +} + +void test_path_dotgit__isvalid_dotgit_with_hfs_ignorables(void) +{ + cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + + cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + + cl_assert_equal_b(true, git_path_validate(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); +} diff --git a/tests/refs/branches/create.c b/tests/refs/branches/create.c index 7a49ad54896..2fb11668b50 100644 --- a/tests/refs/branches/create.c +++ b/tests/refs/branches/create.c @@ -145,7 +145,7 @@ void test_refs_branches_create__can_create_branch_with_unicode(void) const char *expected[] = { nfc, nfd, emoji }; unsigned int i; bool fs_decompose_unicode = - git_path_does_fs_decompose_unicode(git_repository_path(repo)); + git_fs_path_does_decompose_unicode(git_repository_path(repo)); retrieve_known_commit(&target, repo); diff --git a/tests/refs/branches/delete.c b/tests/refs/branches/delete.c index aad5c090fc3..077882b22e1 100644 --- a/tests/refs/branches/delete.c +++ b/tests/refs/branches/delete.c @@ -173,13 +173,13 @@ void test_refs_branches_delete__removes_empty_folders(void) cl_git_pass(git_str_joinpath(&ref_folder, commondir, "refs/heads/some/deep")); cl_git_pass(git_str_join3(&reflog_folder, '/', commondir, GIT_REFLOG_DIR, "refs/heads/some/deep")); - cl_assert(git_path_exists(git_str_cstr(&ref_folder)) == true); - cl_assert(git_path_exists(git_str_cstr(&reflog_folder)) == true); + cl_assert(git_fs_path_exists(git_str_cstr(&ref_folder)) == true); + cl_assert(git_fs_path_exists(git_str_cstr(&reflog_folder)) == true); cl_git_pass(git_branch_delete(branch)); - cl_assert(git_path_exists(git_str_cstr(&ref_folder)) == false); - cl_assert(git_path_exists(git_str_cstr(&reflog_folder)) == false); + cl_assert(git_fs_path_exists(git_str_cstr(&ref_folder)) == false); + cl_assert(git_fs_path_exists(git_str_cstr(&reflog_folder)) == false); git_reference_free(branch); git_str_dispose(&ref_folder); diff --git a/tests/refs/delete.c b/tests/refs/delete.c index c76d126eb15..42cc534b561 100644 --- a/tests/refs/delete.c +++ b/tests/refs/delete.c @@ -33,7 +33,7 @@ void test_refs_delete__packed_loose(void) /* Ensure the loose reference exists on the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name)); - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); /* Lookup the reference */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name)); @@ -49,7 +49,7 @@ void test_refs_delete__packed_loose(void) cl_git_fail(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name)); /* Ensure the loose reference doesn't exist any longer on the file system */ - cl_assert(!git_path_exists(temp_path.ptr)); + cl_assert(!git_fs_path_exists(temp_path.ptr)); git_reference_free(another_looked_up_ref); git_str_dispose(&temp_path); diff --git a/tests/refs/pack.c b/tests/refs/pack.c index 125b1adb0a5..1c1cd51cba5 100644 --- a/tests/refs/pack.c +++ b/tests/refs/pack.c @@ -63,7 +63,7 @@ void test_refs_pack__loose(void) /* Ensure the packed-refs file exists */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), GIT_PACKEDREFS_FILE)); - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); /* Ensure the known ref can still be looked up but is now packed */ cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name)); @@ -72,7 +72,7 @@ void test_refs_pack__loose(void) /* Ensure the known ref has been removed from the loose folder structure */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), loose_tag_ref_name)); - cl_assert(!git_path_exists(temp_path.ptr)); + cl_assert(!git_fs_path_exists(temp_path.ptr)); git_reference_free(reference); git_str_dispose(&temp_path); diff --git a/tests/refs/ref_helpers.c b/tests/refs/ref_helpers.c index e55364c6e62..943d0f55189 100644 --- a/tests/refs/ref_helpers.c +++ b/tests/refs/ref_helpers.c @@ -16,7 +16,7 @@ int reference_is_packed(git_reference *ref) git_reference_name(ref)) < 0) return -1; - packed = !git_path_isfile(ref_path.ptr); + packed = !git_fs_path_isfile(ref_path.ptr); git_str_dispose(&ref_path); diff --git a/tests/refs/reflog/reflog.c b/tests/refs/reflog/reflog.c index 5bb6138dff4..32ce7ffb7ad 100644 --- a/tests/refs/reflog/reflog.c +++ b/tests/refs/reflog/reflog.c @@ -107,15 +107,15 @@ void test_refs_reflog_reflog__renaming_the_reference_moves_the_reflog(void) git_str_joinpath(&master_log_path, git_str_cstr(&master_log_path), "refs/heads/master"); git_str_joinpath(&moved_log_path, git_str_cstr(&moved_log_path), "refs/moved"); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&master_log_path))); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&moved_log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&master_log_path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&moved_log_path))); cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master")); cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0, NULL)); git_reference_free(master); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&master_log_path))); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&moved_log_path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&master_log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&moved_log_path))); git_reference_free(new_master); git_str_dispose(&moved_log_path); @@ -130,13 +130,13 @@ void test_refs_reflog_reflog__deleting_the_reference_deletes_the_reflog(void) git_str_joinpath(&master_log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); git_str_joinpath(&master_log_path, git_str_cstr(&master_log_path), "refs/heads/master"); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&master_log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&master_log_path))); cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master")); cl_git_pass(git_reference_delete(master)); git_reference_free(master); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&master_log_path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&master_log_path))); git_str_dispose(&master_log_path); } @@ -153,7 +153,7 @@ void test_refs_reflog_reflog__removes_empty_reflog_dir(void) git_str_joinpath(&log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); git_str_joinpath(&log_path, git_str_cstr(&log_path), "refs/heads/new-dir/new-head"); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&log_path))); cl_git_pass(git_reference_delete(ref)); git_reference_free(ref); @@ -180,7 +180,7 @@ void test_refs_reflog_reflog__fails_gracefully_on_nonempty_reflog_dir(void) git_str_joinpath(&log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); git_str_joinpath(&log_path, git_str_cstr(&log_path), "refs/heads/new-dir/new-head"); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&log_path))); /* delete the ref manually, leave the reflog */ cl_must_pass(p_unlink("testrepo.git/refs/heads/new-dir/new-head")); @@ -212,7 +212,7 @@ void test_refs_reflog_reflog__reading_the_reflog_from_a_reference_with_no_log_re git_str subtrees_log_path = GIT_STR_INIT; git_str_join_n(&subtrees_log_path, '/', 3, git_repository_path(g_repo), GIT_REFLOG_DIR, refname); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&subtrees_log_path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&subtrees_log_path))); cl_git_pass(git_reflog_read(&reflog, g_repo, refname)); diff --git a/tests/refs/rename.c b/tests/refs/rename.c index fa732234a72..f71e657820f 100644 --- a/tests/refs/rename.c +++ b/tests/refs/rename.c @@ -41,7 +41,7 @@ void test_refs_rename__loose(void) /* Ensure the ref doesn't exist on the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), new_name)); - cl_assert(!git_path_exists(temp_path.ptr)); + cl_assert(!git_fs_path_exists(temp_path.ptr)); /* Retrieval of the reference to rename */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, loose_tag_ref_name)); @@ -67,7 +67,7 @@ void test_refs_rename__loose(void) /* ...and the ref can be found in the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), new_name)); - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); git_reference_free(new_ref); git_reference_free(another_looked_up_ref); @@ -83,7 +83,7 @@ void test_refs_rename__packed(void) /* Ensure the ref doesn't exist on the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), packed_head_name)); - cl_assert(!git_path_exists(temp_path.ptr)); + cl_assert(!git_fs_path_exists(temp_path.ptr)); /* The reference can however be looked-up... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name)); @@ -109,7 +109,7 @@ void test_refs_rename__packed(void) /* ...and the ref now happily lives in the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), brand_new_name)); - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); git_reference_free(new_ref); git_reference_free(another_looked_up_ref); @@ -125,7 +125,7 @@ void test_refs_rename__packed_doesnt_pack_others(void) /* Ensure the other reference exists on the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name)); - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); /* Lookup the other reference */ cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name)); @@ -151,7 +151,7 @@ void test_refs_rename__packed_doesnt_pack_others(void) cl_assert(reference_is_packed(another_looked_up_ref) == 0); /* Ensure the other ref still exists on the file system */ - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); git_reference_free(renamed_ref); git_reference_free(another_looked_up_ref); diff --git a/tests/refs/revparse.c b/tests/refs/revparse.c index 9c960702ae6..d02249754b8 100644 --- a/tests/refs/revparse.c +++ b/tests/refs/revparse.c @@ -329,13 +329,13 @@ static void create_fake_stash_reference_and_reflog(git_repository *repo) git_str_joinpath(&log_path, git_repository_path(repo), "logs/refs/fakestash"); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&log_path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&log_path))); cl_git_pass(git_reference_lookup(&master, repo, "refs/heads/master")); cl_git_pass(git_reference_rename(&new_master, master, "refs/fakestash", 0, NULL)); git_reference_free(master); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&log_path))); git_str_dispose(&log_path); git_reference_free(new_master); diff --git a/tests/repo/config.c b/tests/repo/config.c index 0b9daac98c7..ee7e43dffb4 100644 --- a/tests/repo/config.c +++ b/tests/repo/config.c @@ -14,7 +14,7 @@ void test_repo_config__initialize(void) git_str_clear(&path); cl_must_pass(p_mkdir("alternate", 0777)); - cl_git_pass(git_path_prettify(&path, "alternate", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "alternate", NULL)); } void test_repo_config__cleanup(void) @@ -25,7 +25,7 @@ void test_repo_config__cleanup(void) cl_git_pass( git_futils_rmdir_r("alternate", NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(!git_path_isdir("alternate")); + cl_assert(!git_fs_path_isdir("alternate")); cl_fixture_cleanup("empty_standard_repo"); @@ -101,7 +101,7 @@ void test_repo_config__read_with_no_configs_at_all(void) /* with none */ cl_must_pass(p_unlink("empty_standard_repo/.git/config")); - cl_assert(!git_path_isfile("empty_standard_repo/.git/config")); + cl_assert(!git_fs_path_isfile("empty_standard_repo/.git/config")); cl_git_pass(git_repository_open(&repo, "empty_standard_repo")); git_repository__configmap_lookup_cache_clear(repo); @@ -177,16 +177,16 @@ void test_repo_config__read_with_no_configs_at_all(void) cl_assert_equal_i(40, val); cl_must_pass(p_unlink("empty_standard_repo/.git/config")); - cl_assert(!git_path_isfile("empty_standard_repo/.git/config")); + cl_assert(!git_fs_path_isfile("empty_standard_repo/.git/config")); cl_must_pass(p_unlink("alternate/1/gitconfig")); - cl_assert(!git_path_isfile("alternate/1/gitconfig")); + cl_assert(!git_fs_path_isfile("alternate/1/gitconfig")); cl_must_pass(p_unlink("alternate/2/config")); - cl_assert(!git_path_isfile("alternate/2/config")); + cl_assert(!git_fs_path_isfile("alternate/2/config")); cl_must_pass(p_unlink("alternate/3/.gitconfig")); - cl_assert(!git_path_isfile("alternate/3/.gitconfig")); + cl_assert(!git_fs_path_isfile("alternate/3/.gitconfig")); git_repository__configmap_lookup_cache_clear(repo); val = -1; @@ -196,8 +196,8 @@ void test_repo_config__read_with_no_configs_at_all(void) /* reopen */ - cl_assert(!git_path_isfile("empty_standard_repo/.git/config")); - cl_assert(!git_path_isfile("alternate/3/.gitconfig")); + cl_assert(!git_fs_path_isfile("empty_standard_repo/.git/config")); + cl_assert(!git_fs_path_isfile("alternate/3/.gitconfig")); cl_git_pass(git_repository_open(&repo, "empty_standard_repo")); git_repository__configmap_lookup_cache_clear(repo); @@ -206,6 +206,6 @@ void test_repo_config__read_with_no_configs_at_all(void) cl_assert_equal_i(7, val); git_repository_free(repo); - cl_assert(!git_path_exists("empty_standard_repo/.git/config")); - cl_assert(!git_path_exists("alternate/3/.gitconfig")); + cl_assert(!git_fs_path_exists("empty_standard_repo/.git/config")); + cl_assert(!git_fs_path_exists("alternate/3/.gitconfig")); } diff --git a/tests/repo/discover.c b/tests/repo/discover.c index 2a24f1b2928..523fdf8e395 100644 --- a/tests/repo/discover.c +++ b/tests/repo/discover.c @@ -33,7 +33,7 @@ static void ensure_repository_discover(const char *start_path, git_str_attach(&resolved, p_realpath(expected_path, NULL), 0); cl_assert(resolved.size > 0); - cl_git_pass(git_path_to_dir(&resolved)); + cl_git_pass(git_fs_path_to_dir(&resolved)); cl_git_pass(git_repository_discover(&found_path, start_path, 1, ceiling_dirs)); cl_assert_equal_s(found_path.ptr, resolved.ptr); @@ -47,7 +47,7 @@ static void write_file(const char *path, const char *content) git_file file; int error; - if (git_path_exists(path)) { + if (git_fs_path_exists(path)) { cl_git_pass(p_unlink(path)); } @@ -65,7 +65,7 @@ static void append_ceiling_dir(git_str *ceiling_dirs, const char *path) git_str pretty_path = GIT_STR_INIT; char ceiling_separator[2] = { GIT_PATH_LIST_SEPARATOR, '\0' }; - cl_git_pass(git_path_prettify_dir(&pretty_path, path, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&pretty_path, path, NULL)); if (ceiling_dirs->size > 0) git_str_puts(ceiling_dirs, ceiling_separator); diff --git a/tests/repo/env.c b/tests/repo/env.c index 4bd45d1a632..e3e522480f2 100644 --- a/tests/repo/env.c +++ b/tests/repo/env.c @@ -24,11 +24,11 @@ void test_repo_env__cleanup(void) { cl_git_sandbox_cleanup(); - if (git_path_isdir("attr")) + if (git_fs_path_isdir("attr")) git_futils_rmdir_r("attr", NULL, GIT_RMDIR_REMOVE_FILES); - if (git_path_isdir("testrepo.git")) + if (git_fs_path_isdir("testrepo.git")) git_futils_rmdir_r("testrepo.git", NULL, GIT_RMDIR_REMOVE_FILES); - if (git_path_isdir("peeled.git")) + if (git_fs_path_isdir("peeled.git")) git_futils_rmdir_r("peeled.git", NULL, GIT_RMDIR_REMOVE_FILES); clear_git_env(); @@ -81,7 +81,7 @@ static void env_cd_( const char *file, const char *func, int line) { git_str cwd_buf = GIT_STR_INIT; - cl_git_pass(git_path_prettify_dir(&cwd_buf, ".", NULL)); + cl_git_pass(git_fs_path_prettify_dir(&cwd_buf, ".", NULL)); cl_must_pass(p_chdir(path)); passfail_(NULL, file, func, line); cl_must_pass(p_chdir(git_str_cstr(&cwd_buf))); @@ -141,7 +141,7 @@ void test_repo_env__open(void) cl_fixture_sandbox("peeled.git"); cl_git_pass(p_rename("attr/.gitted", "attr/.git")); - cl_git_pass(git_path_prettify_dir(&repo_dir_buf, "attr", NULL)); + cl_git_pass(git_fs_path_prettify_dir(&repo_dir_buf, "attr", NULL)); repo_dir = git_str_cstr(&repo_dir_buf); /* GIT_DIR that doesn't exist */ diff --git a/tests/repo/init.c b/tests/repo/init.c index b41608cca6c..7cf6742cad8 100644 --- a/tests/repo/init.c +++ b/tests/repo/init.c @@ -47,7 +47,7 @@ static void ensure_repository_init( { const char *workdir; - cl_assert(!git_path_isdir(working_directory)); + cl_assert(!git_fs_path_isdir(working_directory)); cl_git_pass(git_repository_init(&g_repo, working_directory, is_bare)); @@ -103,7 +103,7 @@ void test_repo_init__bare_repo_escaping_current_workdir(void) git_str path_repository = GIT_STR_INIT; git_str path_current_workdir = GIT_STR_INIT; - cl_git_pass(git_path_prettify_dir(&path_current_workdir, ".", NULL)); + cl_git_pass(git_fs_path_prettify_dir(&path_current_workdir, ".", NULL)); cl_git_pass(git_str_joinpath(&path_repository, git_str_cstr(&path_current_workdir), "a/b/c")); cl_git_pass(git_futils_mkdir_r(git_str_cstr(&path_repository), GIT_DIR_MODE)); @@ -176,15 +176,15 @@ void test_repo_init__additional_templates(void) cl_git_pass( git_str_joinpath(&path, git_repository_path(g_repo), "description")); - cl_assert(git_path_isfile(git_str_cstr(&path))); + cl_assert(git_fs_path_isfile(git_str_cstr(&path))); cl_git_pass( git_str_joinpath(&path, git_repository_path(g_repo), "info/exclude")); - cl_assert(git_path_isfile(git_str_cstr(&path))); + cl_assert(git_fs_path_isfile(git_str_cstr(&path))); cl_git_pass( git_str_joinpath(&path, git_repository_path(g_repo), "hooks")); - cl_assert(git_path_isdir(git_str_cstr(&path))); + cl_assert(git_fs_path_isdir(git_str_cstr(&path))); /* won't confirm specific contents of hooks dir since it may vary */ git_str_dispose(&path); @@ -257,7 +257,7 @@ void test_repo_init__symlinks_win32_enabled_by_global_config(void) git_config *config, *repo_config; int val; - if (!git_path_supports_symlinks("link")) + if (!git_fs_path_supports_symlinks("link")) cl_skip(); create_tmp_global_config("tmp_global_config", "core.symlinks", "true"); @@ -303,7 +303,7 @@ void test_repo_init__symlinks_posix_detected(void) cl_skip(); #else assert_config_entry_on_init( - "core.symlinks", git_path_supports_symlinks("link") ? GIT_ENOTFOUND : false); + "core.symlinks", git_fs_path_supports_symlinks("link") ? GIT_ENOTFOUND : false); #endif } @@ -418,12 +418,12 @@ void test_repo_init__extended_1(void) cl_assert(!git__suffixcmp(git_repository_workdir(g_repo), "/c_wd/")); cl_assert(!git__suffixcmp(git_repository_path(g_repo), "/c.git/")); - cl_assert(git_path_isfile("root/b/c_wd/.git")); + cl_assert(git_fs_path_isfile("root/b/c_wd/.git")); cl_assert(!git_repository_is_bare(g_repo)); /* repo will not be counted as empty because we set head to "development" */ cl_assert(!git_repository_is_empty(g_repo)); - cl_git_pass(git_path_lstat(git_repository_path(g_repo), &st)); + cl_git_pass(git_fs_path_lstat(git_repository_path(g_repo), &st)); cl_assert(S_ISDIR(st.st_mode)); if (cl_is_chmod_supported()) cl_assert((S_ISGID & st.st_mode) == S_ISGID); @@ -482,7 +482,7 @@ void test_repo_init__relative_gitdir_2(void) git_str dot_git_content = GIT_STR_INIT; git_str full_path = GIT_STR_INIT; - cl_git_pass(git_path_prettify(&full_path, ".", NULL)); + cl_git_pass(git_fs_path_prettify(&full_path, ".", NULL)); cl_git_pass(git_str_joinpath(&full_path, full_path.ptr, "root/b/c_wd")); opts.workdir_path = full_path.ptr; @@ -604,16 +604,16 @@ void test_repo_init__at_filesystem_root(void) if (!cl_is_env_set("GITTEST_INVASIVE_FS_STRUCTURE")) cl_skip(); - root_len = git_path_root(sandbox); + root_len = git_fs_path_root(sandbox); cl_assert(root_len >= 0); git_str_put(&root, sandbox, root_len+1); git_str_joinpath(&root, root.ptr, "libgit2_test_dir"); - cl_assert(!git_path_exists(root.ptr)); + cl_assert(!git_fs_path_exists(root.ptr)); cl_git_pass(git_repository_init(&repo, root.ptr, 0)); - cl_assert(git_path_isdir(root.ptr)); + cl_assert(git_fs_path_isdir(root.ptr)); cl_git_pass(git_futils_rmdir_r(root.ptr, NULL, GIT_RMDIR_REMOVE_FILES)); git_str_dispose(&root); diff --git a/tests/repo/open.c b/tests/repo/open.c index 6558805c886..f7ed2c37327 100644 --- a/tests/repo/open.c +++ b/tests/repo/open.c @@ -8,7 +8,7 @@ void test_repo_open__cleanup(void) { cl_git_sandbox_cleanup(); - if (git_path_isdir("alternate")) + if (git_fs_path_isdir("alternate")) git_futils_rmdir_r("alternate", NULL, GIT_RMDIR_REMOVE_FILES); } @@ -147,7 +147,7 @@ void test_repo_open__with_symlinked_config(void) cl_git_pass(git_futils_mkdir_r("home", 0777)); cl_git_mkfile("home/.gitconfig.linked", "[global]\ntest = 4567\n"); cl_must_pass(symlink(".gitconfig.linked", "home/.gitconfig")); - cl_git_pass(git_path_prettify(&path, "home", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "home", NULL)); cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr)); cl_git_pass(git_repository_open(&repo, "empty_standard_repo")); @@ -191,7 +191,7 @@ void test_repo_open__from_git_new_workdir(void) for (scan = links; *scan != NULL; scan++) { git_str_joinpath(&link_tgt, "empty_standard_repo/.git", *scan); - if (git_path_exists(link_tgt.ptr)) { + if (git_fs_path_exists(link_tgt.ptr)) { git_str_joinpath(&link_tgt, "../../empty_standard_repo/.git", *scan); git_str_joinpath(&link, "alternate/.git", *scan); if (strchr(*scan, '/')) @@ -201,7 +201,7 @@ void test_repo_open__from_git_new_workdir(void) } for (scan = copies; *scan != NULL; scan++) { git_str_joinpath(&link_tgt, "empty_standard_repo/.git", *scan); - if (git_path_exists(link_tgt.ptr)) { + if (git_fs_path_exists(link_tgt.ptr)) { git_str_joinpath(&link, "alternate/.git", *scan); cl_git_pass(git_futils_readbuffer(&body, link_tgt.ptr)); @@ -381,7 +381,7 @@ void test_repo_open__no_config(void) /* isolate from system level configs */ cl_must_pass(p_mkdir("alternate", 0777)); - cl_git_pass(git_path_prettify(&path, "alternate", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "alternate", NULL)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr)); cl_git_pass(git_libgit2_opts( diff --git a/tests/repo/setters.c b/tests/repo/setters.c index 2c33db0dbf8..9a965dec60b 100644 --- a/tests/repo/setters.c +++ b/tests/repo/setters.c @@ -50,7 +50,7 @@ void test_repo_setters__setting_a_workdir_creates_a_gitlink(void) cl_git_pass(git_repository_set_workdir(repo, "./new_workdir", true)); - cl_assert(git_path_isfile("./new_workdir/.git")); + cl_assert(git_fs_path_isfile("./new_workdir/.git")); cl_git_pass(git_futils_readbuffer(&content, "./new_workdir/.git")); cl_assert(git__prefixcmp(git_str_cstr(&content), "gitdir: ") == 0); diff --git a/tests/repo/template.c b/tests/repo/template.c index 6f369c6d6e7..b0af96e36f4 100644 --- a/tests/repo/template.c +++ b/tests/repo/template.c @@ -56,10 +56,10 @@ static void assert_hooks_match( struct stat expected_st, st; cl_git_pass(git_str_joinpath(&expected, template_dir, hook_path)); - cl_git_pass(git_path_lstat(expected.ptr, &expected_st)); + cl_git_pass(git_fs_path_lstat(expected.ptr, &expected_st)); cl_git_pass(git_str_joinpath(&actual, repo_dir, hook_path)); - cl_git_pass(git_path_lstat(actual.ptr, &st)); + cl_git_pass(git_fs_path_lstat(actual.ptr, &st)); cl_assert(expected_st.st_size == st.st_size); @@ -88,7 +88,7 @@ static void assert_mode_seems_okay( struct stat st; cl_git_pass(git_str_joinpath(&full, base, path)); - cl_git_pass(git_path_lstat(full.ptr, &st)); + cl_git_pass(git_fs_path_lstat(full.ptr, &st)); git_str_dispose(&full); if (!core_filemode) { diff --git a/tests/reset/hard.c b/tests/reset/hard.c index 36e8f14707e..9d177c02171 100644 --- a/tests/reset/hard.c +++ b/tests/reset/hard.c @@ -79,7 +79,7 @@ void test_reset_hard__resetting_reverts_modified_files(void) cl_git_pass(git_futils_readbuffer(&content, path.ptr)); cl_assert(strequal_ignore_eol(after[i], content.ptr)); } else { - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); } } @@ -154,7 +154,7 @@ void test_reset_hard__resetting_reverts_unmerged(void) cl_git_pass(git_revparse_single(&target, repo, "26a125e")); cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL)); - cl_assert(git_path_exists("status/conflicting_file") == 0); + cl_assert(git_fs_path_exists("status/conflicting_file") == 0); git_object_free(target); target = NULL; @@ -185,11 +185,11 @@ void test_reset_hard__cleans_up_merge(void) cl_git_pass(git_revparse_single(&target, repo, "0017bd4")); cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL)); - cl_assert(!git_path_exists(git_str_cstr(&merge_head_path))); - cl_assert(!git_path_exists(git_str_cstr(&merge_msg_path))); - cl_assert(!git_path_exists(git_str_cstr(&merge_mode_path))); + cl_assert(!git_fs_path_exists(git_str_cstr(&merge_head_path))); + cl_assert(!git_fs_path_exists(git_str_cstr(&merge_msg_path))); + cl_assert(!git_fs_path_exists(git_str_cstr(&merge_mode_path))); - cl_assert(git_path_exists(git_str_cstr(&orig_head_path))); + cl_assert(git_fs_path_exists(git_str_cstr(&orig_head_path))); cl_git_pass(p_unlink(git_str_cstr(&orig_head_path))); git_str_dispose(&merge_head_path); diff --git a/tests/revert/workdir.c b/tests/revert/workdir.c index 36824044b3b..0c98108146a 100644 --- a/tests/revert/workdir.c +++ b/tests/revert/workdir.c @@ -111,7 +111,7 @@ void test_revert_workdir__conflicts(void) "File one\n" \ ">>>>>>> parent of 72333f4... automergeable changes\n") == 0); - cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); cl_git_pass(git_futils_readbuffer(&mergemsg_buf, TEST_REPO_PATH "/.git/MERGE_MSG")); cl_assert(strcmp(mergemsg_buf.ptr, @@ -498,8 +498,8 @@ void test_revert_workdir__nonmerge_fails_mainline_specified(void) opts.mainline = 1; cl_must_fail(git_revert(repo, commit, &opts)); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD")); git_reference_free(head); git_commit_free(commit); @@ -517,8 +517,8 @@ void test_revert_workdir__merge_fails_without_mainline_specified(void) cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); cl_must_fail(git_revert(repo, head, NULL)); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD")); git_commit_free(head); } diff --git a/tests/stash/drop.c b/tests/stash/drop.c index 6b0895ba88c..709ff0f9e88 100644 --- a/tests/stash/drop.c +++ b/tests/stash/drop.c @@ -37,26 +37,26 @@ static void push_three_states(void) cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_add_bypath(index, "zero.txt")); cl_repo_commit_from_index(NULL, repo, signature, 0, "Initial commit"); - cl_assert(git_path_exists("stash/zero.txt")); + cl_assert(git_fs_path_exists("stash/zero.txt")); git_index_free(index); cl_git_mkfile("stash/one.txt", "content\n"); cl_git_pass(git_stash_save( &oid, repo, signature, "First", GIT_STASH_INCLUDE_UNTRACKED)); - cl_assert(!git_path_exists("stash/one.txt")); - cl_assert(git_path_exists("stash/zero.txt")); + cl_assert(!git_fs_path_exists("stash/one.txt")); + cl_assert(git_fs_path_exists("stash/zero.txt")); cl_git_mkfile("stash/two.txt", "content\n"); cl_git_pass(git_stash_save( &oid, repo, signature, "Second", GIT_STASH_INCLUDE_UNTRACKED)); - cl_assert(!git_path_exists("stash/two.txt")); - cl_assert(git_path_exists("stash/zero.txt")); + cl_assert(!git_fs_path_exists("stash/two.txt")); + cl_assert(git_fs_path_exists("stash/zero.txt")); cl_git_mkfile("stash/three.txt", "content\n"); cl_git_pass(git_stash_save( &oid, repo, signature, "Third", GIT_STASH_INCLUDE_UNTRACKED)); - cl_assert(!git_path_exists("stash/three.txt")); - cl_assert(git_path_exists("stash/zero.txt")); + cl_assert(!git_fs_path_exists("stash/three.txt")); + cl_assert(git_fs_path_exists("stash/zero.txt")); } void test_stash_drop__cannot_drop_a_non_existing_stashed_state(void) diff --git a/tests/stash/save.c b/tests/stash/save.c index 1fbcf0957a3..f574211d794 100644 --- a/tests/stash/save.c +++ b/tests/stash/save.c @@ -161,16 +161,16 @@ void test_stash_save__untracked_skips_ignored(void) cl_must_pass(p_mkdir("stash/bundle/vendor", 0777)); cl_git_mkfile("stash/bundle/vendor/blah", "contents\n"); - cl_assert(git_path_exists("stash/when")); /* untracked */ - cl_assert(git_path_exists("stash/just.ignore")); /* ignored */ - cl_assert(git_path_exists("stash/bundle/vendor/blah")); /* ignored */ + cl_assert(git_fs_path_exists("stash/when")); /* untracked */ + cl_assert(git_fs_path_exists("stash/just.ignore")); /* ignored */ + cl_assert(git_fs_path_exists("stash/bundle/vendor/blah")); /* ignored */ cl_git_pass(git_stash_save( &stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); - cl_assert(!git_path_exists("stash/when")); - cl_assert(git_path_exists("stash/bundle/vendor/blah")); - cl_assert(git_path_exists("stash/just.ignore")); + cl_assert(!git_fs_path_exists("stash/when")); + cl_assert(git_fs_path_exists("stash/bundle/vendor/blah")); + cl_assert(git_fs_path_exists("stash/just.ignore")); } void test_stash_save__can_include_untracked_and_ignored_files(void) @@ -185,7 +185,7 @@ void test_stash_save__can_include_untracked_and_ignored_files(void) assert_blob_oid("refs/stash^3:when", "b6ed15e81e2593d7bb6265eb4a991d29dc3e628b"); assert_blob_oid("refs/stash^3:just.ignore", "78925fb1236b98b37a35e9723033e627f97aa88b"); - cl_assert(!git_path_exists("stash/just.ignore")); + cl_assert(!git_fs_path_exists("stash/just.ignore")); } /* @@ -450,9 +450,9 @@ void test_stash_save__ignored_directory(void) cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED | GIT_STASH_INCLUDE_IGNORED)); - cl_assert(!git_path_exists("stash/ignored_directory/sub/some_file")); - cl_assert(!git_path_exists("stash/ignored_directory/sub")); - cl_assert(!git_path_exists("stash/ignored_directory")); + cl_assert(!git_fs_path_exists("stash/ignored_directory/sub/some_file")); + cl_assert(!git_fs_path_exists("stash/ignored_directory/sub")); + cl_assert(!git_fs_path_exists("stash/ignored_directory")); } void test_stash_save__skip_submodules(void) diff --git a/tests/status/submodules.c b/tests/status/submodules.c index 38a39471ac2..d223657b4ea 100644 --- a/tests/status/submodules.c +++ b/tests/status/submodules.c @@ -36,9 +36,9 @@ void test_status_submodules__0(void) g_repo = setup_fixture_submodules(); - cl_assert(git_path_isdir("submodules/.git")); - cl_assert(git_path_isdir("submodules/testrepo/.git")); - cl_assert(git_path_isfile("submodules/.gitmodules")); + cl_assert(git_fs_path_isdir("submodules/.git")); + cl_assert(git_fs_path_isdir("submodules/testrepo/.git")); + cl_assert(git_fs_path_isfile("submodules/.gitmodules")); cl_git_pass( git_status_foreach(g_repo, cb_status__count, &counts) @@ -89,9 +89,9 @@ void test_status_submodules__1(void) g_repo = setup_fixture_submodules(); - cl_assert(git_path_isdir("submodules/.git")); - cl_assert(git_path_isdir("submodules/testrepo/.git")); - cl_assert(git_path_isfile("submodules/.gitmodules")); + cl_assert(git_fs_path_isdir("submodules/.git")); + cl_assert(git_fs_path_isdir("submodules/testrepo/.git")); + cl_assert(git_fs_path_isfile("submodules/.gitmodules")); status_counts_init(counts, expected_files, expected_status); diff --git a/tests/status/worktree.c b/tests/status/worktree.c index 4ab04094a13..692ea93ef7b 100644 --- a/tests/status/worktree.c +++ b/tests/status/worktree.c @@ -109,7 +109,7 @@ static int remove_file_cb(void *data, git_str *file) if (git__suffixcmp(filename, ".git") == 0) return 0; - if (git_path_isdir(filename)) + if (git_fs_path_isdir(filename)) cl_git_pass(git_futils_rmdir_r(filename, NULL, GIT_RMDIR_REMOVE_FILES)); else cl_git_pass(p_unlink(git_str_cstr(file))); @@ -126,7 +126,7 @@ void test_status_worktree__purged_worktree(void) /* first purge the contents of the worktree */ cl_git_pass(git_str_sets(&workdir, git_repository_workdir(repo))); - cl_git_pass(git_path_direach(&workdir, 0, remove_file_cb, NULL)); + cl_git_pass(git_fs_path_direach(&workdir, 0, remove_file_cb, NULL)); git_str_dispose(&workdir); /* now get status */ @@ -374,7 +374,7 @@ void test_status_worktree__issue_592(void) repo = cl_git_sandbox_init("issue_592"); cl_git_pass(git_str_joinpath(&path, git_repository_workdir(repo), "l.txt")); cl_git_pass(p_unlink(git_str_cstr(&path))); - cl_assert(!git_path_exists("issue_592/l.txt")); + cl_assert(!git_fs_path_exists("issue_592/l.txt")); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "l.txt")); @@ -389,7 +389,7 @@ void test_status_worktree__issue_592_2(void) repo = cl_git_sandbox_init("issue_592"); cl_git_pass(git_str_joinpath(&path, git_repository_workdir(repo), "c/a.txt")); cl_git_pass(p_unlink(git_str_cstr(&path))); - cl_assert(!git_path_exists("issue_592/c/a.txt")); + cl_assert(!git_fs_path_exists("issue_592/c/a.txt")); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt")); @@ -405,7 +405,7 @@ void test_status_worktree__issue_592_3(void) cl_git_pass(git_str_joinpath(&path, git_repository_workdir(repo), "c")); cl_git_pass(git_futils_rmdir_r(git_str_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(!git_path_exists("issue_592/c/a.txt")); + cl_assert(!git_fs_path_exists("issue_592/c/a.txt")); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt")); diff --git a/tests/submodule/add.c b/tests/submodule/add.c index b564123dd58..ae5507d7f52 100644 --- a/tests/submodule/add.c +++ b/tests/submodule/add.c @@ -46,11 +46,11 @@ void test_submodule_add__url_absolute(void) ); git_submodule_free(sm); - cl_assert(git_path_isfile("submod2/" "sm_libgit2" "/.git")); + cl_assert(git_fs_path_isfile("submod2/" "sm_libgit2" "/.git")); - cl_assert(git_path_isdir("submod2/.git/modules")); - cl_assert(git_path_isdir("submod2/.git/modules/" "sm_libgit2")); - cl_assert(git_path_isfile("submod2/.git/modules/" "sm_libgit2" "/HEAD")); + cl_assert(git_fs_path_isdir("submod2/.git/modules")); + cl_assert(git_fs_path_isdir("submod2/.git/modules/" "sm_libgit2")); + cl_assert(git_fs_path_isfile("submod2/.git/modules/" "sm_libgit2" "/HEAD")); assert_submodule_url("sm_libgit2", "https://github.com/libgit2/libgit2.git"); cl_git_pass(git_repository_open(&repo, "submod2/" "sm_libgit2")); @@ -72,9 +72,9 @@ void test_submodule_add__url_absolute(void) ); git_submodule_free(sm); - cl_assert(git_path_isdir("submod2/" "sm_libgit2b" "/.git")); - cl_assert(git_path_isfile("submod2/" "sm_libgit2b" "/.git/HEAD")); - cl_assert(!git_path_exists("submod2/.git/modules/" "sm_libgit2b")); + cl_assert(git_fs_path_isdir("submod2/" "sm_libgit2b" "/.git")); + cl_assert(git_fs_path_isfile("submod2/" "sm_libgit2b" "/.git/HEAD")); + cl_assert(!git_fs_path_exists("submod2/.git/modules/" "sm_libgit2b")); assert_submodule_url("sm_libgit2b", "https://github.com/libgit2/libgit2.git"); } @@ -227,7 +227,7 @@ void test_submodule_add__submodule_clone_into_nonempty_dir_succeeds(void) cl_git_pass(git_submodule_clone(NULL, sm, NULL)); cl_git_pass(git_submodule_add_finalize(sm)); - cl_assert(git_path_exists("empty_standard_repo/sm/foobar")); + cl_assert(git_fs_path_exists("empty_standard_repo/sm/foobar")); assert_submodule_exists(g_repo, "sm"); diff --git a/tests/submodule/init.c b/tests/submodule/init.c index bf865a9e81d..a8e1291c4e0 100644 --- a/tests/submodule/init.c +++ b/tests/submodule/init.c @@ -20,7 +20,7 @@ void test_submodule_init__absolute_url(void) g_repo = setup_fixture_submodule_simple(); - cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); + cl_assert(git_fs_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); cl_git_pass(git_str_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); /* write the absolute url to the .gitmodules file*/ @@ -53,7 +53,7 @@ void test_submodule_init__relative_url(void) g_repo = setup_fixture_submodule_simple(); - cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); + cl_assert(git_fs_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); cl_git_pass(git_str_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo")); @@ -91,7 +91,7 @@ void test_submodule_init__relative_url_detached_head(void) cl_git_pass(git_repository_set_head_detached(g_repo, git_commit_id((git_commit *)head_commit))); - cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); + cl_assert(git_fs_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); cl_git_pass(git_str_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo")); diff --git a/tests/submodule/open.c b/tests/submodule/open.c index 4f31feedf9d..e6883d20881 100644 --- a/tests/submodule/open.c +++ b/tests/submodule/open.c @@ -27,9 +27,9 @@ static void assert_sm_valid(git_repository *parent, git_repository *child, const /* assert working directory */ cl_git_pass(git_str_joinpath(&expected, git_repository_workdir(parent), sm_name)); - cl_git_pass(git_path_prettify_dir(&expected, expected.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&expected, expected.ptr, NULL)); cl_git_pass(git_str_sets(&actual, git_repository_workdir(child))); - cl_git_pass(git_path_prettify_dir(&actual, actual.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&actual, actual.ptr, NULL)); cl_assert_equal_s(expected.ptr, actual.ptr); git_str_clear(&expected); @@ -38,14 +38,14 @@ static void assert_sm_valid(git_repository *parent, git_repository *child, const /* assert common directory */ cl_git_pass(git_str_joinpath(&expected, git_repository_commondir(parent), "modules")); cl_git_pass(git_str_joinpath(&expected, expected.ptr, sm_name)); - cl_git_pass(git_path_prettify_dir(&expected, expected.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&expected, expected.ptr, NULL)); cl_git_pass(git_str_sets(&actual, git_repository_commondir(child))); - cl_git_pass(git_path_prettify_dir(&actual, actual.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&actual, actual.ptr, NULL)); cl_assert_equal_s(expected.ptr, actual.ptr); /* assert git directory */ cl_git_pass(git_str_sets(&actual, git_repository_path(child))); - cl_git_pass(git_path_prettify_dir(&actual, actual.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&actual, actual.ptr, NULL)); cl_assert_equal_s(expected.ptr, actual.ptr); git_str_dispose(&expected); diff --git a/tests/submodule/repository_init.c b/tests/submodule/repository_init.c index 3927afc2e06..39b55c403df 100644 --- a/tests/submodule/repository_init.c +++ b/tests/submodule/repository_init.c @@ -26,11 +26,11 @@ void test_submodule_repository_init__basic(void) cl_git_pass(git_futils_readbuffer(&dot_git_content, "submod2/" "sm_gitmodules_only" "/.git")); cl_assert_equal_s("gitdir: ../.git/modules/sm_gitmodules_only/", dot_git_content.ptr); - cl_assert(git_path_isfile("submod2/" "sm_gitmodules_only" "/.git")); + cl_assert(git_fs_path_isfile("submod2/" "sm_gitmodules_only" "/.git")); - cl_assert(git_path_isdir("submod2/.git/modules")); - cl_assert(git_path_isdir("submod2/.git/modules/" "sm_gitmodules_only")); - cl_assert(git_path_isfile("submod2/.git/modules/" "sm_gitmodules_only" "/HEAD")); + cl_assert(git_fs_path_isdir("submod2/.git/modules")); + cl_assert(git_fs_path_isdir("submod2/.git/modules/" "sm_gitmodules_only")); + cl_assert(git_fs_path_isfile("submod2/.git/modules/" "sm_gitmodules_only" "/HEAD")); git_submodule_free(sm); git_repository_free(repo); diff --git a/tests/submodule/submodule_helpers.c b/tests/submodule/submodule_helpers.c index 95d20a009ac..b8fc9f60deb 100644 --- a/tests/submodule/submodule_helpers.c +++ b/tests/submodule/submodule_helpers.c @@ -65,7 +65,7 @@ void rewrite_gitmodules(const char *workdir) continue; } - git_path_prettify(&path, path.ptr, NULL); + git_fs_path_prettify(&path, path.ptr, NULL); git_str_putc(&path, '\n'); cl_assert(!git_str_oom(&path)); diff --git a/tests/worktree/merge.c b/tests/worktree/merge.c index 8bb95d1f706..5b7e2a837c2 100644 --- a/tests/worktree/merge.c +++ b/tests/worktree/merge.c @@ -73,7 +73,7 @@ void test_worktree_merge__merge_setup(void) cl_git_pass(git_str_joinpath(&path, fixture.worktree->gitdir, merge_files[i])); - cl_assert(git_path_exists(path.ptr)); + cl_assert(git_fs_path_exists(path.ptr)); } git_str_dispose(&path); diff --git a/tests/worktree/refs.c b/tests/worktree/refs.c index 5ae17ca1919..557726aafb6 100644 --- a/tests/worktree/refs.c +++ b/tests/worktree/refs.c @@ -181,14 +181,14 @@ void test_worktree_refs__creating_refs_uses_commondir(void) cl_git_pass(git_str_joinpath(&refpath, git_repository_commondir(fixture.worktree), "refs/heads/testbranch")); - cl_assert(!git_path_exists(refpath.ptr)); + cl_assert(!git_fs_path_exists(refpath.ptr)); cl_git_pass(git_repository_head(&head, fixture.worktree)); cl_git_pass(git_commit_lookup(&commit, fixture.worktree, git_reference_target(head))); cl_git_pass(git_branch_create(&branch, fixture.worktree, "testbranch", commit, 0)); cl_git_pass(git_branch_lookup(&lookup, fixture.worktree, "testbranch", GIT_BRANCH_LOCAL)); cl_assert(git_reference_cmp(branch, lookup) == 0); - cl_assert(git_path_exists(refpath.ptr)); + cl_assert(git_fs_path_exists(refpath.ptr)); git_reference_free(lookup); git_reference_free(branch); diff --git a/tests/worktree/submodule.c b/tests/worktree/submodule.c index 4c6c657d385..6b0c074526c 100644 --- a/tests/worktree/submodule.c +++ b/tests/worktree/submodule.c @@ -67,7 +67,7 @@ void test_worktree_submodule__resolve_relative_url(void) git_worktree *wt; cl_git_pass(git_futils_mkdir("subdir", 0755, GIT_MKDIR_PATH)); - cl_git_pass(git_path_prettify_dir(&wt_path, "subdir", NULL)); + cl_git_pass(git_fs_path_prettify_dir(&wt_path, "subdir", NULL)); cl_git_pass(git_str_joinpath(&wt_path, wt_path.ptr, "wt")); /* Open child repository, which is a submodule */ diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index a9a50fbf149..6f14b17f190 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -330,7 +330,7 @@ void test_worktree_worktree__init_existing_path(void) for (i = 0; i < ARRAY_SIZE(wtfiles); i++) { cl_git_pass(git_str_joinpath(&path, fixture.worktree->gitdir, wtfiles[i])); - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); } git_str_dispose(&path); @@ -351,9 +351,9 @@ void test_worktree_worktree__init_submodule(void) cl_git_pass(git_worktree_add(&worktree, sm, "repo-worktree", path.ptr, NULL)); cl_git_pass(git_repository_open_from_worktree(&wt, worktree)); - cl_git_pass(git_path_prettify_dir(&path, path.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&path, path.ptr, NULL)); cl_assert_equal_s(path.ptr, wt->workdir); - cl_git_pass(git_path_prettify_dir(&path, sm->commondir, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&path, sm->commondir, NULL)); cl_assert_equal_s(sm->commondir, wt->commondir); cl_git_pass(git_str_joinpath(&path, sm->gitdir, "worktrees/repo-worktree/")); @@ -560,8 +560,8 @@ void test_worktree_worktree__prune_gitdir_only(void) cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_git_pass(git_worktree_prune(wt, &opts)); - cl_assert(!git_path_exists(wt->gitdir_path)); - cl_assert(git_path_exists(wt->gitlink_path)); + cl_assert(!git_fs_path_exists(wt->gitdir_path)); + cl_assert(git_fs_path_exists(wt->gitlink_path)); git_worktree_free(wt); } @@ -576,8 +576,8 @@ void test_worktree_worktree__prune_worktree(void) cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_git_pass(git_worktree_prune(wt, &opts)); - cl_assert(!git_path_exists(wt->gitdir_path)); - cl_assert(!git_path_exists(wt->gitlink_path)); + cl_assert(!git_fs_path_exists(wt->gitdir_path)); + cl_assert(!git_fs_path_exists(wt->gitlink_path)); git_worktree_free(wt); } From 434a46107bbb1c4d90832c92d4d0f5c89cb82ead Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 09:31:32 -0400 Subject: [PATCH 0596/1616] fs_path: `validate` -> `is_valid` Since we're returning a boolean about validation, the name is more properly "is valid". --- src/fs_path.c | 6 +- src/fs_path.h | 4 +- src/path.c | 2 +- tests/path/core.c | 266 +++++++++++++++++++++++----------------------- 4 files changed, 139 insertions(+), 139 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index e180d586622..ceba02d6235 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1634,7 +1634,7 @@ static bool validate_component( return true; } -bool git_fs_path_validate_ext( +bool git_fs_path_is_valid_ext( const char *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), @@ -1673,9 +1673,9 @@ bool git_fs_path_validate_ext( return true; } -bool git_fs_path_validate(const char *path, unsigned int flags) +bool git_fs_path_is_valid(const char *path, unsigned int flags) { - return git_fs_path_validate_ext(path, flags, NULL, NULL, NULL); + return git_fs_path_is_valid_ext(path, flags, NULL, NULL, NULL); } #ifdef GIT_WIN32 diff --git a/src/fs_path.h b/src/fs_path.h index a60a37d9838..991e7cd830e 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -627,13 +627,13 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url * (trailing ' ' or ':' characters), or filenames ("component names") * that are not supported ('AUX', 'COM1"). */ -extern bool git_fs_path_validate(const char *path, unsigned int flags); +extern bool git_fs_path_is_valid(const char *path, unsigned int flags); /** * Validate a filesystem path; with custom callbacks per-character and * per-path component. */ -extern bool git_fs_path_validate_ext( +extern bool git_fs_path_is_valid_ext( const char *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), diff --git a/src/path.c b/src/path.c index d34125128b8..063009fa1c0 100644 --- a/src/path.c +++ b/src/path.c @@ -301,7 +301,7 @@ bool git_path_validate( data.file_mode = file_mode; data.flags = flags; - return git_fs_path_validate_ext(path, flags, NULL, validate_repo_component, &data); + return git_fs_path_is_valid_ext(path, flags, NULL, validate_repo_component, &data); } static const struct { diff --git a/tests/path/core.c b/tests/path/core.c index 8576b471e5f..f48a76957a6 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -59,180 +59,180 @@ void test_path_core__make_relative(void) void test_path_core__isvalid_standard(void) { - cl_assert_equal_b(true, git_fs_path_validate("foo/bar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar/file.txt", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar/.file", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar/file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar/.file", 0)); } void test_path_core__isvalid_empty_dir_component(void) { - cl_assert_equal_b(false, git_fs_path_validate("foo//bar", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", 0)); /* leading slash */ - cl_assert_equal_b(false, git_fs_path_validate("/", 0)); - cl_assert_equal_b(false, git_fs_path_validate("/foo", 0)); - cl_assert_equal_b(false, git_fs_path_validate("/foo/bar", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("/", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("/foo", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("/foo/bar", 0)); /* trailing slash */ - cl_assert_equal_b(false, git_fs_path_validate("foo/", 0)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar/", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", 0)); } void test_path_core__isvalid_dot_and_dotdot(void) { - cl_assert_equal_b(true, git_fs_path_validate(".", 0)); - cl_assert_equal_b(true, git_fs_path_validate("./foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/.", 0)); - cl_assert_equal_b(true, git_fs_path_validate("./foo", 0)); - - cl_assert_equal_b(true, git_fs_path_validate("..", 0)); - cl_assert_equal_b(true, git_fs_path_validate("../foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/..", 0)); - cl_assert_equal_b(true, git_fs_path_validate("../foo", 0)); - - cl_assert_equal_b(false, git_fs_path_validate(".", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("foo/.", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); - - cl_assert_equal_b(false, git_fs_path_validate("..", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("foo/..", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(true, git_fs_path_is_valid(".", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("./foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/.", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("./foo", 0)); + + cl_assert_equal_b(true, git_fs_path_is_valid("..", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("../foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/..", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("../foo", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid(".", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/.", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + + cl_assert_equal_b(false, git_fs_path_is_valid("..", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/..", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); } void test_path_core__isvalid_backslash(void) { - cl_assert_equal_b(true, git_fs_path_validate("foo\\file.txt", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar\\file.txt", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar\\", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo\\file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar\\file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar\\", 0)); - cl_assert_equal_b(false, git_fs_path_validate("foo\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar\\", GIT_FS_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar\\", GIT_FS_PATH_REJECT_BACKSLASH)); } void test_path_core__isvalid_trailing_dot(void) { - cl_assert_equal_b(true, git_fs_path_validate("foo.", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo...", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar.", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo./bar", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("foo.", GIT_FS_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_fs_path_validate("foo...", GIT_FS_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar.", GIT_FS_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_fs_path_validate("foo./bar", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo.", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo...", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar.", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo./bar", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("foo.", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo...", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar.", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo./bar", GIT_FS_PATH_REJECT_TRAILING_DOT)); } void test_path_core__isvalid_trailing_space(void) { - cl_assert_equal_b(true, git_fs_path_validate("foo ", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo ", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar ", 0)); - cl_assert_equal_b(true, git_fs_path_validate(" ", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo /bar", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_fs_path_validate("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_fs_path_validate(" ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_fs_path_validate("foo /bar", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo ", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo ", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar ", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid(" ", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo /bar", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_is_valid(" ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo /bar", GIT_FS_PATH_REJECT_TRAILING_SPACE)); } void test_path_core__isvalid_trailing_colon(void) { - cl_assert_equal_b(true, git_fs_path_validate("foo:", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar:", 0)); - cl_assert_equal_b(true, git_fs_path_validate(":", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo:/bar", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("foo:", GIT_FS_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar:", GIT_FS_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_fs_path_validate(":", GIT_FS_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_fs_path_validate("foo:/bar", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo:", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar:", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid(":", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo:/bar", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("foo:", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar:", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_is_valid(":", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo:/bar", GIT_FS_PATH_REJECT_TRAILING_COLON)); } void test_path_core__isvalid_dos_paths(void) { - cl_assert_equal_b(true, git_fs_path_validate("aux", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux.", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux:", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux.asdf", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux.asdf\\zippy", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux:asdf\\foobar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("con", 0)); - cl_assert_equal_b(true, git_fs_path_validate("prn", 0)); - cl_assert_equal_b(true, git_fs_path_validate("nul", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("aux", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("aux.", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("aux:", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("aux.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("aux.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("aux:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("con", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("prn", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("nul", GIT_FS_PATH_REJECT_DOS_PATHS)); - - cl_assert_equal_b(true, git_fs_path_validate("aux1", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux1", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("auxn", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("aux\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux.", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux:", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux.asdf", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux.asdf\\zippy", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux:asdf\\foobar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("con", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("prn", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("nul", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("aux", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("aux.", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("aux:", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("aux.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("aux.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("aux:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("con", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("prn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("nul", GIT_FS_PATH_REJECT_DOS_PATHS)); + + cl_assert_equal_b(true, git_fs_path_is_valid("aux1", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux1", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("auxn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); } void test_path_core__isvalid_dos_paths_withnum(void) { - cl_assert_equal_b(true, git_fs_path_validate("com1", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1.", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1:", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1.asdf", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1.asdf\\zippy", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1:asdf\\foobar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1\\foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("lpt1", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("com1", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1.", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1:", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1/foo", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("lpt1", GIT_FS_PATH_REJECT_DOS_PATHS)); - - cl_assert_equal_b(true, git_fs_path_validate("com0", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com0", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("com10", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com10", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("comn", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("com1\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("lpt0", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("lpt10", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("lptn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1.", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1:", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1.asdf", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1.asdf\\zippy", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1:asdf\\foobar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1\\foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("lpt1", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("com1", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1.", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1:", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1/foo", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("lpt1", GIT_FS_PATH_REJECT_DOS_PATHS)); + + cl_assert_equal_b(true, git_fs_path_is_valid("com0", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com0", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("com10", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com10", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("comn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("lpt0", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("lpt10", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("lptn", GIT_FS_PATH_REJECT_DOS_PATHS)); } void test_path_core__isvalid_nt_chars(void) { - cl_assert_equal_b(true, git_fs_path_validate("asdf\001foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf\037bar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdffoo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf:foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf\"bar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf|foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf?bar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf*bar", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("asdf\001foo", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf\037bar", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdffoo", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf:foo", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf\"bar", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf|foo", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf?bar", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf*bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf\001foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf\037bar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdffoo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf:foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf\"bar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf|foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf?bar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf*bar", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("asdf\001foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf\037bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdffoo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf:foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf\"bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf|foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf?bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf*bar", GIT_FS_PATH_REJECT_NT_CHARS)); } void test_path_core__validate_workdir(void) From 63e36c53caa8c3f1581471de64bbef3ca87f3921 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 09:34:32 -0400 Subject: [PATCH 0597/1616] path: `validate` -> `is_valid` Since we're returning a boolean about validation, the name is more properly "is valid". --- src/checkout.c | 4 +- src/index.c | 2 +- src/path.c | 2 +- src/path.h | 2 +- src/refdb_fs.c | 4 +- src/submodule.c | 2 +- src/tree.c | 2 +- tests/path/dotgit.c | 136 ++++++++++++++++++++++---------------------- 8 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/checkout.c b/src/checkout.c index 96ba4da386b..ad4edddd304 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -1281,14 +1281,14 @@ static int checkout_verify_paths( unsigned int flags = GIT_PATH_REJECT_WORKDIR_DEFAULTS; if (action & CHECKOUT_ACTION__REMOVE) { - if (!git_path_validate(repo, delta->old_file.path, delta->old_file.mode, flags)) { + if (!git_path_is_valid(repo, delta->old_file.path, delta->old_file.mode, flags)) { git_error_set(GIT_ERROR_CHECKOUT, "cannot remove invalid path '%s'", delta->old_file.path); return -1; } } if (action & ~CHECKOUT_ACTION__REMOVE) { - if (!git_path_validate(repo, delta->new_file.path, delta->new_file.mode, flags)) { + if (!git_path_is_valid(repo, delta->new_file.path, delta->new_file.mode, flags)) { git_error_set(GIT_ERROR_CHECKOUT, "cannot checkout to invalid path '%s'", delta->new_file.path); return -1; } diff --git a/src/index.c b/src/index.c index 448852f29b1..bd6ea8f03eb 100644 --- a/src/index.c +++ b/src/index.c @@ -945,7 +945,7 @@ static int index_entry_create( if (st) mode = st->st_mode; - if (!git_path_validate(repo, path, mode, path_valid_flags)) { + if (!git_path_is_valid(repo, path, mode, path_valid_flags)) { git_error_set(GIT_ERROR_INDEX, "invalid path: '%s'", path); return -1; } diff --git a/src/path.c b/src/path.c index 063009fa1c0..d54bc5bfe2a 100644 --- a/src/path.c +++ b/src/path.c @@ -285,7 +285,7 @@ GIT_INLINE(unsigned int) dotgit_flags( return flags; } -bool git_path_validate( +bool git_path_is_valid( git_repository *repo, const char *path, uint16_t file_mode, diff --git a/src/path.h b/src/path.h index ca220d12114..f874a16be15 100644 --- a/src/path.h +++ b/src/path.h @@ -25,7 +25,7 @@ #define GIT_PATH_REJECT_INDEX_DEFAULTS \ GIT_FS_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT -extern bool git_path_validate( +extern bool git_path_is_valid( git_repository *repo, const char *path, uint16_t file_mode, diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 39dc16e9d8f..acd6270917e 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -818,7 +818,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char * GIT_ASSERT_ARG(backend); GIT_ASSERT_ARG(name); - if (!git_path_validate(backend->repo, name, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { + if (!git_path_is_valid(backend->repo, name, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { git_error_set(GIT_ERROR_INVALID, "invalid reference name '%s'", name); return GIT_EINVALIDSPEC; } @@ -1857,7 +1857,7 @@ static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char repo = backend->repo; - if (!git_path_validate(backend->repo, refname, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { + if (!git_path_is_valid(backend->repo, refname, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { git_error_set(GIT_ERROR_INVALID, "invalid reference name '%s'", refname); return GIT_EINVALIDSPEC; } diff --git a/src/submodule.c b/src/submodule.c index 727b6c6e471..ffe29ccfba3 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -423,7 +423,7 @@ int git_submodule_name_is_valid(git_repository *repo, const char *name, int flag git_str_attach_notowned(&buf, name, strlen(name)); } - isvalid = git_path_validate(repo, buf.ptr, 0, flags); + isvalid = git_path_is_valid(repo, buf.ptr, 0, flags); git_str_dispose(&buf); return isvalid; diff --git a/src/tree.c b/src/tree.c index 256e720809d..b8e82d48574 100644 --- a/src/tree.c +++ b/src/tree.c @@ -55,7 +55,7 @@ GIT_INLINE(git_filemode_t) normalize_filemode(git_filemode_t filemode) static int valid_entry_name(git_repository *repo, const char *filename) { return *filename != '\0' && - git_path_validate(repo, filename, 0, + git_path_is_valid(repo, filename, 0, GIT_FS_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT | GIT_FS_PATH_REJECT_SLASH); } diff --git a/tests/path/dotgit.c b/tests/path/dotgit.c index 5b3a311379b..9ac68b0ff06 100644 --- a/tests/path/dotgit.c +++ b/tests/path/dotgit.c @@ -114,10 +114,10 @@ void test_path_dotgit__dotgit_modules(void) void test_path_dotgit__dotgit_modules_symlink(void) { - cl_assert_equal_b(true, git_path_validate(NULL, ".gitmodules", 0, GIT_PATH_REJECT_DOT_GIT_HFS|GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules . .::$DATA", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".gitmodules", 0, GIT_PATH_REJECT_DOT_GIT_HFS|GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".gitmodules . .::$DATA", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); } void test_core_path__git_fs_path_is_file(void) @@ -131,76 +131,76 @@ void test_core_path__git_fs_path_is_file(void) void test_path_dotgit__isvalid_dot_git(void) { - cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git/foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.GIT/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/.Git", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - - cl_assert_equal_b(true, git_path_validate(NULL, "!git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/!git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "!git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".tig", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.tig", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".tig/bar", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git/foo", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.git", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.git/bar", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.GIT/bar", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/bar/.Git", 0, 0)); + + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + + cl_assert_equal_b(true, git_path_is_valid(NULL, "!git", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/!git", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "!git/bar", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".tig", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.tig", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".tig/bar", 0, 0)); } void test_path_dotgit__isvalid_dotgit_ntfs(void) { - cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git.. .", 0, 0)); - - cl_assert_equal_b(true, git_path_validate(NULL, "git~1", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1 ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1.. .", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - - cl_assert_equal_b(false, git_path_validate(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git ", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git.", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git.. .", 0, 0)); + + cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1 ", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1.", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1.. .", 0, 0)); + + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + + cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); } void test_path_dotgit__isvalid_dotgit_with_hfs_ignorables(void) { - cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(true, git_path_validate(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + + cl_assert_equal_b(false, git_path_is_valid(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + + cl_assert_equal_b(true, git_path_is_valid(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); } From bef02d3e638ce8c95c9e63622b46d87a0f8ee2b2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 10:57:28 -0400 Subject: [PATCH 0598/1616] fs_path: introduce `str_is_valid` Provide a mechanism for users to limit the number of characters that are examined; `git_fs_path_str_is_valid` and friends will only examine up to `str->size` bytes. `git_fs_path_is_valid` delegates to these new functions by passing `SIZE_MAX` (instead of doing a `strlen`), which is a sentinel value meaning "look for a NUL terminator". --- src/fs_path.c | 21 +++++++++++-------- src/fs_path.h | 52 +++++++++++++++++++++++++++++++++++++---------- tests/path/core.c | 27 ++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index ceba02d6235..fa27a6e73c4 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1634,16 +1634,17 @@ static bool validate_component( return true; } -bool git_fs_path_is_valid_ext( - const char *path, +bool git_fs_path_is_valid_str_ext( + const git_str *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), bool (*validate_component_cb)(const char *component, size_t len, void *payload), void *payload) { const char *start, *c; + size_t len = 0; - for (start = c = path; *c; c++) { + for (start = c = path->ptr; *c && len < path->size; c++, len++) { if (!validate_char(*c, flags)) return false; @@ -1663,6 +1664,15 @@ bool git_fs_path_is_valid_ext( start = c + 1; } + /* + * We want to support paths specified as either `const char *` + * or `git_str *`; we pass size as `SIZE_MAX` when we use a + * `const char *` to avoid a `strlen`. Ensure that we didn't + * have a NUL in the buffer if there was a non-SIZE_MAX length. + */ + if (path->size != SIZE_MAX && len != path->size) + return false; + if (!validate_component(start, (c - start), flags)) return false; @@ -1673,11 +1683,6 @@ bool git_fs_path_is_valid_ext( return true; } -bool git_fs_path_is_valid(const char *path, unsigned int flags) -{ - return git_fs_path_is_valid_ext(path, flags, NULL, NULL, NULL); -} - #ifdef GIT_WIN32 GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) { diff --git a/src/fs_path.h b/src/fs_path.h index 991e7cd830e..2f4bc9f798f 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -620,26 +620,56 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url GIT_FS_PATH_REJECT_TRAVERSAL #endif -/** - * Validate a filesystem path. This ensures that the given path is legal - * and does not contain any "unsafe" components like path traversal ('.' - * or '..'), characters that are inappropriate for lesser filesystems - * (trailing ' ' or ':' characters), or filenames ("component names") - * that are not supported ('AUX', 'COM1"). - */ -extern bool git_fs_path_is_valid(const char *path, unsigned int flags); - /** * Validate a filesystem path; with custom callbacks per-character and * per-path component. */ -extern bool git_fs_path_is_valid_ext( - const char *path, +extern bool git_fs_path_is_valid_str_ext( + const git_str *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), bool (*validate_component_cb)(const char *component, size_t len, void *payload), void *payload); +GIT_INLINE(bool) git_fs_path_is_valid_ext( + const char *path, + unsigned int flags, + bool (*validate_char_cb)(char ch, void *payload), + bool (*validate_component_cb)(const char *component, size_t len, void *payload), + void *payload) +{ + const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); + return git_fs_path_is_valid_str_ext( + &str, + flags, + validate_char_cb, + validate_component_cb, + payload); +} + +/** + * Validate a filesystem path. This ensures that the given path is legal + * and does not contain any "unsafe" components like path traversal ('.' + * or '..'), characters that are inappropriate for lesser filesystems + * (trailing ' ' or ':' characters), or filenames ("component names") + * that are not supported ('AUX', 'COM1"). + */ +GIT_INLINE(bool) git_fs_path_is_valid( + const char *path, + unsigned int flags) +{ + const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); + return git_fs_path_is_valid_str_ext(&str, flags, NULL, NULL, NULL); +} + +/** Validate a filesystem path in a `git_str`. */ +GIT_INLINE(bool) git_fs_path_is_valid_str( + const git_str *path, + unsigned int flags) +{ + return git_fs_path_is_valid_str_ext(path, flags, NULL, NULL, NULL); +} + /** * Validate an on-disk path, taking into account that it will have a * suffix appended (eg, `.lock`). diff --git a/tests/path/core.c b/tests/path/core.c index f48a76957a6..6fa0450ca7c 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -64,6 +64,33 @@ void test_path_core__isvalid_standard(void) cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar/.file", 0)); } +/* Ensure that `is_valid_str` only reads str->size bytes */ +void test_path_core__isvalid_standard_str(void) +{ + git_str str = GIT_STR_INIT_CONST("foo/bar//zap", 0); + + str.size = 0; + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + + str.size = 3; + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + + str.size = 4; + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + + str.size = 5; + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + + str.size = 7; + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + + str.size = 8; + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + + str.size = strlen(str.ptr); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); +} + void test_path_core__isvalid_empty_dir_component(void) { cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", 0)); From dd748dbede1a36f1e929461ecbfcde749eb685bb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 13:04:40 -0400 Subject: [PATCH 0599/1616] fs_path: make empty component validation optional --- src/fs_path.c | 5 ++++- src/fs_path.h | 5 ++++- tests/path/core.c | 43 ++++++++++++++++++++++++++++++------------- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index fa27a6e73c4..483b21c1e86 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1599,7 +1599,7 @@ static bool validate_component( unsigned int flags) { if (len == 0) - return false; + return !(flags & GIT_FS_PATH_REJECT_EMPTY_COMPONENT); if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) && len == 1 && component[0] == '.') @@ -1644,6 +1644,9 @@ bool git_fs_path_is_valid_str_ext( const char *start, *c; size_t len = 0; + if (!flags) + return true; + for (start = c = path->ptr; *c && len < path->size; c++, len++) { if (!validate_char(*c, flags)) return false; diff --git a/src/fs_path.h b/src/fs_path.h index 2f4bc9f798f..275b3d857ac 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -591,7 +591,8 @@ extern bool git_fs_path_is_local_file_url(const char *file_url); extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url_or_path); /* Flags to determine path validity in `git_fs_path_isvalid` */ -#define GIT_FS_PATH_REJECT_TRAVERSAL (1 << 0) +#define GIT_FS_PATH_REJECT_EMPTY_COMPONENT (1 << 0) +#define GIT_FS_PATH_REJECT_TRAVERSAL (1 << 1) #define GIT_FS_PATH_REJECT_SLASH (1 << 2) #define GIT_FS_PATH_REJECT_BACKSLASH (1 << 3) #define GIT_FS_PATH_REJECT_TRAILING_DOT (1 << 4) @@ -608,6 +609,7 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url */ #ifdef GIT_WIN32 # define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ + GIT_FS_PATH_REJECT_EMPTY_COMPONENT | \ GIT_FS_PATH_REJECT_TRAVERSAL | \ GIT_FS_PATH_REJECT_BACKSLASH | \ GIT_FS_PATH_REJECT_TRAILING_DOT | \ @@ -617,6 +619,7 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url GIT_FS_PATH_REJECT_NT_CHARS #else # define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ + GIT_FS_PATH_REJECT_EMPTY_COMPONENT | \ GIT_FS_PATH_REJECT_TRAVERSAL #endif diff --git a/tests/path/core.c b/tests/path/core.c index 6fa0450ca7c..ccb328b1030 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -68,41 +68,58 @@ void test_path_core__isvalid_standard(void) void test_path_core__isvalid_standard_str(void) { git_str str = GIT_STR_INIT_CONST("foo/bar//zap", 0); + unsigned int flags = GIT_FS_PATH_REJECT_EMPTY_COMPONENT; str.size = 0; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); str.size = 3; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); str.size = 4; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); str.size = 5; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); str.size = 7; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); str.size = 8; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); str.size = strlen(str.ptr); - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); } void test_path_core__isvalid_empty_dir_component(void) { - cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", 0)); + unsigned int flags = GIT_FS_PATH_REJECT_EMPTY_COMPONENT; + + /* empty component */ + cl_assert_equal_b(true, git_fs_path_is_valid("foo//bar", 0)); + + /* leading slash */ + cl_assert_equal_b(true, git_fs_path_is_valid("/", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("/foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("/foo/bar", 0)); + + /* trailing slash */ + cl_assert_equal_b(true, git_fs_path_is_valid("foo/", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar/", 0)); + + + /* empty component */ + cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", flags)); /* leading slash */ - cl_assert_equal_b(false, git_fs_path_is_valid("/", 0)); - cl_assert_equal_b(false, git_fs_path_is_valid("/foo", 0)); - cl_assert_equal_b(false, git_fs_path_is_valid("/foo/bar", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("/", flags)); + cl_assert_equal_b(false, git_fs_path_is_valid("/foo", flags)); + cl_assert_equal_b(false, git_fs_path_is_valid("/foo/bar", flags)); /* trailing slash */ - cl_assert_equal_b(false, git_fs_path_is_valid("foo/", 0)); - cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/", flags)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", flags)); } void test_path_core__isvalid_dot_and_dotdot(void) From ebacd24c6039c992ef9122a0d6f7de0ca4ba3bd1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 13:58:18 -0400 Subject: [PATCH 0600/1616] fs_path: add long path validation on windows --- src/fs_path.c | 29 +++++++++++++++++++++++++++++ src/fs_path.h | 10 +++++++--- src/path.c | 2 +- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index 483b21c1e86..de3b03957a9 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1634,11 +1634,25 @@ static bool validate_component( return true; } +#ifdef GIT_WIN32 +GIT_INLINE(bool) validate_length( + const char *path, + size_t len, + size_t utf8_char_len) +{ + GIT_UNUSED(path); + GIT_UNUSED(len); + + return (utf8_char_len <= MAX_PATH); +} +#endif + bool git_fs_path_is_valid_str_ext( const git_str *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), bool (*validate_component_cb)(const char *component, size_t len, void *payload), + bool (*validate_length_cb)(const char *path, size_t len, size_t utf8_char_len), void *payload) { const char *start, *c; @@ -1683,6 +1697,21 @@ bool git_fs_path_is_valid_str_ext( !validate_component_cb(start, (c - start), payload)) return false; +#ifdef GIT_WIN32 + if ((flags & GIT_FS_PATH_REJECT_LONG_PATHS) != 0) { + size_t utf8_len = git_utf8_char_length(path->ptr, len); + + if (!validate_length(path->ptr, len, utf8_len)) + return false; + + if (validate_length_cb && + !validate_length_cb(path->ptr, len, utf8_len)) + return false; + } +#else + GIT_UNUSED(validate_length_cb); +#endif + return true; } diff --git a/src/fs_path.h b/src/fs_path.h index 275b3d857ac..40b4342f1dd 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -600,8 +600,9 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url #define GIT_FS_PATH_REJECT_TRAILING_COLON (1 << 6) #define GIT_FS_PATH_REJECT_DOS_PATHS (1 << 7) #define GIT_FS_PATH_REJECT_NT_CHARS (1 << 8) +#define GIT_FS_PATH_REJECT_LONG_PATHS (1 << 9) -#define GIT_FS_PATH_REJECT_MAX (1 << 8) +#define GIT_FS_PATH_REJECT_MAX (1 << 9) /* Default path safety for writing files to disk: since we use the * Win32 "File Namespace" APIs ("\\?\") we need to protect from @@ -632,6 +633,7 @@ extern bool git_fs_path_is_valid_str_ext( unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), bool (*validate_component_cb)(const char *component, size_t len, void *payload), + bool (*validate_length_cb)(const char *component, size_t len, size_t utf8_char_len), void *payload); GIT_INLINE(bool) git_fs_path_is_valid_ext( @@ -639,6 +641,7 @@ GIT_INLINE(bool) git_fs_path_is_valid_ext( unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), bool (*validate_component_cb)(const char *component, size_t len, void *payload), + bool (*validate_length_cb)(const char *component, size_t len, size_t utf8_char_len), void *payload) { const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); @@ -647,6 +650,7 @@ GIT_INLINE(bool) git_fs_path_is_valid_ext( flags, validate_char_cb, validate_component_cb, + validate_length_cb, payload); } @@ -662,7 +666,7 @@ GIT_INLINE(bool) git_fs_path_is_valid( unsigned int flags) { const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); - return git_fs_path_is_valid_str_ext(&str, flags, NULL, NULL, NULL); + return git_fs_path_is_valid_str_ext(&str, flags, NULL, NULL, NULL, NULL); } /** Validate a filesystem path in a `git_str`. */ @@ -670,7 +674,7 @@ GIT_INLINE(bool) git_fs_path_is_valid_str( const git_str *path, unsigned int flags) { - return git_fs_path_is_valid_str_ext(path, flags, NULL, NULL, NULL); + return git_fs_path_is_valid_str_ext(path, flags, NULL, NULL, NULL, NULL); } /** diff --git a/src/path.c b/src/path.c index d54bc5bfe2a..a6b396f6dc6 100644 --- a/src/path.c +++ b/src/path.c @@ -301,7 +301,7 @@ bool git_path_is_valid( data.file_mode = file_mode; data.flags = flags; - return git_fs_path_is_valid_ext(path, flags, NULL, validate_repo_component, &data); + return git_fs_path_is_valid_ext(path, flags, NULL, validate_repo_component, NULL, &data); } static const struct { From 315a43b2f16fab679126f519a5dce1c9e1e335af Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 17:37:06 -0400 Subject: [PATCH 0601/1616] path: introduce `git_path_str_is_valid` Add a `git_str` based validity check; the existing `git_path_is_valid` defers to it. --- src/fs_path.c | 2 +- src/fs_path.h | 10 +++++----- src/path.c | 6 +++--- src/path.h | 14 ++++++++++++-- tests/path/core.c | 14 +++++++------- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index de3b03957a9..9079c30c9e5 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1647,7 +1647,7 @@ GIT_INLINE(bool) validate_length( } #endif -bool git_fs_path_is_valid_str_ext( +bool git_fs_path_str_is_valid_ext( const git_str *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), diff --git a/src/fs_path.h b/src/fs_path.h index 40b4342f1dd..947c4ae867b 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -628,7 +628,7 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url * Validate a filesystem path; with custom callbacks per-character and * per-path component. */ -extern bool git_fs_path_is_valid_str_ext( +extern bool git_fs_path_str_is_valid_ext( const git_str *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), @@ -645,7 +645,7 @@ GIT_INLINE(bool) git_fs_path_is_valid_ext( void *payload) { const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); - return git_fs_path_is_valid_str_ext( + return git_fs_path_str_is_valid_ext( &str, flags, validate_char_cb, @@ -666,15 +666,15 @@ GIT_INLINE(bool) git_fs_path_is_valid( unsigned int flags) { const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); - return git_fs_path_is_valid_str_ext(&str, flags, NULL, NULL, NULL, NULL); + return git_fs_path_str_is_valid_ext(&str, flags, NULL, NULL, NULL, NULL); } /** Validate a filesystem path in a `git_str`. */ -GIT_INLINE(bool) git_fs_path_is_valid_str( +GIT_INLINE(bool) git_fs_path_str_is_valid( const git_str *path, unsigned int flags) { - return git_fs_path_is_valid_str_ext(path, flags, NULL, NULL, NULL, NULL); + return git_fs_path_str_is_valid_ext(path, flags, NULL, NULL, NULL, NULL); } /** diff --git a/src/path.c b/src/path.c index a6b396f6dc6..933444de241 100644 --- a/src/path.c +++ b/src/path.c @@ -285,9 +285,9 @@ GIT_INLINE(unsigned int) dotgit_flags( return flags; } -bool git_path_is_valid( +bool git_path_str_is_valid( git_repository *repo, - const char *path, + const git_str *path, uint16_t file_mode, unsigned int flags) { @@ -301,7 +301,7 @@ bool git_path_is_valid( data.file_mode = file_mode; data.flags = flags; - return git_fs_path_is_valid_ext(path, flags, NULL, validate_repo_component, NULL, &data); + return git_fs_path_str_is_valid_ext(path, flags, NULL, validate_repo_component, NULL, &data); } static const struct { diff --git a/src/path.h b/src/path.h index f874a16be15..f2ac8484b05 100644 --- a/src/path.h +++ b/src/path.h @@ -25,10 +25,20 @@ #define GIT_PATH_REJECT_INDEX_DEFAULTS \ GIT_FS_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT -extern bool git_path_is_valid( +extern bool git_path_str_is_valid( git_repository *repo, - const char *path, + const git_str *path, uint16_t file_mode, unsigned int flags); +GIT_INLINE(bool) git_path_is_valid( + git_repository *repo, + const char *path, + uint16_t file_mode, + unsigned int flags) +{ + git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); + return git_path_str_is_valid(repo, &str, file_mode, flags); +} + #endif diff --git a/tests/path/core.c b/tests/path/core.c index ccb328b1030..eb6e5b851a6 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -71,25 +71,25 @@ void test_path_core__isvalid_standard_str(void) unsigned int flags = GIT_FS_PATH_REJECT_EMPTY_COMPONENT; str.size = 0; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(false, git_fs_path_str_is_valid(&str, flags)); str.size = 3; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(true, git_fs_path_str_is_valid(&str, flags)); str.size = 4; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(false, git_fs_path_str_is_valid(&str, flags)); str.size = 5; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(true, git_fs_path_str_is_valid(&str, flags)); str.size = 7; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(true, git_fs_path_str_is_valid(&str, flags)); str.size = 8; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(false, git_fs_path_str_is_valid(&str, flags)); str.size = strlen(str.ptr); - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(false, git_fs_path_str_is_valid(&str, flags)); } void test_path_core__isvalid_empty_dir_component(void) From 1728e27c96a2e14328423554d3559166ebd1bab7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 18:19:56 -0400 Subject: [PATCH 0602/1616] path: length validation respecting core.longpaths Teach `git_path_is_valid` to respect `core.longpaths`. Add helper methods to validate length and set the error message appropriately. --- src/path.c | 26 ++++++++++++++++++++++++++ src/path.h | 24 ++++++++++++++++++++++++ tests/path/core.c | 37 +++++++++++++++++++------------------ 3 files changed, 69 insertions(+), 18 deletions(-) diff --git a/src/path.c b/src/path.c index 933444de241..05a3dc2cf90 100644 --- a/src/path.c +++ b/src/path.c @@ -285,6 +285,28 @@ GIT_INLINE(unsigned int) dotgit_flags( return flags; } +GIT_INLINE(unsigned int) length_flags( + git_repository *repo, + unsigned int flags) +{ +#ifdef GIT_WIN32 + int allow = 0; + + if (repo && + git_repository__configmap_lookup(&allow, repo, GIT_CONFIGMAP_LONGPATHS) < 0) + allow = 0; + + if (allow) + flags &= ~GIT_FS_PATH_REJECT_LONG_PATHS; + +#else + GIT_UNUSED(repo); + flags &= ~GIT_FS_PATH_REJECT_LONG_PATHS; +#endif + + return flags; +} + bool git_path_str_is_valid( git_repository *repo, const git_str *path, @@ -297,6 +319,10 @@ bool git_path_str_is_valid( if ((flags & GIT_PATH_REJECT_DOT_GIT)) flags = dotgit_flags(repo, flags); + /* Update the length checks based on platform */ + if ((flags & GIT_FS_PATH_REJECT_LONG_PATHS)) + flags = length_flags(repo, flags); + data.repo = repo; data.file_mode = file_mode; data.flags = flags; diff --git a/src/path.h b/src/path.h index f2ac8484b05..c4a2c425021 100644 --- a/src/path.h +++ b/src/path.h @@ -41,4 +41,28 @@ GIT_INLINE(bool) git_path_is_valid( return git_path_str_is_valid(repo, &str, file_mode, flags); } +GIT_INLINE(int) git_path_validate_str_length( + git_repository *repo, + const git_str *path) +{ + if (!git_path_str_is_valid(repo, path, 0, GIT_FS_PATH_REJECT_LONG_PATHS)) { + if (path->size == SIZE_MAX) + git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%s'", path->ptr); + else + git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%.*s'", (int)path->size, path->ptr); + + return -1; + } + + return 0; +} + +GIT_INLINE(int) git_path_validate_length( + git_repository *repo, + const char *path) +{ + git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); + return git_path_validate_str_length(repo, &str); +} + #endif diff --git a/tests/path/core.c b/tests/path/core.c index eb6e5b851a6..9421941c03f 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "fs_path.h" +#include "path.h" void test_path_core__cleanup(void) { @@ -281,30 +282,30 @@ void test_path_core__isvalid_nt_chars(void) void test_path_core__validate_workdir(void) { - cl_must_pass(git_fs_path_validate_workdir(NULL, "/foo/bar")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\Foo\\Bar")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\UNC\\server\\C$\\folder")); + cl_must_pass(git_path_validate_length(NULL, "/foo/bar")); + cl_must_pass(git_path_validate_length(NULL, "C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_length(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_length(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_length(NULL, "\\\\?\\UNC\\server\\C$\\folder")); #ifdef GIT_WIN32 /* * In the absense of a repo configuration, 259 character paths * succeed. >= 260 character paths fail. */ - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\260.txt")); - cl_must_fail(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\longer_than_260.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\260.txt")); + cl_must_fail(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\longer_than_260.txt")); /* count characters, not bytes */ - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); - cl_must_fail(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_fail(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); #else - cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/ok.txt")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/260.txt")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); + cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/ok.txt")); + cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/260.txt")); + cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); #endif } @@ -320,15 +321,15 @@ void test_path_core__validate_workdir_with_core_longpath(void) cl_git_pass(git_repository_config(&config, repo)); /* fail by default */ - cl_must_fail(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_fail(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); /* set core.longpaths explicitly on */ cl_git_pass(git_config_set_bool(config, "core.longpaths", 1)); - cl_must_pass(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_pass(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); /* set core.longpaths explicitly off */ cl_git_pass(git_config_set_bool(config, "core.longpaths", 0)); - cl_must_fail(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_fail(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); git_config_free(config); git_repository_free(repo); From 91246ee5e0d8be8a15a669844f0893cd0f01c604 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 20:14:34 -0400 Subject: [PATCH 0603/1616] path: use new length validation functions --- src/attrcache.c | 9 +++++++-- src/checkout.c | 6 +++--- src/filter.c | 3 ++- src/ignore.c | 5 +++-- src/iterator.c | 17 ++++++++++++----- src/mailmap.c | 3 ++- src/refdb_fs.c | 2 +- src/repository.c | 6 +++--- src/submodule.c | 2 +- src/worktree.c | 3 ++- 10 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/attrcache.c b/src/attrcache.c index 15c7fab485a..b16d95c3c02 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -12,6 +12,7 @@ #include "config.h" #include "sysdir.h" #include "ignore.h" +#include "path.h" GIT_INLINE(int) attr_cache_lock(git_attr_cache *cache) { @@ -43,6 +44,7 @@ int git_attr_cache__alloc_file_entry( const char *path, git_pool *pool) { + git_str fullpath_str = GIT_STR_INIT; size_t baselen = 0, pathlen = strlen(path); size_t cachesize = sizeof(git_attr_file_entry) + pathlen + 1; git_attr_file_entry *ce; @@ -66,7 +68,10 @@ int git_attr_cache__alloc_file_entry( } memcpy(&ce->fullpath[baselen], path, pathlen); - if (git_fs_path_validate_workdir_with_len(repo, ce->fullpath, pathlen + baselen) < 0) + fullpath_str.ptr = ce->fullpath; + fullpath_str.size = pathlen + baselen; + + if (git_path_validate_str_length(repo, &fullpath_str) < 0) return -1; ce->path = &ce->fullpath[baselen]; @@ -173,7 +178,7 @@ static int attr_cache_lookup( git_str *p = attr_session ? &attr_session->tmp : &path; if (git_str_joinpath(p, source->base, source->filename) < 0 || - git_fs_path_validate_workdir_buf(repo, p) < 0) + git_path_validate_str_length(repo, p) < 0) return -1; filename = p->ptr; diff --git a/src/checkout.c b/src/checkout.c index ad4edddd304..5733f4ab56c 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -329,7 +329,7 @@ static int checkout_target_fullpath( if (path && git_str_puts(&data->target_path, path) < 0) return -1; - if (git_fs_path_validate_workdir_buf(data->repo, &data->target_path) < 0) + if (git_path_validate_str_length(data->repo, &data->target_path) < 0) return -1; *out = &data->target_path; @@ -2035,7 +2035,7 @@ static int checkout_merge_path( int error = 0; if ((error = git_str_joinpath(out, data->opts.target_directory, result->path)) < 0 || - (error = git_fs_path_validate_workdir_buf(data->repo, out)) < 0) + (error = git_path_validate_str_length(data->repo, out)) < 0) return error; /* Most conflicts simply use the filename in the index */ @@ -2338,7 +2338,7 @@ static int validate_target_directory(checkout_data *data) { int error; - if ((error = git_fs_path_validate_workdir(data->repo, data->opts.target_directory)) < 0) + if ((error = git_path_validate_length(data->repo, data->opts.target_directory)) < 0) return error; if (git_fs_path_isdir(data->opts.target_directory)) diff --git a/src/filter.c b/src/filter.c index 95029603303..2712e8c6044 100644 --- a/src/filter.c +++ b/src/filter.c @@ -18,6 +18,7 @@ #include "blob.h" #include "attr_file.h" #include "array.h" +#include "path.h" struct git_filter_source { git_repository *repo; @@ -1095,7 +1096,7 @@ int git_filter_list_stream_file( if ((error = stream_list_init( &stream_start, &filter_streams, filters, target)) < 0 || (error = git_fs_path_join_unrooted(&abspath, path, base, NULL)) < 0 || - (error = git_fs_path_validate_workdir_buf(repo, &abspath)) < 0) + (error = git_path_validate_str_length(repo, &abspath)) < 0) goto done; initialized = 1; diff --git a/src/ignore.c b/src/ignore.c index e7d8b799f5d..cee58d7f15f 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -13,6 +13,7 @@ #include "fs_path.h" #include "config.h" #include "wildmatch.h" +#include "path.h" #define GIT_IGNORE_INTERNAL "[internal]exclude" @@ -320,14 +321,14 @@ int git_ignore__for_path( (error = git_fs_path_resolve_relative(&local, 0)) < 0 || (error = git_fs_path_to_dir(&local)) < 0 || (error = git_str_joinpath(&ignores->dir, workdir, local.ptr)) < 0 || - (error = git_fs_path_validate_workdir_buf(repo, &ignores->dir)) < 0) { + (error = git_path_validate_str_length(repo, &ignores->dir)) < 0) { /* Nothing, we just want to stop on the first error */ } git_str_dispose(&local); } else { if (!(error = git_str_joinpath(&ignores->dir, path, ""))) - error = git_fs_path_validate_filesystem(ignores->dir.ptr, ignores->dir.size); + error = git_path_validate_str_length(NULL, &ignores->dir); } if (error < 0) diff --git a/src/iterator.c b/src/iterator.c index a627e0f887b..a4337bb9ad4 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -9,6 +9,7 @@ #include "tree.h" #include "index.h" +#include "path.h" #define GIT_ITERATOR_FIRST_ACCESS (1 << 15) #define GIT_ITERATOR_HONOR_IGNORES (1 << 16) @@ -1279,7 +1280,7 @@ static int filesystem_iterator_entry_hash( iter->base.repo, entry->path, GIT_OBJECT_BLOB, NULL); if (!(error = git_str_joinpath(&fullpath, iter->root, entry->path)) && - !(error = git_fs_path_validate_workdir_buf(iter->base.repo, &fullpath))) + !(error = git_path_validate_str_length(iter->base.repo, &fullpath))) error = git_odb_hashfile(&entry->id, fullpath.ptr, GIT_OBJECT_BLOB); git_str_dispose(&fullpath); @@ -1361,7 +1362,7 @@ static int filesystem_iterator_frame_push( git_str_puts(&root, iter->root); if (git_str_oom(&root) || - git_fs_path_validate_workdir_buf(iter->base.repo, &root) < 0) { + git_path_validate_str_length(iter->base.repo, &root) < 0) { error = -1; goto done; } @@ -1389,10 +1390,16 @@ static int filesystem_iterator_frame_push( while ((error = git_fs_path_diriter_next(&diriter)) == 0) { iterator_pathlist_search_t pathlist_match = ITERATOR_PATHLIST_FULL; + git_str path_str = GIT_STR_INIT; bool dir_expected = false; - if ((error = git_fs_path_diriter_fullpath(&path, &path_len, &diriter)) < 0 || - (error = git_fs_path_validate_workdir_with_len(iter->base.repo, path, path_len)) < 0) + if ((error = git_fs_path_diriter_fullpath(&path, &path_len, &diriter)) < 0) + goto done; + + path_str.ptr = (char *)path; + path_str.size = path_len; + + if ((error = git_path_validate_str_length(iter->base.repo, &path_str)) < 0) goto done; GIT_ASSERT(path_len > iter->root_len); @@ -1565,7 +1572,7 @@ static int filesystem_iterator_is_dir( } if ((error = git_str_joinpath(&fullpath, iter->root, entry->path)) < 0 || - (error = git_fs_path_validate_workdir_buf(iter->base.repo, &fullpath)) < 0 || + (error = git_path_validate_str_length(iter->base.repo, &fullpath)) < 0 || (error = p_stat(fullpath.ptr, &st)) < 0) goto done; diff --git a/src/mailmap.c b/src/mailmap.c index 4fbb1ae779a..4336fe3e549 100644 --- a/src/mailmap.c +++ b/src/mailmap.c @@ -16,6 +16,7 @@ #include "git2/revparse.h" #include "blob.h" #include "parse.h" +#include "path.h" #define MM_FILE ".mailmap" #define MM_FILE_CONFIG "mailmap.file" @@ -331,7 +332,7 @@ static int mailmap_add_file_ondisk( if (error < 0) goto cleanup; - error = git_fs_path_validate_workdir_buf(repo, &fullpath); + error = git_path_validate_str_length(repo, &fullpath); if (error < 0) goto cleanup; diff --git a/src/refdb_fs.c b/src/refdb_fs.c index acd6270917e..dc291d0f592 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -1362,7 +1362,7 @@ static int refdb_fs_backend__prune_refs( git_str_cstr(&relative_path)); if (!error) - error = git_fs_path_validate_filesystem(base_path.ptr, base_path.size); + error = git_path_validate_str_length(NULL, &base_path); if (error < 0) goto cleanup; diff --git a/src/repository.c b/src/repository.c index 2f7ae9b3d6f..f564453db6b 100644 --- a/src/repository.c +++ b/src/repository.c @@ -32,7 +32,7 @@ #include "annotated_commit.h" #include "submodule.h" #include "worktree.h" - +#include "path.h" #include "strmap.h" #ifdef GIT_WIN32 @@ -2662,7 +2662,7 @@ int git_repository_workdir_path( } if (!(error = git_str_joinpath(out, repo->workdir, path))) - error = git_fs_path_validate_workdir_buf(repo, out); + error = git_path_validate_str_length(repo, out); return error; } @@ -2858,7 +2858,7 @@ int git_repository_hashfile( GIT_ASSERT_ARG(repo); if ((error = git_fs_path_join_unrooted(&full_path, path, workdir, NULL)) < 0 || - (error = git_fs_path_validate_workdir_buf(repo, &full_path)) < 0) + (error = git_path_validate_str_length(repo, &full_path)) < 0) return error; /* diff --git a/src/submodule.c b/src/submodule.c index ffe29ccfba3..0370ac82b38 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -386,7 +386,7 @@ int git_submodule__lookup_with_cache( if (git_str_join3(&path, '/', git_repository_workdir(repo), name, DOT_GIT) < 0 || - git_fs_path_validate_workdir_buf(NULL, &path) < 0) + git_path_validate_str_length(NULL, &path) < 0) return -1; if (git_fs_path_exists(path.ptr)) diff --git a/src/worktree.c b/src/worktree.c index f0fc6d752bb..e08d6d40162 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -9,6 +9,7 @@ #include "buf.h" #include "repository.h" +#include "path.h" #include "git2/branch.h" #include "git2/commit.h" @@ -136,7 +137,7 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char goto out; } - if ((error = git_fs_path_validate_workdir(NULL, dir)) < 0) + if ((error = git_path_validate_length(NULL, dir)) < 0) goto out; if ((wt = git__calloc(1, sizeof(*wt))) == NULL) { From 622514095fd1d731d35b0d69608911445ba3b0c4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 21:09:17 -0400 Subject: [PATCH 0604/1616] fs_path: add length with suffix validation --- src/fs_path.c | 23 +++++++++++++++++++++++ src/fs_path.h | 4 ++++ src/refdb_fs.c | 2 +- src/repository.c | 4 ++-- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index 9079c30c9e5..56980148e9c 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1715,6 +1715,29 @@ bool git_fs_path_str_is_valid_ext( return true; } +int git_fs_path_validate_str_length_with_suffix( + git_str *path, + size_t suffix_len) +{ +#ifdef GIT_WIN32 + size_t utf8_len = git_utf8_char_length(path->ptr, path->size); + size_t total_len; + + if (GIT_ADD_SIZET_OVERFLOW(&total_len, utf8_len, suffix_len) || + total_len > MAX_PATH) { + + git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%.*s'", + (int)path->size, path->ptr); + return -1; + } +#else + GIT_UNUSED(path); + GIT_UNUSED(suffix_len); +#endif + + return 0; +} + #ifdef GIT_WIN32 GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) { diff --git a/src/fs_path.h b/src/fs_path.h index 947c4ae867b..116e8f912bc 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -677,6 +677,10 @@ GIT_INLINE(bool) git_fs_path_str_is_valid( return git_fs_path_str_is_valid_ext(path, flags, NULL, NULL, NULL, NULL); } +extern int git_fs_path_validate_str_length_with_suffix( + git_str *path, + size_t suffix_len); + /** * Validate an on-disk path, taking into account that it will have a * suffix appended (eg, `.lock`). diff --git a/src/refdb_fs.c b/src/refdb_fs.c index dc291d0f592..097d2b38ec8 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -77,7 +77,7 @@ GIT_INLINE(int) loose_path( if (git_str_joinpath(out, base, refname) < 0) return -1; - return git_fs_path_validate_filesystem_with_suffix(out->ptr, out->size, + return git_fs_path_validate_str_length_with_suffix(out, CONST_STRLEN(".lock")); } diff --git a/src/repository.c b/src/repository.c index f564453db6b..3b3f7ca82fb 100644 --- a/src/repository.c +++ b/src/repository.c @@ -240,8 +240,8 @@ GIT_INLINE(int) validate_repo_path(git_str *path) CONST_STRLEN("objects/pack/pack-.pack.lock") + GIT_OID_HEXSZ; - return git_fs_path_validate_filesystem_with_suffix( - path->ptr, path->size, suffix_len); + return git_fs_path_validate_str_length_with_suffix( + path, suffix_len); } /* From 1217c5b232a2343f711ecf4c4ed38211ee6a268a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 21:12:23 -0400 Subject: [PATCH 0605/1616] fs_path: remove now-unused validation functions --- src/fs_path.c | 46 ---------------------------------------------- src/fs_path.h | 22 ---------------------- 2 files changed, 68 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index 56980148e9c..957f389ccc6 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1738,52 +1738,6 @@ int git_fs_path_validate_str_length_with_suffix( return 0; } -#ifdef GIT_WIN32 -GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) -{ - int longpaths = 0; - - if (repo && - git_repository__configmap_lookup(&longpaths, repo, GIT_CONFIGMAP_LONGPATHS) < 0) - longpaths = 0; - - return (longpaths == 0); -} - -#else - -GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) -{ - GIT_UNUSED(repo); - - return false; -} -#endif - -int git_fs_path_validate_workdir(git_repository *repo, const char *path) -{ - if (should_validate_longpaths(repo)) - return git_fs_path_validate_filesystem(path, strlen(path)); - - return 0; -} - -int git_fs_path_validate_workdir_with_len( - git_repository *repo, - const char *path, - size_t path_len) -{ - if (should_validate_longpaths(repo)) - return git_fs_path_validate_filesystem(path, path_len); - - return 0; -} - -int git_fs_path_validate_workdir_buf(git_repository *repo, git_str *path) -{ - return git_fs_path_validate_workdir_with_len(repo, path->ptr, path->size); -} - int git_fs_path_normalize_slashes(git_str *out, const char *path) { int error; diff --git a/src/fs_path.h b/src/fs_path.h index 116e8f912bc..dcedd5eb5fb 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -725,28 +725,6 @@ GIT_INLINE(int) git_fs_path_validate_filesystem( return git_fs_path_validate_filesystem_with_suffix(path, path_len, 0); } -/** - * Validate a path relative to the repo's worktree. This ensures that - * the given working tree path is valid for the operating system/platform. - * This will ensure that an absolute path is smaller than MAX_PATH on - * Windows, while keeping `core.longpaths` configuration settings in mind. - * - * This should be checked by mechamisms like `git_checkout` after - * contructing on-disk paths and before trying to write them. - * - * If the repository is null, no repository configuration is applied. - */ -extern int git_fs_path_validate_workdir( - git_repository *repo, - const char *path); -extern int git_fs_path_validate_workdir_with_len( - git_repository *repo, - const char *path, - size_t path_len); -extern int git_fs_path_validate_workdir_buf( - git_repository *repo, - git_str *buf); - /** * Convert any backslashes into slashes */ From 1a8b2922d953e78bd51fc6d5ef290e1f7e00af3a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 9 Nov 2021 14:15:32 +0000 Subject: [PATCH 0606/1616] win32: include correct path header --- src/fs_path.h | 1 + src/win32/findfile.c | 2 +- src/win32/path_w32.c | 2 +- src/win32/posix_w32.c | 3 +-- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fs_path.h b/src/fs_path.h index dcedd5eb5fb..188dcf303f7 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -12,6 +12,7 @@ #include "posix.h" #include "str.h" #include "vector.h" +#include "utf8.h" #include "git2/sys/path.h" diff --git a/src/win32/findfile.c b/src/win32/findfile.c index 7578d960e39..d4afc4acceb 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -9,7 +9,7 @@ #include "path_w32.h" #include "utf-conv.h" -#include "path.h" +#include "fs_path.h" #define REG_MSYSGIT_INSTALL_LOCAL L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c index 1f765f1deef..5d7ad11f646 100644 --- a/src/win32/path_w32.c +++ b/src/win32/path_w32.c @@ -7,7 +7,7 @@ #include "path_w32.h" -#include "path.h" +#include "fs_path.h" #include "utf-conv.h" #include "posix.h" #include "reparse.h" diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index 398287f9e89..ba46b5ea97a 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -9,10 +9,9 @@ #include "../posix.h" #include "../futils.h" -#include "path.h" +#include "fs_path.h" #include "path_w32.h" #include "utf-conv.h" -#include "repository.h" #include "reparse.h" #include #include From 644c763b761eca2653b567515cc4b59262d58428 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 11 Nov 2021 00:30:40 +0100 Subject: [PATCH 0607/1616] Document that `git_odb` is thread-safe Commit 4ae41f9c639d246d34dac89c3f1d9451c9cfa8d3 made `git_odb` race-free, and added internal locking. Update `docs/threading.md` accordingly, so that APIs built atop libgit2 (e.g. language bindings) can count on this. --- docs/threading.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/threading.md b/docs/threading.md index ddfaf7ae59a..de085c807cc 100644 --- a/docs/threading.md +++ b/docs/threading.md @@ -21,6 +21,9 @@ There are some objects which are read-only/immutable and are thus safe to share across threads, such as references and configuration snapshots. +The `git_odb` object uses locking internally, and is thread-safe to use from +multiple threads simultaneously. + Error messages -------------- From 7891660a1299a3e22fe722634d493e3353eb8cae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BChl?= Date: Thu, 28 Oct 2021 14:15:41 +0200 Subject: [PATCH 0608/1616] update remote/insteadof tests we want to test: - an anonymous repo (a url) - a named repo with a url - a named repo with a url and pushurl and for each of these matching configuration: - only insteadOf - only pushInsteadOf - both insteadOf and pushInsteadOf this change adds test cases for all of these combinations. --- tests/remote/insteadof.c | 110 ++++++++++++++++++++--- tests/resources/testrepo2/.gitted/config | 41 +++++++-- 2 files changed, 128 insertions(+), 23 deletions(-) diff --git a/tests/remote/insteadof.c b/tests/remote/insteadof.c index 05d4757cf0c..c39df4be7f2 100644 --- a/tests/remote/insteadof.c +++ b/tests/remote/insteadof.c @@ -4,7 +4,12 @@ #define REPO_PATH "testrepo2/.gitted" #define REMOTE_ORIGIN "origin" -#define REMOTE_INSTEADOF "insteadof-test" +#define REMOTE_INSTEADOF_URL_FETCH "insteadof-url-fetch" +#define REMOTE_INSTEADOF_URL_PUSH "insteadof-url-push" +#define REMOTE_INSTEADOF_URL_BOTH "insteadof-url-both" +#define REMOTE_INSTEADOF_PUSHURL_FETCH "insteadof-pushurl-fetch" +#define REMOTE_INSTEADOF_PUSHURL_PUSH "insteadof-pushurl-push" +#define REMOTE_INSTEADOF_PUSHURL_BOTH "insteadof-pushurl-both" static git_repository *g_repo; static git_remote *g_remote; @@ -21,7 +26,7 @@ void test_remote_insteadof__cleanup(void) git_remote_free(g_remote); } -void test_remote_insteadof__url_insteadof_not_applicable(void) +void test_remote_insteadof__not_applicable(void) { cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH))); cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_ORIGIN)); @@ -29,44 +34,121 @@ void test_remote_insteadof__url_insteadof_not_applicable(void) cl_assert_equal_s( git_remote_url(g_remote), "https://github.com/libgit2/false.git"); + cl_assert_equal_p(git_remote_pushurl(g_remote), NULL); } -void test_remote_insteadof__url_insteadof_applicable(void) +void test_remote_insteadof__url_insteadof_fetch(void) { cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH))); - cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_INSTEADOF)); + cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_INSTEADOF_URL_FETCH)); cl_assert_equal_s( git_remote_url(g_remote), - "http://github.com/libgit2/libgit2"); + "http://github.com/url/fetch/libgit2"); + cl_assert_equal_p(git_remote_pushurl(g_remote), NULL); } -void test_remote_insteadof__pushurl_insteadof_not_applicable(void) +void test_remote_insteadof__url_insteadof_push(void) { cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH))); - cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_ORIGIN)); + cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_INSTEADOF_URL_PUSH)); - cl_assert_equal_p(git_remote_pushurl(g_remote), NULL); + cl_assert_equal_s( + git_remote_url(g_remote), + "http://example.com/url/push/libgit2"); + cl_assert_equal_s( + git_remote_pushurl(g_remote), + "git@github.com:url/push/libgit2"); } -void test_remote_insteadof__pushurl_insteadof_applicable(void) +void test_remote_insteadof__url_insteadof_both(void) { cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH))); - cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_INSTEADOF)); + cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_INSTEADOF_URL_BOTH)); + cl_assert_equal_s( + git_remote_url(g_remote), + "http://github.com/url/both/libgit2"); cl_assert_equal_s( git_remote_pushurl(g_remote), - "git@github.com:libgit2/libgit2"); + "git@github.com:url/both/libgit2"); } -void test_remote_insteadof__anonymous_remote(void) +void test_remote_insteadof__pushurl_insteadof_fetch(void) +{ + cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH))); + cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_INSTEADOF_PUSHURL_FETCH)); + + cl_assert_equal_s( + git_remote_url(g_remote), + "http://github.com/url/fetch/libgit2"); + cl_assert_equal_s( + git_remote_pushurl(g_remote), + "http://github.com/url/fetch/libgit2-push"); +} + +void test_remote_insteadof__pushurl_insteadof_push(void) +{ + cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH))); + cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_INSTEADOF_PUSHURL_PUSH)); + + cl_assert_equal_s( + git_remote_url(g_remote), + "http://example.com/url/push/libgit2"); + cl_assert_equal_s( + git_remote_pushurl(g_remote), + "http://example.com/url/push/libgit2-push"); +} + +void test_remote_insteadof__pushurl_insteadof_both(void) +{ + cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH))); + cl_git_pass(git_remote_lookup(&g_remote, g_repo, REMOTE_INSTEADOF_PUSHURL_BOTH)); + + cl_assert_equal_s( + git_remote_url(g_remote), + "http://github.com/url/both/libgit2"); + cl_assert_equal_s( + git_remote_pushurl(g_remote), + "http://github.com/url/both/libgit2-push"); +} + +void test_remote_insteadof__anonymous_remote_fetch(void) { cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH))); cl_git_pass(git_remote_create_anonymous(&g_remote, g_repo, - "http://example.com/libgit2/libgit2")); + "http://example.com/url/fetch/libgit2")); cl_assert_equal_s( git_remote_url(g_remote), - "http://github.com/libgit2/libgit2"); + "http://github.com/url/fetch/libgit2"); cl_assert_equal_p(git_remote_pushurl(g_remote), NULL); } + +void test_remote_insteadof__anonymous_remote_push(void) +{ + cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH))); + cl_git_pass(git_remote_create_anonymous(&g_remote, g_repo, + "http://example.com/url/push/libgit2")); + + cl_assert_equal_s( + git_remote_url(g_remote), + "http://example.com/url/push/libgit2"); + cl_assert_equal_s( + git_remote_pushurl(g_remote), + "git@github.com:url/push/libgit2"); +} + +void test_remote_insteadof__anonymous_remote_both(void) +{ + cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH))); + cl_git_pass(git_remote_create_anonymous(&g_remote, g_repo, + "http://example.com/url/both/libgit2")); + + cl_assert_equal_s( + git_remote_url(g_remote), + "http://github.com/url/both/libgit2"); + cl_assert_equal_s( + git_remote_pushurl(g_remote), + "git@github.com:url/both/libgit2"); +} diff --git a/tests/resources/testrepo2/.gitted/config b/tests/resources/testrepo2/.gitted/config index 4af067f0401..6966b8a5dd1 100644 --- a/tests/resources/testrepo2/.gitted/config +++ b/tests/resources/testrepo2/.gitted/config @@ -8,19 +8,42 @@ [remote "origin"] url = https://github.com/libgit2/false.git fetch = +refs/heads/*:refs/remotes/origin/* -[remote "insteadof-test"] - url = http://example.com/libgit2/libgit2 - pushurl = http://github.com/libgit2/libgit2 +[remote "insteadof-url-fetch"] + url = http://example.com/url/fetch/libgit2 + fetch = +refs/heads/*:refs/remotes/test/* +[remote "insteadof-url-push"] + url = http://example.com/url/push/libgit2 + fetch = +refs/heads/*:refs/remotes/test/* +[remote "insteadof-url-both"] + url = http://example.com/url/both/libgit2 + fetch = +refs/heads/*:refs/remotes/test/* +[remote "insteadof-pushurl-fetch"] + url = http://example.com/url/fetch/libgit2 + pushurl = http://example.com/url/fetch/libgit2-push + fetch = +refs/heads/*:refs/remotes/test/* +[remote "insteadof-pushurl-push"] + url = http://example.com/url/push/libgit2 + pushurl = http://example.com/url/push/libgit2-push + fetch = +refs/heads/*:refs/remotes/test/* +[remote "insteadof-pushurl-both"] + url = http://example.com/url/both/libgit2 + pushurl = http://example.com/url/both/libgit2-push fetch = +refs/heads/*:refs/remotes/test/* [branch "master"] remote = origin merge = refs/heads/master rebase = true [url "longer-non-prefix-match"] - insteadOf = ttp://example.com/li + # not applicable because it's not a prefix match + insteadOf = ttp://example.com/url/fetch/li [url "shorter-prefix"] - insteadOf = http://example.co -[url "http://github.com"] - insteadOf = http://example.com -[url "git@github.com:"] - pushInsteadOf = http://github.com/ + # not applicable because the matched prefix is shorter + insteadOf = http://example.com/url/fe +[url "http://github.com/url/fetch"] + insteadOf = http://example.com/url/fetch +[url "http://github.com/url/both"] + insteadOf = http://example.com/url/both +[url "git@github.com:url/push"] + pushInsteadOf = http://example.com/url/push +[url "git@github.com:url/both"] + pushInsteadOf = http://example.com/url/both From 93d321aba29d3d8b3ea5f2930b128da7c136b8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BChl?= Date: Thu, 28 Oct 2021 14:56:29 +0200 Subject: [PATCH 0609/1616] fix remote/insteadof tests --- src/remote.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/remote.c b/src/remote.c index bde4ce779c2..32973f700b5 100644 --- a/src/remote.c +++ b/src/remote.c @@ -30,7 +30,7 @@ static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs); static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name); -char *apply_insteadof(git_config *config, const char *url, int direction); +char *apply_insteadof(git_config *config, const char *url, int direction, int *matched); static int add_refspec_to(git_vector *vector, const char *string, bool is_fetch) { @@ -210,7 +210,9 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem git_str var = GIT_STR_INIT; git_str specbuf = GIT_STR_INIT; const git_remote_create_options dummy_opts = GIT_REMOTE_CREATE_OPTIONS_INIT; + char *tmp; int error = -1; + int matched; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(url); @@ -245,7 +247,12 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem goto on_error; if (opts->repository && !(opts->flags & GIT_REMOTE_CREATE_SKIP_INSTEADOF)) { - remote->url = apply_insteadof(config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH); + remote->url = apply_insteadof(config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH, &matched); + tmp = apply_insteadof(config_ro, canonical_url.ptr, GIT_DIRECTION_PUSH, &matched); + if (matched) { + remote->pushurl = tmp; + GIT_ERROR_CHECK_ALLOC(remote->pushurl); + } } else { remote->url = git__strdup(canonical_url.ptr); } @@ -457,7 +464,9 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) git_remote *remote = NULL; git_str buf = GIT_STR_INIT; const char *val; + char *tmp; int error = 0; + int matched; git_config *config; struct refspec_cb_data data = { NULL }; bool optional_setting_found = false, found; @@ -498,8 +507,13 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO; if (found && strlen(val) > 0) { - remote->url = apply_insteadof(config, val, GIT_DIRECTION_FETCH); + remote->url = apply_insteadof(config, val, GIT_DIRECTION_FETCH, &matched); GIT_ERROR_CHECK_ALLOC(remote->url); + tmp = apply_insteadof(config, val, GIT_DIRECTION_PUSH, &matched); + if (matched) { + remote->pushurl = tmp; + GIT_ERROR_CHECK_ALLOC(remote->pushurl); + } } val = NULL; @@ -518,7 +532,10 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) } if (found && strlen(val) > 0) { - remote->pushurl = apply_insteadof(config, val, GIT_DIRECTION_PUSH); + if (remote->pushurl) { + git__free(remote->pushurl); + } + remote->pushurl = apply_insteadof(config, val, GIT_DIRECTION_FETCH, &matched); GIT_ERROR_CHECK_ALLOC(remote->pushurl); } @@ -2719,7 +2736,7 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_ #define SUFFIX_FETCH "insteadof" #define SUFFIX_PUSH "pushinsteadof" -char *apply_insteadof(git_config *config, const char *url, int direction) +char *apply_insteadof(git_config *config, const char *url, int direction, int *matched) { size_t match_length, prefix_length, suffix_length; char *replacement = NULL; @@ -2732,6 +2749,8 @@ char *apply_insteadof(git_config *config, const char *url, int direction) GIT_ASSERT_ARG_WITH_RETVAL(config, NULL); GIT_ASSERT_ARG_WITH_RETVAL(url, NULL); GIT_ASSERT_ARG_WITH_RETVAL(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH, NULL); + GIT_ASSERT_ARG_WITH_RETVAL(matched, NULL); + *matched = 0; /* Add 1 to prefix/suffix length due to the additional escaped dot */ prefix_length = strlen(PREFIX) + 1; @@ -2777,6 +2796,7 @@ char *apply_insteadof(git_config *config, const char *url, int direction) git__free(replacement); + *matched = 1; return result.ptr; } From 08047ca0121f8e6d82ed4ed5fafa13127285050d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 19:56:31 +0000 Subject: [PATCH 0610/1616] str: git_str_free is never a function --- src/str.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/str.c b/src/str.c index 7b50800c147..9d579f1441f 100644 --- a/src/str.c +++ b/src/str.c @@ -132,13 +132,6 @@ void git_str_dispose(git_str *buf) git_str_init(buf, 0); } -#ifndef GIT_DEPRECATE_HARD -void git_str_free(git_str *buf) -{ - git_str_dispose(buf); -} -#endif - void git_str_clear(git_str *buf) { buf->size = 0; From 9324d16e7356c1928d577a719eaaad264da58b13 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 6 Nov 2021 16:14:47 -0400 Subject: [PATCH 0611/1616] cmake: standardize USE_THREADS and USE_NSEC Threading can now be disabled with `USE_THREADS=OFF` instead of `THREADSAFE=OFF` to better support the other cmake semantics. Nanosecond support is the default _if_ we can detect it. This should be our default always - like threads - and people can opt out explicitly. --- CMakeLists.txt | 25 ++++++++++++++----------- README.md | 2 +- cmake/FindStatNsec.cmake | 30 ++++++++++++------------------ docs/error-handling.md | 2 +- src/CMakeLists.txt | 6 +++--- src/thread.h | 4 ++-- 6 files changed, 33 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7b2e71ca1a..2c442d2a04b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.5.1) project(libgit2 VERSION "1.3.0" LANGUAGES C) # Add find modules to the path -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${libgit2_SOURCE_DIR}/cmake/") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${libgit2_SOURCE_DIR}/cmake") # Modules @@ -30,12 +30,15 @@ include(EnableWarnings) # # Optional subsystems -option(THREADSAFE "Build libgit2 as threadsafe" ON) option(BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON) option(BUILD_TESTS "Build Tests using the Clar suite" ON) option(BUILD_EXAMPLES "Build library usage example apps" OFF) option(BUILD_FUZZERS "Build the fuzz targets" OFF) +# Suggested functionality that may not be available on a per-platform basis +option(USE_THREADS "Use threads for parallel processing when possible" ON) +option(USE_NSEC "Support nanosecond precision file mtimes and ctimes" ON) + # Backend selection option(USE_SSH "Link with libssh2 to enable SSH support" ON) option(USE_HTTPS "Enable HTTPS support. Can be set to a specific backend" ON) @@ -55,7 +58,7 @@ option(DEBUG_STRICT_OPEN "Enable path validation in open" # Output options option(SONAME "Set the (SO)VERSION of the target" ON) option(LIBGIT2_FILENAME "Name of the produced binary" OFF) -option(DEPRECATE_HARD "Do not include deprecated functions in the library" OFF) +option(DEPRECATE_HARD "Do not include deprecated functions in the library" OFF) # Compilation options option(ENABLE_WERROR "Enable compilation with -Werror" OFF) @@ -63,35 +66,35 @@ option(ENABLE_WERROR "Enable compilation with -Werror" if(UNIX) # NTLM client requires crypto libraries from the system HTTPS stack if(NOT USE_HTTPS) - option(USE_NTLMCLIENT "Enable NTLM support on Unix." OFF) + option(USE_NTLMCLIENT "Enable NTLM support on Unix." OFF) else() - option(USE_NTLMCLIENT "Enable NTLM support on Unix." ON) + option(USE_NTLMCLIENT "Enable NTLM support on Unix." ON) endif() - option(ENABLE_REPRODUCIBLE_BUILDS "Enable reproducible builds" OFF) + option(ENABLE_REPRODUCIBLE_BUILDS "Enable reproducible builds" OFF) endif() if(APPLE) - option(USE_ICONV "Link with and use iconv library" ON) + option(USE_ICONV "Link with and use iconv library" ON) endif() if(MSVC) # This option must match the settings used in your program, in particular if you # are linking statically - option(STATIC_CRT "Link the static CRT libraries" ON) + option(STATIC_CRT "Link the static CRT libraries" ON) # If you want to embed a copy of libssh2 into libgit2, pass a # path to libssh2 - option(EMBED_SSH_PATH "Path to libssh2 to embed (Windows)" OFF) + option(EMBED_SSH_PATH "Path to libssh2 to embed (Windows)" OFF) # Enable leak checking using the debugging C runtime. - option(WIN32_LEAKCHECK "Enable leak reporting via crtdbg" OFF) + option(WIN32_LEAKCHECK "Enable leak reporting via crtdbg" OFF) endif() if(WIN32) # By default, libgit2 is built with WinHTTP. To use the built-in # HTTP transport, invoke CMake with the "-DWINHTTP=OFF" argument. - option(WINHTTP "Use Win32 WinHTTP routines" ON) + option(WINHTTP "Use Win32 WinHTTP routines" ON) endif() diff --git a/README.md b/README.md index 2a365df302d..7ed5f6c8097 100644 --- a/README.md +++ b/README.md @@ -279,7 +279,7 @@ The following CMake variables are declared: - `CMAKE_INSTALL_INCLUDEDIR`: Where to install headers to. - `BUILD_SHARED_LIBS`: Build libgit2 as a Shared Library (defaults to ON) - `BUILD_TESTS`: Build the unit and integration test suites (defaults to ON) -- `THREADSAFE`: Build libgit2 with threading support (defaults to ON) +- `USE_THREADS`: Build libgit2 with threading support (defaults to ON) To list all build options and their current value, you can do the following: diff --git a/cmake/FindStatNsec.cmake b/cmake/FindStatNsec.cmake index a4a09fa8120..9dfdf51c4e7 100644 --- a/cmake/FindStatNsec.cmake +++ b/cmake/FindStatNsec.cmake @@ -1,26 +1,20 @@ -INCLUDE(FeatureSummary) +include(FeatureSummary) -CHECK_STRUCT_HAS_MEMBER ("struct stat" st_mtim "sys/types.h;sys/stat.h" +check_struct_has_member("struct stat" st_mtim "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM LANGUAGE C) -CHECK_STRUCT_HAS_MEMBER ("struct stat" st_mtimespec "sys/types.h;sys/stat.h" +check_struct_has_member("struct stat" st_mtimespec "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC LANGUAGE C) -CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtime_nsec sys/stat.h +check_struct_has_member("struct stat" st_mtime_nsec sys/stat.h HAVE_STRUCT_STAT_MTIME_NSEC LANGUAGE C) -IF (HAVE_STRUCT_STAT_ST_MTIM) - CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec sys/stat.h +if(HAVE_STRUCT_STAT_ST_MTIM) + check_struct_has_member("struct stat" st_mtim.tv_nsec sys/stat.h HAVE_STRUCT_STAT_NSEC LANGUAGE C) -ELSEIF (HAVE_STRUCT_STAT_ST_MTIMESPEC) - CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtimespec.tv_nsec sys/stat.h +elseif(HAVE_STRUCT_STAT_ST_MTIMESPEC) + check_struct_has_member("struct stat" st_mtimespec.tv_nsec sys/stat.h HAVE_STRUCT_STAT_NSEC LANGUAGE C) -ELSE () - SET( HAVE_STRUCT_STAT_NSEC ON ) -ENDIF() +else() + set(HAVE_STRUCT_STAT_NSEC ON ) +endif() -IF (HAVE_STRUCT_STAT_NSEC OR WIN32) - OPTION( USE_NSEC "Care about sub-second file mtimes and ctimes" ON ) -ELSE() - SET(USE_NSEC OFF) -ENDIF() - -ADD_FEATURE_INFO(nanoseconds USE_NSEC "whether to use sub-second file mtimes and ctimes") +add_feature_info(nanoseconds USE_NSEC "support nanosecond precision file mtimes and ctimes") diff --git a/docs/error-handling.md b/docs/error-handling.md index 05725f2ed06..13ce78f5f6c 100644 --- a/docs/error-handling.md +++ b/docs/error-handling.md @@ -21,7 +21,7 @@ critical failures (such as a packfile being corrupted, a loose object having the wrong access permissions, etc.) all of which will return -1. When the object lookup is successful, it will return 0. -If libgit2 was compiled with threads enabled (`-DTHREADSAFE=ON` when using +If libgit2 was compiled with threads enabled (`-DUSE_THREADS=ON` when using CMake), then the error message will be kept in thread-local storage, so it will not be modified by other threads. If threads are not enabled, then the error message is in global data. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9812fc0e441..de8beefd875 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -81,11 +81,11 @@ if(NEED_LIBRT) list(APPEND LIBGIT2_PC_LIBS "-lrt") endif() -if(THREADSAFE) +if(USE_THREADS) list(APPEND LIBGIT2_LIBS ${CMAKE_THREAD_LIBS_INIT}) list(APPEND LIBGIT2_PC_LIBS ${CMAKE_THREAD_LIBS_INIT}) endif() -add_feature_info(threadsafe THREADSAFE "threadsafe support") +add_feature_info(threadsafe USE_THREADS "threadsafe support") if(WIN32 AND EMBED_SSH_PATH) @@ -277,7 +277,7 @@ endif() add_feature_info(iconv GIT_USE_ICONV "iconv encoding conversion support") -if(THREADSAFE) +if(USE_THREADS) if(NOT WIN32) find_package(Threads REQUIRED) endif() diff --git a/src/thread.h b/src/thread.h index 4b091c0a29a..82eb7fcab03 100644 --- a/src/thread.h +++ b/src/thread.h @@ -12,7 +12,7 @@ #if defined(__clang__) # if (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 1)) -# error Atomic primitives do not exist on this version of clang; configure libgit2 with -DTHREADSAFE=OFF +# error Atomic primitives do not exist on this version of clang; configure libgit2 with -DUSE_THREADS=OFF # else # define GIT_BUILTIN_ATOMIC # endif @@ -20,7 +20,7 @@ #elif defined(__GNUC__) # if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)) -# error Atomic primitives do not exist on this version of gcc; configure libgit2 with -DTHREADSAFE=OFF +# error Atomic primitives do not exist on this version of gcc; configure libgit2 with -DUSE_THREADS=OFF # elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) # define GIT_BUILTIN_ATOMIC # else From 789ab915607c3d91d8c04fd217de9bf37c631f5f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 10 Nov 2021 21:02:42 -0500 Subject: [PATCH 0612/1616] cmake: standardize USE_WINHTTP WinHTTP can now be disabled with `USE_WINHTTP=OFF` instead of `WINHTTP=OFF` to better support the other cmake semantics. --- CMakeLists.txt | 4 ++-- cmake/SelectHTTPSBackend.cmake | 2 +- src/CMakeLists.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c442d2a04b..c8825e96662 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,8 +93,8 @@ endif() if(WIN32) # By default, libgit2 is built with WinHTTP. To use the built-in - # HTTP transport, invoke CMake with the "-DWINHTTP=OFF" argument. - option(WINHTTP "Use Win32 WinHTTP routines" ON) + # HTTP transport, invoke CMake with the "-DUSE_WINHTTP=OFF" argument. + option(USE_WINHTTP "Use Win32 WinHTTP routines" ON) endif() diff --git a/cmake/SelectHTTPSBackend.cmake b/cmake/SelectHTTPSBackend.cmake index 4998f0f2ac9..4af747417bf 100644 --- a/cmake/SelectHTTPSBackend.cmake +++ b/cmake/SelectHTTPSBackend.cmake @@ -19,7 +19,7 @@ IF(USE_HTTPS) MESSAGE(STATUS "Security framework is too old, falling back to OpenSSL") SET(USE_HTTPS "OpenSSL") ENDIF() - ELSEIF (WINHTTP) + ELSEIF (USE_WINHTTP) SET(USE_HTTPS "WinHTTP") ELSEIF(OPENSSL_FOUND) SET(USE_HTTPS "OpenSSL") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index de8beefd875..eed04f8ee43 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -98,7 +98,7 @@ if(WIN32 AND EMBED_SSH_PATH) set(GIT_SSH 1) endif() -if(WIN32 AND WINHTTP) +if(WIN32 AND USE_WINHTTP) set(GIT_WINHTTP 1) # Since MinGW does not come with headers or an import library for winhttp, From 6c00fcb767b38c1902c0b1ca15350e7c5766e23d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 10 Nov 2021 17:32:41 -0500 Subject: [PATCH 0613/1616] cmake: USE_SSH is not on by default --- .github/workflows/main.yml | 14 +++++++------- .github/workflows/nightly.yml | 26 +++++++++++++------------- CMakeLists.txt | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e805b1bb891..6e342d1169d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -91,7 +91,7 @@ jobs: env: CC: gcc CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DDEBUG_STRICT_ALLOC=ON -DDEBUG_STRICT_OPEN=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON -DDEBUG_STRICT_ALLOC=ON -DDEBUG_STRICT_OPEN=ON os: ubuntu-latest - # Xenial, GCC, mbedTLS container: @@ -99,7 +99,7 @@ jobs: env: CC: gcc CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON os: ubuntu-latest - # Xenial, Clang, OpenSSL container: @@ -107,14 +107,14 @@ jobs: env: CC: clang CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON os: ubuntu-latest - # Xenial, Clang, mbedTLS container: name: xenial env: CC: clang - CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest - # Focal, Clang 10, mbedTLS, MemorySanitizer @@ -123,7 +123,7 @@ jobs: env: CC: clang-10 CFLAGS: -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer - CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local/msan -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local/msan -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true @@ -136,7 +136,7 @@ jobs: env: CC: clang-10 CFLAGS: -fsanitize=undefined,nullability -fno-sanitize-recover=undefined,nullability -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer - CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true @@ -149,7 +149,7 @@ jobs: env: CC: clang-10 CFLAGS: -fsanitize=thread -fno-optimize-sibling-calls -fno-omit-frame-pointer - CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local -DUSE_HTTPS=OpenSSL -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 47ebf464d11..789f268f8de 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -25,7 +25,7 @@ jobs: env: CC: gcc CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON os: ubuntu-latest - # Xenial, GCC, mbedTLS container: @@ -33,7 +33,7 @@ jobs: env: CC: gcc CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON os: ubuntu-latest - # Xenial, Clang, OpenSSL container: @@ -41,14 +41,14 @@ jobs: env: CC: clang CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON os: ubuntu-latest - # Xenial, Clang, mbedTLS container: name: xenial env: CC: clang - CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest - # Xenial, GCC, thread-free @@ -56,7 +56,7 @@ jobs: name: xenial env: CC: gcc - CMAKE_OPTIONS: -DTHREADSAFE=OFF -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DTHREADSAFE=OFF -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest - # Xenial, Clang, OpenSSL (dynamically loaded) @@ -64,7 +64,7 @@ jobs: name: xenial env: CC: clang - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest - # Focal, Clang 10, mbedTLS, MemorySanitizer @@ -119,7 +119,7 @@ jobs: container: name: centos7 env: - CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON PKG_CONFIG_PATH: /usr/local/lib/pkgconfig SKIP_NEGOTIATE_TESTS: true os: ubuntu-latest @@ -127,7 +127,7 @@ jobs: container: name: centos7 env: - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON PKG_CONFIG_PATH: /usr/local/lib/pkgconfig SKIP_NEGOTIATE_TESTS: true os: ubuntu-latest @@ -212,7 +212,7 @@ jobs: env: CC: gcc CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON RUN_INVASIVE_TESTS: true os: ubuntu-latest - # Bionic, x86, Clang, OpenSSL @@ -223,7 +223,7 @@ jobs: env: CC: clang CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON RUN_INVASIVE_TESTS: true os: ubuntu-latest - # Bionic, x86, GCC, OpenSSL @@ -233,7 +233,7 @@ jobs: env: CC: gcc CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON RUN_INVASIVE_TESTS: true os: ubuntu-latest - # Bionic, arm32, GCC, OpenSSL @@ -244,7 +244,7 @@ jobs: env: CC: gcc CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_GSSAPI=ON -DUSE_SSH=ON RUN_INVASIVE_TESTS: true SKIP_PROXY_TESTS: true os: ubuntu-latest @@ -256,7 +256,7 @@ jobs: env: CC: gcc CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_GSSAPI=ON + CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_GSSAPI=ON -DUSE_SSH=ON RUN_INVASIVE_TESTS: true SKIP_PROXY_TESTS: true os: ubuntu-latest diff --git a/CMakeLists.txt b/CMakeLists.txt index c8825e96662..040881f83d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ option(USE_THREADS "Use threads for parallel processing when possibl option(USE_NSEC "Support nanosecond precision file mtimes and ctimes" ON) # Backend selection -option(USE_SSH "Link with libssh2 to enable SSH support" ON) +option(USE_SSH "Link with libssh2 to enable SSH support" OFF) option(USE_HTTPS "Enable HTTPS support. Can be set to a specific backend" ON) option(USE_SHA1 "Enable SHA1. Can be set to CollisionDetection(ON)/HTTPS/Generic" ON) option(USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF) From 9f37457e17f1b1f9e899b757df3413180719005f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 6 Nov 2021 16:23:03 -0400 Subject: [PATCH 0614/1616] cmake: move cflag defaults into a separate module --- CMakeLists.txt | 189 ++++---------------------------------- cmake/DefaultCFlags.cmake | 153 ++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 171 deletions(-) create mode 100644 cmake/DefaultCFlags.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 040881f83d8..f7f19468cba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,23 +8,6 @@ project(libgit2 VERSION "1.3.0" LANGUAGES C) # Add find modules to the path set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${libgit2_SOURCE_DIR}/cmake") -# Modules - -include(CheckLibraryExists) -include(CheckFunctionExists) -include(CheckSymbolExists) -include(CheckStructHasMember) -include(CheckPrototypeDefinition) -include(AddCFlagIfSupported) -include(FindPkgLibraries) -include(FindThreads) -include(FindStatNsec) -include(Findfutimens) -include(GNUInstallDirs) -include(IdeSplitSources) -include(FeatureSummary) -include(EnableWarnings) - # # Build options # @@ -98,6 +81,24 @@ if(WIN32) endif() +# Modules + +include(CheckLibraryExists) +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CheckStructHasMember) +include(CheckPrototypeDefinition) +include(AddCFlagIfSupported) +include(FindPkgLibraries) +include(FindThreads) +include(FindStatNsec) +include(Findfutimens) +include(GNUInstallDirs) +include(IdeSplitSources) +include(FeatureSummary) +include(EnableWarnings) +include(DefaultCFlags) + # # Compiler / linker flags # @@ -106,160 +107,6 @@ if(DEPRECATE_HARD) add_definitions(-DGIT_DEPRECATE_HARD) endif() -# Platform specific compilation flags -if(MSVC) - add_definitions(-D_SCL_SECURE_NO_WARNINGS) - add_definitions(-D_CRT_SECURE_NO_DEPRECATE) - add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) - - string(REPLACE "/Zm1000" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - - # /GF - String pooling - # /MP - Parallel build - set(CMAKE_C_FLAGS "/GF /MP /nologo ${CMAKE_C_FLAGS}") - - # /Gd - explicitly set cdecl calling convention - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gd") - - if(NOT (MSVC_VERSION LESS 1900)) - # /guard:cf - Enable Control Flow Guard - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /guard:cf") - endif() - - if(STATIC_CRT) - set(CRT_FLAG_DEBUG "/MTd") - set(CRT_FLAG_RELEASE "/MT") - else() - set(CRT_FLAG_DEBUG "/MDd") - set(CRT_FLAG_RELEASE "/MD") - endif() - - if(WIN32_LEAKCHECK) - set(GIT_WIN32_LEAKCHECK 1) - set(CRT_FLAG_DEBUG "${CRT_FLAG_DEBUG}") - set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} Dbghelp.lib") - endif() - - # /Zi - Create debugging information - # /Od - Disable optimization - # /D_DEBUG - #define _DEBUG - # /MTd - Statically link the multithreaded debug version of the CRT - # /MDd - Dynamically link the multithreaded debug version of the CRT - # /RTC1 - Run time checks - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Zi /Od /D_DEBUG /RTC1 ${CRT_FLAG_DEBUG}") - - # /DNDEBUG - Disables asserts - # /MT - Statically link the multithreaded release version of the CRT - # /MD - Dynamically link the multithreaded release version of the CRT - # /O2 - Optimize for speed - # /Oy - Enable frame pointer omission (FPO) (otherwise CMake will automatically turn it off) - # /GL - Link time code generation (whole program optimization) - # /Gy - Function-level linking - set(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /Oy /GL /Gy ${CRT_FLAG_RELEASE}") - - # /Oy- - Disable frame pointer omission (FPO) - set(CMAKE_C_FLAGS_RELWITHDEBINFO "/DNDEBUG /Zi /O2 /Oy- /GL /Gy ${CRT_FLAG_RELEASE}") - - # /O1 - Optimize for size - set(CMAKE_C_FLAGS_MINSIZEREL "/DNDEBUG /O1 /Oy /GL /Gy ${CRT_FLAG_RELEASE}") - - # /IGNORE:4221 - Ignore empty compilation units - set(CMAKE_STATIC_LINKER_FLAGS "/IGNORE:4221") - - # /DYNAMICBASE - Address space load randomization (ASLR) - # /NXCOMPAT - Data execution prevention (DEP) - # /LARGEADDRESSAWARE - >2GB user address space on x86 - # /VERSION - Embed version information in PE header - set(CMAKE_EXE_LINKER_FLAGS "/DYNAMICBASE /NXCOMPAT /LARGEADDRESSAWARE /VERSION:${libgit2_VERSION_MAJOR}.${libgit2_VERSION_MINOR}") - - if(NOT (MSVC_VERSION LESS 1900)) - # /GUARD:CF - Enable Control Flow Guard - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /GUARD:CF") - endif() - - # /DEBUG - Create a PDB - # /LTCG - Link time code generation (whole program optimization) - # /OPT:REF /OPT:ICF - Fold out duplicate code at link step - # /INCREMENTAL:NO - Required to use /LTCG - # /DEBUGTYPE:cv,fixup - Additional data embedded in the PDB (requires /INCREMENTAL:NO, so not on for Debug) - set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG") - set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO") - set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG /RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO /DEBUGTYPE:cv,fixup") - set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO") - - # Same linker settings for DLL as EXE - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") - set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") - set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") - set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}") - set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}") -else() - if(ENABLE_REPRODUCIBLE_BUILDS) - set(CMAKE_C_ARCHIVE_CREATE " Dqc ") - set(CMAKE_C_ARCHIVE_APPEND " Dq ") - set(CMAKE_C_ARCHIVE_FINISH " -D ") - endif() - - if(NOT BUILD_SHARED_LIBS) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - endif() - - set(CMAKE_C_FLAGS "-D_GNU_SOURCE ${CMAKE_C_FLAGS}") - - enable_warnings(all) - enable_warnings(extra) - - if(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - set(CMAKE_C_FLAGS "-D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS ${CMAKE_C_FLAGS}") - endif() - - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -O0") - - if(MINGW OR MSYS) # MinGW and MSYS always do PIC and complain if we tell them to - string(REGEX REPLACE "-fPIC" "" CMAKE_SHARED_LIBRARY_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}") - elseif(BUILD_SHARED_LIBS) - add_c_flag_IF_SUPPORTED(-fvisibility=hidden) - - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") - endif() - - if(MINGW) - # MinGW >= 3.14 uses the C99-style stdio functions - # automatically, but forks like mingw-w64 still want - # us to define this in order to use them - add_definitions(-D__USE_MINGW_ANSI_STDIO=1) - endif() - - enable_warnings(documentation) - disable_warnings(documentation-deprecated-sync) - disable_warnings(missing-field-initializers) - enable_warnings(strict-aliasing) - enable_warnings(strict-prototypes) - enable_warnings(declaration-after-statement) - enable_warnings(shift-count-overflow) - enable_warnings(unused-const-variable) - enable_warnings(unused-function) - enable_warnings(int-conversion) - enable_warnings(c11-extensions) - enable_warnings(c99-c11-compat) - - # MinGW uses gcc, which expects POSIX formatting for printf, but - # uses the Windows C library, which uses its own format specifiers. - # Disable format specifier warnings. - if(MINGW) - disable_warnings(format) - disable_warnings(format-security) - else() - enable_warnings(format) - enable_warnings(format-security) - endif() -endif() - -# Ensure that MinGW provides the correct header files. -if(WIN32 AND NOT CYGWIN) - add_definitions(-DWIN32 -D_WIN32_WINNT=0x0600) -endif() - if(NOT CMAKE_CONFIGURATION_TYPES) # Build Debug by default if(NOT CMAKE_BUILD_TYPE) diff --git a/cmake/DefaultCFlags.cmake b/cmake/DefaultCFlags.cmake new file mode 100644 index 00000000000..d122f6c258e --- /dev/null +++ b/cmake/DefaultCFlags.cmake @@ -0,0 +1,153 @@ +# Platform specific compilation flags +if(MSVC) + add_definitions(-D_SCL_SECURE_NO_WARNINGS) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) + + string(REPLACE "/Zm1000" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + + # /GF - String pooling + # /MP - Parallel build + set(CMAKE_C_FLAGS "/GF /MP /nologo ${CMAKE_C_FLAGS}") + + # /Gd - explicitly set cdecl calling convention + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gd") + + if(NOT (MSVC_VERSION LESS 1900)) + # /guard:cf - Enable Control Flow Guard + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /guard:cf") + endif() + + if(STATIC_CRT) + set(CRT_FLAG_DEBUG "/MTd") + set(CRT_FLAG_RELEASE "/MT") + else() + set(CRT_FLAG_DEBUG "/MDd") + set(CRT_FLAG_RELEASE "/MD") + endif() + + if(WIN32_LEAKCHECK) + set(GIT_WIN32_LEAKCHECK 1) + set(CRT_FLAG_DEBUG "${CRT_FLAG_DEBUG}") + set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} Dbghelp.lib") + endif() + + # /Zi - Create debugging information + # /Od - Disable optimization + # /D_DEBUG - #define _DEBUG + # /MTd - Statically link the multithreaded debug version of the CRT + # /MDd - Dynamically link the multithreaded debug version of the CRT + # /RTC1 - Run time checks + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Zi /Od /D_DEBUG /RTC1 ${CRT_FLAG_DEBUG}") + + # /DNDEBUG - Disables asserts + # /MT - Statically link the multithreaded release version of the CRT + # /MD - Dynamically link the multithreaded release version of the CRT + # /O2 - Optimize for speed + # /Oy - Enable frame pointer omission (FPO) (otherwise CMake will automatically turn it off) + # /GL - Link time code generation (whole program optimization) + # /Gy - Function-level linking + set(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /Oy /GL /Gy ${CRT_FLAG_RELEASE}") + + # /Oy- - Disable frame pointer omission (FPO) + set(CMAKE_C_FLAGS_RELWITHDEBINFO "/DNDEBUG /Zi /O2 /Oy- /GL /Gy ${CRT_FLAG_RELEASE}") + + # /O1 - Optimize for size + set(CMAKE_C_FLAGS_MINSIZEREL "/DNDEBUG /O1 /Oy /GL /Gy ${CRT_FLAG_RELEASE}") + + # /IGNORE:4221 - Ignore empty compilation units + set(CMAKE_STATIC_LINKER_FLAGS "/IGNORE:4221") + + # /DYNAMICBASE - Address space load randomization (ASLR) + # /NXCOMPAT - Data execution prevention (DEP) + # /LARGEADDRESSAWARE - >2GB user address space on x86 + # /VERSION - Embed version information in PE header + set(CMAKE_EXE_LINKER_FLAGS "/DYNAMICBASE /NXCOMPAT /LARGEADDRESSAWARE /VERSION:${libgit2_VERSION_MAJOR}.${libgit2_VERSION_MINOR}") + + if(NOT (MSVC_VERSION LESS 1900)) + # /GUARD:CF - Enable Control Flow Guard + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /GUARD:CF") + endif() + + # /DEBUG - Create a PDB + # /LTCG - Link time code generation (whole program optimization) + # /OPT:REF /OPT:ICF - Fold out duplicate code at link step + # /INCREMENTAL:NO - Required to use /LTCG + # /DEBUGTYPE:cv,fixup - Additional data embedded in the PDB (requires /INCREMENTAL:NO, so not on for Debug) + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO") + set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG /RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO /DEBUGTYPE:cv,fixup") + set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO") + + # Same linker settings for DLL as EXE + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") + set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") + set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}") + set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}") +else() + if(ENABLE_REPRODUCIBLE_BUILDS) + set(CMAKE_C_ARCHIVE_CREATE " Dqc ") + set(CMAKE_C_ARCHIVE_APPEND " Dq ") + set(CMAKE_C_ARCHIVE_FINISH " -D ") + endif() + + if(NOT BUILD_SHARED_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + endif() + + set(CMAKE_C_FLAGS "-D_GNU_SOURCE ${CMAKE_C_FLAGS}") + + enable_warnings(all) + enable_warnings(extra) + + if(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") + set(CMAKE_C_FLAGS "-D_POSIX_C_SOURCE=200112L -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS ${CMAKE_C_FLAGS}") + endif() + + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -O0") + + if(MINGW OR MSYS) # MinGW and MSYS always do PIC and complain if we tell them to + string(REGEX REPLACE "-fPIC" "" CMAKE_SHARED_LIBRARY_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}") + elseif(BUILD_SHARED_LIBS) + add_c_flag_IF_SUPPORTED(-fvisibility=hidden) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + endif() + + if(MINGW) + # MinGW >= 3.14 uses the C99-style stdio functions + # automatically, but forks like mingw-w64 still want + # us to define this in order to use them + add_definitions(-D__USE_MINGW_ANSI_STDIO=1) + endif() + + enable_warnings(documentation) + disable_warnings(documentation-deprecated-sync) + disable_warnings(missing-field-initializers) + enable_warnings(strict-aliasing) + enable_warnings(strict-prototypes) + enable_warnings(declaration-after-statement) + enable_warnings(shift-count-overflow) + enable_warnings(unused-const-variable) + enable_warnings(unused-function) + enable_warnings(int-conversion) + enable_warnings(c11-extensions) + enable_warnings(c99-c11-compat) + + # MinGW uses gcc, which expects POSIX formatting for printf, but + # uses the Windows C library, which uses its own format specifiers. + # Disable format specifier warnings. + if(MINGW) + disable_warnings(format) + disable_warnings(format-security) + else() + enable_warnings(format) + enable_warnings(format-security) + endif() +endif() + +# Ensure that MinGW provides the correct header files. +if(WIN32 AND NOT CYGWIN) + add_definitions(-DWIN32 -D_WIN32_WINNT=0x0600) +endif() From 7b527c12bc07d61fb6d2f0d7bb0b35815dbae49d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 6 Nov 2021 16:38:11 -0400 Subject: [PATCH 0615/1616] cmake: move deprecation definition to src/ There's no need to add the deprecation at the top-level. Our tests add deprecation explicitly. --- CMakeLists.txt | 4 ---- src/CMakeLists.txt | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7f19468cba..46506590eac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,10 +103,6 @@ include(DefaultCFlags) # Compiler / linker flags # -if(DEPRECATE_HARD) - add_definitions(-DGIT_DEPRECATE_HARD) -endif() - if(NOT CMAKE_CONFIGURATION_TYPES) # Build Debug by default if(NOT CMAKE_BUILD_TYPE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eed04f8ee43..e7801165e20 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,10 @@ add_library(git2internal OBJECT) set_target_properties(git2internal PROPERTIES C_STANDARD 90) +if(DEPRECATE_HARD) + add_definitions(-DGIT_DEPRECATE_HARD) +endif() + if(DEBUG_POOL) set(GIT_DEBUG_POOL 1) endif() From 4d2a6839dc5b020b26ab8209952d95411eb34da5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 6 Nov 2021 16:38:57 -0400 Subject: [PATCH 0616/1616] cmake: move fuzzer args to the fuzzer's cmake --- CMakeLists.txt | 17 ++--------------- fuzzers/CMakeLists.txt | 3 +++ 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 46506590eac..5421bd731d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,14 +113,6 @@ else() # that uses CMAKE_CONFIGURATION_TYPES and not CMAKE_BUILD_TYPE endif() -IF(BUILD_FUZZERS AND NOT USE_STANDALONE_FUZZERS) - # The actual sanitizer link target will be added when linking the fuzz - # targets. - set(CMAKE_REQUIRED_FLAGS "-fsanitize=fuzzer-no-link") - add_c_flag(-fsanitize=fuzzer-no-link) - unset(CMAKE_REQUIRED_FLAGS) -endif() - # # Subdirectories # @@ -137,13 +129,8 @@ if(BUILD_EXAMPLES) endif() if(BUILD_FUZZERS) - if(NOT USE_STANDALONE_FUZZERS) - if(BUILD_EXAMPLES) - message(FATAL_ERROR "Cannot build the fuzzer targets and the examples together") - endif() - if(BUILD_TESTS) - message(FATAL_ERROR "Cannot build the fuzzer targets and the tests together") - endif() + if((BUILD_TESTS OR BUILD_EXAMPLES) AND NOT USE_STANDALONE_FUZZERS) + message(FATAL_ERROR "Cannot build the fuzzer and the tests or examples together") endif() add_subdirectory(fuzzers) endif() diff --git a/fuzzers/CMakeLists.txt b/fuzzers/CMakeLists.txt index 8cc61b7519a..1479a2af885 100644 --- a/fuzzers/CMakeLists.txt +++ b/fuzzers/CMakeLists.txt @@ -3,7 +3,10 @@ include_directories(${LIBGIT2_INCLUDES}) include_directories(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) if(BUILD_FUZZERS AND NOT USE_STANDALONE_FUZZERS) + set(CMAKE_REQUIRED_FLAGS "-fsanitize=fuzzer-no-link") add_c_flag(-fsanitize=fuzzer) + add_c_flag(-fsanitize=fuzzer-no-link) + unset(CMAKE_REQUIRED_FLAGS) endif() file(GLOB SRC_FUZZ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *_fuzzer.c) From 207beff5414a44bcde41535a905e51d5b774330b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 6 Nov 2021 16:43:04 -0400 Subject: [PATCH 0617/1616] cmake: reorganize file --- CMakeLists.txt | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5421bd731d0..23d09682d4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,10 @@ if(WIN32) option(USE_WINHTTP "Use Win32 WinHTTP routines" ON) endif() +if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) +endif() + # Modules @@ -99,19 +103,6 @@ include(FeatureSummary) include(EnableWarnings) include(DefaultCFlags) -# -# Compiler / linker flags -# - -if(NOT CMAKE_CONFIGURATION_TYPES) - # Build Debug by default - if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) - endif() -else() - # Using a multi-configuration generator eg MSVC or Xcode - # that uses CMAKE_CONFIGURATION_TYPES and not CMAKE_BUILD_TYPE -endif() # # Subdirectories @@ -135,6 +126,7 @@ if(BUILD_FUZZERS) add_subdirectory(fuzzers) endif() + # Summary feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:") From d3a7a352d59e4075e979bfe9aea73f0f531c32eb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 6 Nov 2021 16:44:07 -0400 Subject: [PATCH 0618/1616] cmake: move test enablement into test cmake --- CMakeLists.txt | 1 - tests/CMakeLists.txt | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23d09682d4b..ae0a5d685bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,7 +111,6 @@ include(DefaultCFlags) add_subdirectory(src) if(BUILD_TESTS) - enable_testing() add_subdirectory(tests) endif() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b85cd6ed363..760925fcf41 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -62,6 +62,8 @@ function(ADD_CLAR_TEST name) endif() endfunction(ADD_CLAR_TEST) +enable_testing() + add_clar_test(offline -v -xonline) add_clar_test(invasive -v -score::ftruncate -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root) add_clar_test(online -v -sonline -xonline::customcert) From 19e99de0540f4117d5ffdfbc058a406b376ec5ad Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 10 Nov 2021 08:14:11 -0500 Subject: [PATCH 0619/1616] cmake: qsort detection in features.h --- src/CMakeLists.txt | 15 +++------------ src/features.h.in | 4 ++++ src/util.c | 16 ++++++++-------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e7801165e20..f3830efe518 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -50,22 +50,13 @@ add_feature_info(futimens GIT_USE_FUTIMENS "futimens support") check_prototype_definition(qsort_r "void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, int (*compar)(void *, const void *, const void *))" - "" "stdlib.h" HAVE_QSORT_R_BSD) -if(HAVE_QSORT_R_BSD) - target_compile_definitions(git2internal PRIVATE HAVE_QSORT_R_BSD) -endif() + "" "stdlib.h" GIT_QSORT_R_BSD) check_prototype_definition(qsort_r "void qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *arg)" - "" "stdlib.h" HAVE_QSORT_R_GNU) -if(HAVE_QSORT_R_GNU) - target_compile_definitions(git2internal PRIVATE HAVE_QSORT_R_GNU) -endif() + "" "stdlib.h" GIT_QSORT_R_GNU) -check_function_exists(qsort_s HAVE_QSORT_S) -if(HAVE_QSORT_S) - target_compile_definitions(git2internal PRIVATE HAVE_QSORT_S) -endif() +check_function_exists(qsort_s GIT_QSORT_S) # Find required dependencies diff --git a/src/features.h.in b/src/features.h.in index a40b6085e8f..81a8ae023c1 100644 --- a/src/features.h.in +++ b/src/features.h.in @@ -24,6 +24,10 @@ #cmakedefine GIT_REGEX_PCRE2 #cmakedefine GIT_REGEX_BUILTIN 1 +#cmakedefine GIT_QSORT_R_BSD +#cmakedefine GIT_QSORT_R_GNU +#cmakedefine GIT_QSORT_S + #cmakedefine GIT_SSH 1 #cmakedefine GIT_SSH_MEMORY_CREDENTIALS 1 diff --git a/src/util.c b/src/util.c index 2b1dadfe84c..e06d4ca0913 100644 --- a/src/util.c +++ b/src/util.c @@ -18,7 +18,7 @@ # endif # include -# ifdef HAVE_QSORT_S +# ifdef GIT_QSORT_S # include # endif #endif @@ -673,7 +673,7 @@ size_t git__unescape(char *str) return (pos - str); } -#if defined(HAVE_QSORT_S) || defined(HAVE_QSORT_R_BSD) +#if defined(GIT_QSORT_S) || defined(GIT_QSORT_R_BSD) typedef struct { git__sort_r_cmp cmp; void *payload; @@ -688,9 +688,9 @@ static int GIT_LIBGIT2_CALL git__qsort_r_glue_cmp( #endif -#if !defined(HAVE_QSORT_R_BSD) && \ - !defined(HAVE_QSORT_R_GNU) && \ - !defined(HAVE_QSORT_S) +#if !defined(GIT_QSORT_R_BSD) && \ + !defined(GIT_QSORT_R_GNU) && \ + !defined(GIT_QSORT_S) static void swap(uint8_t *a, uint8_t *b, size_t elsize) { char tmp[256]; @@ -721,12 +721,12 @@ static void insertsort( void git__qsort_r( void *els, size_t nel, size_t elsize, git__sort_r_cmp cmp, void *payload) { -#if defined(HAVE_QSORT_R_BSD) +#if defined(GIT_QSORT_R_BSD) git__qsort_r_glue glue = { cmp, payload }; qsort_r(els, nel, elsize, &glue, git__qsort_r_glue_cmp); -#elif defined(HAVE_QSORT_R_GNU) +#elif defined(GIT_QSORT_R_GNU) qsort_r(els, nel, elsize, cmp, payload); -#elif defined(HAVE_QSORT_S) +#elif defined(GIT_QSORT_S) git__qsort_r_glue glue = { cmp, payload }; qsort_s(els, nel, elsize, git__qsort_r_glue_cmp, &glue); #else From 16b6e3a9c992c1c1f22fa15cbf8238389f211b1c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 10 Nov 2021 21:33:28 -0500 Subject: [PATCH 0620/1616] cmake: HTTP_Parser is now HTTPParser --- cmake/{FindHTTP_Parser.cmake => FindHTTPParser.cmake} | 0 src/CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename cmake/{FindHTTP_Parser.cmake => FindHTTPParser.cmake} (100%) diff --git a/cmake/FindHTTP_Parser.cmake b/cmake/FindHTTPParser.cmake similarity index 100% rename from cmake/FindHTTP_Parser.cmake rename to cmake/FindHTTPParser.cmake diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f3830efe518..30abfefcb6e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -169,7 +169,7 @@ endif() # Optional external dependency: http-parser if(USE_HTTP_PARSER STREQUAL "system") - find_package(HTTP_Parser) + find_package(HTTPParser) if(HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${HTTP_PARSER_INCLUDE_DIRS}) From de178d36ffd01ca0ba4262becedbd36df8529088 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 10 Nov 2021 21:49:20 -0500 Subject: [PATCH 0621/1616] cmake: refactor http_parser selection Move http_parser selection into its own cmake module. --- cmake/SelectHTTPParser.cmake | 19 +++++++++++++++++++ src/CMakeLists.txt | 22 ++-------------------- 2 files changed, 21 insertions(+), 20 deletions(-) create mode 100644 cmake/SelectHTTPParser.cmake diff --git a/cmake/SelectHTTPParser.cmake b/cmake/SelectHTTPParser.cmake new file mode 100644 index 00000000000..a1724a7c4c3 --- /dev/null +++ b/cmake/SelectHTTPParser.cmake @@ -0,0 +1,19 @@ +# Optional external dependency: http-parser +if(USE_HTTP_PARSER STREQUAL "system") + find_package(HTTP_Parser) + + if(HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${HTTP_PARSER_INCLUDE_DIRS}) + list(APPEND LIBGIT2_LIBS ${HTTP_PARSER_LIBRARIES}) + list(APPEND LIBGIT2_PC_LIBS "-lhttp_parser") + add_feature_info(http-parser ON "http-parser support (system)") + else() + message(FATAL_ERROR "http-parser support was requested but not found") + endif() +else() + message(STATUS "http-parser version 2 was not found or disabled; using bundled 3rd-party sources.") + add_subdirectory("${libgit2_SOURCE_DIR}/deps/http-parser" "${libgit2_BINARY_DIR}/deps/http-parser") + list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/http-parser") + list(APPEND LIBGIT2_OBJECTS "$") + add_feature_info(http-parser ON "http-parser support (bundled)") +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 30abfefcb6e..72b22c82a9c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -113,6 +113,8 @@ endif() include(SelectHTTPSBackend) include(SelectHashes) +include(SelectHTTPParser) + target_sources(git2internal PRIVATE ${SRC_SHA1}) # Specify regular expression implementation @@ -167,26 +169,6 @@ else() message(FATAL_ERROR "The REGEX_BACKEND option provided is not supported") endif() -# Optional external dependency: http-parser -if(USE_HTTP_PARSER STREQUAL "system") - find_package(HTTPParser) - - if(HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2) - list(APPEND LIBGIT2_SYSTEM_INCLUDES ${HTTP_PARSER_INCLUDE_DIRS}) - list(APPEND LIBGIT2_LIBS ${HTTP_PARSER_LIBRARIES}) - list(APPEND LIBGIT2_PC_LIBS "-lhttp_parser") - add_feature_info(http-parser ON "http-parser support (system)") - else() - message(FATAL_ERROR "http-parser support was requested but not found") - endif() -else() - message(STATUS "http-parser version 2 was not found or disabled; using bundled 3rd-party sources.") - add_subdirectory("${libgit2_SOURCE_DIR}/deps/http-parser" "${libgit2_BINARY_DIR}/deps/http-parser") - list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/http-parser") - list(APPEND LIBGIT2_OBJECTS "$") - add_feature_info(http-parser ON "http-parser support (bundled)") -endif() - # Optional external dependency: zlib SanitizeBool(USE_BUNDLED_ZLIB) if(USE_BUNDLED_ZLIB STREQUAL ON) From f0cb3788db73716247f20a69469d353d1178d2a7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 10 Nov 2021 21:51:55 -0500 Subject: [PATCH 0622/1616] cmake: refactor regex selection Move regex selection into its own cmake module. --- cmake/SelectRegex.cmake | 51 +++++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 53 +---------------------------------------- 2 files changed, 52 insertions(+), 52 deletions(-) create mode 100644 cmake/SelectRegex.cmake diff --git a/cmake/SelectRegex.cmake b/cmake/SelectRegex.cmake new file mode 100644 index 00000000000..900d7f150e9 --- /dev/null +++ b/cmake/SelectRegex.cmake @@ -0,0 +1,51 @@ +# Specify regular expression implementation +find_package(PCRE) + +if(REGEX_BACKEND STREQUAL "") + check_symbol_exists(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L) + + if(HAVE_REGCOMP_L) + set(REGEX_BACKEND "regcomp_l") + elseif(PCRE_FOUND) + set(REGEX_BACKEND "pcre") + else() + set(REGEX_BACKEND "builtin") + endif() +endif() + +if(REGEX_BACKEND STREQUAL "regcomp_l") + add_feature_info(regex ON "using system regcomp_l") + set(GIT_REGEX_REGCOMP_L 1) +elseif(REGEX_BACKEND STREQUAL "pcre2") + find_package(PCRE2) + + if(NOT PCRE2_FOUND) + MESSAGE(FATAL_ERROR "PCRE2 support was requested but not found") + endif() + + add_feature_info(regex ON "using system PCRE2") + set(GIT_REGEX_PCRE2 1) + + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE2_INCLUDE_DIRS}) + list(APPEND LIBGIT2_LIBS ${PCRE2_LIBRARIES}) + list(APPEND LIBGIT2_PC_REQUIRES "libpcre2-8") +elseif(REGEX_BACKEND STREQUAL "pcre") + add_feature_info(regex ON "using system PCRE") + set(GIT_REGEX_PCRE 1) + + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE_INCLUDE_DIRS}) + list(APPEND LIBGIT2_LIBS ${PCRE_LIBRARIES}) + list(APPEND LIBGIT2_PC_REQUIRES "libpcre") +elseif(REGEX_BACKEND STREQUAL "regcomp") + add_feature_info(regex ON "using system regcomp") + set(GIT_REGEX_REGCOMP 1) +elseif(REGEX_BACKEND STREQUAL "builtin") + add_feature_info(regex ON "using bundled PCRE") + set(GIT_REGEX_BUILTIN 1) + + add_subdirectory("${libgit2_SOURCE_DIR}/deps/pcre" "${libgit2_BINARY_DIR}/deps/pcre") + list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/pcre") + list(APPEND LIBGIT2_OBJECTS $) +else() + message(FATAL_ERROR "The REGEX_BACKEND option provided is not supported") +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 72b22c82a9c..5c2c5271db0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -114,61 +114,10 @@ endif() include(SelectHTTPSBackend) include(SelectHashes) include(SelectHTTPParser) +include(SelectRegex) target_sources(git2internal PRIVATE ${SRC_SHA1}) -# Specify regular expression implementation -find_package(PCRE) - -if(REGEX_BACKEND STREQUAL "") - check_symbol_exists(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L) - - if(HAVE_REGCOMP_L) - set(REGEX_BACKEND "regcomp_l") - elseif(PCRE_FOUND) - set(REGEX_BACKEND "pcre") - else() - set(REGEX_BACKEND "builtin") - endif() -endif() - -if(REGEX_BACKEND STREQUAL "regcomp_l") - add_feature_info(regex ON "using system regcomp_l") - set(GIT_REGEX_REGCOMP_L 1) -elseif(REGEX_BACKEND STREQUAL "pcre2") - find_package(PCRE2) - - if(NOT PCRE2_FOUND) - MESSAGE(FATAL_ERROR "PCRE2 support was requested but not found") - endif() - - add_feature_info(regex ON "using system PCRE2") - set(GIT_REGEX_PCRE2 1) - - list(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE2_INCLUDE_DIRS}) - list(APPEND LIBGIT2_LIBS ${PCRE2_LIBRARIES}) - list(APPEND LIBGIT2_PC_REQUIRES "libpcre2-8") -elseif(REGEX_BACKEND STREQUAL "pcre") - add_feature_info(regex ON "using system PCRE") - set(GIT_REGEX_PCRE 1) - - list(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE_INCLUDE_DIRS}) - list(APPEND LIBGIT2_LIBS ${PCRE_LIBRARIES}) - list(APPEND LIBGIT2_PC_REQUIRES "libpcre") -elseif(REGEX_BACKEND STREQUAL "regcomp") - add_feature_info(regex ON "using system regcomp") - set(GIT_REGEX_REGCOMP 1) -elseif(REGEX_BACKEND STREQUAL "builtin") - add_feature_info(regex ON "using bundled PCRE") - set(GIT_REGEX_BUILTIN 1) - - add_subdirectory("${libgit2_SOURCE_DIR}/deps/pcre" "${libgit2_BINARY_DIR}/deps/pcre") - list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/pcre") - list(APPEND LIBGIT2_OBJECTS $) -else() - message(FATAL_ERROR "The REGEX_BACKEND option provided is not supported") -endif() - # Optional external dependency: zlib SanitizeBool(USE_BUNDLED_ZLIB) if(USE_BUNDLED_ZLIB STREQUAL ON) From e35a22a080ad8127c1b3f058e6eea99d50fcfc79 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 10 Nov 2021 21:55:23 -0500 Subject: [PATCH 0623/1616] cmake: refactor libssh2 selection Move SSH selection into its own cmake module. --- cmake/SelectSSH.cmake | 41 +++++++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 27 +-------------------------- 2 files changed, 42 insertions(+), 26 deletions(-) create mode 100644 cmake/SelectSSH.cmake diff --git a/cmake/SelectSSH.cmake b/cmake/SelectSSH.cmake new file mode 100644 index 00000000000..0356ee3e7bc --- /dev/null +++ b/cmake/SelectSSH.cmake @@ -0,0 +1,41 @@ +# Optional external dependency: libssh2 +if(USE_SSH) + find_pkglibraries(LIBSSH2 libssh2) + if(NOT LIBSSH2_FOUND) + find_package(LibSSH2) + set(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR}) + get_filename_component(LIBSSH2_LIBRARY_DIRS "${LIBSSH2_LIBRARY}" DIRECTORY) + set(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY}) + set(LIBSSH2_LDFLAGS "-lssh2") + endif() + + if(NOT LIBSSH2_FOUND) + message(FATAL_ERROR "LIBSSH2 not found. Set CMAKE_PREFIX_PATH if it is installed outside of the default search path.") + endif() +endif() + +if(LIBSSH2_FOUND) + set(GIT_SSH 1) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${LIBSSH2_INCLUDE_DIRS}) + list(APPEND LIBGIT2_LIBS ${LIBSSH2_LIBRARIES}) + list(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS}) + + check_library_exists("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS) + if(HAVE_LIBSSH2_MEMORY_CREDENTIALS) + set(GIT_SSH_MEMORY_CREDENTIALS 1) + endif() +else() + message(STATUS "LIBSSH2 not found. Set CMAKE_PREFIX_PATH if it is installed outside of the default search path.") +endif() + +if(WIN32 AND EMBED_SSH_PATH) + file(GLOB SSH_SRC "${EMBED_SSH_PATH}/src/*.c") + list(SORT SSH_SRC) + list(APPEND LIBGIT2_OBJECTS ${SSH_SRC}) + + list(APPEND LIBGIT2_INCLUDES "${EMBED_SSH_PATH}/include") + file(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"") + set(GIT_SSH 1) +endif() + +add_feature_info(SSH GIT_SSH "SSH transport support") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5c2c5271db0..819fc42461c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -115,6 +115,7 @@ include(SelectHTTPSBackend) include(SelectHashes) include(SelectHTTPParser) include(SelectRegex) +include(SelectSSH) target_sources(git2internal PRIVATE ${SRC_SHA1}) @@ -151,32 +152,6 @@ elseif(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND) add_feature_info(zlib ON "using bundled zlib") endif() -# Optional external dependency: libssh2 -if(USE_SSH) - find_pkglibraries(LIBSSH2 libssh2) - if(NOT LIBSSH2_FOUND) - find_package(LibSSH2) - set(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR}) - get_filename_component(LIBSSH2_LIBRARY_DIRS "${LIBSSH2_LIBRARY}" DIRECTORY) - set(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY}) - set(LIBSSH2_LDFLAGS "-lssh2") - endif() -endif() -if(LIBSSH2_FOUND) - set(GIT_SSH 1) - list(APPEND LIBGIT2_SYSTEM_INCLUDES ${LIBSSH2_INCLUDE_DIRS}) - list(APPEND LIBGIT2_LIBS ${LIBSSH2_LIBRARIES}) - list(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS}) - - check_library_exists("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS) - if(HAVE_LIBSSH2_MEMORY_CREDENTIALS) - set(GIT_SSH_MEMORY_CREDENTIALS 1) - endif() -else() - message(STATUS "LIBSSH2 not found. Set CMAKE_PREFIX_PATH if it is installed outside of the default search path.") -endif() -add_feature_info(SSH GIT_SSH "SSH transport support") - # Optional external dependency: ntlmclient if(USE_NTLMCLIENT) set(GIT_NTLM 1) From 83fa548078b0b35030ba028676d6b5674d86ba18 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 10 Nov 2021 21:58:12 -0500 Subject: [PATCH 0624/1616] cmake: refactor WinHTTP selection Move WinHTTP selection into its own cmake module. --- cmake/SelectWinHTTP.cmake | 17 +++++++++++++++++ src/CMakeLists.txt | 19 +------------------ 2 files changed, 18 insertions(+), 18 deletions(-) create mode 100644 cmake/SelectWinHTTP.cmake diff --git a/cmake/SelectWinHTTP.cmake b/cmake/SelectWinHTTP.cmake new file mode 100644 index 00000000000..a4110045fe0 --- /dev/null +++ b/cmake/SelectWinHTTP.cmake @@ -0,0 +1,17 @@ +if(WIN32 AND WINHTTP) + set(GIT_WINHTTP 1) + + # Since MinGW does not come with headers or an import library for winhttp, + # we have to include a private header and generate our own import library + if(MINGW) + add_subdirectory("${libgit2_SOURCE_DIR}/deps/winhttp" "${libgit2_BINARY_DIR}/deps/winhttp") + list(APPEND LIBGIT2_LIBS winhttp) + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/winhttp") + else() + list(APPEND LIBGIT2_LIBS "winhttp") + list(APPEND LIBGIT2_PC_LIBS "-lwinhttp") + endif() + + list(APPEND LIBGIT2_LIBS "rpcrt4" "crypt32" "ole32") + list(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32") +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 819fc42461c..8a57b2345af 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -93,29 +93,12 @@ if(WIN32 AND EMBED_SSH_PATH) set(GIT_SSH 1) endif() -if(WIN32 AND USE_WINHTTP) - set(GIT_WINHTTP 1) - - # Since MinGW does not come with headers or an import library for winhttp, - # we have to include a private header and generate our own import library - if(MINGW) - add_subdirectory("${libgit2_SOURCE_DIR}/deps/winhttp" "${libgit2_BINARY_DIR}/deps/winhttp") - list(APPEND LIBGIT2_LIBS winhttp) - list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/winhttp") - else() - list(APPEND LIBGIT2_LIBS "winhttp") - list(APPEND LIBGIT2_PC_LIBS "-lwinhttp") - endif() - - list(APPEND LIBGIT2_LIBS "rpcrt4" "crypt32" "ole32") - list(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32") -endif() - include(SelectHTTPSBackend) include(SelectHashes) include(SelectHTTPParser) include(SelectRegex) include(SelectSSH) +include(SelectWinHTTP) target_sources(git2internal PRIVATE ${SRC_SHA1}) From 4e84ddd5b091b6e6e85ff6484e72d9f90da1c4b0 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 10 Nov 2021 21:59:46 -0500 Subject: [PATCH 0625/1616] cmake: refactor zlib selection Move zlib selection into its own cmake module. --- cmake/SelectZlib.cmake | 34 ++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 34 +--------------------------------- 2 files changed, 35 insertions(+), 33 deletions(-) create mode 100644 cmake/SelectZlib.cmake diff --git a/cmake/SelectZlib.cmake b/cmake/SelectZlib.cmake new file mode 100644 index 00000000000..2dfc6c86e76 --- /dev/null +++ b/cmake/SelectZlib.cmake @@ -0,0 +1,34 @@ +# Optional external dependency: zlib +include(SanitizeBool) + +SanitizeBool(USE_BUNDLED_ZLIB) +if(USE_BUNDLED_ZLIB STREQUAL ON) + set(USE_BUNDLED_ZLIB "Bundled") +endif() + +if(USE_BUNDLED_ZLIB STREQUAL "OFF") + find_package(ZLIB) + if(ZLIB_FOUND) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ZLIB_INCLUDE_DIRS}) + list(APPEND LIBGIT2_LIBS ${ZLIB_LIBRARIES}) + if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + list(APPEND LIBGIT2_PC_LIBS "-lz") + else() + list(APPEND LIBGIT2_PC_REQUIRES "zlib") + endif() + add_feature_info(zlib ON "using system zlib") + else() + message(STATUS "zlib was not found; using bundled 3rd-party sources." ) + endif() +endif() +if(USE_BUNDLED_ZLIB STREQUAL "Chromium") + add_subdirectory("${libgit2_SOURCE_DIR}/deps/chromium-zlib" "${libgit2_BINARY_DIR}/deps/chromium-zlib") + list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/chromium-zlib") + list(APPEND LIBGIT2_OBJECTS $) + add_feature_info(zlib ON "using (Chromium) bundled zlib") +elseif(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND) + add_subdirectory("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib") + list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib") + list(APPEND LIBGIT2_OBJECTS $) + add_feature_info(zlib ON "using bundled zlib") +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8a57b2345af..ae02ef9aa42 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -99,42 +99,10 @@ include(SelectHTTPParser) include(SelectRegex) include(SelectSSH) include(SelectWinHTTP) +include(SelectZlib) target_sources(git2internal PRIVATE ${SRC_SHA1}) -# Optional external dependency: zlib -SanitizeBool(USE_BUNDLED_ZLIB) -if(USE_BUNDLED_ZLIB STREQUAL ON) - set(USE_BUNDLED_ZLIB "Bundled") -endif() - -if(USE_BUNDLED_ZLIB STREQUAL "OFF") - find_package(ZLIB) - if(ZLIB_FOUND) - list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ZLIB_INCLUDE_DIRS}) - list(APPEND LIBGIT2_LIBS ${ZLIB_LIBRARIES}) - if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - list(APPEND LIBGIT2_PC_LIBS "-lz") - else() - list(APPEND LIBGIT2_PC_REQUIRES "zlib") - endif() - add_feature_info(zlib ON "using system zlib") - else() - message(STATUS "zlib was not found; using bundled 3rd-party sources." ) - endif() -endif() -if(USE_BUNDLED_ZLIB STREQUAL "Chromium") - add_subdirectory("${libgit2_SOURCE_DIR}/deps/chromium-zlib" "${libgit2_BINARY_DIR}/deps/chromium-zlib") - list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/chromium-zlib") - list(APPEND LIBGIT2_OBJECTS $) - add_feature_info(zlib ON "using (Chromium) bundled zlib") -elseif(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND) - add_subdirectory("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib") - list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib") - list(APPEND LIBGIT2_OBJECTS $) - add_feature_info(zlib ON "using bundled zlib") -endif() - # Optional external dependency: ntlmclient if(USE_NTLMCLIENT) set(GIT_NTLM 1) From de665a430a36aace250845c75094b07cf9c1735c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BChl?= Date: Thu, 11 Nov 2021 21:55:28 +0100 Subject: [PATCH 0626/1616] remote: improve apply_insteadof function signature --- src/remote.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/remote.c b/src/remote.c index 32973f700b5..fb9f6f8dac0 100644 --- a/src/remote.c +++ b/src/remote.c @@ -30,7 +30,7 @@ static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs); static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name); -char *apply_insteadof(git_config *config, const char *url, int direction, int *matched); +char *apply_insteadof(bool *matched, git_config *config, const char *url, int direction); static int add_refspec_to(git_vector *vector, const char *string, bool is_fetch) { @@ -212,7 +212,7 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem const git_remote_create_options dummy_opts = GIT_REMOTE_CREATE_OPTIONS_INIT; char *tmp; int error = -1; - int matched; + bool matched; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(url); @@ -247,8 +247,8 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem goto on_error; if (opts->repository && !(opts->flags & GIT_REMOTE_CREATE_SKIP_INSTEADOF)) { - remote->url = apply_insteadof(config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH, &matched); - tmp = apply_insteadof(config_ro, canonical_url.ptr, GIT_DIRECTION_PUSH, &matched); + remote->url = apply_insteadof(&matched, config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH); + tmp = apply_insteadof(&matched, config_ro, canonical_url.ptr, GIT_DIRECTION_PUSH); if (matched) { remote->pushurl = tmp; GIT_ERROR_CHECK_ALLOC(remote->pushurl); @@ -466,7 +466,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) const char *val; char *tmp; int error = 0; - int matched; + bool matched; git_config *config; struct refspec_cb_data data = { NULL }; bool optional_setting_found = false, found; @@ -507,9 +507,9 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO; if (found && strlen(val) > 0) { - remote->url = apply_insteadof(config, val, GIT_DIRECTION_FETCH, &matched); + remote->url = apply_insteadof(&matched, config, val, GIT_DIRECTION_FETCH); GIT_ERROR_CHECK_ALLOC(remote->url); - tmp = apply_insteadof(config, val, GIT_DIRECTION_PUSH, &matched); + tmp = apply_insteadof(&matched, config, val, GIT_DIRECTION_PUSH); if (matched) { remote->pushurl = tmp; GIT_ERROR_CHECK_ALLOC(remote->pushurl); @@ -535,7 +535,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) if (remote->pushurl) { git__free(remote->pushurl); } - remote->pushurl = apply_insteadof(config, val, GIT_DIRECTION_FETCH, &matched); + remote->pushurl = apply_insteadof(&matched, config, val, GIT_DIRECTION_FETCH); GIT_ERROR_CHECK_ALLOC(remote->pushurl); } @@ -2736,7 +2736,7 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_ #define SUFFIX_FETCH "insteadof" #define SUFFIX_PUSH "pushinsteadof" -char *apply_insteadof(git_config *config, const char *url, int direction, int *matched) +char *apply_insteadof(bool *matched, git_config *config, const char *url, int direction) { size_t match_length, prefix_length, suffix_length; char *replacement = NULL; From cf522050bf904c0de92d5a0fc75f50db412ed59d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 16:24:37 -0500 Subject: [PATCH 0627/1616] clar: emit `clar_suite.h` with test declarations We may want to have test function declarations; produce a header file with (only) the test declarations. Update clar to avoid overwriting the file unnecessarily to avoid bumping timestamps and potentially recompiling unnecessarily. --- tests/generate.py | 75 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/tests/generate.py b/tests/generate.py index 9ed6edef302..d2cdb684ad0 100644 --- a/tests/generate.py +++ b/tests/generate.py @@ -8,7 +8,7 @@ from __future__ import with_statement from string import Template -import re, fnmatch, os, sys, codecs, pickle +import re, fnmatch, os, sys, codecs, pickle, io class Module(object): class Template(object): @@ -147,7 +147,7 @@ def __init__(self, path, output): self.path = path self.output = output - def should_generate(self, path): + def maybe_generate(self, path): if not os.path.isfile(path): return True @@ -216,33 +216,82 @@ def callback_count(self): return sum(len(module.callbacks) for module in self.modules.values()) def write(self): - output = os.path.join(self.output, 'clar.suite') + wrote_suite = self.write_suite() + wrote_header = self.write_header() - if not self.should_generate(output): + if wrote_suite or wrote_header: + self.save_cache() + return True + + return False + + def write_output(self, fn, data): + if not self.maybe_generate(fn): return False - with open(output, 'w') as data: + current = None + + try: + with open(fn, 'r') as input: + current = input.read() + except OSError: + pass + except IOError: + pass + + if current == data: + return False + + with open(fn, 'w') as output: + output.write(data) + + return True + + def write_suite(self): + suite_fn = os.path.join(self.output, 'clar.suite') + + with io.StringIO() as suite_file: modules = sorted(self.modules.values(), key=lambda module: module.name) for module in modules: t = Module.DeclarationTemplate(module) - data.write(t.render()) + suite_file.write(t.render()) for module in modules: t = Module.CallbacksTemplate(module) - data.write(t.render()) + suite_file.write(t.render()) suites = "static struct clar_suite _clar_suites[] = {" + ','.join( Module.InfoTemplate(module).render() for module in modules ) + "\n};\n" - data.write(suites) + suite_file.write(suites) - data.write("static const size_t _clar_suite_count = %d;\n" % self.suite_count()) - data.write("static const size_t _clar_callback_count = %d;\n" % self.callback_count()) + suite_file.write(u"static const size_t _clar_suite_count = %d;\n" % self.suite_count()) + suite_file.write(u"static const size_t _clar_callback_count = %d;\n" % self.callback_count()) - self.save_cache() - return True + return self.write_output(suite_fn, suite_file.getvalue()) + + return False + + def write_header(self): + header_fn = os.path.join(self.output, 'clar_suite.h') + + with io.StringIO() as header_file: + header_file.write(u"#ifndef _____clar_suite_h_____\n") + header_file.write(u"#define _____clar_suite_h_____\n") + + modules = sorted(self.modules.values(), key=lambda module: module.name) + + for module in modules: + t = Module.DeclarationTemplate(module) + header_file.write(t.render()) + + header_file.write(u"#endif\n") + + return self.write_output(header_fn, header_file.getvalue()) + + return False if __name__ == '__main__': from optparse import OptionParser @@ -263,5 +312,5 @@ def write(self): suite.load(options.force) suite.disable(options.excluded) if suite.write(): - print("Written `clar.suite` (%d tests in %d suites)" % (suite.callback_count(), suite.suite_count())) + print("Written `clar.suite`, `clar_suite.h` (%d tests in %d suites)" % (suite.callback_count(), suite.suite_count())) From 49f03c0305d89e4bcee6c12af956381f70e14753 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 16:53:33 -0500 Subject: [PATCH 0628/1616] tests: include test declarations for old gcc Older versions of gcc do not believe that we've adequately declared our test functions. Include `clar_suite.h` conditionally for those old versions. Do not do this on newer compilers to avoid unnecessary recompilation of the entire suite when we add or remove a test function. --- tests/CMakeLists.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 760925fcf41..e109913ff4e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -25,7 +25,7 @@ if(MSVC_IDE) endif() add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clar.suite + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clar.suite ${CMAKE_CURRENT_BINARY_DIR}/clar_suite.h COMMAND ${PYTHON_EXECUTABLE} generate.py -o "${CMAKE_CURRENT_BINARY_DIR}" -f -xonline -xstress -xperf . DEPENDS ${SRC_TEST} WORKING_DIRECTORY ${CLAR_PATH} @@ -48,6 +48,14 @@ target_include_directories(libgit2_tests PRIVATE ../src PUBLIC ../include) target_link_libraries(libgit2_tests ${LIBGIT2_LIBS}) ide_split_sources(libgit2_tests) +# +# Old versions of gcc require us to declare our test functions; don't do +# this on newer compilers to avoid unnecessary recompilation. +# +if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) + add_definitions(-include \"clar_suite.h\") +endif() + if(MSVC_IDE) # Precompiled headers set_target_properties(libgit2_tests PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") From 0429894e0bd1eee077e07b22528d569c8636d6f1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 12:28:07 -0500 Subject: [PATCH 0629/1616] tests: declare trace handler as static --- tests/clar_libgit2_trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/clar_libgit2_trace.c b/tests/clar_libgit2_trace.c index 8eb6d4e8dd9..ebb0f41dda7 100644 --- a/tests/clar_libgit2_trace.c +++ b/tests/clar_libgit2_trace.c @@ -150,7 +150,7 @@ static cl_perf_timer s_timer_run = CL_PERF_TIMER_INIT; */ static cl_perf_timer s_timer_test = CL_PERF_TIMER_INIT; -void _cl_trace_cb__event_handler( +static void _cl_trace_cb__event_handler( cl_trace_event ev, const char *suite_name, const char *test_name, From 489aec44477181afa05db41bfd04bb0febe83f59 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 12:33:14 -0500 Subject: [PATCH 0630/1616] fuzzers: declare standalone functions --- fuzzers/commit_graph_fuzzer.c | 2 ++ fuzzers/config_file_fuzzer.c | 2 ++ fuzzers/download_refs_fuzzer.c | 2 ++ fuzzers/midx_fuzzer.c | 2 ++ fuzzers/objects_fuzzer.c | 2 ++ fuzzers/packfile_fuzzer.c | 2 ++ fuzzers/patch_parse_fuzzer.c | 2 ++ fuzzers/standalone_driver.c | 3 +-- fuzzers/standalone_driver.h | 14 ++++++++++++++ 9 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 fuzzers/standalone_driver.h diff --git a/fuzzers/commit_graph_fuzzer.c b/fuzzers/commit_graph_fuzzer.c index 05783a25936..1c46d78c714 100644 --- a/fuzzers/commit_graph_fuzzer.c +++ b/fuzzers/commit_graph_fuzzer.c @@ -17,6 +17,8 @@ #include "hash.h" #include "commit_graph.h" +#include "standalone_driver.h" + int LLVMFuzzerInitialize(int *argc, char ***argv) { GIT_UNUSED(argc); diff --git a/fuzzers/config_file_fuzzer.c b/fuzzers/config_file_fuzzer.c index 526c93928da..582d74aff09 100644 --- a/fuzzers/config_file_fuzzer.c +++ b/fuzzers/config_file_fuzzer.c @@ -10,6 +10,8 @@ #include "git2.h" #include "config_backend.h" +#include "standalone_driver.h" + #define UNUSED(x) (void)(x) int foreach_cb(const git_config_entry *entry, void *payload) diff --git a/fuzzers/download_refs_fuzzer.c b/fuzzers/download_refs_fuzzer.c index c5726cba186..bdaa6aab6c5 100644 --- a/fuzzers/download_refs_fuzzer.c +++ b/fuzzers/download_refs_fuzzer.c @@ -15,6 +15,8 @@ #include "git2/sys/transport.h" #include "futils.h" +#include "standalone_driver.h" + #define UNUSED(x) (void)(x) struct fuzzer_buffer { diff --git a/fuzzers/midx_fuzzer.c b/fuzzers/midx_fuzzer.c index 3cd609063fe..4c3124e4782 100644 --- a/fuzzers/midx_fuzzer.c +++ b/fuzzers/midx_fuzzer.c @@ -16,6 +16,8 @@ #include "hash.h" #include "midx.h" +#include "standalone_driver.h" + int LLVMFuzzerInitialize(int *argc, char ***argv) { GIT_UNUSED(argc); diff --git a/fuzzers/objects_fuzzer.c b/fuzzers/objects_fuzzer.c index 1feff778ddd..51b4a1ed415 100644 --- a/fuzzers/objects_fuzzer.c +++ b/fuzzers/objects_fuzzer.c @@ -10,6 +10,8 @@ #include "git2.h" #include "object.h" +#include "standalone_driver.h" + #define UNUSED(x) (void)(x) int LLVMFuzzerInitialize(int *argc, char ***argv) diff --git a/fuzzers/packfile_fuzzer.c b/fuzzers/packfile_fuzzer.c index f739b956376..8667cb9c589 100644 --- a/fuzzers/packfile_fuzzer.c +++ b/fuzzers/packfile_fuzzer.c @@ -14,6 +14,8 @@ #include "common.h" #include "str.h" +#include "standalone_driver.h" + static git_odb *odb = NULL; static git_odb_backend *mempack = NULL; diff --git a/fuzzers/patch_parse_fuzzer.c b/fuzzers/patch_parse_fuzzer.c index a9b02ad4dd3..2e65a01fd88 100644 --- a/fuzzers/patch_parse_fuzzer.c +++ b/fuzzers/patch_parse_fuzzer.c @@ -11,6 +11,8 @@ #include "patch.h" #include "patch_parse.h" +#include "standalone_driver.h" + #define UNUSED(x) (void)(x) int LLVMFuzzerInitialize(int *argc, char ***argv) diff --git a/fuzzers/standalone_driver.c b/fuzzers/standalone_driver.c index c29102e6524..cd4f71751ae 100644 --- a/fuzzers/standalone_driver.c +++ b/fuzzers/standalone_driver.c @@ -11,8 +11,7 @@ #include "futils.h" #include "path.h" -extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size); -extern int LLVMFuzzerInitialize(int *argc, char ***argv); +#include "standalone_driver.h" static int run_one_file(const char *filename) { diff --git a/fuzzers/standalone_driver.h b/fuzzers/standalone_driver.h new file mode 100644 index 00000000000..507fcb9fdb1 --- /dev/null +++ b/fuzzers/standalone_driver.h @@ -0,0 +1,14 @@ +/* + * 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_standalone_driver_h__ +#define INCLUDE_standalone_driver_h__ + +extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size); +extern int LLVMFuzzerInitialize(int *argc, char ***argv); + +#endif From 2374ba8d49ac9dfb084596259ec82c87b384fc32 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 17:15:47 -0500 Subject: [PATCH 0631/1616] fuzzers: declare static functions as static --- fuzzers/config_file_fuzzer.c | 2 +- fuzzers/download_refs_fuzzer.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fuzzers/config_file_fuzzer.c b/fuzzers/config_file_fuzzer.c index 582d74aff09..890adbfc528 100644 --- a/fuzzers/config_file_fuzzer.c +++ b/fuzzers/config_file_fuzzer.c @@ -14,7 +14,7 @@ #define UNUSED(x) (void)(x) -int foreach_cb(const git_config_entry *entry, void *payload) +static int foreach_cb(const git_config_entry *entry, void *payload) { UNUSED(entry); UNUSED(payload); diff --git a/fuzzers/download_refs_fuzzer.c b/fuzzers/download_refs_fuzzer.c index bdaa6aab6c5..ff95cd107ef 100644 --- a/fuzzers/download_refs_fuzzer.c +++ b/fuzzers/download_refs_fuzzer.c @@ -132,7 +132,7 @@ static int fuzzer_subtransport_new( return 0; } -int fuzzer_subtransport_cb( +static int fuzzer_subtransport_cb( git_smart_subtransport **out, git_transport *owner, void *payload) @@ -147,7 +147,7 @@ int fuzzer_subtransport_cb( return 0; } -int fuzzer_transport_cb(git_transport **out, git_remote *owner, void *param) +static int fuzzer_transport_cb(git_transport **out, git_remote *owner, void *param) { git_smart_subtransport_definition def = { fuzzer_subtransport_cb, @@ -157,7 +157,7 @@ int fuzzer_transport_cb(git_transport **out, git_remote *owner, void *param) return git_transport_smart(out, owner, &def); } -void fuzzer_git_abort(const char *op) +static void fuzzer_git_abort(const char *op) { const git_error *err = git_error_last(); fprintf(stderr, "unexpected libgit error: %s: %s\n", From 8be226148f22559cb859a1c035243a7379465665 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 12:47:02 -0500 Subject: [PATCH 0632/1616] examples: remove unused function --- examples/add.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/examples/add.c b/examples/add.c index 542360ea9bf..5014bd71f41 100644 --- a/examples/add.c +++ b/examples/add.c @@ -110,21 +110,6 @@ int print_matched_cb(const char *path, const char *matched_pathspec, void *paylo return ret; } -void init_array(git_strarray *array, int argc, char **argv) -{ - unsigned int i; - - array->count = argc; - array->strings = calloc(array->count, sizeof(char *)); - assert(array->strings != NULL); - - for (i = 0; i < array->count; i++) { - array->strings[i] = argv[i]; - } - - return; -} - void print_usage(void) { fprintf(stderr, "usage: add [options] [--] file-spec [file-spec] [...]\n\n"); From eabbee0454b74d149ba5f23f1141cc7492fb694f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 12:48:19 -0500 Subject: [PATCH 0633/1616] example: declare print_usage function --- examples/add.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/add.c b/examples/add.c index 5014bd71f41..4ff7c79e2ab 100644 --- a/examples/add.c +++ b/examples/add.c @@ -110,7 +110,7 @@ int print_matched_cb(const char *path, const char *matched_pathspec, void *paylo return ret; } -void print_usage(void) +static void print_usage(void) { fprintf(stderr, "usage: add [options] [--] file-spec [file-spec] [...]\n\n"); fprintf(stderr, "\t-n, --dry-run dry run\n"); From 3f024b6d5439eda83d8bebc197db062c4d6bdfeb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 12:57:44 -0500 Subject: [PATCH 0634/1616] clar: declare summary functions as static --- tests/clar/summary.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/clar/summary.h b/tests/clar/summary.h index 1af110efa23..6279f5057d7 100644 --- a/tests/clar/summary.h +++ b/tests/clar/summary.h @@ -2,7 +2,7 @@ #include #include -int clar_summary_close_tag( +static int clar_summary_close_tag( struct clar_summary *summary, const char *tag, int indent) { const char *indt; @@ -14,12 +14,12 @@ int clar_summary_close_tag( return fprintf(summary->fp, "%s\n", indt, tag); } -int clar_summary_testsuites(struct clar_summary *summary) +static int clar_summary_testsuites(struct clar_summary *summary) { return fprintf(summary->fp, "\n"); } -int clar_summary_testsuite(struct clar_summary *summary, +static int clar_summary_testsuite(struct clar_summary *summary, int idn, const char *name, const char *pkg, time_t timestamp, double elapsed, int test_count, int fail_count, int error_count) { @@ -42,7 +42,7 @@ int clar_summary_testsuite(struct clar_summary *summary, idn, name, pkg, iso_dt, elapsed, test_count, fail_count, error_count); } -int clar_summary_testcase(struct clar_summary *summary, +static int clar_summary_testcase(struct clar_summary *summary, const char *name, const char *classname, double elapsed) { return fprintf(summary->fp, @@ -50,7 +50,7 @@ int clar_summary_testcase(struct clar_summary *summary, name, classname, elapsed); } -int clar_summary_failure(struct clar_summary *summary, +static int clar_summary_failure(struct clar_summary *summary, const char *type, const char *message, const char *desc) { return fprintf(summary->fp, From ca14942e19788bd01334af64554c3095f3ff0d4a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 13:28:08 -0500 Subject: [PATCH 0635/1616] tests: declare functions statically where appropriate --- tests/checkout/tree.c | 10 +- tests/clone/nonetwork.c | 2 +- tests/commit/commit.c | 4 +- tests/config/stress.c | 2 +- tests/core/copy.c | 4 +- tests/diff/binary.c | 2 +- tests/diff/rename.c | 2 +- tests/diff/tree.c | 2 +- tests/email/create.c.bak | 386 ++++++++++++++++++++++++++++++++++ tests/fetchhead/nonetwork.c | 4 +- tests/filter/custom_helpers.c | 2 +- tests/filter/file.c | 6 +- tests/merge/merge_helpers.c | 2 +- tests/network/fetchlocal.c | 4 +- tests/network/remote/push.c | 4 +- tests/notes/notes.c | 2 +- tests/object/tag/write.c | 2 +- tests/odb/loose.c | 2 +- tests/online/clone.c | 4 +- tests/online/push_util.c | 2 +- tests/pack/filelimit.c | 2 +- tests/patch/print.c | 2 +- tests/path/dotgit.c | 2 +- tests/path/win32.c | 16 +- tests/rebase/iterator.c | 2 +- tests/rebase/merge.c | 2 +- tests/rebase/sign.c | 2 +- tests/refs/shorthand.c | 2 +- tests/remote/fetch.c | 2 +- tests/remote/httpproxy.c | 6 +- tests/stash/apply.c | 6 +- tests/stash/drop.c | 2 +- tests/status/worktree.c | 2 +- tests/submodule/modify.c | 6 +- 34 files changed, 442 insertions(+), 60 deletions(-) create mode 100644 tests/email/create.c.bak diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c index 2f54f4e3e89..de7dd7d9a74 100644 --- a/tests/checkout/tree.c +++ b/tests/checkout/tree.c @@ -509,7 +509,7 @@ void test_checkout_tree__can_disable_pattern_match(void) cl_assert(git_fs_path_isfile("testrepo/branch_file.txt")); } -void assert_conflict( +static void assert_conflict( const char *entry_path, const char *new_content, const char *parent_sha, @@ -1034,7 +1034,8 @@ void test_checkout_tree__filemode_preserved_in_index(void) git_index_free(index); } -mode_t read_filemode(const char *path) +#ifndef GIT_WIN32 +static mode_t read_filemode(const char *path) { git_str fullpath = GIT_STR_INIT; struct stat st; @@ -1050,6 +1051,7 @@ mode_t read_filemode(const char *path) return result; } +#endif void test_checkout_tree__filemode_preserved_in_workdir(void) { @@ -1267,7 +1269,7 @@ void test_checkout_tree__case_changing_rename(void) git_commit_free(master_commit); } -void perfdata_cb(const git_checkout_perfdata *in, void *payload) +static void perfdata_cb(const git_checkout_perfdata *in, void *payload) { memcpy(payload, in, sizeof(git_checkout_perfdata)); } @@ -1296,7 +1298,7 @@ void test_checkout_tree__can_collect_perfdata(void) git_object_free(obj); } -void update_attr_callback( +static void update_attr_callback( const char *path, size_t completed_steps, size_t total_steps, diff --git a/tests/clone/nonetwork.c b/tests/clone/nonetwork.c index c3515b53f24..eab63363516 100644 --- a/tests/clone/nonetwork.c +++ b/tests/clone/nonetwork.c @@ -109,7 +109,7 @@ void test_clone_nonetwork__fail_with_already_existing_but_non_empty_directory(vo cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); } -int custom_origin_name_remote_create( +static int custom_origin_name_remote_create( git_remote **out, git_repository *repo, const char *name, diff --git a/tests/commit/commit.c b/tests/commit/commit.c index b03169bc8d4..d4e333b6ad8 100644 --- a/tests/commit/commit.c +++ b/tests/commit/commit.c @@ -111,7 +111,7 @@ void test_commit_commit__create_initial_commit_parent_not_current(void) git_signature_free(s); } -void assert_commit_summary(const char *expected, const char *given) +static void assert_commit_summary(const char *expected, const char *given) { git_commit *dummy; @@ -123,7 +123,7 @@ void assert_commit_summary(const char *expected, const char *given) git_commit__free(dummy); } -void assert_commit_body(const char *expected, const char *given) +static void assert_commit_body(const char *expected, const char *given) { git_commit *dummy; diff --git a/tests/config/stress.c b/tests/config/stress.c index c823284ff29..69e6810facf 100644 --- a/tests/config/stress.c +++ b/tests/config/stress.c @@ -39,7 +39,7 @@ void test_config_stress__dont_break_on_invalid_input(void) git_config_free(config); } -void assert_config_value(git_config *config, const char *key, const char *value) +static void assert_config_value(git_config *config, const char *key, const char *value) { git_buf_dispose(&buf); cl_git_pass(git_config_get_string_buf(&buf, config, key)); diff --git a/tests/core/copy.c b/tests/core/copy.c index 2b90fb6bfdf..b03d7108380 100644 --- a/tests/core/copy.c +++ b/tests/core/copy.c @@ -45,7 +45,8 @@ void test_core_copy__file_in_dir(void) cl_assert(!git_fs_path_isdir("an_dir")); } -void assert_hard_link(const char *path) +#ifndef GIT_WIN32 +static void assert_hard_link(const char *path) { /* we assert this by checking that there's more than one link to the file */ struct stat st; @@ -54,6 +55,7 @@ void assert_hard_link(const char *path) cl_git_pass(p_stat(path, &st)); cl_assert(st.st_nlink > 1); } +#endif void test_core_copy__tree(void) { diff --git a/tests/diff/binary.c b/tests/diff/binary.c index 24d2b22ef45..4e71f39c640 100644 --- a/tests/diff/binary.c +++ b/tests/diff/binary.c @@ -17,7 +17,7 @@ void test_diff_binary__cleanup(void) cl_git_sandbox_cleanup(); } -void test_patch( +static void test_patch( const char *one, const char *two, const git_diff_options *opts, diff --git a/tests/diff/rename.c b/tests/diff/rename.c index d28a4d989ed..41dc95eb4ec 100644 --- a/tests/diff/rename.c +++ b/tests/diff/rename.c @@ -938,7 +938,7 @@ struct rename_expected size_t idx; }; -int test_names_expected(const git_diff_delta *delta, float progress, void *p) +static int test_names_expected(const git_diff_delta *delta, float progress, void *p) { struct rename_expected *expected = p; diff --git a/tests/diff/tree.c b/tests/diff/tree.c index dfe4d254cca..e03ee7b228f 100644 --- a/tests/diff/tree.c +++ b/tests/diff/tree.c @@ -320,7 +320,7 @@ void test_diff_tree__checks_options_version(void) err = git_error_last(); } -void process_tree_to_tree_diffing( +static void process_tree_to_tree_diffing( const char *old_commit, const char *new_commit) { diff --git a/tests/email/create.c.bak b/tests/email/create.c.bak new file mode 100644 index 00000000000..3bb95a6f633 --- /dev/null +++ b/tests/email/create.c.bak @@ -0,0 +1,386 @@ +#include "clar.h" +#include "clar_libgit2.h" + +#include "buffer.h" +#include "diff_generate.h" + +static git_repository *repo; + +void test_email_create__initialize(void) +{ + repo = cl_git_sandbox_init("diff_format_email"); +} + +void test_email_create__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +static void email_for_commit( + git_buf *out, + const char *commit_id, + git_email_create_options *opts) +{ + git_oid oid; + git_commit *commit = NULL; + git_diff *diff = NULL; + + git_oid_fromstr(&oid, commit_id); + + cl_git_pass(git_commit_lookup(&commit, repo, &oid)); + + cl_git_pass(git_email_create_from_commit(out, commit, opts)); + + git_diff_free(diff); + git_commit_free(commit); +} + +static void assert_email_match( + const char *expected, + const char *commit_id, + git_email_create_options *opts) +{ + git_buf buf = GIT_BUF_INIT; + + email_for_commit(&buf, commit_id, opts); + cl_assert_equal_s(expected, git_buf_cstr(&buf)); + + git_buf_dispose(&buf); +} + +static void assert_subject_match( + const char *expected, + const char *commit_id, + git_email_create_options *opts) +{ + git_buf buf = GIT_BUF_INIT; + const char *loc; + + email_for_commit(&buf, commit_id, opts); + + cl_assert((loc = strstr(buf.ptr, "\nSubject: ")) != NULL); + git_buf_consume(&buf, (loc + 10)); + git_buf_truncate_at_char(&buf, '\n'); + + cl_assert_equal_s(expected, git_buf_cstr(&buf)); + + git_buf_dispose(&buf); +} + +void test_email_create__commit(void) +{ + const char *expected = + "From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Wed, 9 Apr 2014 20:57:01 +0200\n" \ + "Subject: [PATCH] Modify some content\n" \ + "\n" \ + "---\n" \ + " file1.txt | 8 +++++---\n" \ + " 1 file changed, 5 insertions(+), 3 deletions(-)\n" \ + "\n" \ + "diff --git a/file1.txt b/file1.txt\n" \ + "index 94aaae8..af8f41d 100644\n" \ + "--- a/file1.txt\n" \ + "+++ b/file1.txt\n" \ + "@@ -1,15 +1,17 @@\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "+_file1.txt_\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "+\n" \ + "+\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "+_file1.txt_\n" \ + "+_file1.txt_\n" \ + " file1.txt\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + assert_email_match( + expected, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", NULL); +} + +void test_email_create__custom_summary_and_body(void) +{ + const char *expected = "From 627e7e12d87e07a83fad5b6bfa25e86ead4a5270 Mon Sep 17 00:00:00 2001\n" \ + "From: Patrick Steinhardt \n" \ + "Date: Tue, 24 Nov 2015 13:34:39 +0100\n" \ + "Subject: [PPPPPATCH 2/4] This is a subject\n" \ + "\n" \ + "Modify content of file3.txt by appending a new line. Make this\n" \ + "commit message somewhat longer to test behavior with newlines\n" \ + "embedded in the message body.\n" \ + "\n" \ + "Also test if new paragraphs are included correctly.\n" \ + "---\n" \ + " file3.txt | 1 +\n" \ + " 1 file changed, 1 insertion(+)\n" \ + "\n" \ + "diff --git a/file3.txt b/file3.txt\n" \ + "index 9a2d780..7309653 100644\n" \ + "--- a/file3.txt\n" \ + "+++ b/file3.txt\n" \ + "@@ -3,3 +3,4 @@ file3!\n" \ + " file3\n" \ + " file3\n" \ + " file3\n" \ + "+file3\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + const char *summary = "This is a subject\nwith\nnewlines"; + const char *body = "Modify content of file3.txt by appending a new line. Make this\n" \ + "commit message somewhat longer to test behavior with newlines\n" \ + "embedded in the message body.\n" \ + "\n" \ + "Also test if new paragraphs are included correctly."; + + git_oid oid; + git_commit *commit = NULL; + git_diff *diff = NULL; + git_buf buf = GIT_BUF_INIT; + git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; + + opts.subject_prefix = "PPPPPATCH"; + + git_oid_fromstr(&oid, "627e7e12d87e07a83fad5b6bfa25e86ead4a5270"); + cl_git_pass(git_commit_lookup(&commit, repo, &oid)); + cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); + cl_git_pass(git_email_create_from_diff(&buf, diff, 2, 4, &oid, summary, body, git_commit_author(commit), &opts)); + + cl_assert_equal_s(expected, git_buf_cstr(&buf)); + + git_diff_free(diff); + git_commit_free(commit); + git_buf_dispose(&buf); +} + +void test_email_create__mode_change(void) +{ + const char *expected = + "From 7ade76dd34bba4733cf9878079f9fd4a456a9189 Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Thu, 10 Apr 2014 10:05:03 +0200\n" \ + "Subject: [PATCH] Update permissions\n" \ + "\n" \ + "---\n" \ + " file1.txt.renamed | 0\n" \ + " 1 file changed, 0 insertions(+), 0 deletions(-)\n" \ + " mode change 100644 => 100755 file1.txt.renamed\n" \ + "\n" \ + "diff --git a/file1.txt.renamed b/file1.txt.renamed\n" \ + "old mode 100644\n" \ + "new mode 100755\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + assert_email_match(expected, "7ade76dd34bba4733cf9878079f9fd4a456a9189", NULL); +} + +void test_email_create__rename(void) +{ + const char *expected = + "From 6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Wed, 9 Apr 2014 21:15:56 +0200\n" \ + "Subject: [PATCH] Renamed file1.txt -> file1.txt.renamed\n" \ + "\n" \ + "---\n" \ + " file1.txt => file1.txt.renamed | 4 ++--\n" \ + " 1 file changed, 2 insertions(+), 2 deletions(-)\n" \ + "\n" \ + "diff --git a/file1.txt b/file1.txt.renamed\n" \ + "similarity index 86%\n" \ + "rename from file1.txt\n" \ + "rename to file1.txt.renamed\n" \ + "index af8f41d..a97157a 100644\n" \ + "--- a/file1.txt\n" \ + "+++ b/file1.txt.renamed\n" \ + "@@ -3,13 +3,13 @@ file1.txt\n" \ + " _file1.txt_\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "-file1.txt\n" \ + "+file1.txt_renamed\n" \ + " file1.txt\n" \ + " \n" \ + " \n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "-file1.txt\n" \ + "+file1.txt_renamed\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " _file1.txt_\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + assert_email_match(expected, "6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d", NULL); +} + +void test_email_create__rename_as_add_delete(void) +{ + const char *expected = + "From 6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Wed, 9 Apr 2014 21:15:56 +0200\n" \ + "Subject: [PATCH] Renamed file1.txt -> file1.txt.renamed\n" \ + "\n" \ + "---\n" \ + " file1.txt | 17 -----------------\n" \ + " file1.txt.renamed | 17 +++++++++++++++++\n" \ + " 2 files changed, 17 insertions(+), 17 deletions(-)\n" \ + " delete mode 100644 file1.txt\n" \ + " create mode 100644 file1.txt.renamed\n" \ + "\n" \ + "diff --git a/file1.txt b/file1.txt\n" \ + "deleted file mode 100644\n" \ + "index af8f41d..0000000\n" \ + "--- a/file1.txt\n" \ + "+++ /dev/null\n" \ + "@@ -1,17 +0,0 @@\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-_file1.txt_\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-\n" \ + "-\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-_file1.txt_\n" \ + "-_file1.txt_\n" \ + "-file1.txt\n" \ + "diff --git a/file1.txt.renamed b/file1.txt.renamed\n" \ + "new file mode 100644\n" \ + "index 0000000..a97157a\n" \ + "--- /dev/null\n" \ + "+++ b/file1.txt.renamed\n" \ + "@@ -0,0 +1,17 @@\n" \ + "+file1.txt\n" \ + "+file1.txt\n" \ + "+_file1.txt_\n" \ + "+file1.txt\n" \ + "+file1.txt\n" \ + "+file1.txt_renamed\n" \ + "+file1.txt\n" \ + "+\n" \ + "+\n" \ + "+file1.txt\n" \ + "+file1.txt\n" \ + "+file1.txt_renamed\n" \ + "+file1.txt\n" \ + "+file1.txt\n" \ + "+_file1.txt_\n" \ + "+_file1.txt_\n" \ + "+file1.txt\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; + opts.flags |= GIT_EMAIL_CREATE_NO_RENAMES; + + assert_email_match(expected, "6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d", &opts); +} + +void test_email_create__binary(void) +{ + const char *expected = + "From 8d7523f6fcb2404257889abe0d96f093d9f524f9 Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Sun, 13 Apr 2014 18:10:18 +0200\n" \ + "Subject: [PATCH] Modified binary file\n" \ + "\n" \ + "---\n" \ + " binary.bin | Bin 3 -> 5 bytes\n" \ + " 1 file changed, 0 insertions(+), 0 deletions(-)\n" \ + "\n" \ + "diff --git a/binary.bin b/binary.bin\n" \ + "index bd474b2519cc15eab801ff851cc7d50f0dee49a1..9ac35ff15cd8864aeafd889e4826a3150f0b06c4 100644\n" \ + "GIT binary patch\n" \ + "literal 5\n" \ + "Mc${NkU}WL~000&M4gdfE\n" \ + "\n" \ + "literal 3\n" \ + "Kc${Nk-~s>u4FC%O\n" \ + "\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + assert_email_match(expected, "8d7523f6fcb2404257889abe0d96f093d9f524f9", NULL); +} + +void test_email_create__binary_not_included(void) +{ + const char *expected = + "From 8d7523f6fcb2404257889abe0d96f093d9f524f9 Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys \n" \ + "Date: Sun, 13 Apr 2014 18:10:18 +0200\n" \ + "Subject: [PATCH] Modified binary file\n" \ + "\n" \ + "---\n" \ + " binary.bin | Bin 3 -> 5 bytes\n" \ + " 1 file changed, 0 insertions(+), 0 deletions(-)\n" \ + "\n" \ + "diff --git a/binary.bin b/binary.bin\n" \ + "index bd474b2..9ac35ff 100644\n" \ + "Binary files a/binary.bin and b/binary.bin differ\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; + opts.diff_opts.flags &= ~GIT_DIFF_SHOW_BINARY; + + assert_email_match(expected, "8d7523f6fcb2404257889abe0d96f093d9f524f9", &opts); +} + +void test_email_create__commit_subjects(void) +{ + git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; + + assert_subject_match("[PATCH] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.reroll_number = 42; + assert_subject_match("[PATCH v42] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.flags |= GIT_EMAIL_CREATE_ALWAYS_NUMBER; + assert_subject_match("[PATCH v42 1/1] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.start_number = 9; + assert_subject_match("[PATCH v42 9/9] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.subject_prefix = ""; + assert_subject_match("[v42 9/9] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.reroll_number = 0; + assert_subject_match("[9/9] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.start_number = 0; + assert_subject_match("[1/1] Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); + + opts.flags = GIT_EMAIL_CREATE_OMIT_NUMBERS; + assert_subject_match("Modify some content", "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); +} diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c index 334755cc348..0e446d94e7a 100644 --- a/tests/fetchhead/nonetwork.c +++ b/tests/fetchhead/nonetwork.c @@ -408,7 +408,7 @@ static bool found_master; static bool found_haacked; static bool find_master_haacked_called; -int find_master_haacked(const char *ref_name, const char *remote_url, const git_oid *oid, unsigned int is_merge, void *payload) +static int find_master_haacked(const char *ref_name, const char *remote_url, const git_oid *oid, unsigned int is_merge, void *payload) { GIT_UNUSED(remote_url); GIT_UNUSED(oid); @@ -466,7 +466,7 @@ struct prefix_count { int expected; }; -int count_refs(const char *ref_name, const char *remote_url, const git_oid *oid, unsigned int is_merge, void *payload) +static int count_refs(const char *ref_name, const char *remote_url, const git_oid *oid, unsigned int is_merge, void *payload) { int i; struct prefix_count *prefix_counts = (struct prefix_count *) payload; diff --git a/tests/filter/custom_helpers.c b/tests/filter/custom_helpers.c index 7aa3777e66b..f98f65c229d 100644 --- a/tests/filter/custom_helpers.c +++ b/tests/filter/custom_helpers.c @@ -128,7 +128,7 @@ git_filter *create_reverse_filter(const char *attrs) return filter; } -int erroneous_filter_stream( +static int erroneous_filter_stream( git_writestream **out, git_filter *self, void **payload, diff --git a/tests/filter/file.c b/tests/filter/file.c index 3b7ab19e280..14b33bab9b5 100644 --- a/tests/filter/file.c +++ b/tests/filter/file.c @@ -55,19 +55,19 @@ struct buf_writestream { git_str buf; }; -int buf_writestream_write(git_writestream *s, const char *buf, size_t len) +static int buf_writestream_write(git_writestream *s, const char *buf, size_t len) { struct buf_writestream *stream = (struct buf_writestream *)s; return git_str_put(&stream->buf, buf, len); } -int buf_writestream_close(git_writestream *s) +static int buf_writestream_close(git_writestream *s) { GIT_UNUSED(s); return 0; } -void buf_writestream_free(git_writestream *s) +static void buf_writestream_free(git_writestream *s) { struct buf_writestream *stream = (struct buf_writestream *)s; git_str_dispose(&stream->buf); diff --git a/tests/merge/merge_helpers.c b/tests/merge/merge_helpers.c index 73a1d852de2..ce3cd229bb0 100644 --- a/tests/merge/merge_helpers.c +++ b/tests/merge/merge_helpers.c @@ -328,7 +328,7 @@ int merge_test_reuc(git_index *index, const struct merge_reuc_entry expected[], return 1; } -int dircount(void *payload, git_str *pathbuf) +static int dircount(void *payload, git_str *pathbuf) { size_t *entries = payload; size_t len = git_str_len(pathbuf); diff --git a/tests/network/fetchlocal.c b/tests/network/fetchlocal.c index 302d1544cfb..e299d3ec86c 100644 --- a/tests/network/fetchlocal.c +++ b/tests/network/fetchlocal.c @@ -108,7 +108,7 @@ void test_network_fetchlocal__prune(void) git_repository_free(repo); } -int update_tips_fail_on_call(const char *ref, const git_oid *old, const git_oid *new, void *data) +static int update_tips_fail_on_call(const char *ref, const git_oid *old, const git_oid *new, void *data) { GIT_UNUSED(ref); GIT_UNUSED(old); @@ -119,7 +119,7 @@ int update_tips_fail_on_call(const char *ref, const git_oid *old, const git_oid return 0; } -void assert_ref_exists(git_repository *repo, const char *name) +static void assert_ref_exists(git_repository *repo, const char *name) { git_reference *ref; diff --git a/tests/network/remote/push.c b/tests/network/remote/push.c index 34860542e45..3905debdfee 100644 --- a/tests/network/remote/push.c +++ b/tests/network/remote/push.c @@ -29,7 +29,7 @@ void test_network_remote_push__cleanup(void) cl_fixture_cleanup("dummy.git"); } -int negotiation_cb(const git_push_update **updates, size_t len, void *payload) +static int negotiation_cb(const git_push_update **updates, size_t len, void *payload) { const git_push_update *expected = payload; @@ -69,7 +69,7 @@ void test_network_remote_push__delete_notification(void) } -void create_dummy_commit(git_reference **out, git_repository *repo) +static void create_dummy_commit(git_reference **out, git_repository *repo) { git_index *index; git_oid tree_id, commit_id; diff --git a/tests/notes/notes.c b/tests/notes/notes.c index dd9ad1e4b13..a36cddb8ad4 100644 --- a/tests/notes/notes.c +++ b/tests/notes/notes.c @@ -103,7 +103,7 @@ static int note_list_create_cb( return 0; } -void assert_notes_seen(struct note_create_payload payload[], size_t n) +static void assert_notes_seen(struct note_create_payload payload[], size_t n) { size_t seen = 0, i; diff --git a/tests/object/tag/write.c b/tests/object/tag/write.c index 48c8bfd36aa..3c1a9895641 100644 --- a/tests/object/tag/write.c +++ b/tests/object/tag/write.c @@ -221,7 +221,7 @@ void test_object_tag_write__deleting_with_an_invalid_name_returns_EINVALIDSPEC(v cl_assert_equal_i(GIT_EINVALIDSPEC, git_tag_delete(g_repo, "Inv@{id")); } -void create_annotation(git_oid *tag_id, const char *name) +static void create_annotation(git_oid *tag_id, const char *name) { git_object *target; git_oid target_id; diff --git a/tests/odb/loose.c b/tests/odb/loose.c index 5cf567cc26a..dbbc1490e44 100644 --- a/tests/odb/loose.c +++ b/tests/odb/loose.c @@ -187,7 +187,7 @@ void test_odb_loose__read_header(void) test_read_header(&some); } -void test_write_object_permission( +static void test_write_object_permission( mode_t dir_mode, mode_t file_mode, mode_t expected_dir_mode, mode_t expected_file_mode) { diff --git a/tests/online/clone.c b/tests/online/clone.c index ba88dff9c54..8186dda167a 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -361,7 +361,7 @@ void test_online_clone__cred_callback_called_again_on_auth_failure(void) cl_assert_equal_i(3, counter); } -int cred_default( +static int cred_default( git_credential **cred, const char *url, const char *user_from_url, @@ -618,7 +618,7 @@ void test_online_clone__ssh_cannot_change_username(void) cl_git_fail(git_clone(&g_repo, "ssh://git@github.com/libgit2/TestGitRepository", "./foo", &g_options)); } -int ssh_certificate_check(git_cert *cert, int valid, const char *host, void *payload) +static int ssh_certificate_check(git_cert *cert, int valid, const char *host, void *payload) { git_cert_hostkey *key; git_oid expected = {{0}}, actual = {{0}}; diff --git a/tests/online/push_util.c b/tests/online/push_util.c index 94e310f3d83..cd1831d4c71 100644 --- a/tests/online/push_util.c +++ b/tests/online/push_util.c @@ -10,7 +10,7 @@ void updated_tip_free(updated_tip *t) git__free(t); } -void push_status_free(push_status *s) +static void push_status_free(push_status *s) { git__free(s->ref); git__free(s->msg); diff --git a/tests/pack/filelimit.c b/tests/pack/filelimit.c index 2b7bf6e9542..fa08485fb92 100644 --- a/tests/pack/filelimit.c +++ b/tests/pack/filelimit.c @@ -47,7 +47,7 @@ void test_pack_filelimit__cleanup(void) * (README.md) has the same content in all commits, but the second one * (file.txt) has a different content in each commit. */ -void create_packfile_commit( +static void create_packfile_commit( git_repository *repo, git_oid *out_commit_id, git_oid *parent_id, diff --git a/tests/patch/print.c b/tests/patch/print.c index b0a9339436d..33cf27ddb06 100644 --- a/tests/patch/print.c +++ b/tests/patch/print.c @@ -9,7 +9,7 @@ * and then print a variety of patch files. */ -void patch_print_from_patchfile(const char *data, size_t len) +static void patch_print_from_patchfile(const char *data, size_t len) { git_patch *patch; git_buf buf = GIT_BUF_INIT; diff --git a/tests/path/dotgit.c b/tests/path/dotgit.c index 9ac68b0ff06..855145f420b 100644 --- a/tests/path/dotgit.c +++ b/tests/path/dotgit.c @@ -120,7 +120,7 @@ void test_path_dotgit__dotgit_modules_symlink(void) cl_assert_equal_b(false, git_path_is_valid(NULL, ".gitmodules . .::$DATA", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); } -void test_core_path__git_fs_path_is_file(void) +void test_path_dotgit__git_fs_path_is_file(void) { cl_git_fail(git_path_is_gitfile("blob", 4, -1, GIT_PATH_FS_HFS)); cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITIGNORE, GIT_PATH_FS_HFS)); diff --git a/tests/path/win32.c b/tests/path/win32.c index 46b5c9f7015..ff166395dad 100644 --- a/tests/path/win32.c +++ b/tests/path/win32.c @@ -6,35 +6,27 @@ #include "win32/path_w32.h" #endif -void test_utf8_to_utf16(const char *utf8_in, const wchar_t *utf16_expected) -{ #ifdef GIT_WIN32 +static void test_utf8_to_utf16(const char *utf8_in, const wchar_t *utf16_expected) +{ git_win32_path path_utf16; int path_utf16len; cl_assert((path_utf16len = git_win32_path_from_utf8(path_utf16, utf8_in)) >= 0); cl_assert_equal_wcs(utf16_expected, path_utf16); cl_assert_equal_i(wcslen(utf16_expected), path_utf16len); -#else - GIT_UNUSED(utf8_in); - GIT_UNUSED(utf16_expected); -#endif } -void test_utf8_to_utf16_relative(const char* utf8_in, const wchar_t* utf16_expected) +static void test_utf8_to_utf16_relative(const char* utf8_in, const wchar_t* utf16_expected) { -#ifdef GIT_WIN32 git_win32_path path_utf16; int path_utf16len; cl_assert((path_utf16len = git_win32_path_relative_from_utf8(path_utf16, utf8_in)) >= 0); cl_assert_equal_wcs(utf16_expected, path_utf16); cl_assert_equal_i(wcslen(utf16_expected), path_utf16len); -#else - GIT_UNUSED(utf8_in); - GIT_UNUSED(utf16_expected); -#endif } +#endif void test_path_win32__utf8_to_utf16(void) { diff --git a/tests/rebase/iterator.c b/tests/rebase/iterator.c index 49a601243fe..a120f28aca8 100644 --- a/tests/rebase/iterator.c +++ b/tests/rebase/iterator.c @@ -47,7 +47,7 @@ static void test_operations(git_rebase *rebase, size_t expected_current) } } -void test_iterator(bool inmemory) +static void test_iterator(bool inmemory) { git_rebase *rebase; git_rebase_options opts = GIT_REBASE_OPTIONS_INIT; diff --git a/tests/rebase/merge.c b/tests/rebase/merge.c index d24e4facffe..5f730f750b3 100644 --- a/tests/rebase/merge.c +++ b/tests/rebase/merge.c @@ -729,7 +729,7 @@ void test_rebase_merge__copy_notes_disabled_in_config(void) test_copy_note(NULL, 0); } -void rebase_checkout_progress_cb( +static void rebase_checkout_progress_cb( const char *path, size_t completed_steps, size_t total_steps, diff --git a/tests/rebase/sign.c b/tests/rebase/sign.c index dc99407dd87..4064cf79b5f 100644 --- a/tests/rebase/sign.c +++ b/tests/rebase/sign.c @@ -86,7 +86,7 @@ committer Rebaser 1405694510 +0000\n"; git_rebase_free(rebase); } -int create_cb_signed_gpg( +static int create_cb_signed_gpg( git_oid *out, const git_signature *author, const git_signature *committer, diff --git a/tests/refs/shorthand.c b/tests/refs/shorthand.c index f995d26cac7..e008adc744e 100644 --- a/tests/refs/shorthand.c +++ b/tests/refs/shorthand.c @@ -2,7 +2,7 @@ #include "repository.h" -void assert_shorthand(git_repository *repo, const char *refname, const char *shorthand) +static void assert_shorthand(git_repository *repo, const char *refname, const char *shorthand) { git_reference *ref; diff --git a/tests/remote/fetch.c b/tests/remote/fetch.c index 209c42993b1..3700462676f 100644 --- a/tests/remote/fetch.c +++ b/tests/remote/fetch.c @@ -62,7 +62,7 @@ void test_remote_fetch__cleanup(void) { * @param force Whether to use a spec with '+' prefixed to force the refs * to update */ -void do_time_travelling_fetch(git_oid *commit1id, git_oid *commit2id, +static void do_time_travelling_fetch(git_oid *commit1id, git_oid *commit2id, bool force) { char *refspec_strs = { force ? FORCE_FETCHSPEC : NON_FORCE_FETCHSPEC, diff --git a/tests/remote/httpproxy.c b/tests/remote/httpproxy.c index 8cd4371f555..f62a2545bac 100644 --- a/tests/remote/httpproxy.c +++ b/tests/remote/httpproxy.c @@ -40,7 +40,7 @@ void test_remote_httpproxy__cleanup(void) cl_git_sandbox_cleanup(); } -void assert_proxy_is(const char *expected) +static void assert_proxy_is(const char *expected) { git_remote *remote; char *proxy; @@ -57,7 +57,7 @@ void assert_proxy_is(const char *expected) git__free(proxy); } -void assert_config_match(const char *config, const char *expected) +static void assert_config_match(const char *config, const char *expected) { git_remote *remote; char *proxy; @@ -106,7 +106,7 @@ void test_remote_httpproxy__config_empty_overrides(void) assert_config_match("remote.lg2.proxy", ""); } -void assert_global_config_match(const char *config, const char *expected) +static void assert_global_config_match(const char *config, const char *expected) { git_remote *remote; char *proxy; diff --git a/tests/stash/apply.c b/tests/stash/apply.c index c3d1ef0c29f..5125ae6399b 100644 --- a/tests/stash/apply.c +++ b/tests/stash/apply.c @@ -316,7 +316,7 @@ struct seen_paths { bool when; }; -int checkout_notify( +static int checkout_notify( git_checkout_notify_t why, const char *path, const git_diff_file *baseline, @@ -368,7 +368,7 @@ void test_stash_apply__executes_notify_cb(void) cl_assert_equal_b(true, seen_paths.when); } -int progress_cb( +static int progress_cb( git_stash_apply_progress_t progress, void *payload) { @@ -393,7 +393,7 @@ void test_stash_apply__calls_progress_cb(void) cl_assert_equal_i(progress, GIT_STASH_APPLY_PROGRESS_DONE); } -int aborting_progress_cb( +static int aborting_progress_cb( git_stash_apply_progress_t progress, void *payload) { diff --git a/tests/stash/drop.c b/tests/stash/drop.c index 709ff0f9e88..a5714717274 100644 --- a/tests/stash/drop.c +++ b/tests/stash/drop.c @@ -140,7 +140,7 @@ void test_stash_drop__dropping_the_last_entry_removes_the_stash(void) git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE), GIT_ENOTFOUND); } -void retrieve_top_stash_id(git_oid *out) +static void retrieve_top_stash_id(git_oid *out) { git_object *top_stash; diff --git a/tests/status/worktree.c b/tests/status/worktree.c index 692ea93ef7b..00c6ec2d5cf 100644 --- a/tests/status/worktree.c +++ b/tests/status/worktree.c @@ -43,7 +43,7 @@ void test_status_worktree__whole_repository(void) cl_assert_equal_i(0, counts.wrong_sorted_path); } -void assert_show( +static void assert_show( const int entry_counts, const char *entry_paths[], const unsigned int entry_statuses[], diff --git a/tests/submodule/modify.c b/tests/submodule/modify.c index fd3b0f80bbf..7e7f0ca1592 100644 --- a/tests/submodule/modify.c +++ b/tests/submodule/modify.c @@ -128,7 +128,7 @@ void test_submodule_modify__sync(void) git_submodule_free(sm3); } -void assert_ignore_change(git_submodule_ignore_t ignore) +static void assert_ignore_change(git_submodule_ignore_t ignore) { git_submodule *sm; @@ -146,7 +146,7 @@ void test_submodule_modify__set_ignore(void) assert_ignore_change(GIT_SUBMODULE_IGNORE_ALL); } -void assert_update_change(git_submodule_update_t update) +static void assert_update_change(git_submodule_update_t update) { git_submodule *sm; @@ -164,7 +164,7 @@ void test_submodule_modify__set_update(void) assert_update_change(GIT_SUBMODULE_UPDATE_CHECKOUT); } -void assert_recurse_change(git_submodule_recurse_t recurse) +static void assert_recurse_change(git_submodule_recurse_t recurse) { git_submodule *sm; From bfdc09714f07d4007c94dee6a9567cee6be9f290 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 13:32:00 -0500 Subject: [PATCH 0636/1616] test: correct test names --- tests/odb/loose.c | 2 +- tests/refs/branches/name.c | 2 +- tests/refs/tags/name.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/odb/loose.c b/tests/odb/loose.c index dbbc1490e44..fe013a78c20 100644 --- a/tests/odb/loose.c +++ b/tests/odb/loose.c @@ -228,7 +228,7 @@ void test_odb_loose__permissions_standard(void) test_write_object_permission(0, 0, GIT_OBJECT_DIR_MODE, GIT_OBJECT_FILE_MODE); } -void test_odb_loose_permissions_readonly(void) +void test_odb_loose__permissions_readonly(void) { test_write_object_permission(0777, 0444, 0777, 0444); } diff --git a/tests/refs/branches/name.c b/tests/refs/branches/name.c index 290916eecd0..efa68e32b11 100644 --- a/tests/refs/branches/name.c +++ b/tests/refs/branches/name.c @@ -51,7 +51,7 @@ static int name_is_valid(const char *name) return valid; } -void test_refs_branches_is_name_valid(void) +void test_refs_branches_name__is_name_valid(void) { cl_assert_equal_i(true, name_is_valid("master")); cl_assert_equal_i(true, name_is_valid("test/master")); diff --git a/tests/refs/tags/name.c b/tests/refs/tags/name.c index 0ca5df7d641..1dd1760b9ed 100644 --- a/tests/refs/tags/name.c +++ b/tests/refs/tags/name.c @@ -7,7 +7,7 @@ static int name_is_valid(const char *name) return valid; } -void test_refs_tags_is_name_valid(void) +void test_refs_tags_name__is_name_valid(void) { cl_assert_equal_i(true, name_is_valid("sometag")); cl_assert_equal_i(true, name_is_valid("test/sometag")); From 8d2b31109d980462e1853bef3edf08ddecd094b2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 19:58:49 +0000 Subject: [PATCH 0637/1616] tests: include function declarations --- tests/filter/custom_helpers.c | 1 + tests/merge/merge_helpers.h | 4 ++++ tests/refs/ref_helpers.c | 1 + tests/refs/reflog/reflog_helpers.c | 3 ++- tests/refs/reflog/reflog_helpers.h | 8 +++++--- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/filter/custom_helpers.c b/tests/filter/custom_helpers.c index f98f65c229d..95a9f978e2b 100644 --- a/tests/filter/custom_helpers.c +++ b/tests/filter/custom_helpers.c @@ -2,6 +2,7 @@ #include "posix.h" #include "filter.h" #include "git2/sys/filter.h" +#include "custom_helpers.h" #define VERY_SECURE_ENCRYPTION(b) ((b) ^ 0xff) diff --git a/tests/merge/merge_helpers.h b/tests/merge/merge_helpers.h index 166b4eefddb..339812ba590 100644 --- a/tests/merge/merge_helpers.h +++ b/tests/merge/merge_helpers.h @@ -65,4 +65,8 @@ int merge_test_reuc(git_index *index, const struct merge_reuc_entry expected[], int merge_test_workdir(git_repository *repo, const struct merge_index_entry expected[], size_t expected_len); +void merge__dump_names(git_index *index); +void merge__dump_index_entries(git_vector *index_entries); +void merge__dump_reuc(git_index *index); + #endif diff --git a/tests/refs/ref_helpers.c b/tests/refs/ref_helpers.c index 943d0f55189..70d5d36d540 100644 --- a/tests/refs/ref_helpers.c +++ b/tests/refs/ref_helpers.c @@ -3,6 +3,7 @@ #include "common.h" #include "util.h" #include "path.h" +#include "ref_helpers.h" int reference_is_packed(git_reference *ref) { diff --git a/tests/refs/reflog/reflog_helpers.c b/tests/refs/reflog/reflog_helpers.c index 22619a4e3b6..2ea41ee061e 100644 --- a/tests/refs/reflog/reflog_helpers.c +++ b/tests/refs/reflog/reflog_helpers.c @@ -2,8 +2,9 @@ #include "repository.h" #include "reflog.h" +#include "reflog_helpers.h" -static int reflog_entry_tostr(git_str *out, const git_reflog_entry *entry) +int reflog_entry_tostr(git_str *out, const git_reflog_entry *entry) { char old_oid[GIT_OID_HEXSZ], new_oid[GIT_OID_HEXSZ]; diff --git a/tests/refs/reflog/reflog_helpers.h b/tests/refs/reflog/reflog_helpers.h index 80814ea2892..4cd92cadc31 100644 --- a/tests/refs/reflog/reflog_helpers.h +++ b/tests/refs/reflog/reflog_helpers.h @@ -1,10 +1,12 @@ size_t reflog_entrycount(git_repository *repo, const char *name); #define cl_reflog_check_entry(repo, reflog, idx, old_spec, new_spec, email, message) \ - cl_reflog_check_entry_(repo, reflog, idx, old_spec, new_spec, email, message, __FILE__, __LINE__) + cl_reflog_check_entry_(repo, reflog, idx, old_spec, new_spec, email, message, __FILE__, __FUNCTION__, __LINE__) void cl_reflog_check_entry_(git_repository *repo, const char *reflog, size_t idx, - const char *old_spec, const char *new_spec, - const char *email, const char *message, const char *file, int line); + const char *old_spec, const char *new_spec, + const char *email, const char *message, + const char *file, const char *func, int line); void reflog_print(git_repository *repo, const char *reflog_name); +int reflog_entry_tostr(git_str *out, const git_reflog_entry *entry); From 4a6ef5a4a6cabfaa7147aab28130da49e5b177ea Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 17:04:24 -0500 Subject: [PATCH 0638/1616] cmake: move missing-declarations warning to top-level We should enforce declarations throughout the code-base, including examples, fuzzers and tests, not just in the `src` tree. --- cmake/DefaultCFlags.cmake | 1 + src/CMakeLists.txt | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/DefaultCFlags.cmake b/cmake/DefaultCFlags.cmake index d122f6c258e..fa59e1d97e5 100644 --- a/cmake/DefaultCFlags.cmake +++ b/cmake/DefaultCFlags.cmake @@ -125,6 +125,7 @@ else() enable_warnings(documentation) disable_warnings(documentation-deprecated-sync) disable_warnings(missing-field-initializers) + enable_warnings(missing-declarations) enable_warnings(strict-aliasing) enable_warnings(strict-prototypes) enable_warnings(declaration-after-statement) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ae02ef9aa42..6a128cfa8c8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,8 +41,6 @@ set(LIBGIT2_INCLUDES set(LIBGIT2_SYSTEM_INCLUDES "") set(LIBGIT2_LIBS "") -enable_warnings(missing-declarations) - if(HAVE_FUTIMENS) set(GIT_USE_FUTIMENS 1) endif () From 709b1b62686d3526eb27169a4d80c0ed4e8f7e55 Mon Sep 17 00:00:00 2001 From: Jason Nader Date: Fri, 5 Nov 2021 02:28:37 +0900 Subject: [PATCH 0639/1616] repository: do not copy templates if dir nonexistent This mimics the behaviour of git which just prints a warning and continues with the repo initialisation. --- src/repository.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/repository.c b/src/repository.c index 29684e463db..2002e118639 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2032,9 +2032,15 @@ static int repo_init_structure( git_str_dispose(&template_buf); git_config_free(cfg); + /* If tdir does not exist, then do not error out. This matches the + * behaviour of git(1), which just prints a warning and continues. + * TODO: issue warning when warning API is available. + * `git` prints to stderr: 'warning: templates not found in /path/to/tdir' + */ if (error < 0) { - if (!default_template) + if (!default_template && error != GIT_ENOTFOUND) { return error; + } /* if template was default, ignore error and use internal */ git_error_clear(); From bc0d1ad21e17a610dd484a8970cb2765ae8b6c8e Mon Sep 17 00:00:00 2001 From: Jason Nader Date: Fri, 5 Nov 2021 03:08:43 +0900 Subject: [PATCH 0640/1616] tests: try to init with non-existent template path --- tests/repo/template.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/repo/template.c b/tests/repo/template.c index 6f369c6d6e7..99d4b6fd404 100644 --- a/tests/repo/template.c +++ b/tests/repo/template.c @@ -293,3 +293,13 @@ void test_repo_template__empty_template_path(void) setup_repo("foo", &opts); } + +void test_repo_template__nonexistent_template_path(void) +{ + git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; + + opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; + opts.template_path = "/tmp/path/that/does/not/exist/for/libgit2/test"; + + setup_repo("bar", &opts); +} From 0c4d24dad2db95132568043bb086dff2af400eda Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sun, 14 Nov 2021 02:24:39 -0800 Subject: [PATCH 0641/1616] Fix a gcc 11 warning in src/threadstate.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building under gcc 11, there is a warning about a misaligned guard clause because there were mixed spaces and tabs: ``` [128/634] Building C object src/CMakeFiles/git2internal.dir/threadstate.c.o ../src/threadstate.c: In function ‘threadstate_dispose’: ../src/threadstate.c:39:5: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation] 39 | if (threadstate->error_t.message != git_str__initstr) | ^~ ../src/threadstate.c:41:9: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’ 41 | threadstate->error_t.message = NULL; | ^~~~~~~~~~~ ../src/threadstate.c: At top level: ``` This change indents the code with tabs for consistency with the rest of the code, which makes the warning go away. --- src/threadstate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/threadstate.c b/src/threadstate.c index f67cf082bb4..9e3ef581849 100644 --- a/src/threadstate.c +++ b/src/threadstate.c @@ -36,8 +36,8 @@ static void threadstate_dispose(git_threadstate *threadstate) if (!threadstate) return; - if (threadstate->error_t.message != git_str__initstr) - git__free(threadstate->error_t.message); + if (threadstate->error_t.message != git_str__initstr) + git__free(threadstate->error_t.message); threadstate->error_t.message = NULL; } From 5675312e5aeb0c8b438df3ba9da7542673b2e0e7 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sun, 14 Nov 2021 02:27:10 -0800 Subject: [PATCH 0642/1616] Fix a gcc 11 warning in src/thread.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building under gcc 11, there is a warning about an incompatible pointer type, since [`__atomic_exchange`](https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html) does not take `volatile` pointers: ``` In file included from ../src/common.h:81, from ../src/transports/winhttp.c:8: ../src/thread-utils.h: In function ‘git___swap’: ../src/thread-utils.h:168:9: warning: argument 3 of ‘__atomic_exchange’ discards ‘volatile’ qualifier [-Wincompatible-pointer-types] 168 | __atomic_exchange(ptr, &newval, &foundval, __ATOMIC_SEQ_CST); | ^~~~~~~~~~~~~~~~~ ``` This change drops the `volatile` qualifier so that the pointer type matches what `__atomic_exchange` expects. --- src/thread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thread.h b/src/thread.h index 82eb7fcab03..4bbac9fd870 100644 --- a/src/thread.h +++ b/src/thread.h @@ -180,7 +180,7 @@ GIT_INLINE(volatile void *) git_atomic__swap( #if defined(GIT_WIN32) return InterlockedExchangePointer(ptr, newval); #elif defined(GIT_BUILTIN_ATOMIC) - void * volatile foundval = NULL; + void * foundval = NULL; __atomic_exchange(ptr, &newval, &foundval, __ATOMIC_SEQ_CST); return foundval; #elif defined(GIT_BUILTIN_SYNC) From c3fec45645e6939b3604d2d233be6f97ff629f87 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 22:37:36 -0500 Subject: [PATCH 0643/1616] cmake: reformat modules Apply the standard project cmake formatting to the modules. --- cmake/AddCFlagIfSupported.cmake | 42 +-- cmake/EnableWarnings.cmake | 26 +- cmake/FindCoreFoundation.cmake | 26 +- cmake/FindGSSAPI.cmake | 456 ++++++++++++-------------------- cmake/FindGSSFramework.cmake | 26 +- cmake/FindHTTPParser.cmake | 34 +-- cmake/FindIconv.cmake | 54 ++-- cmake/FindLibSSH2.cmake | 10 +- cmake/FindPCRE.cmake | 26 +- cmake/FindPCRE2.cmake | 24 +- cmake/FindPkgLibraries.cmake | 38 +-- cmake/FindSecurity.cmake | 28 +- cmake/Findfutimens.cmake | 16 +- cmake/FindmbedTLS.cmake | 133 +++++----- cmake/IdeSplitSources.cmake | 34 +-- cmake/PkgBuildConfig.cmake | 120 ++++----- cmake/SanitizeBool.cmake | 40 +-- cmake/SelectGSSAPI.cmake | 74 +++--- cmake/SelectHTTPSBackend.cmake | 200 +++++++------- cmake/SelectHashes.cmake | 94 +++---- 20 files changed, 689 insertions(+), 812 deletions(-) diff --git a/cmake/AddCFlagIfSupported.cmake b/cmake/AddCFlagIfSupported.cmake index b7aaa7910a9..685f26a00fc 100644 --- a/cmake/AddCFlagIfSupported.cmake +++ b/cmake/AddCFlagIfSupported.cmake @@ -3,28 +3,28 @@ # - the compiler flag to test # This internally calls the CHECK_C_COMPILER_FLAG macro. -INCLUDE(CheckCCompilerFlag) +include(CheckCCompilerFlag) -MACRO(ADD_C_FLAG _FLAG) - STRING(TOUPPER ${_FLAG} UPCASE) - STRING(REGEX REPLACE "[-=]" "_" UPCASE_PRETTY ${UPCASE}) - STRING(REGEX REPLACE "^_+" "" UPCASE_PRETTY ${UPCASE_PRETTY}) - CHECK_C_COMPILER_FLAG(${_FLAG} IS_${UPCASE_PRETTY}_SUPPORTED) +macro(ADD_C_FLAG _FLAG) + string(TOUPPER ${_FLAG} UPCASE) + string(REGEX REPLACE "[-=]" "_" UPCASE_PRETTY ${UPCASE}) + string(REGEX REPLACE "^_+" "" UPCASE_PRETTY ${UPCASE_PRETTY}) + check_c_compiler_flag(${_FLAG} IS_${UPCASE_PRETTY}_SUPPORTED) - IF(IS_${UPCASE_PRETTY}_SUPPORTED) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_FLAG}") - ELSE() - MESSAGE(FATAL_ERROR "Required flag ${_FLAG} is not supported") - ENDIF() -ENDMACRO() + if(IS_${UPCASE_PRETTY}_SUPPORTED) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_FLAG}") + else() + message(FATAL_ERROR "Required flag ${_FLAG} is not supported") + endif() +endmacro() -MACRO(ADD_C_FLAG_IF_SUPPORTED _FLAG) - STRING(TOUPPER ${_FLAG} UPCASE) - STRING(REGEX REPLACE "[-=]" "_" UPCASE_PRETTY ${UPCASE}) - STRING(REGEX REPLACE "^_+" "" UPCASE_PRETTY ${UPCASE_PRETTY}) - CHECK_C_COMPILER_FLAG(${_FLAG} IS_${UPCASE_PRETTY}_SUPPORTED) +macro(ADD_C_FLAG_IF_SUPPORTED _FLAG) + string(TOUPPER ${_FLAG} UPCASE) + string(REGEX REPLACE "[-=]" "_" UPCASE_PRETTY ${UPCASE}) + string(REGEX REPLACE "^_+" "" UPCASE_PRETTY ${UPCASE_PRETTY}) + check_c_compiler_flag(${_FLAG} IS_${UPCASE_PRETTY}_SUPPORTED) - IF(IS_${UPCASE_PRETTY}_SUPPORTED) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_FLAG}") - ENDIF() -ENDMACRO() + if(IS_${UPCASE_PRETTY}_SUPPORTED) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_FLAG}") + endif() +endmacro() diff --git a/cmake/EnableWarnings.cmake b/cmake/EnableWarnings.cmake index b61ed7e90d4..0700b521b68 100644 --- a/cmake/EnableWarnings.cmake +++ b/cmake/EnableWarnings.cmake @@ -1,15 +1,15 @@ -MACRO(ENABLE_WARNINGS flag) - ADD_C_FLAG_IF_SUPPORTED(-W${flag}) -ENDMACRO() +macro(ENABLE_WARNINGS flag) + add_c_flag_if_supported(-W${flag}) +endmacro() -MACRO(DISABLE_WARNINGS flag) - ADD_C_FLAG_IF_SUPPORTED(-Wno-${flag}) -ENDMACRO() +macro(DISABLE_WARNINGS flag) + add_c_flag_if_supported(-Wno-${flag}) +endmacro() -IF(ENABLE_WERROR) - IF(MSVC) - ADD_COMPILE_OPTIONS(-WX) - ELSE() - ADD_C_FLAG_IF_SUPPORTED(-Werror) - ENDIF() -ENDIF() +if(ENABLE_WERROR) + if(MSVC) + add_compile_options(-WX) + else() + add_c_flag_if_supported(-Werror) + endif() +endif() diff --git a/cmake/FindCoreFoundation.cmake b/cmake/FindCoreFoundation.cmake index 191aa595cfc..b419ec9abd9 100644 --- a/cmake/FindCoreFoundation.cmake +++ b/cmake/FindCoreFoundation.cmake @@ -6,21 +6,21 @@ # COREFOUNDATION_LDFLAGS # -FIND_PATH(COREFOUNDATION_INCLUDE_DIR NAMES CoreFoundation.h) -FIND_LIBRARY(COREFOUNDATION_LIBRARIES NAMES CoreFoundation) -IF (COREFOUNDATION_INCLUDE_DIR AND COREFOUNDATION_LIBRARIES) - IF (NOT CoreFoundation_FIND_QUIETLY) - MESSAGE(STATUS "Found CoreFoundation ${COREFOUNDATION_LIBRARIES}") - ENDIF() - SET(COREFOUNDATION_FOUND TRUE) - SET(COREFOUNDATION_LDFLAGS "-framework CoreFoundation") -ENDIF () +find_path(COREFOUNDATION_INCLUDE_DIR NAMES CoreFoundation.h) +find_library(COREFOUNDATION_LIBRARIES NAMES CoreFoundation) +if(COREFOUNDATION_INCLUDE_DIR AND COREFOUNDATION_LIBRARIES) + if(NOT CoreFoundation_FIND_QUIETLY) + message(STATUS "Found CoreFoundation ${COREFOUNDATION_LIBRARIES}") + endif() + set(COREFOUNDATION_FOUND TRUE) + set(COREFOUNDATION_LDFLAGS "-framework CoreFoundation") +endif() -IF (CoreFoundation_FIND_REQUIRED AND NOT COREFOUNDATION_FOUND) - MESSAGE(FATAL_ERROR "CoreFoundation not found") -ENDIF() +if(CoreFoundation_FIND_REQUIRED AND NOT COREFOUNDATION_FOUND) + message(FATAL_ERROR "CoreFoundation not found") +endif() -MARK_AS_ADVANCED( +mark_as_advanced( COREFOUNDATION_INCLUDE_DIR COREFOUNDATION_LIBRARIES ) diff --git a/cmake/FindGSSAPI.cmake b/cmake/FindGSSAPI.cmake index 37357c4cd4b..0f5932a2202 100644 --- a/cmake/FindGSSAPI.cmake +++ b/cmake/FindGSSAPI.cmake @@ -25,300 +25,184 @@ # find_path(GSSAPI_ROOT_DIR - NAMES - include/gssapi.h - include/gssapi/gssapi.h - HINTS - ${_GSSAPI_ROOT_HINTS} - PATHS - ${_GSSAPI_ROOT_PATHS} -) + NAMES include/gssapi.h include/gssapi/gssapi.h + HINTS ${_GSSAPI_ROOT_HINTS} + PATHS ${_GSSAPI_ROOT_PATHS}) mark_as_advanced(GSSAPI_ROOT_DIR) -if (UNIX) - find_program(KRB5_CONFIG - NAMES - krb5-config - PATHS - ${GSSAPI_ROOT_DIR}/bin - /opt/local/bin) - mark_as_advanced(KRB5_CONFIG) - - if (KRB5_CONFIG) - # Check if we have MIT KRB5 - execute_process( - COMMAND - ${KRB5_CONFIG} --vendor - RESULT_VARIABLE - _GSSAPI_VENDOR_RESULT - OUTPUT_VARIABLE - _GSSAPI_VENDOR_STRING) - - if (_GSSAPI_VENDOR_STRING MATCHES ".*Massachusetts.*") - set(GSSAPI_FLAVOR_MIT TRUE) - else() - execute_process( - COMMAND - ${KRB5_CONFIG} --libs gssapi - RESULT_VARIABLE - _GSSAPI_LIBS_RESULT - OUTPUT_VARIABLE - _GSSAPI_LIBS_STRING) - - if (_GSSAPI_LIBS_STRING MATCHES ".*roken.*") - set(GSSAPI_FLAVOR_HEIMDAL TRUE) - endif() - endif() - - # Get the include dir - execute_process( - COMMAND - ${KRB5_CONFIG} --cflags gssapi - RESULT_VARIABLE - _GSSAPI_INCLUDE_RESULT - OUTPUT_VARIABLE - _GSSAPI_INCLUDE_STRING) - string(REGEX REPLACE "(\r?\n)+$" "" _GSSAPI_INCLUDE_STRING "${_GSSAPI_INCLUDE_STRING}") - string(REGEX REPLACE " *-I" "" _GSSAPI_INCLUDEDIR "${_GSSAPI_INCLUDE_STRING}") - endif() - - if (NOT GSSAPI_FLAVOR_MIT AND NOT GSSAPI_FLAVOR_HEIMDAL) - # Check for HEIMDAL - find_package(PkgConfig) - if (PKG_CONFIG_FOUND) - pkg_check_modules(_GSSAPI heimdal-gssapi) - endif (PKG_CONFIG_FOUND) - - if (_GSSAPI_FOUND) - set(GSSAPI_FLAVOR_HEIMDAL TRUE) - else() - find_path(_GSSAPI_ROKEN - NAMES - roken.h - PATHS - ${GSSAPI_ROOT_DIR}/include - ${_GSSAPI_INCLUDEDIR}) - if (_GSSAPI_ROKEN) - set(GSSAPI_FLAVOR_HEIMDAL TRUE) - endif() - endif () - endif() -endif (UNIX) +if(UNIX) + find_program(KRB5_CONFIG + NAMES krb5-config + PATHS ${GSSAPI_ROOT_DIR}/bin /opt/local/bin) + mark_as_advanced(KRB5_CONFIG) + + if(KRB5_CONFIG) + # Check if we have MIT KRB5 + execute_process( + COMMAND ${KRB5_CONFIG} --vendor + RESULT_VARIABLE _GSSAPI_VENDOR_RESULT + OUTPUT_VARIABLE _GSSAPI_VENDOR_STRING) + + if(_GSSAPI_VENDOR_STRING MATCHES ".*Massachusetts.*") + set(GSSAPI_FLAVOR_MIT TRUE) + else() + execute_process( + COMMAND ${KRB5_CONFIG} --libs gssapi + RESULT_VARIABLE _GSSAPI_LIBS_RESULT + OUTPUT_VARIABLE _GSSAPI_LIBS_STRING) + + if(_GSSAPI_LIBS_STRING MATCHES ".*roken.*") + set(GSSAPI_FLAVOR_HEIMDAL TRUE) + endif() + endif() + + # Get the include dir + execute_process( + COMMAND ${KRB5_CONFIG} --cflags gssapi + RESULT_VARIABLE _GSSAPI_INCLUDE_RESULT + OUTPUT_VARIABLE _GSSAPI_INCLUDE_STRING) + string(REGEX REPLACE "(\r?\n)+$" "" _GSSAPI_INCLUDE_STRING "${_GSSAPI_INCLUDE_STRING}") + string(REGEX REPLACE " *-I" "" _GSSAPI_INCLUDEDIR "${_GSSAPI_INCLUDE_STRING}") + endif() + + if(NOT GSSAPI_FLAVOR_MIT AND NOT GSSAPI_FLAVOR_HEIMDAL) + # Check for HEIMDAL + find_package(PkgConfig) + if(PKG_CONFIG_FOUND) + pkg_check_modules(_GSSAPI heimdal-gssapi) + endif() + + if(_GSSAPI_FOUND) + set(GSSAPI_FLAVOR_HEIMDAL TRUE) + else() + find_path(_GSSAPI_ROKEN + NAMES roken.h + PATHS ${GSSAPI_ROOT_DIR}/include ${_GSSAPI_INCLUDEDIR}) + if(_GSSAPI_ROKEN) + set(GSSAPI_FLAVOR_HEIMDAL TRUE) + endif() + endif() + endif() +endif() find_path(GSSAPI_INCLUDE_DIR - NAMES - gssapi.h - gssapi/gssapi.h - PATHS - ${GSSAPI_ROOT_DIR}/include - ${_GSSAPI_INCLUDEDIR} -) - -if (GSSAPI_FLAVOR_MIT) - find_library(GSSAPI_LIBRARY - NAMES - gssapi_krb5 - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(KRB5_LIBRARY - NAMES - krb5 - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(K5CRYPTO_LIBRARY - NAMES - k5crypto - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(COM_ERR_LIBRARY - NAMES - com_err - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - if (GSSAPI_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${GSSAPI_LIBRARY} - ) - endif (GSSAPI_LIBRARY) - - if (KRB5_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${KRB5_LIBRARY} - ) - endif (KRB5_LIBRARY) - - if (K5CRYPTO_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${K5CRYPTO_LIBRARY} - ) - endif (K5CRYPTO_LIBRARY) - - if (COM_ERR_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${COM_ERR_LIBRARY} - ) - endif (COM_ERR_LIBRARY) -endif (GSSAPI_FLAVOR_MIT) - -if (GSSAPI_FLAVOR_HEIMDAL) - find_library(GSSAPI_LIBRARY - NAMES - gssapi - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(KRB5_LIBRARY - NAMES - krb5 - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(HCRYPTO_LIBRARY - NAMES - hcrypto - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(COM_ERR_LIBRARY - NAMES - com_err - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(HEIMNTLM_LIBRARY - NAMES - heimntlm - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(HX509_LIBRARY - NAMES - hx509 - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(ASN1_LIBRARY - NAMES - asn1 - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(WIND_LIBRARY - NAMES - wind - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - find_library(ROKEN_LIBRARY - NAMES - roken - PATHS - ${GSSAPI_ROOT_DIR}/lib - ${_GSSAPI_LIBDIR} - ) - - if (GSSAPI_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${GSSAPI_LIBRARY} - ) - endif (GSSAPI_LIBRARY) - - if (KRB5_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${KRB5_LIBRARY} - ) - endif (KRB5_LIBRARY) - - if (HCRYPTO_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${HCRYPTO_LIBRARY} - ) - endif (HCRYPTO_LIBRARY) - - if (COM_ERR_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${COM_ERR_LIBRARY} - ) - endif (COM_ERR_LIBRARY) - - if (HEIMNTLM_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${HEIMNTLM_LIBRARY} - ) - endif (HEIMNTLM_LIBRARY) - - if (HX509_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${HX509_LIBRARY} - ) - endif (HX509_LIBRARY) - - if (ASN1_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${ASN1_LIBRARY} - ) - endif (ASN1_LIBRARY) - - if (WIND_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${WIND_LIBRARY} - ) - endif (WIND_LIBRARY) - - if (ROKEN_LIBRARY) - set(GSSAPI_LIBRARIES - ${GSSAPI_LIBRARIES} - ${WIND_LIBRARY} - ) - endif (ROKEN_LIBRARY) -endif (GSSAPI_FLAVOR_HEIMDAL) + NAMES gssapi.h gssapi/gssapi.h + PATHS ${GSSAPI_ROOT_DIR}/include ${_GSSAPI_INCLUDEDIR}) + +if(GSSAPI_FLAVOR_MIT) + find_library(GSSAPI_LIBRARY + NAMES gssapi_krb5 + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + find_library(KRB5_LIBRARY + NAMES krb5 + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + find_library(K5CRYPTO_LIBRARY + NAMES k5crypto + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + find_library(COM_ERR_LIBRARY + NAMES com_err + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + if(GSSAPI_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${GSSAPI_LIBRARY}) + endif() + + if(KRB5_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${KRB5_LIBRARY}) + endif() + + if(K5CRYPTO_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${K5CRYPTO_LIBRARY}) + endif() + + if(COM_ERR_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${COM_ERR_LIBRARY}) + endif() +endif() + +if(GSSAPI_FLAVOR_HEIMDAL) + find_library(GSSAPI_LIBRARY + NAMES gssapi + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + find_library(KRB5_LIBRARY + NAMES krb5 + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + find_library(HCRYPTO_LIBRARY + NAMES hcrypto + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + find_library(COM_ERR_LIBRARY + NAMES com_err + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + find_library(HEIMNTLM_LIBRARY + NAMES heimntlm + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + find_library(HX509_LIBRARY + NAMES hx509 + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + find_library(ASN1_LIBRARY + NAMES asn1 + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + find_library(WIND_LIBRARY + NAMES wind + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + find_library(ROKEN_LIBRARY + NAMES roken + PATHS ${GSSAPI_ROOT_DIR}/lib ${_GSSAPI_LIBDIR}) + + if(GSSAPI_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${GSSAPI_LIBRARY}) + endif() + + if(KRB5_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${KRB5_LIBRARY}) + endif() + + if(HCRYPTO_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${HCRYPTO_LIBRARY}) + endif() + + if(COM_ERR_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${COM_ERR_LIBRARY}) + endif() + + if(HEIMNTLM_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${HEIMNTLM_LIBRARY}) + endif() + + if(HX509_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${HX509_LIBRARY}) + endif() + + if(ASN1_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${ASN1_LIBRARY}) + endif() + + if(WIND_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${WIND_LIBRARY}) + endif() + + if(ROKEN_LIBRARY) + set(GSSAPI_LIBRARIES ${GSSAPI_LIBRARIES} ${WIND_LIBRARY}) + endif() +endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GSSAPI DEFAULT_MSG GSSAPI_LIBRARIES GSSAPI_INCLUDE_DIR) -if (GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES) - set(GSSAPI_FOUND TRUE) -endif (GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES) +if(GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES) + set(GSSAPI_FOUND TRUE) +endif(GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES) # show the GSSAPI_INCLUDE_DIRS and GSSAPI_LIBRARIES variables only in the advanced view mark_as_advanced(GSSAPI_INCLUDE_DIRS GSSAPI_LIBRARIES) diff --git a/cmake/FindGSSFramework.cmake b/cmake/FindGSSFramework.cmake index dcf7249160c..1b0c936d7cc 100644 --- a/cmake/FindGSSFramework.cmake +++ b/cmake/FindGSSFramework.cmake @@ -7,21 +7,21 @@ # GSSFRAMEWORK_LDFLAGS # -FIND_PATH(GSSFRAMEWORK_INCLUDE_DIR NAMES GSS.h) -FIND_LIBRARY(GSSFRAMEWORK_LIBRARIES NAMES GSS) -IF (GSSFRAMEWORK_INCLUDE_DIR AND GSSFRAMEWORK_LIBRARIES) - IF (NOT CoreFoundation_FIND_QUIETLY) - MESSAGE(STATUS "Found GSS.framework ${GSSFRAMEWORK_LIBRARIES}") - ENDIF() - SET(GSSFRAMEWORK_FOUND TRUE) - SET(GSSFRAMEWORK_LDFLAGS "-framework GSS") -ENDIF () +find_path(GSSFRAMEWORK_INCLUDE_DIR NAMES GSS.h) +find_library(GSSFRAMEWORK_LIBRARIES NAMES GSS) +if(GSSFRAMEWORK_INCLUDE_DIR AND GSSFRAMEWORK_LIBRARIES) + if(NOT CoreFoundation_FIND_QUIETLY) + message(STATUS "Found GSS.framework ${GSSFRAMEWORK_LIBRARIES}") + endif() + set(GSSFRAMEWORK_FOUND TRUE) + set(GSSFRAMEWORK_LDFLAGS "-framework GSS") +endif() -IF (GSS_FIND_REQUIRED AND NOT GSSFRAMEWORK_FOUND) - MESSAGE(FATAL_ERROR "CoreFoundation not found") -ENDIF() +if(GSS_FIND_REQUIRED AND NOT GSSFRAMEWORK_FOUND) + message(FATAL_ERROR "CoreFoundation not found") +endif() -MARK_AS_ADVANCED( +mark_as_advanced( GSSFRAMEWORK_INCLUDE_DIR GSSFRAMEWORK_LIBRARIES GSSFRAMEWORK_LDFLAGS diff --git a/cmake/FindHTTPParser.cmake b/cmake/FindHTTPParser.cmake index d92bf75cc60..3350190e054 100644 --- a/cmake/FindHTTPParser.cmake +++ b/cmake/FindHTTPParser.cmake @@ -10,30 +10,30 @@ # HTTP_PARSER_VERSION_STRING - the version of http-parser found # Find the header and library -FIND_PATH(HTTP_PARSER_INCLUDE_DIR NAMES http_parser.h) -FIND_LIBRARY(HTTP_PARSER_LIBRARY NAMES http_parser libhttp_parser) +find_path(HTTP_PARSER_INCLUDE_DIR NAMES http_parser.h) +find_library(HTTP_PARSER_LIBRARY NAMES http_parser libhttp_parser) # Found the header, read version -if (HTTP_PARSER_INCLUDE_DIR AND EXISTS "${HTTP_PARSER_INCLUDE_DIR}/http_parser.h") - FILE(READ "${HTTP_PARSER_INCLUDE_DIR}/http_parser.h" HTTP_PARSER_H) - IF (HTTP_PARSER_H) - STRING(REGEX REPLACE ".*#define[\t ]+HTTP_PARSER_VERSION_MAJOR[\t ]+([0-9]+).*" "\\1" HTTP_PARSER_VERSION_MAJOR "${HTTP_PARSER_H}") - STRING(REGEX REPLACE ".*#define[\t ]+HTTP_PARSER_VERSION_MINOR[\t ]+([0-9]+).*" "\\1" HTTP_PARSER_VERSION_MINOR "${HTTP_PARSER_H}") - SET(HTTP_PARSER_VERSION_STRING "${HTTP_PARSER_VERSION_MAJOR}.${HTTP_PARSER_VERSION_MINOR}") - ENDIF() - UNSET(HTTP_PARSER_H) -ENDIF() +if(HTTP_PARSER_INCLUDE_DIR AND EXISTS "${HTTP_PARSER_INCLUDE_DIR}/http_parser.h") + file(READ "${HTTP_PARSER_INCLUDE_DIR}/http_parser.h" HTTP_PARSER_H) + if(HTTP_PARSER_H) + string(REGEX REPLACE ".*#define[\t ]+HTTP_PARSER_VERSION_MAJOR[\t ]+([0-9]+).*" "\\1" HTTP_PARSER_VERSION_MAJOR "${HTTP_PARSER_H}") + string(REGEX REPLACE ".*#define[\t ]+HTTP_PARSER_VERSION_MINOR[\t ]+([0-9]+).*" "\\1" HTTP_PARSER_VERSION_MINOR "${HTTP_PARSER_H}") + set(HTTP_PARSER_VERSION_STRING "${HTTP_PARSER_VERSION_MAJOR}.${HTTP_PARSER_VERSION_MINOR}") + endif() + unset(HTTP_PARSER_H) +endif() # Handle the QUIETLY and REQUIRED arguments and set HTTP_PARSER_FOUND # to TRUE if all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(HTTP_Parser REQUIRED_VARS HTTP_PARSER_INCLUDE_DIR HTTP_PARSER_LIBRARY) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(HTTP_Parser REQUIRED_VARS HTTP_PARSER_INCLUDE_DIR HTTP_PARSER_LIBRARY) # Hide advanced variables -MARK_AS_ADVANCED(HTTP_PARSER_INCLUDE_DIR HTTP_PARSER_LIBRARY) +mark_as_advanced(HTTP_PARSER_INCLUDE_DIR HTTP_PARSER_LIBRARY) # Set standard variables -IF (HTTP_PARSER_FOUND) - SET(HTTP_PARSER_LIBRARIES ${HTTP_PARSER_LIBRARY}) +if(HTTP_PARSER_FOUND) + set(HTTP_PARSER_LIBRARIES ${HTTP_PARSER_LIBRARY}) set(HTTP_PARSER_INCLUDE_DIRS ${HTTP_PARSER_INCLUDE_DIR}) -ENDIF() +endif() diff --git a/cmake/FindIconv.cmake b/cmake/FindIconv.cmake index 3c66cdad41c..9e6ded99dc4 100644 --- a/cmake/FindIconv.cmake +++ b/cmake/FindIconv.cmake @@ -6,40 +6,40 @@ # ICONV_LIBRARIES - Link these to use Iconv # -IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) +if(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) # Already in cache, be silent - SET(ICONV_FIND_QUIETLY TRUE) -ENDIF() + set(ICONV_FIND_QUIETLY TRUE) +endif() -FIND_PATH(ICONV_INCLUDE_DIR iconv.h) -CHECK_FUNCTION_EXISTS(iconv_open libc_has_iconv) -FIND_LIBRARY(iconv_lib NAMES iconv libiconv libiconv-2 c) +find_path(ICONV_INCLUDE_DIR iconv.h) +check_function_exists(iconv_open libc_has_iconv) +find_library(iconv_lib NAMES iconv libiconv libiconv-2 c) -IF(ICONV_INCLUDE_DIR AND libc_has_iconv) - SET(ICONV_FOUND TRUE) - SET(ICONV_LIBRARIES "") - IF(NOT ICONV_FIND_QUIETLY) - MESSAGE(STATUS "Found Iconv: provided by libc") - ENDIF(NOT ICONV_FIND_QUIETLY) -ELSEIF(ICONV_INCLUDE_DIR AND iconv_lib) - SET(ICONV_FOUND TRUE) +if(ICONV_INCLUDE_DIR AND libc_has_iconv) + set(ICONV_FOUND TRUE) + set(ICONV_LIBRARIES "") + if(NOT ICONV_FIND_QUIETLY) + message(STATUS "Found Iconv: provided by libc") + endif(NOT ICONV_FIND_QUIETLY) +elseif(ICONV_INCLUDE_DIR AND iconv_lib) + set(ICONV_FOUND TRUE) # split iconv into -L and -l linker options, so we can # set them for pkg-config - GET_FILENAME_COMPONENT(iconv_path ${iconv_lib} PATH) - GET_FILENAME_COMPONENT(iconv_name ${iconv_lib} NAME_WE) - STRING(REGEX REPLACE "^lib" "" iconv_name ${iconv_name}) - SET(ICONV_LIBRARIES "-L${iconv_path} -l${iconv_name}") + get_filename_component(iconv_path ${iconv_lib} PATH) + get_filename_component(iconv_name ${iconv_lib} NAME_WE) + string(REGEX REPLACE "^lib" "" iconv_name ${iconv_name}) + set(ICONV_LIBRARIES "-L${iconv_path} -l${iconv_name}") - IF(NOT ICONV_FIND_QUIETLY) - MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}") - ENDIF(NOT ICONV_FIND_QUIETLY) -ELSE() - IF(Iconv_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find Iconv") - ENDIF(Iconv_FIND_REQUIRED) -ENDIF() + if(NOT ICONV_FIND_QUIETLY) + message(STATUS "Found Iconv: ${ICONV_LIBRARIES}") + endif() +else() + if(Iconv_FIND_REQUIRED) + message(FATAL_ERROR "Could not find Iconv") + endif(Iconv_FIND_REQUIRED) +endif() -MARK_AS_ADVANCED( +mark_as_advanced( ICONV_INCLUDE_DIR ICONV_LIBRARIES ) diff --git a/cmake/FindLibSSH2.cmake b/cmake/FindLibSSH2.cmake index ff5893525a6..c571997c434 100644 --- a/cmake/FindLibSSH2.cmake +++ b/cmake/FindLibSSH2.cmake @@ -2,12 +2,12 @@ # LIBSSH2_INCLUDE_DIR - the libssh2 include directory # LIBSSH2_LIBRARY - the libssh2 library name -FIND_PATH(LIBSSH2_INCLUDE_DIR libssh2.h) +find_path(LIBSSH2_INCLUDE_DIR libssh2.h) -FIND_LIBRARY(LIBSSH2_LIBRARY NAMES ssh2 libssh2) +find_library(LIBSSH2_LIBRARY NAMES ssh2 libssh2) -INCLUDE(FindPackageHandleStandardArgs) +include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LibSSH2 - REQUIRED_VARS LIBSSH2_LIBRARY LIBSSH2_INCLUDE_DIR) + REQUIRED_VARS LIBSSH2_LIBRARY LIBSSH2_INCLUDE_DIR) -MARK_AS_ADVANCED(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY) +mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY) diff --git a/cmake/FindPCRE.cmake b/cmake/FindPCRE.cmake index 74ed61e5391..3a7cfad919c 100644 --- a/cmake/FindPCRE.cmake +++ b/cmake/FindPCRE.cmake @@ -16,23 +16,23 @@ # PCRE_FOUND - True if pcre found. # Look for the header file. -FIND_PATH(PCRE_INCLUDE_DIR NAMES pcreposix.h) +find_path(PCRE_INCLUDE_DIR NAMES pcreposix.h) # Look for the library. -FIND_LIBRARY(PCRE_LIBRARY NAMES pcre) -FIND_LIBRARY(PCRE_POSIX_LIBRARY NAMES pcreposix) +find_library(PCRE_LIBRARY NAMES pcre) +find_library(PCRE_POSIX_LIBRARY NAMES pcreposix) # Handle the QUIETLY and REQUIRED arguments and set PCRE_FOUND to TRUE if all listed variables are TRUE. -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARY PCRE_POSIX_LIBRARY PCRE_INCLUDE_DIR) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PCRE DEFAULT_MSG PCRE_LIBRARY PCRE_POSIX_LIBRARY PCRE_INCLUDE_DIR) # Copy the results to the output variables. -IF(PCRE_FOUND) - SET(PCRE_LIBRARIES ${PCRE_LIBRARY} ${PCRE_POSIX_LIBRARY}) - SET(PCRE_INCLUDE_DIRS ${PCRE_INCLUDE_DIR}) -ELSE(PCRE_FOUND) - SET(PCRE_LIBRARIES) - SET(PCRE_INCLUDE_DIRS) -ENDIF(PCRE_FOUND) +if(PCRE_FOUND) + set(PCRE_LIBRARIES ${PCRE_LIBRARY} ${PCRE_POSIX_LIBRARY}) + set(PCRE_INCLUDE_DIRS ${PCRE_INCLUDE_DIR}) +else(PCRE_FOUND) + set(PCRE_LIBRARIES) + set(PCRE_INCLUDE_DIRS) +endif() -MARK_AS_ADVANCED(PCRE_INCLUDE_DIRS PCRE_LIBRARIES) +mark_as_advanced(PCRE_INCLUDE_DIRS PCRE_LIBRARIES) diff --git a/cmake/FindPCRE2.cmake b/cmake/FindPCRE2.cmake index f8c5639d57c..d4b8e676184 100644 --- a/cmake/FindPCRE2.cmake +++ b/cmake/FindPCRE2.cmake @@ -16,22 +16,22 @@ # PCRE2_FOUND - True if pcre found. # Look for the header file. -FIND_PATH(PCRE2_INCLUDE_DIR NAMES pcre2posix.h) +find_path(PCRE2_INCLUDE_DIR NAMES pcre2posix.h) # Look for the library. -FIND_LIBRARY(PCRE2_LIBRARY NAMES pcre2-8) +find_library(PCRE2_LIBRARY NAMES pcre2-8) # Handle the QUIETLY and REQUIRED arguments and set PCRE2_FOUND to TRUE if all listed variables are TRUE. -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE2 DEFAULT_MSG PCRE2_LIBRARY PCRE2_INCLUDE_DIR) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PCRE2 DEFAULT_MSG PCRE2_LIBRARY PCRE2_INCLUDE_DIR) # Copy the results to the output variables. -IF(PCRE2_FOUND) - SET(PCRE2_LIBRARIES ${PCRE2_LIBRARY}) - SET(PCRE2_INCLUDE_DIRS ${PCRE2_INCLUDE_DIR}) -ELSE(PCRE2_FOUND) - SET(PCRE2_LIBRARIES) - SET(PCRE2_INCLUDE_DIRS) -ENDIF(PCRE2_FOUND) +if(PCRE2_FOUND) + set(PCRE2_LIBRARIES ${PCRE2_LIBRARY}) + set(PCRE2_INCLUDE_DIRS ${PCRE2_INCLUDE_DIR}) +else(PCRE2_FOUND) + set(PCRE2_LIBRARIES) + set(PCRE2_INCLUDE_DIRS) +endif() -MARK_AS_ADVANCED(PCRE2_INCLUDE_DIRS PCRE2_LIBRARIES) +mark_as_advanced(PCRE2_INCLUDE_DIRS PCRE2_LIBRARIES) diff --git a/cmake/FindPkgLibraries.cmake b/cmake/FindPkgLibraries.cmake index 49311c382a8..220bb2ce21a 100644 --- a/cmake/FindPkgLibraries.cmake +++ b/cmake/FindPkgLibraries.cmake @@ -1,28 +1,28 @@ -INCLUDE(FindPkgConfig) +include(FindPkgConfig) # This function will find and set up a pkg-config based module. # If a pc-file was found, it will resolve library paths to # absolute paths. Furthermore, the function will automatically # fall back to use static libraries in case no dynamic libraries # were found. -FUNCTION(FIND_PKGLIBRARIES prefix package) - PKG_CHECK_MODULES(${prefix} ${package}) - IF(NOT ${prefix}_FOUND) - RETURN() - ENDIF() +function(FIND_PKGLIBRARIES prefix package) + pkg_check_modules(${prefix} ${package}) + if(NOT ${prefix}_FOUND) + return() + endif() - FOREACH(LIBRARY ${${prefix}_LIBRARIES}) - FIND_LIBRARY(${LIBRARY}_RESOLVED ${LIBRARY} PATHS ${${prefix}_LIBRARY_DIRS}) - IF(${${LIBRARY}_RESOLVED} STREQUAL "${LIBRARY}_RESOLVED-NOTFOUND") - MESSAGE(FATAL_ERROR "could not resolve ${LIBRARY}") - ENDIF() - LIST(APPEND RESOLVED_LIBRARIES ${${LIBRARY}_RESOLVED}) - ENDFOREACH(LIBRARY) + foreach(LIBRARY ${${prefix}_LIBRARIES}) + find_library(${LIBRARY}_RESOLVED ${LIBRARY} PATHS ${${prefix}_LIBRARY_DIRS}) + if(${${LIBRARY}_RESOLVED} STREQUAL "${LIBRARY}_RESOLVED-NOTFOUND") + message(FATAL_ERROR "could not resolve ${LIBRARY}") + endif() + list(APPEND RESOLVED_LIBRARIES ${${LIBRARY}_RESOLVED}) + endforeach() - SET(${prefix}_FOUND 1 PARENT_SCOPE) - SET(${prefix}_LIBRARIES ${RESOLVED_LIBRARIES} PARENT_SCOPE) - SET(${prefix}_INCLUDE_DIRS ${${prefix}_INCLUDE_DIRS} PARENT_SCOPE) - SET(${prefix}_LDFLAGS ${${prefix}_LDFLAGS} PARENT_SCOPE) + set(${prefix}_FOUND 1 PARENT_SCOPE) + set(${prefix}_LIBRARIES ${RESOLVED_LIBRARIES} PARENT_SCOPE) + set(${prefix}_INCLUDE_DIRS ${${prefix}_INCLUDE_DIRS} PARENT_SCOPE) + set(${prefix}_LDFLAGS ${${prefix}_LDFLAGS} PARENT_SCOPE) - MESSAGE(STATUS " Resolved libraries: ${RESOLVED_LIBRARIES}") -ENDFUNCTION() + message(STATUS " Resolved libraries: ${RESOLVED_LIBRARIES}") +endfunction() diff --git a/cmake/FindSecurity.cmake b/cmake/FindSecurity.cmake index a538c02c1ec..14a2e2dd7bb 100644 --- a/cmake/FindSecurity.cmake +++ b/cmake/FindSecurity.cmake @@ -7,22 +7,22 @@ # SECURITY_HAS_SSLCREATECONTEXT # -FIND_PATH(SECURITY_INCLUDE_DIR NAMES Security/Security.h) -FIND_LIBRARY(SECURITY_LIBRARIES NAMES Security) -IF (SECURITY_INCLUDE_DIR AND SECURITY_LIBRARIES) - IF (NOT Security_FIND_QUIETLY) - MESSAGE(STATUS "Found Security ${SECURITY_LIBRARIES}") - ENDIF() - SET(SECURITY_FOUND TRUE) - SET(SECURITY_LDFLAGS "-framework Security") - CHECK_LIBRARY_EXISTS("${SECURITY_LIBRARIES}" SSLCreateContext "Security/SecureTransport.h" SECURITY_HAS_SSLCREATECONTEXT) -ENDIF () +find_path(SECURITY_INCLUDE_DIR NAMES Security/Security.h) +find_library(SECURITY_LIBRARIES NAMES Security) +if(SECURITY_INCLUDE_DIR AND SECURITY_LIBRARIES) + if(NOT Security_FIND_QUIETLY) + message(STATUS "Found Security ${SECURITY_LIBRARIES}") + endif() + set(SECURITY_FOUND TRUE) + set(SECURITY_LDFLAGS "-framework Security") + check_library_exists("${SECURITY_LIBRARIES}" SSLCreateContext "Security/SecureTransport.h" SECURITY_HAS_SSLCREATECONTEXT) +endif() -IF (Security_FIND_REQUIRED AND NOT SECURITY_FOUND) - MESSAGE(FATAL_ERROR "Security not found") -ENDIF() +if(Security_FIND_REQUIRED AND NOT SECURITY_FOUND) + message(FATAL_ERROR "Security not found") +endif() -MARK_AS_ADVANCED( +mark_as_advanced( SECURITY_INCLUDE_DIR SECURITY_LIBRARIES ) diff --git a/cmake/Findfutimens.cmake b/cmake/Findfutimens.cmake index 73b79528ac6..3449c9d54e9 100644 --- a/cmake/Findfutimens.cmake +++ b/cmake/Findfutimens.cmake @@ -1,14 +1,14 @@ -INCLUDE(EnableWarnings) +include(EnableWarnings) -IF (APPLE) +if(APPLE) # We cannot simply CHECK_FUNCTION_EXISTS on macOS because # MACOSX_DEPLOYMENT_TARGET may be set to a version in the past # that doesn't have futimens. Instead we need to enable warnings # as errors, then check for the symbol existing in `sys/stat.h`, # then reset warnings as errors. - ENABLE_WARNINGS(error) - CHECK_SYMBOL_EXISTS(futimens sys/stat.h HAVE_FUTIMENS) - DISABLE_WARNINGS(error) -ELSE () - CHECK_FUNCTION_EXISTS(futimens HAVE_FUTIMENS) -ENDIF () + enable_warnings(error) + check_symbol_exists(futimens sys/stat.h HAVE_FUTIMENS) + disable_warnings(error) +else() + check_function_exists(futimens HAVE_FUTIMENS) +endif() diff --git a/cmake/FindmbedTLS.cmake b/cmake/FindmbedTLS.cmake index 93297555e81..a4a5487c296 100644 --- a/cmake/FindmbedTLS.cmake +++ b/cmake/FindmbedTLS.cmake @@ -13,81 +13,74 @@ # Hint # MBEDTLS_ROOT_DIR can be pointed to a local mbedTLS installation. -SET(_MBEDTLS_ROOT_HINTS - ${MBEDTLS_ROOT_DIR} - ENV MBEDTLS_ROOT_DIR -) +set(_MBEDTLS_ROOT_HINTS + ${MBEDTLS_ROOT_DIR} + ENV MBEDTLS_ROOT_DIR) -SET(_MBEDTLS_ROOT_HINTS_AND_PATHS - HINTS ${_MBEDTLS_ROOT_HINTS} - PATHS ${_MBEDTLS_ROOT_PATHS} -) +set(_MBEDTLS_ROOT_HINTS_AND_PATHS + HINTS ${_MBEDTLS_ROOT_HINTS} + PATHS ${_MBEDTLS_ROOT_PATHS}) -FIND_PATH(MBEDTLS_INCLUDE_DIR - NAMES mbedtls/version.h - ${_MBEDTLS_ROOT_HINTS_AND_PATHS} - PATH_SUFFIXES include -) +find_path(MBEDTLS_INCLUDE_DIR + NAMES mbedtls/version.h + ${_MBEDTLS_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES include) -IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES) - # Already in cache, be silent - SET(MBEDTLS_FIND_QUIETLY TRUE) -ENDIF() +if(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES) + # Already in cache, be silent + set(MBEDTLS_FIND_QUIETLY TRUE) +endif() -FIND_LIBRARY(MBEDTLS_LIBRARY - NAMES mbedtls libmbedtls - ${_MBEDTLS_ROOT_HINTS_AND_PATHS} - PATH_SUFFIXES library -) -FIND_LIBRARY(MBEDX509_LIBRARY - NAMES mbedx509 libmbedx509 - ${_MBEDTLS_ROOT_HINTS_AND_PATHS} - PATH_SUFFIXES library -) -FIND_LIBRARY(MBEDCRYPTO_LIBRARY - NAMES mbedcrypto libmbedcrypto - ${_MBEDTLS_ROOT_HINTS_AND_PATHS} - PATH_SUFFIXES library -) +find_library(MBEDTLS_LIBRARY + NAMES mbedtls libmbedtls + ${_MBEDTLS_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES library) +find_library(MBEDX509_LIBRARY + NAMES mbedx509 libmbedx509 + ${_MBEDTLS_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES library) +find_library(MBEDCRYPTO_LIBRARY + NAMES mbedcrypto libmbedcrypto + ${_MBEDTLS_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES library) -IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY) - SET(MBEDTLS_FOUND TRUE) -ENDIF() +if(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY) + set(MBEDTLS_FOUND TRUE) +endif() -IF(MBEDTLS_FOUND) - # split mbedTLS into -L and -l linker options, so we can set them for pkg-config - GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH) - GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE) - GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE) - GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE) - STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE}) - STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE}) - STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE}) - SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}") +if(MBEDTLS_FOUND) + # split mbedTLS into -L and -l linker options, so we can set them for pkg-config + get_filename_component(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH) + get_filename_component(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE) + get_filename_component(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE) + get_filename_component(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE) + string(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE}) + string(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE}) + string(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE}) + set(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}") - IF(NOT MBEDTLS_FIND_QUIETLY) - MESSAGE(STATUS "Found mbedTLS:") - FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT) - STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT}) - IF (MBEDTLSMATCH) - STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH}) - MESSAGE(STATUS " version ${MBEDTLS_VERSION}") - ENDIF(MBEDTLSMATCH) - MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}") - MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}") - MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}") - ENDIF(NOT MBEDTLS_FIND_QUIETLY) -ELSE(MBEDTLS_FOUND) - IF(MBEDTLS_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find mbedTLS") - ENDIF(MBEDTLS_FIND_REQUIRED) -ENDIF(MBEDTLS_FOUND) + if(NOT MBEDTLS_FIND_QUIETLY) + message(STATUS "Found mbedTLS:") + file(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT) + string(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT}) + if(MBEDTLSMATCH) + string(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH}) + message(STATUS " version ${MBEDTLS_VERSION}") + endif() + message(STATUS " TLS: ${MBEDTLS_LIBRARY}") + message(STATUS " X509: ${MBEDX509_LIBRARY}") + message(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}") + endif() +else(MBEDTLS_FOUND) + if(MBEDTLS_FIND_REQUIRED) + message(FATAL_ERROR "Could not find mbedTLS") + endif() +endif() -MARK_AS_ADVANCED( - MBEDTLS_INCLUDE_DIR - MBEDTLS_LIBRARY_DIR - MBEDTLS_LIBRARIES - MBEDTLS_LIBRARY - MBEDX509_LIBRARY - MBEDCRYPTO_LIBRARY -) +mark_as_advanced( + MBEDTLS_INCLUDE_DIR + MBEDTLS_LIBRARY_DIR + MBEDTLS_LIBRARIES + MBEDTLS_LIBRARY + MBEDX509_LIBRARY + MBEDCRYPTO_LIBRARY) diff --git a/cmake/IdeSplitSources.cmake b/cmake/IdeSplitSources.cmake index 396f18eb4a1..4a55d89b096 100644 --- a/cmake/IdeSplitSources.cmake +++ b/cmake/IdeSplitSources.cmake @@ -3,20 +3,20 @@ # Visual Studio, so that you can navigate into the libgit2_tests project, # and see the folders within the tests folder (instead of just seeing all # source and tests in a single folder.) -FUNCTION(IDE_SPLIT_SOURCES target) - IF(MSVC_IDE OR CMAKE_GENERATOR STREQUAL Xcode) - GET_TARGET_PROPERTY(sources ${target} SOURCES) - FOREACH(source ${sources}) - IF(source MATCHES ".*/") - STRING(REPLACE ${libgit2_SOURCE_DIR}/ "" rel ${source}) - IF(rel) - STRING(REGEX REPLACE "/([^/]*)$" "" rel ${rel}) - IF(rel) - STRING(REPLACE "/" "\\\\" rel ${rel}) - SOURCE_GROUP(${rel} FILES ${source}) - ENDIF() - ENDIF() - ENDIF() - ENDFOREACH() - ENDIF() -ENDFUNCTION() +function(IDE_SPLIT_SOURCES target) + if(MSVC_IDE OR CMAKE_GENERATOR STREQUAL Xcode) + get_target_property(sources ${target} SOURCES) + foreach(source ${sources}) + if(source MATCHES ".*/") + string(REPLACE ${libgit2_SOURCE_DIR}/ "" rel ${source}) + if(rel) + string(REGEX REPLACE "/([^/]*)$" "" rel ${rel}) + if(rel) + string(REPLACE "/" "\\\\" rel ${rel}) + source_group(${rel} FILES ${source}) + endif() + endif() + endif() + endforeach() + endif() +endfunction() diff --git a/cmake/PkgBuildConfig.cmake b/cmake/PkgBuildConfig.cmake index 54c5e294cc7..c8939e63a2e 100644 --- a/cmake/PkgBuildConfig.cmake +++ b/cmake/PkgBuildConfig.cmake @@ -2,76 +2,76 @@ # function(pkg_build_config) - set(options) - set(oneValueArgs NAME DESCRIPTION VERSION FILENAME LIBS_SELF) - set(multiValueArgs LIBS PRIVATE_LIBS REQUIRES CFLAGS) + set(options) + set(oneValueArgs NAME DESCRIPTION VERSION FILENAME LIBS_SELF) + set(multiValueArgs LIBS PRIVATE_LIBS REQUIRES CFLAGS) - cmake_parse_arguments(PKGCONFIG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + cmake_parse_arguments(PKGCONFIG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - if (NOT DEFINED PKGCONFIG_FILENAME AND DEFINED PKGCONFIG_NAME) - set(PKGCONFIG_FILENAME ${PKGCONFIG_NAME}) - endif() - if (NOT DEFINED PKGCONFIG_FILENAME) - message(FATAL_ERROR "Missing FILENAME argument") - endif() - set(PKGCONFIG_FILE "${PROJECT_BINARY_DIR}/${PKGCONFIG_FILENAME}.pc") + if (NOT DEFINED PKGCONFIG_FILENAME AND DEFINED PKGCONFIG_NAME) + set(PKGCONFIG_FILENAME ${PKGCONFIG_NAME}) + endif() + if (NOT DEFINED PKGCONFIG_FILENAME) + message(FATAL_ERROR "Missing FILENAME argument") + endif() + set(PKGCONFIG_FILE "${PROJECT_BINARY_DIR}/${PKGCONFIG_FILENAME}.pc") - if (NOT DEFINED PKGCONFIG_DESCRIPTION) - message(FATAL_ERROR "Missing DESCRIPTION argument") - endif() + if (NOT DEFINED PKGCONFIG_DESCRIPTION) + message(FATAL_ERROR "Missing DESCRIPTION argument") + endif() - if (NOT DEFINED PKGCONFIG_VERSION) - message(FATAL_ERROR "Missing VERSION argument") - endif() + if (NOT DEFINED PKGCONFIG_VERSION) + message(FATAL_ERROR "Missing VERSION argument") + endif() - # Write .pc "header" - file(WRITE "${PKGCONFIG_FILE}" - "prefix=\"${CMAKE_INSTALL_PREFIX}\"\n" - "libdir=\"${CMAKE_INSTALL_FULL_LIBDIR}\"\n" - "includedir=\"${CMAKE_INSTALL_FULL_INCLUDEDIR}\"\n" - "\n" - "Name: ${PKGCONFIG_NAME}\n" - "Description: ${PKGCONFIG_DESCRIPTION}\n" - "Version: ${PKGCONFIG_VERSION}\n" - ) + # Write .pc "header" + file(WRITE "${PKGCONFIG_FILE}" + "prefix=\"${CMAKE_INSTALL_PREFIX}\"\n" + "libdir=\"${CMAKE_INSTALL_FULL_LIBDIR}\"\n" + "includedir=\"${CMAKE_INSTALL_FULL_INCLUDEDIR}\"\n" + "\n" + "Name: ${PKGCONFIG_NAME}\n" + "Description: ${PKGCONFIG_DESCRIPTION}\n" + "Version: ${PKGCONFIG_VERSION}\n" + ) - # Prepare Libs - if(NOT DEFINED PKGCONFIG_LIBS_SELF) - set(PKGCONFIG_LIBS_SELF "${PKGCONFIG_FILE}") - endif() + # Prepare Libs + if(NOT DEFINED PKGCONFIG_LIBS_SELF) + set(PKGCONFIG_LIBS_SELF "${PKGCONFIG_FILE}") + endif() - if(NOT DEFINED PKGCONFIG_LIBS) - set(PKGCONFIG_LIBS "-l${PKGCONFIG_LIBS_SELF}") - else() - list(INSERT PKGCONFIG_LIBS 0 "-l${PKGCONFIG_LIBS_SELF}") - endif() + if(NOT DEFINED PKGCONFIG_LIBS) + set(PKGCONFIG_LIBS "-l${PKGCONFIG_LIBS_SELF}") + else() + list(INSERT PKGCONFIG_LIBS 0 "-l${PKGCONFIG_LIBS_SELF}") + endif() - list(REMOVE_DUPLICATES PKGCONFIG_LIBS) - string(REPLACE ";" " " PKGCONFIG_LIBS "${PKGCONFIG_LIBS}") - file(APPEND "${PKGCONFIG_FILE}" "Libs: -L\${libdir} ${PKGCONFIG_LIBS}\n") + list(REMOVE_DUPLICATES PKGCONFIG_LIBS) + string(REPLACE ";" " " PKGCONFIG_LIBS "${PKGCONFIG_LIBS}") + file(APPEND "${PKGCONFIG_FILE}" "Libs: -L\${libdir} ${PKGCONFIG_LIBS}\n") - # Prepare Libs.private - if(DEFINED PKGCONFIG_PRIVATE_LIBS) - list(REMOVE_DUPLICATES PKGCONFIG_PRIVATE_LIBS) - string(REPLACE ";" " " PKGCONFIG_PRIVATE_LIBS "${PKGCONFIG_PRIVATE_LIBS}") - file(APPEND "${PKGCONFIG_FILE}" "Libs.private: ${PKGCONFIG_PRIVATE_LIBS}\n") - endif() + # Prepare Libs.private + if(DEFINED PKGCONFIG_PRIVATE_LIBS) + list(REMOVE_DUPLICATES PKGCONFIG_PRIVATE_LIBS) + string(REPLACE ";" " " PKGCONFIG_PRIVATE_LIBS "${PKGCONFIG_PRIVATE_LIBS}") + file(APPEND "${PKGCONFIG_FILE}" "Libs.private: ${PKGCONFIG_PRIVATE_LIBS}\n") + endif() - # Prepare Requires.private - if(DEFINED PKGCONFIG_REQUIRES) - list(REMOVE_DUPLICATES PKGCONFIG_REQUIRES) - string(REPLACE ";" " " PKGCONFIG_REQUIRES "${PKGCONFIG_REQUIRES}") - file(APPEND "${PKGCONFIG_FILE}" "Requires.private: ${PKGCONFIG_REQUIRES}\n") - endif() + # Prepare Requires.private + if(DEFINED PKGCONFIG_REQUIRES) + list(REMOVE_DUPLICATES PKGCONFIG_REQUIRES) + string(REPLACE ";" " " PKGCONFIG_REQUIRES "${PKGCONFIG_REQUIRES}") + file(APPEND "${PKGCONFIG_FILE}" "Requires.private: ${PKGCONFIG_REQUIRES}\n") + endif() - # Prepare Cflags - if(DEFINED PKGCONFIG_CFLAGS) - string(REPLACE ";" " " PKGCONFIG_CFLAGS "${PKGCONFIG_CFLAGS}") - else() - set(PKGCONFIG_CFLAGS "") - endif() - file(APPEND "${PKGCONFIG_FILE}" "Cflags: -I\${includedir} ${PKGCONFIG_CFLAGS}\n") + # Prepare Cflags + if(DEFINED PKGCONFIG_CFLAGS) + string(REPLACE ";" " " PKGCONFIG_CFLAGS "${PKGCONFIG_CFLAGS}") + else() + set(PKGCONFIG_CFLAGS "") + endif() + file(APPEND "${PKGCONFIG_FILE}" "Cflags: -I\${includedir} ${PKGCONFIG_CFLAGS}\n") - # Install .pc file - install(FILES "${PKGCONFIG_FILE}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + # Install .pc file + install(FILES "${PKGCONFIG_FILE}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") endfunction() diff --git a/cmake/SanitizeBool.cmake b/cmake/SanitizeBool.cmake index b5b99a69047..586c17d0528 100644 --- a/cmake/SanitizeBool.cmake +++ b/cmake/SanitizeBool.cmake @@ -1,20 +1,20 @@ -FUNCTION(SanitizeBool VAR) - STRING(TOLOWER "${${VAR}}" VALUE) - IF(VALUE STREQUAL "on") - SET(${VAR} "ON" PARENT_SCOPE) - ELSEIF(VALUE STREQUAL "yes") - SET(${VAR} "ON" PARENT_SCOPE) - ELSEIF(VALUE STREQUAL "true") - SET(${VAR} "ON" PARENT_SCOPE) - ELSEIF(VALUE STREQUAL "1") - SET(${VAR} "ON" PARENT_SCOPE) - ELSEIF(VALUE STREQUAL "off") - SET(${VAR} "OFF" PARENT_SCOPE) - ELSEIF(VALUE STREQUAL "no") - SET(${VAR} "OFF" PARENT_SCOPE) - ELSEIF(VALUE STREQUAL "false") - SET(${VAR} "OFF" PARENT_SCOPE) - ELSEIF(VALUE STREQUAL "0") - SET(${VAR} "OFF" PARENT_SCOPE) - ENDIF() -ENDFUNCTION() +function(SanitizeBool VAR) + string(TOLOWER "${${VAR}}" VALUE) + if(VALUE STREQUAL "on") + set(${VAR} "ON" PARENT_SCOPE) + elseif(VALUE STREQUAL "yes") + set(${VAR} "ON" PARENT_SCOPE) + elseif(VALUE STREQUAL "true") + set(${VAR} "ON" PARENT_SCOPE) + elseif(VALUE STREQUAL "1") + set(${VAR} "ON" PARENT_SCOPE) + elseif(VALUE STREQUAL "off") + set(${VAR} "OFF" PARENT_SCOPE) + elseif(VALUE STREQUAL "no") + set(${VAR} "OFF" PARENT_SCOPE) + elseif(VALUE STREQUAL "false") + set(${VAR} "OFF" PARENT_SCOPE) + elseif(VALUE STREQUAL "0") + set(${VAR} "OFF" PARENT_SCOPE) + endif() +endfunction() diff --git a/cmake/SelectGSSAPI.cmake b/cmake/SelectGSSAPI.cmake index 0a42eeefdfd..e9c5c75c138 100644 --- a/cmake/SelectGSSAPI.cmake +++ b/cmake/SelectGSSAPI.cmake @@ -1,48 +1,48 @@ -INCLUDE(SanitizeBool) +include(SanitizeBool) # We try to find any packages our backends might use -FIND_PACKAGE(GSSAPI) -IF (CMAKE_SYSTEM_NAME MATCHES "Darwin") - INCLUDE(FindGSSFramework) -ENDIF() +find_package(GSSAPI) +if(CMAKE_SYSTEM_NAME MATCHES "Darwin") + include(FindGSSFramework) +endif() -IF(USE_GSSAPI) +if(USE_GSSAPI) # Auto-select GSS backend - SanitizeBool(USE_GSSAPI) - IF (USE_GSSAPI STREQUAL ON) - IF (GSSFRAMEWORK_FOUND) - SET(USE_GSSAPI "GSS.framework") - ELSEIF(GSSAPI_FOUND) - SET(USE_GSSAPI "gssapi") - ELSE() - MESSAGE(FATAL_ERROR "Unable to autodetect a usable GSS backend." + sanitizebool(USE_GSSAPI) + if(USE_GSSAPI STREQUAL ON) + if(GSSFRAMEWORK_FOUND) + set(USE_GSSAPI "GSS.framework") + elseif(GSSAPI_FOUND) + set(USE_GSSAPI "gssapi") + else() + message(FATAL_ERROR "Unable to autodetect a usable GSS backend." "Please pass the backend name explicitly (-DUSE_GSS=backend)") - ENDIF() - ENDIF() + endif() + endif() # Check that we can find what's required for the selected backend - IF (USE_GSSAPI STREQUAL "GSS.framework") - IF (NOT GSSFRAMEWORK_FOUND) - MESSAGE(FATAL_ERROR "Asked for GSS.framework backend, but it wasn't found") - ENDIF() + if(USE_GSSAPI STREQUAL "GSS.framework") + if(NOT GSSFRAMEWORK_FOUND) + message(FATAL_ERROR "Asked for GSS.framework backend, but it wasn't found") + endif() - LIST(APPEND LIBGIT2_LIBS ${GSSFRAMEWORK_LIBRARIES}) + list(APPEND LIBGIT2_LIBS ${GSSFRAMEWORK_LIBRARIES}) - SET(GIT_GSSFRAMEWORK 1) - ADD_FEATURE_INFO(SPNEGO GIT_GSSFRAMEWORK "SPNEGO authentication support (${USE_GSSAPI})") - ELSEIF (USE_GSSAPI STREQUAL "gssapi") - IF (NOT GSSAPI_FOUND) - MESSAGE(FATAL_ERROR "Asked for gssapi GSS backend, but it wasn't found") - ENDIF() + set(GIT_GSSFRAMEWORK 1) + add_feature_info(SPNEGO GIT_GSSFRAMEWORK "SPNEGO authentication support (${USE_GSSAPI})") + elseif(USE_GSSAPI STREQUAL "gssapi") + if(NOT GSSAPI_FOUND) + message(FATAL_ERROR "Asked for gssapi GSS backend, but it wasn't found") + endif() - LIST(APPEND LIBGIT2_LIBS ${GSSAPI_LIBRARIES}) + list(APPEND LIBGIT2_LIBS ${GSSAPI_LIBRARIES}) - SET(GIT_GSSAPI 1) - ADD_FEATURE_INFO(SPNEGO GIT_GSSAPI "SPNEGO authentication support (${USE_GSSAPI})") - ELSE() - MESSAGE(FATAL_ERROR "Asked for backend ${USE_GSSAPI} but it wasn't found") - ENDIF() -ELSE() - SET(GIT_GSSAPI 0) - ADD_FEATURE_INFO(SPNEGO NO "SPNEGO authentication support") -ENDIF() + set(GIT_GSSAPI 1) + add_feature_info(SPNEGO GIT_GSSAPI "SPNEGO authentication support (${USE_GSSAPI})") + else() + message(FATAL_ERROR "Asked for backend ${USE_GSSAPI} but it wasn't found") + endif() +else() + set(GIT_GSSAPI 0) + add_feature_info(SPNEGO NO "SPNEGO authentication support") +endif() diff --git a/cmake/SelectHTTPSBackend.cmake b/cmake/SelectHTTPSBackend.cmake index 4af747417bf..1c6bd6a59a5 100644 --- a/cmake/SelectHTTPSBackend.cmake +++ b/cmake/SelectHTTPSBackend.cmake @@ -1,124 +1,124 @@ -INCLUDE(SanitizeBool) +include(SanitizeBool) # We try to find any packages our backends might use -FIND_PACKAGE(OpenSSL) -FIND_PACKAGE(mbedTLS) -IF (CMAKE_SYSTEM_NAME MATCHES "Darwin") - FIND_PACKAGE(Security) - FIND_PACKAGE(CoreFoundation) -ENDIF() +find_package(OpenSSL) +find_package(mbedTLS) +if(CMAKE_SYSTEM_NAME MATCHES "Darwin") + find_package(Security) + find_package(CoreFoundation) +endif() -IF(USE_HTTPS) +if(USE_HTTPS) # Auto-select TLS backend - SanitizeBool(USE_HTTPS) - IF (USE_HTTPS STREQUAL ON) - IF (SECURITY_FOUND) - IF (SECURITY_HAS_SSLCREATECONTEXT) - SET(USE_HTTPS "SecureTransport") - ELSE() - MESSAGE(STATUS "Security framework is too old, falling back to OpenSSL") - SET(USE_HTTPS "OpenSSL") - ENDIF() - ELSEIF (USE_WINHTTP) - SET(USE_HTTPS "WinHTTP") - ELSEIF(OPENSSL_FOUND) - SET(USE_HTTPS "OpenSSL") - ELSEIF(MBEDTLS_FOUND) - SET(USE_HTTPS "mbedTLS") - ELSE() - MESSAGE(FATAL_ERROR "Unable to autodetect a usable HTTPS backend." + sanitizebool(USE_HTTPS) + if(USE_HTTPS STREQUAL ON) + if(SECURITY_FOUND) + if(SECURITY_HAS_SSLCREATECONTEXT) + set(USE_HTTPS "SecureTransport") + else() + message(STATUS "Security framework is too old, falling back to OpenSSL") + set(USE_HTTPS "OpenSSL") + endif() + elseif(USE_WINHTTP) + set(USE_HTTPS "WinHTTP") + elseif(OPENSSL_FOUND) + set(USE_HTTPS "OpenSSL") + elseif(MBEDTLS_FOUND) + set(USE_HTTPS "mbedTLS") + else() + message(FATAL_ERROR "Unable to autodetect a usable HTTPS backend." "Please pass the backend name explicitly (-DUSE_HTTPS=backend)") - ENDIF() - ENDIF() + endif() + endif() # Check that we can find what's required for the selected backend - IF (USE_HTTPS STREQUAL "SecureTransport") - IF (NOT COREFOUNDATION_FOUND) - MESSAGE(FATAL_ERROR "Cannot use SecureTransport backend, CoreFoundation.framework not found") - ENDIF() - IF (NOT SECURITY_FOUND) - MESSAGE(FATAL_ERROR "Cannot use SecureTransport backend, Security.framework not found") - ENDIF() - IF (NOT SECURITY_HAS_SSLCREATECONTEXT) - MESSAGE(FATAL_ERROR "Cannot use SecureTransport backend, SSLCreateContext not supported") - ENDIF() + if(USE_HTTPS STREQUAL "SecureTransport") + if(NOT COREFOUNDATION_FOUND) + message(FATAL_ERROR "Cannot use SecureTransport backend, CoreFoundation.framework not found") + endif() + if(NOT SECURITY_FOUND) + message(FATAL_ERROR "Cannot use SecureTransport backend, Security.framework not found") + endif() + if(NOT SECURITY_HAS_SSLCREATECONTEXT) + message(FATAL_ERROR "Cannot use SecureTransport backend, SSLCreateContext not supported") + endif() - SET(GIT_SECURE_TRANSPORT 1) - LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${SECURITY_INCLUDE_DIR}) - LIST(APPEND LIBGIT2_LIBS ${COREFOUNDATION_LDFLAGS} ${SECURITY_LDFLAGS}) - LIST(APPEND LIBGIT2_PC_LIBS ${COREFOUNDATION_LDFLAGS} ${SECURITY_LDFLAGS}) - ELSEIF (USE_HTTPS STREQUAL "OpenSSL") - IF (NOT OPENSSL_FOUND) - MESSAGE(FATAL_ERROR "Asked for OpenSSL TLS backend, but it wasn't found") - ENDIF() + set(GIT_SECURE_TRANSPORT 1) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${SECURITY_INCLUDE_DIR}) + list(APPEND LIBGIT2_LIBS ${COREFOUNDATION_LDFLAGS} ${SECURITY_LDFLAGS}) + list(APPEND LIBGIT2_PC_LIBS ${COREFOUNDATION_LDFLAGS} ${SECURITY_LDFLAGS}) + elseif(USE_HTTPS STREQUAL "OpenSSL") + if(NOT OPENSSL_FOUND) + message(FATAL_ERROR "Asked for OpenSSL TLS backend, but it wasn't found") + endif() - SET(GIT_OPENSSL 1) - LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${OPENSSL_INCLUDE_DIR}) - LIST(APPEND LIBGIT2_LIBS ${OPENSSL_LIBRARIES}) - LIST(APPEND LIBGIT2_PC_LIBS ${OPENSSL_LDFLAGS}) - LIST(APPEND LIBGIT2_PC_REQUIRES "openssl") - ELSEIF(USE_HTTPS STREQUAL "mbedTLS") - IF (NOT MBEDTLS_FOUND) - MESSAGE(FATAL_ERROR "Asked for mbedTLS backend, but it wasn't found") - ENDIF() + set(GIT_OPENSSL 1) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${OPENSSL_INCLUDE_DIR}) + list(APPEND LIBGIT2_LIBS ${OPENSSL_LIBRARIES}) + list(APPEND LIBGIT2_PC_LIBS ${OPENSSL_LDFLAGS}) + list(APPEND LIBGIT2_PC_REQUIRES "openssl") + elseif(USE_HTTPS STREQUAL "mbedTLS") + if(NOT MBEDTLS_FOUND) + message(FATAL_ERROR "Asked for mbedTLS backend, but it wasn't found") + endif() - IF(NOT CERT_LOCATION) - MESSAGE(STATUS "Auto-detecting default certificates location") - IF(CMAKE_SYSTEM_NAME MATCHES Darwin) + if(NOT CERT_LOCATION) + message(STATUS "Auto-detecting default certificates location") + if(CMAKE_SYSTEM_NAME MATCHES Darwin) # Check for an Homebrew installation - SET(OPENSSL_CMD "/usr/local/opt/openssl/bin/openssl") - ELSE() - SET(OPENSSL_CMD "openssl") - ENDIF() - EXECUTE_PROCESS(COMMAND ${OPENSSL_CMD} version -d OUTPUT_VARIABLE OPENSSL_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) - IF(OPENSSL_DIR) - STRING(REGEX REPLACE "^OPENSSLDIR: \"(.*)\"$" "\\1/" OPENSSL_DIR ${OPENSSL_DIR}) + set(OPENSSL_CMD "/usr/local/opt/openssl/bin/openssl") + else() + set(OPENSSL_CMD "openssl") + endif() + execute_process(COMMAND ${OPENSSL_CMD} version -d OUTPUT_VARIABLE OPENSSL_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) + if(OPENSSL_DIR) + string(REGEX REPLACE "^OPENSSLDIR: \"(.*)\"$" "\\1/" OPENSSL_DIR ${OPENSSL_DIR}) - SET(OPENSSL_CA_LOCATIONS + set(OPENSSL_CA_LOCATIONS "ca-bundle.pem" # OpenSUSE Leap 42.1 "cert.pem" # Ubuntu 14.04, FreeBSD "certs/ca-certificates.crt" # Ubuntu 16.04 "certs/ca.pem" # Debian 7 ) - FOREACH(SUFFIX IN LISTS OPENSSL_CA_LOCATIONS) - SET(LOC "${OPENSSL_DIR}${SUFFIX}") - IF(NOT CERT_LOCATION AND EXISTS "${OPENSSL_DIR}${SUFFIX}") - SET(CERT_LOCATION ${LOC}) - ENDIF() - ENDFOREACH() - ELSE() - MESSAGE(FATAL_ERROR "Unable to find OpenSSL executable. Please provide default certificate location via CERT_LOCATION") - ENDIF() - ENDIF() + foreach(SUFFIX IN LISTS OPENSSL_CA_LOCATIONS) + set(LOC "${OPENSSL_DIR}${SUFFIX}") + if(NOT CERT_LOCATION AND EXISTS "${OPENSSL_DIR}${SUFFIX}") + set(CERT_LOCATION ${LOC}) + endif() + endforeach() + else() + message(FATAL_ERROR "Unable to find OpenSSL executable. Please provide default certificate location via CERT_LOCATION") + endif() + endif() - IF(CERT_LOCATION) - IF(NOT EXISTS ${CERT_LOCATION}) - MESSAGE(FATAL_ERROR "Cannot use CERT_LOCATION=${CERT_LOCATION} as it doesn't exist") - ENDIF() - ADD_FEATURE_INFO(CERT_LOCATION ON "using certificates from ${CERT_LOCATION}") - ADD_DEFINITIONS(-DGIT_DEFAULT_CERT_LOCATION="${CERT_LOCATION}") - ENDIF() + if(CERT_LOCATION) + if(NOT EXISTS ${CERT_LOCATION}) + message(FATAL_ERROR "Cannot use CERT_LOCATION=${CERT_LOCATION} as it doesn't exist") + endif() + add_feature_info(CERT_LOCATION ON "using certificates from ${CERT_LOCATION}") + add_definitions(-DGIT_DEFAULT_CERT_LOCATION="${CERT_LOCATION}") + endif() - SET(GIT_MBEDTLS 1) - LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${MBEDTLS_INCLUDE_DIR}) - LIST(APPEND LIBGIT2_LIBS ${MBEDTLS_LIBRARIES}) + set(GIT_MBEDTLS 1) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${MBEDTLS_INCLUDE_DIR}) + list(APPEND LIBGIT2_LIBS ${MBEDTLS_LIBRARIES}) # mbedTLS has no pkgconfig file, hence we can't require it # https://github.com/ARMmbed/mbedtls/issues/228 # For now, pass its link flags as our own - LIST(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LIBRARIES}) - ELSEIF (USE_HTTPS STREQUAL "WinHTTP") + list(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LIBRARIES}) + elseif(USE_HTTPS STREQUAL "WinHTTP") # WinHTTP setup was handled in the WinHTTP-specific block above - ELSEIF (USE_HTTPS STREQUAL "OpenSSL-Dynamic") - SET(GIT_OPENSSL 1) - SET(GIT_OPENSSL_DYNAMIC 1) - LIST(APPEND LIBGIT2_LIBS dl) - ELSE() - MESSAGE(FATAL_ERROR "Asked for backend ${USE_HTTPS} but it wasn't found") - ENDIF() + elseif(USE_HTTPS STREQUAL "OpenSSL-Dynamic") + set(GIT_OPENSSL 1) + set(GIT_OPENSSL_DYNAMIC 1) + list(APPEND LIBGIT2_LIBS dl) + else() + message(FATAL_ERROR "Asked for backend ${USE_HTTPS} but it wasn't found") + endif() - SET(GIT_HTTPS 1) - ADD_FEATURE_INFO(HTTPS GIT_HTTPS "using ${USE_HTTPS}") -ELSE() - SET(GIT_HTTPS 0) - ADD_FEATURE_INFO(HTTPS NO "") -ENDIF() + set(GIT_HTTPS 1) + add_feature_info(HTTPS GIT_HTTPS "using ${USE_HTTPS}") +else() + set(GIT_HTTPS 0) + add_feature_info(HTTPS NO "") +endif() diff --git a/cmake/SelectHashes.cmake b/cmake/SelectHashes.cmake index 092cdfd051a..fee8b29022c 100644 --- a/cmake/SelectHashes.cmake +++ b/cmake/SelectHashes.cmake @@ -1,62 +1,62 @@ # Select a hash backend -INCLUDE(SanitizeBool) +include(SanitizeBool) # USE_SHA1=CollisionDetection(ON)/HTTPS/Generic/OFF -SanitizeBool(USE_SHA1) -IF(USE_SHA1 STREQUAL ON) - SET(USE_SHA1 "CollisionDetection") -ELSEIF(USE_SHA1 STREQUAL "HTTPS") - IF(USE_HTTPS STREQUAL "SecureTransport") - SET(USE_SHA1 "CommonCrypto") - ELSEIF(USE_HTTPS STREQUAL "WinHTTP") - SET(USE_SHA1 "Win32") - ELSEIF(USE_HTTPS) - SET(USE_SHA1 ${USE_HTTPS}) - ELSE() - SET(USE_SHA1 "CollisionDetection") - ENDIF() -ENDIF() +sanitizebool(USE_SHA1) +if(USE_SHA1 STREQUAL ON) + set(USE_SHA1 "CollisionDetection") +elseif(USE_SHA1 STREQUAL "HTTPS") + if(USE_HTTPS STREQUAL "SecureTransport") + set(USE_SHA1 "CommonCrypto") + elseif(USE_HTTPS STREQUAL "WinHTTP") + set(USE_SHA1 "Win32") + elseif(USE_HTTPS) + set(USE_SHA1 ${USE_HTTPS}) + else() + set(USE_SHA1 "CollisionDetection") + endif() +endif() -IF(USE_SHA1 STREQUAL "CollisionDetection") - SET(GIT_SHA1_COLLISIONDETECT 1) - ADD_DEFINITIONS(-DSHA1DC_NO_STANDARD_INCLUDES=1) - ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_SHA1_C=\"common.h\") - ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"common.h\") - FILE(GLOB SRC_SHA1 hash/sha1/collisiondetect.* hash/sha1/sha1dc/*) -ELSEIF(USE_SHA1 STREQUAL "OpenSSL") +if(USE_SHA1 STREQUAL "CollisionDetection") + set(GIT_SHA1_COLLISIONDETECT 1) + add_definitions(-DSHA1DC_NO_STANDARD_INCLUDES=1) + add_definitions(-DSHA1DC_CUSTOM_INCLUDE_SHA1_C=\"common.h\") + add_definitions(-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"common.h\") + file(GLOB SRC_SHA1 hash/sha1/collisiondetect.* hash/sha1/sha1dc/*) +elseif(USE_SHA1 STREQUAL "OpenSSL") # OPENSSL_FOUND should already be set, we're checking USE_HTTPS - SET(GIT_SHA1_OPENSSL 1) - IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - LIST(APPEND LIBGIT2_PC_LIBS "-lssl") - ELSE() - LIST(APPEND LIBGIT2_PC_REQUIRES "openssl") - ENDIF() - FILE(GLOB SRC_SHA1 hash/sha1/openssl.*) -ELSEIF(USE_SHA1 STREQUAL "CommonCrypto") - SET(GIT_SHA1_COMMON_CRYPTO 1) - FILE(GLOB SRC_SHA1 hash/sha1/common_crypto.*) -ELSEIF(USE_SHA1 STREQUAL "mbedTLS") - SET(GIT_SHA1_MBEDTLS 1) - FILE(GLOB SRC_SHA1 hash/sha1/mbedtls.*) - LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${MBEDTLS_INCLUDE_DIR}) - LIST(APPEND LIBGIT2_LIBS ${MBEDTLS_LIBRARIES}) + set(GIT_SHA1_OPENSSL 1) + if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + list(APPEND LIBGIT2_PC_LIBS "-lssl") + else() + list(APPEND LIBGIT2_PC_REQUIRES "openssl") + endif() + file(GLOB SRC_SHA1 hash/sha1/openssl.*) +elseif(USE_SHA1 STREQUAL "CommonCrypto") + set(GIT_SHA1_COMMON_CRYPTO 1) + file(GLOB SRC_SHA1 hash/sha1/common_crypto.*) +elseif(USE_SHA1 STREQUAL "mbedTLS") + set(GIT_SHA1_MBEDTLS 1) + file(GLOB SRC_SHA1 hash/sha1/mbedtls.*) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${MBEDTLS_INCLUDE_DIR}) + list(APPEND LIBGIT2_LIBS ${MBEDTLS_LIBRARIES}) # mbedTLS has no pkgconfig file, hence we can't require it # https://github.com/ARMmbed/mbedtls/issues/228 # For now, pass its link flags as our own - LIST(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LIBRARIES}) -ELSEIF(USE_SHA1 STREQUAL "Win32") - SET(GIT_SHA1_WIN32 1) - FILE(GLOB SRC_SHA1 hash/sha1/win32.*) -ELSEIF(USE_SHA1 STREQUAL "Generic") - FILE(GLOB SRC_SHA1 hash/sha1/generic.*) -ELSE() - MESSAGE(FATAL_ERROR "Asked for unknown SHA1 backend: ${USE_SHA1}") -ENDIF() + list(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LIBRARIES}) +elseif(USE_SHA1 STREQUAL "Win32") + set(GIT_SHA1_WIN32 1) + file(GLOB SRC_SHA1 hash/sha1/win32.*) +elseif(USE_SHA1 STREQUAL "Generic") + file(GLOB SRC_SHA1 hash/sha1/generic.*) +else() + message(FATAL_ERROR "Asked for unknown SHA1 backend: ${USE_SHA1}") +endif() list(APPEND SRC_SHA1 "hash/sha1.h") list(SORT SRC_SHA1) -ADD_FEATURE_INFO(SHA ON "using ${USE_SHA1}") +add_feature_info(SHA ON "using ${USE_SHA1}") From 395b3dc403621f1ab3c400780b057cae91c6f6c1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 22:10:51 -0500 Subject: [PATCH 0644/1616] cmake: refactor global variables Update the global variables `LIBGIT2_OBJECTS` to `LIBGIT2_DEPENDENCY_OBJECTS` for clarity and consistency. --- cmake/SelectGSSAPI.cmake | 4 ++-- cmake/SelectHTTPParser.cmake | 6 +++--- cmake/SelectHTTPSBackend.cmake | 8 ++++---- cmake/SelectHashes.cmake | 4 ++-- cmake/SelectRegex.cmake | 8 ++++---- cmake/SelectSSH.cmake | 6 +++--- cmake/SelectWinHTTP.cmake | 6 +++--- cmake/SelectZlib.cmake | 10 +++++----- examples/CMakeLists.txt | 9 +++++---- fuzzers/CMakeLists.txt | 14 +++++++------- src/CMakeLists.txt | 30 +++++++++++++++--------------- tests/CMakeLists.txt | 12 +++++------- 12 files changed, 58 insertions(+), 59 deletions(-) diff --git a/cmake/SelectGSSAPI.cmake b/cmake/SelectGSSAPI.cmake index e9c5c75c138..24e2d68b9a7 100644 --- a/cmake/SelectGSSAPI.cmake +++ b/cmake/SelectGSSAPI.cmake @@ -26,7 +26,7 @@ if(USE_GSSAPI) message(FATAL_ERROR "Asked for GSS.framework backend, but it wasn't found") endif() - list(APPEND LIBGIT2_LIBS ${GSSFRAMEWORK_LIBRARIES}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${GSSFRAMEWORK_LIBRARIES}) set(GIT_GSSFRAMEWORK 1) add_feature_info(SPNEGO GIT_GSSFRAMEWORK "SPNEGO authentication support (${USE_GSSAPI})") @@ -35,7 +35,7 @@ if(USE_GSSAPI) message(FATAL_ERROR "Asked for gssapi GSS backend, but it wasn't found") endif() - list(APPEND LIBGIT2_LIBS ${GSSAPI_LIBRARIES}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${GSSAPI_LIBRARIES}) set(GIT_GSSAPI 1) add_feature_info(SPNEGO GIT_GSSAPI "SPNEGO authentication support (${USE_GSSAPI})") diff --git a/cmake/SelectHTTPParser.cmake b/cmake/SelectHTTPParser.cmake index a1724a7c4c3..721f7fa9f1a 100644 --- a/cmake/SelectHTTPParser.cmake +++ b/cmake/SelectHTTPParser.cmake @@ -4,7 +4,7 @@ if(USE_HTTP_PARSER STREQUAL "system") if(HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${HTTP_PARSER_INCLUDE_DIRS}) - list(APPEND LIBGIT2_LIBS ${HTTP_PARSER_LIBRARIES}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${HTTP_PARSER_LIBRARIES}) list(APPEND LIBGIT2_PC_LIBS "-lhttp_parser") add_feature_info(http-parser ON "http-parser support (system)") else() @@ -13,7 +13,7 @@ if(USE_HTTP_PARSER STREQUAL "system") else() message(STATUS "http-parser version 2 was not found or disabled; using bundled 3rd-party sources.") add_subdirectory("${libgit2_SOURCE_DIR}/deps/http-parser" "${libgit2_BINARY_DIR}/deps/http-parser") - list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/http-parser") - list(APPEND LIBGIT2_OBJECTS "$") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/http-parser") + list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") add_feature_info(http-parser ON "http-parser support (bundled)") endif() diff --git a/cmake/SelectHTTPSBackend.cmake b/cmake/SelectHTTPSBackend.cmake index 1c6bd6a59a5..79319502eb3 100644 --- a/cmake/SelectHTTPSBackend.cmake +++ b/cmake/SelectHTTPSBackend.cmake @@ -45,7 +45,7 @@ if(USE_HTTPS) set(GIT_SECURE_TRANSPORT 1) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${SECURITY_INCLUDE_DIR}) - list(APPEND LIBGIT2_LIBS ${COREFOUNDATION_LDFLAGS} ${SECURITY_LDFLAGS}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${COREFOUNDATION_LDFLAGS} ${SECURITY_LDFLAGS}) list(APPEND LIBGIT2_PC_LIBS ${COREFOUNDATION_LDFLAGS} ${SECURITY_LDFLAGS}) elseif(USE_HTTPS STREQUAL "OpenSSL") if(NOT OPENSSL_FOUND) @@ -54,7 +54,7 @@ if(USE_HTTPS) set(GIT_OPENSSL 1) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${OPENSSL_INCLUDE_DIR}) - list(APPEND LIBGIT2_LIBS ${OPENSSL_LIBRARIES}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${OPENSSL_LIBRARIES}) list(APPEND LIBGIT2_PC_LIBS ${OPENSSL_LDFLAGS}) list(APPEND LIBGIT2_PC_REQUIRES "openssl") elseif(USE_HTTPS STREQUAL "mbedTLS") @@ -101,7 +101,7 @@ if(USE_HTTPS) set(GIT_MBEDTLS 1) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${MBEDTLS_INCLUDE_DIR}) - list(APPEND LIBGIT2_LIBS ${MBEDTLS_LIBRARIES}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${MBEDTLS_LIBRARIES}) # mbedTLS has no pkgconfig file, hence we can't require it # https://github.com/ARMmbed/mbedtls/issues/228 # For now, pass its link flags as our own @@ -111,7 +111,7 @@ if(USE_HTTPS) elseif(USE_HTTPS STREQUAL "OpenSSL-Dynamic") set(GIT_OPENSSL 1) set(GIT_OPENSSL_DYNAMIC 1) - list(APPEND LIBGIT2_LIBS dl) + list(APPEND LIBGIT2_SYSTEM_LIBS dl) else() message(FATAL_ERROR "Asked for backend ${USE_HTTPS} but it wasn't found") endif() diff --git a/cmake/SelectHashes.cmake b/cmake/SelectHashes.cmake index fee8b29022c..fdefb57fda4 100644 --- a/cmake/SelectHashes.cmake +++ b/cmake/SelectHashes.cmake @@ -3,10 +3,10 @@ include(SanitizeBool) # USE_SHA1=CollisionDetection(ON)/HTTPS/Generic/OFF - sanitizebool(USE_SHA1) + if(USE_SHA1 STREQUAL ON) - set(USE_SHA1 "CollisionDetection") + SET(USE_SHA1 "CollisionDetection") elseif(USE_SHA1 STREQUAL "HTTPS") if(USE_HTTPS STREQUAL "SecureTransport") set(USE_SHA1 "CommonCrypto") diff --git a/cmake/SelectRegex.cmake b/cmake/SelectRegex.cmake index 900d7f150e9..1553d658718 100644 --- a/cmake/SelectRegex.cmake +++ b/cmake/SelectRegex.cmake @@ -27,14 +27,14 @@ elseif(REGEX_BACKEND STREQUAL "pcre2") set(GIT_REGEX_PCRE2 1) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE2_INCLUDE_DIRS}) - list(APPEND LIBGIT2_LIBS ${PCRE2_LIBRARIES}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${PCRE2_LIBRARIES}) list(APPEND LIBGIT2_PC_REQUIRES "libpcre2-8") elseif(REGEX_BACKEND STREQUAL "pcre") add_feature_info(regex ON "using system PCRE") set(GIT_REGEX_PCRE 1) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE_INCLUDE_DIRS}) - list(APPEND LIBGIT2_LIBS ${PCRE_LIBRARIES}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${PCRE_LIBRARIES}) list(APPEND LIBGIT2_PC_REQUIRES "libpcre") elseif(REGEX_BACKEND STREQUAL "regcomp") add_feature_info(regex ON "using system regcomp") @@ -44,8 +44,8 @@ elseif(REGEX_BACKEND STREQUAL "builtin") set(GIT_REGEX_BUILTIN 1) add_subdirectory("${libgit2_SOURCE_DIR}/deps/pcre" "${libgit2_BINARY_DIR}/deps/pcre") - list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/pcre") - list(APPEND LIBGIT2_OBJECTS $) + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/pcre") + list(APPEND LIBGIT2_DEPENDENCY_OBJECTS $) else() message(FATAL_ERROR "The REGEX_BACKEND option provided is not supported") endif() diff --git a/cmake/SelectSSH.cmake b/cmake/SelectSSH.cmake index 0356ee3e7bc..23dfc978521 100644 --- a/cmake/SelectSSH.cmake +++ b/cmake/SelectSSH.cmake @@ -17,7 +17,7 @@ endif() if(LIBSSH2_FOUND) set(GIT_SSH 1) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${LIBSSH2_INCLUDE_DIRS}) - list(APPEND LIBGIT2_LIBS ${LIBSSH2_LIBRARIES}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${LIBSSH2_LIBRARIES}) list(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS}) check_library_exists("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS) @@ -31,9 +31,9 @@ endif() if(WIN32 AND EMBED_SSH_PATH) file(GLOB SSH_SRC "${EMBED_SSH_PATH}/src/*.c") list(SORT SSH_SRC) - list(APPEND LIBGIT2_OBJECTS ${SSH_SRC}) + list(APPEND LIBGIT2_DEPENDENCY_OBJECTS ${SSH_SRC}) - list(APPEND LIBGIT2_INCLUDES "${EMBED_SSH_PATH}/include") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${EMBED_SSH_PATH}/include") file(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"") set(GIT_SSH 1) endif() diff --git a/cmake/SelectWinHTTP.cmake b/cmake/SelectWinHTTP.cmake index a4110045fe0..1d950c9009d 100644 --- a/cmake/SelectWinHTTP.cmake +++ b/cmake/SelectWinHTTP.cmake @@ -5,13 +5,13 @@ if(WIN32 AND WINHTTP) # we have to include a private header and generate our own import library if(MINGW) add_subdirectory("${libgit2_SOURCE_DIR}/deps/winhttp" "${libgit2_BINARY_DIR}/deps/winhttp") - list(APPEND LIBGIT2_LIBS winhttp) + list(APPEND LIBGIT2_SYSTEM_LIBS winhttp) list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/winhttp") else() - list(APPEND LIBGIT2_LIBS "winhttp") + list(APPEND LIBGIT2_SYSTEM_LIBS "winhttp") list(APPEND LIBGIT2_PC_LIBS "-lwinhttp") endif() - list(APPEND LIBGIT2_LIBS "rpcrt4" "crypt32" "ole32") + list(APPEND LIBGIT2_SYSTEM_LIBS "rpcrt4" "crypt32" "ole32") list(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32") endif() diff --git a/cmake/SelectZlib.cmake b/cmake/SelectZlib.cmake index 2dfc6c86e76..e377d43b636 100644 --- a/cmake/SelectZlib.cmake +++ b/cmake/SelectZlib.cmake @@ -10,7 +10,7 @@ if(USE_BUNDLED_ZLIB STREQUAL "OFF") find_package(ZLIB) if(ZLIB_FOUND) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ZLIB_INCLUDE_DIRS}) - list(APPEND LIBGIT2_LIBS ${ZLIB_LIBRARIES}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${ZLIB_LIBRARIES}) if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") list(APPEND LIBGIT2_PC_LIBS "-lz") else() @@ -23,12 +23,12 @@ if(USE_BUNDLED_ZLIB STREQUAL "OFF") endif() if(USE_BUNDLED_ZLIB STREQUAL "Chromium") add_subdirectory("${libgit2_SOURCE_DIR}/deps/chromium-zlib" "${libgit2_BINARY_DIR}/deps/chromium-zlib") - list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/chromium-zlib") - list(APPEND LIBGIT2_OBJECTS $) + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/chromium-zlib") + list(APPEND LIBGIT2_DEPENDENCY_OBJECTS $) add_feature_info(zlib ON "using (Chromium) bundled zlib") elseif(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND) add_subdirectory("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib") - list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib") - list(APPEND LIBGIT2_OBJECTS $) + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib") + list(APPEND LIBGIT2_DEPENDENCY_OBJECTS $) add_feature_info(zlib ON "using bundled zlib") endif() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a7970a6d098..235e72adaed 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,13 +1,14 @@ -include_directories(${LIBGIT2_INCLUDES}) -include_directories(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) +file(GLOB SRC_EXAMPLES *.c *.h) -file(GLOB LG2_SOURCES *.c *.h) -add_executable(lg2 ${LG2_SOURCES}) +add_executable(lg2 ${SRC_EXAMPLES}) set_target_properties(lg2 PROPERTIES C_STANDARD 90) # Ensure that we do not use deprecated functions internally add_definitions(-DGIT_DEPRECATE_HARD) +target_include_directories(lg2 PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES}) +target_include_directories(lg2 SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) + if(WIN32 OR ANDROID) target_link_libraries(lg2 git2) else() diff --git a/fuzzers/CMakeLists.txt b/fuzzers/CMakeLists.txt index 1479a2af885..eaa490fd9b4 100644 --- a/fuzzers/CMakeLists.txt +++ b/fuzzers/CMakeLists.txt @@ -1,7 +1,3 @@ -link_directories(${LIBGIT2_LIBDIRS}) -include_directories(${LIBGIT2_INCLUDES}) -include_directories(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) - if(BUILD_FUZZERS AND NOT USE_STANDALONE_FUZZERS) set(CMAKE_REQUIRED_FLAGS "-fsanitize=fuzzer-no-link") add_c_flag(-fsanitize=fuzzer) @@ -9,8 +5,8 @@ if(BUILD_FUZZERS AND NOT USE_STANDALONE_FUZZERS) unset(CMAKE_REQUIRED_FLAGS) endif() -file(GLOB SRC_FUZZ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *_fuzzer.c) -foreach(fuzz_target_src ${SRC_FUZZ}) +file(GLOB SRC_FUZZERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *_fuzzer.c) +foreach(fuzz_target_src ${SRC_FUZZERS}) string(REPLACE ".c" "" fuzz_target_name ${fuzz_target_src}) string(REPLACE "_fuzzer" "" fuzz_name ${fuzz_target_name}) @@ -20,7 +16,11 @@ foreach(fuzz_target_src ${SRC_FUZZ}) endif() add_executable(${fuzz_target_name} ${${fuzz_target_name}_SOURCES}) set_target_properties(${fuzz_target_name} PROPERTIES C_STANDARD 90) - target_link_libraries(${fuzz_target_name} ${LIBGIT2_LIBS}) + + target_include_directories(${fuzz_target_name} PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES}) + target_include_directories(${fuzz_target_name} SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) + + target_link_libraries(${fuzz_target_name} ${LIBGIT2_SYSTEM_LIBS}) add_test(${fuzz_target_name} "${CMAKE_CURRENT_BINARY_DIR}/${fuzz_target_name}" "${CMAKE_CURRENT_SOURCE_DIR}/corpora/${fuzz_name}") endforeach() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a128cfa8c8..b23b6a0460c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -38,8 +38,6 @@ set(LIBGIT2_INCLUDES "${CMAKE_CURRENT_BINARY_DIR}" "${libgit2_SOURCE_DIR}/src" "${libgit2_SOURCE_DIR}/include") -set(LIBGIT2_SYSTEM_INCLUDES "") -set(LIBGIT2_LIBS "") if(HAVE_FUTIMENS) set(GIT_USE_FUTIMENS 1) @@ -59,23 +57,23 @@ check_function_exists(qsort_s GIT_QSORT_S) # Find required dependencies if(WIN32) - list(APPEND LIBGIT2_LIBS ws2_32) + list(APPEND LIBGIT2_SYSTEM_LIBS ws2_32) elseif(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - list(APPEND LIBGIT2_LIBS socket nsl) + list(APPEND LIBGIT2_SYSTEM_LIBS socket nsl) list(APPEND LIBGIT2_PC_LIBS "-lsocket" "-lnsl") elseif(CMAKE_SYSTEM_NAME MATCHES "Haiku") - list(APPEND LIBGIT2_LIBS network) + list(APPEND LIBGIT2_SYSTEM_LIBS network) list(APPEND LIBGIT2_PC_LIBS "-lnetwork") endif() check_library_exists(rt clock_gettime "time.h" NEED_LIBRT) if(NEED_LIBRT) - list(APPEND LIBGIT2_LIBS rt) + list(APPEND LIBGIT2_SYSTEM_LIBS rt) list(APPEND LIBGIT2_PC_LIBS "-lrt") endif() if(USE_THREADS) - list(APPEND LIBGIT2_LIBS ${CMAKE_THREAD_LIBS_INIT}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT}) list(APPEND LIBGIT2_PC_LIBS ${CMAKE_THREAD_LIBS_INIT}) endif() add_feature_info(threadsafe USE_THREADS "threadsafe support") @@ -105,8 +103,8 @@ target_sources(git2internal PRIVATE ${SRC_SHA1}) if(USE_NTLMCLIENT) set(GIT_NTLM 1) add_subdirectory("${libgit2_SOURCE_DIR}/deps/ntlmclient" "${libgit2_BINARY_DIR}/deps/ntlmclient") - list(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/ntlmclient") - list(APPEND LIBGIT2_OBJECTS "$") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") endif() add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix") @@ -121,7 +119,7 @@ endif() if(ICONV_FOUND) set(GIT_USE_ICONV 1) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ICONV_INCLUDE_DIR}) - list(APPEND LIBGIT2_LIBS ${ICONV_LIBRARIES}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${ICONV_LIBRARIES}) list(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES}) endif() add_feature_info(iconv GIT_USE_ICONV "iconv encoding conversion support") @@ -210,15 +208,17 @@ endif() configure_file(features.h.in git2/sys/features.h) ide_split_sources(git2internal) -list(APPEND LIBGIT2_OBJECTS $) +list(APPEND LIBGIT2_OBJECTS $ ${LIBGIT2_DEPENDENCY_OBJECTS}) -target_include_directories(git2internal PRIVATE ${LIBGIT2_INCLUDES} PUBLIC ${libgit2_SOURCE_DIR}/include) +target_include_directories(git2internal PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${libgit2_SOURCE_DIR}/include) target_include_directories(git2internal SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) -set(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE) set(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE) +set(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE) +set(LIBGIT2_DEPENDENCY_INCLUDES ${LIBGIT2_DEPENDENCY_INCLUDES} PARENT_SCOPE) +set(LIBGIT2_DEPENDENCY_OBJECTS ${LIBGIT2_DEPENDENCY_OBJECTS} PARENT_SCOPE) set(LIBGIT2_SYSTEM_INCLUDES ${LIBGIT2_SYSTEM_INCLUDES} PARENT_SCOPE) -set(LIBGIT2_LIBS ${LIBGIT2_LIBS} PARENT_SCOPE) +set(LIBGIT2_SYSTEM_LIBS ${LIBGIT2_SYSTEM_LIBS} PARENT_SCOPE) if(XCODE_VERSION) # This is required for Xcode to actually link the libgit2 library @@ -229,7 +229,7 @@ endif() # Compile and link libgit2 add_library(git2 ${WIN_RC} ${LIBGIT2_OBJECTS}) -target_link_libraries(git2 ${LIBGIT2_LIBS}) +target_link_libraries(git2 ${LIBGIT2_SYSTEM_LIBS}) set_target_properties(git2 PROPERTIES C_STANDARD 90) set_target_properties(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e109913ff4e..07247035050 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,7 +16,7 @@ add_definitions(-D_FILE_OFFSET_BITS=64) # Ensure that we do not use deprecated functions internally add_definitions(-DGIT_DEPRECATE_HARD) -include_directories(${CLAR_PATH} ${libgit2_BINARY_DIR}/src) +set(TEST_INCLUDES "${CLAR_PATH}" "${CMAKE_CURRENT_BINARY_DIR}") file(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h) set(SRC_CLAR "main.c" "clar_libgit2.c" "clar_libgit2_trace.c" "clar_libgit2_timer.c" "clar.c") @@ -30,22 +30,20 @@ add_custom_command( DEPENDS ${SRC_TEST} WORKING_DIRECTORY ${CLAR_PATH} ) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) set_source_files_properties( ${CLAR_PATH}/clar.c PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clar.suite) -include_directories(${LIBGIT2_INCLUDES}) -include_directories(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES}) - add_executable(libgit2_tests ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS}) set_target_properties(libgit2_tests PROPERTIES C_STANDARD 90) set_target_properties(libgit2_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) -target_include_directories(libgit2_tests PRIVATE ../src PUBLIC ../include) -target_link_libraries(libgit2_tests ${LIBGIT2_LIBS}) +target_include_directories(libgit2_tests PRIVATE ${TEST_INCLUDES} ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES}) +target_include_directories(libgit2_tests SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) +target_link_libraries(libgit2_tests ${LIBGIT2_SYSTEM_LIBS}) + ide_split_sources(libgit2_tests) # From c7f6ecb3911b5bc8052428a3605802403c673730 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 22:54:14 -0500 Subject: [PATCH 0645/1616] cmake: use a string not a boolean for LIBGIT2_FILENAME --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae0a5d685bd..664abc0d23b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ option(DEBUG_STRICT_OPEN "Enable path validation in open" # Output options option(SONAME "Set the (SO)VERSION of the target" ON) -option(LIBGIT2_FILENAME "Name of the produced binary" OFF) + set(LIBGIT2_FILENAME "git2" CACHE STRING "Name of the produced binary") option(DEPRECATE_HARD "Do not include deprecated functions in the library" OFF) # Compilation options From 2c154145a8f7ce3c01f1afc40e3934c1e43c377e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 11 Nov 2021 23:09:44 -0500 Subject: [PATCH 0646/1616] cmake: move sha1 source selection into CMakeLists.txt The select hashes module selects the hash; the CMakeLists.txt selects the files to implement it. --- cmake/SelectHashes.cmake | 14 ++------------ src/CMakeLists.txt | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/cmake/SelectHashes.cmake b/cmake/SelectHashes.cmake index fdefb57fda4..bedd8c4e332 100644 --- a/cmake/SelectHashes.cmake +++ b/cmake/SelectHashes.cmake @@ -24,7 +24,6 @@ if(USE_SHA1 STREQUAL "CollisionDetection") add_definitions(-DSHA1DC_NO_STANDARD_INCLUDES=1) add_definitions(-DSHA1DC_CUSTOM_INCLUDE_SHA1_C=\"common.h\") add_definitions(-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"common.h\") - file(GLOB SRC_SHA1 hash/sha1/collisiondetect.* hash/sha1/sha1dc/*) elseif(USE_SHA1 STREQUAL "OpenSSL") # OPENSSL_FOUND should already be set, we're checking USE_HTTPS @@ -34,29 +33,20 @@ elseif(USE_SHA1 STREQUAL "OpenSSL") else() list(APPEND LIBGIT2_PC_REQUIRES "openssl") endif() - file(GLOB SRC_SHA1 hash/sha1/openssl.*) elseif(USE_SHA1 STREQUAL "CommonCrypto") set(GIT_SHA1_COMMON_CRYPTO 1) - file(GLOB SRC_SHA1 hash/sha1/common_crypto.*) elseif(USE_SHA1 STREQUAL "mbedTLS") set(GIT_SHA1_MBEDTLS 1) - file(GLOB SRC_SHA1 hash/sha1/mbedtls.*) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${MBEDTLS_INCLUDE_DIR}) - list(APPEND LIBGIT2_LIBS ${MBEDTLS_LIBRARIES}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${MBEDTLS_LIBRARIES}) # mbedTLS has no pkgconfig file, hence we can't require it # https://github.com/ARMmbed/mbedtls/issues/228 # For now, pass its link flags as our own list(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LIBRARIES}) elseif(USE_SHA1 STREQUAL "Win32") set(GIT_SHA1_WIN32 1) - file(GLOB SRC_SHA1 hash/sha1/win32.*) -elseif(USE_SHA1 STREQUAL "Generic") - file(GLOB SRC_SHA1 hash/sha1/generic.*) -else() +elseif(NOT (USE_SHA1 STREQUAL "Generic")) message(FATAL_ERROR "Asked for unknown SHA1 backend: ${USE_SHA1}") endif() -list(APPEND SRC_SHA1 "hash/sha1.h") -list(SORT SRC_SHA1) - add_feature_info(SHA ON "using ${USE_SHA1}") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b23b6a0460c..d6a1036675b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -97,6 +97,21 @@ include(SelectSSH) include(SelectWinHTTP) include(SelectZlib) + +if(USE_SHA1 STREQUAL "CollisionDetection") + file(GLOB SRC_SHA1 hash/sha1/collisiondetect.* hash/sha1/sha1dc/*) +elseif(USE_SHA1 STREQUAL "OpenSSL") + file(GLOB SRC_SHA1 hash/sha1/openssl.*) +elseif(USE_SHA1 STREQUAL "CommonCrypto") + file(GLOB SRC_SHA1 hash/sha1/common_crypto.*) +elseif(USE_SHA1 STREQUAL "mbedTLS") + file(GLOB SRC_SHA1 hash/sha1/mbedtls.*) +elseif(USE_SHA1 STREQUAL "Win32") + file(GLOB SRC_SHA1 hash/sha1/win32.*) +elseif(USE_SHA1 STREQUAL "Generic") + file(GLOB SRC_SHA1 hash/sha1/generic.*) +endif() +list(APPEND SRC_SHA1 "hash/sha1.h") target_sources(git2internal PRIVATE ${SRC_SHA1}) # Optional external dependency: ntlmclient From 5221e1854846ac31dd2ada44fb29dc705104e851 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Sat, 2 Oct 2021 23:54:14 +0200 Subject: [PATCH 0647/1616] Add target for testing libgit2 headers --- tests/CMakeLists.txt | 14 +++++++++++++- tests/headertest.c | 13 +++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/headertest.c diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 07247035050..d42c6ad5ba4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -51,7 +51,7 @@ ide_split_sources(libgit2_tests) # this on newer compilers to avoid unnecessary recompilation. # if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) - add_definitions(-include \"clar_suite.h\") + target_compile_options(libgit2_tests PRIVATE -include "clar_suite.h") endif() if(MSVC_IDE) @@ -79,3 +79,15 @@ add_clar_test(ssh -v -sonline::push -sonline::clone::ssh_cert -s add_clar_test(proxy -v -sonline::clone::proxy) add_clar_test(auth_clone -v -sonline::clone::cred) add_clar_test(auth_clone_and_push -v -sonline::clone::push -sonline::push) + +# Header file validation project +add_executable(headertest headertest.c) +set_target_properties(headertest PROPERTIES C_STANDARD 90) +set_target_properties(headertest PROPERTIES C_EXTENSIONS OFF) +target_include_directories(headertest PRIVATE ${LIBGIT2_INCLUDES}) + +if (MSVC) + target_compile_options(headertest PUBLIC /W4 /WX) +else() + target_compile_options(headertest PUBLIC -Wall -Wextra -pedantic -Werror) +endif() diff --git a/tests/headertest.c b/tests/headertest.c new file mode 100644 index 00000000000..2af8a14eca5 --- /dev/null +++ b/tests/headertest.c @@ -0,0 +1,13 @@ +/* + * Dummy project to validate header files + * + * This project is not intended to be executed, it should only include all + * header files to make sure that they can be used with stricter compiler + * settings than the libgit2 source files generally supports. + */ +#include "git2.h" + +int main(void) +{ + return 0; +} From 38c3449822162e7b7669c1cc7ca778afccb59406 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Sun, 3 Oct 2021 00:12:52 +0200 Subject: [PATCH 0648/1616] Make enum in includes C90 compliant by removing trailing comma. --- include/git2/apply.h | 4 ++-- include/git2/attr.h | 2 +- include/git2/blame.h | 2 +- include/git2/blob.h | 2 +- include/git2/cert.h | 4 ++-- include/git2/checkout.h | 2 +- include/git2/clone.h | 2 +- include/git2/common.h | 2 +- include/git2/config.h | 2 +- include/git2/credential.h | 2 +- include/git2/deprecated.h | 2 +- include/git2/describe.h | 2 +- include/git2/diff.h | 14 +++++++------- include/git2/email.h | 2 +- include/git2/errors.h | 2 +- include/git2/filter.h | 4 ++-- include/git2/index.h | 10 +++++----- include/git2/merge.h | 10 +++++----- include/git2/odb_backend.h | 2 +- include/git2/pack.h | 2 +- include/git2/pathspec.h | 2 +- include/git2/proxy.h | 2 +- include/git2/rebase.h | 2 +- include/git2/refs.h | 2 +- include/git2/remote.h | 8 ++++---- include/git2/repository.h | 8 ++++---- include/git2/reset.h | 2 +- include/git2/revparse.h | 2 +- include/git2/revwalk.h | 2 +- include/git2/stash.h | 6 +++--- include/git2/status.h | 6 +++--- include/git2/submodule.h | 2 +- include/git2/sys/commit_graph.h | 2 +- include/git2/sys/stream.h | 2 +- include/git2/sys/transport.h | 4 ++-- include/git2/tree.h | 4 ++-- include/git2/types.h | 12 ++++++------ include/git2/worktree.h | 2 +- 38 files changed, 72 insertions(+), 72 deletions(-) diff --git a/include/git2/apply.h b/include/git2/apply.h index bc637df1c2a..814bc8f166c 100644 --- a/include/git2/apply.h +++ b/include/git2/apply.h @@ -59,7 +59,7 @@ typedef enum { * Don't actually make changes, just test that the patch applies. * This is the equivalent of `git apply --check`. */ - GIT_APPLY_CHECK = (1 << 0), + GIT_APPLY_CHECK = (1 << 0) } git_apply_flags_t; /** @@ -127,7 +127,7 @@ typedef enum { * Apply the patch to both the working directory and the index. * This is the equivalent of `git apply --index`. */ - GIT_APPLY_LOCATION_BOTH = 2, + GIT_APPLY_LOCATION_BOTH = 2 } git_apply_location_t; /** diff --git a/include/git2/attr.h b/include/git2/attr.h index 3891a0c9729..157192c9d7b 100644 --- a/include/git2/attr.h +++ b/include/git2/attr.h @@ -83,7 +83,7 @@ typedef enum { GIT_ATTR_VALUE_UNSPECIFIED = 0, /**< The attribute has been left unspecified */ GIT_ATTR_VALUE_TRUE, /**< The attribute has been set */ GIT_ATTR_VALUE_FALSE, /**< The attribute has been unset */ - GIT_ATTR_VALUE_STRING, /**< This attribute has a value */ + GIT_ATTR_VALUE_STRING /**< This attribute has a value */ } git_attr_value_t; /** diff --git a/include/git2/blame.h b/include/git2/blame.h index d193ce14ed5..33a9fbc98d9 100644 --- a/include/git2/blame.h +++ b/include/git2/blame.h @@ -73,7 +73,7 @@ typedef enum { GIT_BLAME_USE_MAILMAP = (1<<5), /** Ignore whitespace differences */ - GIT_BLAME_IGNORE_WHITESPACE = (1<<6), + GIT_BLAME_IGNORE_WHITESPACE = (1<<6) } git_blame_flag_t; /** diff --git a/include/git2/blob.h b/include/git2/blob.h index 8fc73919d93..4922b087a56 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -119,7 +119,7 @@ typedef enum { * When set, filters will be loaded from a `.gitattributes` file * in the specified commit. */ - GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT = (1 << 3), + GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT = (1 << 3) } git_blob_filter_flag_t; /** diff --git a/include/git2/cert.h b/include/git2/cert.h index 0ed38ffcdd4..05213a57192 100644 --- a/include/git2/cert.h +++ b/include/git2/cert.h @@ -44,7 +44,7 @@ typedef enum git_cert_t { * information about the certificate. This is used when using * curl. */ - GIT_CERT_STRARRAY, + GIT_CERT_STRARRAY } git_cert_t; /** @@ -82,7 +82,7 @@ typedef enum { /** SHA-256 is available */ GIT_CERT_SSH_SHA256 = (1 << 2), /** Raw hostkey is available */ - GIT_CERT_SSH_RAW = (1 << 3), + GIT_CERT_SSH_RAW = (1 << 3) } git_cert_ssh_t; typedef enum { diff --git a/include/git2/checkout.h b/include/git2/checkout.h index c7aeee43120..f026d5bc2a4 100644 --- a/include/git2/checkout.h +++ b/include/git2/checkout.h @@ -190,7 +190,7 @@ typedef enum { /** Recursively checkout submodules with same options (NOT IMPLEMENTED) */ GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16), /** Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */ - GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17), + GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17) } git_checkout_strategy_t; diff --git a/include/git2/clone.h b/include/git2/clone.h index 3c3ea260eff..c517ec3d61e 100644 --- a/include/git2/clone.h +++ b/include/git2/clone.h @@ -49,7 +49,7 @@ typedef enum { * Bypass the git-aware transport, but do not try to use * hardlinks. */ - GIT_CLONE_LOCAL_NO_LINKS, + GIT_CLONE_LOCAL_NO_LINKS } git_clone_local_t; /** diff --git a/include/git2/common.h b/include/git2/common.h index 2ee82902529..d62d9be188d 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -147,7 +147,7 @@ typedef enum { * If set, libgit2 was built with support for sub-second resolution in file * modification times. */ - GIT_FEATURE_NSEC = (1 << 3), + GIT_FEATURE_NSEC = (1 << 3) } git_feature_t; /** diff --git a/include/git2/config.h b/include/git2/config.h index 7c8e388b237..cad01ea4974 100644 --- a/include/git2/config.h +++ b/include/git2/config.h @@ -55,7 +55,7 @@ typedef enum { /** Represents the highest level available config file (i.e. the most * specific config file available that actually is loaded) */ - GIT_CONFIG_HIGHEST_LEVEL = -1, + GIT_CONFIG_HIGHEST_LEVEL = -1 } git_config_level_t; /** diff --git a/include/git2/credential.h b/include/git2/credential.h index 9426a6ea2bf..a4e68e85382 100644 --- a/include/git2/credential.h +++ b/include/git2/credential.h @@ -75,7 +75,7 @@ typedef enum { * * @see git_credential_ssh_key_memory_new */ - GIT_CREDENTIAL_SSH_MEMORY = (1u << 6), + GIT_CREDENTIAL_SSH_MEMORY = (1u << 6) } git_credential_t; /** diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index 37b9fa0e2f1..f73d7da6181 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -313,7 +313,7 @@ typedef enum { GIT_DIFF_FORMAT_EMAIL_NONE = 0, /** Don't insert "[PATCH]" in the subject header*/ - GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER = (1 << 0), + GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER = (1 << 0) } git_diff_format_email_flags_t; diff --git a/include/git2/describe.h b/include/git2/describe.h index 1d2ca1496fb..e8afd687972 100644 --- a/include/git2/describe.h +++ b/include/git2/describe.h @@ -30,7 +30,7 @@ GIT_BEGIN_DECL typedef enum { GIT_DESCRIBE_DEFAULT, GIT_DESCRIBE_TAGS, - GIT_DESCRIBE_ALL, + GIT_DESCRIBE_ALL } git_describe_strategy_t; /** diff --git a/include/git2/diff.h b/include/git2/diff.h index b0119b9f79f..c040cd19053 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -170,7 +170,7 @@ typedef enum { /** Include the necessary deflate / delta information so that `git-apply` * can apply given diff information to binary files. */ - GIT_DIFF_SHOW_BINARY = (1u << 30), + GIT_DIFF_SHOW_BINARY = (1u << 30) } git_diff_option_t; /** @@ -207,7 +207,7 @@ typedef enum { GIT_DIFF_FLAG_BINARY = (1u << 0), /**< file(s) treated as binary data */ GIT_DIFF_FLAG_NOT_BINARY = (1u << 1), /**< file(s) treated as text data */ GIT_DIFF_FLAG_VALID_ID = (1u << 2), /**< `id` value is known correct */ - GIT_DIFF_FLAG_EXISTS = (1u << 3), /**< file exists at this side of the delta */ + GIT_DIFF_FLAG_EXISTS = (1u << 3) /**< file exists at this side of the delta */ } git_diff_flag_t; /** @@ -231,7 +231,7 @@ typedef enum { GIT_DELTA_UNTRACKED = 7, /**< entry is untracked item in workdir */ GIT_DELTA_TYPECHANGE = 8, /**< type of entry changed between old and new */ GIT_DELTA_UNREADABLE = 9, /**< entry is unreadable */ - GIT_DELTA_CONFLICTED = 10, /**< entry in the index is conflicted */ + GIT_DELTA_CONFLICTED = 10 /**< entry in the index is conflicted */ } git_delta_t; /** @@ -497,7 +497,7 @@ typedef enum { GIT_DIFF_BINARY_LITERAL, /** The binary data is the delta from one side to the other. */ - GIT_DIFF_BINARY_DELTA, + GIT_DIFF_BINARY_DELTA } git_diff_binary_t; /** The contents of one of the files in a binary diff. */ @@ -706,7 +706,7 @@ typedef enum { * GIT_DIFF_INCLUDE_UNMODIFIED flag. If you do not want UNMODIFIED * records in the final result, pass this flag to have them removed. */ - GIT_DIFF_FIND_REMOVE_UNMODIFIED = (1u << 16), + GIT_DIFF_FIND_REMOVE_UNMODIFIED = (1u << 16) } git_diff_find_t; /** @@ -1107,7 +1107,7 @@ typedef enum { GIT_DIFF_FORMAT_RAW = 3u, /**< like git diff --raw */ GIT_DIFF_FORMAT_NAME_ONLY = 4u, /**< like git diff --name-only */ GIT_DIFF_FORMAT_NAME_STATUS = 5u, /**< like git diff --name-status */ - GIT_DIFF_FORMAT_PATCH_ID = 6u, /**< git diff as used by git patch-id */ + GIT_DIFF_FORMAT_PATCH_ID = 6u /**< git diff as used by git patch-id */ } git_diff_format_t; /** @@ -1311,7 +1311,7 @@ typedef enum { GIT_DIFF_STATS_NUMBER = (1u << 2), /** Extended header information such as creations, renames and mode changes, equivalent of `--summary` */ - GIT_DIFF_STATS_INCLUDE_SUMMARY = (1u << 3), + GIT_DIFF_STATS_INCLUDE_SUMMARY = (1u << 3) } git_diff_stats_format_t; /** diff --git a/include/git2/email.h b/include/git2/email.h index b56be5d0edc..20393653e9f 100644 --- a/include/git2/email.h +++ b/include/git2/email.h @@ -34,7 +34,7 @@ typedef enum { GIT_EMAIL_CREATE_ALWAYS_NUMBER = (1u << 1), /** Do not perform rename or similarity detection. */ - GIT_EMAIL_CREATE_NO_RENAMES = (1u << 2), + GIT_EMAIL_CREATE_NO_RENAMES = (1u << 2) } git_email_create_flags_t; /** diff --git a/include/git2/errors.h b/include/git2/errors.h index de51582d58e..5a5f8c5a249 100644 --- a/include/git2/errors.h +++ b/include/git2/errors.h @@ -57,7 +57,7 @@ typedef enum { GIT_RETRY = -32, /**< Internal only */ GIT_EMISMATCH = -33, /**< Hashsum mismatch in object */ GIT_EINDEXDIRTY = -34, /**< Unsaved changes in the index would be overwritten */ - GIT_EAPPLYFAIL = -35, /**< Patch application failed */ + GIT_EAPPLYFAIL = -35 /**< Patch application failed */ } git_error_code; /** diff --git a/include/git2/filter.h b/include/git2/filter.h index 0465e5b144a..632bb84e316 100644 --- a/include/git2/filter.h +++ b/include/git2/filter.h @@ -32,7 +32,7 @@ typedef enum { GIT_FILTER_TO_WORKTREE = 0, GIT_FILTER_SMUDGE = GIT_FILTER_TO_WORKTREE, GIT_FILTER_TO_ODB = 1, - GIT_FILTER_CLEAN = GIT_FILTER_TO_ODB, + GIT_FILTER_CLEAN = GIT_FILTER_TO_ODB } git_filter_mode_t; /** @@ -54,7 +54,7 @@ typedef enum { * Load attributes from `.gitattributes` in a given commit. * This can only be specified in a `git_filter_options`. */ - GIT_FILTER_ATTRIBUTES_FROM_COMMIT = (1u << 3), + GIT_FILTER_ATTRIBUTES_FROM_COMMIT = (1u << 3) } git_filter_flag_t; /** diff --git a/include/git2/index.h b/include/git2/index.h index 532a52091f4..5864791e6f8 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -86,7 +86,7 @@ typedef struct git_index_entry { */ typedef enum { GIT_INDEX_ENTRY_EXTENDED = (0x4000), - GIT_INDEX_ENTRY_VALID = (0x8000), + GIT_INDEX_ENTRY_VALID = (0x8000) } git_index_entry_flag_t; #define GIT_INDEX_ENTRY_STAGE(E) \ @@ -119,7 +119,7 @@ typedef enum { GIT_INDEX_ENTRY_EXTENDED_FLAGS = (GIT_INDEX_ENTRY_INTENT_TO_ADD | GIT_INDEX_ENTRY_SKIP_WORKTREE), - GIT_INDEX_ENTRY_UPTODATE = (1 << 2), + GIT_INDEX_ENTRY_UPTODATE = (1 << 2) } git_index_entry_extended_flag_t; /** Capabilities of system that affect index actions. */ @@ -127,7 +127,7 @@ typedef enum { GIT_INDEX_CAPABILITY_IGNORE_CASE = 1, GIT_INDEX_CAPABILITY_NO_FILEMODE = 2, GIT_INDEX_CAPABILITY_NO_SYMLINKS = 4, - GIT_INDEX_CAPABILITY_FROM_OWNER = -1, + GIT_INDEX_CAPABILITY_FROM_OWNER = -1 } git_index_capability_t; @@ -140,7 +140,7 @@ typedef enum { GIT_INDEX_ADD_DEFAULT = 0, GIT_INDEX_ADD_FORCE = (1u << 0), GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH = (1u << 1), - GIT_INDEX_ADD_CHECK_PATHSPEC = (1u << 2), + GIT_INDEX_ADD_CHECK_PATHSPEC = (1u << 2) } git_index_add_option_t; /** Git index stage states */ @@ -163,7 +163,7 @@ typedef enum { GIT_INDEX_STAGE_OURS = 2, /** The "theirs" side of a conflict. */ - GIT_INDEX_STAGE_THEIRS = 3, + GIT_INDEX_STAGE_THEIRS = 3 } git_index_stage_t; /** diff --git a/include/git2/merge.h b/include/git2/merge.h index fc27c9d1dc9..e32c53fcc03 100644 --- a/include/git2/merge.h +++ b/include/git2/merge.h @@ -91,7 +91,7 @@ typedef enum { * instead simply use the first base. This flag provides a similar * merge base to `git-merge-resolve`. */ - GIT_MERGE_NO_RECURSIVE = (1 << 3), + GIT_MERGE_NO_RECURSIVE = (1 << 3) } git_merge_flag_t; /** @@ -127,7 +127,7 @@ typedef enum { * which has the result of combining both files. The index will not * record a conflict. */ - GIT_MERGE_FILE_FAVOR_UNION = 3, + GIT_MERGE_FILE_FAVOR_UNION = 3 } git_merge_file_favor_t; /** @@ -159,7 +159,7 @@ typedef enum { GIT_MERGE_FILE_DIFF_PATIENCE = (1 << 6), /** Take extra time to find minimal diff */ - GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7), + GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7) } git_merge_file_flag_t; #define GIT_MERGE_CONFLICT_MARKER_SIZE 7 @@ -341,7 +341,7 @@ typedef enum { * a valid commit. No merge can be performed, but the caller may wish * to simply set HEAD to the target commit(s). */ - GIT_MERGE_ANALYSIS_UNBORN = (1 << 3), + GIT_MERGE_ANALYSIS_UNBORN = (1 << 3) } git_merge_analysis_t; /** @@ -364,7 +364,7 @@ typedef enum { * There is a `merge.ff=only` configuration setting, suggesting that * the user only wants fast-forward merges. */ - GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY = (1 << 1), + GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY = (1 << 1) } git_merge_preference_t; /** diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h index c593bac26cb..5ad777b177d 100644 --- a/include/git2/odb_backend.h +++ b/include/git2/odb_backend.h @@ -71,7 +71,7 @@ GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *inde typedef enum { GIT_STREAM_RDONLY = (1 << 1), GIT_STREAM_WRONLY = (1 << 2), - GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY), + GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY) } git_odb_stream_t; /** diff --git a/include/git2/pack.h b/include/git2/pack.h index 3b9beb66521..cd28a4f5b73 100644 --- a/include/git2/pack.h +++ b/include/git2/pack.h @@ -51,7 +51,7 @@ GIT_BEGIN_DECL */ typedef enum { GIT_PACKBUILDER_ADDING_OBJECTS = 0, - GIT_PACKBUILDER_DELTAFICATION = 1, + GIT_PACKBUILDER_DELTAFICATION = 1 } git_packbuilder_stage_t; /** diff --git a/include/git2/pathspec.h b/include/git2/pathspec.h index 32996578970..acbd5cd1d6f 100644 --- a/include/git2/pathspec.h +++ b/include/git2/pathspec.h @@ -69,7 +69,7 @@ typedef enum { * just test if there were any matches at all or in combination with * GIT_PATHSPEC_FIND_FAILURES to validate a pathspec. */ - GIT_PATHSPEC_FAILURES_ONLY = (1u << 5), + GIT_PATHSPEC_FAILURES_ONLY = (1u << 5) } git_pathspec_flag_t; /** diff --git a/include/git2/proxy.h b/include/git2/proxy.h index 653425dee07..cfc0c645f8b 100644 --- a/include/git2/proxy.h +++ b/include/git2/proxy.h @@ -32,7 +32,7 @@ typedef enum { /** * Connect via the URL given in the options */ - GIT_PROXY_SPECIFIED, + GIT_PROXY_SPECIFIED } git_proxy_t; /** diff --git a/include/git2/rebase.h b/include/git2/rebase.h index 11e452cbf01..2a5dece7c89 100644 --- a/include/git2/rebase.h +++ b/include/git2/rebase.h @@ -152,7 +152,7 @@ typedef enum { * No commit will be cherry-picked. The client should run the given * command and (if successful) continue. */ - GIT_REBASE_OPERATION_EXEC, + GIT_REBASE_OPERATION_EXEC } git_rebase_operation_t; #define GIT_REBASE_OPTIONS_VERSION 1 diff --git a/include/git2/refs.h b/include/git2/refs.h index 7ebb209b291..3a0095bb62b 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -686,7 +686,7 @@ typedef enum { * so the `ONELEVEL` naming rules aren't enforced and 'master' * becomes a valid name. */ - GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND = (1u << 2), + GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND = (1u << 2) } git_reference_format_t; /** diff --git a/include/git2/remote.h b/include/git2/remote.h index 4d57eaaf74f..088f528a6c6 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -49,7 +49,7 @@ typedef enum { GIT_REMOTE_CREATE_SKIP_INSTEADOF = (1 << 0), /** Don't build a fetchspec from the name if none is set */ - GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC = (1 << 1), + GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC = (1 << 1) } git_remote_create_flags; /** @@ -443,7 +443,7 @@ GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo); typedef enum git_remote_completion_t { GIT_REMOTE_COMPLETION_DOWNLOAD, GIT_REMOTE_COMPLETION_INDEXING, - GIT_REMOTE_COMPLETION_ERROR, + GIT_REMOTE_COMPLETION_ERROR } git_remote_completion_t; /** Push network progress notification function */ @@ -665,7 +665,7 @@ typedef enum { /** * Force pruning off */ - GIT_FETCH_NO_PRUNE, + GIT_FETCH_NO_PRUNE } git_fetch_prune_t; /** @@ -690,7 +690,7 @@ typedef enum { /** * Ask for the all the tags. */ - GIT_REMOTE_DOWNLOAD_TAGS_ALL, + GIT_REMOTE_DOWNLOAD_TAGS_ALL } git_remote_autotag_option_t; /** diff --git a/include/git2/repository.h b/include/git2/repository.h index 8d1cffc9bf6..8bd877be42f 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -141,7 +141,7 @@ typedef enum { * `git_repository_open_ext` with this flag will error out if either * $GIT_WORK_TREE or $GIT_COMMON_DIR is set. */ - GIT_REPOSITORY_OPEN_FROM_ENV = (1 << 4), + GIT_REPOSITORY_OPEN_FROM_ENV = (1 << 4) } git_repository_open_flag_t; /** @@ -267,7 +267,7 @@ typedef enum { * If an alternate workdir is specified, use relative paths for the gitdir * and core.worktree. */ - GIT_REPOSITORY_INIT_RELATIVE_GITLINK = (1u << 6), + GIT_REPOSITORY_INIT_RELATIVE_GITLINK = (1u << 6) } git_repository_init_flag_t; /** @@ -292,7 +292,7 @@ typedef enum { /** * Use "--shared=all" behavior, adding world readability. */ - GIT_REPOSITORY_INIT_SHARED_ALL = 0002777, + GIT_REPOSITORY_INIT_SHARED_ALL = 0002777 } git_repository_init_mode_t; /** @@ -876,7 +876,7 @@ typedef enum { GIT_REPOSITORY_STATE_REBASE_INTERACTIVE, GIT_REPOSITORY_STATE_REBASE_MERGE, GIT_REPOSITORY_STATE_APPLY_MAILBOX, - GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE, + GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE } git_repository_state_t; /** diff --git a/include/git2/reset.h b/include/git2/reset.h index be25414336a..7a471bdd0cb 100644 --- a/include/git2/reset.h +++ b/include/git2/reset.h @@ -26,7 +26,7 @@ GIT_BEGIN_DECL typedef enum { GIT_RESET_SOFT = 1, /**< Move the head to the given commit */ GIT_RESET_MIXED = 2, /**< SOFT plus reset index to the commit */ - GIT_RESET_HARD = 3, /**< MIXED plus changes in working tree discarded */ + GIT_RESET_HARD = 3 /**< MIXED plus changes in working tree discarded */ } git_reset_t; /** diff --git a/include/git2/revparse.h b/include/git2/revparse.h index e14ddee96cf..51ea2dc13f5 100644 --- a/include/git2/revparse.h +++ b/include/git2/revparse.h @@ -74,7 +74,7 @@ typedef enum { /** The spec targeted a range of commits. */ GIT_REVSPEC_RANGE = 1 << 1, /** The spec used the '...' operator, which invokes special semantics. */ - GIT_REVSPEC_MERGE_BASE = 1 << 2, + GIT_REVSPEC_MERGE_BASE = 1 << 2 } git_revspec_t; /** diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h index 98dcbf8d13a..241479d568e 100644 --- a/include/git2/revwalk.h +++ b/include/git2/revwalk.h @@ -49,7 +49,7 @@ typedef enum { * order; this sorting mode can be combined with * any of the above. */ - GIT_SORT_REVERSE = 1 << 2, + GIT_SORT_REVERSE = 1 << 2 } git_sort_t; /** diff --git a/include/git2/stash.h b/include/git2/stash.h index 795920ebc76..32e6f95764c 100644 --- a/include/git2/stash.h +++ b/include/git2/stash.h @@ -44,7 +44,7 @@ typedef enum { * All ignored files are also stashed and then cleaned up from * the working directory */ - GIT_STASH_INCLUDE_IGNORED = (1 << 2), + GIT_STASH_INCLUDE_IGNORED = (1 << 2) } git_stash_flags; /** @@ -78,7 +78,7 @@ typedef enum { /* Try to reinstate not only the working tree's changes, * but also the index's changes. */ - GIT_STASH_APPLY_REINSTATE_INDEX = (1 << 0), + GIT_STASH_APPLY_REINSTATE_INDEX = (1 << 0) } git_stash_apply_flags; /** Stash apply progression states */ @@ -104,7 +104,7 @@ typedef enum { GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED, /** The stash was applied successfully. */ - GIT_STASH_APPLY_PROGRESS_DONE, + GIT_STASH_APPLY_PROGRESS_DONE } git_stash_apply_progress_t; /** diff --git a/include/git2/status.h b/include/git2/status.h index 543e3faa8f7..526df639905 100644 --- a/include/git2/status.h +++ b/include/git2/status.h @@ -48,7 +48,7 @@ typedef enum { GIT_STATUS_WT_UNREADABLE = (1u << 12), GIT_STATUS_IGNORED = (1u << 14), - GIT_STATUS_CONFLICTED = (1u << 15), + GIT_STATUS_CONFLICTED = (1u << 15) } git_status_t; /** @@ -87,7 +87,7 @@ typedef enum { * Only gives status based on index to working directory comparison, * not comparing the index to the HEAD. */ - GIT_STATUS_SHOW_WORKDIR_ONLY = 2, + GIT_STATUS_SHOW_WORKDIR_ONLY = 2 } git_status_show_t; /** @@ -204,7 +204,7 @@ typedef enum { * Unreadable files will be detected and given the status * untracked instead of unreadable. */ - GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED = (1u << 15), + GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED = (1u << 15) } git_status_opt_t; #define GIT_STATUS_OPT_DEFAULTS \ diff --git a/include/git2/submodule.h b/include/git2/submodule.h index 29d8bc1ce55..c6eeb96dc45 100644 --- a/include/git2/submodule.h +++ b/include/git2/submodule.h @@ -85,7 +85,7 @@ typedef enum { GIT_SUBMODULE_STATUS_WD_MODIFIED = (1u << 10), GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED = (1u << 11), GIT_SUBMODULE_STATUS_WD_WD_MODIFIED = (1u << 12), - GIT_SUBMODULE_STATUS_WD_UNTRACKED = (1u << 13), + GIT_SUBMODULE_STATUS_WD_UNTRACKED = (1u << 13) } git_submodule_status_t; #define GIT_SUBMODULE_STATUS__IN_FLAGS 0x000Fu diff --git a/include/git2/sys/commit_graph.h b/include/git2/sys/commit_graph.h index f6c0fc4b5db..823c7ed579b 100644 --- a/include/git2/sys/commit_graph.h +++ b/include/git2/sys/commit_graph.h @@ -94,7 +94,7 @@ typedef enum { * Do not split commit-graph files. The other split strategy-related option * fields are ignored. */ - GIT_COMMIT_GRAPH_SPLIT_STRATEGY_SINGLE_FILE = 0, + GIT_COMMIT_GRAPH_SPLIT_STRATEGY_SINGLE_FILE = 0 } git_commit_graph_split_strategy_t; /** diff --git a/include/git2/sys/stream.h b/include/git2/sys/stream.h index 6f93cc48c32..e0e03a2d764 100644 --- a/include/git2/sys/stream.h +++ b/include/git2/sys/stream.h @@ -79,7 +79,7 @@ typedef enum { GIT_STREAM_STANDARD = 1, /** A TLS-encrypted socket. */ - GIT_STREAM_TLS = 2, + GIT_STREAM_TLS = 2 } git_stream_t; /** diff --git a/include/git2/sys/transport.h b/include/git2/sys/transport.h index fee34544fa9..76003ee8470 100644 --- a/include/git2/sys/transport.h +++ b/include/git2/sys/transport.h @@ -30,7 +30,7 @@ GIT_BEGIN_DECL * Currently unused. */ typedef enum { - GIT_TRANSPORTFLAGS_NONE = 0, + GIT_TRANSPORTFLAGS_NONE = 0 } git_transport_flags_t; struct git_transport { @@ -289,7 +289,7 @@ typedef enum { GIT_SERVICE_UPLOADPACK_LS = 1, GIT_SERVICE_UPLOADPACK = 2, GIT_SERVICE_RECEIVEPACK_LS = 3, - GIT_SERVICE_RECEIVEPACK = 4, + GIT_SERVICE_RECEIVEPACK = 4 } git_smart_service_t; typedef struct git_smart_subtransport git_smart_subtransport; diff --git a/include/git2/tree.h b/include/git2/tree.h index f2289fc7e6c..db24bf6ed55 100644 --- a/include/git2/tree.h +++ b/include/git2/tree.h @@ -386,7 +386,7 @@ typedef int GIT_CALLBACK(git_treewalk_cb)( /** Tree traversal modes */ typedef enum { GIT_TREEWALK_PRE = 0, /* Pre-order */ - GIT_TREEWALK_POST = 1, /* Post-order */ + GIT_TREEWALK_POST = 1 /* Post-order */ } git_treewalk_mode; /** @@ -428,7 +428,7 @@ typedef enum { /** Update or insert an entry at the specified path */ GIT_TREE_UPDATE_UPSERT, /** Remove an entry from the specified path */ - GIT_TREE_UPDATE_REMOVE, + GIT_TREE_UPDATE_REMOVE } git_tree_update_t; /** diff --git a/include/git2/types.h b/include/git2/types.h index aac8e42e285..34d8c99ef7c 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -78,7 +78,7 @@ typedef enum { GIT_OBJECT_BLOB = 3, /**< A file revision object. */ GIT_OBJECT_TAG = 4, /**< An annotated tag object. */ GIT_OBJECT_OFS_DELTA = 6, /**< A delta, base is given by an offset. */ - GIT_OBJECT_REF_DELTA = 7, /**< A delta, base is given by object id. */ + GIT_OBJECT_REF_DELTA = 7 /**< A delta, base is given by object id. */ } git_object_t; /** An open object database handle. */ @@ -208,14 +208,14 @@ typedef enum { GIT_REFERENCE_INVALID = 0, /**< Invalid reference */ GIT_REFERENCE_DIRECT = 1, /**< A reference that points at an object id */ GIT_REFERENCE_SYMBOLIC = 2, /**< A reference that points at another reference */ - GIT_REFERENCE_ALL = GIT_REFERENCE_DIRECT | GIT_REFERENCE_SYMBOLIC, + GIT_REFERENCE_ALL = GIT_REFERENCE_DIRECT | GIT_REFERENCE_SYMBOLIC } git_reference_t; /** Basic type of any Git branch. */ typedef enum { GIT_BRANCH_LOCAL = 1, GIT_BRANCH_REMOTE = 2, - GIT_BRANCH_ALL = GIT_BRANCH_LOCAL|GIT_BRANCH_REMOTE, + GIT_BRANCH_ALL = GIT_BRANCH_LOCAL|GIT_BRANCH_REMOTE } git_branch_t; /** Valid modes for index and tree entries. */ @@ -225,7 +225,7 @@ typedef enum { GIT_FILEMODE_BLOB = 0100644, GIT_FILEMODE_BLOB_EXECUTABLE = 0100755, GIT_FILEMODE_LINK = 0120000, - GIT_FILEMODE_COMMIT = 0160000, + GIT_FILEMODE_COMMIT = 0160000 } git_filemode_t; /** @@ -334,7 +334,7 @@ typedef enum { GIT_SUBMODULE_IGNORE_NONE = 1, /**< any change or untracked == dirty */ GIT_SUBMODULE_IGNORE_UNTRACKED = 2, /**< dirty if tracked files change */ GIT_SUBMODULE_IGNORE_DIRTY = 3, /**< only dirty if HEAD moved */ - GIT_SUBMODULE_IGNORE_ALL = 4, /**< never dirty */ + GIT_SUBMODULE_IGNORE_ALL = 4 /**< never dirty */ } git_submodule_ignore_t; /** @@ -350,7 +350,7 @@ typedef enum { typedef enum { GIT_SUBMODULE_RECURSE_NO = 0, GIT_SUBMODULE_RECURSE_YES = 1, - GIT_SUBMODULE_RECURSE_ONDEMAND = 2, + GIT_SUBMODULE_RECURSE_ONDEMAND = 2 } git_submodule_recurse_t; typedef struct git_writestream git_writestream; diff --git a/include/git2/worktree.h b/include/git2/worktree.h index 23084d8cd87..85cf1a6084a 100644 --- a/include/git2/worktree.h +++ b/include/git2/worktree.h @@ -185,7 +185,7 @@ typedef enum { /* Prune working tree even if it is locked */ GIT_WORKTREE_PRUNE_LOCKED = 1u << 1, /* Prune checked out working tree */ - GIT_WORKTREE_PRUNE_WORKING_TREE = 1u << 2, + GIT_WORKTREE_PRUNE_WORKING_TREE = 1u << 2 } git_worktree_prune_t; /** From 43d9f0e3fe96823d88475fd9edae07732c84dbc8 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Fri, 22 Oct 2021 22:39:10 +0200 Subject: [PATCH 0649/1616] ntmlclient: make enum C90 compliant by removing trailing comma --- deps/ntlmclient/ntlm.h | 8 ++++---- deps/ntlmclient/ntlmclient.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/deps/ntlmclient/ntlm.h b/deps/ntlmclient/ntlm.h index 227f5bcbafa..4abfd7a8528 100644 --- a/deps/ntlmclient/ntlm.h +++ b/deps/ntlmclient/ntlm.h @@ -30,7 +30,7 @@ typedef enum { NTLM_STATE_CHALLENGE = 1, NTLM_STATE_RESPONSE = 2, NTLM_STATE_ERROR = 3, - NTLM_STATE_COMPLETE = 4, + NTLM_STATE_COMPLETE = 4 } ntlm_state; typedef struct { @@ -122,7 +122,7 @@ struct ntlm_client { }; typedef enum { - NTLM_ENABLE_HOSTVERSION = (1 << 31), + NTLM_ENABLE_HOSTVERSION = (1 << 31) } ntlm_client_internal_flags; typedef enum { @@ -130,7 +130,7 @@ typedef enum { NTLM_TARGET_INFO_SERVER = 1, NTLM_TARGET_INFO_DOMAIN = 2, NTLM_TARGET_INFO_SERVER_DNS = 3, - NTLM_TARGET_INFO_DOMAIN_DNS = 4, + NTLM_TARGET_INFO_DOMAIN_DNS = 4 } ntlm_target_info_type_t; typedef enum { @@ -168,7 +168,7 @@ typedef enum { NTLM_NEGOTIATE_TARGET_INFO = 0x00800000, /* Version information should be provided */ - NTLM_NEGOTIATE_VERSION = 0x01000000, + NTLM_NEGOTIATE_VERSION = 0x01000000 } ntlm_negotiate_t; extern int ntlm_client_set_nonce(ntlm_client *ntlm, uint64_t nonce); diff --git a/deps/ntlmclient/ntlmclient.h b/deps/ntlmclient/ntlmclient.h index bf57b17c6fd..958b27e6246 100644 --- a/deps/ntlmclient/ntlmclient.h +++ b/deps/ntlmclient/ntlmclient.h @@ -32,7 +32,7 @@ typedef enum { /** * The input provided to the function is missing or invalid. */ - NTLM_CLIENT_ERROR_INVALID_INPUT = -2, + NTLM_CLIENT_ERROR_INVALID_INPUT = -2 } ntlm_error_code; /* @@ -98,7 +98,7 @@ typedef enum { * its idea of its hostname in the challenge message. You may * then set the authentication target based on it. */ - NTLM_CLIENT_DISABLE_REQUEST_TARGET = (1 << 4), + NTLM_CLIENT_DISABLE_REQUEST_TARGET = (1 << 4) } ntlm_client_flags; From 7dcc29fc4652caeb09de39827cfd1a80726b5995 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Fri, 22 Oct 2021 22:51:59 +0200 Subject: [PATCH 0650/1616] Make enum in src,tests and examples C90 compliant by removing trailing comma. --- examples/add.c | 2 +- examples/remote.c | 2 +- examples/status.c | 2 +- src/annotated_commit.h | 2 +- src/checkout.c | 2 +- src/commit.h | 2 +- src/commit_graph.c | 2 +- src/crlf.c | 2 +- src/diff.h | 2 +- src/diff_driver.c | 2 +- src/diff_generate.h | 4 ++-- src/futils.h | 6 +++--- src/ignore.h | 2 +- src/index.c | 2 +- src/iterator.c | 2 +- src/iterator.h | 4 ++-- src/merge.h | 6 +++--- src/netops.h | 2 +- src/odb.h | 2 +- src/patch_generate.h | 2 +- src/patch_parse.c | 2 +- src/pathspec.h | 2 +- src/pqueue.h | 2 +- src/rebase.c | 2 +- src/refdb_fs.c | 2 +- src/repository.h | 4 ++-- src/submodule.c | 2 +- src/submodule.h | 2 +- src/sysdir.h | 2 +- src/trailer.c | 2 +- src/transaction.c | 2 +- src/transports/auth.h | 2 +- src/transports/smart.h | 2 +- src/transports/winhttp.c | 2 +- src/vector.h | 2 +- src/zstream.h | 2 +- tests/clar.h | 6 +++--- 37 files changed, 46 insertions(+), 46 deletions(-) diff --git a/examples/add.c b/examples/add.c index 4ff7c79e2ab..1c93b11404a 100644 --- a/examples/add.c +++ b/examples/add.c @@ -28,7 +28,7 @@ enum index_mode { INDEX_NONE, - INDEX_ADD, + INDEX_ADD }; struct index_options { diff --git a/examples/remote.c b/examples/remote.c index 57f758c6ca3..14fac030cd1 100644 --- a/examples/remote.c +++ b/examples/remote.c @@ -27,7 +27,7 @@ enum subcmd { subcmd_remove, subcmd_rename, subcmd_seturl, - subcmd_show, + subcmd_show }; struct remote_opts { diff --git a/examples/status.c b/examples/status.c index 8cf922127bf..e659efb059b 100644 --- a/examples/status.c +++ b/examples/status.c @@ -38,7 +38,7 @@ enum { FORMAT_DEFAULT = 0, FORMAT_LONG = 1, FORMAT_SHORT = 2, - FORMAT_PORCELAIN = 3, + FORMAT_PORCELAIN = 3 }; #define MAX_PATHSPEC 8 diff --git a/src/annotated_commit.h b/src/annotated_commit.h index b390066b2c9..444a2ed1072 100644 --- a/src/annotated_commit.h +++ b/src/annotated_commit.h @@ -15,7 +15,7 @@ typedef enum { GIT_ANNOTATED_COMMIT_REAL = 1, - GIT_ANNOTATED_COMMIT_VIRTUAL = 2, + GIT_ANNOTATED_COMMIT_VIRTUAL = 2 } git_annotated_commit_t; /** diff --git a/src/checkout.c b/src/checkout.c index 5733f4ab56c..11be2e84fa3 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -45,7 +45,7 @@ enum { CHECKOUT_ACTION__UPDATE_CONFLICT = 32, CHECKOUT_ACTION__MAX = 32, CHECKOUT_ACTION__REMOVE_AND_UPDATE = - (CHECKOUT_ACTION__UPDATE_BLOB | CHECKOUT_ACTION__REMOVE), + (CHECKOUT_ACTION__UPDATE_BLOB | CHECKOUT_ACTION__REMOVE) }; typedef struct { diff --git a/src/commit.h b/src/commit.h index 9378eab2d0c..7a2454e6192 100644 --- a/src/commit.h +++ b/src/commit.h @@ -61,7 +61,7 @@ int git_commit__parse(void *commit, git_odb_object *obj); int git_commit__parse_raw(void *commit, const char *data, size_t size); typedef enum { - GIT_COMMIT_PARSE_QUICK = (1 << 0), /**< Only parse parents and committer info */ + GIT_COMMIT_PARSE_QUICK = (1 << 0) /**< Only parse parents and committer info */ } git_commit__parse_flags; int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned int flags); diff --git a/src/commit_graph.c b/src/commit_graph.c index f9a4bd2b270..924a3992b0c 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -754,7 +754,7 @@ enum generation_number_commit_state { GENERATION_NUMBER_COMMIT_STATE_UNVISITED = 0, GENERATION_NUMBER_COMMIT_STATE_ADDED = 1, GENERATION_NUMBER_COMMIT_STATE_EXPANDED = 2, - GENERATION_NUMBER_COMMIT_STATE_VISITED = 3, + GENERATION_NUMBER_COMMIT_STATE_VISITED = 3 }; static int compute_generation_numbers(git_vector *commits) diff --git a/src/crlf.c b/src/crlf.c index 7895ddec2a9..1e1f1e84558 100644 --- a/src/crlf.c +++ b/src/crlf.c @@ -26,7 +26,7 @@ typedef enum { GIT_CRLF_TEXT_CRLF, GIT_CRLF_AUTO, GIT_CRLF_AUTO_INPUT, - GIT_CRLF_AUTO_CRLF, + GIT_CRLF_AUTO_CRLF } git_crlf_t; struct crlf_attrs { diff --git a/src/diff.h b/src/diff.h index 4b033980912..2cc35e65b7c 100644 --- a/src/diff.h +++ b/src/diff.h @@ -26,7 +26,7 @@ typedef enum { GIT_DIFF_TYPE_UNKNOWN = 0, GIT_DIFF_TYPE_GENERATED = 1, - GIT_DIFF_TYPE_PARSED = 2, + GIT_DIFF_TYPE_PARSED = 2 } git_diff_origin_t; struct git_diff { diff --git a/src/diff_driver.c b/src/diff_driver.c index f6b51d8bae6..a20723fcc7a 100644 --- a/src/diff_driver.c +++ b/src/diff_driver.c @@ -21,7 +21,7 @@ typedef enum { DIFF_DRIVER_AUTO = 0, DIFF_DRIVER_BINARY = 1, DIFF_DRIVER_TEXT = 2, - DIFF_DRIVER_PATTERNLIST = 3, + DIFF_DRIVER_PATTERNLIST = 3 } git_diff_driver_t; typedef struct { diff --git a/src/diff_generate.h b/src/diff_generate.h index 5186d552c2c..f39bf6b2a38 100644 --- a/src/diff_generate.h +++ b/src/diff_generate.h @@ -18,7 +18,7 @@ enum { GIT_DIFFCAPS_IGNORE_STAT = (1 << 1), /* use stat? */ GIT_DIFFCAPS_TRUST_MODE_BITS = (1 << 2), /* use st_mode? */ GIT_DIFFCAPS_TRUST_CTIME = (1 << 3), /* use st_ctime? */ - GIT_DIFFCAPS_USE_DEV = (1 << 4), /* use st_dev? */ + GIT_DIFFCAPS_USE_DEV = (1 << 4) /* use st_dev? */ }; #define DIFF_FLAGS_KNOWN_BINARY (GIT_DIFF_FLAG_BINARY|GIT_DIFF_FLAG_NOT_BINARY) @@ -36,7 +36,7 @@ enum { GIT_DIFF_FLAG__TO_SPLIT = (1 << 17), /* split entry during rename det. */ GIT_DIFF_FLAG__IS_RENAME_TARGET = (1 << 18), GIT_DIFF_FLAG__IS_RENAME_SOURCE = (1 << 19), - GIT_DIFF_FLAG__HAS_SELF_SIMILARITY = (1 << 20), + GIT_DIFF_FLAG__HAS_SELF_SIMILARITY = (1 << 20) }; #define GIT_DIFF_FLAG__CLEAR_INTERNAL(F) (F) = ((F) & 0x00FFFF) diff --git a/src/futils.h b/src/futils.h index 22098addfe3..1386dc482b5 100644 --- a/src/futils.h +++ b/src/futils.h @@ -96,7 +96,7 @@ typedef enum { GIT_MKDIR_SKIP_LAST2 = 32, GIT_MKDIR_VERIFY_DIR = 64, GIT_MKDIR_REMOVE_FILES = 128, - GIT_MKDIR_REMOVE_SYMLINKS = 256, + GIT_MKDIR_REMOVE_SYMLINKS = 256 } git_futils_mkdir_flags; struct git_futils_mkdir_perfdata @@ -159,7 +159,7 @@ typedef enum { GIT_RMDIR_SKIP_NONEMPTY = (1 << 1), GIT_RMDIR_EMPTY_PARENTS = (1 << 2), GIT_RMDIR_REMOVE_BLOCKERS = (1 << 3), - GIT_RMDIR_SKIP_ROOT = (1 << 4), + GIT_RMDIR_SKIP_ROOT = (1 << 4) } git_futils_rmdir_flags; /** @@ -224,7 +224,7 @@ typedef enum { GIT_CPDIR_OVERWRITE = (1u << 3), GIT_CPDIR_CHMOD_DIRS = (1u << 4), GIT_CPDIR_SIMPLE_TO_MODE = (1u << 5), - GIT_CPDIR_LINK_FILES = (1u << 6), + GIT_CPDIR_LINK_FILES = (1u << 6) } git_futils_cpdir_flags; /** diff --git a/src/ignore.h b/src/ignore.h index 7991952589a..aa5ca62b7af 100644 --- a/src/ignore.h +++ b/src/ignore.h @@ -48,7 +48,7 @@ enum { GIT_IGNORE_UNCHECKED = -2, GIT_IGNORE_NOTFOUND = -1, GIT_IGNORE_FALSE = 0, - GIT_IGNORE_TRUE = 1, + GIT_IGNORE_TRUE = 1 }; extern int git_ignore__lookup(int *out, git_ignores *ign, const char *path, git_dir_flag dir_flag); diff --git a/src/index.c b/src/index.c index bd6ea8f03eb..7ade4341fcc 100644 --- a/src/index.c +++ b/src/index.c @@ -3386,7 +3386,7 @@ enum { INDEX_ACTION_NONE = 0, INDEX_ACTION_UPDATE = 1, INDEX_ACTION_REMOVE = 2, - INDEX_ACTION_ADDALL = 3, + INDEX_ACTION_ADDALL = 3 }; int git_index_add_all( diff --git a/src/iterator.c b/src/iterator.c index a4337bb9ad4..15bb63dc83d 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -293,7 +293,7 @@ typedef enum { ITERATOR_PATHLIST_IS_FILE = 1, ITERATOR_PATHLIST_IS_DIR = 2, ITERATOR_PATHLIST_IS_PARENT = 3, - ITERATOR_PATHLIST_FULL = 4, + ITERATOR_PATHLIST_FULL = 4 } iterator_pathlist_search_t; static iterator_pathlist_search_t iterator_pathlist_search( diff --git a/src/iterator.h b/src/iterator.h index e55c1047ab3..6bb8489d035 100644 --- a/src/iterator.h +++ b/src/iterator.h @@ -21,7 +21,7 @@ typedef enum { GIT_ITERATOR_TREE = 1, GIT_ITERATOR_INDEX = 2, GIT_ITERATOR_WORKDIR = 3, - GIT_ITERATOR_FS = 4, + GIT_ITERATOR_FS = 4 } git_iterator_t; typedef enum { @@ -42,7 +42,7 @@ typedef enum { /** descend into symlinked directories */ GIT_ITERATOR_DESCEND_SYMLINKS = (1u << 7), /** hash files in workdir or filesystem iterators */ - GIT_ITERATOR_INCLUDE_HASH = (1u << 8), + GIT_ITERATOR_INCLUDE_HASH = (1u << 8) } git_iterator_flag_t; typedef enum { diff --git a/src/merge.h b/src/merge.h index 3e7f80c6ee2..632f2d8e3ae 100644 --- a/src/merge.h +++ b/src/merge.h @@ -29,12 +29,12 @@ /** Internal merge flags. */ enum { /** The merge is for a virtual base in a recursive merge. */ - GIT_MERGE__VIRTUAL_BASE = (1 << 31), + GIT_MERGE__VIRTUAL_BASE = (1 << 31) }; enum { /** Accept the conflict file, staging it as the merge result. */ - GIT_MERGE_FILE_FAVOR__CONFLICTED = 4, + GIT_MERGE_FILE_FAVOR__CONFLICTED = 4 }; @@ -83,7 +83,7 @@ typedef enum { GIT_MERGE_DIFF_DIRECTORY_FILE = (1 << 10), /* The child of a folder that is in a directory/file conflict. */ - GIT_MERGE_DIFF_DF_CHILD = (1 << 11), + GIT_MERGE_DIFF_DF_CHILD = (1 << 11) } git_merge_diff_t; typedef struct { diff --git a/src/netops.h b/src/netops.h index 7140b39bc45..56f96853459 100644 --- a/src/netops.h +++ b/src/netops.h @@ -42,7 +42,7 @@ typedef struct gitno_buffer { /* Flags to gitno_connect */ enum { /* Attempt to create an SSL connection. */ - GITNO_CONNECT_SSL = 1, + GITNO_CONNECT_SSL = 1 }; /** diff --git a/src/odb.h b/src/odb.h index 4a8ebff1913..5aa4cc84a4c 100644 --- a/src/odb.h +++ b/src/odb.h @@ -53,7 +53,7 @@ struct git_odb { }; typedef enum { - GIT_ODB_CAP_FROM_OWNER = -1, + GIT_ODB_CAP_FROM_OWNER = -1 } git_odb_cap_t; /* diff --git a/src/patch_generate.h b/src/patch_generate.h index 20f78cbfab8..0e09d27ca4e 100644 --- a/src/patch_generate.h +++ b/src/patch_generate.h @@ -21,7 +21,7 @@ enum { GIT_PATCH_GENERATED_DIFFABLE = (1 << 3), /* the difference between the two sides has been computed */ GIT_PATCH_GENERATED_DIFFED = (1 << 4), - GIT_PATCH_GENERATED_FLATTENED = (1 << 5), + GIT_PATCH_GENERATED_FLATTENED = (1 << 5) }; struct git_patch_generated { diff --git a/src/patch_parse.c b/src/patch_parse.c index 891cf79a3a1..37822fcccaa 100644 --- a/src/patch_parse.c +++ b/src/patch_parse.c @@ -382,7 +382,7 @@ typedef enum { STATE_RENAME, STATE_COPY, - STATE_END, + STATE_END } parse_header_state; typedef struct { diff --git a/src/pathspec.h b/src/pathspec.h index bfdcd48a707..0256cb92775 100644 --- a/src/pathspec.h +++ b/src/pathspec.h @@ -25,7 +25,7 @@ struct git_pathspec { enum { PATHSPEC_DATATYPE_STRINGS = 0, - PATHSPEC_DATATYPE_DIFF = 1, + PATHSPEC_DATATYPE_DIFF = 1 }; typedef git_array_t(char *) git_pathspec_string_array_t; diff --git a/src/pqueue.h b/src/pqueue.h index c0a6cd49e47..4db74ea0371 100644 --- a/src/pqueue.h +++ b/src/pqueue.h @@ -15,7 +15,7 @@ typedef git_vector git_pqueue; enum { /* flag meaning: don't grow heap, keep highest values only */ - GIT_PQUEUE_FIXED_SIZE = (GIT_VECTOR_FLAG_MAX << 1), + GIT_PQUEUE_FIXED_SIZE = (GIT_VECTOR_FLAG_MAX << 1) }; /** diff --git a/src/rebase.c b/src/rebase.c index 26b03b38c8a..4ad37643b76 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -53,7 +53,7 @@ typedef enum { GIT_REBASE_NONE = 0, GIT_REBASE_APPLY = 1, GIT_REBASE_MERGE = 2, - GIT_REBASE_INTERACTIVE = 3, + GIT_REBASE_INTERACTIVE = 3 } git_rebase_t; struct git_rebase { diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 097d2b38ec8..055ca2559ce 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -35,7 +35,7 @@ enum { PACKREF_HAS_PEEL = 1, PACKREF_WAS_LOOSE = 2, PACKREF_CANNOT_PEEL = 4, - PACKREF_SHADOWED = 8, + PACKREF_SHADOWED = 8 }; enum { diff --git a/src/repository.h b/src/repository.h index 1ea5a44f767..3c3aa1e8ea4 100644 --- a/src/repository.h +++ b/src/repository.h @@ -118,14 +118,14 @@ typedef enum { /* core.fsyncObjectFiles */ GIT_FSYNCOBJECTFILES_DEFAULT = GIT_CONFIGMAP_FALSE, /* core.longpaths */ - GIT_LONGPATHS_DEFAULT = GIT_CONFIGMAP_FALSE, + GIT_LONGPATHS_DEFAULT = GIT_CONFIGMAP_FALSE } git_configmap_value; /* internal repository init flags */ enum { GIT_REPOSITORY_INIT__HAS_DOTGIT = (1u << 16), GIT_REPOSITORY_INIT__NATURAL_WD = (1u << 17), - GIT_REPOSITORY_INIT__IS_REINIT = (1u << 18), + GIT_REPOSITORY_INIT__IS_REINIT = (1u << 18) }; /** Internal structure for repository object */ diff --git a/src/submodule.c b/src/submodule.c index 0370ac82b38..0f4f0726c9f 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -61,7 +61,7 @@ enum { }; enum { GITMODULES_EXISTING = 0, - GITMODULES_CREATE = 1, + GITMODULES_CREATE = 1 }; static int submodule_alloc(git_submodule **out, git_repository *repo, const char *name); diff --git a/src/submodule.h b/src/submodule.h index b01ff68a203..7fa98248620 100644 --- a/src/submodule.h +++ b/src/submodule.h @@ -110,7 +110,7 @@ enum { GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE = (1u << 24), GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE = (1u << 25), GIT_SUBMODULE_STATUS__WD_NOT_SUBMODULE = (1u << 26), - GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES = (1u << 27), + GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES = (1u << 27) }; #define GIT_SUBMODULE_STATUS__CLEAR_INTERNAL(S) \ diff --git a/src/sysdir.h b/src/sysdir.h index d12bac9d9be..43392a0226c 100644 --- a/src/sysdir.h +++ b/src/sysdir.h @@ -74,7 +74,7 @@ typedef enum { GIT_SYSDIR_XDG = 2, GIT_SYSDIR_PROGRAMDATA = 3, GIT_SYSDIR_TEMPLATE = 4, - GIT_SYSDIR__MAX = 5, + GIT_SYSDIR__MAX = 5 } git_sysdir_t; /** diff --git a/src/trailer.c b/src/trailer.c index 61cdd1ba170..4761c9922f2 100644 --- a/src/trailer.c +++ b/src/trailer.c @@ -286,7 +286,7 @@ enum trailer_state { S_VALUE = 4, S_VALUE_NL = 5, S_VALUE_END = 6, - S_IGNORE = 7, + S_IGNORE = 7 }; #define NEXT(st) { state = (st); ptr++; continue; } diff --git a/src/transaction.c b/src/transaction.c index 98fa1ba900c..ccffa9984cc 100644 --- a/src/transaction.c +++ b/src/transaction.c @@ -23,7 +23,7 @@ typedef enum { TRANSACTION_NONE, TRANSACTION_REFS, - TRANSACTION_CONFIG, + TRANSACTION_CONFIG } transaction_t; typedef struct { diff --git a/src/transports/auth.h b/src/transports/auth.h index 824d7198cfc..64680cc5358 100644 --- a/src/transports/auth.h +++ b/src/transports/auth.h @@ -15,7 +15,7 @@ typedef enum { GIT_HTTP_AUTH_BASIC = 1, GIT_HTTP_AUTH_NEGOTIATE = 2, - GIT_HTTP_AUTH_NTLM = 4, + GIT_HTTP_AUTH_NTLM = 4 } git_http_auth_t; typedef struct git_http_auth_context git_http_auth_context; diff --git a/src/transports/smart.h b/src/transports/smart.h index 225e64996c7..a9cab31acd9 100644 --- a/src/transports/smart.h +++ b/src/transports/smart.h @@ -46,7 +46,7 @@ typedef enum { GIT_PKT_PROGRESS, GIT_PKT_OK, GIT_PKT_NG, - GIT_PKT_UNPACK, + GIT_PKT_UNPACK } git_pkt_type; /* Used for multi_ack and multi_ack_detailed */ diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index efbaf0298a7..60f536fdb9f 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -99,7 +99,7 @@ typedef enum { GIT_WINHTTP_AUTH_BASIC = 1, GIT_WINHTTP_AUTH_NTLM = 2, GIT_WINHTTP_AUTH_NEGOTIATE = 4, - GIT_WINHTTP_AUTH_DIGEST = 8, + GIT_WINHTTP_AUTH_DIGEST = 8 } winhttp_authmechanism_t; typedef struct { diff --git a/src/vector.h b/src/vector.h index 3dcec3d1319..ae3c79a4cdb 100644 --- a/src/vector.h +++ b/src/vector.h @@ -13,7 +13,7 @@ typedef int (*git_vector_cmp)(const void *, const void *); enum { GIT_VECTOR_SORTED = (1u << 0), - GIT_VECTOR_FLAG_MAX = (1u << 1), + GIT_VECTOR_FLAG_MAX = (1u << 1) }; typedef struct git_vector { diff --git a/src/zstream.h b/src/zstream.h index 3a59d9a369d..3f8b1c72ff4 100644 --- a/src/zstream.h +++ b/src/zstream.h @@ -15,7 +15,7 @@ typedef enum { GIT_ZSTREAM_INFLATE, - GIT_ZSTREAM_DEFLATE, + GIT_ZSTREAM_DEFLATE } git_zstream_t; typedef struct { diff --git a/tests/clar.h b/tests/clar.h index 8c22382bd56..3f659c2f6c4 100644 --- a/tests/clar.h +++ b/tests/clar.h @@ -13,12 +13,12 @@ enum cl_test_status { CL_TEST_OK, CL_TEST_FAILURE, CL_TEST_SKIP, - CL_TEST_NOTRUN, + CL_TEST_NOTRUN }; enum cl_output_format { CL_OUTPUT_CLAP, - CL_OUTPUT_TAP, + CL_OUTPUT_TAP }; /** Setup clar environment */ @@ -60,7 +60,7 @@ typedef enum cl_trace_event { CL_TRACE__TEST__END, CL_TRACE__TEST__RUN_BEGIN, CL_TRACE__TEST__RUN_END, - CL_TRACE__TEST__LONGJMP, + CL_TRACE__TEST__LONGJMP } cl_trace_event; typedef void (cl_trace_cb)( From 86685f8f1d586b0201ab51d8e5923379967f4e74 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 16 Nov 2021 17:10:08 -0500 Subject: [PATCH 0651/1616] cmake: better explain why headertests exists --- tests/CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d42c6ad5ba4..b42359a637c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -80,14 +80,19 @@ add_clar_test(proxy -v -sonline::clone::proxy) add_clar_test(auth_clone -v -sonline::clone::cred) add_clar_test(auth_clone_and_push -v -sonline::clone::push -sonline::push) -# Header file validation project +# +# Header file validation project: ensure that we do not publish any sloppy +# definitions in our headers and that a consumer can include +# even when they have aggressive C90 warnings enabled. +# + add_executable(headertest headertest.c) set_target_properties(headertest PROPERTIES C_STANDARD 90) set_target_properties(headertest PROPERTIES C_EXTENSIONS OFF) target_include_directories(headertest PRIVATE ${LIBGIT2_INCLUDES}) if (MSVC) - target_compile_options(headertest PUBLIC /W4 /WX) + target_compile_options(headertest PUBLIC /W4 /WX) else() - target_compile_options(headertest PUBLIC -Wall -Wextra -pedantic -Werror) + target_compile_options(headertest PUBLIC -Wall -Wextra -pedantic -Werror) endif() From 6b2ea90966fd090e3b134ec57b85a8adfe4b89be Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 16 Nov 2021 23:21:29 -0500 Subject: [PATCH 0652/1616] tag: set validity to 0 by default `git_tag_name_is_valid` needs to set validity to 0 when it short-circuits. --- src/tag.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tag.c b/src/tag.c index 7a155147d1c..837658a19f3 100644 --- a/src/tag.c +++ b/src/tag.c @@ -539,6 +539,8 @@ int git_tag_name_is_valid(int *valid, const char *name) GIT_ASSERT(valid); + *valid = 0; + /* * Discourage tag name starting with dash, * https://github.com/git/git/commit/4f0accd638b8d2 From 4a54d8e39e053377a877c65e897f2424b11a51e4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 17 Nov 2021 07:27:39 -0500 Subject: [PATCH 0653/1616] cmake: enable testing at the top level Ensure that we `enable_testing()` at the top-level CMakeLists.txt or else we'll need to navigate within the build directory to the correct place in the hierarchy to run `ctest`. Now we can `ctest` at the top-level again. --- CMakeLists.txt | 1 + tests/CMakeLists.txt | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 664abc0d23b..c414bbe3ad0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,6 +111,7 @@ include(DefaultCFlags) add_subdirectory(src) if(BUILD_TESTS) + enable_testing() add_subdirectory(tests) endif() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b42359a637c..84df92a451e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -68,8 +68,6 @@ function(ADD_CLAR_TEST name) endif() endfunction(ADD_CLAR_TEST) -enable_testing() - add_clar_test(offline -v -xonline) add_clar_test(invasive -v -score::ftruncate -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root) add_clar_test(online -v -sonline -xonline::customcert) From 1b8d14ac2a31eb48665ffbf2a984399a77ea62d8 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 17 Nov 2021 08:25:56 -0500 Subject: [PATCH 0654/1616] cmake: use WINHTTP when USE_WINHTTP is specified --- cmake/SelectWinHTTP.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/SelectWinHTTP.cmake b/cmake/SelectWinHTTP.cmake index 1d950c9009d..667b4007e8a 100644 --- a/cmake/SelectWinHTTP.cmake +++ b/cmake/SelectWinHTTP.cmake @@ -1,4 +1,4 @@ -if(WIN32 AND WINHTTP) +if(WIN32 AND USE_WINHTTP) set(GIT_WINHTTP 1) # Since MinGW does not come with headers or an import library for winhttp, From b2c40314c7c8ae4b645f776f04dfe06983ad8ba3 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 18 Nov 2021 12:19:32 -0500 Subject: [PATCH 0655/1616] date: make it a proper `git_date` utility class Instead of `git__date`, just use `git_date`. --- src/date.c | 4 ++-- src/date.h | 33 +++++++++++++++++++++++++++++++++ src/email.c | 3 ++- src/revparse.c | 3 ++- src/util.h | 20 -------------------- tests/date/date.c | 6 +++--- tests/date/rfc2822.c | 10 +++++----- 7 files changed, 47 insertions(+), 32 deletions(-) create mode 100644 src/date.h diff --git a/src/date.c b/src/date.c index 2297ee66cf3..f7498e77fe4 100644 --- a/src/date.c +++ b/src/date.c @@ -857,7 +857,7 @@ static git_time_t approxidate_str(const char *date, return update_tm(&tm, &now, 0); } -int git__date_parse(git_time_t *out, const char *date) +int git_date_parse(git_time_t *out, const char *date) { time_t time_sec; git_time_t timestamp; @@ -875,7 +875,7 @@ int git__date_parse(git_time_t *out, const char *date) return error_ret; } -int git__date_rfc2822_fmt(char *out, size_t len, const git_time *date) +int git_date_rfc2822_fmt(char *out, size_t len, const git_time *date) { int written; struct tm gmt; diff --git a/src/date.h b/src/date.h new file mode 100644 index 00000000000..133f20b3797 --- /dev/null +++ b/src/date.h @@ -0,0 +1,33 @@ +/* + * 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_date_h__ +#define INCLUDE_date_h__ + +#include "util.h" +#include "str.h" + +/* + * Parse a string into a value as a git_time_t. + * + * Sample valid input: + * - "yesterday" + * - "July 17, 2003" + * - "2003-7-17 08:23" + */ +extern int git_date_parse(git_time_t *out, const char *date); + +/* + * Format a git_time as a RFC2822 string + * + * @param out buffer to store formatted date; a '\\0' terminator will automatically be added. + * @param len size of the buffer; should be atleast `GIT_DATE_RFC2822_SZ` in size; + * @param date the date to be formatted + * @return 0 if successful; -1 on error + */ +extern int git_date_rfc2822_fmt(char *out, size_t len, const git_time *date); + +#endif diff --git a/src/email.c b/src/email.c index 3459c054034..66ed2dd9fb8 100644 --- a/src/email.c +++ b/src/email.c @@ -12,6 +12,7 @@ #include "diff_generate.h" #include "diff_stats.h" #include "patch.h" +#include "date.h" #include "git2/email.h" #include "git2/patch.h" @@ -123,7 +124,7 @@ static int append_header( if ((error = git_oid_fmt(id, commit_id)) < 0 || (error = git_str_printf(out, "From %.*s %s\n", GIT_OID_HEXSZ, id, EMAIL_TIMESTAMP)) < 0 || (error = git_str_printf(out, "From: %s <%s>\n", author->name, author->email)) < 0 || - (error = git__date_rfc2822_fmt(date, sizeof(date), &author->when)) < 0 || + (error = git_date_rfc2822_fmt(date, sizeof(date), &author->when)) < 0 || (error = git_str_printf(out, "Date: %s\n", date)) < 0 || (error = append_subject(out, patch_idx, patch_count, summary, opts)) < 0) return error; diff --git a/src/revparse.c b/src/revparse.c index cf39936a5b1..52dd0720ba8 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -11,6 +11,7 @@ #include "tree.h" #include "refdb.h" #include "regexp.h" +#include "date.h" #include "git2.h" @@ -344,7 +345,7 @@ static int handle_at_syntax(git_object **out, git_reference **ref, const char *s goto cleanup; } - if (git__date_parse(×tamp, curly_braces_content) < 0) + if (git_date_parse(×tamp, curly_braces_content) < 0) goto cleanup; error = retrieve_revobject_from_reflog(out, ref, repo, git_str_cstr(&identifier), (size_t)timestamp); diff --git a/src/util.h b/src/util.h index 30cdd0ddfe2..3d6ee120779 100644 --- a/src/util.h +++ b/src/util.h @@ -294,26 +294,6 @@ GIT_INLINE(bool) git__isxdigit(int c) */ extern int git__parse_bool(int *out, const char *value); -/* - * Parse a string into a value as a git_time_t. - * - * Sample valid input: - * - "yesterday" - * - "July 17, 2003" - * - "2003-7-17 08:23" - */ -extern int git__date_parse(git_time_t *out, const char *date); - -/* - * Format a git_time as a RFC2822 string - * - * @param out buffer to store formatted date; a '\\0' terminator will automatically be added. - * @param len size of the buffer; should be atleast `GIT_DATE_RFC2822_SZ` in size; - * @param date the date to be formatted - * @return 0 if successful; -1 on error - */ -extern int git__date_rfc2822_fmt(char *out, size_t len, const git_time *date); - /* * Unescapes a string in-place. * diff --git a/tests/date/date.c b/tests/date/date.c index 88881d1e137..f70b4fea960 100644 --- a/tests/date/date.c +++ b/tests/date/date.c @@ -1,6 +1,6 @@ #include "clar_libgit2.h" -#include "util.h" +#include "date.h" void test_date_date__overflow(void) { @@ -8,8 +8,8 @@ void test_date_date__overflow(void) git_time_t d2038, d2039; /* This is expected to fail on a 32-bit machine. */ - cl_git_pass(git__date_parse(&d2038, "2038-1-1")); - cl_git_pass(git__date_parse(&d2039, "2039-1-1")); + cl_git_pass(git_date_parse(&d2038, "2038-1-1")); + cl_git_pass(git_date_parse(&d2039, "2039-1-1")); cl_assert(d2038 < d2039); #endif } diff --git a/tests/date/rfc2822.c b/tests/date/rfc2822.c index d98c1f05efa..c94c8403f0f 100644 --- a/tests/date/rfc2822.c +++ b/tests/date/rfc2822.c @@ -1,13 +1,13 @@ #include "clar_libgit2.h" -#include "util.h" +#include "date.h" void test_date_rfc2822__format_rfc2822_no_offset(void) { git_time t = {1397031663, 0}; char buf[GIT_DATE_RFC2822_SZ]; - cl_git_pass(git__date_rfc2822_fmt(buf, sizeof(buf), &t)); + cl_git_pass(git_date_rfc2822_fmt(buf, sizeof(buf), &t)); cl_assert(strcmp(buf, "Wed, 9 Apr 2014 08:21:03 +0000") == 0); } @@ -16,7 +16,7 @@ void test_date_rfc2822__format_rfc2822_positive_offset(void) git_time t = {1397031663, 120}; char buf[GIT_DATE_RFC2822_SZ]; - cl_git_pass(git__date_rfc2822_fmt(buf, sizeof(buf), &t)); + cl_git_pass(git_date_rfc2822_fmt(buf, sizeof(buf), &t)); cl_assert(strcmp(buf, "Wed, 9 Apr 2014 10:21:03 +0200") == 0); } @@ -25,7 +25,7 @@ void test_date_rfc2822__format_rfc2822_negative_offset(void) git_time t = {1397031663, -120}; char buf[GIT_DATE_RFC2822_SZ]; - cl_git_pass(git__date_rfc2822_fmt(buf, sizeof(buf), &t)); + cl_git_pass(git_date_rfc2822_fmt(buf, sizeof(buf), &t)); cl_assert(strcmp(buf, "Wed, 9 Apr 2014 06:21:03 -0200") == 0); } @@ -35,6 +35,6 @@ void test_date_rfc2822__format_rfc2822_buffer_too_small(void) git_time t = {1397031663 + 86400, 0}; char buf[GIT_DATE_RFC2822_SZ-1]; - cl_git_fail(git__date_rfc2822_fmt(buf, sizeof(buf), &t)); + cl_git_fail(git_date_rfc2822_fmt(buf, sizeof(buf), &t)); } From add30a838867820788c871c1d034fcf68c2ad12c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 18 Nov 2021 12:36:25 -0500 Subject: [PATCH 0656/1616] date: rfc2822 formatting uses a `git_buf` instead of a static string --- src/date.c | 20 +++++++------------- src/date.h | 8 ++++---- src/email.c | 17 ++++++++++++++--- src/util.h | 2 -- tests/date/rfc2822.c | 31 ++++++++++++++----------------- 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/date.c b/src/date.c index f7498e77fe4..52cc30824f8 100644 --- a/src/date.c +++ b/src/date.c @@ -13,6 +13,7 @@ #include "util.h" #include "cache.h" #include "posix.h" +#include "date.h" #include #include @@ -875,31 +876,24 @@ int git_date_parse(git_time_t *out, const char *date) return error_ret; } -int git_date_rfc2822_fmt(char *out, size_t len, const git_time *date) +int git_date_rfc2822_fmt(git_str *out, git_time_t time, int offset) { - int written; - struct tm gmt; time_t t; + struct tm gmt; GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(date); - t = (time_t) (date->time + date->offset * 60); + t = (time_t) (time + offset * 60); - if (p_gmtime_r (&t, &gmt) == NULL) + if (p_gmtime_r(&t, &gmt) == NULL) return -1; - written = p_snprintf(out, len, "%.3s, %u %.3s %.4u %02u:%02u:%02u %+03d%02d", + return git_str_printf(out, "%.3s, %u %.3s %.4u %02u:%02u:%02u %+03d%02d", weekday_names[gmt.tm_wday], gmt.tm_mday, month_names[gmt.tm_mon], gmt.tm_year + 1900, gmt.tm_hour, gmt.tm_min, gmt.tm_sec, - date->offset / 60, date->offset % 60); - - if (written < 0 || (written > (int) len - 1)) - return -1; - - return 0; + offset / 60, offset % 60); } diff --git a/src/date.h b/src/date.h index 133f20b3797..7ebd3c30e41 100644 --- a/src/date.h +++ b/src/date.h @@ -23,11 +23,11 @@ extern int git_date_parse(git_time_t *out, const char *date); /* * Format a git_time as a RFC2822 string * - * @param out buffer to store formatted date; a '\\0' terminator will automatically be added. - * @param len size of the buffer; should be atleast `GIT_DATE_RFC2822_SZ` in size; - * @param date the date to be formatted + * @param out buffer to store formatted date + * @param time the time to be formatted + * @param offset the timezone offset * @return 0 if successful; -1 on error */ -extern int git_date_rfc2822_fmt(char *out, size_t len, const git_time *date); +extern int git_date_rfc2822_fmt(git_str *out, git_time_t time, int offset); #endif diff --git a/src/email.c b/src/email.c index 66ed2dd9fb8..e19a2928cbb 100644 --- a/src/email.c +++ b/src/email.c @@ -73,6 +73,19 @@ static int append_prefix( return git_str_oom(out) ? -1 : 0; } +static int append_date( + git_str *out, + const git_time *date) +{ + int error; + + if ((error = git_str_printf(out, "Date: ")) == 0 && + (error = git_date_rfc2822_fmt(out, date->time, date->offset)) == 0) + error = git_str_putc(out, '\n'); + + return error; +} + static int append_subject( git_str *out, size_t patch_idx, @@ -118,14 +131,12 @@ static int append_header( git_email_create_options *opts) { char id[GIT_OID_HEXSZ]; - char date[GIT_DATE_RFC2822_SZ]; int error; if ((error = git_oid_fmt(id, commit_id)) < 0 || (error = git_str_printf(out, "From %.*s %s\n", GIT_OID_HEXSZ, id, EMAIL_TIMESTAMP)) < 0 || (error = git_str_printf(out, "From: %s <%s>\n", author->name, author->email)) < 0 || - (error = git_date_rfc2822_fmt(date, sizeof(date), &author->when)) < 0 || - (error = git_str_printf(out, "Date: %s\n", date)) < 0 || + (error = append_date(out, &author->when)) < 0 || (error = append_subject(out, patch_idx, patch_count, summary, opts)) < 0) return error; diff --git a/src/util.h b/src/util.h index 3d6ee120779..141779ade85 100644 --- a/src/util.h +++ b/src/util.h @@ -37,8 +37,6 @@ # define GIT_CONTAINER_OF(ptr, type, member) (type *)(ptr) #endif -#define GIT_DATE_RFC2822_SZ 32 - /** * Return the length of a constant string. * We are aware that `strlen` performs the same task and is usually diff --git a/tests/date/rfc2822.c b/tests/date/rfc2822.c index c94c8403f0f..b0bbcfce514 100644 --- a/tests/date/rfc2822.c +++ b/tests/date/rfc2822.c @@ -5,36 +5,33 @@ void test_date_rfc2822__format_rfc2822_no_offset(void) { git_time t = {1397031663, 0}; - char buf[GIT_DATE_RFC2822_SZ]; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_date_rfc2822_fmt(buf, sizeof(buf), &t)); - cl_assert(strcmp(buf, "Wed, 9 Apr 2014 08:21:03 +0000") == 0); + cl_git_pass(git_date_rfc2822_fmt(&buf, t.time, t.offset)); + cl_assert_equal_s("Wed, 9 Apr 2014 08:21:03 +0000", buf.ptr); + + git_str_dispose(&buf); } void test_date_rfc2822__format_rfc2822_positive_offset(void) { git_time t = {1397031663, 120}; - char buf[GIT_DATE_RFC2822_SZ]; + git_str buf = GIT_STR_INIT; + + cl_git_pass(git_date_rfc2822_fmt(&buf, t.time, t.offset)); + cl_assert_equal_s("Wed, 9 Apr 2014 10:21:03 +0200", buf.ptr); - cl_git_pass(git_date_rfc2822_fmt(buf, sizeof(buf), &t)); - cl_assert(strcmp(buf, "Wed, 9 Apr 2014 10:21:03 +0200") == 0); + git_str_dispose(&buf); } void test_date_rfc2822__format_rfc2822_negative_offset(void) { git_time t = {1397031663, -120}; - char buf[GIT_DATE_RFC2822_SZ]; + git_str buf = GIT_STR_INIT; - cl_git_pass(git_date_rfc2822_fmt(buf, sizeof(buf), &t)); - cl_assert(strcmp(buf, "Wed, 9 Apr 2014 06:21:03 -0200") == 0); -} - -void test_date_rfc2822__format_rfc2822_buffer_too_small(void) -{ - /* "Wed, 10 Apr 2014 08:21:03 +0000" */ - git_time t = {1397031663 + 86400, 0}; - char buf[GIT_DATE_RFC2822_SZ-1]; + cl_git_pass(git_date_rfc2822_fmt(&buf, t.time, t.offset)); + cl_assert_equal_s("Wed, 9 Apr 2014 06:21:03 -0200", buf.ptr); - cl_git_fail(git_date_rfc2822_fmt(buf, sizeof(buf), &t)); + git_str_dispose(&buf); } From ea62f546dca580f366d1208e63c3aae26fdc9538 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 14 Nov 2021 16:41:11 -0500 Subject: [PATCH 0657/1616] utf8: include `utf8.h` in tests --- tests/core/utf8.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/core/utf8.c b/tests/core/utf8.c index 021828e9e1c..e1987b8d631 100644 --- a/tests/core/utf8.c +++ b/tests/core/utf8.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" +#include "utf8.h" void test_core_utf8__char_length(void) { From fc42c28ebe8bd4b524cc0f1594395a04b7d8e796 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 19 Nov 2021 09:36:03 -0500 Subject: [PATCH 0658/1616] util: don't include unnecessary system libraries Remove some unnecessary includes from utility code. --- src/date.c | 1 - src/fs_path.h | 2 -- src/futils.c | 6 ++++-- src/hash.h | 1 - src/net.c | 1 - src/unix/map.c | 2 -- src/unix/posix.h | 4 +--- src/unix/realpath.c | 2 -- tests/core/copy.c | 1 - tests/core/env.c | 1 - tests/core/link.c | 1 - tests/core/mkdir.c | 1 - tests/core/stat.c | 1 - tests/path/win32.c | 1 - 14 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/date.c b/src/date.c index 52cc30824f8..1529276e222 100644 --- a/src/date.c +++ b/src/date.c @@ -11,7 +11,6 @@ #endif #include "util.h" -#include "cache.h" #include "posix.h" #include "date.h" diff --git a/src/fs_path.h b/src/fs_path.h index 188dcf303f7..9720d34ce12 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -14,8 +14,6 @@ #include "vector.h" #include "utf8.h" -#include "git2/sys/path.h" - /** * Path manipulation utils * diff --git a/src/futils.c b/src/futils.c index 7ec1009bd67..454ed79de23 100644 --- a/src/futils.c +++ b/src/futils.c @@ -15,6 +15,8 @@ #include "win32/findfile.h" #endif +#define GIT_FILEMODE_DEFAULT 0100666 + int git_futils_mkpath2file(const char *file_path, const mode_t mode) { return git_futils_mkdir( @@ -256,7 +258,7 @@ int git_futils_readbuffer(git_str *buf, const char *path) } int git_futils_writebuffer( - const git_str *buf, const char *path, int flags, mode_t mode) + const git_str *buf, const char *path, int flags, mode_t mode) { int fd, do_fsync = 0, error = 0; @@ -269,7 +271,7 @@ int git_futils_writebuffer( flags &= ~O_FSYNC; if (!mode) - mode = GIT_FILEMODE_BLOB; + mode = GIT_FILEMODE_DEFAULT; if ((fd = p_open(path, flags, mode)) < 0) { git_error_set(GIT_ERROR_OS, "could not open '%s' for writing", path); diff --git a/src/hash.h b/src/hash.h index 10b14a904b9..2b2eaf6d670 100644 --- a/src/hash.h +++ b/src/hash.h @@ -10,7 +10,6 @@ #include "common.h" -#include "git2/oid.h" #include "hash/sha1.h" typedef struct { diff --git a/src/net.c b/src/net.c index 58792ee7df2..a91e7460ec0 100644 --- a/src/net.c +++ b/src/net.c @@ -9,7 +9,6 @@ #include "netops.h" #include -#include "git2/errors.h" #include "posix.h" #include "str.h" diff --git a/src/unix/map.c b/src/unix/map.c index 88f283ce815..23fcb786e5a 100644 --- a/src/unix/map.c +++ b/src/unix/map.c @@ -7,8 +7,6 @@ #include "common.h" -#include "git2/common.h" - #if !defined(GIT_WIN32) && !defined(NO_MMAP) #include "map.h" diff --git a/src/unix/posix.h b/src/unix/posix.h index 7b3325e7817..27a8fecd4ce 100644 --- a/src/unix/posix.h +++ b/src/unix/posix.h @@ -7,9 +7,7 @@ #ifndef INCLUDE_unix_posix_h__ #define INCLUDE_unix_posix_h__ -#ifndef LIBGIT2_NO_FEATURES_H -# include "git2/sys/features.h" -#endif +#include "common.h" #include #include diff --git a/src/unix/realpath.c b/src/unix/realpath.c index 893bac87b36..f1ca669f74d 100644 --- a/src/unix/realpath.c +++ b/src/unix/realpath.c @@ -7,8 +7,6 @@ #include "common.h" -#include "git2/common.h" - #ifndef GIT_WIN32 #include diff --git a/tests/core/copy.c b/tests/core/copy.c index b03d7108380..6d22b503d46 100644 --- a/tests/core/copy.c +++ b/tests/core/copy.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "futils.h" -#include "path.h" #include "posix.h" void test_core_copy__file(void) diff --git a/tests/core/env.c b/tests/core/env.c index 88c5c6aa3be..8ba9b91240a 100644 --- a/tests/core/env.c +++ b/tests/core/env.c @@ -1,7 +1,6 @@ #include "clar_libgit2.h" #include "futils.h" #include "sysdir.h" -#include "path.h" #ifdef GIT_WIN32 #define NUM_VARS 5 diff --git a/tests/core/link.c b/tests/core/link.c index 6ab79b2a869..a1e2706b270 100644 --- a/tests/core/link.c +++ b/tests/core/link.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "posix.h" -#include "path.h" #ifdef GIT_WIN32 # include "win32/reparse.h" diff --git a/tests/core/mkdir.c b/tests/core/mkdir.c index 8d4b9afd67b..58a4cfcdb81 100644 --- a/tests/core/mkdir.c +++ b/tests/core/mkdir.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "futils.h" -#include "path.h" #include "posix.h" static void cleanup_basic_dirs(void *ref) diff --git a/tests/core/stat.c b/tests/core/stat.c index 022380ba66a..210072fe3a2 100644 --- a/tests/core/stat.c +++ b/tests/core/stat.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" #include "futils.h" -#include "path.h" #include "posix.h" void test_core_stat__initialize(void) diff --git a/tests/path/win32.c b/tests/path/win32.c index ff166395dad..64d8d8e08f8 100644 --- a/tests/path/win32.c +++ b/tests/path/win32.c @@ -1,6 +1,5 @@ #include "clar_libgit2.h" -#include "path.h" #ifdef GIT_WIN32 #include "win32/path_w32.h" From 91365fd87c5b09462268eb83b01d3a30d6931c2a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 22 Nov 2021 09:02:38 -0500 Subject: [PATCH 0659/1616] sha1: tests should use hashes, not oid computation The tests that examine sha1 behavior (including collision detection) should test against the hash functionality directly, not indirectly using the oid functions. --- tests/core/sha1.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/tests/core/sha1.c b/tests/core/sha1.c index 92582d69a2b..9ccdaab3ce5 100644 --- a/tests/core/sha1.c +++ b/tests/core/sha1.c @@ -13,7 +13,7 @@ void test_core_sha1__cleanup(void) cl_fixture_cleanup(FIXTURE_DIR); } -static int sha1_file(git_oid *out, const char *filename) +static int sha1_file(unsigned char *out, const char *filename) { git_hash_ctx ctx; char buf[2048]; @@ -31,7 +31,7 @@ static int sha1_file(git_oid *out, const char *filename) cl_assert_equal_i(0, read_len); p_close(fd); - ret = git_hash_final(out->id, &ctx); + ret = git_hash_final(out, &ctx); git_hash_ctx_cleanup(&ctx); return ret; @@ -39,26 +39,32 @@ static int sha1_file(git_oid *out, const char *filename) void test_core_sha1__sum(void) { - git_oid oid, expected; + unsigned char expected[GIT_HASH_SHA1_SIZE] = { + 0x4e, 0x72, 0x67, 0x9e, 0x3e, 0xa4, 0xd0, 0x4e, 0x0c, 0x64, + 0x2f, 0x02, 0x9e, 0x61, 0xeb, 0x80, 0x56, 0xc7, 0xed, 0x94 + }; + unsigned char actual[GIT_HASH_SHA1_SIZE]; - cl_git_pass(sha1_file(&oid, FIXTURE_DIR "/hello_c")); - git_oid_fromstr(&expected, "4e72679e3ea4d04e0c642f029e61eb8056c7ed94"); - cl_assert_equal_oid(&expected, &oid); + cl_git_pass(sha1_file(actual, FIXTURE_DIR "/hello_c")); + cl_assert_equal_i(0, memcmp(expected, actual, GIT_HASH_SHA1_SIZE)); } /* test that sha1 collision detection works when enabled */ void test_core_sha1__detect_collision_attack(void) { - git_oid oid, expected; + unsigned char actual[GIT_HASH_SHA1_SIZE]; + unsigned char expected[GIT_HASH_SHA1_SIZE] = { + 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, + 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a + }; #ifdef GIT_SHA1_COLLISIONDETECT GIT_UNUSED(&expected); - cl_git_fail(sha1_file(&oid, FIXTURE_DIR "/shattered-1.pdf")); + cl_git_fail(sha1_file(actual, FIXTURE_DIR "/shattered-1.pdf")); cl_assert_equal_s("SHA1 collision attack detected", git_error_last()->message); #else - cl_git_pass(sha1_file(&oid, FIXTURE_DIR "/shattered-1.pdf")); - git_oid_fromstr(&expected, "38762cf7f55934b34d179ae6a4c80cadccbb7f0a"); - cl_assert_equal_oid(&expected, &oid); + cl_git_pass(sha1_file(actual, FIXTURE_DIR "/shattered-1.pdf")); + cl_assert_equal_i(0, memcmp(expected, actual, GIT_HASH_SHA1_SIZE)); #endif } From adcf638cca0a3b38f51a6d7c9b7ce479528cd854 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 21 Nov 2021 21:34:17 -0500 Subject: [PATCH 0660/1616] filebuf: use hashes not oids The filebuf functions should use hashes directly, not indirectly using the oid functions. --- src/filebuf.c | 6 +++--- src/filebuf.h | 2 +- src/index.c | 2 +- src/indexer.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/filebuf.c b/src/filebuf.c index f0bd0004f12..eafcba3bd6f 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -386,9 +386,9 @@ int git_filebuf_open_withsize(git_filebuf *file, const char *path, int flags, mo return error; } -int git_filebuf_hash(git_oid *oid, git_filebuf *file) +int git_filebuf_hash(unsigned char *out, git_filebuf *file) { - GIT_ASSERT_ARG(oid); + GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(file); GIT_ASSERT_ARG(file->compute_digest); @@ -397,7 +397,7 @@ int git_filebuf_hash(git_oid *oid, git_filebuf *file) if (verify_last_error(file) < 0) return -1; - git_hash_final(oid->id, &file->digest); + git_hash_final(out, &file->digest); git_hash_ctx_cleanup(&file->digest); file->compute_digest = 0; diff --git a/src/filebuf.h b/src/filebuf.h index 9d53bc3076f..adbb19936ad 100644 --- a/src/filebuf.h +++ b/src/filebuf.h @@ -87,7 +87,7 @@ int git_filebuf_open_withsize(git_filebuf *file, const char *path, int flags, mo int git_filebuf_commit(git_filebuf *lock); int git_filebuf_commit_at(git_filebuf *lock, const char *path); void git_filebuf_cleanup(git_filebuf *lock); -int git_filebuf_hash(git_oid *oid, git_filebuf *file); +int git_filebuf_hash(unsigned char *out, git_filebuf *file); int git_filebuf_flush(git_filebuf *file); int git_filebuf_stats(time_t *mtime, size_t *size, git_filebuf *file); diff --git a/src/index.c b/src/index.c index 7ade4341fcc..a2d80bc6e3a 100644 --- a/src/index.c +++ b/src/index.c @@ -3080,7 +3080,7 @@ static int write_index(git_oid *checksum, git_index *index, git_filebuf *file) return -1; /* get out the hash for all the contents we've appended to the file */ - git_filebuf_hash(&hash_final, file); + git_filebuf_hash(hash_final.id, file); git_oid_cpy(checksum, &hash_final); /* write it at the end of the file */ diff --git a/src/indexer.c b/src/indexer.c index 213ad7581a5..d9396e058f8 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -1289,7 +1289,7 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) goto on_error; /* Write out the hash of the idx */ - if (git_filebuf_hash(&trailer_hash, &index_file) < 0) + if (git_filebuf_hash(trailer_hash.id, &index_file) < 0) goto on_error; git_filebuf_write(&index_file, &trailer_hash, sizeof(git_oid)); From 84083dcc8bd41332ccac9d7b537f3e254d79011c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 19 Nov 2021 08:48:08 -0500 Subject: [PATCH 0661/1616] cmake: use CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR Instead of using the project-specific `libgit2_SOURCE_DIR` and `libgit2_BINARY_DIR` variables, use `CMAKE_SOURCE_DIR` and `CMAKE_BINARY_DIR`. --- CMakeLists.txt | 2 +- cmake/IdeSplitSources.cmake | 2 +- cmake/SelectHTTPParser.cmake | 4 ++-- cmake/SelectRegex.cmake | 4 ++-- cmake/SelectWinHTTP.cmake | 4 ++-- cmake/SelectZlib.cmake | 8 ++++---- deps/winhttp/CMakeLists.txt | 8 +++----- src/CMakeLists.txt | 26 +++++++++++++------------- tests/CMakeLists.txt | 6 +++--- 9 files changed, 31 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c414bbe3ad0..3a010681b06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.5.1) project(libgit2 VERSION "1.3.0" LANGUAGES C) # Add find modules to the path -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${libgit2_SOURCE_DIR}/cmake") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") # # Build options diff --git a/cmake/IdeSplitSources.cmake b/cmake/IdeSplitSources.cmake index 4a55d89b096..9e16cbc5fde 100644 --- a/cmake/IdeSplitSources.cmake +++ b/cmake/IdeSplitSources.cmake @@ -8,7 +8,7 @@ function(IDE_SPLIT_SOURCES target) get_target_property(sources ${target} SOURCES) foreach(source ${sources}) if(source MATCHES ".*/") - string(REPLACE ${libgit2_SOURCE_DIR}/ "" rel ${source}) + string(REPLACE ${CMAKE_SOURCE_DIR}/ "" rel ${source}) if(rel) string(REGEX REPLACE "/([^/]*)$" "" rel ${rel}) if(rel) diff --git a/cmake/SelectHTTPParser.cmake b/cmake/SelectHTTPParser.cmake index 721f7fa9f1a..ffc897fbc41 100644 --- a/cmake/SelectHTTPParser.cmake +++ b/cmake/SelectHTTPParser.cmake @@ -12,8 +12,8 @@ if(USE_HTTP_PARSER STREQUAL "system") endif() else() message(STATUS "http-parser version 2 was not found or disabled; using bundled 3rd-party sources.") - add_subdirectory("${libgit2_SOURCE_DIR}/deps/http-parser" "${libgit2_BINARY_DIR}/deps/http-parser") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/http-parser") + add_subdirectory("${CMAKE_SOURCE_DIR}/deps/http-parser" "${CMAKE_BINARY_DIR}/deps/http-parser") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/http-parser") list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") add_feature_info(http-parser ON "http-parser support (bundled)") endif() diff --git a/cmake/SelectRegex.cmake b/cmake/SelectRegex.cmake index 1553d658718..88aa156b7e5 100644 --- a/cmake/SelectRegex.cmake +++ b/cmake/SelectRegex.cmake @@ -43,8 +43,8 @@ elseif(REGEX_BACKEND STREQUAL "builtin") add_feature_info(regex ON "using bundled PCRE") set(GIT_REGEX_BUILTIN 1) - add_subdirectory("${libgit2_SOURCE_DIR}/deps/pcre" "${libgit2_BINARY_DIR}/deps/pcre") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/pcre") + add_subdirectory("${CMAKE_SOURCE_DIR}/deps/pcre" "${CMAKE_BINARY_DIR}/deps/pcre") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/pcre") list(APPEND LIBGIT2_DEPENDENCY_OBJECTS $) else() message(FATAL_ERROR "The REGEX_BACKEND option provided is not supported") diff --git a/cmake/SelectWinHTTP.cmake b/cmake/SelectWinHTTP.cmake index 667b4007e8a..38642e13645 100644 --- a/cmake/SelectWinHTTP.cmake +++ b/cmake/SelectWinHTTP.cmake @@ -4,9 +4,9 @@ if(WIN32 AND USE_WINHTTP) # Since MinGW does not come with headers or an import library for winhttp, # we have to include a private header and generate our own import library if(MINGW) - add_subdirectory("${libgit2_SOURCE_DIR}/deps/winhttp" "${libgit2_BINARY_DIR}/deps/winhttp") + add_subdirectory("${CMAKE_SOURCE_DIR}/deps/winhttp" "${CMAKE_BINARY_DIR}/deps/winhttp") list(APPEND LIBGIT2_SYSTEM_LIBS winhttp) - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/winhttp") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/winhttp") else() list(APPEND LIBGIT2_SYSTEM_LIBS "winhttp") list(APPEND LIBGIT2_PC_LIBS "-lwinhttp") diff --git a/cmake/SelectZlib.cmake b/cmake/SelectZlib.cmake index e377d43b636..0de1d4a98cd 100644 --- a/cmake/SelectZlib.cmake +++ b/cmake/SelectZlib.cmake @@ -22,13 +22,13 @@ if(USE_BUNDLED_ZLIB STREQUAL "OFF") endif() endif() if(USE_BUNDLED_ZLIB STREQUAL "Chromium") - add_subdirectory("${libgit2_SOURCE_DIR}/deps/chromium-zlib" "${libgit2_BINARY_DIR}/deps/chromium-zlib") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/chromium-zlib") + add_subdirectory("${CMAKE_SOURCE_DIR}/deps/chromium-zlib" "${CMAKE_BINARY_DIR}/deps/chromium-zlib") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/chromium-zlib") list(APPEND LIBGIT2_DEPENDENCY_OBJECTS $) add_feature_info(zlib ON "using (Chromium) bundled zlib") elseif(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND) - add_subdirectory("${libgit2_SOURCE_DIR}/deps/zlib" "${libgit2_BINARY_DIR}/deps/zlib") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/zlib") + add_subdirectory("${CMAKE_SOURCE_DIR}/deps/zlib" "${CMAKE_BINARY_DIR}/deps/zlib") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/zlib") list(APPEND LIBGIT2_DEPENDENCY_OBJECTS $) add_feature_info(zlib ON "using bundled zlib") endif() diff --git a/deps/winhttp/CMakeLists.txt b/deps/winhttp/CMakeLists.txt index 0ad2ac5f0ea..c11a867a872 100644 --- a/deps/winhttp/CMakeLists.txt +++ b/deps/winhttp/CMakeLists.txt @@ -3,7 +3,7 @@ if(NOT DLLTOOL) message(FATAL_ERROR "Could not find dlltool command") endif() -set(LIBWINHTTP_PATH "${libgit2_BINARY_DIR}/deps/winhttp") +set(LIBWINHTTP_PATH "${CMAKE_BINARY_DIR}/deps/winhttp") set(LIBWINHTTP_PATH ${LIBWINHTTP_PATH} PARENT_SCOPE) file(MAKE_DIRECTORY ${LIBWINHTTP_PATH}) @@ -17,10 +17,8 @@ add_custom_command( OUTPUT ${LIBWINHTTP_PATH}/libwinhttp.a COMMAND ${DLLTOOL} -d ${WINHTTP_DEF} -k -D winhttp.dll -l libwinhttp.a DEPENDS ${WINHTTP_DEF} - WORKING_DIRECTORY ${LIBWINHTTP_PATH} -) + WORKING_DIRECTORY ${LIBWINHTTP_PATH}) set_source_files_properties( ${CMAKE_CURRENT_SOURCE_DIR}/src/transports/winhttp.c - PROPERTIES OBJECT_DEPENDS ${LIBWINHTTP_PATH}/libwinhttp.a -) + PROPERTIES OBJECT_DEPENDS ${LIBWINHTTP_PATH}/libwinhttp.a) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d6a1036675b..03609b681cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,8 +36,8 @@ set(LIBGIT2_PC_LIBS "") set(LIBGIT2_INCLUDES "${CMAKE_CURRENT_BINARY_DIR}" - "${libgit2_SOURCE_DIR}/src" - "${libgit2_SOURCE_DIR}/include") + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/include") if(HAVE_FUTIMENS) set(GIT_USE_FUTIMENS 1) @@ -117,8 +117,8 @@ target_sources(git2internal PRIVATE ${SRC_SHA1}) # Optional external dependency: ntlmclient if(USE_NTLMCLIENT) set(GIT_NTLM 1) - add_subdirectory("${libgit2_SOURCE_DIR}/deps/ntlmclient" "${libgit2_BINARY_DIR}/deps/ntlmclient") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/ntlmclient") + add_subdirectory("${CMAKE_SOURCE_DIR}/deps/ntlmclient" "${CMAKE_BINARY_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/ntlmclient") list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") endif() add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix") @@ -164,9 +164,9 @@ target_compile_definitions(git2internal PRIVATE _FILE_OFFSET_BITS=64) # Collect sourcefiles file(GLOB SRC_H - "${libgit2_SOURCE_DIR}/include/git2.h" - "${libgit2_SOURCE_DIR}/include/git2/*.h" - "${libgit2_SOURCE_DIR}/include/git2/sys/*.h") + "${CMAKE_SOURCE_DIR}/include/git2.h" + "${CMAKE_SOURCE_DIR}/include/git2/*.h" + "${CMAKE_SOURCE_DIR}/include/git2/sys/*.h") list(SORT SRC_H) target_sources(git2internal PRIVATE ${SRC_H}) @@ -225,7 +225,7 @@ configure_file(features.h.in git2/sys/features.h) ide_split_sources(git2internal) list(APPEND LIBGIT2_OBJECTS $ ${LIBGIT2_DEPENDENCY_OBJECTS}) -target_include_directories(git2internal PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${libgit2_SOURCE_DIR}/include) +target_include_directories(git2internal PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${CMAKE_SOURCE_DIR}/include) target_include_directories(git2internal SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) set(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE) @@ -247,9 +247,9 @@ add_library(git2 ${WIN_RC} ${LIBGIT2_OBJECTS}) target_link_libraries(git2 ${LIBGIT2_SYSTEM_LIBS}) set_target_properties(git2 PROPERTIES C_STANDARD 90) -set_target_properties(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) -set_target_properties(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) -set_target_properties(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) +set_target_properties(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set_target_properties(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set_target_properties(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) # Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240) # Win64+MSVC+static libs = linker error @@ -290,5 +290,5 @@ install(TARGETS git2 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) -install(DIRECTORY ${libgit2_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -install(FILES ${libgit2_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(FILES ${CMAKE_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 84df92a451e..2272dec98d8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -38,7 +38,7 @@ set_source_files_properties( add_executable(libgit2_tests ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS}) set_target_properties(libgit2_tests PROPERTIES C_STANDARD 90) -set_target_properties(libgit2_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) +set_target_properties(libgit2_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) target_include_directories(libgit2_tests PRIVATE ${TEST_INCLUDES} ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES}) target_include_directories(libgit2_tests SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) @@ -62,9 +62,9 @@ endif() function(ADD_CLAR_TEST name) if(NOT USE_LEAK_CHECKER STREQUAL "OFF") - add_test(${name} "${libgit2_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${libgit2_BINARY_DIR}/libgit2_tests" ${ARGN}) + add_test(${name} "${CMAKE_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${CMAKE_BINARY_DIR}/libgit2_tests" ${ARGN}) else() - add_test(${name} "${libgit2_BINARY_DIR}/libgit2_tests" ${ARGN}) + add_test(${name} "${CMAKE_BINARY_DIR}/libgit2_tests" ${ARGN}) endif() endfunction(ADD_CLAR_TEST) From 3461aaf77aad4240ec921697293dc681a8564023 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 22 Nov 2021 10:29:29 -0500 Subject: [PATCH 0662/1616] repo: minor formatting fix --- src/repository.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/repository.c b/src/repository.c index 2002e118639..fcdb1b3a977 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2038,9 +2038,8 @@ static int repo_init_structure( * `git` prints to stderr: 'warning: templates not found in /path/to/tdir' */ if (error < 0) { - if (!default_template && error != GIT_ENOTFOUND) { + if (!default_template && error != GIT_ENOTFOUND) return error; - } /* if template was default, ignore error and use internal */ git_error_clear(); From 1e015088d0878ebbf6545702688dff2d69c9eeb5 Mon Sep 17 00:00:00 2001 From: Przemyslaw Ciezkowski Date: Thu, 25 Nov 2021 15:19:17 +0100 Subject: [PATCH 0663/1616] git_commit_summary: ignore lines with spaces Fixes libgit2/libgit2#6065 --- src/commit.c | 19 +++++++++++++++---- tests/commit/commit.c | 3 +++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/commit.c b/src/commit.c index 752d98b022f..81e5b02d352 100644 --- a/src/commit.c +++ b/src/commit.c @@ -546,7 +546,7 @@ const char *git_commit_message(const git_commit *commit) const char *git_commit_summary(git_commit *commit) { git_str summary = GIT_STR_INIT; - const char *msg, *space; + const char *msg, *space, *next; bool space_contains_newline = false; GIT_ASSERT_ARG_WITH_RETVAL(commit, NULL); @@ -555,10 +555,21 @@ const char *git_commit_summary(git_commit *commit) for (msg = git_commit_message(commit), space = NULL; *msg; ++msg) { char next_character = msg[0]; /* stop processing at the end of the first paragraph */ - if (next_character == '\n' && (!msg[1] || msg[1] == '\n')) - break; + if (next_character == '\n') { + if (!msg[1]) + break; + if (msg[1] == '\n') + break; + /* stop processing if next line contains only whitespace */ + next = msg + 1; + while (*next && git__isspace_nonlf(*next)) { + ++next; + } + if (!*next || *next == '\n') + break; + } /* record the beginning of contiguous whitespace runs */ - else if (git__isspace(next_character)) { + if (git__isspace(next_character)) { if(space == NULL) { space = msg; space_contains_newline = false; diff --git a/tests/commit/commit.c b/tests/commit/commit.c index d4e333b6ad8..fd574f7f254 100644 --- a/tests/commit/commit.c +++ b/tests/commit/commit.c @@ -139,8 +139,11 @@ void test_commit_commit__summary(void) { assert_commit_summary("One-liner with no trailing newline", "One-liner with no trailing newline"); assert_commit_summary("One-liner with trailing newline", "One-liner with trailing newline\n"); + assert_commit_summary("One-liner with trailing newline and space", "One-liner with trailing newline and space\n "); assert_commit_summary("Trimmed leading&trailing newlines", "\n\nTrimmed leading&trailing newlines\n\n"); assert_commit_summary("First paragraph only", "\nFirst paragraph only\n\n(There are more!)"); + assert_commit_summary("First paragraph only with space in the next line", "\nFirst paragraph only with space in the next line\n \n(There are more!)"); + assert_commit_summary("First paragraph only with spaces in the next line", "\nFirst paragraph only with spaces in the next line\n \n(There are more!)"); assert_commit_summary("First paragraph with unwrapped trailing\tlines", "\nFirst paragraph\nwith unwrapped\ntrailing\tlines\n\n(Yes, unwrapped!)"); assert_commit_summary("\tLeading tabs", "\tLeading\n\ttabs\n\nare preserved"); /* tabs around newlines are collapsed down to a single space */ assert_commit_summary(" Leading Spaces", " Leading\n Spaces\n\nare preserved"); /* spaces around newlines are collapsed down to a single space */ From fc1a3f456540dfc4dc143b322b943a4264658d56 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 29 Nov 2021 13:36:36 -0500 Subject: [PATCH 0664/1616] object: return GIT_EINVALID on parse errors Return `GIT_EINVALID` on parse errors so that direct callers of parse functions can determine when there was a failure to parse the object. The object parser functions will swallow this error code to prevent it from propagating down the chain to end-users. (`git_merge` should not return `GIT_EINVALID` when a commit it tries to look up is not valid, this would be too vague to be useful.) The only public function that this affects is `git_signature_from_buffer`, which is now documented as returning `GIT_EINVALID` when appropriate. --- include/git2/signature.h | 2 +- src/commit.c | 19 +++++++++++-------- src/commit_list.c | 5 ++--- src/indexer.c | 10 ++++++++-- src/object.c | 13 +++++++++---- src/signature.c | 14 ++++++++++---- src/tag.c | 7 ++++--- src/tree.c | 38 ++++++++++++++++++++++++-------------- 8 files changed, 69 insertions(+), 39 deletions(-) diff --git a/include/git2/signature.h b/include/git2/signature.h index b14f3ea8906..849998e66f7 100644 --- a/include/git2/signature.h +++ b/include/git2/signature.h @@ -71,7 +71,7 @@ GIT_EXTERN(int) git_signature_default(git_signature **out, git_repository *repo) * * @param out new signature * @param buf signature string - * @return 0 on success, or an error code + * @return 0 on success, GIT_EINVALID if the signature is not parseable, or an error code */ GIT_EXTERN(int) git_signature_from_buffer(git_signature **out, const char *buf); diff --git a/src/commit.c b/src/commit.c index 752d98b022f..ceaccb3312c 100644 --- a/src/commit.c +++ b/src/commit.c @@ -395,6 +395,7 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig git_oid parent_id; size_t header_len; git_signature dummy_sig; + int error; GIT_ASSERT_ARG(commit); GIT_ASSERT_ARG(data); @@ -431,14 +432,14 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig commit->author = git__malloc(sizeof(git_signature)); GIT_ERROR_CHECK_ALLOC(commit->author); - if (git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n') < 0) - return -1; + if ((error = git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n')) < 0) + return error; } /* Some tools create multiple author fields, ignore the extra ones */ while (!git__prefixncmp(buffer, buffer_end - buffer, "author ")) { - if (git_signature__parse(&dummy_sig, &buffer, buffer_end, "author ", '\n') < 0) - return -1; + if ((error = git_signature__parse(&dummy_sig, &buffer, buffer_end, "author ", '\n')) < 0) + return error; git__free(dummy_sig.name); git__free(dummy_sig.email); @@ -448,8 +449,8 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig commit->committer = git__malloc(sizeof(git_signature)); GIT_ERROR_CHECK_ALLOC(commit->committer); - if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0) - return -1; + if ((error = git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n')) < 0) + return error; if (flags & GIT_COMMIT_PARSE_QUICK) return 0; @@ -493,7 +494,7 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig bad_buffer: git_error_set(GIT_ERROR_OBJECT, "failed to parse bad commit object"); - return -1; + return GIT_EINVALID; } int git_commit__parse_raw(void *commit, const char *data, size_t size) @@ -971,8 +972,10 @@ int git_commit_create_with_signature( /* The first step is to verify that all the tree and parents exist */ parsed = git__calloc(1, sizeof(git_commit)); GIT_ERROR_CHECK_ALLOC(parsed); - if ((error = commit_parse(parsed, commit_content, strlen(commit_content), 0)) < 0) + if (commit_parse(parsed, commit_content, strlen(commit_content), 0) < 0) { + error = -1; goto cleanup; + } if ((error = validate_tree_and_parents(&parents, repo, &parsed->tree_id, commit_parent_from_commit, parsed, NULL, true)) < 0) goto cleanup; diff --git a/src/commit_list.c b/src/commit_list.c index 692b1495f51..4585508bc41 100644 --- a/src/commit_list.c +++ b/src/commit_list.c @@ -124,16 +124,15 @@ static int commit_quick_parse( { git_oid *parent_oid; git_commit *commit; - int error; size_t i; commit = git__calloc(1, sizeof(*commit)); GIT_ERROR_CHECK_ALLOC(commit); commit->object.repo = walk->repo; - if ((error = git_commit__parse_ext(commit, obj, GIT_COMMIT_PARSE_QUICK)) < 0) { + if (git_commit__parse_ext(commit, obj, GIT_COMMIT_PARSE_QUICK) < 0) { git__free(commit); - return error; + return -1; } if (!git__is_uint16(git_array_size(commit->parent_ids))) { diff --git a/src/indexer.c b/src/indexer.c index d9396e058f8..ff60b400500 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -340,7 +340,7 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj) { git_object *object; git_oid *expected; - int error; + int error = 0; if (obj->type != GIT_OBJECT_BLOB && obj->type != GIT_OBJECT_TREE && @@ -348,8 +348,14 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj) obj->type != GIT_OBJECT_TAG) return 0; - if ((error = git_object__from_raw(&object, obj->data, obj->len, obj->type)) < 0) + if (git_object__from_raw(&object, obj->data, obj->len, obj->type) < 0) { + /* + * parse_raw returns EINVALID on invalid data; downgrade + * that to a normal -1 error code. + */ + error = -1; goto out; + } if ((expected = git_oidmap_get(idx->expected_oids, &object->cached.oid)) != NULL) { git_oidmap_delete(idx->expected_oids, &object->cached.oid); diff --git a/src/object.c b/src/object.c index fb861e9e130..7e6ad3aa286 100644 --- a/src/object.c +++ b/src/object.c @@ -144,12 +144,17 @@ int git_object__from_odb_object( def = &git_objects_table[odb_obj->cached.type]; GIT_ASSERT(def->free && def->parse); - if ((error = def->parse(object, odb_obj)) < 0) + if ((error = def->parse(object, odb_obj)) < 0) { + /* + * parse returns EINVALID on invalid data; downgrade + * that to a normal -1 error code. + */ def->free(object); - else - *object_out = git_cache_store_parsed(&repo->objects, object); + return -1; + } - return error; + *object_out = git_cache_store_parsed(&repo->objects, object); + return 0; } void git_object__free(void *obj) diff --git a/src/signature.c b/src/signature.c index acd5fd72bad..5d6ab572cbf 100644 --- a/src/signature.c +++ b/src/signature.c @@ -23,6 +23,12 @@ void git_signature_free(git_signature *sig) git__free(sig); } +static int signature_parse_error(const char *msg) +{ + git_error_set(GIT_ERROR_INVALID, "failed to parse signature - %s", msg); + return GIT_EINVALID; +} + static int signature_error(const char *msg) { git_error_set(GIT_ERROR_INVALID, "failed to parse signature - %s", msg); @@ -206,13 +212,13 @@ int git_signature__parse(git_signature *sig, const char **buffer_out, if (ender && (buffer_end = memchr(buffer, ender, buffer_end - buffer)) == NULL) - return signature_error("no newline given"); + return signature_parse_error("no newline given"); if (header) { const size_t header_len = strlen(header); if (buffer + header_len >= buffer_end || memcmp(buffer, header, header_len) != 0) - return signature_error("expected prefix doesn't match actual"); + return signature_parse_error("expected prefix doesn't match actual"); buffer += header_len; } @@ -221,7 +227,7 @@ int git_signature__parse(git_signature *sig, const char **buffer_out, email_end = git__memrchr(buffer, '>', buffer_end - buffer); if (!email_start || !email_end || email_end <= email_start) - return signature_error("malformed e-mail"); + return signature_parse_error("malformed e-mail"); email_start += 1; sig->name = extract_trimmed(buffer, email_start - buffer - 1); @@ -237,7 +243,7 @@ int git_signature__parse(git_signature *sig, const char **buffer_out, git__free(sig->name); git__free(sig->email); sig->name = sig->email = NULL; - return signature_error("invalid Unix timestamp"); + return signature_parse_error("invalid Unix timestamp"); } /* do we have a timezone? */ diff --git a/src/tag.c b/src/tag.c index 837658a19f3..5734106faeb 100644 --- a/src/tag.c +++ b/src/tag.c @@ -62,7 +62,7 @@ const char *git_tag_message(const git_tag *t) static int tag_error(const char *str) { git_error_set(GIT_ERROR_TAG, "failed to parse tag: %s", str); - return -1; + return GIT_EINVALID; } static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end) @@ -73,6 +73,7 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end) size_t text_len, alloc_len; const char *search; unsigned int i; + int error; if (git_oid__parse(&tag->target, &buffer, buffer_end, "object ") < 0) return tag_error("object field invalid"); @@ -130,8 +131,8 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end) tag->tagger = git__malloc(sizeof(git_signature)); GIT_ERROR_CHECK_ALLOC(tag->tagger); - if (git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ", '\n') < 0) - return -1; + if ((error = git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ", '\n')) < 0) + return error; } tag->message = NULL; diff --git a/src/tree.c b/src/tree.c index b8e82d48574..7290e154d8d 100644 --- a/src/tree.c +++ b/src/tree.c @@ -351,15 +351,26 @@ size_t git_treebuilder_entrycount(git_treebuilder *bld) return git_strmap_size(bld->map); } -static int tree_error(const char *str, const char *path) +GIT_INLINE(void) set_error(const char *str, const char *path) { if (path) git_error_set(GIT_ERROR_TREE, "%s - %s", str, path); else git_error_set(GIT_ERROR_TREE, "%s", str); +} + +static int tree_error(const char *str, const char *path) +{ + set_error(str, path); return -1; } +static int tree_parse_error(const char *str, const char *path) +{ + set_error(str, path); + return GIT_EINVALID; +} + static int parse_mode(uint16_t *mode_out, const char *buffer, size_t buffer_len, const char **buffer_out) { int32_t mode; @@ -399,19 +410,19 @@ int git_tree__parse_raw(void *_tree, const char *data, size_t size) uint16_t attr; if (parse_mode(&attr, buffer, buffer_end - buffer, &buffer) < 0 || !buffer) - return tree_error("failed to parse tree: can't parse filemode", NULL); + return tree_parse_error("failed to parse tree: can't parse filemode", NULL); if (buffer >= buffer_end || (*buffer++) != ' ') - return tree_error("failed to parse tree: missing space after filemode", NULL); + return tree_parse_error("failed to parse tree: missing space after filemode", NULL); if ((nul = memchr(buffer, 0, buffer_end - buffer)) == NULL) - return tree_error("failed to parse tree: object is corrupted", NULL); + return tree_parse_error("failed to parse tree: object is corrupted", NULL); if ((filename_len = nul - buffer) == 0 || filename_len > UINT16_MAX) - return tree_error("failed to parse tree: can't parse filename", NULL); + return tree_parse_error("failed to parse tree: can't parse filename", NULL); if ((buffer_end - (nul + 1)) < GIT_OID_RAWSZ) - return tree_error("failed to parse tree: can't parse OID", NULL); + return tree_parse_error("failed to parse tree: can't parse OID", NULL); /* Allocate the entry */ { @@ -434,16 +445,15 @@ int git_tree__parse_raw(void *_tree, const char *data, size_t size) int git_tree__parse(void *_tree, git_odb_object *odb_obj) { git_tree *tree = _tree; + const char *data = git_odb_object_data(odb_obj); + size_t size = git_odb_object_size(odb_obj); + int error; - if ((git_tree__parse_raw(tree, - git_odb_object_data(odb_obj), - git_odb_object_size(odb_obj))) < 0) - return -1; - - if (git_odb_object_dup(&tree->odb_obj, odb_obj) < 0) - return -1; + if ((error = git_tree__parse_raw(tree, data, size)) < 0 || + (error = git_odb_object_dup(&tree->odb_obj, odb_obj)) < 0) + return error; - return 0; + return error; } static size_t find_next_dir(const char *dirname, git_index *index, size_t start) From 9f03ebd14b6beb00a9bed52c0568a13f8d5ebb08 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 29 Nov 2021 13:44:42 -0500 Subject: [PATCH 0665/1616] object: introduce a raw content validation function Users may want to validate raw object content; provide them a function to do so. --- include/git2/object.h | 22 ++++++++++++++++++ src/object.c | 32 ++++++++++++++++++++++++++ tests/object/validate.c | 50 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 tests/object/validate.c diff --git a/include/git2/object.h b/include/git2/object.h index 984dbb7ac0a..dbf480ed6be 100644 --- a/include/git2/object.h +++ b/include/git2/object.h @@ -224,6 +224,28 @@ GIT_EXTERN(int) git_object_peel( */ GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source); +/** + * Analyzes a buffer of raw object content and determines its validity. + * Tree, commit, and tag objects will be parsed and ensured that they + * are valid, parseable content. (Blobs are always valid by definition.) + * An error message will be set with an informative message if the object + * is not valid. + * + * @warning This function is experimental and its signature may change in + * the future. + * + * @param valid Output pointer to set with validity of the object content + * @param buf The contents to validate + * @param len The length of the buffer + * @param type The type of the object in the buffer + * @return 0 on success or an error code + */ +GIT_EXTERN(int) git_object_rawcontent_is_valid( + int *valid, + const char *buf, + size_t len, + git_object_t type); + /** @} */ GIT_END_DECL diff --git a/src/object.c b/src/object.c index 7e6ad3aa286..7bc256fcebd 100644 --- a/src/object.c +++ b/src/object.c @@ -567,3 +567,35 @@ bool git_object__is_valid( return true; } + +int git_object_rawcontent_is_valid( + int *valid, + const char *buf, + size_t len, + git_object_t type) +{ + git_object *obj = NULL; + int error; + + GIT_ASSERT_ARG(valid); + GIT_ASSERT_ARG(buf); + + /* Blobs are always valid; don't bother parsing. */ + if (type == GIT_OBJECT_BLOB) { + *valid = 1; + return 0; + } + + error = git_object__from_raw(&obj, buf, len, type); + git_object_free(obj); + + if (error == 0) { + *valid = 1; + return 0; + } else if (error == GIT_EINVALID) { + *valid = 0; + return 0; + } + + return error; +} diff --git a/tests/object/validate.c b/tests/object/validate.c new file mode 100644 index 00000000000..87193deb64c --- /dev/null +++ b/tests/object/validate.c @@ -0,0 +1,50 @@ +#include "clar_libgit2.h" + +#define VALID_COMMIT "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \ + "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \ + "author Edward Thomson 1638286404 -0500\n" \ + "committer Edward Thomson 1638324642 -0500\n" \ + "\n" \ + "commit go here.\n" +#define VALID_TREE "100644 HEADER\0\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42" + +#define INVALID_COMMIT "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \ + "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \ + "committer Edward Thomson 1638324642 -0500\n" \ + "\n" \ + "commit go here.\n" +#define INVALID_TREE "100644 HEADER \x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42" + +void test_object_validate__valid(void) +{ + int valid; + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_BLOB)); + cl_assert_equal_i(1, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_BLOB)); + cl_assert_equal_i(1, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_COMMIT, CONST_STRLEN(VALID_COMMIT), GIT_OBJECT_COMMIT)); + cl_assert_equal_i(1, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_TREE, CONST_STRLEN(VALID_TREE), GIT_OBJECT_TREE)); + cl_assert_equal_i(1, valid); +} + +void test_object_validate__invalid(void) +{ + int valid; + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_COMMIT)); + cl_assert_equal_i(0, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_COMMIT)); + cl_assert_equal_i(0, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_COMMIT, CONST_STRLEN(INVALID_COMMIT), GIT_OBJECT_COMMIT)); + cl_assert_equal_i(0, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_TREE, CONST_STRLEN(INVALID_TREE), GIT_OBJECT_TREE)); + cl_assert_equal_i(0, valid); +} From 433edb54b74cab470a1129cc8df5cbfaa0166c62 Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Thu, 25 Nov 2021 10:22:22 +0100 Subject: [PATCH 0666/1616] Config parsing confused by continuations that start with quotes (fixes issue #6089) Signed-off-by: Sven Strickroth --- src/config_parse.c | 2 +- tests/config/read.c | 13 +++++++++++++ tests/resources/config/config22 | 10 ++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tests/resources/config/config22 diff --git a/src/config_parse.c b/src/config_parse.c index 3159cbef768..e96edc36d5b 100644 --- a/src/config_parse.c +++ b/src/config_parse.c @@ -36,7 +36,7 @@ static int strip_comments(char *line, int in_quotes) char *ptr; for (ptr = line; *ptr; ++ptr) { - if (ptr[0] == '"' && ptr > line && ptr[-1] != '\\') + if (ptr[0] == '"' && ((ptr > line && ptr[-1] != '\\') || ptr == line)) quote_count++; if ((ptr[0] == ';' || ptr[0] == '#') && diff --git a/tests/config/read.c b/tests/config/read.c index 3c96f851955..5d23ce47155 100644 --- a/tests/config/read.c +++ b/tests/config/read.c @@ -219,6 +219,19 @@ void test_config_read__multiline_multiple_quoted_comment_chars(void) git_config_free(cfg); } +void test_config_read__multiline_multiple_quoted_quote_at_beginning_of_line(void) +{ + git_config* cfg; + cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config22"))); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "alias.m")); + cl_assert_equal_s("cmd ;; ;; bar", buf.ptr); + git_buf_dispose(&buf); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "alias.m2")); + cl_assert_equal_s("'; ; something '", buf.ptr); + git_buf_dispose(&buf); + git_config_free(cfg); +} + void test_config_read__header_in_last_line(void) { git_config *cfg; diff --git a/tests/resources/config/config22 b/tests/resources/config/config22 new file mode 100644 index 00000000000..2a8e528ff97 --- /dev/null +++ b/tests/resources/config/config22 @@ -0,0 +1,10 @@ +[alias] + m = cmd \ +";;" \ +";;" \ +bar + m2 = '\ +";" \ +";" \ +something \ +' From 854164a5cad8681983f0912d7255d0845ef4f7c2 Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Thu, 25 Nov 2021 11:02:41 +0100 Subject: [PATCH 0667/1616] Add more tests for contents Signed-off-by: Sven Strickroth --- tests/config/read.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/config/read.c b/tests/config/read.c index 5d23ce47155..a2e668c207b 100644 --- a/tests/config/read.c +++ b/tests/config/read.c @@ -209,6 +209,21 @@ void test_config_read__symbol_headers(void) { git_config *cfg; cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config20"))); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "valid.[subsection].something")); + cl_assert_equal_s("a", buf.ptr); + git_buf_dispose(&buf); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "sec.[subsec]/child.parent")); + cl_assert_equal_s("grand", buf.ptr); + git_buf_dispose(&buf); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "sec2.[subsec2]/child2.type")); + cl_assert_equal_s("dvcs", buf.ptr); + git_buf_dispose(&buf); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "sec3.escape\"quote.vcs")); + cl_assert_equal_s("git", buf.ptr); + git_buf_dispose(&buf); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "sec4.escaping\\slash.lib")); + cl_assert_equal_s("git2", buf.ptr); + git_buf_dispose(&buf); git_config_free(cfg); } From dff05bc308f40fe327364334eaae412afca8ad61 Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Thu, 25 Nov 2021 11:40:20 +0100 Subject: [PATCH 0668/1616] Multiline config values not preserved on saving (fixes issue #6088) Signed-off-by: Sven Strickroth --- src/config_parse.c | 12 ++++++++---- tests/config/write.c | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/config_parse.c b/src/config_parse.c index e96edc36d5b..06931368e7b 100644 --- a/src/config_parse.c +++ b/src/config_parse.c @@ -325,7 +325,7 @@ static int unescape_line( return 0; } -static int parse_multiline_variable(git_config_parser *reader, git_str *value, int in_quotes) +static int parse_multiline_variable(git_config_parser *reader, git_str *value, int in_quotes, size_t *line_len) { int quote_count; bool multiline = true; @@ -338,6 +338,10 @@ static int parse_multiline_variable(git_config_parser *reader, git_str *value, i git_parse_advance_line(&reader->ctx); line = git__strndup(reader->ctx.line, reader->ctx.line_len); GIT_ERROR_CHECK_ALLOC(line); + if (GIT_ADD_SIZET_OVERFLOW(line_len, *line_len, reader->ctx.line_len)) { + error = -1; + goto out; + } /* * We've reached the end of the file, there is no continuation. @@ -415,7 +419,7 @@ static int parse_name( return 0; } -static int parse_variable(git_config_parser *reader, char **var_name, char **var_value) +static int parse_variable(git_config_parser *reader, char **var_name, char **var_value, size_t *line_len) { const char *value_start = NULL; char *line = NULL, *name = NULL, *value = NULL; @@ -449,7 +453,7 @@ static int parse_variable(git_config_parser *reader, char **var_name, char **var git_str_attach(&multi_value, value, 0); value = NULL; - if (parse_multiline_variable(reader, &multi_value, quote_count % 2) < 0 || + if (parse_multiline_variable(reader, &multi_value, quote_count % 2, line_len) < 0 || git_str_oom(&multi_value)) { error = -1; git_str_dispose(&multi_value); @@ -554,7 +558,7 @@ int git_config_parse( break; default: /* assume variable declaration */ - if ((result = parse_variable(parser, &var_name, &var_value)) == 0 && on_variable) { + if ((result = parse_variable(parser, &var_name, &var_value, &line_len)) == 0 && on_variable) { result = on_variable(parser, current_section, var_name, var_value, line_start, line_len, payload); git__free(var_name); git__free(var_value); diff --git a/tests/config/write.c b/tests/config/write.c index 4ee83833f06..9d8c3fe9495 100644 --- a/tests/config/write.c +++ b/tests/config/write.c @@ -8,6 +8,7 @@ void test_config_write__initialize(void) cl_fixture_sandbox("config/config9"); cl_fixture_sandbox("config/config15"); cl_fixture_sandbox("config/config17"); + cl_fixture_sandbox("config/config22"); } void test_config_write__cleanup(void) @@ -15,6 +16,7 @@ void test_config_write__cleanup(void) cl_fixture_cleanup("config9"); cl_fixture_cleanup("config15"); cl_fixture_cleanup("config17"); + cl_fixture_cleanup("config22"); } void test_config_write__replace_value(void) @@ -743,3 +745,20 @@ void test_config_write__preserve_case(void) git_config_free(cfg); } + +void test_config_write__write_config_file_with_multi_line_value(void) +{ + git_config* cfg; + git_buf buf = GIT_BUF_INIT; + + cl_git_pass(git_config_open_ondisk(&cfg, "config22")); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "alias.m")); + cl_assert_equal_s("cmd ;; ;; bar", buf.ptr); + cl_git_pass(git_config_set_string(cfg, "sOMe.ThInG", "foo")); + git_buf_dispose(&buf); + cl_git_pass(git_config_get_string_buf(&buf, cfg, "alias.m")); + cl_assert_equal_s("cmd ;; ;; bar", buf.ptr); + git_buf_dispose(&buf); + + git_config_free(cfg); +} From 4591e76a2d1aa07dc80eaa002b4ed7c58d81c242 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 10 Dec 2021 15:19:59 -0500 Subject: [PATCH 0669/1616] blob: identify binary content Introduce `git_blob_data_is_binary` to examine a blob's data, instead of the blob itself. A replacement for `git_buf_is_binary`. --- include/git2/blob.h | 12 ++++++++++++ src/blob.c | 9 +++++++++ tests/diff/blob.c | 16 ++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/include/git2/blob.h b/include/git2/blob.h index 4922b087a56..59fac9e2061 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -284,6 +284,18 @@ GIT_EXTERN(int) git_blob_create_from_buffer( */ GIT_EXTERN(int) git_blob_is_binary(const git_blob *blob); +/** + * Determine if the given content is most certainly binary or not; + * this is the same mechanism used by `git_blob_is_binary` but only + * looking at raw data. + * + * @param data The blob data which content should be analyzed + * @param len The length of the data + * @return 1 if the content of the blob is detected + * as binary; 0 otherwise. + */ +GIT_EXTERN(int) git_blob_data_is_binary(const char *data, size_t len); + /** * Create an in-memory copy of a blob. The copy must be explicitly * free'd or it will leak. diff --git a/src/blob.c b/src/blob.c index 65841ab03da..19ce8b3b50b 100644 --- a/src/blob.c +++ b/src/blob.c @@ -404,6 +404,15 @@ int git_blob_is_binary(const git_blob *blob) return git_str_is_binary(&content); } +int git_blob_data_is_binary(const char *str, size_t len) +{ + git_str content = GIT_STR_INIT; + + git_str_attach_notowned(&content, str, len); + + return git_str_is_binary(&content); +} + int git_blob_filter_options_init( git_blob_filter_options *opts, unsigned int version) diff --git a/tests/diff/blob.c b/tests/diff/blob.c index 9f71e4ea6e6..d2f42207d7d 100644 --- a/tests/diff/blob.c +++ b/tests/diff/blob.c @@ -604,12 +604,28 @@ void test_diff_blob__can_correctly_detect_a_binary_blob_as_binary(void) cl_assert_equal_i(true, git_blob_is_binary(alien)); } +void test_diff_blob__can_correctly_detect_binary_blob_data_as_binary(void) +{ + /* alien.png */ + const char *content = git_blob_rawcontent(alien); + size_t len = (size_t)git_blob_rawsize(alien); + cl_assert_equal_i(true, git_blob_data_is_binary(content, len)); +} + void test_diff_blob__can_correctly_detect_a_textual_blob_as_non_binary(void) { /* tests/resources/attr/root_test4.txt */ cl_assert_equal_i(false, git_blob_is_binary(d)); } +void test_diff_blob__can_correctly_detect_textual_blob_data_as_non_binary(void) +{ + /* tests/resources/attr/root_test4.txt */ + const char *content = git_blob_rawcontent(d); + size_t len = (size_t)git_blob_rawsize(d); + cl_assert_equal_i(false, git_blob_data_is_binary(content, len)); +} + /* * git_diff_blob_to_buffer tests */ From 5761980d11c739be3b360b5fb0d45552d8495291 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Sat, 11 Dec 2021 22:33:16 -0400 Subject: [PATCH 0670/1616] Simplifications to definitions to avoid UINT64_C --- src/commit_graph.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commit_graph.c b/src/commit_graph.c index 82b3901b3c7..3709fa3410d 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -1075,11 +1075,11 @@ static int commit_graph_write( commit_time = (uint64_t)packed_commit->commit_time; if (generation > GIT_COMMIT_GRAPH_GENERATION_NUMBER_MAX) generation = GIT_COMMIT_GRAPH_GENERATION_NUMBER_MAX; - word = ntohl((uint32_t)((generation << 2) | ((commit_time >> UINT64_C(32)) & UINT64_C(0x3)))); + word = ntohl((uint32_t)((generation << 2) | (((uint32_t)(commit_time >> 32)) & 0x3) )); error = git_str_put(&commit_data, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; - word = ntohl((uint32_t)(commit_time & UINT64_C(0xffffffff))); + word = ntohl((uint32_t)(commit_time & 0xfffffffful)); error = git_str_put(&commit_data, (const char *)&word, sizeof(word)); if (error < 0) goto cleanup; From ad7a51d83496cb6f2bb7b08a426f832f589c7707 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 7 Oct 2021 13:26:52 -0500 Subject: [PATCH 0671/1616] refs: Speed up packed lookups. Currently ref lookups require loading the entire packed-refs file into a hashmap in memory. For repos with large numbers of refs this can be painfully slow. This patch replaces the existing lookup code and instead mmap()'s the packed-refs file and performs a binary search to locate the ref entry. Git uses a similiar approach. The old hash table codepath is still used for unsorted packed-refs files. This patch also fixes a minor bug where the "peeled" trait is never parsed correctly from the packed-refs header. --- docs/changelog.md | 5 + src/refdb_fs.c | 310 ++++++++++++++++-- tests/refs/crashes.c | 24 ++ tests/resources/peeled.git/packed-refs | 2 +- tests/resources/testrepo.git/packed-refs | 2 +- tests/resources/testrepo/.gitted/packed-refs | 2 +- tests/resources/testrepo2/.gitted/packed-refs | 2 +- 7 files changed, 317 insertions(+), 30 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 8060874df0e..3723a080c45 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1963,3 +1963,8 @@ v0.22 functions. This is not something which we can know to do. A last-resort convenience function is provided in sys/openssl.h, `git_openssl_set_locking()` which can be used to set the locking. + +* `git_reference_*()` functions use mmap() + binary search for packed + refs lookups when using the fs backend. Previously all entries were + read into a hashtable, which could be slow for repositories with a + large number of refs. diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 055ca2559ce..2b9d05fa5b4 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -65,9 +65,13 @@ typedef struct refdb_fs_backend { git_iterator_flag_t iterator_flags; uint32_t direach_flags; int fsync; + git_map packed_refs_map; + git_mutex prlock; /* protect packed_refs_map */ + bool sorted; } refdb_fs_backend; static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name); +static const char * packed_set_peeling_mode(const char *data, size_t data_sz, refdb_fs_backend *backend); GIT_INLINE(int) loose_path( git_str *out, @@ -137,27 +141,9 @@ static int packed_reload(refdb_fs_backend *backend) scan = (char *)packedrefs.ptr; eof = scan + packedrefs.size; - backend->peeling_mode = PEELING_NONE; - - if (*scan == '#') { - static const char *traits_header = "# pack-refs with: "; - - if (git__prefixcmp(scan, traits_header) == 0) { - scan += strlen(traits_header); - eol = strchr(scan, '\n'); - - if (!eol) - goto parse_failed; - *eol = '\0'; - - if (strstr(scan, " fully-peeled ") != NULL) { - backend->peeling_mode = PEELING_FULL; - } else if (strstr(scan, " peeled ") != NULL) { - backend->peeling_mode = PEELING_STANDARD; - } - - scan = eol + 1; - } + scan = (char *)packed_set_peeling_mode(scan, packedrefs.size, backend); + if (!scan) { + goto parse_failed; } while (scan < eof && *scan == '#') { @@ -466,10 +452,176 @@ static int ref_error_notfound(const char *name) return GIT_ENOTFOUND; } -static int packed_lookup( - git_reference **out, - refdb_fs_backend *backend, - const char *ref_name) +static const char *packed_set_peeling_mode( + const char *data, + size_t data_sz, + refdb_fs_backend *backend) +{ + static const char *traits_header = "# pack-refs with:"; + const char *eol; + backend->peeling_mode = PEELING_NONE; + + if (data_sz == 0 || *data != '#') { + return data; + } + + if (git__prefixncmp(data, data_sz, traits_header) == 0) { + size_t hdr_sz = strlen(traits_header); + const char *sorted = " sorted "; + const char *peeled = " peeled "; + const char *fully_peeled = " fully-peeled "; + data += hdr_sz; + data_sz -= hdr_sz; + + eol = memchr(data, '\n', data_sz); + + if (!eol) + return NULL; + + if (git__memmem(data, eol - data, fully_peeled, strlen(fully_peeled))) { + backend->peeling_mode = PEELING_FULL; + } else if (git__memmem(data, eol - data, peeled, strlen(peeled))) { + backend->peeling_mode = PEELING_STANDARD; + } + + if (git__memmem(data, eol - data, sorted, strlen(sorted))) { + backend->sorted = true; + } else { + backend->sorted = false; + } + + return eol + 1; + } + return data; +} + +static int packed_map_check(refdb_fs_backend *backend) +{ + int error = 0; + git_file fd = -1; + struct stat st; + + if ((error = git_mutex_lock(&backend->prlock)) < 0) { + return error; + } + + if (backend->packed_refs_map.data) { + git_mutex_unlock(&backend->prlock); + return error; + } + + fd = git_futils_open_ro(backend->refcache->path); + if (fd < 0) { + git_mutex_unlock(&backend->prlock); + if (fd == GIT_ENOTFOUND) { + git_error_clear(); + return 0; + } + return fd; + } + + if (p_fstat(fd, &st) < 0) { + p_close(fd); + git_mutex_unlock(&backend->prlock); + git_error_set(GIT_ERROR_OS, "unable to stat packed-refs '%s'", backend->refcache->path); + return -1; + } + + if (st.st_size == 0) { + p_close(fd); + git_mutex_unlock(&backend->prlock); + return 0; + } + + error = git_futils_mmap_ro(&backend->packed_refs_map, fd, 0, (size_t)st.st_size); + p_close(fd); + if (error < 0) { + git_mutex_unlock(&backend->prlock); + return error; + } + + packed_set_peeling_mode( + backend->packed_refs_map.data, backend->packed_refs_map.len, + backend); + + git_mutex_unlock(&backend->prlock); + return error; +} + +/* + * Find beginning of packed-ref record pointed to by p. + * buf - a lower-bound pointer to some memory buffer + * p - an upper-bound pointer to the same memory buffer + */ +static const char *start_of_record(const char *buf, const char *p) +{ + const char *nl = p; + while (1) { + nl = git__memrchr(buf, '\n', nl - buf); + if (!nl) + return buf; + + if (nl[1] == '^' && nl > buf) + --nl; + else + break; + }; + return nl + 1; +} + +/* + * Find end of packed-ref record pointed to by p. + * end - an upper-bound pointer to some memory buffer + * p - a lower-bound pointer to the same memory buffer + */ +static const char *end_of_record(const char *p, const char *end) +{ + while (1) { + size_t sz = end - p; + p = memchr(p, '\n', sz); + if (!p) { + return end; + } + ++p; + if (p < end && p[0] == '^') + ++p; + else + break; + } + return p; +} + +static int +cmp_record_to_refname(const char *rec, size_t data_end, const char *ref_name) +{ + const size_t ref_len = strlen(ref_name); + int cmp_val; + const char *end; + + rec += GIT_OID_HEXSZ + 1; /* + space */ + if (data_end < GIT_OID_HEXSZ + 3) { + /* an incomplete (corrupt) record is treated as less than ref_name */ + return -1; + } + data_end -= GIT_OID_HEXSZ + 1; + + end = memchr(rec, '\n', data_end); + if (end) { + data_end = end - rec; + } + + cmp_val = memcmp(rec, ref_name, min(ref_len, data_end)); + + if (cmp_val == 0 && data_end != ref_len) { + return (data_end > ref_len) ? 1 : -1; + } + return cmp_val; +} + +static int packed_unsorted_lookup( + git_reference **out, + refdb_fs_backend *backend, + const char *ref_name) { int error = 0; struct packref *entry; @@ -494,6 +646,86 @@ static int packed_lookup( return error; } +static int packed_lookup( + git_reference **out, + refdb_fs_backend *backend, + const char *ref_name) +{ + int error = 0; + const char *left, *right, *data_end; + + if ((error = packed_map_check(backend)) < 0) + return error; + + if (!backend->sorted) { + return packed_unsorted_lookup(out, backend, ref_name); + } + + left = backend->packed_refs_map.data; + right = data_end = ((const char *)backend->packed_refs_map.data) + + backend->packed_refs_map.len; + + while (left < right && *left == '#') { + if (!(left = memchr(left, '\n', data_end - left))) + goto parse_failed; + left++; + } + + while (left < right) { + const char *mid, *rec; + int compare; + + mid = left + (right - left) / 2; + rec = start_of_record(left, mid); + compare = cmp_record_to_refname(rec, data_end - rec, ref_name); + + if (compare < 0) { + left = end_of_record(mid, right); + } else if (compare > 0) { + right = rec; + } else { + const char *eol; + git_oid oid, peel, *peel_ptr = NULL; + + if (data_end - rec < GIT_OID_HEXSZ || + git_oid_fromstr(&oid, rec) < 0) { + goto parse_failed; + } + rec += GIT_OID_HEXSZ + 1; + if (!(eol = memchr(rec, '\n', data_end - rec))) { + goto parse_failed; + } + + /* look for optional "^\n" */ + + if (eol + 1 < data_end) { + rec = eol + 1; + + if (*rec == '^') { + rec++; + if (data_end - rec < GIT_OID_HEXSZ || + git_oid_fromstr(&peel, rec) < 0) { + goto parse_failed; + } + peel_ptr = &peel; + } + } + + *out = git_reference__alloc(ref_name, &oid, peel_ptr); + if (!*out) { + return -1; + } + + return 0; + } + } + return GIT_ENOTFOUND; + +parse_failed: + git_error_set(GIT_ERROR_REFERENCE, "corrupted packed references file"); + return -1; +} + static int refdb_fs_backend__lookup( git_reference **out, git_refdb_backend *_backend, @@ -513,7 +745,6 @@ static int refdb_fs_backend__lookup( git_error_clear(); error = packed_lookup(out, backend, ref_name); } - return error; } @@ -1081,6 +1312,18 @@ static int packed_write(refdb_fs_backend *backend) int error, open_flags = 0; size_t i; + /* take lock and close up packed-refs mmap if open */ + if ((error = git_mutex_lock(&backend->prlock)) < 0) { + return error; + } + + if (backend->packed_refs_map.data) { + git_futils_mmap_free(&backend->packed_refs_map); + backend->packed_refs_map.data = NULL; + } + + git_mutex_unlock(&backend->prlock); + /* lock the cache to updates while we do this */ if ((error = git_sortedcache_wlock(refcache)) < 0) return error; @@ -1568,6 +1811,15 @@ static void refdb_fs_backend__free(git_refdb_backend *_backend) return; git_sortedcache_free(backend->refcache); + + git_mutex_lock(&backend->prlock); + if (backend->packed_refs_map.data) { + git_futils_mmap_free(&backend->packed_refs_map); + backend->packed_refs_map.data = NULL; + } + git_mutex_unlock(&backend->prlock); + git_mutex_free(&backend->prlock); + git__free(backend->gitpath); git__free(backend->commonpath); git__free(backend); @@ -2121,6 +2373,11 @@ int git_refdb_backend_fs( backend = git__calloc(1, sizeof(refdb_fs_backend)); GIT_ERROR_CHECK_ALLOC(backend); + if (git_mutex_init(&backend->prlock) < 0) { + git__free(backend); + return -1; + } + if (git_refdb_init_backend(&backend->parent, GIT_REFDB_BACKEND_VERSION) < 0) goto fail; @@ -2183,6 +2440,7 @@ int git_refdb_backend_fs( return 0; fail: + git_mutex_free(&backend->prlock); git_str_dispose(&gitpath); git__free(backend->gitpath); git__free(backend->commonpath); diff --git a/tests/refs/crashes.c b/tests/refs/crashes.c index 228f479a07a..4f508aed2f4 100644 --- a/tests/refs/crashes.c +++ b/tests/refs/crashes.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" +#include "refs.h" void test_refs_crashes__double_free(void) { @@ -18,3 +19,26 @@ void test_refs_crashes__double_free(void) cl_git_sandbox_cleanup(); } + +void test_refs_crashes__empty_packedrefs(void) +{ + git_repository *repo; + git_reference *ref; + const char *REFNAME = "refs/heads/xxx"; + git_str temp_path = GIT_STR_INIT; + int fd = 0; + + repo = cl_git_sandbox_init("empty_bare.git"); + + /* create zero-length packed-refs file */ + cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(repo), GIT_PACKEDREFS_FILE)); + cl_git_pass(((fd = p_creat(temp_path.ptr, 0644)) < 0)); + cl_git_pass(p_close(fd)); + + /* should fail gracefully */ + cl_git_fail_with( + GIT_ENOTFOUND, git_reference_lookup(&ref, repo, REFNAME)); + + cl_git_sandbox_cleanup(); + git_str_dispose(&temp_path); +} diff --git a/tests/resources/peeled.git/packed-refs b/tests/resources/peeled.git/packed-refs index ad053d550bc..078f237ed3a 100644 --- a/tests/resources/peeled.git/packed-refs +++ b/tests/resources/peeled.git/packed-refs @@ -1,4 +1,4 @@ -# pack-refs with: peeled fully-peeled +# pack-refs with: peeled fully-peeled sorted c2596aa0151888587ec5c0187f261e63412d9e11 refs/foo/tag-outside-tags ^0df1a5865c8abfc09f1f2182e6a31be550e99f07 0df1a5865c8abfc09f1f2182e6a31be550e99f07 refs/heads/master diff --git a/tests/resources/testrepo.git/packed-refs b/tests/resources/testrepo.git/packed-refs index 52f5e876fbc..fadd7e88aba 100644 --- a/tests/resources/testrepo.git/packed-refs +++ b/tests/resources/testrepo.git/packed-refs @@ -1,3 +1,3 @@ -# pack-refs with: peeled +# pack-refs with: peeled sorted 41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/heads/packed 5b5b025afb0b4c913b4c338a42934a3863bf3644 refs/heads/packed-test diff --git a/tests/resources/testrepo/.gitted/packed-refs b/tests/resources/testrepo/.gitted/packed-refs index 6018a19d2e9..b57898695e3 100644 --- a/tests/resources/testrepo/.gitted/packed-refs +++ b/tests/resources/testrepo/.gitted/packed-refs @@ -1,4 +1,4 @@ -# pack-refs with: peeled +# pack-refs with: peeled sorted 41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/heads/packed 5b5b025afb0b4c913b4c338a42934a3863bf3644 refs/heads/packed-test b25fa35b38051e4ae45d4222e795f9df2e43f1d1 refs/tags/packed-tag diff --git a/tests/resources/testrepo2/.gitted/packed-refs b/tests/resources/testrepo2/.gitted/packed-refs index 97ea6a848d1..01de8717328 100644 --- a/tests/resources/testrepo2/.gitted/packed-refs +++ b/tests/resources/testrepo2/.gitted/packed-refs @@ -1,4 +1,4 @@ -# pack-refs with: peeled fully-peeled +# pack-refs with: peeled fully-peeled sorted 36060c58702ed4c2a40832c51758d5344201d89a refs/remotes/origin/master 41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9 refs/remotes/origin/packed 5b5b025afb0b4c913b4c338a42934a3863bf3644 refs/tags/v0.9 From c5cd71b203cd73a815aa4bc8b9ef603800fa8b4b Mon Sep 17 00:00:00 2001 From: Josh Junon Date: Thu, 23 Dec 2021 18:23:34 +0100 Subject: [PATCH 0672/1616] cmake: use PROJECT_SOURCE_DIR of CMAKE_SOURCE_DIR Also applies to *_BINARY_DIR. This effectively reverts 84083dcc8bd41332ccac9d7b537f3e254d79011c, which broke all users of libgit2 that use it as a CMake subdirectory (via `add_subdirectory()`). This is because CMAKE_SOURCE_DIR refers to the root-most CMake directory, which in the case of `add_subdirectory()` is a parent project to libgit2 and thus the paths don't make any sense to the configuration files. Corollary, CMAKE_SOURCE_DIR only makes sense if the CMake project is always the root project - which can rarely be guaranteed. In all honesty, CMake should deprecate and eventually remove CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR. It's been the source of headaches and confusion for years, they're rarely useful over CMAKE_CURRENT_(SOURCE|BINARY)_DIR or PROJECT_(SOURCE|BINARY)_DIR, and they cause a lot of confusing configuration and source code layouts to boot. Any time they are used, they break `add_subdirectory()` almost 100% of the time, cause confusing error messages, and hide subtle bugs. --- CMakeLists.txt | 2 +- cmake/IdeSplitSources.cmake | 2 +- cmake/SelectHTTPParser.cmake | 4 ++-- cmake/SelectRegex.cmake | 4 ++-- cmake/SelectWinHTTP.cmake | 4 ++-- cmake/SelectZlib.cmake | 8 ++++---- deps/winhttp/CMakeLists.txt | 2 +- src/CMakeLists.txt | 26 +++++++++++++------------- tests/CMakeLists.txt | 6 +++--- 9 files changed, 29 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a010681b06..32bb4502bac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.5.1) project(libgit2 VERSION "1.3.0" LANGUAGES C) # Add find modules to the path -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") # # Build options diff --git a/cmake/IdeSplitSources.cmake b/cmake/IdeSplitSources.cmake index 9e16cbc5fde..4f928ac081f 100644 --- a/cmake/IdeSplitSources.cmake +++ b/cmake/IdeSplitSources.cmake @@ -8,7 +8,7 @@ function(IDE_SPLIT_SOURCES target) get_target_property(sources ${target} SOURCES) foreach(source ${sources}) if(source MATCHES ".*/") - string(REPLACE ${CMAKE_SOURCE_DIR}/ "" rel ${source}) + string(REPLACE ${PROJECT_SOURCE_DIR}/ "" rel ${source}) if(rel) string(REGEX REPLACE "/([^/]*)$" "" rel ${rel}) if(rel) diff --git a/cmake/SelectHTTPParser.cmake b/cmake/SelectHTTPParser.cmake index ffc897fbc41..bb6ef551726 100644 --- a/cmake/SelectHTTPParser.cmake +++ b/cmake/SelectHTTPParser.cmake @@ -12,8 +12,8 @@ if(USE_HTTP_PARSER STREQUAL "system") endif() else() message(STATUS "http-parser version 2 was not found or disabled; using bundled 3rd-party sources.") - add_subdirectory("${CMAKE_SOURCE_DIR}/deps/http-parser" "${CMAKE_BINARY_DIR}/deps/http-parser") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/http-parser") + add_subdirectory("${PROJECT_SOURCE_DIR}/deps/http-parser" "${PROJECT_BINARY_DIR}/deps/http-parser") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/http-parser") list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") add_feature_info(http-parser ON "http-parser support (bundled)") endif() diff --git a/cmake/SelectRegex.cmake b/cmake/SelectRegex.cmake index 88aa156b7e5..2a3a91b8cd3 100644 --- a/cmake/SelectRegex.cmake +++ b/cmake/SelectRegex.cmake @@ -43,8 +43,8 @@ elseif(REGEX_BACKEND STREQUAL "builtin") add_feature_info(regex ON "using bundled PCRE") set(GIT_REGEX_BUILTIN 1) - add_subdirectory("${CMAKE_SOURCE_DIR}/deps/pcre" "${CMAKE_BINARY_DIR}/deps/pcre") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/pcre") + add_subdirectory("${PROJECT_SOURCE_DIR}/deps/pcre" "${PROJECT_BINARY_DIR}/deps/pcre") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/pcre") list(APPEND LIBGIT2_DEPENDENCY_OBJECTS $) else() message(FATAL_ERROR "The REGEX_BACKEND option provided is not supported") diff --git a/cmake/SelectWinHTTP.cmake b/cmake/SelectWinHTTP.cmake index 38642e13645..96e0bdbae54 100644 --- a/cmake/SelectWinHTTP.cmake +++ b/cmake/SelectWinHTTP.cmake @@ -4,9 +4,9 @@ if(WIN32 AND USE_WINHTTP) # Since MinGW does not come with headers or an import library for winhttp, # we have to include a private header and generate our own import library if(MINGW) - add_subdirectory("${CMAKE_SOURCE_DIR}/deps/winhttp" "${CMAKE_BINARY_DIR}/deps/winhttp") + add_subdirectory("${PROJECT_SOURCE_DIR}/deps/winhttp" "${PROJECT_BINARY_DIR}/deps/winhttp") list(APPEND LIBGIT2_SYSTEM_LIBS winhttp) - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/winhttp") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/winhttp") else() list(APPEND LIBGIT2_SYSTEM_LIBS "winhttp") list(APPEND LIBGIT2_PC_LIBS "-lwinhttp") diff --git a/cmake/SelectZlib.cmake b/cmake/SelectZlib.cmake index 0de1d4a98cd..fb4361abc80 100644 --- a/cmake/SelectZlib.cmake +++ b/cmake/SelectZlib.cmake @@ -22,13 +22,13 @@ if(USE_BUNDLED_ZLIB STREQUAL "OFF") endif() endif() if(USE_BUNDLED_ZLIB STREQUAL "Chromium") - add_subdirectory("${CMAKE_SOURCE_DIR}/deps/chromium-zlib" "${CMAKE_BINARY_DIR}/deps/chromium-zlib") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/chromium-zlib") + add_subdirectory("${PROJECT_SOURCE_DIR}/deps/chromium-zlib" "${PROJECT_BINARY_DIR}/deps/chromium-zlib") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/chromium-zlib") list(APPEND LIBGIT2_DEPENDENCY_OBJECTS $) add_feature_info(zlib ON "using (Chromium) bundled zlib") elseif(USE_BUNDLED_ZLIB OR NOT ZLIB_FOUND) - add_subdirectory("${CMAKE_SOURCE_DIR}/deps/zlib" "${CMAKE_BINARY_DIR}/deps/zlib") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/zlib") + add_subdirectory("${PROJECT_SOURCE_DIR}/deps/zlib" "${PROJECT_BINARY_DIR}/deps/zlib") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/zlib") list(APPEND LIBGIT2_DEPENDENCY_OBJECTS $) add_feature_info(zlib ON "using bundled zlib") endif() diff --git a/deps/winhttp/CMakeLists.txt b/deps/winhttp/CMakeLists.txt index c11a867a872..1a87989b97f 100644 --- a/deps/winhttp/CMakeLists.txt +++ b/deps/winhttp/CMakeLists.txt @@ -3,7 +3,7 @@ if(NOT DLLTOOL) message(FATAL_ERROR "Could not find dlltool command") endif() -set(LIBWINHTTP_PATH "${CMAKE_BINARY_DIR}/deps/winhttp") +set(LIBWINHTTP_PATH "${PROJECT_BINARY_DIR}/deps/winhttp") set(LIBWINHTTP_PATH ${LIBWINHTTP_PATH} PARENT_SCOPE) file(MAKE_DIRECTORY ${LIBWINHTTP_PATH}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 03609b681cd..98881b5add6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,8 +36,8 @@ set(LIBGIT2_PC_LIBS "") set(LIBGIT2_INCLUDES "${CMAKE_CURRENT_BINARY_DIR}" - "${CMAKE_SOURCE_DIR}/src" - "${CMAKE_SOURCE_DIR}/include") + "${PROJECT_SOURCE_DIR}/src" + "${PROJECT_SOURCE_DIR}/include") if(HAVE_FUTIMENS) set(GIT_USE_FUTIMENS 1) @@ -117,8 +117,8 @@ target_sources(git2internal PRIVATE ${SRC_SHA1}) # Optional external dependency: ntlmclient if(USE_NTLMCLIENT) set(GIT_NTLM 1) - add_subdirectory("${CMAKE_SOURCE_DIR}/deps/ntlmclient" "${CMAKE_BINARY_DIR}/deps/ntlmclient") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${CMAKE_SOURCE_DIR}/deps/ntlmclient") + add_subdirectory("${PROJECT_SOURCE_DIR}/deps/ntlmclient" "${PROJECT_BINARY_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/ntlmclient") list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") endif() add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix") @@ -164,9 +164,9 @@ target_compile_definitions(git2internal PRIVATE _FILE_OFFSET_BITS=64) # Collect sourcefiles file(GLOB SRC_H - "${CMAKE_SOURCE_DIR}/include/git2.h" - "${CMAKE_SOURCE_DIR}/include/git2/*.h" - "${CMAKE_SOURCE_DIR}/include/git2/sys/*.h") + "${PROJECT_SOURCE_DIR}/include/git2.h" + "${PROJECT_SOURCE_DIR}/include/git2/*.h" + "${PROJECT_SOURCE_DIR}/include/git2/sys/*.h") list(SORT SRC_H) target_sources(git2internal PRIVATE ${SRC_H}) @@ -225,7 +225,7 @@ configure_file(features.h.in git2/sys/features.h) ide_split_sources(git2internal) list(APPEND LIBGIT2_OBJECTS $ ${LIBGIT2_DEPENDENCY_OBJECTS}) -target_include_directories(git2internal PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${CMAKE_SOURCE_DIR}/include) +target_include_directories(git2internal PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${PROJECT_SOURCE_DIR}/include) target_include_directories(git2internal SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) set(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE) @@ -247,9 +247,9 @@ add_library(git2 ${WIN_RC} ${LIBGIT2_OBJECTS}) target_link_libraries(git2 ${LIBGIT2_SYSTEM_LIBS}) set_target_properties(git2 PROPERTIES C_STANDARD 90) -set_target_properties(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) -set_target_properties(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) -set_target_properties(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set_target_properties(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) +set_target_properties(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) +set_target_properties(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) # Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240) # Win64+MSVC+static libs = linker error @@ -290,5 +290,5 @@ install(TARGETS git2 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) -install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -install(FILES ${CMAKE_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(FILES ${PROJECT_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2272dec98d8..fdf194d0e9d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -38,7 +38,7 @@ set_source_files_properties( add_executable(libgit2_tests ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS}) set_target_properties(libgit2_tests PROPERTIES C_STANDARD 90) -set_target_properties(libgit2_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set_target_properties(libgit2_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) target_include_directories(libgit2_tests PRIVATE ${TEST_INCLUDES} ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES}) target_include_directories(libgit2_tests SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) @@ -62,9 +62,9 @@ endif() function(ADD_CLAR_TEST name) if(NOT USE_LEAK_CHECKER STREQUAL "OFF") - add_test(${name} "${CMAKE_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${CMAKE_BINARY_DIR}/libgit2_tests" ${ARGN}) + add_test(${name} "${PROJECT_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${PROJECT_BINARY_DIR}/libgit2_tests" ${ARGN}) else() - add_test(${name} "${CMAKE_BINARY_DIR}/libgit2_tests" ${ARGN}) + add_test(${name} "${PROJECT_BINARY_DIR}/libgit2_tests" ${ARGN}) endif() endfunction(ADD_CLAR_TEST) From ffead012283cec68cafb3441e4be55030c94de74 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Thu, 9 Sep 2021 18:02:22 +0200 Subject: [PATCH 0673/1616] Allow user checkout options on git_worktree_add Extend the `git_worktree_add_options` to include `git_checkout_options`. github issue #5949 --- include/git2/worktree.h | 7 ++++++- src/worktree.c | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/git2/worktree.h b/include/git2/worktree.h index 85cf1a6084a..ee6b04b0c2b 100644 --- a/include/git2/worktree.h +++ b/include/git2/worktree.h @@ -86,10 +86,15 @@ typedef struct git_worktree_add_options { int lock; /**< lock newly created worktree */ git_reference *ref; /**< reference to use for the new worktree HEAD */ + + /** + * Options for the checkout. + */ + git_checkout_options checkout_opts; } git_worktree_add_options; #define GIT_WORKTREE_ADD_OPTIONS_VERSION 1 -#define GIT_WORKTREE_ADD_OPTIONS_INIT {GIT_WORKTREE_ADD_OPTIONS_VERSION,0,NULL} +#define GIT_WORKTREE_ADD_OPTIONS_INIT {GIT_WORKTREE_ADD_OPTIONS_VERSION,0,NULL,GIT_CHECKOUT_OPTIONS_INIT} /** * Initialize git_worktree_add_options structure diff --git a/src/worktree.c b/src/worktree.c index e08d6d40162..caf4c58ed97 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -405,7 +405,10 @@ int git_worktree_add(git_worktree **out, git_repository *repo, goto out; /* Checkout worktree's HEAD */ - coopts.checkout_strategy = GIT_CHECKOUT_FORCE; + if (opts != NULL) + memcpy(&coopts, &wtopts.checkout_opts, sizeof(coopts)); + else + coopts.checkout_strategy = GIT_CHECKOUT_FORCE; if ((err = git_checkout_head(wt, &coopts)) < 0) goto out; From 58451759c2fd728149aad6dc91cb0c3e774f68c7 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Thu, 14 Oct 2021 09:55:00 +0200 Subject: [PATCH 0674/1616] Change default checkout strategy from FORCE to SAFE Since we are able to give our own git checkout options, the default git checkout strategy will be the same as initialized in a new git_checkout_options struct. --- src/worktree.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/worktree.c b/src/worktree.c index caf4c58ed97..6bf604227ce 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -407,8 +407,6 @@ int git_worktree_add(git_worktree **out, git_repository *repo, /* Checkout worktree's HEAD */ if (opts != NULL) memcpy(&coopts, &wtopts.checkout_opts, sizeof(coopts)); - else - coopts.checkout_strategy = GIT_CHECKOUT_FORCE; if ((err = git_checkout_head(wt, &coopts)) < 0) goto out; From 8b0ffdcb7b115e8f578303d6d5acbf923cd5c811 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Mon, 8 Nov 2021 17:23:27 +0100 Subject: [PATCH 0675/1616] Add test for `git_worktree_add` no checkout --- tests/worktree/worktree.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index 6f14b17f190..c575920790e 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -292,6 +292,27 @@ void test_worktree_worktree__add_with_explicit_branch(void) git_worktree_free(wt); } +void test_worktree_worktree__add_no_checkout(void) +{ + git_worktree *wt; + git_repository *wtrepo; + git_index *index; + git_buf path = GIT_BUF_INIT; + git_worktree_add_options opts = GIT_WORKTREE_ADD_OPTIONS_INIT; + + opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE; + + cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-no-checkout")); + cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-no-checkout", path.ptr, &opts)); + + cl_git_pass(git_repository_open(&wtrepo, path.ptr)); + cl_git_pass(git_repository_index(&index, wtrepo)); + cl_assert_equal_i(git_index_entrycount(index), 0); + + git_buf_dispose(&path); + git_worktree_free(wt); + git_repository_free(wtrepo); +} void test_worktree_worktree__init_existing_worktree(void) { From 1fa8014a97d34456a2750ddb75f1de7915cc0951 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Mon, 22 Nov 2021 12:07:59 +0100 Subject: [PATCH 0676/1616] Update test for `git_str` usage instead of `git_buf` See commit f0e693b18afbe1de37d7da5b5a8967b6c87d8e53 --- tests/worktree/worktree.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index c575920790e..d44e0a4b607 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -297,19 +297,19 @@ void test_worktree_worktree__add_no_checkout(void) git_worktree *wt; git_repository *wtrepo; git_index *index; - git_buf path = GIT_BUF_INIT; + git_str path = GIT_STR_INIT; git_worktree_add_options opts = GIT_WORKTREE_ADD_OPTIONS_INIT; opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE; - cl_git_pass(git_buf_joinpath(&path, fixture.repo->workdir, "../worktree-no-checkout")); + cl_git_pass(git_str_joinpath(&path, fixture.repo->workdir, "../worktree-no-checkout")); cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-no-checkout", path.ptr, &opts)); cl_git_pass(git_repository_open(&wtrepo, path.ptr)); cl_git_pass(git_repository_index(&index, wtrepo)); cl_assert_equal_i(git_index_entrycount(index), 0); - git_buf_dispose(&path); + git_str_dispose(&path); git_worktree_free(wt); git_repository_free(wtrepo); } From f9a98f9442c0b1c22f8212753fda85603fa948e8 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Mon, 22 Nov 2021 15:16:26 +0100 Subject: [PATCH 0677/1616] Fix test fail because of memory leak --- tests/worktree/worktree.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index d44e0a4b607..ccb6cde25f0 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -311,6 +311,7 @@ void test_worktree_worktree__add_no_checkout(void) git_str_dispose(&path); git_worktree_free(wt); + git_index_free(index); git_repository_free(wtrepo); } From 942cfac129b2cffc2668a7d1d7b7b613e4eef19f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 23 Dec 2021 14:21:23 -0600 Subject: [PATCH 0678/1616] worktree: checkout options suggestions from code review --- include/git2/worktree.h | 2 +- src/worktree.c | 12 ++++++------ tests/worktree/worktree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/git2/worktree.h b/include/git2/worktree.h index ee6b04b0c2b..8691f96db12 100644 --- a/include/git2/worktree.h +++ b/include/git2/worktree.h @@ -90,7 +90,7 @@ typedef struct git_worktree_add_options { /** * Options for the checkout. */ - git_checkout_options checkout_opts; + git_checkout_options checkout_options; } git_worktree_add_options; #define GIT_WORKTREE_ADD_OPTIONS_VERSION 1 diff --git a/src/worktree.c b/src/worktree.c index 6bf604227ce..2ac2274f183 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -304,16 +304,13 @@ int git_worktree_add(git_worktree **out, git_repository *repo, git_reference *ref = NULL, *head = NULL; git_commit *commit = NULL; git_repository *wt = NULL; - git_checkout_options coopts = GIT_CHECKOUT_OPTIONS_INIT; + git_checkout_options coopts; git_worktree_add_options wtopts = GIT_WORKTREE_ADD_OPTIONS_INIT; int err; GIT_ERROR_CHECK_VERSION( opts, GIT_WORKTREE_ADD_OPTIONS_VERSION, "git_worktree_add_options"); - if (opts) - memcpy(&wtopts, opts, sizeof(wtopts)); - GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(name); @@ -321,6 +318,11 @@ int git_worktree_add(git_worktree **out, git_repository *repo, *out = NULL; + if (opts) + memcpy(&wtopts, opts, sizeof(wtopts)); + + memcpy(&coopts, &wtopts.checkout_options, sizeof(coopts)); + if (wtopts.ref) { if (!git_reference_is_branch(wtopts.ref)) { git_error_set(GIT_ERROR_WORKTREE, "reference is not a branch"); @@ -405,8 +407,6 @@ int git_worktree_add(git_worktree **out, git_repository *repo, goto out; /* Checkout worktree's HEAD */ - if (opts != NULL) - memcpy(&coopts, &wtopts.checkout_opts, sizeof(coopts)); if ((err = git_checkout_head(wt, &coopts)) < 0) goto out; diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index ccb6cde25f0..66273d1cb24 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -300,7 +300,7 @@ void test_worktree_worktree__add_no_checkout(void) git_str path = GIT_STR_INIT; git_worktree_add_options opts = GIT_WORKTREE_ADD_OPTIONS_INIT; - opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE; + opts.checkout_options.checkout_strategy = GIT_CHECKOUT_NONE; cl_git_pass(git_str_joinpath(&path, fixture.repo->workdir, "../worktree-no-checkout")); cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-no-checkout", path.ptr, &opts)); From 33d0ad9c9c8655ed8a71591ef006101fd2c3c2cb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 23 Dec 2021 21:18:54 -0600 Subject: [PATCH 0679/1616] remote: refactor insteadof application Using the insteadof helper would leak memory when we didn't really want the pushInsteadOf configuration. Refactor the choice into the function that allocates memory (or now, not) and use a more idiomatic `int` return code. --- src/remote.c | 62 ++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/src/remote.c b/src/remote.c index fb9f6f8dac0..4bab9482d88 100644 --- a/src/remote.c +++ b/src/remote.c @@ -30,7 +30,7 @@ static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs); static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name); -char *apply_insteadof(bool *matched, git_config *config, const char *url, int direction); +static int apply_insteadof(char **out, git_config *config, const char *url, int direction, bool use_default_if_empty); static int add_refspec_to(git_vector *vector, const char *string, bool is_fetch) { @@ -210,9 +210,7 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem git_str var = GIT_STR_INIT; git_str specbuf = GIT_STR_INIT; const git_remote_create_options dummy_opts = GIT_REMOTE_CREATE_OPTIONS_INIT; - char *tmp; int error = -1; - bool matched; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(url); @@ -247,16 +245,13 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem goto on_error; if (opts->repository && !(opts->flags & GIT_REMOTE_CREATE_SKIP_INSTEADOF)) { - remote->url = apply_insteadof(&matched, config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH); - tmp = apply_insteadof(&matched, config_ro, canonical_url.ptr, GIT_DIRECTION_PUSH); - if (matched) { - remote->pushurl = tmp; - GIT_ERROR_CHECK_ALLOC(remote->pushurl); - } + if ((error = apply_insteadof(&remote->url, config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH, true)) < 0 || + (error = apply_insteadof(&remote->pushurl, config_ro, canonical_url.ptr, GIT_DIRECTION_PUSH, false)) < 0) + goto on_error; } else { remote->url = git__strdup(canonical_url.ptr); + GIT_ERROR_CHECK_ALLOC(remote->url); } - GIT_ERROR_CHECK_ALLOC(remote->url); if (opts->name != NULL) { remote->name = git__strdup(opts->name); @@ -464,9 +459,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) git_remote *remote = NULL; git_str buf = GIT_STR_INIT; const char *val; - char *tmp; int error = 0; - bool matched; git_config *config; struct refspec_cb_data data = { NULL }; bool optional_setting_found = false, found; @@ -507,13 +500,9 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO; if (found && strlen(val) > 0) { - remote->url = apply_insteadof(&matched, config, val, GIT_DIRECTION_FETCH); - GIT_ERROR_CHECK_ALLOC(remote->url); - tmp = apply_insteadof(&matched, config, val, GIT_DIRECTION_PUSH); - if (matched) { - remote->pushurl = tmp; - GIT_ERROR_CHECK_ALLOC(remote->pushurl); - } + if ((error = apply_insteadof(&remote->url, config, val, GIT_DIRECTION_FETCH, true)) < 0 || + (error = apply_insteadof(&remote->pushurl, config, val, GIT_DIRECTION_PUSH, false)) < 0) + goto cleanup; } val = NULL; @@ -532,11 +521,11 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) } if (found && strlen(val) > 0) { - if (remote->pushurl) { + if (remote->pushurl) git__free(remote->pushurl); - } - remote->pushurl = apply_insteadof(&matched, config, val, GIT_DIRECTION_FETCH); - GIT_ERROR_CHECK_ALLOC(remote->pushurl); + + if ((error = apply_insteadof(&remote->pushurl, config, val, GIT_DIRECTION_FETCH, true)) < 0) + goto cleanup; } data.remote = remote; @@ -2736,7 +2725,7 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_ #define SUFFIX_FETCH "insteadof" #define SUFFIX_PUSH "pushinsteadof" -char *apply_insteadof(bool *matched, git_config *config, const char *url, int direction) +static int apply_insteadof(char **out, git_config *config, const char *url, int direction, bool use_default_if_empty) { size_t match_length, prefix_length, suffix_length; char *replacement = NULL; @@ -2746,11 +2735,10 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di git_config_entry *entry; git_config_iterator *iter; - GIT_ASSERT_ARG_WITH_RETVAL(config, NULL); - GIT_ASSERT_ARG_WITH_RETVAL(url, NULL); - GIT_ASSERT_ARG_WITH_RETVAL(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH, NULL); - GIT_ASSERT_ARG_WITH_RETVAL(matched, NULL); - *matched = 0; + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(config); + GIT_ASSERT_ARG(url); + GIT_ASSERT_ARG(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH); /* Add 1 to prefix/suffix length due to the additional escaped dot */ prefix_length = strlen(PREFIX) + 1; @@ -2763,7 +2751,7 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di } if (git_config_iterator_glob_new(&iter, config, regexp) < 0) - return NULL; + return -1; match_length = 0; while (git_config_next(&entry, iter) == 0) { @@ -2772,6 +2760,7 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di /* Check if entry value is a prefix of URL */ if (git__prefixcmp(url, entry->value)) continue; + /* Check if entry value is longer than previous * prefixes */ if ((n = strlen(entry->value)) <= match_length) @@ -2789,15 +2778,20 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di git_config_iterator_free(iter); - if (match_length == 0) - return git__strdup(url); + if (match_length == 0 && use_default_if_empty) { + *out = git__strdup(url); + return *out ? 0 : -1; + } else if (match_length == 0) { + *out = NULL; + return 0; + } git_str_printf(&result, "%s%s", replacement, url + match_length); git__free(replacement); - *matched = 1; - return result.ptr; + *out = git_str_detach(&result); + return 0; } /* Deprecated functions */ From c940b6954a61b86c4279fe81b70f680cd59c522a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 23 Dec 2021 22:33:32 -0600 Subject: [PATCH 0680/1616] ci: build with ssh on nightly --- .github/workflows/nightly.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 789f268f8de..9cb5525eb92 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -73,11 +73,12 @@ jobs: env: CC: clang-10 CFLAGS: -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-blacklist=/home/libgit2/source/script/sanitizers.supp -fno-optimize-sibling-calls -fno-omit-frame-pointer - CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local/msan -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON + CMAKE_OPTIONS: -DCMAKE_PREFIX_PATH=/usr/local/msan -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 + UBSAN_OPTIONS: print_stacktrace=1 os: ubuntu-latest - # Focal, Clang 10, OpenSSL, UndefinedBehaviorSanitizer container: From 854429503014e5cff1f4f098c702427a15ce0537 Mon Sep 17 00:00:00 2001 From: Marcin Kolenda Date: Fri, 24 Dec 2021 14:24:07 +0100 Subject: [PATCH 0681/1616] Remove PSGit from Language Bindings section of README PSGit is not using libgit2 library. It is stub of a library and is not developed further. --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 7ed5f6c8097..66f98e2eedc 100644 --- a/README.md +++ b/README.md @@ -392,8 +392,6 @@ Here are the bindings to libgit2 that are currently available: * Git-Raw * PHP * php-git -* PowerShell - * PSGit * Python * pygit2 * R From 3f52f7b9fb6628d8a7068098a596151c812e00c8 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Fri, 24 Dec 2021 10:47:22 -0600 Subject: [PATCH 0682/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 2b9d05fa5b4..8bb6cee29d4 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -556,7 +556,7 @@ static int packed_map_check(refdb_fs_backend *backend) static const char *start_of_record(const char *buf, const char *p) { const char *nl = p; - while (1) { + while (true) { nl = git__memrchr(buf, '\n', nl - buf); if (!nl) return buf; From 0df53fd6367d3ffb0f6a15bde0ab46655048ecd3 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Fri, 24 Dec 2021 10:47:32 -0600 Subject: [PATCH 0683/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 8bb6cee29d4..65bbf66efba 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -579,9 +579,8 @@ static const char *end_of_record(const char *p, const char *end) while (1) { size_t sz = end - p; p = memchr(p, '\n', sz); - if (!p) { + if (!p) return end; - } ++p; if (p < end && p[0] == '^') ++p; From 2b722da41f438553af3a13a6a58b5e9e2392ebc0 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Fri, 24 Dec 2021 10:47:43 -0600 Subject: [PATCH 0684/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 65bbf66efba..adedc8d7a04 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -605,9 +605,8 @@ cmp_record_to_refname(const char *rec, size_t data_end, const char *ref_name) data_end -= GIT_OID_HEXSZ + 1; end = memchr(rec, '\n', data_end); - if (end) { + if (end) data_end = end - rec; - } cmp_val = memcmp(rec, ref_name, min(ref_len, data_end)); From 2ec7b2914ae81ff4eb8037f6dd4e641552f9e001 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Fri, 24 Dec 2021 10:47:53 -0600 Subject: [PATCH 0685/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index adedc8d7a04..a470ef95ab2 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -610,9 +610,8 @@ cmp_record_to_refname(const char *rec, size_t data_end, const char *ref_name) cmp_val = memcmp(rec, ref_name, min(ref_len, data_end)); - if (cmp_val == 0 && data_end != ref_len) { + if (cmp_val == 0 && data_end != ref_len) return (data_end > ref_len) ? 1 : -1; - } return cmp_val; } From 207840d83257a42c5ba39a4490ab04c060142cfe Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Fri, 24 Dec 2021 10:48:02 -0600 Subject: [PATCH 0686/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index a470ef95ab2..4d5ed7c619b 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -654,9 +654,8 @@ static int packed_lookup( if ((error = packed_map_check(backend)) < 0) return error; - if (!backend->sorted) { + if (!backend->sorted) return packed_unsorted_lookup(out, backend, ref_name); - } left = backend->packed_refs_map.data; right = data_end = ((const char *)backend->packed_refs_map.data) + From 3eb3981978e118dce49e40f273f37e3b2dbbbba4 Mon Sep 17 00:00:00 2001 From: Miguel Arroz <750683+arroz@users.noreply.github.com> Date: Wed, 29 Dec 2021 15:26:33 -0800 Subject: [PATCH 0687/1616] Disabling setting `CMAKE_FIND_LIBRARY_SUFFIXES` on Apple platforms. On macOS, since Big Sur, the libraries were moved to a cache. The SDK comes with stubs in the SDK (`/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk/usr/lib/` or whatever SDK version one has installed) where most have the `.tbd` suffix (although some still are `.a`). Forcing `CMAKE_FIND_LIBRARY_SUFFIXES` on Apple platforms broke building, unless one has copies of the libraries installed elsewhere (like Brew), as many libraries (like `iconv` or `pcre`) are not found. This fix disables setting the `CMAKE_FIND_LIBRARY_SUFFIXES` to `.a` if the platform is `APPLE` when building static libs. --- cmake/DefaultCFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/DefaultCFlags.cmake b/cmake/DefaultCFlags.cmake index fa59e1d97e5..ad3db0980af 100644 --- a/cmake/DefaultCFlags.cmake +++ b/cmake/DefaultCFlags.cmake @@ -92,7 +92,7 @@ else() set(CMAKE_C_ARCHIVE_FINISH " -D ") endif() - if(NOT BUILD_SHARED_LIBS) + if(NOT APPLE AND NOT BUILD_SHARED_LIBS) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") endif() From 6aa3603ae44b077c8dc0a506e3cdf989cd3a473e Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Fri, 31 Dec 2021 01:50:45 +0100 Subject: [PATCH 0688/1616] ntmlclient: don't declare dummy HMAC_CTX_cleanup when building with libressl --- deps/ntlmclient/crypt_openssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/ntlmclient/crypt_openssl.c b/deps/ntlmclient/crypt_openssl.c index 463eae4f8fe..bab8276ac92 100644 --- a/deps/ntlmclient/crypt_openssl.c +++ b/deps/ntlmclient/crypt_openssl.c @@ -44,7 +44,7 @@ static inline void HMAC_CTX_free(HMAC_CTX *ctx) #endif -#if OPENSSL_VERSION_NUMBER >= 0x10100000L || defined(CRYPT_OPENSSL_DYNAMIC) +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !LIBRESSL_VERSION_NUMBER) || defined(CRYPT_OPENSSL_DYNAMIC) static inline void HMAC_CTX_cleanup(HMAC_CTX *ctx) { From ef84889189c65b4e977ec199925b1b0ea44ed1cc Mon Sep 17 00:00:00 2001 From: Miguel Arroz <750683+arroz@users.noreply.github.com> Date: Fri, 31 Dec 2021 16:40:58 -0800 Subject: [PATCH 0689/1616] Add `rename_threshold` to `git_status_options`. --- include/git2/status.h | 6 ++++ src/status.c | 3 ++ tests/status/renames.c | 63 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/include/git2/status.h b/include/git2/status.h index 526df639905..d8f9663b42a 100644 --- a/include/git2/status.h +++ b/include/git2/status.h @@ -250,6 +250,12 @@ typedef struct { * working directory and index; defaults to HEAD. */ git_tree *baseline; + + /** + * Threshold above which similar files will be considered renames. + * This is equivalent to the -M option. Defaults to 50. + */ + uint16_t rename_threshold; } git_status_options; #define GIT_STATUS_OPTIONS_VERSION 1 diff --git a/src/status.c b/src/status.c index c98564643fc..b321e0efb7e 100644 --- a/src/status.c +++ b/src/status.c @@ -336,6 +336,9 @@ int git_status_list_new( GIT_DIFF_FIND_RENAMES_FROM_REWRITES | GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY; + if (opts != NULL && opts->rename_threshold != 0) + findopt.rename_threshold = opts->rename_threshold; + if (show != GIT_STATUS_SHOW_WORKDIR_ONLY) { if ((error = git_diff_tree_to_index( &status->head2idx, repo, head, index, &diffopt)) < 0) diff --git a/tests/status/renames.c b/tests/status/renames.c index e69dbcce009..d17a94ca76f 100644 --- a/tests/status/renames.c +++ b/tests/status/renames.c @@ -718,3 +718,66 @@ void test_status_renames__precomposed_unicode_toggle_is_rename(void) #endif } +void test_status_renames__rename_threshold(void) +{ + git_index *index; + git_status_list *statuslist; + git_status_options opts = GIT_STATUS_OPTIONS_INIT; + + _rename_helper(g_repo, "ikeepsix.txt", "newname.txt", + "Line 1\n" \ + "Line 2\n" \ + "Line 3\n" \ + "Line 4\n" \ + "Line 5\n" \ + "Line 6\n" \ + "Line 7\n" \ + "Line 8\n" \ + "Line 9\n" + ); + + opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR; + opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED; + + cl_git_pass(git_repository_index(&index, g_repo)); + + // Default threshold + { + struct status_entry expected[] = { + { GIT_STATUS_WT_RENAMED | GIT_STATUS_WT_MODIFIED, "ikeepsix.txt", "newname.txt" }, + }; + + cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts)); + check_status(statuslist, expected, 1); + git_status_list_free(statuslist); + } + + // Threshold set to 90 + { + struct status_entry expected[] = { + { GIT_STATUS_WT_DELETED, "ikeepsix.txt", NULL }, + { GIT_STATUS_WT_NEW, "newname.txt", NULL } + }; + + opts.rename_threshold = 90; + + cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts)); + check_status(statuslist, expected, 2); + git_status_list_free(statuslist); + } + + // Threshold set to 25 + { + struct status_entry expected[] = { + { GIT_STATUS_WT_RENAMED | GIT_STATUS_WT_MODIFIED, "ikeepsix.txt", "newname.txt" }, + }; + + opts.rename_threshold = 25; + + cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts)); + check_status(statuslist, expected, 1); + git_status_list_free(statuslist); + } + + git_index_free(index); +} From a3436cde9fbdb0ce9eb3c3e0727e3093560e10e9 Mon Sep 17 00:00:00 2001 From: Miguel Arroz <750683+arroz@users.noreply.github.com> Date: Sat, 1 Jan 2022 15:17:08 -0800 Subject: [PATCH 0690/1616] #6154 git_status_list_new case insensitive fix --- src/diff_tform.c | 2 +- .../41/a766bb079e18ff6a24571831bd751168799a02 | 1 + .../ba/8b004914491b129b4feff51b5fd8553b8e8156 | Bin 0 -> 191 bytes .../e5/6d39ca6d946331aa79c9c443d46c8a6ed4f550 | Bin 0 -> 36 bytes .../refs/heads/case-insensitive-status | 1 + tests/status/renames.c | 61 ++++++++++++++++++ 6 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 tests/resources/renames/.gitted/objects/41/a766bb079e18ff6a24571831bd751168799a02 create mode 100644 tests/resources/renames/.gitted/objects/ba/8b004914491b129b4feff51b5fd8553b8e8156 create mode 100644 tests/resources/renames/.gitted/objects/e5/6d39ca6d946331aa79c9c443d46c8a6ed4f550 create mode 100644 tests/resources/renames/.gitted/refs/heads/case-insensitive-status diff --git a/src/diff_tform.c b/src/diff_tform.c index d14134071bc..f9836d24529 100644 --- a/src/diff_tform.c +++ b/src/diff_tform.c @@ -375,7 +375,7 @@ static int apply_splits_and_deletes( size_t i; git_diff_delta *delta; - if (git_vector_init(&onto, expected_size, git_diff_delta__cmp) < 0) + if (git_vector_init(&onto, expected_size, diff->deltas._cmp) < 0) return -1; /* build new delta list without TO_DELETE and splitting TO_SPLIT */ diff --git a/tests/resources/renames/.gitted/objects/41/a766bb079e18ff6a24571831bd751168799a02 b/tests/resources/renames/.gitted/objects/41/a766bb079e18ff6a24571831bd751168799a02 new file mode 100644 index 00000000000..4bd7592d550 --- /dev/null +++ b/tests/resources/renames/.gitted/objects/41/a766bb079e18ff6a24571831bd751168799a02 @@ -0,0 +1 @@ +x­ŽKNÄ0DYû½GDþ#!Ä€C¸ÓÝK‰=ò8pz‚¸‹ZÔ[Ô«¥í{`g÷4:3`N¨µŸ?ƒÆÎè…E‚Á ”Bp˜8™Õ=w®ÌLä, š`uŽžbΜháÈâ­#ÉVŒSù·Öᣬopí½}Ãë%è˜Üsþmïǃûcª­ó}ûšÖ2nNKÛßÀDoô%xáE'­ÕIÏ׃ÿkO]‰J]AÊÆ0 ñƃ Z…ÊŸþ”êƆ_[ \ No newline at end of file diff --git a/tests/resources/renames/.gitted/objects/ba/8b004914491b129b4feff51b5fd8553b8e8156 b/tests/resources/renames/.gitted/objects/ba/8b004914491b129b4feff51b5fd8553b8e8156 new file mode 100644 index 0000000000000000000000000000000000000000..c61d650cecb718ea9a779e631961dfa6da2f49cb GIT binary patch literal 191 zcmV;w06_nE0V^p=O;s>5Fk&z?FfcPQQ3%g3*DI+gVR)Krc`A2Gvf--AlSiDdFT2P!>0ao|w%i_oTpS8BW%55gF5c5 teEU=gs<n literal 0 HcmV?d00001 diff --git a/tests/resources/renames/.gitted/objects/e5/6d39ca6d946331aa79c9c443d46c8a6ed4f550 b/tests/resources/renames/.gitted/objects/e5/6d39ca6d946331aa79c9c443d46c8a6ed4f550 new file mode 100644 index 0000000000000000000000000000000000000000..d6deb188d582582b5d73aed64a0772e19e78fa20 GIT binary patch literal 36 scmb Date: Wed, 5 Jan 2022 09:18:59 -0500 Subject: [PATCH 0691/1616] config: handle empty conditional in includeIf When a config file contains `[includeIf]` (with no condition), we should treat that as a falsey value. This means that we should properly parse a config value of `includeIf.path`. --- src/config_file.c | 15 ++++++++++++--- tests/config/conditionals.c | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/config_file.c b/src/config_file.c index 11b444094cf..91446df0925 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -724,14 +724,23 @@ static const struct { static int parse_conditional_include(config_file_parse_data *parse_data, const char *section, const char *file) { char *condition; - size_t i; + size_t section_len, i; int error = 0, matches; if (!parse_data->repo || !file) return 0; - condition = git__substrdup(section + strlen("includeIf."), - strlen(section) - strlen("includeIf.") - strlen(".path")); + section_len = strlen(section); + + /* + * We checked that the string starts with `includeIf.` and ends + * in `.path` to get here. Make sure it consists of more. + */ + if (section_len < CONST_STRLEN("includeIf.") + CONST_STRLEN(".path")) + return 0; + + condition = git__substrdup(section + CONST_STRLEN("includeIf."), + section_len - CONST_STRLEN("includeIf.") - CONST_STRLEN(".path")); for (i = 0; i < ARRAY_SIZE(conditions); i++) { if (git__prefixcmp(condition, conditions[i].prefix)) diff --git a/tests/config/conditionals.c b/tests/config/conditionals.c index 6249dbd794e..564719dcbcf 100644 --- a/tests/config/conditionals.c +++ b/tests/config/conditionals.c @@ -148,3 +148,28 @@ void test_config_conditionals__onbranch(void) assert_condition_includes("onbranch", "dir*", false); assert_condition_includes("onbranch", "dir/*", false); } + +void test_config_conditionals__empty(void) +{ + git_buf value = GIT_BUF_INIT; + git_str buf = GIT_STR_INIT; + git_config *cfg; + + cl_git_pass(git_str_puts(&buf, "[includeIf]\n")); + cl_git_pass(git_str_puts(&buf, "path = other\n")); + + cl_git_mkfile("empty_standard_repo/.git/config", buf.ptr); + cl_git_mkfile("empty_standard_repo/.git/other", "[foo]\nbar=baz\n"); + _repo = cl_git_sandbox_reopen(); + + git_str_dispose(&buf); + + cl_git_pass(git_repository_config(&cfg, _repo)); + + cl_git_fail_with(GIT_ENOTFOUND, + git_config_get_string_buf(&value, cfg, "foo.bar")); + + git_str_dispose(&buf); + git_buf_dispose(&value); + git_config_free(cfg); +} From 715bfe1048d740b8fa01a9f8534d81a8f65a228d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 5 Jan 2022 09:22:38 -0500 Subject: [PATCH 0692/1616] config: test allocation in config conditionals --- src/config_file.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/config_file.c b/src/config_file.c index 91446df0925..43a6ba440f2 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -740,7 +740,9 @@ static int parse_conditional_include(config_file_parse_data *parse_data, const c return 0; condition = git__substrdup(section + CONST_STRLEN("includeIf."), - section_len - CONST_STRLEN("includeIf.") - CONST_STRLEN(".path")); + section_len - CONST_STRLEN("includeIf.") - CONST_STRLEN(".path")); + + GIT_ERROR_CHECK_ALLOC(condition); for (i = 0; i < ARRAY_SIZE(conditions); i++) { if (git__prefixcmp(condition, conditions[i].prefix)) From 90df43022a011f23f13b7a77a956e3f64e4134a5 Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Wed, 5 Jan 2022 12:18:05 +0200 Subject: [PATCH 0693/1616] Fix typos --- cmake/FindGSSAPI.cmake | 2 +- docs/release.md | 2 +- examples/blame.c | 4 ++-- include/git2/attr.h | 2 +- include/git2/clone.h | 4 ++-- include/git2/describe.h | 2 +- include/git2/diff.h | 4 ++-- include/git2/odb.h | 2 +- include/git2/reflog.h | 2 +- include/git2/refs.h | 2 +- include/git2/remote.h | 2 +- include/git2/repository.h | 10 +++++----- include/git2/reset.h | 2 +- include/git2/submodule.h | 2 +- include/git2/tree.h | 2 +- include/git2/types.h | 2 +- src/attr.c | 2 +- src/branch.c | 2 +- src/cc-compat.h | 2 +- src/checkout.c | 2 +- src/config.h | 2 +- src/fs_path.c | 2 +- src/futils.h | 4 ++-- src/hash/sha1/sha1dc/sha1.c | 2 +- src/index.c | 2 +- src/indexer.c | 2 +- src/khash.h | 2 +- src/merge.c | 4 ++-- src/mwindow.c | 2 +- src/odb_pack.c | 2 +- src/patch_parse.c | 2 +- src/regexp.c | 2 +- src/repository.c | 10 +++++----- src/revwalk.c | 2 +- src/status.c | 2 +- src/streams/openssl_dynamic.h | 6 +++--- src/transports/smart_protocol.c | 2 +- src/transports/ssh.c | 2 +- src/tree.c | 2 +- src/win32/path_w32.c | 2 +- src/win32/posix_w32.c | 2 +- src/win32/w32_leakcheck.c | 2 +- tests/CMakeLists.txt | 2 +- tests/checkout/tree.c | 6 +++--- tests/clar_libgit2_timer.h | 4 ++-- tests/commit/write.c | 2 +- tests/config/multivar.c | 2 +- tests/core/rmdir.c | 4 ++-- tests/core/structinit.c | 2 +- tests/diff/rename.c | 2 +- tests/index/tests.c | 12 ++++++------ tests/network/url/parse.c | 2 +- tests/object/raw/convert.c | 2 +- tests/object/tree/read.c | 2 +- tests/path/core.c | 2 +- tests/path/win32.c | 2 +- tests/refs/branches/delete.c | 2 +- tests/submodule/update.c | 4 ++-- 58 files changed, 83 insertions(+), 83 deletions(-) diff --git a/cmake/FindGSSAPI.cmake b/cmake/FindGSSAPI.cmake index 0f5932a2202..a11d72a67d5 100644 --- a/cmake/FindGSSAPI.cmake +++ b/cmake/FindGSSAPI.cmake @@ -5,7 +5,7 @@ # GSSAPI_ROOT_DIR - Set this variable to the root installation of GSSAPI # # Read-Only variables: -# GSSAPI_FLAVOR_MIT - set to TURE if MIT Kerberos has been found +# GSSAPI_FLAVOR_MIT - set to TRUE if MIT Kerberos has been found # GSSAPI_FLAVOR_HEIMDAL - set to TRUE if Heimdal Kerberos has been found # GSSAPI_FOUND - system has GSSAPI # GSSAPI_INCLUDE_DIR - the GSSAPI include directory diff --git a/docs/release.md b/docs/release.md index 3200c4449e4..87fccaabe63 100644 --- a/docs/release.md +++ b/docs/release.md @@ -80,4 +80,4 @@ and run it against our description file with the tip of `main` checked out. cm doc api.docurium -It will start up a few proceses and write out the results as a new commit onto the `gh-pages` branch. That can be pushed to GitHub to update what will show up on our documentation reference site. +It will start up a few processes and write out the results as a new commit onto the `gh-pages` branch. That can be pushed to GitHub to update what will show up on our documentation reference site. diff --git a/examples/blame.c b/examples/blame.c index 954c97b17d1..77087a5771a 100644 --- a/examples/blame.c +++ b/examples/blame.c @@ -49,7 +49,7 @@ int lg2_blame(git_repository *repo, int argc, char *argv[]) if (o.F) blameopts.flags |= GIT_BLAME_FIRST_PARENT; /** - * The commit range comes in "commitish" form. Use the rev-parse API to + * The commit range comes in "committish" form. Use the rev-parse API to * nail down the end points. */ if (o.commitspec) { @@ -70,7 +70,7 @@ int lg2_blame(git_repository *repo, int argc, char *argv[]) /** * Get the raw data inside the blob for output. We use the - * `commitish:path/to/file.txt` format to find it. + * `committish:path/to/file.txt` format to find it. */ if (git_oid_is_zero(&blameopts.newest_commit)) strcpy(spec, "HEAD"); diff --git a/include/git2/attr.h b/include/git2/attr.h index 157192c9d7b..04f3c7c29bc 100644 --- a/include/git2/attr.h +++ b/include/git2/attr.h @@ -344,7 +344,7 @@ GIT_EXTERN(int) git_attr_cache_flush( * Add a macro definition. * * Macros will automatically be loaded from the top level `.gitattributes` - * file of the repository (plus the build-in "binary" macro). This + * file of the repository (plus the built-in "binary" macro). This * function allows you to add others. For example, to add the default * macro, you would call: * diff --git a/include/git2/clone.h b/include/git2/clone.h index c517ec3d61e..3481f254c9d 100644 --- a/include/git2/clone.h +++ b/include/git2/clone.h @@ -74,8 +74,8 @@ typedef int GIT_CALLBACK(git_remote_create_cb)( void *payload); /** - * The signature of a function matchin git_repository_init, with an - * aditional void * as callback payload. + * The signature of a function matching git_repository_init, with an + * additional void * as callback payload. * * Callers of git_clone my provide a function matching this signature * to override the repository creation and customization process diff --git a/include/git2/describe.h b/include/git2/describe.h index e8afd687972..aaccbcd6f74 100644 --- a/include/git2/describe.h +++ b/include/git2/describe.h @@ -152,7 +152,7 @@ GIT_EXTERN(int) git_describe_commit( * Describe a commit * * Perform the describe operation on the current commit and the - * worktree. After peforming describe on HEAD, a status is run and the + * worktree. After performing describe on HEAD, a status is run and the * description is considered to be dirty if there are. * * @param out pointer to store the result. You must free this once diff --git a/include/git2/diff.h b/include/git2/diff.h index c040cd19053..a820a57c551 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -758,7 +758,7 @@ typedef struct { uint16_t copy_threshold; /** - * Treshold below which similar files will be split into a delete/add pair. + * Threshold below which similar files will be split into a delete/add pair. * This is equivalent to the last part of the -B option. Defaults to 60. */ uint16_t break_rewrite_threshold; @@ -1317,7 +1317,7 @@ typedef enum { /** * Accumulate diff statistics for all patches. * - * @param out Structure containg the diff statistics. + * @param out Structure containing the diff statistics. * @param diff A git_diff generated by one of the above functions. * @return 0 on success; non-zero on error */ diff --git a/include/git2/odb.h b/include/git2/odb.h index 0691aa4d075..9eaf897f8ce 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -578,7 +578,7 @@ GIT_EXTERN(int) git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t /** * Set the git commit-graph for the ODB. * - * After a successfull call, the ownership of the cgraph parameter will be + * After a successful call, the ownership of the cgraph parameter will be * transferred to libgit2, and the caller should not free it. * * The commit-graph can also be unset by explicitly passing NULL as the cgraph diff --git a/include/git2/reflog.h b/include/git2/reflog.h index c949a28f02c..ec365c1fab2 100644 --- a/include/git2/reflog.h +++ b/include/git2/reflog.h @@ -31,7 +31,7 @@ GIT_BEGIN_DECL * git_reflog_free(). * * @param out pointer to reflog - * @param repo the repostiory + * @param repo the repository * @param name reference to look up * @return 0 or an error code */ diff --git a/include/git2/refs.h b/include/git2/refs.h index 3a0095bb62b..06f8bb97c48 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -57,7 +57,7 @@ GIT_EXTERN(int) git_reference_name_to_id( /** * Lookup a reference by DWIMing its short name * - * Apply the git precendence rules to the given shorthand to determine + * Apply the git precedence rules to the given shorthand to determine * which reference the user is referring to. * * @param out pointer in which to store the reference diff --git a/include/git2/remote.h b/include/git2/remote.h index 088f528a6c6..351850db07f 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -893,7 +893,7 @@ GIT_EXTERN(int) git_remote_prune(git_remote *remote, const git_remote_callbacks /** * Perform a push * - * Peform all the steps from a push. + * Perform all the steps from a push. * * @param remote the remote to push to * @param refspecs the refspecs to use for pushing. If NULL or an empty diff --git a/include/git2/repository.h b/include/git2/repository.h index 8bd877be42f..fa37d0fb881 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -808,19 +808,19 @@ GIT_EXTERN(int) git_repository_set_head( * If the provided committish cannot be found in the repository, the HEAD * is unaltered and GIT_ENOTFOUND is returned. * - * If the provided commitish cannot be peeled into a commit, the HEAD + * If the provided committish cannot be peeled into a commit, the HEAD * is unaltered and -1 is returned. * * Otherwise, the HEAD will eventually be detached and will directly point to * the peeled Commit. * * @param repo Repository pointer - * @param commitish Object id of the Commit the HEAD should point to + * @param committish Object id of the Commit the HEAD should point to * @return 0 on success, or an error code */ GIT_EXTERN(int) git_repository_set_head_detached( git_repository *repo, - const git_oid *commitish); + const git_oid *committish); /** * Make the repository HEAD directly point to the Commit. @@ -836,7 +836,7 @@ GIT_EXTERN(int) git_repository_set_head_detached( */ GIT_EXTERN(int) git_repository_set_head_detached_from_annotated( git_repository *repo, - const git_annotated_commit *commitish); + const git_annotated_commit *committish); /** * Detach the HEAD. @@ -846,7 +846,7 @@ GIT_EXTERN(int) git_repository_set_head_detached_from_annotated( * If the HEAD is already detached and points to a Tag, the HEAD is * updated into making it point to the peeled Commit, and 0 is returned. * - * If the HEAD is already detached and points to a non commitish, the HEAD is + * If the HEAD is already detached and points to a non committish, the HEAD is * unaltered, and -1 is returned. * * Otherwise, the HEAD will be detached and point to the peeled Commit. diff --git a/include/git2/reset.h b/include/git2/reset.h index 7a471bdd0cb..b2ee2ba7bfb 100644 --- a/include/git2/reset.h +++ b/include/git2/reset.h @@ -48,7 +48,7 @@ typedef enum { * * @param target Committish to which the Head should be moved to. This object * must belong to the given `repo` and can either be a git_commit or a - * git_tag. When a git_tag is being passed, it should be dereferencable + * git_tag. When a git_tag is being passed, it should be dereferenceable * to a git_commit which oid will be used as the target of the branch. * * @param reset_type Kind of reset operation to perform. diff --git a/include/git2/submodule.h b/include/git2/submodule.h index c6eeb96dc45..319a6056e78 100644 --- a/include/git2/submodule.h +++ b/include/git2/submodule.h @@ -181,7 +181,7 @@ GIT_EXTERN(int) git_submodule_update_options_init( * @param submodule Submodule object * @param init If the submodule is not initialized, setting this flag to true * will initialize the submodule before updating. Otherwise, this will - * return an error if attempting to update an uninitialzed repository. + * return an error if attempting to update an uninitialized repository. * but setting this to true forces them to be updated. * @param options configuration options for the update. If NULL, the * function works as though GIT_SUBMODULE_UPDATE_OPTIONS_INIT was passed. diff --git a/include/git2/tree.h b/include/git2/tree.h index db24bf6ed55..0a33f0b4a84 100644 --- a/include/git2/tree.h +++ b/include/git2/tree.h @@ -255,7 +255,7 @@ GIT_EXTERN(int) git_treebuilder_new( git_treebuilder **out, git_repository *repo, const git_tree *source); /** - * Clear all the entires in the builder + * Clear all the entries in the builder * * @param bld Builder to clear * @return 0 on success; error code otherwise diff --git a/include/git2/types.h b/include/git2/types.h index 34d8c99ef7c..d4b033dc770 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -236,7 +236,7 @@ typedef struct git_refspec git_refspec; /** * Git's idea of a remote repository. A remote can be anonymous (in - * which case it does not have backing configuration entires). + * which case it does not have backing configuration entries). */ typedef struct git_remote git_remote; diff --git a/src/attr.c b/src/attr.c index 409c30b01ea..1623b1d4570 100644 --- a/src/attr.c +++ b/src/attr.c @@ -646,7 +646,7 @@ static int collect_attr_files( if (error < 0) goto cleanup; - /* in precendence order highest to lowest: + /* in precedence order highest to lowest: * - $GIT_DIR/info/attributes * - path components with .gitattributes * - config core.attributesfile diff --git a/src/branch.c b/src/branch.c index cf985f15364..03892a4b0e5 100644 --- a/src/branch.c +++ b/src/branch.c @@ -707,7 +707,7 @@ int git_branch_set_upstream(git_reference *branch, const char *branch_name) if (error < 0) goto on_error; - /* Update the upsteam branch config with the new name */ + /* Update the upstream branch config with the new name */ if (git_str_printf(&key, "branch.%s.remote", shortname) < 0) goto on_error; diff --git a/src/cc-compat.h b/src/cc-compat.h index f701b2d9351..a0971e86c98 100644 --- a/src/cc-compat.h +++ b/src/cc-compat.h @@ -75,7 +75,7 @@ # define PRIdZ "zd" #endif -/* Micosoft Visual C/C++ */ +/* Microsoft Visual C/C++ */ #if defined(_MSC_VER) /* disable "deprecated function" warnings */ # pragma warning ( disable : 4996 ) diff --git a/src/checkout.c b/src/checkout.c index 11be2e84fa3..341ed0879c3 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -963,7 +963,7 @@ static int checkout_conflicts_load(checkout_data *data, git_iterator *workdir, g { git_index *index; - /* Only write conficts from sources that have them: indexes. */ + /* Only write conflicts from sources that have them: indexes. */ if ((index = git_iterator_index(data->target)) == NULL) return 0; diff --git a/src/config.h b/src/config.h index 5dfc9da7165..01b84b157f7 100644 --- a/src/config.h +++ b/src/config.h @@ -96,7 +96,7 @@ int git_config_lookup_map_enum(git_configmap_t *type_out, /** * Unlock the backend with the highest priority * - * Unlocking will allow other writers to updat the configuration + * Unlocking will allow other writers to update the configuration * file. Optionally, any changes performed since the lock will be * applied to the configuration. * diff --git a/src/fs_path.c b/src/fs_path.c index 957f389ccc6..c9f03a7c34b 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -136,7 +136,7 @@ int git_fs_path_basename_r(git_str *buffer, const char *path) /* * Determine if the path is a Windows prefix and, if so, returns - * its actual lentgh. If it is not a prefix, returns -1. + * its actual length. If it is not a prefix, returns -1. */ static int win32_prefix_length(const char *path, int len) { diff --git a/src/futils.h b/src/futils.h index 1386dc482b5..f0d7ec3b03b 100644 --- a/src/futils.h +++ b/src/futils.h @@ -231,10 +231,10 @@ typedef enum { * Copy a directory tree. * * This copies directories and files from one root to another. You can - * pass a combinationof GIT_CPDIR flags as defined above. + * pass a combination of GIT_CPDIR flags as defined above. * * If you pass the CHMOD flag, then the dirmode will be applied to all - * directories that are created during the copy, overiding the natural + * directories that are created during the copy, overriding the natural * permissions. If you do not pass the CHMOD flag, then the dirmode * will actually be copied from the source files and the `dirmode` arg * will be ignored. diff --git a/src/hash/sha1/sha1dc/sha1.c b/src/hash/sha1/sha1dc/sha1.c index 4d03c75d8c2..929822728a3 100644 --- a/src/hash/sha1/sha1dc/sha1.c +++ b/src/hash/sha1/sha1dc/sha1.c @@ -70,7 +70,7 @@ /* Not under GCC-alike or glibc */ #elif defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN) /* - * *BSD and newlib (embeded linux, cygwin, etc). + * *BSD and newlib (embedded linux, cygwin, etc). * the defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN) part prevents * this condition from matching with Solaris/sparc. * (Solaris defines only one endian macro) diff --git a/src/index.c b/src/index.c index a2d80bc6e3a..367fd9c3895 100644 --- a/src/index.c +++ b/src/index.c @@ -3499,7 +3499,7 @@ static int index_apply_to_wd_diff(git_index *index, int action, const git_strarr } /* - * We do the matching ourselves intead of passing the list to + * We do the matching ourselves instead of passing the list to * diff because we want to tell the callback which one * matched, which we do not know if we ask diff to filter for us. */ diff --git a/src/indexer.c b/src/indexer.c index ff60b400500..16db9ca8d72 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -1123,7 +1123,7 @@ static int update_header_and_rehash(git_indexer *idx, git_indexer_progress *stat git_hash_init(&idx->trailer); - /* Update the header to include the numer of local objects we injected */ + /* Update the header to include the number of local objects we injected */ idx->hdr.hdr_entries = htonl(stats->total_objects + stats->local_objects); if (write_at(idx, &idx->hdr, 0, sizeof(struct git_pack_header)) < 0) return -1; diff --git a/src/khash.h b/src/khash.h index 7adccdb0065..c9b7f131f0a 100644 --- a/src/khash.h +++ b/src/khash.h @@ -564,7 +564,7 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key) code; \ } } -/* More conenient interfaces */ +/* More convenient interfaces */ /*! @function @abstract Instantiate a hash set containing integer keys diff --git a/src/merge.c b/src/merge.c index ec7e5bfd106..c871630c6e5 100644 --- a/src/merge.c +++ b/src/merge.c @@ -3019,10 +3019,10 @@ static int merge_check_workdir(size_t *conflicts, git_repository *repo, git_inde *conflicts = 0; /* We need to have merged at least 1 file for the possibility to exist to - * have conflicts with the workdir. Passing 0 as the pathspec count paramter + * have conflicts with the workdir. Passing 0 as the pathspec count parameter * will consider all files in the working directory, that is, we may detect * a conflict if there were untracked files in the workdir prior to starting - * the merge. This typically happens when cherry-picking a commmit whose + * the merge. This typically happens when cherry-picking a commit whose * changes have already been applied. */ if (merged_paths->length == 0) diff --git a/src/mwindow.c b/src/mwindow.c index da2dae2b9d6..d06b7a80e28 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -473,7 +473,7 @@ int git_mwindow_file_register(git_mwindow_file *mwf) git_mwindow_find_lru_file_locked(&lru_file) == 0) { if ((error = git_vector_insert(&closed_files, lru_file)) < 0) { /* - * Exceeding the file limit seems preferrable to being open to + * Exceeding the file limit seems preferable to being open to * data races that can end up corrupting the heap. */ break; diff --git a/src/odb_pack.c b/src/odb_pack.c index 5b752102947..818cc6125d5 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -115,7 +115,7 @@ struct pack_writepack { * | OID can be found. If we can find the offset to that SHA1 inside of the * | index, that means the object is contained inside of the packfile and * | we can stop searching. Before returning, we verify that the - * | packfile behing the index we are searching still exists on disk. + * | packfile behind the index we are searching still exists on disk. * | * |-# pack_entry_find_offset * | Mmap the actual index file to disk if it hasn't been opened diff --git a/src/patch_parse.c b/src/patch_parse.c index 37822fcccaa..78cd96252f8 100644 --- a/src/patch_parse.c +++ b/src/patch_parse.c @@ -353,7 +353,7 @@ static int parse_header_start(git_patch_parsed *patch, git_patch_parse_ctx *ctx) * We cannot expect to be able to always parse paths correctly at this * point. Due to the possibility of unquoted names, whitespaces in * filenames and custom prefixes we have to allow that, though, and just - * proceeed here. We then hope for the "---" and "+++" lines to fix that + * proceed here. We then hope for the "---" and "+++" lines to fix that * for us. */ if (!git_parse_ctx_contains(&ctx->parse_ctx, "\n", 1) && diff --git a/src/regexp.c b/src/regexp.c index c1b9ef4cdb6..2569dea0a9d 100644 --- a/src/regexp.c +++ b/src/regexp.c @@ -45,7 +45,7 @@ int git_regexp_search(const git_regexp *r, const char *string, size_t nmatches, int error; size_t i; - /* The ovec array always needs to be a mutiple of three */ + /* The ovec array always needs to be a multiple of three */ if (nmatches <= ARRAY_SIZE(static_ovec) / 3) ovec = static_ovec; else diff --git a/src/repository.c b/src/repository.c index 8059f108151..80b4a98eb70 100644 --- a/src/repository.c +++ b/src/repository.c @@ -3027,19 +3027,19 @@ int git_repository_set_head( int git_repository_set_head_detached( git_repository *repo, - const git_oid *commitish) + const git_oid *committish) { - return detach(repo, commitish, NULL); + return detach(repo, committish, NULL); } int git_repository_set_head_detached_from_annotated( git_repository *repo, - const git_annotated_commit *commitish) + const git_annotated_commit *committish) { GIT_ASSERT_ARG(repo); - GIT_ASSERT_ARG(commitish); + GIT_ASSERT_ARG(committish); - return detach(repo, git_annotated_commit_id(commitish), commitish->description); + return detach(repo, git_annotated_commit_id(committish), committish->description); } int git_repository_detach_head(git_repository *repo) diff --git a/src/revwalk.c b/src/revwalk.c index e29e9c9b90e..553e0497a14 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -427,7 +427,7 @@ static int add_parents_to_list(git_revwalk *walk, git_commit_list_node *commit, return 0; } -/* How many unintersting commits we want to look at after we run out of interesting ones */ +/* How many uninteresting commits we want to look at after we run out of interesting ones */ #define SLOP 5 static int still_interesting(git_commit_list *list, int64_t time, int slop) diff --git a/src/status.c b/src/status.c index c98564643fc..c653122a221 100644 --- a/src/status.c +++ b/src/status.c @@ -84,7 +84,7 @@ static unsigned int workdir_delta2status( if (!git_oid_equal(&idx2wd->old_file.id, &idx2wd->new_file.id)) { /* if OIDs don't match, we might need to calculate them now to - * discern between RENAMED vs RENAMED+MODIFED + * discern between RENAMED vs RENAMED+MODIFIED */ if (git_oid_is_zero(&idx2wd->old_file.id) && diff->old_src == GIT_ITERATOR_WORKDIR && diff --git a/src/streams/openssl_dynamic.h b/src/streams/openssl_dynamic.h index 12d927a617f..a9969191003 100644 --- a/src/streams/openssl_dynamic.h +++ b/src/streams/openssl_dynamic.h @@ -13,7 +13,7 @@ * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions + * the following conditions are adhered to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms @@ -38,7 +38,7 @@ * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library + * The word 'cryptographic' can be left out if the routines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: @@ -56,7 +56,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * The licence and distribution terms for any publically available version or + * The licence and distribution terms for any publicly available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index a9a623cc7df..e135f45967e 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -137,7 +137,7 @@ int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vec { const char *ptr; - /* No refs or capabilites, odd but not a problem */ + /* No refs or capabilities, odd but not a problem */ if (pkt == NULL || pkt->capabilities == NULL) return GIT_ENOTFOUND; diff --git a/src/transports/ssh.c b/src/transports/ssh.c index e3bb5eef625..711f44af9cf 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -868,7 +868,7 @@ static int list_auth_methods(int *out, LIBSSH2_SESSION *session, const char *use continue; } - /* Skipt it if we don't know it */ + /* Skip it if we don't know it */ ptr = strchr(ptr, ','); } diff --git a/src/tree.c b/src/tree.c index 7290e154d8d..a1545dc2dec 100644 --- a/src/tree.c +++ b/src/tree.c @@ -605,7 +605,7 @@ static int write_tree( /* * This loop is unfortunate, but necessary. The index doesn't have - * any directores, so we need to handle that manually, and we + * any directories, so we need to handle that manually, and we * need to keep track of the current position. */ for (i = start; i < entries; ++i) { diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c index 5d7ad11f646..0e6aff748f4 100644 --- a/src/win32/path_w32.c +++ b/src/win32/path_w32.c @@ -41,7 +41,7 @@ GIT_INLINE(int) path__cwd(wchar_t *path, int size) } /* The Win32 APIs may return "\\?\" once you've used it first. - * But it may not. What a gloriously predictible API! + * But it may not. What a gloriously predictable API! */ if (wcsncmp(path, PATH__NT_NAMESPACE, PATH__NT_NAMESPACE_LEN)) return len; diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index ba46b5ea97a..b6072411d03 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -441,7 +441,7 @@ int p_symlink(const char *target, const char *path) * not want to use `git_win32_path_from_utf8` for converting the target, * as that function will automatically pre-pend the current working * directory in case the path is not absolute. As Git will instead use - * relative symlinks, this is not someting we want. + * relative symlinks, this is not something we want. */ if (git_win32_path_from_utf8(path_w, path) < 0 || git_win32_path_relative_from_utf8(target_w, target) < 0) diff --git a/src/win32/w32_leakcheck.c b/src/win32/w32_leakcheck.c index 5c8425be3ac..0f095de12d2 100644 --- a/src/win32/w32_leakcheck.c +++ b/src/win32/w32_leakcheck.c @@ -199,7 +199,7 @@ int git_win32_leakcheck_stack( return 0; } -/* Strack tracing */ +/* Stack tracing */ #define STACKTRACE_UID_LEN (15) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fdf194d0e9d..f293c158da1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,7 +2,7 @@ set(Python_ADDITIONAL_VERSIONS 3 2.7) find_package(PythonInterp) if(NOT PYTHONINTERP_FOUND) - message(FATAL_ERROR "Could not find a python interpeter, which is needed to build the tests. " + message(FATAL_ERROR "Could not find a python interpreter, which is needed to build the tests. " "Make sure python is available, or pass -DBUILD_TESTS=OFF to skip building the tests") ENDIF() diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c index de7dd7d9a74..d4b57f5d14f 100644 --- a/tests/checkout/tree.c +++ b/tests/checkout/tree.c @@ -66,7 +66,7 @@ void test_checkout_tree__can_checkout_and_remove_directory(void) { cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/")); - /* Checkout brach "subtrees" and update HEAD, so that HEAD matches the + /* Checkout branch "subtrees" and update HEAD, so that HEAD matches the * current working tree */ cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees")); @@ -81,7 +81,7 @@ void test_checkout_tree__can_checkout_and_remove_directory(void) git_object_free(g_object); g_object = NULL; - /* Checkout brach "master" and update HEAD, so that HEAD matches the + /* Checkout branch "master" and update HEAD, so that HEAD matches the * current working tree */ cl_git_pass(git_revparse_single(&g_object, g_repo, "master")); @@ -537,7 +537,7 @@ static void assert_conflict( g_opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - /* Hack-ishy workaound to ensure *all* the index entries + /* Hack-ishy workaround to ensure *all* the index entries * match the content of the tree */ cl_git_pass(git_object_peel(&hack_tree, g_object, GIT_OBJECT_TREE)); diff --git a/tests/clar_libgit2_timer.h b/tests/clar_libgit2_timer.h index 0d150e0189f..7571a52e997 100644 --- a/tests/clar_libgit2_timer.h +++ b/tests/clar_libgit2_timer.h @@ -3,7 +3,7 @@ struct cl_perf_timer { - /* cummulative running time across all start..stop intervals */ + /* cumulative running time across all start..stop intervals */ double sum; /* value of last start..stop interval */ @@ -27,7 +27,7 @@ void cl_perf_timer__stop(cl_perf_timer *t); double cl_perf_timer__last(const cl_perf_timer *t); /** - * return cummulative running time across all start..stop + * return cumulative running time across all start..stop * intervals in seconds. */ double cl_perf_timer__sum(const cl_perf_timer *t); diff --git a/tests/commit/write.c b/tests/commit/write.c index 2c227854616..5a9c9d5a5eb 100644 --- a/tests/commit/write.c +++ b/tests/commit/write.c @@ -155,7 +155,7 @@ void test_commit_write__root(void) cl_git_pass(git_signature_new(&committer, committer_name, committer_email, 123456789, 60)); cl_git_pass(git_signature_new(&author, committer_name, committer_email, 987654321, 90)); - /* First we need to update HEAD so it points to our non-existant branch */ + /* First we need to update HEAD so it points to our non-existent branch */ cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_assert(git_reference_type(head) == GIT_REFERENCE_SYMBOLIC); head_old = git__strdup(git_reference_symbolic_target(head)); diff --git a/tests/config/multivar.c b/tests/config/multivar.c index 4f08a48172f..244e3755965 100644 --- a/tests/config/multivar.c +++ b/tests/config/multivar.c @@ -128,7 +128,7 @@ void test_config_multivar__add(void) int n; cl_git_pass(git_config_open_ondisk(&cfg, "config/config11")); - cl_git_pass(git_config_set_multivar(cfg, _name, "nonexistant", "git://git.otherplace.org/libgit2")); + cl_git_pass(git_config_set_multivar(cfg, _name, "non-existent", "git://git.otherplace.org/libgit2")); n = 0; cl_git_pass(git_config_get_multivar_foreach(cfg, _name, NULL, cb, &n)); diff --git a/tests/core/rmdir.c b/tests/core/rmdir.c index 8e5bd5878f2..f6c66b3a44a 100644 --- a/tests/core/rmdir.c +++ b/tests/core/rmdir.c @@ -33,7 +33,7 @@ void test_core_rmdir__cleanup(void) cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_REMOVE_FILES)); } -/* make sure empty dir can be deleted recusively */ +/* make sure empty dir can be deleted recursively */ void test_core_rmdir__delete_recursive(void) { git_str path = GIT_STR_INIT; @@ -47,7 +47,7 @@ void test_core_rmdir__delete_recursive(void) git_str_dispose(&path); } -/* make sure non-empty dir cannot be deleted recusively */ +/* make sure non-empty dir cannot be deleted recursively */ void test_core_rmdir__fail_to_delete_non_empty_dir(void) { git_str file = GIT_STR_INIT; diff --git a/tests/core/structinit.c b/tests/core/structinit.c index d24da874da5..160e2f61218 100644 --- a/tests/core/structinit.c +++ b/tests/core/structinit.c @@ -67,7 +67,7 @@ void test_core_structinit__compare(void) * which is not guaranteed to be initialized to anything sane at all. * * Assume most compilers, in a debug build, will clear that memory for - * us or set it to sentinal markers. Etc. + * us or set it to sentinel markers. Etc. */ #if !defined(DEBUG) && !defined(_DEBUG) clar__skip(); diff --git a/tests/diff/rename.c b/tests/diff/rename.c index 41dc95eb4ec..30e9ea43201 100644 --- a/tests/diff/rename.c +++ b/tests/diff/rename.c @@ -375,7 +375,7 @@ void test_diff_rename__not_exact_match(void) /* git diff -M -C --find-copies-harder --break-rewrites \ * 1c068dee5790ef1580cfc4cd670915b48d790084 \ * 19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 - * with ignore_space whitespace comparision + * with ignore_space whitespace comparison */ cl_git_pass(git_diff_tree_to_tree( &diff, g_repo, old_tree, new_tree, &diffopts)); diff --git a/tests/index/tests.c b/tests/index/tests.c index b6715574edf..205d12e5b14 100644 --- a/tests/index/tests.c +++ b/tests/index/tests.c @@ -200,14 +200,14 @@ void test_index_tests__write(void) void test_index_tests__sort0(void) { - /* sort the entires in an index */ + /* sort the entries in an index */ /* * TODO: This no longer applies: * index sorting in Git uses some specific changes to the way * directories are sorted. * - * We need to specificially check for this by creating a new + * We need to specifically check for this by creating a new * index, adding entries in random order and then * checking for consistency */ @@ -215,7 +215,7 @@ void test_index_tests__sort0(void) void test_index_tests__sort1(void) { - /* sort the entires in an empty index */ + /* sort the entries in an empty index */ git_index *index; cl_git_pass(git_index_open(&index, "fake-index")); @@ -242,7 +242,7 @@ void test_index_tests__add(void) cl_set_cleanup(&cleanup_myrepo, NULL); - /* Intialize a new repository */ + /* Initialize a new repository */ cl_git_pass(git_repository_init(&repo, "./myrepo", 0)); /* Ensure we're the only guy in the room */ @@ -293,7 +293,7 @@ void test_index_tests__add_frombuffer(void) cl_set_cleanup(&cleanup_myrepo, NULL); - /* Intialize a new repository */ + /* Initialize a new repository */ cl_git_pass(git_repository_init(&repo, "./myrepo", 0)); /* Ensure we're the only guy in the room */ @@ -435,7 +435,7 @@ void test_index_tests__add_frombuffer_reset_entry(void) cl_set_cleanup(&cleanup_myrepo, NULL); - /* Intialize a new repository */ + /* Initialize a new repository */ cl_git_pass(git_repository_init(&repo, "./myrepo", 0)); cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_futils_mkpath2file("myrepo/test.txt", 0777)); diff --git a/tests/network/url/parse.c b/tests/network/url/parse.c index edfd6abecaa..8149ba52c22 100644 --- a/tests/network/url/parse.c +++ b/tests/network/url/parse.c @@ -552,6 +552,6 @@ void test_network_url_parse__ipv6_invalid_addresses(void) cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, "https://user:pass@fe80::dcad:beff:fe00:0001:9191/resource")); - /* Invalid chracter inside address */ + /* Invalid character inside address */ cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, "http://[fe8o::dcad:beff:fe00:0001]/resource")); } diff --git a/tests/object/raw/convert.c b/tests/object/raw/convert.c index 88b1380a481..40a01ae09e5 100644 --- a/tests/object/raw/convert.c +++ b/tests/object/raw/convert.c @@ -38,7 +38,7 @@ void test_object_raw_convert__succeed_on_oid_to_string_conversion(void) cl_assert(*(str+i) == '\0'); /* must not touch bytes past end of string */ cl_assert(*(str+(i+1)) == 'Z'); - /* i == n-1 charaters of string */ + /* i == n-1 characters of string */ cl_git_pass(strncmp(exp, out, i)); } diff --git a/tests/object/tree/read.c b/tests/object/tree/read.c index de2e64c68f5..95a2e70fb9d 100644 --- a/tests/object/tree/read.c +++ b/tests/object/tree/read.c @@ -21,7 +21,7 @@ void test_object_tree_read__cleanup(void) void test_object_tree_read__loaded(void) { - /* acces randomly the entries on a loaded tree */ + /* access randomly the entries on a loaded tree */ git_oid id; git_tree *tree; diff --git a/tests/path/core.c b/tests/path/core.c index 9421941c03f..db5359af8b5 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -290,7 +290,7 @@ void test_path_core__validate_workdir(void) #ifdef GIT_WIN32 /* - * In the absense of a repo configuration, 259 character paths + * In the absence of a repo configuration, 259 character paths * succeed. >= 260 character paths fail. */ cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); diff --git a/tests/path/win32.c b/tests/path/win32.c index 64d8d8e08f8..1aaf6867a26 100644 --- a/tests/path/win32.c +++ b/tests/path/win32.c @@ -269,7 +269,7 @@ void test_path_win32__8dot3_name(void) cl_assert_equal_s("WINDOWS", (shortname = git_win32_path_8dot3_name("C:\\WINDOWS"))); git__free(shortname); - /* Create some predictible short names */ + /* Create some predictable short names */ cl_must_pass(p_mkdir(".foo", 0777)); cl_assert_equal_s("FOO~1", (shortname = git_win32_path_8dot3_name(".foo"))); git__free(shortname); diff --git a/tests/refs/branches/delete.c b/tests/refs/branches/delete.c index 077882b22e1..27995f9e2c8 100644 --- a/tests/refs/branches/delete.c +++ b/tests/refs/branches/delete.c @@ -136,7 +136,7 @@ void test_refs_branches_delete__removes_reflog(void) cl_assert_equal_i(false, git_reference_has_log(repo, "refs/heads/track-local")); - /* Reading a nonexistant reflog creates it, but it should be empty */ + /* Reading a non-existent reflog creates it, but it should be empty */ cl_git_pass(git_reflog_read(&log, repo, "refs/heads/track-local")); cl_assert_equal_i(0, git_reflog_entrycount(log)); git_reflog_free(log); diff --git a/tests/submodule/update.c b/tests/submodule/update.c index 79353e5751c..4aa95985227 100644 --- a/tests/submodule/update.c +++ b/tests/submodule/update.c @@ -11,7 +11,7 @@ void test_submodule_update__cleanup(void) cl_git_sandbox_cleanup(); } -void test_submodule_update__unitialized_submodule_no_init(void) +void test_submodule_update__uninitialized_submodule_no_init(void) { git_submodule *sm; git_submodule_update_options update_options = GIT_SUBMODULE_UPDATE_OPTIONS_INIT; @@ -21,7 +21,7 @@ void test_submodule_update__unitialized_submodule_no_init(void) /* get the submodule */ cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo")); - /* updating an unitialized repository throws */ + /* updating an uninitialized repository throws */ cl_git_fail_with( GIT_ERROR, git_submodule_update(sm, 0, &update_options)); From da5385c6cfea1b43ddbd24f414745cfc44dbcb98 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 6 Jan 2022 07:39:21 -0500 Subject: [PATCH 0694/1616] status: don't use `// ...` in tests, use `/* ... */` --- tests/status/renames.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/status/renames.c b/tests/status/renames.c index d17a94ca76f..d6bb697072c 100644 --- a/tests/status/renames.c +++ b/tests/status/renames.c @@ -723,7 +723,7 @@ void test_status_renames__rename_threshold(void) git_index *index; git_status_list *statuslist; git_status_options opts = GIT_STATUS_OPTIONS_INIT; - + _rename_helper(g_repo, "ikeepsix.txt", "newname.txt", "Line 1\n" \ "Line 2\n" \ @@ -735,49 +735,49 @@ void test_status_renames__rename_threshold(void) "Line 8\n" \ "Line 9\n" ); - + opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR; opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED; - + cl_git_pass(git_repository_index(&index, g_repo)); - - // Default threshold + + /* Default threshold */ { struct status_entry expected[] = { { GIT_STATUS_WT_RENAMED | GIT_STATUS_WT_MODIFIED, "ikeepsix.txt", "newname.txt" }, }; - + cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts)); check_status(statuslist, expected, 1); git_status_list_free(statuslist); } - - // Threshold set to 90 + + /* Threshold set to 90 */ { struct status_entry expected[] = { { GIT_STATUS_WT_DELETED, "ikeepsix.txt", NULL }, { GIT_STATUS_WT_NEW, "newname.txt", NULL } }; - + opts.rename_threshold = 90; - + cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts)); check_status(statuslist, expected, 2); git_status_list_free(statuslist); } - - // Threshold set to 25 + + /* Threshold set to 25 */ { struct status_entry expected[] = { { GIT_STATUS_WT_RENAMED | GIT_STATUS_WT_MODIFIED, "ikeepsix.txt", "newname.txt" }, }; - + opts.rename_threshold = 25; - + cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts)); check_status(statuslist, expected, 1); git_status_list_free(statuslist); } - + git_index_free(index); } From 9faa9199026258b084ecd292d9b93ac56b81ee94 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 6 Jan 2022 07:42:01 -0500 Subject: [PATCH 0695/1616] status: don't use `// ...` in tests, use `/* ... */` --- tests/status/renames.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/status/renames.c b/tests/status/renames.c index 2e61c38656d..d5cf87d07e9 100644 --- a/tests/status/renames.c +++ b/tests/status/renames.c @@ -799,7 +799,7 @@ void test_status_renames__case_insensitive_h2i_and_i2wc(void) }; - // Checkout the correct branch + /* Checkout the correct branch */ checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_git_pass(git_reference_symbolic_set_target( @@ -809,7 +809,7 @@ void test_status_renames__case_insensitive_h2i_and_i2wc(void) cl_git_pass(git_repository_index(&index, g_repo)); - // Rename sixserving.txt, delete Wow.txt, and stage those changes + /* Rename sixserving.txt, delete Wow.txt, and stage those changes */ rename_file(g_repo, "sixserving.txt", "sixserving-renamed.txt"); cl_git_pass(git_str_joinpath( &path_to_delete, git_repository_workdir(g_repo), "Wow.txt")); @@ -819,13 +819,12 @@ void test_status_renames__case_insensitive_h2i_and_i2wc(void) cl_git_pass(git_index_write(index)); - // Change content of sixserving-renamed.txt + /* Change content of sixserving-renamed.txt */ cl_git_pass(git_str_joinpath( &path_to_edit, git_repository_workdir(g_repo), "sixserving-renamed.txt")); cl_git_append2file(path_to_edit.ptr, "New content\n"); - - // Run status + /* Run status */ opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED; opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR; opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX; From 240c195fe5f49133ee48acd8cd12766d9d25e782 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 2 Jan 2022 08:19:45 -0500 Subject: [PATCH 0696/1616] docs: document our API/ABI stability stance --- docs/api-stability.md | 63 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 docs/api-stability.md diff --git a/docs/api-stability.md b/docs/api-stability.md new file mode 100644 index 00000000000..a02e864d1ad --- /dev/null +++ b/docs/api-stability.md @@ -0,0 +1,63 @@ +The maintainers of the libgit2 project believe that having a stable API +to program against is important for our users and the ecosystem - whether +you're building against the libgit2 C APIs directly, creating a wrapper to +a managed language, or programming against one of those managed wrappers +like LibGit2Sharp or Rugged. + +Our API stability considerations are: + +* Our standard API is considered stable through a major release. + + * We define our "standard API" to be anything included in the "git2.h" + header - in other words, anything defined in a header in the `git2` + directory. + + * APIs will maintain their signature and will not be removed within a + major release, but new APIs may be added. + + * Any APIs may be marked as deprecated within a major release, but will + not be removed until the next major release (at the earliest). You + may define `GIT_DEPRECATE_HARD` to produce compiler warnings if you + target these deprecated APIs. + + * We consider API compatibility to be against the C APIs. That means + that we may use macros to keep API compatibility - for example, if we + rename a structure from `git_widget_options` to `git_foobar_options` + then we would `#define git_widget_options git_foobar_options` to retain + API compatibility. Note that this does _not_ provide ABI compatibility. + +* Our systems API is only considered stable through a _minor_ release. + + * We define our "systems API" to be anything included in the `git2/sys` + directory. These are not "standard" APIs but are mechanisms to extend + libgit2 by adding new extensions - for example, a custom HTTPS transport, + TLS engine, or merge strategy. + + * Additionally, the cmake options and the resulting constants that it + produces to be "systems API". + + * Generally these mechanism are well defined and will not need significant + changes, but are considered a part of the library itself and may need + + * Systems API changes will be noted specially within a release's changelog. + +* Our ABI is only considered stable through a _minor_ release. + + * Our ABI consists of actual symbol names in the library, the function + signatures, and the actual layout of structures. These are only + stable within minor releases, they are not stable within major releases + (yet). + + * Since many FFIs use ABIs directly (for example, .NET P/Invoke or Rust), + this instability is unfortunate. + + * In a future major release, we will begin providing ABI stability + throughout the major release cycle. + + * ABI changes will be noted specially within a release's changelog. + +* Point releases are _generally_ only for bugfixes, and generally do _not_ + include new features. This means that point releases generally do _not_ + include new APIs. Point releases will never break API, systems API or + ABI compatibility. + From f5373123d2c20d2986fdee20d821816ce07819aa Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 24 Dec 2021 15:17:52 -0600 Subject: [PATCH 0697/1616] push: don't try to connect in `finish` Push starts by connecting, don't try to connect again, just rely on the existing connection existing. --- src/push.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/push.c b/src/push.c index 3bf7ba5d920..a281dc979fc 100644 --- a/src/push.c +++ b/src/push.c @@ -476,9 +476,10 @@ int git_push_finish(git_push *push, const git_remote_callbacks *callbacks) { int error; - if (!git_remote_connected(push->remote) && - (error = git_remote__connect(push->remote, GIT_DIRECTION_PUSH, callbacks, &push->connection)) < 0) - return error; + if (!git_remote_connected(push->remote)) { + git_error_set(GIT_ERROR_NET, "remote is disconnected"); + return -1; + } if ((error = filter_refs(push->remote)) < 0 || (error = do_push(push, callbacks)) < 0) From f99a0d695c0a1a8e44fc1e5216d481ff016ec65d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 4 Jan 2022 15:17:01 -0500 Subject: [PATCH 0698/1616] remote: improved error reporting Several places in the remote code identify an error and then swallow it; return the error. --- src/fetch.c | 4 ++-- src/push.c | 10 +++++----- src/remote.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/fetch.c b/src/fetch.c index dedbb54fa54..bc5961db4f1 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -87,10 +87,10 @@ static int filter_wants(git_remote *remote, const git_fetch_options *opts) goto cleanup; } - if (git_repository_odb__weakptr(&odb, remote->repo) < 0) + if ((error = git_repository_odb__weakptr(&odb, remote->repo)) < 0) goto cleanup; - if (git_remote_ls((const git_remote_head ***)&heads, &heads_len, remote) < 0) + if ((error = git_remote_ls((const git_remote_head ***)&heads, &heads_len, remote)) < 0) goto cleanup; for (i = 0; i < heads_len; i++) { diff --git a/src/push.c b/src/push.c index a281dc979fc..9733eecf992 100644 --- a/src/push.c +++ b/src/push.c @@ -291,7 +291,7 @@ static int queue_objects(git_push *push) if (git_oid_equal(&spec->loid, &spec->roid)) continue; /* up-to-date */ - if (git_odb_read_header(&size, &type, push->repo->_odb, &spec->loid) < 0) + if ((error = git_odb_read_header(&size, &type, push->repo->_odb, &spec->loid)) < 0) goto on_error; if (type == GIT_OBJECT_TAG) { @@ -301,19 +301,19 @@ static int queue_objects(git_push *push) goto on_error; if (git_object_type(target) == GIT_OBJECT_COMMIT) { - if (git_revwalk_push(rw, git_object_id(target)) < 0) { + if ((error = git_revwalk_push(rw, git_object_id(target))) < 0) { git_object_free(target); goto on_error; } } else { - if (git_packbuilder_insert( - push->pb, git_object_id(target), NULL) < 0) { + if ((error = git_packbuilder_insert( + push->pb, git_object_id(target), NULL)) < 0) { git_object_free(target); goto on_error; } } git_object_free(target); - } else if (git_revwalk_push(rw, &spec->loid) < 0) + } else if ((error = git_revwalk_push(rw, &spec->loid)) < 0) goto on_error; if (!spec->refspec.force) { diff --git a/src/remote.c b/src/remote.c index 4bab9482d88..f697e0fb89e 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1088,7 +1088,7 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const if (ls_to_vector(&refs, remote) < 0) return -1; - if ((git_vector_init(&specs, 0, NULL)) < 0) + if ((error = git_vector_init(&specs, 0, NULL)) < 0) goto on_error; remote->passed_refspecs = 0; From 6fc6eeb66c40310086c8f059cae41de69ad4c6da Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 24 Dec 2021 15:14:38 -0600 Subject: [PATCH 0699/1616] remote: introduce `git_remote_connect_options` The existing mechanism for providing options to remote fetch/push calls, and subsequently to transports, is unsatisfactory. It requires an options structure to avoid breaking the API and callback signatures. 1. Introduce `git_remote_connect_options` to satisfy those needs. 2. Add a new remote connection API, `git_remote_connect_ext` that will take this new options structure. Existing `git_remote_connect` calls will proxy to that. `git_remote_fetch` and `git_remote_push` will proxy their fetch/push options to that as well. 3. Define the interaction between `git_remote_connect` and fetch/push. Connect _may_ be called before fetch/push, but _need not_ be. The semantics of which options would be used for these operations was not specified if you specify options for both connect _and_ fetch. Now these are defined that the fetch or push options will be used _if_ they were specified. Otherwise, the connect options will be used if they were specified. Otherwise, the library's defaults will be used. 4. Update the transports to understand `git_remote_connect_options`. This is a breaking change to the systems API. --- include/git2/remote.h | 165 +++++++++++--- include/git2/sys/transport.h | 47 ++-- src/fetch.c | 11 +- src/fetch.h | 2 +- src/proxy.c | 5 +- src/proxy.h | 2 +- src/push.c | 34 ++- src/push.h | 20 +- src/remote.c | 379 ++++++++++++++++++++++---------- src/remote.h | 17 +- src/transports/http.c | 28 ++- src/transports/local.c | 160 +++++++------- src/transports/smart.c | 163 +++----------- src/transports/smart.h | 20 +- src/transports/smart_protocol.c | 19 +- src/transports/ssh.c | 18 +- src/transports/winhttp.c | 32 +-- 17 files changed, 609 insertions(+), 513 deletions(-) diff --git a/include/git2/remote.h b/include/git2/remote.h index 088f528a6c6..f1aa35f47e0 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -344,23 +344,6 @@ GIT_EXTERN(size_t) git_remote_refspec_count(const git_remote *remote); */ GIT_EXTERN(const git_refspec *)git_remote_get_refspec(const git_remote *remote, size_t n); -/** - * Open a connection to a remote - * - * The transport is selected based on the URL. The direction argument - * is due to a limitation of the git protocol (over TCP or SSH) which - * starts up a specific binary which can only do the one or the other. - * - * @param remote the remote to connect to - * @param direction GIT_DIRECTION_FETCH if you want to fetch or - * GIT_DIRECTION_PUSH if you want to push - * @param callbacks the callbacks to use for this connection - * @param proxy_opts proxy settings - * @param custom_headers extra HTTP headers to use in this connection - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_proxy_options *proxy_opts, const git_strarray *custom_headers); - /** * Get the remote repository's reference advertisement list * @@ -809,7 +792,93 @@ GIT_EXTERN(int) git_push_options_init( unsigned int version); /** - * Download and index the packfile + * Remote creation options structure + * + * Initialize with `GIT_REMOTE_CREATE_OPTIONS_INIT`. Alternatively, you can + * use `git_remote_create_options_init`. + * + */ +typedef struct { + unsigned int version; + + /** Callbacks to use for this connection */ + git_remote_callbacks callbacks; + + /** HTTP Proxy settings */ + git_proxy_options proxy_opts; + + /** Extra HTTP headers to use in this connection */ + git_strarray custom_headers; +} git_remote_connect_options; + +#define GIT_REMOTE_CONNECT_OPTIONS_VERSION 1 +#define GIT_REMOTE_CONNECT_OPTIONS_INIT { \ + GIT_REMOTE_CONNECT_OPTIONS_VERSION, \ + GIT_REMOTE_CALLBACKS_INIT, \ + GIT_PROXY_OPTIONS_INIT } + +/** + * Initialize git_remote_connect_options structure. + * + * Initializes a `git_remote_connect_options` with default values. + * Equivalent to creating an instance with + * `GIT_REMOTE_CONNECT_OPTIONS_INIT`. + * + * @param opts The `git_remote_connect_options` struct to initialize. + * @param version The struct version; pass `GIT_REMOTE_CONNECT_OPTIONS_VERSION`. + * @return Zero on success; -1 on failure. + */ +GIT_EXTERN(int) git_remote_connect_options_init( + git_remote_connect_options *opts, + unsigned int version); + +/** + * Open a connection to a remote. + * + * The transport is selected based on the URL; the direction argument + * is due to a limitation of the git protocol which starts up a + * specific binary which can only do the one or the other. + * + * @param remote the remote to connect to + * @param direction GIT_DIRECTION_FETCH if you want to fetch or + * GIT_DIRECTION_PUSH if you want to push + * @param callbacks the callbacks to use for this connection + * @param proxy_opts proxy settings + * @param custom_headers extra HTTP headers to use in this connection + * @return 0 or an error code + */ +GIT_EXTERN(int) git_remote_connect( + git_remote *remote, + git_direction direction, + const git_remote_callbacks *callbacks, + const git_proxy_options *proxy_opts, + const git_strarray *custom_headers); + +/** + * Open a connection to a remote with extended options. + * + * The transport is selected based on the URL; the direction argument + * is due to a limitation of the git protocol which starts up a + * specific binary which can only do the one or the other. + * + * The given options structure will form the defaults for connection + * options and callback setup. Callers may override these defaults + * by specifying `git_fetch_options` or `git_push_options` in + * subsequent calls. + * + * @param remote the remote to connect to + * @param direction GIT_DIRECTION_FETCH if you want to fetch or + * GIT_DIRECTION_PUSH if you want to push + * @param opts the remote connection options + * @return 0 or an error code + */ +GIT_EXTERN(int) git_remote_connect_ext( + git_remote *remote, + git_direction direction, + const git_remote_connect_options *opts); + +/** + * Download and index the packfile. * * Connect to the remote if it hasn't been done yet, negotiate with * the remote git which objects are missing, download and index the @@ -818,19 +887,31 @@ GIT_EXTERN(int) git_push_options_init( * The .idx file will be created and both it and the packfile with be * renamed to their final name. * + * If options are specified and this remote is already connected then + * the existing remote connection options will be discarded and the + * remote will now use the new options. + * * @param remote the remote * @param refspecs the refspecs to use for this negotiation and * download. Use NULL or an empty array to use the base refspecs - * @param opts the options to use for this fetch + * @param opts the options to use for this fetch or NULL * @return 0 or an error code */ - GIT_EXTERN(int) git_remote_download(git_remote *remote, const git_strarray *refspecs, const git_fetch_options *opts); + GIT_EXTERN(int) git_remote_download( + git_remote *remote, + const git_strarray *refspecs, + const git_fetch_options *opts); /** * Create a packfile and send it to the server * * Connect to the remote if it hasn't been done yet, negotiate with - * the remote git which objects are missing, create a packfile with the missing objects and send it. + * the remote git which objects are missing, create a packfile with + * the missing objects and send it. + * + * If options are specified and this remote is already connected then + * the existing remote connection options will be discarded and the + * remote will now use the new options. * * @param remote the remote * @param refspecs the refspecs to use for this negotiation and @@ -838,17 +919,23 @@ GIT_EXTERN(int) git_push_options_init( * @param opts the options to use for this push * @return 0 or an error code */ -GIT_EXTERN(int) git_remote_upload(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts); +GIT_EXTERN(int) git_remote_upload( + git_remote *remote, + const git_strarray *refspecs, + const git_push_options *opts); /** - * Update the tips to the new state + * Update the tips to the new state. + * + * If callbacks are not specified then the callbacks specified to + * `git_remote_connect` will be used (if it was called). * * @param remote the remote to update * @param reflog_message The message to insert into the reflogs. If * NULL and fetching, the default is "fetch ", where is * the name of the remote (or its url, for in-memory remotes). This * parameter is ignored when pushing. - * @param callbacks pointer to the callback structure to use + * @param callbacks pointer to the callback structure to use or NULL * @param update_fetchhead whether to write to FETCH_HEAD. Pass 1 to behave like git. * @param download_tags what the behaviour for downloading tags is for this fetch. This is * ignored for push. This must be the same value passed to `git_remote_download()`. @@ -862,15 +949,19 @@ GIT_EXTERN(int) git_remote_update_tips( const char *reflog_message); /** - * Download new data and update tips + * Download new data and update tips. * * Convenience function to connect to a remote, download the data, * disconnect and update the remote-tracking branches. * + * If options are specified and this remote is already connected then + * the existing remote connection options will be discarded and the + * remote will now use the new options. + * * @param remote the remote to fetch from * @param refspecs the refspecs to use for this fetch. Pass NULL or an * empty array to use the base refspecs. - * @param opts options to use for this fetch + * @param opts options to use for this fetch or NULL * @param reflog_message The message to insert into the reflogs. If NULL, the * default is "fetch" * @return 0 or an error code @@ -882,27 +973,35 @@ GIT_EXTERN(int) git_remote_fetch( const char *reflog_message); /** - * Prune tracking refs that are no longer present on remote + * Prune tracking refs that are no longer present on remote. + * + * If callbacks are not specified then the callbacks specified to + * `git_remote_connect` will be used (if it was called). * * @param remote the remote to prune * @param callbacks callbacks to use for this prune * @return 0 or an error code */ -GIT_EXTERN(int) git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks); +GIT_EXTERN(int) git_remote_prune( + git_remote *remote, + const git_remote_callbacks *callbacks); /** - * Perform a push + * Perform a push. * - * Peform all the steps from a push. + * If options are specified and this remote is already connected then + * the existing remote connection options will be discarded and the + * remote will now use the new options. * * @param remote the remote to push to * @param refspecs the refspecs to use for pushing. If NULL or an empty * array, the configured refspecs will be used * @param opts options to use for this push */ -GIT_EXTERN(int) git_remote_push(git_remote *remote, - const git_strarray *refspecs, - const git_push_options *opts); +GIT_EXTERN(int) git_remote_push( + git_remote *remote, + const git_strarray *refspecs, + const git_push_options *opts); /** * Get the statistics structure that is filled in by the fetch operation. diff --git a/include/git2/sys/transport.h b/include/git2/sys/transport.h index 76003ee8470..89e6876498b 100644 --- a/include/git2/sys/transport.h +++ b/include/git2/sys/transport.h @@ -24,31 +24,9 @@ GIT_BEGIN_DECL -/** - * Flags to pass to transport - * - * Currently unused. - */ -typedef enum { - GIT_TRANSPORTFLAGS_NONE = 0 -} git_transport_flags_t; - struct git_transport { unsigned int version; /**< The struct version */ - /** Set progress and error callbacks */ - int GIT_CALLBACK(set_callbacks)( - git_transport *transport, - git_transport_message_cb progress_cb, - git_transport_message_cb error_cb, - git_transport_certificate_check_cb certificate_check_cb, - void *payload); - - /** Set custom headers for HTTP requests */ - int GIT_CALLBACK(set_custom_headers)( - git_transport *transport, - const git_strarray *custom_headers); - /** * Connect the transport to the remote repository, using the given * direction. @@ -56,11 +34,17 @@ struct git_transport { int GIT_CALLBACK(connect)( git_transport *transport, const char *url, - git_credential_acquire_cb cred_acquire_cb, - void *cred_acquire_payload, - const git_proxy_options *proxy_opts, int direction, - int flags); + const git_remote_connect_options *connect_opts); + + /** + * Resets the connect options for the given transport. This + * is useful for updating settings or callbacks for an already + * connected transport. + */ + int GIT_CALLBACK(set_connect_opts)( + git_transport *transport, + const git_remote_connect_options *connect_opts); /** * Get the list of available references in the remote repository. @@ -75,7 +59,9 @@ struct git_transport { git_transport *transport); /** Executes the push whose context is in the git_push object. */ - int GIT_CALLBACK(push)(git_transport *transport, git_push *push, const git_remote_callbacks *callbacks); + int GIT_CALLBACK(push)( + git_transport *transport, + git_push *push); /** * Negotiate a fetch with the remote repository. @@ -99,16 +85,11 @@ struct git_transport { int GIT_CALLBACK(download_pack)( git_transport *transport, git_repository *repo, - git_indexer_progress *stats, - git_indexer_progress_cb progress_cb, - void *progress_payload); + git_indexer_progress *stats); /** Checks to see if the transport is connected */ int GIT_CALLBACK(is_connected)(git_transport *transport); - /** Reads the flags value previously passed into connect() */ - int GIT_CALLBACK(read_flags)(git_transport *transport, int *flags); - /** Cancels any outstanding transport operation */ void GIT_CALLBACK(cancel)(git_transport *transport); diff --git a/src/fetch.c b/src/fetch.c index bc5961db4f1..117c8f26f2d 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -134,21 +134,14 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) remote->refs.length); } -int git_fetch_download_pack(git_remote *remote, const git_remote_callbacks *callbacks) +int git_fetch_download_pack(git_remote *remote) { git_transport *t = remote->transport; - git_indexer_progress_cb progress = NULL; - void *payload = NULL; if (!remote->need_pack) return 0; - if (callbacks) { - progress = callbacks->transfer_progress; - payload = callbacks->payload; - } - - return t->download_pack(t, remote->repo, &remote->stats, progress, payload); + return t->download_pack(t, remote->repo, &remote->stats); } int git_fetch_options_init(git_fetch_options *opts, unsigned int version) diff --git a/src/fetch.h b/src/fetch.h index 1c75af9c306..10b6731f0a2 100644 --- a/src/fetch.h +++ b/src/fetch.h @@ -15,7 +15,7 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts); -int git_fetch_download_pack(git_remote *remote, const git_remote_callbacks *callbacks); +int git_fetch_download_pack(git_remote *remote); int git_fetch_setup_walk(git_revwalk **out, git_repository *repo); diff --git a/src/proxy.c b/src/proxy.c index 78a4c5535b6..ef91ad6eaaa 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -39,8 +39,11 @@ int git_proxy_options_dup(git_proxy_options *tgt, const git_proxy_options *src) return 0; } -void git_proxy_options_clear(git_proxy_options *opts) +void git_proxy_options_dispose(git_proxy_options *opts) { + if (!opts) + return; + git__free((char *) opts->url); opts->url = NULL; } diff --git a/src/proxy.h b/src/proxy.h index f8b5c4b50f9..7c0ab598d9a 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -12,6 +12,6 @@ #include "git2/proxy.h" extern int git_proxy_options_dup(git_proxy_options *tgt, const git_proxy_options *src); -extern void git_proxy_options_clear(git_proxy_options *opts); +extern void git_proxy_options_dispose(git_proxy_options *opts); #endif diff --git a/src/push.c b/src/push.c index 9733eecf992..da8aebadd14 100644 --- a/src/push.c +++ b/src/push.c @@ -29,19 +29,26 @@ static int push_status_ref_cmp(const void *a, const void *b) return strcmp(push_status_a->ref, push_status_b->ref); } -int git_push_new(git_push **out, git_remote *remote) +int git_push_new(git_push **out, git_remote *remote, const git_push_options *opts) { git_push *p; *out = NULL; + GIT_ERROR_CHECK_VERSION(opts, GIT_PUSH_OPTIONS_VERSION, "git_push_options"); + p = git__calloc(1, sizeof(*p)); GIT_ERROR_CHECK_ALLOC(p); p->repo = remote->repo; p->remote = remote; p->report_status = 1; - p->pb_parallelism = 1; + p->pb_parallelism = opts ? opts->pb_parallelism : 1; + + if (opts) { + GIT_ERROR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); + memcpy(&p->callbacks, &opts->callbacks, sizeof(git_remote_callbacks)); + } if (git_vector_init(&p->specs, 0, push_spec_rref_cmp) < 0) { git__free(p); @@ -65,20 +72,6 @@ int git_push_new(git_push **out, git_remote *remote) return 0; } -int git_push_set_options(git_push *push, const git_push_options *opts) -{ - if (!push || !opts) - return -1; - - GIT_ERROR_CHECK_VERSION(opts, GIT_PUSH_OPTIONS_VERSION, "git_push_options"); - - push->pb_parallelism = opts->pb_parallelism; - push->connection.custom_headers = &opts->custom_headers; - push->connection.proxy = &opts->proxy_opts; - - return 0; -} - static void free_refspec(push_spec *spec) { if (spec == NULL) @@ -411,10 +404,11 @@ static int calculate_work(git_push *push) return 0; } -static int do_push(git_push *push, const git_remote_callbacks *callbacks) +static int do_push(git_push *push) { int error = 0; git_transport *transport = push->remote->transport; + git_remote_callbacks *callbacks = &push->callbacks; if (!transport->push) { git_error_set(GIT_ERROR_NET, "remote transport doesn't support push"); @@ -446,7 +440,7 @@ static int do_push(git_push *push, const git_remote_callbacks *callbacks) goto on_error; if ((error = queue_objects(push)) < 0 || - (error = transport->push(transport, push, callbacks)) < 0) + (error = transport->push(transport, push)) < 0) goto on_error; on_error: @@ -472,7 +466,7 @@ static int filter_refs(git_remote *remote) return 0; } -int git_push_finish(git_push *push, const git_remote_callbacks *callbacks) +int git_push_finish(git_push *push) { int error; @@ -482,7 +476,7 @@ int git_push_finish(git_push *push, const git_remote_callbacks *callbacks) } if ((error = filter_refs(push->remote)) < 0 || - (error = do_push(push, callbacks)) < 0) + (error = do_push(push)) < 0) return error; if (!push->unpack_ok) { diff --git a/src/push.h b/src/push.h index 86756394055..fc72e845eee 100644 --- a/src/push.h +++ b/src/push.h @@ -41,7 +41,7 @@ struct git_push { /* options */ unsigned pb_parallelism; - git_remote_connection_opts connection; + git_remote_callbacks callbacks; }; /** @@ -56,22 +56,11 @@ void git_push_status_free(push_status *status); * * @param out New push object * @param remote Remote instance + * @param opts Push options or NULL * * @return 0 or an error code */ -int git_push_new(git_push **out, git_remote *remote); - -/** - * Set options on a push object - * - * @param push The push object - * @param opts The options to set on the push object - * - * @return 0 or an error code - */ -int git_push_set_options( - git_push *push, - const git_push_options *opts); +int git_push_new(git_push **out, git_remote *remote, const git_push_options *opts); /** * Add a refspec to be pushed @@ -104,11 +93,10 @@ int git_push_update_tips(git_push *push, const git_remote_callbacks *callbacks); * order to find out which updates were accepted or rejected. * * @param push The push object - * @param callbacks the callbacks to use for this connection * * @return 0 or an error code */ -int git_push_finish(git_push *push, const git_remote_callbacks *callbacks); +int git_push_finish(git_push *push); /** * Invoke callback `cb' on each status entry diff --git a/src/remote.c b/src/remote.c index f697e0fb89e..208d8d00ba0 100644 --- a/src/remote.c +++ b/src/remote.c @@ -16,6 +16,7 @@ #include "refspec.h" #include "fetchhead.h" #include "push.h" +#include "proxy.h" #include "git2/config.h" #include "git2/types.h" @@ -756,54 +757,155 @@ int git_remote__urlfordirection( return resolve_url(url_out, url, direction, callbacks); } -static int remote_transport_set_callbacks(git_transport *t, const git_remote_callbacks *cbs) +int git_remote_connect_options_init( + git_remote_connect_options *opts, + unsigned int version) { - if (!t->set_callbacks || !cbs) + GIT_INIT_STRUCTURE_FROM_TEMPLATE( + opts, version, git_remote_connect_options, GIT_REMOTE_CONNECT_OPTIONS_INIT); + return 0; +} + +int git_remote_connect_options_dup( + git_remote_connect_options *dst, + const git_remote_connect_options *src) +{ + memcpy(dst, src, sizeof(git_remote_connect_options)); + + if (git_proxy_options_dup(&dst->proxy_opts, &src->proxy_opts) < 0 || + git_strarray_copy(&dst->custom_headers, &src->custom_headers) < 0) + return -1; + + return 0; +} + +void git_remote_connect_options_dispose(git_remote_connect_options *opts) +{ + if (!opts) + return; + + git_strarray_dispose(&opts->custom_headers); + git_proxy_options_dispose(&opts->proxy_opts); +} + +static size_t http_header_name_length(const char *http_header) +{ + const char *colon = strchr(http_header, ':'); + if (!colon) + return 0; + return colon - http_header; +} + +static bool is_malformed_http_header(const char *http_header) +{ + const char *c; + size_t name_len; + + /* Disallow \r and \n */ + if ((c = strchr(http_header, '\r')) != NULL) + return true; + if ((c = strchr(http_header, '\n')) != NULL) + return true; + + /* Require a header name followed by : */ + if ((name_len = http_header_name_length(http_header)) < 1) + return true; + + return false; +} + +static char *forbidden_custom_headers[] = { + "User-Agent", + "Host", + "Accept", + "Content-Type", + "Transfer-Encoding", + "Content-Length", +}; + +static bool is_forbidden_custom_header(const char *custom_header) +{ + unsigned long i; + size_t name_len = http_header_name_length(custom_header); + + /* Disallow headers that we set */ + for (i = 0; i < ARRAY_SIZE(forbidden_custom_headers); i++) + if (strncmp(forbidden_custom_headers[i], custom_header, name_len) == 0) + return true; + + return false; +} + +static int validate_custom_headers(const git_strarray *custom_headers) +{ + size_t i; + + if (!custom_headers) return 0; - return t->set_callbacks(t, cbs->sideband_progress, NULL, - cbs->certificate_check, cbs->payload); + for (i = 0; i < custom_headers->count; i++) { + if (is_malformed_http_header(custom_headers->strings[i])) { + git_error_set(GIT_ERROR_INVALID, "custom HTTP header '%s' is malformed", custom_headers->strings[i]); + return -1; + } + + if (is_forbidden_custom_header(custom_headers->strings[i])) { + git_error_set(GIT_ERROR_INVALID, "custom HTTP header '%s' is already set by libgit2", custom_headers->strings[i]); + return -1; + } + } + + return 0; } -static int set_transport_custom_headers(git_transport *t, const git_strarray *custom_headers) +int git_remote_connect_options_normalize( + git_remote_connect_options *dst, + const git_remote_connect_options *src) { - if (!t->set_custom_headers) + git_remote_connect_options_dispose(dst); + + if (!src) { + git_remote_connect_options_init(dst, GIT_REMOTE_CONNECT_OPTIONS_VERSION); return 0; + } + + GIT_ERROR_CHECK_VERSION(src, GIT_REMOTE_CONNECT_OPTIONS_VERSION, "git_remote_connect_options"); + GIT_ERROR_CHECK_VERSION(&src->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); + GIT_ERROR_CHECK_VERSION(&src->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options"); - return t->set_custom_headers(t, custom_headers); + if (validate_custom_headers(&src->custom_headers)) + return -1; + + return git_remote_connect_options_dup(dst, src); } -int git_remote__connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_remote_connection_opts *conn) +int git_remote_connect_ext( + git_remote *remote, + git_direction direction, + const git_remote_connect_options *given_opts) { - git_transport *t; + git_remote_connect_options opts = GIT_REMOTE_CONNECT_OPTIONS_INIT; git_str url = GIT_STR_INIT; - int flags = GIT_TRANSPORTFLAGS_NONE; + git_transport *t; int error; - void *payload = NULL; - git_credential_acquire_cb credentials = NULL; - git_transport_cb transport = NULL; GIT_ASSERT_ARG(remote); - if (callbacks) { - GIT_ERROR_CHECK_VERSION(callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); - credentials = callbacks->credentials; - transport = callbacks->transport; - payload = callbacks->payload; - } + if (given_opts) + memcpy(&opts, given_opts, sizeof(git_remote_connect_options)); - if (conn->proxy) - GIT_ERROR_CHECK_VERSION(conn->proxy, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options"); + GIT_ERROR_CHECK_VERSION(&opts.callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); + GIT_ERROR_CHECK_VERSION(&opts.proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options"); t = remote->transport; - if ((error = git_remote__urlfordirection(&url, remote, direction, callbacks)) < 0) + if ((error = git_remote__urlfordirection(&url, remote, direction, &opts.callbacks)) < 0) goto on_error; /* If we don't have a transport object yet, and the caller specified a * custom transport factory, use that */ - if (!t && transport && - (error = transport(&t, remote, payload)) < 0) + if (!t && opts.callbacks.transport && + (error = opts.callbacks.transport(&t, remote, opts.callbacks.payload)) < 0) goto on_error; /* If we still don't have a transport, then use the global @@ -811,11 +913,7 @@ int git_remote__connect(git_remote *remote, git_direction direction, const git_r if (!t && (error = git_transport_new(&t, remote, url.ptr)) < 0) goto on_error; - if ((error = set_transport_custom_headers(t, conn->custom_headers)) != 0) - goto on_error; - - if ((error = remote_transport_set_callbacks(t, callbacks)) < 0 || - (error = t->connect(t, url.ptr, credentials, payload, conn->proxy, direction, flags)) != 0) + if ((error = t->connect(t, url.ptr, direction, &opts)) != 0) goto on_error; remote->transport = t; @@ -836,14 +934,25 @@ int git_remote__connect(git_remote *remote, git_direction direction, const git_r return error; } -int git_remote_connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_proxy_options *proxy, const git_strarray *custom_headers) +int git_remote_connect( + git_remote *remote, + git_direction direction, + const git_remote_callbacks *callbacks, + const git_proxy_options *proxy, + const git_strarray *custom_headers) { - git_remote_connection_opts conn; + git_remote_connect_options opts = GIT_REMOTE_CONNECT_OPTIONS_INIT; + + if (callbacks) + memcpy(&opts.callbacks, callbacks, sizeof(git_remote_callbacks)); - conn.proxy = proxy; - conn.custom_headers = custom_headers; + if (proxy) + memcpy(&opts.proxy_opts, proxy, sizeof(git_proxy_options)); - return git_remote__connect(remote, direction, callbacks, &conn); + if (custom_headers) + memcpy(&opts.custom_headers, custom_headers, sizeof(git_strarray)); + + return git_remote_connect_ext(remote, direction, &opts); } int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote) @@ -1057,33 +1166,43 @@ static int ls_to_vector(git_vector *out, git_remote *remote) return 0; } -int git_remote_download(git_remote *remote, const git_strarray *refspecs, const git_fetch_options *opts) -{ - int error = -1; - size_t i; - git_vector *to_active, specs = GIT_VECTOR_INIT, refs = GIT_VECTOR_INIT; - const git_remote_callbacks *cbs = NULL; - const git_strarray *custom_headers = NULL; - const git_proxy_options *proxy = NULL; - - GIT_ASSERT_ARG(remote); - - if (!remote->repo) { - git_error_set(GIT_ERROR_INVALID, "cannot download detached remote"); - return -1; +#define copy_opts(out, in) \ + if (in) { \ + (out)->callbacks = (in)->callbacks; \ + (out)->proxy_opts = (in)->proxy_opts; \ + (out)->custom_headers = (in)->custom_headers; \ } - if (opts) { - GIT_ERROR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); - cbs = &opts->callbacks; - custom_headers = &opts->custom_headers; - GIT_ERROR_CHECK_VERSION(&opts->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options"); - proxy = &opts->proxy_opts; +GIT_INLINE(int) connect_opts_from_fetch_opts( + git_remote_connect_options *out, + const git_fetch_options *fetch_opts) +{ + git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT; + copy_opts(&tmp, fetch_opts); + return git_remote_connect_options_normalize(out, &tmp); +} + +static int connect_or_reset_options( + git_remote *remote, + int direction, + git_remote_connect_options *opts) +{ + if (!git_remote_connected(remote)) { + return git_remote_connect_ext(remote, direction, opts); + } else { + return remote->transport->set_connect_opts(remote->transport, opts); } +} - if (!git_remote_connected(remote) && - (error = git_remote_connect(remote, GIT_DIRECTION_FETCH, cbs, proxy, custom_headers)) < 0) - goto on_error; +/* Download from an already connected remote. */ +static int git_remote__download( + git_remote *remote, + const git_strarray *refspecs, + const git_fetch_options *opts) +{ + git_vector *to_active, specs = GIT_VECTOR_INIT, refs = GIT_VECTOR_INIT; + size_t i; + int error; if (ls_to_vector(&refs, remote) < 0) return -1; @@ -1116,7 +1235,7 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const git_vector_free(&specs); if (error < 0) - return error; + goto on_error; if (remote->push) { git_push_free(remote->push); @@ -1124,9 +1243,9 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const } if ((error = git_fetch_negotiate(remote, opts)) < 0) - return error; + goto on_error; - return git_fetch_download_pack(remote, cbs); + error = git_fetch_download_pack(remote); on_error: git_vector_free(&refs); @@ -1135,41 +1254,69 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const return error; } +int git_remote_download( + git_remote *remote, + const git_strarray *refspecs, + const git_fetch_options *opts) +{ + git_remote_connect_options connect_opts = GIT_REMOTE_CONNECT_OPTIONS_INIT; + int error; + + GIT_ASSERT_ARG(remote); + + if (!remote->repo) { + git_error_set(GIT_ERROR_INVALID, "cannot download detached remote"); + return -1; + } + + if (connect_opts_from_fetch_opts(&connect_opts, opts) < 0) + return -1; + + if ((error = connect_or_reset_options(remote, GIT_DIRECTION_FETCH, &connect_opts)) < 0) + return error; + + return git_remote__download(remote, refspecs, opts); +} + int git_remote_fetch( - git_remote *remote, - const git_strarray *refspecs, - const git_fetch_options *opts, - const char *reflog_message) + git_remote *remote, + const git_strarray *refspecs, + const git_fetch_options *opts, + const char *reflog_message) { int error, update_fetchhead = 1; git_remote_autotag_option_t tagopt = remote->download_tags; bool prune = false; git_str reflog_msg_buf = GIT_STR_INIT; - const git_remote_callbacks *cbs = NULL; - git_remote_connection_opts conn = GIT_REMOTE_CONNECTION_OPTIONS_INIT; + git_remote_connect_options connect_opts = GIT_REMOTE_CONNECT_OPTIONS_INIT; + + GIT_ASSERT_ARG(remote); + + if (!remote->repo) { + git_error_set(GIT_ERROR_INVALID, "cannot download detached remote"); + return -1; + } + + if (connect_opts_from_fetch_opts(&connect_opts, opts) < 0) + return -1; + + if ((error = connect_or_reset_options(remote, GIT_DIRECTION_FETCH, &connect_opts)) < 0) + return error; if (opts) { - GIT_ERROR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); - cbs = &opts->callbacks; - conn.custom_headers = &opts->custom_headers; update_fetchhead = opts->update_fetchhead; tagopt = opts->download_tags; - GIT_ERROR_CHECK_VERSION(&opts->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options"); - conn.proxy = &opts->proxy_opts; } /* Connect and download everything */ - if ((error = git_remote__connect(remote, GIT_DIRECTION_FETCH, cbs, &conn)) != 0) - return error; - - error = git_remote_download(remote, refspecs, opts); + error = git_remote__download(remote, refspecs, opts); /* We don't need to be connected anymore */ git_remote_disconnect(remote); /* If the download failed, return the error */ if (error != 0) - return error; + goto done; /* Default reflog message */ if (reflog_message) @@ -1180,10 +1327,10 @@ int git_remote_fetch( } /* Create "remote/foo" branches for all remote branches */ - error = git_remote_update_tips(remote, cbs, update_fetchhead, tagopt, git_str_cstr(&reflog_msg_buf)); + error = git_remote_update_tips(remote, &connect_opts.callbacks, update_fetchhead, tagopt, git_str_cstr(&reflog_msg_buf)); git_str_dispose(&reflog_msg_buf); if (error < 0) - return error; + goto done; if (opts && opts->prune == GIT_FETCH_PRUNE) prune = true; @@ -1195,8 +1342,10 @@ int git_remote_fetch( prune = remote->prune_refs; if (prune) - error = git_remote_prune(remote, cbs); + error = git_remote_prune(remote, &connect_opts.callbacks); +done: + git_remote_connect_options_dispose(&connect_opts); return error; } @@ -2619,14 +2768,25 @@ int git_remote__default_branch(git_str *out, git_remote *remote) return error; } -int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts) +GIT_INLINE(int) connect_opts_from_push_opts( + git_remote_connect_options *out, + const git_push_options *push_opts) { - size_t i; - int error; + git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT; + copy_opts(&tmp, push_opts); + return git_remote_connect_options_normalize(out, &tmp); +} + +int git_remote_upload( + git_remote *remote, + const git_strarray *refspecs, + const git_push_options *opts) +{ + git_remote_connect_options connect_opts = GIT_REMOTE_CONNECT_OPTIONS_INIT; git_push *push; git_refspec *spec; - const git_remote_callbacks *cbs = NULL; - git_remote_connection_opts conn = GIT_REMOTE_CONNECTION_OPTIONS_INIT; + size_t i; + int error; GIT_ASSERT_ARG(remote); @@ -2635,14 +2795,10 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi return -1; } - if (opts) { - cbs = &opts->callbacks; - conn.custom_headers = &opts->custom_headers; - conn.proxy = &opts->proxy_opts; - } + if ((error = connect_opts_from_push_opts(&connect_opts, opts)) < 0) + goto cleanup; - if (!git_remote_connected(remote) && - (error = git_remote__connect(remote, GIT_DIRECTION_PUSH, cbs, &conn)) < 0) + if ((error = connect_or_reset_options(remote, GIT_DIRECTION_PUSH, &connect_opts)) < 0) goto cleanup; free_refspecs(&remote->active_refspecs); @@ -2654,14 +2810,11 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi remote->push = NULL; } - if ((error = git_push_new(&remote->push, remote)) < 0) - return error; + if ((error = git_push_new(&remote->push, remote, opts)) < 0) + goto cleanup; push = remote->push; - if (opts && (error = git_push_set_options(push, opts)) < 0) - goto cleanup; - if (refspecs && refspecs->count > 0) { for (i = 0; i < refspecs->count; i++) { if ((error = git_push_add_refspec(push, refspecs->strings[i])) < 0) @@ -2676,23 +2829,25 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi } } - if ((error = git_push_finish(push, cbs)) < 0) + if ((error = git_push_finish(push)) < 0) goto cleanup; - if (cbs && cbs->push_update_reference && - (error = git_push_status_foreach(push, cbs->push_update_reference, cbs->payload)) < 0) + if (connect_opts.callbacks.push_update_reference && + (error = git_push_status_foreach(push, connect_opts.callbacks.push_update_reference, connect_opts.callbacks.payload)) < 0) goto cleanup; cleanup: + git_remote_connect_options_dispose(&connect_opts); return error; } -int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_push_options *opts) +int git_remote_push( + git_remote *remote, + const git_strarray *refspecs, + const git_push_options *opts) { + git_remote_connect_options connect_opts = GIT_REMOTE_CONNECT_OPTIONS_INIT; int error; - const git_remote_callbacks *cbs = NULL; - const git_strarray *custom_headers = NULL; - const git_proxy_options *proxy = NULL; GIT_ASSERT_ARG(remote); @@ -2701,23 +2856,17 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_ return -1; } - if (opts) { - GIT_ERROR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); - cbs = &opts->callbacks; - custom_headers = &opts->custom_headers; - GIT_ERROR_CHECK_VERSION(&opts->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options"); - proxy = &opts->proxy_opts; - } - - if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs, proxy, custom_headers)) < 0) - return error; + if (connect_opts_from_push_opts(&connect_opts, opts) < 0) + return -1; if ((error = git_remote_upload(remote, refspecs, opts)) < 0) - return error; + goto done; - error = git_remote_update_tips(remote, cbs, 0, 0, NULL); + error = git_remote_update_tips(remote, &connect_opts.callbacks, 0, 0, NULL); +done: git_remote_disconnect(remote); + git_remote_connect_options_dispose(&connect_opts); return error; } diff --git a/src/remote.h b/src/remote.h index 77eefdf4088..1655e1551b6 100644 --- a/src/remote.h +++ b/src/remote.h @@ -37,15 +37,6 @@ struct git_remote { int passed_refspecs; }; -typedef struct git_remote_connection_opts { - const git_strarray *custom_headers; - const git_proxy_options *proxy; -} git_remote_connection_opts; - -#define GIT_REMOTE_CONNECTION_OPTIONS_INIT { NULL, NULL } - -int git_remote__connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_remote_connection_opts *conn); - int git_remote__urlfordirection(git_str *url_out, struct git_remote *remote, int direction, const git_remote_callbacks *callbacks); int git_remote__http_proxy(char **out, git_remote *remote, git_net_url *url); @@ -54,4 +45,12 @@ git_refspec *git_remote__matching_dst_refspec(git_remote *remote, const char *re int git_remote__default_branch(git_str *out, git_remote *remote); +int git_remote_connect_options_dup( + git_remote_connect_options *dst, + const git_remote_connect_options *src); +int git_remote_connect_options_normalize( + git_remote_connect_options *dst, + const git_remote_connect_options *src); +void git_remote_connect_options_dispose(git_remote_connect_options *opts); + #endif diff --git a/src/transports/http.c b/src/transports/http.c index adcb1ac43cd..fa576ff3e97 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -174,6 +174,7 @@ GIT_INLINE(int) handle_remote_auth( git_http_response *response) { http_subtransport *transport = OWNING_SUBTRANSPORT(stream); + git_remote_connect_options *connect_opts = &transport->owner->connect_opts; if (response->server_auth_credtypes == 0) { git_error_set(GIT_ERROR_HTTP, "server requires authentication that we do not support"); @@ -187,8 +188,8 @@ GIT_INLINE(int) handle_remote_auth( transport->owner->url, response->server_auth_schemetypes, response->server_auth_credtypes, - transport->owner->cred_acquire_cb, - transport->owner->cred_acquire_payload); + connect_opts->callbacks.credentials, + connect_opts->callbacks.payload); } GIT_INLINE(int) handle_proxy_auth( @@ -196,6 +197,7 @@ GIT_INLINE(int) handle_proxy_auth( git_http_response *response) { http_subtransport *transport = OWNING_SUBTRANSPORT(stream); + git_remote_connect_options *connect_opts = &transport->owner->connect_opts; if (response->proxy_auth_credtypes == 0) { git_error_set(GIT_ERROR_HTTP, "proxy requires authentication that we do not support"); @@ -206,11 +208,11 @@ GIT_INLINE(int) handle_proxy_auth( return handle_auth( &transport->proxy, SERVER_TYPE_PROXY, - transport->owner->proxy.url, + connect_opts->proxy_opts.url, response->server_auth_schemetypes, response->proxy_auth_credtypes, - transport->owner->proxy.credentials, - transport->owner->proxy.payload); + connect_opts->proxy_opts.credentials, + connect_opts->proxy_opts.payload); } @@ -286,6 +288,7 @@ static int lookup_proxy( bool *out_use, http_subtransport *transport) { + git_remote_connect_options *connect_opts = &transport->owner->connect_opts; const char *proxy; git_remote *remote; char *config = NULL; @@ -294,9 +297,9 @@ static int lookup_proxy( *out_use = false; git_net_url_dispose(&transport->proxy.url); - switch (transport->owner->proxy.type) { + switch (connect_opts->proxy_opts.type) { case GIT_PROXY_SPECIFIED: - proxy = transport->owner->proxy.url; + proxy = connect_opts->proxy_opts.url; break; case GIT_PROXY_AUTO: @@ -345,7 +348,7 @@ static int generate_request( request->credentials = transport->server.cred; request->proxy = use_proxy ? &transport->proxy.url : NULL; request->proxy_credentials = transport->proxy.cred; - request->custom_headers = &transport->owner->custom_headers; + request->custom_headers = &transport->owner->connect_opts.custom_headers; if (stream->service->method == GIT_HTTP_METHOD_POST) { request->chunked = stream->service->chunked; @@ -633,6 +636,7 @@ static int http_action( git_smart_service_t action) { http_subtransport *transport = GIT_CONTAINER_OF(t, http_subtransport, parent); + git_remote_connect_options *connect_opts = &transport->owner->connect_opts; http_stream *stream; const http_service *service; int error; @@ -664,10 +668,10 @@ static int http_action( if (!transport->http_client) { git_http_client_options opts = {0}; - opts.server_certificate_check_cb = transport->owner->certificate_check_cb; - opts.server_certificate_check_payload = transport->owner->message_cb_payload; - opts.proxy_certificate_check_cb = transport->owner->proxy.certificate_check; - opts.proxy_certificate_check_payload = transport->owner->proxy.payload; + opts.server_certificate_check_cb = connect_opts->callbacks.certificate_check; + opts.server_certificate_check_payload = connect_opts->callbacks.payload; + opts.proxy_certificate_check_cb = connect_opts->proxy_opts.certificate_check; + opts.proxy_certificate_check_payload = connect_opts->proxy_opts.payload; if (git_http_client_new(&transport->http_client, &opts) < 0) return -1; diff --git a/src/transports/local.c b/src/transports/local.c index 0983914b1af..6065d4020bd 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -34,12 +34,9 @@ typedef struct { git_remote *owner; char *url; int direction; - int flags; git_atomic32 cancelled; git_repository *repo; - git_transport_message_cb progress_cb; - git_transport_message_cb error_cb; - void *message_cb_payload; + git_remote_connect_options connect_opts; git_vector refs; unsigned connected : 1, have_refs : 1; @@ -200,30 +197,26 @@ static int store_refs(transport_local *t) static int local_connect( git_transport *transport, const char *url, - git_credential_acquire_cb cred_acquire_cb, - void *cred_acquire_payload, - const git_proxy_options *proxy, - int direction, int flags) + int direction, + const git_remote_connect_options *connect_opts) { git_repository *repo; int error; - transport_local *t = (transport_local *) transport; + transport_local *t = (transport_local *)transport; const char *path; git_str buf = GIT_STR_INIT; - GIT_UNUSED(cred_acquire_cb); - GIT_UNUSED(cred_acquire_payload); - GIT_UNUSED(proxy); - if (t->connected) return 0; + if (git_remote_connect_options_normalize(&t->connect_opts, connect_opts) < 0) + return -1; + free_heads(&t->refs); t->url = git__strdup(url); GIT_ERROR_CHECK_ALLOC(t->url); t->direction = direction; - t->flags = flags; /* 'url' may be a url or path; convert to a path */ if ((error = git_fs_path_from_url_or_path(&buf, url)) < 0) { @@ -249,6 +242,20 @@ static int local_connect( return 0; } +static int local_set_connect_opts( + git_transport *transport, + const git_remote_connect_options *connect_opts) +{ + transport_local *t = (transport_local *)transport; + + if (!t->connected) { + git_error_set(GIT_ERROR_NET, "cannot reconfigure a transport that is not connected"); + return -1; + } + + return git_remote_connect_options_normalize(&t->connect_opts, connect_opts); +} + static int local_ls(const git_remote_head ***out, size_t *size, git_transport *transport) { transport_local *t = (transport_local *)transport; @@ -337,10 +344,10 @@ static int transfer_to_push_transfer(const git_indexer_progress *stats, void *pa static int local_push( git_transport *transport, - git_push *push, - const git_remote_callbacks *cbs) + git_push *push) { transport_local *t = (transport_local *)transport; + git_remote_callbacks *cbs = &t->connect_opts.callbacks; git_repository *remote_repo = NULL; push_spec *spec; char *url = NULL; @@ -349,8 +356,6 @@ static int local_push( int error; size_t j; - GIT_UNUSED(cbs); - /* 'push->remote->url' may be a url or path; convert to a path */ if ((error = git_fs_path_from_url_or_path(&buf, push->remote->url)) < 0) { git_str_dispose(&buf); @@ -440,12 +445,11 @@ static int local_push( } if (push->specs.length) { - int flags = t->flags; url = git__strdup(t->url); if (!url || t->parent.close(&t->parent) < 0 || t->parent.connect(&t->parent, url, - NULL, NULL, NULL, GIT_DIRECTION_PUSH, flags)) + GIT_DIRECTION_PUSH, NULL)) goto on_error; } @@ -482,7 +486,7 @@ static int local_counting(int stage, unsigned int current, unsigned int total, v transport_local *t = payload; int error; - if (!t->progress_cb) + if (!t->connect_opts.callbacks.sideband_progress) return 0; if (stage == GIT_PACKBUILDER_ADDING_OBJECTS) { @@ -500,9 +504,19 @@ static int local_counting(int stage, unsigned int current, unsigned int total, v if (git_str_oom(&progress_info)) return -1; - error = t->progress_cb(git_str_cstr(&progress_info), (int)git_str_len(&progress_info), t->message_cb_payload); - git_str_dispose(&progress_info); + if (progress_info.size > INT_MAX) { + git_error_set(GIT_ERROR_NET, "remote sent overly large progress data"); + git_str_dispose(&progress_info); + return -1; + } + + + error = t->connect_opts.callbacks.sideband_progress( + progress_info.ptr, + (int)progress_info.size, + t->connect_opts.callbacks.payload); + git_str_dispose(&progress_info); return error; } @@ -532,9 +546,7 @@ static int foreach_reference_cb(git_reference *reference, void *payload) static int local_download_pack( git_transport *transport, git_repository *repo, - git_indexer_progress *stats, - git_indexer_progress_cb progress_cb, - void *progress_payload) + git_indexer_progress *stats) { transport_local *t = (transport_local*)transport; git_revwalk *walk = NULL; @@ -545,9 +557,11 @@ static int local_download_pack( git_odb_writepack *writepack = NULL; git_odb *odb = NULL; git_str progress_info = GIT_STR_INIT; + foreach_data data = {0}; if ((error = git_revwalk_new(&walk, t->repo)) < 0) goto cleanup; + git_revwalk_sorting(walk, GIT_SORT_TIME); if ((error = git_packbuilder_new(&pack, t->repo)) < 0) @@ -583,44 +597,56 @@ static int local_download_pack( if ((error = git_packbuilder_insert_walk(pack, walk))) goto cleanup; - if ((error = git_str_printf(&progress_info, counting_objects_fmt, git_packbuilder_object_count(pack))) < 0) - goto cleanup; - - if (t->progress_cb && - (error = t->progress_cb(git_str_cstr(&progress_info), (int)git_str_len(&progress_info), t->message_cb_payload)) < 0) - goto cleanup; + if (t->connect_opts.callbacks.sideband_progress) { + if ((error = git_str_printf( + &progress_info, + counting_objects_fmt, + git_packbuilder_object_count(pack))) < 0 || + (error = t->connect_opts.callbacks.sideband_progress( + progress_info.ptr, + (int)progress_info.size, + t->connect_opts.callbacks.payload)) < 0) + goto cleanup; + } /* Walk the objects, building a packfile */ if ((error = git_repository_odb__weakptr(&odb, repo)) < 0) goto cleanup; /* One last one with the newline */ - git_str_clear(&progress_info); - git_str_printf(&progress_info, counting_objects_fmt, git_packbuilder_object_count(pack)); - if ((error = git_str_putc(&progress_info, '\n')) < 0) - goto cleanup; - - if (t->progress_cb && - (error = t->progress_cb(git_str_cstr(&progress_info), (int)git_str_len(&progress_info), t->message_cb_payload)) < 0) - goto cleanup; + if (t->connect_opts.callbacks.sideband_progress) { + git_str_clear(&progress_info); + + if ((error = git_str_printf( + &progress_info, + counting_objects_fmt, + git_packbuilder_object_count(pack))) < 0 || + (error = git_str_putc(&progress_info, '\n')) < 0 || + (error = t->connect_opts.callbacks.sideband_progress( + progress_info.ptr, + (int)progress_info.size, + t->connect_opts.callbacks.payload)) < 0) + goto cleanup; + } - if ((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) != 0) + if ((error = git_odb_write_pack( + &writepack, + odb, + t->connect_opts.callbacks.transfer_progress, + t->connect_opts.callbacks.payload)) < 0) goto cleanup; /* Write the data to the ODB */ - { - foreach_data data = {0}; - data.stats = stats; - data.progress_cb = progress_cb; - data.progress_payload = progress_payload; - data.writepack = writepack; + data.stats = stats; + data.progress_cb = t->connect_opts.callbacks.transfer_progress; + data.progress_payload = t->connect_opts.callbacks.payload; + data.writepack = writepack; - /* autodetect */ - git_packbuilder_set_threads(pack, 0); + /* autodetect */ + git_packbuilder_set_threads(pack, 0); - if ((error = git_packbuilder_foreach(pack, foreach_cb, &data)) != 0) - goto cleanup; - } + if ((error = git_packbuilder_foreach(pack, foreach_cb, &data)) != 0) + goto cleanup; error = writepack->commit(writepack, stats); @@ -632,24 +658,6 @@ static int local_download_pack( return error; } -static int local_set_callbacks( - git_transport *transport, - git_transport_message_cb progress_cb, - git_transport_message_cb error_cb, - git_transport_certificate_check_cb certificate_check_cb, - void *message_cb_payload) -{ - transport_local *t = (transport_local *)transport; - - GIT_UNUSED(certificate_check_cb); - - t->progress_cb = progress_cb; - t->error_cb = error_cb; - t->message_cb_payload = message_cb_payload; - - return 0; -} - static int local_is_connected(git_transport *transport) { transport_local *t = (transport_local *)transport; @@ -657,15 +665,6 @@ static int local_is_connected(git_transport *transport) return t->connected; } -static int local_read_flags(git_transport *transport, int *flags) -{ - transport_local *t = (transport_local *)transport; - - *flags = t->flags; - - return 0; -} - static void local_cancel(git_transport *transport) { transport_local *t = (transport_local *)transport; @@ -720,8 +719,8 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param) GIT_ERROR_CHECK_ALLOC(t); t->parent.version = GIT_TRANSPORT_VERSION; - t->parent.set_callbacks = local_set_callbacks; t->parent.connect = local_connect; + t->parent.set_connect_opts = local_set_connect_opts; t->parent.negotiate_fetch = local_negotiate_fetch; t->parent.download_pack = local_download_pack; t->parent.push = local_push; @@ -729,7 +728,6 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param) t->parent.free = local_free; t->parent.ls = local_ls; t->parent.is_connected = local_is_connected; - t->parent.read_flags = local_read_flags; t->parent.cancel = local_cancel; if ((error = git_vector_init(&t->refs, 0, NULL)) < 0) { diff --git a/src/transports/smart.c b/src/transports/smart.c index fe024de2fd5..4267e884132 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -56,101 +56,6 @@ GIT_INLINE(int) git_smart__reset_stream(transport_smart *t, bool close_subtransp return 0; } -static int git_smart__set_callbacks( - git_transport *transport, - git_transport_message_cb progress_cb, - git_transport_message_cb error_cb, - git_transport_certificate_check_cb certificate_check_cb, - void *message_cb_payload) -{ - transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); - - t->progress_cb = progress_cb; - t->error_cb = error_cb; - t->certificate_check_cb = certificate_check_cb; - t->message_cb_payload = message_cb_payload; - - return 0; -} - -static size_t http_header_name_length(const char *http_header) -{ - const char *colon = strchr(http_header, ':'); - if (!colon) - return 0; - return colon - http_header; -} - -static bool is_malformed_http_header(const char *http_header) -{ - const char *c; - size_t name_len; - - /* Disallow \r and \n */ - c = strchr(http_header, '\r'); - if (c) - return true; - c = strchr(http_header, '\n'); - if (c) - return true; - - /* Require a header name followed by : */ - name_len = http_header_name_length(http_header); - if (name_len < 1) - return true; - - return false; -} - -static char *forbidden_custom_headers[] = { - "User-Agent", - "Host", - "Accept", - "Content-Type", - "Transfer-Encoding", - "Content-Length", -}; - -static bool is_forbidden_custom_header(const char *custom_header) -{ - unsigned long i; - size_t name_len = http_header_name_length(custom_header); - - /* Disallow headers that we set */ - for (i = 0; i < ARRAY_SIZE(forbidden_custom_headers); i++) - if (strncmp(forbidden_custom_headers[i], custom_header, name_len) == 0) - return true; - - return false; -} - -static int git_smart__set_custom_headers( - git_transport *transport, - const git_strarray *custom_headers) -{ - transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); - size_t i; - - if (t->custom_headers.count) - git_strarray_dispose(&t->custom_headers); - - if (!custom_headers) - return 0; - - for (i = 0; i < custom_headers->count; i++) { - if (is_malformed_http_header(custom_headers->strings[i])) { - git_error_set(GIT_ERROR_INVALID, "custom HTTP header '%s' is malformed", custom_headers->strings[i]); - return -1; - } - if (is_forbidden_custom_header(custom_headers->strings[i])) { - git_error_set(GIT_ERROR_INVALID, "custom HTTP header '%s' is already set by libgit2", custom_headers->strings[i]); - return -1; - } - } - - return git_strarray_copy(&t->custom_headers, custom_headers); -} - int git_smart__update_heads(transport_smart *t, git_vector *symrefs) { size_t i; @@ -206,11 +111,8 @@ static void free_symrefs(git_vector *symrefs) static int git_smart__connect( git_transport *transport, const char *url, - git_credential_acquire_cb cred_acquire_cb, - void *cred_acquire_payload, - const git_proxy_options *proxy, int direction, - int flags) + const git_remote_connect_options *connect_opts) { transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); git_smart_subtransport_stream *stream; @@ -223,24 +125,19 @@ static int git_smart__connect( if (git_smart__reset_stream(t, true) < 0) return -1; + if (git_remote_connect_options_normalize(&t->connect_opts, connect_opts) < 0) + return -1; + t->url = git__strdup(url); GIT_ERROR_CHECK_ALLOC(t->url); - git_proxy_options_clear(&t->proxy); - - if (git_proxy_options_dup(&t->proxy, proxy) < 0) - return -1; - t->direction = direction; - t->flags = flags; - t->cred_acquire_cb = cred_acquire_cb; - t->cred_acquire_payload = cred_acquire_payload; - if (GIT_DIRECTION_FETCH == t->direction) + if (GIT_DIRECTION_FETCH == t->direction) { service = GIT_SERVICE_UPLOADPACK_LS; - else if (GIT_DIRECTION_PUSH == t->direction) + } else if (GIT_DIRECTION_PUSH == t->direction) { service = GIT_SERVICE_RECEIVEPACK_LS; - else { + } else { git_error_set(GIT_ERROR_NET, "invalid direction"); return -1; } @@ -315,6 +212,20 @@ static int git_smart__connect( return error; } +static int git_smart__set_connect_opts( + git_transport *transport, + const git_remote_connect_options *opts) +{ + transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); + + if (!t->connected) { + git_error_set(GIT_ERROR_NET, "cannot reconfigure a transport that is not connected"); + return -1; + } + + return git_remote_connect_options_normalize(&t->connect_opts, opts); +} + static int git_smart__ls(const git_remote_head ***out, size_t *size, git_transport *transport) { transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); @@ -401,15 +312,6 @@ static int git_smart__is_connected(git_transport *transport) return t->connected; } -static int git_smart__read_flags(git_transport *transport, int *flags) -{ - transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); - - *flags = t->flags; - - return 0; -} - static int git_smart__close(git_transport *transport) { transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); @@ -465,9 +367,8 @@ static void git_smart__free(git_transport *transport) git_pkt_free(p); git_vector_free(refs); - git__free((char *)t->proxy.url); - git_strarray_dispose(&t->custom_headers); + git_remote_connect_options_dispose(&t->connect_opts); git__free(t); } @@ -482,34 +383,30 @@ static int ref_name_cmp(const void *a, const void *b) int git_transport_smart_certificate_check(git_transport *transport, git_cert *cert, int valid, const char *hostname) { transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); + git_remote_connect_options *connect_opts = &t->connect_opts; GIT_ASSERT_ARG(transport); GIT_ASSERT_ARG(cert); GIT_ASSERT_ARG(hostname); - if (!t->certificate_check_cb) + if (!connect_opts->callbacks.certificate_check) return GIT_PASSTHROUGH; - return t->certificate_check_cb(cert, valid, hostname, t->message_cb_payload); + return connect_opts->callbacks.certificate_check(cert, valid, hostname, connect_opts->callbacks.payload); } int git_transport_smart_credentials(git_credential **out, git_transport *transport, const char *user, int methods) { transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); + git_remote_connect_options *connect_opts = &t->connect_opts; GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(transport); - if (!t->cred_acquire_cb) + if (!connect_opts->callbacks.credentials) return GIT_PASSTHROUGH; - return t->cred_acquire_cb(out, t->url, user, methods, t->cred_acquire_payload); -} - -int git_transport_smart_proxy_options(git_proxy_options *out, git_transport *transport) -{ - transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); - return git_proxy_options_dup(out, &t->proxy); + return connect_opts->callbacks.credentials(out, t->url, user, methods, connect_opts->callbacks.payload); } int git_transport_smart(git_transport **out, git_remote *owner, void *param) @@ -524,9 +421,8 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param) GIT_ERROR_CHECK_ALLOC(t); t->parent.version = GIT_TRANSPORT_VERSION; - t->parent.set_callbacks = git_smart__set_callbacks; - t->parent.set_custom_headers = git_smart__set_custom_headers; t->parent.connect = git_smart__connect; + t->parent.set_connect_opts = git_smart__set_connect_opts; t->parent.close = git_smart__close; t->parent.free = git_smart__free; t->parent.negotiate_fetch = git_smart__negotiate_fetch; @@ -534,7 +430,6 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param) t->parent.push = git_smart__push; t->parent.ls = git_smart__ls; t->parent.is_connected = git_smart__is_connected; - t->parent.read_flags = git_smart__read_flags; t->parent.cancel = git_smart__cancel; t->owner = owner; diff --git a/src/transports/smart.h b/src/transports/smart.h index a9cab31acd9..726bf40b42d 100644 --- a/src/transports/smart.h +++ b/src/transports/smart.h @@ -137,16 +137,8 @@ typedef struct { git_transport parent; git_remote *owner; char *url; - git_credential_acquire_cb cred_acquire_cb; - void *cred_acquire_payload; - git_proxy_options proxy; + git_remote_connect_options connect_opts; int direction; - int flags; - git_transport_message_cb progress_cb; - git_transport_message_cb error_cb; - git_transport_certificate_check_cb certificate_check_cb; - void *message_cb_payload; - git_strarray custom_headers; git_smart_subtransport *wrapped; git_smart_subtransport_stream *current_stream; transport_smart_caps caps; @@ -157,8 +149,8 @@ typedef struct { packetsize_cb packetsize_cb; void *packetsize_payload; unsigned rpc : 1, - have_refs : 1, - connected : 1; + have_refs : 1, + connected : 1; gitno_buffer buffer; char buffer_data[65536]; } transport_smart; @@ -166,7 +158,7 @@ typedef struct { /* smart_protocol.c */ int git_smart__store_refs(transport_smart *t, int flushes); int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vector *symrefs); -int git_smart__push(git_transport *transport, git_push *push, const git_remote_callbacks *cbs); +int git_smart__push(git_transport *transport, git_push *push); int git_smart__negotiate_fetch( git_transport *transport, @@ -177,9 +169,7 @@ int git_smart__negotiate_fetch( int git_smart__download_pack( git_transport *transport, git_repository *repo, - git_indexer_progress *stats, - git_indexer_progress_cb progress_cb, - void *progress_payload); + git_indexer_progress *stats); /* smart.c */ int git_smart__negotiation_step(git_transport *transport, void *data, size_t len); diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index a9a623cc7df..f1f111715dd 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -512,9 +512,7 @@ static int network_packetsize(size_t received, void *payload) int git_smart__download_pack( git_transport *transport, git_repository *repo, - git_indexer_progress *stats, - git_indexer_progress_cb progress_cb, - void *progress_payload) + git_indexer_progress *stats) { transport_smart *t = (transport_smart *)transport; gitno_buffer *buf = &t->buffer; @@ -523,6 +521,10 @@ int git_smart__download_pack( int error = 0; struct network_packetsize_payload npp = {0}; + // TODO + git_indexer_progress_cb progress_cb = t->connect_opts.callbacks.transfer_progress; + void *progress_payload = t->connect_opts.callbacks.payload; + memset(stats, 0, sizeof(git_indexer_progress)); if (progress_cb) { @@ -568,7 +570,7 @@ int git_smart__download_pack( git_error_clear(); error = GIT_EUSER; } else if (pkt->type == GIT_PKT_PROGRESS) { - if (t->progress_cb) { + if (t->connect_opts.callbacks.sideband_progress) { git_pkt_progress *p = (git_pkt_progress *) pkt; if (p->len > INT_MAX) { @@ -577,7 +579,7 @@ int git_smart__download_pack( goto done; } - error = t->progress_cb(p->data, (int)p->len, t->message_cb_payload); + error = t->connect_opts.callbacks.sideband_progress(p->data, (int)p->len, t->connect_opts.callbacks.payload); } } else if (pkt->type == GIT_PKT_DATA) { git_pkt_data *p = (git_pkt_data *) pkt; @@ -811,7 +813,7 @@ static int parse_report(transport_smart *transport, git_push *push) error = -1; break; case GIT_PKT_PROGRESS: - if (transport->progress_cb) { + if (transport->connect_opts.callbacks.sideband_progress) { git_pkt_progress *p = (git_pkt_progress *) pkt; if (p->len > INT_MAX) { @@ -820,7 +822,7 @@ static int parse_report(transport_smart *transport, git_push *push) goto done; } - error = transport->progress_cb(p->data, (int)p->len, transport->message_cb_payload); + error = transport->connect_opts.callbacks.sideband_progress(p->data, (int)p->len, transport->connect_opts.callbacks.payload); } break; default: @@ -987,9 +989,10 @@ static int stream_thunk(void *buf, size_t size, void *data) return error; } -int git_smart__push(git_transport *transport, git_push *push, const git_remote_callbacks *cbs) +int git_smart__push(git_transport *transport, git_push *push) { transport_smart *t = (transport_smart *)transport; + git_remote_callbacks *cbs = &t->connect_opts.callbacks; struct push_packbuilder_payload packbuilder_payload = {0}; git_str pktline = GIT_STR_INIT; int error = 0, need_pack = 0; diff --git a/src/transports/ssh.c b/src/transports/ssh.c index e3bb5eef625..f37bf70bbe8 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -441,11 +441,15 @@ static int request_creds(git_credential **out, ssh_subtransport *t, const char * int error, no_callback = 0; git_credential *cred = NULL; - if (!t->owner->cred_acquire_cb) { + if (!t->owner->connect_opts.callbacks.credentials) { no_callback = 1; } else { - error = t->owner->cred_acquire_cb(&cred, t->owner->url, user, auth_methods, - t->owner->cred_acquire_payload); + error = t->owner->connect_opts.callbacks.credentials( + &cred, + t->owner->url, + user, + auth_methods, + t->owner->connect_opts.callbacks.payload); if (error == GIT_PASSTHROUGH) { no_callback = 1; @@ -558,7 +562,7 @@ static int _git_ssh_setup_conn( if ((error = _git_ssh_session_create(&session, s->io)) < 0) goto done; - if (t->owner->certificate_check_cb != NULL) { + if (t->owner->connect_opts.callbacks.certificate_check != NULL) { git_cert_hostkey cert = {{ 0 }}, *cert_ptr; const char *key; size_t cert_len; @@ -632,7 +636,11 @@ static int _git_ssh_setup_conn( cert_ptr = &cert; - error = t->owner->certificate_check_cb((git_cert *) cert_ptr, 0, urldata.host, t->owner->message_cb_payload); + error = t->owner->connect_opts.callbacks.certificate_check( + (git_cert *)cert_ptr, + 0, + urldata.host, + t->owner->connect_opts.callbacks.payload); if (error < 0 && error != GIT_PASSTHROUGH) { if (!git_error_last()) diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index 60f536fdb9f..9b5a67d3b47 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -293,14 +293,14 @@ static int certificate_check(winhttp_stream *s, int valid) git_cert_x509 cert; /* If there is no override, we should fail if WinHTTP doesn't think it's fine */ - if (t->owner->certificate_check_cb == NULL && !valid) { + if (t->owner->connect_opts.callbacks.certificate_check == NULL && !valid) { if (!git_error_last()) git_error_set(GIT_ERROR_HTTP, "unknown certificate check failure"); return GIT_ECERTIFICATE; } - if (t->owner->certificate_check_cb == NULL || git__strcmp(t->server.url.scheme, "https") != 0) + if (t->owner->connect_opts.callbacks.certificate_check == NULL || git__strcmp(t->server.url.scheme, "https") != 0) return 0; if (!WinHttpQueryOption(s->request, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert_ctx, &cert_ctx_size)) { @@ -312,7 +312,7 @@ static int certificate_check(winhttp_stream *s, int valid) cert.parent.cert_type = GIT_CERT_X509; cert.data = cert_ctx->pbCertEncoded; cert.len = cert_ctx->cbCertEncoded; - error = t->owner->certificate_check_cb((git_cert *) &cert, valid, t->server.url.host, t->owner->message_cb_payload); + error = t->owner->connect_opts.callbacks.certificate_check((git_cert *) &cert, valid, t->server.url.host, t->owner->connect_opts.callbacks.payload); CertFreeCertificateContext(cert_ctx); if (error == GIT_PASSTHROUGH) @@ -426,7 +426,7 @@ static int winhttp_stream_connect(winhttp_stream *s) goto on_error; } - proxy_opts = &t->owner->proxy; + proxy_opts = &t->owner->connect_opts.proxy_opts; if (proxy_opts->type == GIT_PROXY_AUTO) { /* Set proxy if necessary */ if (git_remote__http_proxy(&proxy_url, t->owner->owner, &t->server.url) < 0) @@ -560,10 +560,10 @@ static int winhttp_stream_connect(winhttp_stream *s) } } - for (i = 0; i < t->owner->custom_headers.count; i++) { - if (t->owner->custom_headers.strings[i]) { + for (i = 0; i < t->owner->connect_opts.custom_headers.count; i++) { + if (t->owner->connect_opts.custom_headers.strings[i]) { git_str_clear(&buf); - git_str_puts(&buf, t->owner->custom_headers.strings[i]); + git_str_puts(&buf, t->owner->connect_opts.custom_headers.strings[i]); if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_str_cstr(&buf)) < 0) { git_error_set(GIT_ERROR_OS, "failed to convert custom header to wide characters"); goto on_error; @@ -577,14 +577,6 @@ static int winhttp_stream_connect(winhttp_stream *s) } } - /* If requested, disable certificate validation */ - if (strcmp(t->server.url.scheme, "https") == 0) { - int flags; - - if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0) - goto on_error; - } - if ((error = apply_credentials(s->request, &t->server.url, WINHTTP_AUTH_TARGET_SERVER, t->server.cred, t->server.auth_mechanisms)) < 0) goto on_error; @@ -1218,8 +1210,8 @@ static int winhttp_stream_read( int error = acquire_credentials(s->request, &t->server, t->owner->url, - t->owner->cred_acquire_cb, - t->owner->cred_acquire_payload); + t->owner->connect_opts.callbacks.credentials, + t->owner->connect_opts.callbacks.payload); if (error < 0) { return error; @@ -1231,9 +1223,9 @@ static int winhttp_stream_read( } else if (status_code == HTTP_STATUS_PROXY_AUTH_REQ) { int error = acquire_credentials(s->request, &t->proxy, - t->owner->proxy.url, - t->owner->proxy.credentials, - t->owner->proxy.payload); + t->owner->connect_opts.proxy_opts.url, + t->owner->connect_opts.proxy_opts.credentials, + t->owner->connect_opts.proxy_opts.payload); if (error < 0) { return error; From f8b26df34fa804a6495012384e3bdab1f5223d9a Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Fri, 26 Nov 2021 12:50:40 +0100 Subject: [PATCH 0700/1616] Add `git_apply_options_init` documentation --- include/git2/apply.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/git2/apply.h b/include/git2/apply.h index 814bc8f166c..0aa2b24e637 100644 --- a/include/git2/apply.h +++ b/include/git2/apply.h @@ -89,6 +89,16 @@ typedef struct { #define GIT_APPLY_OPTIONS_VERSION 1 #define GIT_APPLY_OPTIONS_INIT {GIT_APPLY_OPTIONS_VERSION} +/** + * Initialize git_apply_options structure + * + * Initialize a `git_apply_options` with default values. Equivalent to creating + * an instance with GIT_APPLY_OPTIONS_INIT. + * + * @param opts The `git_apply_options` struct to initialize. + * @param version The struct version; pass `GIT_APPLY_OPTIONS_VERSION` + * @return 0 on success or -1 on failure. + */ GIT_EXTERN(int) git_apply_options_init(git_apply_options *opts, unsigned int version); /** From 03aed8bca7473c51148e5fdf8a258bc57f452a85 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Fri, 26 Nov 2021 14:57:41 +0100 Subject: [PATCH 0701/1616] Add missing parameter name --- include/git2/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/config.h b/include/git2/config.h index cad01ea4974..202d36a7e3f 100644 --- a/include/git2/config.h +++ b/include/git2/config.h @@ -73,7 +73,7 @@ typedef struct git_config_entry { /** * Free a config entry */ -GIT_EXTERN(void) git_config_entry_free(git_config_entry *); +GIT_EXTERN(void) git_config_entry_free(git_config_entry *entry); /** * A config enumeration callback From 68bc511abb8574b843209685e0f05a88856d7ecf Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Fri, 26 Nov 2021 15:14:56 +0100 Subject: [PATCH 0702/1616] Add documentation about parameter and return value --- include/git2/apply.h | 4 ++++ include/git2/attr.h | 9 +++++++++ include/git2/blame.h | 3 +++ include/git2/blob.h | 1 + include/git2/branch.h | 2 ++ include/git2/commit.h | 2 ++ include/git2/config.h | 16 ++++++++++++++++ include/git2/credential.h | 1 + include/git2/credential_helpers.h | 1 + include/git2/describe.h | 5 +++++ include/git2/diff.h | 7 +++++++ include/git2/filter.h | 5 +++++ include/git2/graph.h | 1 + include/git2/index.h | 3 +++ include/git2/indexer.h | 6 ++++++ include/git2/merge.h | 2 ++ include/git2/message.h | 2 ++ include/git2/object.h | 1 + include/git2/odb.h | 7 +++++++ include/git2/pack.h | 2 ++ include/git2/patch.h | 8 ++++++++ include/git2/rebase.h | 8 ++++++++ include/git2/refdb.h | 3 +++ include/git2/remote.h | 3 +++ include/git2/repository.h | 5 +++++ include/git2/revwalk.h | 3 +++ include/git2/submodule.h | 5 +++++ include/git2/tag.h | 1 + include/git2/tree.h | 1 + include/git2/worktree.h | 5 +++++ 30 files changed, 122 insertions(+) diff --git a/include/git2/apply.h b/include/git2/apply.h index 0aa2b24e637..db652bde0b3 100644 --- a/include/git2/apply.h +++ b/include/git2/apply.h @@ -32,6 +32,8 @@ GIT_BEGIN_DECL * * @param delta The delta to be applied * @param payload User-specified payload + * @return 0 if the delta is applied, < 0 if the apply process will be aborted + * or > 0 if the delta will not be applied. */ typedef int GIT_CALLBACK(git_apply_delta_cb)( const git_diff_delta *delta, @@ -48,6 +50,8 @@ typedef int GIT_CALLBACK(git_apply_delta_cb)( * * @param hunk The hunk to be applied * @param payload User-specified payload + * @return 0 if the hunk is applied, < 0 if the apply process will be aborted + * or > 0 if the hunk will not be applied. */ typedef int GIT_CALLBACK(git_apply_hunk_cb)( const git_diff_hunk *hunk, diff --git a/include/git2/attr.h b/include/git2/attr.h index 157192c9d7b..c93055083b0 100644 --- a/include/git2/attr.h +++ b/include/git2/attr.h @@ -177,6 +177,7 @@ typedef struct { * not have to exist, but if it does not, then it will be * treated as a plain file (not a directory). * @param name The name of the attribute to look up. + * @return 0 or an error code. */ GIT_EXTERN(int) git_attr_get( const char **value_out, @@ -199,6 +200,7 @@ GIT_EXTERN(int) git_attr_get( * not have to exist, but if it does not, then it will be * treated as a plain file (not a directory). * @param name The name of the attribute to look up. + * @return 0 or an error code. */ GIT_EXTERN(int) git_attr_get_ext( const char **value_out, @@ -235,6 +237,7 @@ GIT_EXTERN(int) git_attr_get_ext( * it will be treated as a plain file (i.e. not a directory). * @param num_attr The number of attributes being looked up * @param names An array of num_attr strings containing attribute names. + * @return 0 or an error code. */ GIT_EXTERN(int) git_attr_get_many( const char **values_out, @@ -259,6 +262,7 @@ GIT_EXTERN(int) git_attr_get_many( * it will be treated as a plain file (i.e. not a directory). * @param num_attr The number of attributes being looked up * @param names An array of num_attr strings containing attribute names. + * @return 0 or an error code. */ GIT_EXTERN(int) git_attr_get_many_ext( const char **values_out, @@ -349,6 +353,11 @@ GIT_EXTERN(int) git_attr_cache_flush( * macro, you would call: * * git_attr_add_macro(repo, "binary", "-diff -crlf"); + * + * @param repo The repository where to add the macro. + * @param name The name of the macro. + * @param values The value for the macro. + * @return 0 or an error code. */ GIT_EXTERN(int) git_attr_add_macro( git_repository *repo, diff --git a/include/git2/blame.h b/include/git2/blame.h index 33a9fbc98d9..cb961a56209 100644 --- a/include/git2/blame.h +++ b/include/git2/blame.h @@ -203,6 +203,9 @@ typedef struct git_blame git_blame; /** * Gets the number of hunks that exist in the blame structure. + * + * @param blame The blame structure to query. + * @return The number of hunks. */ GIT_EXTERN(uint32_t) git_blame_get_hunk_count(git_blame *blame); diff --git a/include/git2/blob.h b/include/git2/blob.h index 59fac9e2061..6db85f38d1b 100644 --- a/include/git2/blob.h +++ b/include/git2/blob.h @@ -302,6 +302,7 @@ GIT_EXTERN(int) git_blob_data_is_binary(const char *data, size_t len); * * @param out Pointer to store the copy of the object * @param source Original object to copy + * @return 0. */ GIT_EXTERN(int) git_blob_dup(git_blob **out, git_blob *source); diff --git a/include/git2/branch.h b/include/git2/branch.h index 24ea7f7d0f3..071622d8337 100644 --- a/include/git2/branch.h +++ b/include/git2/branch.h @@ -34,6 +34,8 @@ GIT_BEGIN_DECL * * @param out Pointer where to store the underlying reference. * + * @param repository the repository where to create the branch. + * * @param branch_name Name for the branch; this name is * validated for consistency. It should also not conflict with * an already existing branch name. diff --git a/include/git2/commit.h b/include/git2/commit.h index 4d74b8994fc..29e7271ea9b 100644 --- a/include/git2/commit.h +++ b/include/git2/commit.h @@ -479,6 +479,7 @@ GIT_EXTERN(int) git_commit_create_buffer( * to the commit and write it into the given repository. * * @param out the resulting commit id + * @param repository the repository where to create the commit. * @param commit_content the content of the unsigned commit object * @param signature the signature to add to the commit. Leave `NULL` * to create a commit without adding a signature field. @@ -499,6 +500,7 @@ GIT_EXTERN(int) git_commit_create_with_signature( * * @param out Pointer to store the copy of the commit * @param source Original commit to copy + * @return 0 */ GIT_EXTERN(int) git_commit_dup(git_commit **out, git_commit *source); diff --git a/include/git2/config.h b/include/git2/config.h index 202d36a7e3f..b3eccbb1757 100644 --- a/include/git2/config.h +++ b/include/git2/config.h @@ -72,6 +72,8 @@ typedef struct git_config_entry { /** * Free a config entry + * + * @param entry The entry to free. */ GIT_EXTERN(void) git_config_entry_free(git_config_entry *entry); @@ -80,6 +82,7 @@ GIT_EXTERN(void) git_config_entry_free(git_config_entry *entry); * * @param entry the entry currently being enumerated * @param payload a user-specified pointer + * @return non-zero to terminate the iteration. */ typedef int GIT_CALLBACK(git_config_foreach_cb)(const git_config_entry *entry, void *payload); @@ -269,6 +272,7 @@ GIT_EXTERN(int) git_config_open_level( * * @param out pointer in which to store the config object * @param config the config object in which to look + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_open_global(git_config **out, git_config *config); @@ -422,6 +426,7 @@ GIT_EXTERN(int) git_config_get_string_buf(git_buf *out, const git_config *cfg, c * interested in. Use NULL to indicate all * @param callback the function to be called on each value of the variable * @param payload opaque pointer to pass to the callback + * @return non-zero to terminate the iteration. */ GIT_EXTERN(int) git_config_get_multivar_foreach(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload); @@ -437,6 +442,7 @@ GIT_EXTERN(int) git_config_get_multivar_foreach(const git_config *cfg, const cha * @param name the variable's name * @param regexp regular expression to filter which variables we're * interested in. Use NULL to indicate all + * @return non-zero to terminate the iteration. */ GIT_EXTERN(int) git_config_multivar_iterator_new(git_config_iterator **out, const git_config *cfg, const char *name, const char *regexp); @@ -515,6 +521,7 @@ GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const c * @param name the variable's name * @param regexp a regular expression to indicate which values to replace * @param value the new value. + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value); @@ -524,6 +531,7 @@ GIT_EXTERN(int) git_config_set_multivar(git_config *cfg, const char *name, const * * @param cfg the configuration * @param name the variable to delete + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_delete_entry(git_config *cfg, const char *name); @@ -569,6 +577,7 @@ GIT_EXTERN(int) git_config_foreach( * * @param out pointer to store the iterator * @param cfg where to ge the variables from + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_iterator_new(git_config_iterator **out, const git_config *cfg); @@ -585,6 +594,7 @@ GIT_EXTERN(int) git_config_iterator_new(git_config_iterator **out, const git_con * @param out pointer to store the iterator * @param cfg where to ge the variables from * @param regexp regular expression to match the names + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_iterator_glob_new(git_config_iterator **out, const git_config *cfg, const char *regexp); @@ -662,6 +672,7 @@ GIT_EXTERN(int) git_config_get_mapped( * @param maps array of `git_configmap` objects specifying the possible mappings * @param map_n number of mapping objects in `maps` * @param value value to parse + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_lookup_map_value( int *out, @@ -678,6 +689,7 @@ GIT_EXTERN(int) git_config_lookup_map_value( * * @param out place to store the result of the parsing * @param value value to parse + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_parse_bool(int *out, const char *value); @@ -690,6 +702,7 @@ GIT_EXTERN(int) git_config_parse_bool(int *out, const char *value); * * @param out place to store the result of the parsing * @param value value to parse + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_parse_int32(int32_t *out, const char *value); @@ -702,6 +715,7 @@ GIT_EXTERN(int) git_config_parse_int32(int32_t *out, const char *value); * * @param out place to store the result of the parsing * @param value value to parse + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value); @@ -717,6 +731,7 @@ GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value); * * @param out placae to store the result of parsing * @param value the path to evaluate + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_parse_path(git_buf *out, const char *value); @@ -735,6 +750,7 @@ GIT_EXTERN(int) git_config_parse_path(git_buf *out, const char *value); * @param regexp regular expression to match against config names (can be NULL) * @param callback the function to call on each variable * @param payload the data to pass to the callback + * @return non-zero to terminate the iteration. */ GIT_EXTERN(int) git_config_backend_foreach_match( git_config_backend *backend, diff --git a/include/git2/credential.h b/include/git2/credential.h index a4e68e85382..7a04bc06479 100644 --- a/include/git2/credential.h +++ b/include/git2/credential.h @@ -254,6 +254,7 @@ typedef void GIT_CALLBACK(git_credential_ssh_interactive_cb)( * Create a new ssh keyboard-interactive based credential object. * The supplied credential parameter will be internally duplicated. * + * @param out The newly created credential object. * @param username Username to use to authenticate. * @param prompt_callback The callback method used for prompts. * @param payload Additional data to pass to the callback. diff --git a/include/git2/credential_helpers.h b/include/git2/credential_helpers.h index 9a70ecb3856..f0fb07041d9 100644 --- a/include/git2/credential_helpers.h +++ b/include/git2/credential_helpers.h @@ -39,6 +39,7 @@ typedef struct git_credential_userpass_payload { * @param allowed_types A bitmask stating which credential types are OK to return. * @param payload The payload provided when specifying this callback. (This is * interpreted as a `git_credential_userpass_payload*`.) + * @return 0 or an error code. */ GIT_EXTERN(int) git_credential_userpass( git_credential **out, diff --git a/include/git2/describe.h b/include/git2/describe.h index e8afd687972..8392ee86e36 100644 --- a/include/git2/describe.h +++ b/include/git2/describe.h @@ -142,6 +142,7 @@ typedef struct git_describe_result git_describe_result; * you're done with it. * @param committish a committish to describe * @param opts the lookup options (or NULL for defaults) + * @return 0 or an error code. */ GIT_EXTERN(int) git_describe_commit( git_describe_result **result, @@ -159,6 +160,7 @@ GIT_EXTERN(int) git_describe_commit( * you're done with it. * @param repo the repository in which to perform the describe * @param opts the lookup options (or NULL for defaults) + * @return 0 or an error code. */ GIT_EXTERN(int) git_describe_workdir( git_describe_result **out, @@ -172,6 +174,7 @@ GIT_EXTERN(int) git_describe_workdir( * @param result the result from `git_describe_commit()` or * `git_describe_workdir()`. * @param opts the formatting options (or NULL for defaults) + * @return 0 or an error code. */ GIT_EXTERN(int) git_describe_format( git_buf *out, @@ -180,6 +183,8 @@ GIT_EXTERN(int) git_describe_format( /** * Free the describe result. + * + * @param result The result to free. */ GIT_EXTERN(void) git_describe_result_free(git_describe_result *result); diff --git a/include/git2/diff.h b/include/git2/diff.h index c040cd19053..b847c15d226 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -831,6 +831,7 @@ GIT_EXTERN(void) git_diff_free(git_diff *diff); * @param old_tree A git_tree object to diff from, or NULL for empty tree. * @param new_tree A git_tree object to diff to, or NULL for empty tree. * @param opts Structure with options to influence diff or NULL for defaults. + * @return 0 or an error code. */ GIT_EXTERN(int) git_diff_tree_to_tree( git_diff **diff, @@ -857,6 +858,7 @@ GIT_EXTERN(int) git_diff_tree_to_tree( * @param old_tree A git_tree object to diff from, or NULL for empty tree. * @param index The index to diff with; repo index used if NULL. * @param opts Structure with options to influence diff or NULL for defaults. + * @return 0 or an error code. */ GIT_EXTERN(int) git_diff_tree_to_index( git_diff **diff, @@ -884,6 +886,7 @@ GIT_EXTERN(int) git_diff_tree_to_index( * @param repo The repository. * @param index The index to diff from; repo index used if NULL. * @param opts Structure with options to influence diff or NULL for defaults. + * @return 0 or an error code. */ GIT_EXTERN(int) git_diff_index_to_workdir( git_diff **diff, @@ -913,6 +916,7 @@ GIT_EXTERN(int) git_diff_index_to_workdir( * @param repo The repository containing the tree. * @param old_tree A git_tree object to diff from, or NULL for empty tree. * @param opts Structure with options to influence diff or NULL for defaults. + * @return 0 or an error code. */ GIT_EXTERN(int) git_diff_tree_to_workdir( git_diff **diff, @@ -932,6 +936,7 @@ GIT_EXTERN(int) git_diff_tree_to_workdir( * @param repo The repository containing the tree. * @param old_tree A git_tree object to diff from, or NULL for empty tree. * @param opts Structure with options to influence diff or NULL for defaults. + * @return 0 or an error code. */ GIT_EXTERN(int) git_diff_tree_to_workdir_with_index( git_diff **diff, @@ -950,6 +955,7 @@ GIT_EXTERN(int) git_diff_tree_to_workdir_with_index( * @param old_index A git_index object to diff from. * @param new_index A git_index object to diff to. * @param opts Structure with options to influence diff or NULL for defaults. + * @return 0 or an error code. */ GIT_EXTERN(int) git_diff_index_to_index( git_diff **diff, @@ -970,6 +976,7 @@ GIT_EXTERN(int) git_diff_index_to_index( * * @param onto Diff to merge into. * @param from Diff to merge. + * @return 0 or an error code. */ GIT_EXTERN(int) git_diff_merge( git_diff *onto, diff --git a/include/git2/filter.h b/include/git2/filter.h index 632bb84e316..79bf14ce5b7 100644 --- a/include/git2/filter.h +++ b/include/git2/filter.h @@ -196,6 +196,7 @@ GIT_EXTERN(int) git_filter_list_apply_to_buffer( * @param repo the repository in which to perform the filtering * @param path the path of the file to filter, a relative path will be * taken as relative to the workdir + * @return 0 or an error code. */ GIT_EXTERN(int) git_filter_list_apply_to_file( git_buf *out, @@ -209,6 +210,7 @@ GIT_EXTERN(int) git_filter_list_apply_to_file( * @param out buffer into which to store the filtered file * @param filters the list of filters to apply * @param blob the blob to filter + * @return 0 or an error code. */ GIT_EXTERN(int) git_filter_list_apply_to_blob( git_buf *out, @@ -222,6 +224,7 @@ GIT_EXTERN(int) git_filter_list_apply_to_blob( * @param buffer the buffer to filter * @param len the size of the buffer * @param target the stream into which the data will be written + * @return 0 or an error code. */ GIT_EXTERN(int) git_filter_list_stream_buffer( git_filter_list *filters, @@ -237,6 +240,7 @@ GIT_EXTERN(int) git_filter_list_stream_buffer( * @param path the path of the file to filter, a relative path will be * taken as relative to the workdir * @param target the stream into which the data will be written + * @return 0 or an error code. */ GIT_EXTERN(int) git_filter_list_stream_file( git_filter_list *filters, @@ -250,6 +254,7 @@ GIT_EXTERN(int) git_filter_list_stream_file( * @param filters the list of filters to apply * @param blob the blob to filter * @param target the stream into which the data will be written + * @return 0 or an error code. */ GIT_EXTERN(int) git_filter_list_stream_blob( git_filter_list *filters, diff --git a/include/git2/graph.h b/include/git2/graph.h index 712ae474a06..56edb2f87f9 100644 --- a/include/git2/graph.h +++ b/include/git2/graph.h @@ -33,6 +33,7 @@ GIT_BEGIN_DECL * @param repo the repository where the commits exist * @param local the commit for local * @param upstream the commit for upstream + * @return 0 or an error code. */ GIT_EXTERN(int) git_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo, const git_oid *local, const git_oid *upstream); diff --git a/include/git2/index.h b/include/git2/index.h index 5864791e6f8..3cf64d827bb 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -491,6 +491,7 @@ GIT_EXTERN(int) git_index_entry_is_conflict(const git_index_entry *entry); * * @param iterator_out The newly created iterator * @param index The index to iterate + * @return 0 or an error code. */ GIT_EXTERN(int) git_index_iterator_new( git_index_iterator **iterator_out, @@ -787,6 +788,7 @@ GIT_EXTERN(int) git_index_conflict_cleanup(git_index *index); /** * Determine if the index contains entries representing file conflicts. * + * @param index An existing index object. * @return 1 if at least one conflict is found, 0 otherwise. */ GIT_EXTERN(int) git_index_has_conflicts(const git_index *index); @@ -811,6 +813,7 @@ GIT_EXTERN(int) git_index_conflict_iterator_new( * @param ancestor_out Pointer to store the ancestor side of the conflict * @param our_out Pointer to store our side of the conflict * @param their_out Pointer to store their side of the conflict + * @param iterator The conflict iterator. * @return 0 (no error), GIT_ITEROVER (iteration is done) or an error code * (negative value) */ diff --git a/include/git2/indexer.h b/include/git2/indexer.h index a434d243f26..8af02a6c03f 100644 --- a/include/git2/indexer.h +++ b/include/git2/indexer.h @@ -98,6 +98,7 @@ GIT_EXTERN(int) git_indexer_options_init( * will be returned if there are bases missing) * @param opts Optional structure containing additional options. See * `git_indexer_options` above. + * @return 0 or an error code. */ GIT_EXTERN(int) git_indexer_new( git_indexer **out, @@ -113,6 +114,7 @@ GIT_EXTERN(int) git_indexer_new( * @param data the data to add * @param size the size of the data in bytes * @param stats stat storage + * @return 0 or an error code. */ GIT_EXTERN(int) git_indexer_append(git_indexer *idx, const void *data, size_t size, git_indexer_progress *stats); @@ -122,6 +124,8 @@ GIT_EXTERN(int) git_indexer_append(git_indexer *idx, const void *data, size_t si * Resolve any pending deltas and write out the index file * * @param idx the indexer + * @param stats Stat storage. + * @return 0 or an error code. */ GIT_EXTERN(int) git_indexer_commit(git_indexer *idx, git_indexer_progress *stats); @@ -132,6 +136,8 @@ GIT_EXTERN(int) git_indexer_commit(git_indexer *idx, git_indexer_progress *stats * names. This is only correct after the index has been finalized. * * @param idx the indexer instance + * @return the packfile's hash. In casewhere the index has not been finalized, + * it will be zeroed out. */ GIT_EXTERN(const git_oid *) git_indexer_hash(const git_indexer *idx); diff --git a/include/git2/merge.h b/include/git2/merge.h index e32c53fcc03..3b3132f26a8 100644 --- a/include/git2/merge.h +++ b/include/git2/merge.h @@ -372,6 +372,7 @@ typedef enum { * merging them into the HEAD of the repository. * * @param analysis_out analysis enumeration that the result is written into + * @param preference_out One of the `git_merge_preference_t` flag. * @param repo the repository to merge * @param their_heads the heads to merge into * @param their_heads_len the number of heads to merge @@ -389,6 +390,7 @@ GIT_EXTERN(int) git_merge_analysis( * merging them into a reference. * * @param analysis_out analysis enumeration that the result is written into + * @param preference_out One of the `git_merge_preference_t` flag. * @param repo the repository to merge * @param our_ref the reference to perform the analysis from * @param their_heads the heads to merge into diff --git a/include/git2/message.h b/include/git2/message.h index 42ca3e5c291..cd3ddf730e0 100644 --- a/include/git2/message.h +++ b/include/git2/message.h @@ -75,6 +75,8 @@ GIT_EXTERN(int) git_message_trailers(git_message_trailer_array *arr, const char /** * Clean's up any allocated memory in the git_message_trailer_array filled by * a call to git_message_trailers. + * + * @param arr The trailer to free. */ GIT_EXTERN(void) git_message_trailer_array_free(git_message_trailer_array *arr); diff --git a/include/git2/object.h b/include/git2/object.h index dbf480ed6be..2692a405645 100644 --- a/include/git2/object.h +++ b/include/git2/object.h @@ -221,6 +221,7 @@ GIT_EXTERN(int) git_object_peel( * * @param dest Pointer to store the copy of the object * @param source Original object to copy + * @return 0 */ GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source); diff --git a/include/git2/odb.h b/include/git2/odb.h index 0691aa4d075..c7c3a88a520 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -345,6 +345,11 @@ GIT_EXTERN(int) git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stre * Read from an odb stream * * Most backends don't implement streaming reads + * + * @param stream the stream + * @param buffer the buffer where to store the readed data. + * @param len the buffer's length + * @return 0 if the read succeeded, error code otherwise */ GIT_EXTERN(int) git_odb_stream_read(git_odb_stream *stream, char *buffer, size_t len); @@ -405,6 +410,7 @@ GIT_EXTERN(int) git_odb_open_rstream( * Be aware that this is called inline with network and indexing operations, * so performance may be affected. * @param progress_payload payload for the progress callback + * @return 0 or an error code. */ GIT_EXTERN(int) git_odb_write_pack( git_odb_writepack **out, @@ -422,6 +428,7 @@ GIT_EXTERN(int) git_odb_write_pack( * exist). * * @param db object database where the `multi-pack-index` file will be written. + * @return 0 or an error code. */ GIT_EXTERN(int) git_odb_write_multi_pack_index( git_odb *db); diff --git a/include/git2/pack.h b/include/git2/pack.h index cd28a4f5b73..253a860cd3b 100644 --- a/include/git2/pack.h +++ b/include/git2/pack.h @@ -148,6 +148,7 @@ GIT_EXTERN(int) git_packbuilder_insert_recur(git_packbuilder *pb, const git_oid * * @param buf Buffer where to write the packfile * @param pb The packbuilder + * @return 0 or an error code */ GIT_EXTERN(int) git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb); @@ -176,6 +177,7 @@ GIT_EXTERN(int) git_packbuilder_write( * names. This is only correct after the packfile has been written. * * @param pb The packbuilder object + * @return 0 or an error code */ GIT_EXTERN(const git_oid *) git_packbuilder_hash(git_packbuilder *pb); diff --git a/include/git2/patch.h b/include/git2/patch.h index fde9659e713..9cf758a3edb 100644 --- a/include/git2/patch.h +++ b/include/git2/patch.h @@ -139,17 +139,25 @@ GIT_EXTERN(int) git_patch_from_buffers( /** * Free a git_patch object. + * + * @param patch The patch to free. */ GIT_EXTERN(void) git_patch_free(git_patch *patch); /** * Get the delta associated with a patch. This delta points to internal * data and you do not have to release it when you are done with it. + * + * @param patch The patch in which to get the delta. + * @return The delta associated with the patch. */ GIT_EXTERN(const git_diff_delta *) git_patch_get_delta(const git_patch *patch); /** * Get the number of hunks in a patch + * + * @param patch The patch in which to get the number of hunks. + * @return The number of hunks of the patch. */ GIT_EXTERN(size_t) git_patch_num_hunks(const git_patch *patch); diff --git a/include/git2/rebase.h b/include/git2/rebase.h index 2a5dece7c89..5edd443d1f8 100644 --- a/include/git2/rebase.h +++ b/include/git2/rebase.h @@ -242,6 +242,7 @@ GIT_EXTERN(int) git_rebase_open( /** * Gets the original `HEAD` ref name for merge rebases. * + * @param rebase The in-progress rebase. * @return The original `HEAD` ref name */ GIT_EXTERN(const char *) git_rebase_orig_head_name(git_rebase *rebase); @@ -249,6 +250,7 @@ GIT_EXTERN(const char *) git_rebase_orig_head_name(git_rebase *rebase); /** * Gets the original `HEAD` id for merge rebases. * + * @param rebase The in-progress rebase. * @return The original `HEAD` id */ GIT_EXTERN(const git_oid *) git_rebase_orig_head_id(git_rebase *rebase); @@ -256,6 +258,7 @@ GIT_EXTERN(const git_oid *) git_rebase_orig_head_id(git_rebase *rebase); /** * Gets the `onto` ref name for merge rebases. * + * @param rebase The in-progress rebase. * @return The `onto` ref name */ GIT_EXTERN(const char *) git_rebase_onto_name(git_rebase *rebase); @@ -263,6 +266,7 @@ GIT_EXTERN(const char *) git_rebase_onto_name(git_rebase *rebase); /** * Gets the `onto` id for merge rebases. * + * @param rebase The in-progress rebase. * @return The `onto` id */ GIT_EXTERN(const git_oid *) git_rebase_onto_id(git_rebase *rebase); @@ -322,6 +326,10 @@ GIT_EXTERN(int) git_rebase_next( * This is only applicable for in-memory rebases; for rebases within * a working directory, the changes were applied to the repository's * index. + * + * @param index The result index of the last operation. + * @param rebase The in-progress rebase. + * @return 0 */ GIT_EXTERN(int) git_rebase_inmemory_index( git_index **index, diff --git a/include/git2/refdb.h b/include/git2/refdb.h index a315876aefd..c4849abdc4e 100644 --- a/include/git2/refdb.h +++ b/include/git2/refdb.h @@ -52,6 +52,9 @@ GIT_EXTERN(int) git_refdb_open(git_refdb **out, git_repository *repo); * Suggests that the given refdb compress or optimize its references. * This mechanism is implementation specific. For on-disk reference * databases, for example, this may pack all loose references. + * + * @param refdb The reference database to optimize. + * @return 0 or an error code. */ GIT_EXTERN(int) git_refdb_compress(git_refdb *refdb); diff --git a/include/git2/remote.h b/include/git2/remote.h index 088f528a6c6..0527fad3e80 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -300,6 +300,7 @@ GIT_EXTERN(int) git_remote_add_fetch(git_repository *repo, const char *remote, c * * @param array pointer to the array in which to store the strings * @param remote the remote to query + * @return 0 or an error code. */ GIT_EXTERN(int) git_remote_get_fetch_refspecs(git_strarray *array, const git_remote *remote); @@ -324,6 +325,7 @@ GIT_EXTERN(int) git_remote_add_push(git_repository *repo, const char *remote, co * * @param array pointer to the array in which to store the strings * @param remote the remote to query + * @return 0 or an error code. */ GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, const git_remote *remote); @@ -899,6 +901,7 @@ GIT_EXTERN(int) git_remote_prune(git_remote *remote, const git_remote_callbacks * @param refspecs the refspecs to use for pushing. If NULL or an empty * array, the configured refspecs will be used * @param opts options to use for this push + * @return 0 or an error code. */ GIT_EXTERN(int) git_remote_push(git_remote *remote, const git_strarray *refspecs, diff --git a/include/git2/repository.h b/include/git2/repository.h index 8bd877be42f..6692537d4e0 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -673,6 +673,9 @@ GIT_EXTERN(int) git_repository_message(git_buf *out, git_repository *repo); * Remove git's prepared message. * * Remove the message that `git_repository_message` retrieves. + * + * @param repo Repository to remove prepared message from. + * @return 0 or an error code. */ GIT_EXTERN(int) git_repository_message_remove(git_repository *repo); @@ -928,6 +931,7 @@ GIT_EXTERN(int) git_repository_is_shallow(git_repository *repo); * @param name where to store the pointer to the name * @param email where to store the pointer to the email * @param repo the repository + * @return 0 */ GIT_EXTERN(int) git_repository_ident(const char **name, const char **email, const git_repository *repo); @@ -941,6 +945,7 @@ GIT_EXTERN(int) git_repository_ident(const char **name, const char **email, cons * @param repo the repository to configure * @param name the name to use for the reflog entries * @param email the email to use for the reflog entries + * @return 0 or an error code. */ GIT_EXTERN(int) git_repository_set_ident(git_repository *repo, const char *name, const char *email); diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h index 241479d568e..b8655e50fef 100644 --- a/include/git2/revwalk.h +++ b/include/git2/revwalk.h @@ -249,6 +249,7 @@ GIT_EXTERN(int) git_revwalk_push_range(git_revwalk *walk, const char *range); * * No parents other than the first for each commit will be enqueued. * + * @param walk The revisionwlaker. * @return 0 or an error code */ GIT_EXTERN(int) git_revwalk_simplify_first_parent(git_revwalk *walk); @@ -277,6 +278,7 @@ GIT_EXTERN(git_repository *) git_revwalk_repository(git_revwalk *walk); * * @param commit_id oid of Commit * @param payload User-specified pointer to data to be passed as data payload + * @return non-zero to hide the commmit and it parrent. */ typedef int GIT_CALLBACK(git_revwalk_hide_cb)( const git_oid *commit_id, @@ -288,6 +290,7 @@ typedef int GIT_CALLBACK(git_revwalk_hide_cb)( * @param walk the revision walker * @param hide_cb callback function to hide a commit and its parents * @param payload data payload to be passed to callback function + * @return 0 or an error code. */ GIT_EXTERN(int) git_revwalk_add_hide_cb( git_revwalk *walk, diff --git a/include/git2/submodule.h b/include/git2/submodule.h index c6eeb96dc45..ed44e3dcf68 100644 --- a/include/git2/submodule.h +++ b/include/git2/submodule.h @@ -229,6 +229,7 @@ GIT_EXTERN(int) git_submodule_lookup( * * @param out Pointer to store the copy of the submodule. * @param source Original submodule to copy. + * @return 0 */ GIT_EXTERN(int) git_submodule_dup(git_submodule **out, git_submodule *source); @@ -320,6 +321,7 @@ GIT_EXTERN(int) git_submodule_clone( * (but doesn't actually do the commit). * * @param submodule The submodule to finish adding. + * @return 0 or an error code. */ GIT_EXTERN(int) git_submodule_add_finalize(git_submodule *submodule); @@ -589,6 +591,9 @@ GIT_EXTERN(int) git_submodule_repo_init( * submodule config, acting like "git submodule sync". This is useful if * you have altered the URL for the submodule (or it has been altered by a * fetch of upstream changes) and you need to update your local repo. + * + * @param submodule The submodule to copy. + * @return 0 or an error code. */ GIT_EXTERN(int) git_submodule_sync(git_submodule *submodule); diff --git a/include/git2/tag.h b/include/git2/tag.h index a3921369dad..98305365590 100644 --- a/include/git2/tag.h +++ b/include/git2/tag.h @@ -362,6 +362,7 @@ GIT_EXTERN(int) git_tag_peel( * * @param out Pointer to store the copy of the tag * @param source Original tag to copy + * @return 0 */ GIT_EXTERN(int) git_tag_dup(git_tag **out, git_tag *source); diff --git a/include/git2/tree.h b/include/git2/tree.h index db24bf6ed55..db7706eeda4 100644 --- a/include/git2/tree.h +++ b/include/git2/tree.h @@ -418,6 +418,7 @@ GIT_EXTERN(int) git_tree_walk( * * @param out Pointer to store the copy of the tree * @param source Original tree to copy + * @return 0 */ GIT_EXTERN(int) git_tree_dup(git_tree **out, git_tree *source); diff --git a/include/git2/worktree.h b/include/git2/worktree.h index 8691f96db12..bb024dc940e 100644 --- a/include/git2/worktree.h +++ b/include/git2/worktree.h @@ -52,6 +52,7 @@ GIT_EXTERN(int) git_worktree_lookup(git_worktree **out, git_repository *repo, co * * @param out Out-pointer for the newly allocated worktree * @param repo Repository to look up worktree for + * @return 0 or an error code */ GIT_EXTERN(int) git_worktree_open_from_repository(git_worktree **out, git_repository *repo); @@ -237,6 +238,10 @@ GIT_EXTERN(int) git_worktree_prune_options_init( * If the worktree is not valid and not locked or if the above * flags have been passed in, this function will return a * positive value. + * + * @param wt Worktree to check. + * @param opts The prunable options. + * @return 1 if the worktree is prunable, 0 otherwise, or an error code. */ GIT_EXTERN(int) git_worktree_is_prunable(git_worktree *wt, git_worktree_prune_options *opts); From 58ae4535b8d20cad7ec92698594f278c9e289745 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Sun, 9 Jan 2022 10:29:00 +0100 Subject: [PATCH 0703/1616] Document return value for git_libgit2_features --- include/git2/common.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/git2/common.h b/include/git2/common.h index d62d9be188d..c421d3cc1e6 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -167,6 +167,9 @@ typedef enum { * - GIT_FEATURE_SSH * Libgit2 supports the SSH protocol for network operations. This requires * the libssh2 library to be found when compiling libgit2 + * + * - GIT_FEATURE_NSEC + * Libgit2 supports the sub-second resolution in file modification times. */ GIT_EXTERN(int) git_libgit2_features(void); From c6ede676131851718fa96580247334e9db4bdb4b Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Sun, 9 Jan 2022 10:35:42 +0100 Subject: [PATCH 0704/1616] Fix misspelling word "ge" -> "get" --- include/git2/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/config.h b/include/git2/config.h index b3eccbb1757..07e0093b58f 100644 --- a/include/git2/config.h +++ b/include/git2/config.h @@ -576,7 +576,7 @@ GIT_EXTERN(int) git_config_foreach( * `git_config_iterator_free` when done. * * @param out pointer to store the iterator - * @param cfg where to ge the variables from + * @param cfg where to get the variables from * @return 0 or an error code. */ GIT_EXTERN(int) git_config_iterator_new(git_config_iterator **out, const git_config *cfg); From 5c8f7a99217cc74d0643f82774acff0aa5bbb610 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Sun, 9 Jan 2022 10:41:24 +0100 Subject: [PATCH 0705/1616] Rephrase param description --- include/git2/ignore.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/ignore.h b/include/git2/ignore.h index f5143f3ad27..4c441c63384 100644 --- a/include/git2/ignore.h +++ b/include/git2/ignore.h @@ -29,7 +29,7 @@ GIT_BEGIN_DECL * This would add three rules to the ignores. * * @param repo The repository to add ignore rules to. - * @param rules Text of rules, a la the contents of a .gitignore file. + * @param rules Text of rules, the contents to add on a .gitignore file. * It is okay to have multiple rules in the text; if so, * each rule should be terminated with a newline. * @return 0 on success From be320340edaaf6e065bd3b7de2791e2c01b222c4 Mon Sep 17 00:00:00 2001 From: Miguel Arroz <750683+arroz@users.noreply.github.com> Date: Sun, 9 Jan 2022 11:59:16 -0800 Subject: [PATCH 0706/1616] Introduced `LINK_WITH_STATIC_LIBRARIES` per PR comments. --- README.md | 2 ++ cmake/DefaultCFlags.cmake | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 66f98e2eedc..1074cd9a8da 100644 --- a/README.md +++ b/README.md @@ -301,6 +301,8 @@ compiler and linker. These flags are rarely used but can be useful for - `CMAKE_FIND_ROOT_PATH`: Override the search path for libraries - `ZLIB_LIBRARY`, `OPENSSL_SSL_LIBRARY` AND `OPENSSL_CRYPTO_LIBRARY`: Tell CMake where to find those specific libraries +- `LINK_WITH_STATIC_LIBRARIES`: Link only with static versions of +system libraries MacOS X ------- diff --git a/cmake/DefaultCFlags.cmake b/cmake/DefaultCFlags.cmake index ad3db0980af..a9c9ab9729c 100644 --- a/cmake/DefaultCFlags.cmake +++ b/cmake/DefaultCFlags.cmake @@ -92,7 +92,7 @@ else() set(CMAKE_C_ARCHIVE_FINISH " -D ") endif() - if(NOT APPLE AND NOT BUILD_SHARED_LIBS) + if(NOT BUILD_SHARED_LIBS AND LINK_WITH_STATIC_LIBRARIES) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") endif() From 4e93ecfa7a5626496cb357c9fe6f5f16f1bcac25 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Tue, 11 Jan 2022 15:06:00 +0100 Subject: [PATCH 0707/1616] Separate function description from short description --- include/git2/odb.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/git2/odb.h b/include/git2/odb.h index c7c3a88a520..7b8d6f96b94 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -214,12 +214,13 @@ typedef struct git_odb_expand_id { /** * Determine if one or more objects can be found in the object database - * by their abbreviated object ID and type. The given array will be - * updated in place: for each abbreviated ID that is unique in the - * database, and of the given type (if specified), the full object ID, - * object ID length (`GIT_OID_HEXSZ`) and type will be written back to - * the array. For IDs that are not found (or are ambiguous), the - * array entry will be zeroed. + * by their abbreviated object ID and type. + * + * The given array will be updated in place: for each abbreviated ID that is + * unique in the database, and of the given type (if specified), + * the full object ID, object ID length (`GIT_OID_HEXSZ`) and type will be + * written back to the array. For IDs that are not found (or are ambiguous), + * the array entry will be zeroed. * * Note that since this function operates on multiple objects, the * underlying database will not be asked to be reloaded if an object is From 7491b3fd5d2d358c148aea0ba1db5e91b7ca9974 Mon Sep 17 00:00:00 2001 From: punkymaniac Date: Wed, 12 Jan 2022 09:38:09 +0100 Subject: [PATCH 0708/1616] Set parameter name as function declaration --- include/git2/branch.h | 2 +- include/git2/commit.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/git2/branch.h b/include/git2/branch.h index 071622d8337..d33a24f72ce 100644 --- a/include/git2/branch.h +++ b/include/git2/branch.h @@ -34,7 +34,7 @@ GIT_BEGIN_DECL * * @param out Pointer where to store the underlying reference. * - * @param repository the repository where to create the branch. + * @param repo the repository where to create the branch. * * @param branch_name Name for the branch; this name is * validated for consistency. It should also not conflict with diff --git a/include/git2/commit.h b/include/git2/commit.h index 29e7271ea9b..2181a7d7efa 100644 --- a/include/git2/commit.h +++ b/include/git2/commit.h @@ -479,7 +479,7 @@ GIT_EXTERN(int) git_commit_create_buffer( * to the commit and write it into the given repository. * * @param out the resulting commit id - * @param repository the repository where to create the commit. + * @param repo the repository where to create the commit. * @param commit_content the content of the unsigned commit object * @param signature the signature to add to the commit. Leave `NULL` * to create a commit without adding a signature field. From cd261af21868aed552e3e4277868441d10ac46e1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 18 Dec 2021 07:42:44 -0500 Subject: [PATCH 0709/1616] ci: use poxygit v0.5.1 The new version of our test git server adds redirect support. Upgrade to it. --- ci/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/test.sh b/ci/test.sh index 4d6c41f7675..e8c111dda43 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -102,7 +102,7 @@ if [ -z "$SKIP_PROXY_TESTS" ]; then fi if [ -z "$SKIP_NTLM_TESTS" ]; then - curl --location --silent --show-error https://github.com/ethomson/poxygit/releases/download/v0.4.0/poxygit-0.4.0.jar >poxygit.jar + curl --location --silent --show-error https://github.com/ethomson/poxygit/releases/download/v0.5.1/poxygit-0.5.1.jar >poxygit.jar echo "" echo "Starting HTTP server..." From c104a56536fa7bac0c1d0702623ebbc769babd03 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 6 Jan 2022 07:56:32 -0500 Subject: [PATCH 0710/1616] ci: stop retrying "flaky" tests We (thankfully) don't have flaky tests anymore, don't retry them. --- ci/test.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ci/test.sh b/ci/test.sh index e8c111dda43..bcbda902af3 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -188,9 +188,7 @@ if [ -z "$SKIP_ONLINE_TESTS" ]; then echo "## Running (online) tests" echo "##############################################################################" - export GITTEST_FLAKY_RETRY=5 run_test online - unset GITTEST_FLAKY_RETRY # Run the online tests that immutably change global state separately # to avoid polluting the test environment. @@ -231,9 +229,7 @@ if [ -z "$SKIP_PROXY_TESTS" ]; then export GITTEST_REMOTE_PROXY_HOST="localhost:8090" export GITTEST_REMOTE_PROXY_USER="foo" export GITTEST_REMOTE_PROXY_PASS="bar" - export GITTEST_FLAKY_RETRY=5 run_test proxy - unset GITTEST_FLAKY_RETRY unset GITTEST_REMOTE_PROXY_HOST unset GITTEST_REMOTE_PROXY_USER unset GITTEST_REMOTE_PROXY_PASS From 342e55ac9104346d925154b5d472cf5f58668f0d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 18 Dec 2021 10:13:18 -0500 Subject: [PATCH 0711/1616] url: optionally allow off-site redirects In redirect application logic, (optionally) allow off-site redirects. --- src/net.c | 6 ++-- src/net.h | 1 + src/transports/http.c | 2 +- src/transports/winhttp.c | 2 +- tests/network/url/redirect.c | 62 +++++++++++++++++++++++------------- 5 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/net.c b/src/net.c index a91e7460ec0..79c3fcd2874 100644 --- a/src/net.c +++ b/src/net.c @@ -315,6 +315,7 @@ static void remove_service_suffix( int git_net_url_apply_redirect( git_net_url *url, const char *redirect_location, + bool allow_offsite, const char *service_suffix) { git_net_url tmp = GIT_NET_URL_INIT; @@ -339,8 +340,8 @@ int git_net_url_apply_redirect( /* Validate that this is a legal redirection */ if (original->scheme && - strcmp(original->scheme, tmp.scheme) != 0 && - strcmp(tmp.scheme, "https") != 0) { + strcmp(original->scheme, tmp.scheme) != 0 && + strcmp(tmp.scheme, "https") != 0) { git_error_set(GIT_ERROR_NET, "cannot redirect from '%s' to '%s'", original->scheme, tmp.scheme); @@ -349,6 +350,7 @@ int git_net_url_apply_redirect( } if (original->host && + !allow_offsite && git__strcasecmp(original->host, tmp.host) != 0) { git_error_set(GIT_ERROR_NET, "cannot redirect from '%s' to '%s'", original->host, tmp.host); diff --git a/src/net.h b/src/net.h index 728add3d0ed..c743974097e 100644 --- a/src/net.h +++ b/src/net.h @@ -46,6 +46,7 @@ extern bool git_net_url_is_ipv6(git_net_url *url); extern int git_net_url_apply_redirect( git_net_url *url, const char *redirect_location, + bool allow_offsite, const char *service_suffix); /** Swaps the contents of one URL for another. */ diff --git a/src/transports/http.c b/src/transports/http.c index fa576ff3e97..6a17fa9abfc 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -233,7 +233,7 @@ static int handle_response( return -1; } - if (git_net_url_apply_redirect(&transport->server.url, response->location, stream->service->url) < 0) { + if (git_net_url_apply_redirect(&transport->server.url, response->location, false, stream->service->url) < 0) { return -1; } diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index 9b5a67d3b47..fdc6cf223b5 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -1190,7 +1190,7 @@ static int winhttp_stream_read( if (!git__prefixcmp_icase(location8, prefix_https)) { /* Upgrade to secure connection; disconnect and start over */ - if (git_net_url_apply_redirect(&t->server.url, location8, s->service_url) < 0) { + if (git_net_url_apply_redirect(&t->server.url, location8, false, s->service_url) < 0) { git__free(location8); return -1; } diff --git a/tests/network/url/redirect.c b/tests/network/url/redirect.c index 2c0b614d995..a94db7daf1e 100644 --- a/tests/network/url/redirect.c +++ b/tests/network/url/redirect.c @@ -17,9 +17,9 @@ void test_network_url_redirect__cleanup(void) void test_network_url_redirect__redirect_http(void) { cl_git_pass(git_net_url_parse(&conndata, - "http://example.com/foo/bar/baz")); + "http://example.com/foo/bar/baz")); cl_git_pass(git_net_url_apply_redirect(&conndata, - "http://example.com/foo/bar/baz", "bar/baz")); + "http://example.com/foo/bar/baz", false, "bar/baz")); cl_assert_equal_s(conndata.scheme, "http"); cl_assert_equal_s(conndata.host, "example.com"); cl_assert_equal_s(conndata.port, "80"); @@ -31,9 +31,9 @@ void test_network_url_redirect__redirect_http(void) void test_network_url_redirect__redirect_ssl(void) { cl_git_pass(git_net_url_parse(&conndata, - "https://example.com/foo/bar/baz")); + "https://example.com/foo/bar/baz")); cl_git_pass(git_net_url_apply_redirect(&conndata, - "https://example.com/foo/bar/baz", "bar/baz")); + "https://example.com/foo/bar/baz", false, "bar/baz")); cl_assert_equal_s(conndata.scheme, "https"); cl_assert_equal_s(conndata.host, "example.com"); cl_assert_equal_s(conndata.port, "443"); @@ -45,9 +45,9 @@ void test_network_url_redirect__redirect_ssl(void) void test_network_url_redirect__redirect_leaves_root_path(void) { cl_git_pass(git_net_url_parse(&conndata, - "https://example.com/foo/bar/baz")); + "https://example.com/foo/bar/baz")); cl_git_pass(git_net_url_apply_redirect(&conndata, - "https://example.com/foo/bar/baz", "/foo/bar/baz")); + "https://example.com/foo/bar/baz", false, "/foo/bar/baz")); cl_assert_equal_s(conndata.scheme, "https"); cl_assert_equal_s(conndata.host, "example.com"); cl_assert_equal_s(conndata.port, "443"); @@ -59,9 +59,9 @@ void test_network_url_redirect__redirect_leaves_root_path(void) void test_network_url_redirect__redirect_encoded_username_password(void) { cl_git_pass(git_net_url_parse(&conndata, - "https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz")); + "https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz")); cl_git_pass(git_net_url_apply_redirect(&conndata, - "https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz", "bar/baz")); + "https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz", false, "bar/baz")); cl_assert_equal_s(conndata.scheme, "https"); cl_assert_equal_s(conndata.host, "example.com"); cl_assert_equal_s(conndata.port, "443"); @@ -70,27 +70,42 @@ void test_network_url_redirect__redirect_encoded_username_password(void) cl_assert_equal_s(conndata.password, "pass@word%zyx%v"); } +void test_network_url_redirect__redirect_cross_host_allowed(void) +{ + cl_git_pass(git_net_url_parse(&conndata, + "https://bar.com/bar/baz")); + cl_git_pass(git_net_url_apply_redirect(&conndata, + "https://foo.com/bar/baz", true, NULL)); + cl_assert_equal_s(conndata.scheme, "https"); + cl_assert_equal_s(conndata.host, "foo.com"); + cl_assert_equal_s(conndata.port, "443"); + cl_assert_equal_s(conndata.path, "/bar/baz"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); +} + void test_network_url_redirect__redirect_cross_host_denied(void) { - cl_git_pass(git_net_url_parse(&conndata, "https://bar.com/bar/baz")); + cl_git_pass(git_net_url_parse(&conndata, + "https://bar.com/bar/baz")); cl_git_fail_with(git_net_url_apply_redirect(&conndata, - "https://foo.com/bar/baz", NULL), - -1); + "https://foo.com/bar/baz", false, NULL), -1); } void test_network_url_redirect__redirect_http_downgrade_denied(void) { - cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/baz")); + cl_git_pass(git_net_url_parse(&conndata, + "https://foo.com/bar/baz")); cl_git_fail_with(git_net_url_apply_redirect(&conndata, - "http://foo.com/bar/baz", NULL), - -1); + "http://foo.com/bar/baz", true, NULL), -1); } void test_network_url_redirect__redirect_relative(void) { - cl_git_pass(git_net_url_parse(&conndata, "http://foo.com/bar/baz/biff")); + cl_git_pass(git_net_url_parse(&conndata, + "http://foo.com/bar/baz/biff")); cl_git_pass(git_net_url_apply_redirect(&conndata, - "/zap/baz/biff?bam", NULL)); + "/zap/baz/biff?bam", true, NULL)); cl_assert_equal_s(conndata.scheme, "http"); cl_assert_equal_s(conndata.host, "foo.com"); cl_assert_equal_s(conndata.port, "80"); @@ -101,9 +116,10 @@ void test_network_url_redirect__redirect_relative(void) void test_network_url_redirect__redirect_relative_ssl(void) { - cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/baz/biff")); + cl_git_pass(git_net_url_parse(&conndata, + "https://foo.com/bar/baz/biff")); cl_git_pass(git_net_url_apply_redirect(&conndata, - "/zap/baz/biff?bam", NULL)); + "/zap/baz/biff?bam", true, NULL)); cl_assert_equal_s(conndata.scheme, "https"); cl_assert_equal_s(conndata.host, "foo.com"); cl_assert_equal_s(conndata.port, "443"); @@ -114,16 +130,18 @@ void test_network_url_redirect__redirect_relative_ssl(void) void test_network_url_redirect__service_query_no_query_params_in_location(void) { - cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/info/refs?service=git-upload-pack")); + cl_git_pass(git_net_url_parse(&conndata, + "https://foo.com/bar/info/refs?service=git-upload-pack")); cl_git_pass(git_net_url_apply_redirect(&conndata, - "/baz/info/refs", "/info/refs?service=git-upload-pack")); + "/baz/info/refs", true, "/info/refs?service=git-upload-pack")); cl_assert_equal_s(conndata.path, "/baz"); } void test_network_url_redirect__service_query_with_query_params_in_location(void) { - cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/info/refs?service=git-upload-pack")); + cl_git_pass(git_net_url_parse(&conndata, + "https://foo.com/bar/info/refs?service=git-upload-pack")); cl_git_pass(git_net_url_apply_redirect(&conndata, - "/baz/info/refs?service=git-upload-pack", "/info/refs?service=git-upload-pack")); + "/baz/info/refs?service=git-upload-pack", true, "/info/refs?service=git-upload-pack")); cl_assert_equal_s(conndata.path, "/baz"); } From 515daeaf4d5918ae93b02a5478adee563b4dac5e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 4 Jan 2022 06:16:30 -0500 Subject: [PATCH 0712/1616] remote: introduce `follow_redirects` connect option Give callers the ability to select how to handle redirects - either supporting redirects during the initial connection (so that, for example, `git.example.com/repo` can redirect to `github.com/example/repo`) or all/no redirects. This is for compatibility with git. --- ci/test.sh | 6 +++- include/git2/remote.h | 45 ++++++++++++++++++++++++++++ src/remote.c | 1 + src/transports/http.c | 22 ++++++++++++-- src/transports/winhttp.c | 4 ++- tests/online/clone.c | 64 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 138 insertions(+), 4 deletions(-) diff --git a/ci/test.sh b/ci/test.sh index bcbda902af3..e1a0e612dac 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -101,7 +101,7 @@ if [ -z "$SKIP_PROXY_TESTS" ]; then java -jar poxyproxy.jar --address 127.0.0.1 --port 8090 --credentials foo:bar --auth-type ntlm --quiet & fi -if [ -z "$SKIP_NTLM_TESTS" ]; then +if [ -z "$SKIP_NTLM_TESTS" -o -z "$SKIP_ONLINE_TESTS" ]; then curl --location --silent --show-error https://github.com/ethomson/poxygit/releases/download/v0.5.1/poxygit-0.5.1.jar >poxygit.jar echo "" @@ -188,7 +188,11 @@ if [ -z "$SKIP_ONLINE_TESTS" ]; then echo "## Running (online) tests" echo "##############################################################################" + export GITTEST_REMOTE_REDIRECT_INITIAL="http://localhost:9000/initial-redirect/libgit2/TestGitRepository" + export GITTEST_REMOTE_REDIRECT_SUBSEQUENT="http://localhost:9000/subsequent-redirect/libgit2/TestGitRepository" run_test online + unset GITTEST_REMOTE_REDIRECT_INITIAL + unset GITTEST_REMOTE_REDIRECT_SUBSEQUENT # Run the online tests that immutably change global state separately # to avoid polluting the test environment. diff --git a/include/git2/remote.h b/include/git2/remote.h index f1aa35f47e0..162b076ea38 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -41,6 +41,30 @@ GIT_EXTERN(int) git_remote_create( const char *name, const char *url); +/** + * Remote redirection settings; whether redirects to another host + * are permitted. By default, git will follow a redirect on the + * initial request (`/info/refs`), but not subsequent requests. + */ +typedef enum { + /** + * Do not follow any off-site redirects at any stage of + * the fetch or push. + */ + GIT_REMOTE_REDIRECT_NONE = (1 << 0), + + /** + * Allow off-site redirects only upon the initial request. + * This is the default. + */ + GIT_REMOTE_REDIRECT_INITIAL = (1 << 1), + + /** + * Allow redirects at any stage in the fetch or push. + */ + GIT_REMOTE_REDIRECT_ALL = (1 << 2) +} git_remote_redirect_t; + /** * Remote creation options flags */ @@ -717,6 +741,13 @@ typedef struct { */ git_proxy_options proxy_opts; + /** + * Whether to allow off-site redirects. If this is not + * specified, the `http.followRedirects` configuration setting + * will be consulted. + */ + git_remote_redirect_t follow_redirects; + /** * Extra headers for this fetch operation */ @@ -768,6 +799,13 @@ typedef struct { */ git_proxy_options proxy_opts; + /** + * Whether to allow off-site redirects. If this is not + * specified, the `http.followRedirects` configuration setting + * will be consulted. + */ + git_remote_redirect_t follow_redirects; + /** * Extra headers for this push operation */ @@ -807,6 +845,13 @@ typedef struct { /** HTTP Proxy settings */ git_proxy_options proxy_opts; + /** + * Whether to allow off-site redirects. If this is not + * specified, the `http.followRedirects` configuration setting + * will be consulted. + */ + git_remote_redirect_t follow_redirects; + /** Extra HTTP headers to use in this connection */ git_strarray custom_headers; } git_remote_connect_options; diff --git a/src/remote.c b/src/remote.c index 208d8d00ba0..2e818cd9194 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1171,6 +1171,7 @@ static int ls_to_vector(git_vector *out, git_remote *remote) (out)->callbacks = (in)->callbacks; \ (out)->proxy_opts = (in)->proxy_opts; \ (out)->custom_headers = (in)->custom_headers; \ + (out)->follow_redirects = (in)->follow_redirects; \ } GIT_INLINE(int) connect_opts_from_fetch_opts( diff --git a/src/transports/http.c b/src/transports/http.c index 6a17fa9abfc..7db5582cab4 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -38,7 +38,8 @@ typedef struct { const char *url; const char *request_type; const char *response_type; - unsigned chunked : 1; + unsigned int initial : 1, + chunked : 1; } http_service; typedef struct { @@ -70,24 +71,28 @@ static const http_service upload_pack_ls_service = { GIT_HTTP_METHOD_GET, "/info/refs?service=git-upload-pack", NULL, "application/x-git-upload-pack-advertisement", + 1, 0 }; static const http_service upload_pack_service = { GIT_HTTP_METHOD_POST, "/git-upload-pack", "application/x-git-upload-pack-request", "application/x-git-upload-pack-result", + 0, 0 }; static const http_service receive_pack_ls_service = { GIT_HTTP_METHOD_GET, "/info/refs?service=git-receive-pack", NULL, "application/x-git-receive-pack-advertisement", + 1, 0 }; static const http_service receive_pack_service = { GIT_HTTP_METHOD_POST, "/git-receive-pack", "application/x-git-receive-pack-request", "application/x-git-receive-pack-result", + 0, 1 }; @@ -215,6 +220,19 @@ GIT_INLINE(int) handle_proxy_auth( connect_opts->proxy_opts.payload); } +static bool allow_redirect(http_stream *stream) +{ + http_subtransport *transport = OWNING_SUBTRANSPORT(stream); + + switch (transport->owner->connect_opts.follow_redirects) { + case GIT_REMOTE_REDIRECT_INITIAL: + return (stream->service->initial == 1); + case GIT_REMOTE_REDIRECT_ALL: + return true; + default: + return false; + } +} static int handle_response( bool *complete, @@ -233,7 +251,7 @@ static int handle_response( return -1; } - if (git_net_url_apply_redirect(&transport->server.url, response->location, false, stream->service->url) < 0) { + if (git_net_url_apply_redirect(&transport->server.url, response->location, allow_redirect(stream), stream->service->url) < 0) { return -1; } diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index fdc6cf223b5..8ec5b37c533 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -1189,8 +1189,10 @@ static int winhttp_stream_read( winhttp_stream_close(s); if (!git__prefixcmp_icase(location8, prefix_https)) { + bool follow = (t->owner->connect_opts.follow_redirects != GIT_REMOTE_REDIRECT_NONE); + /* Upgrade to secure connection; disconnect and start over */ - if (git_net_url_apply_redirect(&t->server.url, location8, false, s->service_url) < 0) { + if (git_net_url_apply_redirect(&t->server.url, location8, follow, s->service_url) < 0) { git__free(location8); return -1; } diff --git a/tests/online/clone.c b/tests/online/clone.c index 8186dda167a..9f2580bb3fd 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -32,6 +32,8 @@ static char *_remote_proxy_user = NULL; static char *_remote_proxy_pass = NULL; static char *_remote_proxy_selfsigned = NULL; static char *_remote_expectcontinue = NULL; +static char *_remote_redirect_initial = NULL; +static char *_remote_redirect_subsequent = NULL; static int _orig_proxies_need_reset = 0; static char *_orig_http_proxy = NULL; @@ -78,6 +80,8 @@ void test_online_clone__initialize(void) _remote_proxy_pass = cl_getenv("GITTEST_REMOTE_PROXY_PASS"); _remote_proxy_selfsigned = cl_getenv("GITTEST_REMOTE_PROXY_SELFSIGNED"); _remote_expectcontinue = cl_getenv("GITTEST_REMOTE_EXPECTCONTINUE"); + _remote_redirect_initial = cl_getenv("GITTEST_REMOTE_REDIRECT_INITIAL"); + _remote_redirect_subsequent = cl_getenv("GITTEST_REMOTE_REDIRECT_SUBSEQUENT"); if (_remote_expectcontinue) git_libgit2_opts(GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE, 1); @@ -92,6 +96,8 @@ void test_online_clone__cleanup(void) g_repo = NULL; } cl_fixture_cleanup("./foo"); + cl_fixture_cleanup("./initial"); + cl_fixture_cleanup("./subsequent"); git__free(_remote_url); git__free(_remote_user); @@ -107,6 +113,8 @@ void test_online_clone__cleanup(void) git__free(_remote_proxy_pass); git__free(_remote_proxy_selfsigned); git__free(_remote_expectcontinue); + git__free(_remote_redirect_initial); + git__free(_remote_redirect_subsequent); if (_orig_proxies_need_reset) { cl_setenv("HTTP_PROXY", _orig_http_proxy); @@ -938,3 +946,59 @@ void test_online_clone__path_whitespace(void) cl_git_pass(git_clone(&g_repo, "https://libgit2@dev.azure.com/libgit2/test/_git/spaces%20in%20the%20name", "./foo", &g_options)); cl_assert(git_fs_path_exists("./foo/master.txt")); } + +void test_online_clone__redirect_default_succeeds_for_initial(void) +{ + git_clone_options options = GIT_CLONE_OPTIONS_INIT; + + if (!_remote_redirect_initial || !_remote_redirect_subsequent) + cl_skip(); + + cl_git_pass(git_clone(&g_repo, _remote_redirect_initial, "./initial", &options)); +} + +void test_online_clone__redirect_default_fails_for_subsequent(void) +{ + git_clone_options options = GIT_CLONE_OPTIONS_INIT; + + if (!_remote_redirect_initial || !_remote_redirect_subsequent) + cl_skip(); + + cl_git_fail(git_clone(&g_repo, _remote_redirect_subsequent, "./fail", &options)); +} + +void test_online_clone__redirect_none(void) +{ + git_clone_options options = GIT_CLONE_OPTIONS_INIT; + + if (!_remote_redirect_initial) + cl_skip(); + + options.fetch_opts.follow_redirects = GIT_REMOTE_REDIRECT_NONE; + + cl_git_fail(git_clone(&g_repo, _remote_redirect_initial, "./fail", &options)); +} + +void test_online_clone__redirect_initial_succeeds_for_initial(void) +{ + git_clone_options options = GIT_CLONE_OPTIONS_INIT; + + if (!_remote_redirect_initial || !_remote_redirect_subsequent) + cl_skip(); + + options.fetch_opts.follow_redirects = GIT_REMOTE_REDIRECT_INITIAL; + + cl_git_pass(git_clone(&g_repo, _remote_redirect_initial, "./initial", &options)); +} + +void test_online_clone__redirect_initial_fails_for_subsequent(void) +{ + git_clone_options options = GIT_CLONE_OPTIONS_INIT; + + if (!_remote_redirect_initial || !_remote_redirect_subsequent) + cl_skip(); + + options.fetch_opts.follow_redirects = GIT_REMOTE_REDIRECT_INITIAL; + + cl_git_fail(git_clone(&g_repo, _remote_redirect_subsequent, "./fail", &options)); +} From fda59a76ffccdbd411aa06e271be03a0d466ae3c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 4 Jan 2022 07:05:20 -0500 Subject: [PATCH 0713/1616] remote: honor `http.followRedirects` configuration option --- src/remote.c | 79 +++++++++++++++++++++++++++++++++--------- src/remote.h | 1 + src/transports/local.c | 4 +-- src/transports/smart.c | 4 +-- 4 files changed, 68 insertions(+), 20 deletions(-) diff --git a/src/remote.c b/src/remote.c index 2e818cd9194..f1010415a0b 100644 --- a/src/remote.c +++ b/src/remote.c @@ -858,25 +858,70 @@ static int validate_custom_headers(const git_strarray *custom_headers) return 0; } +static int lookup_redirect_config( + git_remote_redirect_t *out, + git_repository *repo) +{ + git_config *config; + const char *value; + int bool_value, error = 0; + + if (!repo) { + *out = GIT_REMOTE_REDIRECT_INITIAL; + return 0; + } + + if ((error = git_repository_config_snapshot(&config, repo)) < 0) + goto done; + + if ((error = git_config_get_string(&value, config, "http.followRedirects")) < 0) { + if (error == GIT_ENOTFOUND) { + *out = GIT_REMOTE_REDIRECT_INITIAL; + error = 0; + } + + goto done; + } + + if (git_config_parse_bool(&bool_value, value) == 0) { + *out = bool_value ? GIT_REMOTE_REDIRECT_ALL : + GIT_REMOTE_REDIRECT_NONE; + } else if (strcasecmp(value, "initial") == 0) { + *out = GIT_REMOTE_REDIRECT_INITIAL; + } else { + git_error_set(GIT_ERROR_CONFIG, "invalid configuration setting '%s' for 'http.followRedirects'", value); + error = -1; + } + +done: + git_config_free(config); + return error; +} + int git_remote_connect_options_normalize( git_remote_connect_options *dst, + git_repository *repo, const git_remote_connect_options *src) { git_remote_connect_options_dispose(dst); + git_remote_connect_options_init(dst, GIT_REMOTE_CONNECT_OPTIONS_VERSION); - if (!src) { - git_remote_connect_options_init(dst, GIT_REMOTE_CONNECT_OPTIONS_VERSION); - return 0; - } + if (src) { + GIT_ERROR_CHECK_VERSION(src, GIT_REMOTE_CONNECT_OPTIONS_VERSION, "git_remote_connect_options"); + GIT_ERROR_CHECK_VERSION(&src->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); + GIT_ERROR_CHECK_VERSION(&src->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options"); - GIT_ERROR_CHECK_VERSION(src, GIT_REMOTE_CONNECT_OPTIONS_VERSION, "git_remote_connect_options"); - GIT_ERROR_CHECK_VERSION(&src->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks"); - GIT_ERROR_CHECK_VERSION(&src->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options"); + if (validate_custom_headers(&src->custom_headers) < 0 || + git_remote_connect_options_dup(dst, src) < 0) + return -1; + } - if (validate_custom_headers(&src->custom_headers)) - return -1; + if (dst->follow_redirects == 0) { + if (lookup_redirect_config(&dst->follow_redirects, repo) < 0) + return -1; + } - return git_remote_connect_options_dup(dst, src); + return 0; } int git_remote_connect_ext( @@ -1176,11 +1221,12 @@ static int ls_to_vector(git_vector *out, git_remote *remote) GIT_INLINE(int) connect_opts_from_fetch_opts( git_remote_connect_options *out, + git_remote *remote, const git_fetch_options *fetch_opts) { git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT; copy_opts(&tmp, fetch_opts); - return git_remote_connect_options_normalize(out, &tmp); + return git_remote_connect_options_normalize(out, remote->repo, &tmp); } static int connect_or_reset_options( @@ -1270,7 +1316,7 @@ int git_remote_download( return -1; } - if (connect_opts_from_fetch_opts(&connect_opts, opts) < 0) + if (connect_opts_from_fetch_opts(&connect_opts, remote, opts) < 0) return -1; if ((error = connect_or_reset_options(remote, GIT_DIRECTION_FETCH, &connect_opts)) < 0) @@ -1298,7 +1344,7 @@ int git_remote_fetch( return -1; } - if (connect_opts_from_fetch_opts(&connect_opts, opts) < 0) + if (connect_opts_from_fetch_opts(&connect_opts, remote, opts) < 0) return -1; if ((error = connect_or_reset_options(remote, GIT_DIRECTION_FETCH, &connect_opts)) < 0) @@ -2771,11 +2817,12 @@ int git_remote__default_branch(git_str *out, git_remote *remote) GIT_INLINE(int) connect_opts_from_push_opts( git_remote_connect_options *out, + git_remote *remote, const git_push_options *push_opts) { git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT; copy_opts(&tmp, push_opts); - return git_remote_connect_options_normalize(out, &tmp); + return git_remote_connect_options_normalize(out, remote->repo, &tmp); } int git_remote_upload( @@ -2796,7 +2843,7 @@ int git_remote_upload( return -1; } - if ((error = connect_opts_from_push_opts(&connect_opts, opts)) < 0) + if ((error = connect_opts_from_push_opts(&connect_opts, remote, opts)) < 0) goto cleanup; if ((error = connect_or_reset_options(remote, GIT_DIRECTION_PUSH, &connect_opts)) < 0) @@ -2857,7 +2904,7 @@ int git_remote_push( return -1; } - if (connect_opts_from_push_opts(&connect_opts, opts) < 0) + if (connect_opts_from_push_opts(&connect_opts, remote, opts) < 0) return -1; if ((error = git_remote_upload(remote, refspecs, opts)) < 0) diff --git a/src/remote.h b/src/remote.h index 1655e1551b6..3cf0fd953e2 100644 --- a/src/remote.h +++ b/src/remote.h @@ -50,6 +50,7 @@ int git_remote_connect_options_dup( const git_remote_connect_options *src); int git_remote_connect_options_normalize( git_remote_connect_options *dst, + git_repository *repo, const git_remote_connect_options *src); void git_remote_connect_options_dispose(git_remote_connect_options *opts); diff --git a/src/transports/local.c b/src/transports/local.c index 6065d4020bd..86524edf149 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -209,7 +209,7 @@ static int local_connect( if (t->connected) return 0; - if (git_remote_connect_options_normalize(&t->connect_opts, connect_opts) < 0) + if (git_remote_connect_options_normalize(&t->connect_opts, t->owner->repo, connect_opts) < 0) return -1; free_heads(&t->refs); @@ -253,7 +253,7 @@ static int local_set_connect_opts( return -1; } - return git_remote_connect_options_normalize(&t->connect_opts, connect_opts); + return git_remote_connect_options_normalize(&t->connect_opts, t->owner->repo, connect_opts); } static int local_ls(const git_remote_head ***out, size_t *size, git_transport *transport) diff --git a/src/transports/smart.c b/src/transports/smart.c index 4267e884132..e76c18fc31f 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -125,7 +125,7 @@ static int git_smart__connect( if (git_smart__reset_stream(t, true) < 0) return -1; - if (git_remote_connect_options_normalize(&t->connect_opts, connect_opts) < 0) + if (git_remote_connect_options_normalize(&t->connect_opts, t->owner->repo, connect_opts) < 0) return -1; t->url = git__strdup(url); @@ -223,7 +223,7 @@ static int git_smart__set_connect_opts( return -1; } - return git_remote_connect_options_normalize(&t->connect_opts, opts); + return git_remote_connect_options_normalize(&t->connect_opts, t->owner->repo, opts); } static int git_smart__ls(const git_remote_head ***out, size_t *size, git_transport *transport) From adaa037d3aa438e5a1fb074ed0d239bf4dd5a18b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 4 Jan 2022 16:18:40 -0500 Subject: [PATCH 0714/1616] remote: test honoring configuration option Test that we honor `http.followRedirects` when set to initial or false. --- tests/online/fetch.c | 66 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/tests/online/fetch.c b/tests/online/fetch.c index 9142910154d..e09d338ceb1 100644 --- a/tests/online/fetch.c +++ b/tests/online/fetch.c @@ -7,15 +7,19 @@ static char *_remote_proxy_scheme = NULL; static char *_remote_proxy_host = NULL; static char *_remote_proxy_user = NULL; static char *_remote_proxy_pass = NULL; +static char *_remote_redirect_initial = NULL; +static char *_remote_redirect_subsequent = NULL; void test_online_fetch__initialize(void) { cl_git_pass(git_repository_init(&_repo, "./fetch", 0)); - _remote_proxy_scheme = cl_getenv("GITTEST_REMOTE_PROXY_SCHEME"); - _remote_proxy_host = cl_getenv("GITTEST_REMOTE_PROXY_HOST"); - _remote_proxy_user = cl_getenv("GITTEST_REMOTE_PROXY_USER"); - _remote_proxy_pass = cl_getenv("GITTEST_REMOTE_PROXY_PASS"); + _remote_proxy_scheme = cl_getenv("GITTEST_REMOTE_PROXY_SCHEME"); + _remote_proxy_host = cl_getenv("GITTEST_REMOTE_PROXY_HOST"); + _remote_proxy_user = cl_getenv("GITTEST_REMOTE_PROXY_USER"); + _remote_proxy_pass = cl_getenv("GITTEST_REMOTE_PROXY_PASS"); + _remote_redirect_initial = cl_getenv("GITTEST_REMOTE_REDIRECT_INITIAL"); + _remote_redirect_subsequent = cl_getenv("GITTEST_REMOTE_REDIRECT_SUBSEQUENT"); } void test_online_fetch__cleanup(void) @@ -24,11 +28,14 @@ void test_online_fetch__cleanup(void) _repo = NULL; cl_fixture_cleanup("./fetch"); - - git__free(_remote_proxy_scheme); - git__free(_remote_proxy_host); - git__free(_remote_proxy_user); - git__free(_remote_proxy_pass); + cl_fixture_cleanup("./redirected"); + + git__free(_remote_proxy_scheme); + git__free(_remote_proxy_host); + git__free(_remote_proxy_user); + git__free(_remote_proxy_pass); + git__free(_remote_redirect_initial); + git__free(_remote_redirect_subsequent); } static int update_tips(const char *refname, const git_oid *a, const git_oid *b, void *data) @@ -247,3 +254,44 @@ void test_online_fetch__proxy(void) git_remote_free(remote); git_str_dispose(&url); } + +static int do_redirected_fetch(const char *url, const char *name, const char *config) +{ + git_repository *repo; + git_remote *remote; + int error; + + cl_git_pass(git_repository_init(&repo, "./redirected", 0)); + cl_fixture_cleanup(name); + + if (config) + cl_repo_set_string(repo, "http.followRedirects", config); + + cl_git_pass(git_remote_create(&remote, repo, name, url)); + error = git_remote_fetch(remote, NULL, NULL, NULL); + + git_remote_free(remote); + git_repository_free(repo); + + cl_fixture_cleanup("./redirected"); + + return error; +} + +void test_online_fetch__redirect_config(void) +{ + if (!_remote_redirect_initial || !_remote_redirect_subsequent) + cl_skip(); + + /* config defaults */ + cl_git_pass(do_redirected_fetch(_remote_redirect_initial, "initial", NULL)); + cl_git_fail(do_redirected_fetch(_remote_redirect_subsequent, "subsequent", NULL)); + + /* redirect=initial */ + cl_git_pass(do_redirected_fetch(_remote_redirect_initial, "initial", "initial")); + cl_git_fail(do_redirected_fetch(_remote_redirect_subsequent, "subsequent", "initial")); + + /* redirect=false */ + cl_git_fail(do_redirected_fetch(_remote_redirect_initial, "initial", "false")); + cl_git_fail(do_redirected_fetch(_remote_redirect_subsequent, "subsequent", "false")); +} From f4fec25182eb04ceec05d41e47670b1370ca7420 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 13 Jan 2022 16:54:56 -0500 Subject: [PATCH 0715/1616] ci: minor formatting cleanups to test output --- ci/test.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ci/test.sh b/ci/test.sh index e1a0e612dac..0dc43aa876c 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -83,7 +83,7 @@ echo "########################################################################## if [ -z "$SKIP_GITDAEMON_TESTS" ]; then echo "Starting git daemon..." GITDAEMON_DIR=`mktemp -d ${TMPDIR}/gitdaemon.XXXXXXXX` - git init --bare "${GITDAEMON_DIR}/test.git" + git init --bare "${GITDAEMON_DIR}/test.git" >/dev/null git daemon --listen=localhost --export-all --enable=receive-pack --base-path="${GITDAEMON_DIR}" "${GITDAEMON_DIR}" 2>/dev/null & GITDAEMON_PID=$! disown $GITDAEMON_PID @@ -112,10 +112,11 @@ if [ -z "$SKIP_NTLM_TESTS" -o -z "$SKIP_ONLINE_TESTS" ]; then fi if [ -z "$SKIP_SSH_TESTS" ]; then + echo "" echo "Starting ssh daemon..." HOME=`mktemp -d ${TMPDIR}/home.XXXXXXXX` SSHD_DIR=`mktemp -d ${TMPDIR}/sshd.XXXXXXXX` - git init --bare "${SSHD_DIR}/test.git" + git init --bare "${SSHD_DIR}/test.git" >/dev/null cat >"${SSHD_DIR}/sshd_config" <<-EOF Port 2222 ListenAddress 0.0.0.0 From 10abd7bcafa9eefb17f1deb463f519407e78aefd Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:19:57 -0600 Subject: [PATCH 0716/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 4d5ed7c619b..8ec0efee274 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -71,7 +71,7 @@ typedef struct refdb_fs_backend { } refdb_fs_backend; static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name); -static const char * packed_set_peeling_mode(const char *data, size_t data_sz, refdb_fs_backend *backend); +static char *packed_set_peeling_mode(char *data, size_t data_sz, refdb_fs_backend *backend); GIT_INLINE(int) loose_path( git_str *out, From a0381cf2362f31a761b634db86fd529d081f7507 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:20:04 -0600 Subject: [PATCH 0717/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 8ec0efee274..f8b56fa1277 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -141,7 +141,7 @@ static int packed_reload(refdb_fs_backend *backend) scan = (char *)packedrefs.ptr; eof = scan + packedrefs.size; - scan = (char *)packed_set_peeling_mode(scan, packedrefs.size, backend); + scan = packed_set_peeling_mode(scan, packedrefs.size, backend); if (!scan) { goto parse_failed; } From d89f1fe5ca31004b35ec23f4abc23ff6350e08e8 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:20:09 -0600 Subject: [PATCH 0718/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index f8b56fa1277..3317d6b194d 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -452,8 +452,8 @@ static int ref_error_notfound(const char *name) return GIT_ENOTFOUND; } -static const char *packed_set_peeling_mode( - const char *data, +static char *packed_set_peeling_mode( + char *data, size_t data_sz, refdb_fs_backend *backend) { From c6c6c0bdc5e7d05a00104b68da9905f4dc730390 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:20:14 -0600 Subject: [PATCH 0719/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 3317d6b194d..c9b0da7ce97 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -138,7 +138,7 @@ static int packed_reload(refdb_fs_backend *backend) GIT_UNUSED(git_sortedcache_clear(backend->refcache, false)); - scan = (char *)packedrefs.ptr; + scan = packedrefs.ptr; eof = scan + packedrefs.size; scan = packed_set_peeling_mode(scan, packedrefs.size, backend); From 99fc3d496c9ae4ba24334bba30c7cacf21c9e24a Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:20:20 -0600 Subject: [PATCH 0720/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index c9b0da7ce97..829983ffb0f 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -142,9 +142,8 @@ static int packed_reload(refdb_fs_backend *backend) eof = scan + packedrefs.size; scan = packed_set_peeling_mode(scan, packedrefs.size, backend); - if (!scan) { + if (!scan) goto parse_failed; - } while (scan < eof && *scan == '#') { if (!(eol = strchr(scan, '\n'))) From 620e3abcd4b4da0196296bd1269840c5ad286576 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:20:27 -0600 Subject: [PATCH 0721/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 829983ffb0f..f682676cdc1 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -500,9 +500,8 @@ static int packed_map_check(refdb_fs_backend *backend) git_file fd = -1; struct stat st; - if ((error = git_mutex_lock(&backend->prlock)) < 0) { + if ((error = git_mutex_lock(&backend->prlock)) < 0) return error; - } if (backend->packed_refs_map.data) { git_mutex_unlock(&backend->prlock); From c55275ff0b31bc24e4c39062db3598b339e68e20 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:20:47 -0600 Subject: [PATCH 0722/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index f682676cdc1..f05510e8071 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -483,11 +483,7 @@ static char *packed_set_peeling_mode( backend->peeling_mode = PEELING_STANDARD; } - if (git__memmem(data, eol - data, sorted, strlen(sorted))) { - backend->sorted = true; - } else { - backend->sorted = false; - } + backend->sorted = git__memmem(data, eol - data, sorted, strlen(sorted)); return eol + 1; } From b162bb359525d4fadf48fd74f69a217f93210e49 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:20:53 -0600 Subject: [PATCH 0723/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index f05510e8071..2a80337e04e 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -477,11 +477,10 @@ static char *packed_set_peeling_mode( if (!eol) return NULL; - if (git__memmem(data, eol - data, fully_peeled, strlen(fully_peeled))) { + if (git__memmem(data, eol - data, fully_peeled, strlen(fully_peeled))) backend->peeling_mode = PEELING_FULL; - } else if (git__memmem(data, eol - data, peeled, strlen(peeled))) { + else if (git__memmem(data, eol - data, peeled, strlen(peeled))) backend->peeling_mode = PEELING_STANDARD; - } backend->sorted = git__memmem(data, eol - data, sorted, strlen(sorted)); From 678c9ddf87e569758efafcb69ac844eb47255bb3 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:22:13 -0600 Subject: [PATCH 0724/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 2a80337e04e..6b79073693a 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -457,7 +457,7 @@ static char *packed_set_peeling_mode( refdb_fs_backend *backend) { static const char *traits_header = "# pack-refs with:"; - const char *eol; + char *eol; backend->peeling_mode = PEELING_NONE; if (data_sz == 0 || *data != '#') { From d86b9f7990091bcdb6aec2c71c35e9afb728fbfd Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:23:01 -0600 Subject: [PATCH 0725/1616] Update src/refdb_fs.c Co-authored-by: Edward Thomson --- src/refdb_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 6b79073693a..4d01adfde17 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -651,7 +651,7 @@ static int packed_lookup( return packed_unsorted_lookup(out, backend, ref_name); left = backend->packed_refs_map.data; - right = data_end = ((const char *)backend->packed_refs_map.data) + + right = data_end = backend->packed_refs_map.data + backend->packed_refs_map.len; while (left < right && *left == '#') { From 60faa6310e39bdd00f30f6a74e11902f80e18e18 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:32:48 -0600 Subject: [PATCH 0726/1616] Drop redundant check in packed_set_peeling_mode(). Co-authored-by: Edward Thomson --- src/refdb_fs.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 4d01adfde17..98b25e89a9a 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -460,10 +460,6 @@ static char *packed_set_peeling_mode( char *eol; backend->peeling_mode = PEELING_NONE; - if (data_sz == 0 || *data != '#') { - return data; - } - if (git__prefixncmp(data, data_sz, traits_header) == 0) { size_t hdr_sz = strlen(traits_header); const char *sorted = " sorted "; From cdf05a1d7369933cef68bd0ceac6106af305327e Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Wed, 12 Jan 2022 16:28:45 -0600 Subject: [PATCH 0727/1616] On windows, copy file into memory instead of mmap. Since mmap() on windows locks the file, and this map is long-lived, just copy the file into memory instead. This enables us to keep the lookup() paths the same, while avoiding the downsides of mmap() on windows. --- src/refdb_fs.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 98b25e89a9a..af5345d3b90 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -485,6 +485,19 @@ static char *packed_set_peeling_mode( return data; } +static void packed_map_free(refdb_fs_backend *backend) +{ + if (backend->packed_refs_map.data) { +#ifdef GIT_WIN32 + git__free(backend->packed_refs_map.data); +#else + git_futils_mmap_free(&backend->packed_refs_map); +#endif + backend->packed_refs_map.data = NULL; + backend->packed_refs_map.len = 0; + } +} + static int packed_map_check(refdb_fs_backend *backend) { int error = 0; @@ -522,7 +535,23 @@ static int packed_map_check(refdb_fs_backend *backend) return 0; } +#ifdef GIT_WIN32 + /* on windows, we copy the entire file into memory rather than using + * mmap() because using mmap() on windows also locks the file and this + * map is long-lived. */ + backend->packed_refs_map.len = (size_t)st.st_size; + backend->packed_refs_map.data = + git__malloc(backend->packed_refs_map.len); + GIT_ERROR_CHECK_ALLOC(backend->packed_refs_map.data); + { + ssize_t bytesread = + p_read(fd, backend->packed_refs_map.data, + backend->packed_refs_map.len); + error = (bytesread == (ssize_t)backend->packed_refs_map.len) ? 0 : -1; + } +#else error = git_futils_mmap_ro(&backend->packed_refs_map, fd, 0, (size_t)st.st_size); +#endif p_close(fd); if (error < 0) { git_mutex_unlock(&backend->prlock); @@ -1302,10 +1331,7 @@ static int packed_write(refdb_fs_backend *backend) return error; } - if (backend->packed_refs_map.data) { - git_futils_mmap_free(&backend->packed_refs_map); - backend->packed_refs_map.data = NULL; - } + packed_map_free(backend); git_mutex_unlock(&backend->prlock); @@ -1798,10 +1824,7 @@ static void refdb_fs_backend__free(git_refdb_backend *_backend) git_sortedcache_free(backend->refcache); git_mutex_lock(&backend->prlock); - if (backend->packed_refs_map.data) { - git_futils_mmap_free(&backend->packed_refs_map); - backend->packed_refs_map.data = NULL; - } + packed_map_free(backend); git_mutex_unlock(&backend->prlock); git_mutex_free(&backend->prlock); From ac07a40a3c7827ff92b46afff32379b1ec1950b2 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Wed, 12 Jan 2022 16:57:51 -0600 Subject: [PATCH 0728/1616] Check packed-refs filestamp before reusing mmap. Avoid using a stale mmap() by tracking the filestamp. --- src/refdb_fs.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index af5345d3b90..753cff73c0f 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -67,6 +67,7 @@ typedef struct refdb_fs_backend { int fsync; git_map packed_refs_map; git_mutex prlock; /* protect packed_refs_map */ + git_futils_filestamp packed_refs_stamp; bool sorted; } refdb_fs_backend; @@ -495,6 +496,7 @@ static void packed_map_free(refdb_fs_backend *backend) #endif backend->packed_refs_map.data = NULL; backend->packed_refs_map.len = 0; + git_futils_filestamp_set(&backend->packed_refs_stamp, NULL); } } @@ -507,10 +509,13 @@ static int packed_map_check(refdb_fs_backend *backend) if ((error = git_mutex_lock(&backend->prlock)) < 0) return error; - if (backend->packed_refs_map.data) { + if (backend->packed_refs_map.data && + !git_futils_filestamp_check( + &backend->packed_refs_stamp, backend->refcache->path)) { git_mutex_unlock(&backend->prlock); return error; } + packed_map_free(backend); fd = git_futils_open_ro(backend->refcache->path); if (fd < 0) { @@ -535,6 +540,8 @@ static int packed_map_check(refdb_fs_backend *backend) return 0; } + git_futils_filestamp_set_from_stat(&backend->packed_refs_stamp, &st); + #ifdef GIT_WIN32 /* on windows, we copy the entire file into memory rather than using * mmap() because using mmap() on windows also locks the file and this From 0a72a3ada2dec5405e8e1e4449ed585c4497ffc7 Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Thu, 13 Jan 2022 17:43:30 -0600 Subject: [PATCH 0729/1616] Fix compiler warning on Windows. --- src/refdb_fs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 753cff73c0f..95bda940472 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -479,7 +479,7 @@ static char *packed_set_peeling_mode( else if (git__memmem(data, eol - data, peeled, strlen(peeled))) backend->peeling_mode = PEELING_STANDARD; - backend->sorted = git__memmem(data, eol - data, sorted, strlen(sorted)); + backend->sorted = NULL != git__memmem(data, eol - data, sorted, strlen(sorted)); return eol + 1; } @@ -683,7 +683,7 @@ static int packed_lookup( return packed_unsorted_lookup(out, backend, ref_name); left = backend->packed_refs_map.data; - right = data_end = backend->packed_refs_map.data + + right = data_end = (const char *) backend->packed_refs_map.data + backend->packed_refs_map.len; while (left < right && *left == '#') { From 8d54822269fbfcc85419df6d099ce62a789d187c Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Fri, 14 Jan 2022 23:25:27 +0100 Subject: [PATCH 0730/1616] tests: verify that futils_mktmp respects umask --- tests/core/futils.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/core/futils.c b/tests/core/futils.c index b87ea183bea..3501765f621 100644 --- a/tests/core/futils.c +++ b/tests/core/futils.c @@ -87,3 +87,29 @@ void test_core_futils__recursive_rmdir_keeps_symlink_targets(void) cl_must_pass(p_rmdir("dir-target")); cl_must_pass(p_unlink("file-target")); } + +void test_core_futils__mktmp_umask(void) +{ +#ifdef GIT_WIN32 + cl_skip(); +#else + git_str path = GIT_STR_INIT; + struct stat st; + int fd; + + umask(0); + cl_assert((fd = git_futils_mktmp(&path, "foo", 0777)) >= 0); + cl_must_pass(p_fstat(fd, &st)); + cl_assert_equal_i(st.st_mode & 0777, 0777); + cl_must_pass(p_unlink(path.ptr)); + close(fd); + + umask(077); + cl_assert((fd = git_futils_mktmp(&path, "foo", 0777)) >= 0); + cl_must_pass(p_fstat(fd, &st)); + cl_assert_equal_i(st.st_mode & 0777, 0700); + cl_must_pass(p_unlink(path.ptr)); + close(fd); + git_str_dispose(&path); +#endif +} From 4ac5972811a711f9b26e34fd6b6d6df7f5407953 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Fri, 14 Jan 2022 01:54:09 +0100 Subject: [PATCH 0731/1616] futils_mktmp: don't use umask. Previously, we were using `umask(mask = umask(0))` to fetch the current umask in order to apply it to the desired mode, but this is broken in the presence of threads. There is no portable way to directly fetch umask without mutating it. Instead, add a reimplementation of mkstemp that uses a passed-in mode, instead of explicitly chmodding to 0600 like POSIX requires of mkstemp. Fixes: jmgao/pore#46 --- src/futils.c | 36 +++++++++++++++++++----------------- src/posix.h | 2 ++ 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/futils.c b/src/futils.c index 454ed79de23..318e878f534 100644 --- a/src/futils.c +++ b/src/futils.c @@ -26,30 +26,32 @@ int git_futils_mkpath2file(const char *file_path, const mode_t mode) int git_futils_mktmp(git_str *path_out, const char *filename, mode_t mode) { + const int open_flags = O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC; + /* TMP_MAX is unrelated to mktemp but should provide a reasonable amount */ + unsigned int tries = TMP_MAX; int fd; - mode_t mask; - p_umask(mask = p_umask(0)); + while (tries--) { + git_str_sets(path_out, filename); + git_str_puts(path_out, "_git2_XXXXXX"); - git_str_sets(path_out, filename); - git_str_puts(path_out, "_git2_XXXXXX"); - - if (git_str_oom(path_out)) - return -1; + if (git_str_oom(path_out)) + return -1; - if ((fd = p_mkstemp(path_out->ptr)) < 0) { - git_error_set(GIT_ERROR_OS, - "failed to create temporary file '%s'", path_out->ptr); - return -1; - } + /* Using mktemp is safe when we open with O_CREAT | O_EXCL */ + p_mktemp(path_out->ptr); + /* mktemp sets template to empty string on failure */ + if (path_out->ptr[0] == '\0') + break; - if (p_chmod(path_out->ptr, (mode & ~mask))) { - git_error_set(GIT_ERROR_OS, - "failed to set permissions on file '%s'", path_out->ptr); - return -1; + if ((fd = p_open(path_out->ptr, open_flags, mode)) >= 0) + return fd; } - return fd; + git_error_set(GIT_ERROR_OS, + "failed to create temporary file '%s'", path_out->ptr); + git_str_dispose(path_out); + return -1; } int git_futils_creat_withpath(const char *path, const mode_t dirmode, const mode_t mode) diff --git a/src/posix.h b/src/posix.h index d98bc82ca80..1757764a277 100644 --- a/src/posix.h +++ b/src/posix.h @@ -9,6 +9,7 @@ #include "common.h" +#include #include #include @@ -130,6 +131,7 @@ extern ssize_t p_pwrite(int fd, const void *data, size_t size, off64_t offset); #define p_close(fd) close(fd) #define p_umask(m) umask(m) +#define p_mktemp(p) mktemp(p) extern int p_open(const char *path, int flags, ...); extern int p_creat(const char *path, mode_t mode); From a979cf3d5cc05166de4787ed84ab57fc231046e9 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Wed, 17 Nov 2021 22:19:47 +0100 Subject: [PATCH 0732/1616] c99: change single bit flags to unsigned --- src/checkout.c | 10 +++++----- src/pack-objects.h | 8 ++++---- src/rebase.c | 8 ++++---- src/transports/smart.h | 20 ++++++++++---------- src/worktree.h | 2 +- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/checkout.c b/src/checkout.c index 11be2e84fa3..8c2f706527b 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -81,11 +81,11 @@ typedef struct { const git_index_entry *ours; const git_index_entry *theirs; - int name_collision:1, - directoryfile:1, - one_to_two:1, - binary:1, - submodule:1; + unsigned int name_collision:1, + directoryfile:1, + one_to_two:1, + binary:1, + submodule:1; } checkout_conflictdata; static int checkout_notify( diff --git a/src/pack-objects.h b/src/pack-objects.h index db2038b0a04..cefee40efc2 100644 --- a/src/pack-objects.h +++ b/src/pack-objects.h @@ -46,10 +46,10 @@ typedef struct git_pobject { size_t delta_size; size_t z_delta_size; - int written:1, - recursing:1, - tagged:1, - filled:1; + unsigned int written:1, + recursing:1, + tagged:1, + filled:1; } git_pobject; struct git_packbuilder { diff --git a/src/rebase.c b/src/rebase.c index 4ad37643b76..6f01d399057 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -64,10 +64,10 @@ struct git_rebase { git_rebase_t type; char *state_path; - int head_detached : 1, - inmemory : 1, - quiet : 1, - started : 1; + unsigned int head_detached:1, + inmemory:1, + quiet:1, + started:1; git_array_t(git_rebase_operation) operations; size_t current; diff --git a/src/transports/smart.h b/src/transports/smart.h index a9cab31acd9..c003052c81e 100644 --- a/src/transports/smart.h +++ b/src/transports/smart.h @@ -119,16 +119,16 @@ typedef struct { } git_pkt_unpack; typedef struct transport_smart_caps { - int common:1, - ofs_delta:1, - multi_ack: 1, - multi_ack_detailed: 1, - side_band:1, - side_band_64k:1, - include_tag:1, - delete_refs:1, - report_status:1, - thin_pack:1; + unsigned int common:1, + ofs_delta:1, + multi_ack:1, + multi_ack_detailed:1, + side_band:1, + side_band_64k:1, + include_tag:1, + delete_refs:1, + report_status:1, + thin_pack:1; } transport_smart_caps; typedef int (*packetsize_cb)(size_t received, void *payload); diff --git a/src/worktree.h b/src/worktree.h index 1d40c3a5ddb..587189f81a2 100644 --- a/src/worktree.h +++ b/src/worktree.h @@ -31,7 +31,7 @@ struct git_worktree { /* Path to the parent's working directory */ char *parent_path; - int locked:1; + unsigned int locked:1; }; char *git_worktree__read_link(const char *base, const char *file); From df4448f2b1f3eafd564f4ae61d0d0f21e84916d5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 10 Jan 2022 21:25:05 -0500 Subject: [PATCH 0733/1616] online: test with https instead of git protocol GitHub is removing support for the unauthenticated git protocol; test with the https protocol. --- tests/fetchhead/fetchhead_data.h | 64 ++++++++++++++++---------------- tests/fetchhead/nonetwork.c | 12 +++--- tests/online/fetch.c | 9 +---- tests/online/fetchhead.c | 8 +--- tests/online/remotes.c | 2 +- 5 files changed, 43 insertions(+), 52 deletions(-) diff --git a/tests/fetchhead/fetchhead_data.h b/tests/fetchhead/fetchhead_data.h index c75b65b90f7..77c3220016b 100644 --- a/tests/fetchhead/fetchhead_data.h +++ b/tests/fetchhead/fetchhead_data.h @@ -1,48 +1,48 @@ #define FETCH_HEAD_WILDCARD_DATA_LOCAL \ - "49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \ - "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \ - "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \ - "d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of git://github.com/libgit2/TestGitRepository\n" \ - "55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of git://github.com/libgit2/TestGitRepository\n" \ - "8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of git://github.com/libgit2/TestGitRepository\n" + "49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of https://github.com/libgit2/TestGitRepository\n" \ + "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of https://github.com/libgit2/TestGitRepository\n" \ + "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of https://github.com/libgit2/TestGitRepository\n" \ + "d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of https://github.com/libgit2/TestGitRepository\n" \ + "55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of https://github.com/libgit2/TestGitRepository\n" \ + "8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of https://github.com/libgit2/TestGitRepository\n" #define FETCH_HEAD_WILDCARD_DATA \ - "49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \ - "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \ - "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \ - "d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of git://github.com/libgit2/TestGitRepository\n" \ - "55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of git://github.com/libgit2/TestGitRepository\n" \ - "8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of git://github.com/libgit2/TestGitRepository\n" \ - "6e0c7bdb9b4ed93212491ee778ca1c65047cab4e\tnot-for-merge\ttag 'nearly-dangling' of git://github.com/libgit2/TestGitRepository\n" + "49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of https://github.com/libgit2/TestGitRepository\n" \ + "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of https://github.com/libgit2/TestGitRepository\n" \ + "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of https://github.com/libgit2/TestGitRepository\n" \ + "d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of https://github.com/libgit2/TestGitRepository\n" \ + "55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of https://github.com/libgit2/TestGitRepository\n" \ + "8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of https://github.com/libgit2/TestGitRepository\n" \ + "6e0c7bdb9b4ed93212491ee778ca1c65047cab4e\tnot-for-merge\ttag 'nearly-dangling' of https://github.com/libgit2/TestGitRepository\n" #define FETCH_HEAD_WILDCARD_DATA2 \ - "49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \ - "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \ - "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \ + "49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of https://github.com/libgit2/TestGitRepository\n" \ + "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of https://github.com/libgit2/TestGitRepository\n" \ + "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of https://github.com/libgit2/TestGitRepository\n" \ #define FETCH_HEAD_NO_MERGE_DATA \ - "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \ - "49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \ - "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \ - "d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of git://github.com/libgit2/TestGitRepository\n" \ - "55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of git://github.com/libgit2/TestGitRepository\n" \ - "8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of git://github.com/libgit2/TestGitRepository\n" \ - "6e0c7bdb9b4ed93212491ee778ca1c65047cab4e\tnot-for-merge\ttag 'nearly-dangling' of git://github.com/libgit2/TestGitRepository\n" + "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of https://github.com/libgit2/TestGitRepository\n" \ + "49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of https://github.com/libgit2/TestGitRepository\n" \ + "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of https://github.com/libgit2/TestGitRepository\n" \ + "d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of https://github.com/libgit2/TestGitRepository\n" \ + "55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of https://github.com/libgit2/TestGitRepository\n" \ + "8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of https://github.com/libgit2/TestGitRepository\n" \ + "6e0c7bdb9b4ed93212491ee778ca1c65047cab4e\tnot-for-merge\ttag 'nearly-dangling' of https://github.com/libgit2/TestGitRepository\n" #define FETCH_HEAD_NO_MERGE_DATA2 \ - "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \ - "49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \ - "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \ + "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of https://github.com/libgit2/TestGitRepository\n" \ + "49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of https://github.com/libgit2/TestGitRepository\n" \ + "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of https://github.com/libgit2/TestGitRepository\n" \ #define FETCH_HEAD_NO_MERGE_DATA3 \ - "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" \ - "49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of git://github.com/libgit2/TestGitRepository\n" \ - "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of git://github.com/libgit2/TestGitRepository\n" \ - "8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of git://github.com/libgit2/TestGitRepository\n" \ + "0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of https://github.com/libgit2/TestGitRepository\n" \ + "49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of https://github.com/libgit2/TestGitRepository\n" \ + "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of https://github.com/libgit2/TestGitRepository\n" \ + "8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of https://github.com/libgit2/TestGitRepository\n" \ #define FETCH_HEAD_EXPLICIT_DATA \ - "0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n" + "0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first-merge' of https://github.com/libgit2/TestGitRepository\n" #define FETCH_HEAD_QUOTE_DATA \ - "0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first's-merge' of git://github.com/libgit2/TestGitRepository\n" + "0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first's-merge' of https://github.com/libgit2/TestGitRepository\n" diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c index ab31d361021..aadcc788027 100644 --- a/tests/fetchhead/nonetwork.c +++ b/tests/fetchhead/nonetwork.c @@ -33,42 +33,42 @@ static void populate_fetchhead(git_vector *out, git_repository *repo) "49322bb17d3acc9146f98c97d078513228bbf3c0")); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 1, "refs/heads/master", - "git://github.com/libgit2/TestGitRepository")); + "https://github.com/libgit2/TestGitRepository")); cl_git_pass(git_vector_insert(out, fetchhead_ref)); cl_git_pass(git_oid_fromstr(&oid, "0966a434eb1a025db6b71485ab63a3bfbea520b6")); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0, "refs/heads/first-merge", - "git://github.com/libgit2/TestGitRepository")); + "https://github.com/libgit2/TestGitRepository")); cl_git_pass(git_vector_insert(out, fetchhead_ref)); cl_git_pass(git_oid_fromstr(&oid, "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1")); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0, "refs/heads/no-parent", - "git://github.com/libgit2/TestGitRepository")); + "https://github.com/libgit2/TestGitRepository")); cl_git_pass(git_vector_insert(out, fetchhead_ref)); cl_git_pass(git_oid_fromstr(&oid, "d96c4e80345534eccee5ac7b07fc7603b56124cb")); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0, "refs/tags/annotated_tag", - "git://github.com/libgit2/TestGitRepository")); + "https://github.com/libgit2/TestGitRepository")); cl_git_pass(git_vector_insert(out, fetchhead_ref)); cl_git_pass(git_oid_fromstr(&oid, "55a1a760df4b86a02094a904dfa511deb5655905")); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0, "refs/tags/blob", - "git://github.com/libgit2/TestGitRepository")); + "https://github.com/libgit2/TestGitRepository")); cl_git_pass(git_vector_insert(out, fetchhead_ref)); cl_git_pass(git_oid_fromstr(&oid, "8f50ba15d49353813cc6e20298002c0d17b0a9ee")); cl_git_pass(git_fetchhead_ref_create(&fetchhead_ref, &oid, 0, "refs/tags/commit_tree", - "git://github.com/libgit2/TestGitRepository")); + "https://github.com/libgit2/TestGitRepository")); cl_git_pass(git_vector_insert(out, fetchhead_ref)); cl_git_pass(git_fetchhead_write(repo, out)); diff --git a/tests/online/fetch.c b/tests/online/fetch.c index e09d338ceb1..2be96839d6e 100644 --- a/tests/online/fetch.c +++ b/tests/online/fetch.c @@ -74,11 +74,6 @@ static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n) git_remote_free(remote); } -void test_online_fetch__default_git(void) -{ - do_fetch("git://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6); -} - void test_online_fetch__default_http(void) { do_fetch("http://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, 6); @@ -91,7 +86,7 @@ void test_online_fetch__default_https(void) void test_online_fetch__no_tags_git(void) { - do_fetch("git://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_NONE, 3); + do_fetch("https://github.com/libgit2/TestGitRepository.git", GIT_REMOTE_DOWNLOAD_TAGS_NONE, 3); } void test_online_fetch__no_tags_http(void) @@ -102,7 +97,7 @@ void test_online_fetch__no_tags_http(void) void test_online_fetch__fetch_twice(void) { git_remote *remote; - cl_git_pass(git_remote_create(&remote, _repo, "test", "git://github.com/libgit2/TestGitRepository.git")); + cl_git_pass(git_remote_create(&remote, _repo, "test", "https://github.com/libgit2/TestGitRepository.git")); cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL)); cl_git_pass(git_remote_download(remote, NULL, NULL)); git_remote_disconnect(remote); diff --git a/tests/online/fetchhead.c b/tests/online/fetchhead.c index 30cce3a90ee..1b66c528e97 100644 --- a/tests/online/fetchhead.c +++ b/tests/online/fetchhead.c @@ -5,7 +5,7 @@ #include "../fetchhead/fetchhead_data.h" #include "git2/clone.h" -#define LIVE_REPO_URL "git://github.com/libgit2/TestGitRepository" +#define LIVE_REPO_URL "https://github.com/libgit2/TestGitRepository" static git_repository *g_repo; static git_clone_options g_options; @@ -53,7 +53,6 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet git_remote *remote; git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT; git_str fetchhead_buf = GIT_STR_INIT; - int equals = 0; git_strarray array, *active_refs = NULL; cl_git_pass(git_remote_lookup(&remote, g_repo, "origin")); @@ -70,11 +69,8 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet cl_git_pass(git_futils_readbuffer(&fetchhead_buf, "./foo/.git/FETCH_HEAD")); - equals = (strcmp(fetchhead_buf.ptr, expected_fetchhead) == 0); - + cl_assert_equal_s(fetchhead_buf.ptr, expected_fetchhead); git_str_dispose(&fetchhead_buf); - - cl_assert(equals); } void test_online_fetchhead__wildcard_spec(void) diff --git a/tests/online/remotes.c b/tests/online/remotes.c index f7fe4142ff4..887874d9285 100644 --- a/tests/online/remotes.c +++ b/tests/online/remotes.c @@ -1,6 +1,6 @@ #include "clar_libgit2.h" -#define URL "git://github.com/libgit2/TestGitRepository" +#define URL "https://github.com/libgit2/TestGitRepository" #define REFSPEC "refs/heads/first-merge:refs/remotes/origin/first-merge" static int remote_single_branch(git_remote **out, git_repository *repo, const char *name, const char *url, void *payload) From 3db53eb1a2e9116c7566913fa6384e73c9ba4967 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 10 Jan 2022 21:10:49 -0500 Subject: [PATCH 0734/1616] common: update the error checking macros --- src/common.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/common.h b/src/common.h index 640f948067b..549bddb5932 100644 --- a/src/common.h +++ b/src/common.h @@ -121,12 +121,16 @@ /** * Check a pointer allocation result, returning -1 if it failed. */ -#define GIT_ERROR_CHECK_ALLOC(ptr) if (ptr == NULL) { return -1; } +#define GIT_ERROR_CHECK_ALLOC(ptr) do { \ + if ((ptr) == NULL) { return -1; } \ + } while(0) /** * Check a string buffer allocation result, returning -1 if it failed. */ -#define GIT_ERROR_CHECK_ALLOC_STR(buf) if ((void *)(buf) == NULL || git_str_oom(buf)) { return -1; } +#define GIT_ERROR_CHECK_ALLOC_STR(buf) do { \ + if ((void *)(buf) == NULL || git_str_oom(buf)) { return -1; } \ + } while(0) /** * Check a return value and propagate result if non-zero. From e2bda60a524fef857763ce8605b0be277ef12f37 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 10 Jan 2022 21:12:13 -0500 Subject: [PATCH 0735/1616] url: introduce git_net_url_parse_scp Provide a mechanism for parsing scp-style paths (eg `git@github.com:libgit2/libgit2` into the url form `ssh://git@github.com/libgit2/libgit2`.) --- src/net.c | 189 +++++++++++++++++++++++ src/net.h | 5 +- src/transports/ssh.c | 38 +---- tests/network/url/scp.c | 321 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 515 insertions(+), 38 deletions(-) create mode 100644 tests/network/url/scp.c diff --git a/src/net.c b/src/net.c index 79c3fcd2874..1d4a3916bf0 100644 --- a/src/net.c +++ b/src/net.c @@ -192,6 +192,195 @@ int git_net_url_parse(git_net_url *url, const char *given) return error; } +static int scp_invalid(const char *message) +{ + git_error_set(GIT_ERROR_NET, "invalid scp-style path: %s", message); + return GIT_EINVALIDSPEC; +} + +static bool is_ipv6(const char *str) +{ + const char *c; + size_t colons = 0; + + if (*str++ != '[') + return false; + + for (c = str; *c; c++) { + if (*c == ':') + colons++; + + if (*c == ']') + return (colons > 1); + + if (*c != ':' && + (*c < '0' || *c > '9') && + (*c < 'a' || *c > 'f') && + (*c < 'A' || *c > 'F')) + return false; + } + + return false; +} + +static bool has_at(const char *str) +{ + const char *c; + + for (c = str; *c; c++) { + if (*c == '@') + return true; + + if (*c == ':') + break; + } + + return false; +} + +int git_net_url_parse_scp(git_net_url *url, const char *given) +{ + const char *default_port = default_port_for_scheme("ssh"); + const char *c, *user, *host, *port, *path = NULL; + size_t user_len = 0, host_len = 0, port_len = 0; + unsigned short bracket = 0; + + enum { + NONE, + USER, + HOST_START, HOST, HOST_END, + IPV6, IPV6_END, + PORT_START, PORT, PORT_END, + PATH_START + } state = NONE; + + memset(url, 0, sizeof(git_net_url)); + + for (c = given; *c && !path; c++) { + switch (state) { + case NONE: + switch (*c) { + case '@': + return scp_invalid("unexpected '@'"); + case ':': + return scp_invalid("unexpected ':'"); + case '[': + if (is_ipv6(c)) { + state = IPV6; + host = c; + } else if (bracket++ > 1) { + return scp_invalid("unexpected '['"); + } + break; + default: + if (has_at(c)) { + state = USER; + user = c; + } else { + state = HOST; + host = c; + } + break; + } + break; + + case USER: + if (*c == '@') { + user_len = (c - user); + state = HOST_START; + } + break; + + case HOST_START: + state = (*c == '[') ? IPV6 : HOST; + host = c; + break; + + case HOST: + if (*c == ':') { + host_len = (c - host); + state = bracket ? PORT_START : PATH_START; + } else if (*c == ']') { + if (bracket-- == 0) + return scp_invalid("unexpected ']'"); + + host_len = (c - host); + state = HOST_END; + } + break; + + case HOST_END: + if (*c != ':') + return scp_invalid("unexpected character after hostname"); + state = PATH_START; + break; + + case IPV6: + if (*c == ']') + state = IPV6_END; + break; + + case IPV6_END: + if (*c != ':') + return scp_invalid("unexpected character after ipv6 address"); + + host_len = (c - host); + state = bracket ? PORT_START : PATH_START; + break; + + case PORT_START: + port = c; + state = PORT; + break; + + case PORT: + if (*c == ']') { + if (bracket-- == 0) + return scp_invalid("unexpected ']'"); + + port_len = c - port; + state = PORT_END; + } + break; + + case PORT_END: + if (*c != ':') + return scp_invalid("unexpected character after ipv6 address"); + + state = PATH_START; + break; + + case PATH_START: + path = c; + break; + + default: + GIT_ASSERT("unhandled state"); + } + } + + if (!path) + return scp_invalid("path is required"); + + GIT_ERROR_CHECK_ALLOC(url->scheme = git__strdup("ssh")); + + if (user_len) + GIT_ERROR_CHECK_ALLOC(url->username = git__strndup(user, user_len)); + + GIT_ASSERT(host_len); + GIT_ERROR_CHECK_ALLOC(url->host = git__strndup(host, host_len)); + + if (port_len) + GIT_ERROR_CHECK_ALLOC(url->port = git__strndup(port, port_len)); + else + GIT_ERROR_CHECK_ALLOC(url->port = git__strdup(default_port)); + + GIT_ASSERT(path); + GIT_ERROR_CHECK_ALLOC(url->path = git__strdup(path)); + + return 0; +} + int git_net_url_joinpath( git_net_url *out, git_net_url *one, diff --git a/src/net.h b/src/net.h index c743974097e..739769a39dd 100644 --- a/src/net.h +++ b/src/net.h @@ -24,9 +24,12 @@ typedef struct git_net_url { /** Duplicate a URL */ extern int git_net_url_dup(git_net_url *out, git_net_url *in); -/** Parses a string containing a URL into a structure. */ +/** Parses a string containing a URL into a structure. */ extern int git_net_url_parse(git_net_url *url, const char *str); +/** Parses a string containing an SCP style path into a URL structure. */ +extern int git_net_url_parse_scp(git_net_url *url, const char *str); + /** Appends a path and/or query string to the given URL */ extern int git_net_url_joinpath( git_net_url *out, diff --git a/src/transports/ssh.c b/src/transports/ssh.c index f37bf70bbe8..0f4a0fcc5dd 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -258,37 +258,6 @@ static int ssh_stream_alloc( return 0; } -static int git_ssh_extract_url_parts( - git_net_url *urldata, - const char *url) -{ - char *colon, *at; - const char *start; - - colon = strchr(url, ':'); - - - at = strchr(url, '@'); - if (at) { - start = at + 1; - urldata->username = git__substrdup(url, at - url); - GIT_ERROR_CHECK_ALLOC(urldata->username); - } else { - start = url; - urldata->username = NULL; - } - - if (colon == NULL || (colon < start)) { - git_error_set(GIT_ERROR_NET, "malformed URL"); - return -1; - } - - urldata->host = git__substrdup(start, colon - start); - GIT_ERROR_CHECK_ALLOC(urldata->host); - - return 0; -} - static int ssh_agent_auth(LIBSSH2_SESSION *session, git_credential_ssh_key *c) { int rc = LIBSSH2_ERROR_NONE; @@ -546,14 +515,9 @@ static int _git_ssh_setup_conn( goto post_extract; } } - if ((error = git_ssh_extract_url_parts(&urldata, url)) < 0) + if ((error = git_net_url_parse_scp(&urldata, url)) < 0) goto done; - if (urldata.port == NULL) - urldata.port = git__strdup(SSH_DEFAULT_PORT); - - GIT_ERROR_CHECK_ALLOC(urldata.port); - post_extract: if ((error = git_socket_stream_new(&s->io, urldata.host, urldata.port)) < 0 || (error = git_stream_connect(s->io)) < 0) diff --git a/tests/network/url/scp.c b/tests/network/url/scp.c new file mode 100644 index 00000000000..8cdc832ae30 --- /dev/null +++ b/tests/network/url/scp.c @@ -0,0 +1,321 @@ +#include "clar_libgit2.h" +#include "net.h" + +static git_net_url conndata; + +void test_network_url_scp__initialize(void) +{ + memset(&conndata, 0, sizeof(conndata)); +} + +void test_network_url_scp__cleanup(void) +{ + git_net_url_dispose(&conndata); +} + +/* Hostname */ + +void test_network_url_scp__hostname_trivial(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "example.com:/resource")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "example.com"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__hostname_bracketed(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[example.com]:/resource")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "example.com"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__hostname_root(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "example.com:/")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "example.com"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "/"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__hostname_user(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "git@example.com:/resource")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "example.com"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "git"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__hostname_user_bracketed(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[git@example.com]:/resource")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "example.com"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "git"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__hostname_port(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[example.com:42]:/resource")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "example.com"); + cl_assert_equal_s(conndata.port, "42"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_network_url_scp__hostname_user_port(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[git@example.com:42]:/resource")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "example.com"); + cl_assert_equal_s(conndata.port, "42"); + cl_assert_equal_s(conndata.path, "/resource"); + cl_assert_equal_s(conndata.username, "git"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_network_url_scp__ipv4_trivial(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "192.168.99.88:/resource/a/b/c")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "192.168.99.88"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "/resource/a/b/c"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__ipv4_bracketed(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[192.168.99.88]:/resource/a/b/c")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "192.168.99.88"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "/resource/a/b/c"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__ipv4_user(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "git@192.168.99.88:/resource/a/b/c")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "192.168.99.88"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "/resource/a/b/c"); + cl_assert_equal_s(conndata.username, "git"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__ipv4_port(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[192.168.99.88:1111]:/resource/a/b/c")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "192.168.99.88"); + cl_assert_equal_s(conndata.port, "1111"); + cl_assert_equal_s(conndata.path, "/resource/a/b/c"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_network_url_scp__ipv4_user_port(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[git@192.168.99.88:1111]:/resource/a/b/c")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "192.168.99.88"); + cl_assert_equal_s(conndata.port, "1111"); + cl_assert_equal_s(conndata.path, "/resource/a/b/c"); + cl_assert_equal_s(conndata.username, "git"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_network_url_scp__ipv6_trivial(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[fe80::dcad:beff:fe00:0001]:/resource/foo")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "/resource/foo"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__ipv6_user(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "git@[fe80::dcad:beff:fe00:0001]:/resource/foo")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "/resource/foo"); + cl_assert_equal_s(conndata.username, "git"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__ipv6_port(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[[fe80::dcad:beff:fe00:0001]:99]:/resource/foo")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); + cl_assert_equal_s(conndata.port, "99"); + cl_assert_equal_s(conndata.path, "/resource/foo"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_network_url_scp__ipv6_user_port(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[git@[fe80::dcad:beff:fe00:0001]:99]:/resource/foo")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); + cl_assert_equal_s(conndata.port, "99"); + cl_assert_equal_s(conndata.path, "/resource/foo"); + cl_assert_equal_s(conndata.username, "git"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0); +} + +void test_network_url_scp__hexhost_and_port(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[fe:22]:/resource/foo")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "fe"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "/resource/foo"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__malformed_ipv6_one(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "fe80::dcad:beff:fe00:0001]:/resource")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "fe80"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, ":dcad:beff:fe00:0001]:/resource"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__malformed_ipv6_two(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "[fe80::dcad:beff:fe00:0001]:42]:/resource")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "42]:/resource"); + cl_assert_equal_p(conndata.username, NULL); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__malformed_ipv6_with_user(void) +{ + cl_git_pass(git_net_url_parse_scp(&conndata, "git@[fe80::dcad:beff:fe00:0001]:42]:/resource")); + cl_assert_equal_s(conndata.scheme, "ssh"); + cl_assert_equal_s(conndata.host, "[fe80::dcad:beff:fe00:0001]"); + cl_assert_equal_s(conndata.port, "22"); + cl_assert_equal_s(conndata.path, "42]:/resource"); + cl_assert_equal_s(conndata.username, "git"); + cl_assert_equal_p(conndata.password, NULL); + cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1); +} + +void test_network_url_scp__invalid_addresses(void) +{ + /* Path is required */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "example.com")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "example.com:")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[example.com:42]:")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[git@example.com:42]:")); + + /* Host is required */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + ":")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + ":foo")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "git@:foo")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[]:")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "git@[]:")); + + /* User is required if specified */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "@example.com:foo")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "@:foo")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[@localhost:22]:foo")); + + /* Port is required in brackets */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[example.com:]:foo")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[git@example.com:]:foo")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[fe:]:foo")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[@localhost]:foo")); + + /* Extra brackets are disallowed */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[git@[[fe80::dcad:beff:fe00:0001]]:42]:foo")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[[git@[fe80::dcad:beff:fe00:0001]]:42]:foo")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[[git@[fe80::dcad:beff:fe00:0001]:42]]:foo")); + + /* Closing bracket missing */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[fe80::dcad:beff:fe00:0001:/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[[fe80::dcad:beff:fe00:0001]:42:/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[git@[fe80::dcad:beff:fe00:0001]:42:/resource")); + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse_scp(&conndata, + "[git@[fe80::dcad:beff:fe00:0001:42]:/resource")); + + /* Invalid character inside address */ + cl_git_fail_with(GIT_EINVALIDSPEC, git_net_url_parse(&conndata, + "[fe8o::dcad:beff:fe00:0001]:/resource")); +} From 6913422323a5df43020eeb8bd05cb7780228ecc2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 10 Jan 2022 21:14:40 -0500 Subject: [PATCH 0736/1616] ci: test `[user@host:port]:path` formats --- ci/test.sh | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/ci/test.sh b/ci/test.sh index 0dc43aa876c..a9483977883 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -300,18 +300,28 @@ if [ -z "$SKIP_NEGOTIATE_TESTS" -a -n "$GITTEST_NEGOTIATE_PASSWORD" ]; then fi if [ -z "$SKIP_SSH_TESTS" ]; then - echo "" - echo "Running ssh tests" - echo "" - - export GITTEST_REMOTE_URL="ssh://localhost:2222/$SSHD_DIR/test.git" export GITTEST_REMOTE_USER=$USER export GITTEST_REMOTE_SSH_KEY="${HOME}/.ssh/id_rsa" export GITTEST_REMOTE_SSH_PUBKEY="${HOME}/.ssh/id_rsa.pub" export GITTEST_REMOTE_SSH_PASSPHRASE="" export GITTEST_REMOTE_SSH_FINGERPRINT="${SSH_FINGERPRINT}" + + echo "" + echo "Running ssh tests" + echo "" + + export GITTEST_REMOTE_URL="ssh://localhost:2222/$SSHD_DIR/test.git" run_test ssh unset GITTEST_REMOTE_URL + + echo "" + echo "Running ssh tests (scp-style paths)" + echo "" + + export GITTEST_REMOTE_URL="[localhost:2222]:$SSHD_DIR/test.git" + run_test ssh + unset GITTEST_REMOTE_URL + unset GITTEST_REMOTE_USER unset GITTEST_REMOTE_SSH_KEY unset GITTEST_REMOTE_SSH_PUBKEY From e02e6a5cd2484129e88447b2efb061c228a035d2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 11 Jan 2022 10:19:40 -0500 Subject: [PATCH 0737/1616] url: introduce git_net_str_is_url We occasionally need to determine whether a given string is a URL or something else. (The "something else" may be a git path in a different format, like scp formatting, which needs to be handled differently.) --- src/net.c | 22 +++++++++++++++++++++- src/net.h | 3 +++ tests/network/url/valid.c | 17 +++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 tests/network/url/valid.c diff --git a/src/net.c b/src/net.c index 1d4a3916bf0..a76fd1d7c5b 100644 --- a/src/net.c +++ b/src/net.c @@ -20,6 +20,24 @@ #define DEFAULT_PORT_GIT "9418" #define DEFAULT_PORT_SSH "22" +bool git_net_str_is_url(const char *str) +{ + const char *c; + + for (c = str; *c; c++) { + if (*c == ':' && *(c+1) == '/' && *(c+2) == '/') + return true; + + if ((*c < 'a' || *c > 'z') && + (*c < 'A' || *c > 'Z') && + (*c < '0' || *c > '9') && + (*c != '+' && *c != '-' && *c != '.')) + break; + } + + return false; +} + static const char *default_port_for_scheme(const char *scheme) { if (strcmp(scheme, "http") == 0) @@ -28,7 +46,9 @@ static const char *default_port_for_scheme(const char *scheme) return DEFAULT_PORT_HTTPS; else if (strcmp(scheme, "git") == 0) return DEFAULT_PORT_GIT; - else if (strcmp(scheme, "ssh") == 0) + else if (strcmp(scheme, "ssh") == 0 || + strcmp(scheme, "ssh+git") == 0 || + strcmp(scheme, "git+ssh") == 0) return DEFAULT_PORT_SSH; return NULL; diff --git a/src/net.h b/src/net.h index 739769a39dd..499315e6ce2 100644 --- a/src/net.h +++ b/src/net.h @@ -21,6 +21,9 @@ typedef struct git_net_url { #define GIT_NET_URL_INIT { NULL } +/** Is a given string a url? */ +extern bool git_net_str_is_url(const char *str); + /** Duplicate a URL */ extern int git_net_url_dup(git_net_url *out, git_net_url *in); diff --git a/tests/network/url/valid.c b/tests/network/url/valid.c new file mode 100644 index 00000000000..2b2cb7ba411 --- /dev/null +++ b/tests/network/url/valid.c @@ -0,0 +1,17 @@ +#include "clar_libgit2.h" +#include "net.h" + +void test_network_url_valid__test(void) +{ + cl_assert(git_net_str_is_url("http://example.com/")); + cl_assert(git_net_str_is_url("file://localhost/tmp/foo/")); + cl_assert(git_net_str_is_url("ssh://user@host:42/tmp")); + cl_assert(git_net_str_is_url("git+ssh://user@host:42/tmp")); + cl_assert(git_net_str_is_url("ssh+git://user@host:42/tmp")); + cl_assert(git_net_str_is_url("https://user:pass@example.com/foo/bar")); + + cl_assert(!git_net_str_is_url("host:foo.git")); + cl_assert(!git_net_str_is_url("host:/foo.git")); + cl_assert(!git_net_str_is_url("[host:42]:/foo.git")); + cl_assert(!git_net_str_is_url("[user@host:42]:/foo.git")); +} From 27307ed6c0071dbf6b670e657dba41564b692ad2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 11 Jan 2022 10:39:57 -0500 Subject: [PATCH 0738/1616] ssh: use url parsing functionality Instead of trying to figure out a repo's path from a URL by hand, parse a URL using the parsing functionality. --- src/transports/ssh.c | 87 +++++++++++++------------------------------- 1 file changed, 26 insertions(+), 61 deletions(-) diff --git a/src/transports/ssh.c b/src/transports/ssh.c index 0f4a0fcc5dd..75b8e8b8166 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -24,8 +24,6 @@ #define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport) -static const char *ssh_prefixes[] = { "ssh://", "ssh+git://", "git+ssh://" }; - static const char cmd_uploadpack[] = "git-upload-pack"; static const char cmd_receivepack[] = "git-receive-pack"; @@ -35,7 +33,7 @@ typedef struct { LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; const char *cmd; - char *url; + git_net_url url; unsigned sent_command : 1; } ssh_stream; @@ -63,39 +61,23 @@ static void ssh_error(LIBSSH2_SESSION *session, const char *errmsg) * * For example: git-upload-pack '/libgit2/libgit2' */ -static int gen_proto(git_str *request, const char *cmd, const char *url) +static int gen_proto(git_str *request, const char *cmd, git_net_url *url) { const char *repo; - int len; - size_t i; - - for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) { - const char *p = ssh_prefixes[i]; - if (!git__prefixcmp(url, p)) { - url = url + strlen(p); - repo = strchr(url, '/'); - if (repo && repo[1] == '~') - ++repo; + repo = url->path; - goto done; - } - } - repo = strchr(url, ':'); - if (repo) repo++; + if (repo && repo[0] == '/' && repo[1] == '~') + repo++; -done: - if (!repo) { + if (!repo || !repo[0]) { git_error_set(GIT_ERROR_NET, "malformed git protocol URL"); return -1; } - len = strlen(cmd) + 1 /* Space */ + 1 /* Quote */ + strlen(repo) + 1 /* Quote */ + 1; - - git_str_grow(request, len); git_str_puts(request, cmd); git_str_puts(request, " '"); - git_str_decode_percent(request, repo, strlen(repo)); + git_str_puts(request, repo); git_str_puts(request, "'"); if (git_str_oom(request)) @@ -109,7 +91,7 @@ static int send_command(ssh_stream *s) int error; git_str request = GIT_STR_INIT; - error = gen_proto(&request, s->cmd, s->url); + error = gen_proto(&request, s->cmd, &s->url); if (error < 0) goto cleanup; @@ -224,13 +206,12 @@ static void ssh_stream_free(git_smart_subtransport_stream *stream) s->io = NULL; } - git__free(s->url); + git_net_url_dispose(&s->url); git__free(s); } static int ssh_stream_alloc( ssh_subtransport *t, - const char *url, const char *cmd, git_smart_subtransport_stream **stream) { @@ -248,12 +229,6 @@ static int ssh_stream_alloc( s->cmd = cmd; - s->url = git__strdup(url); - if (!s->url) { - git__free(s); - return -1; - } - *stream = &s->parent; return 0; } @@ -487,9 +462,7 @@ static int _git_ssh_setup_conn( const char *cmd, git_smart_subtransport_stream **stream) { - git_net_url urldata = GIT_NET_URL_INIT; int auth_methods, error = 0; - size_t i; ssh_stream *s; git_credential *cred = NULL; LIBSSH2_SESSION *session=NULL; @@ -498,28 +471,22 @@ static int _git_ssh_setup_conn( t->current_stream = NULL; *stream = NULL; - if (ssh_stream_alloc(t, url, cmd, stream) < 0) + if (ssh_stream_alloc(t, cmd, stream) < 0) return -1; s = (ssh_stream *)*stream; s->session = NULL; s->channel = NULL; - for (i = 0; i < ARRAY_SIZE(ssh_prefixes); ++i) { - const char *p = ssh_prefixes[i]; - - if (!git__prefixcmp(url, p)) { - if ((error = git_net_url_parse(&urldata, url)) < 0) - goto done; + if (git_net_str_is_url(url)) + error = git_net_url_parse(&s->url, url); + else + error = git_net_url_parse_scp(&s->url, url); - goto post_extract; - } - } - if ((error = git_net_url_parse_scp(&urldata, url)) < 0) + if (error < 0) goto done; -post_extract: - if ((error = git_socket_stream_new(&s->io, urldata.host, urldata.port)) < 0 || + if ((error = git_socket_stream_new(&s->io, s->url.host, s->url.port)) < 0 || (error = git_stream_connect(s->io)) < 0) goto done; @@ -603,7 +570,7 @@ static int _git_ssh_setup_conn( error = t->owner->connect_opts.callbacks.certificate_check( (git_cert *)cert_ptr, 0, - urldata.host, + s->url.host, t->owner->connect_opts.callbacks.payload); if (error < 0 && error != GIT_PASSTHROUGH) { @@ -615,21 +582,21 @@ static int _git_ssh_setup_conn( } /* we need the username to ask for auth methods */ - if (!urldata.username) { + if (!s->url.username) { if ((error = request_creds(&cred, t, NULL, GIT_CREDENTIAL_USERNAME)) < 0) goto done; - urldata.username = git__strdup(((git_credential_username *) cred)->username); + s->url.username = git__strdup(((git_credential_username *) cred)->username); cred->free(cred); cred = NULL; - if (!urldata.username) + if (!s->url.username) goto done; - } else if (urldata.username && urldata.password) { - if ((error = git_credential_userpass_plaintext_new(&cred, urldata.username, urldata.password)) < 0) + } else if (s->url.username && s->url.password) { + if ((error = git_credential_userpass_plaintext_new(&cred, s->url.username, s->url.password)) < 0) goto done; } - if ((error = list_auth_methods(&auth_methods, session, urldata.username)) < 0) + if ((error = list_auth_methods(&auth_methods, session, s->url.username)) < 0) goto done; error = GIT_EAUTH; @@ -643,10 +610,10 @@ static int _git_ssh_setup_conn( cred = NULL; } - if ((error = request_creds(&cred, t, urldata.username, auth_methods)) < 0) + if ((error = request_creds(&cred, t, s->url.username, auth_methods)) < 0) goto done; - if (strcmp(urldata.username, git_credential_get_username(cred))) { + if (strcmp(s->url.username, git_credential_get_username(cred))) { git_error_set(GIT_ERROR_SSH, "username does not match previous request"); error = -1; goto done; @@ -656,7 +623,7 @@ static int _git_ssh_setup_conn( if (error == GIT_EAUTH) { /* refresh auth methods */ - if ((error = list_auth_methods(&auth_methods, session, urldata.username)) < 0) + if ((error = list_auth_methods(&auth_methods, session, s->url.username)) < 0) goto done; else error = GIT_EAUTH; @@ -691,8 +658,6 @@ static int _git_ssh_setup_conn( if (cred) cred->free(cred); - git_net_url_dispose(&urldata); - return error; } From d4232e7c91da8365910e3cb947626f3426472330 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 17 Jan 2022 21:21:54 -0500 Subject: [PATCH 0739/1616] Apply suggestions from code review --- include/git2/attr.h | 2 +- include/git2/branch.h | 2 +- include/git2/commit.h | 2 +- include/git2/config.h | 6 +++--- include/git2/indexer.h | 3 +-- include/git2/object.h | 2 +- include/git2/odb.h | 2 +- include/git2/rebase.h | 2 +- include/git2/repository.h | 2 +- include/git2/revwalk.h | 4 ++-- 10 files changed, 13 insertions(+), 14 deletions(-) diff --git a/include/git2/attr.h b/include/git2/attr.h index c93055083b0..66100dff1c5 100644 --- a/include/git2/attr.h +++ b/include/git2/attr.h @@ -354,7 +354,7 @@ GIT_EXTERN(int) git_attr_cache_flush( * * git_attr_add_macro(repo, "binary", "-diff -crlf"); * - * @param repo The repository where to add the macro. + * @param repo The repository to add the macro in. * @param name The name of the macro. * @param values The value for the macro. * @return 0 or an error code. diff --git a/include/git2/branch.h b/include/git2/branch.h index d33a24f72ce..36a393d108f 100644 --- a/include/git2/branch.h +++ b/include/git2/branch.h @@ -34,7 +34,7 @@ GIT_BEGIN_DECL * * @param out Pointer where to store the underlying reference. * - * @param repo the repository where to create the branch. + * @param repo the repository to create the branch in. * * @param branch_name Name for the branch; this name is * validated for consistency. It should also not conflict with diff --git a/include/git2/commit.h b/include/git2/commit.h index 2181a7d7efa..67170cb9c83 100644 --- a/include/git2/commit.h +++ b/include/git2/commit.h @@ -479,7 +479,7 @@ GIT_EXTERN(int) git_commit_create_buffer( * to the commit and write it into the given repository. * * @param out the resulting commit id - * @param repo the repository where to create the commit. + * @param repo the repository to create the commit in. * @param commit_content the content of the unsigned commit object * @param signature the signature to add to the commit. Leave `NULL` * to create a commit without adding a signature field. diff --git a/include/git2/config.h b/include/git2/config.h index 07e0093b58f..a5486a4c97d 100644 --- a/include/git2/config.h +++ b/include/git2/config.h @@ -426,7 +426,7 @@ GIT_EXTERN(int) git_config_get_string_buf(git_buf *out, const git_config *cfg, c * interested in. Use NULL to indicate all * @param callback the function to be called on each value of the variable * @param payload opaque pointer to pass to the callback - * @return non-zero to terminate the iteration. + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_get_multivar_foreach(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload); @@ -442,7 +442,7 @@ GIT_EXTERN(int) git_config_get_multivar_foreach(const git_config *cfg, const cha * @param name the variable's name * @param regexp regular expression to filter which variables we're * interested in. Use NULL to indicate all - * @return non-zero to terminate the iteration. + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_multivar_iterator_new(git_config_iterator **out, const git_config *cfg, const char *name, const char *regexp); @@ -750,7 +750,7 @@ GIT_EXTERN(int) git_config_parse_path(git_buf *out, const char *value); * @param regexp regular expression to match against config names (can be NULL) * @param callback the function to call on each variable * @param payload the data to pass to the callback - * @return non-zero to terminate the iteration. + * @return 0 or an error code. */ GIT_EXTERN(int) git_config_backend_foreach_match( git_config_backend *backend, diff --git a/include/git2/indexer.h b/include/git2/indexer.h index 8af02a6c03f..4bacbd3171f 100644 --- a/include/git2/indexer.h +++ b/include/git2/indexer.h @@ -136,8 +136,7 @@ GIT_EXTERN(int) git_indexer_commit(git_indexer *idx, git_indexer_progress *stats * names. This is only correct after the index has been finalized. * * @param idx the indexer instance - * @return the packfile's hash. In casewhere the index has not been finalized, - * it will be zeroed out. + * @return the packfile's hash */ GIT_EXTERN(const git_oid *) git_indexer_hash(const git_indexer *idx); diff --git a/include/git2/object.h b/include/git2/object.h index 2692a405645..5610a476f49 100644 --- a/include/git2/object.h +++ b/include/git2/object.h @@ -221,7 +221,7 @@ GIT_EXTERN(int) git_object_peel( * * @param dest Pointer to store the copy of the object * @param source Original object to copy - * @return 0 + * @return 0 or an error code */ GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source); diff --git a/include/git2/odb.h b/include/git2/odb.h index 7b8d6f96b94..effe2e546e1 100644 --- a/include/git2/odb.h +++ b/include/git2/odb.h @@ -348,7 +348,7 @@ GIT_EXTERN(int) git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stre * Most backends don't implement streaming reads * * @param stream the stream - * @param buffer the buffer where to store the readed data. + * @param buffer a user-allocated buffer to store the data in. * @param len the buffer's length * @return 0 if the read succeeded, error code otherwise */ diff --git a/include/git2/rebase.h b/include/git2/rebase.h index 5edd443d1f8..b1ac71f94ee 100644 --- a/include/git2/rebase.h +++ b/include/git2/rebase.h @@ -329,7 +329,7 @@ GIT_EXTERN(int) git_rebase_next( * * @param index The result index of the last operation. * @param rebase The in-progress rebase. - * @return 0 + * @return 0 or an error code */ GIT_EXTERN(int) git_rebase_inmemory_index( git_index **index, diff --git a/include/git2/repository.h b/include/git2/repository.h index 6692537d4e0..e276a8a2fdf 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -931,7 +931,7 @@ GIT_EXTERN(int) git_repository_is_shallow(git_repository *repo); * @param name where to store the pointer to the name * @param email where to store the pointer to the email * @param repo the repository - * @return 0 + * @return 0 or an error code */ GIT_EXTERN(int) git_repository_ident(const char **name, const char **email, const git_repository *repo); diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h index b8655e50fef..4aa9f5b1e0e 100644 --- a/include/git2/revwalk.h +++ b/include/git2/revwalk.h @@ -249,7 +249,7 @@ GIT_EXTERN(int) git_revwalk_push_range(git_revwalk *walk, const char *range); * * No parents other than the first for each commit will be enqueued. * - * @param walk The revisionwlaker. + * @param walk The revision walker. * @return 0 or an error code */ GIT_EXTERN(int) git_revwalk_simplify_first_parent(git_revwalk *walk); @@ -278,7 +278,7 @@ GIT_EXTERN(git_repository *) git_revwalk_repository(git_revwalk *walk); * * @param commit_id oid of Commit * @param payload User-specified pointer to data to be passed as data payload - * @return non-zero to hide the commmit and it parrent. + * @return non-zero to hide the commmit and it parent. */ typedef int GIT_CALLBACK(git_revwalk_hide_cb)( const git_oid *commit_id, From 7707caaf474eccc1112f62b9d86a6dd240917b58 Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Fri, 28 Jun 2019 16:42:21 +0200 Subject: [PATCH 0740/1616] Prevent possible buffer overflow Could happen if the path to git.exe is near to MAX_PATH and we append a longer subdir such as "share/git-core" to it. Signed-off-by: Sven Strickroth --- src/win32/findfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32/findfile.c b/src/win32/findfile.c index d4afc4acceb..e31ff972ee8 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -93,7 +93,7 @@ static int win32_find_git_in_path(git_str *buf, const wchar_t *gitexe, const wch continue; wcscpy(&root.path[root.len], gitexe); - if (_waccess(root.path, F_OK) == 0 && root.len > 5) { + if (_waccess(root.path, F_OK) == 0 && root.len > 5 && (root.len - 4 + wcslen(subdir) < MAX_PATH)) { /* replace "bin\\" or "cmd\\" with subdir */ wcscpy(&root.path[root.len - 4], subdir); From f64568ebcb8a5c5be9dcda2a016692edae42a507 Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Fri, 28 Jun 2019 16:49:58 +0200 Subject: [PATCH 0741/1616] Do not unconditionally remove the last 4 chars of the directory where git.exe was found Removal of the last 4 chars is only required for Git for Windows installations in order to find the "root" folder of the Git installation. Fixes issue #5127. Signed-off-by: Sven Strickroth --- src/win32/findfile.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/win32/findfile.c b/src/win32/findfile.c index e31ff972ee8..d5dba8c41be 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -93,9 +93,17 @@ static int win32_find_git_in_path(git_str *buf, const wchar_t *gitexe, const wch continue; wcscpy(&root.path[root.len], gitexe); - if (_waccess(root.path, F_OK) == 0 && root.len > 5 && (root.len - 4 + wcslen(subdir) < MAX_PATH)) { - /* replace "bin\\" or "cmd\\" with subdir */ - wcscpy(&root.path[root.len - 4], subdir); + if (!_waccess(root.path, F_OK)) { + /* replace "bin\\" or "cmd\\" of a Git for Windows installation with subdir OR append path */ + if ((root.len > 5 && wcscmp(root.path - 4, L"cmd\\")) || wcscmp(root.path - 4, L"bin\\")) { + if (root.len - 4 + wcslen(subdir) >= MAX_PATH) + continue; + wcscpy(&root.path[root.len - 4], subdir); + } else { + if (root.len + wcslen(subdir) >= MAX_PATH) + continue; + wcscat(root.path, subdir); + } win32_path_to_8(buf, root.path); return 0; From f3c1bedfa2e5564c60fd6910eace4a44abdf9777 Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Fri, 28 Jun 2019 17:05:57 +0200 Subject: [PATCH 0742/1616] Detect installed x64 versions of Git for Windows Signed-off-by: Sven Strickroth --- src/win32/findfile.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/win32/findfile.c b/src/win32/findfile.c index d5dba8c41be..0dcce148cac 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -191,6 +191,12 @@ int git_win32__find_system_dirs(git_str *out, const wchar_t *subdir) &buf, HKEY_CURRENT_USER, REG_MSYSGIT_INSTALL_LOCAL, subdir) && buf.size) git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); +#ifdef GIT_ARCH_64 + if (!win32_find_git_in_registry( + &buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL_LOCAL, subdir) && buf.size) + git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); +#endif + if (!win32_find_git_in_registry( &buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL, subdir) && buf.size) git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); From 7fd5dfa0fe22f4a91ce5f65c3fe643fbad37bdfd Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Sat, 25 Dec 2021 15:25:15 +0100 Subject: [PATCH 0743/1616] Correctly detect the share/template folder With Git for Windows >= 2 the share folder is in an architecture specific subfolder. This also add support for Git for Windows versions between 2 and 2.24 where also the etc folder is in an architecture specific subfolder. Signed-off-by: Sven Strickroth --- src/win32/findfile.c | 59 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/src/win32/findfile.c b/src/win32/findfile.c index 0dcce148cac..8975894faf9 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -70,6 +70,46 @@ static wchar_t *win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen) return (path != base) ? path : NULL; } +static int win32_find_git_for_windows_architecture_root(_findfile_path *root_path, const wchar_t *subdir) +{ + /* Git for Windows >= 2 comes with a special architecture root (mingw64 and mingw32) + * under which the "share" folder is located, check which we need (none is also ok) */ + + static const wchar_t *architecture_roots[4] = { + L"", // starting with Git 2.24 the etc folder is directly in the root folder + L"mingw64\\", + L"mingw32\\", + NULL, + }; + + const wchar_t **roots = architecture_roots; + for (; *roots != NULL; ++roots) { + git_win32_path tmp_root; + DWORD subdir_len; + if (wcscpy(tmp_root, root_path->path) && + root_path->len + wcslen(*roots) <= MAX_PATH && + wcscat(tmp_root, *roots) && + !_waccess(tmp_root, F_OK)) { + wcscpy(root_path->path, tmp_root); + root_path->len += (DWORD)wcslen(*roots); + + subdir_len = (DWORD)wcslen(subdir); + if (root_path->len + subdir_len >= MAX_PATH) + break; + + // append subdir and check whether it exists for the Git installation + wcscat(tmp_root, subdir); + if (!_waccess(tmp_root, F_OK)) { + wcscpy(root_path->path, tmp_root); + root_path->len += subdir_len; + break; + } + } + } + + return 0; +} + static int win32_find_git_in_path(git_str *buf, const wchar_t *gitexe, const wchar_t *subdir) { wchar_t *env = _wgetenv(L"PATH"), lastch; @@ -94,11 +134,13 @@ static int win32_find_git_in_path(git_str *buf, const wchar_t *gitexe, const wch wcscpy(&root.path[root.len], gitexe); if (!_waccess(root.path, F_OK)) { - /* replace "bin\\" or "cmd\\" of a Git for Windows installation with subdir OR append path */ + /* check whether we found a Git for Windows installation and do some path adjustments OR just append subdir */ if ((root.len > 5 && wcscmp(root.path - 4, L"cmd\\")) || wcscmp(root.path - 4, L"bin\\")) { - if (root.len - 4 + wcslen(subdir) >= MAX_PATH) + /* strip "bin" or "cmd" and try to find architecture root for appending subdir */ + root.len -= 4; + root.path[root.len] = L'\0'; + if (win32_find_git_for_windows_architecture_root(&root, subdir)) continue; - wcscpy(&root.path[root.len - 4], subdir); } else { if (root.len + wcslen(subdir) >= MAX_PATH) continue; @@ -123,22 +165,21 @@ static int win32_find_git_in_registry( if (!RegOpenKeyExW(hive, key, 0, KEY_READ, &hKey)) { DWORD dwType, cbData; - git_win32_path path; + _findfile_path path; /* Ensure that the buffer is big enough to have the suffix attached * after we receive the result. */ cbData = (DWORD)(sizeof(path) - wcslen(subdir) * sizeof(wchar_t)); /* InstallLocation points to the root of the git directory */ - if (!RegQueryValueExW(hKey, L"InstallLocation", NULL, &dwType, (LPBYTE)path, &cbData) && + if (!RegQueryValueExW(hKey, L"InstallLocation", NULL, &dwType, (LPBYTE)path.path, &cbData) && dwType == REG_SZ) { - - /* Append the suffix */ - wcscat(path, subdir); + path.len = cbData; /* Convert to UTF-8, with forward slashes, and output the path * to the provided buffer */ - if (!win32_path_to_8(buf, path)) + if (!win32_find_git_for_windows_architecture_root(&path, subdir) && + !win32_path_to_8(buf, path.path)) error = 0; } From 796fa0dd9ad3e31a526618681489bac184da8ae0 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 16 Jan 2022 20:19:07 +0000 Subject: [PATCH 0744/1616] sysdir: allow resetting cached system dirs --- src/sysdir.c | 16 ++++++++++++++++ src/sysdir.h | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/src/sysdir.c b/src/sysdir.c index 84d212e01f1..c0e14f551bd 100644 --- a/src/sysdir.c +++ b/src/sysdir.c @@ -189,9 +189,25 @@ int git_sysdir_global_init(void) for (i = 0; !error && i < ARRAY_SIZE(git_sysdir__dirs); i++) error = git_sysdir__dirs[i].guess(&git_sysdir__dirs[i].buf); + if (error) + return error; + return git_runtime_shutdown_register(git_sysdir_global_shutdown); } +int git_sysdir_reset(void) +{ + size_t i; + int error = 0; + + for (i = 0; !error && i < ARRAY_SIZE(git_sysdir__dirs); ++i) { + git_str_dispose(&git_sysdir__dirs[i].buf); + error = git_sysdir__dirs[i].guess(&git_sysdir__dirs[i].buf); + } + + return error; +} + static int git_sysdir_check_selector(git_sysdir_t which) { if (which < ARRAY_SIZE(git_sysdir__dirs)) diff --git a/src/sysdir.h b/src/sysdir.h index 43392a0226c..568f27940c8 100644 --- a/src/sysdir.h +++ b/src/sysdir.h @@ -105,4 +105,9 @@ extern int git_sysdir_get(const git_str **out, git_sysdir_t which); */ extern int git_sysdir_set(git_sysdir_t which, const char *paths); +/** + * Reset search paths for global/system/xdg files. + */ +extern int git_sysdir_reset(void); + #endif From ecbb01f52ceddbbe7422aabcc3c5e1de96f6a1c9 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 17 Jan 2022 00:09:13 +0000 Subject: [PATCH 0745/1616] win32: test system paths for gvfs compatibility --- src/win32/findfile.c | 78 ++++++++++++++++++++++------------ src/win32/findfile.h | 1 + tests/win32/systempath.c | 91 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 26 deletions(-) create mode 100644 tests/win32/systempath.c diff --git a/src/win32/findfile.c b/src/win32/findfile.c index 8975894faf9..1e4d3d08257 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -112,12 +112,26 @@ static int win32_find_git_for_windows_architecture_root(_findfile_path *root_pat static int win32_find_git_in_path(git_str *buf, const wchar_t *gitexe, const wchar_t *subdir) { - wchar_t *env = _wgetenv(L"PATH"), lastch; + wchar_t *path, *env, lastch; _findfile_path root; size_t gitexe_len = wcslen(gitexe); + DWORD len; + bool found = false; - if (!env) - return -1; + len = GetEnvironmentVariableW(L"PATH", NULL, 0); + + if (len < 0) + return -1; + + path = git__malloc(len * sizeof(wchar_t)); + GIT_ERROR_CHECK_ALLOC(path); + + len = GetEnvironmentVariableW(L"PATH", path, len); + + if (len < 0) + return -1; + + env = path; while ((env = win32_walkpath(env, root.path, MAX_PATH-1)) && *root.path) { root.len = (DWORD)wcslen(root.path); @@ -148,11 +162,13 @@ static int win32_find_git_in_path(git_str *buf, const wchar_t *gitexe, const wch } win32_path_to_8(buf, root.path); - return 0; + found = true; + break; } } - return GIT_ENOTFOUND; + git__free(path); + return found ? 0 : GIT_ENOTFOUND; } static int win32_find_git_in_registry( @@ -214,37 +230,47 @@ static int win32_find_existing_dirs( return (git_str_oom(out) ? -1 : 0); } -int git_win32__find_system_dirs(git_str *out, const wchar_t *subdir) +int git_win32__find_system_dir_in_path(git_str *out, const wchar_t *subdir) { - git_str buf = GIT_STR_INIT; + /* directories where git.exe & git.cmd are found */ + if (win32_find_git_in_path(out, L"git.exe", subdir) == 0) + return 0; - /* directories where git.exe & git.cmd are found */ - if (!win32_find_git_in_path(&buf, L"git.exe", subdir) && buf.size) - git_str_set(out, buf.ptr, buf.size); - else - git_str_clear(out); + return win32_find_git_in_path(out, L"git.cmd", subdir); +} - if (!win32_find_git_in_path(&buf, L"git.cmd", subdir) && buf.size) - git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); +static int git_win32__find_system_dir_in_registry(git_str *out, const wchar_t *subdir) +{ + git_str buf = GIT_STR_INIT; - /* directories where git is installed according to registry */ - if (!win32_find_git_in_registry( - &buf, HKEY_CURRENT_USER, REG_MSYSGIT_INSTALL_LOCAL, subdir) && buf.size) - git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); + /* directories where git is installed according to registry */ + if (!win32_find_git_in_registry( + &buf, HKEY_CURRENT_USER, REG_MSYSGIT_INSTALL_LOCAL, subdir) && buf.size) + git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); #ifdef GIT_ARCH_64 - if (!win32_find_git_in_registry( - &buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL_LOCAL, subdir) && buf.size) - git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); + if (!win32_find_git_in_registry( + &buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL_LOCAL, subdir) && buf.size) + git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); #endif - if (!win32_find_git_in_registry( - &buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL, subdir) && buf.size) - git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); + if (!win32_find_git_in_registry( + &buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL, subdir) && buf.size) + git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); - git_str_dispose(&buf); + git_str_dispose(&buf); - return (git_str_oom(out) ? -1 : 0); + return (git_str_oom(out) ? -1 : 0); +} + +int git_win32__find_system_dirs(git_str *out, const wchar_t *subdir) +{ + int error; + + if ((error = git_win32__find_system_dir_in_path(out, subdir)) == 0) + error = git_win32__find_system_dir_in_registry(out, subdir); + + return error; } int git_win32__find_global_dirs(git_str *out) diff --git a/src/win32/findfile.h b/src/win32/findfile.h index e11ccebc58c..7f7691ce178 100644 --- a/src/win32/findfile.h +++ b/src/win32/findfile.h @@ -10,6 +10,7 @@ #include "common.h" +extern int git_win32__find_system_dir_in_path(git_str* out, const wchar_t* subdir); extern int git_win32__find_system_dirs(git_str *out, const wchar_t *subpath); extern int git_win32__find_global_dirs(git_str *out); extern int git_win32__find_xdg_dirs(git_str *out); diff --git a/tests/win32/systempath.c b/tests/win32/systempath.c new file mode 100644 index 00000000000..0b77f77030a --- /dev/null +++ b/tests/win32/systempath.c @@ -0,0 +1,91 @@ +#include "clar_libgit2.h" +#include "futils.h" +#include "sysdir.h" +#include "win32/findfile.h" + +static char *path_save; +static git_str gfw_root = GIT_STR_INIT; + +void test_win32_systempath__initialize(void) +{ + path_save = cl_getenv("PATH"); + + cl_git_pass(git_str_puts(&gfw_root, clar_sandbox_path())); + cl_git_pass(git_str_puts(&gfw_root, "/fake_gfw_install")); +} + +void test_win32_systempath__cleanup(void) +{ + cl_fixture_cleanup("fake_gfw_install"); + git_str_dispose(&gfw_root); + + cl_setenv("PATH", path_save); + git__free(path_save); + path_save = NULL; + + git_sysdir_reset(); +} + +static void fix_path(git_str *s) +{ + char *c; + + for (c = s->ptr; *c; c++) { + if (*c == '/') + *c = '\\'; + } +} + +void test_win32_systempath__etc_gitconfig(void) +{ + git_str bin_path = GIT_STR_INIT, exe_path = GIT_STR_INIT, + etc_path = GIT_STR_INIT, config_path = GIT_STR_INIT, + path_env = GIT_STR_INIT, out = GIT_STR_INIT; + git_config *cfg; + int value; + + cl_git_pass(git_str_puts(&bin_path, gfw_root.ptr)); + cl_git_pass(git_str_puts(&bin_path, "/cmd")); + cl_git_pass(git_futils_mkdir_r(bin_path.ptr, 0755)); + + cl_git_pass(git_str_puts(&exe_path, bin_path.ptr)); + cl_git_pass(git_str_puts(&exe_path, "/git.cmd")); + cl_git_mkfile(exe_path.ptr, "This is a fake executable."); + + cl_git_pass(git_str_puts(&etc_path, gfw_root.ptr)); + cl_git_pass(git_str_puts(&etc_path, "/etc")); + cl_git_pass(git_futils_mkdir_r(etc_path.ptr, 0755)); + + git_str_clear(&etc_path); + + cl_git_pass(git_str_puts(&etc_path, gfw_root.ptr)); + cl_git_pass(git_str_puts(&etc_path, "/etc")); + cl_git_pass(git_futils_mkdir_r(etc_path.ptr, 0755)); + + cl_git_pass(git_str_puts(&config_path, etc_path.ptr)); + cl_git_pass(git_str_puts(&config_path, "/gitconfig")); + cl_git_mkfile(config_path.ptr, "[gfw]\n\ttest = 1337\n"); + + fix_path(&bin_path); + + cl_git_pass(git_str_puts(&path_env, "C:\\GitTempTest\\Foo;\"c:\\program files\\doesnotexisttesttemp\";")); + cl_git_pass(git_str_puts(&path_env, bin_path.ptr)); + cl_git_pass(git_str_puts(&path_env, ";C:\\fakefakedoesnotexist")); + cl_setenv("PATH", path_env.ptr); + + cl_git_pass(git_win32__find_system_dir_in_path(&out, L"etc")); + cl_assert_equal_s(out.ptr, etc_path.ptr); + + git_sysdir_reset(); + + cl_git_pass(git_config_open_default(&cfg)); + cl_git_pass(git_config_get_int32(&value, cfg, "gfw.test")); + cl_assert_equal_i(1337, value); + + git_str_dispose(&exe_path); + git_str_dispose(&etc_path); + git_str_dispose(&config_path); + git_str_dispose(&path_env); + git_str_dispose(&out); + git_config_free(cfg); +} From 29960649137251abc07246e7c3075d6fd845d31f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 15 Jan 2022 14:13:53 +0000 Subject: [PATCH 0746/1616] win32: remove unnecessary findfile structure --- src/win32/findfile.c | 79 +++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/src/win32/findfile.c b/src/win32/findfile.c index 1e4d3d08257..b82347fc66f 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -19,16 +19,11 @@ #define REG_MSYSGIT_INSTALL L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" #endif -typedef struct { - git_win32_path path; - DWORD len; -} _findfile_path; - -static int git_win32__expand_path(_findfile_path *dest, const wchar_t *src) +static int git_win32__expand_path(git_win32_path dest, const wchar_t *src) { - dest->len = ExpandEnvironmentStringsW(src, dest->path, ARRAY_SIZE(dest->path)); + DWORD len = ExpandEnvironmentStringsW(src, dest, GIT_WIN_PATH_UTF16); - if (!dest->len || dest->len > ARRAY_SIZE(dest->path)) + if (!len || len > GIT_WIN_PATH_UTF16) return -1; return 0; @@ -70,7 +65,7 @@ static wchar_t *win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen) return (path != base) ? path : NULL; } -static int win32_find_git_for_windows_architecture_root(_findfile_path *root_path, const wchar_t *subdir) +static int win32_find_git_for_windows_architecture_root(git_win32_path root_path, const wchar_t *subdir) { /* Git for Windows >= 2 comes with a special architecture root (mingw64 and mingw32) * under which the "share" folder is located, check which we need (none is also ok) */ @@ -83,25 +78,27 @@ static int win32_find_git_for_windows_architecture_root(_findfile_path *root_pat }; const wchar_t **roots = architecture_roots; + size_t root_path_len = wcslen(root_path); + for (; *roots != NULL; ++roots) { git_win32_path tmp_root; DWORD subdir_len; - if (wcscpy(tmp_root, root_path->path) && - root_path->len + wcslen(*roots) <= MAX_PATH && + if (wcscpy(tmp_root, root_path) && + root_path_len + wcslen(*roots) <= MAX_PATH && wcscat(tmp_root, *roots) && !_waccess(tmp_root, F_OK)) { - wcscpy(root_path->path, tmp_root); - root_path->len += (DWORD)wcslen(*roots); + wcscpy(root_path, tmp_root); + root_path_len += (DWORD)wcslen(*roots); subdir_len = (DWORD)wcslen(subdir); - if (root_path->len + subdir_len >= MAX_PATH) + if (root_path_len + subdir_len >= MAX_PATH) break; // append subdir and check whether it exists for the Git installation wcscat(tmp_root, subdir); if (!_waccess(tmp_root, F_OK)) { - wcscpy(root_path->path, tmp_root); - root_path->len += subdir_len; + wcscpy(root_path, tmp_root); + root_path_len += subdir_len; break; } } @@ -113,7 +110,7 @@ static int win32_find_git_for_windows_architecture_root(_findfile_path *root_pat static int win32_find_git_in_path(git_str *buf, const wchar_t *gitexe, const wchar_t *subdir) { wchar_t *path, *env, lastch; - _findfile_path root; + git_win32_path root; size_t gitexe_len = wcslen(gitexe); DWORD len; bool found = false; @@ -133,35 +130,34 @@ static int win32_find_git_in_path(git_str *buf, const wchar_t *gitexe, const wch env = path; - while ((env = win32_walkpath(env, root.path, MAX_PATH-1)) && *root.path) { - root.len = (DWORD)wcslen(root.path); - lastch = root.path[root.len - 1]; + while ((env = win32_walkpath(env, root, MAX_PATH-1)) && *root) { + size_t root_len = wcslen(root); + lastch = root[root_len - 1]; /* ensure trailing slash (MAX_PATH-1 to walkpath guarantees space) */ if (lastch != L'/' && lastch != L'\\') { - root.path[root.len++] = L'\\'; - root.path[root.len] = L'\0'; + root[root_len++] = L'\\'; + root[root_len] = L'\0'; } - if (root.len + gitexe_len >= MAX_PATH) + if (root_len + gitexe_len >= MAX_PATH) continue; - wcscpy(&root.path[root.len], gitexe); - if (!_waccess(root.path, F_OK)) { + if (!_waccess(root, F_OK)) { /* check whether we found a Git for Windows installation and do some path adjustments OR just append subdir */ - if ((root.len > 5 && wcscmp(root.path - 4, L"cmd\\")) || wcscmp(root.path - 4, L"bin\\")) { + if ((root_len > 5 && wcscmp(root - 4, L"cmd\\")) || wcscmp(root - 4, L"bin\\")) { /* strip "bin" or "cmd" and try to find architecture root for appending subdir */ - root.len -= 4; - root.path[root.len] = L'\0'; - if (win32_find_git_for_windows_architecture_root(&root, subdir)) + root_len -= 4; + root[root_len] = L'\0'; + if (win32_find_git_for_windows_architecture_root(root, subdir)) continue; } else { - if (root.len + wcslen(subdir) >= MAX_PATH) + if (root_len + wcslen(subdir) >= MAX_PATH) continue; - wcscat(root.path, subdir); + wcscat(root, subdir); } - win32_path_to_8(buf, root.path); + win32_path_to_8(buf, root); found = true; break; } @@ -181,21 +177,20 @@ static int win32_find_git_in_registry( if (!RegOpenKeyExW(hive, key, 0, KEY_READ, &hKey)) { DWORD dwType, cbData; - _findfile_path path; + git_win32_path path; /* Ensure that the buffer is big enough to have the suffix attached * after we receive the result. */ cbData = (DWORD)(sizeof(path) - wcslen(subdir) * sizeof(wchar_t)); /* InstallLocation points to the root of the git directory */ - if (!RegQueryValueExW(hKey, L"InstallLocation", NULL, &dwType, (LPBYTE)path.path, &cbData) && + if (!RegQueryValueExW(hKey, L"InstallLocation", NULL, &dwType, (LPBYTE)path, &cbData) && dwType == REG_SZ) { - path.len = cbData; /* Convert to UTF-8, with forward slashes, and output the path * to the provided buffer */ - if (!win32_find_git_for_windows_architecture_root(&path, subdir) && - !win32_path_to_8(buf, path.path)) + if (!win32_find_git_for_windows_architecture_root(path, subdir) && + !win32_path_to_8(buf, path)) error = 0; } @@ -208,17 +203,17 @@ static int win32_find_git_in_registry( static int win32_find_existing_dirs( git_str *out, const wchar_t *tmpl[]) { - _findfile_path path16; + git_win32_path path16; git_str buf = GIT_STR_INIT; git_str_clear(out); for (; *tmpl != NULL; tmpl++) { - if (!git_win32__expand_path(&path16, *tmpl) && - path16.path[0] != L'%' && - !_waccess(path16.path, F_OK)) + if (!git_win32__expand_path(path16, *tmpl) && + path16[0] != L'%' && + !_waccess(path16, F_OK)) { - win32_path_to_8(&buf, path16.path); + win32_path_to_8(&buf, path16); if (buf.size) git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); From 925abee95b55ab24b0cf92771c713569f1f128f4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 15 Jan 2022 20:08:10 +0000 Subject: [PATCH 0747/1616] path: introduce git_fs_path_find_executable Provide a helper function to find an executable in the current process's PATH. --- src/fs_path.c | 56 ++++++++++++++++++ src/fs_path.h | 6 ++ src/win32/path_w32.c | 131 +++++++++++++++++++++++++++++++++++++++++++ src/win32/path_w32.h | 2 + tests/core/path.c | 86 ++++++++++++++++++++++++++++ 5 files changed, 281 insertions(+) diff --git a/src/fs_path.c b/src/fs_path.c index c9f03a7c34b..f9da304f5b6 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1851,3 +1851,59 @@ int git_fs_path_validate_system_file_ownership(const char *path) return ret; #endif } + +int git_fs_path_find_executable(git_str *fullpath, const char *executable) +{ +#ifdef GIT_WIN32 + git_win32_path fullpath_w, executable_w; + int error; + + if (git__utf8_to_16(executable_w, GIT_WIN_PATH_MAX, executable) < 0) + return -1; + + error = git_win32_path_find_executable(fullpath_w, executable_w); + + if (error == 0) + error = git_str_put_w(fullpath, fullpath_w, wcslen(fullpath_w)); + + return error; +#else + git_str path = GIT_STR_INIT; + const char *current_dir, *term; + bool found = false; + + if (git__getenv(&path, "PATH") < 0) + return -1; + + current_dir = path.ptr; + + while (*current_dir) { + if (! (term = strchr(current_dir, GIT_PATH_LIST_SEPARATOR))) + term = strchr(current_dir, '\0'); + + git_str_clear(fullpath); + if (git_str_put(fullpath, current_dir, (term - current_dir)) < 0 || + git_str_putc(fullpath, '/') < 0 || + git_str_puts(fullpath, executable) < 0) + return -1; + + if (git_fs_path_isfile(fullpath->ptr)) { + found = true; + break; + } + + current_dir = term; + + while (*current_dir == GIT_PATH_LIST_SEPARATOR) + current_dir++; + } + + git_str_dispose(&path); + + if (found) + return 0; + + git_str_clear(fullpath); + return GIT_ENOTFOUND; +#endif +} diff --git a/src/fs_path.h b/src/fs_path.h index 9720d34ce12..222c44abcee 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -743,4 +743,10 @@ bool git_fs_path_supports_symlinks(const char *dir); */ int git_fs_path_validate_system_file_ownership(const char *path); +/** + * Search the current PATH for the given executable, returning the full + * path if it is found. + */ +int git_fs_path_find_executable(git_str *fullpath, const char *executable); + #endif diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c index 0e6aff748f4..d9fc8292b0c 100644 --- a/src/win32/path_w32.c +++ b/src/win32/path_w32.c @@ -151,6 +151,137 @@ int git_win32_path_canonicalize(git_win32_path path) return (int)(to - path); } +static int git_win32_path_join( + git_win32_path dest, + const wchar_t *one, + size_t one_len, + const wchar_t *two, + size_t two_len) +{ + size_t backslash = 0; + + if (one_len && two_len && one[one_len - 1] != L'\\') + backslash = 1; + + if (one_len + two_len + backslash > MAX_PATH) { + git_error_set(GIT_ERROR_INVALID, "path too long"); + return -1; + } + + memmove(dest, one, one_len * sizeof(wchar_t)); + + if (backslash) + dest[one_len] = L'\\'; + + memcpy(dest + one_len + backslash, two, two_len * sizeof(wchar_t)); + dest[one_len + backslash + two_len] = L'\0'; + + return 0; +} + +struct win32_path_iter { + wchar_t *env; + const wchar_t *current_dir; +}; + +static int win32_path_iter_init(struct win32_path_iter *iter) +{ + DWORD len = GetEnvironmentVariableW(L"PATH", NULL, 0); + + if (!len && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { + iter->env = NULL; + iter->current_dir = NULL; + return 0; + } else if (!len) { + git_error_set(GIT_ERROR_OS, "could not load PATH"); + return -1; + } + + iter->env = git__malloc(len * sizeof(wchar_t)); + GIT_ERROR_CHECK_ALLOC(iter->env); + + len = GetEnvironmentVariableW(L"PATH", iter->env, len); + + if (len == 0) { + git_error_set(GIT_ERROR_OS, "could not load PATH"); + return -1; + } + + iter->current_dir = iter->env; + return 0; +} + +static int win32_path_iter_next( + const wchar_t **out, + size_t *out_len, + struct win32_path_iter *iter) +{ + const wchar_t *start; + wchar_t term; + size_t len = 0; + + if (!iter->current_dir || !*iter->current_dir) + return GIT_ITEROVER; + + term = (*iter->current_dir == L'"') ? *iter->current_dir++ : L';'; + start = iter->current_dir; + + while (*iter->current_dir && *iter->current_dir != term) { + iter->current_dir++; + len++; + } + + *out = start; + *out_len = len; + + if (term == L'"' && *iter->current_dir) + iter->current_dir++; + + while (*iter->current_dir == L';') + iter->current_dir++; + + return 0; +} + +static void win32_path_iter_dispose(struct win32_path_iter *iter) +{ + if (!iter) + return; + + git__free(iter->env); + iter->env = NULL; + iter->current_dir = NULL; +} + +int git_win32_path_find_executable(git_win32_path fullpath, wchar_t *exe) +{ + struct win32_path_iter path_iter; + const wchar_t *dir; + size_t dir_len, exe_len = wcslen(exe); + bool found = false; + + if (win32_path_iter_init(&path_iter) < 0) + return -1; + + while (win32_path_iter_next(&dir, &dir_len, &path_iter) != GIT_ITEROVER) { + if (git_win32_path_join(fullpath, dir, dir_len, exe, exe_len) < 0) + continue; + + if (_waccess(fullpath, 0) == 0) { + found = true; + break; + } + } + + win32_path_iter_dispose(&path_iter); + + if (found) + return 0; + + fullpath[0] = L'\0'; + return GIT_ENOTFOUND; +} + static int win32_path_cwd(wchar_t *out, size_t len) { int cwd_len; diff --git a/src/win32/path_w32.h b/src/win32/path_w32.h index 4fadf8d0848..837b11ebd72 100644 --- a/src/win32/path_w32.h +++ b/src/win32/path_w32.h @@ -86,4 +86,6 @@ size_t git_win32_path_trim_end(wchar_t *str, size_t len); */ size_t git_win32_path_remove_namespace(wchar_t *str, size_t len); +int git_win32_path_find_executable(git_win32_path fullpath, wchar_t* exe); + #endif diff --git a/tests/core/path.c b/tests/core/path.c index 563dcd2a3ff..a0ae77f1c76 100644 --- a/tests/core/path.c +++ b/tests/core/path.c @@ -2,6 +2,20 @@ #include "futils.h" #include "fs_path.h" +static char *path_save; + +void test_core_path__initialize(void) +{ + path_save = cl_getenv("PATH"); +} + +void test_core_path__cleanup(void) +{ + cl_setenv("PATH", path_save); + git__free(path_save); + path_save = NULL; +} + static void check_dirname(const char *A, const char *B) { @@ -60,6 +74,20 @@ check_joinpath_n( git_str_dispose(&joined_path); } +static void check_setenv(const char* name, const char* value) +{ + char* check; + + cl_git_pass(cl_setenv(name, value)); + check = cl_getenv(name); + + if (value) + cl_assert_equal_s(value, check); + else + cl_assert(check == NULL); + + git__free(check); +} /* get the dirname of a path */ void test_core_path__00_dirname(void) @@ -651,3 +679,61 @@ void test_core_path__16_resolve_relative(void) assert_common_dirlen(6, "a/b/c/foo.txt", "a/b/c/d/e/bar.txt"); assert_common_dirlen(7, "/a/b/c/foo.txt", "/a/b/c/d/e/bar.txt"); } + +static void fix_path(git_str *s) +{ +#ifndef GIT_WIN32 + GIT_UNUSED(s); +#else + char* c; + + for (c = s->ptr; *c; c++) { + if (*c == '/') + *c = '\\'; + } +#endif +} + +void test_core_path__find_exe_in_path(void) +{ + char *orig_path; + git_str sandbox_path = GIT_STR_INIT; + git_str new_path = GIT_STR_INIT, full_path = GIT_STR_INIT, + dummy_path = GIT_STR_INIT; + +#ifdef GIT_WIN32 + static const char *bogus_path_1 = "c:\\does\\not\\exist\\"; + static const char *bogus_path_2 = "e:\\non\\existent"; +#else + static const char *bogus_path_1 = "/this/path/does/not/exist/"; + static const char *bogus_path_2 = "/non/existent"; +#endif + + orig_path = cl_getenv("PATH"); + + git_str_puts(&sandbox_path, clar_sandbox_path()); + git_str_joinpath(&dummy_path, sandbox_path.ptr, "dummmmmmmy_libgit2_file"); + cl_git_rewritefile(dummy_path.ptr, "this is a dummy file"); + + fix_path(&sandbox_path); + fix_path(&dummy_path); + + cl_git_pass(git_str_printf(&new_path, "%s%c%s%c%s%c%s", + bogus_path_1, GIT_PATH_LIST_SEPARATOR, + orig_path, GIT_PATH_LIST_SEPARATOR, + sandbox_path.ptr, GIT_PATH_LIST_SEPARATOR, + bogus_path_2)); + + check_setenv("PATH", new_path.ptr); + + cl_git_fail_with(GIT_ENOTFOUND, git_fs_path_find_executable(&full_path, "this_file_does_not_exist")); + cl_git_pass(git_fs_path_find_executable(&full_path, "dummmmmmmy_libgit2_file")); + + cl_assert_equal_s(full_path.ptr, dummy_path.ptr); + + git_str_dispose(&full_path); + git_str_dispose(&new_path); + git_str_dispose(&dummy_path); + git_str_dispose(&sandbox_path); + git__free(orig_path); +} From 475c6eba4f5ad806b68ebf399818a7e9e9ec4a18 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 17 Jan 2022 17:16:02 +0000 Subject: [PATCH 0748/1616] win32: improve impl & tests for system path / g4w interop We look for a Git for Windows installation to use its git config, so that clients built on libgit2 can interoperate with the Git for Windows CLI (and clients that are built on top of _it_). Look for `git` both in the `PATH` and in the registry. Use the _first_ git install in the path, and the first git install in the registry. Look in both the `etc` dir and the architecture-specific `etc` dirs (`mingw64/etc` and `mingw32/etc`) beneath the installation root. Prefer the git in the `PATH` to the git location in the registry so that users can override that. Include more tests for this behavior. --- src/sysdir.c | 20 +-- src/win32/findfile.c | 316 ++++++++++++++++++------------------- src/win32/findfile.h | 6 +- tests/win32/systemdir.c | 328 +++++++++++++++++++++++++++++++++++++++ tests/win32/systempath.c | 91 ----------- 5 files changed, 490 insertions(+), 271 deletions(-) create mode 100644 tests/win32/systemdir.c delete mode 100644 tests/win32/systempath.c diff --git a/src/sysdir.c b/src/sysdir.c index c0e14f551bd..450cb509b81 100644 --- a/src/sysdir.c +++ b/src/sysdir.c @@ -31,7 +31,7 @@ static int git_sysdir_guess_programdata_dirs(git_str *out) static int git_sysdir_guess_system_dirs(git_str *out) { #ifdef GIT_WIN32 - return git_win32__find_system_dirs(out, L"etc\\"); + return git_win32__find_system_dirs(out, "etc"); #else return git_str_sets(out, "/etc"); #endif @@ -154,7 +154,7 @@ static int git_sysdir_guess_xdg_dirs(git_str *out) static int git_sysdir_guess_template_dirs(git_str *out) { #ifdef GIT_WIN32 - return git_win32__find_system_dirs(out, L"share\\git-core\\templates"); + return git_win32__find_system_dirs(out, "share/git-core/templates"); #else return git_str_sets(out, "/usr/share/git-core/templates"); #endif @@ -190,22 +190,22 @@ int git_sysdir_global_init(void) error = git_sysdir__dirs[i].guess(&git_sysdir__dirs[i].buf); if (error) - return error; + return error; return git_runtime_shutdown_register(git_sysdir_global_shutdown); } int git_sysdir_reset(void) { - size_t i; - int error = 0; + size_t i; + int error = 0; - for (i = 0; !error && i < ARRAY_SIZE(git_sysdir__dirs); ++i) { - git_str_dispose(&git_sysdir__dirs[i].buf); - error = git_sysdir__dirs[i].guess(&git_sysdir__dirs[i].buf); - } + for (i = 0; !error && i < ARRAY_SIZE(git_sysdir__dirs); ++i) { + git_str_dispose(&git_sysdir__dirs[i].buf); + error = git_sysdir__dirs[i].guess(&git_sysdir__dirs[i].buf); + } - return error; + return error; } static int git_sysdir_check_selector(git_sysdir_t which) diff --git a/src/win32/findfile.c b/src/win32/findfile.c index b82347fc66f..516391d7fdd 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -11,13 +11,8 @@ #include "utf-conv.h" #include "fs_path.h" -#define REG_MSYSGIT_INSTALL_LOCAL L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" - -#ifndef _WIN64 -#define REG_MSYSGIT_INSTALL REG_MSYSGIT_INSTALL_LOCAL -#else -#define REG_MSYSGIT_INSTALL L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" -#endif +#define REG_GITFORWINDOWS_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" +#define REG_GITFORWINDOWS_KEY_WOW64 L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" static int git_win32__expand_path(git_win32_path dest, const wchar_t *src) { @@ -44,164 +39,130 @@ static int win32_path_to_8(git_str *dest, const wchar_t *src) return git_str_sets(dest, utf8_path); } -static wchar_t *win32_walkpath(wchar_t *path, wchar_t *buf, size_t buflen) -{ - wchar_t term, *base = path; - - GIT_ASSERT_ARG_WITH_RETVAL(path, NULL); - GIT_ASSERT_ARG_WITH_RETVAL(buf, NULL); - GIT_ASSERT_ARG_WITH_RETVAL(buflen, NULL); - - term = (*path == L'"') ? *path++ : L';'; - - for (buflen--; *path && *path != term && buflen; buflen--) - *buf++ = *path++; - - *buf = L'\0'; /* reserved a byte via initial subtract */ +static git_win32_path mock_registry; +static bool mock_registry_set; - while (*path == term || *path == L';') - path++; - - return (path != base) ? path : NULL; -} - -static int win32_find_git_for_windows_architecture_root(git_win32_path root_path, const wchar_t *subdir) +extern int git_win32__set_registry_system_dir(const wchar_t *mock_sysdir) { - /* Git for Windows >= 2 comes with a special architecture root (mingw64 and mingw32) - * under which the "share" folder is located, check which we need (none is also ok) */ - - static const wchar_t *architecture_roots[4] = { - L"", // starting with Git 2.24 the etc folder is directly in the root folder - L"mingw64\\", - L"mingw32\\", - NULL, - }; - - const wchar_t **roots = architecture_roots; - size_t root_path_len = wcslen(root_path); - - for (; *roots != NULL; ++roots) { - git_win32_path tmp_root; - DWORD subdir_len; - if (wcscpy(tmp_root, root_path) && - root_path_len + wcslen(*roots) <= MAX_PATH && - wcscat(tmp_root, *roots) && - !_waccess(tmp_root, F_OK)) { - wcscpy(root_path, tmp_root); - root_path_len += (DWORD)wcslen(*roots); - - subdir_len = (DWORD)wcslen(subdir); - if (root_path_len + subdir_len >= MAX_PATH) - break; - - // append subdir and check whether it exists for the Git installation - wcscat(tmp_root, subdir); - if (!_waccess(tmp_root, F_OK)) { - wcscpy(root_path, tmp_root); - root_path_len += subdir_len; - break; - } + if (!mock_sysdir) { + mock_registry[0] = L'\0'; + mock_registry_set = false; + } else { + size_t len = wcslen(mock_sysdir); + + if (len > GIT_WIN_PATH_MAX) { + git_error_set(GIT_ERROR_INVALID, "mock path too long"); + return -1; } + + wcscpy(mock_registry, mock_sysdir); + mock_registry_set = true; } return 0; } -static int win32_find_git_in_path(git_str *buf, const wchar_t *gitexe, const wchar_t *subdir) +static int lookup_registry_key( + git_win32_path out, + const HKEY hive, + const wchar_t* key, + const wchar_t *value) { - wchar_t *path, *env, lastch; - git_win32_path root; - size_t gitexe_len = wcslen(gitexe); - DWORD len; - bool found = false; - - len = GetEnvironmentVariableW(L"PATH", NULL, 0); - - if (len < 0) - return -1; - - path = git__malloc(len * sizeof(wchar_t)); - GIT_ERROR_CHECK_ALLOC(path); + HKEY hkey; + DWORD type, size; + int error = GIT_ENOTFOUND; - len = GetEnvironmentVariableW(L"PATH", path, len); + /* + * Registry data may not be NUL terminated, provide room to do + * it ourselves. + */ + size = (DWORD)((sizeof(git_win32_path) - 1) * sizeof(wchar_t)); + + if (RegOpenKeyExW(hive, key, 0, KEY_READ, &hkey) != 0) + return GIT_ENOTFOUND; + + if (RegQueryValueExW(hkey, value, NULL, &type, (LPBYTE)out, &size) == 0 && + type == REG_SZ && + size > 0 && + size < sizeof(git_win32_path)) { + size_t wsize = size / sizeof(wchar_t); + size_t len = wsize - 1; + + if (out[wsize - 1] != L'\0') { + len = wsize; + out[wsize] = L'\0'; + } - if (len < 0) - return -1; + if (out[len - 1] == L'\\') + out[len - 1] = L'\0'; - env = path; + if (_waccess(out, F_OK) == 0) + error = 0; + } - while ((env = win32_walkpath(env, root, MAX_PATH-1)) && *root) { - size_t root_len = wcslen(root); - lastch = root[root_len - 1]; + RegCloseKey(hkey); + return error; +} - /* ensure trailing slash (MAX_PATH-1 to walkpath guarantees space) */ - if (lastch != L'/' && lastch != L'\\') { - root[root_len++] = L'\\'; - root[root_len] = L'\0'; - } +static int find_sysdir_in_registry(git_win32_path out) +{ + if (mock_registry_set) { + if (mock_registry[0] == L'\0') + return GIT_ENOTFOUND; - if (root_len + gitexe_len >= MAX_PATH) - continue; - - if (!_waccess(root, F_OK)) { - /* check whether we found a Git for Windows installation and do some path adjustments OR just append subdir */ - if ((root_len > 5 && wcscmp(root - 4, L"cmd\\")) || wcscmp(root - 4, L"bin\\")) { - /* strip "bin" or "cmd" and try to find architecture root for appending subdir */ - root_len -= 4; - root[root_len] = L'\0'; - if (win32_find_git_for_windows_architecture_root(root, subdir)) - continue; - } else { - if (root_len + wcslen(subdir) >= MAX_PATH) - continue; - wcscat(root, subdir); - } - - win32_path_to_8(buf, root); - found = true; - break; - } + wcscpy(out, mock_registry); + return 0; } - git__free(path); - return found ? 0 : GIT_ENOTFOUND; + if (lookup_registry_key(out, HKEY_CURRENT_USER, REG_GITFORWINDOWS_KEY, L"InstallLocation") == 0 || + lookup_registry_key(out, HKEY_CURRENT_USER, REG_GITFORWINDOWS_KEY_WOW64, L"InstallLocation") == 0 || + lookup_registry_key(out, HKEY_LOCAL_MACHINE, REG_GITFORWINDOWS_KEY, L"InstallLocation") == 0 || + lookup_registry_key(out, HKEY_LOCAL_MACHINE, REG_GITFORWINDOWS_KEY_WOW64, L"InstallLocation") == 0) + return 0; + + return GIT_ENOTFOUND; } -static int win32_find_git_in_registry( - git_str *buf, const HKEY hive, const wchar_t *key, const wchar_t *subdir) +static int find_sysdir_in_path(git_win32_path out) { - HKEY hKey; - int error = GIT_ENOTFOUND; + size_t out_len; - GIT_ASSERT_ARG(buf); + if (git_win32_path_find_executable(out, L"git.exe") < 0 && + git_win32_path_find_executable(out, L"git.cmd") < 0) + return GIT_ENOTFOUND; - if (!RegOpenKeyExW(hive, key, 0, KEY_READ, &hKey)) { - DWORD dwType, cbData; - git_win32_path path; + out_len = wcslen(out); - /* Ensure that the buffer is big enough to have the suffix attached - * after we receive the result. */ - cbData = (DWORD)(sizeof(path) - wcslen(subdir) * sizeof(wchar_t)); + /* Trim the file name */ + if (out_len <= CONST_STRLEN(L"git.exe")) + return GIT_ENOTFOUND; - /* InstallLocation points to the root of the git directory */ - if (!RegQueryValueExW(hKey, L"InstallLocation", NULL, &dwType, (LPBYTE)path, &cbData) && - dwType == REG_SZ) { + out_len -= CONST_STRLEN(L"git.exe"); - /* Convert to UTF-8, with forward slashes, and output the path - * to the provided buffer */ - if (!win32_find_git_for_windows_architecture_root(path, subdir) && - !win32_path_to_8(buf, path)) - error = 0; - } + if (out_len && out[out_len - 1] == L'\\') + out_len--; - RegCloseKey(hKey); - } + /* + * Git for Windows usually places the command in a 'bin' or + * 'cmd' directory, trim that. + */ + if (out_len >= CONST_STRLEN(L"\\bin") && + wcsncmp(&out[out_len - CONST_STRLEN(L"\\bin")], L"\\bin", CONST_STRLEN(L"\\bin")) == 0) + out_len -= CONST_STRLEN(L"\\bin"); + else if (out_len >= CONST_STRLEN(L"\\cmd") && + wcsncmp(&out[out_len - CONST_STRLEN(L"\\cmd")], L"\\cmd", CONST_STRLEN(L"\\cmd")) == 0) + out_len -= CONST_STRLEN(L"\\cmd"); - return error; + if (!out_len) + return GIT_ENOTFOUND; + + out[out_len] = L'\0'; + return 0; } static int win32_find_existing_dirs( - git_str *out, const wchar_t *tmpl[]) + git_str* out, + const wchar_t* tmpl[]) { git_win32_path path16; git_str buf = GIT_STR_INIT; @@ -210,9 +171,8 @@ static int win32_find_existing_dirs( for (; *tmpl != NULL; tmpl++) { if (!git_win32__expand_path(path16, *tmpl) && - path16[0] != L'%' && - !_waccess(path16, F_OK)) - { + path16[0] != L'%' && + !_waccess(path16, F_OK)) { win32_path_to_8(&buf, path16); if (buf.size) @@ -225,47 +185,67 @@ static int win32_find_existing_dirs( return (git_str_oom(out) ? -1 : 0); } -int git_win32__find_system_dir_in_path(git_str *out, const wchar_t *subdir) -{ - /* directories where git.exe & git.cmd are found */ - if (win32_find_git_in_path(out, L"git.exe", subdir) == 0) - return 0; - - return win32_find_git_in_path(out, L"git.cmd", subdir); -} - -static int git_win32__find_system_dir_in_registry(git_str *out, const wchar_t *subdir) +static int append_subdir(git_str *out, git_str *path, const char *subdir) { - git_str buf = GIT_STR_INIT; - - /* directories where git is installed according to registry */ - if (!win32_find_git_in_registry( - &buf, HKEY_CURRENT_USER, REG_MSYSGIT_INSTALL_LOCAL, subdir) && buf.size) - git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); + static const char* architecture_roots[] = { + "", + "mingw64", + "mingw32", + NULL + }; + const char **root; + size_t orig_path_len = path->size; -#ifdef GIT_ARCH_64 - if (!win32_find_git_in_registry( - &buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL_LOCAL, subdir) && buf.size) - git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); -#endif + for (root = architecture_roots; *root; root++) { + if ((*root[0] && git_str_joinpath(path, path->ptr, *root) < 0) || + git_str_joinpath(path, path->ptr, subdir) < 0) + return -1; - if (!win32_find_git_in_registry( - &buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL, subdir) && buf.size) - git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr); + if (git_fs_path_exists(path->ptr) && + git_str_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, path->ptr) < 0) + return -1; - git_str_dispose(&buf); + git_str_truncate(path, orig_path_len); + } - return (git_str_oom(out) ? -1 : 0); + return 0; } -int git_win32__find_system_dirs(git_str *out, const wchar_t *subdir) +int git_win32__find_system_dirs(git_str *out, const char *subdir) { + git_win32_path pathdir, regdir; + git_str path8 = GIT_STR_INIT; + bool has_pathdir, has_regdir; int error; - if ((error = git_win32__find_system_dir_in_path(out, subdir)) == 0) - error = git_win32__find_system_dir_in_registry(out, subdir); + has_pathdir = (find_sysdir_in_path(pathdir) == 0); + has_regdir = (find_sysdir_in_registry(regdir) == 0); - return error; + if (!has_pathdir && !has_regdir) + return GIT_ENOTFOUND; + + /* + * Usually the git in the path is the same git in the registry, + * in this case there's no need to duplicate the paths. + */ + if (has_pathdir && has_regdir && wcscmp(pathdir, regdir) == 0) + has_regdir = false; + + if (has_pathdir) { + if ((error = win32_path_to_8(&path8, pathdir)) < 0 || + (error = append_subdir(out, &path8, subdir)) < 0) + goto done; + } + + if (has_regdir) { + if ((error = win32_path_to_8(&path8, regdir)) < 0 || + (error = append_subdir(out, &path8, subdir)) < 0) + goto done; + } + +done: + git_str_dispose(&path8); + return error; } int git_win32__find_global_dirs(git_str *out) diff --git a/src/win32/findfile.h b/src/win32/findfile.h index 7f7691ce178..61fb7dbad79 100644 --- a/src/win32/findfile.h +++ b/src/win32/findfile.h @@ -10,8 +10,10 @@ #include "common.h" -extern int git_win32__find_system_dir_in_path(git_str* out, const wchar_t* subdir); -extern int git_win32__find_system_dirs(git_str *out, const wchar_t *subpath); +/** Sets the mock registry root for Git for Windows for testing. */ +extern int git_win32__set_registry_system_dir(const wchar_t *mock_sysdir); + +extern int git_win32__find_system_dirs(git_str *out, const char *subpath); extern int git_win32__find_global_dirs(git_str *out); extern int git_win32__find_xdg_dirs(git_str *out); extern int git_win32__find_programdata_dirs(git_str *out); diff --git a/tests/win32/systemdir.c b/tests/win32/systemdir.c new file mode 100644 index 00000000000..46fa06a50e1 --- /dev/null +++ b/tests/win32/systemdir.c @@ -0,0 +1,328 @@ +#include "clar_libgit2.h" +#include "futils.h" +#include "sysdir.h" +#include "win32/findfile.h" + +#ifdef GIT_WIN32 +static char *path_save; +static git_str gfw_path_root = GIT_STR_INIT; +static git_str gfw_registry_root = GIT_STR_INIT; +#endif + +void test_win32_systemdir__initialize(void) +{ +#ifdef GIT_WIN32 + git_str path_env = GIT_STR_INIT; + + path_save = cl_getenv("PATH"); + git_win32__set_registry_system_dir(L""); + + cl_git_pass(git_str_puts(&path_env, "C:\\GitTempTest\\Foo;\"c:\\program files\\doesnotexisttesttemp\";C:\\fakefakedoesnotexist")); + cl_setenv("PATH", path_env.ptr); + + cl_git_pass(git_str_puts(&gfw_path_root, clar_sandbox_path())); + cl_git_pass(git_str_puts(&gfw_path_root, "/fake_gfw_path_install")); + + cl_git_pass(git_str_puts(&gfw_registry_root, clar_sandbox_path())); + cl_git_pass(git_str_puts(&gfw_registry_root, "/fake_gfw_registry_install")); + + git_str_dispose(&path_env); +#endif +} + +void test_win32_systemdir__cleanup(void) +{ +#ifdef GIT_WIN32 + cl_fixture_cleanup("fake_gfw_path_install"); + cl_fixture_cleanup("fake_gfw_registry_install"); + git_str_dispose(&gfw_path_root); + git_str_dispose(&gfw_registry_root); + + cl_setenv("PATH", path_save); + git__free(path_save); + path_save = NULL; + + git_win32__set_registry_system_dir(NULL); + cl_sandbox_set_search_path_defaults(); +#endif +} + +#ifdef GIT_WIN32 +static void fix_path(git_str *s) +{ + char *c; + + for (c = s->ptr; *c; c++) { + if (*c == '/') + *c = '\\'; + } +} + +static void populate_fake_gfw( + git_str *expected_etc_dir, + const char *root, + const char *token, + bool create_gitconfig, + bool create_mingw64_gitconfig, + bool add_to_path, + bool add_to_registry) +{ + git_str bin_path = GIT_STR_INIT, exe_path = GIT_STR_INIT, + etc_path = GIT_STR_INIT, mingw64_path = GIT_STR_INIT, + config_path = GIT_STR_INIT, path_env = GIT_STR_INIT, + config_data = GIT_STR_INIT; + + cl_git_pass(git_str_puts(&bin_path, root)); + cl_git_pass(git_str_puts(&bin_path, "/cmd")); + cl_git_pass(git_futils_mkdir_r(bin_path.ptr, 0755)); + + cl_git_pass(git_str_puts(&exe_path, bin_path.ptr)); + cl_git_pass(git_str_puts(&exe_path, "/git.cmd")); + cl_git_mkfile(exe_path.ptr, "This is a fake executable."); + + cl_git_pass(git_str_puts(&etc_path, root)); + cl_git_pass(git_str_puts(&etc_path, "/etc")); + cl_git_pass(git_futils_mkdir_r(etc_path.ptr, 0755)); + + cl_git_pass(git_str_puts(&mingw64_path, root)); + cl_git_pass(git_str_puts(&mingw64_path, "/mingw64/etc")); + cl_git_pass(git_futils_mkdir_r(mingw64_path.ptr, 0755)); + + if (create_gitconfig) { + git_str_clear(&config_data); + git_str_printf(&config_data, "[gfw]\n\ttest = etc %s\n", token); + + cl_git_pass(git_str_puts(&config_path, etc_path.ptr)); + cl_git_pass(git_str_puts(&config_path, "/gitconfig")); + cl_git_mkfile(config_path.ptr, config_data.ptr); + } + + if (create_mingw64_gitconfig) { + git_str_clear(&config_data); + git_str_printf(&config_data, "[gfw]\n\ttest = mingw64 %s\n", token); + + git_str_clear(&config_path); + cl_git_pass(git_str_puts(&config_path, mingw64_path.ptr)); + cl_git_pass(git_str_puts(&config_path, "/gitconfig")); + cl_git_mkfile(config_path.ptr, config_data.ptr); + } + + if (add_to_path) { + fix_path(&bin_path); + cl_git_pass(git_str_puts(&path_env, "C:\\GitTempTest\\Foo;\"c:\\program files\\doesnotexisttesttemp\";")); + cl_git_pass(git_str_puts(&path_env, bin_path.ptr)); + cl_git_pass(git_str_puts(&path_env, ";C:\\fakefakedoesnotexist")); + cl_setenv("PATH", path_env.ptr); + } + + if (add_to_registry) { + git_win32_path registry_path; + size_t offset = 0; + + cl_assert(git_win32_path_from_utf8(registry_path, root) >= 0); + if (wcsncmp(registry_path, L"\\\\?\\", CONST_STRLEN("\\\\?\\")) == 0) + offset = CONST_STRLEN("\\\\?\\"); + git_win32__set_registry_system_dir(registry_path + offset); + } + + cl_git_pass(git_str_join(expected_etc_dir, GIT_PATH_LIST_SEPARATOR, expected_etc_dir->ptr, etc_path.ptr)); + cl_git_pass(git_str_join(expected_etc_dir, GIT_PATH_LIST_SEPARATOR, expected_etc_dir->ptr, mingw64_path.ptr)); + + git_str_dispose(&bin_path); + git_str_dispose(&exe_path); + git_str_dispose(&etc_path); + git_str_dispose(&mingw64_path); + git_str_dispose(&config_path); + git_str_dispose(&path_env); + git_str_dispose(&config_data); +} + +static void populate_fake_ecosystem( + git_str *expected_etc_dir, + bool create_gitconfig, + bool create_mingw64_gitconfig, + bool path, + bool registry) +{ + if (path) + populate_fake_gfw(expected_etc_dir, gfw_path_root.ptr, "path", create_gitconfig, create_mingw64_gitconfig, true, false); + + if (registry) + populate_fake_gfw(expected_etc_dir, gfw_registry_root.ptr, "registry", create_gitconfig, create_mingw64_gitconfig, false, true); +} +#endif + +void test_win32_systemdir__finds_etc_in_path(void) +{ +#ifdef GIT_WIN32 + git_str expected = GIT_STR_INIT, out = GIT_STR_INIT; + git_config *cfg; + git_buf value = GIT_BUF_INIT; + + populate_fake_ecosystem(&expected, true, false, true, false); + + cl_git_pass(git_win32__find_system_dirs(&out, "etc")); + cl_assert_equal_s(out.ptr, expected.ptr); + + git_sysdir_reset(); + + cl_git_pass(git_config_open_default(&cfg)); + cl_git_pass(git_config_get_string_buf(&value, cfg, "gfw.test")); + cl_assert_equal_s("etc path", value.ptr); + + git_buf_dispose(&value); + git_str_dispose(&expected); + git_str_dispose(&out); + git_config_free(cfg); +#endif +} + +void test_win32_systemdir__finds_mingw64_etc_in_path(void) +{ +#ifdef GIT_WIN32 + git_str expected = GIT_STR_INIT, out = GIT_STR_INIT; + git_config* cfg; + git_buf value = GIT_BUF_INIT; + + populate_fake_ecosystem(&expected, false, true, true, false); + + cl_git_pass(git_win32__find_system_dirs(&out, "etc")); + cl_assert_equal_s(out.ptr, expected.ptr); + + git_sysdir_reset(); + + cl_git_pass(git_config_open_default(&cfg)); + cl_git_pass(git_config_get_string_buf(&value, cfg, "gfw.test")); + cl_assert_equal_s("mingw64 path", value.ptr); + + git_buf_dispose(&value); + git_str_dispose(&expected); + git_str_dispose(&out); + git_config_free(cfg); +#endif +} + +void test_win32_systemdir__prefers_etc_to_mingw64_in_path(void) +{ +#ifdef GIT_WIN32 + git_str expected = GIT_STR_INIT, out = GIT_STR_INIT; + git_config* cfg; + git_buf value = GIT_BUF_INIT; + + populate_fake_ecosystem(&expected, true, true, true, false); + + cl_git_pass(git_win32__find_system_dirs(&out, "etc")); + cl_assert_equal_s(out.ptr, expected.ptr); + + git_sysdir_reset(); + + cl_git_pass(git_config_open_default(&cfg)); + cl_git_pass(git_config_get_string_buf(&value, cfg, "gfw.test")); + cl_assert_equal_s("etc path", value.ptr); + + git_buf_dispose(&value); + git_str_dispose(&expected); + git_str_dispose(&out); + git_config_free(cfg); +#endif +} + +void test_win32_systemdir__finds_etc_in_registry(void) +{ +#ifdef GIT_WIN32 + git_str expected = GIT_STR_INIT, out = GIT_STR_INIT; + git_config* cfg; + git_buf value = GIT_BUF_INIT; + + populate_fake_ecosystem(&expected, true, false, false, true); + + cl_git_pass(git_win32__find_system_dirs(&out, "etc")); + cl_assert_equal_s(out.ptr, expected.ptr); + + git_sysdir_reset(); + + cl_git_pass(git_config_open_default(&cfg)); + cl_git_pass(git_config_get_string_buf(&value, cfg, "gfw.test")); + cl_assert_equal_s("etc registry", value.ptr); + + git_buf_dispose(&value); + git_str_dispose(&expected); + git_str_dispose(&out); + git_config_free(cfg); +#endif +} + +void test_win32_systemdir__finds_mingw64_etc_in_registry(void) +{ +#ifdef GIT_WIN32 + git_str expected = GIT_STR_INIT, out = GIT_STR_INIT; + git_config* cfg; + git_buf value = GIT_BUF_INIT; + + populate_fake_ecosystem(&expected, false, true, false, true); + + cl_git_pass(git_win32__find_system_dirs(&out, "etc")); + cl_assert_equal_s(out.ptr, expected.ptr); + + git_sysdir_reset(); + + cl_git_pass(git_config_open_default(&cfg)); + cl_git_pass(git_config_get_string_buf(&value, cfg, "gfw.test")); + cl_assert_equal_s("mingw64 registry", value.ptr); + + git_buf_dispose(&value); + git_str_dispose(&expected); + git_str_dispose(&out); + git_config_free(cfg); +#endif +} + +void test_win32_systemdir__prefers_etc_to_mingw64_in_registry(void) +{ +#ifdef GIT_WIN32 + git_str expected = GIT_STR_INIT, out = GIT_STR_INIT; + git_config* cfg; + git_buf value = GIT_BUF_INIT; + + populate_fake_ecosystem(&expected, true, true, false, true); + + cl_git_pass(git_win32__find_system_dirs(&out, "etc")); + cl_assert_equal_s(out.ptr, expected.ptr); + + git_sysdir_reset(); + + cl_git_pass(git_config_open_default(&cfg)); + cl_git_pass(git_config_get_string_buf(&value, cfg, "gfw.test")); + cl_assert_equal_s("etc registry", value.ptr); + + git_buf_dispose(&value); + git_str_dispose(&expected); + git_str_dispose(&out); + git_config_free(cfg); +#endif +} + +void test_win32_systemdir__prefers_path_to_registry(void) +{ +#ifdef GIT_WIN32 + git_str expected = GIT_STR_INIT, out = GIT_STR_INIT; + git_config* cfg; + git_buf value = GIT_BUF_INIT; + + populate_fake_ecosystem(&expected, true, true, true, true); + + cl_git_pass(git_win32__find_system_dirs(&out, "etc")); + cl_assert_equal_s(out.ptr, expected.ptr); + + git_sysdir_reset(); + + cl_git_pass(git_config_open_default(&cfg)); + cl_git_pass(git_config_get_string_buf(&value, cfg, "gfw.test")); + cl_assert_equal_s("etc path", value.ptr); + + git_buf_dispose(&value); + git_str_dispose(&expected); + git_str_dispose(&out); + git_config_free(cfg); +#endif +} diff --git a/tests/win32/systempath.c b/tests/win32/systempath.c deleted file mode 100644 index 0b77f77030a..00000000000 --- a/tests/win32/systempath.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "clar_libgit2.h" -#include "futils.h" -#include "sysdir.h" -#include "win32/findfile.h" - -static char *path_save; -static git_str gfw_root = GIT_STR_INIT; - -void test_win32_systempath__initialize(void) -{ - path_save = cl_getenv("PATH"); - - cl_git_pass(git_str_puts(&gfw_root, clar_sandbox_path())); - cl_git_pass(git_str_puts(&gfw_root, "/fake_gfw_install")); -} - -void test_win32_systempath__cleanup(void) -{ - cl_fixture_cleanup("fake_gfw_install"); - git_str_dispose(&gfw_root); - - cl_setenv("PATH", path_save); - git__free(path_save); - path_save = NULL; - - git_sysdir_reset(); -} - -static void fix_path(git_str *s) -{ - char *c; - - for (c = s->ptr; *c; c++) { - if (*c == '/') - *c = '\\'; - } -} - -void test_win32_systempath__etc_gitconfig(void) -{ - git_str bin_path = GIT_STR_INIT, exe_path = GIT_STR_INIT, - etc_path = GIT_STR_INIT, config_path = GIT_STR_INIT, - path_env = GIT_STR_INIT, out = GIT_STR_INIT; - git_config *cfg; - int value; - - cl_git_pass(git_str_puts(&bin_path, gfw_root.ptr)); - cl_git_pass(git_str_puts(&bin_path, "/cmd")); - cl_git_pass(git_futils_mkdir_r(bin_path.ptr, 0755)); - - cl_git_pass(git_str_puts(&exe_path, bin_path.ptr)); - cl_git_pass(git_str_puts(&exe_path, "/git.cmd")); - cl_git_mkfile(exe_path.ptr, "This is a fake executable."); - - cl_git_pass(git_str_puts(&etc_path, gfw_root.ptr)); - cl_git_pass(git_str_puts(&etc_path, "/etc")); - cl_git_pass(git_futils_mkdir_r(etc_path.ptr, 0755)); - - git_str_clear(&etc_path); - - cl_git_pass(git_str_puts(&etc_path, gfw_root.ptr)); - cl_git_pass(git_str_puts(&etc_path, "/etc")); - cl_git_pass(git_futils_mkdir_r(etc_path.ptr, 0755)); - - cl_git_pass(git_str_puts(&config_path, etc_path.ptr)); - cl_git_pass(git_str_puts(&config_path, "/gitconfig")); - cl_git_mkfile(config_path.ptr, "[gfw]\n\ttest = 1337\n"); - - fix_path(&bin_path); - - cl_git_pass(git_str_puts(&path_env, "C:\\GitTempTest\\Foo;\"c:\\program files\\doesnotexisttesttemp\";")); - cl_git_pass(git_str_puts(&path_env, bin_path.ptr)); - cl_git_pass(git_str_puts(&path_env, ";C:\\fakefakedoesnotexist")); - cl_setenv("PATH", path_env.ptr); - - cl_git_pass(git_win32__find_system_dir_in_path(&out, L"etc")); - cl_assert_equal_s(out.ptr, etc_path.ptr); - - git_sysdir_reset(); - - cl_git_pass(git_config_open_default(&cfg)); - cl_git_pass(git_config_get_int32(&value, cfg, "gfw.test")); - cl_assert_equal_i(1337, value); - - git_str_dispose(&exe_path); - git_str_dispose(&etc_path); - git_str_dispose(&config_path); - git_str_dispose(&path_env); - git_str_dispose(&out); - git_config_free(cfg); -} From 5388e0c1181b206531456a4c76a235c513e4952c Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Tue, 23 Nov 2021 00:00:32 +0100 Subject: [PATCH 0749/1616] diff_driver: split global_drivers array into separate elements C99 doesn't allow structures with flexible length array to be placed in an array. --- src/diff_driver.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/diff_driver.c b/src/diff_driver.c index a20723fcc7a..5f25fdb442b 100644 --- a/src/diff_driver.c +++ b/src/diff_driver.c @@ -51,11 +51,9 @@ struct git_diff_driver_registry { #define FORCE_DIFFABLE (GIT_DIFF_FORCE_TEXT | GIT_DIFF_FORCE_BINARY) -static git_diff_driver global_drivers[3] = { - { DIFF_DRIVER_AUTO, 0, 0, }, - { DIFF_DRIVER_BINARY, GIT_DIFF_FORCE_BINARY, 0 }, - { DIFF_DRIVER_TEXT, GIT_DIFF_FORCE_TEXT, 0 }, -}; +static git_diff_driver diff_driver_auto = { DIFF_DRIVER_AUTO, 0, 0 }; +static git_diff_driver diff_driver_binary = { DIFF_DRIVER_BINARY, GIT_DIFF_FORCE_BINARY, 0 }; +static git_diff_driver diff_driver_text = { DIFF_DRIVER_TEXT, GIT_DIFF_FORCE_TEXT, 0 }; git_diff_driver_registry *git_diff_driver_registry_new(void) { @@ -266,7 +264,7 @@ static int git_diff_driver_load( switch (git_config__get_bool_force(cfg, name.ptr, -1)) { case true: /* if diff..binary is true, just return the binary driver */ - *out = &global_drivers[DIFF_DRIVER_BINARY]; + *out = &diff_driver_binary; goto done; case false: /* if diff..binary is false, force binary checks off */ @@ -374,9 +372,9 @@ int git_diff_driver_lookup( else if (GIT_ATTR_IS_UNSPECIFIED(values[0])) /* just use the auto value */; else if (GIT_ATTR_IS_FALSE(values[0])) - *out = &global_drivers[DIFF_DRIVER_BINARY]; + *out = &diff_driver_binary; else if (GIT_ATTR_IS_TRUE(values[0])) - *out = &global_drivers[DIFF_DRIVER_TEXT]; + *out = &diff_driver_text; /* otherwise look for driver information in config and build driver */ else if ((error = git_diff_driver_load(out, repo, values[0])) < 0) { @@ -387,7 +385,7 @@ int git_diff_driver_lookup( } if (!*out) - *out = &global_drivers[DIFF_DRIVER_AUTO]; + *out = &diff_driver_auto; return error; } From f2faa01c75ab35a1fb0fc55647045b3061e61ca3 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 Jan 2022 19:24:18 -0500 Subject: [PATCH 0750/1616] COPYING: remove regex copyright, add PCRE copyright We now bundle PCRE for our regular expression implementation; include that copyright notice and remove the now-unused regular expression copyright. --- COPYING | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/COPYING b/COPYING index 6bb39b0c1d9..efeff148724 100644 --- a/COPYING +++ b/COPYING @@ -406,30 +406,35 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ---------------------------------------------------------------------- -The regex library (deps/regex/) is licensed under the GNU LGPL -(available at the end of this file). +The bundled PCRE implementation (deps/pcre/) is licensed under the BSD +license. -Definitions for data structures and routines for the regular -expression library. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: -Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006,2008 -Free Software Foundation, Inc. -This file is part of the GNU C Library. + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. + * Neither the name of the University of Cambridge nor the name of Google + Inc. nor the names of their contributors may be used to endorse or + promote products derived from this software without specific prior + written permission. -You should have received a copy of the GNU Lesser General Public -License along with the GNU C Library; if not, write to the Free -Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- From 74471eefcea752542a2a6ee5e15b75b6baf05a48 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 21 Jan 2022 19:11:18 -0500 Subject: [PATCH 0751/1616] commit_graph: tests are now `commitgraph` Underscores in filenames in tests indicate a logical separation - so `commit_graph` becomes `commit::graph`. Rename it to `commitgraph` to avoid this. --- tests/graph/{commit_graph.c => commitgraph.c} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tests/graph/{commit_graph.c => commitgraph.c} (97%) diff --git a/tests/graph/commit_graph.c b/tests/graph/commitgraph.c similarity index 97% rename from tests/graph/commit_graph.c rename to tests/graph/commitgraph.c index 83f53f1d405..7607c35a342 100644 --- a/tests/graph/commit_graph.c +++ b/tests/graph/commitgraph.c @@ -6,7 +6,7 @@ #include "commit_graph.h" #include "futils.h" -void test_graph_commit_graph__parse(void) +void test_graph_commitgraph__parse(void) { git_repository *repo; struct git_commit_graph_file *file; @@ -50,7 +50,7 @@ void test_graph_commit_graph__parse(void) git_str_dispose(&commit_graph_path); } -void test_graph_commit_graph__parse_octopus_merge(void) +void test_graph_commitgraph__parse_octopus_merge(void) { git_repository *repo; struct git_commit_graph_file *file; @@ -91,7 +91,7 @@ void test_graph_commit_graph__parse_octopus_merge(void) git_str_dispose(&commit_graph_path); } -void test_graph_commit_graph__writer(void) +void test_graph_commitgraph__writer(void) { git_repository *repo; git_commit_graph_writer *w = NULL; From a9fc14b0f515ec8d27ac7c854c2884b27ebd079e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 21 Jan 2022 19:43:42 -0500 Subject: [PATCH 0752/1616] oid: avoid `tostr_s` in many places The `git_oid_tostr_s` helper is indeed helpful, unless you are using printf debugging (by inserting more `git_oid_tostr_s` calls) shortly after using it. Avoid it before invoking complex functions. --- src/branch.c | 5 ++++- src/reset.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/branch.c b/src/branch.c index 03892a4b0e5..2e29af99dd2 100644 --- a/src/branch.c +++ b/src/branch.c @@ -123,7 +123,10 @@ int git_branch_create( const git_commit *commit, int force) { - return create_branch(ref_out, repository, branch_name, commit, git_oid_tostr_s(git_commit_id(commit)), force); + char commit_id[GIT_OID_HEXSZ + 1]; + + git_oid_tostr(commit_id, GIT_OID_HEXSZ + 1, git_commit_id(commit)); + return create_branch(ref_out, repository, branch_name, commit, commit_id, force); } int git_branch_create_from_annotated( diff --git a/src/reset.c b/src/reset.c index b8327fe5e0b..e0d942e5e17 100644 --- a/src/reset.c +++ b/src/reset.c @@ -188,7 +188,10 @@ int git_reset( git_reset_t reset_type, const git_checkout_options *checkout_opts) { - return reset(repo, target, git_oid_tostr_s(git_object_id(target)), reset_type, checkout_opts); + char to[GIT_OID_HEXSZ + 1]; + + git_oid_tostr(to, GIT_OID_HEXSZ + 1, git_object_id(target)); + return reset(repo, target, to, reset_type, checkout_opts); } int git_reset_from_annotated( From 0e53e55d7b400e303caf271469f584a7cf92036b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 Jan 2022 14:18:48 -0500 Subject: [PATCH 0753/1616] hash: introduce git_hash_fmt A simple hash-to-hexadigit formatter. --- src/hash.c | 16 ++++++++++++++++ src/hash.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/src/hash.c b/src/hash.c index 92e7ff2195f..98ceb05d260 100644 --- a/src/hash.c +++ b/src/hash.c @@ -124,3 +124,19 @@ int git_hash_vec( return error; } + +int git_hash_fmt(char *out, unsigned char *hash, size_t hash_len) +{ + static char hex[] = "0123456789abcdef"; + char *str = out; + size_t i; + + for (i = 0; i < hash_len; i++) { + *str++ = hex[hash[i] >> 4]; + *str++ = hex[hash[i] & 0x0f]; + } + + *str++ = '\0'; + + return 0; +} diff --git a/src/hash.h b/src/hash.h index 2b2eaf6d670..507c1cb256f 100644 --- a/src/hash.h +++ b/src/hash.h @@ -41,4 +41,6 @@ int git_hash_final(unsigned char *out, git_hash_ctx *c); int git_hash_buf(unsigned char *out, const void *data, size_t len, git_hash_algorithm_t algorithm); int git_hash_vec(unsigned char *out, git_str_vec *vec, size_t n, git_hash_algorithm_t algorithm); +int git_hash_fmt(char *out, unsigned char *hash, size_t hash_len); + #endif From b7429e1ddf19d4992efbc5373ccce2218bd9a938 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 Jan 2022 09:44:17 -0500 Subject: [PATCH 0754/1616] midx: use a byte array for checksum --- src/midx.c | 32 ++++++++++++++++++++------------ src/midx.h | 2 +- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/midx.c b/src/midx.c index d4f9bd5a04a..eb99e737303 100644 --- a/src/midx.c +++ b/src/midx.c @@ -178,7 +178,8 @@ int git_midx_parse( struct git_midx_chunk *last_chunk; uint32_t i; off64_t last_chunk_offset, chunk_offset, trailer_offset; - git_oid idx_checksum = {{0}}; + size_t checksum_size; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; int error; struct git_midx_chunk chunk_packfile_names = {0}, chunk_oid_fanout = {0}, @@ -208,14 +209,17 @@ int git_midx_parse( last_chunk_offset = sizeof(struct git_midx_header) + (1 + hdr->chunks) * 12; - trailer_offset = size - GIT_OID_RAWSZ; + + checksum_size = GIT_HASH_SHA1_SIZE; + trailer_offset = size - checksum_size; + if (trailer_offset < last_chunk_offset) return midx_error("wrong index size"); - git_oid_cpy(&idx->checksum, (git_oid *)(data + trailer_offset)); + memcpy(idx->checksum, data + trailer_offset, checksum_size); - if (git_hash_buf(idx_checksum.id, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) + if (git_hash_buf(checksum, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) return midx_error("could not calculate signature"); - if (!git_oid_equal(&idx_checksum, &idx->checksum)) + if (memcmp(checksum, idx->checksum, checksum_size) != 0) return midx_error("index signature mismatch"); chunk_hdr = data + sizeof(struct git_midx_header); @@ -341,7 +345,8 @@ bool git_midx_needs_refresh( git_file fd = -1; struct stat st; ssize_t bytes_read; - git_oid idx_checksum = {{0}}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size; /* TODO: properly open the file without access time using O_NOATIME */ fd = git_futils_open_ro(path); @@ -360,13 +365,14 @@ bool git_midx_needs_refresh( return true; } - bytes_read = p_pread(fd, &idx_checksum, GIT_OID_RAWSZ, st.st_size - GIT_OID_RAWSZ); + checksum_size = GIT_HASH_SHA1_SIZE; + bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - GIT_OID_RAWSZ); p_close(fd); - if (bytes_read != GIT_OID_RAWSZ) + if (bytes_read != (ssize_t)checksum_size) return true; - return !git_oid_equal(&idx_checksum, &idx->checksum); + return (memcmp(checksum, idx->checksum, checksum_size) != 0); } int git_midx_entry_find( @@ -653,7 +659,8 @@ static int midx_write( oid_lookup = GIT_STR_INIT, object_offsets = GIT_STR_INIT, object_large_offsets = GIT_STR_INIT; - git_oid idx_checksum = {{0}}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size; git_midx_entry *entry; object_entry_array_t object_entries_array = GIT_ARRAY_INIT; git_vector object_entries = GIT_VECTOR_INIT; @@ -669,6 +676,7 @@ static int midx_write( hash_cb_data.cb_data = cb_data; hash_cb_data.ctx = &ctx; + checksum_size = GIT_HASH_SHA1_SIZE; error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1); if (error < 0) return error; @@ -820,10 +828,10 @@ static int midx_write( goto cleanup; /* Finalize the checksum and write the trailer. */ - error = git_hash_final(idx_checksum.id, &ctx); + error = git_hash_final(checksum, &ctx); if (error < 0) goto cleanup; - error = write_cb((const char *)&idx_checksum, sizeof(idx_checksum), cb_data); + error = write_cb((char *)checksum, checksum_size, cb_data); if (error < 0) goto cleanup; diff --git a/src/midx.h b/src/midx.h index ef3d534bc99..7dd851bd36b 100644 --- a/src/midx.h +++ b/src/midx.h @@ -51,7 +51,7 @@ typedef struct git_midx_file { size_t num_object_large_offsets; /* The trailer of the file. Contains the SHA1-checksum of the whole file. */ - git_oid checksum; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; /* something like ".git/objects/pack/multi-pack-index". */ git_str filename; From c6e1f2bf22e44ca8980347d6bff4555f6ffdd4c1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 Jan 2022 11:53:09 -0500 Subject: [PATCH 0755/1616] commit_graph: use a byte array for checksum --- src/commit_graph.c | 28 +++++++++++++++++----------- src/commit_graph.h | 4 +++- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/commit_graph.c b/src/commit_graph.c index 292250f6531..70e866b92c2 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -201,7 +201,8 @@ int git_commit_graph_file_parse( struct git_commit_graph_chunk *last_chunk; uint32_t i; off64_t last_chunk_offset, chunk_offset, trailer_offset; - git_oid cgraph_checksum = {{0}}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size; int error; struct git_commit_graph_chunk chunk_oid_fanout = {0}, chunk_oid_lookup = {0}, chunk_commit_data = {0}, chunk_extra_edge_list = {0}, @@ -227,13 +228,15 @@ int git_commit_graph_file_parse( */ last_chunk_offset = sizeof(struct git_commit_graph_header) + (1 + hdr->chunks) * 12; trailer_offset = size - GIT_OID_RAWSZ; + checksum_size = GIT_HASH_SHA1_SIZE; + if (trailer_offset < last_chunk_offset) return commit_graph_error("wrong commit-graph size"); - git_oid_cpy(&file->checksum, (git_oid *)(data + trailer_offset)); + memcpy(file->checksum, (data + trailer_offset), checksum_size); - if (git_hash_buf(cgraph_checksum.id, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) + if (git_hash_buf(checksum, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) return commit_graph_error("could not calculate signature"); - if (!git_oid_equal(&cgraph_checksum, &file->checksum)) + if (memcmp(checksum, file->checksum, checksum_size) != 0) return commit_graph_error("index signature mismatch"); chunk_hdr = data + sizeof(struct git_commit_graph_header); @@ -476,7 +479,8 @@ bool git_commit_graph_file_needs_refresh(const git_commit_graph_file *file, cons git_file fd = -1; struct stat st; ssize_t bytes_read; - git_oid cgraph_checksum = {{0}}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size = GIT_HASH_SHA1_SIZE; /* TODO: properly open the file without access time using O_NOATIME */ fd = git_futils_open_ro(path); @@ -494,12 +498,12 @@ bool git_commit_graph_file_needs_refresh(const git_commit_graph_file *file, cons return true; } - bytes_read = p_pread(fd, cgraph_checksum.id, GIT_OID_RAWSZ, st.st_size - GIT_OID_RAWSZ); + bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - checksum_size); p_close(fd); - if (bytes_read != GIT_OID_RAWSZ) + if (bytes_read != (ssize_t)checksum_size) return true; - return !git_oid_equal(&cgraph_checksum, &file->checksum); + return (memcmp(checksum, file->checksum, checksum_size) != 0); } int git_commit_graph_entry_find( @@ -974,7 +978,8 @@ static int commit_graph_write( off64_t offset; git_str oid_lookup = GIT_STR_INIT, commit_data = GIT_STR_INIT, extra_edge_list = GIT_STR_INIT; - git_oid cgraph_checksum = {{0}}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size; git_hash_ctx ctx; struct commit_graph_write_hash_context hash_cb_data = {0}; @@ -987,6 +992,7 @@ static int commit_graph_write( hash_cb_data.cb_data = cb_data; hash_cb_data.ctx = &ctx; + checksum_size = GIT_HASH_SHA1_SIZE; error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1); if (error < 0) return error; @@ -1133,10 +1139,10 @@ static int commit_graph_write( goto cleanup; /* Finalize the checksum and write the trailer. */ - error = git_hash_final(cgraph_checksum.id, &ctx); + error = git_hash_final(checksum, &ctx); if (error < 0) goto cleanup; - error = write_cb((const char *)&cgraph_checksum, sizeof(cgraph_checksum), cb_data); + error = write_cb((char *)checksum, checksum_size, cb_data); if (error < 0) goto cleanup; diff --git a/src/commit_graph.h b/src/commit_graph.h index 4d2be431c1e..45e125b9e16 100644 --- a/src/commit_graph.h +++ b/src/commit_graph.h @@ -15,6 +15,8 @@ #include "map.h" #include "vector.h" +#include "oid.h" +#include "hash.h" /** * A commit-graph file. @@ -55,7 +57,7 @@ typedef struct git_commit_graph_file { size_t num_extra_edge_list; /* The trailer of the file. Contains the SHA1-checksum of the whole file. */ - git_oid checksum; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; } git_commit_graph_file; /** From afca16a7e0f2bdb071de8d77bb42350e8090bc19 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 Jan 2022 13:14:59 -0500 Subject: [PATCH 0756/1616] config: use a byte array for checksum --- src/config_file.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/config_file.c b/src/config_file.c index 43a6ba440f2..66fcb8ae295 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -19,13 +19,14 @@ #include "regexp.h" #include "sysdir.h" #include "wildmatch.h" +#include "hash.h" /* Max depth for [include] directives */ #define MAX_INCLUDE_DEPTH 10 typedef struct config_file { git_futils_filestamp stamp; - git_oid checksum; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; char *path; git_array_t(struct config_file) includes; } config_file; @@ -132,7 +133,7 @@ static int config_file_is_modified(int *modified, config_file *file) { config_file *include; git_str buf = GIT_STR_INIT; - git_oid hash; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; uint32_t i; int error = 0; @@ -144,10 +145,10 @@ static int config_file_is_modified(int *modified, config_file *file) if ((error = git_futils_readbuffer(&buf, file->path)) < 0) goto out; - if ((error = git_hash_buf(hash.id, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) + if ((error = git_hash_buf(checksum, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) goto out; - if (!git_oid_equal(&hash, &file->checksum)) { + if (memcmp(checksum, file->checksum, GIT_HASH_SHA1_SIZE) != 0) { *modified = 1; goto out; } @@ -880,7 +881,7 @@ static int config_file_read( goto out; git_futils_filestamp_set_from_stat(&file->stamp, &st); - if ((error = git_hash_buf(file->checksum.id, contents.ptr, contents.size, GIT_HASH_ALGORITHM_SHA1)) < 0) + if ((error = git_hash_buf(file->checksum, contents.ptr, contents.size, GIT_HASH_ALGORITHM_SHA1)) < 0) goto out; if ((error = config_file_read_buffer(entries, repo, file, level, depth, From 11ef76a9f5bc04cb61760abebc68e6ac5045bf68 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 Jan 2022 13:31:02 -0500 Subject: [PATCH 0757/1616] index: use a byte array for checksum The index's checksum is not an object ID, so we should not use the `git_oid` type. Use a byte array for checksum calculation and storage. Deprecate the `git_index_checksum` function without a replacement. This is an abstraction that callers should not care about (and indeed do not seem to be using). Remove the unused `git_index__changed_relative_to` function. --- include/git2/index.h | 3 ++ src/index.c | 76 +++++++++++++++++++++----------------------- src/index.h | 9 ++++-- tests/diff/workdir.c | 15 +++++---- 4 files changed, 55 insertions(+), 48 deletions(-) diff --git a/include/git2/index.h b/include/git2/index.h index 3cf64d827bb..981535dadad 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -296,6 +296,7 @@ GIT_EXTERN(int) git_index_write(git_index *index); */ GIT_EXTERN(const char *) git_index_path(const git_index *index); +#ifndef GIT_DEPRECATE_HARD /** * Get the checksum of the index * @@ -303,10 +304,12 @@ GIT_EXTERN(const char *) git_index_path(const git_index *index); * last 20 bytes which are the checksum itself). In cases where the * index does not exist on-disk, it will be zeroed out. * + * @deprecated this function is deprecated with no replacement * @param index an existing index object * @return a pointer to the checksum of the index */ GIT_EXTERN(const git_oid *) git_index_checksum(git_index *index); +#endif /** * Read a tree into the index file with stats diff --git a/src/index.c b/src/index.c index 367fd9c3895..aa97c642195 100644 --- a/src/index.c +++ b/src/index.c @@ -34,7 +34,6 @@ static int index_apply_to_wd_diff(git_index *index, int action, const git_strarr #define minimal_entry_size (offsetof(struct entry_short, path)) -static const size_t INDEX_FOOTER_SIZE = GIT_OID_RAWSZ; static const size_t INDEX_HEADER_SIZE = 12; static const unsigned int INDEX_VERSION_NUMBER_DEFAULT = 2; @@ -121,7 +120,7 @@ static int read_header(struct index_header *dest, const void *buffer); static int parse_index(git_index *index, const char *buffer, size_t buffer_size); static bool is_index_extended(git_index *index); -static int write_index(git_oid *checksum, git_index *index, git_filebuf *file); +static int write_index(unsigned char checksum[GIT_HASH_SHA1_SIZE], size_t *checksum_size, git_index *index, git_filebuf *file); static void index_entry_free(git_index_entry *entry); static void index_entry_reuc_free(git_index_reuc_entry *reuc); @@ -607,10 +606,12 @@ int git_index_caps(const git_index *index) (index->no_symlinks ? GIT_INDEX_CAPABILITY_NO_SYMLINKS : 0)); } +#ifndef GIT_DEPRECATE_HARD const git_oid *git_index_checksum(git_index *index) { - return &index->checksum; + return (git_oid *)index->checksum; } +#endif /** * Returns 1 for changed, 0 for not changed and <0 for errors @@ -619,24 +620,25 @@ static int compare_checksum(git_index *index) { int fd; ssize_t bytes_read; - git_oid checksum = {{ 0 }}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size = GIT_HASH_SHA1_SIZE; if ((fd = p_open(index->index_file_path, O_RDONLY)) < 0) return fd; - if (p_lseek(fd, -20, SEEK_END) < 0) { + if (p_lseek(fd, (0 - (ssize_t)checksum_size), SEEK_END) < 0) { p_close(fd); git_error_set(GIT_ERROR_OS, "failed to seek to end of file"); return -1; } - bytes_read = p_read(fd, &checksum, GIT_OID_RAWSZ); + bytes_read = p_read(fd, checksum, checksum_size); p_close(fd); - if (bytes_read < 0) + if (bytes_read < (ssize_t)checksum_size) return -1; - return !!git_oid_cmp(&checksum, &index->checksum); + return !!memcmp(checksum, index->checksum, checksum_size); } int git_index_read(git_index *index, int force) @@ -703,16 +705,6 @@ int git_index_read_safely(git_index *index) return git_index_read(index, false); } -int git_index__changed_relative_to( - git_index *index, const git_oid *checksum) -{ - /* attempt to update index (ignoring errors) */ - if (git_index_read(index, false) < 0) - git_error_clear(); - - return !!git_oid_cmp(&index->checksum, checksum); -} - static bool is_racy_entry(git_index *index, const git_index_entry *entry) { /* Git special-cases submodules in the check */ @@ -2470,8 +2462,9 @@ static int read_entry( git_index_entry entry = {{0}}; bool compressed = index->version >= INDEX_VERSION_NUMBER_COMP; char *tmp_path = NULL; + size_t checksum_size = GIT_HASH_SHA1_SIZE; - if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size) + if (checksum_size + minimal_entry_size > buffer_size) return -1; /* buffer is not guaranteed to be aligned */ @@ -2552,7 +2545,7 @@ static int read_entry( if (entry_size == 0) return -1; - if (INDEX_FOOTER_SIZE + entry_size > buffer_size) + if (checksum_size + entry_size > buffer_size) return -1; if (index_entry_dup(out, index, &entry) < 0) { @@ -2586,6 +2579,7 @@ static int read_extension(size_t *read_len, git_index *index, const char *buffer { struct index_extension dest; size_t total_size; + size_t checksum_size = GIT_HASH_SHA1_SIZE; /* buffer is not guaranteed to be aligned */ memcpy(&dest, buffer, sizeof(struct index_extension)); @@ -2595,7 +2589,7 @@ static int read_extension(size_t *read_len, git_index *index, const char *buffer if (dest.extension_size > total_size || buffer_size < total_size || - buffer_size - total_size < INDEX_FOOTER_SIZE) { + buffer_size - total_size < checksum_size) { index_error_invalid("extension is truncated"); return -1; } @@ -2632,7 +2626,8 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) int error = 0; unsigned int i; struct index_header header = { 0 }; - git_oid checksum_calculated, checksum_expected; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size = GIT_HASH_SHA1_SIZE; const char *last = NULL; const char *empty = ""; @@ -2644,12 +2639,12 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) buffer_size -= _increase;\ } - if (buffer_size < INDEX_HEADER_SIZE + INDEX_FOOTER_SIZE) + if (buffer_size < INDEX_HEADER_SIZE + checksum_size) return index_error_invalid("insufficient buffer space"); /* Precalculate the SHA1 of the files's contents -- we'll match it to * the provided SHA1 in the footer */ - git_hash_buf(checksum_calculated.id, buffer, buffer_size - INDEX_FOOTER_SIZE, GIT_HASH_ALGORITHM_SHA1); + git_hash_buf(checksum, buffer, buffer_size - checksum_size, GIT_HASH_ALGORITHM_SHA1); /* Parse header */ if ((error = read_header(&header, buffer)) < 0) @@ -2667,7 +2662,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) return error; /* Parse all the entries */ - for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) { + for (i = 0; i < header.entry_count && buffer_size > checksum_size; ++i) { git_index_entry *entry = NULL; size_t entry_size; @@ -2699,7 +2694,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) } /* There's still space for some extensions! */ - while (buffer_size > INDEX_FOOTER_SIZE) { + while (buffer_size > checksum_size) { size_t extension_size; if ((error = read_extension(&extension_size, index, buffer, buffer_size)) < 0) { @@ -2709,22 +2704,20 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) seek_forward(extension_size); } - if (buffer_size != INDEX_FOOTER_SIZE) { + if (buffer_size != checksum_size) { error = index_error_invalid( "buffer size does not match index footer size"); goto done; } /* 160-bit SHA-1 over the content of the index file before this checksum. */ - git_oid_fromraw(&checksum_expected, (const unsigned char *)buffer); - - if (git_oid__cmp(&checksum_calculated, &checksum_expected) != 0) { + if (memcmp(checksum, buffer, checksum_size) != 0) { error = index_error_invalid( "calculated checksum does not match expected"); goto done; } - git_oid_cpy(&index->checksum, &checksum_calculated); + memcpy(index->checksum, checksum, checksum_size); #undef seek_forward @@ -3040,9 +3033,12 @@ static void clear_uptodate(git_index *index) entry->flags_extended &= ~GIT_INDEX_ENTRY_UPTODATE; } -static int write_index(git_oid *checksum, git_index *index, git_filebuf *file) +static int write_index( + unsigned char checksum[GIT_HASH_SHA1_SIZE], + size_t *checksum_size, + git_index *index, + git_filebuf *file) { - git_oid hash_final; struct index_header header; bool is_extended; uint32_t index_version_number; @@ -3050,6 +3046,8 @@ static int write_index(git_oid *checksum, git_index *index, git_filebuf *file) GIT_ASSERT_ARG(index); GIT_ASSERT_ARG(file); + *checksum_size = GIT_HASH_SHA1_SIZE; + if (index->version <= INDEX_VERSION_NUMBER_EXT) { is_extended = is_index_extended(index); index_version_number = is_extended ? INDEX_VERSION_NUMBER_EXT : INDEX_VERSION_NUMBER_LB; @@ -3080,11 +3078,10 @@ static int write_index(git_oid *checksum, git_index *index, git_filebuf *file) return -1; /* get out the hash for all the contents we've appended to the file */ - git_filebuf_hash(hash_final.id, file); - git_oid_cpy(checksum, &hash_final); + git_filebuf_hash(checksum, file); /* write it at the end of the file */ - if (git_filebuf_write(file, hash_final.id, GIT_OID_RAWSZ) < 0) + if (git_filebuf_write(file, checksum, *checksum_size) < 0) return -1; /* file entries are no longer up to date */ @@ -3714,8 +3711,9 @@ int git_indexwriter_init_for_operation( int git_indexwriter_commit(git_indexwriter *writer) { + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size; int error; - git_oid checksum = {{ 0 }}; if (!writer->should_write) return 0; @@ -3723,7 +3721,7 @@ int git_indexwriter_commit(git_indexwriter *writer) git_vector_sort(&writer->index->entries); git_vector_sort(&writer->index->reuc); - if ((error = write_index(&checksum, writer->index, &writer->file)) < 0) { + if ((error = write_index(checksum, &checksum_size, writer->index, &writer->file)) < 0) { git_indexwriter_cleanup(writer); return error; } @@ -3739,7 +3737,7 @@ int git_indexwriter_commit(git_indexwriter *writer) writer->index->dirty = 0; writer->index->on_disk = 1; - git_oid_cpy(&writer->index->checksum, &checksum); + memcpy(writer->index->checksum, checksum, checksum_size); git_index_free(writer->index); writer->index = NULL; diff --git a/src/index.h b/src/index.h index a365867d0bf..71bb096f738 100644 --- a/src/index.h +++ b/src/index.h @@ -27,7 +27,7 @@ struct git_index { char *index_file_path; git_futils_filestamp stamp; - git_oid checksum; /* checksum at the end of the file */ + unsigned char checksum[GIT_HASH_SHA1_SIZE]; git_vector entries; git_idxmap *entries_map; @@ -133,10 +133,13 @@ extern unsigned int git_index__create_mode(unsigned int mode); GIT_INLINE(const git_futils_filestamp *) git_index__filestamp(git_index *index) { - return &index->stamp; + return &index->stamp; } -extern int git_index__changed_relative_to(git_index *index, const git_oid *checksum); +GIT_INLINE(unsigned char *) git_index__checksum(git_index *index) +{ + return index->checksum; +} /* Copy the current entries vector *and* increment the index refcount. * Call `git_index__release_snapshot` when done. diff --git a/tests/diff/workdir.c b/tests/diff/workdir.c index 444fc2f9791..cdf53faa129 100644 --- a/tests/diff/workdir.c +++ b/tests/diff/workdir.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include "diff_helpers.h" #include "repository.h" +#include "index.h" #include "git2/sys/diff.h" #include "../checkout/checkout_helpers.h" @@ -2004,7 +2005,9 @@ void test_diff_workdir__only_writes_index_when_necessary(void) git_diff *diff = NULL; git_reference *head; git_object *head_object; - git_oid initial, first, second; + unsigned char initial[GIT_HASH_SHA1_SIZE], + first[GIT_HASH_SHA1_SIZE], + second[GIT_HASH_SHA1_SIZE]; git_str path = GIT_STR_INIT; struct stat st; struct p_timeval times[2]; @@ -2019,7 +2022,7 @@ void test_diff_workdir__only_writes_index_when_necessary(void) cl_git_pass(git_reset(g_repo, head_object, GIT_RESET_HARD, NULL)); - git_oid_cpy(&initial, git_index_checksum(index)); + memcpy(initial, git_index__checksum(index), GIT_HASH_SHA1_SIZE); /* update the index timestamp to avoid raciness */ cl_must_pass(p_stat("status/.git/index", &st)); @@ -2035,8 +2038,8 @@ void test_diff_workdir__only_writes_index_when_necessary(void) cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts)); git_diff_free(diff); - git_oid_cpy(&first, git_index_checksum(index)); - cl_assert(!git_oid_equal(&initial, &first)); + memcpy(first, git_index__checksum(index), GIT_HASH_SHA1_SIZE); + cl_assert(memcmp(initial, first, GIT_HASH_SHA1_SIZE) != 0); /* touch all the files so stat times are different */ cl_git_pass(git_str_sets(&path, "status")); @@ -2046,8 +2049,8 @@ void test_diff_workdir__only_writes_index_when_necessary(void) git_diff_free(diff); /* ensure the second diff did update the index */ - git_oid_cpy(&second, git_index_checksum(index)); - cl_assert(!git_oid_equal(&first, &second)); + memcpy(second, git_index__checksum(index), GIT_HASH_SHA1_SIZE); + cl_assert(memcmp(first, second, GIT_HASH_SHA1_SIZE) != 0); git_str_dispose(&path); git_object_free(head_object); From d2458af7b7227f0b378e1509d7dfeb958c339590 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 Jan 2022 14:19:13 -0500 Subject: [PATCH 0758/1616] indexer: use a byte array for checksum The index's checksum is not an object ID, so we should not use the `git_oid` type. Use a byte array for checksum calculation and storage. Deprecate the `git_indexer_hash` function. Callers should use the new `git_indexer_name` function which provides a unique packfile name. --- examples/index-pack.c | 4 +--- include/git2/indexer.h | 14 +++++++++++ src/indexer.c | 50 +++++++++++++++++++++++++--------------- tests/pack/indexer.c | 3 +-- tests/pack/packbuilder.c | 13 +++++------ 5 files changed, 53 insertions(+), 31 deletions(-) diff --git a/examples/index-pack.c b/examples/index-pack.c index c58ac038ad0..df37dd0c45e 100644 --- a/examples/index-pack.c +++ b/examples/index-pack.c @@ -17,7 +17,6 @@ int lg2_index_pack(git_repository *repo, int argc, char **argv) git_indexer *idx; git_indexer_progress stats = {0, 0}; int error; - char hash[GIT_OID_HEXSZ + 1] = {0}; int fd; ssize_t read_bytes; char buf[512]; @@ -61,8 +60,7 @@ int lg2_index_pack(git_repository *repo, int argc, char **argv) printf("\rIndexing %u of %u\n", stats.indexed_objects, stats.total_objects); - git_oid_fmt(hash, git_indexer_hash(idx)); - puts(hash); + puts(git_indexer_name(idx)); cleanup: close(fd); diff --git a/include/git2/indexer.h b/include/git2/indexer.h index 4bacbd3171f..ffe9bf366d5 100644 --- a/include/git2/indexer.h +++ b/include/git2/indexer.h @@ -129,16 +129,30 @@ GIT_EXTERN(int) git_indexer_append(git_indexer *idx, const void *data, size_t si */ GIT_EXTERN(int) git_indexer_commit(git_indexer *idx, git_indexer_progress *stats); +#ifndef GIT_DEPRECATE_HARD /** * Get the packfile's hash * * A packfile's name is derived from the sorted hashing of all object * names. This is only correct after the index has been finalized. * + * @deprecated use git_indexer_name * @param idx the indexer instance * @return the packfile's hash */ GIT_EXTERN(const git_oid *) git_indexer_hash(const git_indexer *idx); +#endif + +/** + * Get the unique name for the resulting packfile. + * + * The packfile's name is derived from the packfile's content. + * This is only correct after the index has been finalized. + * + * @param idx the indexer instance + * @return a NUL terminated string for the packfile name + */ +GIT_EXTERN(const char *) git_indexer_name(const git_indexer *idx); /** * Free the indexer and its resources diff --git a/src/indexer.c b/src/indexer.c index 16db9ca8d72..f9a32e7ac64 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -55,7 +55,8 @@ struct git_indexer { git_vector deltas; unsigned int fanout[256]; git_hash_ctx hash_ctx; - git_oid hash; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + char name[(GIT_HASH_SHA1_SIZE * 2) + 1]; git_indexer_progress_cb progress_cb; void *progress_payload; char objbuf[8*1024]; @@ -76,9 +77,16 @@ struct delta_info { off64_t delta_off; }; +#ifndef GIT_DEPRECATE_HARD const git_oid *git_indexer_hash(const git_indexer *idx) { - return &idx->hash; + return (git_oid *)idx->checksum; +} +#endif + +const char *git_indexer_name(const git_indexer *idx) +{ + return idx->name; } static int parse_header(struct git_pack_header *hdr, struct git_pack_file *pack) @@ -897,8 +905,7 @@ static int index_path(git_str *path, git_indexer *idx, const char *suffix) git_str_truncate(path, slash); git_str_puts(path, prefix); - git_oid_fmt(path->ptr + git_str_len(path), &idx->hash); - path->size += GIT_OID_HEXSZ; + git_str_puts(path, idx->name); git_str_puts(path, suffix); return git_str_oom(path) ? -1 : 0; @@ -919,12 +926,13 @@ static int inject_object(git_indexer *idx, git_oid *id) git_odb_object *obj = NULL; struct entry *entry = NULL; struct git_pack_entry *pentry = NULL; - git_oid foo = {{0}}; + unsigned char empty_checksum[GIT_HASH_SHA1_SIZE] = {0}; unsigned char hdr[64]; git_str buf = GIT_STR_INIT; off64_t entry_start; const void *data; size_t len, hdr_len; + size_t checksum_size = GIT_HASH_SHA1_SIZE; int error; if ((error = seek_back_trailer(idx)) < 0) @@ -966,7 +974,7 @@ static int inject_object(git_indexer *idx, git_oid *id) /* Write a fake trailer so the pack functions play ball */ - if ((error = append_to_pack(idx, &foo, GIT_OID_RAWSZ)) < 0) + if ((error = append_to_pack(idx, empty_checksum, checksum_size)) < 0) goto cleanup; idx->pack->mwf.size += GIT_OID_RAWSZ; @@ -1160,9 +1168,11 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) struct git_pack_idx_header hdr; git_str filename = GIT_STR_INIT; struct entry *entry; - git_oid trailer_hash, file_hash; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; git_filebuf index_file = {0}; void *packfile_trailer; + size_t checksum_size = GIT_HASH_SHA1_SIZE; + bool mismatch; if (!idx->parsed_header) { git_error_set(GIT_ERROR_INDEXER, "incomplete pack header"); @@ -1170,27 +1180,27 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) } /* Test for this before resolve_deltas(), as it plays with idx->off */ - if (idx->off + 20 < idx->pack->mwf.size) { + if (idx->off + (ssize_t)checksum_size < idx->pack->mwf.size) { git_error_set(GIT_ERROR_INDEXER, "unexpected data at the end of the pack"); return -1; } - if (idx->off + 20 > idx->pack->mwf.size) { + if (idx->off + (ssize_t)checksum_size > idx->pack->mwf.size) { git_error_set(GIT_ERROR_INDEXER, "missing trailer at the end of the pack"); return -1; } - packfile_trailer = git_mwindow_open(&idx->pack->mwf, &w, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ, &left); + packfile_trailer = git_mwindow_open(&idx->pack->mwf, &w, idx->pack->mwf.size - checksum_size, checksum_size, &left); if (packfile_trailer == NULL) { git_mwindow_close(&w); goto on_error; } /* Compare the packfile trailer as it was sent to us and what we calculated */ - git_oid_fromraw(&file_hash, packfile_trailer); + git_hash_final(checksum, &idx->trailer); + mismatch = !!memcmp(checksum, packfile_trailer, checksum_size); git_mwindow_close(&w); - git_hash_final(trailer_hash.id, &idx->trailer); - if (git_oid_cmp(&file_hash, &trailer_hash)) { + if (mismatch) { git_error_set(GIT_ERROR_INDEXER, "packfile trailer mismatch"); return -1; } @@ -1210,8 +1220,8 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) if (update_header_and_rehash(idx, stats) < 0) return -1; - git_hash_final(trailer_hash.id, &idx->trailer); - write_at(idx, &trailer_hash, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ); + git_hash_final(checksum, &idx->trailer); + write_at(idx, checksum, idx->pack->mwf.size - checksum_size, checksum_size); } /* @@ -1230,7 +1240,9 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) /* Use the trailer hash as the pack file name to ensure * files with different contents have different names */ - git_oid_cpy(&idx->hash, &trailer_hash); + memcpy(idx->checksum, checksum, checksum_size); + if (git_hash_fmt(idx->name, checksum, checksum_size) < 0) + return -1; git_str_sets(&filename, idx->pack->pack_name); git_str_shorten(&filename, strlen("pack")); @@ -1291,14 +1303,14 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) } /* Write out the packfile trailer to the index */ - if (git_filebuf_write(&index_file, &trailer_hash, GIT_OID_RAWSZ) < 0) + if (git_filebuf_write(&index_file, checksum, checksum_size) < 0) goto on_error; /* Write out the hash of the idx */ - if (git_filebuf_hash(trailer_hash.id, &index_file) < 0) + if (git_filebuf_hash(checksum, &index_file) < 0) goto on_error; - git_filebuf_write(&index_file, &trailer_hash, sizeof(git_oid)); + git_filebuf_write(&index_file, checksum, checksum_size); /* Figure out what the final name should be */ if (index_path(&filename, idx, ".idx") < 0) diff --git a/tests/pack/indexer.c b/tests/pack/indexer.c index 954bee9532b..ec48ffd9819 100644 --- a/tests/pack/indexer.c +++ b/tests/pack/indexer.c @@ -169,8 +169,7 @@ void test_pack_indexer__fix_thin(void) cl_assert_equal_i(stats.indexed_objects, 2); cl_assert_equal_i(stats.local_objects, 1); - git_oid_fromstr(&should_id, "fefdb2d740a3a6b6c03a0c7d6ce431c6d5810e13"); - cl_assert_equal_oid(&should_id, git_indexer_hash(idx)); + cl_assert_equal_s("fefdb2d740a3a6b6c03a0c7d6ce431c6d5810e13", git_indexer_name(idx)); git_indexer_free(idx); git_odb_free(odb); diff --git a/tests/pack/packbuilder.c b/tests/pack/packbuilder.c index 5b1f7b9e9f3..73bc6674b12 100644 --- a/tests/pack/packbuilder.c +++ b/tests/pack/packbuilder.c @@ -5,6 +5,7 @@ #include "iterator.h" #include "vector.h" #include "posix.h" +#include "hash.h" static git_repository *_repo; static git_revwalk *_revwalker; @@ -98,8 +99,8 @@ void test_pack_packbuilder__create_pack(void) git_indexer_progress stats; git_str buf = GIT_STR_INIT, path = GIT_STR_INIT; git_hash_ctx ctx; - git_oid hash; - char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0'; + unsigned char hash[GIT_HASH_SHA1_SIZE]; + char hex[(GIT_HASH_SHA1_SIZE * 2) + 1]; seed_packbuilder(); @@ -107,8 +108,7 @@ void test_pack_packbuilder__create_pack(void) cl_git_pass(git_packbuilder_foreach(_packbuilder, feed_indexer, &stats)); cl_git_pass(git_indexer_commit(_indexer, &stats)); - git_oid_fmt(hex, git_indexer_hash(_indexer)); - git_str_printf(&path, "pack-%s.pack", hex); + git_str_printf(&path, "pack-%s.pack", git_indexer_name(_indexer)); /* * By default, packfiles are created with only one thread. @@ -128,14 +128,13 @@ void test_pack_packbuilder__create_pack(void) cl_git_pass(git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1)); cl_git_pass(git_hash_update(&ctx, buf.ptr, buf.size)); - cl_git_pass(git_hash_final(hash.id, &ctx)); + cl_git_pass(git_hash_final(hash, &ctx)); git_hash_ctx_cleanup(&ctx); git_str_dispose(&path); git_str_dispose(&buf); - git_oid_fmt(hex, &hash); - + git_hash_fmt(hex, hash, GIT_HASH_SHA1_SIZE); cl_assert_equal_s(hex, "5d410bdf97cf896f9007681b92868471d636954b"); } From 70d9bfa47c14fd230d081cebb9933622136479ea Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 22 Jan 2022 17:34:36 -0500 Subject: [PATCH 0759/1616] packbuilder: use the packfile name instead of hash Deprecate the `git_packfile_hash` function. Callers should use the new `git_packfile_name` function which provides a unique packfile name. --- fuzzers/packfile_fuzzer.c | 4 ++-- include/git2/pack.h | 28 +++++++++++++++++++++------- src/pack-objects.c | 14 ++++++++++++++ src/pack-objects.h | 3 +++ tests/checkout/crlf.c | 4 ++-- tests/pack/packbuilder.c | 8 ++------ 6 files changed, 44 insertions(+), 17 deletions(-) diff --git a/fuzzers/packfile_fuzzer.c b/fuzzers/packfile_fuzzer.c index 8667cb9c589..6002fa1de8f 100644 --- a/fuzzers/packfile_fuzzer.c +++ b/fuzzers/packfile_fuzzer.c @@ -101,13 +101,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) if (git_indexer_commit(indexer, &stats) < 0) goto cleanup; - if (git_str_printf(&path, "pack-%s.idx", git_oid_tostr_s(git_indexer_hash(indexer))) < 0) + if (git_str_printf(&path, "pack-%s.idx", git_indexer_name(indexer)) < 0) goto cleanup; p_unlink(git_str_cstr(&path)); git_str_clear(&path); - if (git_str_printf(&path, "pack-%s.pack", git_oid_tostr_s(git_indexer_hash(indexer))) < 0) + if (git_str_printf(&path, "pack-%s.pack", git_indexer_name(indexer)) < 0) goto cleanup; p_unlink(git_str_cstr(&path)); diff --git a/include/git2/pack.h b/include/git2/pack.h index 253a860cd3b..0f6bd2ab928 100644 --- a/include/git2/pack.h +++ b/include/git2/pack.h @@ -170,16 +170,30 @@ GIT_EXTERN(int) git_packbuilder_write( git_indexer_progress_cb progress_cb, void *progress_cb_payload); +#ifndef GIT_DEPRECATE_HARD /** -* Get the packfile's hash -* -* A packfile's name is derived from the sorted hashing of all object -* names. This is only correct after the packfile has been written. -* -* @param pb The packbuilder object + * Get the packfile's hash + * + * A packfile's name is derived from the sorted hashing of all object + * names. This is only correct after the packfile has been written. + * + * @deprecated use git_packbuilder_name + * @param pb The packbuilder object * @return 0 or an error code -*/ + */ GIT_EXTERN(const git_oid *) git_packbuilder_hash(git_packbuilder *pb); +#endif + +/** + * Get the unique name for the resulting packfile. + * + * The packfile's name is derived from the packfile's content. + * This is only correct after the packfile has been written. + * + * @param pb the packbuilder instance + * @return a NUL terminated string for the packfile name + */ +GIT_EXTERN(const char *) git_packbuilder_name(git_packbuilder *pb); /** * Callback used to iterate over packed objects diff --git a/src/pack-objects.c b/src/pack-objects.c index e5fc625a465..35c1d55dbb1 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -1422,7 +1422,12 @@ int git_packbuilder_write( if ((error = git_indexer_commit(indexer, &stats)) < 0) goto cleanup; +#ifndef GIT_DEPRECATE_HARD git_oid_cpy(&pb->pack_oid, git_indexer_hash(indexer)); +#endif + + pb->pack_name = git__strdup(git_indexer_name(indexer)); + GIT_ERROR_CHECK_ALLOC(pb->pack_name); cleanup: git_indexer_free(indexer); @@ -1432,10 +1437,17 @@ int git_packbuilder_write( #undef PREPARE_PACK +#ifndef GIT_DEPRECATE_HARD const git_oid *git_packbuilder_hash(git_packbuilder *pb) { return &pb->pack_oid; } +#endif + +const char *git_packbuilder_name(git_packbuilder *pb) +{ + return pb->pack_name; +} static int cb_tree_walk( @@ -1803,5 +1815,7 @@ void git_packbuilder_free(git_packbuilder *pb) git_hash_ctx_cleanup(&pb->ctx); git_zstream_free(&pb->zstream); + git__free(pb->pack_name); + git__free(pb); } diff --git a/src/pack-objects.h b/src/pack-objects.h index cefee40efc2..53c9f5d4504 100644 --- a/src/pack-objects.h +++ b/src/pack-objects.h @@ -73,7 +73,10 @@ struct git_packbuilder { git_oidmap *walk_objects; git_pool object_pool; +#ifndef GIT_DEPRECATE_HARD git_oid pack_oid; /* hash of written pack */ +#endif + char *pack_name; /* name of written pack */ /* synchronization objects */ git_mutex cache_mutex; diff --git a/tests/checkout/crlf.c b/tests/checkout/crlf.c index 8fd16a00444..21f8a852a64 100644 --- a/tests/checkout/crlf.c +++ b/tests/checkout/crlf.c @@ -239,10 +239,10 @@ void test_checkout_crlf__autocrlf_false_index_size_is_unfiltered_size(void) cl_repo_set_bool(g_repo, "core.autocrlf", false); - git_repository_index(&index, g_repo); + cl_git_pass(git_repository_index(&index, g_repo)); tick_index(index); - git_checkout_head(g_repo, &opts); + cl_git_pass(git_checkout_head(g_repo, &opts)); cl_assert((entry = git_index_get_bypath(index, "all-lf", 0)) != NULL); cl_assert(entry->file_size == strlen(ALL_LF_TEXT_RAW)); diff --git a/tests/pack/packbuilder.c b/tests/pack/packbuilder.c index 73bc6674b12..f23579817cf 100644 --- a/tests/pack/packbuilder.c +++ b/tests/pack/packbuilder.c @@ -138,16 +138,12 @@ void test_pack_packbuilder__create_pack(void) cl_assert_equal_s(hex, "5d410bdf97cf896f9007681b92868471d636954b"); } -void test_pack_packbuilder__get_hash(void) +void test_pack_packbuilder__get_name(void) { - char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0'; - seed_packbuilder(); cl_git_pass(git_packbuilder_write(_packbuilder, ".", 0, NULL, NULL)); - git_oid_fmt(hex, git_packbuilder_hash(_packbuilder)); - - cl_assert_equal_s(hex, "7f5fa362c664d68ba7221259be1cbd187434b2f0"); + cl_assert_equal_s("7f5fa362c664d68ba7221259be1cbd187434b2f0", git_packbuilder_name(_packbuilder)); } void test_pack_packbuilder__write_default_path(void) From 1458fb56efad36a5d231793b63b466d5a07a5488 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 29 Jan 2022 07:18:26 -0500 Subject: [PATCH 0760/1616] xdiff: include new xdiff from git Update to the xdiff used in git v2.35.0, with updates to our build configuration to ignore the sort of warnings that we normally care about (signed/unsigned mismatch, unused, etc.) Any git-specific abstraction bits are now redefined for our use in `git-xdiff.h`. It is a (wildly optimistic) hope that we can use that indirection layer to standardize on a shared xdiff implementation. --- src/CMakeLists.txt | 10 ++ src/blame_git.c | 2 +- src/diff_xdiff.c | 11 +- src/merge_file.c | 14 ++- src/patch_generate.c | 28 ++++- src/patch_generate.h | 8 +- src/xdiff/git-xdiff.h | 42 +++++++ src/xdiff/xdiff.h | 30 ++--- src/xdiff/xdiffi.c | 242 +++++++++++++++++++++++------------------ src/xdiff/xemit.c | 30 +++-- src/xdiff/xhistogram.c | 165 +++++++++++++++------------- src/xdiff/xinclude.h | 13 +-- src/xdiff/xmerge.c | 217 +++++++++++++++++------------------- src/xdiff/xpatience.c | 23 +--- src/xdiff/xprepare.c | 35 +++--- src/xdiff/xutils.c | 25 +++-- 16 files changed, 494 insertions(+), 401 deletions(-) create mode 100644 src/xdiff/git-xdiff.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 98881b5add6..fe68d0fe767 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -206,7 +206,17 @@ endif() # errors for the xdiff sources until we've sorted them out if(MSVC) set_source_files_properties(xdiff/xdiffi.c PROPERTIES COMPILE_FLAGS -WX-) + set_source_files_properties(xdiff/xemit.c PROPERTIES COMPILE_FLAGS -WX-) + set_source_files_properties(xdiff/xhistogram.c PROPERTIES COMPILE_FLAGS -WX-) + set_source_files_properties(xdiff/xmerge.c PROPERTIES COMPILE_FLAGS -WX-) set_source_files_properties(xdiff/xutils.c PROPERTIES COMPILE_FLAGS -WX-) + set_source_files_properties(xdiff/xpatience.c PROPERTIES COMPILE_FLAGS -WX-) +else() + set_source_files_properties(xdiff/xdiffi.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-parameter") + set_source_files_properties(xdiff/xemit.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-parameter") + set_source_files_properties(xdiff/xhistogram.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") + set_source_files_properties(xdiff/xutils.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") + set_source_files_properties(xdiff/xpatience.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") endif() # Determine architecture of the machine diff --git a/src/blame_git.c b/src/blame_git.c index 3d514a1bc0f..2504b338ac5 100644 --- a/src/blame_git.c +++ b/src/blame_git.c @@ -393,7 +393,7 @@ static void fill_origin_blob(git_blame__origin *o, mmfile_t *file) memset(file, 0, sizeof(*file)); if (o->blob) { file->ptr = (char*)git_blob_rawcontent(o->blob); - file->size = (size_t)git_blob_rawsize(o->blob); + file->size = (long)git_blob_rawsize(o->blob); } } diff --git a/src/diff_xdiff.c b/src/diff_xdiff.c index 278e2be36e9..3f6eccac13d 100644 --- a/src/diff_xdiff.c +++ b/src/diff_xdiff.c @@ -218,14 +218,9 @@ static int git_xdiff(git_patch_generated_output *output, git_patch_generated *pa * updates are needed to xo->params.flags */ - git_patch_generated_old_data(&info.xd_old_data.ptr, &info.xd_old_data.size, patch); - git_patch_generated_new_data(&info.xd_new_data.ptr, &info.xd_new_data.size, patch); - - if (info.xd_old_data.size > GIT_XDIFF_MAX_SIZE || - info.xd_new_data.size > GIT_XDIFF_MAX_SIZE) { - git_error_set(GIT_ERROR_INVALID, "files too large for diff"); + if (git_patch_generated_old_data(&info.xd_old_data.ptr, &info.xd_old_data.size, patch) < 0 || + git_patch_generated_new_data(&info.xd_new_data.ptr, &info.xd_new_data.size, patch) < 0) return -1; - } xdl_diff(&info.xd_old_data, &info.xd_new_data, &xo->params, &xo->config, &xo->callback); @@ -261,5 +256,5 @@ void git_xdiff_init(git_xdiff_output *xo, const git_diff_options *opts) if (flags & GIT_DIFF_IGNORE_BLANK_LINES) xo->params.flags |= XDF_IGNORE_BLANK_LINES; - xo->callback.outf = git_xdiff_cb; + xo->callback.out_line = git_xdiff_cb; } diff --git a/src/merge_file.c b/src/merge_file.c index bfa3ec52e48..7285884b4af 100644 --- a/src/merge_file.c +++ b/src/merge_file.c @@ -86,22 +86,30 @@ static int merge_file__xdiff( memset(&xmparam, 0x0, sizeof(xmparam_t)); + if (ours->size > LONG_MAX || + theirs->size > LONG_MAX || + (ancestor && ancestor->size > LONG_MAX)) { + git_error_set(GIT_ERROR_MERGE, "failed to merge files"); + error = -1; + goto done; + } + if (ancestor) { xmparam.ancestor = (options.ancestor_label) ? options.ancestor_label : ancestor->path; ancestor_mmfile.ptr = (char *)ancestor->ptr; - ancestor_mmfile.size = ancestor->size; + ancestor_mmfile.size = (long)ancestor->size; } xmparam.file1 = (options.our_label) ? options.our_label : ours->path; our_mmfile.ptr = (char *)ours->ptr; - our_mmfile.size = ours->size; + our_mmfile.size = (long)ours->size; xmparam.file2 = (options.their_label) ? options.their_label : theirs->path; their_mmfile.ptr = (char *)theirs->ptr; - their_mmfile.size = theirs->size; + their_mmfile.size = (long)theirs->size; if (options.favor == GIT_MERGE_FILE_FAVOR_OURS) xmparam.favor = XDL_MERGE_FAVOR_OURS; diff --git a/src/patch_generate.c b/src/patch_generate.c index 6d115affebc..bc598fea870 100644 --- a/src/patch_generate.c +++ b/src/patch_generate.c @@ -750,18 +750,34 @@ git_diff_driver *git_patch_generated_driver(git_patch_generated *patch) return patch->ofile.driver; } -void git_patch_generated_old_data( - char **ptr, size_t *len, git_patch_generated *patch) +int git_patch_generated_old_data( + char **ptr, long *len, git_patch_generated *patch) { + if (patch->ofile.map.len > LONG_MAX || + patch->ofile.map.len > GIT_XDIFF_MAX_SIZE) { + git_error_set(GIT_ERROR_INVALID, "files too large for diff"); + return -1; + } + *ptr = patch->ofile.map.data; - *len = patch->ofile.map.len; + *len = (long)patch->ofile.map.len; + + return 0; } -void git_patch_generated_new_data( - char **ptr, size_t *len, git_patch_generated *patch) +int git_patch_generated_new_data( + char **ptr, long *len, git_patch_generated *patch) { + if (patch->ofile.map.len > LONG_MAX || + patch->ofile.map.len > GIT_XDIFF_MAX_SIZE) { + git_error_set(GIT_ERROR_INVALID, "files too large for diff"); + return -1; + } + *ptr = patch->nfile.map.data; - *len = patch->nfile.map.len; + *len = (long)patch->nfile.map.len; + + return 0; } static int patch_generated_file_cb( diff --git a/src/patch_generate.h b/src/patch_generate.h index 0e09d27ca4e..56e3e9df475 100644 --- a/src/patch_generate.h +++ b/src/patch_generate.h @@ -39,10 +39,10 @@ typedef struct git_patch_generated git_patch_generated; extern git_diff_driver *git_patch_generated_driver(git_patch_generated *); -extern void git_patch_generated_old_data( - char **, size_t *, git_patch_generated *); -extern void git_patch_generated_new_data( - char **, size_t *, git_patch_generated *); +extern int git_patch_generated_old_data( + char **, long *, git_patch_generated *); +extern int git_patch_generated_new_data( + char **, long *, git_patch_generated *); extern int git_patch_generated_from_diff( git_patch **, git_diff *, size_t); diff --git a/src/xdiff/git-xdiff.h b/src/xdiff/git-xdiff.h new file mode 100644 index 00000000000..0b4f0bc04c7 --- /dev/null +++ b/src/xdiff/git-xdiff.h @@ -0,0 +1,42 @@ +/* + * 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. + */ + +/* + * This file provides the necessary indirection between xdiff and + * libgit2. libgit2-specific functionality should live here, so + * that git and libgit2 can share a common xdiff implementation. + */ + +#ifndef INCLUDE_git_xdiff_h__ +#define INCLUDE_git_xdiff_h__ + +#include "regexp.h" + +#define xdl_malloc(x) git__malloc(x) +#define xdl_free(ptr) git__free(ptr) +#define xdl_realloc(ptr, x) git__realloc(ptr, x) + +#define XDL_BUG(msg) GIT_ASSERT(msg) + +#define xdl_regex_t git_regexp +#define xdl_regmatch_t git_regmatch + +GIT_INLINE(int) xdl_regexec_buf( + const xdl_regex_t *preg, const char *buf, size_t size, + size_t nmatch, xdl_regmatch_t pmatch[], int eflags) +{ + GIT_UNUSED(preg); + GIT_UNUSED(buf); + GIT_UNUSED(size); + GIT_UNUSED(nmatch); + GIT_UNUSED(pmatch); + GIT_UNUSED(eflags); + GIT_ASSERT("not implemented"); + return -1; +} + +#endif diff --git a/src/xdiff/xdiff.h b/src/xdiff/xdiff.h index 5b13e77a0d3..a7bf17cd6b7 100644 --- a/src/xdiff/xdiff.h +++ b/src/xdiff/xdiff.h @@ -23,6 +23,8 @@ #if !defined(XDIFF_H) #define XDIFF_H +#include "git-xdiff.h" + #ifdef __cplusplus extern "C" { #endif /* #ifdef __cplusplus */ @@ -50,16 +52,9 @@ extern "C" { /* xdemitconf_t.flags */ #define XDL_EMIT_FUNCNAMES (1 << 0) +#define XDL_EMIT_NO_HUNK_HDR (1 << 1) #define XDL_EMIT_FUNCCONTEXT (1 << 2) -#define XDL_MMB_READONLY (1 << 0) - -#define XDL_MMF_ATOMIC (1 << 0) - -#define XDL_BDOP_INS 1 -#define XDL_BDOP_CPY 2 -#define XDL_BDOP_INSB 3 - /* merge simplification levels */ #define XDL_MERGE_MINIMAL 0 #define XDL_MERGE_EAGER 1 @@ -73,20 +68,25 @@ extern "C" { /* merge output styles */ #define XDL_MERGE_DIFF3 1 +#define XDL_MERGE_ZEALOUS_DIFF3 2 typedef struct s_mmfile { char *ptr; - size_t size; + long size; } mmfile_t; typedef struct s_mmbuffer { char *ptr; - size_t size; + long size; } mmbuffer_t; typedef struct s_xpparam { unsigned long flags; + /* -I */ + xdl_regex_t **ignore_regex; + size_t ignore_regex_nr; + /* See Documentation/diff-options.txt. */ char **anchors; size_t anchors_nr; @@ -94,7 +94,11 @@ typedef struct s_xpparam { typedef struct s_xdemitcb { void *priv; - int (*outf)(void *, mmbuffer_t *, int); + int (*out_hunk)(void *, + long old_begin, long old_nr, + long new_begin, long new_nr, + const char *func, long funclen); + int (*out_line)(void *, mmbuffer_t *, int); } xdemitcb_t; typedef long (*find_func_t)(const char *line, long line_len, char *buffer, long buffer_size, void *priv); @@ -117,10 +121,6 @@ typedef struct s_bdiffparam { } bdiffparam_t; -#define xdl_malloc(x) git__malloc(x) -#define xdl_free(ptr) git__free(ptr) -#define xdl_realloc(ptr,x) git__realloc(ptr,x) - void *xdl_mmfile_first(mmfile_t *mmf, long *size); long xdl_mmfile_size(mmfile_t *mmf); diff --git a/src/xdiff/xdiffi.c b/src/xdiff/xdiffi.c index 916295b448f..af31b7f4b39 100644 --- a/src/xdiff/xdiffi.c +++ b/src/xdiff/xdiffi.c @@ -21,8 +21,6 @@ */ #include "xinclude.h" -#include "integer.h" - #define XDL_MAX_COST_MIN 256 #define XDL_HEUR_MIN_COST 256 @@ -30,41 +28,19 @@ #define XDL_SNAKE_CNT 20 #define XDL_K_HEUR 4 -/** Declare a function as always inlined. */ -#if defined(_MSC_VER) -# define XDL_INLINE(type) static __inline type -#elif defined(__GNUC__) -# define XDL_INLINE(type) static __inline__ type -#else -# define XDL_INLINE(type) static type -#endif - typedef struct s_xdpsplit { long i1, i2; int min_lo, min_hi; } xdpsplit_t; - - - -static long xdl_split(unsigned long const *ha1, long off1, long lim1, - unsigned long const *ha2, long off2, long lim2, - long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl, - xdalgoenv_t *xenv); -static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2); - - - - - /* * See "An O(ND) Difference Algorithm and its Variations", by Eugene Myers. * Basically considers a "box" (off1, off2, lim1, lim2) and scan from both * the forward diagonal starting from (off1, off2) and the backward diagonal * starting from (lim1, lim2). If the K values on the same diagonal crosses - * returns the furthest point of reach. We might end up having to expensive - * cases using this algorithm is full, so a little bit of heuristic is needed - * to cut the search and to return a suboptimal point. + * returns the furthest point of reach. We might encounter expensive edge cases + * using this algorithm, so a little bit of heuristic is needed to cut the + * search and to return a suboptimal point. */ static long xdl_split(unsigned long const *ha1, long off1, long lim1, unsigned long const *ha2, long off2, long lim2, @@ -87,11 +63,13 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1, int got_snake = 0; /* - * We need to extent the diagonal "domain" by one. If the next + * We need to extend the diagonal "domain" by one. If the next * values exits the box boundaries we need to change it in the - * opposite direction because (max - min) must be a power of two. + * opposite direction because (max - min) must be a power of + * two. + * * Also we initialize the external K value to -1 so that we can - * avoid extra conditions check inside the core loop. + * avoid extra conditions in the check inside the core loop. */ if (fmin > dmin) kvdf[--fmin - 1] = -1; @@ -122,11 +100,13 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1, } /* - * We need to extent the diagonal "domain" by one. If the next + * We need to extend the diagonal "domain" by one. If the next * values exits the box boundaries we need to change it in the - * opposite direction because (max - min) must be a power of two. + * opposite direction because (max - min) must be a power of + * two. + * * Also we initialize the external K value to -1 so that we can - * avoid extra conditions check inside the core loop. + * avoid extra conditions in the check inside the core loop. */ if (bmin > dmin) kvdb[--bmin - 1] = XDL_LINE_MAX; @@ -162,7 +142,7 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1, /* * If the edit cost is above the heuristic trigger and if * we got a good snake, we sample current diagonals to see - * if some of the, have reached an "interesting" path. Our + * if some of them have reached an "interesting" path. Our * measure is a function of the distance from the diagonal * corner (i1 + i2) penalized with the distance from the * mid diagonal itself. If this value is above the current @@ -220,8 +200,9 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1, } /* - * Enough is enough. We spent too much time here and now we collect - * the furthest reaching path using the (i1 + i2) measure. + * Enough is enough. We spent too much time here and now we + * collect the furthest reaching path using the (i1 + i2) + * measure. */ if (ec >= xenv->mxcost) { long fbest, fbest1, bbest, bbest1; @@ -268,9 +249,9 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1, /* - * Rule: "Divide et Impera". Recursively split the box in sub-boxes by calling - * the box splitting function. Note that the real job (marking changed lines) - * is done in the two boundary reaching checks. + * Rule: "Divide et Impera" (divide & conquer). Recursively split the box in + * sub-boxes by calling the box splitting function. Note that the real job + * (marking changed lines) is done in the two boundary reaching checks. */ int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1, diffdata_t *dd2, long off2, long lim2, @@ -330,7 +311,7 @@ int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1, int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdfenv_t *xe) { - size_t ndiags, allocsize; + long ndiags; long *kvd, *kvdf, *kvdb; xdalgoenv_t xenv; diffdata_t dd1, dd2; @@ -347,15 +328,14 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, } /* - * Allocate and setup K vectors to be used by the differential algorithm. + * Allocate and setup K vectors to be used by the differential + * algorithm. + * * One is to store the forward path and one to store the backward path. */ - GIT_ERROR_CHECK_ALLOC_ADD3(&ndiags, xe->xdf1.nreff, xe->xdf2.nreff, 3); - GIT_ERROR_CHECK_ALLOC_MULTIPLY(&allocsize, ndiags, 2); - GIT_ERROR_CHECK_ALLOC_ADD(&allocsize, allocsize, 2); - GIT_ERROR_CHECK_ALLOC_MULTIPLY(&allocsize, allocsize, sizeof(long)); + ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3; + if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) { - if (!(kvd = (long *) xdl_malloc(allocsize))) { xdl_free_env(xe); return -1; } @@ -410,19 +390,16 @@ static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, } -static int recs_match(xrecord_t *rec1, xrecord_t *rec2, long flags) +static int recs_match(xrecord_t *rec1, xrecord_t *rec2) { - return (rec1->ha == rec2->ha && - xdl_recmatch(rec1->ptr, rec1->size, - rec2->ptr, rec2->size, - flags)); + return (rec1->ha == rec2->ha); } /* * If a line is indented more than this, get_indent() just returns this value. * This avoids having to do absurd amounts of work for data that are not - * human-readable text, and also ensures that the output of get_indent fits within - * an int. + * human-readable text, and also ensures that the output of get_indent fits + * within an int. */ #define MAX_INDENT 200 @@ -456,9 +433,9 @@ static int get_indent(xrecord_t *rec) } /* - * If more than this number of consecutive blank rows are found, just return this - * value. This avoids requiring O(N^2) work for pathological cases, and also - * ensures that the output of score_split fits in an int. + * If more than this number of consecutive blank rows are found, just return + * this value. This avoids requiring O(N^2) work for pathological cases, and + * also ensures that the output of score_split fits in an int. */ #define MAX_BLANKS 20 @@ -470,8 +447,8 @@ struct split_measurement { int end_of_file; /* - * How much is the line immediately following the split indented (or -1 if - * the line is blank): + * How much is the line immediately following the split indented (or -1 + * if the line is blank): */ int indent; @@ -481,8 +458,8 @@ struct split_measurement { int pre_blank; /* - * How much is the nearest non-blank line above the split indented (or -1 - * if there is no such line)? + * How much is the nearest non-blank line above the split indented (or + * -1 if there is no such line)? */ int pre_indent; @@ -601,15 +578,20 @@ static void measure_split(const xdfile_t *xdf, long split, */ #define INDENT_WEIGHT 60 +/* + * How far do we slide a hunk at most? + */ +#define INDENT_HEURISTIC_MAX_SLIDING 100 + /* * Compute a badness score for the hypothetical split whose measurements are - * stored in m. The weight factors were determined empirically using the tools and - * corpus described in + * stored in m. The weight factors were determined empirically using the tools + * and corpus described in * * https://github.com/mhagger/diff-slider-tools * - * Also see that project if you want to improve the weights based on, for example, - * a larger or more diverse corpus. + * Also see that project if you want to improve the weights based on, for + * example, a larger or more diverse corpus. */ static void score_add_split(const struct split_measurement *m, struct split_score *s) { @@ -741,7 +723,7 @@ static void group_init(xdfile_t *xdf, struct xdlgroup *g) * Move g to describe the next (possibly empty) group in xdf and return 0. If g * is already at the end of the file, do nothing and return -1. */ -XDL_INLINE(int) group_next(xdfile_t *xdf, struct xdlgroup *g) +static inline int group_next(xdfile_t *xdf, struct xdlgroup *g) { if (g->end == xdf->nrec) return -1; @@ -757,7 +739,7 @@ XDL_INLINE(int) group_next(xdfile_t *xdf, struct xdlgroup *g) * Move g to describe the previous (possibly empty) group in xdf and return 0. * If g is already at the beginning of the file, do nothing and return -1. */ -XDL_INLINE(int) group_previous(xdfile_t *xdf, struct xdlgroup *g) +static inline int group_previous(xdfile_t *xdf, struct xdlgroup *g) { if (g->start == 0) return -1; @@ -774,10 +756,10 @@ XDL_INLINE(int) group_previous(xdfile_t *xdf, struct xdlgroup *g) * following group, expand this group to include it. Return 0 on success or -1 * if g cannot be slid down. */ -static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g, long flags) +static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g) { if (g->end < xdf->nrec && - recs_match(xdf->recs[g->start], xdf->recs[g->end], flags)) { + recs_match(xdf->recs[g->start], xdf->recs[g->end])) { xdf->rchg[g->start++] = 0; xdf->rchg[g->end++] = 1; @@ -795,10 +777,10 @@ static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g, long flags) * into a previous group, expand this group to include it. Return 0 on success * or -1 if g cannot be slid up. */ -static int group_slide_up(xdfile_t *xdf, struct xdlgroup *g, long flags) +static int group_slide_up(xdfile_t *xdf, struct xdlgroup *g) { if (g->start > 0 && - recs_match(xdf->recs[g->start - 1], xdf->recs[g->end - 1], flags)) { + recs_match(xdf->recs[g->start - 1], xdf->recs[g->end - 1])) { xdf->rchg[--g->start] = 1; xdf->rchg[--g->end] = 0; @@ -811,12 +793,6 @@ static int group_slide_up(xdfile_t *xdf, struct xdlgroup *g, long flags) } } -static void xdl_bug(const char *msg) -{ - fprintf(stderr, "BUG: %s\n", msg); - exit(1); -} - /* * Move back and forward change groups for a consistent and pretty diff output. * This also helps in finding joinable change groups and reducing the diff @@ -831,13 +807,16 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { group_init(xdfo, &go); while (1) { - /* If the group is empty in the to-be-compacted file, skip it: */ + /* + * If the group is empty in the to-be-compacted file, skip it: + */ if (g.end == g.start) goto next; /* * Now shift the change up and then down as far as possible in - * each direction. If it bumps into any other changes, merge them. + * each direction. If it bumps into any other changes, merge + * them. */ do { groupsize = g.end - g.start; @@ -851,9 +830,9 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { end_matching_other = -1; /* Shift the group backward as much as possible: */ - while (!group_slide_up(xdf, &g, flags)) + while (!group_slide_up(xdf, &g)) if (group_previous(xdfo, &go)) - xdl_bug("group sync broken sliding up"); + XDL_BUG("group sync broken sliding up"); /* * This is this highest that this group can be shifted. @@ -866,10 +845,10 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { /* Now shift the group forward as far as possible: */ while (1) { - if (group_slide_down(xdf, &g, flags)) + if (group_slide_down(xdf, &g)) break; if (group_next(xdfo, &go)) - xdl_bug("group sync broken sliding down"); + XDL_BUG("group sync broken sliding down"); if (go.end > go.start) end_matching_other = g.end; @@ -880,40 +859,46 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { * If the group can be shifted, then we can possibly use this * freedom to produce a more intuitive diff. * - * The group is currently shifted as far down as possible, so the - * heuristics below only have to handle upwards shifts. + * The group is currently shifted as far down as possible, so + * the heuristics below only have to handle upwards shifts. */ if (g.end == earliest_end) { /* no shifting was possible */ } else if (end_matching_other != -1) { /* - * Move the possibly merged group of changes back to line - * up with the last group of changes from the other file - * that it can align with. + * Move the possibly merged group of changes back to + * line up with the last group of changes from the + * other file that it can align with. */ while (go.end == go.start) { - if (group_slide_up(xdf, &g, flags)) - xdl_bug("match disappeared"); + if (group_slide_up(xdf, &g)) + XDL_BUG("match disappeared"); if (group_previous(xdfo, &go)) - xdl_bug("group sync broken sliding to match"); + XDL_BUG("group sync broken sliding to match"); } } else if (flags & XDF_INDENT_HEURISTIC) { /* * Indent heuristic: a group of pure add/delete lines - * implies two splits, one between the end of the "before" - * context and the start of the group, and another between - * the end of the group and the beginning of the "after" - * context. Some splits are aesthetically better and some - * are worse. We compute a badness "score" for each split, - * and add the scores for the two splits to define a - * "score" for each position that the group can be shifted - * to. Then we pick the shift with the lowest score. + * implies two splits, one between the end of the + * "before" context and the start of the group, and + * another between the end of the group and the + * beginning of the "after" context. Some splits are + * aesthetically better and some are worse. We compute + * a badness "score" for each split, and add the scores + * for the two splits to define a "score" for each + * position that the group can be shifted to. Then we + * pick the shift with the lowest score. */ long shift, best_shift = -1; struct split_score best_score; - for (shift = earliest_end; shift <= g.end; shift++) { + shift = earliest_end; + if (g.end - groupsize - 1 > shift) + shift = g.end - groupsize - 1; + if (g.end - INDENT_HEURISTIC_MAX_SLIDING > shift) + shift = g.end - INDENT_HEURISTIC_MAX_SLIDING; + for (; shift <= g.end; shift++) { struct split_measurement m; struct split_score score = {0, 0}; @@ -930,10 +915,10 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { } while (g.end > best_shift) { - if (group_slide_up(xdf, &g, flags)) - xdl_bug("best shift unreached"); + if (group_slide_up(xdf, &g)) + XDL_BUG("best shift unreached"); if (group_previous(xdfo, &go)) - xdl_bug("group sync broken sliding to blank line"); + XDL_BUG("group sync broken sliding to blank line"); } } @@ -942,11 +927,11 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { if (group_next(xdf, &g)) break; if (group_next(xdfo, &go)) - xdl_bug("group sync broken moving to next group"); + XDL_BUG("group sync broken moving to next group"); } if (!group_next(xdfo, &go)) - xdl_bug("group sync broken at end of file"); + XDL_BUG("group sync broken at end of file"); return 0; } @@ -992,8 +977,6 @@ static int xdl_call_hunk_func(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, { xdchange_t *xch, *xche; - (void)xe; - for (xch = xscr; xch; xch = xche->next) { xche = xdl_get_hunk(&xch, xecfg); if (!xch) @@ -1006,7 +989,7 @@ static int xdl_call_hunk_func(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, return 0; } -static void xdl_mark_ignorable(xdchange_t *xscr, xdfenv_t *xe, long flags) +static void xdl_mark_ignorable_lines(xdchange_t *xscr, xdfenv_t *xe, long flags) { xdchange_t *xch; @@ -1027,6 +1010,46 @@ static void xdl_mark_ignorable(xdchange_t *xscr, xdfenv_t *xe, long flags) } } +static int record_matches_regex(xrecord_t *rec, xpparam_t const *xpp) { + xdl_regmatch_t regmatch; + int i; + + for (i = 0; i < xpp->ignore_regex_nr; i++) + if (!xdl_regexec_buf(xpp->ignore_regex[i], rec->ptr, rec->size, 1, + ®match, 0)) + return 1; + + return 0; +} + +static void xdl_mark_ignorable_regex(xdchange_t *xscr, const xdfenv_t *xe, + xpparam_t const *xpp) +{ + xdchange_t *xch; + + for (xch = xscr; xch; xch = xch->next) { + xrecord_t **rec; + int ignore = 1; + long i; + + /* + * Do not override --ignore-blank-lines. + */ + if (xch->ignore) + continue; + + rec = &xe->xdf1.recs[xch->i1]; + for (i = 0; i < xch->chg1 && ignore; i++) + ignore = record_matches_regex(rec[i], xpp); + + rec = &xe->xdf2.recs[xch->i2]; + for (i = 0; i < xch->chg2 && ignore; i++) + ignore = record_matches_regex(rec[i], xpp); + + xch->ignore = ignore; + } +} + int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb) { xdchange_t *xscr; @@ -1046,7 +1069,10 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, } if (xscr) { if (xpp->flags & XDF_IGNORE_BLANK_LINES) - xdl_mark_ignorable(xscr, &xe, xpp->flags); + xdl_mark_ignorable_lines(xscr, &xe, xpp->flags); + + if (xpp->ignore_regex) + xdl_mark_ignorable_regex(xscr, &xe, xpp); if (ef(&xe, xscr, ecb, xecfg) < 0) { diff --git a/src/xdiff/xemit.c b/src/xdiff/xemit.c index 0ffa6553aa9..1cbf2b9829e 100644 --- a/src/xdiff/xemit.c +++ b/src/xdiff/xemit.c @@ -31,7 +31,7 @@ static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec) { static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb) { - long size, psize = (long)strlen(pre); + long size, psize = strlen(pre); char const *rec; size = xdl_get_rec(xdf, ri, &rec); @@ -81,7 +81,7 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg) } else if (distance < max_ignorable && xch->ignore) { ignored += xch->chg2; } else if (lxch != xchp && - xch->i1 + ignored - (lxch->i1 + lxch->chg1) > (unsigned long)max_common) { + xch->i1 + ignored - (lxch->i1 + lxch->chg1) > max_common) { break; } else if (!xch->ignore) { lxch = xch; @@ -97,8 +97,6 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg) static long def_ff(const char *rec, long len, char *buf, long sz, void *priv) { - (void)priv; - if (len > 0 && (isalpha((unsigned char)*rec) || /* identifier? */ *rec == '_' || /* also identifier? */ @@ -174,10 +172,12 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, struct func_line func_line = { 0 }; for (xch = xscr; xch; xch = xche->next) { + xdchange_t *xchp = xch; xche = xdl_get_hunk(&xch, xecfg); if (!xch) break; +pre_context_calculation: s1 = XDL_MAX(xch->i1 - xecfg->ctxlen, 0); s2 = XDL_MAX(xch->i2 - xecfg->ctxlen, 0); @@ -212,8 +212,23 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, if (fs1 < 0) fs1 = 0; if (fs1 < s1) { - s2 -= s1 - fs1; + s2 = XDL_MAX(s2 - (s1 - fs1), 0); s1 = fs1; + + /* + * Did we extend context upwards into an + * ignored change? + */ + while (xchp != xch && + xchp->i1 + xchp->chg1 <= s1 && + xchp->i2 + xchp->chg2 <= s2) + xchp = xchp->next; + + /* If so, show it after all. */ + if (xchp != xch) { + xch = xchp; + goto pre_context_calculation; + } } } @@ -234,7 +249,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, if (fe1 < 0) fe1 = xe->xdf1.nrec; if (fe1 > e1) { - e2 += fe1 - e1; + e2 = XDL_MIN(e2 + (fe1 - e1), xe->xdf2.nrec); e1 = fe1; } @@ -263,7 +278,8 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, s1 - 1, funclineprev); funclineprev = s1 - 1; } - if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2, + if (!(xecfg->flags & XDL_EMIT_NO_HUNK_HDR) && + xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2, func_line.buf, func_line.len, ecb) < 0) return -1; diff --git a/src/xdiff/xhistogram.c b/src/xdiff/xhistogram.c index 00bbfcec4f0..80794748b0d 100644 --- a/src/xdiff/xhistogram.c +++ b/src/xdiff/xhistogram.c @@ -42,8 +42,6 @@ */ #include "xinclude.h" -#include "xtypes.h" -#include "xdiff.h" #define MAX_PTR UINT_MAX #define MAX_CNT UINT_MAX @@ -90,27 +88,21 @@ struct region { #define REC(env, s, l) \ (env->xdf##s.recs[l - 1]) -static int cmp_recs(xpparam_t const *xpp, - xrecord_t *r1, xrecord_t *r2) +static int cmp_recs(xrecord_t *r1, xrecord_t *r2) { - return r1->ha == r2->ha && - xdl_recmatch(r1->ptr, r1->size, r2->ptr, r2->size, - xpp->flags); -} + return r1->ha == r2->ha; -#define CMP_ENV(xpp, env, s1, l1, s2, l2) \ - (cmp_recs(xpp, REC(env, s1, l1), REC(env, s2, l2))) +} #define CMP(i, s1, l1, s2, l2) \ - (cmp_recs(i->xpp, REC(i->env, s1, l1), REC(i->env, s2, l2))) + (cmp_recs(REC(i->env, s1, l1), REC(i->env, s2, l2))) #define TABLE_HASH(index, side, line) \ XDL_HASHLONG((REC(index->env, side, line))->ha, index->table_bits) -static int scanA(struct histindex *index, unsigned int line1, unsigned int count1) +static int scanA(struct histindex *index, int line1, int count1) { - unsigned int ptr; - unsigned int tbl_idx; + unsigned int ptr, tbl_idx; unsigned int chain_len; struct record **rec_chain, *rec; @@ -161,10 +153,8 @@ static int scanA(struct histindex *index, unsigned int line1, unsigned int count return 0; } -static int try_lcs( - struct histindex *index, struct region *lcs, unsigned int b_ptr, - unsigned int line1, unsigned int count1, - unsigned int line2, unsigned int count2) +static int try_lcs(struct histindex *index, struct region *lcs, int b_ptr, + int line1, int count1, int line2, int count2) { unsigned int b_next = b_ptr + 1; struct record *rec = index->records[TABLE_HASH(index, 2, b_ptr)]; @@ -236,59 +226,33 @@ static int try_lcs( return b_next; } -static int find_lcs( - struct histindex *index, struct region *lcs, - unsigned int line1, unsigned int count1, - unsigned int line2, unsigned int count2) +static int fall_back_to_classic_diff(xpparam_t const *xpp, xdfenv_t *env, + int line1, int count1, int line2, int count2) { - unsigned int b_ptr; - - if (scanA(index, line1, count1)) - return -1; - - index->cnt = index->max_chain_length + 1; + xpparam_t xpparam; - for (b_ptr = line2; b_ptr <= LINE_END(2); ) - b_ptr = try_lcs(index, lcs, b_ptr, line1, count1, line2, count2); + memset(&xpparam, 0, sizeof(xpparam)); + xpparam.flags = xpp->flags & ~XDF_DIFF_ALGORITHM_MASK; - return index->has_common && index->max_chain_length < index->cnt; + return xdl_fall_back_diff(env, &xpparam, + line1, count1, line2, count2); } -static int fall_back_to_classic_diff(struct histindex *index, - int line1, int count1, int line2, int count2) +static inline void free_index(struct histindex *index) { - xpparam_t xpp; - xpp.flags = index->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK; - - return xdl_fall_back_diff(index->env, &xpp, - line1, count1, line2, count2); + xdl_free(index->records); + xdl_free(index->line_map); + xdl_free(index->next_ptrs); + xdl_cha_free(&index->rcha); } -static int histogram_diff( - xpparam_t const *xpp, xdfenv_t *env, - unsigned int line1, unsigned int count1, - unsigned int line2, unsigned int count2) +static int find_lcs(xpparam_t const *xpp, xdfenv_t *env, + struct region *lcs, + int line1, int count1, int line2, int count2) { + int b_ptr; + int sz, ret = -1; struct histindex index; - struct region lcs; - size_t sz; - int result = -1; - - if (count1 <= 0 && count2 <= 0) - return 0; - - if (LINE_END(1) >= MAX_PTR) - return -1; - - if (!count1) { - while(count2--) - env->xdf2.rchg[line2++ - 1] = 1; - return 0; - } else if (!count2) { - while(count1--) - env->xdf1.rchg[line1++ - 1] = 1; - return 0; - } memset(&index, 0, sizeof(index)); @@ -302,8 +266,7 @@ static int histogram_diff( index.table_bits = xdl_hashbits(count1); sz = index.records_size = 1 << index.table_bits; - GIT_ERROR_CHECK_ALLOC_MULTIPLY(&sz, sz, sizeof(struct record *)); - + sz *= sizeof(struct record *); if (!(index.records = (struct record **) xdl_malloc(sz))) goto cleanup; memset(index.records, 0, sz); @@ -327,9 +290,55 @@ static int histogram_diff( index.ptr_shift = line1; index.max_chain_length = 64; + if (scanA(&index, line1, count1)) + goto cleanup; + + index.cnt = index.max_chain_length + 1; + + for (b_ptr = line2; b_ptr <= LINE_END(2); ) + b_ptr = try_lcs(&index, lcs, b_ptr, line1, count1, line2, count2); + + if (index.has_common && index.max_chain_length < index.cnt) + ret = 1; + else + ret = 0; + +cleanup: + free_index(&index); + return ret; +} + +static int histogram_diff(xpparam_t const *xpp, xdfenv_t *env, + int line1, int count1, int line2, int count2) +{ + struct region lcs; + int lcs_found; + int result; +redo: + result = -1; + + if (count1 <= 0 && count2 <= 0) + return 0; + + if (LINE_END(1) >= MAX_PTR) + return -1; + + if (!count1) { + while(count2--) + env->xdf2.rchg[line2++ - 1] = 1; + return 0; + } else if (!count2) { + while(count1--) + env->xdf1.rchg[line1++ - 1] = 1; + return 0; + } + memset(&lcs, 0, sizeof(lcs)); - if (find_lcs(&index, &lcs, line1, count1, line2, count2)) - result = fall_back_to_classic_diff(&index, line1, count1, line2, count2); + lcs_found = find_lcs(xpp, env, &lcs, line1, count1, line2, count2); + if (lcs_found < 0) + goto out; + else if (lcs_found) + result = fall_back_to_classic_diff(xpp, env, line1, count1, line2, count2); else { if (lcs.begin1 == 0 && lcs.begin2 == 0) { while (count1--) @@ -342,21 +351,21 @@ static int histogram_diff( line1, lcs.begin1 - line1, line2, lcs.begin2 - line2); if (result) - goto cleanup; - result = histogram_diff(xpp, env, - lcs.end1 + 1, LINE_END(1) - lcs.end1, - lcs.end2 + 1, LINE_END(2) - lcs.end2); - if (result) - goto cleanup; + goto out; + /* + * result = histogram_diff(xpp, env, + * lcs.end1 + 1, LINE_END(1) - lcs.end1, + * lcs.end2 + 1, LINE_END(2) - lcs.end2); + * but let's optimize tail recursion ourself: + */ + count1 = LINE_END(1) - lcs.end1; + line1 = lcs.end1 + 1; + count2 = LINE_END(2) - lcs.end2; + line2 = lcs.end2 + 1; + goto redo; } } - -cleanup: - xdl_free(index.records); - xdl_free(index.line_map); - xdl_free(index.next_ptrs); - xdl_cha_free(&index.rcha); - +out: return result; } diff --git a/src/xdiff/xinclude.h b/src/xdiff/xinclude.h index 068ce42f8e7..75db1d8f357 100644 --- a/src/xdiff/xinclude.h +++ b/src/xdiff/xinclude.h @@ -23,17 +23,7 @@ #if !defined(XINCLUDE_H) #define XINCLUDE_H -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#else -#include -#endif - +#include "git-xdiff.h" #include "xmacros.h" #include "xdiff.h" #include "xtypes.h" @@ -42,6 +32,5 @@ #include "xdiffi.h" #include "xemit.h" -#include "common.h" #endif /* #if !defined(XINCLUDE_H) */ diff --git a/src/xdiff/xmerge.c b/src/xdiff/xmerge.c index 278cbe12429..fff0b594f9a 100644 --- a/src/xdiff/xmerge.c +++ b/src/xdiff/xmerge.c @@ -109,53 +109,44 @@ static int xdl_merge_cmp_lines(xdfenv_t *xe1, int i1, xdfenv_t *xe2, int i2, return 0; } -static int xdl_recs_copy_0(size_t *out, int use_orig, xdfenv_t *xe, int i, int count, int needs_cr, int add_nl, char *dest) +static int xdl_recs_copy_0(int use_orig, xdfenv_t *xe, int i, int count, int needs_cr, int add_nl, char *dest) { xrecord_t **recs; - size_t size = 0; - - *out = 0; + int size = 0; recs = (use_orig ? xe->xdf1.recs : xe->xdf2.recs) + i; if (count < 1) return 0; - for (i = 0; i < count; ) { + for (i = 0; i < count; size += recs[i++]->size) if (dest) memcpy(dest + size, recs[i]->ptr, recs[i]->size); - - GIT_ERROR_CHECK_ALLOC_ADD(&size, size, recs[i++]->size); - } - if (add_nl) { i = recs[count - 1]->size; if (i == 0 || recs[count - 1]->ptr[i - 1] != '\n') { if (needs_cr) { if (dest) dest[size] = '\r'; - GIT_ERROR_CHECK_ALLOC_ADD(&size, size, 1); + size++; } if (dest) dest[size] = '\n'; - - GIT_ERROR_CHECK_ALLOC_ADD(&size, size, 1); + size++; } } - - *out = size; - return 0; + return size; } -static int xdl_recs_copy(size_t *out, xdfenv_t *xe, int i, int count, int needs_cr, int add_nl, char *dest) +static int xdl_recs_copy(xdfenv_t *xe, int i, int count, int needs_cr, int add_nl, char *dest) { - return xdl_recs_copy_0(out, 0, xe, i, count, needs_cr, add_nl, dest); + return xdl_recs_copy_0(0, xe, i, count, needs_cr, add_nl, dest); } -static int xdl_orig_copy(size_t *out, xdfenv_t *xe, int i, int count, int needs_cr, int add_nl, char *dest) +static int xdl_orig_copy(xdfenv_t *xe, int i, int count, int needs_cr, int add_nl, char *dest) { - return xdl_recs_copy_0(out, 1, xe, i, count, needs_cr, add_nl, dest); + return xdl_recs_copy_0(1, xe, i, count, needs_cr, add_nl, dest); } /* @@ -202,32 +193,26 @@ static int is_cr_needed(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m) return needs_cr < 0 ? 0 : needs_cr; } -static int fill_conflict_hunk(size_t *out, xdfenv_t *xe1, const char *name1, +static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1, xdfenv_t *xe2, const char *name2, const char *name3, - size_t size, int i, int style, + int size, int i, int style, xdmerge_t *m, char *dest, int marker_size) { - int marker1_size = (name1 ? (int)strlen(name1) + 1 : 0); - int marker2_size = (name2 ? (int)strlen(name2) + 1 : 0); - int marker3_size = (name3 ? (int)strlen(name3) + 1 : 0); + int marker1_size = (name1 ? strlen(name1) + 1 : 0); + int marker2_size = (name2 ? strlen(name2) + 1 : 0); + int marker3_size = (name3 ? strlen(name3) + 1 : 0); int needs_cr = is_cr_needed(xe1, xe2, m); - size_t copied; - - *out = 0; if (marker_size <= 0) marker_size = DEFAULT_CONFLICT_MARKER_SIZE; /* Before conflicting part */ - if (xdl_recs_copy(&copied, xe1, i, m->i1 - i, 0, 0, - dest ? dest + size : NULL) < 0) - return -1; - - GIT_ERROR_CHECK_ALLOC_ADD(&size, size, copied); + size += xdl_recs_copy(xe1, i, m->i1 - i, 0, 0, + dest ? dest + size : NULL); if (!dest) { - GIT_ERROR_CHECK_ALLOC_ADD5(&size, size, marker_size, 1, needs_cr, marker1_size); + size += marker_size + 1 + needs_cr + marker1_size; } else { memset(dest + size, '<', marker_size); size += marker_size; @@ -242,16 +227,13 @@ static int fill_conflict_hunk(size_t *out, xdfenv_t *xe1, const char *name1, } /* Postimage from side #1 */ - if (xdl_recs_copy(&copied, xe1, m->i1, m->chg1, needs_cr, 1, - dest ? dest + size : NULL) < 0) - return -1; + size += xdl_recs_copy(xe1, m->i1, m->chg1, needs_cr, 1, + dest ? dest + size : NULL); - GIT_ERROR_CHECK_ALLOC_ADD(&size, size, copied); - - if (style == XDL_MERGE_DIFF3) { + if (style == XDL_MERGE_DIFF3 || style == XDL_MERGE_ZEALOUS_DIFF3) { /* Shared preimage */ if (!dest) { - GIT_ERROR_CHECK_ALLOC_ADD5(&size, size, marker_size, 1, needs_cr, marker3_size); + size += marker_size + 1 + needs_cr + marker3_size; } else { memset(dest + size, '|', marker_size); size += marker_size; @@ -264,15 +246,12 @@ static int fill_conflict_hunk(size_t *out, xdfenv_t *xe1, const char *name1, dest[size++] = '\r'; dest[size++] = '\n'; } - - if (xdl_orig_copy(&copied, xe1, m->i0, m->chg0, needs_cr, 1, - dest ? dest + size : NULL) < 0) - return -1; - GIT_ERROR_CHECK_ALLOC_ADD(&size, size, copied); + size += xdl_orig_copy(xe1, m->i0, m->chg0, needs_cr, 1, + dest ? dest + size : NULL); } if (!dest) { - GIT_ERROR_CHECK_ALLOC_ADD4(&size, size, marker_size, 1, needs_cr); + size += marker_size + 1 + needs_cr; } else { memset(dest + size, '=', marker_size); size += marker_size; @@ -282,14 +261,10 @@ static int fill_conflict_hunk(size_t *out, xdfenv_t *xe1, const char *name1, } /* Postimage from side #2 */ - - if (xdl_recs_copy(&copied, xe2, m->i2, m->chg2, needs_cr, 1, - dest ? dest + size : NULL) < 0) - return -1; - GIT_ERROR_CHECK_ALLOC_ADD(&size, size, copied); - + size += xdl_recs_copy(xe2, m->i2, m->chg2, needs_cr, 1, + dest ? dest + size : NULL); if (!dest) { - GIT_ERROR_CHECK_ALLOC_ADD5(&size, size, marker_size, 1, needs_cr, marker2_size); + size += marker_size + 1 + needs_cr + marker2_size; } else { memset(dest + size, '>', marker_size); size += marker_size; @@ -302,71 +277,83 @@ static int fill_conflict_hunk(size_t *out, xdfenv_t *xe1, const char *name1, dest[size++] = '\r'; dest[size++] = '\n'; } - - *out = size; - return 0; + return size; } -static int xdl_fill_merge_buffer(size_t *out, - xdfenv_t *xe1, const char *name1, +static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1, xdfenv_t *xe2, const char *name2, const char *ancestor_name, int favor, xdmerge_t *m, char *dest, int style, int marker_size) { - size_t size, copied; - int i; - - *out = 0; + int size, i; for (size = i = 0; m; m = m->next) { if (favor && !m->mode) m->mode = favor; - if (m->mode == 0) { - if (fill_conflict_hunk(&size, xe1, name1, xe2, name2, + if (m->mode == 0) + size = fill_conflict_hunk(xe1, name1, xe2, name2, ancestor_name, size, i, style, m, dest, - marker_size) < 0) - return -1; - } + marker_size); else if (m->mode & 3) { /* Before conflicting part */ - if (xdl_recs_copy(&copied, xe1, i, m->i1 - i, 0, 0, - dest ? dest + size : NULL) < 0) - return -1; - GIT_ERROR_CHECK_ALLOC_ADD(&size, size, copied); - + size += xdl_recs_copy(xe1, i, m->i1 - i, 0, 0, + dest ? dest + size : NULL); /* Postimage from side #1 */ if (m->mode & 1) { int needs_cr = is_cr_needed(xe1, xe2, m); - if (xdl_recs_copy(&copied, xe1, m->i1, m->chg1, needs_cr, (m->mode & 2), - dest ? dest + size : NULL) < 0) - return -1; - GIT_ERROR_CHECK_ALLOC_ADD(&size, size, copied); + size += xdl_recs_copy(xe1, m->i1, m->chg1, needs_cr, (m->mode & 2), + dest ? dest + size : NULL); } - /* Postimage from side #2 */ - if (m->mode & 2) { - if (xdl_recs_copy(&copied, xe2, m->i2, m->chg2, 0, 0, - dest ? dest + size : NULL) < 0) - return -1; - GIT_ERROR_CHECK_ALLOC_ADD(&size, size, copied); - } + if (m->mode & 2) + size += xdl_recs_copy(xe2, m->i2, m->chg2, 0, 0, + dest ? dest + size : NULL); } else continue; i = m->i1 + m->chg1; } + size += xdl_recs_copy(xe1, i, xe1->xdf2.nrec - i, 0, 0, + dest ? dest + size : NULL); + return size; +} - if (xdl_recs_copy(&copied, xe1, i, xe1->xdf2.nrec - i, 0, 0, - dest ? dest + size : NULL) < 0) - return -1; - GIT_ERROR_CHECK_ALLOC_ADD(&size, size, copied); +static int recmatch(xrecord_t *rec1, xrecord_t *rec2, unsigned long flags) +{ + return xdl_recmatch(rec1->ptr, rec1->size, + rec2->ptr, rec2->size, flags); +} - *out = size; - return 0; +/* + * Remove any common lines from the beginning and end of the conflicted region. + */ +static void xdl_refine_zdiff3_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m, + xpparam_t const *xpp) +{ + xrecord_t **rec1 = xe1->xdf2.recs, **rec2 = xe2->xdf2.recs; + for (; m; m = m->next) { + /* let's handle just the conflicts */ + if (m->mode) + continue; + + while(m->chg1 && m->chg2 && + recmatch(rec1[m->i1], rec2[m->i2], xpp->flags)) { + m->chg1--; + m->chg2--; + m->i1++; + m->i2++; + } + while (m->chg1 && m->chg2 && + recmatch(rec1[m->i1 + m->chg1 - 1], + rec2[m->i2 + m->chg2 - 1], xpp->flags)) { + m->chg1--; + m->chg2--; + } + } } /* @@ -529,7 +516,22 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, int style = xmp->style; int favor = xmp->favor; - if (style == XDL_MERGE_DIFF3) { + /* + * XDL_MERGE_DIFF3 does not attempt to refine conflicts by looking + * at common areas of sides 1 & 2, because the base (side 0) does + * not match and is being shown. Similarly, simplification of + * non-conflicts is also skipped due to the skipping of conflict + * refinement. + * + * XDL_MERGE_ZEALOUS_DIFF3, on the other hand, will attempt to + * refine conflicts looking for common areas of sides 1 & 2. + * However, since the base is being shown and does not match, + * it will only look for common areas at the beginning or end + * of the conflict block. Since XDL_MERGE_ZEALOUS_DIFF3's + * conflict refinement is much more limited in this fashion, the + * conflict simplification will be skipped. + */ + if (style == XDL_MERGE_DIFF3 || style == XDL_MERGE_ZEALOUS_DIFF3) { /* * "diff3 -m" output does not make sense for anything * more aggressive than XDL_MERGE_EAGER. @@ -650,34 +652,31 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, if (!changes) changes = c; /* refine conflicts */ - if (XDL_MERGE_ZEALOUS <= level && - (xdl_refine_conflicts(xe1, xe2, changes, xpp) < 0 || - xdl_simplify_non_conflicts(xe1, changes, - XDL_MERGE_ZEALOUS < level) < 0)) { + if (style == XDL_MERGE_ZEALOUS_DIFF3) { + xdl_refine_zdiff3_conflicts(xe1, xe2, changes, xpp); + } else if (XDL_MERGE_ZEALOUS <= level && + (xdl_refine_conflicts(xe1, xe2, changes, xpp) < 0 || + xdl_simplify_non_conflicts(xe1, changes, + XDL_MERGE_ZEALOUS < level) < 0)) { xdl_cleanup_merge(changes); return -1; } /* output */ if (result) { int marker_size = xmp->marker_size; - size_t size; - - if (xdl_fill_merge_buffer(&size, xe1, name1, xe2, name2, + int size = xdl_fill_merge_buffer(xe1, name1, xe2, name2, ancestor_name, favor, changes, NULL, style, - marker_size) < 0) - return -1; - + marker_size); result->ptr = xdl_malloc(size); if (!result->ptr) { xdl_cleanup_merge(changes); return -1; } result->size = size; - if (xdl_fill_merge_buffer(&size, xe1, name1, xe2, name2, + xdl_fill_merge_buffer(xe1, name1, xe2, name2, ancestor_name, favor, changes, - result->ptr, style, marker_size) < 0) - return -1; + result->ptr, style, marker_size); } return xdl_cleanup_merge(changes); } @@ -717,22 +716,10 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2, status = 0; if (!xscr1) { result->ptr = xdl_malloc(mf2->size); - if (!result->ptr) { - xdl_free_script(xscr2); - xdl_free_env(&xe1); - xdl_free_env(&xe2); - return -1; - } memcpy(result->ptr, mf2->ptr, mf2->size); result->size = mf2->size; } else if (!xscr2) { result->ptr = xdl_malloc(mf1->size); - if (!result->ptr) { - xdl_free_script(xscr1); - xdl_free_env(&xe1); - xdl_free_env(&xe2); - return -1; - } memcpy(result->ptr, mf1->ptr, mf1->size); result->size = mf1->size; } else { diff --git a/src/xdiff/xpatience.c b/src/xdiff/xpatience.c index 53b7d5fd17f..c5d48e80aef 100644 --- a/src/xdiff/xpatience.c +++ b/src/xdiff/xpatience.c @@ -20,8 +20,6 @@ * */ #include "xinclude.h" -#include "xtypes.h" -#include "xdiff.h" /* * The basic idea of patience diff is to find lines that are unique in @@ -78,7 +76,7 @@ struct hashmap { static int is_anchor(xpparam_t const *xpp, const char *line) { - unsigned long i; + int i; for (i = 0; i < xpp->anchors_nr; i++) { if (!strncmp(line, xpp->anchors[i], strlen(xpp->anchors[i]))) return 1; @@ -92,7 +90,7 @@ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map, { xrecord_t **records = pass == 1 ? map->env->xdf1.recs : map->env->xdf2.recs; - xrecord_t *record = records[line - 1], *other; + xrecord_t *record = records[line - 1]; /* * After xdl_prepare_env() (or more precisely, due to * xdl_classify_record()), the "ha" member of the records (AKA lines) @@ -106,11 +104,7 @@ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map, int index = (int)((record->ha << 1) % map->alloc); while (map->entries[index].line1) { - other = map->env->xdf1.recs[map->entries[index].line1 - 1]; - if (map->entries[index].hash != record->ha || - !xdl_recmatch(record->ptr, record->size, - other->ptr, other->size, - map->xpp->flags)) { + if (map->entries[index].hash != record->ha) { if (++index >= map->alloc) index = 0; continue; @@ -217,9 +211,6 @@ static struct entry *find_longest_common_sequence(struct hashmap *map) */ int anchor_i = -1; - if (!sequence) - return NULL; - for (entry = map->first; entry; entry = entry->next) { if (!entry->line2 || entry->line2 == NON_UNIQUE) continue; @@ -258,8 +249,7 @@ static int match(struct hashmap *map, int line1, int line2) { xrecord_t *record1 = map->env->xdf1.recs[line1 - 1]; xrecord_t *record2 = map->env->xdf2.recs[line2 - 1]; - return xdl_recmatch(record1->ptr, record1->size, - record2->ptr, record2->size, map->xpp->flags); + return record1->ha == record2->ha; } static int patience_diff(mmfile_t *file1, mmfile_t *file2, @@ -294,9 +284,6 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first, /* Recurse */ if (next1 > line1 || next2 > line2) { - struct hashmap submap; - - memset(&submap, 0, sizeof(submap)); if (patience_diff(map->file1, map->file2, map->xpp, map->env, line1, next1 - line1, @@ -323,6 +310,8 @@ static int fall_back_to_classic_diff(struct hashmap *map, int line1, int count1, int line2, int count2) { xpparam_t xpp; + + memset(&xpp, 0, sizeof(xpp)); xpp.flags = map->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK; return xdl_fall_back_diff(map->env, &xpp, diff --git a/src/xdiff/xprepare.c b/src/xdiff/xprepare.c index abeb8fb84e6..4527a4a07c4 100644 --- a/src/xdiff/xprepare.c +++ b/src/xdiff/xprepare.c @@ -181,15 +181,11 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_ if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *)))) goto abort; - if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF) - hbits = hsize = 0; - else { - hbits = xdl_hashbits((unsigned int) narec); - hsize = 1 << hbits; - if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *)))) - goto abort; - memset(rhash, 0, hsize * sizeof(xrecord_t *)); - } + hbits = xdl_hashbits((unsigned int) narec); + hsize = 1 << hbits; + if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *)))) + goto abort; + memset(rhash, 0, hsize * sizeof(xrecord_t *)); nrec = 0; if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) { @@ -208,9 +204,7 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_ crec->size = (long) (cur - prev); crec->ha = hav; recs[nrec++] = crec; - - if ((XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) && - xdl_classify_record(pass, cf, rhash, hbits, crec) < 0) + if (xdl_classify_record(pass, cf, rhash, hbits, crec) < 0) goto abort; } } @@ -219,10 +213,13 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_ goto abort; memset(rchg, 0, (nrec + 2) * sizeof(char)); - if (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long)))) - goto abort; - if (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long)))) - goto abort; + if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) && + (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)) { + if (!(rindex = xdl_malloc((nrec + 1) * sizeof(*rindex)))) + goto abort; + if (!(ha = xdl_malloc((nrec + 1) * sizeof(*ha)))) + goto abort; + } xdf->nrec = nrec; xdf->recs = recs; @@ -279,8 +276,7 @@ int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, enl1 = xdl_guess_lines(mf1, sample) + 1; enl2 = xdl_guess_lines(mf2, sample) + 1; - if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF && - xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0) + if (xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0) return -1; if (xdl_prepare_ctx(1, mf1, enl1, xpp, &cf, &xe->xdf1) < 0) { @@ -305,8 +301,7 @@ int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, return -1; } - if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) - xdl_free_classifier(&cf); + xdl_free_classifier(&cf); return 0; } diff --git a/src/xdiff/xutils.c b/src/xdiff/xutils.c index 17c9ae184b6..cfa6e2220ff 100644 --- a/src/xdiff/xutils.c +++ b/src/xdiff/xutils.c @@ -23,8 +23,6 @@ #include "xinclude.h" - - long xdl_bogosqrt(long n) { long i; @@ -52,7 +50,7 @@ int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize, mb[2].size = strlen(mb[2].ptr); i++; } - if (ecb->outf(ecb->priv, mb, i) < 0) { + if (ecb->out_line(ecb->priv, mb, i) < 0) { return -1; } @@ -342,8 +340,9 @@ int xdl_num_out(char *out, long val) { return str - out; } -int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, - const char *func, long funclen, xdemitcb_t *ecb) { +static int xdl_format_hunk_hdr(long s1, long c1, long s2, long c2, + const char *func, long funclen, + xdemitcb_t *ecb) { int nb = 0; mmbuffer_t mb; char buf[128]; @@ -376,7 +375,7 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, nb += 3; if (func && funclen) { buf[nb++] = ' '; - if (funclen > (long)(sizeof(buf) - nb - 1)) + if (funclen > sizeof(buf) - nb - 1) funclen = sizeof(buf) - nb - 1; memcpy(buf + nb, func, funclen); nb += funclen; @@ -385,9 +384,21 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, mb.ptr = buf; mb.size = nb; - if (ecb->outf(ecb->priv, &mb, 1) < 0) + if (ecb->out_line(ecb->priv, &mb, 1) < 0) return -1; + return 0; +} +int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, + const char *func, long funclen, + xdemitcb_t *ecb) { + if (!ecb->out_hunk) + return xdl_format_hunk_hdr(s1, c1, s2, c2, func, funclen, ecb); + if (ecb->out_hunk(ecb->priv, + c1 ? s1 : s1 - 1, c1, + c2 ? s2 : s2 - 1, c2, + func, funclen) < 0) + return -1; return 0; } From c629d2a11cbc5863c4a68eaafa8bf6a99b263f26 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 29 Jan 2022 21:02:15 -0500 Subject: [PATCH 0761/1616] merge: support zdiff3 conflict styles --- include/git2/checkout.h | 5 ++- include/git2/merge.h | 5 ++- src/checkout.c | 5 +++ src/merge_file.c | 2 + tests/merge/conflict_data.h | 9 +++++ tests/merge/files.c | 39 ++++++++++++++++++ tests/merge/workdir/simple.c | 78 ++++++++++++++++++++++++++++++++++++ 7 files changed, 141 insertions(+), 2 deletions(-) diff --git a/include/git2/checkout.h b/include/git2/checkout.h index f026d5bc2a4..9f834111a67 100644 --- a/include/git2/checkout.h +++ b/include/git2/checkout.h @@ -182,7 +182,10 @@ typedef enum { * notifications; don't update the working directory or index. */ GIT_CHECKOUT_DRY_RUN = (1u << 24), - + + /** Include common ancestor data in zdiff3 format for conflicts */ + GIT_CHECKOUT_CONFLICT_STYLE_ZDIFF3 = (1u << 25), + /** * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED */ diff --git a/include/git2/merge.h b/include/git2/merge.h index 3b3132f26a8..edd090cffbc 100644 --- a/include/git2/merge.h +++ b/include/git2/merge.h @@ -159,7 +159,10 @@ typedef enum { GIT_MERGE_FILE_DIFF_PATIENCE = (1 << 6), /** Take extra time to find minimal diff */ - GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7) + GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7), + + /** Create zdiff3 ("zealous diff3")-style files */ + GIT_MERGE_FILE_STYLE_ZDIFF3 = (1 << 8) } git_merge_file_flag_t; #define GIT_MERGE_CONFLICT_MARKER_SIZE 7 diff --git a/src/checkout.c b/src/checkout.c index bc3048cc8d6..6a4643196b0 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -2070,6 +2070,9 @@ static int checkout_write_merge( if (data->opts.checkout_strategy & GIT_CHECKOUT_CONFLICT_STYLE_DIFF3) opts.flags |= GIT_MERGE_FILE_STYLE_DIFF3; + if (data->opts.checkout_strategy & GIT_CHECKOUT_CONFLICT_STYLE_ZDIFF3) + opts.flags |= GIT_MERGE_FILE_STYLE_ZDIFF3; + opts.ancestor_label = data->opts.ancestor_label ? data->opts.ancestor_label : "ancestor"; opts.our_label = data->opts.our_label ? @@ -2493,6 +2496,8 @@ static int checkout_data_init( data->opts.checkout_strategy |= GIT_CHECKOUT_CONFLICT_STYLE_MERGE; else if (strcmp(conflict_style->value, "diff3") == 0) data->opts.checkout_strategy |= GIT_CHECKOUT_CONFLICT_STYLE_DIFF3; + else if (strcmp(conflict_style->value, "zdiff3") == 0) + data->opts.checkout_strategy |= GIT_CHECKOUT_CONFLICT_STYLE_ZDIFF3; else { git_error_set(GIT_ERROR_CHECKOUT, "unknown style '%s' given for 'merge.conflictstyle'", conflict_style->value); diff --git a/src/merge_file.c b/src/merge_file.c index 7285884b4af..732a047b1c9 100644 --- a/src/merge_file.c +++ b/src/merge_file.c @@ -123,6 +123,8 @@ static int merge_file__xdiff( if (options.flags & GIT_MERGE_FILE_STYLE_DIFF3) xmparam.style = XDL_MERGE_DIFF3; + if (options.flags & GIT_MERGE_FILE_STYLE_ZDIFF3) + xmparam.style = XDL_MERGE_ZEALOUS_DIFF3; if (options.flags & GIT_MERGE_FILE_IGNORE_WHITESPACE) xmparam.xpp.flags |= XDF_IGNORE_WHITESPACE; diff --git a/tests/merge/conflict_data.h b/tests/merge/conflict_data.h index 27f19c1b01b..0b1e7ee032e 100644 --- a/tests/merge/conflict_data.h +++ b/tests/merge/conflict_data.h @@ -36,6 +36,15 @@ "this file is changed in branch and master\n" \ ">>>>>>> 7cb63eed597130ba4abb87b3e544b85021905520\n" +#define CONFLICTING_ZDIFF3_FILE \ + "<<<<<<< HEAD\n" \ + "this file is changed in master and branch\n" \ + "||||||| initial\n" \ + "this file is a conflict\n" \ + "=======\n" \ + "this file is changed in branch and master\n" \ + ">>>>>>> 7cb63eed597130ba4abb87b3e544b85021905520\n" + #define CONFLICTING_UNION_FILE \ "this file is changed in master and branch\n" \ "this file is changed in branch and master\n" diff --git a/tests/merge/files.c b/tests/merge/files.c index fbc54e11e50..6296f3b7b68 100644 --- a/tests/merge/files.c +++ b/tests/merge/files.c @@ -424,3 +424,42 @@ void test_merge_files__crlf_conflict_markers_for_crlf_files(void) cl_assert(memcmp(expected_diff3, result.ptr, expected_len) == 0); git_merge_file_result_free(&result); } + +void test_merge_files__conflicts_in_zdiff3(void) +{ + git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT, + ours = GIT_MERGE_FILE_INPUT_INIT, + theirs = GIT_MERGE_FILE_INPUT_INIT; + git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT; + git_merge_file_result result = {0}; + + const char *expected_zdiff3 = + "1,\nfoo,\nbar,\n" \ + "<<<<<<< file.txt\n" \ + "||||||| file.txt\n# add more here\n" \ + "=======\nquux,\nwoot,\n" \ + ">>>>>>> file.txt\nbaz,\n3,\n"; + size_t expected_zdiff3_len = strlen(expected_zdiff3); + + ancestor.ptr = "1,\n# add more here\n3,\n"; + ancestor.size = strlen(ancestor.ptr); + ancestor.path = "file.txt"; + ancestor.mode = 0100644; + + ours.ptr = "1,\nfoo,\nbar,\nbaz,\n3,\n"; + ours.size = strlen(ours.ptr); + ours.path = "file.txt"; + ours.mode = 0100644; + + theirs.ptr = "1,\nfoo,\nbar,\nquux,\nwoot,\nbaz,\n3,\n"; + theirs.size = strlen(theirs.ptr); + theirs.path = "file.txt"; + theirs.mode = 0100644; + + opts.flags |= GIT_MERGE_FILE_STYLE_ZDIFF3; + cl_git_pass(git_merge_file(&result, &ancestor, &ours, &theirs, &opts)); + cl_assert_equal_i(0, result.automergeable); + cl_assert_equal_i(expected_zdiff3_len, result.len); + cl_assert(memcmp(expected_zdiff3, result.ptr, expected_zdiff3_len) == 0); + git_merge_file_result_free(&result); +} diff --git a/tests/merge/workdir/simple.c b/tests/merge/workdir/simple.c index f51ff09a7aa..0b672d6a088 100644 --- a/tests/merge/workdir/simple.c +++ b/tests/merge/workdir/simple.c @@ -323,6 +323,42 @@ void test_merge_workdir_simple__diff3(void) cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3)); } +void test_merge_workdir_simple__zdiff3(void) +{ + git_str conflicting_buf = GIT_STR_INIT; + + struct merge_index_entry merge_index_entries[] = { + ADDED_IN_MASTER_INDEX_ENTRY, + AUTOMERGEABLE_INDEX_ENTRY, + CHANGED_IN_BRANCH_INDEX_ENTRY, + CHANGED_IN_MASTER_INDEX_ENTRY, + + { 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" }, + { 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" }, + { 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" }, + + UNCHANGED_INDEX_ENTRY, + }; + + struct merge_reuc_entry merge_reuc_entries[] = { + AUTOMERGEABLE_REUC_ENTRY, + REMOVED_IN_BRANCH_REUC_ENTRY, + REMOVED_IN_MASTER_REUC_ENTRY + }; + + set_core_autocrlf_to(repo, false); + + merge_simple_branch(0, GIT_CHECKOUT_CONFLICT_STYLE_ZDIFF3); + + cl_git_pass(git_futils_readbuffer(&conflicting_buf, + TEST_REPO_PATH "/conflicting.txt")); + cl_assert_equal_s(CONFLICTING_ZDIFF3_FILE, conflicting_buf.ptr); + git_str_dispose(&conflicting_buf); + + cl_assert(merge_test_index(repo_index, merge_index_entries, 8)); + cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3)); +} + void test_merge_workdir_simple__union(void) { git_str conflicting_buf = GIT_STR_INIT; @@ -436,6 +472,48 @@ void test_merge_workdir_simple__diff3_from_config(void) git_config_free(config); } +void test_merge_workdir_simple__zdiff3_from_config(void) +{ + git_config *config; + git_str conflicting_buf = GIT_STR_INIT; + + struct merge_index_entry merge_index_entries[] = { + ADDED_IN_MASTER_INDEX_ENTRY, + AUTOMERGEABLE_INDEX_ENTRY, + CHANGED_IN_BRANCH_INDEX_ENTRY, + CHANGED_IN_MASTER_INDEX_ENTRY, + + { 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" }, + { 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" }, + { 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" }, + + UNCHANGED_INDEX_ENTRY, + }; + + struct merge_reuc_entry merge_reuc_entries[] = { + AUTOMERGEABLE_REUC_ENTRY, + REMOVED_IN_BRANCH_REUC_ENTRY, + REMOVED_IN_MASTER_REUC_ENTRY + }; + + cl_git_pass(git_repository_config(&config, repo)); + cl_git_pass(git_config_set_string(config, "merge.conflictstyle", "zdiff3")); + + set_core_autocrlf_to(repo, false); + + merge_simple_branch(0, 0); + + cl_git_pass(git_futils_readbuffer(&conflicting_buf, + TEST_REPO_PATH "/conflicting.txt")); + cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_ZDIFF3_FILE) == 0); + git_str_dispose(&conflicting_buf); + + cl_assert(merge_test_index(repo_index, merge_index_entries, 8)); + cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3)); + + git_config_free(config); +} + void test_merge_workdir_simple__merge_overrides_config(void) { git_config *config; From 34e01bd26c7639aad5406ccaebd05b9075b02af2 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Thu, 20 Jan 2022 23:07:05 +0100 Subject: [PATCH 0762/1616] cmake: disable some gnu extensions --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 98881b5add6..e1754e5ac02 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,6 @@ add_library(git2internal OBJECT) set_target_properties(git2internal PROPERTIES C_STANDARD 90) +set_target_properties(git2internal PROPERTIES C_EXTENSIONS OFF) if(DEPRECATE_HARD) From 53e8deb9569a3c533abc7f678f977c28baa3a293 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Sun, 23 Jan 2022 22:33:37 +0100 Subject: [PATCH 0763/1616] Remove stray '// TODO' --- src/transports/smart_protocol.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 69edb4a4da4..06102817de1 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -521,7 +521,6 @@ int git_smart__download_pack( int error = 0; struct network_packetsize_payload npp = {0}; - // TODO git_indexer_progress_cb progress_cb = t->connect_opts.callbacks.transfer_progress; void *progress_payload = t->connect_opts.callbacks.payload; From 4517a48bccf68f16958ed86107f6a4a649925586 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 30 Jan 2022 19:21:32 -0500 Subject: [PATCH 0764/1616] futils: document mktmp's safety --- src/futils.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/futils.h b/src/futils.h index 1386dc482b5..782cf3271eb 100644 --- a/src/futils.h +++ b/src/futils.h @@ -173,8 +173,16 @@ typedef enum { extern int git_futils_rmdir_r(const char *path, const char *base, uint32_t flags); /** - * Create and open a temporary file with a `_git2_` suffix. - * Writes the filename into path_out. + * Create and open a temporary file with a `_git2_` suffix in a + * protected directory; the file created will created will honor + * the current `umask`. Writes the filename into path_out. + * + * This function is *NOT* suitable for use in temporary directories + * that are world writable. It uses `mktemp` (for portability) and + * many `mktemp` implementations use weak random characters. It + * should only be assumed to be suitable for atomically writing + * a new file in a directory that you control. + * * @return On success, an open file descriptor, else an error code < 0. */ extern int git_futils_mktmp(git_str *path_out, const char *filename, mode_t mode); From add2dabb3c16aa49b33904dcdc07cd915efc12fa Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 30 Jan 2022 22:25:59 -0500 Subject: [PATCH 0765/1616] revparse: support bare '@' A bare '@' revision syntax represents HEAD. Support it as such. --- src/revparse.c | 3 +++ tests/refs/revparse.c | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/revparse.c b/src/revparse.c index 5d3ff77ed9d..9bc28e9fcc8 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -799,6 +799,9 @@ static int revparse( if (temp_object != NULL) base_rev = temp_object; break; + } else if (spec[pos+1] == '\0') { + spec = "HEAD"; + break; } /* fall through */ diff --git a/tests/refs/revparse.c b/tests/refs/revparse.c index 5fb75850473..0bd2ae5bc2c 100644 --- a/tests/refs/revparse.c +++ b/tests/refs/revparse.c @@ -881,3 +881,10 @@ void test_refs_revparse__uneven_sizes(void) test_object("a65fedf39aefe402d3bb6e24df4d", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); } + +void test_refs_revparse__parses_at_head(void) +{ + test_id("HEAD", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", NULL, GIT_REVSPEC_SINGLE); + test_id("@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", NULL, GIT_REVSPEC_SINGLE); + test_id("@", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", NULL, GIT_REVSPEC_SINGLE); +} From c0297d47c77139efc22dbba169023e3f53315be5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 30 Jan 2022 22:38:08 -0500 Subject: [PATCH 0766/1616] merge: comment conflicts lines in MERGE_MSG git has started adding comment markers to its conflict lines in MERGE_MSG. Match that behavior. --- src/merge.c | 4 ++-- tests/cherrypick/workdir.c | 14 +++++++------- tests/merge/workdir/simple.c | 4 ++-- tests/revert/workdir.c | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/merge.c b/src/merge.c index c871630c6e5..24650bbff32 100644 --- a/src/merge.c +++ b/src/merge.c @@ -3126,7 +3126,7 @@ int git_merge__append_conflicts_to_merge_msg( (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_APPEND, GIT_MERGE_FILE_MODE)) < 0) goto cleanup; - git_filebuf_printf(&file, "\nConflicts:\n"); + git_filebuf_printf(&file, "\n#Conflicts:\n"); for (i = 0; i < git_index_entrycount(index); i++) { const git_index_entry *e = git_index_get_byindex(index, i); @@ -3135,7 +3135,7 @@ int git_merge__append_conflicts_to_merge_msg( continue; if (last == NULL || strcmp(e->path, last) != 0) - git_filebuf_printf(&file, "\t%s\n", e->path); + git_filebuf_printf(&file, "#\t%s\n", e->path); last = e->path; } diff --git a/tests/cherrypick/workdir.c b/tests/cherrypick/workdir.c index 868b9d5ff94..8fd1ecbdfa2 100644 --- a/tests/cherrypick/workdir.c +++ b/tests/cherrypick/workdir.c @@ -170,9 +170,9 @@ void test_cherrypick_workdir__conflicts(void) cl_assert(strcmp(git_str_cstr(&mergemsg_buf), "Change all files\n" \ "\n" \ - "Conflicts:\n" \ - "\tfile2.txt\n" \ - "\tfile3.txt\n") == 0); + "#Conflicts:\n" \ + "#\tfile2.txt\n" \ + "#\tfile3.txt\n") == 0); cl_git_pass(git_futils_readbuffer(&conflicting_buf, TEST_REPO_PATH "/file2.txt")); @@ -352,10 +352,10 @@ void test_cherrypick_workdir__both_renamed(void) cl_assert(strcmp(git_str_cstr(&mergemsg_buf), "Renamed file3.txt -> file3.txt.renamed\n" \ "\n" \ - "Conflicts:\n" \ - "\tfile3.txt\n" \ - "\tfile3.txt.renamed\n" \ - "\tfile3.txt.renamed_on_branch\n") == 0); + "#Conflicts:\n" \ + "#\tfile3.txt\n" \ + "#\tfile3.txt.renamed\n" \ + "#\tfile3.txt.renamed_on_branch\n") == 0); git_str_dispose(&mergemsg_buf); git_commit_free(commit); diff --git a/tests/merge/workdir/simple.c b/tests/merge/workdir/simple.c index f51ff09a7aa..5b4e6a66c88 100644 --- a/tests/merge/workdir/simple.c +++ b/tests/merge/workdir/simple.c @@ -278,8 +278,8 @@ void test_merge_workdir_simple__mergefile(void) cl_assert(strcmp(git_str_cstr(&mergemsg_buf), "Merge commit '7cb63eed597130ba4abb87b3e544b85021905520'\n" \ "\n" \ - "Conflicts:\n" \ - "\tconflicting.txt\n") == 0); + "#Conflicts:\n" \ + "#\tconflicting.txt\n") == 0); git_str_dispose(&conflicting_buf); git_str_dispose(&mergemsg_buf); diff --git a/tests/revert/workdir.c b/tests/revert/workdir.c index 0c98108146a..3f54280caf6 100644 --- a/tests/revert/workdir.c +++ b/tests/revert/workdir.c @@ -119,8 +119,8 @@ void test_revert_workdir__conflicts(void) "\n" \ "This reverts commit 72333f47d4e83616630ff3b0ffe4c0faebcc3c45.\n" "\n" \ - "Conflicts:\n" \ - "\tfile1.txt\n") == 0); + "#Conflicts:\n" \ + "#\tfile1.txt\n") == 0); git_commit_free(commit); git_commit_free(head); From 6d668ffdc10dcedc7fa7b817fcdb7d5468112d33 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 31 Jan 2022 08:35:58 -0500 Subject: [PATCH 0767/1616] ci: improve the name in CI runs --- .github/workflows/main.yml | 34 +++++++++++------------ .github/workflows/nightly.yml | 52 +++++++++++++++++------------------ 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6e342d1169d..74bab53f308 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,8 +22,7 @@ jobs: # with both the sha and "latest" so that the subsequent runs need not # know the sha. Only do this on CI builds (when the event is a "push") # because PR builds from forks lack permission to write packages. - build_containers: - name: Create docker image + containers: strategy: matrix: container: @@ -46,6 +45,7 @@ jobs: - name: centos7 - name: centos8 runs-on: ubuntu-latest + name: "Create container: ${{ matrix.container.name }}" steps: - name: Check out repository uses: actions/checkout@v2 @@ -80,12 +80,11 @@ jobs: # and their details. Then we build either in a docker container (Linux) # or on the actual hosts (macOS, Windows). build: - name: Build - needs: [ build_containers ] + needs: [ containers ] strategy: matrix: platform: - - # Xenial, GCC, OpenSSL + - name: "Linux (Xenial, GCC, OpenSSL)" container: name: xenial env: @@ -93,7 +92,7 @@ jobs: CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON -DDEBUG_STRICT_ALLOC=ON -DDEBUG_STRICT_OPEN=ON os: ubuntu-latest - - # Xenial, GCC, mbedTLS + - name: Linux (Xenial, GCC, mbedTLS) container: name: xenial env: @@ -101,7 +100,7 @@ jobs: CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON os: ubuntu-latest - - # Xenial, Clang, OpenSSL + - name: "Linux (Xenial, Clang, OpenSSL)" container: name: xenial env: @@ -109,7 +108,7 @@ jobs: CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON os: ubuntu-latest - - # Xenial, Clang, mbedTLS + - name: "Linux (Xenial, Clang, mbedTLS)" container: name: xenial env: @@ -117,7 +116,7 @@ jobs: CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest - - # Focal, Clang 10, mbedTLS, MemorySanitizer + - name: "Linux (MemorySanitizer)" container: name: focal env: @@ -130,7 +129,7 @@ jobs: ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 UBSAN_OPTIONS: print_stacktrace=1 os: ubuntu-latest - - # Focal, Clang 10, OpenSSL, UndefinedBehaviorSanitizer + - name: "Linux (UndefinedBehaviorSanitizer)" container: name: focal env: @@ -143,7 +142,7 @@ jobs: ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 UBSAN_OPTIONS: print_stacktrace=1 os: ubuntu-latest - - # Focal, Clang 10, OpenSSL, ThreadSanitizer + - name: "Linux (ThreadSanitizer)" container: name: focal env: @@ -157,7 +156,7 @@ jobs: UBSAN_OPTIONS: print_stacktrace=1 TSAN_OPTIONS: suppressions=/home/libgit2/source/script/thread-sanitizer.supp second_deadlock_stack=1 os: ubuntu-latest - - # macOS + - name: "macOS" os: macos-10.15 env: CC: clang @@ -166,7 +165,7 @@ jobs: SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true setup-script: osx - - # Windows amd64 Visual Studio + - name: "Windows (amd64, Visual Studio)" os: windows-2019 env: ARCH: amd64 @@ -174,7 +173,7 @@ jobs: CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - - # Windows x86 Visual Studio + - name: "Windows (x86, Visual Studio)" os: windows-2019 env: ARCH: x86 @@ -182,7 +181,7 @@ jobs: CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - - # Windows amd64 mingw + - name: "Windows (amd64, mingw)" os: windows-2019 setup-script: mingw env: @@ -193,7 +192,7 @@ jobs: BUILD_PATH: D:\Temp\mingw64\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - - # Windows x86 mingw + - name: "Windows (x86, mingw)" os: windows-2019 setup-script: mingw env: @@ -207,6 +206,7 @@ jobs: fail-fast: false env: ${{ matrix.platform.env }} runs-on: ${{ matrix.platform.os }} + name: "Build: ${{ matrix.platform.name }}" steps: - name: Check out repository uses: actions/checkout@v2 @@ -269,7 +269,7 @@ jobs: # published to our documentation site. documentation: name: Generate documentation - needs: [build_containers] + needs: [ containers ] runs-on: ubuntu-latest steps: - name: Check out repository diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 9cb5525eb92..5513d5b435f 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -15,11 +15,10 @@ jobs: # targets and their details. Then we build either in a docker container # (Linux) or on the actual hosts (macOS, Windows). build: - name: Build strategy: matrix: platform: - - # Xenial, GCC, OpenSSL + - name: Linux (Xenial, GCC, OpenSSL) container: name: xenial env: @@ -27,7 +26,7 @@ jobs: CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON os: ubuntu-latest - - # Xenial, GCC, mbedTLS + - name: "Linux (Xenial, GCC, mbedTLS)" container: name: xenial env: @@ -35,7 +34,7 @@ jobs: CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON os: ubuntu-latest - - # Xenial, Clang, OpenSSL + - name: "Linux (Xenial, Clang, OpenSSL)" container: name: xenial env: @@ -43,7 +42,7 @@ jobs: CMAKE_GENERATOR: Ninja CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON os: ubuntu-latest - - # Xenial, Clang, mbedTLS + - name: "Linux (Xenial, Clang, mbedTLS)" container: name: xenial env: @@ -51,7 +50,7 @@ jobs: CMAKE_OPTIONS: -DUSE_HTTPS=mbedTLS -DUSE_SHA1=HTTPS -DREGEX_BACKEND=pcre -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest - - # Xenial, GCC, thread-free + - name: "Linux (no threads)" container: name: xenial env: @@ -59,7 +58,7 @@ jobs: CMAKE_OPTIONS: -DTHREADSAFE=OFF -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest - - # Xenial, Clang, OpenSSL (dynamically loaded) + - name: "Linux (dynamically-loaded OpenSSL)" container: name: xenial env: @@ -67,7 +66,7 @@ jobs: CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON CMAKE_GENERATOR: Ninja os: ubuntu-latest - - # Focal, Clang 10, mbedTLS, MemorySanitizer + - name: "Linux (MemorySanitizer)" container: name: focal env: @@ -80,7 +79,7 @@ jobs: ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 UBSAN_OPTIONS: print_stacktrace=1 os: ubuntu-latest - - # Focal, Clang 10, OpenSSL, UndefinedBehaviorSanitizer + - name: "Linux (UndefinedBehaviorSanitizer)" container: name: focal env: @@ -92,7 +91,7 @@ jobs: SKIP_NEGOTIATE_TESTS: true ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 os: ubuntu-latest - - # Focal, Clang 10, OpenSSL, ThreadSanitizer + - name: "Linux (ThreadSanitizer)" container: name: focal env: @@ -105,7 +104,7 @@ jobs: ASAN_SYMBOLIZER_PATH: /usr/bin/llvm-symbolizer-10 TSAN_OPTIONS: suppressions=/home/libgit2/source/script/thread-sanitizer.supp second_deadlock_stack=1 os: ubuntu-latest - - # Focal, Clang 10, mmap emulation (NO_MMAP) + - name: "Linux (no mmap)" container: name: focal env: @@ -116,7 +115,7 @@ jobs: SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true os: ubuntu-latest - - # CentOS 7 + - name: "Linux (CentOS 7)" container: name: centos7 env: @@ -124,7 +123,7 @@ jobs: PKG_CONFIG_PATH: /usr/local/lib/pkgconfig SKIP_NEGOTIATE_TESTS: true os: ubuntu-latest - - # CentOS 7, OpenSSL (dynamically loaded) + - name: "Linux (CentOS 7, dynamically-loaded OpenSSL)" container: name: centos7 env: @@ -132,7 +131,7 @@ jobs: PKG_CONFIG_PATH: /usr/local/lib/pkgconfig SKIP_NEGOTIATE_TESTS: true os: ubuntu-latest - - # CentOS 8 + - name: "Linux (CentOS 8)" container: name: centos8 env: @@ -141,7 +140,7 @@ jobs: SKIP_NEGOTIATE_TESTS: true SKIP_SSH_TESTS: true os: ubuntu-latest - - # CentOS 8, OpenSSL (dynamically loaded) + - name: "Linux (CentOS 8, dynamically-loaded OpenSSL)" container: name: centos8 env: @@ -150,7 +149,7 @@ jobs: SKIP_NEGOTIATE_TESTS: true SKIP_SSH_TESTS: true os: ubuntu-latest - - # macOS + - name: "macOS" os: macos-10.15 env: CC: clang @@ -159,7 +158,7 @@ jobs: SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true setup-script: osx - - # Windows amd64 Visual Studio + - name: "Windows (amd64, Visual Studio)" os: windows-2019 env: ARCH: amd64 @@ -167,7 +166,7 @@ jobs: CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - - # Windows amd64 Visual Studio (NO_MMAP) + - name: "Windows (no mmap)" os: windows-2019 env: ARCH: amd64 @@ -176,7 +175,7 @@ jobs: CMAKE_OPTIONS: -A x64 -DDEPRECATE_HARD=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - - # Windows x86 Visual Studio + - name: "Windows (x86, Visual Studio)" os: windows-2019 env: ARCH: x86 @@ -184,7 +183,7 @@ jobs: CMAKE_OPTIONS: -A Win32 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DUSE_SHA1=HTTPS -DUSE_BUNDLED_ZLIB=ON SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - - # Windows amd64 mingw + - name: "Windows (amd64, mingw)" os: windows-2019 setup-script: mingw env: @@ -195,7 +194,7 @@ jobs: BUILD_PATH: D:\Temp\mingw64\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - - # Windows x86 mingw + - name: "Windows (x86, mingw)" os: windows-2019 setup-script: mingw env: @@ -206,7 +205,7 @@ jobs: BUILD_PATH: D:\Temp\mingw32\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin SKIP_SSH_TESTS: true SKIP_NEGOTIATE_TESTS: true - - # Bionic, GCC, OpenSSL (dynamically loaded) + - name: "Linux (Bionic, GCC, dynamically-loaded OpenSSL)" container: name: bionic dockerfile: bionic @@ -216,7 +215,7 @@ jobs: CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON RUN_INVASIVE_TESTS: true os: ubuntu-latest - - # Bionic, x86, Clang, OpenSSL + - name: "Linux (x86, Bionic, Clang, OpenSSL)" container: name: bionic-x86 dockerfile: bionic @@ -227,7 +226,7 @@ jobs: CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON RUN_INVASIVE_TESTS: true os: ubuntu-latest - - # Bionic, x86, GCC, OpenSSL + - name: "Linux (x86, Bionic, GCC, OpenSSL)" container: name: bionic-x86 dockerfile: bionic @@ -237,7 +236,7 @@ jobs: CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON RUN_INVASIVE_TESTS: true os: ubuntu-latest - - # Bionic, arm32, GCC, OpenSSL + - name: "Linux (arm32, Bionic, GCC, OpenSSL)" container: name: bionic-arm32 dockerfile: bionic @@ -249,7 +248,7 @@ jobs: RUN_INVASIVE_TESTS: true SKIP_PROXY_TESTS: true os: ubuntu-latest - - # Bionic, arm64, GCC, OpenSSL + - name: "Linux (arm64, Bionic, GCC, OpenSSL)" container: name: bionic-arm64 dockerfile: bionic @@ -262,6 +261,7 @@ jobs: SKIP_PROXY_TESTS: true os: ubuntu-latest fail-fast: false + name: "Build ${{ matrix.platform.name }}" env: ${{ matrix.platform.env }} runs-on: ${{ matrix.platform.os }} steps: From b3384af2d8c239c94a5067abb81a9bb433f95096 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Thu, 3 Feb 2022 12:27:01 +0100 Subject: [PATCH 0768/1616] C90: add inline macro to xdiff and mbedtls --- src/streams/mbedtls.c | 14 ++++++++------ src/xdiff/git-xdiff.h | 11 +++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/streams/mbedtls.c b/src/streams/mbedtls.c index b3a35ab0200..0cf5c8af1fb 100644 --- a/src/streams/mbedtls.c +++ b/src/streams/mbedtls.c @@ -23,12 +23,14 @@ #endif /* Work around C90-conformance issues */ -#if defined(_MSC_VER) -# define inline __inline -#elif defined(__GNUC__) -# define inline __inline__ -#else -# define inline +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) +# if defined(_MSC_VER) +# define inline __inline +# elif defined(__GNUC__) +# define inline __inline__ +# else +# define inline +# endif #endif #include diff --git a/src/xdiff/git-xdiff.h b/src/xdiff/git-xdiff.h index 0b4f0bc04c7..b75dba8195a 100644 --- a/src/xdiff/git-xdiff.h +++ b/src/xdiff/git-xdiff.h @@ -16,6 +16,17 @@ #include "regexp.h" +/* Work around C90-conformance issues */ +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) +# if defined(_MSC_VER) +# define inline __inline +# elif defined(__GNUC__) +# define inline __inline__ +# else +# define inline +# endif +#endif + #define xdl_malloc(x) git__malloc(x) #define xdl_free(ptr) git__free(ptr) #define xdl_realloc(ptr, x) git__realloc(ptr, x) From b82d566464baf6616ad26c7a3fdbbb2c68f8f971 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Feb 2022 09:03:37 -0500 Subject: [PATCH 0769/1616] oid: introduce git_oid__is_hexstr Introduce a function that determines whether a given string is a valid object id (40 chars of hexadigits). --- src/oid.h | 12 ++++++++++++ tests/core/oid.c | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/src/oid.h b/src/oid.h index 84231ffca90..7a89d218755 100644 --- a/src/oid.h +++ b/src/oid.h @@ -48,4 +48,16 @@ GIT_INLINE(void) git_oid__cpy_prefix( out->id[len / 2] &= 0xF0; } +GIT_INLINE(bool) git_oid__is_hexstr(const char *str) +{ + size_t i; + + for (i = 0; str[i] != '\0'; i++) { + if (git__fromhex(str[i]) < 0) + return false; + } + + return (i == GIT_OID_HEXSZ); +} + #endif diff --git a/tests/core/oid.c b/tests/core/oid.c index 7ee6fb67dab..894feadf61d 100644 --- a/tests/core/oid.c +++ b/tests/core/oid.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" +#include "oid.h" static git_oid id; static git_oid idp; @@ -68,3 +69,11 @@ void test_core_oid__ncmp(void) cl_assert(!git_oid_ncmp(&id, &id, 40)); cl_assert(!git_oid_ncmp(&id, &id, 41)); } + +void test_core_oid__is_hexstr(void) +{ + cl_assert(git_oid__is_hexstr("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); + cl_assert(!git_oid__is_hexstr("deadbeefdeadbeef")); + cl_assert(!git_oid__is_hexstr("zeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); + cl_assert(!git_oid__is_hexstr("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef1")); +} From b1e83cca1bbc255627950b4e8d4fdb1174bf7a12 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Feb 2022 09:26:54 -0500 Subject: [PATCH 0770/1616] remote: refactor ref updating Pull ref updating into its own function for future uses. --- src/remote.c | 64 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/src/remote.c b/src/remote.c index f1010415a0b..a0cb1efdbdf 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1702,6 +1702,42 @@ int git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks) return error; } +static int update_ref( + const git_remote *remote, + const char *ref_name, + git_oid *id, + const char *msg, + const git_remote_callbacks *callbacks) +{ + git_reference *ref; + git_oid old_id; + int error; + + error = git_reference_name_to_id(&old_id, remote->repo, ref_name); + + if (error < 0 && error != GIT_ENOTFOUND) + return error; + else if (error == 0 && git_oid_equal(&old_id, id)) + return 0; + + /* If we did find a current reference, make sure we haven't lost a race */ + if (error) + error = git_reference_create(&ref, remote->repo, ref_name, id, true, msg); + else + error = git_reference_create_matching(&ref, remote->repo, ref_name, id, true, &old_id, msg); + + git_reference_free(ref); + + if (error < 0) + return error; + + if (callbacks && callbacks->update_tips && + (error = callbacks->update_tips(ref_name, &old_id, id, callbacks->payload)) < 0) + return error; + + return 0; +} + static int update_tips_for_spec( git_remote *remote, const git_remote_callbacks *callbacks, @@ -1908,14 +1944,12 @@ static int opportunistic_updates(const git_remote *remote, const git_remote_call size_t i, j, k; git_refspec *spec; git_remote_head *head; - git_reference *ref; git_str refname = GIT_STR_INIT; int error = 0; i = j = k = 0; while ((error = next_head(remote, refs, &spec, &head, &i, &j, &k)) == 0) { - git_oid old = {{ 0 }}; /* * If we got here, there is a refspec which was used * for fetching which matches the source of one of the @@ -1925,29 +1959,9 @@ static int opportunistic_updates(const git_remote *remote, const git_remote_call */ git_str_clear(&refname); - if ((error = git_refspec__transform(&refname, spec, head->name)) < 0) - goto cleanup; - - error = git_reference_name_to_id(&old, remote->repo, refname.ptr); - if (error < 0 && error != GIT_ENOTFOUND) + if ((error = git_refspec__transform(&refname, spec, head->name)) < 0 || + (error = update_ref(remote, refname.ptr, &head->oid, msg, callbacks)) < 0) goto cleanup; - - if (!git_oid_cmp(&old, &head->oid)) - continue; - - /* If we did find a current reference, make sure we haven't lost a race */ - if (error) - error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, true, msg); - else - error = git_reference_create_matching(&ref, remote->repo, refname.ptr, &head->oid, true, &old, msg); - git_reference_free(ref); - if (error < 0) - goto cleanup; - - if (callbacks && callbacks->update_tips != NULL) { - if (callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload) < 0) - goto cleanup; - } } if (error == GIT_ITEROVER) @@ -2018,7 +2032,7 @@ int git_remote_update_tips( goto out; } - /* Only try to do opportunistic updates if the refpec lists differ. */ + /* Only try to do opportunistic updates if the refspec lists differ. */ if (remote->passed_refspecs) error = opportunistic_updates(remote, callbacks, &refs, reflog_message); From b523776785e542792bd22f185ed0a678ab07c872 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Feb 2022 10:43:08 -0500 Subject: [PATCH 0771/1616] remote: refactor update tips function Move the functionality to update an individual tip out of the loop; although the update tip function remains rather gnarly, at least the outer function is a bit less onerous. --- src/remote.c | 218 ++++++++++++++++++++++++++++----------------------- 1 file changed, 118 insertions(+), 100 deletions(-) diff --git a/src/remote.c b/src/remote.c index a0cb1efdbdf..fd470366e5e 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1738,141 +1738,153 @@ static int update_ref( return 0; } -static int update_tips_for_spec( - git_remote *remote, - const git_remote_callbacks *callbacks, - int update_fetchhead, - git_remote_autotag_option_t tagopt, - git_refspec *spec, - git_vector *refs, - const char *log_message) +static int update_one_tip( + git_vector *update_heads, + git_remote *remote, + git_refspec *spec, + git_remote_head *head, + git_refspec *tagspec, + git_remote_autotag_option_t tagopt, + const char *log_message, + const git_remote_callbacks *callbacks) { - int error = 0, autotag, valid; - unsigned int i = 0; + git_odb *odb; git_str refname = GIT_STR_INIT; + git_reference *ref = NULL; + bool autotag = false; git_oid old; - git_odb *odb; - git_remote_head *head; - git_reference *ref; - git_refspec tagspec; - git_vector update_heads; + int valid; + int error; - GIT_ASSERT_ARG(remote); + if ((error = git_repository_odb__weakptr(&odb, remote->repo)) < 0) + goto done; - if (git_repository_odb__weakptr(&odb, remote->repo) < 0) - return -1; + /* Ignore malformed ref names (which also saves us from tag^{} */ + if ((error = git_reference_name_is_valid(&valid, head->name)) < 0) + goto done; - if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0) - return -1; + if (!valid) + goto done; - /* Make a copy of the transport's refs */ - if (git_vector_init(&update_heads, 16, NULL) < 0) - return -1; + /* If we have a tag, see if the auto-follow rules say to update it */ + if (git_refspec_src_matches(tagspec, head->name)) { + if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_AUTO) + autotag = true; - for (; i < refs->length; ++i) { - head = git_vector_get(refs, i); - autotag = 0; - git_str_clear(&refname); + if (tagopt != GIT_REMOTE_DOWNLOAD_TAGS_NONE) { + if (git_str_puts(&refname, head->name) < 0) + goto done; + } + } - /* Ignore malformed ref names (which also saves us from tag^{} */ - if (git_reference_name_is_valid(&valid, head->name) < 0) - goto on_error; + /* If we didn't want to auto-follow the tag, check if the refspec matches */ + if (!autotag && git_refspec_src_matches(spec, head->name)) { + if (spec->dst) { + if ((error = git_refspec__transform(&refname, spec, head->name)) < 0) + goto done; + } else { + /* + * no rhs means store it in FETCH_HEAD, even if we don't + * update anything else. + */ + error = git_vector_insert(update_heads, head); + goto done; + } + } - if (!valid) - continue; + /* If we still don't have a refname, we don't want it */ + if (git_str_len(&refname) == 0) + goto done; - /* If we have a tag, see if the auto-follow rules say to update it */ - if (git_refspec_src_matches(&tagspec, head->name)) { - if (tagopt != GIT_REMOTE_DOWNLOAD_TAGS_NONE) { + /* In autotag mode, only create tags for objects already in db */ + if (autotag && !git_odb_exists(odb, &head->oid)) + goto done; - if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_AUTO) - autotag = 1; + if (!autotag && (error = git_vector_insert(update_heads, head)) < 0) + goto done; - git_str_clear(&refname); - if (git_str_puts(&refname, head->name) < 0) - goto on_error; - } - } + error = git_reference_name_to_id(&old, remote->repo, refname.ptr); - /* If we didn't want to auto-follow the tag, check if the refspec matches */ - if (!autotag && git_refspec_src_matches(spec, head->name)) { - if (spec->dst) { - if (git_refspec__transform(&refname, spec, head->name) < 0) - goto on_error; - } else { - /* - * no rhs mans store it in FETCH_HEAD, even if we don't - update anything else. - */ - if ((error = git_vector_insert(&update_heads, head)) < 0) - goto on_error; + if (error < 0 && error != GIT_ENOTFOUND) + goto done; - continue; - } - } + if (!spec->force && + !git_graph_descendant_of(remote->repo, &head->oid, &old)) { + error = 0; + goto done; + } - /* If we still don't have a refname, we don't want it */ - if (git_str_len(&refname) == 0) { - continue; - } + if (error == GIT_ENOTFOUND) { + memset(&old, 0, GIT_OID_RAWSZ); + error = 0; - /* In autotag mode, only create tags for objects already in db */ - if (autotag && !git_odb_exists(odb, &head->oid)) - continue; + if (autotag && (error = git_vector_insert(update_heads, head)) < 0) + goto done; + } - if (!autotag && git_vector_insert(&update_heads, head) < 0) - goto on_error; + if (!git_oid__cmp(&old, &head->oid)) + goto done; - error = git_reference_name_to_id(&old, remote->repo, refname.ptr); - if (error < 0 && error != GIT_ENOTFOUND) - goto on_error; + /* In autotag mode, don't overwrite any locally-existing tags */ + error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, !autotag, + log_message); - if (!(error || error == GIT_ENOTFOUND) - && !spec->force - && !git_graph_descendant_of(remote->repo, &head->oid, &old)) - continue; + if (error < 0) { + if (error == GIT_EEXISTS) + error = 0; - if (error == GIT_ENOTFOUND) { - memset(&old, 0, GIT_OID_RAWSZ); + goto done; + } - if (autotag && git_vector_insert(&update_heads, head) < 0) - goto on_error; - } + if (callbacks && callbacks->update_tips != NULL && + callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload) < 0) + git_error_set_after_callback_function(error, "git_remote_fetch"); - if (!git_oid__cmp(&old, &head->oid)) - continue; +done: + git_reference_free(ref); + return error; +} - /* In autotag mode, don't overwrite any locally-existing tags */ - error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, !autotag, - log_message); +static int update_tips_for_spec( + git_remote *remote, + const git_remote_callbacks *callbacks, + int update_fetchhead, + git_remote_autotag_option_t tagopt, + git_refspec *spec, + git_vector *refs, + const char *log_message) +{ + git_refspec tagspec; + git_remote_head *head; + git_vector update_heads; + int error = 0; + size_t i; - if (error == GIT_EEXISTS) - continue; + GIT_ASSERT_ARG(remote); - if (error < 0) - goto on_error; + if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0) + return -1; - git_reference_free(ref); + /* Make a copy of the transport's refs */ + if (git_vector_init(&update_heads, 16, NULL) < 0) + return -1; - if (callbacks && callbacks->update_tips != NULL) { - if (callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload) < 0) - goto on_error; - } + git_vector_foreach(refs, i, head) { + if (update_one_tip(&update_heads, remote, spec, head, &tagspec, tagopt, log_message, callbacks) < 0) + goto on_error; } if (update_fetchhead && (error = git_remote_write_fetchhead(remote, spec, &update_heads)) < 0) goto on_error; - git_vector_free(&update_heads); git_refspec__dispose(&tagspec); - git_str_dispose(&refname); + git_vector_free(&update_heads); return 0; on_error: - git_vector_free(&update_heads); git_refspec__dispose(&tagspec); - git_str_dispose(&refname); + git_vector_free(&update_heads); return -1; } @@ -1938,8 +1950,11 @@ static int next_head(const git_remote *remote, git_vector *refs, return GIT_ITEROVER; } -static int opportunistic_updates(const git_remote *remote, const git_remote_callbacks *callbacks, - git_vector *refs, const char *msg) +static int opportunistic_updates( + const git_remote *remote, + const git_remote_callbacks *callbacks, + git_vector *refs, + const char *msg) { size_t i, j, k; git_refspec *spec; @@ -1949,6 +1964,7 @@ static int opportunistic_updates(const git_remote *remote, const git_remote_call i = j = k = 0; + /* Handle refspecs matching remote heads */ while ((error = next_head(remote, refs, &spec, &head, &i, &j, &k)) == 0) { /* * If we got here, there is a refspec which was used @@ -1964,8 +1980,10 @@ static int opportunistic_updates(const git_remote *remote, const git_remote_call goto cleanup; } - if (error == GIT_ITEROVER) - error = 0; + if (error != GIT_ITEROVER) + goto cleanup; + + error = 0; cleanup: git_str_dispose(&refname); From 923c16527c30c7ad067ebb308b1572b3d163b54c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 6 Feb 2022 09:36:51 -0500 Subject: [PATCH 0772/1616] transport: add capabilities query function --- include/git2/sys/transport.h | 10 ++++++++++ src/transports/local.c | 9 +++++++++ src/transports/smart.c | 9 +++++++++ 3 files changed, 28 insertions(+) diff --git a/include/git2/sys/transport.h b/include/git2/sys/transport.h index 89e6876498b..f0c2a3eabeb 100644 --- a/include/git2/sys/transport.h +++ b/include/git2/sys/transport.h @@ -46,6 +46,16 @@ struct git_transport { git_transport *transport, const git_remote_connect_options *connect_opts); + /** + * Gets the capabilities for this remote repository. + * + * This function may be called after a successful call to + * `connect()`. + */ + int GIT_CALLBACK(capabilities)( + unsigned int *capabilities, + git_transport *transport); + /** * Get the list of available references in the remote repository. * diff --git a/src/transports/local.c b/src/transports/local.c index 86524edf149..0c768fad833 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -256,6 +256,14 @@ static int local_set_connect_opts( return git_remote_connect_options_normalize(&t->connect_opts, t->owner->repo, connect_opts); } +static int local_capabilities(unsigned int *capabilities, git_transport *transport) +{ + GIT_UNUSED(transport); + + *capabilities = 0; + return 0; +} + static int local_ls(const git_remote_head ***out, size_t *size, git_transport *transport) { transport_local *t = (transport_local *)transport; @@ -721,6 +729,7 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param) t->parent.version = GIT_TRANSPORT_VERSION; t->parent.connect = local_connect; t->parent.set_connect_opts = local_set_connect_opts; + t->parent.capabilities = local_capabilities; t->parent.negotiate_fetch = local_negotiate_fetch; t->parent.download_pack = local_download_pack; t->parent.push = local_push; diff --git a/src/transports/smart.c b/src/transports/smart.c index e76c18fc31f..3b58b84dae4 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -226,6 +226,14 @@ static int git_smart__set_connect_opts( return git_remote_connect_options_normalize(&t->connect_opts, t->owner->repo, opts); } +static int git_smart__capabilities(unsigned int *capabilities, git_transport *transport) +{ + GIT_UNUSED(transport); + + *capabilities = 0; + return 0; +} + static int git_smart__ls(const git_remote_head ***out, size_t *size, git_transport *transport) { transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); @@ -423,6 +431,7 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param) t->parent.version = GIT_TRANSPORT_VERSION; t->parent.connect = git_smart__connect; t->parent.set_connect_opts = git_smart__set_connect_opts; + t->parent.capabilities = git_smart__capabilities; t->parent.close = git_smart__close; t->parent.free = git_smart__free; t->parent.negotiate_fetch = git_smart__negotiate_fetch; From 7a00adcc68ed84fb1f7f9403bfaf7a0a4503e310 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 6 Feb 2022 14:58:33 -0500 Subject: [PATCH 0773/1616] remote: introduce git_remote_capabilities Provide a mechanism for (internal) users to determine a remote's capabilities from the transport. --- src/remote.c | 14 ++++++++++++++ src/remote.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/remote.c b/src/remote.c index fd470366e5e..b588864674d 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1012,6 +1012,20 @@ int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote return remote->transport->ls(out, size, remote->transport); } +int git_remote_capabilities(unsigned int *out, git_remote *remote) +{ + GIT_ASSERT_ARG(remote); + + *out = 0; + + if (!remote->transport) { + git_error_set(GIT_ERROR_NET, "this remote has never connected"); + return -1; + } + + return remote->transport->capabilities(out, remote->transport); +} + static int lookup_config(char **out, git_config *cfg, const char *name) { git_config_entry *ce = NULL; diff --git a/src/remote.h b/src/remote.h index 3cf0fd953e2..0952c7c5cb8 100644 --- a/src/remote.h +++ b/src/remote.h @@ -54,4 +54,6 @@ int git_remote_connect_options_normalize( const git_remote_connect_options *src); void git_remote_connect_options_dispose(git_remote_connect_options *opts); +int git_remote_capabilities(unsigned int *out, git_remote *remote); + #endif From 37d98aaf4463db1ccb6a325409210aab799db115 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 6 Feb 2022 14:59:24 -0500 Subject: [PATCH 0774/1616] transport: transports can indicate support for fetch by oid --- include/git2/sys/remote.h | 31 +++++++++++++++++++++++++++++++ src/transports/local.c | 4 +++- src/transports/smart.c | 10 +++++++++- src/transports/smart.h | 6 +++++- src/transports/smart_protocol.c | 12 ++++++++++++ 5 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 include/git2/sys/remote.h diff --git a/include/git2/sys/remote.h b/include/git2/sys/remote.h new file mode 100644 index 00000000000..dd243ca55d6 --- /dev/null +++ b/include/git2/sys/remote.h @@ -0,0 +1,31 @@ +/* + * 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_sys_git_remote_h +#define INCLUDE_sys_git_remote_h + +/** + * @file git2/sys/remote.h + * @brief Low-level remote functionality for custom transports + * @defgroup git_remote Low-level remote functionality + * @ingroup Git + * @{ +*/ + +GIT_BEGIN_DECL + +typedef enum { + /** Remote supports fetching an advertised object by ID. */ + GIT_REMOTE_CAPABILITY_TIP_OID = (1 << 0), + + /** Remote supports fetching an individual reachable object. */ + GIT_REMOTE_CAPABILITY_REACHABLE_OID = (1 << 1), +} git_remote_capability_t; + +/** @} */ +GIT_END_DECL +#endif diff --git a/src/transports/local.c b/src/transports/local.c index 0c768fad833..6c754a034a4 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -28,6 +28,7 @@ #include "git2/pack.h" #include "git2/commit.h" #include "git2/revparse.h" +#include "git2/sys/remote.h" typedef struct { git_transport parent; @@ -260,7 +261,8 @@ static int local_capabilities(unsigned int *capabilities, git_transport *transpo { GIT_UNUSED(transport); - *capabilities = 0; + *capabilities = GIT_REMOTE_CAPABILITY_TIP_OID | + GIT_REMOTE_CAPABILITY_REACHABLE_OID; return 0; } diff --git a/src/transports/smart.c b/src/transports/smart.c index 3b58b84dae4..801fcbe53bf 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -8,6 +8,7 @@ #include "smart.h" #include "git2.h" +#include "git2/sys/remote.h" #include "refs.h" #include "refspec.h" #include "proxy.h" @@ -228,9 +229,16 @@ static int git_smart__set_connect_opts( static int git_smart__capabilities(unsigned int *capabilities, git_transport *transport) { - GIT_UNUSED(transport); + transport_smart *t = GIT_CONTAINER_OF(transport, transport_smart, parent); *capabilities = 0; + + if (t->caps.want_tip_sha1) + *capabilities |= GIT_REMOTE_CAPABILITY_TIP_OID; + + if (t->caps.want_reachable_sha1) + *capabilities |= GIT_REMOTE_CAPABILITY_REACHABLE_OID; + return 0; } diff --git a/src/transports/smart.h b/src/transports/smart.h index 8860a1ebdf5..9323d6c444e 100644 --- a/src/transports/smart.h +++ b/src/transports/smart.h @@ -30,6 +30,8 @@ #define GIT_CAP_REPORT_STATUS "report-status" #define GIT_CAP_THIN_PACK "thin-pack" #define GIT_CAP_SYMREF "symref" +#define GIT_CAP_WANT_TIP_SHA1 "allow-tip-sha1-in-want" +#define GIT_CAP_WANT_REACHABLE_SHA1 "allow-reachable-sha1-in-want" extern bool git_smart__ofs_delta_enabled; @@ -128,7 +130,9 @@ typedef struct transport_smart_caps { include_tag:1, delete_refs:1, report_status:1, - thin_pack:1; + thin_pack:1, + want_tip_sha1:1, + want_reachable_sha1:1; } transport_smart_caps; typedef int (*packetsize_cb)(size_t received, void *payload); diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 06102817de1..e61c5f48bc1 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -205,6 +205,18 @@ int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vec continue; } + if (!git__prefixcmp(ptr, GIT_CAP_WANT_TIP_SHA1)) { + caps->common = caps->want_tip_sha1 = 1; + ptr += strlen(GIT_CAP_DELETE_REFS); + continue; + } + + if (!git__prefixcmp(ptr, GIT_CAP_WANT_REACHABLE_SHA1)) { + caps->common = caps->want_reachable_sha1 = 1; + ptr += strlen(GIT_CAP_DELETE_REFS); + continue; + } + /* We don't know this capability, so skip it */ ptr = strchr(ptr, ' '); } From 07264ea7b1750ede7d10d64d5451f4ab30d24562 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 6 Feb 2022 14:07:36 -0500 Subject: [PATCH 0775/1616] fetch: add a test for local fetching --- src/remote.c | 4 +++- tests/fetch/local.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/fetch/local.c diff --git a/src/remote.c b/src/remote.c index b588864674d..baec1ede555 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1822,7 +1822,8 @@ static int update_one_tip( if (error < 0 && error != GIT_ENOTFOUND) goto done; - if (!spec->force && + if (!(error || error == GIT_ENOTFOUND) && + !spec->force && !git_graph_descendant_of(remote->repo, &head->oid, &old)) { error = 0; goto done; @@ -1856,6 +1857,7 @@ static int update_one_tip( done: git_reference_free(ref); + git_str_dispose(&refname); return error; } diff --git a/tests/fetch/local.c b/tests/fetch/local.c new file mode 100644 index 00000000000..b4583b2708b --- /dev/null +++ b/tests/fetch/local.c @@ -0,0 +1,36 @@ +#include "clar_libgit2.h" +#include "futils.h" + +static git_repository *repo; + +void test_fetch_local__initialize(void) +{ + cl_git_pass(git_repository_init(&repo, "./fetch", 0)); +} + +void test_fetch_local__cleanup(void) +{ + git_repository_free(repo); + repo = NULL; + + cl_fixture_cleanup("./fetch"); +} + +void test_fetch_local__defaults(void) +{ + git_remote *remote; + git_object *obj; + git_oid expected_id; + + cl_git_pass(git_remote_create(&remote, repo, "test", + cl_fixture("testrepo.git"))); + cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL)); + + git_oid_fromstr(&expected_id, "258f0e2a959a364e40ed6603d5d44fbb24765b10"); + + cl_git_pass(git_revparse_single(&obj, repo, "refs/remotes/test/haacked")); + cl_assert_equal_oid(&expected_id, git_object_id(obj)); + + git_object_free(obj); + git_remote_free(remote); +} From 9d88300a8ee9f184dd0299d0c1ba8487a6c2fb1a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 5 Feb 2022 12:35:46 -0500 Subject: [PATCH 0776/1616] fetch: support oids in fetch specs --- src/fetch.c | 80 ++++++++++++++++++++++++++++++++++++-------- src/remote.c | 32 +++++++++++++++++- src/remote.h | 1 + tests/fetch/local.c | 31 +++++++++++++++++ tests/online/fetch.c | 31 +++++++++++++++++ 5 files changed, 160 insertions(+), 15 deletions(-) diff --git a/src/fetch.c b/src/fetch.c index 117c8f26f2d..03d38452cb9 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -11,6 +11,7 @@ #include "git2/refs.h" #include "git2/revwalk.h" #include "git2/transport.h" +#include "git2/sys/remote.h" #include "remote.h" #include "refspec.h" @@ -19,7 +20,7 @@ #include "repository.h" #include "refs.h" -static int maybe_want(git_remote *remote, git_remote_head *head, git_odb *odb, git_refspec *tagspec, git_remote_autotag_option_t tagopt) +static int maybe_want(git_remote *remote, git_remote_head *head, git_refspec *tagspec, git_remote_autotag_option_t tagopt) { int match = 0, valid; @@ -44,23 +45,57 @@ static int maybe_want(git_remote *remote, git_remote_head *head, git_odb *odb, g if (!match) return 0; - /* If we have the object, mark it so we don't ask for it */ - if (git_odb_exists(odb, &head->oid)) { - head->local = 1; + return git_vector_insert(&remote->refs, head); +} + +static int mark_local(git_remote *remote) +{ + git_remote_head *head; + git_odb *odb; + size_t i; + + if (git_repository_odb__weakptr(&odb, remote->repo) < 0) + return -1; + + 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)) + head->local = 1; + else + remote->need_pack = 1; } - else - remote->need_pack = 1; - return git_vector_insert(&remote->refs, head); + return 0; +} + +static int maybe_want_oid(git_remote *remote, git_refspec *spec) +{ + git_remote_head *oid_head; + + oid_head = git__calloc(1, sizeof(git_remote_head)); + GIT_ERROR_CHECK_ALLOC(oid_head); + + git_oid_fromstr(&oid_head->oid, spec->src); + oid_head->name = git__strdup(spec->dst); + GIT_ERROR_CHECK_ALLOC(oid_head->name); + + if (git_vector_insert(&remote->local_heads, oid_head) < 0 || + git_vector_insert(&remote->refs, oid_head) < 0) + return -1; + + return 0; } static int filter_wants(git_remote *remote, const git_fetch_options *opts) { git_remote_head **heads; - git_refspec tagspec, head; + git_refspec tagspec, head, *spec; int error = 0; git_odb *odb; size_t i, heads_len; + unsigned int remote_caps; + unsigned int oid_mask = GIT_REMOTE_CAPABILITY_TIP_OID | + GIT_REMOTE_CAPABILITY_REACHABLE_OID; git_remote_autotag_option_t tagopt = remote->download_tags; if (opts && opts->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED) @@ -90,14 +125,33 @@ static int filter_wants(git_remote *remote, const git_fetch_options *opts) if ((error = git_repository_odb__weakptr(&odb, remote->repo)) < 0) goto cleanup; - if ((error = git_remote_ls((const git_remote_head ***)&heads, &heads_len, remote)) < 0) + if ((error = git_remote_ls((const git_remote_head ***)&heads, &heads_len, remote)) < 0 || + (error = git_remote_capabilities(&remote_caps, remote)) < 0) goto cleanup; + /* Handle remote heads */ for (i = 0; i < heads_len; i++) { - if ((error = maybe_want(remote, heads[i], odb, &tagspec, tagopt)) < 0) - break; + if ((error = maybe_want(remote, heads[i], &tagspec, tagopt)) < 0) + goto cleanup; + } + + /* Handle explicitly specified OID specs */ + git_vector_foreach(&remote->active_refspecs, i, spec) { + if (!git_oid__is_hexstr(spec->src)) + continue; + + if (!(remote_caps & oid_mask)) { + git_error_set(GIT_ERROR_INVALID, "cannot fetch a specific object from the remote repository"); + error = -1; + goto cleanup; + } + + if ((error = maybe_want_oid(remote, spec)) < 0) + goto cleanup; } + error = mark_local(remote); + cleanup: git_refspec__dispose(&tagspec); @@ -115,10 +169,8 @@ int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts) remote->need_pack = 0; - if (filter_wants(remote, opts) < 0) { - git_error_set(GIT_ERROR_NET, "failed to filter the reference list for wants"); + if (filter_wants(remote, opts) < 0) return -1; - } /* Don't try to negotiate when we don't want anything */ if (!remote->need_pack) diff --git a/src/remote.c b/src/remote.c index baec1ede555..038afc6f5bf 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1871,7 +1871,7 @@ static int update_tips_for_spec( const char *log_message) { git_refspec tagspec; - git_remote_head *head; + git_remote_head *head, oid_head; git_vector update_heads; int error = 0; size_t i; @@ -1885,11 +1885,27 @@ static int update_tips_for_spec( if (git_vector_init(&update_heads, 16, NULL) < 0) return -1; + /* Update tips based on the remote heads */ git_vector_foreach(refs, i, head) { if (update_one_tip(&update_heads, remote, spec, head, &tagspec, tagopt, log_message, callbacks) < 0) goto on_error; } + /* Handle specified oid sources */ + if (git_oid__is_hexstr(spec->src)) { + git_oid id; + + if ((error = git_oid_fromstr(&id, spec->src)) < 0 || + (error = update_ref(remote, spec->dst, &id, log_message, callbacks)) < 0) + goto on_error; + + git_oid_cpy(&oid_head.oid, &id); + oid_head.name = spec->src; + + if ((error = git_vector_insert(&update_heads, &oid_head)) < 0) + goto on_error; + } + if (update_fetchhead && (error = git_remote_write_fetchhead(remote, spec, &update_heads)) < 0) goto on_error; @@ -2107,6 +2123,17 @@ int git_remote_disconnect(git_remote *remote) return 0; } +static void free_heads(git_vector *heads) +{ + git_remote_head *head; + size_t i; + + git_vector_foreach(heads, i, head) { + git__free(head->name); + git__free(head); + } +} + void git_remote_free(git_remote *remote) { if (remote == NULL) @@ -2130,6 +2157,9 @@ void git_remote_free(git_remote *remote) free_refspecs(&remote->passive_refspecs); git_vector_free(&remote->passive_refspecs); + free_heads(&remote->local_heads); + git_vector_free(&remote->local_heads); + git_push_free(remote->push); git__free(remote->url); git__free(remote->pushurl); diff --git a/src/remote.h b/src/remote.h index 0952c7c5cb8..ea9c7d17ff8 100644 --- a/src/remote.h +++ b/src/remote.h @@ -27,6 +27,7 @@ struct git_remote { git_vector refspecs; git_vector active_refspecs; git_vector passive_refspecs; + git_vector local_heads; git_transport *transport; git_repository *repo; git_push *push; diff --git a/tests/fetch/local.c b/tests/fetch/local.c index b4583b2708b..20bd7adf479 100644 --- a/tests/fetch/local.c +++ b/tests/fetch/local.c @@ -34,3 +34,34 @@ void test_fetch_local__defaults(void) git_object_free(obj); git_remote_free(remote); } + +void test_fetch_local__reachable_commit(void) +{ + git_remote *remote; + git_strarray refspecs; + git_object *obj; + git_oid expected_id; + git_str fetchhead = GIT_STR_INIT; + char *refspec = "+5b5b025afb0b4c913b4c338a42934a3863bf3644:refs/success"; + + refspecs.strings = &refspec; + refspecs.count = 1; + + git_oid_fromstr(&expected_id, "5b5b025afb0b4c913b4c338a42934a3863bf3644"); + + cl_git_pass(git_remote_create(&remote, repo, "test", + cl_fixture("testrepo.git"))); + cl_git_pass(git_remote_fetch(remote, &refspecs, NULL, NULL)); + + cl_git_pass(git_revparse_single(&obj, repo, "refs/success")); + cl_assert_equal_oid(&expected_id, git_object_id(obj)); + + cl_git_pass(git_futils_readbuffer(&fetchhead, "./fetch/.git/FETCH_HEAD")); + cl_assert_equal_strn(fetchhead.ptr, + "5b5b025afb0b4c913b4c338a42934a3863bf3644\t\t'5b5b025afb0b4c913b4c338a42934a3863bf3644' of ", + strlen("5b5b025afb0b4c913b4c338a42934a3863bf3644\t\t'5b5b025afb0b4c913b4c338a42934a3863bf3644' of ")); + + git_str_dispose(&fetchhead); + git_object_free(obj); + git_remote_free(remote); +} diff --git a/tests/online/fetch.c b/tests/online/fetch.c index 2be96839d6e..7334f7e8b29 100644 --- a/tests/online/fetch.c +++ b/tests/online/fetch.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" +#include "futils.h" static git_repository *_repo; static int counter; @@ -290,3 +291,33 @@ void test_online_fetch__redirect_config(void) cl_git_fail(do_redirected_fetch(_remote_redirect_initial, "initial", "false")); cl_git_fail(do_redirected_fetch(_remote_redirect_subsequent, "subsequent", "false")); } + +void test_online_fetch__reachable_commit(void) +{ + git_remote *remote; + git_strarray refspecs; + git_object *obj; + git_oid expected_id; + git_str fetchhead = GIT_STR_INIT; + char *refspec = "+2c349335b7f797072cf729c4f3bb0914ecb6dec9:refs/success"; + + refspecs.strings = &refspec; + refspecs.count = 1; + + git_oid_fromstr(&expected_id, "2c349335b7f797072cf729c4f3bb0914ecb6dec9"); + + cl_git_pass(git_remote_create(&remote, _repo, "test", + "https://github.com/libgit2/TestGitRepository")); + cl_git_pass(git_remote_fetch(remote, &refspecs, NULL, NULL)); + + cl_git_pass(git_revparse_single(&obj, _repo, "refs/success")); + cl_assert_equal_oid(&expected_id, git_object_id(obj)); + + cl_git_pass(git_futils_readbuffer(&fetchhead, "./fetch/.git/FETCH_HEAD")); + cl_assert_equal_s(fetchhead.ptr, + "2c349335b7f797072cf729c4f3bb0914ecb6dec9\t\t'2c349335b7f797072cf729c4f3bb0914ecb6dec9' of https://github.com/libgit2/TestGitRepository\n"); + + git_str_dispose(&fetchhead); + git_object_free(obj); + git_remote_free(remote); +} From caaa1fdf8b7233736e9d6f5ae040eb4d8071e5b8 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Mon, 7 Feb 2022 00:58:38 +0100 Subject: [PATCH 0777/1616] merge: change enum GIT_MERGE_FILE_FAVOR__CONFLICTED to flag GIT_MERGE_FILE__CONFLICTED This is to avoid a possible problem where the value is set to the same as GIT_MERGE_FILE_SIMPLIFY_ALNUM in git_merge_file_flag_t --- src/merge.c | 2 +- src/merge.h | 2 +- src/merge_driver.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/merge.c b/src/merge.c index 24650bbff32..5f3a37bbebd 100644 --- a/src/merge.c +++ b/src/merge.c @@ -2120,7 +2120,7 @@ int git_merge__iterators( file_opts.ancestor_label = "merged common ancestors"; file_opts.our_label = "Temporary merge branch 1"; file_opts.their_label = "Temporary merge branch 2"; - file_opts.flags |= GIT_MERGE_FILE_FAVOR__CONFLICTED; + file_opts.flags |= GIT_MERGE_FILE__CONFLICTED; file_opts.marker_size = GIT_MERGE_CONFLICT_MARKER_SIZE + 2; } diff --git a/src/merge.h b/src/merge.h index 632f2d8e3ae..1b541bf62b1 100644 --- a/src/merge.h +++ b/src/merge.h @@ -34,7 +34,7 @@ enum { enum { /** Accept the conflict file, staging it as the merge result. */ - GIT_MERGE_FILE_FAVOR__CONFLICTED = 4 + GIT_MERGE_FILE__CONFLICTED = (1 << 30) }; diff --git a/src/merge_driver.c b/src/merge_driver.c index be4d3bf8a2a..66b257a4f15 100644 --- a/src/merge_driver.c +++ b/src/merge_driver.c @@ -93,7 +93,7 @@ int git_merge_driver__builtin_apply( goto done; if (!result.automergeable && - !(file_opts.flags & GIT_MERGE_FILE_FAVOR__CONFLICTED)) { + !(file_opts.flags & GIT_MERGE_FILE__CONFLICTED)) { error = GIT_EMERGECONFLICT; goto done; } From fed3fef451a45c0b654f996760f403b454f23616 Mon Sep 17 00:00:00 2001 From: Peter Pettersson Date: Mon, 7 Feb 2022 00:45:44 +0100 Subject: [PATCH 0778/1616] merge: allocate merge flags for internal use Allocate flags in git_merge_flag_t and git_merge_file_flag_t for internal usage to prevent accidental double allocation. --- include/git2/merge.h | 10 ++++++++-- src/merge.h | 15 ++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/include/git2/merge.h b/include/git2/merge.h index edd090cffbc..a30833915d3 100644 --- a/include/git2/merge.h +++ b/include/git2/merge.h @@ -91,7 +91,10 @@ typedef enum { * instead simply use the first base. This flag provides a similar * merge base to `git-merge-resolve`. */ - GIT_MERGE_NO_RECURSIVE = (1 << 3) + GIT_MERGE_NO_RECURSIVE = (1 << 3), + + /* This flag is reserved for internal library use */ + GIT_MERGE__INTERNAL_FLAG = (1 << 30) } git_merge_flag_t; /** @@ -162,7 +165,10 @@ typedef enum { GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7), /** Create zdiff3 ("zealous diff3")-style files */ - GIT_MERGE_FILE_STYLE_ZDIFF3 = (1 << 8) + GIT_MERGE_FILE_STYLE_ZDIFF3 = (1 << 8), + + /* This flag is reserved for internal library use */ + GIT_MERGE_FILE__INTERNAL_FLAG = (1 << 30) } git_merge_file_flag_t; #define GIT_MERGE_CONFLICT_MARKER_SIZE 7 diff --git a/src/merge.h b/src/merge.h index 1b541bf62b1..e033e876af3 100644 --- a/src/merge.h +++ b/src/merge.h @@ -27,15 +27,12 @@ /** Internal merge flags. */ -enum { - /** The merge is for a virtual base in a recursive merge. */ - GIT_MERGE__VIRTUAL_BASE = (1 << 31) -}; - -enum { - /** Accept the conflict file, staging it as the merge result. */ - GIT_MERGE_FILE__CONFLICTED = (1 << 30) -}; + +/** The merge is for a virtual base in a recursive merge. */ +#define GIT_MERGE__VIRTUAL_BASE (GIT_MERGE__INTERNAL_FLAG) + +/** Accept the conflict file, staging it as the merge result. */ +#define GIT_MERGE_FILE__CONFLICTED (GIT_MERGE_FILE__INTERNAL_FLAG) /** Types of changes when files are merged from branch to branch. */ From 19ec5923db885f089a1b862615f752ddf6c80dec Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Mon, 7 Feb 2022 09:29:40 -0600 Subject: [PATCH 0779/1616] push: Prepare pack before sending pack header. For large pushes, preparing the pack can take a while. Currently we send the pack header first, followed by preparing the pack and then finally sending the pack. Unfortunately github.com will terminate a git-receive-pack command over http if it is idle for more than 10 seconds. This is easily exceeded for a large push, and so the push is rejected with a Broken Pipe error. This patch moves the pack preparation ahead of sending the pack header, so that the timeout is avoided. prepare_pack() can be called multiple times but will only do the work once, so the original PREPARE_PACK call inside git_packbuilder_foreach() remains. --- src/pack-objects.c | 2 +- src/pack-objects.h | 2 ++ src/transports/smart_protocol.c | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pack-objects.c b/src/pack-objects.c index e5fc625a465..abe978b9db9 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -1308,7 +1308,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list, #define ll_find_deltas(pb, l, ls, w, d) find_deltas(pb, l, &ls, w, d) #endif -static int prepare_pack(git_packbuilder *pb) +int prepare_pack(git_packbuilder *pb) { git_pobject **delta_list; size_t i, n = 0; diff --git a/src/pack-objects.h b/src/pack-objects.h index db2038b0a04..35bae3ad6b4 100644 --- a/src/pack-objects.h +++ b/src/pack-objects.h @@ -97,5 +97,7 @@ struct git_packbuilder { }; int git_packbuilder__write_buf(git_str *buf, git_packbuilder *pb); +int prepare_pack(git_packbuilder *pb); + #endif diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index a9a623cc7df..625f8500934 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -1034,6 +1034,10 @@ int git_smart__push(git_transport *transport, git_push *push, const git_remote_c } } + /* prepare pack before sending pack header to avoid timeouts */ + if (need_pack && ((error = prepare_pack(push->pb))) < 0) + goto done; + if ((error = git_smart__get_push_stream(t, &packbuilder_payload.stream)) < 0 || (error = gen_pktline(&pktline, push)) < 0 || (error = packbuilder_payload.stream->write(packbuilder_payload.stream, git_str_cstr(&pktline), git_str_len(&pktline))) < 0) From c19a3c7a23a972e25e013cff300343323e65a55f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 7 Feb 2022 11:22:04 -0500 Subject: [PATCH 0780/1616] odb: check for write failures --- src/odb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/odb.c b/src/odb.c index 156d03076c5..3abeae280e2 100644 --- a/src/odb.c +++ b/src/odb.c @@ -1501,10 +1501,10 @@ int git_odb_write( if ((error = git_odb_open_wstream(&stream, db, len, type)) != 0) return error; - stream->write(stream, data, len); - error = stream->finalize_write(stream, oid); - git_odb_stream_free(stream); + if ((error = stream->write(stream, data, len)) == 0) + error = stream->finalize_write(stream, oid); + git_odb_stream_free(stream); return error; } From 9177585410f35bd04793e3762eed9f7d57bf326e Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Tue, 8 Feb 2022 18:04:52 +0000 Subject: [PATCH 0781/1616] Update src/pack-objects.h Co-authored-by: Edward Thomson --- src/pack-objects.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pack-objects.h b/src/pack-objects.h index 35bae3ad6b4..3021e9ce00e 100644 --- a/src/pack-objects.h +++ b/src/pack-objects.h @@ -97,7 +97,7 @@ struct git_packbuilder { }; int git_packbuilder__write_buf(git_str *buf, git_packbuilder *pb); -int prepare_pack(git_packbuilder *pb); +int git_packbuilder__prepare(git_packbuilder *pb); #endif From aceac672fd0431ec55d4efe3f037c596700ad46c Mon Sep 17 00:00:00 2001 From: Colin Stolley Date: Tue, 8 Feb 2022 12:14:50 -0600 Subject: [PATCH 0782/1616] Rename prepare_pack() to git_packbuilder__prepare() --- src/pack-objects.c | 4 ++-- src/transports/smart_protocol.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pack-objects.c b/src/pack-objects.c index abe978b9db9..ab441a2b47a 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -1308,7 +1308,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list, #define ll_find_deltas(pb, l, ls, w, d) find_deltas(pb, l, &ls, w, d) #endif -int prepare_pack(git_packbuilder *pb) +int git_packbuilder__prepare(git_packbuilder *pb) { git_pobject **delta_list; size_t i, n = 0; @@ -1353,7 +1353,7 @@ int prepare_pack(git_packbuilder *pb) return 0; } -#define PREPARE_PACK if (prepare_pack(pb) < 0) { return -1; } +#define PREPARE_PACK if (git_packbuilder__prepare(pb) < 0) { return -1; } int git_packbuilder_foreach(git_packbuilder *pb, int (*cb)(void *buf, size_t size, void *payload), void *payload) { diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 625f8500934..7d7d1340e0e 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -1035,7 +1035,7 @@ int git_smart__push(git_transport *transport, git_push *push, const git_remote_c } /* prepare pack before sending pack header to avoid timeouts */ - if (need_pack && ((error = prepare_pack(push->pb))) < 0) + if (need_pack && ((error = git_packbuilder__prepare(push->pb))) < 0) goto done; if ((error = git_smart__get_push_stream(t, &packbuilder_payload.stream)) < 0 || From 3c53796cbe4e8c8425b4b41598913bb5cbc1f5a1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 7 Feb 2022 19:38:32 -0500 Subject: [PATCH 0783/1616] rand: introduce git_rand PRNG Introduce `git_rand`, a PRNG based on xoroshiro256**, a fast, all-purpose pseudo-random number generator: https://prng.di.unimi.it The PRNG will be seeded by the system's entropy store when possible, falling back to current time and system data (pid, uptime, etc). Inspiration for this was taken from libressl, but since our PRNG is not used for cryptographic purposes (and indeed currently only generates a unique temp file name that is written in a protected directory), this should be more than sufficient. Our implementation of xoroshiro256** was taken almost strictly from the original author's sources, but was tested against PractRand to ensure that there were no foolish mistranslations: ``` RNG_test using PractRand version 0.94 RNG = RNG_stdin64, seed = unknown test set = core, folding = standard (64 bit) rng=RNG_stdin64, seed=unknown length= 256 megabytes (2^28 bytes), time= 2.9 seconds no anomalies in 210 test result(s) rng=RNG_stdin64, seed=unknown length= 512 megabytes (2^29 bytes), time= 6.2 seconds no anomalies in 226 test result(s) rng=RNG_stdin64, seed=unknown length= 1 gigabyte (2^30 bytes), time= 12.7 seconds no anomalies in 243 test result(s) rng=RNG_stdin64, seed=unknown length= 2 gigabytes (2^31 bytes), time= 25.4 seconds no anomalies in 261 test result(s) rng=RNG_stdin64, seed=unknown length= 4 gigabytes (2^32 bytes), time= 50.6 seconds no anomalies in 277 test result(s) rng=RNG_stdin64, seed=unknown length= 8 gigabytes (2^33 bytes), time= 104 seconds no anomalies in 294 test result(s) ``` --- COPYING | 12 +++ src/CMakeLists.txt | 2 + src/features.h.in | 2 + src/libgit2.c | 2 + src/rand.c | 226 +++++++++++++++++++++++++++++++++++++++++++++ src/rand.h | 37 ++++++++ 6 files changed, 281 insertions(+) create mode 100644 src/rand.c create mode 100644 src/rand.h diff --git a/COPYING b/COPYING index efeff148724..ccfb7dbf8de 100644 --- a/COPYING +++ b/COPYING @@ -1132,3 +1132,15 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +---------------------------------------------------------------------- + +The xoroshiro256** implementation is licensed in the public domain: + +Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) + +To the extent possible under law, the author has dedicated all copyright +and related and neighboring rights to this software to the public domain +worldwide. This software is distributed without any warranty. + +See . + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e2da4bc90d1..e7b54d036ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -55,6 +55,8 @@ check_prototype_definition(qsort_r check_function_exists(qsort_s GIT_QSORT_S) +check_function_exists(getentropy GIT_RAND_GETENTROPY) + # Find required dependencies if(WIN32) diff --git a/src/features.h.in b/src/features.h.in index 81a8ae023c1..f920135da59 100644 --- a/src/features.h.in +++ b/src/features.h.in @@ -48,4 +48,6 @@ #cmakedefine GIT_SHA1_OPENSSL 1 #cmakedefine GIT_SHA1_MBEDTLS 1 +#cmakedefine GIT_RAND_GETENTROPY 1 + #endif diff --git a/src/libgit2.c b/src/libgit2.c index b3a72de18f9..b17485d7f22 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -20,6 +20,7 @@ #include "mwindow.h" #include "object.h" #include "odb.h" +#include "rand.h" #include "refs.h" #include "runtime.h" #include "sysdir.h" @@ -70,6 +71,7 @@ int git_libgit2_init(void) git_allocator_global_init, git_threadstate_global_init, git_threads_global_init, + git_rand_global_init, git_hash_global_init, git_sysdir_global_init, git_filter_global_init, diff --git a/src/rand.c b/src/rand.c new file mode 100644 index 00000000000..0a208134e4c --- /dev/null +++ b/src/rand.c @@ -0,0 +1,226 @@ +/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) + +To the extent possible under law, the author has dedicated all copyright +and related and neighboring rights to this software to the public domain +worldwide. This software is distributed without any warranty. + +See . */ + +#include "common.h" +#include "rand.h" +#include "runtime.h" + +#if defined(GIT_RAND_GETENTROPY) +# include +#endif + +static uint64_t state[4]; +static git_mutex state_lock; + +typedef union { + double f; + uint64_t d; +} bits; + +#if defined(GIT_WIN32) +GIT_INLINE(int) getseed(uint64_t *seed) +{ + HCRYPTPROV provider; + SYSTEMTIME systemtime; + FILETIME filetime, idletime, kerneltime, usertime; + bits convert; + + if (CryptAcquireContext(&provider, 0, 0, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) { + BOOL success = CryptGenRandom(provider, sizeof(uint64_t), (void *)seed); + CryptReleaseContext(provider, 0); + + if (success) + return 0; + } + + GetSystemTime(&systemtime); + if (!SystemTimeToFileTime(&systemtime, &filetime)) { + git_error_set(GIT_ERROR_OS, "could not get time for random seed"); + return -1; + } + + /* Fall-through: generate a seed from the time and system state */ + *seed = 0; + *seed |= ((uint64_t)filetime.dwLowDateTime << 32); + *seed |= ((uint64_t)filetime.dwHighDateTime); + + GetSystemTimes(&idletime, &kerneltime, &usertime); + + *seed ^= ((uint64_t)idletime.dwLowDateTime << 32); + *seed ^= ((uint64_t)kerneltime.dwLowDateTime); + *seed ^= ((uint64_t)usertime.dwLowDateTime << 32); + + *seed ^= ((uint64_t)idletime.dwHighDateTime); + *seed ^= ((uint64_t)kerneltime.dwHighDateTime << 12); + *seed ^= ((uint64_t)usertime.dwHighDateTime << 24); + + *seed ^= ((uint64_t)GetCurrentProcessId() << 32); + *seed ^= ((uint64_t)GetCurrentThreadId() << 48); + + convert.f = git__timer(); *seed ^= (convert.d); + + /* Mix in the addresses of some functions and variables */ + *seed ^= (((uint64_t)((uintptr_t)seed) << 32)); + *seed ^= (((uint64_t)((uintptr_t)&errno))); + + return 0; +} + +#else + +GIT_INLINE(int) getseed(uint64_t *seed) +{ + struct timeval tv; + double loadavg[3]; + bits convert; + int fd; + +# if defined(GIT_RAND_GETENTROPY) + GIT_UNUSED((fd = 0)); + + if (getentropy(seed, sizeof(uint64_t)) == 0) + return 0; +# else + /* + * Try to read from /dev/urandom; most modern systems will have + * this, but we may be chrooted, etc, so it's not a fatal error + */ + if ((fd = open("/dev/urandom", O_RDONLY)) >= 0) { + ssize_t ret = read(fd, seed, sizeof(uint64_t)); + close(fd); + + if (ret == (ssize_t)sizeof(uint64_t)) + return 0; + } +# endif + + /* Fall-through: generate a seed from the time and system state */ + if (gettimeofday(&tv, NULL) < 0) { + git_error_set(GIT_ERROR_OS, "could get time for random seed"); + return -1; + } + + getloadavg(loadavg, 3); + + *seed = 0; + *seed |= ((uint64_t)tv.tv_usec << 40); + *seed |= ((uint64_t)tv.tv_sec); + + *seed ^= ((uint64_t)getpid() << 48); + *seed ^= ((uint64_t)getppid() << 32); + *seed ^= ((uint64_t)getpgid(0) << 28); + *seed ^= ((uint64_t)getsid(0) << 16); + *seed ^= ((uint64_t)getuid() << 8); + *seed ^= ((uint64_t)getgid()); + + convert.f = loadavg[0]; *seed ^= (convert.d >> 36); + convert.f = loadavg[1]; *seed ^= (convert.d); + convert.f = loadavg[2]; *seed ^= (convert.d >> 16); + + convert.f = git__timer(); *seed ^= (convert.d); + + /* Mix in the addresses of some variables */ + *seed ^= ((uint64_t)((size_t)((void *)seed)) << 32); + *seed ^= ((uint64_t)((size_t)((void *)&errno))); + + return 0; +} +#endif + +static void git_rand_global_shutdown(void) +{ + git_mutex_free(&state_lock); +} + +int git_rand_global_init(void) +{ + uint64_t seed = 0; + + if (git_mutex_init(&state_lock) < 0 || getseed(&seed) < 0) + return -1; + + if (!seed) { + git_error_set(GIT_ERROR_INTERNAL, "failed to generate random seed"); + return -1; + } + + git_rand_seed(seed); + git_runtime_shutdown_register(git_rand_global_shutdown); + + return 0; +} + +/* + * This is splitmix64. xoroshiro256** uses 256 bit seed; this is used + * to generate 256 bits of seed from the given 64, per the author's + * recommendation. + */ +GIT_INLINE(uint64_t) splitmix64(uint64_t *in) +{ + uint64_t z; + + *in += 0x9e3779b97f4a7c15; + + z = *in; + z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; + z = (z ^ (z >> 27)) * 0x94d049bb133111eb; + return z ^ (z >> 31); +} + +void git_rand_seed(uint64_t seed) +{ + uint64_t mixer; + + mixer = seed; + + git_mutex_lock(&state_lock); + state[0] = splitmix64(&mixer); + state[1] = splitmix64(&mixer); + state[2] = splitmix64(&mixer); + state[3] = splitmix64(&mixer); + git_mutex_unlock(&state_lock); +} + +/* This is xoshiro256** 1.0, one of our all-purpose, rock-solid + generators. It has excellent (sub-ns) speed, a state (256 bits) that is + large enough for any parallel application, and it passes all tests we + are aware of. + + For generating just floating-point numbers, xoshiro256+ is even faster. + + The state must be seeded so that it is not everywhere zero. If you have + a 64-bit seed, we suggest to seed a splitmix64 generator and use its + output to fill s. */ + +GIT_INLINE(uint64_t) rotl(const uint64_t x, int k) { + return (x << k) | (x >> (64 - k)); +} + +uint64_t git_rand_next(void) { + uint64_t t, result; + + git_mutex_lock(&state_lock); + + result = rotl(state[1] * 5, 7) * 9; + + t = state[1] << 17; + + state[2] ^= state[0]; + state[3] ^= state[1]; + state[1] ^= state[2]; + state[0] ^= state[3]; + + state[2] ^= t; + + state[3] = rotl(state[3], 45); + + git_mutex_unlock(&state_lock); + + return result; +} diff --git a/src/rand.h b/src/rand.h new file mode 100644 index 00000000000..2e60561e51d --- /dev/null +++ b/src/rand.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_rand_h__ +#define INCLUDE_rand_h__ + +#include "common.h" + +/** + * Initialize the random number generation subsystem. This will + * seed the random number generator with the system's entropy pool, + * if available, and will fall back to the current time and + * system information if not. + */ +int git_rand_global_init(void); + +/** + * Seed the pseudo-random number generator. This is not needed to be + * called; the PRNG is seeded by `git_rand_global_init`, but it may + * be useful for testing. When the same seed is specified, the same + * sequence of random numbers from `git_rand_next` is emitted. + * + * @param seed the seed to use + */ +void git_rand_seed(uint64_t seed); + +/** + * Get the next pseudo-random number in the sequence. + * + * @return a 64-bit pseudo-random number + */ +uint64_t git_rand_next(void); + +#endif From 86c58a5b6f89785fe6982f161e7c1f4075839a73 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 7 Feb 2022 23:10:38 -0500 Subject: [PATCH 0784/1616] str: add hexadigit encoding to strings --- src/str.c | 26 ++++++++++++++++++++++++++ src/str.h | 3 +++ 2 files changed, 29 insertions(+) diff --git a/src/str.c b/src/str.c index 9d579f1441f..0d405bfda50 100644 --- a/src/str.c +++ b/src/str.c @@ -217,6 +217,32 @@ int git_str_puts(git_str *buf, const char *string) return git_str_put(buf, string, strlen(string)); } +static char hex_encode[] = "0123456789abcdef"; + +int git_str_encode_hexstr(git_str *str, const char *data, size_t len) +{ + size_t new_size, i; + char *s; + + GIT_ERROR_CHECK_ALLOC_MULTIPLY(&new_size, len, 2); + GIT_ERROR_CHECK_ALLOC_ADD(&new_size, new_size, 1); + + if (git_str_grow_by(str, new_size) < 0) + return -1; + + s = str->ptr + str->size; + + for (i = 0; i < len; i++) { + *s++ = hex_encode[(data[i] & 0xf0) >> 4]; + *s++ = hex_encode[(data[i] & 0x0f)]; + } + + str->size += (len * 2); + str->ptr[str->size] = '\0'; + + return 0; +} + static const char base64_encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; diff --git a/src/str.h b/src/str.h index af7acc21f87..ef769ce2f98 100644 --- a/src/str.h +++ b/src/str.h @@ -217,6 +217,9 @@ int git_str_cmp(const git_str *a, const git_str *b); int git_str_quote(git_str *str); int git_str_unquote(git_str *str); +/* Write data as a hex string */ +int git_str_encode_hexstr(git_str *str, const char *data, size_t len); + /* Write data as base64 encoded in string buffer */ int git_str_encode_base64(git_str *str, const char *data, size_t len); /* Decode the given bas64 and write the result to the string buffer */ From 53063e77fed6b9a133b35558416994bf43caf699 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 7 Feb 2022 23:11:11 -0500 Subject: [PATCH 0785/1616] futils: use our random function for mktemp `mktemp` on mingw is exceedingly deficient, using a single monotonically increasing alphabetic character and the pid. We need to use our own random number generator for temporary filenames. --- src/futils.c | 17 ++++++++--------- src/futils.h | 11 ++++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/futils.c b/src/futils.c index 318e878f534..42c35955e30 100644 --- a/src/futils.c +++ b/src/futils.c @@ -10,6 +10,8 @@ #include "runtime.h" #include "strmap.h" #include "hash.h" +#include "rand.h" + #include #if GIT_WIN32 #include "win32/findfile.h" @@ -27,23 +29,20 @@ int git_futils_mkpath2file(const char *file_path, const mode_t mode) int git_futils_mktmp(git_str *path_out, const char *filename, mode_t mode) { const int open_flags = O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC; - /* TMP_MAX is unrelated to mktemp but should provide a reasonable amount */ - unsigned int tries = TMP_MAX; + unsigned int tries = 32; int fd; while (tries--) { + uint64_t rand = git_rand_next(); + git_str_sets(path_out, filename); - git_str_puts(path_out, "_git2_XXXXXX"); + git_str_puts(path_out, "_git2_"); + git_str_encode_hexstr(path_out, (void *)&rand, sizeof(uint64_t)); if (git_str_oom(path_out)) return -1; - /* Using mktemp is safe when we open with O_CREAT | O_EXCL */ - p_mktemp(path_out->ptr); - /* mktemp sets template to empty string on failure */ - if (path_out->ptr[0] == '\0') - break; - + /* Note that we open with O_CREAT | O_EXCL */ if ((fd = p_open(path_out->ptr, open_flags, mode)) >= 0) return fd; } diff --git a/src/futils.h b/src/futils.h index 1827cbafef3..a82ec41cc63 100644 --- a/src/futils.h +++ b/src/futils.h @@ -177,11 +177,12 @@ extern int git_futils_rmdir_r(const char *path, const char *base, uint32_t flags * protected directory; the file created will created will honor * the current `umask`. Writes the filename into path_out. * - * This function is *NOT* suitable for use in temporary directories - * that are world writable. It uses `mktemp` (for portability) and - * many `mktemp` implementations use weak random characters. It - * should only be assumed to be suitable for atomically writing - * a new file in a directory that you control. + * This function uses a high-quality PRNG seeded by the system's + * entropy pool _where available_ and falls back to a simple seed + * (time plus system information) when not. This is suitable for + * writing within a protected directory, but the system's safe + * temporary file creation functions should be preferred where + * available when writing into world-writable (temp) directories. * * @return On success, an open file descriptor, else an error code < 0. */ From 97fade4f1968ab0cf3afdfe86323feeebeaea494 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 8 Feb 2022 12:19:59 -0500 Subject: [PATCH 0786/1616] fs_path: use new mktmp to query unicode support --- src/fs_path.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index f9da304f5b6..7a657778a3b 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1040,8 +1040,8 @@ int git_fs_path_iconv(git_fs_path_iconv_t *ic, const char **in, size_t *inlen) return -1; } -static const char *nfc_file = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D.XXXXXX"; -static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D.XXXXXX"; +static const char *nfc_file = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D"; +static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"; /* Check if the platform is decomposing unicode data for us. We will * emulate core Git and prefer to use precomposed unicode data internally @@ -1054,39 +1054,42 @@ static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D.XXXXXX"; */ bool git_fs_path_does_decompose_unicode(const char *root) { - git_str path = GIT_STR_INIT; + git_str nfc_path = GIT_STR_INIT; + git_str nfd_path = GIT_STR_INIT; int fd; bool found_decomposed = false; - char tmp[6]; + size_t orig_len; + const char *trailer; /* Create a file using a precomposed path and then try to find it * using the decomposed name. If the lookup fails, then we will mark * that we should precompose unicode for this repository. */ - if (git_str_joinpath(&path, root, nfc_file) < 0 || - (fd = p_mkstemp(path.ptr)) < 0) + if (git_str_joinpath(&nfc_path, root, nfc_file) < 0) + goto done; + + /* record original path length before trailer */ + orig_len = nfc_path.size; + + if ((fd = git_futils_mktmp(&nfc_path, nfc_path.ptr, 0666)) < 0) goto done; p_close(fd); - /* record trailing digits generated by mkstemp */ - memcpy(tmp, path.ptr + path.size - sizeof(tmp), sizeof(tmp)); + trailer = nfc_path.ptr + orig_len; /* try to look up as NFD path */ - if (git_str_joinpath(&path, root, nfd_file) < 0) + if (git_str_joinpath(&nfd_path, root, nfd_file) < 0 || + git_str_puts(&nfd_path, trailer) < 0) goto done; - memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); - found_decomposed = git_fs_path_exists(path.ptr); + found_decomposed = git_fs_path_exists(nfd_path.ptr); /* remove temporary file (using original precomposed path) */ - if (git_str_joinpath(&path, root, nfc_file) < 0) - goto done; - memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); - - (void)p_unlink(path.ptr); + (void)p_unlink(nfc_path.ptr); done: - git_str_dispose(&path); + git_str_dispose(&nfc_path); + git_str_dispose(&nfd_path); return found_decomposed; } From b933c14a9297ca616305098ee81ea5ffd392384d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 8 Feb 2022 12:22:15 -0500 Subject: [PATCH 0787/1616] util: remove `p_mktemp` / `p_mkstemp` We have our own temporary file creation function now in `git_futils_mktmp`, remove the others since they may be terrible on some platforms. --- src/posix.h | 1 - src/unix/posix.h | 1 - src/win32/posix.h | 1 - src/win32/posix_w32.c | 14 -------------- 4 files changed, 17 deletions(-) diff --git a/src/posix.h b/src/posix.h index 1757764a277..e6f60307811 100644 --- a/src/posix.h +++ b/src/posix.h @@ -131,7 +131,6 @@ extern ssize_t p_pwrite(int fd, const void *data, size_t size, off64_t offset); #define p_close(fd) close(fd) #define p_umask(m) umask(m) -#define p_mktemp(p) mktemp(p) extern int p_open(const char *path, int flags, ...); extern int p_creat(const char *path, mode_t mode); diff --git a/src/unix/posix.h b/src/unix/posix.h index 27a8fecd4ce..49065e5336c 100644 --- a/src/unix/posix.h +++ b/src/unix/posix.h @@ -58,7 +58,6 @@ GIT_INLINE(int) p_fsync(int fd) #define p_strncasecmp(s1, s2, c) strncasecmp(s1, s2, c) #define p_vsnprintf(b, c, f, a) vsnprintf(b, c, f, a) #define p_snprintf snprintf -#define p_mkstemp(p) mkstemp(p) #define p_chdir(p) chdir(p) #define p_rmdir(p) rmdir(p) #define p_access(p,m) access(p,m) diff --git a/src/win32/posix.h b/src/win32/posix.h index 87c6b436ae7..578347f1527 100644 --- a/src/win32/posix.h +++ b/src/win32/posix.h @@ -42,7 +42,6 @@ extern int p_inet_pton(int af, const char *src, void* dst); extern int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr); extern int p_snprintf(char *buffer, size_t count, const char *format, ...) GIT_FORMAT_PRINTF(3, 4); -extern int p_mkstemp(char *tmp_path); extern int p_chdir(const char *path); extern int p_chmod(const char *path, mode_t mode); extern int p_rmdir(const char *path); diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index b6072411d03..5f7cd0c2645 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -860,20 +860,6 @@ int p_snprintf(char *buffer, size_t count, const char *format, ...) return r; } -/* TODO: wut? */ -int p_mkstemp(char *tmp_path) -{ -#if defined(_MSC_VER) && _MSC_VER >= 1500 - if (_mktemp_s(tmp_path, strlen(tmp_path) + 1) != 0) - return -1; -#else - if (_mktemp(tmp_path) == NULL) - return -1; -#endif - - return p_open(tmp_path, O_RDWR | O_CREAT | O_EXCL, 0744); /* -V536 */ -} - int p_access(const char *path, mode_t mode) { git_win32_path buf; From 0a0cd67dcbc9406f57de17be5d1dde25897677dd Mon Sep 17 00:00:00 2001 From: Iliyas Jorio Date: Tue, 8 Feb 2022 20:18:15 +0100 Subject: [PATCH 0788/1616] diff_file: fix crash if size of diffed file changes in workdir "diff_file_content_load_workdir_file()" maps a file from the workdir into memory. It uses git_diff_file.size to determine the size of the memory mapping. If this value goes stale, the mmaped area would be sized incorrectly. This could occur if an external program changes the contents of the file after libgit2 had cached its size. This used to segfault if the file becomes smaller (mmaped area too large). This patch causes diff_file_content_load_workdir_file to fail without crashing if it detects that the file size has changed. --- src/diff_file.c | 15 ++++-- tests/diff/externalmodifications.c | 77 ++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 tests/diff/externalmodifications.c diff --git a/src/diff_file.c b/src/diff_file.c index 78e332f2247..0a5ded72a4d 100644 --- a/src/diff_file.c +++ b/src/diff_file.c @@ -328,16 +328,25 @@ static int diff_file_content_load_workdir_file( git_filter_list *fl = NULL; git_file fd = git_futils_open_ro(git_str_cstr(path)); git_str raw = GIT_STR_INIT; + git_object_size_t new_file_size = 0; if (fd < 0) return fd; - if (!fc->file->size) - error = git_futils_filesize(&fc->file->size, fd); + error = git_futils_filesize(&new_file_size, fd); - if (error < 0 || !fc->file->size) + if (error < 0 || !new_file_size) goto cleanup; + /* if file size doesn't match cached value, abort */ + if (fc->file->size && fc->file->size != new_file_size) + { + error = -1; + goto cleanup; + } + + fc->file->size = new_file_size; + if ((diff_opts->flags & GIT_DIFF_SHOW_BINARY) == 0 && diff_file_content_binary_by_size(fc)) goto cleanup; diff --git a/tests/diff/externalmodifications.c b/tests/diff/externalmodifications.c new file mode 100644 index 00000000000..d18e1feee96 --- /dev/null +++ b/tests/diff/externalmodifications.c @@ -0,0 +1,77 @@ +#include "clar_libgit2.h" +#include "../checkout/checkout_helpers.h" + +#include "index.h" +#include "repository.h" + +static git_repository *g_repo; + +void test_diff_externalmodifications__initialize(void) +{ + g_repo = cl_git_sandbox_init("testrepo2"); +} + +void test_diff_externalmodifications__cleanup(void) +{ + cl_git_sandbox_cleanup(); + g_repo = NULL; +} + +void test_diff_externalmodifications__file_becomes_smaller(void) +{ + git_index *index; + git_diff *diff; + git_patch* patch; + git_str path = GIT_STR_INIT; + char big_string[500001]; + + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "README")); + + /* Modify the file with a large string */ + memset(big_string, '\n', sizeof(big_string) - 1); + big_string[sizeof(big_string) - 1] = '\0'; + cl_git_mkfile(path.ptr, big_string); + + /* Get a diff */ + cl_git_pass(git_repository_index(&index, g_repo)); + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL)); + cl_assert_equal_i(1, git_diff_num_deltas(diff)); + cl_assert_equal_i(500000, git_diff_get_delta(diff, 0)->new_file.size); + + /* Simulate file modification after we've gotten the diff. + * Write a shorter string to ensure that we don't mmap 500KB from + * the previous revision, which would most likely crash. */ + cl_git_mkfile(path.ptr, "hello"); + + /* Attempt to get a patch */ + cl_git_fail(git_patch_from_diff(&patch, diff, 0)); + + git_index_free(index); + git_diff_free(diff); + git_str_dispose(&path); +} + +void test_diff_externalmodifications__file_deleted(void) +{ + git_index *index; + git_diff *diff; + git_patch* patch; + git_str path = GIT_STR_INIT; + + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "README")); + + /* Get a diff */ + cl_git_pass(git_repository_index(&index, g_repo)); + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL)); + cl_assert_equal_i(0, git_diff_num_deltas(diff)); + + /* Delete the file */ + cl_git_rmfile(path.ptr); + + /* Attempt to get a patch */ + cl_git_fail(git_patch_from_diff(&patch, diff, 0)); + + git_index_free(index); + git_diff_free(diff); + git_str_dispose(&path); +} From 3bac68ff05ae1a87975b8850b554830b4dea27d3 Mon Sep 17 00:00:00 2001 From: Iliyas Jorio Date: Wed, 9 Feb 2022 18:54:34 +0100 Subject: [PATCH 0789/1616] diff_file: Apply suggestions from code review Skip new_file_size non-zero test, custom error message if file changed in workdir Co-authored-by: Edward Thomson --- src/diff_file.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diff_file.c b/src/diff_file.c index 0a5ded72a4d..9804a943c80 100644 --- a/src/diff_file.c +++ b/src/diff_file.c @@ -335,12 +335,12 @@ static int diff_file_content_load_workdir_file( error = git_futils_filesize(&new_file_size, fd); - if (error < 0 || !new_file_size) + if (error < 0) goto cleanup; /* if file size doesn't match cached value, abort */ - if (fc->file->size && fc->file->size != new_file_size) - { + if (fc->file->size && fc->file->size != new_file_size) { + git_error_set(GIT_ERROR_FILESYSTEM, "file changed before we could read it"); error = -1; goto cleanup; } From 9aade20b4e1a1dd49ed2f85d832193d94f9d9900 Mon Sep 17 00:00:00 2001 From: Iliyas Jorio Date: Wed, 9 Feb 2022 19:04:52 +0100 Subject: [PATCH 0790/1616] diff_file: test workdir file becomes empty after obtaining a diff --- tests/diff/externalmodifications.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/diff/externalmodifications.c b/tests/diff/externalmodifications.c index d18e1feee96..09687c51e0e 100644 --- a/tests/diff/externalmodifications.c +++ b/tests/diff/externalmodifications.c @@ -51,6 +51,35 @@ void test_diff_externalmodifications__file_becomes_smaller(void) git_str_dispose(&path); } +void test_diff_externalmodifications__file_becomes_empty(void) +{ + git_index *index; + git_diff *diff; + git_patch* patch; + git_str path = GIT_STR_INIT; + + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "README")); + + /* Modify the file */ + cl_git_mkfile(path.ptr, "hello"); + + /* Get a diff */ + cl_git_pass(git_repository_index(&index, g_repo)); + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL)); + cl_assert_equal_i(1, git_diff_num_deltas(diff)); + cl_assert_equal_i(5, git_diff_get_delta(diff, 0)->new_file.size); + + /* Empty out the file after we've gotten the diff */ + cl_git_mkfile(path.ptr, ""); + + /* Attempt to get a patch */ + cl_git_fail(git_patch_from_diff(&patch, diff, 0)); + + git_index_free(index); + git_diff_free(diff); + git_str_dispose(&path); +} + void test_diff_externalmodifications__file_deleted(void) { git_index *index; From e1415dc3fabdcf88b7e83abc1208b3aa440e9f31 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 11 Feb 2022 11:02:00 -0500 Subject: [PATCH 0791/1616] diff_file: test empty workdir file grows after obtaining a diff This test was also provided by @jorio https://github.com/libgit2/libgit2/pull/6208#issuecomment-1034072050 --- tests/diff/externalmodifications.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/diff/externalmodifications.c b/tests/diff/externalmodifications.c index 09687c51e0e..df62c33165e 100644 --- a/tests/diff/externalmodifications.c +++ b/tests/diff/externalmodifications.c @@ -96,7 +96,7 @@ void test_diff_externalmodifications__file_deleted(void) /* Delete the file */ cl_git_rmfile(path.ptr); - + /* Attempt to get a patch */ cl_git_fail(git_patch_from_diff(&patch, diff, 0)); @@ -104,3 +104,30 @@ void test_diff_externalmodifications__file_deleted(void) git_diff_free(diff); git_str_dispose(&path); } + +void test_diff_externalmodifications__empty_file_becomes_non_empty(void) +{ + git_index *index; + git_diff *diff; + git_patch* patch; + git_str path = GIT_STR_INIT; + + cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "README")); + + /* Empty out the file */ + cl_git_mkfile(path.ptr, ""); + + /* Get a diff */ + cl_git_pass(git_repository_index(&index, g_repo)); + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL)); + cl_assert_equal_i(1, git_diff_num_deltas(diff)); + cl_assert_equal_i(0, git_diff_get_delta(diff, 0)->new_file.size); + + /* Simulate file modification after we've gotten the diff */ + cl_git_mkfile(path.ptr, "hello"); + cl_git_fail(git_patch_from_diff(&patch, diff, 0)); + + git_index_free(index); + git_diff_free(diff); + git_str_dispose(&path); +} From e86e81c5d97aa6879b0e7850f734c606cbbd2a90 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 12 Feb 2022 06:58:05 -0500 Subject: [PATCH 0792/1616] oid: make empty tree id global Move the empty tree ID into a global space so that it can be generally used. --- src/oid.c | 4 ++++ src/oid.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/oid.c b/src/oid.c index dbc5a5a9092..1a50d3d791d 100644 --- a/src/oid.c +++ b/src/oid.c @@ -13,6 +13,10 @@ #include #include +const git_oid git_oid__empty_tree_sha1 = + {{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, + 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }}; + static char to_hex[] = "0123456789abcdef"; static int oid_error_invalid(const char *msg) diff --git a/src/oid.h b/src/oid.h index 7a89d218755..5c9b68f02f6 100644 --- a/src/oid.h +++ b/src/oid.h @@ -11,6 +11,8 @@ #include "git2/oid.h" +extern const git_oid git_oid__empty_tree_sha1; + /** * Format a git_oid into a newly allocated c-string. * From 359240b674ad809c4986596bfe8a6837ee386e13 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 11 Feb 2022 17:56:05 -0500 Subject: [PATCH 0793/1616] diff: indicate when the file size is "valid" When we know the file size (because we're producing it from a working directory iterator, or an index with an up-to-date cache) then set a flag indicating as such. This removes the ambiguity about a 0 file size, which could indicate that a file exists and is 0 bytes, or that we haven't read it yet. --- include/git2/diff.h | 3 ++- src/diff_generate.c | 24 ++++++++++++++++++++++++ src/diff_generate.h | 4 +++- src/diff_tform.c | 3 ++- src/odb.c | 6 ++---- src/oid.c | 3 +++ src/oid.h | 1 + 7 files changed, 37 insertions(+), 7 deletions(-) diff --git a/include/git2/diff.h b/include/git2/diff.h index 9424ffd0678..3839f0033ce 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -207,7 +207,8 @@ typedef enum { GIT_DIFF_FLAG_BINARY = (1u << 0), /**< file(s) treated as binary data */ GIT_DIFF_FLAG_NOT_BINARY = (1u << 1), /**< file(s) treated as text data */ GIT_DIFF_FLAG_VALID_ID = (1u << 2), /**< `id` value is known correct */ - GIT_DIFF_FLAG_EXISTS = (1u << 3) /**< file exists at this side of the delta */ + GIT_DIFF_FLAG_EXISTS = (1u << 3), /**< file exists at this side of the delta */ + GIT_DIFF_FLAG_VALID_SIZE = (1u << 4) /**< file size value is known correct */ } git_diff_flag_t; /** diff --git a/src/diff_generate.c b/src/diff_generate.c index dca16d51a4e..cfaefba66c2 100644 --- a/src/diff_generate.c +++ b/src/diff_generate.c @@ -117,6 +117,26 @@ static bool diff_pathspec_match( matched_pathspec, NULL); } +static void diff_delta__flag_known_size(git_diff_file *file) +{ + /* + * If we don't know the ID, that can only come from the workdir + * iterator, which means we *do* know the file size. This is a + * leaky abstraction, but alas. Otherwise, we test against the + * empty blob id. + */ + if (file->size || + !(file->flags & GIT_DIFF_FLAG_VALID_ID) || + git_oid_equal(&file->id, &git_oid__empty_blob_sha1)) + file->flags |= GIT_DIFF_FLAG_VALID_SIZE; +} + +static void diff_delta__flag_known_sizes(git_diff_delta *delta) +{ + diff_delta__flag_known_size(&delta->old_file); + diff_delta__flag_known_size(&delta->new_file); +} + static int diff_delta__from_one( git_diff_generated *diff, git_delta_t status, @@ -182,6 +202,8 @@ static int diff_delta__from_one( if (has_old || !git_oid_is_zero(&delta->new_file.id)) delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID; + diff_delta__flag_known_sizes(delta); + return diff_insert_delta(diff, delta, matched_pathspec); } @@ -244,6 +266,8 @@ static int diff_delta__from_two( delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID; } + diff_delta__flag_known_sizes(delta); + return diff_insert_delta(diff, delta, matched_pathspec); } diff --git a/src/diff_generate.h b/src/diff_generate.h index f39bf6b2a38..b782f29c6e4 100644 --- a/src/diff_generate.h +++ b/src/diff_generate.h @@ -119,8 +119,10 @@ GIT_INLINE(int) git_diff_file__resolve_zero_size( git_odb_free(odb); - if (!error) + if (!error) { file->size = (git_object_size_t)len; + file->flags |= GIT_DIFF_FLAG_VALID_SIZE; + } return error; } diff --git a/src/diff_tform.c b/src/diff_tform.c index f9836d24529..913d649b0fb 100644 --- a/src/diff_tform.c +++ b/src/diff_tform.c @@ -460,7 +460,8 @@ static int similarity_init( info->blob = NULL; git_str_init(&info->data, 0); - if (info->file->size > 0 || info->src == GIT_ITERATOR_WORKDIR) + if ((info->file->flags & GIT_DIFF_FLAG_VALID_SIZE) || + info->src == GIT_ITERATOR_WORKDIR) return 0; return git_diff_file__resolve_zero_size( diff --git a/src/odb.c b/src/odb.c index 3abeae280e2..14eff53c7b8 100644 --- a/src/odb.c +++ b/src/odb.c @@ -16,6 +16,7 @@ #include "filter.h" #include "repository.h" #include "blob.h" +#include "oid.h" #include "git2/odb_backend.h" #include "git2/oid.h" @@ -58,10 +59,7 @@ static int error_null_oid(int error, const char *message); static git_object_t odb_hardcoded_type(const git_oid *id) { - static git_oid empty_tree = {{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, - 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }}; - - if (!git_oid_cmp(id, &empty_tree)) + if (!git_oid_cmp(id, &git_oid__empty_tree_sha1)) return GIT_OBJECT_TREE; return GIT_OBJECT_INVALID; diff --git a/src/oid.c b/src/oid.c index 1a50d3d791d..19061e899f7 100644 --- a/src/oid.c +++ b/src/oid.c @@ -13,6 +13,9 @@ #include #include +const git_oid git_oid__empty_blob_sha1 = + {{ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, + 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 }}; const git_oid git_oid__empty_tree_sha1 = {{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }}; diff --git a/src/oid.h b/src/oid.h index 5c9b68f02f6..5baec33e5cd 100644 --- a/src/oid.h +++ b/src/oid.h @@ -11,6 +11,7 @@ #include "git2/oid.h" +extern const git_oid git_oid__empty_blob_sha1; extern const git_oid git_oid__empty_tree_sha1; /** From d2ce981ffc49949f225d6a925b40dc72c7d4151e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 11 Feb 2022 17:54:34 -0500 Subject: [PATCH 0794/1616] diff: fail generation if a file changes size When we know that we know a file's size, and the file's size changes, fail. --- src/diff_file.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diff_file.c b/src/diff_file.c index 9804a943c80..c7e9fbeeed3 100644 --- a/src/diff_file.c +++ b/src/diff_file.c @@ -338,15 +338,15 @@ static int diff_file_content_load_workdir_file( if (error < 0) goto cleanup; - /* if file size doesn't match cached value, abort */ - if (fc->file->size && fc->file->size != new_file_size) { + if (!(fc->file->flags & GIT_DIFF_FLAG_VALID_SIZE)) { + fc->file->size = new_file_size; + fc->file->flags |= GIT_DIFF_FLAG_VALID_SIZE; + } else if (fc->file->size != new_file_size) { git_error_set(GIT_ERROR_FILESYSTEM, "file changed before we could read it"); error = -1; goto cleanup; } - fc->file->size = new_file_size; - if ((diff_opts->flags & GIT_DIFF_SHOW_BINARY) == 0 && diff_file_content_binary_by_size(fc)) goto cleanup; From 0fbf62cd2027e4ad6aed1d207099c17d2414073c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 12 Feb 2022 08:46:55 -0500 Subject: [PATCH 0795/1616] merge: make the internal flags public We made the flags that enable recursive merge internal, on the assumption that nobody would want them and they're hard to reason about. (Giving people an option that nobody wants is just extra noise.) However, it made it hard for _us_ to reason about. There's no good reason to keep it private, let's just make it public and push that cognitive load onto our poor users. But they should expect it, they're dealing with git, after all. --- include/git2/merge.h | 17 +++++++++++++---- src/merge.c | 6 +++--- src/merge.h | 10 ---------- src/merge_driver.c | 2 +- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/include/git2/merge.h b/include/git2/merge.h index a30833915d3..e90941a499f 100644 --- a/include/git2/merge.h +++ b/include/git2/merge.h @@ -93,8 +93,13 @@ typedef enum { */ GIT_MERGE_NO_RECURSIVE = (1 << 3), - /* This flag is reserved for internal library use */ - GIT_MERGE__INTERNAL_FLAG = (1 << 30) + /** + * Treat this merge as if it is to produce the virtual base + * of a recursive merge. This will ensure that there are + * no conflicts, any conflicting regions will keep conflict + * markers in the merge result. + */ + GIT_MERGE_VIRTUAL_BASE = (1 << 4) } git_merge_flag_t; /** @@ -167,8 +172,12 @@ typedef enum { /** Create zdiff3 ("zealous diff3")-style files */ GIT_MERGE_FILE_STYLE_ZDIFF3 = (1 << 8), - /* This flag is reserved for internal library use */ - GIT_MERGE_FILE__INTERNAL_FLAG = (1 << 30) + /** + * Do not produce file conflicts when common regions have + * changed; keep the conflict markers in the file and accept + * that as the merge result. + */ + GIT_MERGE_FILE_ACCEPT_CONFLICTS = (1 << 9) } git_merge_file_flag_t; #define GIT_MERGE_CONFLICT_MARKER_SIZE 7 diff --git a/src/merge.c b/src/merge.c index 5f3a37bbebd..641b32632b1 100644 --- a/src/merge.c +++ b/src/merge.c @@ -2116,11 +2116,11 @@ int git_merge__iterators( file_opts.flags = opts.file_flags; /* use the git-inspired labels when virtual base building */ - if (opts.flags & GIT_MERGE__VIRTUAL_BASE) { + if (opts.flags & GIT_MERGE_VIRTUAL_BASE) { file_opts.ancestor_label = "merged common ancestors"; file_opts.our_label = "Temporary merge branch 1"; file_opts.their_label = "Temporary merge branch 2"; - file_opts.flags |= GIT_MERGE_FILE__CONFLICTED; + file_opts.flags |= GIT_MERGE_FILE_ACCEPT_CONFLICTS; file_opts.marker_size = GIT_MERGE_CONFLICT_MARKER_SIZE + 2; } @@ -2280,7 +2280,7 @@ static int create_virtual_base( memcpy(&virtual_opts, opts, sizeof(git_merge_options)); virtual_opts.flags &= ~GIT_MERGE_FAIL_ON_CONFLICT; - virtual_opts.flags |= GIT_MERGE__VIRTUAL_BASE; + virtual_opts.flags |= GIT_MERGE_VIRTUAL_BASE; if ((merge_annotated_commits(&index, NULL, repo, one, two, recursion_level + 1, &virtual_opts)) < 0) diff --git a/src/merge.h b/src/merge.h index e033e876af3..23932905e80 100644 --- a/src/merge.h +++ b/src/merge.h @@ -25,16 +25,6 @@ #define GIT_MERGE_DEFAULT_RENAME_THRESHOLD 50 #define GIT_MERGE_DEFAULT_TARGET_LIMIT 1000 - -/** Internal merge flags. */ - -/** The merge is for a virtual base in a recursive merge. */ -#define GIT_MERGE__VIRTUAL_BASE (GIT_MERGE__INTERNAL_FLAG) - -/** Accept the conflict file, staging it as the merge result. */ -#define GIT_MERGE_FILE__CONFLICTED (GIT_MERGE_FILE__INTERNAL_FLAG) - - /** Types of changes when files are merged from branch to branch. */ typedef enum { /* No conflict - a change only occurs in one branch. */ diff --git a/src/merge_driver.c b/src/merge_driver.c index 66b257a4f15..19b35ac0ea6 100644 --- a/src/merge_driver.c +++ b/src/merge_driver.c @@ -93,7 +93,7 @@ int git_merge_driver__builtin_apply( goto done; if (!result.automergeable && - !(file_opts.flags & GIT_MERGE_FILE__CONFLICTED)) { + !(file_opts.flags & GIT_MERGE_FILE_ACCEPT_CONFLICTS)) { error = GIT_EMERGECONFLICT; goto done; } From e3aad1dea091b709b2e5c78d06cae3324fd44c13 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 12 Feb 2022 10:27:12 -0500 Subject: [PATCH 0796/1616] meta: add a release configuration file Let's let GitHub handle our release notes as much as possible: https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes --- .github/release.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/release.yml diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 00000000000..a9f7aa0f2e4 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,20 @@ +changelog: + categories: + - title: New features + labels: + - feature + - title: Bug fixes + labels: + - bug + - title: Code cleanups + labels: + - cleanup + - title: CI improvements + labels: + - build + - title: Documentation improvements + labels: + - documentation + - title: Other Changes + labels: + - '*' From 4c88b9d37502785c12224ae928464e87bdb3086b Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sat, 12 Feb 2022 21:29:43 -0500 Subject: [PATCH 0797/1616] release.yml: use sentence case for everything --- .github/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/release.yml b/.github/release.yml index a9f7aa0f2e4..c3c8da29041 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -15,6 +15,6 @@ changelog: - title: Documentation improvements labels: - documentation - - title: Other Changes + - title: Other changes labels: - '*' From 77ef1a6e14d97fb1527f4664264a62afc74e2cfb Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Sun, 13 Feb 2022 14:11:46 +0530 Subject: [PATCH 0798/1616] Update common.h --- examples/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/common.h b/examples/common.h index f86e92c3574..901c0414613 100644 --- a/examples/common.h +++ b/examples/common.h @@ -45,7 +45,7 @@ #endif #ifdef _MSC_VER -#define snprintf sprintf_s +#define snprintf _snprintf #define strcasecmp strcmpi #endif From 5c949d1faf1d02ea3c2e2b63214856ba3bc72b68 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 13 Feb 2022 10:06:15 -0500 Subject: [PATCH 0799/1616] v1.4: update version numbers --- CMakeLists.txt | 2 +- include/git2/version.h | 6 +++--- package.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 32bb4502bac..8c19d2ed3a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5.1) -project(libgit2 VERSION "1.3.0" LANGUAGES C) +project(libgit2 VERSION "1.4.0" LANGUAGES C) # Add find modules to the path set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") diff --git a/include/git2/version.h b/include/git2/version.h index 3503a62781a..9007ca92884 100644 --- a/include/git2/version.h +++ b/include/git2/version.h @@ -7,12 +7,12 @@ #ifndef INCLUDE_git_version_h__ #define INCLUDE_git_version_h__ -#define LIBGIT2_VERSION "1.3.0" +#define LIBGIT2_VERSION "1.4.0" #define LIBGIT2_VER_MAJOR 1 -#define LIBGIT2_VER_MINOR 3 +#define LIBGIT2_VER_MINOR 4 #define LIBGIT2_VER_REVISION 0 #define LIBGIT2_VER_PATCH 0 -#define LIBGIT2_SOVERSION "1.3" +#define LIBGIT2_SOVERSION "1.4" #endif diff --git a/package.json b/package.json index e2e672f9fe6..6952563b6f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "libgit2", - "version": "1.3.0", + "version": "1.4.0", "repo": "https://github.com/libgit2/libgit2", "description": " A cross-platform, linkable library implementation of Git that you can use in your application.", "install": "mkdir build && cd build && cmake .. && cmake --build ." From bafd044fd944f8835e0a9254729e0052e5858ba7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 13 Feb 2022 10:07:49 -0500 Subject: [PATCH 0800/1616] v1.4: update the changelog --- docs/changelog.md | 93 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 3723a080c45..cbfcf4cfecf 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,3 +1,96 @@ +v1.4 +---- + +This is release v1.4.0, "Fisematenten". This release includes several new features and bugfixes, improves compatibility with git, and begins preparation for SHA256 support in a future release. + +## What's Changed +### New features +* diff: update rename limit to 1000 to match git's behavior by @ethomson in https://github.com/libgit2/libgit2/pull/6092 +* odb: support checking for object existence without refresh by @joshtriplett in https://github.com/libgit2/libgit2/pull/6107 +* object: provide a low-level mechanism to validate whether a raw object is valid (`git_object_rawcontent_is_valid`) by @ethomson in https://github.com/libgit2/libgit2/pull/6128 +* blob: provide a function to identify binary content by @ethomson in https://github.com/libgit2/libgit2/pull/6142 +* status: add `rename_threshold` to `git_status_options`. by @arroz in https://github.com/libgit2/libgit2/pull/6158 +* remote: support `http.followRedirects` (`false` and `initial`) and follow initial redirects by default by @ethomson in https://github.com/libgit2/libgit2/pull/6175 +* remote: support scp style paths with ports (`[git@github.com:22]:libgit2/libgit2`) by @ethomson in https://github.com/libgit2/libgit2/pull/6167 +* win32: update git for windows configuration file location compatibility by @csware in https://github.com/libgit2/libgit2/pull/6151 and @ethomson in https://github.com/libgit2/libgit2/pull/6180 +* refs: speed up packed reference lookups when packed refs are sorted by @ccstolley in https://github.com/libgit2/libgit2/pull/6138 +* merge: support zdiff3 conflict styles by @ethomson in https://github.com/libgit2/libgit2/pull/6195 +* remote: support fetching by object id (using "+oid:ref" refspec syntax) by @ethomson in https://github.com/libgit2/libgit2/pull/6203 +* merge: callers can specify virtual-base building behavior and to optionally accept conflict markers as a resolution by @boretrk in https://github.com/libgit2/libgit2/pull/6204 + +### Bug fixes +* Fix a gcc 11 warning in src/threadstate.c by @lhchavez in https://github.com/libgit2/libgit2/pull/6115 +* Fix a gcc 11 warning in src/thread.h by @lhchavez in https://github.com/libgit2/libgit2/pull/6116 +* cmake: re-enable WinHTTP by @ethomson in https://github.com/libgit2/libgit2/pull/6120 +* Fix repo init when template dir is non-existent by @ammgws in https://github.com/libgit2/libgit2/pull/6106 +* cmake: use project-specific root variable instead of CMAKE_SOURCE_DIR by @Qix- in https://github.com/libgit2/libgit2/pull/6146 +* Better revparse compatibility for at time notation by @yoichi in https://github.com/libgit2/libgit2/pull/6095 +* remotes: fix insteadOf/pushInsteadOf handling by @mkhl in https://github.com/libgit2/libgit2/pull/6101 +* git_commit_summary: ignore lines with spaces by @stforek in https://github.com/libgit2/libgit2/pull/6125 +* Config parsing by @csware in https://github.com/libgit2/libgit2/pull/6124 +* config: handle empty conditional in includeIf by @ethomson in https://github.com/libgit2/libgit2/pull/6165 +* #6154 git_status_list_new case insensitive fix by @arroz in https://github.com/libgit2/libgit2/pull/6159 +* futils_mktmp: don't use umask by @boretrk in https://github.com/libgit2/libgit2/pull/6178 +* revparse: support bare '@' by @ethomson in https://github.com/libgit2/libgit2/pull/6196 +* odb: check for write failures by @ethomson in https://github.com/libgit2/libgit2/pull/6206 +* push: Prepare pack before sending pack header. by @ccstolley in https://github.com/libgit2/libgit2/pull/6205 +* mktmp: improve our temp file creation by @ethomson in https://github.com/libgit2/libgit2/pull/6207 +* diff_file: fix crash if size of diffed file changes in workdir by @jorio in https://github.com/libgit2/libgit2/pull/6208 +* merge: comment conflicts lines in MERGE_MSG by @ethomson in https://github.com/libgit2/libgit2/pull/6197 +* Fix crashes in example programs on Windows (sprintf_s not compatible with snprintf) by @apnadkarni in https://github.com/libgit2/libgit2/pull/6212 + +### Code cleanups +* Introduce `git_remote_connect_options` by @ethomson in https://github.com/libgit2/libgit2/pull/6161 +* hash: separate hashes and git_oid by @ethomson in https://github.com/libgit2/libgit2/pull/6082 +* `git_buf`: now a public-only API (`git_str` is our internal API) by @ethomson in https://github.com/libgit2/libgit2/pull/6078 +* cmake: cleanups and consistency by @ethomson in https://github.com/libgit2/libgit2/pull/6084 +* path: refactor utility path functions by @ethomson in https://github.com/libgit2/libgit2/pull/6104 +* str: git_str_free is never a function by @ethomson in https://github.com/libgit2/libgit2/pull/6111 +* cmake refactorings by @ethomson in https://github.com/libgit2/libgit2/pull/6112 +* Add missing-declarations warning globally by @ethomson in https://github.com/libgit2/libgit2/pull/6113 +* cmake: further refactorings by @ethomson in https://github.com/libgit2/libgit2/pull/6114 +* tag: set validity to 0 by default by @ethomson in https://github.com/libgit2/libgit2/pull/6119 +* util: minor cleanup and refactoring to the date class by @ethomson in https://github.com/libgit2/libgit2/pull/6121 +* Minor code cleanups by @ethomson in https://github.com/libgit2/libgit2/pull/6122 +* Fix a long long that crept past by @NattyNarwhal in https://github.com/libgit2/libgit2/pull/6094 +* remote: refactor insteadof application by @ethomson in https://github.com/libgit2/libgit2/pull/6147 +* ntmlclient: fix linking with libressl by @boretrk in https://github.com/libgit2/libgit2/pull/6157 +* c99: change single bit flags to unsigned by @boretrk in https://github.com/libgit2/libgit2/pull/6179 +* Fix typos by @rex4539 in https://github.com/libgit2/libgit2/pull/6164 +* diff_driver: split global_drivers array into separate elements by @boretrk in https://github.com/libgit2/libgit2/pull/6184 +* cmake: disable some gnu extensions by @boretrk in https://github.com/libgit2/libgit2/pull/6185 +* Disabling setting `CMAKE_FIND_LIBRARY_SUFFIXES` on Apple platforms. by @arroz in https://github.com/libgit2/libgit2/pull/6153 +* C90: add inline macro to xdiff and mbedtls by @boretrk in https://github.com/libgit2/libgit2/pull/6200 +* SHA256: early preparation by @ethomson in https://github.com/libgit2/libgit2/pull/6192 + +### CI improvements +* tests: rename test runner to `libgit2_tests`, build option to `BUILD_TESTS`. by @ethomson in https://github.com/libgit2/libgit2/pull/6083 +* ci: only update docs on push by @ethomson in https://github.com/libgit2/libgit2/pull/6108 +* Pedantic header test by @boretrk in https://github.com/libgit2/libgit2/pull/6086 +* ci: build with ssh on nightly by @ethomson in https://github.com/libgit2/libgit2/pull/6148 +* ci: improve the name in CI runs by @ethomson in https://github.com/libgit2/libgit2/pull/6198 + +### Documentation improvements +* Document that `git_odb` is thread-safe by @joshtriplett in https://github.com/libgit2/libgit2/pull/6109 +* Improve documentation by @punkymaniac in https://github.com/libgit2/libgit2/pull/6168 + +### Other changes +* libgit2_clar is now libgit2_tests by @mkhl in https://github.com/libgit2/libgit2/pull/6100 +* Remove PSGit from Language Bindings section of README by @cestrand in https://github.com/libgit2/libgit2/pull/6150 +* COPYING: remove regex copyright, add PCRE copyright by @ethomson in https://github.com/libgit2/libgit2/pull/6187 +* meta: add a release configuration file by @ethomson in https://github.com/libgit2/libgit2/pull/6211 + +## New Contributors +* @mkhl made their first contribution in https://github.com/libgit2/libgit2/pull/6100 +* @ammgws made their first contribution in https://github.com/libgit2/libgit2/pull/6106 +* @yoichi made their first contribution in https://github.com/libgit2/libgit2/pull/6095 +* @stforek made their first contribution in https://github.com/libgit2/libgit2/pull/6125 +* @cestrand made their first contribution in https://github.com/libgit2/libgit2/pull/6150 +* @rex4539 made their first contribution in https://github.com/libgit2/libgit2/pull/6164 +* @jorio made their first contribution in https://github.com/libgit2/libgit2/pull/6208 + +**Full Changelog**: https://github.com/libgit2/libgit2/compare/v1.3.0...v1.4.0 + v1.3 ---- From 9c9405df21051791d0a9092d6f363dfce3fe4544 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 13 Feb 2022 11:19:39 -0500 Subject: [PATCH 0801/1616] meta: show build status for v1.3 and v1.4 branches --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1074cd9a8da..c73b50701ad 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ libgit2 - the Git linkable library | Build Status | | | ------------ | - | | **main** branch CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush) | -| **v1.2 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.2&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.2) | -| **v1.1 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.1&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.1) | +| **v1.4 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.4&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.4) | +| **v1.3 branch** CI builds | [![CI Build](https://github.com/libgit2/libgit2/workflows/CI%20Build/badge.svg?branch=maint%2Fv1.3&event=push)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22CI+Build%22+event%3Apush+branch%3Amaint%2Fv1.3) | | **Nightly** builds | [![Nightly Build](https://github.com/libgit2/libgit2/workflows/Nightly%20Build/badge.svg)](https://github.com/libgit2/libgit2/actions?query=workflow%3A%22Nightly+Build%22) [![Coverity Scan Status](https://scan.coverity.com/projects/639/badge.svg)](https://scan.coverity.com/projects/639) | `libgit2` is a portable, pure C implementation of the Git core methods From 8bc9eda779b2e2602fc74944aba5d39198e0642f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Sun, 13 Feb 2022 21:23:56 +0100 Subject: [PATCH 0802/1616] cmake: Fix package name for system http-parser Fix building against system http-parser library by fixing the find_package() argument. It seems to have been accidentally changed from HTTPParser to HTTP_Parser in de178d36f, effectively making the build against system library fail to find it: ``` CMake Warning at cmake/SelectHTTPParser.cmake:3 (find_package): By not providing "FindHTTP_Parser.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "HTTP_Parser", but CMake did not find one. Could not find a package configuration file provided by "HTTP_Parser" with any of the following names: HTTP_ParserConfig.cmake http_parser-config.cmake Add the installation prefix of "HTTP_Parser" to CMAKE_PREFIX_PATH or set "HTTP_Parser_DIR" to a directory containing one of the above files. If "HTTP_Parser" provides a separate development package or SDK, be sure it has been installed. Call Stack (most recent call first): src/CMakeLists.txt:97 (include) CMake Error at cmake/SelectHTTPParser.cmake:11 (message): http-parser support was requested but not found Call Stack (most recent call first): src/CMakeLists.txt:97 (include) ``` --- cmake/SelectHTTPParser.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/SelectHTTPParser.cmake b/cmake/SelectHTTPParser.cmake index bb6ef551726..955aea3308c 100644 --- a/cmake/SelectHTTPParser.cmake +++ b/cmake/SelectHTTPParser.cmake @@ -1,6 +1,6 @@ # Optional external dependency: http-parser if(USE_HTTP_PARSER STREQUAL "system") - find_package(HTTP_Parser) + find_package(HTTPParser) if(HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2) list(APPEND LIBGIT2_SYSTEM_INCLUDES ${HTTP_PARSER_INCLUDE_DIRS}) From aab7c0babc3f0ad7c548847237e85f00ef82fe6b Mon Sep 17 00:00:00 2001 From: "Ashok P. Nadkarni" Date: Mon, 14 Feb 2022 13:57:07 +0530 Subject: [PATCH 0803/1616] Free parent and ref in lg2_commit before returning. --- examples/commit.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/commit.c b/examples/commit.c index cd9782de107..aedc1af7e1c 100644 --- a/examples/commit.c +++ b/examples/commit.c @@ -26,7 +26,7 @@ * This does have: * * - Example of performing a git commit with a comment - * + * */ int lg2_commit(git_repository *repo, int argc, char **argv) { @@ -36,10 +36,10 @@ int lg2_commit(git_repository *repo, int argc, char **argv) git_oid commit_oid,tree_oid; git_tree *tree; - git_index *index; + git_index *index; git_object *parent = NULL; git_reference *ref = NULL; - git_signature *signature; + git_signature *signature; /* Validate args */ if (argc < 3 || strcmp(opt, "-m") != 0) { @@ -62,9 +62,9 @@ int lg2_commit(git_repository *repo, int argc, char **argv) check_lg2(git_index_write(index), "Could not write index", NULL);; check_lg2(git_tree_lookup(&tree, repo, &tree_oid), "Error looking up tree", NULL); - + check_lg2(git_signature_default(&signature, repo), "Error creating signature", NULL); - + check_lg2(git_commit_create_v( &commit_oid, repo, @@ -78,7 +78,9 @@ int lg2_commit(git_repository *repo, int argc, char **argv) git_index_free(index); git_signature_free(signature); - git_tree_free(tree); + git_tree_free(tree); + git_object_free(parent); + git_reference_free(ref); return error; } From ae74d5ac41aa6158442f4643f285ab8b71a7750d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 14 Feb 2022 07:01:43 -0500 Subject: [PATCH 0804/1616] meta: update version number to v1.5.0-alpha Update the version number in main to v1.5.0-alpha. This helps people understand that the main builds are not part of the v1.4.0 release train. We use "alpha" to indicate builds out of main (or nightlies) as semver v2 requires the prerelease component is compared lexicographically. Thus, our "beta" and "rc" releases should follow. --- CMakeLists.txt | 2 +- include/git2/version.h | 13 +++++++------ package.json | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c19d2ed3a3..eb137ecdd62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5.1) -project(libgit2 VERSION "1.4.0" LANGUAGES C) +project(libgit2 VERSION "1.5.0" LANGUAGES C) # Add find modules to the path set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") diff --git a/include/git2/version.h b/include/git2/version.h index 9007ca92884..ad36eb5697a 100644 --- a/include/git2/version.h +++ b/include/git2/version.h @@ -7,12 +7,13 @@ #ifndef INCLUDE_git_version_h__ #define INCLUDE_git_version_h__ -#define LIBGIT2_VERSION "1.4.0" -#define LIBGIT2_VER_MAJOR 1 -#define LIBGIT2_VER_MINOR 4 -#define LIBGIT2_VER_REVISION 0 -#define LIBGIT2_VER_PATCH 0 +#define LIBGIT2_VERSION "1.5.0-alpha" +#define LIBGIT2_VER_MAJOR 1 +#define LIBGIT2_VER_MINOR 5 +#define LIBGIT2_VER_REVISION 0 +#define LIBGIT2_VER_PATCH 0 +#define LIBGIT2_VER_PRERELEASE "alpha" -#define LIBGIT2_SOVERSION "1.4" +#define LIBGIT2_SOVERSION "1.5" #endif diff --git a/package.json b/package.json index 6952563b6f4..139fc3891f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "libgit2", - "version": "1.4.0", + "version": "1.5.0-alpha", "repo": "https://github.com/libgit2/libgit2", "description": " A cross-platform, linkable library implementation of Git that you can use in your application.", "install": "mkdir build && cd build && cmake .. && cmake --build ." From 056fe4be05cd8623fb210a1be4aa0529ce08ed66 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 14 Feb 2022 07:12:36 -0500 Subject: [PATCH 0805/1616] meta: provide an accessor for prerelease info --- include/git2/common.h | 11 +++++++++++ src/libgit2.c | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/include/git2/common.h b/include/git2/common.h index c421d3cc1e6..52000e8eb2a 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -121,6 +121,17 @@ GIT_BEGIN_DECL */ GIT_EXTERN(int) git_libgit2_version(int *major, int *minor, int *rev); +/** + * Return the prerelease state of the libgit2 library currently being + * used. For nightly builds during active development, this will be + * "alpha". Releases may have a "beta" or release candidate ("rc1", + * "rc2", etc) prerelease. For a final release, this function returns + * NULL. + * + * @return the name of the prerelease state or NULL + */ +GIT_EXTERN(const char *) git_libgit2_prerelease(void); + /** * Combinations of these values describe the features with which libgit2 * was compiled diff --git a/src/libgit2.c b/src/libgit2.c index b17485d7f22..efad3bf6d7c 100644 --- a/src/libgit2.c +++ b/src/libgit2.c @@ -107,6 +107,11 @@ int git_libgit2_version(int *major, int *minor, int *rev) return 0; } +const char *git_libgit2_prerelease(void) +{ + return LIBGIT2_VER_PRERELEASE; +} + int git_libgit2_features(void) { return 0 From b152b0300e7f9c0d8e4e34b6970311b96a85862c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 14 Feb 2022 10:27:48 -0500 Subject: [PATCH 0806/1616] meta: document version information for libgit2 --- include/git2/version.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/git2/version.h b/include/git2/version.h index ad36eb5697a..84af817e211 100644 --- a/include/git2/version.h +++ b/include/git2/version.h @@ -7,13 +7,33 @@ #ifndef INCLUDE_git_version_h__ #define INCLUDE_git_version_h__ +/** + * The version string for libgit2. This string follows semantic + * versioning (v2) guidelines. + */ #define LIBGIT2_VERSION "1.5.0-alpha" + +/** The major version number for this version of libgit2. */ #define LIBGIT2_VER_MAJOR 1 + +/** The minor version number for this version of libgit2. */ #define LIBGIT2_VER_MINOR 5 + +/** The revision ("teeny") version number for this version of libgit2. */ #define LIBGIT2_VER_REVISION 0 + +/** The Windows DLL patch number for this version of libgit2. */ #define LIBGIT2_VER_PATCH 0 + +/** + * The prerelease string for this version of libgit2. For development + * (nightly) builds, this will be "alpha". For prereleases, this will be + * a prerelease name like "beta" or "rc1". For final releases, this will + * be `NULL`. + */ #define LIBGIT2_VER_PRERELEASE "alpha" +/** The library ABI soversion for this version of libgit2. */ #define LIBGIT2_SOVERSION "1.5" #endif From b722c45d1635c1966ed117020f5650458f148e67 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 17 Feb 2022 13:55:34 -0500 Subject: [PATCH 0807/1616] xdiff: use xdl_free not free We've added a lovely abstraction layer in xdiff so that it can call our allocation functions. But it also needs to call our free functions. We missed some `free` calls in `xmerge.c`. Update them to use `xdl_free`. Without this, we will pass a pointer allocated with a custom allocator to the system free function. :bomb: --- src/xdiff/xdiff.h | 4 ++-- src/xdiff/xmerge.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xdiff/xdiff.h b/src/xdiff/xdiff.h index a7bf17cd6b7..fb47f63fbf7 100644 --- a/src/xdiff/xdiff.h +++ b/src/xdiff/xdiff.h @@ -23,12 +23,12 @@ #if !defined(XDIFF_H) #define XDIFF_H -#include "git-xdiff.h" - #ifdef __cplusplus extern "C" { #endif /* #ifdef __cplusplus */ +#include "git-xdiff.h" + /* xpparm_t.flags */ #define XDF_NEED_MINIMAL (1 << 0) diff --git a/src/xdiff/xmerge.c b/src/xdiff/xmerge.c index fff0b594f9a..433e2d74157 100644 --- a/src/xdiff/xmerge.c +++ b/src/xdiff/xmerge.c @@ -88,7 +88,7 @@ static int xdl_cleanup_merge(xdmerge_t *c) if (c->mode == 0) count++; next_c = c->next; - free(c); + xdl_free(c); } return count; } @@ -456,7 +456,7 @@ static void xdl_merge_two_conflicts(xdmerge_t *m) m->chg1 = next_m->i1 + next_m->chg1 - m->i1; m->chg2 = next_m->i2 + next_m->chg2 - m->i2; m->next = next_m->next; - free(next_m); + xdl_free(next_m); } /* From 15860aa0b29907e1a795ca2f91a2f66de63fcf59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 21 Feb 2022 10:03:06 +0100 Subject: [PATCH 0808/1616] remote: do store the update_tips callback error value We use `git_error_set_after_callback_function` to determine whether `update_tips` returned an error but do not store its return value making us think it always returns 0. Fix it by adding the common patter of storing it inside the `if` when calling it. --- src/remote.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/remote.c b/src/remote.c index 038afc6f5bf..f6421b9ebf1 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1852,7 +1852,7 @@ static int update_one_tip( } if (callbacks && callbacks->update_tips != NULL && - callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload) < 0) + (error = callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload)) < 0) git_error_set_after_callback_function(error, "git_remote_fetch"); done: From e35b5e44aa65d0289347ea199b7954a2a556ad9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 21 Feb 2022 10:34:13 +0100 Subject: [PATCH 0809/1616] test: add test for the behaviour of update_tips on error --- tests/network/fetchlocal.c | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/network/fetchlocal.c b/tests/network/fetchlocal.c index c54f454722f..dc37c38ab6b 100644 --- a/tests/network/fetchlocal.c +++ b/tests/network/fetchlocal.c @@ -509,3 +509,44 @@ void test_network_fetchlocal__prune_load_fetch_prune_config(void) git_remote_free(origin); git_repository_free(repo); } + +static int update_tips_error(const char *ref, const git_oid *old, const git_oid *new, void *data) +{ + int *callcount = (int *) data; + + GIT_UNUSED(ref); + GIT_UNUSED(old); + GIT_UNUSED(new); + + (*callcount)++; + + return -1; +} + +void test_network_fetchlocal__update_tips_error_is_propagated(void) +{ + git_repository *repo; + git_reference_iterator *iterator; + git_reference *ref; + git_remote *remote; + git_fetch_options options = GIT_FETCH_OPTIONS_INIT; + int callcount = 0; + + cl_git_pass(git_repository_init(&repo, "foo.git", true)); + cl_set_cleanup(cleanup_local_repo, "foo.git"); + + cl_git_pass(git_remote_create_with_fetchspec(&remote, repo, "origin", cl_git_fixture_url("testrepo.git"), "+refs/heads/*:refs/remotes/update-tips/*")); + + options.callbacks.update_tips = update_tips_error; + options.callbacks.payload = &callcount; + + cl_git_fail(git_remote_fetch(remote, NULL, &options, NULL)); + cl_assert_equal_i(1, callcount); + + cl_git_pass(git_reference_iterator_glob_new(&iterator, repo, "refs/remotes/update-tips/**/")); + cl_assert_equal_i(GIT_ITEROVER, git_reference_next(&ref, iterator)); + + git_reference_iterator_free(iterator); + git_remote_free(remote); + git_repository_free(repo); +} From f45121edd174bd2f87881f3b6fdad4232741a9ad Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 21 Feb 2022 16:13:52 +0000 Subject: [PATCH 0810/1616] win32: `find_system_dirs` does not return `GIT_ENOTFOUND` Allow for no Git for Windows installation. When there is no GfW found in the path or registry, `git_win32__find_system_dirs` would return a `GIT_ENOTFOUND`. Callers were not expecting this. Since this is no error, we simply return `0` so that callers can move on with their lives. --- src/win32/findfile.c | 2 +- tests/win32/systemdir.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/win32/findfile.c b/src/win32/findfile.c index 516391d7fdd..725a90167f2 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -222,7 +222,7 @@ int git_win32__find_system_dirs(git_str *out, const char *subdir) has_regdir = (find_sysdir_in_registry(regdir) == 0); if (!has_pathdir && !has_regdir) - return GIT_ENOTFOUND; + return 0; /* * Usually the git in the path is the same git in the registry, diff --git a/tests/win32/systemdir.c b/tests/win32/systemdir.c index 46fa06a50e1..52c1784a1b7 100644 --- a/tests/win32/systemdir.c +++ b/tests/win32/systemdir.c @@ -326,3 +326,13 @@ void test_win32_systemdir__prefers_path_to_registry(void) git_config_free(cfg); #endif } + +void test_win32_systemdir__no_git_installed(void) +{ +#ifdef GIT_WIN32 + git_str out = GIT_STR_INIT; + + cl_git_pass(git_win32__find_system_dirs(&out, "etc")); + cl_assert_equal_s(out.ptr, ""); +#endif +} From c716b9f295c0a46073f134a23735dd7b811745fe Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 21 Feb 2022 10:16:05 -0500 Subject: [PATCH 0811/1616] odb: initialize `object` before use Newer gcc is complaining about `object` being potentially not initialized; initialize it. --- src/odb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odb.c b/src/odb.c index 14eff53c7b8..6d714ba547d 100644 --- a/src/odb.c +++ b/src/odb.c @@ -1067,7 +1067,7 @@ int git_odb_expand_ids( int git_odb_read_header(size_t *len_p, git_object_t *type_p, git_odb *db, const git_oid *id) { int error; - git_odb_object *object; + git_odb_object *object = NULL; error = git_odb__read_header_or_object(&object, len_p, type_p, db, id); From 49e180c862dc7c6d1f62a53bf8756e25b3417968 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 15 Feb 2022 22:55:48 -0500 Subject: [PATCH 0812/1616] errors: expose `git_error_set` The `git_error_set` function is useful for callers who implement backends and advanced callbacks. Expose it. --- include/git2/errors.h | 18 ++++++++++++++++-- src/errors.h | 3 +-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/git2/errors.h b/include/git2/errors.h index 5a5f8c5a249..62f363507b8 100644 --- a/include/git2/errors.h +++ b/include/git2/errors.h @@ -130,7 +130,8 @@ GIT_EXTERN(const git_error *) git_error_last(void); GIT_EXTERN(void) git_error_clear(void); /** - * Set the error message string for this thread. + * Set the error message string for this thread, using `printf`-style + * formatting. * * This function is public so that custom ODB backends and the like can * relay an error message through libgit2. Most regular users of libgit2 @@ -143,7 +144,20 @@ GIT_EXTERN(void) git_error_clear(void); * * @param error_class One of the `git_error_t` enum above describing the * general subsystem that is responsible for the error. - * @param string The formatted error message to keep + * @param fmt The `printf`-style format string; subsequent arguments must + * be the arguments for the format string. + */ +GIT_EXTERN(void) git_error_set(int error_class, const char *fmt, ...) + GIT_FORMAT_PRINTF(2, 3); + +/** + * Set the error message string for this thread. This function is like + * `git_error_set` but takes a static string instead of a `printf`-style + * format. + * + * @param error_class One of the `git_error_t` enum above describing the + * general subsystem that is responsible for the error. + * @param string The error message to keep * @return 0 on success or -1 on failure */ GIT_EXTERN(int) git_error_set_str(int error_class, const char *string); diff --git a/src/errors.h b/src/errors.h index a2f60f752d8..772c7bad18b 100644 --- a/src/errors.h +++ b/src/errors.h @@ -11,9 +11,8 @@ #include "common.h" /* - * Set the error message for this thread, formatting as needed. + * `vprintf`-style formatting for the error message for this thread. */ -void git_error_set(int error_class, const char *fmt, ...) GIT_FORMAT_PRINTF(2, 3); void git_error_vset(int error_class, const char *fmt, va_list ap); /** From ef4ab2988320005cbcb3db920e6b41f10b3c60cf Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 14 Nov 2021 08:47:40 -0500 Subject: [PATCH 0813/1616] refactor: `src` is now `src/libgit2` --- src/CMakeLists.txt | 303 +---------------- src/libgit2/CMakeLists.txt | 305 ++++++++++++++++++ src/{ => libgit2}/alloc.c | 0 src/{ => libgit2}/alloc.h | 0 src/{ => libgit2}/allocators/failalloc.c | 0 src/{ => libgit2}/allocators/failalloc.h | 0 src/{ => libgit2}/allocators/stdalloc.c | 0 src/{ => libgit2}/allocators/stdalloc.h | 0 .../allocators/win32_leakcheck.c | 0 .../allocators/win32_leakcheck.h | 0 src/{ => libgit2}/annotated_commit.c | 0 src/{ => libgit2}/annotated_commit.h | 0 src/{ => libgit2}/apply.c | 0 src/{ => libgit2}/apply.h | 0 src/{ => libgit2}/array.h | 0 src/{ => libgit2}/assert_safe.h | 0 src/{ => libgit2}/attr.c | 0 src/{ => libgit2}/attr.h | 0 src/{ => libgit2}/attr_file.c | 0 src/{ => libgit2}/attr_file.h | 0 src/{ => libgit2}/attrcache.c | 0 src/{ => libgit2}/attrcache.h | 0 src/{ => libgit2}/bitvec.h | 0 src/{ => libgit2}/blame.c | 0 src/{ => libgit2}/blame.h | 0 src/{ => libgit2}/blame_git.c | 0 src/{ => libgit2}/blame_git.h | 0 src/{ => libgit2}/blob.c | 0 src/{ => libgit2}/blob.h | 0 src/{ => libgit2}/branch.c | 0 src/{ => libgit2}/branch.h | 0 src/{ => libgit2}/buf.c | 0 src/{ => libgit2}/buf.h | 0 src/{ => libgit2}/cache.c | 0 src/{ => libgit2}/cache.h | 0 src/{ => libgit2}/cc-compat.h | 0 src/{ => libgit2}/checkout.c | 0 src/{ => libgit2}/checkout.h | 0 src/{ => libgit2}/cherrypick.c | 0 src/{ => libgit2}/clone.c | 0 src/{ => libgit2}/clone.h | 0 src/{ => libgit2}/commit.c | 0 src/{ => libgit2}/commit.h | 0 src/{ => libgit2}/commit_graph.c | 0 src/{ => libgit2}/commit_graph.h | 0 src/{ => libgit2}/commit_list.c | 0 src/{ => libgit2}/commit_list.h | 0 src/{ => libgit2}/common.h | 0 src/{ => libgit2}/config.c | 0 src/{ => libgit2}/config.h | 0 src/{ => libgit2}/config_backend.h | 0 src/{ => libgit2}/config_cache.c | 0 src/{ => libgit2}/config_entries.c | 0 src/{ => libgit2}/config_entries.h | 0 src/{ => libgit2}/config_file.c | 0 src/{ => libgit2}/config_mem.c | 0 src/{ => libgit2}/config_parse.c | 0 src/{ => libgit2}/config_parse.h | 0 src/{ => libgit2}/config_snapshot.c | 0 src/{ => libgit2}/crlf.c | 0 src/{ => libgit2}/date.c | 0 src/{ => libgit2}/date.h | 0 src/{ => libgit2}/delta.c | 0 src/{ => libgit2}/delta.h | 0 src/{ => libgit2}/describe.c | 0 src/{ => libgit2}/diff.c | 0 src/{ => libgit2}/diff.h | 0 src/{ => libgit2}/diff_driver.c | 0 src/{ => libgit2}/diff_driver.h | 0 src/{ => libgit2}/diff_file.c | 0 src/{ => libgit2}/diff_file.h | 0 src/{ => libgit2}/diff_generate.c | 0 src/{ => libgit2}/diff_generate.h | 0 src/{ => libgit2}/diff_parse.c | 0 src/{ => libgit2}/diff_parse.h | 0 src/{ => libgit2}/diff_print.c | 0 src/{ => libgit2}/diff_stats.c | 0 src/{ => libgit2}/diff_stats.h | 0 src/{ => libgit2}/diff_tform.c | 0 src/{ => libgit2}/diff_tform.h | 0 src/{ => libgit2}/diff_xdiff.c | 0 src/{ => libgit2}/diff_xdiff.h | 0 src/{ => libgit2}/email.c | 0 src/{ => libgit2}/email.h | 0 src/{ => libgit2}/errors.c | 0 src/{ => libgit2}/errors.h | 0 src/{ => libgit2}/features.h.in | 0 src/{ => libgit2}/fetch.c | 0 src/{ => libgit2}/fetch.h | 0 src/{ => libgit2}/fetchhead.c | 0 src/{ => libgit2}/fetchhead.h | 0 src/{ => libgit2}/filebuf.c | 0 src/{ => libgit2}/filebuf.h | 0 src/{ => libgit2}/filter.c | 0 src/{ => libgit2}/filter.h | 0 src/{ => libgit2}/fs_path.c | 0 src/{ => libgit2}/fs_path.h | 0 src/{ => libgit2}/futils.c | 0 src/{ => libgit2}/futils.h | 0 src/{ => libgit2}/graph.c | 0 src/{ => libgit2}/hash.c | 0 src/{ => libgit2}/hash.h | 0 src/{ => libgit2}/hash/sha1.h | 0 src/{ => libgit2}/hash/sha1/collisiondetect.c | 0 src/{ => libgit2}/hash/sha1/collisiondetect.h | 0 src/{ => libgit2}/hash/sha1/common_crypto.c | 0 src/{ => libgit2}/hash/sha1/common_crypto.h | 0 src/{ => libgit2}/hash/sha1/generic.c | 0 src/{ => libgit2}/hash/sha1/generic.h | 0 src/{ => libgit2}/hash/sha1/mbedtls.c | 0 src/{ => libgit2}/hash/sha1/mbedtls.h | 0 src/{ => libgit2}/hash/sha1/openssl.c | 0 src/{ => libgit2}/hash/sha1/openssl.h | 0 src/{ => libgit2}/hash/sha1/sha1dc/sha1.c | 0 src/{ => libgit2}/hash/sha1/sha1dc/sha1.h | 0 .../hash/sha1/sha1dc/ubc_check.c | 0 .../hash/sha1/sha1dc/ubc_check.h | 0 src/{ => libgit2}/hash/sha1/win32.c | 0 src/{ => libgit2}/hash/sha1/win32.h | 0 src/{ => libgit2}/hashsig.c | 0 src/{ => libgit2}/ident.c | 0 src/{ => libgit2}/idxmap.c | 0 src/{ => libgit2}/idxmap.h | 0 src/{ => libgit2}/ignore.c | 0 src/{ => libgit2}/ignore.h | 0 src/{ => libgit2}/index.c | 0 src/{ => libgit2}/index.h | 0 src/{ => libgit2}/indexer.c | 0 src/{ => libgit2}/indexer.h | 0 src/{ => libgit2}/integer.h | 0 src/{ => libgit2}/iterator.c | 0 src/{ => libgit2}/iterator.h | 0 src/{ => libgit2}/khash.h | 0 src/{ => libgit2}/libgit2.c | 0 src/{ => libgit2}/libgit2.h | 0 src/{ => libgit2}/mailmap.c | 0 src/{ => libgit2}/mailmap.h | 0 src/{ => libgit2}/map.h | 0 src/{ => libgit2}/merge.c | 0 src/{ => libgit2}/merge.h | 0 src/{ => libgit2}/merge_driver.c | 0 src/{ => libgit2}/merge_driver.h | 0 src/{ => libgit2}/merge_file.c | 0 src/{ => libgit2}/message.c | 0 src/{ => libgit2}/midx.c | 0 src/{ => libgit2}/midx.h | 0 src/{ => libgit2}/mwindow.c | 0 src/{ => libgit2}/mwindow.h | 0 src/{ => libgit2}/net.c | 0 src/{ => libgit2}/net.h | 0 src/{ => libgit2}/netops.c | 0 src/{ => libgit2}/netops.h | 0 src/{ => libgit2}/notes.c | 0 src/{ => libgit2}/notes.h | 0 src/{ => libgit2}/object.c | 0 src/{ => libgit2}/object.h | 0 src/{ => libgit2}/object_api.c | 0 src/{ => libgit2}/odb.c | 0 src/{ => libgit2}/odb.h | 0 src/{ => libgit2}/odb_loose.c | 0 src/{ => libgit2}/odb_mempack.c | 0 src/{ => libgit2}/odb_pack.c | 0 src/{ => libgit2}/offmap.c | 0 src/{ => libgit2}/offmap.h | 0 src/{ => libgit2}/oid.c | 0 src/{ => libgit2}/oid.h | 0 src/{ => libgit2}/oidarray.c | 0 src/{ => libgit2}/oidarray.h | 0 src/{ => libgit2}/oidmap.c | 0 src/{ => libgit2}/oidmap.h | 0 src/{ => libgit2}/pack-objects.c | 0 src/{ => libgit2}/pack-objects.h | 0 src/{ => libgit2}/pack.c | 0 src/{ => libgit2}/pack.h | 0 src/{ => libgit2}/parse.c | 0 src/{ => libgit2}/parse.h | 0 src/{ => libgit2}/patch.c | 0 src/{ => libgit2}/patch.h | 0 src/{ => libgit2}/patch_generate.c | 0 src/{ => libgit2}/patch_generate.h | 0 src/{ => libgit2}/patch_parse.c | 0 src/{ => libgit2}/patch_parse.h | 0 src/{ => libgit2}/path.c | 0 src/{ => libgit2}/path.h | 0 src/{ => libgit2}/pathspec.c | 0 src/{ => libgit2}/pathspec.h | 0 src/{ => libgit2}/pool.c | 0 src/{ => libgit2}/pool.h | 0 src/{ => libgit2}/posix.c | 0 src/{ => libgit2}/posix.h | 0 src/{ => libgit2}/pqueue.c | 0 src/{ => libgit2}/pqueue.h | 0 src/{ => libgit2}/proxy.c | 0 src/{ => libgit2}/proxy.h | 0 src/{ => libgit2}/push.c | 0 src/{ => libgit2}/push.h | 0 src/{ => libgit2}/reader.c | 0 src/{ => libgit2}/reader.h | 0 src/{ => libgit2}/rebase.c | 0 src/{ => libgit2}/refdb.c | 0 src/{ => libgit2}/refdb.h | 0 src/{ => libgit2}/refdb_fs.c | 0 src/{ => libgit2}/reflog.c | 0 src/{ => libgit2}/reflog.h | 0 src/{ => libgit2}/refs.c | 0 src/{ => libgit2}/refs.h | 0 src/{ => libgit2}/refspec.c | 0 src/{ => libgit2}/refspec.h | 0 src/{ => libgit2}/regexp.c | 0 src/{ => libgit2}/regexp.h | 0 src/{ => libgit2}/remote.c | 0 src/{ => libgit2}/remote.h | 0 src/{ => libgit2}/repo_template.h | 0 src/{ => libgit2}/repository.c | 0 src/{ => libgit2}/repository.h | 0 src/{ => libgit2}/reset.c | 0 src/{ => libgit2}/revert.c | 0 src/{ => libgit2}/revparse.c | 0 src/{ => libgit2}/revwalk.c | 0 src/{ => libgit2}/revwalk.h | 0 src/{ => libgit2}/runtime.c | 0 src/{ => libgit2}/runtime.h | 0 src/{ => libgit2}/settings.h | 0 src/{ => libgit2}/signature.c | 0 src/{ => libgit2}/signature.h | 0 src/{ => libgit2}/sortedcache.c | 0 src/{ => libgit2}/sortedcache.h | 0 src/{ => libgit2}/stash.c | 0 src/{ => libgit2}/status.c | 0 src/{ => libgit2}/status.h | 0 src/{ => libgit2}/str.c | 0 src/{ => libgit2}/str.h | 0 src/{ => libgit2}/strarray.c | 0 src/{ => libgit2}/stream.h | 0 src/{ => libgit2}/streams/mbedtls.c | 0 src/{ => libgit2}/streams/mbedtls.h | 0 src/{ => libgit2}/streams/openssl.c | 0 src/{ => libgit2}/streams/openssl.h | 0 src/{ => libgit2}/streams/openssl_dynamic.c | 0 src/{ => libgit2}/streams/openssl_dynamic.h | 0 src/{ => libgit2}/streams/openssl_legacy.c | 0 src/{ => libgit2}/streams/openssl_legacy.h | 0 src/{ => libgit2}/streams/registry.c | 0 src/{ => libgit2}/streams/registry.h | 0 src/{ => libgit2}/streams/socket.c | 0 src/{ => libgit2}/streams/socket.h | 0 src/{ => libgit2}/streams/stransport.c | 0 src/{ => libgit2}/streams/stransport.h | 0 src/{ => libgit2}/streams/tls.c | 0 src/{ => libgit2}/streams/tls.h | 0 src/{ => libgit2}/strmap.c | 0 src/{ => libgit2}/strmap.h | 0 src/{ => libgit2}/strnlen.h | 0 src/{ => libgit2}/submodule.c | 0 src/{ => libgit2}/submodule.h | 0 src/{ => libgit2}/sysdir.c | 0 src/{ => libgit2}/sysdir.h | 0 src/{ => libgit2}/tag.c | 0 src/{ => libgit2}/tag.h | 0 src/{ => libgit2}/thread.c | 0 src/{ => libgit2}/thread.h | 0 src/{ => libgit2}/threadstate.c | 0 src/{ => libgit2}/threadstate.h | 0 src/{ => libgit2}/trace.c | 0 src/{ => libgit2}/trace.h | 0 src/{ => libgit2}/trailer.c | 0 src/{ => libgit2}/transaction.c | 0 src/{ => libgit2}/transaction.h | 0 src/{ => libgit2}/transport.c | 0 src/{ => libgit2}/transports/auth.c | 0 src/{ => libgit2}/transports/auth.h | 0 src/{ => libgit2}/transports/auth_negotiate.c | 0 src/{ => libgit2}/transports/auth_negotiate.h | 0 src/{ => libgit2}/transports/auth_ntlm.c | 0 src/{ => libgit2}/transports/auth_ntlm.h | 0 src/{ => libgit2}/transports/credential.c | 0 .../transports/credential_helpers.c | 0 src/{ => libgit2}/transports/git.c | 0 src/{ => libgit2}/transports/http.c | 0 src/{ => libgit2}/transports/http.h | 0 src/{ => libgit2}/transports/httpclient.c | 0 src/{ => libgit2}/transports/httpclient.h | 0 src/{ => libgit2}/transports/local.c | 0 src/{ => libgit2}/transports/smart.c | 0 src/{ => libgit2}/transports/smart.h | 0 src/{ => libgit2}/transports/smart_pkt.c | 0 src/{ => libgit2}/transports/smart_protocol.c | 0 src/{ => libgit2}/transports/ssh.c | 0 src/{ => libgit2}/transports/ssh.h | 0 src/{ => libgit2}/transports/winhttp.c | 0 src/{ => libgit2}/tree-cache.c | 0 src/{ => libgit2}/tree-cache.h | 0 src/{ => libgit2}/tree.c | 0 src/{ => libgit2}/tree.h | 0 src/{ => libgit2}/tsort.c | 0 src/{ => libgit2}/unix/map.c | 0 src/{ => libgit2}/unix/posix.h | 0 src/{ => libgit2}/unix/pthread.h | 0 src/{ => libgit2}/unix/realpath.c | 0 src/{ => libgit2}/userdiff.h | 0 src/{ => libgit2}/utf8.c | 0 src/{ => libgit2}/utf8.h | 0 src/{ => libgit2}/util.c | 0 src/{ => libgit2}/util.h | 0 src/libgit2/util/platform.h.in | 34 ++ src/{ => libgit2}/varint.c | 0 src/{ => libgit2}/varint.h | 0 src/{ => libgit2}/vector.c | 0 src/{ => libgit2}/vector.h | 0 src/{ => libgit2}/wildmatch.c | 0 src/{ => libgit2}/wildmatch.h | 0 src/{ => libgit2}/win32/dir.c | 0 src/{ => libgit2}/win32/dir.h | 0 src/{ => libgit2}/win32/error.c | 0 src/{ => libgit2}/win32/error.h | 0 src/{ => libgit2}/win32/findfile.c | 0 src/{ => libgit2}/win32/findfile.h | 0 src/{ => libgit2}/win32/git2.rc | 2 +- src/{ => libgit2}/win32/map.c | 0 src/{ => libgit2}/win32/mingw-compat.h | 0 src/{ => libgit2}/win32/msvc-compat.h | 0 src/{ => libgit2}/win32/path_w32.c | 0 src/{ => libgit2}/win32/path_w32.h | 0 src/{ => libgit2}/win32/posix.h | 0 src/{ => libgit2}/win32/posix_w32.c | 0 src/{ => libgit2}/win32/precompiled.c | 0 src/{ => libgit2}/win32/precompiled.h | 0 src/{ => libgit2}/win32/reparse.h | 0 src/{ => libgit2}/win32/thread.c | 0 src/{ => libgit2}/win32/thread.h | 0 src/{ => libgit2}/win32/utf-conv.c | 0 src/{ => libgit2}/win32/utf-conv.h | 0 src/{ => libgit2}/win32/version.h | 0 src/{ => libgit2}/win32/w32_buffer.c | 0 src/{ => libgit2}/win32/w32_buffer.h | 0 src/{ => libgit2}/win32/w32_common.h | 0 src/{ => libgit2}/win32/w32_leakcheck.c | 0 src/{ => libgit2}/win32/w32_leakcheck.h | 0 src/{ => libgit2}/win32/w32_util.c | 0 src/{ => libgit2}/win32/w32_util.h | 0 src/{ => libgit2}/win32/win32-compat.h | 0 src/{ => libgit2}/worktree.c | 0 src/{ => libgit2}/worktree.h | 0 src/{ => libgit2}/xdiff/git-xdiff.h | 0 src/{ => libgit2}/xdiff/xdiff.h | 0 src/{ => libgit2}/xdiff/xdiffi.c | 0 src/{ => libgit2}/xdiff/xdiffi.h | 0 src/{ => libgit2}/xdiff/xemit.c | 0 src/{ => libgit2}/xdiff/xemit.h | 0 src/{ => libgit2}/xdiff/xhistogram.c | 0 src/{ => libgit2}/xdiff/xinclude.h | 0 src/{ => libgit2}/xdiff/xmacros.h | 0 src/{ => libgit2}/xdiff/xmerge.c | 0 src/{ => libgit2}/xdiff/xpatience.c | 0 src/{ => libgit2}/xdiff/xprepare.c | 0 src/{ => libgit2}/xdiff/xprepare.h | 0 src/{ => libgit2}/xdiff/xtypes.h | 0 src/{ => libgit2}/xdiff/xutils.c | 0 src/{ => libgit2}/xdiff/xutils.h | 0 src/{ => libgit2}/zstream.c | 0 src/{ => libgit2}/zstream.h | 0 361 files changed, 343 insertions(+), 301 deletions(-) create mode 100644 src/libgit2/CMakeLists.txt rename src/{ => libgit2}/alloc.c (100%) rename src/{ => libgit2}/alloc.h (100%) rename src/{ => libgit2}/allocators/failalloc.c (100%) rename src/{ => libgit2}/allocators/failalloc.h (100%) rename src/{ => libgit2}/allocators/stdalloc.c (100%) rename src/{ => libgit2}/allocators/stdalloc.h (100%) rename src/{ => libgit2}/allocators/win32_leakcheck.c (100%) rename src/{ => libgit2}/allocators/win32_leakcheck.h (100%) rename src/{ => libgit2}/annotated_commit.c (100%) rename src/{ => libgit2}/annotated_commit.h (100%) rename src/{ => libgit2}/apply.c (100%) rename src/{ => libgit2}/apply.h (100%) rename src/{ => libgit2}/array.h (100%) rename src/{ => libgit2}/assert_safe.h (100%) rename src/{ => libgit2}/attr.c (100%) rename src/{ => libgit2}/attr.h (100%) rename src/{ => libgit2}/attr_file.c (100%) rename src/{ => libgit2}/attr_file.h (100%) rename src/{ => libgit2}/attrcache.c (100%) rename src/{ => libgit2}/attrcache.h (100%) rename src/{ => libgit2}/bitvec.h (100%) rename src/{ => libgit2}/blame.c (100%) rename src/{ => libgit2}/blame.h (100%) rename src/{ => libgit2}/blame_git.c (100%) rename src/{ => libgit2}/blame_git.h (100%) rename src/{ => libgit2}/blob.c (100%) rename src/{ => libgit2}/blob.h (100%) rename src/{ => libgit2}/branch.c (100%) rename src/{ => libgit2}/branch.h (100%) rename src/{ => libgit2}/buf.c (100%) rename src/{ => libgit2}/buf.h (100%) rename src/{ => libgit2}/cache.c (100%) rename src/{ => libgit2}/cache.h (100%) rename src/{ => libgit2}/cc-compat.h (100%) rename src/{ => libgit2}/checkout.c (100%) rename src/{ => libgit2}/checkout.h (100%) rename src/{ => libgit2}/cherrypick.c (100%) rename src/{ => libgit2}/clone.c (100%) rename src/{ => libgit2}/clone.h (100%) rename src/{ => libgit2}/commit.c (100%) rename src/{ => libgit2}/commit.h (100%) rename src/{ => libgit2}/commit_graph.c (100%) rename src/{ => libgit2}/commit_graph.h (100%) rename src/{ => libgit2}/commit_list.c (100%) rename src/{ => libgit2}/commit_list.h (100%) rename src/{ => libgit2}/common.h (100%) rename src/{ => libgit2}/config.c (100%) rename src/{ => libgit2}/config.h (100%) rename src/{ => libgit2}/config_backend.h (100%) rename src/{ => libgit2}/config_cache.c (100%) rename src/{ => libgit2}/config_entries.c (100%) rename src/{ => libgit2}/config_entries.h (100%) rename src/{ => libgit2}/config_file.c (100%) rename src/{ => libgit2}/config_mem.c (100%) rename src/{ => libgit2}/config_parse.c (100%) rename src/{ => libgit2}/config_parse.h (100%) rename src/{ => libgit2}/config_snapshot.c (100%) rename src/{ => libgit2}/crlf.c (100%) rename src/{ => libgit2}/date.c (100%) rename src/{ => libgit2}/date.h (100%) rename src/{ => libgit2}/delta.c (100%) rename src/{ => libgit2}/delta.h (100%) rename src/{ => libgit2}/describe.c (100%) rename src/{ => libgit2}/diff.c (100%) rename src/{ => libgit2}/diff.h (100%) rename src/{ => libgit2}/diff_driver.c (100%) rename src/{ => libgit2}/diff_driver.h (100%) rename src/{ => libgit2}/diff_file.c (100%) rename src/{ => libgit2}/diff_file.h (100%) rename src/{ => libgit2}/diff_generate.c (100%) rename src/{ => libgit2}/diff_generate.h (100%) rename src/{ => libgit2}/diff_parse.c (100%) rename src/{ => libgit2}/diff_parse.h (100%) rename src/{ => libgit2}/diff_print.c (100%) rename src/{ => libgit2}/diff_stats.c (100%) rename src/{ => libgit2}/diff_stats.h (100%) rename src/{ => libgit2}/diff_tform.c (100%) rename src/{ => libgit2}/diff_tform.h (100%) rename src/{ => libgit2}/diff_xdiff.c (100%) rename src/{ => libgit2}/diff_xdiff.h (100%) rename src/{ => libgit2}/email.c (100%) rename src/{ => libgit2}/email.h (100%) rename src/{ => libgit2}/errors.c (100%) rename src/{ => libgit2}/errors.h (100%) rename src/{ => libgit2}/features.h.in (100%) rename src/{ => libgit2}/fetch.c (100%) rename src/{ => libgit2}/fetch.h (100%) rename src/{ => libgit2}/fetchhead.c (100%) rename src/{ => libgit2}/fetchhead.h (100%) rename src/{ => libgit2}/filebuf.c (100%) rename src/{ => libgit2}/filebuf.h (100%) rename src/{ => libgit2}/filter.c (100%) rename src/{ => libgit2}/filter.h (100%) rename src/{ => libgit2}/fs_path.c (100%) rename src/{ => libgit2}/fs_path.h (100%) rename src/{ => libgit2}/futils.c (100%) rename src/{ => libgit2}/futils.h (100%) rename src/{ => libgit2}/graph.c (100%) rename src/{ => libgit2}/hash.c (100%) rename src/{ => libgit2}/hash.h (100%) rename src/{ => libgit2}/hash/sha1.h (100%) rename src/{ => libgit2}/hash/sha1/collisiondetect.c (100%) rename src/{ => libgit2}/hash/sha1/collisiondetect.h (100%) rename src/{ => libgit2}/hash/sha1/common_crypto.c (100%) rename src/{ => libgit2}/hash/sha1/common_crypto.h (100%) rename src/{ => libgit2}/hash/sha1/generic.c (100%) rename src/{ => libgit2}/hash/sha1/generic.h (100%) rename src/{ => libgit2}/hash/sha1/mbedtls.c (100%) rename src/{ => libgit2}/hash/sha1/mbedtls.h (100%) rename src/{ => libgit2}/hash/sha1/openssl.c (100%) rename src/{ => libgit2}/hash/sha1/openssl.h (100%) rename src/{ => libgit2}/hash/sha1/sha1dc/sha1.c (100%) rename src/{ => libgit2}/hash/sha1/sha1dc/sha1.h (100%) rename src/{ => libgit2}/hash/sha1/sha1dc/ubc_check.c (100%) rename src/{ => libgit2}/hash/sha1/sha1dc/ubc_check.h (100%) rename src/{ => libgit2}/hash/sha1/win32.c (100%) rename src/{ => libgit2}/hash/sha1/win32.h (100%) rename src/{ => libgit2}/hashsig.c (100%) rename src/{ => libgit2}/ident.c (100%) rename src/{ => libgit2}/idxmap.c (100%) rename src/{ => libgit2}/idxmap.h (100%) rename src/{ => libgit2}/ignore.c (100%) rename src/{ => libgit2}/ignore.h (100%) rename src/{ => libgit2}/index.c (100%) rename src/{ => libgit2}/index.h (100%) rename src/{ => libgit2}/indexer.c (100%) rename src/{ => libgit2}/indexer.h (100%) rename src/{ => libgit2}/integer.h (100%) rename src/{ => libgit2}/iterator.c (100%) rename src/{ => libgit2}/iterator.h (100%) rename src/{ => libgit2}/khash.h (100%) rename src/{ => libgit2}/libgit2.c (100%) rename src/{ => libgit2}/libgit2.h (100%) rename src/{ => libgit2}/mailmap.c (100%) rename src/{ => libgit2}/mailmap.h (100%) rename src/{ => libgit2}/map.h (100%) rename src/{ => libgit2}/merge.c (100%) rename src/{ => libgit2}/merge.h (100%) rename src/{ => libgit2}/merge_driver.c (100%) rename src/{ => libgit2}/merge_driver.h (100%) rename src/{ => libgit2}/merge_file.c (100%) rename src/{ => libgit2}/message.c (100%) rename src/{ => libgit2}/midx.c (100%) rename src/{ => libgit2}/midx.h (100%) rename src/{ => libgit2}/mwindow.c (100%) rename src/{ => libgit2}/mwindow.h (100%) rename src/{ => libgit2}/net.c (100%) rename src/{ => libgit2}/net.h (100%) rename src/{ => libgit2}/netops.c (100%) rename src/{ => libgit2}/netops.h (100%) rename src/{ => libgit2}/notes.c (100%) rename src/{ => libgit2}/notes.h (100%) rename src/{ => libgit2}/object.c (100%) rename src/{ => libgit2}/object.h (100%) rename src/{ => libgit2}/object_api.c (100%) rename src/{ => libgit2}/odb.c (100%) rename src/{ => libgit2}/odb.h (100%) rename src/{ => libgit2}/odb_loose.c (100%) rename src/{ => libgit2}/odb_mempack.c (100%) rename src/{ => libgit2}/odb_pack.c (100%) rename src/{ => libgit2}/offmap.c (100%) rename src/{ => libgit2}/offmap.h (100%) rename src/{ => libgit2}/oid.c (100%) rename src/{ => libgit2}/oid.h (100%) rename src/{ => libgit2}/oidarray.c (100%) rename src/{ => libgit2}/oidarray.h (100%) rename src/{ => libgit2}/oidmap.c (100%) rename src/{ => libgit2}/oidmap.h (100%) rename src/{ => libgit2}/pack-objects.c (100%) rename src/{ => libgit2}/pack-objects.h (100%) rename src/{ => libgit2}/pack.c (100%) rename src/{ => libgit2}/pack.h (100%) rename src/{ => libgit2}/parse.c (100%) rename src/{ => libgit2}/parse.h (100%) rename src/{ => libgit2}/patch.c (100%) rename src/{ => libgit2}/patch.h (100%) rename src/{ => libgit2}/patch_generate.c (100%) rename src/{ => libgit2}/patch_generate.h (100%) rename src/{ => libgit2}/patch_parse.c (100%) rename src/{ => libgit2}/patch_parse.h (100%) rename src/{ => libgit2}/path.c (100%) rename src/{ => libgit2}/path.h (100%) rename src/{ => libgit2}/pathspec.c (100%) rename src/{ => libgit2}/pathspec.h (100%) rename src/{ => libgit2}/pool.c (100%) rename src/{ => libgit2}/pool.h (100%) rename src/{ => libgit2}/posix.c (100%) rename src/{ => libgit2}/posix.h (100%) rename src/{ => libgit2}/pqueue.c (100%) rename src/{ => libgit2}/pqueue.h (100%) rename src/{ => libgit2}/proxy.c (100%) rename src/{ => libgit2}/proxy.h (100%) rename src/{ => libgit2}/push.c (100%) rename src/{ => libgit2}/push.h (100%) rename src/{ => libgit2}/reader.c (100%) rename src/{ => libgit2}/reader.h (100%) rename src/{ => libgit2}/rebase.c (100%) rename src/{ => libgit2}/refdb.c (100%) rename src/{ => libgit2}/refdb.h (100%) rename src/{ => libgit2}/refdb_fs.c (100%) rename src/{ => libgit2}/reflog.c (100%) rename src/{ => libgit2}/reflog.h (100%) rename src/{ => libgit2}/refs.c (100%) rename src/{ => libgit2}/refs.h (100%) rename src/{ => libgit2}/refspec.c (100%) rename src/{ => libgit2}/refspec.h (100%) rename src/{ => libgit2}/regexp.c (100%) rename src/{ => libgit2}/regexp.h (100%) rename src/{ => libgit2}/remote.c (100%) rename src/{ => libgit2}/remote.h (100%) rename src/{ => libgit2}/repo_template.h (100%) rename src/{ => libgit2}/repository.c (100%) rename src/{ => libgit2}/repository.h (100%) rename src/{ => libgit2}/reset.c (100%) rename src/{ => libgit2}/revert.c (100%) rename src/{ => libgit2}/revparse.c (100%) rename src/{ => libgit2}/revwalk.c (100%) rename src/{ => libgit2}/revwalk.h (100%) rename src/{ => libgit2}/runtime.c (100%) rename src/{ => libgit2}/runtime.h (100%) rename src/{ => libgit2}/settings.h (100%) rename src/{ => libgit2}/signature.c (100%) rename src/{ => libgit2}/signature.h (100%) rename src/{ => libgit2}/sortedcache.c (100%) rename src/{ => libgit2}/sortedcache.h (100%) rename src/{ => libgit2}/stash.c (100%) rename src/{ => libgit2}/status.c (100%) rename src/{ => libgit2}/status.h (100%) rename src/{ => libgit2}/str.c (100%) rename src/{ => libgit2}/str.h (100%) rename src/{ => libgit2}/strarray.c (100%) rename src/{ => libgit2}/stream.h (100%) rename src/{ => libgit2}/streams/mbedtls.c (100%) rename src/{ => libgit2}/streams/mbedtls.h (100%) rename src/{ => libgit2}/streams/openssl.c (100%) rename src/{ => libgit2}/streams/openssl.h (100%) rename src/{ => libgit2}/streams/openssl_dynamic.c (100%) rename src/{ => libgit2}/streams/openssl_dynamic.h (100%) rename src/{ => libgit2}/streams/openssl_legacy.c (100%) rename src/{ => libgit2}/streams/openssl_legacy.h (100%) rename src/{ => libgit2}/streams/registry.c (100%) rename src/{ => libgit2}/streams/registry.h (100%) rename src/{ => libgit2}/streams/socket.c (100%) rename src/{ => libgit2}/streams/socket.h (100%) rename src/{ => libgit2}/streams/stransport.c (100%) rename src/{ => libgit2}/streams/stransport.h (100%) rename src/{ => libgit2}/streams/tls.c (100%) rename src/{ => libgit2}/streams/tls.h (100%) rename src/{ => libgit2}/strmap.c (100%) rename src/{ => libgit2}/strmap.h (100%) rename src/{ => libgit2}/strnlen.h (100%) rename src/{ => libgit2}/submodule.c (100%) rename src/{ => libgit2}/submodule.h (100%) rename src/{ => libgit2}/sysdir.c (100%) rename src/{ => libgit2}/sysdir.h (100%) rename src/{ => libgit2}/tag.c (100%) rename src/{ => libgit2}/tag.h (100%) rename src/{ => libgit2}/thread.c (100%) rename src/{ => libgit2}/thread.h (100%) rename src/{ => libgit2}/threadstate.c (100%) rename src/{ => libgit2}/threadstate.h (100%) rename src/{ => libgit2}/trace.c (100%) rename src/{ => libgit2}/trace.h (100%) rename src/{ => libgit2}/trailer.c (100%) rename src/{ => libgit2}/transaction.c (100%) rename src/{ => libgit2}/transaction.h (100%) rename src/{ => libgit2}/transport.c (100%) rename src/{ => libgit2}/transports/auth.c (100%) rename src/{ => libgit2}/transports/auth.h (100%) rename src/{ => libgit2}/transports/auth_negotiate.c (100%) rename src/{ => libgit2}/transports/auth_negotiate.h (100%) rename src/{ => libgit2}/transports/auth_ntlm.c (100%) rename src/{ => libgit2}/transports/auth_ntlm.h (100%) rename src/{ => libgit2}/transports/credential.c (100%) rename src/{ => libgit2}/transports/credential_helpers.c (100%) rename src/{ => libgit2}/transports/git.c (100%) rename src/{ => libgit2}/transports/http.c (100%) rename src/{ => libgit2}/transports/http.h (100%) rename src/{ => libgit2}/transports/httpclient.c (100%) rename src/{ => libgit2}/transports/httpclient.h (100%) rename src/{ => libgit2}/transports/local.c (100%) rename src/{ => libgit2}/transports/smart.c (100%) rename src/{ => libgit2}/transports/smart.h (100%) rename src/{ => libgit2}/transports/smart_pkt.c (100%) rename src/{ => libgit2}/transports/smart_protocol.c (100%) rename src/{ => libgit2}/transports/ssh.c (100%) rename src/{ => libgit2}/transports/ssh.h (100%) rename src/{ => libgit2}/transports/winhttp.c (100%) rename src/{ => libgit2}/tree-cache.c (100%) rename src/{ => libgit2}/tree-cache.h (100%) rename src/{ => libgit2}/tree.c (100%) rename src/{ => libgit2}/tree.h (100%) rename src/{ => libgit2}/tsort.c (100%) rename src/{ => libgit2}/unix/map.c (100%) rename src/{ => libgit2}/unix/posix.h (100%) rename src/{ => libgit2}/unix/pthread.h (100%) rename src/{ => libgit2}/unix/realpath.c (100%) rename src/{ => libgit2}/userdiff.h (100%) rename src/{ => libgit2}/utf8.c (100%) rename src/{ => libgit2}/utf8.h (100%) rename src/{ => libgit2}/util.c (100%) rename src/{ => libgit2}/util.h (100%) create mode 100644 src/libgit2/util/platform.h.in rename src/{ => libgit2}/varint.c (100%) rename src/{ => libgit2}/varint.h (100%) rename src/{ => libgit2}/vector.c (100%) rename src/{ => libgit2}/vector.h (100%) rename src/{ => libgit2}/wildmatch.c (100%) rename src/{ => libgit2}/wildmatch.h (100%) rename src/{ => libgit2}/win32/dir.c (100%) rename src/{ => libgit2}/win32/dir.h (100%) rename src/{ => libgit2}/win32/error.c (100%) rename src/{ => libgit2}/win32/error.h (100%) rename src/{ => libgit2}/win32/findfile.c (100%) rename src/{ => libgit2}/win32/findfile.h (100%) rename src/{ => libgit2}/win32/git2.rc (97%) rename src/{ => libgit2}/win32/map.c (100%) rename src/{ => libgit2}/win32/mingw-compat.h (100%) rename src/{ => libgit2}/win32/msvc-compat.h (100%) rename src/{ => libgit2}/win32/path_w32.c (100%) rename src/{ => libgit2}/win32/path_w32.h (100%) rename src/{ => libgit2}/win32/posix.h (100%) rename src/{ => libgit2}/win32/posix_w32.c (100%) rename src/{ => libgit2}/win32/precompiled.c (100%) rename src/{ => libgit2}/win32/precompiled.h (100%) rename src/{ => libgit2}/win32/reparse.h (100%) rename src/{ => libgit2}/win32/thread.c (100%) rename src/{ => libgit2}/win32/thread.h (100%) rename src/{ => libgit2}/win32/utf-conv.c (100%) rename src/{ => libgit2}/win32/utf-conv.h (100%) rename src/{ => libgit2}/win32/version.h (100%) rename src/{ => libgit2}/win32/w32_buffer.c (100%) rename src/{ => libgit2}/win32/w32_buffer.h (100%) rename src/{ => libgit2}/win32/w32_common.h (100%) rename src/{ => libgit2}/win32/w32_leakcheck.c (100%) rename src/{ => libgit2}/win32/w32_leakcheck.h (100%) rename src/{ => libgit2}/win32/w32_util.c (100%) rename src/{ => libgit2}/win32/w32_util.h (100%) rename src/{ => libgit2}/win32/win32-compat.h (100%) rename src/{ => libgit2}/worktree.c (100%) rename src/{ => libgit2}/worktree.h (100%) rename src/{ => libgit2}/xdiff/git-xdiff.h (100%) rename src/{ => libgit2}/xdiff/xdiff.h (100%) rename src/{ => libgit2}/xdiff/xdiffi.c (100%) rename src/{ => libgit2}/xdiff/xdiffi.h (100%) rename src/{ => libgit2}/xdiff/xemit.c (100%) rename src/{ => libgit2}/xdiff/xemit.h (100%) rename src/{ => libgit2}/xdiff/xhistogram.c (100%) rename src/{ => libgit2}/xdiff/xinclude.h (100%) rename src/{ => libgit2}/xdiff/xmacros.h (100%) rename src/{ => libgit2}/xdiff/xmerge.c (100%) rename src/{ => libgit2}/xdiff/xpatience.c (100%) rename src/{ => libgit2}/xdiff/xprepare.c (100%) rename src/{ => libgit2}/xdiff/xprepare.h (100%) rename src/{ => libgit2}/xdiff/xtypes.h (100%) rename src/{ => libgit2}/xdiff/xutils.c (100%) rename src/{ => libgit2}/xdiff/xutils.h (100%) rename src/{ => libgit2}/zstream.c (100%) rename src/{ => libgit2}/zstream.h (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e7b54d036ab..f6924eff57e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,307 +1,10 @@ -add_library(git2internal OBJECT) -set_target_properties(git2internal PROPERTIES C_STANDARD 90) -set_target_properties(git2internal PROPERTIES C_EXTENSIONS OFF) - - -if(DEPRECATE_HARD) - add_definitions(-DGIT_DEPRECATE_HARD) -endif() - -if(DEBUG_POOL) - set(GIT_DEBUG_POOL 1) -endif() -add_feature_info(debugpool GIT_DEBUG_POOL "debug pool allocator") - -if(DEBUG_STRICT_ALLOC) - set(GIT_DEBUG_STRICT_ALLOC 1) -endif() -add_feature_info(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators") - -if(DEBUG_STRICT_OPEN) - set(GIT_DEBUG_STRICT_OPEN 1) -endif() -add_feature_info(debugopen GIT_DEBUG_STRICT_OPEN "path validation in open") - - -include(PkgBuildConfig) -include(SanitizeBool) - -# This variable will contain the libraries we need to put into -# libgit2.pc's Requires.private. That is, what we're linking to or -# what someone who's statically linking us needs to link to. -set(LIBGIT2_PC_REQUIRES "") -# This will be set later if we use the system's http-parser library or -# use iconv (OSX) and will be written to the Libs.private field in the -# pc file. -set(LIBGIT2_PC_LIBS "") - -set(LIBGIT2_INCLUDES - "${CMAKE_CURRENT_BINARY_DIR}" - "${PROJECT_SOURCE_DIR}/src" - "${PROJECT_SOURCE_DIR}/include") - -if(HAVE_FUTIMENS) - set(GIT_USE_FUTIMENS 1) -endif () -add_feature_info(futimens GIT_USE_FUTIMENS "futimens support") - -check_prototype_definition(qsort_r - "void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, int (*compar)(void *, const void *, const void *))" - "" "stdlib.h" GIT_QSORT_R_BSD) - -check_prototype_definition(qsort_r - "void qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *arg)" - "" "stdlib.h" GIT_QSORT_R_GNU) - -check_function_exists(qsort_s GIT_QSORT_S) - -check_function_exists(getentropy GIT_RAND_GETENTROPY) - -# Find required dependencies - -if(WIN32) - list(APPEND LIBGIT2_SYSTEM_LIBS ws2_32) -elseif(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - list(APPEND LIBGIT2_SYSTEM_LIBS socket nsl) - list(APPEND LIBGIT2_PC_LIBS "-lsocket" "-lnsl") -elseif(CMAKE_SYSTEM_NAME MATCHES "Haiku") - list(APPEND LIBGIT2_SYSTEM_LIBS network) - list(APPEND LIBGIT2_PC_LIBS "-lnetwork") -endif() - -check_library_exists(rt clock_gettime "time.h" NEED_LIBRT) -if(NEED_LIBRT) - list(APPEND LIBGIT2_SYSTEM_LIBS rt) - list(APPEND LIBGIT2_PC_LIBS "-lrt") -endif() - -if(USE_THREADS) - list(APPEND LIBGIT2_SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT}) - list(APPEND LIBGIT2_PC_LIBS ${CMAKE_THREAD_LIBS_INIT}) -endif() -add_feature_info(threadsafe USE_THREADS "threadsafe support") - - -if(WIN32 AND EMBED_SSH_PATH) - file(GLOB SRC_SSH "${EMBED_SSH_PATH}/src/*.c") - list(SORT SRC_SSH) - target_sources(git2internal PRIVATE ${SRC_SSH}) - - list(APPEND LIBGIT2_SYSTEM_INCLUDES "${EMBED_SSH_PATH}/include") - file(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"") - set(GIT_SSH 1) -endif() - -include(SelectHTTPSBackend) -include(SelectHashes) -include(SelectHTTPParser) -include(SelectRegex) -include(SelectSSH) -include(SelectWinHTTP) -include(SelectZlib) - - -if(USE_SHA1 STREQUAL "CollisionDetection") - file(GLOB SRC_SHA1 hash/sha1/collisiondetect.* hash/sha1/sha1dc/*) -elseif(USE_SHA1 STREQUAL "OpenSSL") - file(GLOB SRC_SHA1 hash/sha1/openssl.*) -elseif(USE_SHA1 STREQUAL "CommonCrypto") - file(GLOB SRC_SHA1 hash/sha1/common_crypto.*) -elseif(USE_SHA1 STREQUAL "mbedTLS") - file(GLOB SRC_SHA1 hash/sha1/mbedtls.*) -elseif(USE_SHA1 STREQUAL "Win32") - file(GLOB SRC_SHA1 hash/sha1/win32.*) -elseif(USE_SHA1 STREQUAL "Generic") - file(GLOB SRC_SHA1 hash/sha1/generic.*) -endif() -list(APPEND SRC_SHA1 "hash/sha1.h") -target_sources(git2internal PRIVATE ${SRC_SHA1}) - -# Optional external dependency: ntlmclient -if(USE_NTLMCLIENT) - set(GIT_NTLM 1) - add_subdirectory("${PROJECT_SOURCE_DIR}/deps/ntlmclient" "${PROJECT_BINARY_DIR}/deps/ntlmclient") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/ntlmclient") - list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") -endif() -add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix") - -# Optional external dependency: GSSAPI - -include(SelectGSSAPI) - -# Optional external dependency: iconv -if(USE_ICONV) - find_package(Iconv) -endif() -if(ICONV_FOUND) - set(GIT_USE_ICONV 1) - list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ICONV_INCLUDE_DIR}) - list(APPEND LIBGIT2_SYSTEM_LIBS ${ICONV_LIBRARIES}) - list(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES}) -endif() -add_feature_info(iconv GIT_USE_ICONV "iconv encoding conversion support") - - -if(USE_THREADS) - if(NOT WIN32) - find_package(Threads REQUIRED) - endif() - - set(GIT_THREADS 1) -endif() - -if(USE_NSEC) - set(GIT_USE_NSEC 1) -endif() - -if(HAVE_STRUCT_STAT_ST_MTIM) - set(GIT_USE_STAT_MTIM 1) -elseif(HAVE_STRUCT_STAT_ST_MTIMESPEC) - set(GIT_USE_STAT_MTIMESPEC 1) -elseif(HAVE_STRUCT_STAT_ST_MTIME_NSEC) - set(GIT_USE_STAT_MTIME_NSEC 1) -endif() - -target_compile_definitions(git2internal PRIVATE _FILE_OFFSET_BITS=64) - -# Collect sourcefiles -file(GLOB SRC_H - "${PROJECT_SOURCE_DIR}/include/git2.h" - "${PROJECT_SOURCE_DIR}/include/git2/*.h" - "${PROJECT_SOURCE_DIR}/include/git2/sys/*.h") -list(SORT SRC_H) -target_sources(git2internal PRIVATE ${SRC_H}) - -# On Windows use specific platform sources -if(WIN32 AND NOT CYGWIN) - set(WIN_RC "win32/git2.rc") - - file(GLOB SRC_OS win32/*.c win32/*.h) - list(SORT SRC_OS) - target_sources(git2internal PRIVATE ${SRC_OS}) -elseif(AMIGA) - target_compile_definitions(git2internal PRIVATE NO_ADDRINFO NO_READDIR_R NO_MMAP) -else() - file(GLOB SRC_OS unix/*.c unix/*.h) - list(SORT SRC_OS) - target_sources(git2internal PRIVATE ${SRC_OS}) -endif() - -if(USE_LEAK_CHECKER STREQUAL "valgrind") - target_compile_definitions(git2internal PRIVATE VALGRIND) -endif() - -file(GLOB SRC_GIT2 *.c *.h - allocators/*.c allocators/*.h - streams/*.c streams/*.h - transports/*.c transports/*.h - xdiff/*.c xdiff/*.h) -list(SORT SRC_GIT2) -target_sources(git2internal PRIVATE ${SRC_GIT2}) - -if(APPLE) - # The old Secure Transport API has been deprecated in macOS 10.15. - set_source_files_properties(streams/stransport.c PROPERTIES COMPILE_FLAGS -Wno-deprecated) -endif() - -# the xdiff dependency is not (yet) warning-free, disable warnings as -# errors for the xdiff sources until we've sorted them out -if(MSVC) - set_source_files_properties(xdiff/xdiffi.c PROPERTIES COMPILE_FLAGS -WX-) - set_source_files_properties(xdiff/xemit.c PROPERTIES COMPILE_FLAGS -WX-) - set_source_files_properties(xdiff/xhistogram.c PROPERTIES COMPILE_FLAGS -WX-) - set_source_files_properties(xdiff/xmerge.c PROPERTIES COMPILE_FLAGS -WX-) - set_source_files_properties(xdiff/xutils.c PROPERTIES COMPILE_FLAGS -WX-) - set_source_files_properties(xdiff/xpatience.c PROPERTIES COMPILE_FLAGS -WX-) -else() - set_source_files_properties(xdiff/xdiffi.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-parameter") - set_source_files_properties(xdiff/xemit.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-parameter") - set_source_files_properties(xdiff/xhistogram.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") - set_source_files_properties(xdiff/xutils.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") - set_source_files_properties(xdiff/xpatience.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") -endif() - -# Determine architecture of the machine -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(GIT_ARCH_64 1) -elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) - set(GIT_ARCH_32 1) -elseif(CMAKE_SIZEOF_VOID_P) - message(FATAL_ERROR "Unsupported architecture (pointer size is ${CMAKE_SIZEOF_VOID_P} bytes)") -else() - message(FATAL_ERROR "Unsupported architecture (CMAKE_SIZEOF_VOID_P is unset)") -endif() - -configure_file(features.h.in git2/sys/features.h) - -ide_split_sources(git2internal) -list(APPEND LIBGIT2_OBJECTS $ ${LIBGIT2_DEPENDENCY_OBJECTS}) - -target_include_directories(git2internal PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${PROJECT_SOURCE_DIR}/include) -target_include_directories(git2internal SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) +add_subdirectory(libgit2) +# re-export these to the root so that peer projects (tests, fuzzers, +# examples) can use them set(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE) set(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE) set(LIBGIT2_DEPENDENCY_INCLUDES ${LIBGIT2_DEPENDENCY_INCLUDES} PARENT_SCOPE) set(LIBGIT2_DEPENDENCY_OBJECTS ${LIBGIT2_DEPENDENCY_OBJECTS} PARENT_SCOPE) set(LIBGIT2_SYSTEM_INCLUDES ${LIBGIT2_SYSTEM_INCLUDES} PARENT_SCOPE) set(LIBGIT2_SYSTEM_LIBS ${LIBGIT2_SYSTEM_LIBS} PARENT_SCOPE) - -if(XCODE_VERSION) - # This is required for Xcode to actually link the libgit2 library - # when using only object libraries. - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.c "") - list(APPEND LIBGIT2_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/dummy.c) -endif() - -# Compile and link libgit2 -add_library(git2 ${WIN_RC} ${LIBGIT2_OBJECTS}) -target_link_libraries(git2 ${LIBGIT2_SYSTEM_LIBS}) - -set_target_properties(git2 PROPERTIES C_STANDARD 90) -set_target_properties(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) -set_target_properties(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) -set_target_properties(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) - -# Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240) -# Win64+MSVC+static libs = linker error -if(MSVC AND GIT_ARCH_64 AND NOT BUILD_SHARED_LIBS) - set_target_properties(git2 PROPERTIES STATIC_LIBRARY_FLAGS "/MACHINE:x64") -endif() - -ide_split_sources(git2) - -if(SONAME) - set_target_properties(git2 PROPERTIES VERSION ${libgit2_VERSION}) - set_target_properties(git2 PROPERTIES SOVERSION "${libgit2_VERSION_MAJOR}.${libgit2_VERSION_MINOR}") - if(LIBGIT2_FILENAME) - target_compile_definitions(git2 PRIVATE LIBGIT2_FILENAME=\"${LIBGIT2_FILENAME}\") - set_target_properties(git2 PROPERTIES OUTPUT_NAME ${LIBGIT2_FILENAME}) - elseif(DEFINED LIBGIT2_PREFIX) - set_target_properties(git2 PROPERTIES PREFIX "${LIBGIT2_PREFIX}") - endif() -endif() - -pkg_build_config(NAME libgit2 - VERSION ${libgit2_VERSION} - DESCRIPTION "The git library, take 2" - LIBS_SELF git2 - PRIVATE_LIBS ${LIBGIT2_PC_LIBS} - REQUIRES ${LIBGIT2_PC_REQUIRES} -) - -if(MSVC_IDE) - # Precompiled headers - set_target_properties(git2 PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") - set_source_files_properties(win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h") -endif() - -# Install -install(TARGETS git2 - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} -) -install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -install(FILES ${PROJECT_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/libgit2/CMakeLists.txt b/src/libgit2/CMakeLists.txt new file mode 100644 index 00000000000..e6cdddd491e --- /dev/null +++ b/src/libgit2/CMakeLists.txt @@ -0,0 +1,305 @@ +add_library(git2internal OBJECT) +set_target_properties(git2internal PROPERTIES C_STANDARD 90) +set_target_properties(git2internal PROPERTIES C_EXTENSIONS OFF) + + +if(DEPRECATE_HARD) + add_definitions(-DGIT_DEPRECATE_HARD) +endif() + +if(DEBUG_POOL) + set(GIT_DEBUG_POOL 1) +endif() +add_feature_info(debugpool GIT_DEBUG_POOL "debug pool allocator") + +if(DEBUG_STRICT_ALLOC) + set(GIT_DEBUG_STRICT_ALLOC 1) +endif() +add_feature_info(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators") + +if(DEBUG_STRICT_OPEN) + set(GIT_DEBUG_STRICT_OPEN 1) +endif() +add_feature_info(debugopen GIT_DEBUG_STRICT_OPEN "path validation in open") + + +include(PkgBuildConfig) +include(SanitizeBool) + +# This variable will contain the libraries we need to put into +# libgit2.pc's Requires.private. That is, what we're linking to or +# what someone who's statically linking us needs to link to. +set(LIBGIT2_PC_REQUIRES "") +# This will be set later if we use the system's http-parser library or +# use iconv (OSX) and will be written to the Libs.private field in the +# pc file. +set(LIBGIT2_PC_LIBS "") + +set(LIBGIT2_INCLUDES + "${CMAKE_CURRENT_BINARY_DIR}" + "${PROJECT_SOURCE_DIR}/src/libgit2" + "${PROJECT_SOURCE_DIR}/include") + +if(HAVE_FUTIMENS) + set(GIT_USE_FUTIMENS 1) +endif () +add_feature_info(futimens GIT_USE_FUTIMENS "futimens support") + +check_prototype_definition(qsort_r + "void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, int (*compar)(void *, const void *, const void *))" + "" "stdlib.h" GIT_QSORT_R_BSD) + +check_prototype_definition(qsort_r + "void qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *arg)" + "" "stdlib.h" GIT_QSORT_R_GNU) + +check_function_exists(qsort_s GIT_QSORT_S) + +# Find required dependencies + +if(WIN32) + list(APPEND LIBGIT2_SYSTEM_LIBS ws2_32) +elseif(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") + list(APPEND LIBGIT2_SYSTEM_LIBS socket nsl) + list(APPEND LIBGIT2_PC_LIBS "-lsocket" "-lnsl") +elseif(CMAKE_SYSTEM_NAME MATCHES "Haiku") + list(APPEND LIBGIT2_SYSTEM_LIBS network) + list(APPEND LIBGIT2_PC_LIBS "-lnetwork") +endif() + +check_library_exists(rt clock_gettime "time.h" NEED_LIBRT) +if(NEED_LIBRT) + list(APPEND LIBGIT2_SYSTEM_LIBS rt) + list(APPEND LIBGIT2_PC_LIBS "-lrt") +endif() + +if(USE_THREADS) + list(APPEND LIBGIT2_SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT}) + list(APPEND LIBGIT2_PC_LIBS ${CMAKE_THREAD_LIBS_INIT}) +endif() +add_feature_info(threadsafe USE_THREADS "threadsafe support") + + +if(WIN32 AND EMBED_SSH_PATH) + file(GLOB SRC_SSH "${EMBED_SSH_PATH}/src/*.c") + list(SORT SRC_SSH) + target_sources(git2internal PRIVATE ${SRC_SSH}) + + list(APPEND LIBGIT2_SYSTEM_INCLUDES "${EMBED_SSH_PATH}/include") + file(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"") + set(GIT_SSH 1) +endif() + +include(SelectHTTPSBackend) +include(SelectHashes) +include(SelectHTTPParser) +include(SelectRegex) +include(SelectSSH) +include(SelectWinHTTP) +include(SelectZlib) + + +if(USE_SHA1 STREQUAL "CollisionDetection") + file(GLOB SRC_SHA1 hash/sha1/collisiondetect.* hash/sha1/sha1dc/*) +elseif(USE_SHA1 STREQUAL "OpenSSL") + file(GLOB SRC_SHA1 hash/sha1/openssl.*) +elseif(USE_SHA1 STREQUAL "CommonCrypto") + file(GLOB SRC_SHA1 hash/sha1/common_crypto.*) +elseif(USE_SHA1 STREQUAL "mbedTLS") + file(GLOB SRC_SHA1 hash/sha1/mbedtls.*) +elseif(USE_SHA1 STREQUAL "Win32") + file(GLOB SRC_SHA1 hash/sha1/win32.*) +elseif(USE_SHA1 STREQUAL "Generic") + file(GLOB SRC_SHA1 hash/sha1/generic.*) +endif() +list(APPEND SRC_SHA1 "hash/sha1.h") +target_sources(git2internal PRIVATE ${SRC_SHA1}) + +# Optional external dependency: ntlmclient +if(USE_NTLMCLIENT) + set(GIT_NTLM 1) + add_subdirectory("${PROJECT_SOURCE_DIR}/deps/ntlmclient" "${PROJECT_BINARY_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") +endif() +add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix") + +# Optional external dependency: GSSAPI + +include(SelectGSSAPI) + +# Optional external dependency: iconv +if(USE_ICONV) + find_package(Iconv) +endif() +if(ICONV_FOUND) + set(GIT_USE_ICONV 1) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ICONV_INCLUDE_DIR}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${ICONV_LIBRARIES}) + list(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES}) +endif() +add_feature_info(iconv GIT_USE_ICONV "iconv encoding conversion support") + + +if(USE_THREADS) + if(NOT WIN32) + find_package(Threads REQUIRED) + endif() + + set(GIT_THREADS 1) +endif() + +if(USE_NSEC) + set(GIT_USE_NSEC 1) +endif() + +if(HAVE_STRUCT_STAT_ST_MTIM) + set(GIT_USE_STAT_MTIM 1) +elseif(HAVE_STRUCT_STAT_ST_MTIMESPEC) + set(GIT_USE_STAT_MTIMESPEC 1) +elseif(HAVE_STRUCT_STAT_ST_MTIME_NSEC) + set(GIT_USE_STAT_MTIME_NSEC 1) +endif() + +target_compile_definitions(git2internal PRIVATE _FILE_OFFSET_BITS=64) + +# Collect sourcefiles +file(GLOB SRC_H + "${PROJECT_SOURCE_DIR}/include/git2.h" + "${PROJECT_SOURCE_DIR}/include/git2/*.h" + "${PROJECT_SOURCE_DIR}/include/git2/sys/*.h") +list(SORT SRC_H) +target_sources(git2internal PRIVATE ${SRC_H}) + +# On Windows use specific platform sources +if(WIN32 AND NOT CYGWIN) + set(WIN_RC "win32/git2.rc") + + file(GLOB SRC_OS win32/*.c win32/*.h) + list(SORT SRC_OS) + target_sources(git2internal PRIVATE ${SRC_OS}) +elseif(AMIGA) + target_compile_definitions(git2internal PRIVATE NO_ADDRINFO NO_READDIR_R NO_MMAP) +else() + file(GLOB SRC_OS unix/*.c unix/*.h) + list(SORT SRC_OS) + target_sources(git2internal PRIVATE ${SRC_OS}) +endif() + +if(USE_LEAK_CHECKER STREQUAL "valgrind") + target_compile_definitions(git2internal PRIVATE VALGRIND) +endif() + +file(GLOB SRC_GIT2 *.c *.h + allocators/*.c allocators/*.h + streams/*.c streams/*.h + transports/*.c transports/*.h + xdiff/*.c xdiff/*.h) +list(SORT SRC_GIT2) +target_sources(git2internal PRIVATE ${SRC_GIT2}) + +if(APPLE) + # The old Secure Transport API has been deprecated in macOS 10.15. + set_source_files_properties(streams/stransport.c PROPERTIES COMPILE_FLAGS -Wno-deprecated) +endif() + +# the xdiff dependency is not (yet) warning-free, disable warnings as +# errors for the xdiff sources until we've sorted them out + if(MSVC) + set_source_files_properties(xdiff/xdiffi.c PROPERTIES COMPILE_FLAGS -WX-) + set_source_files_properties(xdiff/xemit.c PROPERTIES COMPILE_FLAGS -WX-) + set_source_files_properties(xdiff/xhistogram.c PROPERTIES COMPILE_FLAGS -WX-) + set_source_files_properties(xdiff/xmerge.c PROPERTIES COMPILE_FLAGS -WX-) + set_source_files_properties(xdiff/xutils.c PROPERTIES COMPILE_FLAGS -WX-) + set_source_files_properties(xdiff/xpatience.c PROPERTIES COMPILE_FLAGS -WX-) +else() + set_source_files_properties(xdiff/xdiffi.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-parameter") + set_source_files_properties(xdiff/xemit.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-unused-parameter") + set_source_files_properties(xdiff/xhistogram.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") + set_source_files_properties(xdiff/xutils.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") + set_source_files_properties(xdiff/xpatience.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") + endif() + +# Determine architecture of the machine +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(GIT_ARCH_64 1) +elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(GIT_ARCH_32 1) +elseif(CMAKE_SIZEOF_VOID_P) + message(FATAL_ERROR "Unsupported architecture (pointer size is ${CMAKE_SIZEOF_VOID_P} bytes)") +else() + message(FATAL_ERROR "Unsupported architecture (CMAKE_SIZEOF_VOID_P is unset)") +endif() + +configure_file(features.h.in git2/sys/features.h) + +ide_split_sources(git2internal) +list(APPEND LIBGIT2_OBJECTS $ ${LIBGIT2_DEPENDENCY_OBJECTS}) + +target_include_directories(git2internal PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${PROJECT_SOURCE_DIR}/include) +target_include_directories(git2internal SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) + +set(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE) +set(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE) +set(LIBGIT2_DEPENDENCY_INCLUDES ${LIBGIT2_DEPENDENCY_INCLUDES} PARENT_SCOPE) +set(LIBGIT2_DEPENDENCY_OBJECTS ${LIBGIT2_DEPENDENCY_OBJECTS} PARENT_SCOPE) +set(LIBGIT2_SYSTEM_INCLUDES ${LIBGIT2_SYSTEM_INCLUDES} PARENT_SCOPE) +set(LIBGIT2_SYSTEM_LIBS ${LIBGIT2_SYSTEM_LIBS} PARENT_SCOPE) + +if(XCODE_VERSION) + # This is required for Xcode to actually link the libgit2 library + # when using only object libraries. + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.c "") + list(APPEND LIBGIT2_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/dummy.c) +endif() + +# Compile and link libgit2 +add_library(git2 ${WIN_RC} ${LIBGIT2_OBJECTS}) +target_link_libraries(git2 ${LIBGIT2_SYSTEM_LIBS}) + +set_target_properties(git2 PROPERTIES C_STANDARD 90) +set_target_properties(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) +set_target_properties(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) +set_target_properties(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) + +# Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240) +# Win64+MSVC+static libs = linker error +if(MSVC AND GIT_ARCH_64 AND NOT BUILD_SHARED_LIBS) + set_target_properties(git2 PROPERTIES STATIC_LIBRARY_FLAGS "/MACHINE:x64") +endif() + +ide_split_sources(git2) + +if(SONAME) + set_target_properties(git2 PROPERTIES VERSION ${libgit2_VERSION}) + set_target_properties(git2 PROPERTIES SOVERSION "${libgit2_VERSION_MAJOR}.${libgit2_VERSION_MINOR}") + if(LIBGIT2_FILENAME) + target_compile_definitions(git2 PRIVATE LIBGIT2_FILENAME=\"${LIBGIT2_FILENAME}\") + set_target_properties(git2 PROPERTIES OUTPUT_NAME ${LIBGIT2_FILENAME}) + elseif(DEFINED LIBGIT2_PREFIX) + set_target_properties(git2 PROPERTIES PREFIX "${LIBGIT2_PREFIX}") + endif() +endif() + +pkg_build_config(NAME libgit2 + VERSION ${libgit2_VERSION} + DESCRIPTION "The git library, take 2" + LIBS_SELF git2 + PRIVATE_LIBS ${LIBGIT2_PC_LIBS} + REQUIRES ${LIBGIT2_PC_REQUIRES} +) + +if(MSVC_IDE) + # Precompiled headers + set_target_properties(git2 PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") + set_source_files_properties(win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h") +endif() + +# Install +install(TARGETS git2 + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) +install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(FILES ${PROJECT_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/alloc.c b/src/libgit2/alloc.c similarity index 100% rename from src/alloc.c rename to src/libgit2/alloc.c diff --git a/src/alloc.h b/src/libgit2/alloc.h similarity index 100% rename from src/alloc.h rename to src/libgit2/alloc.h diff --git a/src/allocators/failalloc.c b/src/libgit2/allocators/failalloc.c similarity index 100% rename from src/allocators/failalloc.c rename to src/libgit2/allocators/failalloc.c diff --git a/src/allocators/failalloc.h b/src/libgit2/allocators/failalloc.h similarity index 100% rename from src/allocators/failalloc.h rename to src/libgit2/allocators/failalloc.h diff --git a/src/allocators/stdalloc.c b/src/libgit2/allocators/stdalloc.c similarity index 100% rename from src/allocators/stdalloc.c rename to src/libgit2/allocators/stdalloc.c diff --git a/src/allocators/stdalloc.h b/src/libgit2/allocators/stdalloc.h similarity index 100% rename from src/allocators/stdalloc.h rename to src/libgit2/allocators/stdalloc.h diff --git a/src/allocators/win32_leakcheck.c b/src/libgit2/allocators/win32_leakcheck.c similarity index 100% rename from src/allocators/win32_leakcheck.c rename to src/libgit2/allocators/win32_leakcheck.c diff --git a/src/allocators/win32_leakcheck.h b/src/libgit2/allocators/win32_leakcheck.h similarity index 100% rename from src/allocators/win32_leakcheck.h rename to src/libgit2/allocators/win32_leakcheck.h diff --git a/src/annotated_commit.c b/src/libgit2/annotated_commit.c similarity index 100% rename from src/annotated_commit.c rename to src/libgit2/annotated_commit.c diff --git a/src/annotated_commit.h b/src/libgit2/annotated_commit.h similarity index 100% rename from src/annotated_commit.h rename to src/libgit2/annotated_commit.h diff --git a/src/apply.c b/src/libgit2/apply.c similarity index 100% rename from src/apply.c rename to src/libgit2/apply.c diff --git a/src/apply.h b/src/libgit2/apply.h similarity index 100% rename from src/apply.h rename to src/libgit2/apply.h diff --git a/src/array.h b/src/libgit2/array.h similarity index 100% rename from src/array.h rename to src/libgit2/array.h diff --git a/src/assert_safe.h b/src/libgit2/assert_safe.h similarity index 100% rename from src/assert_safe.h rename to src/libgit2/assert_safe.h diff --git a/src/attr.c b/src/libgit2/attr.c similarity index 100% rename from src/attr.c rename to src/libgit2/attr.c diff --git a/src/attr.h b/src/libgit2/attr.h similarity index 100% rename from src/attr.h rename to src/libgit2/attr.h diff --git a/src/attr_file.c b/src/libgit2/attr_file.c similarity index 100% rename from src/attr_file.c rename to src/libgit2/attr_file.c diff --git a/src/attr_file.h b/src/libgit2/attr_file.h similarity index 100% rename from src/attr_file.h rename to src/libgit2/attr_file.h diff --git a/src/attrcache.c b/src/libgit2/attrcache.c similarity index 100% rename from src/attrcache.c rename to src/libgit2/attrcache.c diff --git a/src/attrcache.h b/src/libgit2/attrcache.h similarity index 100% rename from src/attrcache.h rename to src/libgit2/attrcache.h diff --git a/src/bitvec.h b/src/libgit2/bitvec.h similarity index 100% rename from src/bitvec.h rename to src/libgit2/bitvec.h diff --git a/src/blame.c b/src/libgit2/blame.c similarity index 100% rename from src/blame.c rename to src/libgit2/blame.c diff --git a/src/blame.h b/src/libgit2/blame.h similarity index 100% rename from src/blame.h rename to src/libgit2/blame.h diff --git a/src/blame_git.c b/src/libgit2/blame_git.c similarity index 100% rename from src/blame_git.c rename to src/libgit2/blame_git.c diff --git a/src/blame_git.h b/src/libgit2/blame_git.h similarity index 100% rename from src/blame_git.h rename to src/libgit2/blame_git.h diff --git a/src/blob.c b/src/libgit2/blob.c similarity index 100% rename from src/blob.c rename to src/libgit2/blob.c diff --git a/src/blob.h b/src/libgit2/blob.h similarity index 100% rename from src/blob.h rename to src/libgit2/blob.h diff --git a/src/branch.c b/src/libgit2/branch.c similarity index 100% rename from src/branch.c rename to src/libgit2/branch.c diff --git a/src/branch.h b/src/libgit2/branch.h similarity index 100% rename from src/branch.h rename to src/libgit2/branch.h diff --git a/src/buf.c b/src/libgit2/buf.c similarity index 100% rename from src/buf.c rename to src/libgit2/buf.c diff --git a/src/buf.h b/src/libgit2/buf.h similarity index 100% rename from src/buf.h rename to src/libgit2/buf.h diff --git a/src/cache.c b/src/libgit2/cache.c similarity index 100% rename from src/cache.c rename to src/libgit2/cache.c diff --git a/src/cache.h b/src/libgit2/cache.h similarity index 100% rename from src/cache.h rename to src/libgit2/cache.h diff --git a/src/cc-compat.h b/src/libgit2/cc-compat.h similarity index 100% rename from src/cc-compat.h rename to src/libgit2/cc-compat.h diff --git a/src/checkout.c b/src/libgit2/checkout.c similarity index 100% rename from src/checkout.c rename to src/libgit2/checkout.c diff --git a/src/checkout.h b/src/libgit2/checkout.h similarity index 100% rename from src/checkout.h rename to src/libgit2/checkout.h diff --git a/src/cherrypick.c b/src/libgit2/cherrypick.c similarity index 100% rename from src/cherrypick.c rename to src/libgit2/cherrypick.c diff --git a/src/clone.c b/src/libgit2/clone.c similarity index 100% rename from src/clone.c rename to src/libgit2/clone.c diff --git a/src/clone.h b/src/libgit2/clone.h similarity index 100% rename from src/clone.h rename to src/libgit2/clone.h diff --git a/src/commit.c b/src/libgit2/commit.c similarity index 100% rename from src/commit.c rename to src/libgit2/commit.c diff --git a/src/commit.h b/src/libgit2/commit.h similarity index 100% rename from src/commit.h rename to src/libgit2/commit.h diff --git a/src/commit_graph.c b/src/libgit2/commit_graph.c similarity index 100% rename from src/commit_graph.c rename to src/libgit2/commit_graph.c diff --git a/src/commit_graph.h b/src/libgit2/commit_graph.h similarity index 100% rename from src/commit_graph.h rename to src/libgit2/commit_graph.h diff --git a/src/commit_list.c b/src/libgit2/commit_list.c similarity index 100% rename from src/commit_list.c rename to src/libgit2/commit_list.c diff --git a/src/commit_list.h b/src/libgit2/commit_list.h similarity index 100% rename from src/commit_list.h rename to src/libgit2/commit_list.h diff --git a/src/common.h b/src/libgit2/common.h similarity index 100% rename from src/common.h rename to src/libgit2/common.h diff --git a/src/config.c b/src/libgit2/config.c similarity index 100% rename from src/config.c rename to src/libgit2/config.c diff --git a/src/config.h b/src/libgit2/config.h similarity index 100% rename from src/config.h rename to src/libgit2/config.h diff --git a/src/config_backend.h b/src/libgit2/config_backend.h similarity index 100% rename from src/config_backend.h rename to src/libgit2/config_backend.h diff --git a/src/config_cache.c b/src/libgit2/config_cache.c similarity index 100% rename from src/config_cache.c rename to src/libgit2/config_cache.c diff --git a/src/config_entries.c b/src/libgit2/config_entries.c similarity index 100% rename from src/config_entries.c rename to src/libgit2/config_entries.c diff --git a/src/config_entries.h b/src/libgit2/config_entries.h similarity index 100% rename from src/config_entries.h rename to src/libgit2/config_entries.h diff --git a/src/config_file.c b/src/libgit2/config_file.c similarity index 100% rename from src/config_file.c rename to src/libgit2/config_file.c diff --git a/src/config_mem.c b/src/libgit2/config_mem.c similarity index 100% rename from src/config_mem.c rename to src/libgit2/config_mem.c diff --git a/src/config_parse.c b/src/libgit2/config_parse.c similarity index 100% rename from src/config_parse.c rename to src/libgit2/config_parse.c diff --git a/src/config_parse.h b/src/libgit2/config_parse.h similarity index 100% rename from src/config_parse.h rename to src/libgit2/config_parse.h diff --git a/src/config_snapshot.c b/src/libgit2/config_snapshot.c similarity index 100% rename from src/config_snapshot.c rename to src/libgit2/config_snapshot.c diff --git a/src/crlf.c b/src/libgit2/crlf.c similarity index 100% rename from src/crlf.c rename to src/libgit2/crlf.c diff --git a/src/date.c b/src/libgit2/date.c similarity index 100% rename from src/date.c rename to src/libgit2/date.c diff --git a/src/date.h b/src/libgit2/date.h similarity index 100% rename from src/date.h rename to src/libgit2/date.h diff --git a/src/delta.c b/src/libgit2/delta.c similarity index 100% rename from src/delta.c rename to src/libgit2/delta.c diff --git a/src/delta.h b/src/libgit2/delta.h similarity index 100% rename from src/delta.h rename to src/libgit2/delta.h diff --git a/src/describe.c b/src/libgit2/describe.c similarity index 100% rename from src/describe.c rename to src/libgit2/describe.c diff --git a/src/diff.c b/src/libgit2/diff.c similarity index 100% rename from src/diff.c rename to src/libgit2/diff.c diff --git a/src/diff.h b/src/libgit2/diff.h similarity index 100% rename from src/diff.h rename to src/libgit2/diff.h diff --git a/src/diff_driver.c b/src/libgit2/diff_driver.c similarity index 100% rename from src/diff_driver.c rename to src/libgit2/diff_driver.c diff --git a/src/diff_driver.h b/src/libgit2/diff_driver.h similarity index 100% rename from src/diff_driver.h rename to src/libgit2/diff_driver.h diff --git a/src/diff_file.c b/src/libgit2/diff_file.c similarity index 100% rename from src/diff_file.c rename to src/libgit2/diff_file.c diff --git a/src/diff_file.h b/src/libgit2/diff_file.h similarity index 100% rename from src/diff_file.h rename to src/libgit2/diff_file.h diff --git a/src/diff_generate.c b/src/libgit2/diff_generate.c similarity index 100% rename from src/diff_generate.c rename to src/libgit2/diff_generate.c diff --git a/src/diff_generate.h b/src/libgit2/diff_generate.h similarity index 100% rename from src/diff_generate.h rename to src/libgit2/diff_generate.h diff --git a/src/diff_parse.c b/src/libgit2/diff_parse.c similarity index 100% rename from src/diff_parse.c rename to src/libgit2/diff_parse.c diff --git a/src/diff_parse.h b/src/libgit2/diff_parse.h similarity index 100% rename from src/diff_parse.h rename to src/libgit2/diff_parse.h diff --git a/src/diff_print.c b/src/libgit2/diff_print.c similarity index 100% rename from src/diff_print.c rename to src/libgit2/diff_print.c diff --git a/src/diff_stats.c b/src/libgit2/diff_stats.c similarity index 100% rename from src/diff_stats.c rename to src/libgit2/diff_stats.c diff --git a/src/diff_stats.h b/src/libgit2/diff_stats.h similarity index 100% rename from src/diff_stats.h rename to src/libgit2/diff_stats.h diff --git a/src/diff_tform.c b/src/libgit2/diff_tform.c similarity index 100% rename from src/diff_tform.c rename to src/libgit2/diff_tform.c diff --git a/src/diff_tform.h b/src/libgit2/diff_tform.h similarity index 100% rename from src/diff_tform.h rename to src/libgit2/diff_tform.h diff --git a/src/diff_xdiff.c b/src/libgit2/diff_xdiff.c similarity index 100% rename from src/diff_xdiff.c rename to src/libgit2/diff_xdiff.c diff --git a/src/diff_xdiff.h b/src/libgit2/diff_xdiff.h similarity index 100% rename from src/diff_xdiff.h rename to src/libgit2/diff_xdiff.h diff --git a/src/email.c b/src/libgit2/email.c similarity index 100% rename from src/email.c rename to src/libgit2/email.c diff --git a/src/email.h b/src/libgit2/email.h similarity index 100% rename from src/email.h rename to src/libgit2/email.h diff --git a/src/errors.c b/src/libgit2/errors.c similarity index 100% rename from src/errors.c rename to src/libgit2/errors.c diff --git a/src/errors.h b/src/libgit2/errors.h similarity index 100% rename from src/errors.h rename to src/libgit2/errors.h diff --git a/src/features.h.in b/src/libgit2/features.h.in similarity index 100% rename from src/features.h.in rename to src/libgit2/features.h.in diff --git a/src/fetch.c b/src/libgit2/fetch.c similarity index 100% rename from src/fetch.c rename to src/libgit2/fetch.c diff --git a/src/fetch.h b/src/libgit2/fetch.h similarity index 100% rename from src/fetch.h rename to src/libgit2/fetch.h diff --git a/src/fetchhead.c b/src/libgit2/fetchhead.c similarity index 100% rename from src/fetchhead.c rename to src/libgit2/fetchhead.c diff --git a/src/fetchhead.h b/src/libgit2/fetchhead.h similarity index 100% rename from src/fetchhead.h rename to src/libgit2/fetchhead.h diff --git a/src/filebuf.c b/src/libgit2/filebuf.c similarity index 100% rename from src/filebuf.c rename to src/libgit2/filebuf.c diff --git a/src/filebuf.h b/src/libgit2/filebuf.h similarity index 100% rename from src/filebuf.h rename to src/libgit2/filebuf.h diff --git a/src/filter.c b/src/libgit2/filter.c similarity index 100% rename from src/filter.c rename to src/libgit2/filter.c diff --git a/src/filter.h b/src/libgit2/filter.h similarity index 100% rename from src/filter.h rename to src/libgit2/filter.h diff --git a/src/fs_path.c b/src/libgit2/fs_path.c similarity index 100% rename from src/fs_path.c rename to src/libgit2/fs_path.c diff --git a/src/fs_path.h b/src/libgit2/fs_path.h similarity index 100% rename from src/fs_path.h rename to src/libgit2/fs_path.h diff --git a/src/futils.c b/src/libgit2/futils.c similarity index 100% rename from src/futils.c rename to src/libgit2/futils.c diff --git a/src/futils.h b/src/libgit2/futils.h similarity index 100% rename from src/futils.h rename to src/libgit2/futils.h diff --git a/src/graph.c b/src/libgit2/graph.c similarity index 100% rename from src/graph.c rename to src/libgit2/graph.c diff --git a/src/hash.c b/src/libgit2/hash.c similarity index 100% rename from src/hash.c rename to src/libgit2/hash.c diff --git a/src/hash.h b/src/libgit2/hash.h similarity index 100% rename from src/hash.h rename to src/libgit2/hash.h diff --git a/src/hash/sha1.h b/src/libgit2/hash/sha1.h similarity index 100% rename from src/hash/sha1.h rename to src/libgit2/hash/sha1.h diff --git a/src/hash/sha1/collisiondetect.c b/src/libgit2/hash/sha1/collisiondetect.c similarity index 100% rename from src/hash/sha1/collisiondetect.c rename to src/libgit2/hash/sha1/collisiondetect.c diff --git a/src/hash/sha1/collisiondetect.h b/src/libgit2/hash/sha1/collisiondetect.h similarity index 100% rename from src/hash/sha1/collisiondetect.h rename to src/libgit2/hash/sha1/collisiondetect.h diff --git a/src/hash/sha1/common_crypto.c b/src/libgit2/hash/sha1/common_crypto.c similarity index 100% rename from src/hash/sha1/common_crypto.c rename to src/libgit2/hash/sha1/common_crypto.c diff --git a/src/hash/sha1/common_crypto.h b/src/libgit2/hash/sha1/common_crypto.h similarity index 100% rename from src/hash/sha1/common_crypto.h rename to src/libgit2/hash/sha1/common_crypto.h diff --git a/src/hash/sha1/generic.c b/src/libgit2/hash/sha1/generic.c similarity index 100% rename from src/hash/sha1/generic.c rename to src/libgit2/hash/sha1/generic.c diff --git a/src/hash/sha1/generic.h b/src/libgit2/hash/sha1/generic.h similarity index 100% rename from src/hash/sha1/generic.h rename to src/libgit2/hash/sha1/generic.h diff --git a/src/hash/sha1/mbedtls.c b/src/libgit2/hash/sha1/mbedtls.c similarity index 100% rename from src/hash/sha1/mbedtls.c rename to src/libgit2/hash/sha1/mbedtls.c diff --git a/src/hash/sha1/mbedtls.h b/src/libgit2/hash/sha1/mbedtls.h similarity index 100% rename from src/hash/sha1/mbedtls.h rename to src/libgit2/hash/sha1/mbedtls.h diff --git a/src/hash/sha1/openssl.c b/src/libgit2/hash/sha1/openssl.c similarity index 100% rename from src/hash/sha1/openssl.c rename to src/libgit2/hash/sha1/openssl.c diff --git a/src/hash/sha1/openssl.h b/src/libgit2/hash/sha1/openssl.h similarity index 100% rename from src/hash/sha1/openssl.h rename to src/libgit2/hash/sha1/openssl.h diff --git a/src/hash/sha1/sha1dc/sha1.c b/src/libgit2/hash/sha1/sha1dc/sha1.c similarity index 100% rename from src/hash/sha1/sha1dc/sha1.c rename to src/libgit2/hash/sha1/sha1dc/sha1.c diff --git a/src/hash/sha1/sha1dc/sha1.h b/src/libgit2/hash/sha1/sha1dc/sha1.h similarity index 100% rename from src/hash/sha1/sha1dc/sha1.h rename to src/libgit2/hash/sha1/sha1dc/sha1.h diff --git a/src/hash/sha1/sha1dc/ubc_check.c b/src/libgit2/hash/sha1/sha1dc/ubc_check.c similarity index 100% rename from src/hash/sha1/sha1dc/ubc_check.c rename to src/libgit2/hash/sha1/sha1dc/ubc_check.c diff --git a/src/hash/sha1/sha1dc/ubc_check.h b/src/libgit2/hash/sha1/sha1dc/ubc_check.h similarity index 100% rename from src/hash/sha1/sha1dc/ubc_check.h rename to src/libgit2/hash/sha1/sha1dc/ubc_check.h diff --git a/src/hash/sha1/win32.c b/src/libgit2/hash/sha1/win32.c similarity index 100% rename from src/hash/sha1/win32.c rename to src/libgit2/hash/sha1/win32.c diff --git a/src/hash/sha1/win32.h b/src/libgit2/hash/sha1/win32.h similarity index 100% rename from src/hash/sha1/win32.h rename to src/libgit2/hash/sha1/win32.h diff --git a/src/hashsig.c b/src/libgit2/hashsig.c similarity index 100% rename from src/hashsig.c rename to src/libgit2/hashsig.c diff --git a/src/ident.c b/src/libgit2/ident.c similarity index 100% rename from src/ident.c rename to src/libgit2/ident.c diff --git a/src/idxmap.c b/src/libgit2/idxmap.c similarity index 100% rename from src/idxmap.c rename to src/libgit2/idxmap.c diff --git a/src/idxmap.h b/src/libgit2/idxmap.h similarity index 100% rename from src/idxmap.h rename to src/libgit2/idxmap.h diff --git a/src/ignore.c b/src/libgit2/ignore.c similarity index 100% rename from src/ignore.c rename to src/libgit2/ignore.c diff --git a/src/ignore.h b/src/libgit2/ignore.h similarity index 100% rename from src/ignore.h rename to src/libgit2/ignore.h diff --git a/src/index.c b/src/libgit2/index.c similarity index 100% rename from src/index.c rename to src/libgit2/index.c diff --git a/src/index.h b/src/libgit2/index.h similarity index 100% rename from src/index.h rename to src/libgit2/index.h diff --git a/src/indexer.c b/src/libgit2/indexer.c similarity index 100% rename from src/indexer.c rename to src/libgit2/indexer.c diff --git a/src/indexer.h b/src/libgit2/indexer.h similarity index 100% rename from src/indexer.h rename to src/libgit2/indexer.h diff --git a/src/integer.h b/src/libgit2/integer.h similarity index 100% rename from src/integer.h rename to src/libgit2/integer.h diff --git a/src/iterator.c b/src/libgit2/iterator.c similarity index 100% rename from src/iterator.c rename to src/libgit2/iterator.c diff --git a/src/iterator.h b/src/libgit2/iterator.h similarity index 100% rename from src/iterator.h rename to src/libgit2/iterator.h diff --git a/src/khash.h b/src/libgit2/khash.h similarity index 100% rename from src/khash.h rename to src/libgit2/khash.h diff --git a/src/libgit2.c b/src/libgit2/libgit2.c similarity index 100% rename from src/libgit2.c rename to src/libgit2/libgit2.c diff --git a/src/libgit2.h b/src/libgit2/libgit2.h similarity index 100% rename from src/libgit2.h rename to src/libgit2/libgit2.h diff --git a/src/mailmap.c b/src/libgit2/mailmap.c similarity index 100% rename from src/mailmap.c rename to src/libgit2/mailmap.c diff --git a/src/mailmap.h b/src/libgit2/mailmap.h similarity index 100% rename from src/mailmap.h rename to src/libgit2/mailmap.h diff --git a/src/map.h b/src/libgit2/map.h similarity index 100% rename from src/map.h rename to src/libgit2/map.h diff --git a/src/merge.c b/src/libgit2/merge.c similarity index 100% rename from src/merge.c rename to src/libgit2/merge.c diff --git a/src/merge.h b/src/libgit2/merge.h similarity index 100% rename from src/merge.h rename to src/libgit2/merge.h diff --git a/src/merge_driver.c b/src/libgit2/merge_driver.c similarity index 100% rename from src/merge_driver.c rename to src/libgit2/merge_driver.c diff --git a/src/merge_driver.h b/src/libgit2/merge_driver.h similarity index 100% rename from src/merge_driver.h rename to src/libgit2/merge_driver.h diff --git a/src/merge_file.c b/src/libgit2/merge_file.c similarity index 100% rename from src/merge_file.c rename to src/libgit2/merge_file.c diff --git a/src/message.c b/src/libgit2/message.c similarity index 100% rename from src/message.c rename to src/libgit2/message.c diff --git a/src/midx.c b/src/libgit2/midx.c similarity index 100% rename from src/midx.c rename to src/libgit2/midx.c diff --git a/src/midx.h b/src/libgit2/midx.h similarity index 100% rename from src/midx.h rename to src/libgit2/midx.h diff --git a/src/mwindow.c b/src/libgit2/mwindow.c similarity index 100% rename from src/mwindow.c rename to src/libgit2/mwindow.c diff --git a/src/mwindow.h b/src/libgit2/mwindow.h similarity index 100% rename from src/mwindow.h rename to src/libgit2/mwindow.h diff --git a/src/net.c b/src/libgit2/net.c similarity index 100% rename from src/net.c rename to src/libgit2/net.c diff --git a/src/net.h b/src/libgit2/net.h similarity index 100% rename from src/net.h rename to src/libgit2/net.h diff --git a/src/netops.c b/src/libgit2/netops.c similarity index 100% rename from src/netops.c rename to src/libgit2/netops.c diff --git a/src/netops.h b/src/libgit2/netops.h similarity index 100% rename from src/netops.h rename to src/libgit2/netops.h diff --git a/src/notes.c b/src/libgit2/notes.c similarity index 100% rename from src/notes.c rename to src/libgit2/notes.c diff --git a/src/notes.h b/src/libgit2/notes.h similarity index 100% rename from src/notes.h rename to src/libgit2/notes.h diff --git a/src/object.c b/src/libgit2/object.c similarity index 100% rename from src/object.c rename to src/libgit2/object.c diff --git a/src/object.h b/src/libgit2/object.h similarity index 100% rename from src/object.h rename to src/libgit2/object.h diff --git a/src/object_api.c b/src/libgit2/object_api.c similarity index 100% rename from src/object_api.c rename to src/libgit2/object_api.c diff --git a/src/odb.c b/src/libgit2/odb.c similarity index 100% rename from src/odb.c rename to src/libgit2/odb.c diff --git a/src/odb.h b/src/libgit2/odb.h similarity index 100% rename from src/odb.h rename to src/libgit2/odb.h diff --git a/src/odb_loose.c b/src/libgit2/odb_loose.c similarity index 100% rename from src/odb_loose.c rename to src/libgit2/odb_loose.c diff --git a/src/odb_mempack.c b/src/libgit2/odb_mempack.c similarity index 100% rename from src/odb_mempack.c rename to src/libgit2/odb_mempack.c diff --git a/src/odb_pack.c b/src/libgit2/odb_pack.c similarity index 100% rename from src/odb_pack.c rename to src/libgit2/odb_pack.c diff --git a/src/offmap.c b/src/libgit2/offmap.c similarity index 100% rename from src/offmap.c rename to src/libgit2/offmap.c diff --git a/src/offmap.h b/src/libgit2/offmap.h similarity index 100% rename from src/offmap.h rename to src/libgit2/offmap.h diff --git a/src/oid.c b/src/libgit2/oid.c similarity index 100% rename from src/oid.c rename to src/libgit2/oid.c diff --git a/src/oid.h b/src/libgit2/oid.h similarity index 100% rename from src/oid.h rename to src/libgit2/oid.h diff --git a/src/oidarray.c b/src/libgit2/oidarray.c similarity index 100% rename from src/oidarray.c rename to src/libgit2/oidarray.c diff --git a/src/oidarray.h b/src/libgit2/oidarray.h similarity index 100% rename from src/oidarray.h rename to src/libgit2/oidarray.h diff --git a/src/oidmap.c b/src/libgit2/oidmap.c similarity index 100% rename from src/oidmap.c rename to src/libgit2/oidmap.c diff --git a/src/oidmap.h b/src/libgit2/oidmap.h similarity index 100% rename from src/oidmap.h rename to src/libgit2/oidmap.h diff --git a/src/pack-objects.c b/src/libgit2/pack-objects.c similarity index 100% rename from src/pack-objects.c rename to src/libgit2/pack-objects.c diff --git a/src/pack-objects.h b/src/libgit2/pack-objects.h similarity index 100% rename from src/pack-objects.h rename to src/libgit2/pack-objects.h diff --git a/src/pack.c b/src/libgit2/pack.c similarity index 100% rename from src/pack.c rename to src/libgit2/pack.c diff --git a/src/pack.h b/src/libgit2/pack.h similarity index 100% rename from src/pack.h rename to src/libgit2/pack.h diff --git a/src/parse.c b/src/libgit2/parse.c similarity index 100% rename from src/parse.c rename to src/libgit2/parse.c diff --git a/src/parse.h b/src/libgit2/parse.h similarity index 100% rename from src/parse.h rename to src/libgit2/parse.h diff --git a/src/patch.c b/src/libgit2/patch.c similarity index 100% rename from src/patch.c rename to src/libgit2/patch.c diff --git a/src/patch.h b/src/libgit2/patch.h similarity index 100% rename from src/patch.h rename to src/libgit2/patch.h diff --git a/src/patch_generate.c b/src/libgit2/patch_generate.c similarity index 100% rename from src/patch_generate.c rename to src/libgit2/patch_generate.c diff --git a/src/patch_generate.h b/src/libgit2/patch_generate.h similarity index 100% rename from src/patch_generate.h rename to src/libgit2/patch_generate.h diff --git a/src/patch_parse.c b/src/libgit2/patch_parse.c similarity index 100% rename from src/patch_parse.c rename to src/libgit2/patch_parse.c diff --git a/src/patch_parse.h b/src/libgit2/patch_parse.h similarity index 100% rename from src/patch_parse.h rename to src/libgit2/patch_parse.h diff --git a/src/path.c b/src/libgit2/path.c similarity index 100% rename from src/path.c rename to src/libgit2/path.c diff --git a/src/path.h b/src/libgit2/path.h similarity index 100% rename from src/path.h rename to src/libgit2/path.h diff --git a/src/pathspec.c b/src/libgit2/pathspec.c similarity index 100% rename from src/pathspec.c rename to src/libgit2/pathspec.c diff --git a/src/pathspec.h b/src/libgit2/pathspec.h similarity index 100% rename from src/pathspec.h rename to src/libgit2/pathspec.h diff --git a/src/pool.c b/src/libgit2/pool.c similarity index 100% rename from src/pool.c rename to src/libgit2/pool.c diff --git a/src/pool.h b/src/libgit2/pool.h similarity index 100% rename from src/pool.h rename to src/libgit2/pool.h diff --git a/src/posix.c b/src/libgit2/posix.c similarity index 100% rename from src/posix.c rename to src/libgit2/posix.c diff --git a/src/posix.h b/src/libgit2/posix.h similarity index 100% rename from src/posix.h rename to src/libgit2/posix.h diff --git a/src/pqueue.c b/src/libgit2/pqueue.c similarity index 100% rename from src/pqueue.c rename to src/libgit2/pqueue.c diff --git a/src/pqueue.h b/src/libgit2/pqueue.h similarity index 100% rename from src/pqueue.h rename to src/libgit2/pqueue.h diff --git a/src/proxy.c b/src/libgit2/proxy.c similarity index 100% rename from src/proxy.c rename to src/libgit2/proxy.c diff --git a/src/proxy.h b/src/libgit2/proxy.h similarity index 100% rename from src/proxy.h rename to src/libgit2/proxy.h diff --git a/src/push.c b/src/libgit2/push.c similarity index 100% rename from src/push.c rename to src/libgit2/push.c diff --git a/src/push.h b/src/libgit2/push.h similarity index 100% rename from src/push.h rename to src/libgit2/push.h diff --git a/src/reader.c b/src/libgit2/reader.c similarity index 100% rename from src/reader.c rename to src/libgit2/reader.c diff --git a/src/reader.h b/src/libgit2/reader.h similarity index 100% rename from src/reader.h rename to src/libgit2/reader.h diff --git a/src/rebase.c b/src/libgit2/rebase.c similarity index 100% rename from src/rebase.c rename to src/libgit2/rebase.c diff --git a/src/refdb.c b/src/libgit2/refdb.c similarity index 100% rename from src/refdb.c rename to src/libgit2/refdb.c diff --git a/src/refdb.h b/src/libgit2/refdb.h similarity index 100% rename from src/refdb.h rename to src/libgit2/refdb.h diff --git a/src/refdb_fs.c b/src/libgit2/refdb_fs.c similarity index 100% rename from src/refdb_fs.c rename to src/libgit2/refdb_fs.c diff --git a/src/reflog.c b/src/libgit2/reflog.c similarity index 100% rename from src/reflog.c rename to src/libgit2/reflog.c diff --git a/src/reflog.h b/src/libgit2/reflog.h similarity index 100% rename from src/reflog.h rename to src/libgit2/reflog.h diff --git a/src/refs.c b/src/libgit2/refs.c similarity index 100% rename from src/refs.c rename to src/libgit2/refs.c diff --git a/src/refs.h b/src/libgit2/refs.h similarity index 100% rename from src/refs.h rename to src/libgit2/refs.h diff --git a/src/refspec.c b/src/libgit2/refspec.c similarity index 100% rename from src/refspec.c rename to src/libgit2/refspec.c diff --git a/src/refspec.h b/src/libgit2/refspec.h similarity index 100% rename from src/refspec.h rename to src/libgit2/refspec.h diff --git a/src/regexp.c b/src/libgit2/regexp.c similarity index 100% rename from src/regexp.c rename to src/libgit2/regexp.c diff --git a/src/regexp.h b/src/libgit2/regexp.h similarity index 100% rename from src/regexp.h rename to src/libgit2/regexp.h diff --git a/src/remote.c b/src/libgit2/remote.c similarity index 100% rename from src/remote.c rename to src/libgit2/remote.c diff --git a/src/remote.h b/src/libgit2/remote.h similarity index 100% rename from src/remote.h rename to src/libgit2/remote.h diff --git a/src/repo_template.h b/src/libgit2/repo_template.h similarity index 100% rename from src/repo_template.h rename to src/libgit2/repo_template.h diff --git a/src/repository.c b/src/libgit2/repository.c similarity index 100% rename from src/repository.c rename to src/libgit2/repository.c diff --git a/src/repository.h b/src/libgit2/repository.h similarity index 100% rename from src/repository.h rename to src/libgit2/repository.h diff --git a/src/reset.c b/src/libgit2/reset.c similarity index 100% rename from src/reset.c rename to src/libgit2/reset.c diff --git a/src/revert.c b/src/libgit2/revert.c similarity index 100% rename from src/revert.c rename to src/libgit2/revert.c diff --git a/src/revparse.c b/src/libgit2/revparse.c similarity index 100% rename from src/revparse.c rename to src/libgit2/revparse.c diff --git a/src/revwalk.c b/src/libgit2/revwalk.c similarity index 100% rename from src/revwalk.c rename to src/libgit2/revwalk.c diff --git a/src/revwalk.h b/src/libgit2/revwalk.h similarity index 100% rename from src/revwalk.h rename to src/libgit2/revwalk.h diff --git a/src/runtime.c b/src/libgit2/runtime.c similarity index 100% rename from src/runtime.c rename to src/libgit2/runtime.c diff --git a/src/runtime.h b/src/libgit2/runtime.h similarity index 100% rename from src/runtime.h rename to src/libgit2/runtime.h diff --git a/src/settings.h b/src/libgit2/settings.h similarity index 100% rename from src/settings.h rename to src/libgit2/settings.h diff --git a/src/signature.c b/src/libgit2/signature.c similarity index 100% rename from src/signature.c rename to src/libgit2/signature.c diff --git a/src/signature.h b/src/libgit2/signature.h similarity index 100% rename from src/signature.h rename to src/libgit2/signature.h diff --git a/src/sortedcache.c b/src/libgit2/sortedcache.c similarity index 100% rename from src/sortedcache.c rename to src/libgit2/sortedcache.c diff --git a/src/sortedcache.h b/src/libgit2/sortedcache.h similarity index 100% rename from src/sortedcache.h rename to src/libgit2/sortedcache.h diff --git a/src/stash.c b/src/libgit2/stash.c similarity index 100% rename from src/stash.c rename to src/libgit2/stash.c diff --git a/src/status.c b/src/libgit2/status.c similarity index 100% rename from src/status.c rename to src/libgit2/status.c diff --git a/src/status.h b/src/libgit2/status.h similarity index 100% rename from src/status.h rename to src/libgit2/status.h diff --git a/src/str.c b/src/libgit2/str.c similarity index 100% rename from src/str.c rename to src/libgit2/str.c diff --git a/src/str.h b/src/libgit2/str.h similarity index 100% rename from src/str.h rename to src/libgit2/str.h diff --git a/src/strarray.c b/src/libgit2/strarray.c similarity index 100% rename from src/strarray.c rename to src/libgit2/strarray.c diff --git a/src/stream.h b/src/libgit2/stream.h similarity index 100% rename from src/stream.h rename to src/libgit2/stream.h diff --git a/src/streams/mbedtls.c b/src/libgit2/streams/mbedtls.c similarity index 100% rename from src/streams/mbedtls.c rename to src/libgit2/streams/mbedtls.c diff --git a/src/streams/mbedtls.h b/src/libgit2/streams/mbedtls.h similarity index 100% rename from src/streams/mbedtls.h rename to src/libgit2/streams/mbedtls.h diff --git a/src/streams/openssl.c b/src/libgit2/streams/openssl.c similarity index 100% rename from src/streams/openssl.c rename to src/libgit2/streams/openssl.c diff --git a/src/streams/openssl.h b/src/libgit2/streams/openssl.h similarity index 100% rename from src/streams/openssl.h rename to src/libgit2/streams/openssl.h diff --git a/src/streams/openssl_dynamic.c b/src/libgit2/streams/openssl_dynamic.c similarity index 100% rename from src/streams/openssl_dynamic.c rename to src/libgit2/streams/openssl_dynamic.c diff --git a/src/streams/openssl_dynamic.h b/src/libgit2/streams/openssl_dynamic.h similarity index 100% rename from src/streams/openssl_dynamic.h rename to src/libgit2/streams/openssl_dynamic.h diff --git a/src/streams/openssl_legacy.c b/src/libgit2/streams/openssl_legacy.c similarity index 100% rename from src/streams/openssl_legacy.c rename to src/libgit2/streams/openssl_legacy.c diff --git a/src/streams/openssl_legacy.h b/src/libgit2/streams/openssl_legacy.h similarity index 100% rename from src/streams/openssl_legacy.h rename to src/libgit2/streams/openssl_legacy.h diff --git a/src/streams/registry.c b/src/libgit2/streams/registry.c similarity index 100% rename from src/streams/registry.c rename to src/libgit2/streams/registry.c diff --git a/src/streams/registry.h b/src/libgit2/streams/registry.h similarity index 100% rename from src/streams/registry.h rename to src/libgit2/streams/registry.h diff --git a/src/streams/socket.c b/src/libgit2/streams/socket.c similarity index 100% rename from src/streams/socket.c rename to src/libgit2/streams/socket.c diff --git a/src/streams/socket.h b/src/libgit2/streams/socket.h similarity index 100% rename from src/streams/socket.h rename to src/libgit2/streams/socket.h diff --git a/src/streams/stransport.c b/src/libgit2/streams/stransport.c similarity index 100% rename from src/streams/stransport.c rename to src/libgit2/streams/stransport.c diff --git a/src/streams/stransport.h b/src/libgit2/streams/stransport.h similarity index 100% rename from src/streams/stransport.h rename to src/libgit2/streams/stransport.h diff --git a/src/streams/tls.c b/src/libgit2/streams/tls.c similarity index 100% rename from src/streams/tls.c rename to src/libgit2/streams/tls.c diff --git a/src/streams/tls.h b/src/libgit2/streams/tls.h similarity index 100% rename from src/streams/tls.h rename to src/libgit2/streams/tls.h diff --git a/src/strmap.c b/src/libgit2/strmap.c similarity index 100% rename from src/strmap.c rename to src/libgit2/strmap.c diff --git a/src/strmap.h b/src/libgit2/strmap.h similarity index 100% rename from src/strmap.h rename to src/libgit2/strmap.h diff --git a/src/strnlen.h b/src/libgit2/strnlen.h similarity index 100% rename from src/strnlen.h rename to src/libgit2/strnlen.h diff --git a/src/submodule.c b/src/libgit2/submodule.c similarity index 100% rename from src/submodule.c rename to src/libgit2/submodule.c diff --git a/src/submodule.h b/src/libgit2/submodule.h similarity index 100% rename from src/submodule.h rename to src/libgit2/submodule.h diff --git a/src/sysdir.c b/src/libgit2/sysdir.c similarity index 100% rename from src/sysdir.c rename to src/libgit2/sysdir.c diff --git a/src/sysdir.h b/src/libgit2/sysdir.h similarity index 100% rename from src/sysdir.h rename to src/libgit2/sysdir.h diff --git a/src/tag.c b/src/libgit2/tag.c similarity index 100% rename from src/tag.c rename to src/libgit2/tag.c diff --git a/src/tag.h b/src/libgit2/tag.h similarity index 100% rename from src/tag.h rename to src/libgit2/tag.h diff --git a/src/thread.c b/src/libgit2/thread.c similarity index 100% rename from src/thread.c rename to src/libgit2/thread.c diff --git a/src/thread.h b/src/libgit2/thread.h similarity index 100% rename from src/thread.h rename to src/libgit2/thread.h diff --git a/src/threadstate.c b/src/libgit2/threadstate.c similarity index 100% rename from src/threadstate.c rename to src/libgit2/threadstate.c diff --git a/src/threadstate.h b/src/libgit2/threadstate.h similarity index 100% rename from src/threadstate.h rename to src/libgit2/threadstate.h diff --git a/src/trace.c b/src/libgit2/trace.c similarity index 100% rename from src/trace.c rename to src/libgit2/trace.c diff --git a/src/trace.h b/src/libgit2/trace.h similarity index 100% rename from src/trace.h rename to src/libgit2/trace.h diff --git a/src/trailer.c b/src/libgit2/trailer.c similarity index 100% rename from src/trailer.c rename to src/libgit2/trailer.c diff --git a/src/transaction.c b/src/libgit2/transaction.c similarity index 100% rename from src/transaction.c rename to src/libgit2/transaction.c diff --git a/src/transaction.h b/src/libgit2/transaction.h similarity index 100% rename from src/transaction.h rename to src/libgit2/transaction.h diff --git a/src/transport.c b/src/libgit2/transport.c similarity index 100% rename from src/transport.c rename to src/libgit2/transport.c diff --git a/src/transports/auth.c b/src/libgit2/transports/auth.c similarity index 100% rename from src/transports/auth.c rename to src/libgit2/transports/auth.c diff --git a/src/transports/auth.h b/src/libgit2/transports/auth.h similarity index 100% rename from src/transports/auth.h rename to src/libgit2/transports/auth.h diff --git a/src/transports/auth_negotiate.c b/src/libgit2/transports/auth_negotiate.c similarity index 100% rename from src/transports/auth_negotiate.c rename to src/libgit2/transports/auth_negotiate.c diff --git a/src/transports/auth_negotiate.h b/src/libgit2/transports/auth_negotiate.h similarity index 100% rename from src/transports/auth_negotiate.h rename to src/libgit2/transports/auth_negotiate.h diff --git a/src/transports/auth_ntlm.c b/src/libgit2/transports/auth_ntlm.c similarity index 100% rename from src/transports/auth_ntlm.c rename to src/libgit2/transports/auth_ntlm.c diff --git a/src/transports/auth_ntlm.h b/src/libgit2/transports/auth_ntlm.h similarity index 100% rename from src/transports/auth_ntlm.h rename to src/libgit2/transports/auth_ntlm.h diff --git a/src/transports/credential.c b/src/libgit2/transports/credential.c similarity index 100% rename from src/transports/credential.c rename to src/libgit2/transports/credential.c diff --git a/src/transports/credential_helpers.c b/src/libgit2/transports/credential_helpers.c similarity index 100% rename from src/transports/credential_helpers.c rename to src/libgit2/transports/credential_helpers.c diff --git a/src/transports/git.c b/src/libgit2/transports/git.c similarity index 100% rename from src/transports/git.c rename to src/libgit2/transports/git.c diff --git a/src/transports/http.c b/src/libgit2/transports/http.c similarity index 100% rename from src/transports/http.c rename to src/libgit2/transports/http.c diff --git a/src/transports/http.h b/src/libgit2/transports/http.h similarity index 100% rename from src/transports/http.h rename to src/libgit2/transports/http.h diff --git a/src/transports/httpclient.c b/src/libgit2/transports/httpclient.c similarity index 100% rename from src/transports/httpclient.c rename to src/libgit2/transports/httpclient.c diff --git a/src/transports/httpclient.h b/src/libgit2/transports/httpclient.h similarity index 100% rename from src/transports/httpclient.h rename to src/libgit2/transports/httpclient.h diff --git a/src/transports/local.c b/src/libgit2/transports/local.c similarity index 100% rename from src/transports/local.c rename to src/libgit2/transports/local.c diff --git a/src/transports/smart.c b/src/libgit2/transports/smart.c similarity index 100% rename from src/transports/smart.c rename to src/libgit2/transports/smart.c diff --git a/src/transports/smart.h b/src/libgit2/transports/smart.h similarity index 100% rename from src/transports/smart.h rename to src/libgit2/transports/smart.h diff --git a/src/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c similarity index 100% rename from src/transports/smart_pkt.c rename to src/libgit2/transports/smart_pkt.c diff --git a/src/transports/smart_protocol.c b/src/libgit2/transports/smart_protocol.c similarity index 100% rename from src/transports/smart_protocol.c rename to src/libgit2/transports/smart_protocol.c diff --git a/src/transports/ssh.c b/src/libgit2/transports/ssh.c similarity index 100% rename from src/transports/ssh.c rename to src/libgit2/transports/ssh.c diff --git a/src/transports/ssh.h b/src/libgit2/transports/ssh.h similarity index 100% rename from src/transports/ssh.h rename to src/libgit2/transports/ssh.h diff --git a/src/transports/winhttp.c b/src/libgit2/transports/winhttp.c similarity index 100% rename from src/transports/winhttp.c rename to src/libgit2/transports/winhttp.c diff --git a/src/tree-cache.c b/src/libgit2/tree-cache.c similarity index 100% rename from src/tree-cache.c rename to src/libgit2/tree-cache.c diff --git a/src/tree-cache.h b/src/libgit2/tree-cache.h similarity index 100% rename from src/tree-cache.h rename to src/libgit2/tree-cache.h diff --git a/src/tree.c b/src/libgit2/tree.c similarity index 100% rename from src/tree.c rename to src/libgit2/tree.c diff --git a/src/tree.h b/src/libgit2/tree.h similarity index 100% rename from src/tree.h rename to src/libgit2/tree.h diff --git a/src/tsort.c b/src/libgit2/tsort.c similarity index 100% rename from src/tsort.c rename to src/libgit2/tsort.c diff --git a/src/unix/map.c b/src/libgit2/unix/map.c similarity index 100% rename from src/unix/map.c rename to src/libgit2/unix/map.c diff --git a/src/unix/posix.h b/src/libgit2/unix/posix.h similarity index 100% rename from src/unix/posix.h rename to src/libgit2/unix/posix.h diff --git a/src/unix/pthread.h b/src/libgit2/unix/pthread.h similarity index 100% rename from src/unix/pthread.h rename to src/libgit2/unix/pthread.h diff --git a/src/unix/realpath.c b/src/libgit2/unix/realpath.c similarity index 100% rename from src/unix/realpath.c rename to src/libgit2/unix/realpath.c diff --git a/src/userdiff.h b/src/libgit2/userdiff.h similarity index 100% rename from src/userdiff.h rename to src/libgit2/userdiff.h diff --git a/src/utf8.c b/src/libgit2/utf8.c similarity index 100% rename from src/utf8.c rename to src/libgit2/utf8.c diff --git a/src/utf8.h b/src/libgit2/utf8.h similarity index 100% rename from src/utf8.h rename to src/libgit2/utf8.h diff --git a/src/util.c b/src/libgit2/util.c similarity index 100% rename from src/util.c rename to src/libgit2/util.c diff --git a/src/util.h b/src/libgit2/util.h similarity index 100% rename from src/util.h rename to src/libgit2/util.h diff --git a/src/libgit2/util/platform.h.in b/src/libgit2/util/platform.h.in new file mode 100644 index 00000000000..e511fe33109 --- /dev/null +++ b/src/libgit2/util/platform.h.in @@ -0,0 +1,34 @@ +#ifndef INCLUDE_platform_h__ +#define INCLUDE_platform_h__ + +#cmakedefine GIT_DEBUG_POOL 1 +#cmakedefine GIT_DEBUG_STRICT_ALLOC 1 +#cmakedefine GIT_DEBUG_STRICT_OPEN 1 + +#cmakedefine GIT_WIN32_LEAKCHECK 1 + +#cmakedefine GIT_ARCH_64 1 +#cmakedefine GIT_ARCH_32 1 + +#cmakedefine GIT_USE_STAT_MTIM 1 +#cmakedefine GIT_USE_STAT_MTIMESPEC 1 +#cmakedefine GIT_USE_STAT_MTIME_NSEC 1 +#cmakedefine GIT_USE_FUTIMENS 1 + +#cmakedefine GIT_USE_QSORT_R_BSD 1 +#cmakedefine GIT_USE_QSORT_R_GNU 1 +#cmakedefine GIT_USE_QSORT_S 1 + +#cmakedefine GIT_REGEX_REGCOMP_L 1 +#cmakedefine GIT_REGEX_REGCOMP 1 +#cmakedefine GIT_REGEX_PCRE 1 +#cmakedefine GIT_REGEX_PCRE2 1 +#cmakedefine GIT_REGEX_BUILTIN 1 + +#cmakedefine GIT_SHA1_COLLISIONDETECT 1 +#cmakedefine GIT_SHA1_WIN32 1 +#cmakedefine GIT_SHA1_COMMON_CRYPTO 1 +#cmakedefine GIT_SHA1_OPENSSL 1 +#cmakedefine GIT_SHA1_MBEDTLS 1 + +#endif diff --git a/src/varint.c b/src/libgit2/varint.c similarity index 100% rename from src/varint.c rename to src/libgit2/varint.c diff --git a/src/varint.h b/src/libgit2/varint.h similarity index 100% rename from src/varint.h rename to src/libgit2/varint.h diff --git a/src/vector.c b/src/libgit2/vector.c similarity index 100% rename from src/vector.c rename to src/libgit2/vector.c diff --git a/src/vector.h b/src/libgit2/vector.h similarity index 100% rename from src/vector.h rename to src/libgit2/vector.h diff --git a/src/wildmatch.c b/src/libgit2/wildmatch.c similarity index 100% rename from src/wildmatch.c rename to src/libgit2/wildmatch.c diff --git a/src/wildmatch.h b/src/libgit2/wildmatch.h similarity index 100% rename from src/wildmatch.h rename to src/libgit2/wildmatch.h diff --git a/src/win32/dir.c b/src/libgit2/win32/dir.c similarity index 100% rename from src/win32/dir.c rename to src/libgit2/win32/dir.c diff --git a/src/win32/dir.h b/src/libgit2/win32/dir.h similarity index 100% rename from src/win32/dir.h rename to src/libgit2/win32/dir.h diff --git a/src/win32/error.c b/src/libgit2/win32/error.c similarity index 100% rename from src/win32/error.c rename to src/libgit2/win32/error.c diff --git a/src/win32/error.h b/src/libgit2/win32/error.h similarity index 100% rename from src/win32/error.h rename to src/libgit2/win32/error.h diff --git a/src/win32/findfile.c b/src/libgit2/win32/findfile.c similarity index 100% rename from src/win32/findfile.c rename to src/libgit2/win32/findfile.c diff --git a/src/win32/findfile.h b/src/libgit2/win32/findfile.h similarity index 100% rename from src/win32/findfile.h rename to src/libgit2/win32/findfile.h diff --git a/src/win32/git2.rc b/src/libgit2/win32/git2.rc similarity index 97% rename from src/win32/git2.rc rename to src/libgit2/win32/git2.rc index d273afd7066..3f97239da39 100644 --- a/src/win32/git2.rc +++ b/src/libgit2/win32/git2.rc @@ -1,5 +1,5 @@ #include -#include "../../include/git2/version.h" +#include "../../../include/git2/version.h" #ifndef LIBGIT2_FILENAME # ifdef __GNUC__ diff --git a/src/win32/map.c b/src/libgit2/win32/map.c similarity index 100% rename from src/win32/map.c rename to src/libgit2/win32/map.c diff --git a/src/win32/mingw-compat.h b/src/libgit2/win32/mingw-compat.h similarity index 100% rename from src/win32/mingw-compat.h rename to src/libgit2/win32/mingw-compat.h diff --git a/src/win32/msvc-compat.h b/src/libgit2/win32/msvc-compat.h similarity index 100% rename from src/win32/msvc-compat.h rename to src/libgit2/win32/msvc-compat.h diff --git a/src/win32/path_w32.c b/src/libgit2/win32/path_w32.c similarity index 100% rename from src/win32/path_w32.c rename to src/libgit2/win32/path_w32.c diff --git a/src/win32/path_w32.h b/src/libgit2/win32/path_w32.h similarity index 100% rename from src/win32/path_w32.h rename to src/libgit2/win32/path_w32.h diff --git a/src/win32/posix.h b/src/libgit2/win32/posix.h similarity index 100% rename from src/win32/posix.h rename to src/libgit2/win32/posix.h diff --git a/src/win32/posix_w32.c b/src/libgit2/win32/posix_w32.c similarity index 100% rename from src/win32/posix_w32.c rename to src/libgit2/win32/posix_w32.c diff --git a/src/win32/precompiled.c b/src/libgit2/win32/precompiled.c similarity index 100% rename from src/win32/precompiled.c rename to src/libgit2/win32/precompiled.c diff --git a/src/win32/precompiled.h b/src/libgit2/win32/precompiled.h similarity index 100% rename from src/win32/precompiled.h rename to src/libgit2/win32/precompiled.h diff --git a/src/win32/reparse.h b/src/libgit2/win32/reparse.h similarity index 100% rename from src/win32/reparse.h rename to src/libgit2/win32/reparse.h diff --git a/src/win32/thread.c b/src/libgit2/win32/thread.c similarity index 100% rename from src/win32/thread.c rename to src/libgit2/win32/thread.c diff --git a/src/win32/thread.h b/src/libgit2/win32/thread.h similarity index 100% rename from src/win32/thread.h rename to src/libgit2/win32/thread.h diff --git a/src/win32/utf-conv.c b/src/libgit2/win32/utf-conv.c similarity index 100% rename from src/win32/utf-conv.c rename to src/libgit2/win32/utf-conv.c diff --git a/src/win32/utf-conv.h b/src/libgit2/win32/utf-conv.h similarity index 100% rename from src/win32/utf-conv.h rename to src/libgit2/win32/utf-conv.h diff --git a/src/win32/version.h b/src/libgit2/win32/version.h similarity index 100% rename from src/win32/version.h rename to src/libgit2/win32/version.h diff --git a/src/win32/w32_buffer.c b/src/libgit2/win32/w32_buffer.c similarity index 100% rename from src/win32/w32_buffer.c rename to src/libgit2/win32/w32_buffer.c diff --git a/src/win32/w32_buffer.h b/src/libgit2/win32/w32_buffer.h similarity index 100% rename from src/win32/w32_buffer.h rename to src/libgit2/win32/w32_buffer.h diff --git a/src/win32/w32_common.h b/src/libgit2/win32/w32_common.h similarity index 100% rename from src/win32/w32_common.h rename to src/libgit2/win32/w32_common.h diff --git a/src/win32/w32_leakcheck.c b/src/libgit2/win32/w32_leakcheck.c similarity index 100% rename from src/win32/w32_leakcheck.c rename to src/libgit2/win32/w32_leakcheck.c diff --git a/src/win32/w32_leakcheck.h b/src/libgit2/win32/w32_leakcheck.h similarity index 100% rename from src/win32/w32_leakcheck.h rename to src/libgit2/win32/w32_leakcheck.h diff --git a/src/win32/w32_util.c b/src/libgit2/win32/w32_util.c similarity index 100% rename from src/win32/w32_util.c rename to src/libgit2/win32/w32_util.c diff --git a/src/win32/w32_util.h b/src/libgit2/win32/w32_util.h similarity index 100% rename from src/win32/w32_util.h rename to src/libgit2/win32/w32_util.h diff --git a/src/win32/win32-compat.h b/src/libgit2/win32/win32-compat.h similarity index 100% rename from src/win32/win32-compat.h rename to src/libgit2/win32/win32-compat.h diff --git a/src/worktree.c b/src/libgit2/worktree.c similarity index 100% rename from src/worktree.c rename to src/libgit2/worktree.c diff --git a/src/worktree.h b/src/libgit2/worktree.h similarity index 100% rename from src/worktree.h rename to src/libgit2/worktree.h diff --git a/src/xdiff/git-xdiff.h b/src/libgit2/xdiff/git-xdiff.h similarity index 100% rename from src/xdiff/git-xdiff.h rename to src/libgit2/xdiff/git-xdiff.h diff --git a/src/xdiff/xdiff.h b/src/libgit2/xdiff/xdiff.h similarity index 100% rename from src/xdiff/xdiff.h rename to src/libgit2/xdiff/xdiff.h diff --git a/src/xdiff/xdiffi.c b/src/libgit2/xdiff/xdiffi.c similarity index 100% rename from src/xdiff/xdiffi.c rename to src/libgit2/xdiff/xdiffi.c diff --git a/src/xdiff/xdiffi.h b/src/libgit2/xdiff/xdiffi.h similarity index 100% rename from src/xdiff/xdiffi.h rename to src/libgit2/xdiff/xdiffi.h diff --git a/src/xdiff/xemit.c b/src/libgit2/xdiff/xemit.c similarity index 100% rename from src/xdiff/xemit.c rename to src/libgit2/xdiff/xemit.c diff --git a/src/xdiff/xemit.h b/src/libgit2/xdiff/xemit.h similarity index 100% rename from src/xdiff/xemit.h rename to src/libgit2/xdiff/xemit.h diff --git a/src/xdiff/xhistogram.c b/src/libgit2/xdiff/xhistogram.c similarity index 100% rename from src/xdiff/xhistogram.c rename to src/libgit2/xdiff/xhistogram.c diff --git a/src/xdiff/xinclude.h b/src/libgit2/xdiff/xinclude.h similarity index 100% rename from src/xdiff/xinclude.h rename to src/libgit2/xdiff/xinclude.h diff --git a/src/xdiff/xmacros.h b/src/libgit2/xdiff/xmacros.h similarity index 100% rename from src/xdiff/xmacros.h rename to src/libgit2/xdiff/xmacros.h diff --git a/src/xdiff/xmerge.c b/src/libgit2/xdiff/xmerge.c similarity index 100% rename from src/xdiff/xmerge.c rename to src/libgit2/xdiff/xmerge.c diff --git a/src/xdiff/xpatience.c b/src/libgit2/xdiff/xpatience.c similarity index 100% rename from src/xdiff/xpatience.c rename to src/libgit2/xdiff/xpatience.c diff --git a/src/xdiff/xprepare.c b/src/libgit2/xdiff/xprepare.c similarity index 100% rename from src/xdiff/xprepare.c rename to src/libgit2/xdiff/xprepare.c diff --git a/src/xdiff/xprepare.h b/src/libgit2/xdiff/xprepare.h similarity index 100% rename from src/xdiff/xprepare.h rename to src/libgit2/xdiff/xprepare.h diff --git a/src/xdiff/xtypes.h b/src/libgit2/xdiff/xtypes.h similarity index 100% rename from src/xdiff/xtypes.h rename to src/libgit2/xdiff/xtypes.h diff --git a/src/xdiff/xutils.c b/src/libgit2/xdiff/xutils.c similarity index 100% rename from src/xdiff/xutils.c rename to src/libgit2/xdiff/xutils.c diff --git a/src/xdiff/xutils.h b/src/libgit2/xdiff/xutils.h similarity index 100% rename from src/xdiff/xutils.h rename to src/libgit2/xdiff/xutils.h diff --git a/src/zstream.c b/src/libgit2/zstream.c similarity index 100% rename from src/zstream.c rename to src/libgit2/zstream.c diff --git a/src/zstream.h b/src/libgit2/zstream.h similarity index 100% rename from src/zstream.h rename to src/libgit2/zstream.h From c3b7ace9cf3216928a31886b32c264e0cd3cde75 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 14 Nov 2021 16:43:53 -0500 Subject: [PATCH 0814/1616] refactor: make util an object library Instead of simply including the utility files directly, make them a cmake object library for easy reusability between other projects within libgit2. Now the top-level `src` is responsible for platform selection, while the next-level `libgit2` and `util` configurations are responsible for identifying what objects they include. --- cmake/SelectHashes.cmake | 3 - src/CMakeLists.txt | 178 +++++++++++++++++ src/README.md | 10 + src/{libgit2 => }/features.h.in | 0 src/libgit2/CMakeLists.txt | 183 ++++++++--------- src/libgit2/blob.c | 2 +- src/libgit2/common.h | 189 ++---------------- src/libgit2/diff_xdiff.c | 1 + src/libgit2/filter.c | 2 +- src/libgit2/{win32 => }/git2.rc | 2 +- src/libgit2/netops.c | 1 - src/libgit2/odb.c | 2 +- src/libgit2/path.c | 1 + src/libgit2/util/platform.h.in | 34 ---- src/util/CMakeLists.txt | 59 ++++++ src/{libgit2 => util}/alloc.c | 0 src/{libgit2 => util}/alloc.h | 0 src/{libgit2 => util}/allocators/failalloc.c | 0 src/{libgit2 => util}/allocators/failalloc.h | 2 +- src/{libgit2 => util}/allocators/stdalloc.c | 0 src/{libgit2 => util}/allocators/stdalloc.h | 2 +- .../allocators/win32_leakcheck.c | 0 .../allocators/win32_leakcheck.h | 2 +- src/{libgit2 => util}/array.h | 2 +- src/{libgit2 => util}/assert_safe.h | 0 src/{libgit2 => util}/bitvec.h | 0 src/{libgit2 => util}/cc-compat.h | 0 src/{libgit2 => util}/date.c | 7 +- src/{libgit2 => util}/date.h | 0 src/{libgit2 => util}/filebuf.c | 2 +- src/{libgit2 => util}/filebuf.h | 2 +- src/{libgit2 => util}/fs_path.c | 18 +- src/{libgit2 => util}/fs_path.h | 2 +- src/{libgit2 => util}/futils.c | 2 +- src/{libgit2 => util}/futils.h | 2 +- src/util/git2_util.h | 168 ++++++++++++++++ src/{libgit2 => util}/hash.c | 0 src/{libgit2 => util}/hash.h | 2 +- src/{libgit2 => util}/hash/sha1.h | 2 +- .../hash/sha1/collisiondetect.c | 0 .../hash/sha1/collisiondetect.h | 0 .../hash/sha1/common_crypto.c | 0 .../hash/sha1/common_crypto.h | 0 src/{libgit2 => util}/hash/sha1/generic.c | 0 src/{libgit2 => util}/hash/sha1/generic.h | 0 src/{libgit2 => util}/hash/sha1/mbedtls.c | 0 src/{libgit2 => util}/hash/sha1/mbedtls.h | 0 src/{libgit2 => util}/hash/sha1/openssl.c | 0 src/{libgit2 => util}/hash/sha1/openssl.h | 0 src/{libgit2 => util}/hash/sha1/sha1dc/sha1.c | 0 src/{libgit2 => util}/hash/sha1/sha1dc/sha1.h | 0 .../hash/sha1/sha1dc/ubc_check.c | 0 .../hash/sha1/sha1dc/ubc_check.h | 0 src/{libgit2 => util}/hash/sha1/win32.c | 0 src/{libgit2 => util}/hash/sha1/win32.h | 0 src/{libgit2 => util}/integer.h | 0 src/{libgit2 => util}/khash.h | 0 src/{libgit2 => util}/map.h | 2 +- src/{libgit2 => util}/net.c | 1 - src/{libgit2 => util}/net.h | 2 +- src/{libgit2 => util}/pool.c | 0 src/{libgit2 => util}/pool.h | 2 +- src/{libgit2 => util}/posix.c | 0 src/{libgit2 => util}/posix.h | 2 +- src/{libgit2 => util}/pqueue.c | 0 src/{libgit2 => util}/pqueue.h | 2 +- src/{ => util}/rand.c | 2 +- src/{ => util}/rand.h | 2 +- src/{libgit2 => util}/regexp.c | 0 src/{libgit2 => util}/regexp.h | 2 +- src/{libgit2 => util}/runtime.c | 2 +- src/{libgit2 => util}/runtime.h | 2 +- src/{libgit2 => util}/sortedcache.c | 0 src/{libgit2 => util}/sortedcache.h | 2 +- src/{libgit2 => util}/str.c | 0 src/{libgit2 => util}/str.h | 2 +- src/{libgit2 => util}/strmap.c | 0 src/{libgit2 => util}/strmap.h | 2 +- src/{libgit2 => util}/strnlen.h | 0 src/{libgit2 => util}/thread.c | 2 +- src/{libgit2 => util}/thread.h | 0 src/{libgit2 => util}/tsort.c | 2 +- src/{libgit2 => util}/unix/map.c | 2 +- src/{libgit2 => util}/unix/posix.h | 2 +- src/{libgit2 => util}/unix/pthread.h | 0 src/{libgit2 => util}/unix/realpath.c | 2 +- src/{libgit2 => util}/utf8.c | 2 +- src/{libgit2 => util}/utf8.h | 2 +- src/{libgit2 => util}/util.c | 2 +- src/{libgit2 => util}/util.h | 2 +- src/{libgit2 => util}/varint.c | 0 src/{libgit2 => util}/varint.h | 2 +- src/{libgit2 => util}/vector.c | 0 src/{libgit2 => util}/vector.h | 2 +- src/{libgit2 => util}/wildmatch.c | 0 src/{libgit2 => util}/wildmatch.h | 2 +- src/{libgit2 => util}/win32/dir.c | 0 src/{libgit2 => util}/win32/dir.h | 2 +- src/{libgit2 => util}/win32/error.c | 0 src/{libgit2 => util}/win32/error.h | 2 +- src/{libgit2 => util}/win32/findfile.c | 0 src/{libgit2 => util}/win32/findfile.h | 2 +- src/{libgit2 => util}/win32/map.c | 2 +- src/{libgit2 => util}/win32/mingw-compat.h | 0 src/{libgit2 => util}/win32/msvc-compat.h | 0 src/{libgit2 => util}/win32/path_w32.c | 0 src/{libgit2 => util}/win32/path_w32.h | 2 +- src/{libgit2 => util}/win32/posix.h | 2 +- src/{libgit2 => util}/win32/posix_w32.c | 2 +- src/{libgit2 => util}/win32/precompiled.c | 0 src/{libgit2 => util}/win32/precompiled.h | 2 +- src/{libgit2 => util}/win32/reparse.h | 0 src/{libgit2 => util}/win32/thread.c | 0 src/{libgit2 => util}/win32/thread.h | 2 +- src/{libgit2 => util}/win32/utf-conv.c | 0 src/{libgit2 => util}/win32/utf-conv.h | 2 +- src/{libgit2 => util}/win32/version.h | 0 src/{libgit2 => util}/win32/w32_buffer.c | 0 src/{libgit2 => util}/win32/w32_buffer.h | 2 +- src/{libgit2 => util}/win32/w32_common.h | 0 src/{libgit2 => util}/win32/w32_leakcheck.c | 0 src/{libgit2 => util}/win32/w32_leakcheck.h | 2 +- src/{libgit2 => util}/win32/w32_util.c | 0 src/{libgit2 => util}/win32/w32_util.h | 2 +- src/{libgit2 => util}/win32/win32-compat.h | 0 src/{libgit2 => util}/zstream.c | 0 src/{libgit2 => util}/zstream.h | 2 +- 127 files changed, 584 insertions(+), 377 deletions(-) create mode 100644 src/README.md rename src/{libgit2 => }/features.h.in (100%) rename src/libgit2/{win32 => }/git2.rc (97%) delete mode 100644 src/libgit2/util/platform.h.in create mode 100644 src/util/CMakeLists.txt rename src/{libgit2 => util}/alloc.c (100%) rename src/{libgit2 => util}/alloc.h (100%) rename src/{libgit2 => util}/allocators/failalloc.c (100%) rename src/{libgit2 => util}/allocators/failalloc.h (97%) rename src/{libgit2 => util}/allocators/stdalloc.c (100%) rename src/{libgit2 => util}/allocators/stdalloc.h (94%) rename src/{libgit2 => util}/allocators/win32_leakcheck.c (100%) rename src/{libgit2 => util}/allocators/win32_leakcheck.h (94%) rename src/{libgit2 => util}/array.h (99%) rename src/{libgit2 => util}/assert_safe.h (100%) rename src/{libgit2 => util}/bitvec.h (100%) rename src/{libgit2 => util}/cc-compat.h (100%) rename src/{libgit2 => util}/date.c (98%) rename src/{libgit2 => util}/date.h (100%) rename src/{libgit2 => util}/filebuf.c (99%) rename src/{libgit2 => util}/filebuf.h (99%) rename src/{libgit2 => util}/fs_path.c (99%) rename src/{libgit2 => util}/fs_path.h (99%) rename src/{libgit2 => util}/futils.c (99%) rename src/{libgit2 => util}/futils.h (99%) create mode 100644 src/util/git2_util.h rename src/{libgit2 => util}/hash.c (100%) rename src/{libgit2 => util}/hash.h (98%) rename src/{libgit2 => util}/hash/sha1.h (97%) rename src/{libgit2 => util}/hash/sha1/collisiondetect.c (100%) rename src/{libgit2 => util}/hash/sha1/collisiondetect.h (100%) rename src/{libgit2 => util}/hash/sha1/common_crypto.c (100%) rename src/{libgit2 => util}/hash/sha1/common_crypto.h (100%) rename src/{libgit2 => util}/hash/sha1/generic.c (100%) rename src/{libgit2 => util}/hash/sha1/generic.h (100%) rename src/{libgit2 => util}/hash/sha1/mbedtls.c (100%) rename src/{libgit2 => util}/hash/sha1/mbedtls.h (100%) rename src/{libgit2 => util}/hash/sha1/openssl.c (100%) rename src/{libgit2 => util}/hash/sha1/openssl.h (100%) rename src/{libgit2 => util}/hash/sha1/sha1dc/sha1.c (100%) rename src/{libgit2 => util}/hash/sha1/sha1dc/sha1.h (100%) rename src/{libgit2 => util}/hash/sha1/sha1dc/ubc_check.c (100%) rename src/{libgit2 => util}/hash/sha1/sha1dc/ubc_check.h (100%) rename src/{libgit2 => util}/hash/sha1/win32.c (100%) rename src/{libgit2 => util}/hash/sha1/win32.h (100%) rename src/{libgit2 => util}/integer.h (100%) rename src/{libgit2 => util}/khash.h (100%) rename src/{libgit2 => util}/map.h (98%) rename src/{libgit2 => util}/net.c (99%) rename src/{libgit2 => util}/net.h (99%) rename src/{libgit2 => util}/pool.c (100%) rename src/{libgit2 => util}/pool.h (99%) rename src/{libgit2 => util}/posix.c (100%) rename src/{libgit2 => util}/posix.h (99%) rename src/{libgit2 => util}/pqueue.c (100%) rename src/{libgit2 => util}/pqueue.h (98%) rename src/{ => util}/rand.c (99%) rename src/{ => util}/rand.h (97%) rename src/{libgit2 => util}/regexp.c (100%) rename src/{libgit2 => util}/regexp.h (99%) rename src/{libgit2 => util}/runtime.c (99%) rename src/{libgit2 => util}/runtime.h (98%) rename src/{libgit2 => util}/sortedcache.c (100%) rename src/{libgit2 => util}/sortedcache.h (99%) rename src/{libgit2 => util}/str.c (100%) rename src/{libgit2 => util}/str.h (99%) rename src/{libgit2 => util}/strmap.c (100%) rename src/{libgit2 => util}/strmap.h (99%) rename src/{libgit2 => util}/strnlen.h (100%) rename src/{libgit2 => util}/thread.c (99%) rename src/{libgit2 => util}/thread.h (100%) rename src/{libgit2 => util}/tsort.c (99%) rename src/{libgit2 => util}/unix/map.c (98%) rename src/{libgit2 => util}/unix/posix.h (99%) rename src/{libgit2 => util}/unix/pthread.h (100%) rename src/{libgit2 => util}/unix/realpath.c (96%) rename src/{libgit2 => util}/utf8.c (99%) rename src/{libgit2 => util}/utf8.h (98%) rename src/{libgit2 => util}/util.c (99%) rename src/{libgit2 => util}/util.h (99%) rename src/{libgit2 => util}/varint.c (100%) rename src/{libgit2 => util}/varint.h (94%) rename src/{libgit2 => util}/vector.c (100%) rename src/{libgit2 => util}/vector.h (99%) rename src/{libgit2 => util}/wildmatch.c (100%) rename src/{libgit2 => util}/wildmatch.h (95%) rename src/{libgit2 => util}/win32/dir.c (100%) rename src/{libgit2 => util}/win32/dir.h (97%) rename src/{libgit2 => util}/win32/error.c (100%) rename src/{libgit2 => util}/win32/error.h (93%) rename src/{libgit2 => util}/win32/findfile.c (100%) rename src/{libgit2 => util}/win32/findfile.h (96%) rename src/{libgit2 => util}/win32/map.c (99%) rename src/{libgit2 => util}/win32/mingw-compat.h (100%) rename src/{libgit2 => util}/win32/msvc-compat.h (100%) rename src/{libgit2 => util}/win32/path_w32.c (100%) rename src/{libgit2 => util}/win32/path_w32.h (99%) rename src/{libgit2 => util}/win32/posix.h (99%) rename src/{libgit2 => util}/win32/posix_w32.c (99%) rename src/{libgit2 => util}/win32/precompiled.c (100%) rename src/{libgit2 => util}/win32/precompiled.h (93%) rename src/{libgit2 => util}/win32/reparse.h (100%) rename src/{libgit2 => util}/win32/thread.c (100%) rename src/{libgit2 => util}/win32/thread.h (98%) rename src/{libgit2 => util}/win32/utf-conv.c (100%) rename src/{libgit2 => util}/win32/utf-conv.h (98%) rename src/{libgit2 => util}/win32/version.h (100%) rename src/{libgit2 => util}/win32/w32_buffer.c (100%) rename src/{libgit2 => util}/win32/w32_buffer.h (95%) rename src/{libgit2 => util}/win32/w32_common.h (100%) rename src/{libgit2 => util}/win32/w32_leakcheck.c (100%) rename src/{libgit2 => util}/win32/w32_leakcheck.h (99%) rename src/{libgit2 => util}/win32/w32_util.c (100%) rename src/{libgit2 => util}/win32/w32_util.h (99%) rename src/{libgit2 => util}/win32/win32-compat.h (100%) rename src/{libgit2 => util}/zstream.c (100%) rename src/{libgit2 => util}/zstream.h (98%) diff --git a/cmake/SelectHashes.cmake b/cmake/SelectHashes.cmake index bedd8c4e332..575ae8f8d27 100644 --- a/cmake/SelectHashes.cmake +++ b/cmake/SelectHashes.cmake @@ -21,9 +21,6 @@ endif() if(USE_SHA1 STREQUAL "CollisionDetection") set(GIT_SHA1_COLLISIONDETECT 1) - add_definitions(-DSHA1DC_NO_STANDARD_INCLUDES=1) - add_definitions(-DSHA1DC_CUSTOM_INCLUDE_SHA1_C=\"common.h\") - add_definitions(-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"common.h\") elseif(USE_SHA1 STREQUAL "OpenSSL") # OPENSSL_FOUND should already be set, we're checking USE_HTTPS diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f6924eff57e..bbb724057ef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,182 @@ +# The main libgit2 source tree: this CMakeLists.txt identifies platform +# support and includes the subprojects that make up core libgit2 support. + +# +# Optional build configuration settings +# + +if(DEPRECATE_HARD) + add_definitions(-DGIT_DEPRECATE_HARD) +endif() + +if(USE_LEAK_CHECKER STREQUAL "valgrind") + add_definitions(-DVALGRIND) +endif() + +# +# Optional debugging functionality +# + +if(DEBUG_POOL) + set(GIT_DEBUG_POOL 1) +endif() +add_feature_info(debugpool GIT_DEBUG_POOL "debug pool allocator") + +if(DEBUG_STRICT_ALLOC) + set(GIT_DEBUG_STRICT_ALLOC 1) +endif() +add_feature_info(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators") + +if(DEBUG_STRICT_OPEN) + set(GIT_DEBUG_STRICT_OPEN 1) +endif() +add_feature_info(debugopen GIT_DEBUG_STRICT_OPEN "path validation in open") + +# +# Optional feature enablement +# + +include(SelectGSSAPI) +include(SelectHTTPSBackend) +include(SelectHashes) +include(SelectHTTPParser) +include(SelectRegex) +include(SelectSSH) +include(SelectWinHTTP) +include(SelectZlib) + +# +# Platform support +# + +# futimes/futimens + +if(HAVE_FUTIMENS) + set(GIT_USE_FUTIMENS 1) +endif () +add_feature_info(futimens GIT_USE_FUTIMENS "futimens support") + +# qsort + +check_prototype_definition(qsort_r + "void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, int (*compar)(void *, const void *, const void *))" + "" "stdlib.h" GIT_QSORT_R_BSD) + +check_prototype_definition(qsort_r + "void qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *arg)" + "" "stdlib.h" GIT_QSORT_R_GNU) + +check_function_exists(qsort_s GIT_QSORT_S) + +# determine architecture of the machine + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(GIT_ARCH_64 1) +elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(GIT_ARCH_32 1) +elseif(CMAKE_SIZEOF_VOID_P) + message(FATAL_ERROR "Unsupported architecture (pointer size is ${CMAKE_SIZEOF_VOID_P} bytes)") +else() + message(FATAL_ERROR "Unsupported architecture (CMAKE_SIZEOF_VOID_P is unset)") +endif() + +# nanosecond mtime/ctime support + +if(USE_NSEC) + set(GIT_USE_NSEC 1) +endif() + +# high-resolution stat support + +if(HAVE_STRUCT_STAT_ST_MTIM) + set(GIT_USE_STAT_MTIM 1) +elseif(HAVE_STRUCT_STAT_ST_MTIMESPEC) + set(GIT_USE_STAT_MTIMESPEC 1) +elseif(HAVE_STRUCT_STAT_ST_MTIME_NSEC) + set(GIT_USE_STAT_MTIME_NSEC 1) +endif() + +# realtime support + +check_library_exists(rt clock_gettime "time.h" NEED_LIBRT) +if(NEED_LIBRT) + list(APPEND LIBGIT2_SYSTEM_LIBS rt) + list(APPEND LIBGIT2_PC_LIBS "-lrt") +endif() + +# platform libraries + +if(WIN32) + list(APPEND LIBGIT2_SYSTEM_LIBS ws2_32) +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") + list(APPEND LIBGIT2_SYSTEM_LIBS socket nsl) + list(APPEND LIBGIT2_PC_LIBS "-lsocket" "-lnsl") +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "Haiku") + list(APPEND LIBGIT2_SYSTEM_LIBS network) + list(APPEND LIBGIT2_PC_LIBS "-lnetwork") +endif() + +if(AMIGA) + add_definitions(-DNO_ADDRINFO -DNO_READDIR_R -DNO_MMAP) +endif() + +# threads + +if(USE_THREADS) + if(NOT WIN32) + find_package(Threads REQUIRED) + list(APPEND LIBGIT2_SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT}) + list(APPEND LIBGIT2_PC_LIBS ${CMAKE_THREAD_LIBS_INIT}) + endif() + + set(GIT_THREADS 1) +endif() +add_feature_info(threadsafe USE_THREADS "threadsafe support") + +# +# Optional bundled features +# + +# ntlmclient +if(USE_NTLMCLIENT) + set(GIT_NTLM 1) + add_subdirectory("${libgit2_SOURCE_DIR}/deps/ntlmclient" "${libgit2_BINARY_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") +endif() +add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix") + +# +# Optional external dependencies + +# iconv +if(USE_ICONV) + find_package(Iconv) +endif() +if(ICONV_FOUND) + set(GIT_USE_ICONV 1) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ICONV_INCLUDE_DIR}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${ICONV_LIBRARIES}) + list(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES}) +endif() +add_feature_info(iconv GIT_USE_ICONV "iconv encoding conversion support") + +# +# Configure support +# + +configure_file(features.h.in git2/sys/features.h) + +# +# Include child projects +# + add_subdirectory(libgit2) +add_subdirectory(util) # re-export these to the root so that peer projects (tests, fuzzers, # examples) can use them diff --git a/src/README.md b/src/README.md new file mode 100644 index 00000000000..12e0d0e4361 --- /dev/null +++ b/src/README.md @@ -0,0 +1,10 @@ +# libgit2 sources + +This is the source that makes up the core of libgit2 and its related +projects. + +* `libgit2` + This is the libgit2 project, a cross-platform, linkable library + implementation of Git that you can use in your application. +* `util` + A shared utility library for these projects. diff --git a/src/libgit2/features.h.in b/src/features.h.in similarity index 100% rename from src/libgit2/features.h.in rename to src/features.h.in diff --git a/src/libgit2/CMakeLists.txt b/src/libgit2/CMakeLists.txt index e6cdddd491e..3dac83d7a42 100644 --- a/src/libgit2/CMakeLists.txt +++ b/src/libgit2/CMakeLists.txt @@ -2,94 +2,99 @@ add_library(git2internal OBJECT) set_target_properties(git2internal PROPERTIES C_STANDARD 90) set_target_properties(git2internal PROPERTIES C_EXTENSIONS OFF) - -if(DEPRECATE_HARD) - add_definitions(-DGIT_DEPRECATE_HARD) -endif() - -if(DEBUG_POOL) - set(GIT_DEBUG_POOL 1) -endif() -add_feature_info(debugpool GIT_DEBUG_POOL "debug pool allocator") - -if(DEBUG_STRICT_ALLOC) - set(GIT_DEBUG_STRICT_ALLOC 1) -endif() -add_feature_info(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators") - -if(DEBUG_STRICT_OPEN) - set(GIT_DEBUG_STRICT_OPEN 1) -endif() -add_feature_info(debugopen GIT_DEBUG_STRICT_OPEN "path validation in open") - - include(PkgBuildConfig) -include(SanitizeBool) - -# This variable will contain the libraries we need to put into -# libgit2.pc's Requires.private. That is, what we're linking to or -# what someone who's statically linking us needs to link to. -set(LIBGIT2_PC_REQUIRES "") -# This will be set later if we use the system's http-parser library or -# use iconv (OSX) and will be written to the Libs.private field in the -# pc file. -set(LIBGIT2_PC_LIBS "") set(LIBGIT2_INCLUDES - "${CMAKE_CURRENT_BINARY_DIR}" + "${PROJECT_BINARY_DIR}/src" "${PROJECT_SOURCE_DIR}/src/libgit2" + "${PROJECT_SOURCE_DIR}/src/util" "${PROJECT_SOURCE_DIR}/include") -if(HAVE_FUTIMENS) - set(GIT_USE_FUTIMENS 1) -endif () -add_feature_info(futimens GIT_USE_FUTIMENS "futimens support") +if(WIN32 AND EMBED_SSH_PATH) + file(GLOB SRC_SSH "${EMBED_SSH_PATH}/src/*.c") + list(SORT SRC_SSH) + target_sources(git2internal PRIVATE ${SRC_SSH}) -check_prototype_definition(qsort_r - "void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, int (*compar)(void *, const void *, const void *))" - "" "stdlib.h" GIT_QSORT_R_BSD) + list(APPEND LIBGIT2_SYSTEM_INCLUDES "${EMBED_SSH_PATH}/include") + file(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"") + set(GIT_SSH 1) +endif() -check_prototype_definition(qsort_r - "void qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *arg)" - "" "stdlib.h" GIT_QSORT_R_GNU) +<<<<<<< HEAD +include(SelectHTTPSBackend) +include(SelectHashes) +include(SelectHTTPParser) +include(SelectRegex) +include(SelectSSH) +include(SelectWinHTTP) +include(SelectZlib) -check_function_exists(qsort_s GIT_QSORT_S) -# Find required dependencies +if(USE_SHA1 STREQUAL "CollisionDetection") + file(GLOB SRC_SHA1 hash/sha1/collisiondetect.* hash/sha1/sha1dc/*) +elseif(USE_SHA1 STREQUAL "OpenSSL") + file(GLOB SRC_SHA1 hash/sha1/openssl.*) +elseif(USE_SHA1 STREQUAL "CommonCrypto") + file(GLOB SRC_SHA1 hash/sha1/common_crypto.*) +elseif(USE_SHA1 STREQUAL "mbedTLS") + file(GLOB SRC_SHA1 hash/sha1/mbedtls.*) +elseif(USE_SHA1 STREQUAL "Win32") + file(GLOB SRC_SHA1 hash/sha1/win32.*) +elseif(USE_SHA1 STREQUAL "Generic") + file(GLOB SRC_SHA1 hash/sha1/generic.*) +endif() +list(APPEND SRC_SHA1 "hash/sha1.h") +target_sources(git2internal PRIVATE ${SRC_SHA1}) -if(WIN32) - list(APPEND LIBGIT2_SYSTEM_LIBS ws2_32) -elseif(CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - list(APPEND LIBGIT2_SYSTEM_LIBS socket nsl) - list(APPEND LIBGIT2_PC_LIBS "-lsocket" "-lnsl") -elseif(CMAKE_SYSTEM_NAME MATCHES "Haiku") - list(APPEND LIBGIT2_SYSTEM_LIBS network) - list(APPEND LIBGIT2_PC_LIBS "-lnetwork") +# Optional external dependency: ntlmclient +if(USE_NTLMCLIENT) + set(GIT_NTLM 1) + add_subdirectory("${PROJECT_SOURCE_DIR}/deps/ntlmclient" "${PROJECT_BINARY_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") endif() +add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix") -check_library_exists(rt clock_gettime "time.h" NEED_LIBRT) -if(NEED_LIBRT) - list(APPEND LIBGIT2_SYSTEM_LIBS rt) - list(APPEND LIBGIT2_PC_LIBS "-lrt") +# Optional external dependency: GSSAPI + +include(SelectGSSAPI) + +# Optional external dependency: iconv +if(USE_ICONV) + find_package(Iconv) endif() +if(ICONV_FOUND) + set(GIT_USE_ICONV 1) + list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ICONV_INCLUDE_DIR}) + list(APPEND LIBGIT2_SYSTEM_LIBS ${ICONV_LIBRARIES}) + list(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES}) +endif() +add_feature_info(iconv GIT_USE_ICONV "iconv encoding conversion support") + if(USE_THREADS) - list(APPEND LIBGIT2_SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT}) - list(APPEND LIBGIT2_PC_LIBS ${CMAKE_THREAD_LIBS_INIT}) -endif() -add_feature_info(threadsafe USE_THREADS "threadsafe support") + if(NOT WIN32) + find_package(Threads REQUIRED) + endif() + set(GIT_THREADS 1) +endif() -if(WIN32 AND EMBED_SSH_PATH) - file(GLOB SRC_SSH "${EMBED_SSH_PATH}/src/*.c") - list(SORT SRC_SSH) - target_sources(git2internal PRIVATE ${SRC_SSH}) +if(USE_NSEC) + set(GIT_USE_NSEC 1) +endif() - list(APPEND LIBGIT2_SYSTEM_INCLUDES "${EMBED_SSH_PATH}/include") - file(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"") - set(GIT_SSH 1) +if(HAVE_STRUCT_STAT_ST_MTIM) + set(GIT_USE_STAT_MTIM 1) +elseif(HAVE_STRUCT_STAT_ST_MTIMESPEC) + set(GIT_USE_STAT_MTIMESPEC 1) +elseif(HAVE_STRUCT_STAT_ST_MTIME_NSEC) + set(GIT_USE_STAT_MTIME_NSEC 1) endif() +target_compile_definitions(git2internal PRIVATE _FILE_OFFSET_BITS=64) + +||||||| parent of a930dafb4 (refactor: make util an object library) include(SelectHTTPSBackend) include(SelectHashes) include(SelectHTTPParser) @@ -163,6 +168,8 @@ endif() target_compile_definitions(git2internal PRIVATE _FILE_OFFSET_BITS=64) +======= +>>>>>>> a930dafb4 (refactor: make util an object library) # Collect sourcefiles file(GLOB SRC_H "${PROJECT_SOURCE_DIR}/include/git2.h" @@ -171,33 +178,18 @@ file(GLOB SRC_H list(SORT SRC_H) target_sources(git2internal PRIVATE ${SRC_H}) -# On Windows use specific platform sources -if(WIN32 AND NOT CYGWIN) - set(WIN_RC "win32/git2.rc") - - file(GLOB SRC_OS win32/*.c win32/*.h) - list(SORT SRC_OS) - target_sources(git2internal PRIVATE ${SRC_OS}) -elseif(AMIGA) - target_compile_definitions(git2internal PRIVATE NO_ADDRINFO NO_READDIR_R NO_MMAP) -else() - file(GLOB SRC_OS unix/*.c unix/*.h) - list(SORT SRC_OS) - target_sources(git2internal PRIVATE ${SRC_OS}) -endif() - -if(USE_LEAK_CHECKER STREQUAL "valgrind") - target_compile_definitions(git2internal PRIVATE VALGRIND) -endif() - file(GLOB SRC_GIT2 *.c *.h - allocators/*.c allocators/*.h streams/*.c streams/*.h transports/*.c transports/*.h xdiff/*.c xdiff/*.h) list(SORT SRC_GIT2) target_sources(git2internal PRIVATE ${SRC_GIT2}) +if(WIN32 AND NOT CYGWIN) + # Add resource information on Windows + set(SRC_RC "git2.rc") +endif() + if(APPLE) # The old Secure Transport API has been deprecated in macOS 10.15. set_source_files_properties(streams/stransport.c PROPERTIES COMPILE_FLAGS -Wno-deprecated) @@ -220,21 +212,8 @@ else() set_source_files_properties(xdiff/xpatience.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") endif() -# Determine architecture of the machine -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(GIT_ARCH_64 1) -elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) - set(GIT_ARCH_32 1) -elseif(CMAKE_SIZEOF_VOID_P) - message(FATAL_ERROR "Unsupported architecture (pointer size is ${CMAKE_SIZEOF_VOID_P} bytes)") -else() - message(FATAL_ERROR "Unsupported architecture (CMAKE_SIZEOF_VOID_P is unset)") -endif() - -configure_file(features.h.in git2/sys/features.h) - ide_split_sources(git2internal) -list(APPEND LIBGIT2_OBJECTS $ ${LIBGIT2_DEPENDENCY_OBJECTS}) +list(APPEND LIBGIT2_OBJECTS $ $ ${LIBGIT2_DEPENDENCY_OBJECTS}) target_include_directories(git2internal PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${PROJECT_SOURCE_DIR}/include) target_include_directories(git2internal SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) @@ -254,7 +233,7 @@ if(XCODE_VERSION) endif() # Compile and link libgit2 -add_library(git2 ${WIN_RC} ${LIBGIT2_OBJECTS}) +add_library(git2 ${SRC_RC} ${LIBGIT2_OBJECTS}) target_link_libraries(git2 ${LIBGIT2_SYSTEM_LIBS}) set_target_properties(git2 PROPERTIES C_STANDARD 90) diff --git a/src/libgit2/blob.c b/src/libgit2/blob.c index 19ce8b3b50b..b1680d3a80c 100644 --- a/src/libgit2/blob.c +++ b/src/libgit2/blob.c @@ -101,7 +101,7 @@ static int write_file_stream( git_oid *id, git_odb *odb, const char *path, git_object_size_t file_size) { int fd, error; - char buffer[FILEIO_BUFSIZE]; + char buffer[GIT_BUFSIZE_FILEIO]; git_odb_stream *stream = NULL; ssize_t read_len = -1; git_object_size_t written = 0; diff --git a/src/libgit2/common.h b/src/libgit2/common.h index 549bddb5932..bb9ec5ac1fe 100644 --- a/src/libgit2/common.h +++ b/src/libgit2/common.h @@ -7,136 +7,31 @@ #ifndef INCLUDE_common_h__ #define INCLUDE_common_h__ -#ifndef LIBGIT2_NO_FEATURES_H -# include "git2/sys/features.h" -#endif - -#include "git2/common.h" -#include "cc-compat.h" - -/** Declare a function as always inlined. */ -#if defined(_MSC_VER) -# define GIT_INLINE(type) static __inline type -#elif defined(__GNUC__) -# define GIT_INLINE(type) static __inline__ type -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# define GIT_INLINE(type) static inline type -#else -# define GIT_INLINE(type) static type -#endif - -/** Support for gcc/clang __has_builtin intrinsic */ -#ifndef __has_builtin -# define __has_builtin(x) 0 -#endif - -/** - * Declare that a function's return value must be used. - * - * Used mostly to guard against potential silent bugs at runtime. This is - * recommended to be added to functions that: - * - * - Allocate / reallocate memory. This prevents memory leaks or errors where - * buffers are expected to have grown to a certain size, but could not be - * resized. - * - Acquire locks. When a lock cannot be acquired, that will almost certainly - * cause a data race / undefined behavior. - */ -#if defined(__GNUC__) -# define GIT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -# define GIT_WARN_UNUSED_RESULT -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef GIT_WIN32 - -# include -# include -# include -# include -# include -# include "win32/msvc-compat.h" -# include "win32/mingw-compat.h" -# include "win32/w32_common.h" -# include "win32/win32-compat.h" -# include "win32/error.h" -# include "win32/version.h" -# ifdef GIT_THREADS -# include "win32/thread.h" -# endif - -#else - -# include -# include -# ifdef GIT_THREADS -# include -# include -# endif - -#define GIT_LIBGIT2_CALL -#define GIT_SYSTEM_CALL - -#ifdef GIT_USE_STAT_ATIMESPEC -# define st_atim st_atimespec -# define st_ctim st_ctimespec -# define st_mtim st_mtimespec -#endif - -# include - -#endif - -#include "git2/types.h" -#include "git2/errors.h" +#include "git2_util.h" #include "errors.h" -#include "thread.h" -#include "integer.h" -#include "assert_safe.h" -#include "utf8.h" /* - * Include the declarations for deprecated functions; this ensures - * that they're decorated with the proper extern/visibility attributes. - */ +* Include the declarations for deprecated functions; this ensures +* that they're decorated with the proper extern/visibility attributes. +*/ #include "git2/deprecated.h" #include "posix.h" -#define DEFAULT_BUFSIZE 65536 -#define FILEIO_BUFSIZE DEFAULT_BUFSIZE -#define FILTERIO_BUFSIZE DEFAULT_BUFSIZE -#define NETIO_BUFSIZE DEFAULT_BUFSIZE - -/** - * Check a pointer allocation result, returning -1 if it failed. - */ -#define GIT_ERROR_CHECK_ALLOC(ptr) do { \ - if ((ptr) == NULL) { return -1; } \ - } while(0) - /** - * Check a string buffer allocation result, returning -1 if it failed. + * Initialize a structure with a version. */ -#define GIT_ERROR_CHECK_ALLOC_STR(buf) do { \ - if ((void *)(buf) == NULL || git_str_oom(buf)) { return -1; } \ - } while(0) +GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int version) +{ + memset(structure, 0, len); + *((int*)structure) = version; +} +#define GIT_INIT_STRUCTURE(S,V) git__init_structure(S, sizeof(*S), V) -/** - * Check a return value and propagate result if non-zero. - */ -#define GIT_ERROR_CHECK_ERROR(code) \ - do { int _err = (code); if (_err) return _err; } while (0) +#define GIT_INIT_STRUCTURE_FROM_TEMPLATE(PTR,VERSION,TYPE,TPL) do { \ + TYPE _tmpl = TPL; \ + GIT_ERROR_CHECK_VERSION(&(VERSION), _tmpl.version, #TYPE); \ + memcpy((PTR), &_tmpl, sizeof(_tmpl)); } while (0) /** * Check a versioned structure for validity @@ -157,58 +52,4 @@ GIT_INLINE(int) git_error__check_version(const void *structure, unsigned int exp } #define GIT_ERROR_CHECK_VERSION(S,V,N) if (git_error__check_version(S,V,N) < 0) return -1 -/** - * Initialize a structure with a version. - */ -GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int version) -{ - memset(structure, 0, len); - *((int*)structure) = version; -} -#define GIT_INIT_STRUCTURE(S,V) git__init_structure(S, sizeof(*S), V) - -#define GIT_INIT_STRUCTURE_FROM_TEMPLATE(PTR,VERSION,TYPE,TPL) do { \ - TYPE _tmpl = TPL; \ - GIT_ERROR_CHECK_VERSION(&(VERSION), _tmpl.version, #TYPE); \ - memcpy((PTR), &_tmpl, sizeof(_tmpl)); } while (0) - - -/** Check for additive overflow, setting an error if would occur. */ -#define GIT_ADD_SIZET_OVERFLOW(out, one, two) \ - (git__add_sizet_overflow(out, one, two) ? (git_error_set_oom(), 1) : 0) - -/** Check for additive overflow, setting an error if would occur. */ -#define GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize) \ - (git__multiply_sizet_overflow(out, nelem, elsize) ? (git_error_set_oom(), 1) : 0) - -/** Check for additive overflow, failing if it would occur. */ -#define GIT_ERROR_CHECK_ALLOC_ADD(out, one, two) \ - if (GIT_ADD_SIZET_OVERFLOW(out, one, two)) { return -1; } - -#define GIT_ERROR_CHECK_ALLOC_ADD3(out, one, two, three) \ - if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \ - GIT_ADD_SIZET_OVERFLOW(out, *(out), three)) { return -1; } - -#define GIT_ERROR_CHECK_ALLOC_ADD4(out, one, two, three, four) \ - if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \ - GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \ - GIT_ADD_SIZET_OVERFLOW(out, *(out), four)) { return -1; } - -#define GIT_ERROR_CHECK_ALLOC_ADD5(out, one, two, three, four, five) \ - if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \ - GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \ - GIT_ADD_SIZET_OVERFLOW(out, *(out), four) || \ - GIT_ADD_SIZET_OVERFLOW(out, *(out), five)) { return -1; } - -/** Check for multiplicative overflow, failing if it would occur. */ -#define GIT_ERROR_CHECK_ALLOC_MULTIPLY(out, nelem, elsize) \ - if (GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize)) { return -1; } - -/* NOTE: other git_error functions are in the public errors.h header file */ - -/* Forward declare git_str */ -typedef struct git_str git_str; - -#include "util.h" - #endif diff --git a/src/libgit2/diff_xdiff.c b/src/libgit2/diff_xdiff.c index 3f6eccac13d..5f56c5209a0 100644 --- a/src/libgit2/diff_xdiff.c +++ b/src/libgit2/diff_xdiff.c @@ -11,6 +11,7 @@ #include "diff.h" #include "diff_driver.h" #include "patch_generate.h" +#include "utf8.h" static int git_xdiff_scan_int(const char **str, int *value) { diff --git a/src/libgit2/filter.c b/src/libgit2/filter.c index 2712e8c6044..20b21572934 100644 --- a/src/libgit2/filter.c +++ b/src/libgit2/filter.c @@ -1085,7 +1085,7 @@ int git_filter_list_stream_file( const char *path, git_writestream *target) { - char buf[FILTERIO_BUFSIZE]; + char buf[GIT_BUFSIZE_FILTERIO]; git_str abspath = GIT_STR_INIT; const char *base = repo ? git_repository_workdir(repo) : NULL; git_vector filter_streams = GIT_VECTOR_INIT; diff --git a/src/libgit2/win32/git2.rc b/src/libgit2/git2.rc similarity index 97% rename from src/libgit2/win32/git2.rc rename to src/libgit2/git2.rc index 3f97239da39..d273afd7066 100644 --- a/src/libgit2/win32/git2.rc +++ b/src/libgit2/git2.rc @@ -1,5 +1,5 @@ #include -#include "../../../include/git2/version.h" +#include "../../include/git2/version.h" #ifndef LIBGIT2_FILENAME # ifdef __GNUC__ diff --git a/src/libgit2/netops.c b/src/libgit2/netops.c index 0a27365b8ae..00640c600ee 100644 --- a/src/libgit2/netops.c +++ b/src/libgit2/netops.c @@ -12,7 +12,6 @@ #include "posix.h" #include "str.h" -#include "http_parser.h" #include "runtime.h" int gitno_recv(gitno_buffer *buf) diff --git a/src/libgit2/odb.c b/src/libgit2/odb.c index 6d714ba547d..7b98c72ee8e 100644 --- a/src/libgit2/odb.c +++ b/src/libgit2/odb.c @@ -198,7 +198,7 @@ void git_odb_object_free(git_odb_object *object) int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_object_t type) { size_t hdr_len; - char hdr[64], buffer[FILEIO_BUFSIZE]; + char hdr[64], buffer[GIT_BUFSIZE_FILEIO]; git_hash_ctx ctx; ssize_t read_len = 0; int error = 0; diff --git a/src/libgit2/path.c b/src/libgit2/path.c index 05a3dc2cf90..a19340efe6f 100644 --- a/src/libgit2/path.c +++ b/src/libgit2/path.c @@ -9,6 +9,7 @@ #include "repository.h" #include "fs_path.h" +#include "utf8.h" typedef struct { git_repository *repo; diff --git a/src/libgit2/util/platform.h.in b/src/libgit2/util/platform.h.in deleted file mode 100644 index e511fe33109..00000000000 --- a/src/libgit2/util/platform.h.in +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef INCLUDE_platform_h__ -#define INCLUDE_platform_h__ - -#cmakedefine GIT_DEBUG_POOL 1 -#cmakedefine GIT_DEBUG_STRICT_ALLOC 1 -#cmakedefine GIT_DEBUG_STRICT_OPEN 1 - -#cmakedefine GIT_WIN32_LEAKCHECK 1 - -#cmakedefine GIT_ARCH_64 1 -#cmakedefine GIT_ARCH_32 1 - -#cmakedefine GIT_USE_STAT_MTIM 1 -#cmakedefine GIT_USE_STAT_MTIMESPEC 1 -#cmakedefine GIT_USE_STAT_MTIME_NSEC 1 -#cmakedefine GIT_USE_FUTIMENS 1 - -#cmakedefine GIT_USE_QSORT_R_BSD 1 -#cmakedefine GIT_USE_QSORT_R_GNU 1 -#cmakedefine GIT_USE_QSORT_S 1 - -#cmakedefine GIT_REGEX_REGCOMP_L 1 -#cmakedefine GIT_REGEX_REGCOMP 1 -#cmakedefine GIT_REGEX_PCRE 1 -#cmakedefine GIT_REGEX_PCRE2 1 -#cmakedefine GIT_REGEX_BUILTIN 1 - -#cmakedefine GIT_SHA1_COLLISIONDETECT 1 -#cmakedefine GIT_SHA1_WIN32 1 -#cmakedefine GIT_SHA1_COMMON_CRYPTO 1 -#cmakedefine GIT_SHA1_OPENSSL 1 -#cmakedefine GIT_SHA1_MBEDTLS 1 - -#endif diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt new file mode 100644 index 00000000000..ea2df0a560b --- /dev/null +++ b/src/util/CMakeLists.txt @@ -0,0 +1,59 @@ +# util: a shared library for common utility functions for libgit2 projects + +add_library(util OBJECT) +set_target_properties(util PROPERTIES C_STANDARD 90) +set_target_properties(util PROPERTIES C_EXTENSIONS OFF) + +set(UTIL_INCLUDES + "${PROJECT_BINARY_DIR}/src" + "${PROJECT_SOURCE_DIR}/src/util" + "${PROJECT_SOURCE_DIR}/include") + +file(GLOB UTIL_SRC *.c *.h allocators/*.c allocators/*.h hash/sha1.h) +list(SORT UTIL_SRC) + +# +# Platform specific sources +# + +if(WIN32 AND NOT CYGWIN) + file(GLOB UTIL_SRC_OS win32/*.c win32/*.h) + list(SORT UTIL_SRC_OS) +elseif(NOT AMIGA) + file(GLOB UTIL_SRC_OS unix/*.c unix/*.h) + list(SORT UTIL_SRC_OS) +endif() + +# +# Hash backend selection +# + +if(USE_SHA1 STREQUAL "CollisionDetection") + file(GLOB UTIL_SRC_HASH hash/sha1/collisiondetect.* hash/sha1/sha1dc/*) + target_compile_definitions(util PRIVATE SHA1DC_NO_STANDARD_INCLUDES=1) + target_compile_definitions(util PRIVATE SHA1DC_CUSTOM_INCLUDE_SHA1_C=\"git2_util.h\") + target_compile_definitions(util PRIVATE SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"git2_util.h\") +elseif(USE_SHA1 STREQUAL "OpenSSL") + file(GLOB UTIL_SRC_HASH hash/sha1/openssl.*) +elseif(USE_SHA1 STREQUAL "CommonCrypto") + file(GLOB UTIL_SRC_HASH hash/sha1/common_crypto.*) +elseif(USE_SHA1 STREQUAL "mbedTLS") + file(GLOB UTIL_SRC_HASH hash/sha1/mbedtls.*) +elseif(USE_SHA1 STREQUAL "Win32") + file(GLOB UTIL_SRC_HASH hash/sha1/win32.*) +elseif(USE_SHA1 STREQUAL "Generic") + file(GLOB UTIL_SRC_HASH hash/sha1/generic.*) +else() + message(FATAL_ERROR "Asked for unknown SHA1 backend: ${USE_SHA1}") +endif() + +list(SORT UTIL_SRC_HASH) + +# +# Build the library +# + +target_sources(util PRIVATE ${UTIL_SRC} ${UTIL_SRC_OS} ${UTIL_SRC_HASH}) + +target_include_directories(util PRIVATE ${UTIL_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${libgit2_SOURCE_DIR}/include) +target_include_directories(util SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) diff --git a/src/libgit2/alloc.c b/src/util/alloc.c similarity index 100% rename from src/libgit2/alloc.c rename to src/util/alloc.c diff --git a/src/libgit2/alloc.h b/src/util/alloc.h similarity index 100% rename from src/libgit2/alloc.h rename to src/util/alloc.h diff --git a/src/libgit2/allocators/failalloc.c b/src/util/allocators/failalloc.c similarity index 100% rename from src/libgit2/allocators/failalloc.c rename to src/util/allocators/failalloc.c diff --git a/src/libgit2/allocators/failalloc.h b/src/util/allocators/failalloc.h similarity index 97% rename from src/libgit2/allocators/failalloc.h rename to src/util/allocators/failalloc.h index 6115e51e78f..91264a0bb91 100644 --- a/src/libgit2/allocators/failalloc.h +++ b/src/util/allocators/failalloc.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_allocators_failalloc_h__ #define INCLUDE_allocators_failalloc_h__ -#include "common.h" +#include "git2_util.h" extern void *git_failalloc_malloc(size_t len, const char *file, int line); extern void *git_failalloc_calloc(size_t nelem, size_t elsize, const char *file, int line); diff --git a/src/libgit2/allocators/stdalloc.c b/src/util/allocators/stdalloc.c similarity index 100% rename from src/libgit2/allocators/stdalloc.c rename to src/util/allocators/stdalloc.c diff --git a/src/libgit2/allocators/stdalloc.h b/src/util/allocators/stdalloc.h similarity index 94% rename from src/libgit2/allocators/stdalloc.h rename to src/util/allocators/stdalloc.h index fa23fe6e346..955038cb0d5 100644 --- a/src/libgit2/allocators/stdalloc.h +++ b/src/util/allocators/stdalloc.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_allocators_stdalloc_h__ #define INCLUDE_allocators_stdalloc_h__ -#include "common.h" +#include "git2_util.h" #include "alloc.h" diff --git a/src/libgit2/allocators/win32_leakcheck.c b/src/util/allocators/win32_leakcheck.c similarity index 100% rename from src/libgit2/allocators/win32_leakcheck.c rename to src/util/allocators/win32_leakcheck.c diff --git a/src/libgit2/allocators/win32_leakcheck.h b/src/util/allocators/win32_leakcheck.h similarity index 94% rename from src/libgit2/allocators/win32_leakcheck.h rename to src/util/allocators/win32_leakcheck.h index 089690f90a2..edcd9307f90 100644 --- a/src/libgit2/allocators/win32_leakcheck.h +++ b/src/util/allocators/win32_leakcheck.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_allocators_win32_leakcheck_h #define INCLUDE_allocators_win32_leakcheck_h -#include "common.h" +#include "git2_util.h" #include "alloc.h" diff --git a/src/libgit2/array.h b/src/util/array.h similarity index 99% rename from src/libgit2/array.h rename to src/util/array.h index e97688b365f..cbab52ad1f3 100644 --- a/src/libgit2/array.h +++ b/src/util/array.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_array_h__ #define INCLUDE_array_h__ -#include "common.h" +#include "git2_util.h" /* * Use this to declare a typesafe resizable array of items, a la: diff --git a/src/libgit2/assert_safe.h b/src/util/assert_safe.h similarity index 100% rename from src/libgit2/assert_safe.h rename to src/util/assert_safe.h diff --git a/src/libgit2/bitvec.h b/src/util/bitvec.h similarity index 100% rename from src/libgit2/bitvec.h rename to src/util/bitvec.h diff --git a/src/libgit2/cc-compat.h b/src/util/cc-compat.h similarity index 100% rename from src/libgit2/cc-compat.h rename to src/util/cc-compat.h diff --git a/src/libgit2/date.c b/src/util/date.c similarity index 98% rename from src/libgit2/date.c rename to src/util/date.c index 0e5ffc96b06..4d757e21a00 100644 --- a/src/libgit2/date.c +++ b/src/util/date.c @@ -1,10 +1,11 @@ /* - * GIT - The information manager from hell + * Copyright (C) the libgit2 contributors. All rights reserved. * - * Copyright (C) Linus Torvalds, 2005 + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. */ -#include "common.h" +#include "git2_util.h" #ifndef GIT_WIN32 #include diff --git a/src/libgit2/date.h b/src/util/date.h similarity index 100% rename from src/libgit2/date.h rename to src/util/date.h diff --git a/src/libgit2/filebuf.c b/src/util/filebuf.c similarity index 99% rename from src/libgit2/filebuf.c rename to src/util/filebuf.c index eafcba3bd6f..e014d43b25f 100644 --- a/src/libgit2/filebuf.c +++ b/src/util/filebuf.c @@ -65,7 +65,7 @@ static int lock_file(git_filebuf *file, int flags, mode_t mode) if ((flags & GIT_FILEBUF_APPEND) && git_fs_path_exists(file->path_original) == true) { git_file source; - char buffer[FILEIO_BUFSIZE]; + char buffer[GIT_BUFSIZE_FILEIO]; ssize_t read_bytes; int error = 0; diff --git a/src/libgit2/filebuf.h b/src/util/filebuf.h similarity index 99% rename from src/libgit2/filebuf.h rename to src/util/filebuf.h index adbb19936ad..4a61ae4e3bf 100644 --- a/src/libgit2/filebuf.h +++ b/src/util/filebuf.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_filebuf_h__ #define INCLUDE_filebuf_h__ -#include "common.h" +#include "git2_util.h" #include "futils.h" #include "hash.h" diff --git a/src/libgit2/fs_path.c b/src/util/fs_path.c similarity index 99% rename from src/libgit2/fs_path.c rename to src/util/fs_path.c index 7a657778a3b..920c3907349 100644 --- a/src/libgit2/fs_path.c +++ b/src/util/fs_path.c @@ -7,8 +7,9 @@ #include "fs_path.h" +#include "git2_util.h" +#include "futils.h" #include "posix.h" -#include "repository.h" #ifdef GIT_WIN32 #include "win32/posix.h" #include "win32/w32_buffer.h" @@ -21,6 +22,13 @@ #include #include +#define ensure_error_set(code) do { \ + const git_error *e = git_error_last(); \ + if (!e || !e->message) \ + git_error_set(e ? e->klass : GIT_ERROR_CALLBACK, \ + "filesystem callback returned %d", code); \ + } while(0) + static int dos_drive_prefix_length(const char *path) { int i; @@ -530,7 +538,7 @@ int git_fs_path_walk_up( if (!scan) { error = cb(data, ""); if (error) - git_error_set_after_callback(error); + ensure_error_set(error); return error; } @@ -543,7 +551,7 @@ int git_fs_path_walk_up( iter.ptr[scan] = oldc; if (error) { - git_error_set_after_callback(error); + ensure_error_set(error); break; } @@ -563,7 +571,7 @@ int git_fs_path_walk_up( if (!error && stop == 0 && iter.ptr[0] != '/') { error = cb(data, ""); if (error) - git_error_set_after_callback(error); + ensure_error_set(error); } return error; @@ -1167,7 +1175,7 @@ int git_fs_path_direach( /* Only set our own error if the callback did not set one already */ if (error != 0) { if (!git_error_last()) - git_error_set_after_callback(error); + ensure_error_set(error); break; } diff --git a/src/libgit2/fs_path.h b/src/util/fs_path.h similarity index 99% rename from src/libgit2/fs_path.h rename to src/util/fs_path.h index 222c44abcee..bb840c43c6b 100644 --- a/src/libgit2/fs_path.h +++ b/src/util/fs_path.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_fs_path_h__ #define INCLUDE_fs_path_h__ -#include "common.h" +#include "git2_util.h" #include "posix.h" #include "str.h" diff --git a/src/libgit2/futils.c b/src/util/futils.c similarity index 99% rename from src/libgit2/futils.c rename to src/util/futils.c index 42c35955e30..2b0dbf362af 100644 --- a/src/libgit2/futils.c +++ b/src/util/futils.c @@ -856,7 +856,7 @@ int git_futils_fake_symlink(const char *target, const char *path) static int cp_by_fd(int ifd, int ofd, bool close_fd_when_done) { int error = 0; - char buffer[FILEIO_BUFSIZE]; + char buffer[GIT_BUFSIZE_FILEIO]; ssize_t len = 0; while (!error && (len = p_read(ifd, buffer, sizeof(buffer))) > 0) diff --git a/src/libgit2/futils.h b/src/util/futils.h similarity index 99% rename from src/libgit2/futils.h rename to src/util/futils.h index a82ec41cc63..fb1afcbd596 100644 --- a/src/libgit2/futils.h +++ b/src/util/futils.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_futils_h__ #define INCLUDE_futils_h__ -#include "common.h" +#include "git2_util.h" #include "map.h" #include "posix.h" diff --git a/src/util/git2_util.h b/src/util/git2_util.h new file mode 100644 index 00000000000..ad3f1c71fc3 --- /dev/null +++ b/src/util/git2_util.h @@ -0,0 +1,168 @@ +/* + * 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_git2_util_h__ +#define INCLUDE_git2_util_h__ + +#ifndef LIBGIT2_NO_FEATURES_H +# include "git2/sys/features.h" +#endif + +#include "git2/common.h" +#include "cc-compat.h" + +typedef struct git_str git_str; + +/** Declare a function as always inlined. */ +#if defined(_MSC_VER) +# define GIT_INLINE(type) static __inline type +#elif defined(__GNUC__) +# define GIT_INLINE(type) static __inline__ type +#else +# define GIT_INLINE(type) static type +#endif + +/** Support for gcc/clang __has_builtin intrinsic */ +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +/** + * Declare that a function's return value must be used. + * + * Used mostly to guard against potential silent bugs at runtime. This is + * recommended to be added to functions that: + * + * - Allocate / reallocate memory. This prevents memory leaks or errors where + * buffers are expected to have grown to a certain size, but could not be + * resized. + * - Acquire locks. When a lock cannot be acquired, that will almost certainly + * cause a data race / undefined behavior. + */ +#if defined(__GNUC__) +# define GIT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +# define GIT_WARN_UNUSED_RESULT +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef GIT_WIN32 + +# include +# include +# include +# include +# include +# include "win32/msvc-compat.h" +# include "win32/mingw-compat.h" +# include "win32/win32-compat.h" +# include "win32/w32_common.h" +# include "win32/version.h" +# include "win32/error.h" +# ifdef GIT_THREADS +# include "win32/thread.h" +# endif + +#else + +# include +# include +# ifdef GIT_THREADS +# include +# include +# endif + +#define GIT_LIBGIT2_CALL +#define GIT_SYSTEM_CALL + +#ifdef GIT_USE_STAT_ATIMESPEC +# define st_atim st_atimespec +# define st_ctim st_ctimespec +# define st_mtim st_mtimespec +#endif + +# include + +#endif + +#include "git2/types.h" +#include "git2/errors.h" +#include "thread.h" +#include "integer.h" +#include "assert_safe.h" + +#include "posix.h" + +#define GIT_BUFSIZE_DEFAULT 65536 +#define GIT_BUFSIZE_FILEIO GIT_BUFSIZE_DEFAULT +#define GIT_BUFSIZE_FILTERIO GIT_BUFSIZE_DEFAULT +#define GIT_BUFSIZE_NETIO GIT_BUFSIZE_DEFAULT + + +/** + * Check a pointer allocation result, returning -1 if it failed. + */ +#define GIT_ERROR_CHECK_ALLOC(ptr) do { \ + if ((ptr) == NULL) { return -1; } \ + } while(0) + +/** + * Check a buffer allocation result, returning -1 if it failed. + */ +#define GIT_ERROR_CHECK_ALLOC_STR(buf) do { \ + if ((void *)(buf) == NULL || git_str_oom(buf)) { return -1; } \ + } while(0) + +/** + * Check a return value and propagate result if non-zero. + */ +#define GIT_ERROR_CHECK_ERROR(code) \ + do { int _err = (code); if (_err) return _err; } while (0) + + +/** Check for additive overflow, setting an error if would occur. */ +#define GIT_ADD_SIZET_OVERFLOW(out, one, two) \ + (git__add_sizet_overflow(out, one, two) ? (git_error_set_oom(), 1) : 0) + +/** Check for additive overflow, setting an error if would occur. */ +#define GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize) \ + (git__multiply_sizet_overflow(out, nelem, elsize) ? (git_error_set_oom(), 1) : 0) + +/** Check for additive overflow, failing if it would occur. */ +#define GIT_ERROR_CHECK_ALLOC_ADD(out, one, two) \ + if (GIT_ADD_SIZET_OVERFLOW(out, one, two)) { return -1; } + +#define GIT_ERROR_CHECK_ALLOC_ADD3(out, one, two, three) \ + if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \ + GIT_ADD_SIZET_OVERFLOW(out, *(out), three)) { return -1; } + +#define GIT_ERROR_CHECK_ALLOC_ADD4(out, one, two, three, four) \ + if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \ + GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \ + GIT_ADD_SIZET_OVERFLOW(out, *(out), four)) { return -1; } + +#define GIT_ERROR_CHECK_ALLOC_ADD5(out, one, two, three, four, five) \ + if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \ + GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \ + GIT_ADD_SIZET_OVERFLOW(out, *(out), four) || \ + GIT_ADD_SIZET_OVERFLOW(out, *(out), five)) { return -1; } + +/** Check for multiplicative overflow, failing if it would occur. */ +#define GIT_ERROR_CHECK_ALLOC_MULTIPLY(out, nelem, elsize) \ + if (GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize)) { return -1; } + +#include "util.h" + +#endif diff --git a/src/libgit2/hash.c b/src/util/hash.c similarity index 100% rename from src/libgit2/hash.c rename to src/util/hash.c diff --git a/src/libgit2/hash.h b/src/util/hash.h similarity index 98% rename from src/libgit2/hash.h rename to src/util/hash.h index 507c1cb256f..5f138656349 100644 --- a/src/libgit2/hash.h +++ b/src/util/hash.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_hash_h__ #define INCLUDE_hash_h__ -#include "common.h" +#include "git2_util.h" #include "hash/sha1.h" diff --git a/src/libgit2/hash/sha1.h b/src/util/hash/sha1.h similarity index 97% rename from src/libgit2/hash/sha1.h rename to src/util/hash/sha1.h index 4b4dae3f831..9d32bce42e5 100644 --- a/src/libgit2/hash/sha1.h +++ b/src/util/hash/sha1.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_hash_sha1_h__ #define INCLUDE_hash_sha1_h__ -#include "common.h" +#include "git2_util.h" typedef struct git_hash_sha1_ctx git_hash_sha1_ctx; diff --git a/src/libgit2/hash/sha1/collisiondetect.c b/src/util/hash/sha1/collisiondetect.c similarity index 100% rename from src/libgit2/hash/sha1/collisiondetect.c rename to src/util/hash/sha1/collisiondetect.c diff --git a/src/libgit2/hash/sha1/collisiondetect.h b/src/util/hash/sha1/collisiondetect.h similarity index 100% rename from src/libgit2/hash/sha1/collisiondetect.h rename to src/util/hash/sha1/collisiondetect.h diff --git a/src/libgit2/hash/sha1/common_crypto.c b/src/util/hash/sha1/common_crypto.c similarity index 100% rename from src/libgit2/hash/sha1/common_crypto.c rename to src/util/hash/sha1/common_crypto.c diff --git a/src/libgit2/hash/sha1/common_crypto.h b/src/util/hash/sha1/common_crypto.h similarity index 100% rename from src/libgit2/hash/sha1/common_crypto.h rename to src/util/hash/sha1/common_crypto.h diff --git a/src/libgit2/hash/sha1/generic.c b/src/util/hash/sha1/generic.c similarity index 100% rename from src/libgit2/hash/sha1/generic.c rename to src/util/hash/sha1/generic.c diff --git a/src/libgit2/hash/sha1/generic.h b/src/util/hash/sha1/generic.h similarity index 100% rename from src/libgit2/hash/sha1/generic.h rename to src/util/hash/sha1/generic.h diff --git a/src/libgit2/hash/sha1/mbedtls.c b/src/util/hash/sha1/mbedtls.c similarity index 100% rename from src/libgit2/hash/sha1/mbedtls.c rename to src/util/hash/sha1/mbedtls.c diff --git a/src/libgit2/hash/sha1/mbedtls.h b/src/util/hash/sha1/mbedtls.h similarity index 100% rename from src/libgit2/hash/sha1/mbedtls.h rename to src/util/hash/sha1/mbedtls.h diff --git a/src/libgit2/hash/sha1/openssl.c b/src/util/hash/sha1/openssl.c similarity index 100% rename from src/libgit2/hash/sha1/openssl.c rename to src/util/hash/sha1/openssl.c diff --git a/src/libgit2/hash/sha1/openssl.h b/src/util/hash/sha1/openssl.h similarity index 100% rename from src/libgit2/hash/sha1/openssl.h rename to src/util/hash/sha1/openssl.h diff --git a/src/libgit2/hash/sha1/sha1dc/sha1.c b/src/util/hash/sha1/sha1dc/sha1.c similarity index 100% rename from src/libgit2/hash/sha1/sha1dc/sha1.c rename to src/util/hash/sha1/sha1dc/sha1.c diff --git a/src/libgit2/hash/sha1/sha1dc/sha1.h b/src/util/hash/sha1/sha1dc/sha1.h similarity index 100% rename from src/libgit2/hash/sha1/sha1dc/sha1.h rename to src/util/hash/sha1/sha1dc/sha1.h diff --git a/src/libgit2/hash/sha1/sha1dc/ubc_check.c b/src/util/hash/sha1/sha1dc/ubc_check.c similarity index 100% rename from src/libgit2/hash/sha1/sha1dc/ubc_check.c rename to src/util/hash/sha1/sha1dc/ubc_check.c diff --git a/src/libgit2/hash/sha1/sha1dc/ubc_check.h b/src/util/hash/sha1/sha1dc/ubc_check.h similarity index 100% rename from src/libgit2/hash/sha1/sha1dc/ubc_check.h rename to src/util/hash/sha1/sha1dc/ubc_check.h diff --git a/src/libgit2/hash/sha1/win32.c b/src/util/hash/sha1/win32.c similarity index 100% rename from src/libgit2/hash/sha1/win32.c rename to src/util/hash/sha1/win32.c diff --git a/src/libgit2/hash/sha1/win32.h b/src/util/hash/sha1/win32.h similarity index 100% rename from src/libgit2/hash/sha1/win32.h rename to src/util/hash/sha1/win32.h diff --git a/src/libgit2/integer.h b/src/util/integer.h similarity index 100% rename from src/libgit2/integer.h rename to src/util/integer.h diff --git a/src/libgit2/khash.h b/src/util/khash.h similarity index 100% rename from src/libgit2/khash.h rename to src/util/khash.h diff --git a/src/libgit2/map.h b/src/util/map.h similarity index 98% rename from src/libgit2/map.h rename to src/util/map.h index 01931d199c0..c101e46f6a6 100644 --- a/src/libgit2/map.h +++ b/src/util/map.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_map_h__ #define INCLUDE_map_h__ -#include "common.h" +#include "git2_util.h" /* p_mmap() prot values */ diff --git a/src/libgit2/net.c b/src/util/net.c similarity index 99% rename from src/libgit2/net.c rename to src/util/net.c index a76fd1d7c5b..b2236daf8a1 100644 --- a/src/libgit2/net.c +++ b/src/util/net.c @@ -6,7 +6,6 @@ */ #include "net.h" -#include "netops.h" #include diff --git a/src/libgit2/net.h b/src/util/net.h similarity index 99% rename from src/libgit2/net.h rename to src/util/net.h index 499315e6ce2..88030a95295 100644 --- a/src/libgit2/net.h +++ b/src/util/net.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_net_h__ #define INCLUDE_net_h__ -#include "common.h" +#include "git2_util.h" typedef struct git_net_url { char *scheme; diff --git a/src/libgit2/pool.c b/src/util/pool.c similarity index 100% rename from src/libgit2/pool.c rename to src/util/pool.c diff --git a/src/libgit2/pool.h b/src/util/pool.h similarity index 99% rename from src/libgit2/pool.h rename to src/util/pool.h index cecb84665ff..0238431b0a0 100644 --- a/src/libgit2/pool.h +++ b/src/util/pool.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_pool_h__ #define INCLUDE_pool_h__ -#include "common.h" +#include "git2_util.h" #include "vector.h" diff --git a/src/libgit2/posix.c b/src/util/posix.c similarity index 100% rename from src/libgit2/posix.c rename to src/util/posix.c diff --git a/src/libgit2/posix.h b/src/util/posix.h similarity index 99% rename from src/libgit2/posix.h rename to src/util/posix.h index e6f60307811..c8f8cd9d2cc 100644 --- a/src/libgit2/posix.h +++ b/src/util/posix.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_posix_h__ #define INCLUDE_posix_h__ -#include "common.h" +#include "git2_util.h" #include #include diff --git a/src/libgit2/pqueue.c b/src/util/pqueue.c similarity index 100% rename from src/libgit2/pqueue.c rename to src/util/pqueue.c diff --git a/src/libgit2/pqueue.h b/src/util/pqueue.h similarity index 98% rename from src/libgit2/pqueue.h rename to src/util/pqueue.h index 4db74ea0371..97232b4a9fd 100644 --- a/src/libgit2/pqueue.h +++ b/src/util/pqueue.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_pqueue_h__ #define INCLUDE_pqueue_h__ -#include "common.h" +#include "git2_util.h" #include "vector.h" diff --git a/src/rand.c b/src/util/rand.c similarity index 99% rename from src/rand.c rename to src/util/rand.c index 0a208134e4c..4324949023b 100644 --- a/src/rand.c +++ b/src/util/rand.c @@ -6,7 +6,7 @@ worldwide. This software is distributed without any warranty. See . */ -#include "common.h" +#include "git2_util.h" #include "rand.h" #include "runtime.h" diff --git a/src/rand.h b/src/util/rand.h similarity index 97% rename from src/rand.h rename to src/util/rand.h index 2e60561e51d..fa0619aa27d 100644 --- a/src/rand.h +++ b/src/util/rand.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_rand_h__ #define INCLUDE_rand_h__ -#include "common.h" +#include "git2_util.h" /** * Initialize the random number generation subsystem. This will diff --git a/src/libgit2/regexp.c b/src/util/regexp.c similarity index 100% rename from src/libgit2/regexp.c rename to src/util/regexp.c diff --git a/src/libgit2/regexp.h b/src/util/regexp.h similarity index 99% rename from src/libgit2/regexp.h rename to src/util/regexp.h index 2592ef38352..d0862b10786 100644 --- a/src/libgit2/regexp.h +++ b/src/util/regexp.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_regexp_h__ #define INCLUDE_regexp_h__ -#include "common.h" +#include "git2_util.h" #if defined(GIT_REGEX_BUILTIN) || defined(GIT_REGEX_PCRE) # include "pcre.h" diff --git a/src/libgit2/runtime.c b/src/util/runtime.c similarity index 99% rename from src/libgit2/runtime.c rename to src/util/runtime.c index c05dee8b96d..a7711ffc44c 100644 --- a/src/libgit2/runtime.c +++ b/src/util/runtime.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "common.h" +#include "git2_util.h" #include "runtime.h" static git_runtime_shutdown_fn shutdown_callback[32]; diff --git a/src/libgit2/runtime.h b/src/util/runtime.h similarity index 98% rename from src/libgit2/runtime.h rename to src/util/runtime.h index 24ac58ee96c..6cbfd6043a4 100644 --- a/src/libgit2/runtime.h +++ b/src/util/runtime.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_runtime_h__ #define INCLUDE_runtime_h__ -#include "common.h" +#include "git2_util.h" typedef int (*git_runtime_init_fn)(void); typedef void (*git_runtime_shutdown_fn)(void); diff --git a/src/libgit2/sortedcache.c b/src/util/sortedcache.c similarity index 100% rename from src/libgit2/sortedcache.c rename to src/util/sortedcache.c diff --git a/src/libgit2/sortedcache.h b/src/util/sortedcache.h similarity index 99% rename from src/libgit2/sortedcache.h rename to src/util/sortedcache.h index ef260a093a5..3eee4659f58 100644 --- a/src/libgit2/sortedcache.h +++ b/src/util/sortedcache.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_sorted_cache_h__ #define INCLUDE_sorted_cache_h__ -#include "common.h" +#include "git2_util.h" #include "util.h" #include "futils.h" diff --git a/src/libgit2/str.c b/src/util/str.c similarity index 100% rename from src/libgit2/str.c rename to src/util/str.c diff --git a/src/libgit2/str.h b/src/util/str.h similarity index 99% rename from src/libgit2/str.h rename to src/util/str.h index ef769ce2f98..588e6fc22bc 100644 --- a/src/libgit2/str.h +++ b/src/util/str.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_str_h__ #define INCLUDE_str_h__ -#include "common.h" +#include "git2_util.h" struct git_str { char *ptr; diff --git a/src/libgit2/strmap.c b/src/util/strmap.c similarity index 100% rename from src/libgit2/strmap.c rename to src/util/strmap.c diff --git a/src/libgit2/strmap.h b/src/util/strmap.h similarity index 99% rename from src/libgit2/strmap.h rename to src/util/strmap.h index 9f5e4cc8bab..b64d3dcb55d 100644 --- a/src/libgit2/strmap.h +++ b/src/util/strmap.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_strmap_h__ #define INCLUDE_strmap_h__ -#include "common.h" +#include "git2_util.h" /** A map with C strings as key. */ typedef struct kh_str_s git_strmap; diff --git a/src/libgit2/strnlen.h b/src/util/strnlen.h similarity index 100% rename from src/libgit2/strnlen.h rename to src/util/strnlen.h diff --git a/src/libgit2/thread.c b/src/util/thread.c similarity index 99% rename from src/libgit2/thread.c rename to src/util/thread.c index 3171771d7f3..bc7364f8c1a 100644 --- a/src/libgit2/thread.c +++ b/src/util/thread.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "common.h" +#include "git2_util.h" #if !defined(GIT_THREADS) diff --git a/src/libgit2/thread.h b/src/util/thread.h similarity index 100% rename from src/libgit2/thread.h rename to src/util/thread.h diff --git a/src/libgit2/tsort.c b/src/util/tsort.c similarity index 99% rename from src/libgit2/tsort.c rename to src/util/tsort.c index 045efad23f6..2ef03d03a88 100644 --- a/src/libgit2/tsort.c +++ b/src/util/tsort.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "common.h" +#include "git2_util.h" /** * An array-of-pointers implementation of Python's Timsort diff --git a/src/libgit2/unix/map.c b/src/util/unix/map.c similarity index 98% rename from src/libgit2/unix/map.c rename to src/util/unix/map.c index 23fcb786e5a..93307768947 100644 --- a/src/libgit2/unix/map.c +++ b/src/util/unix/map.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "common.h" +#include "git2_util.h" #if !defined(GIT_WIN32) && !defined(NO_MMAP) diff --git a/src/libgit2/unix/posix.h b/src/util/unix/posix.h similarity index 99% rename from src/libgit2/unix/posix.h rename to src/util/unix/posix.h index 49065e5336c..778477e8e2f 100644 --- a/src/libgit2/unix/posix.h +++ b/src/util/unix/posix.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_unix_posix_h__ #define INCLUDE_unix_posix_h__ -#include "common.h" +#include "git2_util.h" #include #include diff --git a/src/libgit2/unix/pthread.h b/src/util/unix/pthread.h similarity index 100% rename from src/libgit2/unix/pthread.h rename to src/util/unix/pthread.h diff --git a/src/libgit2/unix/realpath.c b/src/util/unix/realpath.c similarity index 96% rename from src/libgit2/unix/realpath.c rename to src/util/unix/realpath.c index f1ca669f74d..9e31a63b9f4 100644 --- a/src/libgit2/unix/realpath.c +++ b/src/util/unix/realpath.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "common.h" +#include "git2_util.h" #ifndef GIT_WIN32 diff --git a/src/libgit2/utf8.c b/src/util/utf8.c similarity index 99% rename from src/libgit2/utf8.c rename to src/util/utf8.c index 77065cb710e..c566fdf2084 100644 --- a/src/libgit2/utf8.c +++ b/src/util/utf8.c @@ -7,7 +7,7 @@ #include "utf8.h" -#include "common.h" +#include "git2_util.h" /* * git_utf8_iterate is taken from the utf8proc project, diff --git a/src/libgit2/utf8.h b/src/util/utf8.h similarity index 98% rename from src/libgit2/utf8.h rename to src/util/utf8.h index dff91b2945a..753ab07e2a5 100644 --- a/src/libgit2/utf8.h +++ b/src/util/utf8.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_utf8_h__ #define INCLUDE_utf8_h__ -#include "common.h" +#include "git2_util.h" /* * Iterate through an UTF-8 string, yielding one codepoint at a time. diff --git a/src/libgit2/util.c b/src/util/util.c similarity index 99% rename from src/libgit2/util.c rename to src/util/util.c index e06d4ca0913..aee95fddfb5 100644 --- a/src/libgit2/util.c +++ b/src/util/util.c @@ -7,7 +7,7 @@ #include "util.h" -#include "common.h" +#include "git2_util.h" #ifdef GIT_WIN32 # include "win32/utf-conv.h" diff --git a/src/libgit2/util.h b/src/util/util.h similarity index 99% rename from src/libgit2/util.h rename to src/util/util.h index 141779ade85..8d6d1d6b683 100644 --- a/src/libgit2/util.h +++ b/src/util/util.h @@ -12,7 +12,7 @@ #endif #include "str.h" -#include "common.h" +#include "git2_util.h" #include "strnlen.h" #include "thread.h" diff --git a/src/libgit2/varint.c b/src/util/varint.c similarity index 100% rename from src/libgit2/varint.c rename to src/util/varint.c diff --git a/src/libgit2/varint.h b/src/util/varint.h similarity index 94% rename from src/libgit2/varint.h rename to src/util/varint.h index 652e2248657..79b8f5548a9 100644 --- a/src/libgit2/varint.h +++ b/src/util/varint.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_varint_h__ #define INCLUDE_varint_h__ -#include "common.h" +#include "git2_util.h" #include diff --git a/src/libgit2/vector.c b/src/util/vector.c similarity index 100% rename from src/libgit2/vector.c rename to src/util/vector.c diff --git a/src/libgit2/vector.h b/src/util/vector.h similarity index 99% rename from src/libgit2/vector.h rename to src/util/vector.h index ae3c79a4cdb..e50cdfefcbd 100644 --- a/src/libgit2/vector.h +++ b/src/util/vector.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_vector_h__ #define INCLUDE_vector_h__ -#include "common.h" +#include "git2_util.h" typedef int (*git_vector_cmp)(const void *, const void *); diff --git a/src/libgit2/wildmatch.c b/src/util/wildmatch.c similarity index 100% rename from src/libgit2/wildmatch.c rename to src/util/wildmatch.c diff --git a/src/libgit2/wildmatch.h b/src/util/wildmatch.h similarity index 95% rename from src/libgit2/wildmatch.h rename to src/util/wildmatch.h index 44bb575a611..f2064050025 100644 --- a/src/libgit2/wildmatch.h +++ b/src/util/wildmatch.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_wildmatch_h__ #define INCLUDE_wildmatch_h__ -#include "common.h" +#include "git2_util.h" #define WM_CASEFOLD 1 #define WM_PATHNAME 2 diff --git a/src/libgit2/win32/dir.c b/src/util/win32/dir.c similarity index 100% rename from src/libgit2/win32/dir.c rename to src/util/win32/dir.c diff --git a/src/libgit2/win32/dir.h b/src/util/win32/dir.h similarity index 97% rename from src/libgit2/win32/dir.h rename to src/util/win32/dir.h index acd64729eb9..810111534df 100644 --- a/src/libgit2/win32/dir.h +++ b/src/util/win32/dir.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_win32_dir_h__ #define INCLUDE_win32_dir_h__ -#include "common.h" +#include "git2_util.h" #include "w32_util.h" diff --git a/src/libgit2/win32/error.c b/src/util/win32/error.c similarity index 100% rename from src/libgit2/win32/error.c rename to src/util/win32/error.c diff --git a/src/libgit2/win32/error.h b/src/util/win32/error.h similarity index 93% rename from src/libgit2/win32/error.h rename to src/util/win32/error.h index 9e81141ce1d..fd53b7f99a8 100644 --- a/src/libgit2/win32/error.h +++ b/src/util/win32/error.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_win32_error_h__ #define INCLUDE_win32_error_h__ -#include "common.h" +#include "git2_util.h" extern char *git_win32_get_error_message(DWORD error_code); diff --git a/src/libgit2/win32/findfile.c b/src/util/win32/findfile.c similarity index 100% rename from src/libgit2/win32/findfile.c rename to src/util/win32/findfile.c diff --git a/src/libgit2/win32/findfile.h b/src/util/win32/findfile.h similarity index 96% rename from src/libgit2/win32/findfile.h rename to src/util/win32/findfile.h index 61fb7dbad79..7b191d1feff 100644 --- a/src/libgit2/win32/findfile.h +++ b/src/util/win32/findfile.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_win32_findfile_h__ #define INCLUDE_win32_findfile_h__ -#include "common.h" +#include "git2_util.h" /** Sets the mock registry root for Git for Windows for testing. */ extern int git_win32__set_registry_system_dir(const wchar_t *mock_sysdir); diff --git a/src/libgit2/win32/map.c b/src/util/win32/map.c similarity index 99% rename from src/libgit2/win32/map.c rename to src/util/win32/map.c index 2aabc9b153d..52e1363eac9 100644 --- a/src/libgit2/win32/map.c +++ b/src/util/win32/map.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "common.h" +#include "git2_util.h" #include "map.h" #include diff --git a/src/libgit2/win32/mingw-compat.h b/src/util/win32/mingw-compat.h similarity index 100% rename from src/libgit2/win32/mingw-compat.h rename to src/util/win32/mingw-compat.h diff --git a/src/libgit2/win32/msvc-compat.h b/src/util/win32/msvc-compat.h similarity index 100% rename from src/libgit2/win32/msvc-compat.h rename to src/util/win32/msvc-compat.h diff --git a/src/libgit2/win32/path_w32.c b/src/util/win32/path_w32.c similarity index 100% rename from src/libgit2/win32/path_w32.c rename to src/util/win32/path_w32.c diff --git a/src/libgit2/win32/path_w32.h b/src/util/win32/path_w32.h similarity index 99% rename from src/libgit2/win32/path_w32.h rename to src/util/win32/path_w32.h index 837b11ebd72..b241d5c8a6f 100644 --- a/src/libgit2/win32/path_w32.h +++ b/src/util/win32/path_w32.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_win32_path_w32_h__ #define INCLUDE_win32_path_w32_h__ -#include "common.h" +#include "git2_util.h" /** * Create a Win32 path (in UCS-2 format) from a UTF-8 string. If the given diff --git a/src/libgit2/win32/posix.h b/src/util/win32/posix.h similarity index 99% rename from src/libgit2/win32/posix.h rename to src/util/win32/posix.h index 578347f1527..03fa2ac52b6 100644 --- a/src/libgit2/win32/posix.h +++ b/src/util/win32/posix.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_win32_posix_h__ #define INCLUDE_win32_posix_h__ -#include "common.h" +#include "git2_util.h" #include "../posix.h" #include "win32-compat.h" #include "path_w32.h" diff --git a/src/libgit2/win32/posix_w32.c b/src/util/win32/posix_w32.c similarity index 99% rename from src/libgit2/win32/posix_w32.c rename to src/util/win32/posix_w32.c index 5f7cd0c2645..5862e5c9ad6 100644 --- a/src/libgit2/win32/posix_w32.c +++ b/src/util/win32/posix_w32.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "common.h" +#include "git2_util.h" #include "../posix.h" #include "../futils.h" diff --git a/src/libgit2/win32/precompiled.c b/src/util/win32/precompiled.c similarity index 100% rename from src/libgit2/win32/precompiled.c rename to src/util/win32/precompiled.c diff --git a/src/libgit2/win32/precompiled.h b/src/util/win32/precompiled.h similarity index 93% rename from src/libgit2/win32/precompiled.h rename to src/util/win32/precompiled.h index 806b1698a09..1163c3d63eb 100644 --- a/src/libgit2/win32/precompiled.h +++ b/src/util/win32/precompiled.h @@ -1,4 +1,4 @@ -#include "common.h" +#include "git2_util.h" #include #include diff --git a/src/libgit2/win32/reparse.h b/src/util/win32/reparse.h similarity index 100% rename from src/libgit2/win32/reparse.h rename to src/util/win32/reparse.h diff --git a/src/libgit2/win32/thread.c b/src/util/win32/thread.c similarity index 100% rename from src/libgit2/win32/thread.c rename to src/util/win32/thread.c diff --git a/src/libgit2/win32/thread.h b/src/util/win32/thread.h similarity index 98% rename from src/libgit2/win32/thread.h rename to src/util/win32/thread.h index 8305036b4d6..184762e2aa9 100644 --- a/src/libgit2/win32/thread.h +++ b/src/util/win32/thread.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_win32_thread_h__ #define INCLUDE_win32_thread_h__ -#include "common.h" +#include "git2_util.h" #if defined (_MSC_VER) # define GIT_RESTRICT __restrict diff --git a/src/libgit2/win32/utf-conv.c b/src/util/win32/utf-conv.c similarity index 100% rename from src/libgit2/win32/utf-conv.c rename to src/util/win32/utf-conv.c diff --git a/src/libgit2/win32/utf-conv.h b/src/util/win32/utf-conv.h similarity index 98% rename from src/libgit2/win32/utf-conv.h rename to src/util/win32/utf-conv.h index 6090a4b356a..120d647efdf 100644 --- a/src/libgit2/win32/utf-conv.h +++ b/src/util/win32/utf-conv.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_win32_utf_conv_h__ #define INCLUDE_win32_utf_conv_h__ -#include "common.h" +#include "git2_util.h" #include diff --git a/src/libgit2/win32/version.h b/src/util/win32/version.h similarity index 100% rename from src/libgit2/win32/version.h rename to src/util/win32/version.h diff --git a/src/libgit2/win32/w32_buffer.c b/src/util/win32/w32_buffer.c similarity index 100% rename from src/libgit2/win32/w32_buffer.c rename to src/util/win32/w32_buffer.c diff --git a/src/libgit2/win32/w32_buffer.h b/src/util/win32/w32_buffer.h similarity index 95% rename from src/libgit2/win32/w32_buffer.h rename to src/util/win32/w32_buffer.h index 4227296d8f5..68ea9603567 100644 --- a/src/libgit2/win32/w32_buffer.h +++ b/src/util/win32/w32_buffer.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_win32_w32_buffer_h__ #define INCLUDE_win32_w32_buffer_h__ -#include "common.h" +#include "git2_util.h" #include "str.h" /** diff --git a/src/libgit2/win32/w32_common.h b/src/util/win32/w32_common.h similarity index 100% rename from src/libgit2/win32/w32_common.h rename to src/util/win32/w32_common.h diff --git a/src/libgit2/win32/w32_leakcheck.c b/src/util/win32/w32_leakcheck.c similarity index 100% rename from src/libgit2/win32/w32_leakcheck.c rename to src/util/win32/w32_leakcheck.c diff --git a/src/libgit2/win32/w32_leakcheck.h b/src/util/win32/w32_leakcheck.h similarity index 99% rename from src/libgit2/win32/w32_leakcheck.h rename to src/util/win32/w32_leakcheck.h index cb45e3675be..82d863851ee 100644 --- a/src/libgit2/win32/w32_leakcheck.h +++ b/src/util/win32/w32_leakcheck.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_win32_leakcheck_h__ #define INCLUDE_win32_leakcheck_h__ -#include "common.h" +#include "git2_util.h" /* Initialize the win32 leak checking system. */ int git_win32_leakcheck_global_init(void); diff --git a/src/libgit2/win32/w32_util.c b/src/util/win32/w32_util.c similarity index 100% rename from src/libgit2/win32/w32_util.c rename to src/util/win32/w32_util.c diff --git a/src/libgit2/win32/w32_util.h b/src/util/win32/w32_util.h similarity index 99% rename from src/libgit2/win32/w32_util.h rename to src/util/win32/w32_util.h index 1321d30e66b..519663720d5 100644 --- a/src/libgit2/win32/w32_util.h +++ b/src/util/win32/w32_util.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_win32_w32_util_h__ #define INCLUDE_win32_w32_util_h__ -#include "common.h" +#include "git2_util.h" #include "utf-conv.h" #include "posix.h" diff --git a/src/libgit2/win32/win32-compat.h b/src/util/win32/win32-compat.h similarity index 100% rename from src/libgit2/win32/win32-compat.h rename to src/util/win32/win32-compat.h diff --git a/src/libgit2/zstream.c b/src/util/zstream.c similarity index 100% rename from src/libgit2/zstream.c rename to src/util/zstream.c diff --git a/src/libgit2/zstream.h b/src/util/zstream.h similarity index 98% rename from src/libgit2/zstream.h rename to src/util/zstream.h index 3f8b1c72ff4..d78b1129145 100644 --- a/src/libgit2/zstream.h +++ b/src/util/zstream.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_zstream_h__ #define INCLUDE_zstream_h__ -#include "common.h" +#include "git2_util.h" #include From 5fcfada500073ddd4acbfa0b0906e37025b45556 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 15 Nov 2021 07:45:16 -0500 Subject: [PATCH 0815/1616] cmake: document CMakeLists.txt hierarchy --- CMakeLists.txt | 5 ++++- examples/CMakeLists.txt | 2 ++ fuzzers/CMakeLists.txt | 2 ++ src/libgit2/CMakeLists.txt | 3 +++ src/util/CMakeLists.txt | 1 + tests/CMakeLists.txt | 2 ++ 6 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb137ecdd62..90ecc92fee2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,8 @@ -# CMake build script for the libgit2 project +# libgit2: the cross-platform, linkable library implementation of git. # See `README.md` for build instructions. +# +# This top-level CMakeLists.txt sets up configuration options and +# determines which subprojects to build. cmake_minimum_required(VERSION 3.5.1) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 235e72adaed..956b0382781 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,3 +1,5 @@ +# examples: code usage examples of libgit2 + file(GLOB SRC_EXAMPLES *.c *.h) add_executable(lg2 ${SRC_EXAMPLES}) diff --git a/fuzzers/CMakeLists.txt b/fuzzers/CMakeLists.txt index eaa490fd9b4..a2c19ed408a 100644 --- a/fuzzers/CMakeLists.txt +++ b/fuzzers/CMakeLists.txt @@ -1,3 +1,5 @@ +# fuzzers: libFuzzer and standalone fuzzing utilities + if(BUILD_FUZZERS AND NOT USE_STANDALONE_FUZZERS) set(CMAKE_REQUIRED_FLAGS "-fsanitize=fuzzer-no-link") add_c_flag(-fsanitize=fuzzer) diff --git a/src/libgit2/CMakeLists.txt b/src/libgit2/CMakeLists.txt index 3dac83d7a42..52fdf0d88ed 100644 --- a/src/libgit2/CMakeLists.txt +++ b/src/libgit2/CMakeLists.txt @@ -1,3 +1,6 @@ +# libgit2: the shared library: this CMakeLists.txt compiles the core +# git library functionality. + add_library(git2internal OBJECT) set_target_properties(git2internal PROPERTIES C_STANDARD 90) set_target_properties(git2internal PROPERTIES C_EXTENSIONS OFF) diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index ea2df0a560b..b725d54269d 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -54,6 +54,7 @@ list(SORT UTIL_SRC_HASH) # target_sources(util PRIVATE ${UTIL_SRC} ${UTIL_SRC_OS} ${UTIL_SRC_HASH}) +ide_split_sources(util) target_include_directories(util PRIVATE ${UTIL_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${libgit2_SOURCE_DIR}/include) target_include_directories(util SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f293c158da1..33dfd0ae822 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,3 +1,5 @@ +# tests: the unit and integration tests for libgit2 + set(Python_ADDITIONAL_VERSIONS 3 2.7) find_package(PythonInterp) From d7b49ed4427bf4823ac5a18a176f317c6d2717ac Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 15 Nov 2021 14:54:17 -0500 Subject: [PATCH 0816/1616] cmake: remove unnecessary xcode hack --- src/libgit2/CMakeLists.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/libgit2/CMakeLists.txt b/src/libgit2/CMakeLists.txt index 52fdf0d88ed..7d8b9aef627 100644 --- a/src/libgit2/CMakeLists.txt +++ b/src/libgit2/CMakeLists.txt @@ -228,13 +228,6 @@ set(LIBGIT2_DEPENDENCY_OBJECTS ${LIBGIT2_DEPENDENCY_OBJECTS} PARENT_SCOPE) set(LIBGIT2_SYSTEM_INCLUDES ${LIBGIT2_SYSTEM_INCLUDES} PARENT_SCOPE) set(LIBGIT2_SYSTEM_LIBS ${LIBGIT2_SYSTEM_LIBS} PARENT_SCOPE) -if(XCODE_VERSION) - # This is required for Xcode to actually link the libgit2 library - # when using only object libraries. - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.c "") - list(APPEND LIBGIT2_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/dummy.c) -endif() - # Compile and link libgit2 add_library(git2 ${SRC_RC} ${LIBGIT2_OBJECTS}) target_link_libraries(git2 ${LIBGIT2_SYSTEM_LIBS}) From 91ba089663f5efc3bd4ba14a5099372cf5ce57a6 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 15 Nov 2021 09:54:00 -0500 Subject: [PATCH 0817/1616] cmake: rename git2internal target to libgit2 The `git2internal` target is actually the git library; call it such so that IDE users have visibility into it. --- examples/CMakeLists.txt | 4 +- src/libgit2/CMakeLists.txt | 217 ++++++------------------------------- 2 files changed, 36 insertions(+), 185 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 956b0382781..8e38c7d4e66 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -12,7 +12,7 @@ target_include_directories(lg2 PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_ target_include_directories(lg2 SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) if(WIN32 OR ANDROID) - target_link_libraries(lg2 git2) + target_link_libraries(lg2 libgit2package) else() - target_link_libraries(lg2 git2 pthread) + target_link_libraries(lg2 libgit2package pthread) endif() diff --git a/src/libgit2/CMakeLists.txt b/src/libgit2/CMakeLists.txt index 7d8b9aef627..0c7ddddbad7 100644 --- a/src/libgit2/CMakeLists.txt +++ b/src/libgit2/CMakeLists.txt @@ -1,9 +1,9 @@ # libgit2: the shared library: this CMakeLists.txt compiles the core # git library functionality. -add_library(git2internal OBJECT) -set_target_properties(git2internal PROPERTIES C_STANDARD 90) -set_target_properties(git2internal PROPERTIES C_EXTENSIONS OFF) +add_library(libgit2 OBJECT) +set_target_properties(libgit2 PROPERTIES C_STANDARD 90) +set_target_properties(libgit2 PROPERTIES C_EXTENSIONS OFF) include(PkgBuildConfig) @@ -16,177 +16,27 @@ set(LIBGIT2_INCLUDES if(WIN32 AND EMBED_SSH_PATH) file(GLOB SRC_SSH "${EMBED_SSH_PATH}/src/*.c") list(SORT SRC_SSH) - target_sources(git2internal PRIVATE ${SRC_SSH}) + target_sources(libgit2 PRIVATE ${SRC_SSH}) list(APPEND LIBGIT2_SYSTEM_INCLUDES "${EMBED_SSH_PATH}/include") file(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"") set(GIT_SSH 1) endif() -<<<<<<< HEAD -include(SelectHTTPSBackend) -include(SelectHashes) -include(SelectHTTPParser) -include(SelectRegex) -include(SelectSSH) -include(SelectWinHTTP) -include(SelectZlib) - - -if(USE_SHA1 STREQUAL "CollisionDetection") - file(GLOB SRC_SHA1 hash/sha1/collisiondetect.* hash/sha1/sha1dc/*) -elseif(USE_SHA1 STREQUAL "OpenSSL") - file(GLOB SRC_SHA1 hash/sha1/openssl.*) -elseif(USE_SHA1 STREQUAL "CommonCrypto") - file(GLOB SRC_SHA1 hash/sha1/common_crypto.*) -elseif(USE_SHA1 STREQUAL "mbedTLS") - file(GLOB SRC_SHA1 hash/sha1/mbedtls.*) -elseif(USE_SHA1 STREQUAL "Win32") - file(GLOB SRC_SHA1 hash/sha1/win32.*) -elseif(USE_SHA1 STREQUAL "Generic") - file(GLOB SRC_SHA1 hash/sha1/generic.*) -endif() -list(APPEND SRC_SHA1 "hash/sha1.h") -target_sources(git2internal PRIVATE ${SRC_SHA1}) - -# Optional external dependency: ntlmclient -if(USE_NTLMCLIENT) - set(GIT_NTLM 1) - add_subdirectory("${PROJECT_SOURCE_DIR}/deps/ntlmclient" "${PROJECT_BINARY_DIR}/deps/ntlmclient") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/ntlmclient") - list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") -endif() -add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix") - -# Optional external dependency: GSSAPI - -include(SelectGSSAPI) - -# Optional external dependency: iconv -if(USE_ICONV) - find_package(Iconv) -endif() -if(ICONV_FOUND) - set(GIT_USE_ICONV 1) - list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ICONV_INCLUDE_DIR}) - list(APPEND LIBGIT2_SYSTEM_LIBS ${ICONV_LIBRARIES}) - list(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES}) -endif() -add_feature_info(iconv GIT_USE_ICONV "iconv encoding conversion support") - - -if(USE_THREADS) - if(NOT WIN32) - find_package(Threads REQUIRED) - endif() - - set(GIT_THREADS 1) -endif() - -if(USE_NSEC) - set(GIT_USE_NSEC 1) -endif() - -if(HAVE_STRUCT_STAT_ST_MTIM) - set(GIT_USE_STAT_MTIM 1) -elseif(HAVE_STRUCT_STAT_ST_MTIMESPEC) - set(GIT_USE_STAT_MTIMESPEC 1) -elseif(HAVE_STRUCT_STAT_ST_MTIME_NSEC) - set(GIT_USE_STAT_MTIME_NSEC 1) -endif() - -target_compile_definitions(git2internal PRIVATE _FILE_OFFSET_BITS=64) - -||||||| parent of a930dafb4 (refactor: make util an object library) -include(SelectHTTPSBackend) -include(SelectHashes) -include(SelectHTTPParser) -include(SelectRegex) -include(SelectSSH) -include(SelectWinHTTP) -include(SelectZlib) - - -if(USE_SHA1 STREQUAL "CollisionDetection") - file(GLOB SRC_SHA1 hash/sha1/collisiondetect.* hash/sha1/sha1dc/*) -elseif(USE_SHA1 STREQUAL "OpenSSL") - file(GLOB SRC_SHA1 hash/sha1/openssl.*) -elseif(USE_SHA1 STREQUAL "CommonCrypto") - file(GLOB SRC_SHA1 hash/sha1/common_crypto.*) -elseif(USE_SHA1 STREQUAL "mbedTLS") - file(GLOB SRC_SHA1 hash/sha1/mbedtls.*) -elseif(USE_SHA1 STREQUAL "Win32") - file(GLOB SRC_SHA1 hash/sha1/win32.*) -elseif(USE_SHA1 STREQUAL "Generic") - file(GLOB SRC_SHA1 hash/sha1/generic.*) -endif() -list(APPEND SRC_SHA1 "hash/sha1.h") -target_sources(git2internal PRIVATE ${SRC_SHA1}) - -# Optional external dependency: ntlmclient -if(USE_NTLMCLIENT) - set(GIT_NTLM 1) - add_subdirectory("${PROJECT_SOURCE_DIR}/deps/ntlmclient" "${PROJECT_BINARY_DIR}/deps/ntlmclient") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/ntlmclient") - list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") -endif() -add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix") - -# Optional external dependency: GSSAPI - -include(SelectGSSAPI) - -# Optional external dependency: iconv -if(USE_ICONV) - find_package(Iconv) -endif() -if(ICONV_FOUND) - set(GIT_USE_ICONV 1) - list(APPEND LIBGIT2_SYSTEM_INCLUDES ${ICONV_INCLUDE_DIR}) - list(APPEND LIBGIT2_SYSTEM_LIBS ${ICONV_LIBRARIES}) - list(APPEND LIBGIT2_PC_LIBS ${ICONV_LIBRARIES}) -endif() -add_feature_info(iconv GIT_USE_ICONV "iconv encoding conversion support") - - -if(USE_THREADS) - if(NOT WIN32) - find_package(Threads REQUIRED) - endif() - - set(GIT_THREADS 1) -endif() - -if(USE_NSEC) - set(GIT_USE_NSEC 1) -endif() - -if(HAVE_STRUCT_STAT_ST_MTIM) - set(GIT_USE_STAT_MTIM 1) -elseif(HAVE_STRUCT_STAT_ST_MTIMESPEC) - set(GIT_USE_STAT_MTIMESPEC 1) -elseif(HAVE_STRUCT_STAT_ST_MTIME_NSEC) - set(GIT_USE_STAT_MTIME_NSEC 1) -endif() - -target_compile_definitions(git2internal PRIVATE _FILE_OFFSET_BITS=64) - -======= ->>>>>>> a930dafb4 (refactor: make util an object library) # Collect sourcefiles file(GLOB SRC_H "${PROJECT_SOURCE_DIR}/include/git2.h" "${PROJECT_SOURCE_DIR}/include/git2/*.h" "${PROJECT_SOURCE_DIR}/include/git2/sys/*.h") list(SORT SRC_H) -target_sources(git2internal PRIVATE ${SRC_H}) +target_sources(libgit2 PRIVATE ${SRC_H}) file(GLOB SRC_GIT2 *.c *.h streams/*.c streams/*.h transports/*.c transports/*.h xdiff/*.c xdiff/*.h) list(SORT SRC_GIT2) -target_sources(git2internal PRIVATE ${SRC_GIT2}) +target_sources(libgit2 PRIVATE ${SRC_GIT2}) if(WIN32 AND NOT CYGWIN) # Add resource information on Windows @@ -198,9 +48,9 @@ if(APPLE) set_source_files_properties(streams/stransport.c PROPERTIES COMPILE_FLAGS -Wno-deprecated) endif() -# the xdiff dependency is not (yet) warning-free, disable warnings as -# errors for the xdiff sources until we've sorted them out - if(MSVC) +# the xdiff dependency is not (yet) warning-free, disable warnings +# as errors for the xdiff sources until we've sorted them out +if(MSVC) set_source_files_properties(xdiff/xdiffi.c PROPERTIES COMPILE_FLAGS -WX-) set_source_files_properties(xdiff/xemit.c PROPERTIES COMPILE_FLAGS -WX-) set_source_files_properties(xdiff/xhistogram.c PROPERTIES COMPILE_FLAGS -WX-) @@ -213,13 +63,13 @@ else() set_source_files_properties(xdiff/xhistogram.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") set_source_files_properties(xdiff/xutils.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") set_source_files_properties(xdiff/xpatience.c PROPERTIES COMPILE_FLAGS "-Wno-sign-compare") - endif() +endif() -ide_split_sources(git2internal) -list(APPEND LIBGIT2_OBJECTS $ $ ${LIBGIT2_DEPENDENCY_OBJECTS}) +ide_split_sources(libgit2) +list(APPEND LIBGIT2_OBJECTS $ $ ${LIBGIT2_DEPENDENCY_OBJECTS}) -target_include_directories(git2internal PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${PROJECT_SOURCE_DIR}/include) -target_include_directories(git2internal SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) +target_include_directories(libgit2 PRIVATE ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES} PUBLIC ${PROJECT_SOURCE_DIR}/include) +target_include_directories(libgit2 SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) set(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE) set(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE) @@ -228,31 +78,34 @@ set(LIBGIT2_DEPENDENCY_OBJECTS ${LIBGIT2_DEPENDENCY_OBJECTS} PARENT_SCOPE) set(LIBGIT2_SYSTEM_INCLUDES ${LIBGIT2_SYSTEM_INCLUDES} PARENT_SCOPE) set(LIBGIT2_SYSTEM_LIBS ${LIBGIT2_SYSTEM_LIBS} PARENT_SCOPE) +# # Compile and link libgit2 -add_library(git2 ${SRC_RC} ${LIBGIT2_OBJECTS}) -target_link_libraries(git2 ${LIBGIT2_SYSTEM_LIBS}) +# + +add_library(libgit2package ${SRC_RC} ${LIBGIT2_OBJECTS}) +target_link_libraries(libgit2package ${LIBGIT2_SYSTEM_LIBS}) -set_target_properties(git2 PROPERTIES C_STANDARD 90) -set_target_properties(git2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) -set_target_properties(git2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) -set_target_properties(git2 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) +set_target_properties(libgit2package PROPERTIES C_STANDARD 90) +set_target_properties(libgit2package PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) +set_target_properties(libgit2package PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) +set_target_properties(libgit2package PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) # Workaround for Cmake bug #0011240 (see http://public.kitware.com/Bug/view.php?id=11240) # Win64+MSVC+static libs = linker error if(MSVC AND GIT_ARCH_64 AND NOT BUILD_SHARED_LIBS) - set_target_properties(git2 PROPERTIES STATIC_LIBRARY_FLAGS "/MACHINE:x64") + set_target_properties(libgit2package PROPERTIES STATIC_LIBRARY_FLAGS "/MACHINE:x64") endif() -ide_split_sources(git2) +ide_split_sources(libgit2package) if(SONAME) - set_target_properties(git2 PROPERTIES VERSION ${libgit2_VERSION}) - set_target_properties(git2 PROPERTIES SOVERSION "${libgit2_VERSION_MAJOR}.${libgit2_VERSION_MINOR}") + set_target_properties(libgit2package PROPERTIES VERSION ${libgit2_VERSION}) + set_target_properties(libgit2package PROPERTIES SOVERSION "${libgit2_VERSION_MAJOR}.${libgit2_VERSION_MINOR}") if(LIBGIT2_FILENAME) - target_compile_definitions(git2 PRIVATE LIBGIT2_FILENAME=\"${LIBGIT2_FILENAME}\") - set_target_properties(git2 PROPERTIES OUTPUT_NAME ${LIBGIT2_FILENAME}) + target_compile_definitions(libgit2package PRIVATE LIBGIT2_FILENAME=\"${LIBGIT2_FILENAME}\") + set_target_properties(libgit2package PROPERTIES OUTPUT_NAME ${LIBGIT2_FILENAME}) elseif(DEFINED LIBGIT2_PREFIX) - set_target_properties(git2 PROPERTIES PREFIX "${LIBGIT2_PREFIX}") + set_target_properties(libgit2package PROPERTIES PREFIX "${LIBGIT2_PREFIX}") endif() endif() @@ -261,20 +114,18 @@ pkg_build_config(NAME libgit2 DESCRIPTION "The git library, take 2" LIBS_SELF git2 PRIVATE_LIBS ${LIBGIT2_PC_LIBS} - REQUIRES ${LIBGIT2_PC_REQUIRES} -) + REQUIRES ${LIBGIT2_PC_REQUIRES}) if(MSVC_IDE) # Precompiled headers - set_target_properties(git2 PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") + set_target_properties(libgit2package PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") set_source_files_properties(win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h") endif() # Install -install(TARGETS git2 +install(TARGETS libgit2package RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} -) + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/git2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(FILES ${PROJECT_SOURCE_DIR}/include/git2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) From 3344fddc97bbdea9c1b6ebb6f7fb6dbd70b41dfb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 16 Nov 2021 23:29:22 -0500 Subject: [PATCH 0818/1616] refactor: `tests` is now `tests/libgit2` Like we want to separate libgit2 and utility source code, we want to separate libgit2 and utility tests. Start by moving all the tests into libgit2. --- src/CMakeLists.txt | 4 +- tests/CMakeLists.txt | 100 +----------------- tests/README.md | 62 +++++++---- tests/libgit2/CMakeLists.txt | 98 +++++++++++++++++ tests/{ => libgit2}/apply/apply_helpers.c | 0 tests/{ => libgit2}/apply/apply_helpers.h | 0 tests/{ => libgit2}/apply/both.c | 0 tests/{ => libgit2}/apply/callbacks.c | 0 tests/{ => libgit2}/apply/check.c | 0 tests/{ => libgit2}/apply/fromdiff.c | 0 tests/{ => libgit2}/apply/fromfile.c | 0 tests/{ => libgit2}/apply/index.c | 0 tests/{ => libgit2}/apply/partial.c | 0 tests/{ => libgit2}/apply/tree.c | 0 tests/{ => libgit2}/apply/workdir.c | 0 tests/{ => libgit2}/attr/attr_expect.h | 0 tests/{ => libgit2}/attr/file.c | 0 tests/{ => libgit2}/attr/flags.c | 0 tests/{ => libgit2}/attr/lookup.c | 0 tests/{ => libgit2}/attr/macro.c | 0 tests/{ => libgit2}/attr/repo.c | 0 tests/{ => libgit2}/blame/blame_helpers.c | 0 tests/{ => libgit2}/blame/blame_helpers.h | 0 tests/{ => libgit2}/blame/buffer.c | 0 tests/{ => libgit2}/blame/getters.c | 0 tests/{ => libgit2}/blame/harder.c | 0 tests/{ => libgit2}/blame/simple.c | 0 tests/{ => libgit2}/checkout/binaryunicode.c | 0 .../{ => libgit2}/checkout/checkout_helpers.c | 0 .../{ => libgit2}/checkout/checkout_helpers.h | 0 tests/{ => libgit2}/checkout/conflict.c | 0 tests/{ => libgit2}/checkout/crlf.c | 0 tests/{ => libgit2}/checkout/head.c | 0 tests/{ => libgit2}/checkout/icase.c | 0 tests/{ => libgit2}/checkout/index.c | 0 tests/{ => libgit2}/checkout/nasty.c | 0 tests/{ => libgit2}/checkout/tree.c | 0 tests/{ => libgit2}/checkout/typechange.c | 0 tests/{ => libgit2}/cherrypick/bare.c | 0 tests/{ => libgit2}/cherrypick/workdir.c | 0 tests/{ => libgit2}/clar.c | 0 tests/{ => libgit2}/clar.h | 0 tests/{ => libgit2}/clar/fixtures.h | 0 tests/{ => libgit2}/clar/fs.h | 0 tests/{ => libgit2}/clar/print.h | 0 tests/{ => libgit2}/clar/sandbox.h | 0 tests/{ => libgit2}/clar/summary.h | 0 tests/{ => libgit2}/clar_libgit2.c | 0 tests/{ => libgit2}/clar_libgit2.h | 0 tests/{ => libgit2}/clar_libgit2_timer.c | 0 tests/{ => libgit2}/clar_libgit2_timer.h | 0 tests/{ => libgit2}/clar_libgit2_trace.c | 0 tests/{ => libgit2}/clar_libgit2_trace.h | 0 tests/{ => libgit2}/clone/empty.c | 0 tests/{ => libgit2}/clone/local.c | 0 tests/{ => libgit2}/clone/nonetwork.c | 0 tests/{ => libgit2}/clone/transport.c | 0 tests/{ => libgit2}/commit/commit.c | 0 tests/{ => libgit2}/commit/parent.c | 0 tests/{ => libgit2}/commit/parse.c | 0 tests/{ => libgit2}/commit/signature.c | 0 tests/{ => libgit2}/commit/write.c | 0 tests/{ => libgit2}/config/add.c | 0 tests/{ => libgit2}/config/backend.c | 0 tests/{ => libgit2}/config/conditionals.c | 0 tests/{ => libgit2}/config/config_helpers.c | 0 tests/{ => libgit2}/config/config_helpers.h | 0 tests/{ => libgit2}/config/configlevel.c | 0 tests/{ => libgit2}/config/global.c | 0 tests/{ => libgit2}/config/include.c | 0 tests/{ => libgit2}/config/memory.c | 0 tests/{ => libgit2}/config/multivar.c | 0 tests/{ => libgit2}/config/new.c | 0 tests/{ => libgit2}/config/read.c | 0 tests/{ => libgit2}/config/readonly.c | 0 tests/{ => libgit2}/config/rename.c | 0 tests/{ => libgit2}/config/snapshot.c | 0 tests/{ => libgit2}/config/stress.c | 0 tests/{ => libgit2}/config/validkeyname.c | 0 tests/{ => libgit2}/config/write.c | 0 tests/{ => libgit2}/core/array.c | 0 tests/{ => libgit2}/core/assert.c | 0 tests/{ => libgit2}/core/bitvec.c | 0 tests/{ => libgit2}/core/buf.c | 0 tests/{ => libgit2}/core/copy.c | 0 tests/{ => libgit2}/core/dirent.c | 0 tests/{ => libgit2}/core/encoding.c | 0 tests/{ => libgit2}/core/env.c | 0 tests/{ => libgit2}/core/errors.c | 0 tests/{ => libgit2}/core/features.c | 0 tests/{ => libgit2}/core/filebuf.c | 0 tests/{ => libgit2}/core/ftruncate.c | 0 tests/{ => libgit2}/core/futils.c | 0 tests/{ => libgit2}/core/gitstr.c | 0 tests/{ => libgit2}/core/hex.c | 0 tests/{ => libgit2}/core/iconv.c | 0 tests/{ => libgit2}/core/init.c | 0 tests/{ => libgit2}/core/integer.c | 0 tests/{ => libgit2}/core/link.c | 0 tests/{ => libgit2}/core/memmem.c | 0 tests/{ => libgit2}/core/mkdir.c | 0 tests/{ => libgit2}/core/oid.c | 0 tests/{ => libgit2}/core/oidmap.c | 0 tests/{ => libgit2}/core/opts.c | 0 tests/{ => libgit2}/core/path.c | 0 tests/{ => libgit2}/core/pool.c | 0 tests/{ => libgit2}/core/posix.c | 0 tests/{ => libgit2}/core/pqueue.c | 0 tests/{ => libgit2}/core/qsort.c | 0 tests/{ => libgit2}/core/regexp.c | 0 tests/{ => libgit2}/core/rmdir.c | 0 tests/{ => libgit2}/core/sha1.c | 0 tests/{ => libgit2}/core/sortedcache.c | 0 tests/{ => libgit2}/core/stat.c | 0 tests/{ => libgit2}/core/string.c | 0 tests/{ => libgit2}/core/strmap.c | 0 tests/{ => libgit2}/core/strtol.c | 0 tests/{ => libgit2}/core/structinit.c | 0 tests/{ => libgit2}/core/useragent.c | 0 tests/{ => libgit2}/core/utf8.c | 0 tests/{ => libgit2}/core/vector.c | 0 tests/{ => libgit2}/core/wildmatch.c | 0 tests/{ => libgit2}/core/zstream.c | 0 tests/{ => libgit2}/date/date.c | 0 tests/{ => libgit2}/date/rfc2822.c | 0 tests/{ => libgit2}/delta/apply.c | 0 tests/{ => libgit2}/describe/describe.c | 0 .../{ => libgit2}/describe/describe_helpers.c | 0 .../{ => libgit2}/describe/describe_helpers.h | 0 tests/{ => libgit2}/describe/t6120.c | 0 tests/{ => libgit2}/diff/binary.c | 0 tests/{ => libgit2}/diff/blob.c | 0 tests/{ => libgit2}/diff/diff_helpers.c | 0 tests/{ => libgit2}/diff/diff_helpers.h | 0 tests/{ => libgit2}/diff/diffiter.c | 0 tests/{ => libgit2}/diff/drivers.c | 0 .../diff/externalmodifications.c | 0 tests/{ => libgit2}/diff/format_email.c | 0 tests/{ => libgit2}/diff/index.c | 0 tests/{ => libgit2}/diff/notify.c | 0 tests/{ => libgit2}/diff/parse.c | 0 tests/{ => libgit2}/diff/patch.c | 0 tests/{ => libgit2}/diff/patchid.c | 0 tests/{ => libgit2}/diff/pathspec.c | 0 tests/{ => libgit2}/diff/racediffiter.c | 0 tests/{ => libgit2}/diff/rename.c | 0 tests/{ => libgit2}/diff/stats.c | 0 tests/{ => libgit2}/diff/submodules.c | 0 tests/{ => libgit2}/diff/tree.c | 0 tests/{ => libgit2}/diff/workdir.c | 0 tests/{ => libgit2}/email/create.c | 0 tests/{ => libgit2}/email/create.c.bak | 0 tests/{ => libgit2}/fetch/local.c | 0 .../{ => libgit2}/fetchhead/fetchhead_data.h | 0 tests/{ => libgit2}/fetchhead/nonetwork.c | 0 tests/{ => libgit2}/filter/bare.c | 0 tests/{ => libgit2}/filter/blob.c | 0 tests/{ => libgit2}/filter/crlf.c | 0 tests/{ => libgit2}/filter/crlf.h | 0 tests/{ => libgit2}/filter/custom.c | 0 tests/{ => libgit2}/filter/custom_helpers.c | 0 tests/{ => libgit2}/filter/custom_helpers.h | 0 tests/{ => libgit2}/filter/file.c | 0 tests/{ => libgit2}/filter/ident.c | 0 tests/{ => libgit2}/filter/query.c | 0 tests/{ => libgit2}/filter/stream.c | 0 tests/{ => libgit2}/filter/systemattrs.c | 0 tests/{ => libgit2}/filter/wildcard.c | 0 tests/{ => libgit2}/generate.py | 0 tests/{ => libgit2}/graph/ahead_behind.c | 0 tests/{ => libgit2}/graph/commitgraph.c | 0 tests/{ => libgit2}/graph/descendant_of.c | 0 .../{ => libgit2}/graph/reachable_from_any.c | 0 tests/{ => libgit2}/headertest.c | 0 tests/{ => libgit2}/ignore/path.c | 0 tests/{ => libgit2}/ignore/status.c | 0 tests/{ => libgit2}/index/add.c | 0 tests/{ => libgit2}/index/addall.c | 0 tests/{ => libgit2}/index/bypath.c | 0 tests/{ => libgit2}/index/cache.c | 0 tests/{ => libgit2}/index/collision.c | 0 tests/{ => libgit2}/index/conflicts.c | 0 tests/{ => libgit2}/index/conflicts.h | 0 tests/{ => libgit2}/index/crlf.c | 0 tests/{ => libgit2}/index/filemodes.c | 0 tests/{ => libgit2}/index/inmemory.c | 0 tests/{ => libgit2}/index/names.c | 0 tests/{ => libgit2}/index/nsec.c | 0 tests/{ => libgit2}/index/racy.c | 0 tests/{ => libgit2}/index/read_index.c | 0 tests/{ => libgit2}/index/read_tree.c | 0 tests/{ => libgit2}/index/rename.c | 0 tests/{ => libgit2}/index/reuc.c | 0 tests/{ => libgit2}/index/splitindex.c | 0 tests/{ => libgit2}/index/stage.c | 0 tests/{ => libgit2}/index/tests.c | 0 tests/{ => libgit2}/index/version.c | 0 tests/{ => libgit2}/iterator/index.c | 0 .../{ => libgit2}/iterator/iterator_helpers.c | 0 .../{ => libgit2}/iterator/iterator_helpers.h | 0 tests/{ => libgit2}/iterator/tree.c | 0 tests/{ => libgit2}/iterator/workdir.c | 0 tests/{ => libgit2}/mailmap/basic.c | 0 tests/{ => libgit2}/mailmap/blame.c | 0 .../{ => libgit2}/mailmap/mailmap_testdata.h | 0 tests/{ => libgit2}/mailmap/parsing.c | 0 tests/{ => libgit2}/main.c | 0 tests/{ => libgit2}/merge/analysis.c | 0 tests/{ => libgit2}/merge/annotated_commit.c | 0 tests/{ => libgit2}/merge/conflict_data.h | 0 tests/{ => libgit2}/merge/driver.c | 0 tests/{ => libgit2}/merge/files.c | 0 tests/{ => libgit2}/merge/merge_helpers.c | 0 tests/{ => libgit2}/merge/merge_helpers.h | 0 tests/{ => libgit2}/merge/trees/automerge.c | 0 tests/{ => libgit2}/merge/trees/commits.c | 0 .../{ => libgit2}/merge/trees/modeconflict.c | 0 tests/{ => libgit2}/merge/trees/recursive.c | 0 tests/{ => libgit2}/merge/trees/renames.c | 0 tests/{ => libgit2}/merge/trees/treediff.c | 0 tests/{ => libgit2}/merge/trees/trivial.c | 0 tests/{ => libgit2}/merge/trees/whitespace.c | 0 tests/{ => libgit2}/merge/workdir/dirty.c | 0 tests/{ => libgit2}/merge/workdir/recursive.c | 0 tests/{ => libgit2}/merge/workdir/renames.c | 0 tests/{ => libgit2}/merge/workdir/setup.c | 0 tests/{ => libgit2}/merge/workdir/simple.c | 0 .../{ => libgit2}/merge/workdir/submodules.c | 0 tests/{ => libgit2}/merge/workdir/trivial.c | 0 tests/{ => libgit2}/message/trailer.c | 0 tests/{ => libgit2}/network/cred.c | 0 tests/{ => libgit2}/network/fetchlocal.c | 0 tests/{ => libgit2}/network/matchhost.c | 0 tests/{ => libgit2}/network/refspecs.c | 0 .../network/remote/defaultbranch.c | 0 tests/{ => libgit2}/network/remote/delete.c | 0 .../network/remote/isvalidname.c | 0 tests/{ => libgit2}/network/remote/local.c | 0 tests/{ => libgit2}/network/remote/push.c | 0 tests/{ => libgit2}/network/remote/remotes.c | 0 tests/{ => libgit2}/network/remote/rename.c | 0 tests/{ => libgit2}/network/url/joinpath.c | 0 tests/{ => libgit2}/network/url/parse.c | 0 tests/{ => libgit2}/network/url/pattern.c | 0 tests/{ => libgit2}/network/url/redirect.c | 0 tests/{ => libgit2}/network/url/scp.c | 0 tests/{ => libgit2}/network/url/valid.c | 0 tests/{ => libgit2}/notes/notes.c | 0 tests/{ => libgit2}/notes/notesref.c | 0 tests/{ => libgit2}/object/blob/filter.c | 0 tests/{ => libgit2}/object/blob/fromstream.c | 0 tests/{ => libgit2}/object/blob/write.c | 0 tests/{ => libgit2}/object/cache.c | 0 .../object/commit/commitstagedfile.c | 0 tests/{ => libgit2}/object/commit/parse.c | 0 tests/{ => libgit2}/object/lookup.c | 0 tests/{ => libgit2}/object/lookupbypath.c | 0 tests/{ => libgit2}/object/message.c | 0 tests/{ => libgit2}/object/peel.c | 0 tests/{ => libgit2}/object/raw/chars.c | 0 tests/{ => libgit2}/object/raw/compare.c | 0 tests/{ => libgit2}/object/raw/convert.c | 0 tests/{ => libgit2}/object/raw/data.h | 0 tests/{ => libgit2}/object/raw/fromstr.c | 0 tests/{ => libgit2}/object/raw/hash.c | 0 tests/{ => libgit2}/object/raw/short.c | 0 tests/{ => libgit2}/object/raw/size.c | 0 tests/{ => libgit2}/object/raw/type2string.c | 0 tests/{ => libgit2}/object/raw/write.c | 0 tests/{ => libgit2}/object/shortid.c | 0 tests/{ => libgit2}/object/tag/list.c | 0 tests/{ => libgit2}/object/tag/parse.c | 0 tests/{ => libgit2}/object/tag/peel.c | 0 tests/{ => libgit2}/object/tag/read.c | 0 tests/{ => libgit2}/object/tag/write.c | 0 tests/{ => libgit2}/object/tree/attributes.c | 0 .../object/tree/duplicateentries.c | 0 tests/{ => libgit2}/object/tree/frompath.c | 0 tests/{ => libgit2}/object/tree/parse.c | 0 tests/{ => libgit2}/object/tree/read.c | 0 tests/{ => libgit2}/object/tree/update.c | 0 tests/{ => libgit2}/object/tree/walk.c | 0 tests/{ => libgit2}/object/tree/write.c | 0 tests/{ => libgit2}/object/validate.c | 0 tests/{ => libgit2}/odb/alternates.c | 0 .../odb/backend/backend_helpers.c | 0 .../odb/backend/backend_helpers.h | 0 tests/{ => libgit2}/odb/backend/mempack.c | 0 tests/{ => libgit2}/odb/backend/multiple.c | 0 tests/{ => libgit2}/odb/backend/nobackend.c | 0 .../{ => libgit2}/odb/backend/nonrefreshing.c | 0 tests/{ => libgit2}/odb/backend/refreshing.c | 0 tests/{ => libgit2}/odb/backend/simple.c | 0 tests/{ => libgit2}/odb/emptyobjects.c | 0 tests/{ => libgit2}/odb/foreach.c | 0 tests/{ => libgit2}/odb/freshen.c | 0 tests/{ => libgit2}/odb/largefiles.c | 0 tests/{ => libgit2}/odb/loose.c | 0 tests/{ => libgit2}/odb/loose_data.h | 0 tests/{ => libgit2}/odb/mixed.c | 0 tests/{ => libgit2}/odb/pack_data.h | 0 tests/{ => libgit2}/odb/pack_data_one.h | 0 tests/{ => libgit2}/odb/packed.c | 0 tests/{ => libgit2}/odb/packed_one.c | 0 tests/{ => libgit2}/odb/sorting.c | 0 tests/{ => libgit2}/odb/streamwrite.c | 0 tests/{ => libgit2}/online/badssl.c | 0 tests/{ => libgit2}/online/clone.c | 0 tests/{ => libgit2}/online/customcert.c | 0 tests/{ => libgit2}/online/fetch.c | 0 tests/{ => libgit2}/online/fetchhead.c | 0 tests/{ => libgit2}/online/push.c | 0 tests/{ => libgit2}/online/push_util.c | 0 tests/{ => libgit2}/online/push_util.h | 0 tests/{ => libgit2}/online/remotes.c | 0 tests/{ => libgit2}/pack/filelimit.c | 0 tests/{ => libgit2}/pack/indexer.c | 0 tests/{ => libgit2}/pack/midx.c | 0 tests/{ => libgit2}/pack/packbuilder.c | 0 tests/{ => libgit2}/pack/sharing.c | 0 tests/{ => libgit2}/pack/threadsafety.c | 0 tests/{ => libgit2}/patch/parse.c | 0 tests/{ => libgit2}/patch/patch_common.h | 0 tests/{ => libgit2}/patch/print.c | 0 tests/{ => libgit2}/path/core.c | 0 tests/{ => libgit2}/path/dotgit.c | 0 tests/{ => libgit2}/path/win32.c | 0 .../perf/helper__perf__do_merge.c | 0 .../perf/helper__perf__do_merge.h | 0 .../{ => libgit2}/perf/helper__perf__timer.c | 0 .../{ => libgit2}/perf/helper__perf__timer.h | 0 tests/{ => libgit2}/perf/merge.c | 0 tests/{ => libgit2}/precompiled.c | 0 tests/{ => libgit2}/precompiled.h | 0 tests/{ => libgit2}/rebase/abort.c | 0 tests/{ => libgit2}/rebase/inmemory.c | 0 tests/{ => libgit2}/rebase/iterator.c | 0 tests/{ => libgit2}/rebase/merge.c | 0 tests/{ => libgit2}/rebase/setup.c | 0 tests/{ => libgit2}/rebase/sign.c | 0 tests/{ => libgit2}/rebase/submodule.c | 0 tests/{ => libgit2}/refs/basic.c | 0 .../{ => libgit2}/refs/branches/checkedout.c | 0 tests/{ => libgit2}/refs/branches/create.c | 0 tests/{ => libgit2}/refs/branches/delete.c | 0 tests/{ => libgit2}/refs/branches/ishead.c | 0 tests/{ => libgit2}/refs/branches/iterator.c | 0 tests/{ => libgit2}/refs/branches/lookup.c | 0 tests/{ => libgit2}/refs/branches/move.c | 0 tests/{ => libgit2}/refs/branches/name.c | 0 tests/{ => libgit2}/refs/branches/remote.c | 0 tests/{ => libgit2}/refs/branches/upstream.c | 0 .../refs/branches/upstreamname.c | 0 tests/{ => libgit2}/refs/crashes.c | 0 tests/{ => libgit2}/refs/create.c | 0 tests/{ => libgit2}/refs/delete.c | 0 tests/{ => libgit2}/refs/dup.c | 0 tests/{ => libgit2}/refs/foreachglob.c | 0 tests/{ => libgit2}/refs/isvalidname.c | 0 tests/{ => libgit2}/refs/iterator.c | 0 tests/{ => libgit2}/refs/list.c | 0 tests/{ => libgit2}/refs/listall.c | 0 tests/{ => libgit2}/refs/lookup.c | 0 tests/{ => libgit2}/refs/namespaces.c | 0 tests/{ => libgit2}/refs/normalize.c | 0 tests/{ => libgit2}/refs/overwrite.c | 0 tests/{ => libgit2}/refs/pack.c | 0 tests/{ => libgit2}/refs/peel.c | 0 tests/{ => libgit2}/refs/races.c | 0 tests/{ => libgit2}/refs/read.c | 0 tests/{ => libgit2}/refs/ref_helpers.c | 0 tests/{ => libgit2}/refs/ref_helpers.h | 0 tests/{ => libgit2}/refs/reflog/drop.c | 0 tests/{ => libgit2}/refs/reflog/messages.c | 0 tests/{ => libgit2}/refs/reflog/reflog.c | 0 .../refs/reflog/reflog_helpers.c | 0 .../refs/reflog/reflog_helpers.h | 0 tests/{ => libgit2}/refs/rename.c | 0 tests/{ => libgit2}/refs/revparse.c | 0 tests/{ => libgit2}/refs/setter.c | 0 tests/{ => libgit2}/refs/shorthand.c | 0 tests/{ => libgit2}/refs/tags/name.c | 0 tests/{ => libgit2}/refs/transactions.c | 0 tests/{ => libgit2}/refs/unicode.c | 0 tests/{ => libgit2}/refs/update.c | 0 tests/{ => libgit2}/remote/create.c | 0 tests/{ => libgit2}/remote/fetch.c | 0 tests/{ => libgit2}/remote/httpproxy.c | 0 tests/{ => libgit2}/remote/insteadof.c | 0 tests/{ => libgit2}/remote/list.c | 0 tests/{ => libgit2}/repo/config.c | 0 tests/{ => libgit2}/repo/discover.c | 0 tests/{ => libgit2}/repo/env.c | 0 tests/{ => libgit2}/repo/extensions.c | 0 tests/{ => libgit2}/repo/getters.c | 0 tests/{ => libgit2}/repo/hashfile.c | 0 tests/{ => libgit2}/repo/head.c | 0 tests/{ => libgit2}/repo/headtree.c | 0 tests/{ => libgit2}/repo/init.c | 0 tests/{ => libgit2}/repo/message.c | 0 tests/{ => libgit2}/repo/new.c | 0 tests/{ => libgit2}/repo/open.c | 0 tests/{ => libgit2}/repo/pathspec.c | 0 tests/{ => libgit2}/repo/repo_helpers.c | 0 tests/{ => libgit2}/repo/repo_helpers.h | 0 tests/{ => libgit2}/repo/reservedname.c | 0 tests/{ => libgit2}/repo/setters.c | 0 tests/{ => libgit2}/repo/shallow.c | 0 tests/{ => libgit2}/repo/state.c | 0 tests/{ => libgit2}/repo/template.c | 0 tests/{ => libgit2}/reset/default.c | 0 tests/{ => libgit2}/reset/hard.c | 0 tests/{ => libgit2}/reset/mixed.c | 0 tests/{ => libgit2}/reset/reset_helpers.c | 0 tests/{ => libgit2}/reset/reset_helpers.h | 0 tests/{ => libgit2}/reset/soft.c | 0 tests/{ => libgit2}/revert/bare.c | 0 tests/{ => libgit2}/revert/rename.c | 0 tests/{ => libgit2}/revert/workdir.c | 0 tests/{ => libgit2}/revwalk/basic.c | 0 tests/{ => libgit2}/revwalk/hidecb.c | 0 tests/{ => libgit2}/revwalk/mergebase.c | 0 .../{ => libgit2}/revwalk/signatureparsing.c | 0 tests/{ => libgit2}/revwalk/simplify.c | 0 tests/{ => libgit2}/stash/apply.c | 0 tests/{ => libgit2}/stash/drop.c | 0 tests/{ => libgit2}/stash/foreach.c | 0 tests/{ => libgit2}/stash/save.c | 0 tests/{ => libgit2}/stash/stash_helpers.c | 0 tests/{ => libgit2}/stash/stash_helpers.h | 0 tests/{ => libgit2}/stash/submodules.c | 0 tests/{ => libgit2}/status/renames.c | 0 tests/{ => libgit2}/status/single.c | 0 tests/{ => libgit2}/status/status_data.h | 0 tests/{ => libgit2}/status/status_helpers.c | 0 tests/{ => libgit2}/status/status_helpers.h | 0 tests/{ => libgit2}/status/submodules.c | 0 tests/{ => libgit2}/status/worktree.c | 0 tests/{ => libgit2}/status/worktree_init.c | 0 tests/{ => libgit2}/str/basic.c | 0 tests/{ => libgit2}/str/oom.c | 0 tests/{ => libgit2}/str/percent.c | 0 tests/{ => libgit2}/str/quote.c | 0 tests/{ => libgit2}/str/splice.c | 0 tests/{ => libgit2}/stream/deprecated.c | 0 tests/{ => libgit2}/stream/registration.c | 0 tests/{ => libgit2}/stress/diff.c | 0 tests/{ => libgit2}/submodule/add.c | 0 tests/{ => libgit2}/submodule/escape.c | 0 tests/{ => libgit2}/submodule/init.c | 0 tests/{ => libgit2}/submodule/inject_option.c | 0 tests/{ => libgit2}/submodule/lookup.c | 0 tests/{ => libgit2}/submodule/modify.c | 0 tests/{ => libgit2}/submodule/nosubs.c | 0 tests/{ => libgit2}/submodule/open.c | 0 .../{ => libgit2}/submodule/repository_init.c | 0 tests/{ => libgit2}/submodule/status.c | 0 .../submodule/submodule_helpers.c | 0 .../submodule/submodule_helpers.h | 0 tests/{ => libgit2}/submodule/update.c | 0 tests/{ => libgit2}/threads/atomic.c | 0 tests/{ => libgit2}/threads/basic.c | 0 tests/{ => libgit2}/threads/diff.c | 0 tests/{ => libgit2}/threads/iterator.c | 0 tests/{ => libgit2}/threads/refdb.c | 0 tests/{ => libgit2}/threads/thread_helpers.c | 0 tests/{ => libgit2}/threads/thread_helpers.h | 0 tests/{ => libgit2}/threads/tlsdata.c | 0 tests/{ => libgit2}/trace/trace.c | 0 .../{ => libgit2}/trace/windows/stacktrace.c | 0 tests/{ => libgit2}/transport/register.c | 0 tests/{ => libgit2}/transports/smart/packet.c | 0 tests/{ => libgit2}/valgrind-supp-mac.txt | 0 tests/{ => libgit2}/win32/forbidden.c | 0 tests/{ => libgit2}/win32/longpath.c | 0 tests/{ => libgit2}/win32/systemdir.c | 0 tests/{ => libgit2}/worktree/bare.c | 0 tests/{ => libgit2}/worktree/config.c | 0 tests/{ => libgit2}/worktree/merge.c | 0 tests/{ => libgit2}/worktree/open.c | 0 tests/{ => libgit2}/worktree/reflog.c | 0 tests/{ => libgit2}/worktree/refs.c | 0 tests/{ => libgit2}/worktree/repository.c | 0 tests/{ => libgit2}/worktree/submodule.c | 0 tests/{ => libgit2}/worktree/worktree.c | 0 .../{ => libgit2}/worktree/worktree_helpers.c | 0 .../{ => libgit2}/worktree/worktree_helpers.h | 0 487 files changed, 147 insertions(+), 117 deletions(-) create mode 100644 tests/libgit2/CMakeLists.txt rename tests/{ => libgit2}/apply/apply_helpers.c (100%) rename tests/{ => libgit2}/apply/apply_helpers.h (100%) rename tests/{ => libgit2}/apply/both.c (100%) rename tests/{ => libgit2}/apply/callbacks.c (100%) rename tests/{ => libgit2}/apply/check.c (100%) rename tests/{ => libgit2}/apply/fromdiff.c (100%) rename tests/{ => libgit2}/apply/fromfile.c (100%) rename tests/{ => libgit2}/apply/index.c (100%) rename tests/{ => libgit2}/apply/partial.c (100%) rename tests/{ => libgit2}/apply/tree.c (100%) rename tests/{ => libgit2}/apply/workdir.c (100%) rename tests/{ => libgit2}/attr/attr_expect.h (100%) rename tests/{ => libgit2}/attr/file.c (100%) rename tests/{ => libgit2}/attr/flags.c (100%) rename tests/{ => libgit2}/attr/lookup.c (100%) rename tests/{ => libgit2}/attr/macro.c (100%) rename tests/{ => libgit2}/attr/repo.c (100%) rename tests/{ => libgit2}/blame/blame_helpers.c (100%) rename tests/{ => libgit2}/blame/blame_helpers.h (100%) rename tests/{ => libgit2}/blame/buffer.c (100%) rename tests/{ => libgit2}/blame/getters.c (100%) rename tests/{ => libgit2}/blame/harder.c (100%) rename tests/{ => libgit2}/blame/simple.c (100%) rename tests/{ => libgit2}/checkout/binaryunicode.c (100%) rename tests/{ => libgit2}/checkout/checkout_helpers.c (100%) rename tests/{ => libgit2}/checkout/checkout_helpers.h (100%) rename tests/{ => libgit2}/checkout/conflict.c (100%) rename tests/{ => libgit2}/checkout/crlf.c (100%) rename tests/{ => libgit2}/checkout/head.c (100%) rename tests/{ => libgit2}/checkout/icase.c (100%) rename tests/{ => libgit2}/checkout/index.c (100%) rename tests/{ => libgit2}/checkout/nasty.c (100%) rename tests/{ => libgit2}/checkout/tree.c (100%) rename tests/{ => libgit2}/checkout/typechange.c (100%) rename tests/{ => libgit2}/cherrypick/bare.c (100%) rename tests/{ => libgit2}/cherrypick/workdir.c (100%) rename tests/{ => libgit2}/clar.c (100%) rename tests/{ => libgit2}/clar.h (100%) rename tests/{ => libgit2}/clar/fixtures.h (100%) rename tests/{ => libgit2}/clar/fs.h (100%) rename tests/{ => libgit2}/clar/print.h (100%) rename tests/{ => libgit2}/clar/sandbox.h (100%) rename tests/{ => libgit2}/clar/summary.h (100%) rename tests/{ => libgit2}/clar_libgit2.c (100%) rename tests/{ => libgit2}/clar_libgit2.h (100%) rename tests/{ => libgit2}/clar_libgit2_timer.c (100%) rename tests/{ => libgit2}/clar_libgit2_timer.h (100%) rename tests/{ => libgit2}/clar_libgit2_trace.c (100%) rename tests/{ => libgit2}/clar_libgit2_trace.h (100%) rename tests/{ => libgit2}/clone/empty.c (100%) rename tests/{ => libgit2}/clone/local.c (100%) rename tests/{ => libgit2}/clone/nonetwork.c (100%) rename tests/{ => libgit2}/clone/transport.c (100%) rename tests/{ => libgit2}/commit/commit.c (100%) rename tests/{ => libgit2}/commit/parent.c (100%) rename tests/{ => libgit2}/commit/parse.c (100%) rename tests/{ => libgit2}/commit/signature.c (100%) rename tests/{ => libgit2}/commit/write.c (100%) rename tests/{ => libgit2}/config/add.c (100%) rename tests/{ => libgit2}/config/backend.c (100%) rename tests/{ => libgit2}/config/conditionals.c (100%) rename tests/{ => libgit2}/config/config_helpers.c (100%) rename tests/{ => libgit2}/config/config_helpers.h (100%) rename tests/{ => libgit2}/config/configlevel.c (100%) rename tests/{ => libgit2}/config/global.c (100%) rename tests/{ => libgit2}/config/include.c (100%) rename tests/{ => libgit2}/config/memory.c (100%) rename tests/{ => libgit2}/config/multivar.c (100%) rename tests/{ => libgit2}/config/new.c (100%) rename tests/{ => libgit2}/config/read.c (100%) rename tests/{ => libgit2}/config/readonly.c (100%) rename tests/{ => libgit2}/config/rename.c (100%) rename tests/{ => libgit2}/config/snapshot.c (100%) rename tests/{ => libgit2}/config/stress.c (100%) rename tests/{ => libgit2}/config/validkeyname.c (100%) rename tests/{ => libgit2}/config/write.c (100%) rename tests/{ => libgit2}/core/array.c (100%) rename tests/{ => libgit2}/core/assert.c (100%) rename tests/{ => libgit2}/core/bitvec.c (100%) rename tests/{ => libgit2}/core/buf.c (100%) rename tests/{ => libgit2}/core/copy.c (100%) rename tests/{ => libgit2}/core/dirent.c (100%) rename tests/{ => libgit2}/core/encoding.c (100%) rename tests/{ => libgit2}/core/env.c (100%) rename tests/{ => libgit2}/core/errors.c (100%) rename tests/{ => libgit2}/core/features.c (100%) rename tests/{ => libgit2}/core/filebuf.c (100%) rename tests/{ => libgit2}/core/ftruncate.c (100%) rename tests/{ => libgit2}/core/futils.c (100%) rename tests/{ => libgit2}/core/gitstr.c (100%) rename tests/{ => libgit2}/core/hex.c (100%) rename tests/{ => libgit2}/core/iconv.c (100%) rename tests/{ => libgit2}/core/init.c (100%) rename tests/{ => libgit2}/core/integer.c (100%) rename tests/{ => libgit2}/core/link.c (100%) rename tests/{ => libgit2}/core/memmem.c (100%) rename tests/{ => libgit2}/core/mkdir.c (100%) rename tests/{ => libgit2}/core/oid.c (100%) rename tests/{ => libgit2}/core/oidmap.c (100%) rename tests/{ => libgit2}/core/opts.c (100%) rename tests/{ => libgit2}/core/path.c (100%) rename tests/{ => libgit2}/core/pool.c (100%) rename tests/{ => libgit2}/core/posix.c (100%) rename tests/{ => libgit2}/core/pqueue.c (100%) rename tests/{ => libgit2}/core/qsort.c (100%) rename tests/{ => libgit2}/core/regexp.c (100%) rename tests/{ => libgit2}/core/rmdir.c (100%) rename tests/{ => libgit2}/core/sha1.c (100%) rename tests/{ => libgit2}/core/sortedcache.c (100%) rename tests/{ => libgit2}/core/stat.c (100%) rename tests/{ => libgit2}/core/string.c (100%) rename tests/{ => libgit2}/core/strmap.c (100%) rename tests/{ => libgit2}/core/strtol.c (100%) rename tests/{ => libgit2}/core/structinit.c (100%) rename tests/{ => libgit2}/core/useragent.c (100%) rename tests/{ => libgit2}/core/utf8.c (100%) rename tests/{ => libgit2}/core/vector.c (100%) rename tests/{ => libgit2}/core/wildmatch.c (100%) rename tests/{ => libgit2}/core/zstream.c (100%) rename tests/{ => libgit2}/date/date.c (100%) rename tests/{ => libgit2}/date/rfc2822.c (100%) rename tests/{ => libgit2}/delta/apply.c (100%) rename tests/{ => libgit2}/describe/describe.c (100%) rename tests/{ => libgit2}/describe/describe_helpers.c (100%) rename tests/{ => libgit2}/describe/describe_helpers.h (100%) rename tests/{ => libgit2}/describe/t6120.c (100%) rename tests/{ => libgit2}/diff/binary.c (100%) rename tests/{ => libgit2}/diff/blob.c (100%) rename tests/{ => libgit2}/diff/diff_helpers.c (100%) rename tests/{ => libgit2}/diff/diff_helpers.h (100%) rename tests/{ => libgit2}/diff/diffiter.c (100%) rename tests/{ => libgit2}/diff/drivers.c (100%) rename tests/{ => libgit2}/diff/externalmodifications.c (100%) rename tests/{ => libgit2}/diff/format_email.c (100%) rename tests/{ => libgit2}/diff/index.c (100%) rename tests/{ => libgit2}/diff/notify.c (100%) rename tests/{ => libgit2}/diff/parse.c (100%) rename tests/{ => libgit2}/diff/patch.c (100%) rename tests/{ => libgit2}/diff/patchid.c (100%) rename tests/{ => libgit2}/diff/pathspec.c (100%) rename tests/{ => libgit2}/diff/racediffiter.c (100%) rename tests/{ => libgit2}/diff/rename.c (100%) rename tests/{ => libgit2}/diff/stats.c (100%) rename tests/{ => libgit2}/diff/submodules.c (100%) rename tests/{ => libgit2}/diff/tree.c (100%) rename tests/{ => libgit2}/diff/workdir.c (100%) rename tests/{ => libgit2}/email/create.c (100%) rename tests/{ => libgit2}/email/create.c.bak (100%) rename tests/{ => libgit2}/fetch/local.c (100%) rename tests/{ => libgit2}/fetchhead/fetchhead_data.h (100%) rename tests/{ => libgit2}/fetchhead/nonetwork.c (100%) rename tests/{ => libgit2}/filter/bare.c (100%) rename tests/{ => libgit2}/filter/blob.c (100%) rename tests/{ => libgit2}/filter/crlf.c (100%) rename tests/{ => libgit2}/filter/crlf.h (100%) rename tests/{ => libgit2}/filter/custom.c (100%) rename tests/{ => libgit2}/filter/custom_helpers.c (100%) rename tests/{ => libgit2}/filter/custom_helpers.h (100%) rename tests/{ => libgit2}/filter/file.c (100%) rename tests/{ => libgit2}/filter/ident.c (100%) rename tests/{ => libgit2}/filter/query.c (100%) rename tests/{ => libgit2}/filter/stream.c (100%) rename tests/{ => libgit2}/filter/systemattrs.c (100%) rename tests/{ => libgit2}/filter/wildcard.c (100%) rename tests/{ => libgit2}/generate.py (100%) rename tests/{ => libgit2}/graph/ahead_behind.c (100%) rename tests/{ => libgit2}/graph/commitgraph.c (100%) rename tests/{ => libgit2}/graph/descendant_of.c (100%) rename tests/{ => libgit2}/graph/reachable_from_any.c (100%) rename tests/{ => libgit2}/headertest.c (100%) rename tests/{ => libgit2}/ignore/path.c (100%) rename tests/{ => libgit2}/ignore/status.c (100%) rename tests/{ => libgit2}/index/add.c (100%) rename tests/{ => libgit2}/index/addall.c (100%) rename tests/{ => libgit2}/index/bypath.c (100%) rename tests/{ => libgit2}/index/cache.c (100%) rename tests/{ => libgit2}/index/collision.c (100%) rename tests/{ => libgit2}/index/conflicts.c (100%) rename tests/{ => libgit2}/index/conflicts.h (100%) rename tests/{ => libgit2}/index/crlf.c (100%) rename tests/{ => libgit2}/index/filemodes.c (100%) rename tests/{ => libgit2}/index/inmemory.c (100%) rename tests/{ => libgit2}/index/names.c (100%) rename tests/{ => libgit2}/index/nsec.c (100%) rename tests/{ => libgit2}/index/racy.c (100%) rename tests/{ => libgit2}/index/read_index.c (100%) rename tests/{ => libgit2}/index/read_tree.c (100%) rename tests/{ => libgit2}/index/rename.c (100%) rename tests/{ => libgit2}/index/reuc.c (100%) rename tests/{ => libgit2}/index/splitindex.c (100%) rename tests/{ => libgit2}/index/stage.c (100%) rename tests/{ => libgit2}/index/tests.c (100%) rename tests/{ => libgit2}/index/version.c (100%) rename tests/{ => libgit2}/iterator/index.c (100%) rename tests/{ => libgit2}/iterator/iterator_helpers.c (100%) rename tests/{ => libgit2}/iterator/iterator_helpers.h (100%) rename tests/{ => libgit2}/iterator/tree.c (100%) rename tests/{ => libgit2}/iterator/workdir.c (100%) rename tests/{ => libgit2}/mailmap/basic.c (100%) rename tests/{ => libgit2}/mailmap/blame.c (100%) rename tests/{ => libgit2}/mailmap/mailmap_testdata.h (100%) rename tests/{ => libgit2}/mailmap/parsing.c (100%) rename tests/{ => libgit2}/main.c (100%) rename tests/{ => libgit2}/merge/analysis.c (100%) rename tests/{ => libgit2}/merge/annotated_commit.c (100%) rename tests/{ => libgit2}/merge/conflict_data.h (100%) rename tests/{ => libgit2}/merge/driver.c (100%) rename tests/{ => libgit2}/merge/files.c (100%) rename tests/{ => libgit2}/merge/merge_helpers.c (100%) rename tests/{ => libgit2}/merge/merge_helpers.h (100%) rename tests/{ => libgit2}/merge/trees/automerge.c (100%) rename tests/{ => libgit2}/merge/trees/commits.c (100%) rename tests/{ => libgit2}/merge/trees/modeconflict.c (100%) rename tests/{ => libgit2}/merge/trees/recursive.c (100%) rename tests/{ => libgit2}/merge/trees/renames.c (100%) rename tests/{ => libgit2}/merge/trees/treediff.c (100%) rename tests/{ => libgit2}/merge/trees/trivial.c (100%) rename tests/{ => libgit2}/merge/trees/whitespace.c (100%) rename tests/{ => libgit2}/merge/workdir/dirty.c (100%) rename tests/{ => libgit2}/merge/workdir/recursive.c (100%) rename tests/{ => libgit2}/merge/workdir/renames.c (100%) rename tests/{ => libgit2}/merge/workdir/setup.c (100%) rename tests/{ => libgit2}/merge/workdir/simple.c (100%) rename tests/{ => libgit2}/merge/workdir/submodules.c (100%) rename tests/{ => libgit2}/merge/workdir/trivial.c (100%) rename tests/{ => libgit2}/message/trailer.c (100%) rename tests/{ => libgit2}/network/cred.c (100%) rename tests/{ => libgit2}/network/fetchlocal.c (100%) rename tests/{ => libgit2}/network/matchhost.c (100%) rename tests/{ => libgit2}/network/refspecs.c (100%) rename tests/{ => libgit2}/network/remote/defaultbranch.c (100%) rename tests/{ => libgit2}/network/remote/delete.c (100%) rename tests/{ => libgit2}/network/remote/isvalidname.c (100%) rename tests/{ => libgit2}/network/remote/local.c (100%) rename tests/{ => libgit2}/network/remote/push.c (100%) rename tests/{ => libgit2}/network/remote/remotes.c (100%) rename tests/{ => libgit2}/network/remote/rename.c (100%) rename tests/{ => libgit2}/network/url/joinpath.c (100%) rename tests/{ => libgit2}/network/url/parse.c (100%) rename tests/{ => libgit2}/network/url/pattern.c (100%) rename tests/{ => libgit2}/network/url/redirect.c (100%) rename tests/{ => libgit2}/network/url/scp.c (100%) rename tests/{ => libgit2}/network/url/valid.c (100%) rename tests/{ => libgit2}/notes/notes.c (100%) rename tests/{ => libgit2}/notes/notesref.c (100%) rename tests/{ => libgit2}/object/blob/filter.c (100%) rename tests/{ => libgit2}/object/blob/fromstream.c (100%) rename tests/{ => libgit2}/object/blob/write.c (100%) rename tests/{ => libgit2}/object/cache.c (100%) rename tests/{ => libgit2}/object/commit/commitstagedfile.c (100%) rename tests/{ => libgit2}/object/commit/parse.c (100%) rename tests/{ => libgit2}/object/lookup.c (100%) rename tests/{ => libgit2}/object/lookupbypath.c (100%) rename tests/{ => libgit2}/object/message.c (100%) rename tests/{ => libgit2}/object/peel.c (100%) rename tests/{ => libgit2}/object/raw/chars.c (100%) rename tests/{ => libgit2}/object/raw/compare.c (100%) rename tests/{ => libgit2}/object/raw/convert.c (100%) rename tests/{ => libgit2}/object/raw/data.h (100%) rename tests/{ => libgit2}/object/raw/fromstr.c (100%) rename tests/{ => libgit2}/object/raw/hash.c (100%) rename tests/{ => libgit2}/object/raw/short.c (100%) rename tests/{ => libgit2}/object/raw/size.c (100%) rename tests/{ => libgit2}/object/raw/type2string.c (100%) rename tests/{ => libgit2}/object/raw/write.c (100%) rename tests/{ => libgit2}/object/shortid.c (100%) rename tests/{ => libgit2}/object/tag/list.c (100%) rename tests/{ => libgit2}/object/tag/parse.c (100%) rename tests/{ => libgit2}/object/tag/peel.c (100%) rename tests/{ => libgit2}/object/tag/read.c (100%) rename tests/{ => libgit2}/object/tag/write.c (100%) rename tests/{ => libgit2}/object/tree/attributes.c (100%) rename tests/{ => libgit2}/object/tree/duplicateentries.c (100%) rename tests/{ => libgit2}/object/tree/frompath.c (100%) rename tests/{ => libgit2}/object/tree/parse.c (100%) rename tests/{ => libgit2}/object/tree/read.c (100%) rename tests/{ => libgit2}/object/tree/update.c (100%) rename tests/{ => libgit2}/object/tree/walk.c (100%) rename tests/{ => libgit2}/object/tree/write.c (100%) rename tests/{ => libgit2}/object/validate.c (100%) rename tests/{ => libgit2}/odb/alternates.c (100%) rename tests/{ => libgit2}/odb/backend/backend_helpers.c (100%) rename tests/{ => libgit2}/odb/backend/backend_helpers.h (100%) rename tests/{ => libgit2}/odb/backend/mempack.c (100%) rename tests/{ => libgit2}/odb/backend/multiple.c (100%) rename tests/{ => libgit2}/odb/backend/nobackend.c (100%) rename tests/{ => libgit2}/odb/backend/nonrefreshing.c (100%) rename tests/{ => libgit2}/odb/backend/refreshing.c (100%) rename tests/{ => libgit2}/odb/backend/simple.c (100%) rename tests/{ => libgit2}/odb/emptyobjects.c (100%) rename tests/{ => libgit2}/odb/foreach.c (100%) rename tests/{ => libgit2}/odb/freshen.c (100%) rename tests/{ => libgit2}/odb/largefiles.c (100%) rename tests/{ => libgit2}/odb/loose.c (100%) rename tests/{ => libgit2}/odb/loose_data.h (100%) rename tests/{ => libgit2}/odb/mixed.c (100%) rename tests/{ => libgit2}/odb/pack_data.h (100%) rename tests/{ => libgit2}/odb/pack_data_one.h (100%) rename tests/{ => libgit2}/odb/packed.c (100%) rename tests/{ => libgit2}/odb/packed_one.c (100%) rename tests/{ => libgit2}/odb/sorting.c (100%) rename tests/{ => libgit2}/odb/streamwrite.c (100%) rename tests/{ => libgit2}/online/badssl.c (100%) rename tests/{ => libgit2}/online/clone.c (100%) rename tests/{ => libgit2}/online/customcert.c (100%) rename tests/{ => libgit2}/online/fetch.c (100%) rename tests/{ => libgit2}/online/fetchhead.c (100%) rename tests/{ => libgit2}/online/push.c (100%) rename tests/{ => libgit2}/online/push_util.c (100%) rename tests/{ => libgit2}/online/push_util.h (100%) rename tests/{ => libgit2}/online/remotes.c (100%) rename tests/{ => libgit2}/pack/filelimit.c (100%) rename tests/{ => libgit2}/pack/indexer.c (100%) rename tests/{ => libgit2}/pack/midx.c (100%) rename tests/{ => libgit2}/pack/packbuilder.c (100%) rename tests/{ => libgit2}/pack/sharing.c (100%) rename tests/{ => libgit2}/pack/threadsafety.c (100%) rename tests/{ => libgit2}/patch/parse.c (100%) rename tests/{ => libgit2}/patch/patch_common.h (100%) rename tests/{ => libgit2}/patch/print.c (100%) rename tests/{ => libgit2}/path/core.c (100%) rename tests/{ => libgit2}/path/dotgit.c (100%) rename tests/{ => libgit2}/path/win32.c (100%) rename tests/{ => libgit2}/perf/helper__perf__do_merge.c (100%) rename tests/{ => libgit2}/perf/helper__perf__do_merge.h (100%) rename tests/{ => libgit2}/perf/helper__perf__timer.c (100%) rename tests/{ => libgit2}/perf/helper__perf__timer.h (100%) rename tests/{ => libgit2}/perf/merge.c (100%) rename tests/{ => libgit2}/precompiled.c (100%) rename tests/{ => libgit2}/precompiled.h (100%) rename tests/{ => libgit2}/rebase/abort.c (100%) rename tests/{ => libgit2}/rebase/inmemory.c (100%) rename tests/{ => libgit2}/rebase/iterator.c (100%) rename tests/{ => libgit2}/rebase/merge.c (100%) rename tests/{ => libgit2}/rebase/setup.c (100%) rename tests/{ => libgit2}/rebase/sign.c (100%) rename tests/{ => libgit2}/rebase/submodule.c (100%) rename tests/{ => libgit2}/refs/basic.c (100%) rename tests/{ => libgit2}/refs/branches/checkedout.c (100%) rename tests/{ => libgit2}/refs/branches/create.c (100%) rename tests/{ => libgit2}/refs/branches/delete.c (100%) rename tests/{ => libgit2}/refs/branches/ishead.c (100%) rename tests/{ => libgit2}/refs/branches/iterator.c (100%) rename tests/{ => libgit2}/refs/branches/lookup.c (100%) rename tests/{ => libgit2}/refs/branches/move.c (100%) rename tests/{ => libgit2}/refs/branches/name.c (100%) rename tests/{ => libgit2}/refs/branches/remote.c (100%) rename tests/{ => libgit2}/refs/branches/upstream.c (100%) rename tests/{ => libgit2}/refs/branches/upstreamname.c (100%) rename tests/{ => libgit2}/refs/crashes.c (100%) rename tests/{ => libgit2}/refs/create.c (100%) rename tests/{ => libgit2}/refs/delete.c (100%) rename tests/{ => libgit2}/refs/dup.c (100%) rename tests/{ => libgit2}/refs/foreachglob.c (100%) rename tests/{ => libgit2}/refs/isvalidname.c (100%) rename tests/{ => libgit2}/refs/iterator.c (100%) rename tests/{ => libgit2}/refs/list.c (100%) rename tests/{ => libgit2}/refs/listall.c (100%) rename tests/{ => libgit2}/refs/lookup.c (100%) rename tests/{ => libgit2}/refs/namespaces.c (100%) rename tests/{ => libgit2}/refs/normalize.c (100%) rename tests/{ => libgit2}/refs/overwrite.c (100%) rename tests/{ => libgit2}/refs/pack.c (100%) rename tests/{ => libgit2}/refs/peel.c (100%) rename tests/{ => libgit2}/refs/races.c (100%) rename tests/{ => libgit2}/refs/read.c (100%) rename tests/{ => libgit2}/refs/ref_helpers.c (100%) rename tests/{ => libgit2}/refs/ref_helpers.h (100%) rename tests/{ => libgit2}/refs/reflog/drop.c (100%) rename tests/{ => libgit2}/refs/reflog/messages.c (100%) rename tests/{ => libgit2}/refs/reflog/reflog.c (100%) rename tests/{ => libgit2}/refs/reflog/reflog_helpers.c (100%) rename tests/{ => libgit2}/refs/reflog/reflog_helpers.h (100%) rename tests/{ => libgit2}/refs/rename.c (100%) rename tests/{ => libgit2}/refs/revparse.c (100%) rename tests/{ => libgit2}/refs/setter.c (100%) rename tests/{ => libgit2}/refs/shorthand.c (100%) rename tests/{ => libgit2}/refs/tags/name.c (100%) rename tests/{ => libgit2}/refs/transactions.c (100%) rename tests/{ => libgit2}/refs/unicode.c (100%) rename tests/{ => libgit2}/refs/update.c (100%) rename tests/{ => libgit2}/remote/create.c (100%) rename tests/{ => libgit2}/remote/fetch.c (100%) rename tests/{ => libgit2}/remote/httpproxy.c (100%) rename tests/{ => libgit2}/remote/insteadof.c (100%) rename tests/{ => libgit2}/remote/list.c (100%) rename tests/{ => libgit2}/repo/config.c (100%) rename tests/{ => libgit2}/repo/discover.c (100%) rename tests/{ => libgit2}/repo/env.c (100%) rename tests/{ => libgit2}/repo/extensions.c (100%) rename tests/{ => libgit2}/repo/getters.c (100%) rename tests/{ => libgit2}/repo/hashfile.c (100%) rename tests/{ => libgit2}/repo/head.c (100%) rename tests/{ => libgit2}/repo/headtree.c (100%) rename tests/{ => libgit2}/repo/init.c (100%) rename tests/{ => libgit2}/repo/message.c (100%) rename tests/{ => libgit2}/repo/new.c (100%) rename tests/{ => libgit2}/repo/open.c (100%) rename tests/{ => libgit2}/repo/pathspec.c (100%) rename tests/{ => libgit2}/repo/repo_helpers.c (100%) rename tests/{ => libgit2}/repo/repo_helpers.h (100%) rename tests/{ => libgit2}/repo/reservedname.c (100%) rename tests/{ => libgit2}/repo/setters.c (100%) rename tests/{ => libgit2}/repo/shallow.c (100%) rename tests/{ => libgit2}/repo/state.c (100%) rename tests/{ => libgit2}/repo/template.c (100%) rename tests/{ => libgit2}/reset/default.c (100%) rename tests/{ => libgit2}/reset/hard.c (100%) rename tests/{ => libgit2}/reset/mixed.c (100%) rename tests/{ => libgit2}/reset/reset_helpers.c (100%) rename tests/{ => libgit2}/reset/reset_helpers.h (100%) rename tests/{ => libgit2}/reset/soft.c (100%) rename tests/{ => libgit2}/revert/bare.c (100%) rename tests/{ => libgit2}/revert/rename.c (100%) rename tests/{ => libgit2}/revert/workdir.c (100%) rename tests/{ => libgit2}/revwalk/basic.c (100%) rename tests/{ => libgit2}/revwalk/hidecb.c (100%) rename tests/{ => libgit2}/revwalk/mergebase.c (100%) rename tests/{ => libgit2}/revwalk/signatureparsing.c (100%) rename tests/{ => libgit2}/revwalk/simplify.c (100%) rename tests/{ => libgit2}/stash/apply.c (100%) rename tests/{ => libgit2}/stash/drop.c (100%) rename tests/{ => libgit2}/stash/foreach.c (100%) rename tests/{ => libgit2}/stash/save.c (100%) rename tests/{ => libgit2}/stash/stash_helpers.c (100%) rename tests/{ => libgit2}/stash/stash_helpers.h (100%) rename tests/{ => libgit2}/stash/submodules.c (100%) rename tests/{ => libgit2}/status/renames.c (100%) rename tests/{ => libgit2}/status/single.c (100%) rename tests/{ => libgit2}/status/status_data.h (100%) rename tests/{ => libgit2}/status/status_helpers.c (100%) rename tests/{ => libgit2}/status/status_helpers.h (100%) rename tests/{ => libgit2}/status/submodules.c (100%) rename tests/{ => libgit2}/status/worktree.c (100%) rename tests/{ => libgit2}/status/worktree_init.c (100%) rename tests/{ => libgit2}/str/basic.c (100%) rename tests/{ => libgit2}/str/oom.c (100%) rename tests/{ => libgit2}/str/percent.c (100%) rename tests/{ => libgit2}/str/quote.c (100%) rename tests/{ => libgit2}/str/splice.c (100%) rename tests/{ => libgit2}/stream/deprecated.c (100%) rename tests/{ => libgit2}/stream/registration.c (100%) rename tests/{ => libgit2}/stress/diff.c (100%) rename tests/{ => libgit2}/submodule/add.c (100%) rename tests/{ => libgit2}/submodule/escape.c (100%) rename tests/{ => libgit2}/submodule/init.c (100%) rename tests/{ => libgit2}/submodule/inject_option.c (100%) rename tests/{ => libgit2}/submodule/lookup.c (100%) rename tests/{ => libgit2}/submodule/modify.c (100%) rename tests/{ => libgit2}/submodule/nosubs.c (100%) rename tests/{ => libgit2}/submodule/open.c (100%) rename tests/{ => libgit2}/submodule/repository_init.c (100%) rename tests/{ => libgit2}/submodule/status.c (100%) rename tests/{ => libgit2}/submodule/submodule_helpers.c (100%) rename tests/{ => libgit2}/submodule/submodule_helpers.h (100%) rename tests/{ => libgit2}/submodule/update.c (100%) rename tests/{ => libgit2}/threads/atomic.c (100%) rename tests/{ => libgit2}/threads/basic.c (100%) rename tests/{ => libgit2}/threads/diff.c (100%) rename tests/{ => libgit2}/threads/iterator.c (100%) rename tests/{ => libgit2}/threads/refdb.c (100%) rename tests/{ => libgit2}/threads/thread_helpers.c (100%) rename tests/{ => libgit2}/threads/thread_helpers.h (100%) rename tests/{ => libgit2}/threads/tlsdata.c (100%) rename tests/{ => libgit2}/trace/trace.c (100%) rename tests/{ => libgit2}/trace/windows/stacktrace.c (100%) rename tests/{ => libgit2}/transport/register.c (100%) rename tests/{ => libgit2}/transports/smart/packet.c (100%) rename tests/{ => libgit2}/valgrind-supp-mac.txt (100%) rename tests/{ => libgit2}/win32/forbidden.c (100%) rename tests/{ => libgit2}/win32/longpath.c (100%) rename tests/{ => libgit2}/win32/systemdir.c (100%) rename tests/{ => libgit2}/worktree/bare.c (100%) rename tests/{ => libgit2}/worktree/config.c (100%) rename tests/{ => libgit2}/worktree/merge.c (100%) rename tests/{ => libgit2}/worktree/open.c (100%) rename tests/{ => libgit2}/worktree/reflog.c (100%) rename tests/{ => libgit2}/worktree/refs.c (100%) rename tests/{ => libgit2}/worktree/repository.c (100%) rename tests/{ => libgit2}/worktree/submodule.c (100%) rename tests/{ => libgit2}/worktree/worktree.c (100%) rename tests/{ => libgit2}/worktree/worktree_helpers.c (100%) rename tests/{ => libgit2}/worktree/worktree_helpers.h (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bbb724057ef..8b0d7f44353 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -144,8 +144,8 @@ add_feature_info(threadsafe USE_THREADS "threadsafe support") # ntlmclient if(USE_NTLMCLIENT) set(GIT_NTLM 1) - add_subdirectory("${libgit2_SOURCE_DIR}/deps/ntlmclient" "${libgit2_BINARY_DIR}/deps/ntlmclient") - list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${libgit2_SOURCE_DIR}/deps/ntlmclient") + add_subdirectory("${PROJECT_SOURCE_DIR}/deps/ntlmclient" "${PROJECT_BINARY_DIR}/deps/ntlmclient") + list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${PROJECT_SOURCE_DIR}/deps/ntlmclient") list(APPEND LIBGIT2_DEPENDENCY_OBJECTS "$") endif() add_feature_info(ntlmclient GIT_NTLM "NTLM authentication support for Unix") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 33dfd0ae822..d17f5258929 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,98 +1,4 @@ -# tests: the unit and integration tests for libgit2 +# The main libgit2 tests tree: this CMakeLists.txt includes the +# subprojects that make up core libgit2 support. -set(Python_ADDITIONAL_VERSIONS 3 2.7) -find_package(PythonInterp) - -if(NOT PYTHONINTERP_FOUND) - message(FATAL_ERROR "Could not find a python interpreter, which is needed to build the tests. " - "Make sure python is available, or pass -DBUILD_TESTS=OFF to skip building the tests") -ENDIF() - -set(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/resources/") -set(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}") -add_definitions(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\") -add_definitions(-DCLAR_TMPDIR=\"libgit2_tests\") -add_definitions(-DCLAR_WIN32_LONGPATHS) -add_definitions(-D_FILE_OFFSET_BITS=64) - -# Ensure that we do not use deprecated functions internally -add_definitions(-DGIT_DEPRECATE_HARD) - -set(TEST_INCLUDES "${CLAR_PATH}" "${CMAKE_CURRENT_BINARY_DIR}") -file(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h) -set(SRC_CLAR "main.c" "clar_libgit2.c" "clar_libgit2_trace.c" "clar_libgit2_timer.c" "clar.c") - -if(MSVC_IDE) - list(APPEND SRC_CLAR "precompiled.c") -endif() - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clar.suite ${CMAKE_CURRENT_BINARY_DIR}/clar_suite.h - COMMAND ${PYTHON_EXECUTABLE} generate.py -o "${CMAKE_CURRENT_BINARY_DIR}" -f -xonline -xstress -xperf . - DEPENDS ${SRC_TEST} - WORKING_DIRECTORY ${CLAR_PATH} -) - -set_source_files_properties( - ${CLAR_PATH}/clar.c - PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clar.suite) - -add_executable(libgit2_tests ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS}) - -set_target_properties(libgit2_tests PROPERTIES C_STANDARD 90) -set_target_properties(libgit2_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) - -target_include_directories(libgit2_tests PRIVATE ${TEST_INCLUDES} ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES}) -target_include_directories(libgit2_tests SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) -target_link_libraries(libgit2_tests ${LIBGIT2_SYSTEM_LIBS}) - -ide_split_sources(libgit2_tests) - -# -# Old versions of gcc require us to declare our test functions; don't do -# this on newer compilers to avoid unnecessary recompilation. -# -if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) - target_compile_options(libgit2_tests PRIVATE -include "clar_suite.h") -endif() - -if(MSVC_IDE) - # Precompiled headers - set_target_properties(libgit2_tests PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") - set_source_files_properties("precompiled.c" COMPILE_FLAGS "/Ycprecompiled.h") -endif() - -function(ADD_CLAR_TEST name) - if(NOT USE_LEAK_CHECKER STREQUAL "OFF") - add_test(${name} "${PROJECT_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${PROJECT_BINARY_DIR}/libgit2_tests" ${ARGN}) - else() - add_test(${name} "${PROJECT_BINARY_DIR}/libgit2_tests" ${ARGN}) - endif() -endfunction(ADD_CLAR_TEST) - -add_clar_test(offline -v -xonline) -add_clar_test(invasive -v -score::ftruncate -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root) -add_clar_test(online -v -sonline -xonline::customcert) -add_clar_test(online_customcert -v -sonline::customcert) -add_clar_test(gitdaemon -v -sonline::push) -add_clar_test(ssh -v -sonline::push -sonline::clone::ssh_cert -sonline::clone::ssh_with_paths -sonline::clone::path_whitespace_ssh) -add_clar_test(proxy -v -sonline::clone::proxy) -add_clar_test(auth_clone -v -sonline::clone::cred) -add_clar_test(auth_clone_and_push -v -sonline::clone::push -sonline::push) - -# -# Header file validation project: ensure that we do not publish any sloppy -# definitions in our headers and that a consumer can include -# even when they have aggressive C90 warnings enabled. -# - -add_executable(headertest headertest.c) -set_target_properties(headertest PROPERTIES C_STANDARD 90) -set_target_properties(headertest PROPERTIES C_EXTENSIONS OFF) -target_include_directories(headertest PRIVATE ${LIBGIT2_INCLUDES}) - -if (MSVC) - target_compile_options(headertest PUBLIC /W4 /WX) -else() - target_compile_options(headertest PUBLIC -Wall -Wextra -pedantic -Werror) -endif() +add_subdirectory(libgit2) diff --git a/tests/README.md b/tests/README.md index 4369a8f3381..68c2788baf2 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,33 +1,49 @@ -Writing Clar tests for libgit2 -============================== +# libgit2 tests -For information on the Clar testing framework and a detailed introduction -please visit: +These are the unit and integration tests for the libgit2 projects. -https://github.com/vmg/clar +* `libgit2` + These tests exercise the core git functionality in libgit2 itself. +* `resources` + These are the resources for the tests, including files and git + repositories. +## Writing tests for libgit2 -* Write your modules and tests. Use good, meaningful names. +libgit2 uses the [clar test framework](http://github.com/clar-test/clar), a +C testing framework. -* Make sure you actually build the tests by setting: +The best resources for learning clar are [clar itself](https://github.com/clar-test/clar) +and the existing tests within libgit2. In general: - cmake -DBUILD_TESTS=ON build/ +* If you place a `.c` file into a test directory, it is eligible to contain +test cases. +* The function name for your test is important; test function names begin + with `test_`, followed by the folder path (underscore separated), two + underscores as a delimiter, then the test name. For example, a file + `merge/analysis.c` may contain a test `uptodate`: -* Test: + ``` + void test_merge_analysis__uptodate(void) + { + ... + } + ``` - ./build/libgit2_tests +* You can run an individual test by passing `-s` to the test runner. Tests + are referred to by their function names; for example, the function + `test_merge_analysis__uptodate` is referred to as `merge::analysis::uptodate`. + To run only that function you can use the `-s` option on the test runner: -* Make sure everything is fine. + ``` + libgit2_tests -smerge::analysis::uptodate + ``` -* Send your pull request. That's it. - - -Memory leak checks ------------------- +## Memory leak checking These are automatically run as part of CI, but if you want to check locally: -#### Linux +### Linux Uses [`valgrind`](http://www.valgrind.org/): @@ -38,7 +54,7 @@ $ valgrind --leak-check=full --show-reachable=yes --num-callers=50 --suppression ./libgit2_tests ``` -#### macOS +### macOS Uses [`leaks`](https://developer.apple.com/library/archive/documentation/Performance/Conceptual/ManagingMemory/Articles/FindingLeaks.html), which requires XCode installed: @@ -46,3 +62,13 @@ Uses [`leaks`](https://developer.apple.com/library/archive/documentation/Perform $ MallocStackLogging=1 MallocScribble=1 MallocLogFile=/dev/null CLAR_AT_EXIT="leaks -quiet \$PPID" \ ./libgit2_tests ``` + +### Windows + +Build with the `WIN32_LEAKCHECK` option: + +```console +$ cmake -DBUILD_TESTS=ON -DWIN32_LEAKCHECK=ON .. +$ cmake --build . +$ ./libgit2_tests +``` diff --git a/tests/libgit2/CMakeLists.txt b/tests/libgit2/CMakeLists.txt new file mode 100644 index 00000000000..8bf199ecf1c --- /dev/null +++ b/tests/libgit2/CMakeLists.txt @@ -0,0 +1,98 @@ +# tests: the unit and integration tests for libgit2 + +set(Python_ADDITIONAL_VERSIONS 3 2.7) +find_package(PythonInterp) + +if(NOT PYTHONINTERP_FOUND) + message(FATAL_ERROR "Could not find a python interpreter, which is needed to build the tests. " + "Make sure python is available, or pass -DBUILD_TESTS=OFF to skip building the tests") +ENDIF() + +set(CLAR_FIXTURES "${PROJECT_SOURCE_DIR}/tests/resources/") +set(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}") +add_definitions(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\") +add_definitions(-DCLAR_TMPDIR=\"libgit2_tests\") +add_definitions(-DCLAR_WIN32_LONGPATHS) +add_definitions(-D_FILE_OFFSET_BITS=64) + +# Ensure that we do not use deprecated functions internally +add_definitions(-DGIT_DEPRECATE_HARD) + +set(TEST_INCLUDES "${CLAR_PATH}" "${CMAKE_CURRENT_BINARY_DIR}") +file(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h) +set(SRC_CLAR "main.c" "clar_libgit2.c" "clar_libgit2_trace.c" "clar_libgit2_timer.c" "clar.c") + +if(MSVC_IDE) + list(APPEND SRC_CLAR "precompiled.c") +endif() + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clar.suite ${CMAKE_CURRENT_BINARY_DIR}/clar_suite.h + COMMAND ${PYTHON_EXECUTABLE} generate.py -o "${CMAKE_CURRENT_BINARY_DIR}" -f -xonline -xstress -xperf . + DEPENDS ${SRC_TEST} + WORKING_DIRECTORY ${CLAR_PATH} +) + +set_source_files_properties( + ${CLAR_PATH}/clar.c + PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clar.suite) + +add_executable(libgit2_tests ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS}) + +set_target_properties(libgit2_tests PROPERTIES C_STANDARD 90) +set_target_properties(libgit2_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) + +target_include_directories(libgit2_tests PRIVATE ${TEST_INCLUDES} ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES}) +target_include_directories(libgit2_tests SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) +target_link_libraries(libgit2_tests ${LIBGIT2_SYSTEM_LIBS}) + +ide_split_sources(libgit2_tests) + +# +# Old versions of gcc require us to declare our test functions; don't do +# this on newer compilers to avoid unnecessary recompilation. +# +if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) + target_compile_options(libgit2_tests PRIVATE -include "clar_suite.h") +endif() + +if(MSVC_IDE) + # Precompiled headers + set_target_properties(libgit2_tests PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") + set_source_files_properties("precompiled.c" COMPILE_FLAGS "/Ycprecompiled.h") +endif() + +function(ADD_CLAR_TEST name) + if(NOT USE_LEAK_CHECKER STREQUAL "OFF") + add_test(${name} "${PROJECT_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${PROJECT_BINARY_DIR}/libgit2_tests" ${ARGN}) + else() + add_test(${name} "${PROJECT_BINARY_DIR}/libgit2_tests" ${ARGN}) + endif() +endfunction(ADD_CLAR_TEST) + +add_clar_test(offline -v -xonline) +add_clar_test(invasive -v -score::ftruncate -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root) +add_clar_test(online -v -sonline -xonline::customcert) +add_clar_test(online_customcert -v -sonline::customcert) +add_clar_test(gitdaemon -v -sonline::push) +add_clar_test(ssh -v -sonline::push -sonline::clone::ssh_cert -sonline::clone::ssh_with_paths -sonline::clone::path_whitespace_ssh) +add_clar_test(proxy -v -sonline::clone::proxy) +add_clar_test(auth_clone -v -sonline::clone::cred) +add_clar_test(auth_clone_and_push -v -sonline::clone::push -sonline::push) + +# +# Header file validation project: ensure that we do not publish any sloppy +# definitions in our headers and that a consumer can include +# even when they have aggressive C90 warnings enabled. +# + +add_executable(headertest headertest.c) +set_target_properties(headertest PROPERTIES C_STANDARD 90) +set_target_properties(headertest PROPERTIES C_EXTENSIONS OFF) +target_include_directories(headertest PRIVATE ${LIBGIT2_INCLUDES}) + +if (MSVC) + target_compile_options(headertest PUBLIC /W4 /WX) +else() + target_compile_options(headertest PUBLIC -Wall -Wextra -pedantic -Werror) +endif() diff --git a/tests/apply/apply_helpers.c b/tests/libgit2/apply/apply_helpers.c similarity index 100% rename from tests/apply/apply_helpers.c rename to tests/libgit2/apply/apply_helpers.c diff --git a/tests/apply/apply_helpers.h b/tests/libgit2/apply/apply_helpers.h similarity index 100% rename from tests/apply/apply_helpers.h rename to tests/libgit2/apply/apply_helpers.h diff --git a/tests/apply/both.c b/tests/libgit2/apply/both.c similarity index 100% rename from tests/apply/both.c rename to tests/libgit2/apply/both.c diff --git a/tests/apply/callbacks.c b/tests/libgit2/apply/callbacks.c similarity index 100% rename from tests/apply/callbacks.c rename to tests/libgit2/apply/callbacks.c diff --git a/tests/apply/check.c b/tests/libgit2/apply/check.c similarity index 100% rename from tests/apply/check.c rename to tests/libgit2/apply/check.c diff --git a/tests/apply/fromdiff.c b/tests/libgit2/apply/fromdiff.c similarity index 100% rename from tests/apply/fromdiff.c rename to tests/libgit2/apply/fromdiff.c diff --git a/tests/apply/fromfile.c b/tests/libgit2/apply/fromfile.c similarity index 100% rename from tests/apply/fromfile.c rename to tests/libgit2/apply/fromfile.c diff --git a/tests/apply/index.c b/tests/libgit2/apply/index.c similarity index 100% rename from tests/apply/index.c rename to tests/libgit2/apply/index.c diff --git a/tests/apply/partial.c b/tests/libgit2/apply/partial.c similarity index 100% rename from tests/apply/partial.c rename to tests/libgit2/apply/partial.c diff --git a/tests/apply/tree.c b/tests/libgit2/apply/tree.c similarity index 100% rename from tests/apply/tree.c rename to tests/libgit2/apply/tree.c diff --git a/tests/apply/workdir.c b/tests/libgit2/apply/workdir.c similarity index 100% rename from tests/apply/workdir.c rename to tests/libgit2/apply/workdir.c diff --git a/tests/attr/attr_expect.h b/tests/libgit2/attr/attr_expect.h similarity index 100% rename from tests/attr/attr_expect.h rename to tests/libgit2/attr/attr_expect.h diff --git a/tests/attr/file.c b/tests/libgit2/attr/file.c similarity index 100% rename from tests/attr/file.c rename to tests/libgit2/attr/file.c diff --git a/tests/attr/flags.c b/tests/libgit2/attr/flags.c similarity index 100% rename from tests/attr/flags.c rename to tests/libgit2/attr/flags.c diff --git a/tests/attr/lookup.c b/tests/libgit2/attr/lookup.c similarity index 100% rename from tests/attr/lookup.c rename to tests/libgit2/attr/lookup.c diff --git a/tests/attr/macro.c b/tests/libgit2/attr/macro.c similarity index 100% rename from tests/attr/macro.c rename to tests/libgit2/attr/macro.c diff --git a/tests/attr/repo.c b/tests/libgit2/attr/repo.c similarity index 100% rename from tests/attr/repo.c rename to tests/libgit2/attr/repo.c diff --git a/tests/blame/blame_helpers.c b/tests/libgit2/blame/blame_helpers.c similarity index 100% rename from tests/blame/blame_helpers.c rename to tests/libgit2/blame/blame_helpers.c diff --git a/tests/blame/blame_helpers.h b/tests/libgit2/blame/blame_helpers.h similarity index 100% rename from tests/blame/blame_helpers.h rename to tests/libgit2/blame/blame_helpers.h diff --git a/tests/blame/buffer.c b/tests/libgit2/blame/buffer.c similarity index 100% rename from tests/blame/buffer.c rename to tests/libgit2/blame/buffer.c diff --git a/tests/blame/getters.c b/tests/libgit2/blame/getters.c similarity index 100% rename from tests/blame/getters.c rename to tests/libgit2/blame/getters.c diff --git a/tests/blame/harder.c b/tests/libgit2/blame/harder.c similarity index 100% rename from tests/blame/harder.c rename to tests/libgit2/blame/harder.c diff --git a/tests/blame/simple.c b/tests/libgit2/blame/simple.c similarity index 100% rename from tests/blame/simple.c rename to tests/libgit2/blame/simple.c diff --git a/tests/checkout/binaryunicode.c b/tests/libgit2/checkout/binaryunicode.c similarity index 100% rename from tests/checkout/binaryunicode.c rename to tests/libgit2/checkout/binaryunicode.c diff --git a/tests/checkout/checkout_helpers.c b/tests/libgit2/checkout/checkout_helpers.c similarity index 100% rename from tests/checkout/checkout_helpers.c rename to tests/libgit2/checkout/checkout_helpers.c diff --git a/tests/checkout/checkout_helpers.h b/tests/libgit2/checkout/checkout_helpers.h similarity index 100% rename from tests/checkout/checkout_helpers.h rename to tests/libgit2/checkout/checkout_helpers.h diff --git a/tests/checkout/conflict.c b/tests/libgit2/checkout/conflict.c similarity index 100% rename from tests/checkout/conflict.c rename to tests/libgit2/checkout/conflict.c diff --git a/tests/checkout/crlf.c b/tests/libgit2/checkout/crlf.c similarity index 100% rename from tests/checkout/crlf.c rename to tests/libgit2/checkout/crlf.c diff --git a/tests/checkout/head.c b/tests/libgit2/checkout/head.c similarity index 100% rename from tests/checkout/head.c rename to tests/libgit2/checkout/head.c diff --git a/tests/checkout/icase.c b/tests/libgit2/checkout/icase.c similarity index 100% rename from tests/checkout/icase.c rename to tests/libgit2/checkout/icase.c diff --git a/tests/checkout/index.c b/tests/libgit2/checkout/index.c similarity index 100% rename from tests/checkout/index.c rename to tests/libgit2/checkout/index.c diff --git a/tests/checkout/nasty.c b/tests/libgit2/checkout/nasty.c similarity index 100% rename from tests/checkout/nasty.c rename to tests/libgit2/checkout/nasty.c diff --git a/tests/checkout/tree.c b/tests/libgit2/checkout/tree.c similarity index 100% rename from tests/checkout/tree.c rename to tests/libgit2/checkout/tree.c diff --git a/tests/checkout/typechange.c b/tests/libgit2/checkout/typechange.c similarity index 100% rename from tests/checkout/typechange.c rename to tests/libgit2/checkout/typechange.c diff --git a/tests/cherrypick/bare.c b/tests/libgit2/cherrypick/bare.c similarity index 100% rename from tests/cherrypick/bare.c rename to tests/libgit2/cherrypick/bare.c diff --git a/tests/cherrypick/workdir.c b/tests/libgit2/cherrypick/workdir.c similarity index 100% rename from tests/cherrypick/workdir.c rename to tests/libgit2/cherrypick/workdir.c diff --git a/tests/clar.c b/tests/libgit2/clar.c similarity index 100% rename from tests/clar.c rename to tests/libgit2/clar.c diff --git a/tests/clar.h b/tests/libgit2/clar.h similarity index 100% rename from tests/clar.h rename to tests/libgit2/clar.h diff --git a/tests/clar/fixtures.h b/tests/libgit2/clar/fixtures.h similarity index 100% rename from tests/clar/fixtures.h rename to tests/libgit2/clar/fixtures.h diff --git a/tests/clar/fs.h b/tests/libgit2/clar/fs.h similarity index 100% rename from tests/clar/fs.h rename to tests/libgit2/clar/fs.h diff --git a/tests/clar/print.h b/tests/libgit2/clar/print.h similarity index 100% rename from tests/clar/print.h rename to tests/libgit2/clar/print.h diff --git a/tests/clar/sandbox.h b/tests/libgit2/clar/sandbox.h similarity index 100% rename from tests/clar/sandbox.h rename to tests/libgit2/clar/sandbox.h diff --git a/tests/clar/summary.h b/tests/libgit2/clar/summary.h similarity index 100% rename from tests/clar/summary.h rename to tests/libgit2/clar/summary.h diff --git a/tests/clar_libgit2.c b/tests/libgit2/clar_libgit2.c similarity index 100% rename from tests/clar_libgit2.c rename to tests/libgit2/clar_libgit2.c diff --git a/tests/clar_libgit2.h b/tests/libgit2/clar_libgit2.h similarity index 100% rename from tests/clar_libgit2.h rename to tests/libgit2/clar_libgit2.h diff --git a/tests/clar_libgit2_timer.c b/tests/libgit2/clar_libgit2_timer.c similarity index 100% rename from tests/clar_libgit2_timer.c rename to tests/libgit2/clar_libgit2_timer.c diff --git a/tests/clar_libgit2_timer.h b/tests/libgit2/clar_libgit2_timer.h similarity index 100% rename from tests/clar_libgit2_timer.h rename to tests/libgit2/clar_libgit2_timer.h diff --git a/tests/clar_libgit2_trace.c b/tests/libgit2/clar_libgit2_trace.c similarity index 100% rename from tests/clar_libgit2_trace.c rename to tests/libgit2/clar_libgit2_trace.c diff --git a/tests/clar_libgit2_trace.h b/tests/libgit2/clar_libgit2_trace.h similarity index 100% rename from tests/clar_libgit2_trace.h rename to tests/libgit2/clar_libgit2_trace.h diff --git a/tests/clone/empty.c b/tests/libgit2/clone/empty.c similarity index 100% rename from tests/clone/empty.c rename to tests/libgit2/clone/empty.c diff --git a/tests/clone/local.c b/tests/libgit2/clone/local.c similarity index 100% rename from tests/clone/local.c rename to tests/libgit2/clone/local.c diff --git a/tests/clone/nonetwork.c b/tests/libgit2/clone/nonetwork.c similarity index 100% rename from tests/clone/nonetwork.c rename to tests/libgit2/clone/nonetwork.c diff --git a/tests/clone/transport.c b/tests/libgit2/clone/transport.c similarity index 100% rename from tests/clone/transport.c rename to tests/libgit2/clone/transport.c diff --git a/tests/commit/commit.c b/tests/libgit2/commit/commit.c similarity index 100% rename from tests/commit/commit.c rename to tests/libgit2/commit/commit.c diff --git a/tests/commit/parent.c b/tests/libgit2/commit/parent.c similarity index 100% rename from tests/commit/parent.c rename to tests/libgit2/commit/parent.c diff --git a/tests/commit/parse.c b/tests/libgit2/commit/parse.c similarity index 100% rename from tests/commit/parse.c rename to tests/libgit2/commit/parse.c diff --git a/tests/commit/signature.c b/tests/libgit2/commit/signature.c similarity index 100% rename from tests/commit/signature.c rename to tests/libgit2/commit/signature.c diff --git a/tests/commit/write.c b/tests/libgit2/commit/write.c similarity index 100% rename from tests/commit/write.c rename to tests/libgit2/commit/write.c diff --git a/tests/config/add.c b/tests/libgit2/config/add.c similarity index 100% rename from tests/config/add.c rename to tests/libgit2/config/add.c diff --git a/tests/config/backend.c b/tests/libgit2/config/backend.c similarity index 100% rename from tests/config/backend.c rename to tests/libgit2/config/backend.c diff --git a/tests/config/conditionals.c b/tests/libgit2/config/conditionals.c similarity index 100% rename from tests/config/conditionals.c rename to tests/libgit2/config/conditionals.c diff --git a/tests/config/config_helpers.c b/tests/libgit2/config/config_helpers.c similarity index 100% rename from tests/config/config_helpers.c rename to tests/libgit2/config/config_helpers.c diff --git a/tests/config/config_helpers.h b/tests/libgit2/config/config_helpers.h similarity index 100% rename from tests/config/config_helpers.h rename to tests/libgit2/config/config_helpers.h diff --git a/tests/config/configlevel.c b/tests/libgit2/config/configlevel.c similarity index 100% rename from tests/config/configlevel.c rename to tests/libgit2/config/configlevel.c diff --git a/tests/config/global.c b/tests/libgit2/config/global.c similarity index 100% rename from tests/config/global.c rename to tests/libgit2/config/global.c diff --git a/tests/config/include.c b/tests/libgit2/config/include.c similarity index 100% rename from tests/config/include.c rename to tests/libgit2/config/include.c diff --git a/tests/config/memory.c b/tests/libgit2/config/memory.c similarity index 100% rename from tests/config/memory.c rename to tests/libgit2/config/memory.c diff --git a/tests/config/multivar.c b/tests/libgit2/config/multivar.c similarity index 100% rename from tests/config/multivar.c rename to tests/libgit2/config/multivar.c diff --git a/tests/config/new.c b/tests/libgit2/config/new.c similarity index 100% rename from tests/config/new.c rename to tests/libgit2/config/new.c diff --git a/tests/config/read.c b/tests/libgit2/config/read.c similarity index 100% rename from tests/config/read.c rename to tests/libgit2/config/read.c diff --git a/tests/config/readonly.c b/tests/libgit2/config/readonly.c similarity index 100% rename from tests/config/readonly.c rename to tests/libgit2/config/readonly.c diff --git a/tests/config/rename.c b/tests/libgit2/config/rename.c similarity index 100% rename from tests/config/rename.c rename to tests/libgit2/config/rename.c diff --git a/tests/config/snapshot.c b/tests/libgit2/config/snapshot.c similarity index 100% rename from tests/config/snapshot.c rename to tests/libgit2/config/snapshot.c diff --git a/tests/config/stress.c b/tests/libgit2/config/stress.c similarity index 100% rename from tests/config/stress.c rename to tests/libgit2/config/stress.c diff --git a/tests/config/validkeyname.c b/tests/libgit2/config/validkeyname.c similarity index 100% rename from tests/config/validkeyname.c rename to tests/libgit2/config/validkeyname.c diff --git a/tests/config/write.c b/tests/libgit2/config/write.c similarity index 100% rename from tests/config/write.c rename to tests/libgit2/config/write.c diff --git a/tests/core/array.c b/tests/libgit2/core/array.c similarity index 100% rename from tests/core/array.c rename to tests/libgit2/core/array.c diff --git a/tests/core/assert.c b/tests/libgit2/core/assert.c similarity index 100% rename from tests/core/assert.c rename to tests/libgit2/core/assert.c diff --git a/tests/core/bitvec.c b/tests/libgit2/core/bitvec.c similarity index 100% rename from tests/core/bitvec.c rename to tests/libgit2/core/bitvec.c diff --git a/tests/core/buf.c b/tests/libgit2/core/buf.c similarity index 100% rename from tests/core/buf.c rename to tests/libgit2/core/buf.c diff --git a/tests/core/copy.c b/tests/libgit2/core/copy.c similarity index 100% rename from tests/core/copy.c rename to tests/libgit2/core/copy.c diff --git a/tests/core/dirent.c b/tests/libgit2/core/dirent.c similarity index 100% rename from tests/core/dirent.c rename to tests/libgit2/core/dirent.c diff --git a/tests/core/encoding.c b/tests/libgit2/core/encoding.c similarity index 100% rename from tests/core/encoding.c rename to tests/libgit2/core/encoding.c diff --git a/tests/core/env.c b/tests/libgit2/core/env.c similarity index 100% rename from tests/core/env.c rename to tests/libgit2/core/env.c diff --git a/tests/core/errors.c b/tests/libgit2/core/errors.c similarity index 100% rename from tests/core/errors.c rename to tests/libgit2/core/errors.c diff --git a/tests/core/features.c b/tests/libgit2/core/features.c similarity index 100% rename from tests/core/features.c rename to tests/libgit2/core/features.c diff --git a/tests/core/filebuf.c b/tests/libgit2/core/filebuf.c similarity index 100% rename from tests/core/filebuf.c rename to tests/libgit2/core/filebuf.c diff --git a/tests/core/ftruncate.c b/tests/libgit2/core/ftruncate.c similarity index 100% rename from tests/core/ftruncate.c rename to tests/libgit2/core/ftruncate.c diff --git a/tests/core/futils.c b/tests/libgit2/core/futils.c similarity index 100% rename from tests/core/futils.c rename to tests/libgit2/core/futils.c diff --git a/tests/core/gitstr.c b/tests/libgit2/core/gitstr.c similarity index 100% rename from tests/core/gitstr.c rename to tests/libgit2/core/gitstr.c diff --git a/tests/core/hex.c b/tests/libgit2/core/hex.c similarity index 100% rename from tests/core/hex.c rename to tests/libgit2/core/hex.c diff --git a/tests/core/iconv.c b/tests/libgit2/core/iconv.c similarity index 100% rename from tests/core/iconv.c rename to tests/libgit2/core/iconv.c diff --git a/tests/core/init.c b/tests/libgit2/core/init.c similarity index 100% rename from tests/core/init.c rename to tests/libgit2/core/init.c diff --git a/tests/core/integer.c b/tests/libgit2/core/integer.c similarity index 100% rename from tests/core/integer.c rename to tests/libgit2/core/integer.c diff --git a/tests/core/link.c b/tests/libgit2/core/link.c similarity index 100% rename from tests/core/link.c rename to tests/libgit2/core/link.c diff --git a/tests/core/memmem.c b/tests/libgit2/core/memmem.c similarity index 100% rename from tests/core/memmem.c rename to tests/libgit2/core/memmem.c diff --git a/tests/core/mkdir.c b/tests/libgit2/core/mkdir.c similarity index 100% rename from tests/core/mkdir.c rename to tests/libgit2/core/mkdir.c diff --git a/tests/core/oid.c b/tests/libgit2/core/oid.c similarity index 100% rename from tests/core/oid.c rename to tests/libgit2/core/oid.c diff --git a/tests/core/oidmap.c b/tests/libgit2/core/oidmap.c similarity index 100% rename from tests/core/oidmap.c rename to tests/libgit2/core/oidmap.c diff --git a/tests/core/opts.c b/tests/libgit2/core/opts.c similarity index 100% rename from tests/core/opts.c rename to tests/libgit2/core/opts.c diff --git a/tests/core/path.c b/tests/libgit2/core/path.c similarity index 100% rename from tests/core/path.c rename to tests/libgit2/core/path.c diff --git a/tests/core/pool.c b/tests/libgit2/core/pool.c similarity index 100% rename from tests/core/pool.c rename to tests/libgit2/core/pool.c diff --git a/tests/core/posix.c b/tests/libgit2/core/posix.c similarity index 100% rename from tests/core/posix.c rename to tests/libgit2/core/posix.c diff --git a/tests/core/pqueue.c b/tests/libgit2/core/pqueue.c similarity index 100% rename from tests/core/pqueue.c rename to tests/libgit2/core/pqueue.c diff --git a/tests/core/qsort.c b/tests/libgit2/core/qsort.c similarity index 100% rename from tests/core/qsort.c rename to tests/libgit2/core/qsort.c diff --git a/tests/core/regexp.c b/tests/libgit2/core/regexp.c similarity index 100% rename from tests/core/regexp.c rename to tests/libgit2/core/regexp.c diff --git a/tests/core/rmdir.c b/tests/libgit2/core/rmdir.c similarity index 100% rename from tests/core/rmdir.c rename to tests/libgit2/core/rmdir.c diff --git a/tests/core/sha1.c b/tests/libgit2/core/sha1.c similarity index 100% rename from tests/core/sha1.c rename to tests/libgit2/core/sha1.c diff --git a/tests/core/sortedcache.c b/tests/libgit2/core/sortedcache.c similarity index 100% rename from tests/core/sortedcache.c rename to tests/libgit2/core/sortedcache.c diff --git a/tests/core/stat.c b/tests/libgit2/core/stat.c similarity index 100% rename from tests/core/stat.c rename to tests/libgit2/core/stat.c diff --git a/tests/core/string.c b/tests/libgit2/core/string.c similarity index 100% rename from tests/core/string.c rename to tests/libgit2/core/string.c diff --git a/tests/core/strmap.c b/tests/libgit2/core/strmap.c similarity index 100% rename from tests/core/strmap.c rename to tests/libgit2/core/strmap.c diff --git a/tests/core/strtol.c b/tests/libgit2/core/strtol.c similarity index 100% rename from tests/core/strtol.c rename to tests/libgit2/core/strtol.c diff --git a/tests/core/structinit.c b/tests/libgit2/core/structinit.c similarity index 100% rename from tests/core/structinit.c rename to tests/libgit2/core/structinit.c diff --git a/tests/core/useragent.c b/tests/libgit2/core/useragent.c similarity index 100% rename from tests/core/useragent.c rename to tests/libgit2/core/useragent.c diff --git a/tests/core/utf8.c b/tests/libgit2/core/utf8.c similarity index 100% rename from tests/core/utf8.c rename to tests/libgit2/core/utf8.c diff --git a/tests/core/vector.c b/tests/libgit2/core/vector.c similarity index 100% rename from tests/core/vector.c rename to tests/libgit2/core/vector.c diff --git a/tests/core/wildmatch.c b/tests/libgit2/core/wildmatch.c similarity index 100% rename from tests/core/wildmatch.c rename to tests/libgit2/core/wildmatch.c diff --git a/tests/core/zstream.c b/tests/libgit2/core/zstream.c similarity index 100% rename from tests/core/zstream.c rename to tests/libgit2/core/zstream.c diff --git a/tests/date/date.c b/tests/libgit2/date/date.c similarity index 100% rename from tests/date/date.c rename to tests/libgit2/date/date.c diff --git a/tests/date/rfc2822.c b/tests/libgit2/date/rfc2822.c similarity index 100% rename from tests/date/rfc2822.c rename to tests/libgit2/date/rfc2822.c diff --git a/tests/delta/apply.c b/tests/libgit2/delta/apply.c similarity index 100% rename from tests/delta/apply.c rename to tests/libgit2/delta/apply.c diff --git a/tests/describe/describe.c b/tests/libgit2/describe/describe.c similarity index 100% rename from tests/describe/describe.c rename to tests/libgit2/describe/describe.c diff --git a/tests/describe/describe_helpers.c b/tests/libgit2/describe/describe_helpers.c similarity index 100% rename from tests/describe/describe_helpers.c rename to tests/libgit2/describe/describe_helpers.c diff --git a/tests/describe/describe_helpers.h b/tests/libgit2/describe/describe_helpers.h similarity index 100% rename from tests/describe/describe_helpers.h rename to tests/libgit2/describe/describe_helpers.h diff --git a/tests/describe/t6120.c b/tests/libgit2/describe/t6120.c similarity index 100% rename from tests/describe/t6120.c rename to tests/libgit2/describe/t6120.c diff --git a/tests/diff/binary.c b/tests/libgit2/diff/binary.c similarity index 100% rename from tests/diff/binary.c rename to tests/libgit2/diff/binary.c diff --git a/tests/diff/blob.c b/tests/libgit2/diff/blob.c similarity index 100% rename from tests/diff/blob.c rename to tests/libgit2/diff/blob.c diff --git a/tests/diff/diff_helpers.c b/tests/libgit2/diff/diff_helpers.c similarity index 100% rename from tests/diff/diff_helpers.c rename to tests/libgit2/diff/diff_helpers.c diff --git a/tests/diff/diff_helpers.h b/tests/libgit2/diff/diff_helpers.h similarity index 100% rename from tests/diff/diff_helpers.h rename to tests/libgit2/diff/diff_helpers.h diff --git a/tests/diff/diffiter.c b/tests/libgit2/diff/diffiter.c similarity index 100% rename from tests/diff/diffiter.c rename to tests/libgit2/diff/diffiter.c diff --git a/tests/diff/drivers.c b/tests/libgit2/diff/drivers.c similarity index 100% rename from tests/diff/drivers.c rename to tests/libgit2/diff/drivers.c diff --git a/tests/diff/externalmodifications.c b/tests/libgit2/diff/externalmodifications.c similarity index 100% rename from tests/diff/externalmodifications.c rename to tests/libgit2/diff/externalmodifications.c diff --git a/tests/diff/format_email.c b/tests/libgit2/diff/format_email.c similarity index 100% rename from tests/diff/format_email.c rename to tests/libgit2/diff/format_email.c diff --git a/tests/diff/index.c b/tests/libgit2/diff/index.c similarity index 100% rename from tests/diff/index.c rename to tests/libgit2/diff/index.c diff --git a/tests/diff/notify.c b/tests/libgit2/diff/notify.c similarity index 100% rename from tests/diff/notify.c rename to tests/libgit2/diff/notify.c diff --git a/tests/diff/parse.c b/tests/libgit2/diff/parse.c similarity index 100% rename from tests/diff/parse.c rename to tests/libgit2/diff/parse.c diff --git a/tests/diff/patch.c b/tests/libgit2/diff/patch.c similarity index 100% rename from tests/diff/patch.c rename to tests/libgit2/diff/patch.c diff --git a/tests/diff/patchid.c b/tests/libgit2/diff/patchid.c similarity index 100% rename from tests/diff/patchid.c rename to tests/libgit2/diff/patchid.c diff --git a/tests/diff/pathspec.c b/tests/libgit2/diff/pathspec.c similarity index 100% rename from tests/diff/pathspec.c rename to tests/libgit2/diff/pathspec.c diff --git a/tests/diff/racediffiter.c b/tests/libgit2/diff/racediffiter.c similarity index 100% rename from tests/diff/racediffiter.c rename to tests/libgit2/diff/racediffiter.c diff --git a/tests/diff/rename.c b/tests/libgit2/diff/rename.c similarity index 100% rename from tests/diff/rename.c rename to tests/libgit2/diff/rename.c diff --git a/tests/diff/stats.c b/tests/libgit2/diff/stats.c similarity index 100% rename from tests/diff/stats.c rename to tests/libgit2/diff/stats.c diff --git a/tests/diff/submodules.c b/tests/libgit2/diff/submodules.c similarity index 100% rename from tests/diff/submodules.c rename to tests/libgit2/diff/submodules.c diff --git a/tests/diff/tree.c b/tests/libgit2/diff/tree.c similarity index 100% rename from tests/diff/tree.c rename to tests/libgit2/diff/tree.c diff --git a/tests/diff/workdir.c b/tests/libgit2/diff/workdir.c similarity index 100% rename from tests/diff/workdir.c rename to tests/libgit2/diff/workdir.c diff --git a/tests/email/create.c b/tests/libgit2/email/create.c similarity index 100% rename from tests/email/create.c rename to tests/libgit2/email/create.c diff --git a/tests/email/create.c.bak b/tests/libgit2/email/create.c.bak similarity index 100% rename from tests/email/create.c.bak rename to tests/libgit2/email/create.c.bak diff --git a/tests/fetch/local.c b/tests/libgit2/fetch/local.c similarity index 100% rename from tests/fetch/local.c rename to tests/libgit2/fetch/local.c diff --git a/tests/fetchhead/fetchhead_data.h b/tests/libgit2/fetchhead/fetchhead_data.h similarity index 100% rename from tests/fetchhead/fetchhead_data.h rename to tests/libgit2/fetchhead/fetchhead_data.h diff --git a/tests/fetchhead/nonetwork.c b/tests/libgit2/fetchhead/nonetwork.c similarity index 100% rename from tests/fetchhead/nonetwork.c rename to tests/libgit2/fetchhead/nonetwork.c diff --git a/tests/filter/bare.c b/tests/libgit2/filter/bare.c similarity index 100% rename from tests/filter/bare.c rename to tests/libgit2/filter/bare.c diff --git a/tests/filter/blob.c b/tests/libgit2/filter/blob.c similarity index 100% rename from tests/filter/blob.c rename to tests/libgit2/filter/blob.c diff --git a/tests/filter/crlf.c b/tests/libgit2/filter/crlf.c similarity index 100% rename from tests/filter/crlf.c rename to tests/libgit2/filter/crlf.c diff --git a/tests/filter/crlf.h b/tests/libgit2/filter/crlf.h similarity index 100% rename from tests/filter/crlf.h rename to tests/libgit2/filter/crlf.h diff --git a/tests/filter/custom.c b/tests/libgit2/filter/custom.c similarity index 100% rename from tests/filter/custom.c rename to tests/libgit2/filter/custom.c diff --git a/tests/filter/custom_helpers.c b/tests/libgit2/filter/custom_helpers.c similarity index 100% rename from tests/filter/custom_helpers.c rename to tests/libgit2/filter/custom_helpers.c diff --git a/tests/filter/custom_helpers.h b/tests/libgit2/filter/custom_helpers.h similarity index 100% rename from tests/filter/custom_helpers.h rename to tests/libgit2/filter/custom_helpers.h diff --git a/tests/filter/file.c b/tests/libgit2/filter/file.c similarity index 100% rename from tests/filter/file.c rename to tests/libgit2/filter/file.c diff --git a/tests/filter/ident.c b/tests/libgit2/filter/ident.c similarity index 100% rename from tests/filter/ident.c rename to tests/libgit2/filter/ident.c diff --git a/tests/filter/query.c b/tests/libgit2/filter/query.c similarity index 100% rename from tests/filter/query.c rename to tests/libgit2/filter/query.c diff --git a/tests/filter/stream.c b/tests/libgit2/filter/stream.c similarity index 100% rename from tests/filter/stream.c rename to tests/libgit2/filter/stream.c diff --git a/tests/filter/systemattrs.c b/tests/libgit2/filter/systemattrs.c similarity index 100% rename from tests/filter/systemattrs.c rename to tests/libgit2/filter/systemattrs.c diff --git a/tests/filter/wildcard.c b/tests/libgit2/filter/wildcard.c similarity index 100% rename from tests/filter/wildcard.c rename to tests/libgit2/filter/wildcard.c diff --git a/tests/generate.py b/tests/libgit2/generate.py similarity index 100% rename from tests/generate.py rename to tests/libgit2/generate.py diff --git a/tests/graph/ahead_behind.c b/tests/libgit2/graph/ahead_behind.c similarity index 100% rename from tests/graph/ahead_behind.c rename to tests/libgit2/graph/ahead_behind.c diff --git a/tests/graph/commitgraph.c b/tests/libgit2/graph/commitgraph.c similarity index 100% rename from tests/graph/commitgraph.c rename to tests/libgit2/graph/commitgraph.c diff --git a/tests/graph/descendant_of.c b/tests/libgit2/graph/descendant_of.c similarity index 100% rename from tests/graph/descendant_of.c rename to tests/libgit2/graph/descendant_of.c diff --git a/tests/graph/reachable_from_any.c b/tests/libgit2/graph/reachable_from_any.c similarity index 100% rename from tests/graph/reachable_from_any.c rename to tests/libgit2/graph/reachable_from_any.c diff --git a/tests/headertest.c b/tests/libgit2/headertest.c similarity index 100% rename from tests/headertest.c rename to tests/libgit2/headertest.c diff --git a/tests/ignore/path.c b/tests/libgit2/ignore/path.c similarity index 100% rename from tests/ignore/path.c rename to tests/libgit2/ignore/path.c diff --git a/tests/ignore/status.c b/tests/libgit2/ignore/status.c similarity index 100% rename from tests/ignore/status.c rename to tests/libgit2/ignore/status.c diff --git a/tests/index/add.c b/tests/libgit2/index/add.c similarity index 100% rename from tests/index/add.c rename to tests/libgit2/index/add.c diff --git a/tests/index/addall.c b/tests/libgit2/index/addall.c similarity index 100% rename from tests/index/addall.c rename to tests/libgit2/index/addall.c diff --git a/tests/index/bypath.c b/tests/libgit2/index/bypath.c similarity index 100% rename from tests/index/bypath.c rename to tests/libgit2/index/bypath.c diff --git a/tests/index/cache.c b/tests/libgit2/index/cache.c similarity index 100% rename from tests/index/cache.c rename to tests/libgit2/index/cache.c diff --git a/tests/index/collision.c b/tests/libgit2/index/collision.c similarity index 100% rename from tests/index/collision.c rename to tests/libgit2/index/collision.c diff --git a/tests/index/conflicts.c b/tests/libgit2/index/conflicts.c similarity index 100% rename from tests/index/conflicts.c rename to tests/libgit2/index/conflicts.c diff --git a/tests/index/conflicts.h b/tests/libgit2/index/conflicts.h similarity index 100% rename from tests/index/conflicts.h rename to tests/libgit2/index/conflicts.h diff --git a/tests/index/crlf.c b/tests/libgit2/index/crlf.c similarity index 100% rename from tests/index/crlf.c rename to tests/libgit2/index/crlf.c diff --git a/tests/index/filemodes.c b/tests/libgit2/index/filemodes.c similarity index 100% rename from tests/index/filemodes.c rename to tests/libgit2/index/filemodes.c diff --git a/tests/index/inmemory.c b/tests/libgit2/index/inmemory.c similarity index 100% rename from tests/index/inmemory.c rename to tests/libgit2/index/inmemory.c diff --git a/tests/index/names.c b/tests/libgit2/index/names.c similarity index 100% rename from tests/index/names.c rename to tests/libgit2/index/names.c diff --git a/tests/index/nsec.c b/tests/libgit2/index/nsec.c similarity index 100% rename from tests/index/nsec.c rename to tests/libgit2/index/nsec.c diff --git a/tests/index/racy.c b/tests/libgit2/index/racy.c similarity index 100% rename from tests/index/racy.c rename to tests/libgit2/index/racy.c diff --git a/tests/index/read_index.c b/tests/libgit2/index/read_index.c similarity index 100% rename from tests/index/read_index.c rename to tests/libgit2/index/read_index.c diff --git a/tests/index/read_tree.c b/tests/libgit2/index/read_tree.c similarity index 100% rename from tests/index/read_tree.c rename to tests/libgit2/index/read_tree.c diff --git a/tests/index/rename.c b/tests/libgit2/index/rename.c similarity index 100% rename from tests/index/rename.c rename to tests/libgit2/index/rename.c diff --git a/tests/index/reuc.c b/tests/libgit2/index/reuc.c similarity index 100% rename from tests/index/reuc.c rename to tests/libgit2/index/reuc.c diff --git a/tests/index/splitindex.c b/tests/libgit2/index/splitindex.c similarity index 100% rename from tests/index/splitindex.c rename to tests/libgit2/index/splitindex.c diff --git a/tests/index/stage.c b/tests/libgit2/index/stage.c similarity index 100% rename from tests/index/stage.c rename to tests/libgit2/index/stage.c diff --git a/tests/index/tests.c b/tests/libgit2/index/tests.c similarity index 100% rename from tests/index/tests.c rename to tests/libgit2/index/tests.c diff --git a/tests/index/version.c b/tests/libgit2/index/version.c similarity index 100% rename from tests/index/version.c rename to tests/libgit2/index/version.c diff --git a/tests/iterator/index.c b/tests/libgit2/iterator/index.c similarity index 100% rename from tests/iterator/index.c rename to tests/libgit2/iterator/index.c diff --git a/tests/iterator/iterator_helpers.c b/tests/libgit2/iterator/iterator_helpers.c similarity index 100% rename from tests/iterator/iterator_helpers.c rename to tests/libgit2/iterator/iterator_helpers.c diff --git a/tests/iterator/iterator_helpers.h b/tests/libgit2/iterator/iterator_helpers.h similarity index 100% rename from tests/iterator/iterator_helpers.h rename to tests/libgit2/iterator/iterator_helpers.h diff --git a/tests/iterator/tree.c b/tests/libgit2/iterator/tree.c similarity index 100% rename from tests/iterator/tree.c rename to tests/libgit2/iterator/tree.c diff --git a/tests/iterator/workdir.c b/tests/libgit2/iterator/workdir.c similarity index 100% rename from tests/iterator/workdir.c rename to tests/libgit2/iterator/workdir.c diff --git a/tests/mailmap/basic.c b/tests/libgit2/mailmap/basic.c similarity index 100% rename from tests/mailmap/basic.c rename to tests/libgit2/mailmap/basic.c diff --git a/tests/mailmap/blame.c b/tests/libgit2/mailmap/blame.c similarity index 100% rename from tests/mailmap/blame.c rename to tests/libgit2/mailmap/blame.c diff --git a/tests/mailmap/mailmap_testdata.h b/tests/libgit2/mailmap/mailmap_testdata.h similarity index 100% rename from tests/mailmap/mailmap_testdata.h rename to tests/libgit2/mailmap/mailmap_testdata.h diff --git a/tests/mailmap/parsing.c b/tests/libgit2/mailmap/parsing.c similarity index 100% rename from tests/mailmap/parsing.c rename to tests/libgit2/mailmap/parsing.c diff --git a/tests/main.c b/tests/libgit2/main.c similarity index 100% rename from tests/main.c rename to tests/libgit2/main.c diff --git a/tests/merge/analysis.c b/tests/libgit2/merge/analysis.c similarity index 100% rename from tests/merge/analysis.c rename to tests/libgit2/merge/analysis.c diff --git a/tests/merge/annotated_commit.c b/tests/libgit2/merge/annotated_commit.c similarity index 100% rename from tests/merge/annotated_commit.c rename to tests/libgit2/merge/annotated_commit.c diff --git a/tests/merge/conflict_data.h b/tests/libgit2/merge/conflict_data.h similarity index 100% rename from tests/merge/conflict_data.h rename to tests/libgit2/merge/conflict_data.h diff --git a/tests/merge/driver.c b/tests/libgit2/merge/driver.c similarity index 100% rename from tests/merge/driver.c rename to tests/libgit2/merge/driver.c diff --git a/tests/merge/files.c b/tests/libgit2/merge/files.c similarity index 100% rename from tests/merge/files.c rename to tests/libgit2/merge/files.c diff --git a/tests/merge/merge_helpers.c b/tests/libgit2/merge/merge_helpers.c similarity index 100% rename from tests/merge/merge_helpers.c rename to tests/libgit2/merge/merge_helpers.c diff --git a/tests/merge/merge_helpers.h b/tests/libgit2/merge/merge_helpers.h similarity index 100% rename from tests/merge/merge_helpers.h rename to tests/libgit2/merge/merge_helpers.h diff --git a/tests/merge/trees/automerge.c b/tests/libgit2/merge/trees/automerge.c similarity index 100% rename from tests/merge/trees/automerge.c rename to tests/libgit2/merge/trees/automerge.c diff --git a/tests/merge/trees/commits.c b/tests/libgit2/merge/trees/commits.c similarity index 100% rename from tests/merge/trees/commits.c rename to tests/libgit2/merge/trees/commits.c diff --git a/tests/merge/trees/modeconflict.c b/tests/libgit2/merge/trees/modeconflict.c similarity index 100% rename from tests/merge/trees/modeconflict.c rename to tests/libgit2/merge/trees/modeconflict.c diff --git a/tests/merge/trees/recursive.c b/tests/libgit2/merge/trees/recursive.c similarity index 100% rename from tests/merge/trees/recursive.c rename to tests/libgit2/merge/trees/recursive.c diff --git a/tests/merge/trees/renames.c b/tests/libgit2/merge/trees/renames.c similarity index 100% rename from tests/merge/trees/renames.c rename to tests/libgit2/merge/trees/renames.c diff --git a/tests/merge/trees/treediff.c b/tests/libgit2/merge/trees/treediff.c similarity index 100% rename from tests/merge/trees/treediff.c rename to tests/libgit2/merge/trees/treediff.c diff --git a/tests/merge/trees/trivial.c b/tests/libgit2/merge/trees/trivial.c similarity index 100% rename from tests/merge/trees/trivial.c rename to tests/libgit2/merge/trees/trivial.c diff --git a/tests/merge/trees/whitespace.c b/tests/libgit2/merge/trees/whitespace.c similarity index 100% rename from tests/merge/trees/whitespace.c rename to tests/libgit2/merge/trees/whitespace.c diff --git a/tests/merge/workdir/dirty.c b/tests/libgit2/merge/workdir/dirty.c similarity index 100% rename from tests/merge/workdir/dirty.c rename to tests/libgit2/merge/workdir/dirty.c diff --git a/tests/merge/workdir/recursive.c b/tests/libgit2/merge/workdir/recursive.c similarity index 100% rename from tests/merge/workdir/recursive.c rename to tests/libgit2/merge/workdir/recursive.c diff --git a/tests/merge/workdir/renames.c b/tests/libgit2/merge/workdir/renames.c similarity index 100% rename from tests/merge/workdir/renames.c rename to tests/libgit2/merge/workdir/renames.c diff --git a/tests/merge/workdir/setup.c b/tests/libgit2/merge/workdir/setup.c similarity index 100% rename from tests/merge/workdir/setup.c rename to tests/libgit2/merge/workdir/setup.c diff --git a/tests/merge/workdir/simple.c b/tests/libgit2/merge/workdir/simple.c similarity index 100% rename from tests/merge/workdir/simple.c rename to tests/libgit2/merge/workdir/simple.c diff --git a/tests/merge/workdir/submodules.c b/tests/libgit2/merge/workdir/submodules.c similarity index 100% rename from tests/merge/workdir/submodules.c rename to tests/libgit2/merge/workdir/submodules.c diff --git a/tests/merge/workdir/trivial.c b/tests/libgit2/merge/workdir/trivial.c similarity index 100% rename from tests/merge/workdir/trivial.c rename to tests/libgit2/merge/workdir/trivial.c diff --git a/tests/message/trailer.c b/tests/libgit2/message/trailer.c similarity index 100% rename from tests/message/trailer.c rename to tests/libgit2/message/trailer.c diff --git a/tests/network/cred.c b/tests/libgit2/network/cred.c similarity index 100% rename from tests/network/cred.c rename to tests/libgit2/network/cred.c diff --git a/tests/network/fetchlocal.c b/tests/libgit2/network/fetchlocal.c similarity index 100% rename from tests/network/fetchlocal.c rename to tests/libgit2/network/fetchlocal.c diff --git a/tests/network/matchhost.c b/tests/libgit2/network/matchhost.c similarity index 100% rename from tests/network/matchhost.c rename to tests/libgit2/network/matchhost.c diff --git a/tests/network/refspecs.c b/tests/libgit2/network/refspecs.c similarity index 100% rename from tests/network/refspecs.c rename to tests/libgit2/network/refspecs.c diff --git a/tests/network/remote/defaultbranch.c b/tests/libgit2/network/remote/defaultbranch.c similarity index 100% rename from tests/network/remote/defaultbranch.c rename to tests/libgit2/network/remote/defaultbranch.c diff --git a/tests/network/remote/delete.c b/tests/libgit2/network/remote/delete.c similarity index 100% rename from tests/network/remote/delete.c rename to tests/libgit2/network/remote/delete.c diff --git a/tests/network/remote/isvalidname.c b/tests/libgit2/network/remote/isvalidname.c similarity index 100% rename from tests/network/remote/isvalidname.c rename to tests/libgit2/network/remote/isvalidname.c diff --git a/tests/network/remote/local.c b/tests/libgit2/network/remote/local.c similarity index 100% rename from tests/network/remote/local.c rename to tests/libgit2/network/remote/local.c diff --git a/tests/network/remote/push.c b/tests/libgit2/network/remote/push.c similarity index 100% rename from tests/network/remote/push.c rename to tests/libgit2/network/remote/push.c diff --git a/tests/network/remote/remotes.c b/tests/libgit2/network/remote/remotes.c similarity index 100% rename from tests/network/remote/remotes.c rename to tests/libgit2/network/remote/remotes.c diff --git a/tests/network/remote/rename.c b/tests/libgit2/network/remote/rename.c similarity index 100% rename from tests/network/remote/rename.c rename to tests/libgit2/network/remote/rename.c diff --git a/tests/network/url/joinpath.c b/tests/libgit2/network/url/joinpath.c similarity index 100% rename from tests/network/url/joinpath.c rename to tests/libgit2/network/url/joinpath.c diff --git a/tests/network/url/parse.c b/tests/libgit2/network/url/parse.c similarity index 100% rename from tests/network/url/parse.c rename to tests/libgit2/network/url/parse.c diff --git a/tests/network/url/pattern.c b/tests/libgit2/network/url/pattern.c similarity index 100% rename from tests/network/url/pattern.c rename to tests/libgit2/network/url/pattern.c diff --git a/tests/network/url/redirect.c b/tests/libgit2/network/url/redirect.c similarity index 100% rename from tests/network/url/redirect.c rename to tests/libgit2/network/url/redirect.c diff --git a/tests/network/url/scp.c b/tests/libgit2/network/url/scp.c similarity index 100% rename from tests/network/url/scp.c rename to tests/libgit2/network/url/scp.c diff --git a/tests/network/url/valid.c b/tests/libgit2/network/url/valid.c similarity index 100% rename from tests/network/url/valid.c rename to tests/libgit2/network/url/valid.c diff --git a/tests/notes/notes.c b/tests/libgit2/notes/notes.c similarity index 100% rename from tests/notes/notes.c rename to tests/libgit2/notes/notes.c diff --git a/tests/notes/notesref.c b/tests/libgit2/notes/notesref.c similarity index 100% rename from tests/notes/notesref.c rename to tests/libgit2/notes/notesref.c diff --git a/tests/object/blob/filter.c b/tests/libgit2/object/blob/filter.c similarity index 100% rename from tests/object/blob/filter.c rename to tests/libgit2/object/blob/filter.c diff --git a/tests/object/blob/fromstream.c b/tests/libgit2/object/blob/fromstream.c similarity index 100% rename from tests/object/blob/fromstream.c rename to tests/libgit2/object/blob/fromstream.c diff --git a/tests/object/blob/write.c b/tests/libgit2/object/blob/write.c similarity index 100% rename from tests/object/blob/write.c rename to tests/libgit2/object/blob/write.c diff --git a/tests/object/cache.c b/tests/libgit2/object/cache.c similarity index 100% rename from tests/object/cache.c rename to tests/libgit2/object/cache.c diff --git a/tests/object/commit/commitstagedfile.c b/tests/libgit2/object/commit/commitstagedfile.c similarity index 100% rename from tests/object/commit/commitstagedfile.c rename to tests/libgit2/object/commit/commitstagedfile.c diff --git a/tests/object/commit/parse.c b/tests/libgit2/object/commit/parse.c similarity index 100% rename from tests/object/commit/parse.c rename to tests/libgit2/object/commit/parse.c diff --git a/tests/object/lookup.c b/tests/libgit2/object/lookup.c similarity index 100% rename from tests/object/lookup.c rename to tests/libgit2/object/lookup.c diff --git a/tests/object/lookupbypath.c b/tests/libgit2/object/lookupbypath.c similarity index 100% rename from tests/object/lookupbypath.c rename to tests/libgit2/object/lookupbypath.c diff --git a/tests/object/message.c b/tests/libgit2/object/message.c similarity index 100% rename from tests/object/message.c rename to tests/libgit2/object/message.c diff --git a/tests/object/peel.c b/tests/libgit2/object/peel.c similarity index 100% rename from tests/object/peel.c rename to tests/libgit2/object/peel.c diff --git a/tests/object/raw/chars.c b/tests/libgit2/object/raw/chars.c similarity index 100% rename from tests/object/raw/chars.c rename to tests/libgit2/object/raw/chars.c diff --git a/tests/object/raw/compare.c b/tests/libgit2/object/raw/compare.c similarity index 100% rename from tests/object/raw/compare.c rename to tests/libgit2/object/raw/compare.c diff --git a/tests/object/raw/convert.c b/tests/libgit2/object/raw/convert.c similarity index 100% rename from tests/object/raw/convert.c rename to tests/libgit2/object/raw/convert.c diff --git a/tests/object/raw/data.h b/tests/libgit2/object/raw/data.h similarity index 100% rename from tests/object/raw/data.h rename to tests/libgit2/object/raw/data.h diff --git a/tests/object/raw/fromstr.c b/tests/libgit2/object/raw/fromstr.c similarity index 100% rename from tests/object/raw/fromstr.c rename to tests/libgit2/object/raw/fromstr.c diff --git a/tests/object/raw/hash.c b/tests/libgit2/object/raw/hash.c similarity index 100% rename from tests/object/raw/hash.c rename to tests/libgit2/object/raw/hash.c diff --git a/tests/object/raw/short.c b/tests/libgit2/object/raw/short.c similarity index 100% rename from tests/object/raw/short.c rename to tests/libgit2/object/raw/short.c diff --git a/tests/object/raw/size.c b/tests/libgit2/object/raw/size.c similarity index 100% rename from tests/object/raw/size.c rename to tests/libgit2/object/raw/size.c diff --git a/tests/object/raw/type2string.c b/tests/libgit2/object/raw/type2string.c similarity index 100% rename from tests/object/raw/type2string.c rename to tests/libgit2/object/raw/type2string.c diff --git a/tests/object/raw/write.c b/tests/libgit2/object/raw/write.c similarity index 100% rename from tests/object/raw/write.c rename to tests/libgit2/object/raw/write.c diff --git a/tests/object/shortid.c b/tests/libgit2/object/shortid.c similarity index 100% rename from tests/object/shortid.c rename to tests/libgit2/object/shortid.c diff --git a/tests/object/tag/list.c b/tests/libgit2/object/tag/list.c similarity index 100% rename from tests/object/tag/list.c rename to tests/libgit2/object/tag/list.c diff --git a/tests/object/tag/parse.c b/tests/libgit2/object/tag/parse.c similarity index 100% rename from tests/object/tag/parse.c rename to tests/libgit2/object/tag/parse.c diff --git a/tests/object/tag/peel.c b/tests/libgit2/object/tag/peel.c similarity index 100% rename from tests/object/tag/peel.c rename to tests/libgit2/object/tag/peel.c diff --git a/tests/object/tag/read.c b/tests/libgit2/object/tag/read.c similarity index 100% rename from tests/object/tag/read.c rename to tests/libgit2/object/tag/read.c diff --git a/tests/object/tag/write.c b/tests/libgit2/object/tag/write.c similarity index 100% rename from tests/object/tag/write.c rename to tests/libgit2/object/tag/write.c diff --git a/tests/object/tree/attributes.c b/tests/libgit2/object/tree/attributes.c similarity index 100% rename from tests/object/tree/attributes.c rename to tests/libgit2/object/tree/attributes.c diff --git a/tests/object/tree/duplicateentries.c b/tests/libgit2/object/tree/duplicateentries.c similarity index 100% rename from tests/object/tree/duplicateentries.c rename to tests/libgit2/object/tree/duplicateentries.c diff --git a/tests/object/tree/frompath.c b/tests/libgit2/object/tree/frompath.c similarity index 100% rename from tests/object/tree/frompath.c rename to tests/libgit2/object/tree/frompath.c diff --git a/tests/object/tree/parse.c b/tests/libgit2/object/tree/parse.c similarity index 100% rename from tests/object/tree/parse.c rename to tests/libgit2/object/tree/parse.c diff --git a/tests/object/tree/read.c b/tests/libgit2/object/tree/read.c similarity index 100% rename from tests/object/tree/read.c rename to tests/libgit2/object/tree/read.c diff --git a/tests/object/tree/update.c b/tests/libgit2/object/tree/update.c similarity index 100% rename from tests/object/tree/update.c rename to tests/libgit2/object/tree/update.c diff --git a/tests/object/tree/walk.c b/tests/libgit2/object/tree/walk.c similarity index 100% rename from tests/object/tree/walk.c rename to tests/libgit2/object/tree/walk.c diff --git a/tests/object/tree/write.c b/tests/libgit2/object/tree/write.c similarity index 100% rename from tests/object/tree/write.c rename to tests/libgit2/object/tree/write.c diff --git a/tests/object/validate.c b/tests/libgit2/object/validate.c similarity index 100% rename from tests/object/validate.c rename to tests/libgit2/object/validate.c diff --git a/tests/odb/alternates.c b/tests/libgit2/odb/alternates.c similarity index 100% rename from tests/odb/alternates.c rename to tests/libgit2/odb/alternates.c diff --git a/tests/odb/backend/backend_helpers.c b/tests/libgit2/odb/backend/backend_helpers.c similarity index 100% rename from tests/odb/backend/backend_helpers.c rename to tests/libgit2/odb/backend/backend_helpers.c diff --git a/tests/odb/backend/backend_helpers.h b/tests/libgit2/odb/backend/backend_helpers.h similarity index 100% rename from tests/odb/backend/backend_helpers.h rename to tests/libgit2/odb/backend/backend_helpers.h diff --git a/tests/odb/backend/mempack.c b/tests/libgit2/odb/backend/mempack.c similarity index 100% rename from tests/odb/backend/mempack.c rename to tests/libgit2/odb/backend/mempack.c diff --git a/tests/odb/backend/multiple.c b/tests/libgit2/odb/backend/multiple.c similarity index 100% rename from tests/odb/backend/multiple.c rename to tests/libgit2/odb/backend/multiple.c diff --git a/tests/odb/backend/nobackend.c b/tests/libgit2/odb/backend/nobackend.c similarity index 100% rename from tests/odb/backend/nobackend.c rename to tests/libgit2/odb/backend/nobackend.c diff --git a/tests/odb/backend/nonrefreshing.c b/tests/libgit2/odb/backend/nonrefreshing.c similarity index 100% rename from tests/odb/backend/nonrefreshing.c rename to tests/libgit2/odb/backend/nonrefreshing.c diff --git a/tests/odb/backend/refreshing.c b/tests/libgit2/odb/backend/refreshing.c similarity index 100% rename from tests/odb/backend/refreshing.c rename to tests/libgit2/odb/backend/refreshing.c diff --git a/tests/odb/backend/simple.c b/tests/libgit2/odb/backend/simple.c similarity index 100% rename from tests/odb/backend/simple.c rename to tests/libgit2/odb/backend/simple.c diff --git a/tests/odb/emptyobjects.c b/tests/libgit2/odb/emptyobjects.c similarity index 100% rename from tests/odb/emptyobjects.c rename to tests/libgit2/odb/emptyobjects.c diff --git a/tests/odb/foreach.c b/tests/libgit2/odb/foreach.c similarity index 100% rename from tests/odb/foreach.c rename to tests/libgit2/odb/foreach.c diff --git a/tests/odb/freshen.c b/tests/libgit2/odb/freshen.c similarity index 100% rename from tests/odb/freshen.c rename to tests/libgit2/odb/freshen.c diff --git a/tests/odb/largefiles.c b/tests/libgit2/odb/largefiles.c similarity index 100% rename from tests/odb/largefiles.c rename to tests/libgit2/odb/largefiles.c diff --git a/tests/odb/loose.c b/tests/libgit2/odb/loose.c similarity index 100% rename from tests/odb/loose.c rename to tests/libgit2/odb/loose.c diff --git a/tests/odb/loose_data.h b/tests/libgit2/odb/loose_data.h similarity index 100% rename from tests/odb/loose_data.h rename to tests/libgit2/odb/loose_data.h diff --git a/tests/odb/mixed.c b/tests/libgit2/odb/mixed.c similarity index 100% rename from tests/odb/mixed.c rename to tests/libgit2/odb/mixed.c diff --git a/tests/odb/pack_data.h b/tests/libgit2/odb/pack_data.h similarity index 100% rename from tests/odb/pack_data.h rename to tests/libgit2/odb/pack_data.h diff --git a/tests/odb/pack_data_one.h b/tests/libgit2/odb/pack_data_one.h similarity index 100% rename from tests/odb/pack_data_one.h rename to tests/libgit2/odb/pack_data_one.h diff --git a/tests/odb/packed.c b/tests/libgit2/odb/packed.c similarity index 100% rename from tests/odb/packed.c rename to tests/libgit2/odb/packed.c diff --git a/tests/odb/packed_one.c b/tests/libgit2/odb/packed_one.c similarity index 100% rename from tests/odb/packed_one.c rename to tests/libgit2/odb/packed_one.c diff --git a/tests/odb/sorting.c b/tests/libgit2/odb/sorting.c similarity index 100% rename from tests/odb/sorting.c rename to tests/libgit2/odb/sorting.c diff --git a/tests/odb/streamwrite.c b/tests/libgit2/odb/streamwrite.c similarity index 100% rename from tests/odb/streamwrite.c rename to tests/libgit2/odb/streamwrite.c diff --git a/tests/online/badssl.c b/tests/libgit2/online/badssl.c similarity index 100% rename from tests/online/badssl.c rename to tests/libgit2/online/badssl.c diff --git a/tests/online/clone.c b/tests/libgit2/online/clone.c similarity index 100% rename from tests/online/clone.c rename to tests/libgit2/online/clone.c diff --git a/tests/online/customcert.c b/tests/libgit2/online/customcert.c similarity index 100% rename from tests/online/customcert.c rename to tests/libgit2/online/customcert.c diff --git a/tests/online/fetch.c b/tests/libgit2/online/fetch.c similarity index 100% rename from tests/online/fetch.c rename to tests/libgit2/online/fetch.c diff --git a/tests/online/fetchhead.c b/tests/libgit2/online/fetchhead.c similarity index 100% rename from tests/online/fetchhead.c rename to tests/libgit2/online/fetchhead.c diff --git a/tests/online/push.c b/tests/libgit2/online/push.c similarity index 100% rename from tests/online/push.c rename to tests/libgit2/online/push.c diff --git a/tests/online/push_util.c b/tests/libgit2/online/push_util.c similarity index 100% rename from tests/online/push_util.c rename to tests/libgit2/online/push_util.c diff --git a/tests/online/push_util.h b/tests/libgit2/online/push_util.h similarity index 100% rename from tests/online/push_util.h rename to tests/libgit2/online/push_util.h diff --git a/tests/online/remotes.c b/tests/libgit2/online/remotes.c similarity index 100% rename from tests/online/remotes.c rename to tests/libgit2/online/remotes.c diff --git a/tests/pack/filelimit.c b/tests/libgit2/pack/filelimit.c similarity index 100% rename from tests/pack/filelimit.c rename to tests/libgit2/pack/filelimit.c diff --git a/tests/pack/indexer.c b/tests/libgit2/pack/indexer.c similarity index 100% rename from tests/pack/indexer.c rename to tests/libgit2/pack/indexer.c diff --git a/tests/pack/midx.c b/tests/libgit2/pack/midx.c similarity index 100% rename from tests/pack/midx.c rename to tests/libgit2/pack/midx.c diff --git a/tests/pack/packbuilder.c b/tests/libgit2/pack/packbuilder.c similarity index 100% rename from tests/pack/packbuilder.c rename to tests/libgit2/pack/packbuilder.c diff --git a/tests/pack/sharing.c b/tests/libgit2/pack/sharing.c similarity index 100% rename from tests/pack/sharing.c rename to tests/libgit2/pack/sharing.c diff --git a/tests/pack/threadsafety.c b/tests/libgit2/pack/threadsafety.c similarity index 100% rename from tests/pack/threadsafety.c rename to tests/libgit2/pack/threadsafety.c diff --git a/tests/patch/parse.c b/tests/libgit2/patch/parse.c similarity index 100% rename from tests/patch/parse.c rename to tests/libgit2/patch/parse.c diff --git a/tests/patch/patch_common.h b/tests/libgit2/patch/patch_common.h similarity index 100% rename from tests/patch/patch_common.h rename to tests/libgit2/patch/patch_common.h diff --git a/tests/patch/print.c b/tests/libgit2/patch/print.c similarity index 100% rename from tests/patch/print.c rename to tests/libgit2/patch/print.c diff --git a/tests/path/core.c b/tests/libgit2/path/core.c similarity index 100% rename from tests/path/core.c rename to tests/libgit2/path/core.c diff --git a/tests/path/dotgit.c b/tests/libgit2/path/dotgit.c similarity index 100% rename from tests/path/dotgit.c rename to tests/libgit2/path/dotgit.c diff --git a/tests/path/win32.c b/tests/libgit2/path/win32.c similarity index 100% rename from tests/path/win32.c rename to tests/libgit2/path/win32.c diff --git a/tests/perf/helper__perf__do_merge.c b/tests/libgit2/perf/helper__perf__do_merge.c similarity index 100% rename from tests/perf/helper__perf__do_merge.c rename to tests/libgit2/perf/helper__perf__do_merge.c diff --git a/tests/perf/helper__perf__do_merge.h b/tests/libgit2/perf/helper__perf__do_merge.h similarity index 100% rename from tests/perf/helper__perf__do_merge.h rename to tests/libgit2/perf/helper__perf__do_merge.h diff --git a/tests/perf/helper__perf__timer.c b/tests/libgit2/perf/helper__perf__timer.c similarity index 100% rename from tests/perf/helper__perf__timer.c rename to tests/libgit2/perf/helper__perf__timer.c diff --git a/tests/perf/helper__perf__timer.h b/tests/libgit2/perf/helper__perf__timer.h similarity index 100% rename from tests/perf/helper__perf__timer.h rename to tests/libgit2/perf/helper__perf__timer.h diff --git a/tests/perf/merge.c b/tests/libgit2/perf/merge.c similarity index 100% rename from tests/perf/merge.c rename to tests/libgit2/perf/merge.c diff --git a/tests/precompiled.c b/tests/libgit2/precompiled.c similarity index 100% rename from tests/precompiled.c rename to tests/libgit2/precompiled.c diff --git a/tests/precompiled.h b/tests/libgit2/precompiled.h similarity index 100% rename from tests/precompiled.h rename to tests/libgit2/precompiled.h diff --git a/tests/rebase/abort.c b/tests/libgit2/rebase/abort.c similarity index 100% rename from tests/rebase/abort.c rename to tests/libgit2/rebase/abort.c diff --git a/tests/rebase/inmemory.c b/tests/libgit2/rebase/inmemory.c similarity index 100% rename from tests/rebase/inmemory.c rename to tests/libgit2/rebase/inmemory.c diff --git a/tests/rebase/iterator.c b/tests/libgit2/rebase/iterator.c similarity index 100% rename from tests/rebase/iterator.c rename to tests/libgit2/rebase/iterator.c diff --git a/tests/rebase/merge.c b/tests/libgit2/rebase/merge.c similarity index 100% rename from tests/rebase/merge.c rename to tests/libgit2/rebase/merge.c diff --git a/tests/rebase/setup.c b/tests/libgit2/rebase/setup.c similarity index 100% rename from tests/rebase/setup.c rename to tests/libgit2/rebase/setup.c diff --git a/tests/rebase/sign.c b/tests/libgit2/rebase/sign.c similarity index 100% rename from tests/rebase/sign.c rename to tests/libgit2/rebase/sign.c diff --git a/tests/rebase/submodule.c b/tests/libgit2/rebase/submodule.c similarity index 100% rename from tests/rebase/submodule.c rename to tests/libgit2/rebase/submodule.c diff --git a/tests/refs/basic.c b/tests/libgit2/refs/basic.c similarity index 100% rename from tests/refs/basic.c rename to tests/libgit2/refs/basic.c diff --git a/tests/refs/branches/checkedout.c b/tests/libgit2/refs/branches/checkedout.c similarity index 100% rename from tests/refs/branches/checkedout.c rename to tests/libgit2/refs/branches/checkedout.c diff --git a/tests/refs/branches/create.c b/tests/libgit2/refs/branches/create.c similarity index 100% rename from tests/refs/branches/create.c rename to tests/libgit2/refs/branches/create.c diff --git a/tests/refs/branches/delete.c b/tests/libgit2/refs/branches/delete.c similarity index 100% rename from tests/refs/branches/delete.c rename to tests/libgit2/refs/branches/delete.c diff --git a/tests/refs/branches/ishead.c b/tests/libgit2/refs/branches/ishead.c similarity index 100% rename from tests/refs/branches/ishead.c rename to tests/libgit2/refs/branches/ishead.c diff --git a/tests/refs/branches/iterator.c b/tests/libgit2/refs/branches/iterator.c similarity index 100% rename from tests/refs/branches/iterator.c rename to tests/libgit2/refs/branches/iterator.c diff --git a/tests/refs/branches/lookup.c b/tests/libgit2/refs/branches/lookup.c similarity index 100% rename from tests/refs/branches/lookup.c rename to tests/libgit2/refs/branches/lookup.c diff --git a/tests/refs/branches/move.c b/tests/libgit2/refs/branches/move.c similarity index 100% rename from tests/refs/branches/move.c rename to tests/libgit2/refs/branches/move.c diff --git a/tests/refs/branches/name.c b/tests/libgit2/refs/branches/name.c similarity index 100% rename from tests/refs/branches/name.c rename to tests/libgit2/refs/branches/name.c diff --git a/tests/refs/branches/remote.c b/tests/libgit2/refs/branches/remote.c similarity index 100% rename from tests/refs/branches/remote.c rename to tests/libgit2/refs/branches/remote.c diff --git a/tests/refs/branches/upstream.c b/tests/libgit2/refs/branches/upstream.c similarity index 100% rename from tests/refs/branches/upstream.c rename to tests/libgit2/refs/branches/upstream.c diff --git a/tests/refs/branches/upstreamname.c b/tests/libgit2/refs/branches/upstreamname.c similarity index 100% rename from tests/refs/branches/upstreamname.c rename to tests/libgit2/refs/branches/upstreamname.c diff --git a/tests/refs/crashes.c b/tests/libgit2/refs/crashes.c similarity index 100% rename from tests/refs/crashes.c rename to tests/libgit2/refs/crashes.c diff --git a/tests/refs/create.c b/tests/libgit2/refs/create.c similarity index 100% rename from tests/refs/create.c rename to tests/libgit2/refs/create.c diff --git a/tests/refs/delete.c b/tests/libgit2/refs/delete.c similarity index 100% rename from tests/refs/delete.c rename to tests/libgit2/refs/delete.c diff --git a/tests/refs/dup.c b/tests/libgit2/refs/dup.c similarity index 100% rename from tests/refs/dup.c rename to tests/libgit2/refs/dup.c diff --git a/tests/refs/foreachglob.c b/tests/libgit2/refs/foreachglob.c similarity index 100% rename from tests/refs/foreachglob.c rename to tests/libgit2/refs/foreachglob.c diff --git a/tests/refs/isvalidname.c b/tests/libgit2/refs/isvalidname.c similarity index 100% rename from tests/refs/isvalidname.c rename to tests/libgit2/refs/isvalidname.c diff --git a/tests/refs/iterator.c b/tests/libgit2/refs/iterator.c similarity index 100% rename from tests/refs/iterator.c rename to tests/libgit2/refs/iterator.c diff --git a/tests/refs/list.c b/tests/libgit2/refs/list.c similarity index 100% rename from tests/refs/list.c rename to tests/libgit2/refs/list.c diff --git a/tests/refs/listall.c b/tests/libgit2/refs/listall.c similarity index 100% rename from tests/refs/listall.c rename to tests/libgit2/refs/listall.c diff --git a/tests/refs/lookup.c b/tests/libgit2/refs/lookup.c similarity index 100% rename from tests/refs/lookup.c rename to tests/libgit2/refs/lookup.c diff --git a/tests/refs/namespaces.c b/tests/libgit2/refs/namespaces.c similarity index 100% rename from tests/refs/namespaces.c rename to tests/libgit2/refs/namespaces.c diff --git a/tests/refs/normalize.c b/tests/libgit2/refs/normalize.c similarity index 100% rename from tests/refs/normalize.c rename to tests/libgit2/refs/normalize.c diff --git a/tests/refs/overwrite.c b/tests/libgit2/refs/overwrite.c similarity index 100% rename from tests/refs/overwrite.c rename to tests/libgit2/refs/overwrite.c diff --git a/tests/refs/pack.c b/tests/libgit2/refs/pack.c similarity index 100% rename from tests/refs/pack.c rename to tests/libgit2/refs/pack.c diff --git a/tests/refs/peel.c b/tests/libgit2/refs/peel.c similarity index 100% rename from tests/refs/peel.c rename to tests/libgit2/refs/peel.c diff --git a/tests/refs/races.c b/tests/libgit2/refs/races.c similarity index 100% rename from tests/refs/races.c rename to tests/libgit2/refs/races.c diff --git a/tests/refs/read.c b/tests/libgit2/refs/read.c similarity index 100% rename from tests/refs/read.c rename to tests/libgit2/refs/read.c diff --git a/tests/refs/ref_helpers.c b/tests/libgit2/refs/ref_helpers.c similarity index 100% rename from tests/refs/ref_helpers.c rename to tests/libgit2/refs/ref_helpers.c diff --git a/tests/refs/ref_helpers.h b/tests/libgit2/refs/ref_helpers.h similarity index 100% rename from tests/refs/ref_helpers.h rename to tests/libgit2/refs/ref_helpers.h diff --git a/tests/refs/reflog/drop.c b/tests/libgit2/refs/reflog/drop.c similarity index 100% rename from tests/refs/reflog/drop.c rename to tests/libgit2/refs/reflog/drop.c diff --git a/tests/refs/reflog/messages.c b/tests/libgit2/refs/reflog/messages.c similarity index 100% rename from tests/refs/reflog/messages.c rename to tests/libgit2/refs/reflog/messages.c diff --git a/tests/refs/reflog/reflog.c b/tests/libgit2/refs/reflog/reflog.c similarity index 100% rename from tests/refs/reflog/reflog.c rename to tests/libgit2/refs/reflog/reflog.c diff --git a/tests/refs/reflog/reflog_helpers.c b/tests/libgit2/refs/reflog/reflog_helpers.c similarity index 100% rename from tests/refs/reflog/reflog_helpers.c rename to tests/libgit2/refs/reflog/reflog_helpers.c diff --git a/tests/refs/reflog/reflog_helpers.h b/tests/libgit2/refs/reflog/reflog_helpers.h similarity index 100% rename from tests/refs/reflog/reflog_helpers.h rename to tests/libgit2/refs/reflog/reflog_helpers.h diff --git a/tests/refs/rename.c b/tests/libgit2/refs/rename.c similarity index 100% rename from tests/refs/rename.c rename to tests/libgit2/refs/rename.c diff --git a/tests/refs/revparse.c b/tests/libgit2/refs/revparse.c similarity index 100% rename from tests/refs/revparse.c rename to tests/libgit2/refs/revparse.c diff --git a/tests/refs/setter.c b/tests/libgit2/refs/setter.c similarity index 100% rename from tests/refs/setter.c rename to tests/libgit2/refs/setter.c diff --git a/tests/refs/shorthand.c b/tests/libgit2/refs/shorthand.c similarity index 100% rename from tests/refs/shorthand.c rename to tests/libgit2/refs/shorthand.c diff --git a/tests/refs/tags/name.c b/tests/libgit2/refs/tags/name.c similarity index 100% rename from tests/refs/tags/name.c rename to tests/libgit2/refs/tags/name.c diff --git a/tests/refs/transactions.c b/tests/libgit2/refs/transactions.c similarity index 100% rename from tests/refs/transactions.c rename to tests/libgit2/refs/transactions.c diff --git a/tests/refs/unicode.c b/tests/libgit2/refs/unicode.c similarity index 100% rename from tests/refs/unicode.c rename to tests/libgit2/refs/unicode.c diff --git a/tests/refs/update.c b/tests/libgit2/refs/update.c similarity index 100% rename from tests/refs/update.c rename to tests/libgit2/refs/update.c diff --git a/tests/remote/create.c b/tests/libgit2/remote/create.c similarity index 100% rename from tests/remote/create.c rename to tests/libgit2/remote/create.c diff --git a/tests/remote/fetch.c b/tests/libgit2/remote/fetch.c similarity index 100% rename from tests/remote/fetch.c rename to tests/libgit2/remote/fetch.c diff --git a/tests/remote/httpproxy.c b/tests/libgit2/remote/httpproxy.c similarity index 100% rename from tests/remote/httpproxy.c rename to tests/libgit2/remote/httpproxy.c diff --git a/tests/remote/insteadof.c b/tests/libgit2/remote/insteadof.c similarity index 100% rename from tests/remote/insteadof.c rename to tests/libgit2/remote/insteadof.c diff --git a/tests/remote/list.c b/tests/libgit2/remote/list.c similarity index 100% rename from tests/remote/list.c rename to tests/libgit2/remote/list.c diff --git a/tests/repo/config.c b/tests/libgit2/repo/config.c similarity index 100% rename from tests/repo/config.c rename to tests/libgit2/repo/config.c diff --git a/tests/repo/discover.c b/tests/libgit2/repo/discover.c similarity index 100% rename from tests/repo/discover.c rename to tests/libgit2/repo/discover.c diff --git a/tests/repo/env.c b/tests/libgit2/repo/env.c similarity index 100% rename from tests/repo/env.c rename to tests/libgit2/repo/env.c diff --git a/tests/repo/extensions.c b/tests/libgit2/repo/extensions.c similarity index 100% rename from tests/repo/extensions.c rename to tests/libgit2/repo/extensions.c diff --git a/tests/repo/getters.c b/tests/libgit2/repo/getters.c similarity index 100% rename from tests/repo/getters.c rename to tests/libgit2/repo/getters.c diff --git a/tests/repo/hashfile.c b/tests/libgit2/repo/hashfile.c similarity index 100% rename from tests/repo/hashfile.c rename to tests/libgit2/repo/hashfile.c diff --git a/tests/repo/head.c b/tests/libgit2/repo/head.c similarity index 100% rename from tests/repo/head.c rename to tests/libgit2/repo/head.c diff --git a/tests/repo/headtree.c b/tests/libgit2/repo/headtree.c similarity index 100% rename from tests/repo/headtree.c rename to tests/libgit2/repo/headtree.c diff --git a/tests/repo/init.c b/tests/libgit2/repo/init.c similarity index 100% rename from tests/repo/init.c rename to tests/libgit2/repo/init.c diff --git a/tests/repo/message.c b/tests/libgit2/repo/message.c similarity index 100% rename from tests/repo/message.c rename to tests/libgit2/repo/message.c diff --git a/tests/repo/new.c b/tests/libgit2/repo/new.c similarity index 100% rename from tests/repo/new.c rename to tests/libgit2/repo/new.c diff --git a/tests/repo/open.c b/tests/libgit2/repo/open.c similarity index 100% rename from tests/repo/open.c rename to tests/libgit2/repo/open.c diff --git a/tests/repo/pathspec.c b/tests/libgit2/repo/pathspec.c similarity index 100% rename from tests/repo/pathspec.c rename to tests/libgit2/repo/pathspec.c diff --git a/tests/repo/repo_helpers.c b/tests/libgit2/repo/repo_helpers.c similarity index 100% rename from tests/repo/repo_helpers.c rename to tests/libgit2/repo/repo_helpers.c diff --git a/tests/repo/repo_helpers.h b/tests/libgit2/repo/repo_helpers.h similarity index 100% rename from tests/repo/repo_helpers.h rename to tests/libgit2/repo/repo_helpers.h diff --git a/tests/repo/reservedname.c b/tests/libgit2/repo/reservedname.c similarity index 100% rename from tests/repo/reservedname.c rename to tests/libgit2/repo/reservedname.c diff --git a/tests/repo/setters.c b/tests/libgit2/repo/setters.c similarity index 100% rename from tests/repo/setters.c rename to tests/libgit2/repo/setters.c diff --git a/tests/repo/shallow.c b/tests/libgit2/repo/shallow.c similarity index 100% rename from tests/repo/shallow.c rename to tests/libgit2/repo/shallow.c diff --git a/tests/repo/state.c b/tests/libgit2/repo/state.c similarity index 100% rename from tests/repo/state.c rename to tests/libgit2/repo/state.c diff --git a/tests/repo/template.c b/tests/libgit2/repo/template.c similarity index 100% rename from tests/repo/template.c rename to tests/libgit2/repo/template.c diff --git a/tests/reset/default.c b/tests/libgit2/reset/default.c similarity index 100% rename from tests/reset/default.c rename to tests/libgit2/reset/default.c diff --git a/tests/reset/hard.c b/tests/libgit2/reset/hard.c similarity index 100% rename from tests/reset/hard.c rename to tests/libgit2/reset/hard.c diff --git a/tests/reset/mixed.c b/tests/libgit2/reset/mixed.c similarity index 100% rename from tests/reset/mixed.c rename to tests/libgit2/reset/mixed.c diff --git a/tests/reset/reset_helpers.c b/tests/libgit2/reset/reset_helpers.c similarity index 100% rename from tests/reset/reset_helpers.c rename to tests/libgit2/reset/reset_helpers.c diff --git a/tests/reset/reset_helpers.h b/tests/libgit2/reset/reset_helpers.h similarity index 100% rename from tests/reset/reset_helpers.h rename to tests/libgit2/reset/reset_helpers.h diff --git a/tests/reset/soft.c b/tests/libgit2/reset/soft.c similarity index 100% rename from tests/reset/soft.c rename to tests/libgit2/reset/soft.c diff --git a/tests/revert/bare.c b/tests/libgit2/revert/bare.c similarity index 100% rename from tests/revert/bare.c rename to tests/libgit2/revert/bare.c diff --git a/tests/revert/rename.c b/tests/libgit2/revert/rename.c similarity index 100% rename from tests/revert/rename.c rename to tests/libgit2/revert/rename.c diff --git a/tests/revert/workdir.c b/tests/libgit2/revert/workdir.c similarity index 100% rename from tests/revert/workdir.c rename to tests/libgit2/revert/workdir.c diff --git a/tests/revwalk/basic.c b/tests/libgit2/revwalk/basic.c similarity index 100% rename from tests/revwalk/basic.c rename to tests/libgit2/revwalk/basic.c diff --git a/tests/revwalk/hidecb.c b/tests/libgit2/revwalk/hidecb.c similarity index 100% rename from tests/revwalk/hidecb.c rename to tests/libgit2/revwalk/hidecb.c diff --git a/tests/revwalk/mergebase.c b/tests/libgit2/revwalk/mergebase.c similarity index 100% rename from tests/revwalk/mergebase.c rename to tests/libgit2/revwalk/mergebase.c diff --git a/tests/revwalk/signatureparsing.c b/tests/libgit2/revwalk/signatureparsing.c similarity index 100% rename from tests/revwalk/signatureparsing.c rename to tests/libgit2/revwalk/signatureparsing.c diff --git a/tests/revwalk/simplify.c b/tests/libgit2/revwalk/simplify.c similarity index 100% rename from tests/revwalk/simplify.c rename to tests/libgit2/revwalk/simplify.c diff --git a/tests/stash/apply.c b/tests/libgit2/stash/apply.c similarity index 100% rename from tests/stash/apply.c rename to tests/libgit2/stash/apply.c diff --git a/tests/stash/drop.c b/tests/libgit2/stash/drop.c similarity index 100% rename from tests/stash/drop.c rename to tests/libgit2/stash/drop.c diff --git a/tests/stash/foreach.c b/tests/libgit2/stash/foreach.c similarity index 100% rename from tests/stash/foreach.c rename to tests/libgit2/stash/foreach.c diff --git a/tests/stash/save.c b/tests/libgit2/stash/save.c similarity index 100% rename from tests/stash/save.c rename to tests/libgit2/stash/save.c diff --git a/tests/stash/stash_helpers.c b/tests/libgit2/stash/stash_helpers.c similarity index 100% rename from tests/stash/stash_helpers.c rename to tests/libgit2/stash/stash_helpers.c diff --git a/tests/stash/stash_helpers.h b/tests/libgit2/stash/stash_helpers.h similarity index 100% rename from tests/stash/stash_helpers.h rename to tests/libgit2/stash/stash_helpers.h diff --git a/tests/stash/submodules.c b/tests/libgit2/stash/submodules.c similarity index 100% rename from tests/stash/submodules.c rename to tests/libgit2/stash/submodules.c diff --git a/tests/status/renames.c b/tests/libgit2/status/renames.c similarity index 100% rename from tests/status/renames.c rename to tests/libgit2/status/renames.c diff --git a/tests/status/single.c b/tests/libgit2/status/single.c similarity index 100% rename from tests/status/single.c rename to tests/libgit2/status/single.c diff --git a/tests/status/status_data.h b/tests/libgit2/status/status_data.h similarity index 100% rename from tests/status/status_data.h rename to tests/libgit2/status/status_data.h diff --git a/tests/status/status_helpers.c b/tests/libgit2/status/status_helpers.c similarity index 100% rename from tests/status/status_helpers.c rename to tests/libgit2/status/status_helpers.c diff --git a/tests/status/status_helpers.h b/tests/libgit2/status/status_helpers.h similarity index 100% rename from tests/status/status_helpers.h rename to tests/libgit2/status/status_helpers.h diff --git a/tests/status/submodules.c b/tests/libgit2/status/submodules.c similarity index 100% rename from tests/status/submodules.c rename to tests/libgit2/status/submodules.c diff --git a/tests/status/worktree.c b/tests/libgit2/status/worktree.c similarity index 100% rename from tests/status/worktree.c rename to tests/libgit2/status/worktree.c diff --git a/tests/status/worktree_init.c b/tests/libgit2/status/worktree_init.c similarity index 100% rename from tests/status/worktree_init.c rename to tests/libgit2/status/worktree_init.c diff --git a/tests/str/basic.c b/tests/libgit2/str/basic.c similarity index 100% rename from tests/str/basic.c rename to tests/libgit2/str/basic.c diff --git a/tests/str/oom.c b/tests/libgit2/str/oom.c similarity index 100% rename from tests/str/oom.c rename to tests/libgit2/str/oom.c diff --git a/tests/str/percent.c b/tests/libgit2/str/percent.c similarity index 100% rename from tests/str/percent.c rename to tests/libgit2/str/percent.c diff --git a/tests/str/quote.c b/tests/libgit2/str/quote.c similarity index 100% rename from tests/str/quote.c rename to tests/libgit2/str/quote.c diff --git a/tests/str/splice.c b/tests/libgit2/str/splice.c similarity index 100% rename from tests/str/splice.c rename to tests/libgit2/str/splice.c diff --git a/tests/stream/deprecated.c b/tests/libgit2/stream/deprecated.c similarity index 100% rename from tests/stream/deprecated.c rename to tests/libgit2/stream/deprecated.c diff --git a/tests/stream/registration.c b/tests/libgit2/stream/registration.c similarity index 100% rename from tests/stream/registration.c rename to tests/libgit2/stream/registration.c diff --git a/tests/stress/diff.c b/tests/libgit2/stress/diff.c similarity index 100% rename from tests/stress/diff.c rename to tests/libgit2/stress/diff.c diff --git a/tests/submodule/add.c b/tests/libgit2/submodule/add.c similarity index 100% rename from tests/submodule/add.c rename to tests/libgit2/submodule/add.c diff --git a/tests/submodule/escape.c b/tests/libgit2/submodule/escape.c similarity index 100% rename from tests/submodule/escape.c rename to tests/libgit2/submodule/escape.c diff --git a/tests/submodule/init.c b/tests/libgit2/submodule/init.c similarity index 100% rename from tests/submodule/init.c rename to tests/libgit2/submodule/init.c diff --git a/tests/submodule/inject_option.c b/tests/libgit2/submodule/inject_option.c similarity index 100% rename from tests/submodule/inject_option.c rename to tests/libgit2/submodule/inject_option.c diff --git a/tests/submodule/lookup.c b/tests/libgit2/submodule/lookup.c similarity index 100% rename from tests/submodule/lookup.c rename to tests/libgit2/submodule/lookup.c diff --git a/tests/submodule/modify.c b/tests/libgit2/submodule/modify.c similarity index 100% rename from tests/submodule/modify.c rename to tests/libgit2/submodule/modify.c diff --git a/tests/submodule/nosubs.c b/tests/libgit2/submodule/nosubs.c similarity index 100% rename from tests/submodule/nosubs.c rename to tests/libgit2/submodule/nosubs.c diff --git a/tests/submodule/open.c b/tests/libgit2/submodule/open.c similarity index 100% rename from tests/submodule/open.c rename to tests/libgit2/submodule/open.c diff --git a/tests/submodule/repository_init.c b/tests/libgit2/submodule/repository_init.c similarity index 100% rename from tests/submodule/repository_init.c rename to tests/libgit2/submodule/repository_init.c diff --git a/tests/submodule/status.c b/tests/libgit2/submodule/status.c similarity index 100% rename from tests/submodule/status.c rename to tests/libgit2/submodule/status.c diff --git a/tests/submodule/submodule_helpers.c b/tests/libgit2/submodule/submodule_helpers.c similarity index 100% rename from tests/submodule/submodule_helpers.c rename to tests/libgit2/submodule/submodule_helpers.c diff --git a/tests/submodule/submodule_helpers.h b/tests/libgit2/submodule/submodule_helpers.h similarity index 100% rename from tests/submodule/submodule_helpers.h rename to tests/libgit2/submodule/submodule_helpers.h diff --git a/tests/submodule/update.c b/tests/libgit2/submodule/update.c similarity index 100% rename from tests/submodule/update.c rename to tests/libgit2/submodule/update.c diff --git a/tests/threads/atomic.c b/tests/libgit2/threads/atomic.c similarity index 100% rename from tests/threads/atomic.c rename to tests/libgit2/threads/atomic.c diff --git a/tests/threads/basic.c b/tests/libgit2/threads/basic.c similarity index 100% rename from tests/threads/basic.c rename to tests/libgit2/threads/basic.c diff --git a/tests/threads/diff.c b/tests/libgit2/threads/diff.c similarity index 100% rename from tests/threads/diff.c rename to tests/libgit2/threads/diff.c diff --git a/tests/threads/iterator.c b/tests/libgit2/threads/iterator.c similarity index 100% rename from tests/threads/iterator.c rename to tests/libgit2/threads/iterator.c diff --git a/tests/threads/refdb.c b/tests/libgit2/threads/refdb.c similarity index 100% rename from tests/threads/refdb.c rename to tests/libgit2/threads/refdb.c diff --git a/tests/threads/thread_helpers.c b/tests/libgit2/threads/thread_helpers.c similarity index 100% rename from tests/threads/thread_helpers.c rename to tests/libgit2/threads/thread_helpers.c diff --git a/tests/threads/thread_helpers.h b/tests/libgit2/threads/thread_helpers.h similarity index 100% rename from tests/threads/thread_helpers.h rename to tests/libgit2/threads/thread_helpers.h diff --git a/tests/threads/tlsdata.c b/tests/libgit2/threads/tlsdata.c similarity index 100% rename from tests/threads/tlsdata.c rename to tests/libgit2/threads/tlsdata.c diff --git a/tests/trace/trace.c b/tests/libgit2/trace/trace.c similarity index 100% rename from tests/trace/trace.c rename to tests/libgit2/trace/trace.c diff --git a/tests/trace/windows/stacktrace.c b/tests/libgit2/trace/windows/stacktrace.c similarity index 100% rename from tests/trace/windows/stacktrace.c rename to tests/libgit2/trace/windows/stacktrace.c diff --git a/tests/transport/register.c b/tests/libgit2/transport/register.c similarity index 100% rename from tests/transport/register.c rename to tests/libgit2/transport/register.c diff --git a/tests/transports/smart/packet.c b/tests/libgit2/transports/smart/packet.c similarity index 100% rename from tests/transports/smart/packet.c rename to tests/libgit2/transports/smart/packet.c diff --git a/tests/valgrind-supp-mac.txt b/tests/libgit2/valgrind-supp-mac.txt similarity index 100% rename from tests/valgrind-supp-mac.txt rename to tests/libgit2/valgrind-supp-mac.txt diff --git a/tests/win32/forbidden.c b/tests/libgit2/win32/forbidden.c similarity index 100% rename from tests/win32/forbidden.c rename to tests/libgit2/win32/forbidden.c diff --git a/tests/win32/longpath.c b/tests/libgit2/win32/longpath.c similarity index 100% rename from tests/win32/longpath.c rename to tests/libgit2/win32/longpath.c diff --git a/tests/win32/systemdir.c b/tests/libgit2/win32/systemdir.c similarity index 100% rename from tests/win32/systemdir.c rename to tests/libgit2/win32/systemdir.c diff --git a/tests/worktree/bare.c b/tests/libgit2/worktree/bare.c similarity index 100% rename from tests/worktree/bare.c rename to tests/libgit2/worktree/bare.c diff --git a/tests/worktree/config.c b/tests/libgit2/worktree/config.c similarity index 100% rename from tests/worktree/config.c rename to tests/libgit2/worktree/config.c diff --git a/tests/worktree/merge.c b/tests/libgit2/worktree/merge.c similarity index 100% rename from tests/worktree/merge.c rename to tests/libgit2/worktree/merge.c diff --git a/tests/worktree/open.c b/tests/libgit2/worktree/open.c similarity index 100% rename from tests/worktree/open.c rename to tests/libgit2/worktree/open.c diff --git a/tests/worktree/reflog.c b/tests/libgit2/worktree/reflog.c similarity index 100% rename from tests/worktree/reflog.c rename to tests/libgit2/worktree/reflog.c diff --git a/tests/worktree/refs.c b/tests/libgit2/worktree/refs.c similarity index 100% rename from tests/worktree/refs.c rename to tests/libgit2/worktree/refs.c diff --git a/tests/worktree/repository.c b/tests/libgit2/worktree/repository.c similarity index 100% rename from tests/worktree/repository.c rename to tests/libgit2/worktree/repository.c diff --git a/tests/worktree/submodule.c b/tests/libgit2/worktree/submodule.c similarity index 100% rename from tests/worktree/submodule.c rename to tests/libgit2/worktree/submodule.c diff --git a/tests/worktree/worktree.c b/tests/libgit2/worktree/worktree.c similarity index 100% rename from tests/worktree/worktree.c rename to tests/libgit2/worktree/worktree.c diff --git a/tests/worktree/worktree_helpers.c b/tests/libgit2/worktree/worktree_helpers.c similarity index 100% rename from tests/worktree/worktree_helpers.c rename to tests/libgit2/worktree/worktree_helpers.c diff --git a/tests/worktree/worktree_helpers.h b/tests/libgit2/worktree/worktree_helpers.h similarity index 100% rename from tests/worktree/worktree_helpers.h rename to tests/libgit2/worktree/worktree_helpers.h From 25bc84fb8f702b57983d374f1c79b93a2d7543f1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 16 Nov 2021 23:41:00 -0500 Subject: [PATCH 0819/1616] refactor: move clar into separate directory --- tests/README.md | 6 ++++-- tests/{libgit2 => clar}/clar.c | 0 tests/{libgit2 => clar}/clar.h | 0 tests/{libgit2 => clar}/clar/fixtures.h | 0 tests/{libgit2 => clar}/clar/fs.h | 0 tests/{libgit2 => clar}/clar/print.h | 0 tests/{libgit2 => clar}/clar/sandbox.h | 0 tests/{libgit2 => clar}/clar/summary.h | 0 tests/{libgit2 => clar}/clar_libgit2.c | 0 tests/{libgit2 => clar}/clar_libgit2.h | 0 tests/{libgit2 => clar}/clar_libgit2_timer.c | 0 tests/{libgit2 => clar}/clar_libgit2_timer.h | 0 tests/{libgit2 => clar}/clar_libgit2_trace.c | 0 tests/{libgit2 => clar}/clar_libgit2_trace.h | 0 tests/{libgit2 => clar}/generate.py | 0 tests/{libgit2 => clar}/main.c | 0 tests/libgit2/CMakeLists.txt | 15 ++++++++------- tests/libgit2/remote/fetch.c | 8 ++++---- 18 files changed, 16 insertions(+), 13 deletions(-) rename tests/{libgit2 => clar}/clar.c (100%) rename tests/{libgit2 => clar}/clar.h (100%) rename tests/{libgit2 => clar}/clar/fixtures.h (100%) rename tests/{libgit2 => clar}/clar/fs.h (100%) rename tests/{libgit2 => clar}/clar/print.h (100%) rename tests/{libgit2 => clar}/clar/sandbox.h (100%) rename tests/{libgit2 => clar}/clar/summary.h (100%) rename tests/{libgit2 => clar}/clar_libgit2.c (100%) rename tests/{libgit2 => clar}/clar_libgit2.h (100%) rename tests/{libgit2 => clar}/clar_libgit2_timer.c (100%) rename tests/{libgit2 => clar}/clar_libgit2_timer.h (100%) rename tests/{libgit2 => clar}/clar_libgit2_trace.c (100%) rename tests/{libgit2 => clar}/clar_libgit2_trace.h (100%) rename tests/{libgit2 => clar}/generate.py (100%) rename tests/{libgit2 => clar}/main.c (100%) diff --git a/tests/README.md b/tests/README.md index 68c2788baf2..2e3b2630e37 100644 --- a/tests/README.md +++ b/tests/README.md @@ -2,9 +2,11 @@ These are the unit and integration tests for the libgit2 projects. -* `libgit2` +* `clar` + This is [clar](https://github.com/clar-test/clar) the common test framework. +* `libgit2` These tests exercise the core git functionality in libgit2 itself. -* `resources` +* `resources` These are the resources for the tests, including files and git repositories. diff --git a/tests/libgit2/clar.c b/tests/clar/clar.c similarity index 100% rename from tests/libgit2/clar.c rename to tests/clar/clar.c diff --git a/tests/libgit2/clar.h b/tests/clar/clar.h similarity index 100% rename from tests/libgit2/clar.h rename to tests/clar/clar.h diff --git a/tests/libgit2/clar/fixtures.h b/tests/clar/clar/fixtures.h similarity index 100% rename from tests/libgit2/clar/fixtures.h rename to tests/clar/clar/fixtures.h diff --git a/tests/libgit2/clar/fs.h b/tests/clar/clar/fs.h similarity index 100% rename from tests/libgit2/clar/fs.h rename to tests/clar/clar/fs.h diff --git a/tests/libgit2/clar/print.h b/tests/clar/clar/print.h similarity index 100% rename from tests/libgit2/clar/print.h rename to tests/clar/clar/print.h diff --git a/tests/libgit2/clar/sandbox.h b/tests/clar/clar/sandbox.h similarity index 100% rename from tests/libgit2/clar/sandbox.h rename to tests/clar/clar/sandbox.h diff --git a/tests/libgit2/clar/summary.h b/tests/clar/clar/summary.h similarity index 100% rename from tests/libgit2/clar/summary.h rename to tests/clar/clar/summary.h diff --git a/tests/libgit2/clar_libgit2.c b/tests/clar/clar_libgit2.c similarity index 100% rename from tests/libgit2/clar_libgit2.c rename to tests/clar/clar_libgit2.c diff --git a/tests/libgit2/clar_libgit2.h b/tests/clar/clar_libgit2.h similarity index 100% rename from tests/libgit2/clar_libgit2.h rename to tests/clar/clar_libgit2.h diff --git a/tests/libgit2/clar_libgit2_timer.c b/tests/clar/clar_libgit2_timer.c similarity index 100% rename from tests/libgit2/clar_libgit2_timer.c rename to tests/clar/clar_libgit2_timer.c diff --git a/tests/libgit2/clar_libgit2_timer.h b/tests/clar/clar_libgit2_timer.h similarity index 100% rename from tests/libgit2/clar_libgit2_timer.h rename to tests/clar/clar_libgit2_timer.h diff --git a/tests/libgit2/clar_libgit2_trace.c b/tests/clar/clar_libgit2_trace.c similarity index 100% rename from tests/libgit2/clar_libgit2_trace.c rename to tests/clar/clar_libgit2_trace.c diff --git a/tests/libgit2/clar_libgit2_trace.h b/tests/clar/clar_libgit2_trace.h similarity index 100% rename from tests/libgit2/clar_libgit2_trace.h rename to tests/clar/clar_libgit2_trace.h diff --git a/tests/libgit2/generate.py b/tests/clar/generate.py similarity index 100% rename from tests/libgit2/generate.py rename to tests/clar/generate.py diff --git a/tests/libgit2/main.c b/tests/clar/main.c similarity index 100% rename from tests/libgit2/main.c rename to tests/clar/main.c diff --git a/tests/libgit2/CMakeLists.txt b/tests/libgit2/CMakeLists.txt index 8bf199ecf1c..9ab01077a51 100644 --- a/tests/libgit2/CMakeLists.txt +++ b/tests/libgit2/CMakeLists.txt @@ -8,8 +8,9 @@ if(NOT PYTHONINTERP_FOUND) "Make sure python is available, or pass -DBUILD_TESTS=OFF to skip building the tests") ENDIF() +set(CLAR_PATH "${PROJECT_SOURCE_DIR}/tests/clar") set(CLAR_FIXTURES "${PROJECT_SOURCE_DIR}/tests/resources/") -set(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}") +set(TEST_PATH "${CMAKE_CURRENT_SOURCE_DIR}") add_definitions(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\") add_definitions(-DCLAR_TMPDIR=\"libgit2_tests\") add_definitions(-DCLAR_WIN32_LONGPATHS) @@ -18,19 +19,19 @@ add_definitions(-D_FILE_OFFSET_BITS=64) # Ensure that we do not use deprecated functions internally add_definitions(-DGIT_DEPRECATE_HARD) -set(TEST_INCLUDES "${CLAR_PATH}" "${CMAKE_CURRENT_BINARY_DIR}") -file(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h) -set(SRC_CLAR "main.c" "clar_libgit2.c" "clar_libgit2_trace.c" "clar_libgit2_timer.c" "clar.c") +set(TEST_INCLUDES "${CLAR_PATH}" "${TEST_PATH}" "${CMAKE_CURRENT_BINARY_DIR}") +file(GLOB_RECURSE SRC_TEST ${TEST_PATH}/*/*.c ${TEST_PATH}/*/*.h) +file(GLOB_RECURSE SRC_CLAR ${CLAR_PATH}/*.c ${CLAR_PATH}/*.h) if(MSVC_IDE) - list(APPEND SRC_CLAR "precompiled.c") + list(APPEND SRC_TEST "precompiled.c") endif() add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clar.suite ${CMAKE_CURRENT_BINARY_DIR}/clar_suite.h - COMMAND ${PYTHON_EXECUTABLE} generate.py -o "${CMAKE_CURRENT_BINARY_DIR}" -f -xonline -xstress -xperf . + COMMAND ${PYTHON_EXECUTABLE} ${CLAR_PATH}/generate.py -o "${CMAKE_CURRENT_BINARY_DIR}" -f -xonline -xstress -xperf . DEPENDS ${SRC_TEST} - WORKING_DIRECTORY ${CLAR_PATH} + WORKING_DIRECTORY ${TEST_PATH} ) set_source_files_properties( diff --git a/tests/libgit2/remote/fetch.c b/tests/libgit2/remote/fetch.c index 3700462676f..85e99206fdc 100644 --- a/tests/libgit2/remote/fetch.c +++ b/tests/libgit2/remote/fetch.c @@ -1,4 +1,4 @@ -#include "../clar_libgit2.h" +#include "clar_libgit2.h" #include "remote.h" #include "repository.h" @@ -82,9 +82,9 @@ static void do_time_travelling_fetch(git_oid *commit1id, git_oid *commit2id, cl_git_pass(git_treebuilder_write(&empty_tree_id, tb)); cl_git_pass(git_tree_lookup(&empty_tree, repo1, &empty_tree_id)); cl_git_pass(git_signature_default(&sig, repo1)); - cl_git_pass(git_commit_create(commit1id, repo1, REPO1_REFNAME, sig, + cl_git_pass(git_commit_create(commit1id, repo1, REPO1_REFNAME, sig, sig, NULL, "one", empty_tree, 0, NULL)); - cl_git_pass(git_commit_create_v(commit2id, repo1, REPO1_REFNAME, sig, + cl_git_pass(git_commit_create_v(commit2id, repo1, REPO1_REFNAME, sig, sig, NULL, "two", empty_tree, 1, commit1id)); git_tree_free(empty_tree); @@ -118,7 +118,7 @@ static void do_time_travelling_fetch(git_oid *commit1id, git_oid *commit2id, git_reference *ref; git_reference *ref2; cl_git_pass(git_reference_lookup(&ref, repo1, REPO1_REFNAME)); - cl_git_pass(git_reference_set_target(&ref2, ref, commit1id, + cl_git_pass(git_reference_set_target(&ref2, ref, commit1id, "rollback")); git_reference_free(ref); git_reference_free(ref2); From 2b09b5d7a0e856f6a5b23bfbd38537f8ee472523 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 16 Nov 2021 23:47:14 -0500 Subject: [PATCH 0820/1616] refactor: move headertest into separate test folder --- tests/CMakeLists.txt | 1 + tests/README.md | 3 +++ tests/headertest/CMakeLists.txt | 14 ++++++++++++++ tests/{libgit2 => headertest}/headertest.c | 0 tests/libgit2/CMakeLists.txt | 17 ----------------- 5 files changed, 18 insertions(+), 17 deletions(-) create mode 100644 tests/headertest/CMakeLists.txt rename tests/{libgit2 => headertest}/headertest.c (100%) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d17f5258929..7214d94de9b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,4 +1,5 @@ # The main libgit2 tests tree: this CMakeLists.txt includes the # subprojects that make up core libgit2 support. +add_subdirectory(headertest) add_subdirectory(libgit2) diff --git a/tests/README.md b/tests/README.md index 2e3b2630e37..91b26f592d3 100644 --- a/tests/README.md +++ b/tests/README.md @@ -4,6 +4,9 @@ These are the unit and integration tests for the libgit2 projects. * `clar` This is [clar](https://github.com/clar-test/clar) the common test framework. +* `headertest` + This is a simple project that ensures that our public headers are + compatible with extremely strict compilation options. * `libgit2` These tests exercise the core git functionality in libgit2 itself. * `resources` diff --git a/tests/headertest/CMakeLists.txt b/tests/headertest/CMakeLists.txt new file mode 100644 index 00000000000..c70ce1ae19c --- /dev/null +++ b/tests/headertest/CMakeLists.txt @@ -0,0 +1,14 @@ +# Header file validation project: ensure that we do not publish any sloppy +# definitions in our headers and that a consumer can include +# even when they have aggressive C90 warnings enabled. + +add_executable(headertest headertest.c) +set_target_properties(headertest PROPERTIES C_STANDARD 90) +set_target_properties(headertest PROPERTIES C_EXTENSIONS OFF) +target_include_directories(headertest PRIVATE ${LIBGIT2_INCLUDES}) + +if (MSVC) + target_compile_options(headertest PUBLIC /W4 /WX) +else() + target_compile_options(headertest PUBLIC -Wall -Wextra -pedantic -Werror) +endif() diff --git a/tests/libgit2/headertest.c b/tests/headertest/headertest.c similarity index 100% rename from tests/libgit2/headertest.c rename to tests/headertest/headertest.c diff --git a/tests/libgit2/CMakeLists.txt b/tests/libgit2/CMakeLists.txt index 9ab01077a51..90ae6253e11 100644 --- a/tests/libgit2/CMakeLists.txt +++ b/tests/libgit2/CMakeLists.txt @@ -80,20 +80,3 @@ add_clar_test(ssh -v -sonline::push -sonline::clone::ssh_cert -s add_clar_test(proxy -v -sonline::clone::proxy) add_clar_test(auth_clone -v -sonline::clone::cred) add_clar_test(auth_clone_and_push -v -sonline::clone::push -sonline::push) - -# -# Header file validation project: ensure that we do not publish any sloppy -# definitions in our headers and that a consumer can include -# even when they have aggressive C90 warnings enabled. -# - -add_executable(headertest headertest.c) -set_target_properties(headertest PROPERTIES C_STANDARD 90) -set_target_properties(headertest PROPERTIES C_EXTENSIONS OFF) -target_include_directories(headertest PRIVATE ${LIBGIT2_INCLUDES}) - -if (MSVC) - target_compile_options(headertest PUBLIC /W4 /WX) -else() - target_compile_options(headertest PUBLIC -Wall -Wextra -pedantic -Werror) -endif() From e6d93612e86f50809b941030ef605382895e6f0a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 16 Nov 2021 23:59:43 -0500 Subject: [PATCH 0821/1616] refactor: move utility tests into util --- ci/test.sh | 22 +- tests/CMakeLists.txt | 1 + tests/README.md | 2 + tests/libgit2/core/hashsig.c | 182 ++++++++++++++++ tests/libgit2/core/pool.c | 61 +----- tests/libgit2/diff/userdiff.c | 25 +++ tests/libgit2/path/dotgit.c | 206 ------------------ tests/libgit2/path/validate.c | 63 ++++++ tests/util/CMakeLists.txt | 75 +++++++ tests/{libgit2/core => util}/array.c | 2 +- tests/{libgit2/core => util}/assert.c | 8 +- tests/{libgit2/core => util}/bitvec.c | 2 +- tests/{libgit2/core => util}/copy.c | 6 +- tests/util/crlf.h | 30 +++ tests/{libgit2/core => util}/dirent.c | 18 +- tests/{libgit2/core => util}/encoding.c | 4 +- tests/{libgit2/core => util}/errors.c | 16 +- tests/{libgit2/core => util}/filebuf.c | 24 +-- tests/{libgit2/core => util}/ftruncate.c | 8 +- tests/{libgit2/core => util}/futils.c | 12 +- tests/{libgit2/core => util}/gitstr.c | 235 +++------------------ tests/{libgit2/core => util}/hex.c | 2 +- tests/{libgit2/core => util}/iconv.c | 10 +- tests/{libgit2/core => util}/init.c | 6 +- tests/{libgit2/core => util}/integer.c | 6 +- tests/{libgit2/core => util}/link.c | 50 ++--- tests/{libgit2/core => util}/memmem.c | 6 +- tests/{libgit2/core => util}/mkdir.c | 12 +- tests/{libgit2/core => util}/path.c | 36 ++-- tests/{libgit2 => util}/path/core.c | 62 ------ tests/{libgit2 => util}/path/win32.c | 0 tests/util/pool.c | 62 ++++++ tests/{libgit2/core => util}/posix.c | 14 +- tests/{libgit2/core => util}/pqueue.c | 10 +- tests/util/precompiled.c | 1 + tests/util/precompiled.h | 3 + tests/{libgit2/core => util}/qsort.c | 12 +- tests/{libgit2/core => util}/regexp.c | 46 ++-- tests/{libgit2/core => util}/rmdir.c | 14 +- tests/{libgit2/core => util}/sha1.c | 8 +- tests/{libgit2/core => util}/sortedcache.c | 6 +- tests/{libgit2/core => util}/stat.c | 8 +- tests/{libgit2 => util}/str/basic.c | 0 tests/{libgit2 => util}/str/oom.c | 4 +- tests/{libgit2 => util}/str/percent.c | 0 tests/{libgit2 => util}/str/quote.c | 0 tests/{libgit2 => util}/str/splice.c | 0 tests/{libgit2/core => util}/string.c | 16 +- tests/{libgit2/core => util}/strmap.c | 26 +-- tests/{libgit2/core => util}/strtol.c | 16 +- tests/{libgit2/core => util}/utf8.c | 2 +- tests/{libgit2/core => util}/vector.c | 20 +- tests/{libgit2/core => util}/wildmatch.c | 16 +- tests/{libgit2/core => util}/zstream.c | 8 +- 54 files changed, 708 insertions(+), 776 deletions(-) create mode 100644 tests/libgit2/core/hashsig.c create mode 100644 tests/libgit2/diff/userdiff.c delete mode 100644 tests/libgit2/path/dotgit.c create mode 100644 tests/libgit2/path/validate.c create mode 100644 tests/util/CMakeLists.txt rename tests/{libgit2/core => util}/array.c (97%) rename tests/{libgit2/core => util}/assert.c (92%) rename tests/{libgit2/core => util}/bitvec.c (97%) rename tests/{libgit2/core => util}/copy.c (97%) create mode 100644 tests/util/crlf.h rename tests/{libgit2/core => util}/dirent.c (92%) rename tests/{libgit2/core => util}/encoding.c (93%) rename tests/{libgit2/core => util}/errors.c (93%) rename tests/{libgit2/core => util}/filebuf.c (93%) rename tests/{libgit2/core => util}/ftruncate.c (80%) rename tests/{libgit2/core => util}/futils.c (90%) rename tests/{libgit2/core => util}/gitstr.c (80%) rename tests/{libgit2/core => util}/hex.c (94%) rename tests/{libgit2/core => util}/iconv.c (88%) rename tests/{libgit2/core => util}/init.c (88%) rename tests/{libgit2/core => util}/integer.c (99%) rename tests/{libgit2/core => util}/link.c (92%) rename tests/{libgit2/core => util}/memmem.c (90%) rename tests/{libgit2/core => util}/mkdir.c (97%) rename tests/{libgit2/core => util}/path.c (96%) rename tests/{libgit2 => util}/path/core.c (73%) rename tests/{libgit2 => util}/path/win32.c (100%) create mode 100644 tests/util/pool.c rename tests/{libgit2/core => util}/posix.c (95%) rename tests/{libgit2/core => util}/pqueue.c (91%) create mode 100644 tests/util/precompiled.c create mode 100644 tests/util/precompiled.h rename tests/{libgit2/core => util}/qsort.c (87%) rename tests/{libgit2/core => util}/regexp.c (75%) rename tests/{libgit2/core => util}/rmdir.c (91%) rename tests/{libgit2/core => util}/sha1.c (91%) rename tests/{libgit2/core => util}/sortedcache.c (98%) rename tests/{libgit2/core => util}/stat.c (95%) rename tests/{libgit2 => util}/str/basic.c (100%) rename tests/{libgit2 => util}/str/oom.c (90%) rename tests/{libgit2 => util}/str/percent.c (100%) rename tests/{libgit2 => util}/str/quote.c (100%) rename tests/{libgit2 => util}/str/splice.c (100%) rename tests/{libgit2/core => util}/string.c (94%) rename tests/{libgit2/core => util}/strmap.c (85%) rename tests/{libgit2/core => util}/strtol.c (88%) rename tests/{libgit2/core => util}/utf8.c (95%) rename tests/{libgit2/core => util}/vector.c (96%) rename tests/{libgit2/core => util}/wildmatch.c (96%) rename tests/{libgit2/core => util}/zstream.c (96%) diff --git a/ci/test.sh b/ci/test.sh index a9483977883..ec21519877e 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -156,13 +156,25 @@ fi # Run the tests that do not require network connectivity. +if [ -z "$SKIP_UTILITY_TESTS" ]; then + run_test util +fi + if [ -z "$SKIP_OFFLINE_TESTS" ]; then echo "" echo "##############################################################################" - echo "## Running (offline) tests" + echo "## Running core tests" echo "##############################################################################" + echo "" + echo "Running libgit2 integration (offline) tests" + echo "" run_test offline + + echo "" + echo "Running utility tests" + echo "" + run_test util fi if [ -n "$RUN_INVASIVE_TESTS" ]; then @@ -186,7 +198,7 @@ if [ -z "$SKIP_ONLINE_TESTS" ]; then echo "" echo "##############################################################################" - echo "## Running (online) tests" + echo "## Running networking (online) tests" echo "##############################################################################" export GITTEST_REMOTE_REDIRECT_INITIAL="http://localhost:9000/initial-redirect/libgit2/TestGitRepository" @@ -198,9 +210,9 @@ if [ -z "$SKIP_ONLINE_TESTS" ]; then # Run the online tests that immutably change global state separately # to avoid polluting the test environment. echo "" - echo "##############################################################################" - echo "## Running (online_customcert) tests" - echo "##############################################################################" + echo "Running custom certificate (online_customcert) tests" + echo "" + run_test online_customcert fi diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7214d94de9b..df100e980a9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(headertest) add_subdirectory(libgit2) +add_subdirectory(util) diff --git a/tests/README.md b/tests/README.md index 91b26f592d3..5920b154706 100644 --- a/tests/README.md +++ b/tests/README.md @@ -12,6 +12,8 @@ These are the unit and integration tests for the libgit2 projects. * `resources` These are the resources for the tests, including files and git repositories. +* `util` + These are tests of the common utility library. ## Writing tests for libgit2 diff --git a/tests/libgit2/core/hashsig.c b/tests/libgit2/core/hashsig.c new file mode 100644 index 00000000000..6cadb1c1a4b --- /dev/null +++ b/tests/libgit2/core/hashsig.c @@ -0,0 +1,182 @@ +#include "clar_libgit2.h" +#include "git2/sys/hashsig.h" +#include "futils.h" + +#define SIMILARITY_TEST_DATA_1 \ + "000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \ + "010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \ + "020\n021\n022\n023\n024\n025\n026\n027\n028\n029\n" \ + "030\n031\n032\n033\n034\n035\n036\n037\n038\n039\n" \ + "040\n041\n042\n043\n044\n045\n046\n047\n048\n049\n" + +void test_core_hashsig__similarity_metric(void) +{ + git_hashsig *a, *b; + git_str buf = GIT_STR_INIT; + int sim; + + /* in the first case, we compare data to itself and expect 100% match */ + + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); + cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); + cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); + + cl_assert_equal_i(100, git_hashsig_compare(a, b)); + + git_hashsig_free(a); + git_hashsig_free(b); + + /* if we change just a single byte, how much does that change magnify? */ + + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); + cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); + cl_git_pass(git_str_sets(&buf, + "000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \ + "010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \ + "x020x\n021\n022\n023\n024\n025\n026\n027\n028\n029\n" \ + "030\n031\n032\n033\n034\n035\n036\n037\n038\n039\n" \ + "040\n041\n042\n043\n044\n045\n046\n047\n048\n049\n" + )); + cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); + + sim = git_hashsig_compare(a, b); + + cl_assert_in_range(95, sim, 100); /* expect >95% similarity */ + + git_hashsig_free(a); + git_hashsig_free(b); + + /* let's try comparing data to a superset of itself */ + + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); + cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1 + "050\n051\n052\n053\n054\n055\n056\n057\n058\n059\n")); + cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); + + sim = git_hashsig_compare(a, b); + /* 20% lines added ~= 10% lines changed */ + + cl_assert_in_range(85, sim, 95); /* expect similarity around 90% */ + + git_hashsig_free(a); + git_hashsig_free(b); + + /* what if we keep about half the original data and add half new */ + + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); + cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); + cl_git_pass(git_str_sets(&buf, + "000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \ + "010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \ + "020x\n021\n022\n023\n024\n" \ + "x25\nx26\nx27\nx28\nx29\n" \ + "x30\nx31\nx32\nx33\nx34\nx35\nx36\nx37\nx38\nx39\n" \ + "x40\nx41\nx42\nx43\nx44\nx45\nx46\nx47\nx48\nx49\n" + )); + cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); + + sim = git_hashsig_compare(a, b); + /* 50% lines changed */ + + cl_assert_in_range(40, sim, 60); /* expect in the 40-60% similarity range */ + + git_hashsig_free(a); + git_hashsig_free(b); + + /* lastly, let's check that we can hash file content as well */ + + cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); + cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); + + cl_git_pass(git_futils_mkdir("scratch", 0755, GIT_MKDIR_PATH)); + cl_git_mkfile("scratch/testdata", SIMILARITY_TEST_DATA_1); + cl_git_pass(git_hashsig_create_fromfile( + &b, "scratch/testdata", GIT_HASHSIG_NORMAL)); + + cl_assert_equal_i(100, git_hashsig_compare(a, b)); + + git_hashsig_free(a); + git_hashsig_free(b); + + git_str_dispose(&buf); + git_futils_rmdir_r("scratch", NULL, GIT_RMDIR_REMOVE_FILES); +} + +void test_core_hashsig__similarity_metric_whitespace(void) +{ + git_hashsig *a, *b; + git_str buf = GIT_STR_INIT; + int sim, i, j; + git_hashsig_option_t opt; + const char *tabbed = + " for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\n" + " separator = sep[s];\n" + " expect = expect_values[s];\n" + "\n" + " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\n" + " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\n" + " git_str_join(&buf, separator, a[i], b[j]);\n" + " cl_assert_equal_s(*expect, buf.ptr);\n" + " expect++;\n" + " }\n" + " }\n" + " }\n"; + const char *spaced = + " for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\n" + " separator = sep[s];\n" + " expect = expect_values[s];\n" + "\n" + " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\n" + " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\n" + " git_str_join(&buf, separator, a[i], b[j]);\n" + " cl_assert_equal_s(*expect, buf.ptr);\n" + " expect++;\n" + " }\n" + " }\n" + " }\n"; + const char *crlf_spaced2 = + " for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\r\n" + " separator = sep[s];\r\n" + " expect = expect_values[s];\r\n" + "\r\n" + " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\r\n" + " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\r\n" + " git_str_join(&buf, separator, a[i], b[j]);\r\n" + " cl_assert_equal_s(*expect, buf.ptr);\r\n" + " expect++;\r\n" + " }\r\n" + " }\r\n" + " }\r\n"; + const char *text[3] = { tabbed, spaced, crlf_spaced2 }; + + /* let's try variations of our own code with whitespace changes */ + + for (opt = GIT_HASHSIG_NORMAL; opt <= GIT_HASHSIG_SMART_WHITESPACE; ++opt) { + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + cl_git_pass(git_str_sets(&buf, text[i])); + cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, opt)); + + cl_git_pass(git_str_sets(&buf, text[j])); + cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, opt)); + + sim = git_hashsig_compare(a, b); + + if (opt == GIT_HASHSIG_NORMAL) { + if (i == j) + cl_assert_equal_i(100, sim); + else + cl_assert_in_range(0, sim, 30); /* pretty different */ + } else { + cl_assert_equal_i(100, sim); + } + + git_hashsig_free(a); + git_hashsig_free(b); + } + } + } + + git_str_dispose(&buf); +} diff --git a/tests/libgit2/core/pool.c b/tests/libgit2/core/pool.c index b07da0abd07..5746e35b840 100644 --- a/tests/libgit2/core/pool.c +++ b/tests/libgit2/core/pool.c @@ -2,57 +2,9 @@ #include "pool.h" #include "git2/oid.h" -void test_core_pool__0(void) -{ - int i; - git_pool p; - void *ptr; - - git_pool_init(&p, 1); - - for (i = 1; i < 10000; i *= 2) { - ptr = git_pool_malloc(&p, i); - cl_assert(ptr != NULL); - cl_assert(git_pool__ptr_in_pool(&p, ptr)); - cl_assert(!git_pool__ptr_in_pool(&p, &i)); - } - - git_pool_clear(&p); -} - -void test_core_pool__1(void) -{ - int i; - git_pool p; - - git_pool_init(&p, 1); - p.page_size = 4000; - - for (i = 2010; i > 0; i--) - cl_assert(git_pool_malloc(&p, i) != NULL); - -#ifndef GIT_DEBUG_POOL - /* with fixed page size, allocation must end up with these values */ - cl_assert_equal_i(591, git_pool__open_pages(&p)); -#endif - git_pool_clear(&p); - - git_pool_init(&p, 1); - p.page_size = 4120; - - for (i = 2010; i > 0; i--) - cl_assert(git_pool_malloc(&p, i) != NULL); - -#ifndef GIT_DEBUG_POOL - /* with fixed page size, allocation must end up with these values */ - cl_assert_equal_i(sizeof(void *) == 8 ? 575 : 573, git_pool__open_pages(&p)); -#endif - git_pool_clear(&p); -} - static char to_hex[] = "0123456789abcdef"; -void test_core_pool__2(void) +void test_core_pool__oid(void) { git_pool p; char oid_hex[GIT_OID_HEXSZ]; @@ -79,14 +31,3 @@ void test_core_pool__2(void) #endif git_pool_clear(&p); } - -void test_core_pool__strndup_limit(void) -{ - git_pool p; - - git_pool_init(&p, 1); - /* ensure 64 bit doesn't overflow */ - cl_assert(git_pool_strndup(&p, "foo", (size_t)-1) == NULL); - git_pool_clear(&p); -} - diff --git a/tests/libgit2/diff/userdiff.c b/tests/libgit2/diff/userdiff.c new file mode 100644 index 00000000000..23049400934 --- /dev/null +++ b/tests/libgit2/diff/userdiff.c @@ -0,0 +1,25 @@ +#include "clar_libgit2.h" + +#include "userdiff.h" + +static git_regexp regex; + +void test_diff_userdiff__cleanup(void) +{ + git_regexp_dispose(®ex); +} + +void test_diff_userdiff__compile_userdiff_regexps(void) +{ + size_t idx; + + for (idx = 0; idx < ARRAY_SIZE(builtin_defs); ++idx) { + git_diff_driver_definition ddef = builtin_defs[idx]; + + cl_git_pass(git_regexp_compile(®ex, ddef.fns, ddef.flags)); + git_regexp_dispose(®ex); + + cl_git_pass(git_regexp_compile(®ex, ddef.words, 0)); + git_regexp_dispose(®ex); + } +} diff --git a/tests/libgit2/path/dotgit.c b/tests/libgit2/path/dotgit.c deleted file mode 100644 index 855145f420b..00000000000 --- a/tests/libgit2/path/dotgit.c +++ /dev/null @@ -1,206 +0,0 @@ -#include "clar_libgit2.h" - -#include "path.h" - -static char *gitmodules_altnames[] = { - ".gitmodules", - - /* - * Equivalent to the ".git\u200cmodules" string from git but hard-coded - * as a UTF-8 sequence - */ - ".git\xe2\x80\x8cmodules", - - ".Gitmodules", - ".gitmoduleS", - - ".gitmodules ", - ".gitmodules.", - ".gitmodules ", - ".gitmodules. ", - ".gitmodules .", - ".gitmodules..", - ".gitmodules ", - ".gitmodules. ", - ".gitmodules . ", - ".gitmodules .", - - ".Gitmodules ", - ".Gitmodules.", - ".Gitmodules ", - ".Gitmodules. ", - ".Gitmodules .", - ".Gitmodules..", - ".Gitmodules ", - ".Gitmodules. ", - ".Gitmodules . ", - ".Gitmodules .", - - "GITMOD~1", - "gitmod~1", - "GITMOD~2", - "gitmod~3", - "GITMOD~4", - - "GITMOD~1 ", - "gitmod~2.", - "GITMOD~3 ", - "gitmod~4. ", - "GITMOD~1 .", - "gitmod~2 ", - "GITMOD~3. ", - "gitmod~4 . ", - - "GI7EBA~1", - "gi7eba~9", - - "GI7EB~10", - "GI7EB~11", - "GI7EB~99", - "GI7EB~10", - "GI7E~100", - "GI7E~101", - "GI7E~999", - "~1000000", - "~9999999", -}; - -static char *gitmodules_not_altnames[] = { - ".gitmodules x", - ".gitmodules .x", - - " .gitmodules", - - "..gitmodules", - - "gitmodules", - - ".gitmodule", - - ".gitmodules x ", - ".gitmodules .x", - - "GI7EBA~", - "GI7EBA~0", - "GI7EBA~~1", - "GI7EBA~X", - "Gx7EBA~1", - "GI7EBX~1", - - "GI7EB~1", - "GI7EB~01", - "GI7EB~1", -}; - -void test_path_dotgit__dotgit_modules(void) -{ - size_t i; - - cl_assert_equal_i(1, git_path_is_gitfile(".gitmodules", strlen(".gitmodules"), GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_GENERIC)); - cl_assert_equal_i(1, git_path_is_gitfile(".git\xe2\x80\x8cmodules", strlen(".git\xe2\x80\x8cmodules"), GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_GENERIC)); - - for (i = 0; i < ARRAY_SIZE(gitmodules_altnames); i++) { - const char *name = gitmodules_altnames[i]; - if (!git_path_is_gitfile(name, strlen(name), GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_GENERIC)) - cl_fail(name); - } - - for (i = 0; i < ARRAY_SIZE(gitmodules_not_altnames); i++) { - const char *name = gitmodules_not_altnames[i]; - if (git_path_is_gitfile(name, strlen(name), GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_GENERIC)) - cl_fail(name); - } -} - -void test_path_dotgit__dotgit_modules_symlink(void) -{ - cl_assert_equal_b(true, git_path_is_valid(NULL, ".gitmodules", 0, GIT_PATH_REJECT_DOT_GIT_HFS|GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, ".gitmodules . .::$DATA", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); -} - -void test_path_dotgit__git_fs_path_is_file(void) -{ - cl_git_fail(git_path_is_gitfile("blob", 4, -1, GIT_PATH_FS_HFS)); - cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITIGNORE, GIT_PATH_FS_HFS)); - cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS)); - cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITATTRIBUTES, GIT_PATH_FS_HFS)); - cl_git_fail(git_path_is_gitfile("blob", 4, 3, GIT_PATH_FS_HFS)); -} - -void test_path_dotgit__isvalid_dot_git(void) -{ - cl_assert_equal_b(true, git_path_is_valid(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".git/foo", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.git", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.GIT/bar", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/bar/.Git", 0, 0)); - - cl_assert_equal_b(false, git_path_is_valid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_is_valid(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - - cl_assert_equal_b(true, git_path_is_valid(NULL, "!git", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/!git", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "!git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".tig", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.tig", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".tig/bar", 0, 0)); -} - -void test_path_dotgit__isvalid_dotgit_ntfs(void) -{ - cl_assert_equal_b(true, git_path_is_valid(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".git ", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".git.", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".git.. .", 0, 0)); - - cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1 ", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1.", 0, 0)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1.. .", 0, 0)); - - cl_assert_equal_b(false, git_path_is_valid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - - cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); -} - -void test_path_dotgit__isvalid_dotgit_with_hfs_ignorables(void) -{ - cl_assert_equal_b(false, git_path_is_valid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(false, git_path_is_valid(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_is_valid(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(true, git_path_is_valid(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_is_valid(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); -} diff --git a/tests/libgit2/path/validate.c b/tests/libgit2/path/validate.c new file mode 100644 index 00000000000..df92194538b --- /dev/null +++ b/tests/libgit2/path/validate.c @@ -0,0 +1,63 @@ +#include "clar_libgit2.h" +#include "path.h" + +void test_path_validate__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_path_validate__length(void) +{ + cl_must_pass(git_path_validate_length(NULL, "/foo/bar")); + cl_must_pass(git_path_validate_length(NULL, "C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_length(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_length(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_length(NULL, "\\\\?\\UNC\\server\\C$\\folder")); + +#ifdef GIT_WIN32 + /* + * In the absence of a repo configuration, 259 character paths + * succeed. >= 260 character paths fail. + */ + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\260.txt")); + cl_must_fail(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\longer_than_260.txt")); + + /* count characters, not bytes */ + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_fail(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); +#else + cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/ok.txt")); + cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/260.txt")); + cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); +#endif +} + +void test_path_validate__length_with_core_longpath(void) +{ +#ifdef GIT_WIN32 + git_repository *repo; + git_config *config; + + repo = cl_git_sandbox_init("empty_bare.git"); + + cl_git_pass(git_repository_open(&repo, "empty_bare.git")); + cl_git_pass(git_repository_config(&config, repo)); + + /* fail by default */ + cl_must_fail(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + + /* set core.longpaths explicitly on */ + cl_git_pass(git_config_set_bool(config, "core.longpaths", 1)); + cl_must_pass(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + + /* set core.longpaths explicitly off */ + cl_git_pass(git_config_set_bool(config, "core.longpaths", 0)); + cl_must_fail(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + + git_config_free(config); + git_repository_free(repo); +#endif +} diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt new file mode 100644 index 00000000000..739eb58599c --- /dev/null +++ b/tests/util/CMakeLists.txt @@ -0,0 +1,75 @@ +# util: the unit tests for libgit2's utility library + +set(Python_ADDITIONAL_VERSIONS 3 2.7) +find_package(PythonInterp) + +if(NOT PYTHONINTERP_FOUND) + message(FATAL_ERROR "Could not find a python interpeter, which is needed to build the tests. " + "Make sure python is available, or pass -DBUILD_TESTS=OFF to skip building the tests") +ENDIF() + +set(CLAR_PATH "${libgit2_SOURCE_DIR}/tests/clar") +set(CLAR_FIXTURES "${libgit2_SOURCE_DIR}/tests/resources/") +set(TEST_PATH "${CMAKE_CURRENT_SOURCE_DIR}") +add_definitions(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\") +add_definitions(-DCLAR_TMPDIR=\"libgit2_tests\") +add_definitions(-DCLAR_WIN32_LONGPATHS) +add_definitions(-D_FILE_OFFSET_BITS=64) + +# Ensure that we do not use deprecated functions internally +add_definitions(-DGIT_DEPRECATE_HARD) + +set(TEST_INCLUDES "${CLAR_PATH}" "${TEST_PATH}" "${CMAKE_CURRENT_BINARY_DIR}") +file(GLOB_RECURSE SRC_TEST ${TEST_PATH}/*.c ${TEST_PATH}/*.h ${TEST_PATH}/*/*.c ${TEST_PATH}/*/*.h) +file(GLOB_RECURSE SRC_CLAR ${CLAR_PATH}/*.c ${CLAR_PATH}/*.h) + +if(MSVC_IDE) + list(APPEND SRC_TEST "precompiled.c") +endif() + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clar.suite ${CMAKE_CURRENT_BINARY_DIR}/clar_suite.h + COMMAND ${PYTHON_EXECUTABLE} ${CLAR_PATH}/generate.py -o "${CMAKE_CURRENT_BINARY_DIR}" -f . + DEPENDS ${SRC_TEST} + WORKING_DIRECTORY ${TEST_PATH}) + +set_source_files_properties( + ${CLAR_PATH}/clar.c + PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clar.suite) + +add_executable(util_tests ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS}) + +set_target_properties(util_tests PROPERTIES C_STANDARD 90) +set_target_properties(util_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) + +target_include_directories(util_tests PRIVATE ${TEST_INCLUDES} ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES}) +target_include_directories(util_tests SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES}) +target_link_libraries(util_tests ${LIBGIT2_SYSTEM_LIBS}) + +ide_split_sources(util_tests) + +# +# Old versions of gcc require us to declare our test functions; don't do +# this on newer compilers to avoid unnecessary recompilation. +# +if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) + target_compile_options(util_tests PRIVATE -include "clar_suite.h") +endif() + +if(MSVC_IDE) + # Precompiled headers + set_target_properties(util_tests PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") + set_source_files_properties("precompiled.c" COMPILE_FLAGS "/Ycprecompiled.h") +endif() + +function(ADD_CLAR_TEST name) + if(NOT USE_LEAK_CHECKER STREQUAL "OFF") + add_test(${name} "${libgit2_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${libgit2_BINARY_DIR}/util_tests" ${ARGN}) + else() + add_test(${name} "${libgit2_BINARY_DIR}/util_tests" ${ARGN}) + endif() +endfunction(ADD_CLAR_TEST) + +enable_testing() + +add_clar_test(util -v) diff --git a/tests/libgit2/core/array.c b/tests/util/array.c similarity index 97% rename from tests/libgit2/core/array.c rename to tests/util/array.c index 8e626a50613..39fbc811dc4 100644 --- a/tests/libgit2/core/array.c +++ b/tests/util/array.c @@ -15,7 +15,7 @@ static int int_lookup(const void *k, const void *a) git_array_search(&p, integers, int_lookup, &key)); \ cl_assert_equal_i((n), p); -void test_core_array__bsearch2(void) +void test_array__bsearch2(void) { git_array_t(int) integers = GIT_ARRAY_INIT; int *i, key; diff --git a/tests/libgit2/core/assert.c b/tests/util/assert.c similarity index 92% rename from tests/libgit2/core/assert.c rename to tests/util/assert.c index ef75624b9f7..26c42978754 100644 --- a/tests/libgit2/core/assert.c +++ b/tests/util/assert.c @@ -36,7 +36,7 @@ static const char *bad_returns_string(void) return hello_world; } -void test_core_assert__argument(void) +void test_assert__argument(void) { cl_git_fail(dummy_fn(NULL)); cl_assert(git_error_last()); @@ -51,7 +51,7 @@ void test_core_assert__argument(void) cl_git_pass(dummy_fn("foo")); } -void test_core_assert__argument_with_non_int_return_type(void) +void test_assert__argument_with_non_int_return_type(void) { const char *foo = "foo"; @@ -66,7 +66,7 @@ void test_core_assert__argument_with_non_int_return_type(void) cl_assert_equal_p(foo, fn_returns_string(foo)); } -void test_core_assert__argument_with_void_return_type(void) +void test_assert__argument_with_void_return_type(void) { const char *foo = "foo"; @@ -80,7 +80,7 @@ void test_core_assert__argument_with_void_return_type(void) cl_assert_equal_p(NULL, git_error_last()); } -void test_core_assert__internal(void) +void test_assert__internal(void) { cl_git_fail(bad_math()); cl_assert(git_error_last()); diff --git a/tests/libgit2/core/bitvec.c b/tests/util/bitvec.c similarity index 97% rename from tests/libgit2/core/bitvec.c rename to tests/util/bitvec.c index 48d7b99f093..f7845895bab 100644 --- a/tests/libgit2/core/bitvec.c +++ b/tests/util/bitvec.c @@ -35,7 +35,7 @@ static void check_some_bits(git_bitvec *bv, size_t length) cl_assert_equal_b(i % 3 == 0 || i % 7 == 0, git_bitvec_get(bv, i)); } -void test_core_bitvec__0(void) +void test_bitvec__0(void) { git_bitvec bv; diff --git a/tests/libgit2/core/copy.c b/tests/util/copy.c similarity index 97% rename from tests/libgit2/core/copy.c rename to tests/util/copy.c index 6d22b503d46..9b9f6bafc39 100644 --- a/tests/libgit2/core/copy.c +++ b/tests/util/copy.c @@ -2,7 +2,7 @@ #include "futils.h" #include "posix.h" -void test_core_copy__file(void) +void test_copy__file(void) { struct stat st; const char *content = "This is some stuff to copy\n"; @@ -19,7 +19,7 @@ void test_core_copy__file(void) cl_git_pass(p_unlink("copy_me")); } -void test_core_copy__file_in_dir(void) +void test_copy__file_in_dir(void) { struct stat st; const char *content = "This is some other stuff to copy\n"; @@ -56,7 +56,7 @@ static void assert_hard_link(const char *path) } #endif -void test_core_copy__tree(void) +void test_copy__tree(void) { struct stat st; const char *content = "File content\n"; diff --git a/tests/util/crlf.h b/tests/util/crlf.h new file mode 100644 index 00000000000..786edfc96fa --- /dev/null +++ b/tests/util/crlf.h @@ -0,0 +1,30 @@ +#ifndef INCLUDE_filter_crlf_h__ +#define INCLUDE_filter_crlf_h__ + +/* + * file content for files in the resources/crlf repository + */ + +#define UTF8_BOM "\xEF\xBB\xBF" + +#define ALL_CRLF_TEXT_RAW "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n" +#define ALL_LF_TEXT_RAW "lf\nlf\nlf\nlf\nlf\n" +#define MORE_CRLF_TEXT_RAW "crlf\r\ncrlf\r\nlf\ncrlf\r\ncrlf\r\n" +#define MORE_LF_TEXT_RAW "lf\nlf\ncrlf\r\nlf\nlf\n" + +#define ALL_CRLF_TEXT_AS_CRLF ALL_CRLF_TEXT_RAW +#define ALL_LF_TEXT_AS_CRLF "lf\r\nlf\r\nlf\r\nlf\r\nlf\r\n" +#define MORE_CRLF_TEXT_AS_CRLF "crlf\r\ncrlf\r\nlf\r\ncrlf\r\ncrlf\r\n" +#define MORE_LF_TEXT_AS_CRLF "lf\r\nlf\r\ncrlf\r\nlf\r\nlf\r\n" + +#define ALL_CRLF_TEXT_AS_LF "crlf\ncrlf\ncrlf\ncrlf\n" +#define ALL_LF_TEXT_AS_LF ALL_LF_TEXT_RAW +#define MORE_CRLF_TEXT_AS_LF "crlf\ncrlf\nlf\ncrlf\ncrlf\n" +#define MORE_LF_TEXT_AS_LF "lf\nlf\ncrlf\nlf\nlf\n" + +#define FEW_UTF8_CRLF_RAW "\xe2\x9a\xbdThe rest is ASCII01.\r\nThe rest is ASCII02.\r\nThe rest is ASCII03.\r\nThe rest is ASCII04.\r\nThe rest is ASCII05.\r\nThe rest is ASCII06.\r\nThe rest is ASCII07.\r\nThe rest is ASCII08.\r\nThe rest is ASCII09.\r\nThe rest is ASCII10.\r\nThe rest is ASCII11.\r\nThe rest is ASCII12.\r\nThe rest is ASCII13.\r\nThe rest is ASCII14.\r\nThe rest is ASCII15.\r\nThe rest is ASCII16.\r\nThe rest is ASCII17.\r\nThe rest is ASCII18.\r\nThe rest is ASCII19.\r\nThe rest is ASCII20.\r\nThe rest is ASCII21.\r\nThe rest is ASCII22.\r\n" +#define FEW_UTF8_LF_RAW "\xe2\x9a\xbdThe rest is ASCII01.\nThe rest is ASCII02.\nThe rest is ASCII03.\nThe rest is ASCII04.\nThe rest is ASCII05.\nThe rest is ASCII06.\nThe rest is ASCII07.\nThe rest is ASCII08.\nThe rest is ASCII09.\nThe rest is ASCII10.\nThe rest is ASCII11.\nThe rest is ASCII12.\nThe rest is ASCII13.\nThe rest is ASCII14.\nThe rest is ASCII15.\nThe rest is ASCII16.\nThe rest is ASCII17.\nThe rest is ASCII18.\nThe rest is ASCII19.\nThe rest is ASCII20.\nThe rest is ASCII21.\nThe rest is ASCII22.\n" +#define MANY_UTF8_CRLF_RAW "Lets sing!\r\n\xe2\x99\xab\xe2\x99\xaa\xe2\x99\xac\xe2\x99\xa9\r\nEat food\r\n\xf0\x9f\x8d\x85\xf0\x9f\x8d\x95\r\n" +#define MANY_UTF8_LF_RAW "Lets sing!\n\xe2\x99\xab\xe2\x99\xaa\xe2\x99\xac\xe2\x99\xa9\nEat food\n\xf0\x9f\x8d\x85\xf0\x9f\x8d\x95\n" + +#endif diff --git a/tests/libgit2/core/dirent.c b/tests/util/dirent.c similarity index 92% rename from tests/libgit2/core/dirent.c rename to tests/util/dirent.c index 2419ec7ab92..5840c67e046 100644 --- a/tests/libgit2/core/dirent.c +++ b/tests/util/dirent.c @@ -108,7 +108,7 @@ static walk_data dot = { }; /* make sure that the '.' folder is not traversed */ -void test_core_dirent__dont_traverse_dot(void) +void test_dirent__dont_traverse_dot(void) { cl_set_cleanup(&dirent_cleanup__cb, &dot); setup(&dot); @@ -132,7 +132,7 @@ static walk_data sub = { }; /* traverse a subfolder */ -void test_core_dirent__traverse_subfolder(void) +void test_dirent__traverse_subfolder(void) { cl_set_cleanup(&dirent_cleanup__cb, &sub); setup(&sub); @@ -150,7 +150,7 @@ static walk_data sub_slash = { }; /* traverse a slash-terminated subfolder */ -void test_core_dirent__traverse_slash_terminated_folder(void) +void test_dirent__traverse_slash_terminated_folder(void) { cl_set_cleanup(&dirent_cleanup__cb, &sub_slash); setup(&sub_slash); @@ -171,7 +171,7 @@ static walk_data empty = { }; /* make sure that empty folders are not traversed */ -void test_core_dirent__dont_traverse_empty_folders(void) +void test_dirent__dont_traverse_empty_folders(void) { cl_set_cleanup(&dirent_cleanup__cb, &empty); setup(&empty); @@ -199,7 +199,7 @@ static walk_data odd = { }; /* make sure that strange looking filenames ('..c') are traversed */ -void test_core_dirent__traverse_weird_filenames(void) +void test_dirent__traverse_weird_filenames(void) { cl_set_cleanup(&dirent_cleanup__cb, &odd); setup(&odd); @@ -210,7 +210,7 @@ void test_core_dirent__traverse_weird_filenames(void) } /* test filename length limits */ -void test_core_dirent__length_limits(void) +void test_dirent__length_limits(void) { char *big_filename = (char *)git__malloc(FILENAME_MAX + 1); memset(big_filename, 'a', FILENAME_MAX + 1); @@ -221,7 +221,7 @@ void test_core_dirent__length_limits(void) git__free(big_filename); } -void test_core_dirent__empty_dir(void) +void test_dirent__empty_dir(void) { cl_must_pass(p_mkdir("empty_dir", 0777)); cl_assert(git_fs_path_is_empty_dir("empty_dir")); @@ -256,7 +256,7 @@ static void handle_next(git_fs_path_diriter *diriter, walk_data *walk) } /* test directory iterator */ -void test_core_dirent__diriter_with_fullname(void) +void test_dirent__diriter_with_fullname(void) { git_fs_path_diriter diriter = GIT_FS_PATH_DIRITER_INIT; int error; @@ -276,7 +276,7 @@ void test_core_dirent__diriter_with_fullname(void) check_counts(&sub); } -void test_core_dirent__diriter_at_directory_root(void) +void test_dirent__diriter_at_directory_root(void) { git_fs_path_diriter diriter = GIT_FS_PATH_DIRITER_INIT; const char *sandbox_path, *path; diff --git a/tests/libgit2/core/encoding.c b/tests/util/encoding.c similarity index 93% rename from tests/libgit2/core/encoding.c rename to tests/util/encoding.c index 6cec24679dc..a25a3344393 100644 --- a/tests/libgit2/core/encoding.c +++ b/tests/util/encoding.c @@ -1,7 +1,7 @@ #include "clar_libgit2.h" #include "varint.h" -void test_core_encoding__decode(void) +void test_encoding__decode(void) { const unsigned char *buf = (unsigned char *)"AB"; size_t size; @@ -23,7 +23,7 @@ void test_core_encoding__decode(void) } -void test_core_encoding__encode(void) +void test_encoding__encode(void) { unsigned char buf[100]; cl_assert(git_encode_varint(buf, 100, 65) == 1); diff --git a/tests/libgit2/core/errors.c b/tests/util/errors.c similarity index 93% rename from tests/libgit2/core/errors.c rename to tests/util/errors.c index 386ecdc5f4d..78654a753ae 100644 --- a/tests/libgit2/core/errors.c +++ b/tests/util/errors.c @@ -1,6 +1,6 @@ #include "clar_libgit2.h" -void test_core_errors__public_api(void) +void test_errors__public_api(void) { char *str_in_error; @@ -30,7 +30,7 @@ void test_core_errors__public_api(void) #include "util.h" #include "posix.h" -void test_core_errors__new_school(void) +void test_errors__new_school(void) { char *str_in_error; @@ -86,7 +86,7 @@ void test_core_errors__new_school(void) git_error_clear(); } -void test_core_errors__restore(void) +void test_errors__restore(void) { git_error_state err_state = {0}; @@ -110,7 +110,7 @@ void test_core_errors__restore(void) cl_assert_equal_s("Foo: bar", git_error_last()->message); } -void test_core_errors__free_state(void) +void test_errors__free_state(void) { git_error_state err_state = {0}; @@ -131,7 +131,7 @@ void test_core_errors__free_state(void) cl_assert(git_error_last() == NULL); } -void test_core_errors__restore_oom(void) +void test_errors__restore_oom(void) { git_error_state err_state = {0}; const git_error *oom_error = NULL; @@ -163,7 +163,7 @@ static int test_arraysize_multiply(size_t nelem, size_t size) return 0; } -void test_core_errors__integer_overflow_alloc_multiply(void) +void test_errors__integer_overflow_alloc_multiply(void) { cl_git_pass(test_arraysize_multiply(10, 10)); cl_git_pass(test_arraysize_multiply(1000, 1000)); @@ -185,7 +185,7 @@ static int test_arraysize_add(size_t one, size_t two) return 0; } -void test_core_errors__integer_overflow_alloc_add(void) +void test_errors__integer_overflow_alloc_add(void) { cl_git_pass(test_arraysize_add(10, 10)); cl_git_pass(test_arraysize_add(1000, 1000)); @@ -198,7 +198,7 @@ void test_core_errors__integer_overflow_alloc_add(void) cl_assert_equal_s("Out of memory", git_error_last()->message); } -void test_core_errors__integer_overflow_sets_oom(void) +void test_errors__integer_overflow_sets_oom(void) { size_t out; diff --git a/tests/libgit2/core/filebuf.c b/tests/util/filebuf.c similarity index 93% rename from tests/libgit2/core/filebuf.c rename to tests/util/filebuf.c index 6f40c24569f..29b821144da 100644 --- a/tests/libgit2/core/filebuf.c +++ b/tests/util/filebuf.c @@ -2,7 +2,7 @@ #include "filebuf.h" /* make sure git_filebuf_open doesn't delete an existing lock */ -void test_core_filebuf__0(void) +void test_filebuf__0(void) { git_filebuf file = GIT_FILEBUF_INIT; int fd; @@ -21,7 +21,7 @@ void test_core_filebuf__0(void) /* make sure GIT_FILEBUF_APPEND works as expected */ -void test_core_filebuf__1(void) +void test_filebuf__1(void) { git_filebuf file = GIT_FILEBUF_INIT; char test[] = "test"; @@ -39,7 +39,7 @@ void test_core_filebuf__1(void) /* make sure git_filebuf_write writes large buffer correctly */ -void test_core_filebuf__2(void) +void test_filebuf__2(void) { git_filebuf file = GIT_FILEBUF_INIT; char test[] = "test"; @@ -57,7 +57,7 @@ void test_core_filebuf__2(void) } /* make sure git_filebuf_cleanup clears the buffer */ -void test_core_filebuf__4(void) +void test_filebuf__4(void) { git_filebuf file = GIT_FILEBUF_INIT; char test[] = "test"; @@ -73,7 +73,7 @@ void test_core_filebuf__4(void) /* make sure git_filebuf_commit clears the buffer */ -void test_core_filebuf__5(void) +void test_filebuf__5(void) { git_filebuf file = GIT_FILEBUF_INIT; char test[] = "test"; @@ -93,7 +93,7 @@ void test_core_filebuf__5(void) /* make sure git_filebuf_commit takes umask into account */ -void test_core_filebuf__umask(void) +void test_filebuf__umask(void) { git_filebuf file = GIT_FILEBUF_INIT; char test[] = "test"; @@ -124,7 +124,7 @@ void test_core_filebuf__umask(void) cl_must_pass(p_unlink(test)); } -void test_core_filebuf__rename_error(void) +void test_filebuf__rename_error(void) { git_filebuf file = GIT_FILEBUF_INIT; char *dir = "subdir", *test = "subdir/test", *test_lock = "subdir/test.lock"; @@ -152,7 +152,7 @@ void test_core_filebuf__rename_error(void) cl_assert_equal_i(false, git_fs_path_exists(test_lock)); } -void test_core_filebuf__symlink_follow(void) +void test_filebuf__symlink_follow(void) { git_filebuf file = GIT_FILEBUF_INIT; const char *dir = "linkdir", *source = "linkdir/link"; @@ -186,7 +186,7 @@ void test_core_filebuf__symlink_follow(void) cl_git_pass(git_futils_rmdir_r(dir, NULL, GIT_RMDIR_REMOVE_FILES)); } -void test_core_filebuf__symlink_follow_absolute_paths(void) +void test_filebuf__symlink_follow_absolute_paths(void) { git_filebuf file = GIT_FILEBUF_INIT; git_str source = GIT_STR_INIT, target = GIT_STR_INIT; @@ -214,7 +214,7 @@ void test_core_filebuf__symlink_follow_absolute_paths(void) cl_git_pass(git_futils_rmdir_r("linkdir", NULL, GIT_RMDIR_REMOVE_FILES)); } -void test_core_filebuf__symlink_depth(void) +void test_filebuf__symlink_depth(void) { git_filebuf file = GIT_FILEBUF_INIT; const char *dir = "linkdir", *source = "linkdir/link"; @@ -231,7 +231,7 @@ void test_core_filebuf__symlink_depth(void) cl_git_pass(git_futils_rmdir_r(dir, NULL, GIT_RMDIR_REMOVE_FILES)); } -void test_core_filebuf__hidden_file(void) +void test_filebuf__hidden_file(void) { #ifndef GIT_WIN32 cl_skip(); @@ -257,7 +257,7 @@ void test_core_filebuf__hidden_file(void) #endif } -void test_core_filebuf__detects_directory(void) +void test_filebuf__detects_directory(void) { git_filebuf file = GIT_FILEBUF_INIT; diff --git a/tests/libgit2/core/ftruncate.c b/tests/util/ftruncate.c similarity index 80% rename from tests/libgit2/core/ftruncate.c rename to tests/util/ftruncate.c index 0c731cb1e34..e60e5d96dfe 100644 --- a/tests/libgit2/core/ftruncate.c +++ b/tests/util/ftruncate.c @@ -8,7 +8,7 @@ static const char *filename = "core_ftruncate.txt"; static int fd = -1; -void test_core_ftruncate__initialize(void) +void test_ftruncate__initialize(void) { if (!cl_is_env_set("GITTEST_INVASIVE_FS_SIZE")) cl_skip(); @@ -16,7 +16,7 @@ void test_core_ftruncate__initialize(void) cl_must_pass((fd = p_open(filename, O_CREAT | O_RDWR, 0644))); } -void test_core_ftruncate__cleanup(void) +void test_ftruncate__cleanup(void) { if (fd < 0) return; @@ -37,12 +37,12 @@ static void _extend(off64_t i64len) cl_assert(st.st_size == i64len); } -void test_core_ftruncate__2gb(void) +void test_ftruncate__2gb(void) { _extend(0x80000001); } -void test_core_ftruncate__4gb(void) +void test_ftruncate__4gb(void) { _extend(0x100000001); } diff --git a/tests/libgit2/core/futils.c b/tests/util/futils.c similarity index 90% rename from tests/libgit2/core/futils.c rename to tests/util/futils.c index 3501765f621..993b14d9b03 100644 --- a/tests/libgit2/core/futils.c +++ b/tests/util/futils.c @@ -2,17 +2,17 @@ #include "futils.h" /* Fixture setup and teardown */ -void test_core_futils__initialize(void) +void test_futils__initialize(void) { cl_must_pass(p_mkdir("futils", 0777)); } -void test_core_futils__cleanup(void) +void test_futils__cleanup(void) { cl_fixture_cleanup("futils"); } -void test_core_futils__writebuffer(void) +void test_futils__writebuffer(void) { git_str out = GIT_STR_INIT, append = GIT_STR_INIT; @@ -37,7 +37,7 @@ void test_core_futils__writebuffer(void) git_str_dispose(&append); } -void test_core_futils__write_hidden_file(void) +void test_futils__write_hidden_file(void) { #ifndef GIT_WIN32 cl_skip(); @@ -66,7 +66,7 @@ void test_core_futils__write_hidden_file(void) #endif } -void test_core_futils__recursive_rmdir_keeps_symlink_targets(void) +void test_futils__recursive_rmdir_keeps_symlink_targets(void) { if (!git_fs_path_supports_symlinks(clar_sandbox_path())) cl_skip(); @@ -88,7 +88,7 @@ void test_core_futils__recursive_rmdir_keeps_symlink_targets(void) cl_must_pass(p_unlink("file-target")); } -void test_core_futils__mktmp_umask(void) +void test_futils__mktmp_umask(void) { #ifdef GIT_WIN32 cl_skip(); diff --git a/tests/libgit2/core/gitstr.c b/tests/util/gitstr.c similarity index 80% rename from tests/libgit2/core/gitstr.c rename to tests/util/gitstr.c index 0a624e28c02..aea35565bed 100644 --- a/tests/libgit2/core/gitstr.c +++ b/tests/util/gitstr.c @@ -1,5 +1,4 @@ #include "clar_libgit2.h" -#include "git2/sys/hashsig.h" #include "futils.h" #define TESTSTR "Have you seen that? Have you seeeen that??" @@ -12,7 +11,7 @@ const char *test_4096 = TESTSTR_4096; const char *test_8192 = TESTSTR_8192; /* test basic data concatenation */ -void test_core_gitstr__0(void) +void test_gitstr__0(void) { git_str buf = GIT_STR_INIT; @@ -30,7 +29,7 @@ void test_core_gitstr__0(void) } /* test git_str_printf */ -void test_core_gitstr__1(void) +void test_gitstr__1(void) { git_str buf = GIT_STR_INIT; @@ -46,7 +45,7 @@ void test_core_gitstr__1(void) } /* more thorough test of concatenation options */ -void test_core_gitstr__2(void) +void test_gitstr__2(void) { git_str buf = GIT_STR_INIT; int i; @@ -158,7 +157,7 @@ void test_core_gitstr__2(void) } /* let's do some tests with larger buffers to push our limits */ -void test_core_gitstr__3(void) +void test_gitstr__3(void) { git_str buf = GIT_STR_INIT; @@ -181,7 +180,7 @@ void test_core_gitstr__3(void) } /* let's try some producer/consumer tests */ -void test_core_gitstr__4(void) +void test_gitstr__4(void) { git_str buf = GIT_STR_INIT; int i; @@ -277,7 +276,7 @@ check_buf_append_abc( } /* more variations on append tests */ -void test_core_gitstr__5(void) +void test_gitstr__5(void) { check_buf_append("", "", "", 0, 0); check_buf_append("a", "", "a", 1, 0); @@ -320,7 +319,7 @@ void test_core_gitstr__5(void) } /* test swap */ -void test_core_gitstr__6(void) +void test_gitstr__6(void) { git_str a = GIT_STR_INIT; git_str b = GIT_STR_INIT; @@ -344,7 +343,7 @@ void test_core_gitstr__6(void) /* test detach/attach data */ -void test_core_gitstr__7(void) +void test_gitstr__7(void) { const char *fun = "This is fun"; git_str a = GIT_STR_INIT; @@ -455,7 +454,7 @@ check_joinbuf_n_4( } /* test join */ -void test_core_gitstr__8(void) +void test_gitstr__8(void) { git_str a = GIT_STR_INIT; @@ -536,7 +535,7 @@ void test_core_gitstr__8(void) check_joinbuf_n_4(";abcd;", ";efgh;", ";ijkl;", ";mnop;", ";abcd;efgh;ijkl;mnop;"); } -void test_core_gitstr__9(void) +void test_gitstr__9(void) { git_str buf = GIT_STR_INIT; @@ -579,7 +578,7 @@ void test_core_gitstr__9(void) git_str_dispose(&buf); } -void test_core_gitstr__10(void) +void test_gitstr__10(void) { git_str a = GIT_STR_INIT; @@ -596,7 +595,7 @@ void test_core_gitstr__10(void) git_str_dispose(&a); } -void test_core_gitstr__join3(void) +void test_gitstr__join3(void) { git_str a = GIT_STR_INIT; @@ -628,7 +627,7 @@ void test_core_gitstr__join3(void) git_str_dispose(&a); } -void test_core_gitstr__11(void) +void test_gitstr__11(void) { git_str a = GIT_STR_INIT; char *t1[] = { "nothing", "in", "common" }; @@ -663,7 +662,7 @@ void test_core_gitstr__11(void) git_str_dispose(&a); } -void test_core_gitstr__rfind_variants(void) +void test_gitstr__rfind_variants(void) { git_str a = GIT_STR_INIT; ssize_t len; @@ -687,7 +686,7 @@ void test_core_gitstr__rfind_variants(void) git_str_dispose(&a); } -void test_core_gitstr__puts_escaped(void) +void test_gitstr__puts_escaped(void) { git_str a = GIT_STR_INIT; @@ -721,7 +720,7 @@ static void assert_unescape(char *expected, char *to_unescape) { git_str_dispose(&buf); } -void test_core_gitstr__unescape(void) +void test_gitstr__unescape(void) { assert_unescape("Escaped\\", "Es\\ca\\ped\\"); assert_unescape("Es\\caped\\", "Es\\\\ca\\ped\\\\"); @@ -730,7 +729,7 @@ void test_core_gitstr__unescape(void) assert_unescape("", ""); } -void test_core_gitstr__encode_base64(void) +void test_gitstr__encode_base64(void) { git_str buf = GIT_STR_INIT; @@ -755,7 +754,7 @@ void test_core_gitstr__encode_base64(void) git_str_dispose(&buf); } -void test_core_gitstr__decode_base64(void) +void test_gitstr__decode_base64(void) { git_str buf = GIT_STR_INIT; @@ -776,7 +775,7 @@ void test_core_gitstr__decode_base64(void) git_str_dispose(&buf); } -void test_core_gitstr__encode_base85(void) +void test_gitstr__encode_base85(void) { git_str buf = GIT_STR_INIT; @@ -796,7 +795,7 @@ void test_core_gitstr__encode_base85(void) git_str_dispose(&buf); } -void test_core_gitstr__decode_base85(void) +void test_gitstr__decode_base85(void) { git_str buf = GIT_STR_INIT; @@ -818,7 +817,7 @@ void test_core_gitstr__decode_base85(void) git_str_dispose(&buf); } -void test_core_gitstr__decode_base85_fails_gracefully(void) +void test_gitstr__decode_base85_fails_gracefully(void) { git_str buf = GIT_STR_INIT; @@ -834,7 +833,7 @@ void test_core_gitstr__decode_base85_fails_gracefully(void) git_str_dispose(&buf); } -void test_core_gitstr__classify_with_utf8(void) +void test_gitstr__classify_with_utf8(void) { char *data0 = "Simple text\n"; size_t data0len = 12; @@ -863,193 +862,13 @@ void test_core_gitstr__classify_with_utf8(void) cl_assert(!git_str_contains_nul(&b)); } -#define SIMILARITY_TEST_DATA_1 \ - "000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \ - "010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \ - "020\n021\n022\n023\n024\n025\n026\n027\n028\n029\n" \ - "030\n031\n032\n033\n034\n035\n036\n037\n038\n039\n" \ - "040\n041\n042\n043\n044\n045\n046\n047\n048\n049\n" - -void test_core_gitstr__similarity_metric(void) -{ - git_hashsig *a, *b; - git_str buf = GIT_STR_INIT; - int sim; - - /* in the first case, we compare data to itself and expect 100% match */ - - cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); - cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - - cl_assert_equal_i(100, git_hashsig_compare(a, b)); - - git_hashsig_free(a); - git_hashsig_free(b); - - /* if we change just a single byte, how much does that change magnify? */ - - cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); - cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - cl_git_pass(git_str_sets(&buf, - "000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \ - "010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \ - "x020x\n021\n022\n023\n024\n025\n026\n027\n028\n029\n" \ - "030\n031\n032\n033\n034\n035\n036\n037\n038\n039\n" \ - "040\n041\n042\n043\n044\n045\n046\n047\n048\n049\n" - )); - cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - - sim = git_hashsig_compare(a, b); - - cl_assert_in_range(95, sim, 100); /* expect >95% similarity */ - - git_hashsig_free(a); - git_hashsig_free(b); - - /* let's try comparing data to a superset of itself */ - - cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); - cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1 - "050\n051\n052\n053\n054\n055\n056\n057\n058\n059\n")); - cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - - sim = git_hashsig_compare(a, b); - /* 20% lines added ~= 10% lines changed */ - - cl_assert_in_range(85, sim, 95); /* expect similarity around 90% */ - - git_hashsig_free(a); - git_hashsig_free(b); - - /* what if we keep about half the original data and add half new */ - - cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); - cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - cl_git_pass(git_str_sets(&buf, - "000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \ - "010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \ - "020x\n021\n022\n023\n024\n" \ - "x25\nx26\nx27\nx28\nx29\n" \ - "x30\nx31\nx32\nx33\nx34\nx35\nx36\nx37\nx38\nx39\n" \ - "x40\nx41\nx42\nx43\nx44\nx45\nx46\nx47\nx48\nx49\n" - )); - cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - - sim = git_hashsig_compare(a, b); - /* 50% lines changed */ - - cl_assert_in_range(40, sim, 60); /* expect in the 40-60% similarity range */ - - git_hashsig_free(a); - git_hashsig_free(b); - - /* lastly, let's check that we can hash file content as well */ - - cl_git_pass(git_str_sets(&buf, SIMILARITY_TEST_DATA_1)); - cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL)); - - cl_git_pass(git_futils_mkdir("scratch", 0755, GIT_MKDIR_PATH)); - cl_git_mkfile("scratch/testdata", SIMILARITY_TEST_DATA_1); - cl_git_pass(git_hashsig_create_fromfile( - &b, "scratch/testdata", GIT_HASHSIG_NORMAL)); - - cl_assert_equal_i(100, git_hashsig_compare(a, b)); - - git_hashsig_free(a); - git_hashsig_free(b); - - git_str_dispose(&buf); - git_futils_rmdir_r("scratch", NULL, GIT_RMDIR_REMOVE_FILES); -} - - -void test_core_gitstr__similarity_metric_whitespace(void) -{ - git_hashsig *a, *b; - git_str buf = GIT_STR_INIT; - int sim, i, j; - git_hashsig_option_t opt; - const char *tabbed = - " for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\n" - " separator = sep[s];\n" - " expect = expect_values[s];\n" - "\n" - " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\n" - " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\n" - " git_str_join(&buf, separator, a[i], b[j]);\n" - " cl_assert_equal_s(*expect, buf.ptr);\n" - " expect++;\n" - " }\n" - " }\n" - " }\n"; - const char *spaced = - " for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\n" - " separator = sep[s];\n" - " expect = expect_values[s];\n" - "\n" - " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\n" - " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\n" - " git_str_join(&buf, separator, a[i], b[j]);\n" - " cl_assert_equal_s(*expect, buf.ptr);\n" - " expect++;\n" - " }\n" - " }\n" - " }\n"; - const char *crlf_spaced2 = - " for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\r\n" - " separator = sep[s];\r\n" - " expect = expect_values[s];\r\n" - "\r\n" - " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\r\n" - " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\r\n" - " git_str_join(&buf, separator, a[i], b[j]);\r\n" - " cl_assert_equal_s(*expect, buf.ptr);\r\n" - " expect++;\r\n" - " }\r\n" - " }\r\n" - " }\r\n"; - const char *text[3] = { tabbed, spaced, crlf_spaced2 }; - - /* let's try variations of our own code with whitespace changes */ - - for (opt = GIT_HASHSIG_NORMAL; opt <= GIT_HASHSIG_SMART_WHITESPACE; ++opt) { - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - cl_git_pass(git_str_sets(&buf, text[i])); - cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, opt)); - - cl_git_pass(git_str_sets(&buf, text[j])); - cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, opt)); - - sim = git_hashsig_compare(a, b); - - if (opt == GIT_HASHSIG_NORMAL) { - if (i == j) - cl_assert_equal_i(100, sim); - else - cl_assert_in_range(0, sim, 30); /* pretty different */ - } else { - cl_assert_equal_i(100, sim); - } - - git_hashsig_free(a); - git_hashsig_free(b); - } - } - } - - git_str_dispose(&buf); -} - -#include "../filter/crlf.h" +#include "crlf.h" #define check_buf(expected,buf) do { \ cl_assert_equal_s(expected, buf.ptr); \ cl_assert_equal_sz(strlen(expected), buf.size); } while (0) -void test_core_gitstr__lf_and_crlf_conversions(void) +void test_gitstr__lf_and_crlf_conversions(void) { git_str src = GIT_STR_INIT, tgt = GIT_STR_INIT; @@ -1175,7 +994,7 @@ void test_core_gitstr__lf_and_crlf_conversions(void) git_str_dispose(&tgt); } -void test_core_gitstr__dont_grow_borrowed(void) +void test_gitstr__dont_grow_borrowed(void) { const char *somestring = "blah blah"; git_str buf = GIT_STR_INIT; @@ -1188,7 +1007,7 @@ void test_core_gitstr__dont_grow_borrowed(void) cl_git_fail_with(GIT_EINVALID, git_str_grow(&buf, 1024)); } -void test_core_gitstr__dont_hit_infinite_loop_when_resizing(void) +void test_gitstr__dont_hit_infinite_loop_when_resizing(void) { git_str buf = GIT_STR_INIT; @@ -1204,7 +1023,7 @@ void test_core_gitstr__dont_hit_infinite_loop_when_resizing(void) git_str_dispose(&buf); } -void test_core_gitstr__avoid_printing_into_oom_buffer(void) +void test_gitstr__avoid_printing_into_oom_buffer(void) { git_str buf = GIT_STR_INIT; diff --git a/tests/libgit2/core/hex.c b/tests/util/hex.c similarity index 94% rename from tests/libgit2/core/hex.c rename to tests/util/hex.c index 930af16706c..c5fea0a42f5 100644 --- a/tests/libgit2/core/hex.c +++ b/tests/util/hex.c @@ -1,7 +1,7 @@ #include "clar_libgit2.h" #include "util.h" -void test_core_hex__fromhex(void) +void test_hex__fromhex(void) { /* Passing cases */ cl_assert(git__fromhex('0') == 0x0); diff --git a/tests/libgit2/core/iconv.c b/tests/util/iconv.c similarity index 88% rename from tests/libgit2/core/iconv.c rename to tests/util/iconv.c index af1b4eabf48..e14aebb9908 100644 --- a/tests/libgit2/core/iconv.c +++ b/tests/util/iconv.c @@ -7,21 +7,21 @@ static char *nfc = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D"; static char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"; #endif -void test_core_iconv__initialize(void) +void test_iconv__initialize(void) { #ifdef GIT_USE_ICONV cl_git_pass(git_fs_path_iconv_init_precompose(&ic)); #endif } -void test_core_iconv__cleanup(void) +void test_iconv__cleanup(void) { #ifdef GIT_USE_ICONV git_fs_path_iconv_clear(&ic); #endif } -void test_core_iconv__unchanged(void) +void test_iconv__unchanged(void) { #ifdef GIT_USE_ICONV const char *data = "Ascii data", *original = data; @@ -35,7 +35,7 @@ void test_core_iconv__unchanged(void) #endif } -void test_core_iconv__decomposed_to_precomposed(void) +void test_iconv__decomposed_to_precomposed(void) { #ifdef GIT_USE_ICONV const char *data = nfd; @@ -61,7 +61,7 @@ void test_core_iconv__decomposed_to_precomposed(void) #endif } -void test_core_iconv__precomposed_is_unmodified(void) +void test_iconv__precomposed_is_unmodified(void) { #ifdef GIT_USE_ICONV const char *data = nfc; diff --git a/tests/libgit2/core/init.c b/tests/util/init.c similarity index 88% rename from tests/libgit2/core/init.c rename to tests/util/init.c index eba77ef522f..78b3dd039c7 100644 --- a/tests/libgit2/core/init.c +++ b/tests/util/init.c @@ -1,6 +1,6 @@ #include "clar_libgit2.h" -void test_core_init__returns_count(void) +void test_init__returns_count(void) { /* libgit2_tests initializes us first, so we have an existing * initialization. @@ -12,7 +12,7 @@ void test_core_init__returns_count(void) cl_assert_equal_i(1, git_libgit2_shutdown()); } -void test_core_init__reinit_succeeds(void) +void test_init__reinit_succeeds(void) { cl_assert_equal_i(0, git_libgit2_shutdown()); cl_assert_equal_i(1, git_libgit2_init()); @@ -33,7 +33,7 @@ static void *reinit(void *unused) } #endif -void test_core_init__concurrent_init_succeeds(void) +void test_init__concurrent_init_succeeds(void) { #ifdef GIT_THREADS git_thread threads[10]; diff --git a/tests/libgit2/core/integer.c b/tests/util/integer.c similarity index 99% rename from tests/libgit2/core/integer.c rename to tests/util/integer.c index 18364ba6225..2226ab41e41 100644 --- a/tests/libgit2/core/integer.c +++ b/tests/util/integer.c @@ -1,6 +1,6 @@ #include "clar_libgit2.h" -void test_core_integer__multiply_int64_no_overflow(void) +void test_integer__multiply_int64_no_overflow(void) { #if !defined(git__multiply_int64_overflow) int64_t result = 0; @@ -169,7 +169,7 @@ void test_core_integer__multiply_int64_no_overflow(void) #endif } -void test_core_integer__multiply_int64_overflow(void) +void test_integer__multiply_int64_overflow(void) { #if !defined(git__multiply_int64_overflow) int64_t result = 0; @@ -239,7 +239,7 @@ void test_core_integer__multiply_int64_overflow(void) #endif } -void test_core_integer__multiply_int64_edge_cases(void) +void test_integer__multiply_int64_edge_cases(void) { #if !defined(git__multiply_int64_overflow) int64_t result = 0; diff --git a/tests/libgit2/core/link.c b/tests/util/link.c similarity index 92% rename from tests/libgit2/core/link.c rename to tests/util/link.c index a1e2706b270..46cafada7e9 100644 --- a/tests/libgit2/core/link.c +++ b/tests/util/link.c @@ -5,7 +5,7 @@ # include "win32/reparse.h" #endif -void test_core_link__cleanup(void) +void test_link__cleanup(void) { #ifdef GIT_WIN32 RemoveDirectory("lstat_junction"); @@ -195,7 +195,7 @@ static void do_custom_reparse(const char *path) #endif -void test_core_link__stat_regular_file(void) +void test_link__stat_regular_file(void) { struct stat st; @@ -206,7 +206,7 @@ void test_core_link__stat_regular_file(void) cl_assert_equal_i(24, st.st_size); } -void test_core_link__lstat_regular_file(void) +void test_link__lstat_regular_file(void) { struct stat st; @@ -217,7 +217,7 @@ void test_core_link__lstat_regular_file(void) cl_assert_equal_i(24, st.st_size); } -void test_core_link__stat_symlink(void) +void test_link__stat_symlink(void) { struct stat st; @@ -236,7 +236,7 @@ void test_core_link__stat_symlink(void) cl_assert_equal_i(39, st.st_size); } -void test_core_link__stat_symlink_directory(void) +void test_link__stat_symlink_directory(void) { struct stat st; @@ -253,7 +253,7 @@ void test_core_link__stat_symlink_directory(void) cl_assert(S_ISDIR(st.st_mode)); } -void test_core_link__stat_symlink_chain(void) +void test_link__stat_symlink_chain(void) { struct stat st; @@ -270,7 +270,7 @@ void test_core_link__stat_symlink_chain(void) cl_assert_equal_i(39, st.st_size); } -void test_core_link__stat_dangling_symlink(void) +void test_link__stat_dangling_symlink(void) { struct stat st; @@ -283,7 +283,7 @@ void test_core_link__stat_dangling_symlink(void) cl_must_fail(p_stat("stat_dangling", &st)); } -void test_core_link__stat_dangling_symlink_directory(void) +void test_link__stat_dangling_symlink_directory(void) { struct stat st; @@ -296,7 +296,7 @@ void test_core_link__stat_dangling_symlink_directory(void) cl_must_fail(p_stat("stat_dangling", &st)); } -void test_core_link__lstat_symlink(void) +void test_link__lstat_symlink(void) { git_str target_path = GIT_STR_INIT; struct stat st; @@ -323,7 +323,7 @@ void test_core_link__lstat_symlink(void) git_str_dispose(&target_path); } -void test_core_link__lstat_symlink_directory(void) +void test_link__lstat_symlink_directory(void) { git_str target_path = GIT_STR_INIT; struct stat st; @@ -346,7 +346,7 @@ void test_core_link__lstat_symlink_directory(void) git_str_dispose(&target_path); } -void test_core_link__lstat_dangling_symlink(void) +void test_link__lstat_dangling_symlink(void) { struct stat st; @@ -362,7 +362,7 @@ void test_core_link__lstat_dangling_symlink(void) cl_assert_equal_i(strlen("lstat_nonexistent"), st.st_size); } -void test_core_link__lstat_dangling_symlink_directory(void) +void test_link__lstat_dangling_symlink_directory(void) { struct stat st; @@ -378,7 +378,7 @@ void test_core_link__lstat_dangling_symlink_directory(void) cl_assert_equal_i(strlen("lstat_nonexistent"), st.st_size); } -void test_core_link__stat_junction(void) +void test_link__stat_junction(void) { #ifdef GIT_WIN32 git_str target_path = GIT_STR_INIT; @@ -399,7 +399,7 @@ void test_core_link__stat_junction(void) #endif } -void test_core_link__stat_dangling_junction(void) +void test_link__stat_dangling_junction(void) { #ifdef GIT_WIN32 git_str target_path = GIT_STR_INIT; @@ -419,7 +419,7 @@ void test_core_link__stat_dangling_junction(void) #endif } -void test_core_link__lstat_junction(void) +void test_link__lstat_junction(void) { #ifdef GIT_WIN32 git_str target_path = GIT_STR_INIT; @@ -440,7 +440,7 @@ void test_core_link__lstat_junction(void) #endif } -void test_core_link__lstat_dangling_junction(void) +void test_link__lstat_dangling_junction(void) { #ifdef GIT_WIN32 git_str target_path = GIT_STR_INIT; @@ -463,7 +463,7 @@ void test_core_link__lstat_dangling_junction(void) #endif } -void test_core_link__stat_hardlink(void) +void test_link__stat_hardlink(void) { struct stat st; @@ -482,7 +482,7 @@ void test_core_link__stat_hardlink(void) cl_assert_equal_i(26, st.st_size); } -void test_core_link__lstat_hardlink(void) +void test_link__lstat_hardlink(void) { struct stat st; @@ -501,7 +501,7 @@ void test_core_link__lstat_hardlink(void) cl_assert_equal_i(26, st.st_size); } -void test_core_link__stat_reparse_point(void) +void test_link__stat_reparse_point(void) { #ifdef GIT_WIN32 struct stat st; @@ -519,7 +519,7 @@ void test_core_link__stat_reparse_point(void) #endif } -void test_core_link__lstat_reparse_point(void) +void test_link__lstat_reparse_point(void) { #ifdef GIT_WIN32 struct stat st; @@ -533,7 +533,7 @@ void test_core_link__lstat_reparse_point(void) #endif } -void test_core_link__readlink_nonexistent_file(void) +void test_link__readlink_nonexistent_file(void) { char buf[2048]; @@ -541,7 +541,7 @@ void test_core_link__readlink_nonexistent_file(void) cl_assert_equal_i(ENOENT, errno); } -void test_core_link__readlink_normal_file(void) +void test_link__readlink_normal_file(void) { char buf[2048]; @@ -550,7 +550,7 @@ void test_core_link__readlink_normal_file(void) cl_assert_equal_i(EINVAL, errno); } -void test_core_link__readlink_symlink(void) +void test_link__readlink_symlink(void) { git_str target_path = GIT_STR_INIT; int len; @@ -574,7 +574,7 @@ void test_core_link__readlink_symlink(void) git_str_dispose(&target_path); } -void test_core_link__readlink_dangling(void) +void test_link__readlink_dangling(void) { git_str target_path = GIT_STR_INIT; int len; @@ -597,7 +597,7 @@ void test_core_link__readlink_dangling(void) git_str_dispose(&target_path); } -void test_core_link__readlink_multiple(void) +void test_link__readlink_multiple(void) { git_str target_path = GIT_STR_INIT, path3 = GIT_STR_INIT, path2 = GIT_STR_INIT, path1 = GIT_STR_INIT; diff --git a/tests/libgit2/core/memmem.c b/tests/util/memmem.c similarity index 90% rename from tests/libgit2/core/memmem.c rename to tests/util/memmem.c index fd9986d01b4..1c713e8bd64 100644 --- a/tests/libgit2/core/memmem.c +++ b/tests/util/memmem.c @@ -14,7 +14,7 @@ static void assert_absent(const char *haystack, const char *needle) NULL); } -void test_core_memmem__found(void) +void test_memmem__found(void) { assert_found("a", "a", 0); assert_found("ab", "a", 0); @@ -26,7 +26,7 @@ void test_core_memmem__found(void) assert_found("abababc", "abc", 4); } -void test_core_memmem__absent(void) +void test_memmem__absent(void) { assert_absent("a", "b"); assert_absent("a", "aa"); @@ -36,7 +36,7 @@ void test_core_memmem__absent(void) assert_absent("abcabcabc", "bcac"); } -void test_core_memmem__edgecases(void) +void test_memmem__edgecases(void) { assert_absent(NULL, NULL); assert_absent("a", NULL); diff --git a/tests/libgit2/core/mkdir.c b/tests/util/mkdir.c similarity index 97% rename from tests/libgit2/core/mkdir.c rename to tests/util/mkdir.c index 58a4cfcdb81..8658eec0df2 100644 --- a/tests/libgit2/core/mkdir.c +++ b/tests/util/mkdir.c @@ -12,7 +12,7 @@ static void cleanup_basic_dirs(void *ref) git_futils_rmdir_r("d4", NULL, GIT_RMDIR_EMPTY_HIERARCHY); } -void test_core_mkdir__absolute(void) +void test_mkdir__absolute(void) { git_str path = GIT_STR_INIT; @@ -51,7 +51,7 @@ void test_core_mkdir__absolute(void) git_str_dispose(&path); } -void test_core_mkdir__basic(void) +void test_mkdir__basic(void) { cl_set_cleanup(cleanup_basic_dirs, NULL); @@ -97,7 +97,7 @@ static void cleanup_basedir(void *ref) git_futils_rmdir_r("base", NULL, GIT_RMDIR_EMPTY_HIERARCHY); } -void test_core_mkdir__with_base(void) +void test_mkdir__with_base(void) { #define BASEDIR "base/dir/here" @@ -166,7 +166,7 @@ static void check_mode_at_line( "%07o", (int)expected, (int)(actual & 0777)); } -void test_core_mkdir__chmods(void) +void test_mkdir__chmods(void) { struct stat st; mode_t *old = git__malloc(sizeof(mode_t)); @@ -226,7 +226,7 @@ void test_core_mkdir__chmods(void) check_mode(0777, st.st_mode); } -void test_core_mkdir__keeps_parent_symlinks(void) +void test_mkdir__keeps_parent_symlinks(void) { #ifndef GIT_WIN32 git_str path = GIT_STR_INIT; @@ -260,7 +260,7 @@ void test_core_mkdir__keeps_parent_symlinks(void) #endif } -void test_core_mkdir__mkdir_path_inside_unwriteable_parent(void) +void test_mkdir__mkdir_path_inside_unwriteable_parent(void) { struct stat st; mode_t *old; diff --git a/tests/libgit2/core/path.c b/tests/util/path.c similarity index 96% rename from tests/libgit2/core/path.c rename to tests/util/path.c index a0ae77f1c76..404c17a2b75 100644 --- a/tests/libgit2/core/path.c +++ b/tests/util/path.c @@ -4,12 +4,12 @@ static char *path_save; -void test_core_path__initialize(void) +void test_path__initialize(void) { path_save = cl_getenv("PATH"); } -void test_core_path__cleanup(void) +void test_path__cleanup(void) { cl_setenv("PATH", path_save); git__free(path_save); @@ -90,7 +90,7 @@ static void check_setenv(const char* name, const char* value) } /* get the dirname of a path */ -void test_core_path__00_dirname(void) +void test_path__00_dirname(void) { check_dirname(NULL, "."); check_dirname("", "."); @@ -123,7 +123,7 @@ void test_core_path__00_dirname(void) } /* get the base name of a path */ -void test_core_path__01_basename(void) +void test_path__01_basename(void) { check_basename(NULL, "."); check_basename("", "."); @@ -140,7 +140,7 @@ void test_core_path__01_basename(void) } /* properly join path components */ -void test_core_path__05_joins(void) +void test_path__05_joins(void) { check_joinpath("", "", ""); check_joinpath("", "a", "a"); @@ -175,7 +175,7 @@ void test_core_path__05_joins(void) } /* properly join path components for more than one path */ -void test_core_path__06_long_joins(void) +void test_path__06_long_joins(void) { check_joinpath_n("", "", "", "", ""); check_joinpath_n("", "a", "", "", "a/"); @@ -230,7 +230,7 @@ check_string_to_dir( } /* convert paths to dirs */ -void test_core_path__07_path_to_dir(void) +void test_path__07_path_to_dir(void) { check_path_to_dir("", ""); check_path_to_dir(".", "./"); @@ -258,7 +258,7 @@ void test_core_path__07_path_to_dir(void) } /* join path to itself */ -void test_core_path__08_self_join(void) +void test_path__08_self_join(void) { git_str path = GIT_STR_INIT; size_t asize = 0; @@ -302,7 +302,7 @@ static void check_percent_decoding(const char *expected_result, const char *inpu git_str_dispose(&buf); } -void test_core_path__09_percent_decode(void) +void test_path__09_percent_decode(void) { check_percent_decoding("abcd", "abcd"); check_percent_decoding("a2%", "a2%"); @@ -337,7 +337,7 @@ static void check_fromurl(const char *expected_result, const char *input, int sh #define ABS_PATH_MARKER "/" #endif -void test_core_path__10_fromurl(void) +void test_path__10_fromurl(void) { /* Failing cases */ check_fromurl(NULL, "a", 1); @@ -380,7 +380,7 @@ static int check_one_walkup_step(void *ref, const char *path) return 0; } -void test_core_path__11_walkup(void) +void test_path__11_walkup(void) { git_str p = GIT_STR_INIT; @@ -442,7 +442,7 @@ void test_core_path__11_walkup(void) git_str_dispose(&p); } -void test_core_path__11a_walkup_cancel(void) +void test_path__11a_walkup_cancel(void) { git_str p = GIT_STR_INIT; int cancel[] = { 3, 2, 1, 0 }; @@ -478,7 +478,7 @@ void test_core_path__11a_walkup_cancel(void) git_str_dispose(&p); } -void test_core_path__12_offset_to_path_root(void) +void test_path__12_offset_to_path_root(void) { cl_assert(git_fs_path_root("non/rooted/path") == -1); cl_assert(git_fs_path_root("/rooted/path") == 0); @@ -495,7 +495,7 @@ void test_core_path__12_offset_to_path_root(void) #define NON_EXISTING_FILEPATH "i_hope_i_do_not_exist" -void test_core_path__13_cannot_prettify_a_non_existing_file(void) +void test_path__13_cannot_prettify_a_non_existing_file(void) { git_str p = GIT_STR_INIT; @@ -506,7 +506,7 @@ void test_core_path__13_cannot_prettify_a_non_existing_file(void) git_str_dispose(&p); } -void test_core_path__14_apply_relative(void) +void test_path__14_apply_relative(void) { git_str p = GIT_STR_INIT; @@ -575,7 +575,7 @@ static void assert_resolve_relative( cl_assert_equal_s(expected, buf->ptr); } -void test_core_path__15_resolve_relative(void) +void test_path__15_resolve_relative(void) { git_str buf = GIT_STR_INIT; @@ -663,7 +663,7 @@ void test_core_path__15_resolve_relative(void) #define assert_common_dirlen(i, p, q) \ cl_assert_equal_i((i), git_fs_path_common_dirlen((p), (q))); -void test_core_path__16_resolve_relative(void) +void test_path__16_resolve_relative(void) { assert_common_dirlen(0, "", ""); assert_common_dirlen(0, "", "bar.txt"); @@ -694,7 +694,7 @@ static void fix_path(git_str *s) #endif } -void test_core_path__find_exe_in_path(void) +void test_path__find_exe_in_path(void) { char *orig_path; git_str sandbox_path = GIT_STR_INIT; diff --git a/tests/libgit2/path/core.c b/tests/util/path/core.c similarity index 73% rename from tests/libgit2/path/core.c rename to tests/util/path/core.c index db5359af8b5..f30f6c01b0d 100644 --- a/tests/libgit2/path/core.c +++ b/tests/util/path/core.c @@ -1,11 +1,5 @@ #include "clar_libgit2.h" #include "fs_path.h" -#include "path.h" - -void test_path_core__cleanup(void) -{ - cl_git_sandbox_cleanup(); -} static void test_make_relative( const char *expected_path, @@ -280,62 +274,6 @@ void test_path_core__isvalid_nt_chars(void) cl_assert_equal_b(false, git_fs_path_is_valid("asdf*bar", GIT_FS_PATH_REJECT_NT_CHARS)); } -void test_path_core__validate_workdir(void) -{ - cl_must_pass(git_path_validate_length(NULL, "/foo/bar")); - cl_must_pass(git_path_validate_length(NULL, "C:\\Foo\\Bar")); - cl_must_pass(git_path_validate_length(NULL, "\\\\?\\C:\\Foo\\Bar")); - cl_must_pass(git_path_validate_length(NULL, "\\\\?\\C:\\Foo\\Bar")); - cl_must_pass(git_path_validate_length(NULL, "\\\\?\\UNC\\server\\C$\\folder")); - -#ifdef GIT_WIN32 - /* - * In the absence of a repo configuration, 259 character paths - * succeed. >= 260 character paths fail. - */ - cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); - cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\260.txt")); - cl_must_fail(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\longer_than_260.txt")); - - /* count characters, not bytes */ - cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); - cl_must_fail(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); -#else - cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/ok.txt")); - cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/260.txt")); - cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); - cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); - cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); -#endif -} - -void test_path_core__validate_workdir_with_core_longpath(void) -{ -#ifdef GIT_WIN32 - git_repository *repo; - git_config *config; - - repo = cl_git_sandbox_init("empty_bare.git"); - - cl_git_pass(git_repository_open(&repo, "empty_bare.git")); - cl_git_pass(git_repository_config(&config, repo)); - - /* fail by default */ - cl_must_fail(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); - - /* set core.longpaths explicitly on */ - cl_git_pass(git_config_set_bool(config, "core.longpaths", 1)); - cl_must_pass(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); - - /* set core.longpaths explicitly off */ - cl_git_pass(git_config_set_bool(config, "core.longpaths", 0)); - cl_must_fail(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); - - git_config_free(config); - git_repository_free(repo); -#endif -} - static void test_join_unrooted( const char *expected_result, ssize_t expected_rootlen, diff --git a/tests/libgit2/path/win32.c b/tests/util/path/win32.c similarity index 100% rename from tests/libgit2/path/win32.c rename to tests/util/path/win32.c diff --git a/tests/util/pool.c b/tests/util/pool.c new file mode 100644 index 00000000000..464aad73370 --- /dev/null +++ b/tests/util/pool.c @@ -0,0 +1,62 @@ +#include "clar_libgit2.h" +#include "pool.h" +#include "git2/oid.h" + +void test_pool__0(void) +{ + int i; + git_pool p; + void *ptr; + + git_pool_init(&p, 1); + + for (i = 1; i < 10000; i *= 2) { + ptr = git_pool_malloc(&p, i); + cl_assert(ptr != NULL); + cl_assert(git_pool__ptr_in_pool(&p, ptr)); + cl_assert(!git_pool__ptr_in_pool(&p, &i)); + } + + git_pool_clear(&p); +} + +void test_pool__1(void) +{ + int i; + git_pool p; + + git_pool_init(&p, 1); + p.page_size = 4000; + + for (i = 2010; i > 0; i--) + cl_assert(git_pool_malloc(&p, i) != NULL); + +#ifndef GIT_DEBUG_POOL + /* with fixed page size, allocation must end up with these values */ + cl_assert_equal_i(591, git_pool__open_pages(&p)); +#endif + git_pool_clear(&p); + + git_pool_init(&p, 1); + p.page_size = 4120; + + for (i = 2010; i > 0; i--) + cl_assert(git_pool_malloc(&p, i) != NULL); + +#ifndef GIT_DEBUG_POOL + /* with fixed page size, allocation must end up with these values */ + cl_assert_equal_i(sizeof(void *) == 8 ? 575 : 573, git_pool__open_pages(&p)); +#endif + git_pool_clear(&p); +} + +void test_pool__strndup_limit(void) +{ + git_pool p; + + git_pool_init(&p, 1); + /* ensure 64 bit doesn't overflow */ + cl_assert(git_pool_strndup(&p, "foo", (size_t)-1) == NULL); + git_pool_clear(&p); +} + diff --git a/tests/libgit2/core/posix.c b/tests/util/posix.c similarity index 95% rename from tests/libgit2/core/posix.c rename to tests/util/posix.c index cba312913f4..155f03a952b 100644 --- a/tests/libgit2/core/posix.c +++ b/tests/util/posix.c @@ -13,7 +13,7 @@ #include "futils.h" #include "posix.h" -void test_core_posix__initialize(void) +void test_posix__initialize(void) { #ifdef GIT_WIN32 /* on win32, the WSA context needs to be initialized @@ -35,7 +35,7 @@ static bool supports_ipv6(void) #endif } -void test_core_posix__inet_pton(void) +void test_posix__inet_pton(void) { struct in_addr addr; struct in6_addr addr6; @@ -96,7 +96,7 @@ void test_core_posix__inet_pton(void) cl_assert_equal_i(EAFNOSUPPORT, errno); } -void test_core_posix__utimes(void) +void test_posix__utimes(void) { struct p_timeval times[2]; struct stat st; @@ -145,7 +145,7 @@ void test_core_posix__utimes(void) cl_must_pass(p_unlink("foo")); } -void test_core_posix__unlink_removes_symlink(void) +void test_posix__unlink_removes_symlink(void) { if (!git_fs_path_supports_symlinks(clar_sandbox_path())) clar__skip(); @@ -166,7 +166,7 @@ void test_core_posix__unlink_removes_symlink(void) cl_must_pass(p_rmdir("dir")); } -void test_core_posix__symlink_resolves_to_correct_type(void) +void test_posix__symlink_resolves_to_correct_type(void) { git_str contents = GIT_STR_INIT; @@ -190,7 +190,7 @@ void test_core_posix__symlink_resolves_to_correct_type(void) git_str_dispose(&contents); } -void test_core_posix__relative_symlink(void) +void test_posix__relative_symlink(void) { git_str contents = GIT_STR_INIT; @@ -210,7 +210,7 @@ void test_core_posix__relative_symlink(void) git_str_dispose(&contents); } -void test_core_posix__symlink_to_file_across_dirs(void) +void test_posix__symlink_to_file_across_dirs(void) { git_str contents = GIT_STR_INIT; diff --git a/tests/libgit2/core/pqueue.c b/tests/util/pqueue.c similarity index 91% rename from tests/libgit2/core/pqueue.c rename to tests/util/pqueue.c index 2b90f41721e..38931ecfd74 100644 --- a/tests/libgit2/core/pqueue.c +++ b/tests/util/pqueue.c @@ -7,7 +7,7 @@ static int cmp_ints(const void *v1, const void *v2) return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0; } -void test_core_pqueue__items_are_put_in_order(void) +void test_pqueue__items_are_put_in_order(void) { git_pqueue pq; int i, vals[20]; @@ -36,7 +36,7 @@ void test_core_pqueue__items_are_put_in_order(void) git_pqueue_free(&pq); } -void test_core_pqueue__interleave_inserts_and_pops(void) +void test_pqueue__interleave_inserts_and_pops(void) { git_pqueue pq; int chunk, v, i, vals[200]; @@ -70,7 +70,7 @@ void test_core_pqueue__interleave_inserts_and_pops(void) git_pqueue_free(&pq); } -void test_core_pqueue__max_heap_size(void) +void test_pqueue__max_heap_size(void) { git_pqueue pq; int i, vals[100]; @@ -95,7 +95,7 @@ void test_core_pqueue__max_heap_size(void) git_pqueue_free(&pq); } -void test_core_pqueue__max_heap_size_without_comparison(void) +void test_pqueue__max_heap_size_without_comparison(void) { git_pqueue pq; int i, vals[100] = { 0 }; @@ -123,7 +123,7 @@ static int cmp_ints_like_commit_time(const void *a, const void *b) return *((const int *)a) < *((const int *)b); } -void test_core_pqueue__interleaved_pushes_and_pops(void) +void test_pqueue__interleaved_pushes_and_pops(void) { git_pqueue pq; int i, j, *val; diff --git a/tests/util/precompiled.c b/tests/util/precompiled.c new file mode 100644 index 00000000000..5f656a45da8 --- /dev/null +++ b/tests/util/precompiled.c @@ -0,0 +1 @@ +#include "precompiled.h" diff --git a/tests/util/precompiled.h b/tests/util/precompiled.h new file mode 100644 index 00000000000..6fa21423b4b --- /dev/null +++ b/tests/util/precompiled.h @@ -0,0 +1,3 @@ +#include "common.h" +#include "clar.h" +#include "clar_libgit2.h" diff --git a/tests/libgit2/core/qsort.c b/tests/util/qsort.c similarity index 87% rename from tests/libgit2/core/qsort.c rename to tests/util/qsort.c index efb79e6e97a..d8fa20a0a5d 100644 --- a/tests/libgit2/core/qsort.c +++ b/tests/util/qsort.c @@ -38,37 +38,37 @@ static int cmp_str(const void *_a, const void *_b, void *payload) return strcmp((const char *) _a, (const char *) _b); } -void test_core_qsort__array_with_single_entry(void) +void test_qsort__array_with_single_entry(void) { int a[] = { 10 }; assert_sorted(a, cmp_int); } -void test_core_qsort__array_with_equal_entries(void) +void test_qsort__array_with_equal_entries(void) { int a[] = { 4, 4, 4, 4 }; assert_sorted(a, cmp_int); } -void test_core_qsort__sorted_array(void) +void test_qsort__sorted_array(void) { int a[] = { 1, 10 }; assert_sorted(a, cmp_int); } -void test_core_qsort__unsorted_array(void) +void test_qsort__unsorted_array(void) { int a[] = { 123, 9, 412938, 10, 234, 89 }; assert_sorted(a, cmp_int); } -void test_core_qsort__sorting_strings(void) +void test_qsort__sorting_strings(void) { char *a[] = { "foo", "bar", "baz" }; assert_sorted(a, cmp_str); } -void test_core_qsort__sorting_big_entries(void) +void test_qsort__sorting_big_entries(void) { struct big_entries a[5]; diff --git a/tests/libgit2/core/regexp.c b/tests/util/regexp.c similarity index 75% rename from tests/libgit2/core/regexp.c rename to tests/util/regexp.c index 8db5641e5e4..a76955d59ce 100644 --- a/tests/libgit2/core/regexp.c +++ b/tests/util/regexp.c @@ -3,7 +3,6 @@ #include #include "regexp.h" -#include "userdiff.h" #if LC_ALL > 0 static const char *old_locales[LC_ALL]; @@ -11,14 +10,14 @@ static const char *old_locales[LC_ALL]; static git_regexp regex; -void test_core_regexp__initialize(void) +void test_regexp__initialize(void) { #if LC_ALL > 0 memset(&old_locales, 0, sizeof(old_locales)); #endif } -void test_core_regexp__cleanup(void) +void test_regexp__cleanup(void) { git_regexp_dispose(®ex); } @@ -39,13 +38,13 @@ static void try_set_locale(int category) } -void test_core_regexp__compile_ignores_global_locale_ctype(void) +void test_regexp__compile_ignores_global_locale_ctype(void) { try_set_locale(LC_CTYPE); cl_git_pass(git_regexp_compile(®ex, "[\xc0-\xff][\x80-\xbf]", 0)); } -void test_core_regexp__compile_ignores_global_locale_collate(void) +void test_regexp__compile_ignores_global_locale_collate(void) { #ifdef GIT_WIN32 cl_skip(); @@ -55,7 +54,7 @@ void test_core_regexp__compile_ignores_global_locale_collate(void) cl_git_pass(git_regexp_compile(®ex, "[\xc0-\xff][\x80-\xbf]", 0)); } -void test_core_regexp__regex_matches_digits_with_locale(void) +void test_regexp__regex_matches_digits_with_locale(void) { char c, str[2]; @@ -75,7 +74,7 @@ void test_core_regexp__regex_matches_digits_with_locale(void) } } -void test_core_regexp__regex_matches_alphabet_with_locale(void) +void test_regexp__regex_matches_alphabet_with_locale(void) { char c, str[2]; @@ -99,40 +98,25 @@ void test_core_regexp__regex_matches_alphabet_with_locale(void) } } -void test_core_regexp__compile_userdiff_regexps(void) -{ - size_t idx; - - for (idx = 0; idx < ARRAY_SIZE(builtin_defs); ++idx) { - git_diff_driver_definition ddef = builtin_defs[idx]; - - cl_git_pass(git_regexp_compile(®ex, ddef.fns, ddef.flags)); - git_regexp_dispose(®ex); - - cl_git_pass(git_regexp_compile(®ex, ddef.words, 0)); - git_regexp_dispose(®ex); - } -} - -void test_core_regexp__simple_search_matches(void) +void test_regexp__simple_search_matches(void) { cl_git_pass(git_regexp_compile(®ex, "a", 0)); cl_git_pass(git_regexp_search(®ex, "a", 0, NULL)); } -void test_core_regexp__case_insensitive_search_matches(void) +void test_regexp__case_insensitive_search_matches(void) { cl_git_pass(git_regexp_compile(®ex, "a", GIT_REGEXP_ICASE)); cl_git_pass(git_regexp_search(®ex, "A", 0, NULL)); } -void test_core_regexp__nonmatching_search_returns_error(void) +void test_regexp__nonmatching_search_returns_error(void) { cl_git_pass(git_regexp_compile(®ex, "a", 0)); cl_git_fail(git_regexp_search(®ex, "b", 0, NULL)); } -void test_core_regexp__search_finds_complete_match(void) +void test_regexp__search_finds_complete_match(void) { git_regmatch matches[1]; @@ -142,7 +126,7 @@ void test_core_regexp__search_finds_complete_match(void) cl_assert_equal_i(matches[0].end, 3); } -void test_core_regexp__search_finds_correct_offsets(void) +void test_regexp__search_finds_correct_offsets(void) { git_regmatch matches[3]; @@ -156,7 +140,7 @@ void test_core_regexp__search_finds_correct_offsets(void) cl_assert_equal_i(matches[2].end, 2); } -void test_core_regexp__search_finds_empty_group(void) +void test_regexp__search_finds_empty_group(void) { git_regmatch matches[3]; @@ -170,7 +154,7 @@ void test_core_regexp__search_finds_empty_group(void) cl_assert_equal_i(matches[2].end, 1); } -void test_core_regexp__search_fills_matches_with_first_matching_groups(void) +void test_regexp__search_fills_matches_with_first_matching_groups(void) { git_regmatch matches[2]; @@ -182,7 +166,7 @@ void test_core_regexp__search_fills_matches_with_first_matching_groups(void) cl_assert_equal_i(matches[1].end, 1); } -void test_core_regexp__search_skips_nonmatching_group(void) +void test_regexp__search_skips_nonmatching_group(void) { git_regmatch matches[4]; @@ -198,7 +182,7 @@ void test_core_regexp__search_skips_nonmatching_group(void) cl_assert_equal_i(matches[3].end, 2); } -void test_core_regexp__search_initializes_trailing_nonmatching_groups(void) +void test_regexp__search_initializes_trailing_nonmatching_groups(void) { git_regmatch matches[3]; diff --git a/tests/libgit2/core/rmdir.c b/tests/util/rmdir.c similarity index 91% rename from tests/libgit2/core/rmdir.c rename to tests/util/rmdir.c index f6c66b3a44a..71ec05f9bab 100644 --- a/tests/libgit2/core/rmdir.c +++ b/tests/util/rmdir.c @@ -3,7 +3,7 @@ static const char *empty_tmp_dir = "test_gitfo_rmdir_recurs_test"; -void test_core_rmdir__initialize(void) +void test_rmdir__initialize(void) { git_str path = GIT_STR_INIT; @@ -27,14 +27,14 @@ void test_core_rmdir__initialize(void) git_str_dispose(&path); } -void test_core_rmdir__cleanup(void) +void test_rmdir__cleanup(void) { if (git_fs_path_exists(empty_tmp_dir)) cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_REMOVE_FILES)); } /* make sure empty dir can be deleted recursively */ -void test_core_rmdir__delete_recursive(void) +void test_rmdir__delete_recursive(void) { git_str path = GIT_STR_INIT; cl_git_pass(git_str_joinpath(&path, empty_tmp_dir, "/one")); @@ -48,7 +48,7 @@ void test_core_rmdir__delete_recursive(void) } /* make sure non-empty dir cannot be deleted recursively */ -void test_core_rmdir__fail_to_delete_non_empty_dir(void) +void test_rmdir__fail_to_delete_non_empty_dir(void) { git_str file = GIT_STR_INIT; @@ -66,13 +66,13 @@ void test_core_rmdir__fail_to_delete_non_empty_dir(void) git_str_dispose(&file); } -void test_core_rmdir__keep_base(void) +void test_rmdir__keep_base(void) { cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_SKIP_ROOT)); cl_assert(git_fs_path_exists(empty_tmp_dir)); } -void test_core_rmdir__can_skip_non_empty_dir(void) +void test_rmdir__can_skip_non_empty_dir(void) { git_str file = GIT_STR_INIT; @@ -89,7 +89,7 @@ void test_core_rmdir__can_skip_non_empty_dir(void) git_str_dispose(&file); } -void test_core_rmdir__can_remove_empty_parents(void) +void test_rmdir__can_remove_empty_parents(void) { git_str file = GIT_STR_INIT; diff --git a/tests/libgit2/core/sha1.c b/tests/util/sha1.c similarity index 91% rename from tests/libgit2/core/sha1.c rename to tests/util/sha1.c index 9ccdaab3ce5..68982758e9c 100644 --- a/tests/libgit2/core/sha1.c +++ b/tests/util/sha1.c @@ -3,12 +3,12 @@ #define FIXTURE_DIR "sha1" -void test_core_sha1__initialize(void) +void test_sha1__initialize(void) { cl_fixture_sandbox(FIXTURE_DIR); } -void test_core_sha1__cleanup(void) +void test_sha1__cleanup(void) { cl_fixture_cleanup(FIXTURE_DIR); } @@ -37,7 +37,7 @@ static int sha1_file(unsigned char *out, const char *filename) return ret; } -void test_core_sha1__sum(void) +void test_sha1__sum(void) { unsigned char expected[GIT_HASH_SHA1_SIZE] = { 0x4e, 0x72, 0x67, 0x9e, 0x3e, 0xa4, 0xd0, 0x4e, 0x0c, 0x64, @@ -50,7 +50,7 @@ void test_core_sha1__sum(void) } /* test that sha1 collision detection works when enabled */ -void test_core_sha1__detect_collision_attack(void) +void test_sha1__detect_collision_attack(void) { unsigned char actual[GIT_HASH_SHA1_SIZE]; unsigned char expected[GIT_HASH_SHA1_SIZE] = { diff --git a/tests/libgit2/core/sortedcache.c b/tests/util/sortedcache.c similarity index 98% rename from tests/libgit2/core/sortedcache.c rename to tests/util/sortedcache.c index cb4e34efaaf..72da7aeb1f1 100644 --- a/tests/libgit2/core/sortedcache.c +++ b/tests/util/sortedcache.c @@ -6,7 +6,7 @@ static int name_only_cmp(const void *a, const void *b) return strcmp(a, b); } -void test_core_sortedcache__name_only(void) +void test_sortedcache__name_only(void) { git_sortedcache *sc; void *item; @@ -84,7 +84,7 @@ static void sortedcache_test_struct_free(void *payload, void *item_) item->smaller_value = 0; } -void test_core_sortedcache__in_memory(void) +void test_sortedcache__in_memory(void) { git_sortedcache *sc; sortedcache_test_struct *item; @@ -269,7 +269,7 @@ static void sortedcache_test_reload(git_sortedcache *sc) git_str_dispose(&buf); } -void test_core_sortedcache__on_disk(void) +void test_sortedcache__on_disk(void) { git_sortedcache *sc; sortedcache_test_struct *item; diff --git a/tests/libgit2/core/stat.c b/tests/util/stat.c similarity index 95% rename from tests/libgit2/core/stat.c rename to tests/util/stat.c index 210072fe3a2..84c23fb21eb 100644 --- a/tests/libgit2/core/stat.c +++ b/tests/util/stat.c @@ -2,14 +2,14 @@ #include "futils.h" #include "posix.h" -void test_core_stat__initialize(void) +void test_stat__initialize(void) { cl_git_pass(git_futils_mkdir("root/d1/d2", 0755, GIT_MKDIR_PATH)); cl_git_mkfile("root/file", "whatever\n"); cl_git_mkfile("root/d1/file", "whatever\n"); } -void test_core_stat__cleanup(void) +void test_stat__cleanup(void) { git_futils_rmdir_r("root", NULL, GIT_RMDIR_REMOVE_FILES); } @@ -17,7 +17,7 @@ void test_core_stat__cleanup(void) #define cl_assert_error(val) \ do { err = errno; cl_assert_equal_i((val), err); } while (0) -void test_core_stat__0(void) +void test_stat__0(void) { struct stat st; int err; @@ -94,7 +94,7 @@ void test_core_stat__0(void) cl_assert_error(ENOTDIR); } -void test_core_stat__root(void) +void test_stat__root(void) { const char *sandbox = clar_sandbox_path(); git_str root = GIT_STR_INIT; diff --git a/tests/libgit2/str/basic.c b/tests/util/str/basic.c similarity index 100% rename from tests/libgit2/str/basic.c rename to tests/util/str/basic.c diff --git a/tests/libgit2/str/oom.c b/tests/util/str/oom.c similarity index 90% rename from tests/libgit2/str/oom.c rename to tests/util/str/oom.c index 3d59ead0197..dd3796674f6 100644 --- a/tests/libgit2/str/oom.c +++ b/tests/util/str/oom.c @@ -25,12 +25,12 @@ void test_str_oom__initialize(void) oom_alloc.gmalloc = oom_malloc; oom_alloc.grealloc = oom_realloc; - cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ALLOCATOR, &oom_alloc)); + cl_git_pass(git_allocator_setup(&oom_alloc)); } void test_str_oom__cleanup(void) { - cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ALLOCATOR, NULL)); + cl_git_pass(git_allocator_setup(NULL)); } void test_str_oom__grow(void) diff --git a/tests/libgit2/str/percent.c b/tests/util/str/percent.c similarity index 100% rename from tests/libgit2/str/percent.c rename to tests/util/str/percent.c diff --git a/tests/libgit2/str/quote.c b/tests/util/str/quote.c similarity index 100% rename from tests/libgit2/str/quote.c rename to tests/util/str/quote.c diff --git a/tests/libgit2/str/splice.c b/tests/util/str/splice.c similarity index 100% rename from tests/libgit2/str/splice.c rename to tests/util/str/splice.c diff --git a/tests/libgit2/core/string.c b/tests/util/string.c similarity index 94% rename from tests/libgit2/core/string.c rename to tests/util/string.c index 928dfbcc1fc..de04dea6983 100644 --- a/tests/libgit2/core/string.c +++ b/tests/util/string.c @@ -1,7 +1,7 @@ #include "clar_libgit2.h" /* compare prefixes */ -void test_core_string__0(void) +void test_string__0(void) { cl_assert(git__prefixcmp("", "") == 0); cl_assert(git__prefixcmp("a", "") == 0); @@ -14,7 +14,7 @@ void test_core_string__0(void) } /* compare suffixes */ -void test_core_string__1(void) +void test_string__1(void) { cl_assert(git__suffixcmp("", "") == 0); cl_assert(git__suffixcmp("a", "") == 0); @@ -27,7 +27,7 @@ void test_core_string__1(void) } /* compare icase sorting with case equality */ -void test_core_string__2(void) +void test_string__2(void) { cl_assert(git__strcasesort_cmp("", "") == 0); cl_assert(git__strcasesort_cmp("foo", "foo") == 0); @@ -41,7 +41,7 @@ void test_core_string__2(void) } /* compare prefixes with len */ -void test_core_string__prefixncmp(void) +void test_string__prefixncmp(void) { cl_assert(git__prefixncmp("", 0, "") == 0); cl_assert(git__prefixncmp("a", 1, "") == 0); @@ -58,7 +58,7 @@ void test_core_string__prefixncmp(void) } /* compare prefixes with len */ -void test_core_string__prefixncmp_icase(void) +void test_string__prefixncmp_icase(void) { cl_assert(git__prefixncmp_icase("", 0, "") == 0); cl_assert(git__prefixncmp_icase("a", 1, "") == 0); @@ -82,7 +82,7 @@ void test_core_string__prefixncmp_icase(void) cl_assert(git__prefixncmp_icase("ab", 1, "aa") < 0); } -void test_core_string__strcmp(void) +void test_string__strcmp(void) { cl_assert(git__strcmp("", "") == 0); cl_assert(git__strcmp("foo", "foo") == 0); @@ -103,7 +103,7 @@ void test_core_string__strcmp(void) cl_assert(git__strcmp("\303\215", "\303\255") < 0); } -void test_core_string__strcasecmp(void) +void test_string__strcasecmp(void) { cl_assert(git__strcasecmp("", "") == 0); cl_assert(git__strcasecmp("foo", "foo") == 0); @@ -124,7 +124,7 @@ void test_core_string__strcasecmp(void) cl_assert(git__strcasecmp("\303\215", "\303\255") < 0); } -void test_core_string__strlcmp(void) +void test_string__strlcmp(void) { const char foo[3] = { 'f', 'o', 'o' }; diff --git a/tests/libgit2/core/strmap.c b/tests/util/strmap.c similarity index 85% rename from tests/libgit2/core/strmap.c rename to tests/util/strmap.c index ba118ae1e56..c4f5c864704 100644 --- a/tests/libgit2/core/strmap.c +++ b/tests/util/strmap.c @@ -3,18 +3,18 @@ static git_strmap *g_table; -void test_core_strmap__initialize(void) +void test_strmap__initialize(void) { cl_git_pass(git_strmap_new(&g_table)); cl_assert(g_table != NULL); } -void test_core_strmap__cleanup(void) +void test_strmap__cleanup(void) { git_strmap_free(g_table); } -void test_core_strmap__0(void) +void test_strmap__0(void) { cl_assert(git_strmap_size(g_table) == 0); } @@ -40,7 +40,7 @@ static void insert_strings(git_strmap *table, size_t count) cl_assert_equal_i(git_strmap_size(table), count); } -void test_core_strmap__inserted_strings_can_be_retrieved(void) +void test_strmap__inserted_strings_can_be_retrieved(void) { char *str; int i; @@ -57,7 +57,7 @@ void test_core_strmap__inserted_strings_can_be_retrieved(void) cl_assert(i == 20); } -void test_core_strmap__deleted_entry_cannot_be_retrieved(void) +void test_strmap__deleted_entry_cannot_be_retrieved(void) { char *str; int i; @@ -77,7 +77,7 @@ void test_core_strmap__deleted_entry_cannot_be_retrieved(void) cl_assert_equal_i(i, 19); } -void test_core_strmap__inserting_many_keys_succeeds(void) +void test_strmap__inserting_many_keys_succeeds(void) { char *str; int i; @@ -89,7 +89,7 @@ void test_core_strmap__inserting_many_keys_succeeds(void) cl_assert_equal_i(i, 10000); } -void test_core_strmap__get_succeeds_with_existing_entries(void) +void test_strmap__get_succeeds_with_existing_entries(void) { const char *keys[] = { "foo", "bar", "gobble" }; char *values[] = { "oof", "rab", "elbbog" }; @@ -103,7 +103,7 @@ void test_core_strmap__get_succeeds_with_existing_entries(void) cl_assert_equal_s(git_strmap_get(g_table, "gobble"), "elbbog"); } -void test_core_strmap__get_returns_null_on_nonexisting_key(void) +void test_strmap__get_returns_null_on_nonexisting_key(void) { const char *keys[] = { "foo", "bar", "gobble" }; char *values[] = { "oof", "rab", "elbbog" }; @@ -115,13 +115,13 @@ void test_core_strmap__get_returns_null_on_nonexisting_key(void) cl_assert_equal_p(git_strmap_get(g_table, "other"), NULL); } -void test_core_strmap__set_persists_key(void) +void test_strmap__set_persists_key(void) { cl_git_pass(git_strmap_set(g_table, "foo", "oof")); cl_assert_equal_s(git_strmap_get(g_table, "foo"), "oof"); } -void test_core_strmap__set_persists_multpile_keys(void) +void test_strmap__set_persists_multpile_keys(void) { cl_git_pass(git_strmap_set(g_table, "foo", "oof")); cl_git_pass(git_strmap_set(g_table, "bar", "rab")); @@ -129,7 +129,7 @@ void test_core_strmap__set_persists_multpile_keys(void) cl_assert_equal_s(git_strmap_get(g_table, "bar"), "rab"); } -void test_core_strmap__set_updates_existing_key(void) +void test_strmap__set_updates_existing_key(void) { cl_git_pass(git_strmap_set(g_table, "foo", "oof")); cl_git_pass(git_strmap_set(g_table, "bar", "rab")); @@ -142,7 +142,7 @@ void test_core_strmap__set_updates_existing_key(void) cl_assert_equal_s(git_strmap_get(g_table, "foo"), "other"); } -void test_core_strmap__iteration(void) +void test_strmap__iteration(void) { struct { char *key; @@ -182,7 +182,7 @@ void test_core_strmap__iteration(void) cl_assert_equal_i(n, ARRAY_SIZE(entries)); } -void test_core_strmap__iterating_empty_map_stops_immediately(void) +void test_strmap__iterating_empty_map_stops_immediately(void) { size_t i = 0; diff --git a/tests/libgit2/core/strtol.c b/tests/util/strtol.c similarity index 88% rename from tests/libgit2/core/strtol.c rename to tests/util/strtol.c index 851b91b0a40..54c63ca08fd 100644 --- a/tests/libgit2/core/strtol.c +++ b/tests/util/strtol.c @@ -26,7 +26,7 @@ static void assert_l64_fails(const char *string, int base) cl_git_fail(git__strntol64(&i, string, strlen(string), NULL, base)); } -void test_core_strtol__int32(void) +void test_strtol__int32(void) { assert_l32_parses("123", 123, 10); assert_l32_parses(" +123 ", 123, 10); @@ -43,7 +43,7 @@ void test_core_strtol__int32(void) assert_l32_fails(" -2147483657 ", 10); } -void test_core_strtol__int64(void) +void test_strtol__int64(void) { assert_l64_parses("123", 123, 10); assert_l64_parses(" +123 ", 123, 10); @@ -66,7 +66,7 @@ void test_core_strtol__int64(void) assert_l64_fails("-0x8000000000000001", 16); } -void test_core_strtol__base_autodetection(void) +void test_strtol__base_autodetection(void) { assert_l64_parses("0", 0, 0); assert_l64_parses("00", 0, 0); @@ -78,7 +78,7 @@ void test_core_strtol__base_autodetection(void) assert_l64_parses("0x18", 24, 0); } -void test_core_strtol__buffer_length_with_autodetection_truncates(void) +void test_strtol__buffer_length_with_autodetection_truncates(void) { int64_t i64; @@ -88,7 +88,7 @@ void test_core_strtol__buffer_length_with_autodetection_truncates(void) cl_assert_equal_i(i64, 1); } -void test_core_strtol__buffer_length_truncates(void) +void test_strtol__buffer_length_truncates(void) { int32_t i32; int64_t i64; @@ -100,7 +100,7 @@ void test_core_strtol__buffer_length_truncates(void) cl_assert_equal_i(i64, 1); } -void test_core_strtol__buffer_length_with_leading_ws_truncates(void) +void test_strtol__buffer_length_with_leading_ws_truncates(void) { int64_t i64; @@ -110,7 +110,7 @@ void test_core_strtol__buffer_length_with_leading_ws_truncates(void) cl_assert_equal_i(i64, 1); } -void test_core_strtol__buffer_length_with_leading_sign_truncates(void) +void test_strtol__buffer_length_with_leading_sign_truncates(void) { int64_t i64; @@ -120,7 +120,7 @@ void test_core_strtol__buffer_length_with_leading_sign_truncates(void) cl_assert_equal_i(i64, -1); } -void test_core_strtol__error_message_cuts_off(void) +void test_strtol__error_message_cuts_off(void) { assert_l32_fails("2147483657foobar", 10); cl_assert(strstr(git_error_last()->message, "2147483657") != NULL); diff --git a/tests/libgit2/core/utf8.c b/tests/util/utf8.c similarity index 95% rename from tests/libgit2/core/utf8.c rename to tests/util/utf8.c index e1987b8d631..3987603bb1a 100644 --- a/tests/libgit2/core/utf8.c +++ b/tests/util/utf8.c @@ -1,7 +1,7 @@ #include "clar_libgit2.h" #include "utf8.h" -void test_core_utf8__char_length(void) +void test_utf8__char_length(void) { cl_assert_equal_i(0, git_utf8_char_length("", 0)); cl_assert_equal_i(1, git_utf8_char_length("$", 1)); diff --git a/tests/libgit2/core/vector.c b/tests/util/vector.c similarity index 96% rename from tests/libgit2/core/vector.c rename to tests/util/vector.c index 08cd2c19bf9..04afaa49658 100644 --- a/tests/libgit2/core/vector.c +++ b/tests/util/vector.c @@ -4,7 +4,7 @@ #include "vector.h" /* initial size of 1 would cause writing past array bounds */ -void test_core_vector__0(void) +void test_vector__0(void) { git_vector x; int i; @@ -17,7 +17,7 @@ void test_core_vector__0(void) /* don't read past array bounds on remove() */ -void test_core_vector__1(void) +void test_vector__1(void) { git_vector x; /* make initial capacity exact for our insertions. */ @@ -37,7 +37,7 @@ static int test_cmp(const void *a, const void *b) } /* remove duplicates */ -void test_core_vector__2(void) +void test_vector__2(void) { git_vector x; int *ptrs[2]; @@ -72,7 +72,7 @@ static int compare_them(const void *a, const void *b) } /* insert_sorted */ -void test_core_vector__3(void) +void test_vector__3(void) { git_vector x; intptr_t i; @@ -95,7 +95,7 @@ void test_core_vector__3(void) } /* insert_sorted with duplicates */ -void test_core_vector__4(void) +void test_vector__4(void) { git_vector x; intptr_t i; @@ -158,7 +158,7 @@ static my_struct *alloc_struct(int value) } /* insert_sorted with duplicates and special handling */ -void test_core_vector__5(void) +void test_vector__5(void) { git_vector x; int i; @@ -199,7 +199,7 @@ static int remove_ones(const git_vector *v, size_t idx, void *p) } /* Test removal based on callback */ -void test_core_vector__remove_matching(void) +void test_vector__remove_matching(void) { git_vector x; size_t i; @@ -287,7 +287,7 @@ static void assert_vector(git_vector *x, void *expected[], size_t len) cl_assert(expected[i] == x->contents[i]); } -void test_core_vector__grow_and_shrink(void) +void test_vector__grow_and_shrink(void) { git_vector x = GIT_VECTOR_INIT; void *expected1[] = { @@ -379,7 +379,7 @@ void test_core_vector__grow_and_shrink(void) git_vector_free(&x); } -void test_core_vector__reverse(void) +void test_vector__reverse(void) { git_vector v = GIT_VECTOR_INIT; size_t i; @@ -410,7 +410,7 @@ void test_core_vector__reverse(void) git_vector_free(&v); } -void test_core_vector__dup_empty_vector(void) +void test_vector__dup_empty_vector(void) { git_vector v = GIT_VECTOR_INIT; git_vector dup = GIT_VECTOR_INIT; diff --git a/tests/libgit2/core/wildmatch.c b/tests/util/wildmatch.c similarity index 96% rename from tests/libgit2/core/wildmatch.c rename to tests/util/wildmatch.c index 7c56ee7b836..a5af61ab4b3 100644 --- a/tests/libgit2/core/wildmatch.c +++ b/tests/util/wildmatch.c @@ -26,7 +26,7 @@ static void assert_matches_(const char *string, const char *pattern, * tests for git-ls-files. */ -void test_core_wildmatch__basic_wildmatch(void) +void test_wildmatch__basic_wildmatch(void) { assert_matches("foo", "foo", 1, 1, 1, 1); assert_matches("foo", "bar", 0, 0, 0, 0); @@ -58,7 +58,7 @@ void test_core_wildmatch__basic_wildmatch(void) assert_matches("]", "]", 1, 1, 1, 1); } -void test_core_wildmatch__slash_matching_features(void) +void test_wildmatch__slash_matching_features(void) { assert_matches("foo/baz/bar", "foo*bar", 0, 0, 1, 1); assert_matches("foo/baz/bar", "foo**bar", 0, 0, 1, 1); @@ -90,7 +90,7 @@ void test_core_wildmatch__slash_matching_features(void) assert_matches("deep/foo/bar/baz/x", "**/bar/*/*", 1, 1, 1, 1); } -void test_core_wildmatch__various_additional(void) +void test_wildmatch__various_additional(void) { assert_matches("acrt", "a[c-c]st", 0, 0, 0, 0); assert_matches("acrt", "a[c-c]rt", 1, 1, 1, 1); @@ -115,7 +115,7 @@ void test_core_wildmatch__various_additional(void) assert_matches("foo/bar/baz/to", "**/t[o]", 1, 1, 1, 1); } -void test_core_wildmatch__character_classes(void) +void test_wildmatch__character_classes(void) { assert_matches("a1B", "[[:alpha:]][[:digit:]][[:upper:]]", 1, 1, 1, 1); assert_matches("a", "[[:digit:][:upper:][:space:]]", 0, 1, 0, 1); @@ -136,7 +136,7 @@ void test_core_wildmatch__character_classes(void) assert_matches("q", "[a-c[:digit:]x-z]", 0, 0, 0, 0); } -void test_core_wildmatch__additional_with_malformed(void) +void test_wildmatch__additional_with_malformed(void) { assert_matches("]", "[\\\\-^]", 1, 1, 1, 1); assert_matches("[", "[\\\\-^]", 0, 0, 0, 0); @@ -190,7 +190,7 @@ void test_core_wildmatch__additional_with_malformed(void) assert_matches("-", "[[-\\]]", 0, 0, 0, 0); } -void test_core_wildmatch__recursion(void) +void test_wildmatch__recursion(void) { assert_matches("-adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1", "-*-*-*-*-*-*-12-*-*-*-m-*-*-*", 1, 1, 1, 1); assert_matches("-adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1", "-*-*-*-*-*-*-12-*-*-*-m-*-*-*", 0, 0, 0, 0); @@ -210,7 +210,7 @@ void test_core_wildmatch__recursion(void) assert_matches("ab/cXd/efXg/hi", "**/*X*/**/*i", 1, 1, 1, 1); } -void test_core_wildmatch__pathmatch(void) +void test_wildmatch__pathmatch(void) { assert_matches("foo", "fo", 0, 0, 0, 0); assert_matches("foo/bar", "foo/bar", 1, 1, 1, 1); @@ -229,7 +229,7 @@ void test_core_wildmatch__pathmatch(void) assert_matches("ab/cXd/efXg/hi", "*Xg*i", 0, 0, 1, 1); } -void test_core_wildmatch__case_sensitivity(void) +void test_wildmatch__case_sensitivity(void) { assert_matches("a", "[A-Z]", 0, 1, 0, 1); assert_matches("A", "[A-Z]", 1, 1, 1, 1); diff --git a/tests/libgit2/core/zstream.c b/tests/util/zstream.c similarity index 96% rename from tests/libgit2/core/zstream.c rename to tests/util/zstream.c index c22e81008b6..5c89895c7ce 100644 --- a/tests/libgit2/core/zstream.c +++ b/tests/util/zstream.c @@ -41,7 +41,7 @@ static void assert_zlib_equal_( #define assert_zlib_equal(E,EL,C,CL) \ assert_zlib_equal_(E, EL, C, CL, #EL " != " #CL, __FILE__, __func__, (int)__LINE__) -void test_core_zstream__basic(void) +void test_zstream__basic(void) { git_zstream z = GIT_ZSTREAM_INIT; char out[128]; @@ -57,7 +57,7 @@ void test_core_zstream__basic(void) assert_zlib_equal(data, strlen(data) + 1, out, outlen); } -void test_core_zstream__fails_on_trailing_garbage(void) +void test_zstream__fails_on_trailing_garbage(void) { git_str deflated = GIT_STR_INIT, inflated = GIT_STR_INIT; char i = 0; @@ -76,7 +76,7 @@ void test_core_zstream__fails_on_trailing_garbage(void) git_str_dispose(&inflated); } -void test_core_zstream__buffer(void) +void test_zstream__buffer(void) { git_str out = GIT_STR_INIT; cl_git_pass(git_zstream_deflatebuf(&out, data, strlen(data) + 1)); @@ -140,7 +140,7 @@ static void compress_and_decompress_input_various_ways(git_str *input) git__free(fixed); } -void test_core_zstream__big_data(void) +void test_zstream__big_data(void) { git_str in = GIT_STR_INIT; size_t scan, target; From d02f4f7ad73d91504b9c9eb096989684edbc3417 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 17 Nov 2021 14:31:29 -0500 Subject: [PATCH 0822/1616] cmake: refactor `add_clar_test` into separate module --- ci/test.sh | 4 ---- cmake/AddClarTest.cmake | 7 +++++++ tests/libgit2/CMakeLists.txt | 27 ++++++++++----------------- tests/util/CMakeLists.txt | 11 ++--------- 4 files changed, 19 insertions(+), 30 deletions(-) create mode 100644 cmake/AddClarTest.cmake diff --git a/ci/test.sh b/ci/test.sh index ec21519877e..0815522a952 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -156,10 +156,6 @@ fi # Run the tests that do not require network connectivity. -if [ -z "$SKIP_UTILITY_TESTS" ]; then - run_test util -fi - if [ -z "$SKIP_OFFLINE_TESTS" ]; then echo "" echo "##############################################################################" diff --git a/cmake/AddClarTest.cmake b/cmake/AddClarTest.cmake new file mode 100644 index 00000000000..74394163825 --- /dev/null +++ b/cmake/AddClarTest.cmake @@ -0,0 +1,7 @@ +function(ADD_CLAR_TEST project name) + if(NOT USE_LEAK_CHECKER STREQUAL "OFF") + add_test(${name} "${PROJECT_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${PROJECT_BINARY_DIR}/${project}" ${ARGN}) + else() + add_test(${name} "${PROJECT_BINARY_DIR}/${project}" ${ARGN}) + endif() +endfunction(ADD_CLAR_TEST) diff --git a/tests/libgit2/CMakeLists.txt b/tests/libgit2/CMakeLists.txt index 90ae6253e11..27f421ad629 100644 --- a/tests/libgit2/CMakeLists.txt +++ b/tests/libgit2/CMakeLists.txt @@ -63,20 +63,13 @@ if(MSVC_IDE) set_source_files_properties("precompiled.c" COMPILE_FLAGS "/Ycprecompiled.h") endif() -function(ADD_CLAR_TEST name) - if(NOT USE_LEAK_CHECKER STREQUAL "OFF") - add_test(${name} "${PROJECT_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${PROJECT_BINARY_DIR}/libgit2_tests" ${ARGN}) - else() - add_test(${name} "${PROJECT_BINARY_DIR}/libgit2_tests" ${ARGN}) - endif() -endfunction(ADD_CLAR_TEST) - -add_clar_test(offline -v -xonline) -add_clar_test(invasive -v -score::ftruncate -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root) -add_clar_test(online -v -sonline -xonline::customcert) -add_clar_test(online_customcert -v -sonline::customcert) -add_clar_test(gitdaemon -v -sonline::push) -add_clar_test(ssh -v -sonline::push -sonline::clone::ssh_cert -sonline::clone::ssh_with_paths -sonline::clone::path_whitespace_ssh) -add_clar_test(proxy -v -sonline::clone::proxy) -add_clar_test(auth_clone -v -sonline::clone::cred) -add_clar_test(auth_clone_and_push -v -sonline::clone::push -sonline::push) +include(AddClarTest) +add_clar_test(libgit2_tests offline -v -xonline) +add_clar_test(libgit2_tests invasive -v -score::ftruncate -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root) +add_clar_test(libgit2_tests online -v -sonline -xonline::customcert) +add_clar_test(libgit2_tests online_customcert -v -sonline::customcert) +add_clar_test(libgit2_tests gitdaemon -v -sonline::push) +add_clar_test(libgit2_tests ssh -v -sonline::push -sonline::clone::ssh_cert -sonline::clone::ssh_with_paths -sonline::clone::path_whitespace_ssh) +add_clar_test(libgit2_tests proxy -v -sonline::clone::proxy) +add_clar_test(libgit2_tests auth_clone -v -sonline::clone::cred) +add_clar_test(libgit2_tests auth_clone_and_push -v -sonline::clone::push -sonline::push) diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt index 739eb58599c..232590ffdfc 100644 --- a/tests/util/CMakeLists.txt +++ b/tests/util/CMakeLists.txt @@ -62,14 +62,7 @@ if(MSVC_IDE) set_source_files_properties("precompiled.c" COMPILE_FLAGS "/Ycprecompiled.h") endif() -function(ADD_CLAR_TEST name) - if(NOT USE_LEAK_CHECKER STREQUAL "OFF") - add_test(${name} "${libgit2_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${libgit2_BINARY_DIR}/util_tests" ${ARGN}) - else() - add_test(${name} "${libgit2_BINARY_DIR}/util_tests" ${ARGN}) - endif() -endfunction(ADD_CLAR_TEST) - enable_testing() -add_clar_test(util -v) +include(AddClarTest) +add_clar_test(util_tests util -v) From 3a3ab065f0685202c854e13708ddfd2a93d75e2c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 3 May 2020 23:13:28 +0100 Subject: [PATCH 0823/1616] cli: infrastructure for a cli project Introduce a command-line interface for libgit2. The goal is for it to be git-compatible. 1. The libgit2 developers can more easily dogfood libgit2 to find bugs, and performance issues. 2. There is growing usage of libgit2's examples as a client; libgit2's examples should be exactly that - simple code samples that illustrate libgit2's usage. This satisfies that need directly. 3. By producing a client ourselves, we can better understand the needs of client creators, possibly producing a shared "middleware" for commonly-used pieces of client functionality like interacting with external tools. 4. Since git is the reference implementation, we may be able to benefit from git's unit tests, running their test suite against our CLI to ensure correct behavior. This commit introduces a simple infrastructure for the CLI. The CLI is currently links libgit2 statically; this is because the utility layer is required for libgit2 _but_ shares the error state handling with libgit2 itself. There's no obviously good solution here without introducing annoying indirection or more complexity. Until we can untangle that dependency, this is a good step forward. In the meantime, we link the libgit2 object files, but we do not include the (private) libgit2 headers. This constrains the CLI to the public libgit2 interfaces. --- CMakeLists.txt | 1 + src/CMakeLists.txt | 4 + src/README.md | 2 + src/cli/CMakeLists.txt | 53 +++ src/cli/README.md | 3 + src/cli/cli.h | 18 + src/cli/error.h | 51 +++ src/cli/main.c | 51 +++ src/cli/opt.c | 750 ++++++++++++++++++++++++++++++++++++ src/cli/opt.h | 362 +++++++++++++++++ src/cli/win32/precompiled.c | 1 + src/cli/win32/precompiled.h | 3 + 12 files changed, 1299 insertions(+) create mode 100644 src/cli/CMakeLists.txt create mode 100644 src/cli/README.md create mode 100644 src/cli/cli.h create mode 100644 src/cli/error.h create mode 100644 src/cli/main.c create mode 100644 src/cli/opt.c create mode 100644 src/cli/opt.h create mode 100644 src/cli/win32/precompiled.c create mode 100644 src/cli/win32/precompiled.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 90ecc92fee2..763bd437bc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") # Optional subsystems option(BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON) option(BUILD_TESTS "Build Tests using the Clar suite" ON) +option(BUILD_CLI "Build the command-line interface" ON) option(BUILD_EXAMPLES "Build library usage example apps" OFF) option(BUILD_FUZZERS "Build the fuzz targets" OFF) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8b0d7f44353..72ec410fcae 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -178,6 +178,10 @@ configure_file(features.h.in git2/sys/features.h) add_subdirectory(libgit2) add_subdirectory(util) +if(BUILD_CLI) + add_subdirectory(cli) +endif() + # re-export these to the root so that peer projects (tests, fuzzers, # examples) can use them set(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE) diff --git a/src/README.md b/src/README.md index 12e0d0e4361..10b86c1dcf0 100644 --- a/src/README.md +++ b/src/README.md @@ -3,6 +3,8 @@ This is the source that makes up the core of libgit2 and its related projects. +* `cli` + A git-compatible command-line interface that uses libgit2. * `libgit2` This is the libgit2 project, a cross-platform, linkable library implementation of Git that you can use in your application. diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt new file mode 100644 index 00000000000..4f347e93f0b --- /dev/null +++ b/src/cli/CMakeLists.txt @@ -0,0 +1,53 @@ +set(CLI_INCLUDES + "${libgit2_BINARY_DIR}/src" + "${libgit2_SOURCE_DIR}/src/util" + "${libgit2_SOURCE_DIR}/src/cli" + "${libgit2_SOURCE_DIR}/include") + +if(WIN32 AND NOT CYGWIN) + file(GLOB CLI_SRC_OS win32/*.c) + list(SORT CLI_SRC_OS) +else() + file(GLOB CLI_SRC_OS unix/*.c) + list(SORT CLI_SRC_OS) +endif() + +file(GLOB CLI_SRC_C *.c *.h) +list(SORT CLI_SRC_C) + +# +# The CLI currently needs to be statically linked against libgit2 because +# the utility library uses libgit2's thread-local error buffers. TODO: +# remove this dependency and allow us to dynamically link against libgit2. +# + +if(BUILD_CLI STREQUAL "dynamic") + set(CLI_LIBGIT2_LIBRARY libgit2package) +else() + set(CLI_LIBGIT2_OBJECTS $) +endif() + +# +# Compile and link the CLI +# + +add_executable(git2_cli ${CLI_SRC_C} ${CLI_SRC_OS} ${CLI_OBJECTS} + $ + ${CLI_LIBGIT2_OBJECTS} + ${LIBGIT2_DEPENDENCY_OBJECTS}) +target_link_libraries(git2_cli ${CLI_LIBGIT2_LIBRARY} ${LIBGIT2_SYSTEM_LIBS}) + +set_target_properties(git2_cli PROPERTIES C_STANDARD 90) +set_target_properties(git2_cli PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR}) + +ide_split_sources(git2_cli) + +target_include_directories(git2_cli PRIVATE ${CLI_INCLUDES}) + +if(MSVC_IDE) + # Precompiled headers + set_target_properties(git2_cli PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") + set_source_files_properties(win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h") +endif() + +install(TARGETS git2_cli RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/cli/README.md b/src/cli/README.md new file mode 100644 index 00000000000..eefd2ff27f6 --- /dev/null +++ b/src/cli/README.md @@ -0,0 +1,3 @@ +# cli + +A git-compatible command-line interface that uses libgit2. diff --git a/src/cli/cli.h b/src/cli/cli.h new file mode 100644 index 00000000000..a27081d873f --- /dev/null +++ b/src/cli/cli.h @@ -0,0 +1,18 @@ +/* + * 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 CLI_cli_h__ +#define CLI_cli_h__ + +#define PROGRAM_NAME "git2" + +#include "git2_util.h" + +#include "error.h" +#include "opt.h" + +#endif /* CLI_cli_h__ */ diff --git a/src/cli/error.h b/src/cli/error.h new file mode 100644 index 00000000000..cce7a54c093 --- /dev/null +++ b/src/cli/error.h @@ -0,0 +1,51 @@ +/* + * 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 CLI_error_h__ +#define CLI_error_h__ + +#include "cli.h" +#include + +#define CLI_EXIT_OK 0 +#define CLI_EXIT_ERROR 1 +#define CLI_EXIT_OS 128 +#define CLI_EXIT_GIT 128 +#define CLI_EXIT_USAGE 129 + +#define cli_error__print(fmt) do { \ + va_list ap; \ + va_start(ap, fmt); \ + fprintf(stderr, "%s: ", PROGRAM_NAME); \ + vfprintf(stderr, fmt, ap); \ + fprintf(stderr, "\n"); \ + va_end(ap); \ + } while(0) + +GIT_INLINE(int) cli_error(const char *fmt, ...) +{ + cli_error__print(fmt); + return CLI_EXIT_ERROR; +} + +GIT_INLINE(int) cli_error_usage(const char *fmt, ...) +{ + cli_error__print(fmt); + return CLI_EXIT_USAGE; +} + +GIT_INLINE(int) cli_error_git(void) +{ + const git_error *err = git_error_last(); + fprintf(stderr, "%s: %s\n", PROGRAM_NAME, + err ? err->message : "unknown error"); + return CLI_EXIT_GIT; +} + +#define cli_error_os() (perror(PROGRAM_NAME), CLI_EXIT_OS) + +#endif /* CLI_error_h__ */ diff --git a/src/cli/main.c b/src/cli/main.c new file mode 100644 index 00000000000..709f6b45217 --- /dev/null +++ b/src/cli/main.c @@ -0,0 +1,51 @@ +/* + * 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 +#include +#include "cli.h" + +static int show_version = 0; + +static const cli_opt_spec common_opts[] = { + { CLI_OPT_TYPE_SWITCH, "version", 0, &show_version, 1, + CLI_OPT_USAGE_DEFAULT, NULL, "display the version" }, + { 0 } +}; + +int main(int argc, char **argv) +{ + cli_opt_parser optparser; + cli_opt opt; + int ret = 0; + + if (git_libgit2_init() < 0) { + cli_error("failed to initialize libgit2"); + exit(CLI_EXIT_GIT); + } + + cli_opt_parser_init(&optparser, common_opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU); + + /* Parse the top-level (common) options and command information */ + while (cli_opt_parser_next(&opt, &optparser)) { + if (!opt.spec) { + cli_opt_status_fprint(stderr, PROGRAM_NAME, &opt); + cli_opt_usage_fprint(stderr, PROGRAM_NAME, common_opts); + ret = CLI_EXIT_USAGE; + goto done; + } + } + + if (show_version) { + printf("%s version %s\n", PROGRAM_NAME, LIBGIT2_VERSION); + goto done; + } + +done: + git_libgit2_shutdown(); + return ret; +} diff --git a/src/cli/opt.c b/src/cli/opt.c new file mode 100644 index 00000000000..11faa92c56e --- /dev/null +++ b/src/cli/opt.c @@ -0,0 +1,750 @@ +/* + * Copyright (c), Edward Thomson + * All rights reserved. + * + * This file is part of adopt, distributed under the MIT license. + * For full terms and conditions, see the included LICENSE file. + * + * THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT. + * + * This file was produced by using the `rename.pl` script included with + * adopt. The command-line specified was: + * + * ./rename.pl cli_opt --filename=opt --include=cli.h --inline=GIT_INLINE --header-guard=CLI_opt_h__ --lowercase-status + */ + +#include +#include +#include +#include +#include + +#include "cli.h" +#include "opt.h" + +#ifdef _WIN32 +# include +#else +# include +# include +#endif + +#ifdef _MSC_VER +# define alloca _alloca +#endif + +#define spec_is_option_type(x) \ + ((x)->type == CLI_OPT_TYPE_BOOL || \ + (x)->type == CLI_OPT_TYPE_SWITCH || \ + (x)->type == CLI_OPT_TYPE_VALUE) + +GIT_INLINE(const cli_opt_spec *) spec_for_long( + int *is_negated, + int *has_value, + const char **value, + const cli_opt_parser *parser, + const char *arg) +{ + const cli_opt_spec *spec; + char *eql; + size_t eql_pos; + + eql = strchr(arg, '='); + eql_pos = (eql = strchr(arg, '=')) ? (size_t)(eql - arg) : strlen(arg); + + for (spec = parser->specs; spec->type; ++spec) { + /* Handle -- (everything after this is literal) */ + if (spec->type == CLI_OPT_TYPE_LITERAL && arg[0] == '\0') + return spec; + + /* Handle --no-option arguments for bool types */ + if (spec->type == CLI_OPT_TYPE_BOOL && + strncmp(arg, "no-", 3) == 0 && + strcmp(arg + 3, spec->name) == 0) { + *is_negated = 1; + return spec; + } + + /* Handle the typical --option arguments */ + if (spec_is_option_type(spec) && + spec->name && + strcmp(arg, spec->name) == 0) + return spec; + + /* Handle --option=value arguments */ + if (spec->type == CLI_OPT_TYPE_VALUE && + eql && + strncmp(arg, spec->name, eql_pos) == 0 && + spec->name[eql_pos] == '\0') { + *has_value = 1; + *value = arg[eql_pos + 1] ? &arg[eql_pos + 1] : NULL; + return spec; + } + } + + return NULL; +} + +GIT_INLINE(const cli_opt_spec *) spec_for_short( + const char **value, + const cli_opt_parser *parser, + const char *arg) +{ + const cli_opt_spec *spec; + + for (spec = parser->specs; spec->type; ++spec) { + /* Handle -svalue short options with a value */ + if (spec->type == CLI_OPT_TYPE_VALUE && + arg[0] == spec->alias && + arg[1] != '\0') { + *value = &arg[1]; + return spec; + } + + /* Handle typical -s short options */ + if (arg[0] == spec->alias) { + *value = NULL; + return spec; + } + } + + return NULL; +} + +GIT_INLINE(const cli_opt_spec *) spec_for_arg(cli_opt_parser *parser) +{ + const cli_opt_spec *spec; + size_t args = 0; + + for (spec = parser->specs; spec->type; ++spec) { + if (spec->type == CLI_OPT_TYPE_ARG) { + if (args == parser->arg_idx) { + parser->arg_idx++; + return spec; + } + + args++; + } + + if (spec->type == CLI_OPT_TYPE_ARGS && args == parser->arg_idx) + return spec; + } + + return NULL; +} + +GIT_INLINE(int) spec_is_choice(const cli_opt_spec *spec) +{ + return ((spec + 1)->type && + ((spec + 1)->usage & CLI_OPT_USAGE_CHOICE)); +} + +/* + * If we have a choice with switches and bare arguments, and we see + * the switch, then we no longer expect the bare argument. + */ +GIT_INLINE(void) consume_choices(const cli_opt_spec *spec, cli_opt_parser *parser) +{ + /* back up to the beginning of the choices */ + while (spec->type && (spec->usage & CLI_OPT_USAGE_CHOICE)) + --spec; + + if (!spec_is_choice(spec)) + return; + + do { + if (spec->type == CLI_OPT_TYPE_ARG) + parser->arg_idx++; + ++spec; + } while(spec->type && (spec->usage & CLI_OPT_USAGE_CHOICE)); +} + +static cli_opt_status_t parse_long(cli_opt *opt, cli_opt_parser *parser) +{ + const cli_opt_spec *spec; + char *arg = parser->args[parser->idx++]; + const char *value = NULL; + int is_negated = 0, has_value = 0; + + opt->arg = arg; + + if ((spec = spec_for_long(&is_negated, &has_value, &value, parser, &arg[2])) == NULL) { + opt->spec = NULL; + opt->status = CLI_OPT_STATUS_UNKNOWN_OPTION; + goto done; + } + + opt->spec = spec; + + /* Future options parsed as literal */ + if (spec->type == CLI_OPT_TYPE_LITERAL) + parser->in_literal = 1; + + /* --bool or --no-bool */ + else if (spec->type == CLI_OPT_TYPE_BOOL && spec->value) + *((int *)spec->value) = !is_negated; + + /* --accumulate */ + else if (spec->type == CLI_OPT_TYPE_ACCUMULATOR && spec->value) + *((int *)spec->value) += spec->switch_value ? spec->switch_value : 1; + + /* --switch */ + else if (spec->type == CLI_OPT_TYPE_SWITCH && spec->value) + *((int *)spec->value) = spec->switch_value; + + /* Parse values as "--foo=bar" or "--foo bar" */ + else if (spec->type == CLI_OPT_TYPE_VALUE) { + if (has_value) + opt->value = (char *)value; + else if ((parser->idx + 1) <= parser->args_len) + opt->value = parser->args[parser->idx++]; + + if (spec->value) + *((char **)spec->value) = opt->value; + } + + /* Required argument was not provided */ + if (spec->type == CLI_OPT_TYPE_VALUE && + !opt->value && + !(spec->usage & CLI_OPT_USAGE_VALUE_OPTIONAL)) + opt->status = CLI_OPT_STATUS_MISSING_VALUE; + else + opt->status = CLI_OPT_STATUS_OK; + + consume_choices(opt->spec, parser); + +done: + return opt->status; +} + +static cli_opt_status_t parse_short(cli_opt *opt, cli_opt_parser *parser) +{ + const cli_opt_spec *spec; + char *arg = parser->args[parser->idx++]; + const char *value; + + opt->arg = arg; + + if ((spec = spec_for_short(&value, parser, &arg[1 + parser->in_short])) == NULL) { + opt->spec = NULL; + opt->status = CLI_OPT_STATUS_UNKNOWN_OPTION; + goto done; + } + + opt->spec = spec; + + if (spec->type == CLI_OPT_TYPE_BOOL && spec->value) + *((int *)spec->value) = 1; + + else if (spec->type == CLI_OPT_TYPE_ACCUMULATOR && spec->value) + *((int *)spec->value) += spec->switch_value ? spec->switch_value : 1; + + else if (spec->type == CLI_OPT_TYPE_SWITCH && spec->value) + *((int *)spec->value) = spec->switch_value; + + /* Parse values as "-ifoo" or "-i foo" */ + else if (spec->type == CLI_OPT_TYPE_VALUE) { + if (value) + opt->value = (char *)value; + else if ((parser->idx + 1) <= parser->args_len) + opt->value = parser->args[parser->idx++]; + + if (spec->value) + *((char **)spec->value) = opt->value; + } + + /* + * Handle compressed short arguments, like "-fbcd"; see if there's + * another character after the one we processed. If not, advance + * the parser index. + */ + if (spec->type != CLI_OPT_TYPE_VALUE && arg[2 + parser->in_short] != '\0') { + parser->in_short++; + parser->idx--; + } else { + parser->in_short = 0; + } + + /* Required argument was not provided */ + if (spec->type == CLI_OPT_TYPE_VALUE && !opt->value) + opt->status = CLI_OPT_STATUS_MISSING_VALUE; + else + opt->status = CLI_OPT_STATUS_OK; + + consume_choices(opt->spec, parser); + +done: + return opt->status; +} + +static cli_opt_status_t parse_arg(cli_opt *opt, cli_opt_parser *parser) +{ + const cli_opt_spec *spec = spec_for_arg(parser); + + opt->spec = spec; + opt->arg = parser->args[parser->idx]; + + if (!spec) { + parser->idx++; + opt->status = CLI_OPT_STATUS_UNKNOWN_OPTION; + } else if (spec->type == CLI_OPT_TYPE_ARGS) { + if (spec->value) + *((char ***)spec->value) = &parser->args[parser->idx]; + + /* + * We have started a list of arguments; the remainder of + * given arguments need not be examined. + */ + parser->in_args = (parser->args_len - parser->idx); + parser->idx = parser->args_len; + opt->args_len = parser->in_args; + opt->status = CLI_OPT_STATUS_OK; + } else { + if (spec->value) + *((char **)spec->value) = parser->args[parser->idx]; + + parser->idx++; + opt->status = CLI_OPT_STATUS_OK; + } + + return opt->status; +} + +static int support_gnu_style(unsigned int flags) +{ + if ((flags & CLI_OPT_PARSE_FORCE_GNU) != 0) + return 1; + + if ((flags & CLI_OPT_PARSE_GNU) == 0) + return 0; + + /* TODO: Windows */ +#if defined(_WIN32) && defined(UNICODE) + if (_wgetenv(L"POSIXLY_CORRECT") != NULL) + return 0; +#else + if (getenv("POSIXLY_CORRECT") != NULL) + return 0; +#endif + + return 1; +} + +void cli_opt_parser_init( + cli_opt_parser *parser, + const cli_opt_spec specs[], + char **args, + size_t args_len, + unsigned int flags) +{ + assert(parser); + + memset(parser, 0x0, sizeof(cli_opt_parser)); + + parser->specs = specs; + parser->args = args; + parser->args_len = args_len; + parser->flags = flags; + + parser->needs_sort = support_gnu_style(flags); +} + +GIT_INLINE(const cli_opt_spec *) spec_for_sort( + int *needs_value, + const cli_opt_parser *parser, + const char *arg) +{ + int is_negated, has_value = 0; + const char *value; + const cli_opt_spec *spec = NULL; + size_t idx = 0; + + *needs_value = 0; + + if (strncmp(arg, "--", 2) == 0) { + spec = spec_for_long(&is_negated, &has_value, &value, parser, &arg[2]); + *needs_value = !has_value; + } + + else if (strncmp(arg, "-", 1) == 0) { + spec = spec_for_short(&value, parser, &arg[1]); + + /* + * Advance through compressed short arguments to see if + * the last one has a value, eg "-xvffilename". + */ + while (spec && !value && arg[1 + ++idx] != '\0') + spec = spec_for_short(&value, parser, &arg[1 + idx]); + + *needs_value = (value == NULL); + } + + return spec; +} + +/* + * Some parsers allow for handling arguments like "file1 --help file2"; + * this is done by re-sorting the arguments in-place; emulate that. + */ +static int sort_gnu_style(cli_opt_parser *parser) +{ + size_t i, j, insert_idx = parser->idx, offset; + const cli_opt_spec *spec; + char *option, *value; + int needs_value, changed = 0; + + parser->needs_sort = 0; + + for (i = parser->idx; i < parser->args_len; i++) { + spec = spec_for_sort(&needs_value, parser, parser->args[i]); + + /* Not a "-" or "--" prefixed option. No change. */ + if (!spec) + continue; + + /* A "--" alone means remaining args are literal. */ + if (spec->type == CLI_OPT_TYPE_LITERAL) + break; + + option = parser->args[i]; + + /* + * If the argument is a value type and doesn't already + * have a value (eg "--foo=bar" or "-fbar") then we need + * to copy the next argument as its value. + */ + if (spec->type == CLI_OPT_TYPE_VALUE && needs_value) { + /* + * A required value is not provided; set parser + * index to this value so that we fail on it. + */ + if (i + 1 >= parser->args_len) { + parser->idx = i; + return 1; + } + + value = parser->args[i + 1]; + offset = 1; + } else { + value = NULL; + offset = 0; + } + + /* Caller error if args[0] is an option. */ + if (i == 0) + return 0; + + /* Shift args up one (or two) and insert the option */ + for (j = i; j > insert_idx; j--) + parser->args[j + offset] = parser->args[j - 1]; + + parser->args[insert_idx] = option; + + if (value) + parser->args[insert_idx + 1] = value; + + insert_idx += (1 + offset); + i += offset; + + changed = 1; + } + + return changed; +} + +cli_opt_status_t cli_opt_parser_next(cli_opt *opt, cli_opt_parser *parser) +{ + assert(opt && parser); + + memset(opt, 0x0, sizeof(cli_opt)); + + if (parser->idx >= parser->args_len) { + opt->args_len = parser->in_args; + return CLI_OPT_STATUS_DONE; + } + + /* Handle options in long form, those beginning with "--" */ + if (strncmp(parser->args[parser->idx], "--", 2) == 0 && + !parser->in_short && + !parser->in_literal) + return parse_long(opt, parser); + + /* Handle options in short form, those beginning with "-" */ + else if (parser->in_short || + (strncmp(parser->args[parser->idx], "-", 1) == 0 && + !parser->in_literal)) + return parse_short(opt, parser); + + /* + * We've reached the first "bare" argument. In POSIX mode, all + * remaining items on the command line are arguments. In GNU + * mode, there may be long or short options after this. Sort any + * options up to this position then re-parse the current position. + */ + if (parser->needs_sort && sort_gnu_style(parser)) + return cli_opt_parser_next(opt, parser); + + return parse_arg(opt, parser); +} + +GIT_INLINE(int) spec_included(const cli_opt_spec **specs, const cli_opt_spec *spec) +{ + const cli_opt_spec **i; + + for (i = specs; *i; ++i) { + if (spec == *i) + return 1; + } + + return 0; +} + +static cli_opt_status_t validate_required( + cli_opt *opt, + const cli_opt_spec specs[], + const cli_opt_spec **given_specs) +{ + const cli_opt_spec *spec, *required; + int given; + + /* + * Iterate over the possible specs to identify requirements and + * ensure that those have been given on the command-line. + * Note that we can have required *choices*, where one in a + * list of choices must be specified. + */ + for (spec = specs, required = NULL, given = 0; spec->type; ++spec) { + if (!required && (spec->usage & CLI_OPT_USAGE_REQUIRED)) { + required = spec; + given = 0; + } else if (!required) { + continue; + } + + if (!given) + given = spec_included(given_specs, spec); + + /* + * Validate the requirement unless we're in a required + * choice. In that case, keep the required state and + * validate at the end of the choice list. + */ + if (!spec_is_choice(spec)) { + if (!given) { + opt->spec = required; + opt->status = CLI_OPT_STATUS_MISSING_ARGUMENT; + break; + } + + required = NULL; + given = 0; + } + } + + return opt->status; +} + +cli_opt_status_t cli_opt_parse( + cli_opt *opt, + const cli_opt_spec specs[], + char **args, + size_t args_len, + unsigned int flags) +{ + cli_opt_parser parser; + const cli_opt_spec **given_specs; + size_t given_idx = 0; + + cli_opt_parser_init(&parser, specs, args, args_len, flags); + + given_specs = alloca(sizeof(const cli_opt_spec *) * (args_len + 1)); + + while (cli_opt_parser_next(opt, &parser)) { + if (opt->status != CLI_OPT_STATUS_OK && + opt->status != CLI_OPT_STATUS_DONE) + return opt->status; + + if ((opt->spec->usage & CLI_OPT_USAGE_STOP_PARSING)) + return (opt->status = CLI_OPT_STATUS_DONE); + + given_specs[given_idx++] = opt->spec; + } + + given_specs[given_idx] = NULL; + + return validate_required(opt, specs, given_specs); +} + +static int spec_name_fprint(FILE *file, const cli_opt_spec *spec) +{ + int error; + + if (spec->type == CLI_OPT_TYPE_ARG) + error = fprintf(file, "%s", spec->value_name); + else if (spec->type == CLI_OPT_TYPE_ARGS) + error = fprintf(file, "%s", spec->value_name); + else if (spec->alias && !(spec->usage & CLI_OPT_USAGE_SHOW_LONG)) + error = fprintf(file, "-%c", spec->alias); + else + error = fprintf(file, "--%s", spec->name); + + return error; +} + +int cli_opt_status_fprint( + FILE *file, + const char *command, + const cli_opt *opt) +{ + const cli_opt_spec *choice; + int error; + + if (command && (error = fprintf(file, "%s: ", command)) < 0) + return error; + + switch (opt->status) { + case CLI_OPT_STATUS_DONE: + error = fprintf(file, "finished processing arguments (no error)\n"); + break; + case CLI_OPT_STATUS_OK: + error = fprintf(file, "no error\n"); + break; + case CLI_OPT_STATUS_UNKNOWN_OPTION: + error = fprintf(file, "unknown option: %s\n", opt->arg); + break; + case CLI_OPT_STATUS_MISSING_VALUE: + if ((error = fprintf(file, "argument '")) < 0 || + (error = spec_name_fprint(file, opt->spec)) < 0 || + (error = fprintf(file, "' requires a value.\n")) < 0) + break; + break; + case CLI_OPT_STATUS_MISSING_ARGUMENT: + if (spec_is_choice(opt->spec)) { + int is_choice = 1; + + if (spec_is_choice((opt->spec)+1)) + error = fprintf(file, "one of"); + else + error = fprintf(file, "either"); + + if (error < 0) + break; + + for (choice = opt->spec; is_choice; ++choice) { + is_choice = spec_is_choice(choice); + + if (!is_choice) + error = fprintf(file, " or"); + else if (choice != opt->spec) + error = fprintf(file, ","); + + if ((error < 0) || + (error = fprintf(file, " '")) < 0 || + (error = spec_name_fprint(file, choice)) < 0 || + (error = fprintf(file, "'")) < 0) + break; + + if (!spec_is_choice(choice)) + break; + } + + if ((error < 0) || + (error = fprintf(file, " is required.\n")) < 0) + break; + } else { + if ((error = fprintf(file, "argument '")) < 0 || + (error = spec_name_fprint(file, opt->spec)) < 0 || + (error = fprintf(file, "' is required.\n")) < 0) + break; + } + + break; + default: + error = fprintf(file, "unknown status: %d\n", opt->status); + break; + } + + return error; +} + +int cli_opt_usage_fprint( + FILE *file, + const char *command, + const cli_opt_spec specs[]) +{ + const cli_opt_spec *spec; + int choice = 0, next_choice = 0, optional = 0; + int error; + + if ((error = fprintf(file, "usage: %s", command)) < 0) + goto done; + + for (spec = specs; spec->type; ++spec) { + if (!choice) + optional = !(spec->usage & CLI_OPT_USAGE_REQUIRED); + + next_choice = !!((spec + 1)->usage & CLI_OPT_USAGE_CHOICE); + + if (spec->usage & CLI_OPT_USAGE_HIDDEN) + continue; + + if (choice) + error = fprintf(file, "|"); + else + error = fprintf(file, " "); + + if (error < 0) + goto done; + + if (optional && !choice && (error = fprintf(file, "[")) < 0) + error = fprintf(file, "["); + if (!optional && !choice && next_choice) + error = fprintf(file, "("); + + if (error < 0) + goto done; + + if (spec->type == CLI_OPT_TYPE_VALUE && spec->alias && + !(spec->usage & CLI_OPT_USAGE_VALUE_OPTIONAL) && + !(spec->usage & CLI_OPT_USAGE_SHOW_LONG)) + error = fprintf(file, "-%c <%s>", spec->alias, spec->value_name); + else if (spec->type == CLI_OPT_TYPE_VALUE && spec->alias && + !(spec->usage & CLI_OPT_USAGE_SHOW_LONG)) + error = fprintf(file, "-%c [<%s>]", spec->alias, spec->value_name); + else if (spec->type == CLI_OPT_TYPE_VALUE && + !(spec->usage & CLI_OPT_USAGE_VALUE_OPTIONAL)) + error = fprintf(file, "--%s[=<%s>]", spec->name, spec->value_name); + else if (spec->type == CLI_OPT_TYPE_VALUE) + error = fprintf(file, "--%s=<%s>", spec->name, spec->value_name); + else if (spec->type == CLI_OPT_TYPE_ARG) + error = fprintf(file, "<%s>", spec->value_name); + else if (spec->type == CLI_OPT_TYPE_ARGS) + error = fprintf(file, "<%s>...", spec->value_name); + else if (spec->type == CLI_OPT_TYPE_LITERAL) + error = fprintf(file, "--"); + else if (spec->alias && !(spec->usage & CLI_OPT_USAGE_SHOW_LONG)) + error = fprintf(file, "-%c", spec->alias); + else + error = fprintf(file, "--%s", spec->name); + + if (error < 0) + goto done; + + if (!optional && choice && !next_choice) + error = fprintf(file, ")"); + else if (optional && !next_choice) + error = fprintf(file, "]"); + + if (error < 0) + goto done; + + choice = next_choice; + } + + error = fprintf(file, "\n"); + +done: + error = (error < 0) ? -1 : 0; + return error; +} + diff --git a/src/cli/opt.h b/src/cli/opt.h new file mode 100644 index 00000000000..f7b6b9326aa --- /dev/null +++ b/src/cli/opt.h @@ -0,0 +1,362 @@ +/* + * Copyright (c), Edward Thomson + * All rights reserved. + * + * This file is part of adopt, distributed under the MIT license. + * For full terms and conditions, see the included LICENSE file. + * + * THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT. + * + * This file was produced by using the `rename.pl` script included with + * adopt. The command-line specified was: + * + * ./rename.pl cli_opt --filename=opt --include=cli.h --inline=GIT_INLINE --header-guard=CLI_opt_h__ --lowercase-status + */ + +#ifndef CLI_opt_h__ +#define CLI_opt_h__ + +#include +#include + +/** + * The type of argument to be parsed. + */ +typedef enum { + CLI_OPT_TYPE_NONE = 0, + + /** + * An option that, when specified, sets a given value to true. + * This is useful for options like "--debug". A negation + * option (beginning with "no-") is implicitly specified; for + * example "--no-debug". The `value` pointer in the returned + * option will be set to `1` when this is specified, and set to + * `0` when the negation "no-" option is specified. + */ + CLI_OPT_TYPE_BOOL, + + /** + * An option that, when specified, sets the given `value` pointer + * to the specified `switch_value`. This is useful for booleans + * where you do not want the implicit negation that comes with an + * `CLI_OPT_TYPE_BOOL`, or for switches that multiplex a value, like + * setting a mode. For example, `--read` may set the `value` to + * `MODE_READ` and `--write` may set the `value` to `MODE_WRITE`. + */ + CLI_OPT_TYPE_SWITCH, + + /** + * An option that, when specified, increments the given + * `value` by the given `switch_value`. This can be specified + * multiple times to continue to increment the `value`. + * (For example, "-vvv" to set verbosity to 3.) + */ + CLI_OPT_TYPE_ACCUMULATOR, + + /** + * An option that takes a value, for example `-n value`, + * `-nvalue`, `--name value` or `--name=value`. + */ + CLI_OPT_TYPE_VALUE, + + /** + * A bare "--" that indicates that arguments following this are + * literal. This allows callers to specify things that might + * otherwise look like options, for example to operate on a file + * named "-rf" then you can invoke "program -- -rf" to treat + * "-rf" as an argument not an option. + */ + CLI_OPT_TYPE_LITERAL, + + /** + * A single argument, not an option. When options are exhausted, + * arguments will be matches in the order that they're specified + * in the spec list. For example, if two `CLI_OPT_TYPE_ARGS` are + * specified, `input_file` and `output_file`, then the first bare + * argument on the command line will be `input_file` and the + * second will be `output_file`. + */ + CLI_OPT_TYPE_ARG, + + /** + * A collection of arguments. This is useful when you want to take + * a list of arguments, for example, multiple paths. When specified, + * the value will be set to the first argument in the list. + */ + CLI_OPT_TYPE_ARGS, +} cli_opt_type_t; + +/** + * Additional information about an option, including parsing + * restrictions and usage information to be displayed to the end-user. + */ +typedef enum { + /** Defaults for the argument. */ + CLI_OPT_USAGE_DEFAULT = 0, + + /** This argument is required. */ + CLI_OPT_USAGE_REQUIRED = (1u << 0), + + /** + * This is a multiple choice argument, combined with the previous + * argument. For example, when the previous argument is `-f` and + * this optional is applied to an argument of type `-b` then one + * of `-f` or `-b` may be specified. + */ + CLI_OPT_USAGE_CHOICE = (1u << 1), + + /** + * This argument short-circuits the remainder of parsing. + * Useful for arguments like `--help`. + */ + CLI_OPT_USAGE_STOP_PARSING = (1u << 2), + + /** The argument's value is optional ("-n" or "-n foo") */ + CLI_OPT_USAGE_VALUE_OPTIONAL = (1u << 3), + + /** This argument should not be displayed in usage. */ + CLI_OPT_USAGE_HIDDEN = (1u << 4), + + /** In usage, show the long format instead of the abbreviated format. */ + CLI_OPT_USAGE_SHOW_LONG = (1u << 5), +} cli_opt_usage_t; + +typedef enum { + /** Default parsing behavior. */ + CLI_OPT_PARSE_DEFAULT = 0, + + /** + * Parse with GNU `getopt_long` style behavior, where options can + * be intermixed with arguments at any position (for example, + * "file1 --help file2".) Like `getopt_long`, this can mutate the + * arguments given. + */ + CLI_OPT_PARSE_GNU = (1u << 0), + + /** + * Force GNU `getopt_long` style behavior; the `POSIXLY_CORRECT` + * environment variable is ignored. + */ + CLI_OPT_PARSE_FORCE_GNU = (1u << 1), +} cli_opt_flag_t; + +/** Specification for an available option. */ +typedef struct cli_opt_spec { + /** Type of option expected. */ + cli_opt_type_t type; + + /** Name of the long option. */ + const char *name; + + /** The alias is the short (one-character) option alias. */ + const char alias; + + /** + * If this spec is of type `CLI_OPT_TYPE_BOOL`, this is a pointer + * to an `int` that will be set to `1` if the option is specified. + * + * If this spec is of type `CLI_OPT_TYPE_SWITCH`, this is a pointer + * to an `int` that will be set to the opt's `switch_value` (below) + * when this option is specified. + * + * If this spec is of type `CLI_OPT_TYPE_ACCUMULATOR`, this is a + * pointer to an `int` that will be incremented by the opt's + * `switch_value` (below). If no `switch_value` is provided then + * the value will be incremented by 1. + * + * If this spec is of type `CLI_OPT_TYPE_VALUE`, + * `CLI_OPT_TYPE_VALUE_OPTIONAL`, or `CLI_OPT_TYPE_ARG`, this is + * a pointer to a `char *` that will be set to the value + * specified on the command line. + * + * If this spec is of type `CLI_OPT_TYPE_ARGS`, this is a pointer + * to a `char **` that will be set to the remaining values + * specified on the command line. + */ + void *value; + + /** + * If this spec is of type `CLI_OPT_TYPE_SWITCH`, this is the value + * to set in the option's `value` pointer when it is specified. If + * this spec is of type `CLI_OPT_TYPE_ACCUMULATOR`, this is the value + * to increment in the option's `value` pointer when it is + * specified. This is ignored for other opt types. + */ + int switch_value; + + /** + * Optional usage flags that change parsing behavior and how + * usage information is shown to the end-user. + */ + uint32_t usage; + + /** + * The name of the value, provided when creating usage information. + * This is required only for the functions that display usage + * information and only when a spec is of type `CLI_OPT_TYPE_VALUE, + * `CLI_OPT_TYPE_ARG` or `CLI_OPT_TYPE_ARGS``. + */ + const char *value_name; + + /** + * Optional short description of the option to display to the + * end-user. This is only used when creating usage information. + */ + const char *help; +} cli_opt_spec; + +/** Return value for `cli_opt_parser_next`. */ +typedef enum { + /** Parsing is complete; there are no more arguments. */ + CLI_OPT_STATUS_DONE = 0, + + /** + * This argument was parsed correctly; the `opt` structure is + * populated and the value pointer has been set. + */ + CLI_OPT_STATUS_OK = 1, + + /** + * The argument could not be parsed correctly, it does not match + * any of the specifications provided. + */ + CLI_OPT_STATUS_UNKNOWN_OPTION = 2, + + /** + * The argument matched a spec of type `CLI_OPT_VALUE`, but no value + * was provided. + */ + CLI_OPT_STATUS_MISSING_VALUE = 3, + + /** A required argument was not provided. */ + CLI_OPT_STATUS_MISSING_ARGUMENT = 4, +} cli_opt_status_t; + +/** An option provided on the command-line. */ +typedef struct cli_opt { + /** The status of parsing the most recent argument. */ + cli_opt_status_t status; + + /** + * The specification that was provided on the command-line, or + * `NULL` if the argument did not match an `cli_opt_spec`. + */ + const cli_opt_spec *spec; + + /** + * The argument as it was specified on the command-line, including + * dashes, eg, `-f` or `--foo`. + */ + char *arg; + + /** + * If the spec is of type `CLI_OPT_VALUE` or `CLI_OPT_VALUE_OPTIONAL`, + * this is the value provided to the argument. + */ + char *value; + + /** + * If the argument is of type `CLI_OPT_ARGS`, this is the number of + * arguments remaining. This value is persisted even when parsing + * is complete and `status` == `CLI_OPT_STATUS_DONE`. + */ + size_t args_len; +} cli_opt; + +/* The internal parser state. Callers should not modify this structure. */ +typedef struct cli_opt_parser { + const cli_opt_spec *specs; + char **args; + size_t args_len; + unsigned int flags; + + /* Parser state */ + size_t idx; + size_t arg_idx; + size_t in_args; + size_t in_short; + int needs_sort : 1, + in_literal : 1; +} cli_opt_parser; + +/** + * Parses all the command-line arguments and updates all the options using + * the pointers provided. Parsing stops on any invalid argument and + * information about the failure will be provided in the opt argument. + * + * This is the simplest way to parse options; it handles the initialization + * (`parser_init`) and looping (`parser_next`). + * + * @param opt The The `cli_opt` information that failed parsing + * @param specs A NULL-terminated array of `cli_opt_spec`s that can be parsed + * @param args The arguments that will be parsed + * @param args_len The length of arguments to be parsed + * @param flags The `cli_opt_flag_t flags for parsing + */ +cli_opt_status_t cli_opt_parse( + cli_opt *opt, + const cli_opt_spec specs[], + char **args, + size_t args_len, + unsigned int flags); + +/** + * Initializes a parser that parses the given arguments according to the + * given specifications. + * + * @param parser The `cli_opt_parser` that will be initialized + * @param specs A NULL-terminated array of `cli_opt_spec`s that can be parsed + * @param args The arguments that will be parsed + * @param args_len The length of arguments to be parsed + * @param flags The `cli_opt_flag_t flags for parsing + */ +void cli_opt_parser_init( + cli_opt_parser *parser, + const cli_opt_spec specs[], + char **args, + size_t args_len, + unsigned int flags); + +/** + * Parses the next command-line argument and places the information about + * the argument into the given `opt` data. + * + * @param opt The `cli_opt` information parsed from the argument + * @param parser An `cli_opt_parser` that has been initialized with + * `cli_opt_parser_init` + * @return true if the caller should continue iterating, or 0 if there are + * no arguments left to process. + */ +cli_opt_status_t cli_opt_parser_next( + cli_opt *opt, + cli_opt_parser *parser); + +/** + * Prints the status after parsing the most recent argument. This is + * useful for printing an error message when an unknown argument was + * specified, or when an argument was specified without a value. + * + * @param file The file to print information to + * @param command The name of the command to use when printing (optional) + * @param opt The option that failed to parse + * @return 0 on success, -1 on failure + */ +int cli_opt_status_fprint( + FILE *file, + const char *command, + const cli_opt *opt); + +/** + * Prints usage information to the given file handle. + * + * @param file The file to print information to + * @param command The name of the command to use when printing + * @param specs The specifications allowed by the command + * @return 0 on success, -1 on failure + */ +int cli_opt_usage_fprint( + FILE *file, + const char *command, + const cli_opt_spec specs[]); + +#endif /* CLI_opt_h__ */ diff --git a/src/cli/win32/precompiled.c b/src/cli/win32/precompiled.c new file mode 100644 index 00000000000..5f656a45da8 --- /dev/null +++ b/src/cli/win32/precompiled.c @@ -0,0 +1 @@ +#include "precompiled.h" diff --git a/src/cli/win32/precompiled.h b/src/cli/win32/precompiled.h new file mode 100644 index 00000000000..b0309b864ad --- /dev/null +++ b/src/cli/win32/precompiled.h @@ -0,0 +1,3 @@ +#include + +#include "cli.h" From 8526cbd56b0395b9427727e81e6f3c89768337b9 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 26 Nov 2021 09:37:29 -0500 Subject: [PATCH 0824/1616] opt: use a custom function to print usage Our argument parser (https://github.com/ethomson/adopt) includes a function to print a usage message based on the allowed options. Omit this and use a cutom function that understands that we have subcommands ("checkout", "revert", etc) that each have their own options. --- src/cli/cli.h | 1 + src/cli/main.c | 2 +- src/cli/opt.c | 83 +------------------ src/cli/opt.h | 15 +--- src/cli/opt_usage.c | 194 ++++++++++++++++++++++++++++++++++++++++++++ src/cli/opt_usage.h | 35 ++++++++ 6 files changed, 233 insertions(+), 97 deletions(-) create mode 100644 src/cli/opt_usage.c create mode 100644 src/cli/opt_usage.h diff --git a/src/cli/cli.h b/src/cli/cli.h index a27081d873f..222d53a7446 100644 --- a/src/cli/cli.h +++ b/src/cli/cli.h @@ -14,5 +14,6 @@ #include "error.h" #include "opt.h" +#include "opt_usage.h" #endif /* CLI_cli_h__ */ diff --git a/src/cli/main.c b/src/cli/main.c index 709f6b45217..5eff56a1d6b 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -34,7 +34,7 @@ int main(int argc, char **argv) while (cli_opt_parser_next(&opt, &optparser)) { if (!opt.spec) { cli_opt_status_fprint(stderr, PROGRAM_NAME, &opt); - cli_opt_usage_fprint(stderr, PROGRAM_NAME, common_opts); + cli_opt_usage_fprint(stderr, PROGRAM_NAME, NULL, common_opts); ret = CLI_EXIT_USAGE; goto done; } diff --git a/src/cli/opt.c b/src/cli/opt.c index 11faa92c56e..72df5877fbf 100644 --- a/src/cli/opt.c +++ b/src/cli/opt.c @@ -10,7 +10,7 @@ * This file was produced by using the `rename.pl` script included with * adopt. The command-line specified was: * - * ./rename.pl cli_opt --filename=opt --include=cli.h --inline=GIT_INLINE --header-guard=CLI_opt_h__ --lowercase-status + * ./rename.pl cli_opt --filename=opt --include=cli.h --inline=GIT_INLINE --header-guard=CLI_opt_h__ --lowercase-status --without-usage */ #include @@ -667,84 +667,3 @@ int cli_opt_status_fprint( return error; } -int cli_opt_usage_fprint( - FILE *file, - const char *command, - const cli_opt_spec specs[]) -{ - const cli_opt_spec *spec; - int choice = 0, next_choice = 0, optional = 0; - int error; - - if ((error = fprintf(file, "usage: %s", command)) < 0) - goto done; - - for (spec = specs; spec->type; ++spec) { - if (!choice) - optional = !(spec->usage & CLI_OPT_USAGE_REQUIRED); - - next_choice = !!((spec + 1)->usage & CLI_OPT_USAGE_CHOICE); - - if (spec->usage & CLI_OPT_USAGE_HIDDEN) - continue; - - if (choice) - error = fprintf(file, "|"); - else - error = fprintf(file, " "); - - if (error < 0) - goto done; - - if (optional && !choice && (error = fprintf(file, "[")) < 0) - error = fprintf(file, "["); - if (!optional && !choice && next_choice) - error = fprintf(file, "("); - - if (error < 0) - goto done; - - if (spec->type == CLI_OPT_TYPE_VALUE && spec->alias && - !(spec->usage & CLI_OPT_USAGE_VALUE_OPTIONAL) && - !(spec->usage & CLI_OPT_USAGE_SHOW_LONG)) - error = fprintf(file, "-%c <%s>", spec->alias, spec->value_name); - else if (spec->type == CLI_OPT_TYPE_VALUE && spec->alias && - !(spec->usage & CLI_OPT_USAGE_SHOW_LONG)) - error = fprintf(file, "-%c [<%s>]", spec->alias, spec->value_name); - else if (spec->type == CLI_OPT_TYPE_VALUE && - !(spec->usage & CLI_OPT_USAGE_VALUE_OPTIONAL)) - error = fprintf(file, "--%s[=<%s>]", spec->name, spec->value_name); - else if (spec->type == CLI_OPT_TYPE_VALUE) - error = fprintf(file, "--%s=<%s>", spec->name, spec->value_name); - else if (spec->type == CLI_OPT_TYPE_ARG) - error = fprintf(file, "<%s>", spec->value_name); - else if (spec->type == CLI_OPT_TYPE_ARGS) - error = fprintf(file, "<%s>...", spec->value_name); - else if (spec->type == CLI_OPT_TYPE_LITERAL) - error = fprintf(file, "--"); - else if (spec->alias && !(spec->usage & CLI_OPT_USAGE_SHOW_LONG)) - error = fprintf(file, "-%c", spec->alias); - else - error = fprintf(file, "--%s", spec->name); - - if (error < 0) - goto done; - - if (!optional && choice && !next_choice) - error = fprintf(file, ")"); - else if (optional && !next_choice) - error = fprintf(file, "]"); - - if (error < 0) - goto done; - - choice = next_choice; - } - - error = fprintf(file, "\n"); - -done: - error = (error < 0) ? -1 : 0; - return error; -} - diff --git a/src/cli/opt.h b/src/cli/opt.h index f7b6b9326aa..6c1d4603ecd 100644 --- a/src/cli/opt.h +++ b/src/cli/opt.h @@ -10,7 +10,7 @@ * This file was produced by using the `rename.pl` script included with * adopt. The command-line specified was: * - * ./rename.pl cli_opt --filename=opt --include=cli.h --inline=GIT_INLINE --header-guard=CLI_opt_h__ --lowercase-status + * ./rename.pl cli_opt --filename=opt --include=cli.h --inline=GIT_INLINE --header-guard=CLI_opt_h__ --lowercase-status --without-usage */ #ifndef CLI_opt_h__ @@ -346,17 +346,4 @@ int cli_opt_status_fprint( const char *command, const cli_opt *opt); -/** - * Prints usage information to the given file handle. - * - * @param file The file to print information to - * @param command The name of the command to use when printing - * @param specs The specifications allowed by the command - * @return 0 on success, -1 on failure - */ -int cli_opt_usage_fprint( - FILE *file, - const char *command, - const cli_opt_spec specs[]); - #endif /* CLI_opt_h__ */ diff --git a/src/cli/opt_usage.c b/src/cli/opt_usage.c new file mode 100644 index 00000000000..6e5d6006ee1 --- /dev/null +++ b/src/cli/opt_usage.c @@ -0,0 +1,194 @@ +/* + * 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 "cli.h" +#include "str.h" + +static int print_spec_name(git_str *out, const cli_opt_spec *spec) +{ + if (spec->type == CLI_OPT_TYPE_VALUE && spec->alias && + !(spec->usage & CLI_OPT_USAGE_VALUE_OPTIONAL) && + !(spec->usage & CLI_OPT_USAGE_SHOW_LONG)) + return git_str_printf(out, "-%c <%s>", spec->alias, spec->value_name); + if (spec->type == CLI_OPT_TYPE_VALUE && spec->alias && + !(spec->usage & CLI_OPT_USAGE_SHOW_LONG)) + return git_str_printf(out, "-%c [<%s>]", spec->alias, spec->value_name); + if (spec->type == CLI_OPT_TYPE_VALUE && + !(spec->usage & CLI_OPT_USAGE_VALUE_OPTIONAL)) + return git_str_printf(out, "--%s[=<%s>]", spec->name, spec->value_name); + if (spec->type == CLI_OPT_TYPE_VALUE) + return git_str_printf(out, "--%s=<%s>", spec->name, spec->value_name); + if (spec->type == CLI_OPT_TYPE_ARG) + return git_str_printf(out, "<%s>", spec->value_name); + if (spec->type == CLI_OPT_TYPE_ARGS) + return git_str_printf(out, "<%s>...", spec->value_name); + if (spec->type == CLI_OPT_TYPE_LITERAL) + return git_str_printf(out, "--"); + if (spec->alias && !(spec->usage & CLI_OPT_USAGE_SHOW_LONG)) + return git_str_printf(out, "-%c", spec->alias); + if (spec->name) + return git_str_printf(out, "--%s", spec->name); + + GIT_ASSERT(0); +} + +/* + * This is similar to adopt's function, but modified to understand + * that we have a command ("git") and a "subcommand" ("checkout"). + * It also understands a terminal's line length and wrap appropriately, + * using a `git_str` for storage. + */ +int cli_opt_usage_fprint( + FILE *file, + const char *command, + const char *subcommand, + const cli_opt_spec specs[]) +{ + git_str usage = GIT_BUF_INIT, opt = GIT_BUF_INIT; + const cli_opt_spec *spec; + size_t i, prefixlen, linelen; + bool choice = false, next_choice = false, optional = false; + int error; + + /* TODO: query actual console width. */ + int console_width = 80; + + if ((error = git_str_printf(&usage, "usage: %s", command)) < 0) + goto done; + + if (subcommand && + (error = git_str_printf(&usage, " %s", subcommand)) < 0) + goto done; + + linelen = git_str_len(&usage); + prefixlen = linelen + 1; + + for (spec = specs; spec->type; ++spec) { + if (!choice) + optional = !(spec->usage & CLI_OPT_USAGE_REQUIRED); + + next_choice = !!((spec + 1)->usage & CLI_OPT_USAGE_CHOICE); + + if (spec->usage & CLI_OPT_USAGE_HIDDEN) + continue; + + if (choice) + git_str_putc(&opt, '|'); + else + git_str_clear(&opt); + + if (optional && !choice) + git_str_putc(&opt, '['); + if (!optional && !choice && next_choice) + git_str_putc(&opt, '('); + + if ((error = print_spec_name(&opt, spec)) < 0) + goto done; + + if (!optional && choice && !next_choice) + git_str_putc(&opt, ')'); + else if (optional && !next_choice) + git_str_putc(&opt, ']'); + + if ((choice = next_choice)) + continue; + + if (git_str_oom(&opt)) { + error = -1; + goto done; + } + + if (linelen > prefixlen && + console_width > 0 && + linelen + git_str_len(&opt) + 1 > (size_t)console_width) { + git_str_putc(&usage, '\n'); + + for (i = 0; i < prefixlen; i++) + git_str_putc(&usage, ' '); + + linelen = prefixlen; + } else { + git_str_putc(&usage, ' '); + linelen += git_str_len(&opt) + 1; + } + + git_str_puts(&usage, git_str_cstr(&opt)); + + if (git_str_oom(&usage)) { + error = -1; + goto done; + } + } + + error = fprintf(file, "%s\n", git_str_cstr(&usage)); + +done: + error = (error < 0) ? -1 : 0; + + git_str_dispose(&usage); + git_str_dispose(&opt); + return error; +} + +int cli_opt_usage_error( + const char *subcommand, + const cli_opt_spec specs[], + const cli_opt *invalid_opt) +{ + cli_opt_status_fprint(stderr, PROGRAM_NAME, invalid_opt); + cli_opt_usage_fprint(stderr, PROGRAM_NAME, subcommand, specs); + return CLI_EXIT_USAGE; +} + +int cli_opt_help_fprint( + FILE *file, + const cli_opt_spec specs[]) +{ + git_str help = GIT_BUF_INIT; + const cli_opt_spec *spec; + int error; + + /* Display required arguments first */ + for (spec = specs; spec->type; ++spec) { + if (! (spec->usage & CLI_OPT_USAGE_REQUIRED) || + (spec->usage & CLI_OPT_USAGE_HIDDEN)) + continue; + + git_str_printf(&help, " "); + + if ((error = print_spec_name(&help, spec)) < 0) + goto done; + + git_str_printf(&help, ": %s\n", spec->help); + } + + /* Display the remaining arguments */ + for (spec = specs; spec->type; ++spec) { + if ((spec->usage & CLI_OPT_USAGE_REQUIRED) || + (spec->usage & CLI_OPT_USAGE_HIDDEN)) + continue; + + git_str_printf(&help, " "); + + if ((error = print_spec_name(&help, spec)) < 0) + goto done; + + git_str_printf(&help, ": %s\n", spec->help); + + } + + if (git_str_oom(&help) || + p_write(fileno(file), help.ptr, help.size) < 0) + error = -1; + +done: + error = (error < 0) ? -1 : 0; + + git_str_dispose(&help); + return error; +} + diff --git a/src/cli/opt_usage.h b/src/cli/opt_usage.h new file mode 100644 index 00000000000..c752494e1aa --- /dev/null +++ b/src/cli/opt_usage.h @@ -0,0 +1,35 @@ +/* + * 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 CLI_opt_usage_h__ +#define CLI_opt_usage_h__ + +/** + * Prints usage information to the given file handle. + * + * @param file The file to print information to + * @param command The name of the command to use when printing + * @param subcommand The name of the subcommand (eg "checkout") to use when printing, or NULL to skip + * @param specs The specifications allowed by the command + * @return 0 on success, -1 on failure + */ +int cli_opt_usage_fprint( + FILE *file, + const char *command, + const char *subcommand, + const cli_opt_spec specs[]); + +int cli_opt_usage_error( + const char *subcommand, + const cli_opt_spec specs[], + const cli_opt *invalid_opt); + +int cli_opt_help_fprint( + FILE *file, + const cli_opt_spec specs[]); + +#endif /* CLI_opt_usage_h__ */ From c6dd82d9f14e9e24a52af637c4a56218ead13eda Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 23 Feb 2020 11:54:33 +0000 Subject: [PATCH 0825/1616] cli: introduce a help command Add a framework for commands to be defined, and add our first one, "help". When `git2_cli help` is run, the `cmd_help` function will be invoked with the remaining command line arguments. This allows users to invoke `git2_cli help foo` to get information about the `foo` subcommand. --- src/cli/README.md | 19 ++++++++++++ src/cli/cmd.c | 21 +++++++++++++ src/cli/cmd.h | 30 ++++++++++++++++++ src/cli/cmd_help.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++ src/cli/main.c | 51 +++++++++++++++++++++++++++--- 5 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 src/cli/cmd.c create mode 100644 src/cli/cmd.h create mode 100644 src/cli/cmd_help.c diff --git a/src/cli/README.md b/src/cli/README.md index eefd2ff27f6..26f11d90afb 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -1,3 +1,22 @@ # cli A git-compatible command-line interface that uses libgit2. + +## Adding commands + +1. Individual commands have a `main`-like top-level entrypoint. For example: + + ```c + int cmd_help(int argc, char **argv) + ``` + + Although this is the same signature as `main`, commands are not built as + individual standalone executables, they'll be linked into the main cli. + (Though there may be an option for command executables to be built as + standalone executables in the future.) + +2. Commands are prototyped in `cmd.h` and added to `main.c`'s list of + commands (`cli_cmds[]`). Commands should be specified with their name, + entrypoint and a brief description that can be printed in `git help`. + This is done because commands are linked into the main cli. + diff --git a/src/cli/cmd.c b/src/cli/cmd.c new file mode 100644 index 00000000000..2a7e71cdbcb --- /dev/null +++ b/src/cli/cmd.c @@ -0,0 +1,21 @@ +/* + * 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 "cli.h" +#include "cmd.h" + +const cli_cmd_spec *cli_cmd_spec_byname(const char *name) +{ + const cli_cmd_spec *cmd; + + for (cmd = cli_cmds; cmd->name; cmd++) { + if (!strcmp(cmd->name, name)) + return cmd; + } + + return NULL; +} diff --git a/src/cli/cmd.h b/src/cli/cmd.h new file mode 100644 index 00000000000..816614efcb5 --- /dev/null +++ b/src/cli/cmd.h @@ -0,0 +1,30 @@ +/* + * 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 CLI_cmd_h__ +#define CLI_cmd_h__ + +/* Command definitions */ +typedef struct { + const char *name; + int (*fn)(int argc, char **argv); + const char *desc; +} cli_cmd_spec; + +/* Options that are common to all commands (eg --help, --git-dir) */ +extern const cli_opt_spec cli_common_opts[]; + +/* All the commands supported by the CLI */ +extern const cli_cmd_spec cli_cmds[]; + +/* Find a command by name */ +extern const cli_cmd_spec *cli_cmd_spec_byname(const char *name); + +/* Commands */ +extern int cmd_help(int argc, char **argv); + +#endif /* CLI_cmd_h__ */ diff --git a/src/cli/cmd_help.c b/src/cli/cmd_help.c new file mode 100644 index 00000000000..d2ff5d4f482 --- /dev/null +++ b/src/cli/cmd_help.c @@ -0,0 +1,77 @@ +/* + * 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 +#include +#include "cli.h" +#include "cmd.h" + +#define COMMAND_NAME "help" + +static char *command; +static int show_help; + +static const cli_opt_spec opts[] = { + { CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1, + CLI_OPT_USAGE_HIDDEN, NULL, "display help about the help command" }, + { CLI_OPT_TYPE_ARG, "command", 0, &command, 0, + CLI_OPT_USAGE_DEFAULT, "command", "the command to show help for" }, + { 0 }, +}; + +static int print_help(void) +{ + cli_opt_usage_fprint(stdout, PROGRAM_NAME, COMMAND_NAME, opts); + printf("\n"); + + printf("Display help information about %s. If a command is specified, help\n", PROGRAM_NAME); + printf("about that command will be shown. Otherwise, general information about\n"); + printf("%s will be shown, including the commands available.\n", PROGRAM_NAME); + + return 0; +} + +static int print_commands(void) +{ + const cli_cmd_spec *cmd; + + cli_opt_usage_fprint(stdout, PROGRAM_NAME, NULL, cli_common_opts); + printf("\n"); + + printf("These are the %s commands available:\n\n", PROGRAM_NAME); + + for (cmd = cli_cmds; cmd->name; cmd++) + printf(" %-8s %s\n", cmd->name, cmd->desc); + + printf("\nSee '%s help ' for more information on a specific command.\n", PROGRAM_NAME); + + return 0; +} + +int cmd_help(int argc, char **argv) +{ + cli_opt invalid_opt; + + if (cli_opt_parse(&invalid_opt, opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU)) + return cli_opt_usage_error(COMMAND_NAME, opts, &invalid_opt); + + /* Show the meta-help */ + if (show_help) + return print_help(); + + /* We were not asked to show help for a specific command. */ + if (!command) + return print_commands(); + + /* If the user asks for help with the help command */ + if (strcmp(command, "help") == 0) + return print_help(); + + fprintf(stderr, "%s: '%s' is not a %s command. See '%s help'.\n", + PROGRAM_NAME, command, PROGRAM_NAME, PROGRAM_NAME); + return CLI_EXIT_ERROR; +} diff --git a/src/cli/main.c b/src/cli/main.c index 5eff56a1d6b..c68c349f737 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -8,19 +8,36 @@ #include #include #include "cli.h" +#include "cmd.h" +static int show_help = 0; static int show_version = 0; +static char *command = NULL; +static char **args = NULL; -static const cli_opt_spec common_opts[] = { - { CLI_OPT_TYPE_SWITCH, "version", 0, &show_version, 1, - CLI_OPT_USAGE_DEFAULT, NULL, "display the version" }, +const cli_opt_spec cli_common_opts[] = { + { CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1, + CLI_OPT_USAGE_DEFAULT, NULL, "display help information" }, + { CLI_OPT_TYPE_SWITCH, "version", 0, &show_version, 1, + CLI_OPT_USAGE_DEFAULT, NULL, "display the version" }, + { CLI_OPT_TYPE_ARG, "command", 0, &command, 0, + CLI_OPT_USAGE_REQUIRED, "command", "the command to run" }, + { CLI_OPT_TYPE_ARGS, "args", 0, &args, 0, + CLI_OPT_USAGE_DEFAULT, "args", "arguments for the command" }, { 0 } }; +const cli_cmd_spec cli_cmds[] = { + { "help", cmd_help, "Display help information" }, + { NULL } +}; + int main(int argc, char **argv) { + const cli_cmd_spec *cmd; cli_opt_parser optparser; cli_opt opt; + int args_len = 0; int ret = 0; if (git_libgit2_init() < 0) { @@ -28,16 +45,26 @@ int main(int argc, char **argv) exit(CLI_EXIT_GIT); } - cli_opt_parser_init(&optparser, common_opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU); + cli_opt_parser_init(&optparser, cli_common_opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU); /* Parse the top-level (common) options and command information */ while (cli_opt_parser_next(&opt, &optparser)) { if (!opt.spec) { cli_opt_status_fprint(stderr, PROGRAM_NAME, &opt); - cli_opt_usage_fprint(stderr, PROGRAM_NAME, NULL, common_opts); + cli_opt_usage_fprint(stderr, PROGRAM_NAME, NULL, cli_common_opts); ret = CLI_EXIT_USAGE; goto done; } + + /* + * When we see a command, stop parsing and capture the + * remaining arguments as args for the command itself. + */ + if (command) { + args = &argv[optparser.idx]; + args_len = (int)(argc - optparser.idx); + break; + } } if (show_version) { @@ -45,6 +72,20 @@ int main(int argc, char **argv) goto done; } + /* If there was no command, we want to invoke "help" */ + if (!command || show_help) { + cli_opt_usage_fprint(stdout, PROGRAM_NAME, NULL, cli_common_opts); + goto done; + } + + if ((cmd = cli_cmd_spec_byname(command)) == NULL) { + ret = cli_error("'%s' is not a %s command. See '%s help'.", + command, PROGRAM_NAME, PROGRAM_NAME); + goto done; + } + + ret = cmd->fn(args_len, args); + done: git_libgit2_shutdown(); return ret; From f8e7d8fdde563df6c9351296b6330bb8cc859066 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Fri, 26 Nov 2021 17:33:38 -0500 Subject: [PATCH 0826/1616] cli: support `help ` Support `help ` by re-invoking the command itself with the `--help` argument. This allows us to keep the help logic with the commands itself. --- src/cli/README.md | 4 ++++ src/cli/cmd_help.c | 23 ++++++++++++++++------- src/cli/main.c | 17 ++++++++++++++--- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/cli/README.md b/src/cli/README.md index 26f11d90afb..3087c39c425 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -20,3 +20,7 @@ A git-compatible command-line interface that uses libgit2. entrypoint and a brief description that can be printed in `git help`. This is done because commands are linked into the main cli. +3. Commands should accept a `--help` option that displays their help + information. This will be shown when a user runs ` --help` and + when a user runs `help `. + diff --git a/src/cli/cmd_help.c b/src/cli/cmd_help.c index d2ff5d4f482..7ee9822427c 100644 --- a/src/cli/cmd_help.c +++ b/src/cli/cmd_help.c @@ -45,7 +45,7 @@ static int print_commands(void) printf("These are the %s commands available:\n\n", PROGRAM_NAME); for (cmd = cli_cmds; cmd->name; cmd++) - printf(" %-8s %s\n", cmd->name, cmd->desc); + printf(" %-11s %s\n", cmd->name, cmd->desc); printf("\nSee '%s help ' for more information on a specific command.\n", PROGRAM_NAME); @@ -54,6 +54,8 @@ static int print_commands(void) int cmd_help(int argc, char **argv) { + char *fake_args[2]; + const cli_cmd_spec *cmd; cli_opt invalid_opt; if (cli_opt_parse(&invalid_opt, opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU)) @@ -67,11 +69,18 @@ int cmd_help(int argc, char **argv) if (!command) return print_commands(); - /* If the user asks for help with the help command */ - if (strcmp(command, "help") == 0) - return print_help(); + /* + * If we were asked for help for a command (eg, `help `), + * delegate back to that command's `--help` option. This lets + * commands own their help. Emulate the command-line arguments + * that would invoke ` --help` and invoke that command. + */ + fake_args[0] = command; + fake_args[1] = "--help"; + + if ((cmd = cli_cmd_spec_byname(command)) == NULL) + return cli_error("'%s' is not a %s command. See '%s help'.", + command, PROGRAM_NAME, PROGRAM_NAME); - fprintf(stderr, "%s: '%s' is not a %s command. See '%s help'.\n", - PROGRAM_NAME, command, PROGRAM_NAME, PROGRAM_NAME); - return CLI_EXIT_ERROR; + return cmd->fn(2, fake_args); } diff --git a/src/cli/main.c b/src/cli/main.c index c68c349f737..d961f659f41 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -37,6 +37,8 @@ int main(int argc, char **argv) const cli_cmd_spec *cmd; cli_opt_parser optparser; cli_opt opt; + char *help_args[3] = { NULL }; + int help_args_len; int args_len = 0; int ret = 0; @@ -72,10 +74,19 @@ int main(int argc, char **argv) goto done; } - /* If there was no command, we want to invoke "help" */ + /* + * If `--help ` is specified, delegate to that command's + * `--help` option. If no command is specified, run the `help` + * command. Do this by updating the args to emulate that behavior. + */ if (!command || show_help) { - cli_opt_usage_fprint(stdout, PROGRAM_NAME, NULL, cli_common_opts); - goto done; + help_args[0] = command ? (char *)command : "help"; + help_args[1] = command ? "--help" : NULL; + help_args_len = command ? 2 : 1; + + command = help_args[0]; + args = help_args; + args_len = help_args_len; } if ((cmd = cli_cmd_spec_byname(command)) == NULL) { From b877122750aa0435bab701825378754783d09485 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 28 Nov 2021 10:32:03 -0500 Subject: [PATCH 0827/1616] cli: add `cat-file` command Introduce a simple command that emulates `git cat-file`. --- src/cli/cmd.h | 1 + src/cli/cmd_cat_file.c | 204 +++++++++++++++++++++++++++++++++++++++++ src/cli/main.c | 3 +- 3 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 src/cli/cmd_cat_file.c diff --git a/src/cli/cmd.h b/src/cli/cmd.h index 816614efcb5..cc1743ed225 100644 --- a/src/cli/cmd.h +++ b/src/cli/cmd.h @@ -25,6 +25,7 @@ extern const cli_cmd_spec cli_cmds[]; extern const cli_cmd_spec *cli_cmd_spec_byname(const char *name); /* Commands */ +extern int cmd_cat_file(int argc, char **argv); extern int cmd_help(int argc, char **argv); #endif /* CLI_cmd_h__ */ diff --git a/src/cli/cmd_cat_file.c b/src/cli/cmd_cat_file.c new file mode 100644 index 00000000000..fb53a722ba2 --- /dev/null +++ b/src/cli/cmd_cat_file.c @@ -0,0 +1,204 @@ +/* + * 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 +#include "cli.h" +#include "cmd.h" + +#define COMMAND_NAME "cat-file" + +typedef enum { + DISPLAY_CONTENT = 0, + DISPLAY_EXISTS, + DISPLAY_PRETTY, + DISPLAY_SIZE, + DISPLAY_TYPE +} display_t; + +static int show_help; +static int display = DISPLAY_CONTENT; +static char *type_name, *object_spec; + +static const cli_opt_spec opts[] = { + { CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1, + CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING, NULL, + "display help about the " COMMAND_NAME " command" }, + + { CLI_OPT_TYPE_SWITCH, NULL, 't', &display, DISPLAY_TYPE, + CLI_OPT_USAGE_REQUIRED, NULL, "display the type of the object" }, + { CLI_OPT_TYPE_SWITCH, NULL, 's', &display, DISPLAY_SIZE, + CLI_OPT_USAGE_CHOICE, NULL, "display the size of the object" }, + { CLI_OPT_TYPE_SWITCH, NULL, 'e', &display, DISPLAY_EXISTS, + CLI_OPT_USAGE_CHOICE, NULL, "displays nothing unless the object is corrupt" }, + { CLI_OPT_TYPE_SWITCH, NULL, 'p', &display, DISPLAY_PRETTY, + CLI_OPT_USAGE_CHOICE, NULL, "pretty-print the object" }, + { CLI_OPT_TYPE_ARG, "type", 0, &type_name, 0, + CLI_OPT_USAGE_CHOICE, "type", "the type of object to display" }, + { CLI_OPT_TYPE_ARG, "object", 0, &object_spec, 0, + CLI_OPT_USAGE_REQUIRED, "object", "the object to display" }, + { 0 }, +}; + +static void print_help(void) +{ + cli_opt_usage_fprint(stdout, PROGRAM_NAME, COMMAND_NAME, opts); + printf("\n"); + + printf("Display the content for the given object in the repository.\n"); + printf("\n"); + + printf("Options:\n"); + + cli_opt_help_fprint(stdout, opts); +} + +static int print_odb(git_object *object, display_t display) +{ + git_odb *odb = NULL; + git_odb_object *odb_object = NULL; + const unsigned char *content; + git_object_size_t size; + int ret = 0; + + /* + * Our parsed blobs retain the raw content; all other objects are + * parsed into a working representation. To get the raw content, + * we need to do an ODB lookup. (Thankfully, this should be cached + * in-memory from our last call.) + */ + if (git_object_type(object) == GIT_OBJECT_BLOB) { + content = git_blob_rawcontent((git_blob *)object); + size = git_blob_rawsize((git_blob *)object); + } else { + if (git_repository_odb(&odb, git_object_owner(object)) < 0 || + git_odb_read(&odb_object, odb, git_object_id(object)) < 0) { + ret = cli_error_git(); + goto done; + } + + content = git_odb_object_data(odb_object); + size = git_odb_object_size(odb_object); + } + + switch (display) { + case DISPLAY_SIZE: + if (printf("%" PRIu64 "\n", size) < 0) + ret = cli_error_os(); + break; + case DISPLAY_CONTENT: + if (p_write(fileno(stdout), content, (size_t)size) < 0) + ret = cli_error_os(); + break; + default: + GIT_ASSERT(0); + } + +done: + git_odb_object_free(odb_object); + git_odb_free(odb); + return ret; +} + +static int print_type(git_object *object) +{ + if (printf("%s\n", git_object_type2string(git_object_type(object))) < 0) + return cli_error_os(); + + return 0; +} + +static int print_pretty(git_object *object) +{ + const git_tree_entry *entry; + size_t i, count; + + /* + * Only trees are stored in an unreadable format and benefit from + * pretty-printing. + */ + if (git_object_type(object) != GIT_OBJECT_TREE) + return print_odb(object, DISPLAY_CONTENT); + + for (i = 0, count = git_tree_entrycount((git_tree *)object); i < count; i++) { + entry = git_tree_entry_byindex((git_tree *)object, i); + + if (printf("%06o %s %s\t%s\n", + git_tree_entry_filemode_raw(entry), + git_object_type2string(git_tree_entry_type(entry)), + git_oid_tostr_s(git_tree_entry_id(entry)), + git_tree_entry_name(entry)) < 0) + return cli_error_os(); + } + + return 0; +} + +int cmd_cat_file(int argc, char **argv) +{ + git_repository *repo = NULL; + git_object *object = NULL; + git_object_t type; + cli_opt invalid_opt; + int giterr, ret = 0; + + if (cli_opt_parse(&invalid_opt, opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU)) + return cli_opt_usage_error(COMMAND_NAME, opts, &invalid_opt); + + if (show_help) { + print_help(); + return 0; + } + + if (git_repository_open_ext(&repo, ".", GIT_REPOSITORY_OPEN_FROM_ENV, NULL) < 0) + return cli_error_git(); + + if ((giterr = git_revparse_single(&object, repo, object_spec)) < 0) { + if (display == DISPLAY_EXISTS && giterr == GIT_ENOTFOUND) + ret = 1; + else + ret = cli_error_git(); + + goto done; + } + + if (type_name) { + git_object *peeled; + + if ((type = git_object_string2type(type_name)) == GIT_OBJECT_INVALID) { + ret = cli_error_usage("invalid object type '%s'", type_name); + goto done; + } + + if (git_object_peel(&peeled, object, type) < 0) { + ret = cli_error_git(); + goto done; + } + + git_object_free(object); + object = peeled; + } + + switch (display) { + case DISPLAY_EXISTS: + ret = 0; + break; + case DISPLAY_TYPE: + ret = print_type(object); + break; + case DISPLAY_PRETTY: + ret = print_pretty(object); + break; + default: + ret = print_odb(object, display); + break; + } + +done: + git_object_free(object); + git_repository_free(repo); + return ret; +} diff --git a/src/cli/main.c b/src/cli/main.c index d961f659f41..4b422368201 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -28,7 +28,8 @@ const cli_opt_spec cli_common_opts[] = { }; const cli_cmd_spec cli_cmds[] = { - { "help", cmd_help, "Display help information" }, + { "cat-file", cmd_cat_file, "Display an object in the repository" }, + { "help", cmd_help, "Display help information" }, { NULL } }; From e7be6b76b68ca34a207b3d816546817cb2459615 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 29 Nov 2021 12:04:06 -0500 Subject: [PATCH 0828/1616] futils: provide an option to read a whole file by fd --- src/util/futils.c | 36 ++++++++++++++++++++++++++++++++++++ src/util/futils.h | 1 + 2 files changed, 37 insertions(+) diff --git a/src/util/futils.c b/src/util/futils.c index 2b0dbf362af..9b8d468c506 100644 --- a/src/util/futils.c +++ b/src/util/futils.c @@ -179,6 +179,42 @@ int git_futils_readbuffer_fd(git_str *buf, git_file fd, size_t len) return 0; } +int git_futils_readbuffer_fd_full(git_str *buf, git_file fd) +{ + static size_t blocksize = 10240; + size_t alloc_len = 0, total_size = 0; + ssize_t read_size = 0; + + git_str_clear(buf); + + while (true) { + GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, blocksize); + + if (git_str_grow(buf, alloc_len) < 0) + return -1; + + /* p_read loops internally to read blocksize bytes */ + read_size = p_read(fd, buf->ptr, blocksize); + + if (read_size < 0) { + git_error_set(GIT_ERROR_OS, "failed to read descriptor"); + git_str_dispose(buf); + return -1; + } + + total_size += read_size; + + if ((size_t)read_size < blocksize) { + break; + } + } + + buf->ptr[total_size] = '\0'; + buf->size = total_size; + + return 0; +} + int git_futils_readbuffer_updated( git_str *out, const char *path, diff --git a/src/util/futils.h b/src/util/futils.h index fb1afcbd596..3f207afb2f2 100644 --- a/src/util/futils.h +++ b/src/util/futils.h @@ -27,6 +27,7 @@ extern int git_futils_readbuffer_updated( const char *path, unsigned char checksum[GIT_HASH_SHA1_SIZE], int *updated); +extern int git_futils_readbuffer_fd_full(git_str *obj, git_file fd); extern int git_futils_readbuffer_fd(git_str *obj, git_file fd, size_t len); /* Additional constants for `git_futils_writebuffer`'s `open_flags`. We From dcabef22af8ea30aa606e19605cf71887a0b428f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 21 Feb 2022 13:06:43 -0500 Subject: [PATCH 0829/1616] futils: produce improved error messages --- src/util/futils.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/util/futils.c b/src/util/futils.c index 9b8d468c506..cb872de09f6 100644 --- a/src/util/futils.c +++ b/src/util/futils.c @@ -167,12 +167,18 @@ int git_futils_readbuffer_fd(git_str *buf, git_file fd, size_t len) /* p_read loops internally to read len bytes */ read_size = p_read(fd, buf->ptr, len); - if (read_size != (ssize_t)len) { + if (read_size < 0) { git_error_set(GIT_ERROR_OS, "failed to read descriptor"); git_str_dispose(buf); return -1; } + if ((size_t)read_size != len) { + git_error_set(GIT_ERROR_FILESYSTEM, "could not read (expected %" PRIuZ " bytes, read %" PRIuZ ")", len, (size_t)read_size); + git_str_dispose(buf); + return -1; + } + buf->ptr[read_size] = '\0'; buf->size = read_size; From e427d0a1589c67bea3c1e822cd9edd83e0705f74 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 30 Nov 2021 10:33:24 -0500 Subject: [PATCH 0830/1616] cli: add `hash-object` command Introduce a simple command that emulates `git hash-object`. --- src/cli/cmd.h | 1 + src/cli/cmd_hash_object.c | 135 ++++++++++++++++++++++++++++++++++++++ src/cli/main.c | 5 +- 3 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 src/cli/cmd_hash_object.c diff --git a/src/cli/cmd.h b/src/cli/cmd.h index cc1743ed225..664b5021a75 100644 --- a/src/cli/cmd.h +++ b/src/cli/cmd.h @@ -26,6 +26,7 @@ extern const cli_cmd_spec *cli_cmd_spec_byname(const char *name); /* Commands */ extern int cmd_cat_file(int argc, char **argv); +extern int cmd_hash_object(int argc, char **argv); extern int cmd_help(int argc, char **argv); #endif /* CLI_cmd_h__ */ diff --git a/src/cli/cmd_hash_object.c b/src/cli/cmd_hash_object.c new file mode 100644 index 00000000000..5cfe9146a6b --- /dev/null +++ b/src/cli/cmd_hash_object.c @@ -0,0 +1,135 @@ +/* + * 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 +#include "cli.h" +#include "cmd.h" + +#include "futils.h" + +#define COMMAND_NAME "hash-object" + +static int show_help; +static char *type_name; +static int write_object, read_stdin, literally; +static char **filenames; + +static const cli_opt_spec opts[] = { + { CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1, + CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING, NULL, + "display help about the " COMMAND_NAME " command" }, + + { CLI_OPT_TYPE_VALUE, NULL, 't', &type_name, 0, + CLI_OPT_USAGE_DEFAULT, "type", "the type of object to hash (default: \"blob\")" }, + { CLI_OPT_TYPE_SWITCH, NULL, 'w', &write_object, 1, + CLI_OPT_USAGE_DEFAULT, NULL, "write the object to the object database" }, + { CLI_OPT_TYPE_SWITCH, "literally", 0, &literally, 1, + CLI_OPT_USAGE_DEFAULT, NULL, "do not validate the object contents" }, + { CLI_OPT_TYPE_SWITCH, "stdin", 0, &read_stdin, 1, + CLI_OPT_USAGE_REQUIRED, NULL, "read content from stdin" }, + { CLI_OPT_TYPE_ARGS, "file", 0, &filenames, 0, + CLI_OPT_USAGE_CHOICE, "file", "the file (or files) to read and hash" }, + { 0 }, +}; + +static void print_help(void) +{ + cli_opt_usage_fprint(stdout, PROGRAM_NAME, COMMAND_NAME, opts); + printf("\n"); + + printf("Compute the object ID for a given file and optionally write that file\nto the object database.\n"); + printf("\n"); + + printf("Options:\n"); + + cli_opt_help_fprint(stdout, opts); +} + +static int hash_buf(git_odb *odb, git_str *buf, git_object_t type) +{ + git_oid oid; + + if (!literally) { + int valid = 0; + + if (git_object_rawcontent_is_valid(&valid, buf->ptr, buf->size, type) < 0 || !valid) + return cli_error_git(); + } + + if (write_object) { + if (git_odb_write(&oid, odb, buf->ptr, buf->size, type) < 0) + return cli_error_git(); + } else { + if (git_odb_hash(&oid, buf->ptr, buf->size, type) < 0) + return cli_error_git(); + } + + if (printf("%s\n", git_oid_tostr_s(&oid)) < 0) + return cli_error_os(); + + return 0; +} + +int cmd_hash_object(int argc, char **argv) +{ + git_repository *repo = NULL; + git_odb *odb = NULL; + git_str buf = GIT_STR_INIT; + cli_opt invalid_opt; + git_object_t type = GIT_OBJECT_BLOB; + char **filename; + int ret = 0; + + if (cli_opt_parse(&invalid_opt, opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU)) + return cli_opt_usage_error(COMMAND_NAME, opts, &invalid_opt); + + if (show_help) { + print_help(); + return 0; + } + + if (type_name && (type = git_object_string2type(type_name)) == GIT_OBJECT_INVALID) + return cli_error_usage("invalid object type '%s'", type_name); + + if (write_object && + (git_repository_open_ext(&repo, ".", GIT_REPOSITORY_OPEN_FROM_ENV, NULL) < 0 || + git_repository_odb(&odb, repo) < 0)) { + ret = cli_error_git(); + goto done; + } + + /* + * TODO: we're reading blobs, we shouldn't pull them all into main + * memory, we should just stream them into the odb instead. + * (Or create a `git_odb_writefile` API.) + */ + if (read_stdin) { + if (git_futils_readbuffer_fd_full(&buf, fileno(stdin)) < 0) { + ret = cli_error_git(); + goto done; + } + + if ((ret = hash_buf(odb, &buf, type)) != 0) + goto done; + } else { + for (filename = filenames; *filename; filename++) { + if (git_futils_readbuffer(&buf, *filename) < 0) { + ret = cli_error_git(); + goto done; + } + + if ((ret = hash_buf(odb, &buf, type)) != 0) + goto done; + } + } + +done: + git_str_dispose(&buf); + git_odb_free(odb); + git_repository_free(repo); + return ret; +} diff --git a/src/cli/main.c b/src/cli/main.c index 4b422368201..08abb324f87 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -28,8 +28,9 @@ const cli_opt_spec cli_common_opts[] = { }; const cli_cmd_spec cli_cmds[] = { - { "cat-file", cmd_cat_file, "Display an object in the repository" }, - { "help", cmd_help, "Display help information" }, + { "cat-file", cmd_cat_file, "Display an object in the repository" }, + { "hash-object", cmd_hash_object, "Hash a raw object and product its object ID" }, + { "help", cmd_help, "Display help information" }, { NULL } }; From e32db9f2b85685801fb249e35bf62a32ef09dc98 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 27 Feb 2022 08:54:09 -0500 Subject: [PATCH 0831/1616] cli: always give a value to `error` --- src/cli/opt_usage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/opt_usage.c b/src/cli/opt_usage.c index 6e5d6006ee1..478b416316d 100644 --- a/src/cli/opt_usage.c +++ b/src/cli/opt_usage.c @@ -150,7 +150,7 @@ int cli_opt_help_fprint( { git_str help = GIT_BUF_INIT; const cli_opt_spec *spec; - int error; + int error = 0; /* Display required arguments first */ for (spec = specs; spec->type; ++spec) { From d9b041e6d7de9e2fc8fcdbb6e28acba45af4d888 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 27 Feb 2022 09:20:58 -0500 Subject: [PATCH 0832/1616] assert: add `ASSERT_WITH_CLEANUP` Now that we safely assert and return, we may need to be in a place where we need to unlock mutexes or cleanup resources. Provide `ASSERT_WITH_CLEANUP` that permits for this behavior by taking a block. --- src/util/assert_safe.h | 16 ++++++++++++++++ tests/util/assert.c | 23 +++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/util/assert_safe.h b/src/util/assert_safe.h index 8c261100f3e..cc0bac551d2 100644 --- a/src/util/assert_safe.h +++ b/src/util/assert_safe.h @@ -24,6 +24,8 @@ # define GIT_ASSERT_WITH_RETVAL(expr, fail) assert(expr) # define GIT_ASSERT_ARG_WITH_RETVAL(expr, fail) assert(expr) + +# define GIT_ASSERT_WITH_CLEANUP(expr, cleanup) assert(expr) #else /** Internal consistency check to stop the function. */ @@ -53,6 +55,20 @@ } \ } while(0) +/** + * Go to to the given label on assertion failures; useful when you have + * taken a lock or otherwise need to release a resource. + */ +# define GIT_ASSERT_WITH_CLEANUP(expr, cleanup) \ + GIT_ASSERT__WITH_CLEANUP(expr, GIT_ERROR_INTERNAL, "unrecoverable internal error", cleanup) + +# define GIT_ASSERT__WITH_CLEANUP(expr, code, msg, cleanup) do { \ + if (!(expr)) { \ + git_error_set(code, "%s: '%s'", msg, #expr); \ + cleanup; \ + } \ + } while(0) + #endif /* GIT_ASSERT_HARD */ #endif diff --git a/tests/util/assert.c b/tests/util/assert.c index 26c42978754..3babc475ae3 100644 --- a/tests/util/assert.c +++ b/tests/util/assert.c @@ -36,6 +36,21 @@ static const char *bad_returns_string(void) return hello_world; } +static int has_cleanup(void) +{ + int error = 42; + + GIT_ASSERT_WITH_CLEANUP(1 + 1 == 3, { + error = 99; + goto foobar; + }); + + return 0; + +foobar: + return error; +} + void test_assert__argument(void) { cl_git_fail(dummy_fn(NULL)); @@ -92,3 +107,11 @@ void test_assert__internal(void) cl_assert_equal_i(GIT_ERROR_INTERNAL, git_error_last()->klass); cl_assert_equal_s("unrecoverable internal error: '1 + 1 == 3'", git_error_last()->message); } + +void test_assert__with_cleanup(void) +{ + cl_git_fail_with(99, has_cleanup()); + cl_assert(git_error_last()); + cl_assert_equal_i(GIT_ERROR_INTERNAL, git_error_last()->klass); + cl_assert_equal_s("unrecoverable internal error: '1 + 1 == 3'", git_error_last()->message); +} From 043a87a0aaae203537e069af9f2599c18a9732a5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 27 Feb 2022 09:21:53 -0500 Subject: [PATCH 0833/1616] refdb: unlock mutex on assertion failure If we're safely asserting (and returning an error to the caller), we should still unlock our mutex. --- src/libgit2/refdb_fs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libgit2/refdb_fs.c b/src/libgit2/refdb_fs.c index 95bda940472..ef85016b1e4 100644 --- a/src/libgit2/refdb_fs.c +++ b/src/libgit2/refdb_fs.c @@ -1361,7 +1361,11 @@ static int packed_write(refdb_fs_backend *backend) for (i = 0; i < git_sortedcache_entrycount(refcache); ++i) { struct packref *ref = git_sortedcache_entry(refcache, i); - GIT_ASSERT(ref); + + GIT_ASSERT_WITH_CLEANUP(ref, { + error = -1; + goto fail; + }); if ((error = packed_find_peel(backend, ref)) < 0) goto fail; From 9f0088c4ed82e30635b01466f80b0bc0584acb08 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 27 Feb 2022 09:26:16 -0500 Subject: [PATCH 0834/1616] fs_path: exit quickly in `dirname_r` failure When we encounter a situation where we need to exit, simply `return -1` instead of trying to set `len = -1` and then jumping to the exit handler, which would erroneously do work based on the `len` value. --- src/util/fs_path.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/util/fs_path.c b/src/util/fs_path.c index 920c3907349..65842426c63 100644 --- a/src/util/fs_path.c +++ b/src/util/fs_path.c @@ -109,7 +109,7 @@ int git_fs_path_basename_r(git_str *buffer, const char *path) /* Empty or NULL string gets treated as "." */ if (path == NULL || *path == '\0') { startp = "."; - len = 1; + len = 1; goto Exit; } @@ -121,7 +121,7 @@ int git_fs_path_basename_r(git_str *buffer, const char *path) /* All slashes becomes "/" */ if (endp == path && *endp == '/') { startp = "/"; - len = 1; + len = 1; goto Exit; } @@ -193,8 +193,7 @@ int git_fs_path_dirname_r(git_str *buffer, const char *path) if (endp - path + 1 > INT_MAX) { git_error_set(GIT_ERROR_INVALID, "path too long"); - len = -1; - goto Exit; + return -1; } if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) { @@ -219,8 +218,7 @@ int git_fs_path_dirname_r(git_str *buffer, const char *path) if (endp - path + 1 > INT_MAX) { git_error_set(GIT_ERROR_INVALID, "path too long"); - len = -1; - goto Exit; + return -1; } if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) { From 241d838f4878c251290291be1fb847cc6c6cbd03 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 27 Feb 2022 10:02:05 -0500 Subject: [PATCH 0835/1616] http: skip processing when body is null or 0 length Mistakenly `&&` when we should have `||`d. --- src/libgit2/transports/httpclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libgit2/transports/httpclient.c b/src/libgit2/transports/httpclient.c index 75782da82f9..f07923ef296 100644 --- a/src/libgit2/transports/httpclient.c +++ b/src/libgit2/transports/httpclient.c @@ -395,7 +395,7 @@ static int on_body(http_parser *parser, const char *buf, size_t len) size_t max_len; /* Saw data when we expected not to (eg, in consume_response_body) */ - if (ctx->output_buf == NULL && ctx->output_size == 0) { + if (ctx->output_buf == NULL || ctx->output_size == 0) { ctx->parse_status = PARSE_STATUS_NO_OUTPUT; return 0; } From 073e63d0a4fcce09cf6a2dc7d7f974f1bbbef792 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 27 Feb 2022 10:05:24 -0500 Subject: [PATCH 0836/1616] object: validate that `odb_obj` was set --- src/libgit2/object.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libgit2/object.c b/src/libgit2/object.c index 7bc256fcebd..b828f88f68c 100644 --- a/src/libgit2/object.c +++ b/src/libgit2/object.c @@ -250,6 +250,7 @@ int git_object_lookup_prefix( if (error < 0) return error; + GIT_ASSERT(odb_obj); error = git_object__from_odb_object(object_out, repo, odb_obj, type); git_odb_object_free(odb_obj); From b08fe71d3bc6d01e6e7f248bc01a6fc11fa03f4c Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 27 Feb 2022 23:16:05 -0500 Subject: [PATCH 0837/1616] cmake: export libraries needed to compile against libgit2 If users are using us as a direct dependency (via `add_subdirectory`) then they may want to know the libraries to link to; tell them. --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 763bd437bc4..750b7089df8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,14 @@ if(BUILD_FUZZERS) endif() +# Export for people who use us as a dependency + +if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") + set(LIBGIT2_DEPENDENCY_OBJECTS ${LIBGIT2_DEPENDENCY_OBJECTS} PARENT_SCOPE) + set(LIBGIT2_SYSTEM_LIBS ${LIBGIT2_SYSTEM_LIBS} PARENT_SCOPE) +endif() + + # Summary feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:") From cfdf36f989cadba458c733607476631043af27d0 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 22 Feb 2022 21:49:15 -0500 Subject: [PATCH 0838/1616] ci: rename build setup scripts Rename our build setup scripts to include the `build` name so that we can add additional CI setup scripts with no ambiguity. --- .github/workflows/main.yml | 2 +- .github/workflows/nightly.yml | 2 +- ci/{setup-mingw.sh => setup-mingw-build.sh} | 4 +++- ci/{setup-osx.sh => setup-osx-build.sh} | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) rename ci/{setup-mingw.sh => setup-mingw-build.sh} (97%) rename ci/{setup-osx.sh => setup-osx-build.sh} (95%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 74bab53f308..0ac8b8b8726 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -214,7 +214,7 @@ jobs: path: source fetch-depth: 0 - name: Set up build environment - run: source/ci/setup-${{ matrix.platform.setup-script }}.sh + run: source/ci/setup-${{ matrix.platform.setup-script }}-build.sh shell: bash if: matrix.platform.setup-script != '' - name: Setup QEMU diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 5513d5b435f..4f24be6194e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -271,7 +271,7 @@ jobs: path: source fetch-depth: 0 - name: Set up build environment - run: source/ci/setup-${{ matrix.platform.setup-script }}.sh + run: source/ci/setup-${{ matrix.platform.setup-script }}-build.sh shell: bash if: matrix.platform.setup-script != '' - name: Setup QEMU diff --git a/ci/setup-mingw.sh b/ci/setup-mingw-build.sh similarity index 97% rename from ci/setup-mingw.sh rename to ci/setup-mingw-build.sh index f5a882d2bdf..3d72b24eb50 100755 --- a/ci/setup-mingw.sh +++ b/ci/setup-mingw-build.sh @@ -1,4 +1,6 @@ -#!/bin/sh -e +#!/bin/sh + +set -ex echo "##############################################################################" echo "## Downloading mingw" diff --git a/ci/setup-osx.sh b/ci/setup-osx-build.sh similarity index 95% rename from ci/setup-osx.sh rename to ci/setup-osx-build.sh index 2e630eedbba..0b95e7629e4 100755 --- a/ci/setup-osx.sh +++ b/ci/setup-osx-build.sh @@ -1,6 +1,6 @@ #!/bin/sh -set -x +set -ex brew update brew install pkgconfig zlib curl openssl libssh2 ninja From e48bb3b708d75dc0a41590543a5f844509d87d8e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 22 Feb 2022 21:52:08 -0500 Subject: [PATCH 0839/1616] ci: allow for build-time (`cmake --build`) options Allow for options in the `cmake --build` phase, so that callers can specify (eg) the config type. --- ci/build.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ci/build.sh b/ci/build.sh index 5a51f925ad0..21a45af5f58 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -59,7 +59,7 @@ echo "########################################################################## echo "## Configuring build environment" echo "##############################################################################" -echo cmake -DENABLE_WERROR=ON -DBUILD_EXAMPLES=ON -DBUILD_FUZZERS=ON -DUSE_STANDALONE_FUZZERS=ON -G \"${CMAKE_GENERATOR}\" ${CMAKE_OPTIONS} -S \"${SOURCE_DIR}\" +echo "${CMAKE}" -DENABLE_WERROR=ON -DBUILD_EXAMPLES=ON -DBUILD_FUZZERS=ON -DUSE_STANDALONE_FUZZERS=ON -G \"${CMAKE_GENERATOR}\" ${CMAKE_OPTIONS} -S \"${SOURCE_DIR}\" env PATH="${BUILD_PATH}" "${CMAKE}" -DENABLE_WERROR=ON -DBUILD_EXAMPLES=ON -DBUILD_FUZZERS=ON -DUSE_STANDALONE_FUZZERS=ON -G "${CMAKE_GENERATOR}" ${CMAKE_OPTIONS} -S "${SOURCE_DIR}" echo "" @@ -69,10 +69,11 @@ echo "########################################################################## # Determine parallelism; newer cmake supports `--build --parallel` but # we cannot yet rely on that. -if [ "${CMAKE_GENERATOR}" = "Unix Makefiles" -a "${CORES}" != "" ]; then +if [ "${CMAKE_GENERATOR}" = "Unix Makefiles" -a "${CORES}" != "" -a "${CMAKE_BUILD_OPTIONS}" = "" ]; then BUILDER=(make -j ${CORES}) else - BUILDER=("${CMAKE}" --build .) + BUILDER=("${CMAKE}" --build . ${CMAKE_BUILD_OPTIONS}) fi +echo "${BUILDER[@]}" env PATH="${BUILD_PATH}" "${BUILDER[@]}" From 93037bab1c6758c7939d16ea59b0e434e5ddea86 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 22 Feb 2022 22:00:37 -0500 Subject: [PATCH 0840/1616] tests: add benchmark tests Add a benchmark test suite that wraps hyperfine and is suitable for producing data about test runs of a CLI or A/B testing CLIs. --- tests/README.md | 2 + tests/benchmarks/README.md | 121 ++++++ tests/benchmarks/benchmark.sh | 298 ++++++++++++++ tests/benchmarks/benchmark_helpers.sh | 363 ++++++++++++++++++ tests/benchmarks/hash-object__text_100kb | 7 + tests/benchmarks/hash-object__text_10mb | 7 + tests/benchmarks/hash-object__text_1kb | 7 + .../benchmarks/hash-object__text_cached_100kb | 7 + .../benchmarks/hash-object__text_cached_10mb | 7 + tests/benchmarks/hash-object__text_cached_1kb | 7 + .../benchmarks/hash-object__write_text_100kb | 9 + tests/benchmarks/hash-object__write_text_10mb | 9 + tests/benchmarks/hash-object__write_text_1kb | 9 + .../hash-object__write_text_cached_100kb | 9 + .../hash-object__write_text_cached_10mb | 9 + .../hash-object__write_text_cached_1kb | 9 + 16 files changed, 880 insertions(+) create mode 100644 tests/benchmarks/README.md create mode 100755 tests/benchmarks/benchmark.sh create mode 100644 tests/benchmarks/benchmark_helpers.sh create mode 100755 tests/benchmarks/hash-object__text_100kb create mode 100755 tests/benchmarks/hash-object__text_10mb create mode 100755 tests/benchmarks/hash-object__text_1kb create mode 100755 tests/benchmarks/hash-object__text_cached_100kb create mode 100755 tests/benchmarks/hash-object__text_cached_10mb create mode 100755 tests/benchmarks/hash-object__text_cached_1kb create mode 100755 tests/benchmarks/hash-object__write_text_100kb create mode 100755 tests/benchmarks/hash-object__write_text_10mb create mode 100755 tests/benchmarks/hash-object__write_text_1kb create mode 100755 tests/benchmarks/hash-object__write_text_cached_100kb create mode 100755 tests/benchmarks/hash-object__write_text_cached_10mb create mode 100755 tests/benchmarks/hash-object__write_text_cached_1kb diff --git a/tests/README.md b/tests/README.md index 5920b154706..460e045e386 100644 --- a/tests/README.md +++ b/tests/README.md @@ -2,6 +2,8 @@ These are the unit and integration tests for the libgit2 projects. +* `benchmarks` + These are benchmark tests that excercise the CLI. * `clar` This is [clar](https://github.com/clar-test/clar) the common test framework. * `headertest` diff --git a/tests/benchmarks/README.md b/tests/benchmarks/README.md new file mode 100644 index 00000000000..f66b27aea3b --- /dev/null +++ b/tests/benchmarks/README.md @@ -0,0 +1,121 @@ +# libgit2 benchmarks + +This folder contains the individual benchmark tests for libgit2, +meant for understanding the performance characteristics of libgit2, +comparing your development code to the existing libgit2 code, or +comparing libgit2 to the git reference implementation. + +## Running benchmark tests + +Benchmark tests can be run in several different ways: running all +benchmarks, running one (or more) suite of benchmarks, or running a +single individual benchmark. You can target either an individual +version of a CLI, or you can A/B test a baseline CLI against a test +CLI. + +### Specifying the command-line interface to test + +By default, the `git` in your path is benchmarked. Use the +`-c` (or `--cli`) option to specify the command-line interface +to test. + +Example: `libgit2_bench --cli git2_cli` will run the tests against +`git2_cli`. + +### Running tests to compare two different implementations + +You can compare a baseline command-line interface against a test +command-line interface using the `-b (or `--baseline-cli`) option. + +Example: `libgit2_bench --baseline-cli git --cli git2_cli` will +run the tests against both `git` and `git2_cli`. + +### Running individual benchmark tests + +Similar to how a test suite or individual test is specified in +[clar](https://github.com/clar-test/clar), the `-s` (or `--suite`) +option may be used to specify the suite or individual test to run. +Like clar, the suite and test name are separated by `::`, and like +clar, this is a prefix match. + +Examples: +* `libgit2_bench -shash_object` will run the tests in the + `hash_object` suite. +* `libgit2_bench -shash_object::random_1kb` will run the + `hash_object::random_1kb` test. +* `libgit2_bench -shash_object::random` will run all the tests that + begin with `hash_object::random`. + +## Writing benchmark tests + +Benchmark tests are meant to be easy to write. Each individual +benchmark is a shell script that allows it to do set up (eg, creating +or cloning a repository, creating temporary files, etc), then running +benchmarks, then teardown. + +The `benchmark_helpers.sh` script provides many helpful utility +functions to allow for cross-platform benchmarking, as well as a +wrapper for `hyperfine` that is suited to testing libgit2. +Note that the helper script must be included first, at the beginning +of the benchmark test. + +### Benchmark example + +This simplistic example compares the speed of running the `git help` +command in the baseline CLI to the test CLI. + +```bash +#!/bin/bash -e + +# include the benchmark library +. "$(dirname "$0")/benchmark_helpers.sh" + +# run the "help" command; this will benchmark `git2_cli help` +gitbench help +``` + +### Naming + +The filename of the benchmark itself is important. A benchmark's +filename should be the name of the benchmark suite, followed by two +underscores, followed by the name of the benchmark. For example, +`hash-object__random_1kb` is the `random_1kb` test in the `hash-object` +suite. + +### Options + +The `gitbench` function accepts several options. + +* `--sandbox ` + The name of a test resource (in the `tests/resources` directory). + This will be copied as-is to the sandbox location before test + execution. This is copied _before_ the `prepare` script is run. + This option may be specified multiple times. +* `--repository ` + The name of a test resource repository (in the `tests/resources` + directory). This repository will be copied into a sandbox location + before test execution, and your test will run in this directory. + This is copied _before_ the `prepare` script is run. +* `--prepare