summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PROJECTS.md3
-rw-r--r--include/git2/remote.h60
-rwxr-xr-xscript/cibuild.sh5
-rw-r--r--src/branch.c6
-rw-r--r--src/checkout.c4
-rw-r--r--src/global.c6
-rw-r--r--src/indexer.c12
-rw-r--r--src/odb.c4
-rw-r--r--src/push.c70
-rw-r--r--src/push.h6
-rw-r--r--src/refspec.c6
-rw-r--r--src/remote.c66
-rw-r--r--src/transports/http.c1
-rw-r--r--src/transports/local.c4
-rw-r--r--src/transports/smart_protocol.c12
-rw-r--r--tests/network/remote/local.c41
-rw-r--r--tests/odb/emptyobjects.c18
-rw-r--r--tests/online/fetch.c11
-rw-r--r--tests/online/push.c160
-rw-r--r--tests/online/push_util.c16
-rw-r--r--tests/online/push_util.h14
-rw-r--r--tests/refs/branches/upstream.c16
-rw-r--r--tests/resources/crlf/.gitted/objects/04/4bcd5c9bf5ebdd51e514a9a36457018f06f6e11
-rw-r--r--tests/resources/crlf/.gitted/objects/12/faf3c1ea55f572473cec9052fca468c3584ccb1
-rw-r--r--tests/resources/crlf/.gitted/objects/2b/55b4b94f655c857635b6a9005c056aa7de35322
-rw-r--r--tests/resources/crlf/.gitted/objects/2c/9a868cfdf8e270d0ec68164433376c68fb1789bin169 -> 0 bytes
-rw-r--r--tests/resources/crlf/.gitted/objects/78/db270c1841841f75a8157321bdcb50ab12e6c3bin0 -> 156 bytes
-rw-r--r--tests/resources/crlf/.gitted/objects/ba/aa042ab2976f8264e467988e6112ee518ec62ebin159 -> 0 bytes
-rw-r--r--tests/resources/crlf/.gitted/refs/heads/master2
-rw-r--r--tests/resources/crlf/.gitted/refs/heads/utf82
-rw-r--r--tests/status/worktree_init.c1
31 files changed, 392 insertions, 158 deletions
diff --git a/PROJECTS.md b/PROJECTS.md
index 5a09adae1..4f200b7f9 100644
--- a/PROJECTS.md
+++ b/PROJECTS.md
@@ -89,14 +89,11 @@ might make good smaller projects by themselves.
using binary search every time
* Tree builder improvements:
* Extend to allow building a tree hierarchy
-* Move the tagopt mechanism to the newer git 1.9 interpretation of
- --tags [#2120](https://github.com/libgit2/libgit2/issues/2120)
* Apply-patch API
* Add a patch editing API to enable "git add -p" type operations
* Textconv API to filter binary data before generating diffs (something
like the current Filter API, probably).
* Performance profiling and improvement
-* Build in handling of "empty tree" and "empty blob" SHAs
* Support "git replace" ref replacements
* Include conflicts in diff results and in status
* GIT_DELTA_CONFLICT for items in conflict (with multiple files)
diff --git a/include/git2/remote.h b/include/git2/remote.h
index 0d7fd230f..4aabd94b6 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -14,6 +14,7 @@
#include "indexer.h"
#include "strarray.h"
#include "transport.h"
+#include "push.h"
/**
* @file git2/remote.h
@@ -280,14 +281,19 @@ GIT_EXTERN(const git_refspec *)git_remote_get_refspec(const git_remote *remote,
GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction);
/**
- * Get a list of refs at the remote
+ * Get the remote repository's reference advertisement list
*
- * The remote (or more exactly its transport) must be connected. The
- * memory belongs to the remote.
+ * Get the list of references with which the server responds to a new
+ * connection.
*
- * The array will stay valid as long as the remote object exists and
- * its transport isn't changed, but a copy is recommended for usage of
- * the data.
+ * The remote (or more exactly its transport) must have connected to
+ * the remote repository. This list is available as soon as the
+ * connection to the remote is initiated and it remains available
+ * after disconnecting.
+ *
+ * The memory belongs to the remote. The pointer will be valid as long
+ * as a new connection is not initiated, but it is recommended that
+ * you make a copy in order to make use of the data.
*
* @param out pointer to the array
* @param size the number of remote heads
@@ -337,8 +343,7 @@ GIT_EXTERN(void) git_remote_stop(git_remote *remote);
/**
* Disconnect from the remote
*
- * Close the connection to the remote and free the underlying
- * transport.
+ * Close the connection to the remote.
*
* @param remote the remote to disconnect from
*/
@@ -390,6 +395,23 @@ GIT_EXTERN(int) git_remote_fetch(
const char *reflog_message);
/**
+ * Perform a push
+ *
+ * Peform all the steps from a push.
+ *
+ * @param remote the remote to push to
+ * @param refspecs the refspecs to use for pushing. If none are
+ * passed, the configured refspecs will be used
+ * @param opts the options
+ * @param signature signature to use for the reflog of updated references
+ * @param reflog_message message to use for the reflog of upated references
+ */
+GIT_EXTERN(int) git_remote_push(git_remote *remote,
+ git_strarray *refspecs,
+ const git_push_options *opts,
+ const git_signature *signature, const char *reflog_message);
+
+/**
* Get a list of the configured remotes for a repo
*
* The string array must be freed by the user.
@@ -462,6 +484,28 @@ struct git_remote_callbacks {
int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data);
/**
+ * Function to call with progress information during pack
+ * building. Be aware that this is called inline with pack
+ * building operations, so performance may be affected.
+ */
+ git_packbuilder_progress pack_progress;
+
+ /**
+ * Function to call with progress information during the
+ * upload portion of a push. Be aware that this is called
+ * inline with pack building operations, so performance may be
+ * affected.
+ */
+ git_push_transfer_progress push_transfer_progress;
+
+ /**
+ * Called for each updated reference on push. If `status` is
+ * not `NULL`, the update was rejected by the remote server
+ * and `status` contains the reason given.
+ */
+ int (*push_update_reference)(const char *refname, const char *status, void *data);
+
+ /**
* This will be passed to each of the callbacks in this struct
* as the last parameter.
*/
diff --git a/script/cibuild.sh b/script/cibuild.sh
index 360c28663..8983dcce0 100755
--- a/script/cibuild.sh
+++ b/script/cibuild.sh
@@ -44,6 +44,9 @@ export GITTEST_REMOTE_SSH_PUBKEY="$HOME/.ssh/id_rsa.pub"
export GITTEST_REMOTE_SSH_PASSPHRASE=""
if [ -e ./libgit2_clar ]; then
- ./libgit2_clar -sonline::push -sonline::clone::cred_callback -sonline::clone::ssh_cert &&
+ ./libgit2_clar -sonline::push -sonline::clone::ssh_cert &&
./libgit2_clar -sonline::clone::ssh_with_paths
+ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
+ ./libgit2_clar -sonline::clone::cred_callback
+ fi
fi
diff --git a/src/branch.c b/src/branch.c
index 01402a2e9..b4e4b0564 100644
--- a/src/branch.c
+++ b/src/branch.c
@@ -400,6 +400,12 @@ int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *r
if ((error = retrieve_upstream_configuration(&str, cfg, refname, "branch.%s.remote")) < 0)
goto cleanup;
+ if (!*str) {
+ giterr_set(GITERR_REFERENCE, "branch '%s' does not have an upstream remote", refname);
+ error = GIT_ENOTFOUND;
+ goto cleanup;
+ }
+
error = git_buf_puts(buf, str);
cleanup:
diff --git a/src/checkout.c b/src/checkout.c
index 44e2f3b27..4e879e36f 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -1145,12 +1145,16 @@ static int checkout_conflict_append_remove(
checkout_data *data = payload;
const char *name;
+ assert(ancestor || ours || theirs);
+
if (ancestor)
name = git__strdup(ancestor->path);
else if (ours)
name = git__strdup(ours->path);
else if (theirs)
name = git__strdup(theirs->path);
+ else
+ abort();
GITERR_CHECK_ALLOC(name);
diff --git a/src/global.c b/src/global.c
index da903cb94..006202a2c 100644
--- a/src/global.c
+++ b/src/global.c
@@ -67,7 +67,13 @@ void openssl_locking_function(int mode, int n, const char *file, int line)
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);
git__free(openssl_locks);
}
#endif
diff --git a/src/indexer.c b/src/indexer.c
index 620e8186b..0e682dd6e 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -120,6 +120,7 @@ int git_indexer_new(
idx->progress_cb = progress_cb;
idx->progress_payload = progress_payload;
idx->mode = mode ? mode : GIT_PACK_FILE_MODE;
+ git_hash_ctx_init(&idx->hash_ctx);
git_hash_ctx_init(&idx->trailer);
error = git_buf_joinpath(&path, prefix, suff);
@@ -265,7 +266,6 @@ static int store_object(git_indexer *idx)
struct entry *entry;
git_off_t entry_size;
struct git_pack_entry *pentry;
- git_hash_ctx *ctx = &idx->hash_ctx;
git_off_t entry_start = idx->entry_start;
entry = git__calloc(1, sizeof(*entry));
@@ -274,7 +274,7 @@ static int store_object(git_indexer *idx)
pentry = git__calloc(1, sizeof(struct git_pack_entry));
GITERR_CHECK_ALLOC(pentry);
- git_hash_final(&oid, ctx);
+ git_hash_final(&oid, &idx->hash_ctx);
entry_size = idx->off - entry_start;
if (entry_start > UINT31_MAX) {
entry->offset = UINT32_MAX;
@@ -557,7 +557,7 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
git_mwindow_close(&w);
idx->entry_start = entry_start;
- git_hash_ctx_init(&idx->hash_ctx);
+ git_hash_init(&idx->hash_ctx);
if (type == GIT_OBJ_REF_DELTA || type == GIT_OBJ_OFS_DELTA) {
error = advance_delta_offset(idx, type);
@@ -843,12 +843,10 @@ static int update_header_and_rehash(git_indexer *idx, git_transfer_progress *sta
git_mwindow *w = NULL;
git_mwindow_file *mwf;
unsigned int left;
- git_hash_ctx *ctx;
mwf = &idx->pack->mwf;
- ctx = &idx->trailer;
- git_hash_ctx_init(ctx);
+ git_hash_init(&idx->trailer);
/* Update the header to include the numer of local objects we injected */
@@ -1061,5 +1059,7 @@ void git_indexer_free(git_indexer *idx)
git_mutex_unlock(&git__mwindow_mutex);
}
+ git_hash_ctx_cleanup(&idx->trailer);
+ git_hash_ctx_cleanup(&idx->hash_ctx);
git__free(idx);
}
diff --git a/src/odb.c b/src/odb.c
index 2c19c0311..5961b35a7 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -762,12 +762,12 @@ static int hardcoded_objects(git_rawobj *raw, const git_oid *id)
if (!git_oid_cmp(id, &empty_blob)) {
raw->type = GIT_OBJ_BLOB;
raw->len = 0;
- raw->data = NULL;
+ raw->data = git__calloc(1, sizeof(uint8_t));
return 0;
} else if (!git_oid_cmp(id, &empty_tree)) {
raw->type = GIT_OBJ_TREE;
raw->len = 0;
- raw->data = NULL;
+ raw->data = git__calloc(1, sizeof(uint8_t));
return 0;
} else {
return GIT_ENOTFOUND;
diff --git a/src/push.c b/src/push.c
index be5ec1c0e..6671da465 100644
--- a/src/push.c
+++ b/src/push.c
@@ -19,7 +19,7 @@ static int push_spec_rref_cmp(const void *a, const void *b)
{
const push_spec *push_spec_a = a, *push_spec_b = b;
- return strcmp(push_spec_a->rref, push_spec_b->rref);
+ return strcmp(push_spec_a->refspec.dst, push_spec_b->refspec.dst);
}
static int push_status_ref_cmp(const void *a, const void *b)
@@ -94,12 +94,7 @@ static void free_refspec(push_spec *spec)
if (spec == NULL)
return;
- if (spec->lref)
- git__free(spec->lref);
-
- if (spec->rref)
- git__free(spec->rref);
-
+ git_refspec__free(&spec->refspec);
git__free(spec);
}
@@ -134,47 +129,25 @@ static int check_lref(git_push *push, char *ref)
static int parse_refspec(git_push *push, push_spec **spec, const char *str)
{
push_spec *s;
- char *delim;
*spec = NULL;
s = git__calloc(1, sizeof(*s));
GITERR_CHECK_ALLOC(s);
- if (str[0] == '+') {
- s->force = true;
- str++;
+ if (git_refspec__parse(&s->refspec, str, false) < 0) {
+ giterr_set(GITERR_INVALID, "invalid refspec %s", str);
+ goto on_error;
}
- delim = strchr(str, ':');
- if (delim == NULL) {
- s->lref = git__strdup(str);
- if (!s->lref || check_lref(push, s->lref) < 0)
- goto on_error;
- } else {
- if (delim - str) {
- s->lref = git__strndup(str, delim - str);
- if (!s->lref || check_lref(push, s->lref) < 0)
- goto on_error;
- }
-
- if (strlen(delim + 1)) {
- s->rref = git__strdup(delim + 1);
- if (!s->rref || check_rref(s->rref) < 0)
- goto on_error;
- }
+ if (s->refspec.src && s->refspec.src[0] != '\0' &&
+ check_lref(push, s->refspec.src) < 0) {
+ goto on_error;
}
- if (!s->lref && !s->rref)
+ if (check_rref(s->refspec.dst) < 0)
goto on_error;
- /* If rref is ommitted, use the same ref name as lref */
- if (!s->rref) {
- s->rref = git__strdup(s->lref);
- if (!s->rref || check_rref(s->rref) < 0)
- goto on_error;
- }
-
*spec = s;
return 0;
@@ -220,7 +193,7 @@ int git_push_update_tips(
/* Find matching push ref spec */
git_vector_foreach(&push->specs, j, push_spec) {
- if (!strcmp(push_spec->rref, status->ref))
+ if (!strcmp(push_spec->refspec.dst, status->ref))
break;
}
@@ -353,14 +326,15 @@ static int revwalk(git_vector *commits, git_push *push)
} else if (git_revwalk_push(rw, &spec->loid) < 0)
goto on_error;
- if (!spec->force) {
+ if (!spec->refspec.force) {
git_oid base;
if (git_oid_iszero(&spec->roid))
continue;
if (!git_odb_exists(push->repo->_odb, &spec->roid)) {
- giterr_set(GITERR_REFERENCE, "Cannot push missing reference");
+ giterr_set(GITERR_REFERENCE,
+ "Cannot push because a reference that you are trying to update on the remote contains commits that are not present locally.");
error = GIT_ENONFASTFORWARD;
goto on_error;
}
@@ -571,22 +545,20 @@ static int calculate_work(git_push *push)
/* Update local and remote oids*/
git_vector_foreach(&push->specs, i, spec) {
- if (spec->lref) {
+ if (spec->refspec.src && spec->refspec.src[0]!= '\0') {
/* This is a create or update. Local ref must exist. */
if (git_reference_name_to_id(
- &spec->loid, push->repo, spec->lref) < 0) {
- giterr_set(GITERR_REFERENCE, "No such reference '%s'", spec->lref);
+ &spec->loid, push->repo, spec->refspec.src) < 0) {
+ giterr_set(GITERR_REFERENCE, "No such reference '%s'", spec->refspec.src);
return -1;
}
}
- if (spec->rref) {
- /* Remote ref may or may not (e.g. during create) already exist. */
- git_vector_foreach(&push->remote->refs, j, head) {
- if (!strcmp(spec->rref, head->name)) {
- git_oid_cpy(&spec->roid, &head->oid);
- break;
- }
+ /* Remote ref may or may not (e.g. during create) already exist. */
+ git_vector_foreach(&push->remote->refs, j, head) {
+ if (!strcmp(spec->refspec.dst, head->name)) {
+ git_oid_cpy(&spec->roid, &head->oid);
+ break;
}
}
}
diff --git a/src/push.h b/src/push.h
index 6c8bf7229..68fa868dd 100644
--- a/src/push.h
+++ b/src/push.h
@@ -8,15 +8,13 @@
#define INCLUDE_push_h__
#include "git2.h"
+#include "refspec.h"
typedef struct push_spec {
- char *lref;
- char *rref;
+ struct git_refspec refspec;
git_oid loid;
git_oid roid;
-
- bool force;
} push_spec;
typedef struct push_status {
diff --git a/src/refspec.c b/src/refspec.c
index 9f0df35a7..a56c44cc0 100644
--- a/src/refspec.c
+++ b/src/refspec.c
@@ -119,6 +119,12 @@ int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch)
if (!git_reference__is_valid_name(refspec->dst, flags))
goto invalid;
}
+
+ /* if the RHS is empty, then it's a copy of the LHS */
+ if (!refspec->dst) {
+ refspec->dst = git__strdup(refspec->src);
+ GITERR_CHECK_ALLOC(refspec->dst);
+ }
}
refspec->string = git__strdup(input);
diff --git a/src/remote.c b/src/remote.c
index cc9f85cd1..b1a84075e 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -163,6 +163,10 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
if (fetch != NULL) {
if (add_refspec(remote, fetch, true) < 0)
goto on_error;
+
+ /* Move the data over to where the matching functions can find them */
+ if (dwim_refspecs(&remote->active_refspecs, &remote->refspecs, &remote->refs) < 0)
+ goto on_error;
}
if (!name)
@@ -702,7 +706,7 @@ int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote
assert(remote);
if (!remote->transport) {
- giterr_set(GITERR_NET, "No transport bound to this remote");
+ giterr_set(GITERR_NET, "this remote has never connected");
return -1;
}
@@ -2111,3 +2115,63 @@ int git_remote_default_branch(git_buf *out, git_remote *remote)
return git_buf_puts(out, guess->name);
}
+
+int git_remote_push(git_remote *remote, git_strarray *refspecs, const git_push_options *opts,
+ const git_signature *signature, const char *reflog_message)
+{
+ int error;
+ size_t i;
+ git_push *push = NULL;
+ git_remote_callbacks *cbs;
+ git_refspec *spec;
+
+ assert(remote && refspecs);
+
+ if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH)) < 0)
+ return error;
+
+ if ((error = git_push_new(&push, remote)) < 0)
+ goto cleanup;
+
+ 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)
+ goto cleanup;
+ }
+ } else {
+ git_vector_foreach(&remote->refspecs, i, spec) {
+ if (!spec->push)
+ continue;
+ if ((error = git_push_add_refspec(push, spec->string)) < 0)
+ goto cleanup;
+ }
+ }
+
+ cbs = &remote->callbacks;
+ if ((error = git_push_set_callbacks(push,
+ cbs->pack_progress, cbs->payload,
+ cbs->push_transfer_progress, cbs->payload)) < 0)
+ goto cleanup;
+
+ if ((error = git_push_finish(push)) < 0)
+ goto cleanup;
+
+ if (!git_push_unpack_ok(push)) {
+ error = -1;
+ giterr_set(GITERR_NET, "error in the remote while trying to unpack");
+ goto cleanup;
+ }
+
+ if ((error = git_push_status_foreach(push, cbs->push_update_reference, cbs->payload)) < 0)
+ goto cleanup;
+
+ error = git_push_update_tips(push, signature, reflog_message);
+
+cleanup:
+ git_remote_disconnect(remote);
+ git_push_free(push);
+ return error;
+}
diff --git a/src/transports/http.c b/src/transports/http.c
index 4070b683a..234ee229f 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -1009,6 +1009,7 @@ static int http_close(git_smart_subtransport *subtransport)
git_vector_clear(&t->auth_contexts);
gitno_connection_data_free_ptrs(&t->connection_data);
+ memset(&t->connection_data, 0x0, sizeof(gitno_connection_data));
return 0;
}
diff --git a/src/transports/local.c b/src/transports/local.c
index f859f0b70..05302a13f 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -405,7 +405,7 @@ static int local_push(
git_vector_foreach(&push->specs, j, spec) {
push_status *status;
const git_error *last;
- char *ref = spec->rref ? spec->rref : spec->lref;
+ char *ref = spec->refspec.dst;
status = git__calloc(sizeof(push_status), 1);
if (!status)
@@ -417,7 +417,7 @@ static int local_push(
goto on_error;
}
- error = local_push_update_remote_ref(remote_repo, spec->lref, spec->rref,
+ error = local_push_update_remote_ref(remote_repo, spec->refspec.src, spec->refspec.dst,
&spec->loid, &spec->roid);
switch (error) {
diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c
index 7c20382dc..e110da07e 100644
--- a/src/transports/smart_protocol.c
+++ b/src/transports/smart_protocol.c
@@ -645,7 +645,7 @@ static int gen_pktline(git_buf *buf, git_push *push)
old_id[GIT_OID_HEXSZ] = '\0'; new_id[GIT_OID_HEXSZ] = '\0';
git_vector_foreach(&push->specs, i, spec) {
- len = 2*GIT_OID_HEXSZ + 7 + strlen(spec->rref);
+ len = 2*GIT_OID_HEXSZ + 7 + strlen(spec->refspec.dst);
if (i == 0) {
++len; /* '\0' */
@@ -657,7 +657,7 @@ 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->rref);
+ git_buf_printf(buf, "%04"PRIxZ"%s %s %s", len, old_id, new_id, spec->refspec.dst);
if (i == 0) {
git_buf_putc(buf, '\0');
@@ -816,7 +816,7 @@ static int add_ref_from_push_spec(git_vector *refs, push_spec *push_spec)
added->type = GIT_PKT_REF;
git_oid_cpy(&added->head.oid, &push_spec->loid);
- added->head.name = git__strdup(push_spec->rref);
+ added->head.name = git__strdup(push_spec->refspec.dst);
if (!added->head.name ||
git_vector_insert(refs, added) < 0) {
@@ -855,7 +855,7 @@ static int update_refs_from_report(
/* For each push spec we sent to the server, we should have
* gotten back a status packet in the push report which matches */
- if (strcmp(push_spec->rref, push_status->ref)) {
+ if (strcmp(push_spec->refspec.dst, push_status->ref)) {
giterr_set(GITERR_NET, "report-status: protocol error");
return -1;
}
@@ -872,7 +872,7 @@ static int update_refs_from_report(
push_status = git_vector_get(push_report, i);
ref = git_vector_get(refs, j);
- cmp = strcmp(push_spec->rref, ref->head.name);
+ cmp = strcmp(push_spec->refspec.dst, ref->head.name);
/* Iterate appropriately */
if (cmp <= 0) i++;
@@ -985,7 +985,7 @@ int git_smart__push(git_transport *transport, git_push *push)
* cases except when we only send delete commands
*/
git_vector_foreach(&push->specs, i, spec) {
- if (spec->lref) {
+ if (spec->refspec.src && spec->refspec.src[0] != '\0') {
need_pack = 1;
break;
}
diff --git a/tests/network/remote/local.c b/tests/network/remote/local.c
index a69af645d..b4a68e59e 100644
--- a/tests/network/remote/local.c
+++ b/tests/network/remote/local.c
@@ -212,7 +212,7 @@ void test_network_remote_local__push_to_bare_remote(void)
/* Try to push */
cl_git_pass(git_push_new(&push, localremote));
- cl_git_pass(git_push_add_refspec(push, "refs/heads/master:"));
+ cl_git_pass(git_push_add_refspec(push, "refs/heads/master"));
cl_git_pass(git_push_finish(push));
cl_assert(git_push_unpack_ok(push));
@@ -258,7 +258,7 @@ void test_network_remote_local__push_to_bare_remote_with_file_url(void)
/* Try to push */
cl_git_pass(git_push_new(&push, localremote));
- cl_git_pass(git_push_add_refspec(push, "refs/heads/master:"));
+ cl_git_pass(git_push_add_refspec(push, "refs/heads/master"));
cl_git_pass(git_push_finish(push));
cl_assert(git_push_unpack_ok(push));
@@ -301,7 +301,7 @@ void test_network_remote_local__push_to_non_bare_remote(void)
/* Try to push */
cl_git_pass(git_push_new(&push, localremote));
- cl_git_pass(git_push_add_refspec(push, "refs/heads/master:"));
+ cl_git_pass(git_push_add_refspec(push, "refs/heads/master"));
cl_git_fail_with(git_push_finish(push), GIT_EBAREREPO);
cl_assert_equal_i(0, git_push_unpack_ok(push));
@@ -429,3 +429,38 @@ void test_network_remote_local__opportunistic_update(void)
cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/origin/master"));
git_reference_free(ref);
}
+
+void test_network_remote_local__update_tips_for_new_remote(void) {
+ git_repository *src_repo;
+ git_repository *dst_repo;
+ git_remote *new_remote;
+ git_push *push;
+ git_reference* branch;
+
+ /* Copy test repo */
+ cl_fixture_sandbox("testrepo.git");
+ cl_git_pass(git_repository_open(&src_repo, "testrepo.git"));
+
+ /* Set up an empty bare repo to push into */
+ cl_git_pass(git_repository_init(&dst_repo, "./localbare.git", 1));
+
+ /* Push to bare repo */
+ cl_git_pass(git_remote_create(&new_remote, src_repo, "bare", "./localbare.git"));
+ cl_git_pass(git_remote_connect(new_remote, GIT_DIRECTION_PUSH));
+ cl_git_pass(git_push_new(&push, new_remote));
+ cl_git_pass(git_push_add_refspec(push, "refs/heads/master"));
+ cl_git_pass(git_push_finish(push));
+ cl_assert(git_push_unpack_ok(push));
+
+ /* Update tips and make sure remote branch has been created */
+ cl_git_pass(git_push_update_tips(push, NULL, NULL));
+ cl_git_pass(git_branch_lookup(&branch, src_repo, "bare/master", GIT_BRANCH_REMOTE));
+
+ git_reference_free(branch);
+ git_push_free(push);
+ git_remote_free(new_remote);
+ git_repository_free(dst_repo);
+ cl_fixture_cleanup("localbare.git");
+ git_repository_free(src_repo);
+ cl_fixture_cleanup("testrepo.git");
+}
diff --git a/tests/odb/emptyobjects.c b/tests/odb/emptyobjects.c
index d6d832cdf..783d05197 100644
--- a/tests/odb/emptyobjects.c
+++ b/tests/odb/emptyobjects.c
@@ -21,6 +21,8 @@ void test_odb_emptyobjects__read(void)
cl_git_pass(git_oid_fromstr(&id, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"));
cl_git_pass(git_blob_lookup(&blob, g_repo, &id));
cl_assert_equal_i(GIT_OBJ_BLOB, git_object_type((git_object *) blob));
+ cl_assert(git_blob_rawcontent(blob));
+ cl_assert_equal_s("", git_blob_rawcontent(blob));
cl_assert_equal_i(0, git_blob_rawsize(blob));
git_blob_free(blob);
}
@@ -37,3 +39,19 @@ void test_odb_emptyobjects__read_tree(void)
cl_assert_equal_p(NULL, git_tree_entry_byname(tree, "foo"));
git_tree_free(tree);
}
+
+void test_odb_emptyobjects__read_tree_odb(void)
+{
+ git_oid id;
+ git_odb *odb;
+ git_odb_object *tree_odb;
+
+ cl_git_pass(git_oid_fromstr(&id, "4b825dc642cb6eb9a060e54bf8d69288fbee4904"));
+ cl_git_pass(git_repository_odb(&odb, g_repo));
+ cl_git_pass(git_odb_read(&tree_odb, odb, &id));
+ cl_assert(git_odb_object_data(tree_odb));
+ cl_assert_equal_s("", git_odb_object_data(tree_odb));
+ cl_assert_equal_i(0, git_odb_object_size(tree_odb));
+ git_odb_object_free(tree_odb);
+ git_odb_free(odb);
+}
diff --git a/tests/online/fetch.c b/tests/online/fetch.c
index ec16dd2fd..848b87410 100644
--- a/tests/online/fetch.c
+++ b/tests/online/fetch.c
@@ -202,3 +202,14 @@ void test_online_fetch__remote_symrefs(void)
git_remote_free(remote);
}
+
+void test_online_fetch__twice(void)
+{
+ git_remote *remote;
+
+ cl_git_pass(git_remote_create(&remote, _repo, "test", "http://github.com/libgit2/TestGitRepository.git"));
+ cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
+ cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
+
+ git_remote_free(remote);
+}
diff --git a/tests/online/push.c b/tests/online/push.c
index b09c7ad1f..6424b5ba6 100644
--- a/tests/online/push.c
+++ b/tests/online/push.c
@@ -89,46 +89,38 @@ static int cred_acquire_cb(
return -1;
}
-/* the results of a push status. when used for expected values, msg may be NULL
- * to indicate that it should not be matched. */
-typedef struct {
- const char *ref;
- int success;
- const char *msg;
-} push_status;
-
/**
* git_push_status_foreach callback that records status entries.
* @param data (git_vector *) of push_status instances
*/
-static int record_push_status_cb(const char *ref, const char *msg, void *data)
+static int record_push_status_cb(const char *ref, const char *msg, void *payload)
{
- git_vector *statuses = (git_vector *)data;
+ record_callbacks_data *data = (record_callbacks_data *) payload;
push_status *s;
- cl_assert(s = git__malloc(sizeof(*s)));
- s->ref = ref;
+ cl_assert(s = git__calloc(1, sizeof(*s)));
+ if (ref)
+ cl_assert(s->ref = git__strdup(ref));
s->success = (msg == NULL);
- s->msg = msg;
+ if (msg)
+ cl_assert(s->msg = git__strdup(msg));
- git_vector_insert(statuses, s);
+ git_vector_insert(&data->statuses, s);
return 0;
}
-static void do_verify_push_status(git_push *push, const push_status expected[], const size_t expected_len)
+static void do_verify_push_status(record_callbacks_data *data, const push_status expected[], const size_t expected_len)
{
- git_vector actual = GIT_VECTOR_INIT;
+ git_vector *actual = &data->statuses;
push_status *iter;
bool failed = false;
size_t i;
- git_push_status_foreach(push, record_push_status_cb, &actual);
-
- if (expected_len != actual.length)
+ if (expected_len != actual->length)
failed = true;
else
- git_vector_foreach(&actual, i, iter)
+ git_vector_foreach(actual, i, iter)
if (strcmp(expected[i].ref, iter->ref) ||
(expected[i].success != iter->success) ||
(expected[i].msg && (!iter->msg || strcmp(expected[i].msg, iter->msg)))) {
@@ -149,7 +141,7 @@ static void do_verify_push_status(git_push *push, const push_status expected[],
git_buf_puts(&msg, "\nACTUAL:\n");
- git_vector_foreach(&actual, i, iter) {
+ git_vector_foreach(actual, i, iter) {
if (iter->success)
git_buf_printf(&msg, "%s: success\n", iter->ref);
else
@@ -161,10 +153,10 @@ static void do_verify_push_status(git_push *push, const push_status expected[],
git_buf_free(&msg);
}
- git_vector_foreach(&actual, i, iter)
+ git_vector_foreach(actual, i, iter)
git__free(iter);
- git_vector_free(&actual);
+ git_vector_free(actual);
}
/**
@@ -431,22 +423,24 @@ void test_online_push__cleanup(void)
static int push_pack_progress_cb(
int stage, unsigned int current, unsigned int total, void* payload)
{
- int *calls = (int *)payload;
+ record_callbacks_data *data = (record_callbacks_data *) payload;
GIT_UNUSED(stage); GIT_UNUSED(current); GIT_UNUSED(total);
- if (*calls < 0)
- return *calls;
- (*calls)++;
+ if (data->pack_progress_calls < 0)
+ return data->pack_progress_calls;
+
+ data->pack_progress_calls++;
return 0;
}
static int push_transfer_progress_cb(
unsigned int current, unsigned int total, size_t bytes, void* payload)
{
- int *calls = (int *)payload;
+ record_callbacks_data *data = (record_callbacks_data *) payload;
GIT_UNUSED(current); GIT_UNUSED(total); GIT_UNUSED(bytes);
- if (*calls < 0)
- return *calls;
- (*calls)++;
+ if (data->transfer_progress_calls < 0)
+ return data->transfer_progress_calls;
+
+ data->transfer_progress_calls++;
return 0;
}
@@ -466,62 +460,63 @@ static void do_push(
expected_ref expected_refs[], size_t expected_refs_len,
int expected_ret, int check_progress_cb, int check_update_tips_cb)
{
- git_push *push;
git_push_options opts = GIT_PUSH_OPTIONS_INIT;
size_t i;
- int pack_progress_calls = 0, transfer_progress_calls = 0;
+ int error;
+ git_strarray specs = {0};
git_signature *pusher;
+ git_remote_callbacks callbacks;
+ record_callbacks_data *data;
if (_remote) {
/* Auto-detect the number of threads to use */
opts.pb_parallelism = 0;
cl_git_pass(git_signature_now(&pusher, "Foo Bar", "foo@example.com"));
- cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH));
- cl_git_pass(git_push_new(&push, _remote));
- cl_git_pass(git_push_set_options(push, &opts));
+ memcpy(&callbacks, git_remote_get_callbacks(_remote), sizeof(callbacks));
+ data = callbacks.payload;
- if (check_progress_cb) {
- /* if EUSER, then abort in transfer */
- if (expected_ret == GIT_EUSER)
- transfer_progress_calls = GIT_EUSER;
+ callbacks.pack_progress = push_pack_progress_cb;
+ callbacks.push_transfer_progress = push_transfer_progress_cb;
+ callbacks.push_update_reference = record_push_status_cb;
+ cl_git_pass(git_remote_set_callbacks(_remote, &callbacks));
- cl_git_pass(
- git_push_set_callbacks(
- push, push_pack_progress_cb, &pack_progress_calls,
- push_transfer_progress_cb, &transfer_progress_calls));
+ if (refspecs_len) {
+ specs.count = refspecs_len;
+ specs.strings = git__calloc(refspecs_len, sizeof(char *));
+ cl_assert(specs.strings);
}
for (i = 0; i < refspecs_len; i++)
- cl_git_pass(git_push_add_refspec(push, refspecs[i]));
+ specs.strings[i] = (char *) refspecs[i];
+
+ /* if EUSER, then abort in transfer */
+ if (check_progress_cb && expected_ret == GIT_EUSER)
+ data->transfer_progress_calls = GIT_EUSER;
+
+ error = git_remote_push(_remote, &specs, &opts, pusher, "test push");
+ git__free(specs.strings);
if (expected_ret < 0) {
- cl_git_fail_with(git_push_finish(push), expected_ret);
- cl_assert_equal_i(0, git_push_unpack_ok(push));
+ cl_git_fail_with(expected_ret, error);
} else {
- cl_git_pass(git_push_finish(push));
- cl_assert_equal_i(1, git_push_unpack_ok(push));
+ cl_git_pass(error);
}
- if (check_progress_cb && !expected_ret) {
- cl_assert(pack_progress_calls > 0);
- cl_assert(transfer_progress_calls > 0);
+ if (check_progress_cb && expected_ret == 0) {
+ cl_assert(data->pack_progress_calls > 0);
+ cl_assert(data->transfer_progress_calls > 0);
}
- do_verify_push_status(push, expected_statuses, expected_statuses_len);
+ do_verify_push_status(data, expected_statuses, expected_statuses_len);
verify_refs(_remote, expected_refs, expected_refs_len);
-
- cl_git_pass(git_push_update_tips(push, pusher, "test push"));
verify_tracking_branches(_remote, expected_refs, expected_refs_len);
if (check_update_tips_cb)
verify_update_tips_callback(_remote, expected_refs, expected_refs_len);
- git_push_free(push);
-
- git_remote_disconnect(_remote);
git_signature_free(pusher);
}
@@ -631,11 +626,11 @@ void test_online_push__multi(void)
void test_online_push__implicit_tgt(void)
{
- const char *specs1[] = { "refs/heads/b1:" };
+ const char *specs1[] = { "refs/heads/b1" };
push_status exp_stats1[] = { { "refs/heads/b1", 1 } };
expected_ref exp_refs1[] = { { "refs/heads/b1", &_oid_b1 } };
- const char *specs2[] = { "refs/heads/b2:" };
+ const char *specs2[] = { "refs/heads/b2" };
push_status exp_stats2[] = { { "refs/heads/b2", 1 } };
expected_ref exp_refs2[] = {
{ "refs/heads/b1", &_oid_b1 },
@@ -838,22 +833,19 @@ void test_online_push__bad_refspecs(void)
void test_online_push__expressions(void)
{
+ git_push *push;
+
/* TODO: Expressions in refspecs doesn't actually work yet */
const char *specs_left_expr[] = { "refs/heads/b2~1:refs/heads/b2" };
- /* expect not NULL to indicate failure (core git replies "funny refname",
- * other servers may be less pithy. */
- const char *specs_right_expr[] = { "refs/heads/b2:refs/heads/b2~1" };
- push_status exp_stats_right_expr[] = { { "refs/heads/b2~1", 0 } };
+ cl_git_pass(git_push_new(&push, _remote));
+ cl_git_fail(git_push_add_refspec(push, "refs/heads/b2:refs/heads/b2~1"));
+ git_push_free(push);
/* TODO: Find a more precise way of checking errors than a exit code of -1. */
do_push(specs_left_expr, ARRAY_SIZE(specs_left_expr),
NULL, 0,
NULL, 0, -1, 0, 0);
-
- do_push(specs_right_expr, ARRAY_SIZE(specs_right_expr),
- exp_stats_right_expr, ARRAY_SIZE(exp_stats_right_expr),
- NULL, 0, 0, 1, 1);
}
void test_online_push__notes(void)
@@ -885,3 +877,35 @@ void test_online_push__notes(void)
git_signature_free(signature);
}
+
+void test_online_push__configured(void)
+{
+ git_oid note_oid, *target_oid, expected_oid;
+ git_signature *signature;
+ const char *specs[] = { "refs/notes/commits:refs/notes/commits" };
+ push_status exp_stats[] = { { "refs/notes/commits", 1 } };
+ expected_ref exp_refs[] = { { "refs/notes/commits", &expected_oid } };
+ const char *specs_del[] = { ":refs/notes/commits" };
+
+ git_oid_fromstr(&expected_oid, "8461a99b27b7043e58ff6e1f5d2cf07d282534fb");
+
+ target_oid = &_oid_b6;
+
+ cl_git_pass(git_remote_add_push(_remote, specs[0]));
+
+ /* Create note to push */
+ cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
+ cl_git_pass(git_note_create(&note_oid, _repo, signature, signature, NULL, target_oid, "hello world\n", 0));
+
+ do_push(NULL, 0,
+ exp_stats, ARRAY_SIZE(exp_stats),
+ exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
+
+ /* And make sure to delete the note */
+
+ do_push(specs_del, ARRAY_SIZE(specs_del),
+ exp_stats, 1,
+ NULL, 0, 0, 0, 0);
+
+ git_signature_free(signature);
+}
diff --git a/tests/online/push_util.c b/tests/online/push_util.c
index 68e71eacc..cd483c7c0 100644
--- a/tests/online/push_util.c
+++ b/tests/online/push_util.c
@@ -14,15 +14,31 @@ void updated_tip_free(updated_tip *t)
git__free(t);
}
+void push_status_free(push_status *s)
+{
+ git__free(s->ref);
+ git__free(s->msg);
+ git__free(s);
+}
+
void record_callbacks_data_clear(record_callbacks_data *data)
{
size_t i;
updated_tip *tip;
+ push_status *status;
git_vector_foreach(&data->updated_tips, i, tip)
updated_tip_free(tip);
git_vector_free(&data->updated_tips);
+
+ git_vector_foreach(&data->statuses, i, status)
+ push_status_free(status);
+
+ git_vector_free(&data->statuses);
+
+ data->pack_progress_calls = 0;
+ data->transfer_progress_calls = 0;
}
int record_update_tips_cb(const char *refname, const git_oid *a, const git_oid *b, void *data)
diff --git a/tests/online/push_util.h b/tests/online/push_util.h
index 7736912d6..2e05c4ed7 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, data }
+ { GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, data }
typedef struct {
char *name;
@@ -22,6 +22,9 @@ typedef struct {
typedef struct {
git_vector updated_tips;
+ git_vector statuses;
+ int pack_progress_calls;
+ int transfer_progress_calls;
} record_callbacks_data;
typedef struct {
@@ -29,6 +32,15 @@ typedef struct {
const git_oid *oid;
} expected_ref;
+/* the results of a push status. when used for expected values, msg may be NULL
+ * to indicate that it should not be matched. */
+typedef struct {
+ char *ref;
+ int success;
+ char *msg;
+} push_status;
+
+
void updated_tip_free(updated_tip *t);
void record_callbacks_data_clear(record_callbacks_data *data);
diff --git a/tests/refs/branches/upstream.c b/tests/refs/branches/upstream.c
index abf7933d3..b20b93753 100644
--- a/tests/refs/branches/upstream.c
+++ b/tests/refs/branches/upstream.c
@@ -70,6 +70,22 @@ void test_refs_branches_upstream__upstream_remote(void)
git_buf_free(&buf);
}
+void test_refs_branches_upstream__upstream_remote_empty_value(void)
+{
+ git_repository *repository;
+ git_config *cfg;
+ git_buf buf = GIT_BUF_INIT;
+
+ repository = cl_git_sandbox_init("testrepo.git");
+ cl_git_pass(git_repository_config(&cfg, repository));
+ cl_git_pass(git_config_set_string(cfg, "branch.master.remote", ""));
+ cl_git_fail_with(GIT_ENOTFOUND, git_branch_upstream_remote(&buf, repository, "refs/heads/master"));
+
+ cl_git_pass(git_config_delete_entry(cfg, "branch.master.remote"));
+ cl_git_fail_with(GIT_ENOTFOUND, git_branch_upstream_remote(&buf, repository, "refs/heads/master"));
+ cl_git_sandbox_cleanup();
+}
+
static void assert_merge_and_or_remote_key_missing(git_repository *repository, const git_commit *target, const char *entry_name)
{
git_reference *branch;
diff --git a/tests/resources/crlf/.gitted/objects/04/4bcd5c9bf5ebdd51e514a9a36457018f06f6e1 b/tests/resources/crlf/.gitted/objects/04/4bcd5c9bf5ebdd51e514a9a36457018f06f6e1
new file mode 100644
index 000000000..a32a9b282
--- /dev/null
+++ b/tests/resources/crlf/.gitted/objects/04/4bcd5c9bf5ebdd51e514a9a36457018f06f6e1
@@ -0,0 +1 @@
+x-j0D{W4H++C(ɡ]aJU|}̃ʺ. кVE@vȔvBx=%l sDxH!x3E9AhPdUTk {k+Av`C2|h괟lR{~/]`z-̥<]M5?]udr&K! \ No newline at end of file
diff --git a/tests/resources/crlf/.gitted/objects/12/faf3c1ea55f572473cec9052fca468c3584ccb b/tests/resources/crlf/.gitted/objects/12/faf3c1ea55f572473cec9052fca468c3584ccb
deleted file mode 100644
index 96d5b2f91..000000000
--- a/tests/resources/crlf/.gitted/objects/12/faf3c1ea55f572473cec9052fca468c3584ccb
+++ /dev/null
@@ -1 +0,0 @@
-x 1}Nۀ,b6K6`.ؾQoab-A0dXbtnr:0cy(*Y<B0q m-y|TSα6Gsٗ^%.lu#Qg?w@j뵔DŠl?gDl 7kP \ No newline at end of file
diff --git a/tests/resources/crlf/.gitted/objects/2b/55b4b94f655c857635b6a9005c056aa7de3532 b/tests/resources/crlf/.gitted/objects/2b/55b4b94f655c857635b6a9005c056aa7de3532
new file mode 100644
index 000000000..031fd6681
--- /dev/null
+++ b/tests/resources/crlf/.gitted/objects/2b/55b4b94f655c857635b6a9005c056aa7de3532
@@ -0,0 +1,2 @@
+x-Kj0D)z2tca].O VȄ zRݶԛAvyIfLi.υPɘL0d<=&b{O.09o4ŜI˔
+G_jk -Yھ~XTW ذ NjqKu:_ǣ]na.ZZk7!<#WF \ No newline at end of file
diff --git a/tests/resources/crlf/.gitted/objects/2c/9a868cfdf8e270d0ec68164433376c68fb1789 b/tests/resources/crlf/.gitted/objects/2c/9a868cfdf8e270d0ec68164433376c68fb1789
deleted file mode 100644
index 218e9d192..000000000
--- a/tests/resources/crlf/.gitted/objects/2c/9a868cfdf8e270d0ec68164433376c68fb1789
+++ /dev/null
Binary files differ
diff --git a/tests/resources/crlf/.gitted/objects/78/db270c1841841f75a8157321bdcb50ab12e6c3 b/tests/resources/crlf/.gitted/objects/78/db270c1841841f75a8157321bdcb50ab12e6c3
new file mode 100644
index 000000000..8a55bb082
--- /dev/null
+++ b/tests/resources/crlf/.gitted/objects/78/db270c1841841f75a8157321bdcb50ab12e6c3
Binary files differ
diff --git a/tests/resources/crlf/.gitted/objects/ba/aa042ab2976f8264e467988e6112ee518ec62e b/tests/resources/crlf/.gitted/objects/ba/aa042ab2976f8264e467988e6112ee518ec62e
deleted file mode 100644
index 4c544d5ef..000000000
--- a/tests/resources/crlf/.gitted/objects/ba/aa042ab2976f8264e467988e6112ee518ec62e
+++ /dev/null
Binary files differ
diff --git a/tests/resources/crlf/.gitted/refs/heads/master b/tests/resources/crlf/.gitted/refs/heads/master
index cfdaaf37b..c150a9776 100644
--- a/tests/resources/crlf/.gitted/refs/heads/master
+++ b/tests/resources/crlf/.gitted/refs/heads/master
@@ -1 +1 @@
-2c9a868cfdf8e270d0ec68164433376c68fb1789
+044bcd5c9bf5ebdd51e514a9a36457018f06f6e1
diff --git a/tests/resources/crlf/.gitted/refs/heads/utf8 b/tests/resources/crlf/.gitted/refs/heads/utf8
index 4b32f7f91..f8e6cf51c 100644
--- a/tests/resources/crlf/.gitted/refs/heads/utf8
+++ b/tests/resources/crlf/.gitted/refs/heads/utf8
@@ -1 +1 @@
-baaa042ab2976f8264e467988e6112ee518ec62e
+2b55b4b94f655c857635b6a9005c056aa7de3532
diff --git a/tests/status/worktree_init.c b/tests/status/worktree_init.c
index 3e43c8c20..cc7e126f1 100644
--- a/tests/status/worktree_init.c
+++ b/tests/status/worktree_init.c
@@ -127,7 +127,6 @@ void test_status_worktree_init__bracket_in_filename(void)
git_index *index;
status_entry_single result;
unsigned int status_flags;
- int error;
#define FILE_WITH_BRACKET "LICENSE[1].md"
#define FILE_WITHOUT_BRACKET "LICENSE1.md"