From 3e17e86383f64efefdd1d1a5979b13a3b98b39f3 Mon Sep 17 00:00:00 2001 From: Dmitry Golomidov Date: Tue, 21 May 2013 13:18:39 -0700 Subject: [PATCH 01/16] exposing functions for use within GitKit --- include/git2/transport.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/git2/transport.h b/include/git2/transport.h index 81bb3abe156..ff2f8c11fe9 100644 --- a/include/git2/transport.h +++ b/include/git2/transport.h @@ -84,7 +84,6 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new( const char *username, const char *password); -#ifdef GIT_SSH /** * Creates a new ssh key file and passphrase credential object. * The supplied credential parameter will be internally duplicated. @@ -116,9 +115,8 @@ GIT_EXTERN(int) git_cred_ssh_publickey_new( git_cred **out, const char *publickey, size_t publickey_len, - git_cred_sign_callback, + void* git_cred_sign_callback, void *sign_data); -#endif /** * Signature of a function which acquires a credential object. From 7e60995c96e33adda085982fd59fd5faec1ed620 Mon Sep 17 00:00:00 2001 From: Dmitry Golomidov Date: Thu, 23 May 2013 11:10:37 -0700 Subject: [PATCH 02/16] making signatures consistent --- src/transports/cred.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transports/cred.c b/src/transports/cred.c index 4916c6e18ad..cb0009b221a 100644 --- a/src/transports/cred.c +++ b/src/transports/cred.c @@ -133,7 +133,7 @@ int git_cred_ssh_publickey_new( git_cred **cred, const char *publickey, size_t publickey_len, - LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), + void *sign_callback, void *sign_data) { git_cred_ssh_publickey *c; From a64f7f44acacb3d04eb6cbf4ee284d00ec264e30 Mon Sep 17 00:00:00 2001 From: Dmitry Golomidov Date: Thu, 23 May 2013 13:40:16 -0700 Subject: [PATCH 03/16] fixed early EOF --- src/transports/ssh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transports/ssh.c b/src/transports/ssh.c index a312c8d089a..d49ffe1c57b 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -51,7 +51,7 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url) url = url + strlen(prefix_ssh); repo = strchr(url, '/'); } else { - repo = strchr(url, ':'); + repo = strchr(url, ':') + 1; } if (!repo) { From b2d5fc72456b98ad94ce2141d6891ca43f385bde Mon Sep 17 00:00:00 2001 From: Brad Morgan Date: Tue, 28 May 2013 15:18:26 -0400 Subject: [PATCH 04/16] Fixed transport header --- include/git2/transport.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/git2/transport.h b/include/git2/transport.h index ff2f8c11fe9..01f7820f4dc 100644 --- a/include/git2/transport.h +++ b/include/git2/transport.h @@ -11,10 +11,6 @@ #include "net.h" #include "types.h" -#ifdef GIT_SSH -#include -#endif - /** * @file git2/transport.h * @brief Git transport interfaces and functions @@ -49,9 +45,6 @@ typedef struct git_cred_userpass_plaintext { char *password; } git_cred_userpass_plaintext; -#ifdef GIT_SSH -typedef LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*git_cred_sign_callback)); - /* A ssh key file and passphrase */ typedef struct git_cred_ssh_keyfile_passphrase { git_cred parent; @@ -68,7 +61,6 @@ typedef struct git_cred_ssh_publickey { void *sign_callback; void *sign_data; } git_cred_ssh_publickey; -#endif /** * Creates a new plain-text username and password credential object. From d4842f95b64cc0b10712004e677aa41ebe25741d Mon Sep 17 00:00:00 2001 From: Brad Morgan Date: Tue, 28 May 2013 15:26:18 -0400 Subject: [PATCH 05/16] Fixed merge header --- include/git2/merge.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/git2/merge.h b/include/git2/merge.h index 955840569bf..5e687a32e22 100644 --- a/include/git2/merge.h +++ b/include/git2/merge.h @@ -7,11 +7,11 @@ #ifndef INCLUDE_git_merge_h__ #define INCLUDE_git_merge_h__ -#include "git2/common.h" -#include "git2/types.h" -#include "git2/oid.h" -#include "git2/checkout.h" -#include "git2/index.h" +#include "common.h" +#include "types.h" +#include "oid.h" +#include "checkout.h" +#include "index.h" /** * @file git2/merge.h From 1639dd3ff224d2723a6ef46a08dc98f2e927c342 Mon Sep 17 00:00:00 2001 From: Brad Morgan Date: Tue, 28 May 2013 17:23:37 -0400 Subject: [PATCH 06/16] Fixed cred allowed types --- include/git2/transport.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/git2/transport.h b/include/git2/transport.h index 01f7820f4dc..cbd14c75e4d 100644 --- a/include/git2/transport.h +++ b/include/git2/transport.h @@ -26,9 +26,9 @@ GIT_BEGIN_DECL typedef enum { /* git_cred_userpass_plaintext */ - GIT_CREDTYPE_USERPASS_PLAINTEXT = 1, - GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE = 2, - GIT_CREDTYPE_SSH_PUBLICKEY = 3, + GIT_CREDTYPE_USERPASS_PLAINTEXT = 1 << 0, + GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE = 1 << 1, + GIT_CREDTYPE_SSH_PUBLICKEY = 1 << 2, } git_credtype_t; /* The base structure for all credential types */ From fbb219f2830f5fc5b3eeb04a6ab230666a0b1776 Mon Sep 17 00:00:00 2001 From: Brad Morgan Date: Tue, 28 May 2013 17:29:14 -0400 Subject: [PATCH 07/16] Fixed allowed types for ssh connection --- src/transports/ssh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transports/ssh.c b/src/transports/ssh.c index d49ffe1c57b..4b97f0d9973 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -349,7 +349,7 @@ static int _git_ssh_setup_conn( if (t->owner->cred_acquire_cb(&t->cred, t->owner->url, user, - GIT_CREDTYPE_USERPASS_PLAINTEXT | GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE, + GIT_CREDTYPE_USERPASS_PLAINTEXT | GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE | GIT_CREDTYPE_SSH_PUBLICKEY, t->owner->cred_acquire_payload) < 0) return -1; } From 92fc48c8da85d2b6ff04ecdd230c16fe182891a3 Mon Sep 17 00:00:00 2001 From: Jason Allum Date: Tue, 4 Jun 2013 11:05:07 -0400 Subject: [PATCH 08/16] BugFix: Wasn't writing everything. --- src/transports/ssh.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/transports/ssh.c b/src/transports/ssh.c index 4b97f0d9973..d8d8c47ebb5 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -125,13 +125,17 @@ static int ssh_stream_write( if (!s->sent_command && send_command(s) < 0) return -1; - - int rc = libssh2_channel_write(s->channel, buffer, len); - if (rc < 0) { - return -1; + + size_t bytes_written = 0; + while (bytes_written < len) { + int rc = libssh2_channel_write(s->channel, buffer + bytes_written, len - bytes_written); + if (rc < 0) { + return -1; + } + bytes_written += rc; } - return rc; + return 0; } static void ssh_stream_free(git_smart_subtransport_stream *stream) From c5507598d1306334ab6082fcaf6c2a1b05ccae9c Mon Sep 17 00:00:00 2001 From: Dmitry Golomidov Date: Tue, 4 Jun 2013 13:36:47 -0700 Subject: [PATCH 09/16] not adding to revwalk if we are behind the remote --- src/push.c | 11 +++++------ src/push.h | 1 + src/transports/smart_protocol.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/push.c b/src/push.c index 452d7178914..5251be903dd 100644 --- a/src/push.c +++ b/src/push.c @@ -293,8 +293,7 @@ static int revwalk(git_vector *commits, git_push *push) } } git_object_free(target); - } else if (git_revwalk_push(rw, &spec->loid) < 0) - goto on_error; + } if (!spec->force) { git_oid base; @@ -313,15 +312,15 @@ static int revwalk(git_vector *commits, git_push *push) if (error == GIT_ENOTFOUND || (!error && !git_oid_equal(&base, &spec->roid))) { - giterr_set(GITERR_REFERENCE, - "Cannot push non-fastforwardable reference"); - error = GIT_ENONFASTFORWARD; - goto on_error; + spec->rejected = true; } if (error < 0) goto on_error; } + + if (!spec->rejected && git_revwalk_push(rw, &spec->loid) < 0) + goto on_error; } git_vector_foreach(&push->remote->refs, i, head) { diff --git a/src/push.h b/src/push.h index e982b838550..e10229c6a62 100644 --- a/src/push.h +++ b/src/push.h @@ -17,6 +17,7 @@ typedef struct push_spec { git_oid roid; bool force; + bool rejected; } push_spec; typedef struct push_status { diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 6366167175b..a6e77c1373d 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -842,7 +842,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->rejected && spec->lref) { need_pack = 1; break; } From 521d683f2f8eede831959bda4c47f824905dc057 Mon Sep 17 00:00:00 2001 From: Dmitry Golomidov Date: Tue, 4 Jun 2013 13:42:16 -0700 Subject: [PATCH 10/16] still error out when GIT_ENOTFOUND --- src/push.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/push.c b/src/push.c index 5251be903dd..8d14f8487b5 100644 --- a/src/push.c +++ b/src/push.c @@ -309,9 +309,14 @@ static int revwalk(git_vector *commits, git_push *push) error = git_merge_base(&base, push->repo, &spec->loid, &spec->roid); + if (error == GIT_ENOTFOUND) { + giterr_set(GITERR_REFERENCE, + "Cannot push non-fastforwardable reference"); + error = GIT_ENONFASTFORWARD; + goto on_error; + } - if (error == GIT_ENOTFOUND || - (!error && !git_oid_equal(&base, &spec->roid))) { + if ((!error && !git_oid_equal(&base, &spec->roid))) { spec->rejected = true; } From c6b915deebb348aad05a64e69dee72a2ad6bfe00 Mon Sep 17 00:00:00 2001 From: Dmitry Golomidov Date: Tue, 4 Jun 2013 15:00:39 -0700 Subject: [PATCH 11/16] check if need to update at all --- src/push.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/push.c b/src/push.c index 8d14f8487b5..148015dd5b1 100644 --- a/src/push.c +++ b/src/push.c @@ -544,6 +544,37 @@ static int calculate_work(git_push *push) return 0; } +static int filter_rejected_refs(git_push *push) +{ + int error = 0; + bool need_update; + + git_vector filtered_specs; + if ((error = git_vector_init(&filtered_specs, 0, push_spec_rref_cmp)) < 0) { + return error; + } + + push_spec *spec; + unsigned int i; + git_vector_foreach(&push->specs, i, spec) { + if (!need_update && spec->rejected) { + need_update = true; + } else { + if((error = git_vector_insert(&filtered_specs, spec)) < 0) { + git_vector_free(&filtered_specs); + return error; + } + } + } + + if (need_update) { + git_vector_free(&push->specs); + push->specs = filtered_specs; + } + + return 0; +} + static int do_push(git_push *push) { int error; @@ -568,8 +599,9 @@ static int do_push(git_push *push) if ((error = calculate_work(push)) < 0 || (error = queue_objects(push)) < 0 || - (error = transport->push(transport, push)) < 0) - goto on_error; + (error = filter_rejected_refs(push)) < 0 || + (error = transport->push(transport, push)) < 0) + goto on_error; error = 0; From 13cb132e2ecb0eb7946e3c462f8e840da285c426 Mon Sep 17 00:00:00 2001 From: Dmitry Golomidov Date: Tue, 4 Jun 2013 15:21:25 -0700 Subject: [PATCH 12/16] free vector if not needed --- src/push.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/push.c b/src/push.c index 148015dd5b1..799d5fea1a4 100644 --- a/src/push.c +++ b/src/push.c @@ -570,6 +570,8 @@ static int filter_rejected_refs(git_push *push) if (need_update) { git_vector_free(&push->specs); push->specs = filtered_specs; + } else { + git_vector_free(&filtered_specs); } return 0; From 884e187011aa7abf347bb17207f6ea5cdd97699d Mon Sep 17 00:00:00 2001 From: Dmitry Golomidov Date: Wed, 5 Jun 2013 09:07:51 -0700 Subject: [PATCH 13/16] filter out up-to-date/unchanged refspecs --- src/push.c | 20 +++++++++++++------- src/push.h | 10 ++++++++-- src/transports/smart_protocol.c | 3 ++- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/push.c b/src/push.c index 799d5fea1a4..96b15697344 100644 --- a/src/push.c +++ b/src/push.c @@ -123,7 +123,7 @@ static int parse_refspec(git_push *push, push_spec **spec, const char *str) GITERR_CHECK_ALLOC(s); if (str[0] == '+') { - s->force = true; + s->spec_type = SPECTYPE_FORCED; str++; } @@ -258,8 +258,10 @@ static int revwalk(git_vector *commits, git_push *push) */ continue; - if (git_oid_equal(&spec->loid, &spec->roid)) + if (git_oid_equal(&spec->loid, &spec->roid)) { + spec->spec_type = SPECTYPE_UNCHANGED; continue; /* up-to-date */ + } if (git_odb_read_header(&size, &type, push->repo->_odb, &spec->loid) < 0) goto on_error; @@ -293,9 +295,11 @@ static int revwalk(git_vector *commits, git_push *push) } } git_object_free(target); - } + } + + push_spec_t spec_type = spec->spec_type; - if (!spec->force) { + if (spec_type != SPECTYPE_FORCED) { git_oid base; if (git_oid_iszero(&spec->roid)) @@ -317,14 +321,14 @@ static int revwalk(git_vector *commits, git_push *push) } if ((!error && !git_oid_equal(&base, &spec->roid))) { - spec->rejected = true; + spec->spec_type = SPECTYPE_REJECTED; } if (error < 0) goto on_error; } - if (!spec->rejected && git_revwalk_push(rw, &spec->loid) < 0) + if (spec_type != SPECTYPE_REJECTED && spec_type != SPECTYPE_UNCHANGED && git_revwalk_push(rw, &spec->loid) < 0) goto on_error; } @@ -555,9 +559,11 @@ static int filter_rejected_refs(git_push *push) } push_spec *spec; + push_spec_t spec_type; unsigned int i; git_vector_foreach(&push->specs, i, spec) { - if (!need_update && spec->rejected) { + spec_type = spec->spec_type; + if (spec_type == SPECTYPE_REJECTED || spec_type == SPECTYPE_UNCHANGED) { need_update = true; } else { if((error = git_vector_insert(&filtered_specs, spec)) < 0) { diff --git a/src/push.h b/src/push.h index e10229c6a62..0371e125be8 100644 --- a/src/push.h +++ b/src/push.h @@ -9,6 +9,13 @@ #include "git2.h" +typedef enum { + SPECTYPE_NORMAL, + SPECTYPE_FORCED, + SPECTYPE_REJECTED, + SPECTYPE_UNCHANGED, +} push_spec_t; + typedef struct push_spec { char *lref; char *rref; @@ -16,8 +23,7 @@ typedef struct push_spec { git_oid loid; git_oid roid; - bool force; - bool rejected; + push_spec_t spec_type; } push_spec; typedef struct push_status { diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index a6e77c1373d..7ee4751454d 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -842,7 +842,8 @@ 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->rejected && spec->lref) { + push_spec_t spec_type = spec->spec_type; + if (spec_type != SPECTYPE_REJECTED && spec_type != SPECTYPE_UNCHANGED && spec->lref) { need_pack = 1; break; } From 99928e4c7ae4af5db22967fd89439b52cb79b1d9 Mon Sep 17 00:00:00 2001 From: Dmitry Golomidov Date: Wed, 5 Jun 2013 12:31:34 -0700 Subject: [PATCH 14/16] fixed type check bug --- src/push.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/push.c b/src/push.c index 96b15697344..1c3ebce2532 100644 --- a/src/push.c +++ b/src/push.c @@ -122,6 +122,8 @@ static int parse_refspec(git_push *push, push_spec **spec, const char *str) s = git__calloc(1, sizeof(*s)); GITERR_CHECK_ALLOC(s); + s->spec_type = SPECTYPE_NORMAL; + if (str[0] == '+') { s->spec_type = SPECTYPE_FORCED; str++; @@ -322,6 +324,7 @@ static int revwalk(git_vector *commits, git_push *push) if ((!error && !git_oid_equal(&base, &spec->roid))) { spec->spec_type = SPECTYPE_REJECTED; + spec_type = spec->spec_type; } if (error < 0) @@ -551,7 +554,6 @@ static int calculate_work(git_push *push) static int filter_rejected_refs(git_push *push) { int error = 0; - bool need_update; git_vector filtered_specs; if ((error = git_vector_init(&filtered_specs, 0, push_spec_rref_cmp)) < 0) { @@ -563,9 +565,7 @@ static int filter_rejected_refs(git_push *push) unsigned int i; git_vector_foreach(&push->specs, i, spec) { spec_type = spec->spec_type; - if (spec_type == SPECTYPE_REJECTED || spec_type == SPECTYPE_UNCHANGED) { - need_update = true; - } else { + if (spec_type == SPECTYPE_NORMAL || spec_type == SPECTYPE_FORCED) { if((error = git_vector_insert(&filtered_specs, spec)) < 0) { git_vector_free(&filtered_specs); return error; @@ -573,7 +573,7 @@ static int filter_rejected_refs(git_push *push) } } - if (need_update) { + if (filtered_specs.length > 0) { git_vector_free(&push->specs); push->specs = filtered_specs; } else { From ec80b08ef435d33483d7a5888f26e26649bcb227 Mon Sep 17 00:00:00 2001 From: Dmitry Golomidov Date: Wed, 5 Jun 2013 15:11:47 -0700 Subject: [PATCH 15/16] adding spec with NULL roid to revwalk and always updating git_push with filtered refspecs --- src/push.c | 57 +++++++++++++++------------------ src/transports/smart_protocol.c | 3 +- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/push.c b/src/push.c index 1c3ebce2532..9a9783b0a5d 100644 --- a/src/push.c +++ b/src/push.c @@ -304,31 +304,30 @@ static int revwalk(git_vector *commits, git_push *push) if (spec_type != SPECTYPE_FORCED) { 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"); - error = GIT_ENONFASTFORWARD; - goto on_error; - } - - error = git_merge_base(&base, push->repo, - &spec->loid, &spec->roid); - if (error == GIT_ENOTFOUND) { - giterr_set(GITERR_REFERENCE, - "Cannot push non-fastforwardable reference"); - error = GIT_ENONFASTFORWARD; - goto on_error; - } - - if ((!error && !git_oid_equal(&base, &spec->roid))) { - spec->spec_type = SPECTYPE_REJECTED; - spec_type = spec->spec_type; - } - - if (error < 0) - goto on_error; + if (!git_oid_iszero(&spec->roid)) { + if (!git_odb_exists(push->repo->_odb, &spec->roid)) { + giterr_set(GITERR_REFERENCE, "Cannot push missing reference"); + error = GIT_ENONFASTFORWARD; + goto on_error; + } + + error = git_merge_base(&base, push->repo, + &spec->loid, &spec->roid); + if (error == GIT_ENOTFOUND) { + giterr_set(GITERR_REFERENCE, + "Cannot push non-fastforwardable reference"); + error = GIT_ENONFASTFORWARD; + goto on_error; + } + + if ((!error && !git_oid_equal(&base, &spec->roid))) { + spec->spec_type = SPECTYPE_REJECTED; + spec_type = spec->spec_type; + } + + if (error < 0) + goto on_error; + } } if (spec_type != SPECTYPE_REJECTED && spec_type != SPECTYPE_UNCHANGED && git_revwalk_push(rw, &spec->loid) < 0) @@ -573,12 +572,8 @@ static int filter_rejected_refs(git_push *push) } } - if (filtered_specs.length > 0) { - git_vector_free(&push->specs); - push->specs = filtered_specs; - } else { - git_vector_free(&filtered_specs); - } + git_vector_free(&push->specs); + push->specs = filtered_specs; return 0; } diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 7ee4751454d..6366167175b 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -842,8 +842,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) { - push_spec_t spec_type = spec->spec_type; - if (spec_type != SPECTYPE_REJECTED && spec_type != SPECTYPE_UNCHANGED && spec->lref) { + if (spec->lref) { need_pack = 1; break; } From acfa5126314d993cf69f41d0dbe8cf503a4622f0 Mon Sep 17 00:00:00 2001 From: Jason Allum Date: Fri, 19 Jul 2013 12:36:32 -0400 Subject: [PATCH 16/16] We don't stash submodule links. --- src/stash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stash.c b/src/stash.c index 19b29be7700..ec977582419 100644 --- a/src/stash.c +++ b/src/stash.c @@ -185,12 +185,12 @@ static int update_index_cb( case GIT_DELTA_ADDED: case GIT_DELTA_MODIFIED: - if (data->include_changed) + if (data->include_changed && !S_ISGITLINK(delta->new_file.mode)) add_path = delta->new_file.path; break; case GIT_DELTA_DELETED: - if (!data->include_changed) + if (!data->include_changed || S_ISGITLINK(delta->new_file.mode)) break; if (git_index_find(NULL, data->index, delta->old_file.path) == 0) data->error = git_index_remove(