int hiredis_odb_backend__read_header(size_t *len_p, git_otype *type_p, git_odb_backend *_backend, const git_oid *oid) { hiredis_odb_backend *backend; int error; redisReply *reply; char *str_id = calloc(GIT_OID_HEXSZ + 1, sizeof(char)); assert(len_p && type_p && _backend && oid); backend = (hiredis_odb_backend *) _backend; error = GIT_ERROR; git_oid_tostr(str_id, GIT_OID_HEXSZ, oid); reply = redisCommand(backend->db, "HMGET %s:%s:odb:%s %s %s", backend->prefix, backend->repo_path, str_id, "type", "size"); if (reply && reply->type == REDIS_REPLY_ARRAY) { if (reply->element[0]->type != REDIS_REPLY_NIL && reply->element[1]->type != REDIS_REPLY_NIL) { *type_p = (git_otype) atoi(reply->element[0]->str); *len_p = (size_t) atoi(reply->element[1]->str); error = GIT_OK; } else { giterr_set_str(GITERR_ODB, "Redis odb storage corrupted"); error = GIT_ENOTFOUND; } } else { giterr_set_str(GITERR_ODB, "Redis odb storage error"); error = GIT_ERROR; } free(str_id); freeReplyObject(reply); return error; }
int git_refdb_backend_hiredis(git_refdb_backend **backend_out, const char* prefix, const char* path, const char *host, int port, char* password) { hiredis_refdb_backend *backend; redisReply *reply; backend = calloc(1, sizeof(hiredis_refdb_backend)); if (backend == NULL) return GITERR_NOMEMORY; if (sharedConnection == NULL) { sharedConnection = redisConnect(host, port); if (sharedConnection->err) { free(backend); giterr_set_str(GITERR_REFERENCE, "Redis refdb storage couldn't connect to redis server"); return GIT_ERROR; } if (password != NULL) { reply = redisCommand(sharedConnection, "AUTH %s", password); if (reply->type == REDIS_REPLY_ERROR) { freeReplyObject(reply); redisFree(sharedConnection); free(backend); giterr_set_str(GITERR_REFERENCE, "Redis refdb storage authentication with redis server failed"); return GIT_ERROR; } freeReplyObject(reply); } } backend->db = sharedConnection; backend->prefix = strdup(prefix); backend->repo_path = strdup(path); backend->parent.exists = &hiredis_refdb_backend__exists; backend->parent.lookup = &hiredis_refdb_backend__lookup; backend->parent.iterator = &hiredis_refdb_backend__iterator; backend->parent.write = &hiredis_refdb_backend__write; backend->parent.del = &hiredis_refdb_backend__del; backend->parent.rename = &hiredis_refdb_backend__rename; backend->parent.compress = NULL; backend->parent.free = &hiredis_refdb_backend__free; backend->parent.has_log = &hiredis_refdb_backend__has_log; backend->parent.ensure_log = &hiredis_refdb_backend__ensure_log; backend->parent.reflog_read = &hiredis_refdb_backend__reflog_read; backend->parent.reflog_write = &hiredis_refdb_backend__reflog_write; backend->parent.reflog_rename = &hiredis_refdb_backend__reflog_rename; backend->parent.reflog_delete = &hiredis_refdb_backend__reflog_delete; *backend_out = (git_refdb_backend *) backend; return GIT_OK; }
int git_odb_backend_hiredis(git_odb_backend **backend_out, const char* prefix, const char* path, const char *host, int port, char* password) { hiredis_odb_backend *backend; redisReply *reply; backend = calloc(1, sizeof (hiredis_odb_backend)); if (backend == NULL) return GITERR_NOMEMORY; if (sharedConnection == NULL) { sharedConnection = redisConnect(host, port); if (sharedConnection->err) { free(backend); giterr_set_str(GITERR_REFERENCE, "Redis odb storage couldn't connect to redis server"); return GIT_ERROR; } if (password != NULL) { reply = redisCommand(sharedConnection, "AUTH %s", password); if (reply == NULL || reply->type == REDIS_REPLY_ERROR) { freeReplyObject(reply); redisFree(sharedConnection); free(backend); giterr_set_str(GITERR_REFERENCE, "Redis odb storage authentication with redis server failed"); return GIT_ERROR; } freeReplyObject(reply); } } backend->db = sharedConnection; backend->prefix = strdup(prefix); backend->repo_path = strdup(path); backend->parent.version = 1; backend->parent.read = &hiredis_odb_backend__read; backend->parent.write = &hiredis_odb_backend__write; backend->parent.read_prefix = &hiredis_odb_backend__read_prefix; backend->parent.read_header = &hiredis_odb_backend__read_header; backend->parent.exists = &hiredis_odb_backend__exists; backend->parent.free = &hiredis_odb_backend__free; backend->parent.writestream = NULL; backend->parent.foreach = NULL; *backend_out = (git_odb_backend *) backend; return GIT_OK; }
int hiredis_refdb_backend__iterator(git_reference_iterator **_iter, struct git_refdb_backend *_backend, const char *glob) { hiredis_refdb_backend *backend; hiredis_refdb_iterator *iterator; int error = GIT_OK; redisReply *reply; assert(_backend); backend = (hiredis_refdb_backend *) _backend; reply = redisCommand(backend->db, "KEYS %s:%s:refdb:%s", backend->prefix, backend->repo_path, (glob != NULL ? glob : "refs/*")); if(reply->type != REDIS_REPLY_ARRAY) { freeReplyObject(reply); giterr_set_str(GITERR_REFERENCE, "Redis refdb storage error"); return GIT_ERROR; } iterator = calloc(1, sizeof(hiredis_refdb_iterator)); iterator->backend = backend; iterator->keys = reply; iterator->parent.next = &hiredis_refdb_backend__iterator_next; iterator->parent.next_name = &hiredis_refdb_backend__iterator_next_name; iterator->parent.free = &hiredis_refdb_backend__iterator_free; *_iter = (git_reference_iterator *) iterator; return GIT_OK; }
/** * Retrieve parents of the commit under construction * * @param parents The vector of parents to create and populate. * @param n_parents The length of parents vector * @param repository The repository * @return 0 on succes, or error code */ static int git2r_retrieve_parents( git_commit ***parents, size_t *n_parents, git_repository *repository) { int err; git_oid oid; git2r_merge_head_cb_data cb_data = {0, NULL, NULL}; git_repository_state_t state; err = git_repository_head_unborn(repository); if (1 == err) { *n_parents = 0; return GIT_OK; } else if (0 != err) { return err; } state = git_repository_state(repository); if (state == GIT_REPOSITORY_STATE_MERGE) { /* Count number of merge heads */ err = git_repository_mergehead_foreach( repository, git2r_repository_mergehead_foreach_cb, &cb_data); if (GIT_OK != err) return err; } *parents = calloc(cb_data.n + 1, sizeof(git_commit*)); if (!parents) { giterr_set_str(GITERR_NONE, git2r_err_alloc_memory_buffer); return GIT_ERROR; } *n_parents = cb_data.n + 1; err = git_reference_name_to_id(&oid, repository, "HEAD"); if (GIT_OK != err) return err; err = git_commit_lookup(&**parents, repository, &oid); if (GIT_OK != err) return err; if (state == GIT_REPOSITORY_STATE_MERGE) { /* Append merge heads to parents */ cb_data.n = 0; cb_data.repository = repository; cb_data.parents = *parents + 1; err = git_repository_mergehead_foreach( repository, git2r_repository_mergehead_foreach_cb, &cb_data); if (GIT_OK != err) return err; } return GIT_OK; }
int RemoteProgressCommand::RemoteProgressCallback(const char* str, int len, void* data) { ((CGitProgressList::Payload*)data)->list->SetProgressLabelText(CUnicodeUtils::GetUnicode(CStringA(str, len))); if (((CGitProgressList::Payload*)data)->list->m_bCancelled) { giterr_set_str(GITERR_NONE, "User cancelled."); return GIT_EUSER; } return 0; }
int git__page_size(size_t *page_size) { long sc_page_size = sysconf(_SC_PAGE_SIZE); if (sc_page_size < 0) { giterr_set_str(GITERR_OS, "Can't determine system page size"); return -1; } *page_size = (size_t) sc_page_size; return 0; }
int hiredis_refdb_backend__lookup(git_reference **out, git_refdb_backend *_backend, const char *ref_name) { hiredis_refdb_backend *backend; int error = GIT_OK; redisReply *reply; git_oid oid; assert(ref_name && _backend); backend = (hiredis_refdb_backend *) _backend; reply = redisCommand(backend->db, "HMGET %s:%s:refdb:%s type target", backend->prefix, backend->repo_path, ref_name); if(reply->type == REDIS_REPLY_ARRAY) { if (reply->element[0]->type != REDIS_REPLY_NIL && reply->element[1]->type != REDIS_REPLY_NIL) { git_ref_t type = (git_ref_t) atoi(reply->element[0]->str); if (type == GIT_REF_OID) { git_oid_fromstr(&oid, reply->element[1]->str); *out = git_reference__alloc(ref_name, &oid, NULL); } else if (type == GIT_REF_SYMBOLIC) { *out = git_reference__alloc_symbolic(ref_name, reply->element[1]->str); } else { giterr_set_str(GITERR_REFERENCE, "Redis refdb storage corrupted (unknown ref type returned)"); error = GIT_ERROR; } } else { giterr_set_str(GITERR_REFERENCE, "Redis refdb couldn't find ref"); error = GIT_ENOTFOUND; } } else { giterr_set_str(GITERR_REFERENCE, "Redis refdb storage error"); error = GIT_ERROR; } freeReplyObject(reply); return error; }
/** * Check for any changes in index * * @param repository The repository * @return 0 if ok, else error code. */ static int git2r_any_changes_in_index(git_repository *repository) { int err; int changes_in_index = 0; size_t i, count; git_status_list *status = NULL; git_status_options opts = GIT_STATUS_OPTIONS_INIT; opts.show = GIT_STATUS_SHOW_INDEX_ONLY; err = git_status_list_new(&status, repository, &opts); if (GIT_OK != err) goto cleanup; count = git_status_list_entrycount(status); for (i = 0; i < count; ++i) { const git_status_entry *s = git_status_byindex(status, i); if (s->status == GIT_STATUS_CURRENT) continue; if (s->status & GIT_STATUS_INDEX_NEW) changes_in_index = 1; else if (s->status & GIT_STATUS_INDEX_MODIFIED) changes_in_index = 1; else if (s->status & GIT_STATUS_INDEX_DELETED) changes_in_index = 1; else if (s->status & GIT_STATUS_INDEX_RENAMED) changes_in_index = 1; else if (s->status & GIT_STATUS_INDEX_TYPECHANGE) changes_in_index = 1; if (changes_in_index) break; } if (!changes_in_index) { giterr_set_str(GITERR_NONE, git2r_err_nothing_added_to_commit); err = GIT_ERROR; } cleanup: if (status) git_status_list_free(status); return err; }
int hiredis_odb_backend__read_prefix(git_oid *out_oid, void **data_p, size_t *len_p, git_otype *type_p, git_odb_backend *_backend, const git_oid *short_oid, size_t len) { if (len >= GIT_OID_HEXSZ) { /* Just match the full identifier */ int error = hiredis_odb_backend__read(data_p, len_p, type_p, _backend, short_oid); if (error == GIT_OK) git_oid_cpy(out_oid, short_oid); return error; } /* TODO prefix */ giterr_set_str(GITERR_ODB, "Redis odb doesn't not implement oid prefix lookup"); return GIT_EINVALID; }
/** * Create and populate a vector of git_annotated_commit objects from * the given fetch head data. * * @param out Pointer the vector of git_annotated_commit objects. * @param repository The repository. * @param fetch_heads List of S4 class git_fetch_head objects. * @param n Length of fetch_heads list. * @return 0 on success, or error code */ static int git2r_merge_heads_from_fetch_heads( git_annotated_commit ***merge_heads, git_repository *repository, SEXP fetch_heads, size_t n) { int err = GIT_OK; size_t i; *merge_heads = calloc(n, sizeof(git_annotated_commit*)); if (!(*merge_heads)) { giterr_set_str(GITERR_NONE, git2r_err_alloc_memory_buffer); return GIT_ERROR; } for (i = 0; i < n; i++) { int err; git_oid oid; SEXP fh = VECTOR_ELT(fetch_heads, i); err = git_oid_fromstr( &oid, CHAR(STRING_ELT(GET_SLOT(fh, Rf_install("sha")), 0))); if (err) goto cleanup; err = git_annotated_commit_from_fetchhead( &((*merge_heads)[i]), repository, CHAR(STRING_ELT(GET_SLOT(fh, Rf_install("ref_name")), 0)), CHAR(STRING_ELT(GET_SLOT(fh, Rf_install("remote_url")), 0)), &oid); if (err) goto cleanup; } cleanup: if (err) { if (*merge_heads) git2r_merge_heads_free(*merge_heads, n); *merge_heads = NULL; } return err; }
int hiredis_refdb_backend__del(git_refdb_backend *_backend, const char *ref_name, const git_oid *old, const char *old_target) { hiredis_refdb_backend *backend; int error = GIT_OK; redisReply *reply; assert(ref_name && _backend); backend = (hiredis_refdb_backend *) _backend; reply = redisCommand(backend->db, "DEL %s:%s:refdb:%s", backend->prefix, backend->repo_path, ref_name); if(reply->type == REDIS_REPLY_ERROR) { giterr_set_str(GITERR_REFERENCE, "Redis refdb storage error"); error = GIT_ERROR; } freeReplyObject(reply); return error; }
int hiredis_refdb_backend__exists(int *exists, git_refdb_backend *_backend, const char *ref_name) { hiredis_refdb_backend *backend; int error = GIT_OK; redisReply *reply; assert(ref_name && _backend); backend = (hiredis_refdb_backend *) _backend; reply = redisCommand(backend->db, "EXISTS %s:%s:refdb:%s", backend->prefix, backend->repo_path, ref_name); if (reply->type == REDIS_REPLY_INTEGER) { *exists = reply->integer; } else { giterr_set_str(GITERR_REFERENCE, "Redis refdb storage error"); error = GIT_ERROR; } freeReplyObject(reply); return error; }
int hiredis_refdb_backend__rename(git_reference **out, git_refdb_backend *_backend, const char *old_name, const char *new_name, int force, const git_signature *who, const char *message) { hiredis_refdb_backend *backend; int error = GIT_OK; redisReply *reply; assert(old_name && new_name && _backend); backend = (hiredis_refdb_backend *) _backend; reply = redisCommand(backend->db, "RENAME %s:%s:refdb:%s %s:%s:refdb:%s", backend->prefix, backend->repo_path, old_name, backend->prefix, backend->repo_path, new_name); if(reply->type == REDIS_REPLY_ERROR) { freeReplyObject(reply); giterr_set_str(GITERR_REFERENCE, "Redis refdb storage error"); return GIT_ERROR; } freeReplyObject(reply); return hiredis_refdb_backend__lookup(out, _backend, new_name); }
int hiredis_refdb_backend__write(git_refdb_backend *_backend, const git_reference *ref, int force, const git_signature *who, const char *message, const git_oid *old, const char *old_target) { hiredis_refdb_backend *backend; int error = GIT_OK; redisReply *reply; const char *name = git_reference_name(ref); const git_oid *target; const char *symbolic_target; char oid_str[GIT_OID_HEXSZ + 1]; assert(ref && _backend); backend = (hiredis_refdb_backend *) _backend; target = git_reference_target(ref); /* FIXME handle force correctly */ if (target) { git_oid_nfmt(oid_str, sizeof(oid_str), target); reply = redisCommand(backend->db, "HMSET %s:%s:refdb:%s type %d target %s", backend->prefix, backend->repo_path, name, GIT_REF_OID, oid_str); } else { symbolic_target = git_reference_symbolic_target(ref); reply = redisCommand(backend->db, "HMSET %s:%s:refdb:%s type %d target %s", backend->prefix, backend->repo_path, name, GIT_REF_SYMBOLIC, symbolic_target); } if(reply->type == REDIS_REPLY_ERROR) { giterr_set_str(GITERR_REFERENCE, "Redis refdb storage error"); error = GIT_ERROR; } freeReplyObject(reply); return error; }
/** * Merge branch into HEAD * * @param branch S4 class git_branch to merge into HEAD. * @param merger Who is performing the merge * @param commit_on_success Commit merge commit, if one was created * during a normal merge * @return S4 class git_merge_result */ SEXP git2r_merge_branch(SEXP branch, SEXP merger, SEXP commit_on_success) { int err; SEXP result = R_NilValue; const char *name; git_buf buf = GIT_BUF_INIT; git_branch_t type; git_annotated_commit **merge_heads = NULL; git_reference *reference = NULL; git_repository *repository = NULL; git_signature *who = NULL; if (git2r_arg_check_branch(branch)) git2r_error(__func__, NULL, "'branch'", git2r_err_branch_arg); if (git2r_arg_check_logical(commit_on_success)) git2r_error(__func__, NULL, "'commit_on_success'", git2r_err_logical_arg); if (git2r_arg_check_signature(merger)) git2r_error(__func__, NULL, "'merger'", git2r_err_signature_arg); err = git2r_signature_from_arg(&who, merger); if (err) goto cleanup; repository = git2r_repository_open(GET_SLOT(branch, Rf_install("repo"))); if (!repository) git2r_error(__func__, NULL, git2r_err_invalid_repository, NULL); name = CHAR(STRING_ELT(GET_SLOT(branch, Rf_install("name")), 0)); type = INTEGER(GET_SLOT(branch, Rf_install("type")))[0]; err = git_branch_lookup(&reference, repository, name, type); if (err) goto cleanup; merge_heads = calloc(1, sizeof(git_annotated_commit*)); if (NULL == merge_heads) { giterr_set_str(GITERR_NONE, git2r_err_alloc_memory_buffer); goto cleanup; } err = git_annotated_commit_from_ref( &(merge_heads[0]), repository, reference); if (err) goto cleanup; err = git_buf_printf(&buf, "merge %s", name); if (err) goto cleanup; PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_merge_result"))); err = git2r_merge( result, repository, (const git_annotated_commit **)merge_heads, 1, GIT_MERGE_PREFERENCE_NONE, buf.ptr, who, LOGICAL(commit_on_success)[0]); cleanup: git_buf_free(&buf); if (who) git_signature_free(who); if (merge_heads) git2r_merge_heads_free(merge_heads, 1); if (reference) git_reference_free(reference); if (repository) git_repository_free(repository); if (R_NilValue != result) UNPROTECT(1); if (err) git2r_error(__func__, giterr_last(), NULL, NULL); return result; }
/** * @param merge_result S4 class git_merge_result * @repository The repository * @param merge_head The merge head to merge * @param n The number of merge heads * @param preference The merge preference option (None [0], No * Fast-Forward [1] or Only Fast-Forward [2]) * @param name The name of the merge in the reflog * @param merger Who is performing the merge * @param commit_on_success Commit merge commit, if one was created * during a normal merge * @return 0 on success, or error code */ static int git2r_merge( SEXP merge_result, git_repository *repository, const git_annotated_commit **merge_heads, size_t n, git_merge_preference_t preference, const char *name, git_signature *merger, int commit_on_success) { int err; git_merge_analysis_t merge_analysis; git_merge_preference_t merge_preference; git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT; merge_opts.rename_threshold = 50; merge_opts.target_limit = 200; checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; err = git_merge_analysis( &merge_analysis, &merge_preference, repository, merge_heads, n); if (err) return err; if (merge_analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) { SET_SLOT(merge_result, Rf_install("up_to_date"), ScalarLogical(1)); return GIT_OK; } else { SET_SLOT(merge_result, Rf_install("up_to_date"), ScalarLogical(0)); } if (GIT_MERGE_PREFERENCE_NONE == preference) preference = merge_preference; switch (preference) { case GIT_MERGE_PREFERENCE_NONE: if (merge_analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) { if (1 != n) { giterr_set_str( GITERR_NONE, "Unable to perform Fast-Forward merge " "with mith multiple merge heads."); return GIT_ERROR; } err = git2r_fast_forward_merge( merge_result, merge_heads[0], repository, name); } else if (merge_analysis & GIT_MERGE_ANALYSIS_NORMAL) { err = git2r_normal_merge( merge_result, merge_heads, n, repository, name, merger, commit_on_success, &checkout_opts, &merge_opts); } break; case GIT_MERGE_PREFERENCE_NO_FASTFORWARD: if (merge_analysis & GIT_MERGE_ANALYSIS_NORMAL) { err = git2r_normal_merge( merge_result, merge_heads, n, repository, name, merger, commit_on_success, &checkout_opts, &merge_opts); } break; case GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY: if (merge_analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) { if (1 != n) { giterr_set_str( GITERR_NONE, "Unable to perform Fast-Forward merge " "with mith multiple merge heads."); return GIT_ERROR; } err = git2r_fast_forward_merge( merge_result, merge_heads[0], repository, name); } else { giterr_set_str(GITERR_NONE, "Unable to perform Fast-Forward merge."); return GIT_ERROR; } break; default: giterr_set_str(GITERR_NONE, "Unknown merge option"); return GIT_ERROR; } return GIT_OK; }
int git_pkt_parse_line( git_pkt **head, const char *line, const char **out, size_t bufflen) { int ret; int32_t len; /* Not even enough for the length */ if (bufflen > 0 && bufflen < PKT_LEN_SIZE) return GIT_EBUFS; len = parse_len(line); if (len < 0) { /* * If we fail to parse the length, it might be because the * server is trying to send us the packfile already. */ if (bufflen >= 4 && !git__prefixcmp(line, "PACK")) { giterr_clear(); *out = line; return pack_pkt(head); } return (int)len; } /* * If we were given a buffer length, then make sure there is * enough in the buffer to satisfy this line */ if (bufflen > 0 && bufflen < (size_t)len) return GIT_EBUFS; /* * The length has to be exactly 0 in case of a flush * packet or greater than PKT_LEN_SIZE, as the decoded * length includes its own encoded length of four bytes. */ if (len != 0 && len < PKT_LEN_SIZE) return GIT_ERROR; line += PKT_LEN_SIZE; /* * The Git protocol does not specify empty lines as part * of the protocol. Not knowing what to do with an empty * line, we should return an error upon hitting one. */ if (len == PKT_LEN_SIZE) { giterr_set_str(GITERR_NET, "Invalid empty packet"); return GIT_ERROR; } if (len == 0) { /* Flush pkt */ *out = line; return flush_pkt(head); } len -= PKT_LEN_SIZE; /* the encoded length includes its own size */ if (*line == GIT_SIDE_BAND_DATA) ret = data_pkt(head, line, len); else if (*line == GIT_SIDE_BAND_PROGRESS) ret = sideband_progress_pkt(head, line, len); else if (*line == GIT_SIDE_BAND_ERROR) ret = sideband_error_pkt(head, line, len); else if (!git__prefixcmp(line, "ACK")) ret = ack_pkt(head, line, len); else if (!git__prefixcmp(line, "NAK")) ret = nak_pkt(head); else if (!git__prefixcmp(line, "ERR ")) ret = err_pkt(head, line, len); else if (*line == '#') ret = comment_pkt(head, line, len); else if (!git__prefixcmp(line, "ok")) ret = ok_pkt(head, line, len); else if (!git__prefixcmp(line, "ng")) ret = ng_pkt(head, line, len); else if (!git__prefixcmp(line, "unpack")) ret = unpack_pkt(head, line, len); else ret = ref_pkt(head, line, len); *out = line + len; return ret; }
static int handle(KDriver const *driver, KImplementation const *impl, int requested) { char const *url = k_dictionary_get(k_implementation_get_values(impl), "href"); char const *tag = k_dictionary_get(k_implementation_get_values(impl), "tag"); char const *path = k_dictionary_get(k_implementation_get_meta(impl), "name"); git_repository* repo = NULL; git_remote* origin = NULL; if (git_repository_open(&repo, path) == GIT_OK) { if (git_remote_load(&origin, repo, "origin") != GIT_OK) { git_repository_free(repo); return -1; } if (strcmp(url, git_remote_url(origin)) != 0) { giterr_set_str(GITERR_INVALID, "different origin"); git_repository_free(repo); return -1; } } else { if (git_repository_init(&repo, path, 0) != GIT_OK) { return -1; } if (git_remote_create(&origin, repo, "origin", url) != GIT_OK) { git_repository_free(repo); return -1; } } git_remote_set_update_fetchhead(origin, 0); git_remote_set_cred_acquire_cb(origin, cred_acquire, NULL); if (git_remote_connect(origin, GIT_DIRECTION_FETCH) != GIT_OK) { git_remote_free(origin); git_repository_free(repo); return -1; } if (git_remote_download(origin, transfer_progress, NULL) != GIT_OK) { git_remote_free(origin); git_repository_free(repo); return -1; } if (git_remote_update_tips(origin) != GIT_OK) { git_remote_free(origin); git_repository_free(repo); return -1; } git_object* object = NULL; if (git_revparse_single(&object, repo, tag) != GIT_OK) { git_remote_free(origin); git_repository_free(repo); return -1; } if (git_repository_set_head_detached(repo, git_object_id(object)) != GIT_OK) { git_object_free(object); git_remote_free(origin); git_repository_free(repo); return -1; } git_checkout_opts checkout_opts = GIT_CHECKOUT_OPTS_INIT; checkout_opts.version = GIT_CHECKOUT_OPTS_VERSION; checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; checkout_opts.progress_cb = checkout_progress; checkout_opts.progress_payload = NULL; if (git_checkout_tree(repo, object, &checkout_opts) != GIT_OK) { git_object_free(object); git_remote_free(origin); git_repository_free(repo); return -1; } git_object_free(object); git_remote_free(origin); git_repository_free(repo); return 0; }
int CGitProgressList::UpdateProgress(const git_transfer_progress* stat) { static unsigned int start = 0; unsigned int dt = GetCurrentTime() - start; double speed = 0; if (m_bCancelled) { giterr_set_str(GITERR_NONE, "User cancelled."); return GIT_EUSER; } if (dt > 100) { start = GetCurrentTime(); size_t ds = stat->received_bytes - m_TotalBytesTransferred; speed = ds * 1000.0/dt; m_TotalBytesTransferred = stat->received_bytes; } else return 0; int progress; progress = stat->received_objects + stat->indexed_objects; if ((stat->total_objects > 1000) && m_pProgControl && (!m_pProgControl->IsWindowVisible())) m_pProgControl->ShowWindow(SW_SHOW); if (m_pProgressLabelCtrl && m_pProgressLabelCtrl->IsWindowVisible()) m_pProgressLabelCtrl->ShowWindow(SW_SHOW); if (m_pProgControl) { m_pProgControl->SetPos(progress); m_pProgControl->SetRange32(0, 2 * stat->total_objects); } if (m_pTaskbarList && m_pPostWnd) { m_pTaskbarList->SetProgressState(m_pPostWnd->GetSafeHwnd(), TBPF_NORMAL); m_pTaskbarList->SetProgressValue(m_pPostWnd->GetSafeHwnd(), progress, 2 * stat->total_objects); } CString progText; if (stat->received_bytes < 1024) m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALBYTESTRANSFERRED, (int64_t)stat->received_bytes); else if (stat->received_bytes < 1200000) m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALTRANSFERRED, (int64_t)stat->received_bytes / 1024); else m_sTotalBytesTransferred.Format(IDS_SVN_PROGRESS_TOTALMBTRANSFERRED, (double)((double)stat->received_bytes / 1048576.0)); CString str; if(speed < 1024) str.Format(_T("%.0f B/s"), speed); else if(speed < 1024 * 1024) str.Format(_T("%.2f KiB/s"), speed / 1024); else str.Format(_T("%.2f MiB/s"), speed / 1048576.0); progText.Format(IDS_SVN_PROGRESS_TOTALANDSPEED, (LPCTSTR)m_sTotalBytesTransferred, (LPCTSTR)str); if (m_pProgressLabelCtrl) m_pProgressLabelCtrl->SetWindowText(progText); SetTimer(TRANSFERTIMER, 2000, NULL); return 0; }
static int _git_ssh_setup_conn( ssh_subtransport *t, const char *url, const char *cmd, git_smart_subtransport_stream **stream) { char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL; const char *default_port="22"; ssh_stream *s; LIBSSH2_SESSION* session=NULL; LIBSSH2_CHANNEL* channel=NULL; *stream = NULL; if (ssh_stream_alloc(t, url, cmd, stream) < 0) return -1; s = (ssh_stream *)*stream; if (!git__prefixcmp(url, prefix_ssh)) { if (gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, default_port) < 0) goto on_error; } else { if (git_ssh_extract_url_parts(&host, &user, url) < 0) goto on_error; port = git__strdup(default_port); GITERR_CHECK_ALLOC(port); } if (gitno_connect(&s->socket, host, port, 0) < 0) goto on_error; if (user && pass) { if (git_cred_userpass_plaintext_new(&t->cred, user, pass) < 0) goto on_error; } else if (t->owner->cred_acquire_cb) { if (t->owner->cred_acquire_cb( &t->cred, t->owner->url, user, GIT_CREDTYPE_USERPASS_PLAINTEXT | GIT_CREDTYPE_SSH_KEY | GIT_CREDTYPE_SSH_CUSTOM, t->owner->cred_acquire_payload) < 0) goto on_error; if (!t->cred) { giterr_set(GITERR_SSH, "Callback failed to initialize SSH credentials"); goto on_error; } } else { giterr_set(GITERR_SSH, "Cannot set up SSH connection without credentials"); goto on_error; } assert(t->cred); if (!user && !git_cred_has_username(t->cred)) { giterr_set_str(GITERR_NET, "Cannot authenticate without a username"); goto on_error; } if (_git_ssh_session_create(&session, s->socket) < 0) goto on_error; if (_git_ssh_authenticate_session(session, user, t->cred) < 0) goto on_error; channel = libssh2_channel_open_session(session); if (!channel) { ssh_error(session, "Failed to open SSH channel"); goto on_error; } libssh2_channel_set_blocking(channel, 1); s->session = session; s->channel = channel; t->current_stream = s; git__free(host); git__free(port); git__free(path); git__free(user); git__free(pass); return 0; on_error: s->session = NULL; s->channel = NULL; t->current_stream = NULL; if (*stream) ssh_stream_free(*stream); git__free(host); git__free(port); git__free(user); git__free(pass); if (session) libssh2_session_free(session); return -1; }
void giterr_set_regex(const regex_t *regex, int error_code) { char error_buf[1024]; regerror(error_code, regex, error_buf, sizeof(error_buf)); giterr_set_str(GITERR_REGEX, error_buf); }
/** * Fetch new data and update tips * * @param repo S4 class git_repository * @param name The name of the remote to fetch from * @param credentials The credentials for remote repository access. * @param msg The one line long message to be appended to the reflog * @param verbose Print information each time a reference is updated locally. * @param refspecs The refspecs to use for this fetch. Pass R_NilValue * to use the base refspecs. * @return R_NilValue */ SEXP git2r_remote_fetch( SEXP repo, SEXP name, SEXP credentials, SEXP msg, SEXP verbose, SEXP refspecs) { int err; SEXP result = R_NilValue; const git_transfer_progress *stats; git_remote *remote = NULL; git_repository *repository = NULL; git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT; git2r_transfer_data payload = GIT2R_TRANSFER_DATA_INIT; git_strarray refs = {0}; if (git2r_arg_check_string(name)) git2r_error(__func__, NULL, "'name'", git2r_err_string_arg); if (git2r_arg_check_credentials(credentials)) git2r_error(__func__, NULL, "'credentials'", git2r_err_credentials_arg); if (git2r_arg_check_string(msg)) git2r_error(__func__, NULL, "'msg'", git2r_err_string_arg); if (git2r_arg_check_logical(verbose)) git2r_error(__func__, NULL, "'verbose'", git2r_err_logical_arg); if (refspecs != R_NilValue && git2r_arg_check_string_vec(refspecs)) git2r_error(__func__, NULL, "'refspecs'", git2r_err_string_vec_arg); repository = git2r_repository_open(repo); if (!repository) git2r_error(__func__, NULL, git2r_err_invalid_repository, NULL); err = git_remote_lookup(&remote, repository, CHAR(STRING_ELT(name, 0))); if (err) goto cleanup; if (refspecs != R_NilValue) { size_t i, len; /* Count number of non NA values */ len = length(refspecs); for (i = 0; i < len; i++) if (NA_STRING != STRING_ELT(refspecs, i)) refs.count++; if (refs.count) { /* Allocate the strings in refs */ refs.strings = malloc(refs.count * sizeof(char*)); if (!refs.strings) { giterr_set_str(GITERR_NONE, git2r_err_alloc_memory_buffer); err = GIT_ERROR; goto cleanup; } /* Populate the strings in refs */ for (i = 0; i < refs.count; i++) if (NA_STRING != STRING_ELT(refspecs, i)) refs.strings[i] = (char *)CHAR(STRING_ELT(refspecs, i)); } } if (LOGICAL(verbose)[0]) payload.verbose = 1; payload.credentials = credentials; fetch_opts.callbacks.payload = &payload; fetch_opts.callbacks.credentials = &git2r_cred_acquire_cb; fetch_opts.callbacks.update_tips = &git2r_update_tips_cb; err = git_remote_fetch(remote, &refs, &fetch_opts, CHAR(STRING_ELT(msg, 0))); if (err) goto cleanup; stats = git_remote_stats(remote); PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_transfer_progress"))); git2r_transfer_progress_init(stats, result); cleanup: if (refs.strings) free(refs.strings); if (remote) { if (git_remote_connected(remote)) git_remote_disconnect(remote); git_remote_free(remote); } if (repository) git_repository_free(repository); if (R_NilValue != result) UNPROTECT(1); if (err) git2r_error( __func__, giterr_last(), git2r_err_unable_to_authenticate, NULL); return result; }
/** * Find object specified by revision * * @param repo S4 class git_repository * @param revision The revision string, see * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions * @return S4 object of class git_commit, git_tag or git_tree. */ SEXP git2r_revparse_single(SEXP repo, SEXP revision) { int err; SEXP result = R_NilValue; git_repository *repository = NULL; git_object *treeish = NULL; if (git2r_arg_check_string(revision)) git2r_error(git2r_err_string_arg, __func__, "revision"); repository = git2r_repository_open(repo); if (!repository) git2r_error(git2r_err_invalid_repository, __func__, NULL); err = git_revparse_single( &treeish, repository, CHAR(STRING_ELT(revision, 0))); if (GIT_OK != err) goto cleanup; switch (git_object_type(treeish)) { case GIT_OBJ_COMMIT: PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_commit"))); git2r_commit_init((git_commit*)treeish, repo, result); break; case GIT_OBJ_TAG: PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_tag"))); git2r_tag_init((git_tag*)treeish, repo, result); break; case GIT_OBJ_TREE: PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_tree"))); git2r_tree_init((git_tree*)treeish, repo, result); break; default: giterr_set_str(GITERR_NONE, git2r_err_revparse_single); err = GIT_ERROR; break; } cleanup: if (treeish) git_object_free(treeish); if (repository) git_repository_free(repository); if (R_NilValue != result) UNPROTECT(1); if (GIT_OK != err) { if (GIT_ENOTFOUND == err) { git2r_error( git2r_err_from_libgit2, __func__, "Requested object could not be found"); } else { git2r_error( git2r_err_from_libgit2, __func__, giterr_last()->message); } } return result; }