diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ident.c | 4 | ||||
| -rw-r--r-- | src/indexer.c | 15 | ||||
| -rw-r--r-- | src/openssl_stream.c | 21 | ||||
| -rw-r--r-- | src/pack.c | 7 | ||||
| -rw-r--r-- | src/remote.c | 82 |
5 files changed, 77 insertions, 52 deletions
diff --git a/src/ident.c b/src/ident.c index 6bc80abc7..4718ed664 100644 --- a/src/ident.c +++ b/src/ident.c @@ -56,7 +56,7 @@ static int ident_insert_id( return GIT_PASSTHROUGH; need_size = (size_t)(id_start - from->ptr) + - 5 /* "$Id: " */ + GIT_OID_HEXSZ + 1 /* "$" */ + + 5 /* "$Id: " */ + GIT_OID_HEXSZ + 2 /* " $" */ + (size_t)(from_end - id_end); if (git_buf_grow(to, need_size) < 0) @@ -65,7 +65,7 @@ static int ident_insert_id( 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_putc(to, '$'); + git_buf_put(to, " $", 2); git_buf_put(to, id_end, (size_t)(from_end - id_end)); return git_buf_oom(to) ? -1 : 0; diff --git a/src/indexer.c b/src/indexer.c index 665d50fcd..e39345c71 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -325,6 +325,13 @@ on_error: return -1; } +GIT_INLINE(bool) has_entry(git_indexer *idx, git_oid *id) +{ + khiter_t k; + k = kh_get(oid, idx->pack->idx_cache, id); + return (k != kh_end(idx->pack->idx_cache)); +} + static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_entry *pentry, git_off_t entry_start) { int i, error; @@ -339,8 +346,11 @@ static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_ent pentry->offset = entry_start; k = kh_put(oid, idx->pack->idx_cache, &pentry->sha1, &error); - if (!error) + + if (error <= 0) { + giterr_set(GITERR_INDEXER, "cannot insert object into pack"); return -1; + } kh_value(idx->pack->idx_cache, k) = pentry; @@ -791,6 +801,9 @@ static int fix_thin_pack(git_indexer *idx, git_transfer_progress *stats) git_oid_fromraw(&base, base_info); git_mwindow_close(&w); + if (has_entry(idx, &base)) + return 0; + if (inject_object(idx, &base) < 0) return -1; diff --git a/src/openssl_stream.c b/src/openssl_stream.c index a975bb0c1..9b2d5951c 100644 --- a/src/openssl_stream.c +++ b/src/openssl_stream.c @@ -291,19 +291,14 @@ ssize_t openssl_write(git_stream *stream, const char *data, size_t len, int flag { openssl_stream *st = (openssl_stream *) stream; int ret; - size_t off = 0; GIT_UNUSED(flags); - while (off < len) { - ret = SSL_write(st->ssl, data + off, len - off); - if (ret <= 0 && ret != SSL_ERROR_WANT_WRITE) - return ssl_set_error(st->ssl, ret); - - off += ret; - } + if ((ret = SSL_write(st->ssl, data, len)) <= 0) { + return ssl_set_error(st->ssl, ret); + } - return off; + return ret; } ssize_t openssl_read(git_stream *stream, void *data, size_t len) @@ -311,14 +306,8 @@ ssize_t openssl_read(git_stream *stream, void *data, size_t len) openssl_stream *st = (openssl_stream *) stream; int ret; - do { - ret = SSL_read(st->ssl, data, len); - } while (SSL_get_error(st->ssl, ret) == SSL_ERROR_WANT_READ); - - if (ret < 0) { + if ((ret = SSL_read(st->ssl, data, len)) <= 0) ssl_set_error(st->ssl, ret); - return -1; - } return ret; } diff --git a/src/pack.c b/src/pack.c index 5d0a27b91..105d67510 100644 --- a/src/pack.c +++ b/src/pack.c @@ -959,8 +959,15 @@ git_off_t get_delta_base( if (k != kh_end(p->idx_cache)) { *curpos += 20; return ((struct git_pack_entry *)kh_value(p->idx_cache, k))->offset; + } else { + /* If we're building an index, don't try to find the pack + * entry; we just haven't seen it yet. We'll make + * progress again in the next loop. + */ + return GIT_PASSTHROUGH; } } + /* The base entry _must_ be in the same pack */ if (pack_entry_find_offset(&base_offset, &unused, p, (git_oid *)base_info, GIT_OID_HEXSZ) < 0) return packfile_error("base entry delta is not in the same pack"); diff --git a/src/remote.c b/src/remote.c index 44885bd17..43b34561d 100644 --- a/src/remote.c +++ b/src/remote.c @@ -97,6 +97,7 @@ static int write_add_refspec(git_repository *repo, const char *name, const char { git_config *cfg; git_buf var = GIT_BUF_INIT; + git_refspec spec; const char *fmt; int error; @@ -108,6 +109,15 @@ 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 (giterr_last()->klass != GITERR_NOMEMORY) + error = GIT_EINVALIDSPEC; + + return error; + } + + git_refspec__free(&spec); + if ((error = git_buf_printf(&var, fmt, name)) < 0) return error; @@ -311,15 +321,16 @@ on_error: return -1; } -int git_remote_create_anonymous(git_remote **out, git_repository *repo, const char *url, const char *fetch) +int git_remote_create_anonymous(git_remote **out, git_repository *repo, const char *url) { - return create_internal(out, repo, NULL, url, fetch); + return create_internal(out, repo, NULL, url, NULL); } int git_remote_dup(git_remote **dest, git_remote *source) { + size_t i; int error = 0; - git_strarray refspecs = { 0 }; + git_refspec *spec; git_remote *remote = git__calloc(1, sizeof(git_remote)); GITERR_CHECK_ALLOC(remote); @@ -349,22 +360,15 @@ int git_remote_dup(git_remote **dest, git_remote *source) goto cleanup; } - if ((error = git_remote_get_fetch_refspecs(&refspecs, source)) < 0 || - (error = git_remote_set_fetch_refspecs(remote, &refspecs)) < 0) - goto cleanup; - - git_strarray_free(&refspecs); - - if ((error = git_remote_get_push_refspecs(&refspecs, source)) < 0 || - (error = git_remote_set_push_refspecs(remote, &refspecs)) < 0) - goto cleanup; + git_vector_foreach(&source->refspecs, i, spec) { + if ((error = add_refspec(remote, spec->string, !spec->push)) < 0) + goto cleanup; + } *dest = remote; cleanup: - git_strarray_free(&refspecs); - if (error < 0) git__free(remote); @@ -1449,18 +1453,20 @@ static int next_head(const git_remote *remote, git_vector *refs, return GIT_ITEROVER; } -static int opportunistic_updates(const git_remote *remote, 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; git_remote_head *head; git_reference *ref; git_buf refname = GIT_BUF_INIT; - int error; + 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 @@ -1469,18 +1475,38 @@ static int opportunistic_updates(const git_remote *remote, git_vector *refs, con * FETCH_HEAD */ + git_buf_clear(&refname); if ((error = git_refspec_transform(&refname, spec, head->name)) < 0) - return error; + goto cleanup; - error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, true, msg); - git_buf_free(&refname); - git_reference_free(ref); + error = git_reference_name_to_id(&old, remote->repo, refname.ptr); + if (error < 0 && error != GIT_ENOTFOUND) + 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) - return error; + goto cleanup; + + if (callbacks && callbacks->update_tips != NULL) { + if (callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload) < 0) + goto cleanup; + } } - return 0; + if (error == GIT_ITEROVER) + error = 0; + +cleanup: + git_buf_free(&refname); + return error; } int git_remote_update_tips( @@ -1528,7 +1554,7 @@ int git_remote_update_tips( /* only try to do opportunisitic updates if the refpec lists differ */ if (remote->passed_refspecs) - error = opportunistic_updates(remote, &refs, reflog_message); + error = opportunistic_updates(remote, callbacks, &refs, reflog_message); out: git_vector_free(&refs); @@ -2046,16 +2072,6 @@ static int set_refspecs(git_remote *remote, git_strarray *array, int push) return 0; } -int git_remote_set_fetch_refspecs(git_remote *remote, git_strarray *array) -{ - return set_refspecs(remote, array, false); -} - -int git_remote_set_push_refspecs(git_remote *remote, git_strarray *array) -{ - return set_refspecs(remote, array, true); -} - static int copy_refspecs(git_strarray *array, const git_remote *remote, unsigned int push) { size_t i; |
