void git_index_clear(git_index *index) { unsigned int i; assert(index); for (i = 0; i < index->entries.length; ++i) { git_index_entry *e; e = git_vector_get(&index->entries, i); free((char *)e->path); free(e); } for (i = 0; i < index->unmerged.length; ++i) { git_index_entry_unmerged *e; e = git_vector_get(&index->unmerged, i); free((char *)e->path); free(e); } git_vector_clear(&index->entries); git_vector_clear(&index->unmerged); index->last_modified = 0; free_tree(index->tree); index->tree = NULL; }
/* insert_sorted with duplicates */ void test_core_vector__4(void) { git_vector x; intptr_t i; git_vector_init(&x, 1, &compare_them); for (i = 0; i < 10; i += 2) { git_vector_insert_sorted(&x, (void*)(i + 1), NULL); } for (i = 9; i > 0; i -= 2) { git_vector_insert_sorted(&x, (void*)(i + 1), NULL); } for (i = 0; i < 10; i += 2) { git_vector_insert_sorted(&x, (void*)(i + 1), NULL); } for (i = 9; i > 0; i -= 2) { git_vector_insert_sorted(&x, (void*)(i + 1), NULL); } cl_assert(x.length == 20); for (i = 0; i < 20; ++i) { cl_assert(git_vector_get(&x, i) == (void*)(i / 2 + 1)); } git_vector_free(&x); }
static int packfile_load__cb(void *_data, char *path) { struct pack_backend *backend = (struct pack_backend *)_data; struct git_pack_file *pack; int error; size_t i; if (git__suffixcmp(path, ".idx") != 0) return GIT_SUCCESS; /* not an index */ for (i = 0; i < backend->packs.length; ++i) { struct git_pack_file *p = git_vector_get(&backend->packs, i); if (memcmp(p->pack_name, path, strlen(path) - strlen(".idx")) == 0) return GIT_SUCCESS; } error = git_packfile_check(&pack, path); if (error < GIT_SUCCESS) return git__rethrow(error, "Failed to load packfile"); if (git_vector_insert(&backend->packs, pack) < GIT_SUCCESS) { free(pack); return GIT_ENOMEM; } return GIT_SUCCESS; }
int git_odb_read_header(git_rawobj *out, git_odb *db, const git_oid *id) { unsigned int i; int error = GIT_ENOTFOUND; assert(out && db && id); for (i = 0; i < db->backends.length && error < 0; ++i) { backend_internal *internal = git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; if (b->read_header != NULL) error = b->read_header(out, b, id); } /* * no backend could read only the header. * try reading the whole object and freeing the contents */ if (error < 0) { error = git_odb_read(out, db, id); git_rawobj_close(out); } return error; }
int git_commit__writeback(git_commit *commit, git_odb_source *src) { unsigned int i; if (commit->tree == NULL) return GIT_EMISSINGOBJDATA; git__write_oid(src, "tree", git_tree_id(commit->tree)); for (i = 0; i < commit->parents.length; ++i) { git_commit *parent; parent = git_vector_get(&commit->parents, i); git__write_oid(src, "parent", git_commit_id(parent)); } if (commit->author == NULL) return GIT_EMISSINGOBJDATA; git_signature__write(src, "author", commit->author); if (commit->committer == NULL) return GIT_EMISSINGOBJDATA; git_signature__write(src, "committer", commit->committer); if (commit->message != NULL) git__source_printf(src, "\n%s", commit->message); /* Mark the commit as having all attributes */ commit->full_parse = 1; return GIT_SUCCESS; }
static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid) { int error; size_t i; if ((error = packfile_refresh_all(backend)) < GIT_SUCCESS) return git__rethrow(error, "Failed to find pack entry"); if (backend->last_found && git_pack_entry_find(e, backend->last_found, oid, GIT_OID_HEXSZ) == GIT_SUCCESS) return GIT_SUCCESS; for (i = 0; i < backend->packs.length; ++i) { struct git_pack_file *p; p = git_vector_get(&backend->packs, i); if (p == backend->last_found) continue; if (git_pack_entry_find(e, p, oid, GIT_OID_HEXSZ) == GIT_SUCCESS) { backend->last_found = p; return GIT_SUCCESS; } } return git__throw(GIT_ENOTFOUND, "Failed to find pack entry"); }
/* * Close the least recently used window. You should check to see if * the file descriptors need closing from time to time. */ static int git_mwindow_close_lru(git_mwindow_file *mwf) { unsigned int i; git_mwindow *lru_w = NULL, *lru_l = NULL; /* FIMXE: Does this give us any advantage? */ if(mwf->windows) git_mwindow_scan_lru(mwf, &lru_w, &lru_l); for (i = 0; i < ctl.windowfiles.length; ++i) { git_mwindow_scan_lru(git_vector_get(&ctl.windowfiles, i), &lru_w, &lru_l); } if (lru_w) { git_mwindow_close(&lru_w); ctl.mapped -= lru_w->window_map.len; git_futils_mmap_free(&lru_w->window_map); if (lru_l) lru_l->next = lru_w->next; else mwf->windows = lru_w->next; free(lru_w); ctl.open_windows--; return GIT_SUCCESS; } return git__throw(GIT_ERROR, "Failed to close memory window. Couln't find LRU"); }
/* * Free all the windows in a sequence, typically because we're done * with the file */ void git_mwindow_free_all(git_mwindow_file *mwf) { unsigned int i; /* * Remove these windows from the global list */ for (i = 0; i < ctl.windowfiles.length; ++i){ if (git_vector_get(&ctl.windowfiles, i) == mwf) { git_vector_remove(&ctl.windowfiles, i); break; } } if (ctl.windowfiles.length == 0) { git_vector_free(&ctl.windowfiles); ctl.windowfiles.contents = NULL; } while (mwf->windows) { git_mwindow *w = mwf->windows; assert(w->inuse_cnt == 0); ctl.mapped -= w->window_map.len; ctl.open_windows--; git_futils_mmap_free(&w->window_map); mwf->windows = w->next; free(w); } }
static int packfile_load__cb(void *data, git_buf *path) { struct pack_backend *backend = (pack_backend*) data; struct git_pack_file *pack; const char *path_str = git_buf_cstr(path); size_t i, cmp_len = git_buf_len(path); int error; if (cmp_len <= strlen(".idx") || git__suffixcmp(path_str, ".idx") != 0) return 0; /* not an index */ cmp_len -= strlen(".idx"); for (i = 0; i < backend->packs.length; ++i) { struct git_pack_file *p = (git_pack_file*) git_vector_get(&backend->packs, i); if (memcmp(p->pack_name, path_str, cmp_len) == 0) return 0; } error = git_mwindow_get_pack(&pack, path->ptr); /* ignore missing .pack file as git does */ if (error == GIT_ENOTFOUND) { giterr_clear(); return 0; } if (!error) error = git_vector_insert(&backend->packs, pack); return error; }
/* * Since this is a network connection, we need to parse and store the * pkt-lines at this stage and keep them there. */ static int git_connect(git_transport *transport, int direction) { transport_git *t = (transport_git *) transport; if (direction == GIT_DIR_PUSH) { giterr_set(GITERR_NET, "Pushing over git:// is not supported"); return -1; } t->parent.direction = direction; /* Connect and ask for the refs */ if (do_connect(t, transport->url) < 0) return -1; gitno_buffer_setup(transport, &transport->buffer, t->buff, sizeof(t->buff)); t->parent.connected = 1; if (git_protocol_store_refs(transport, 1) < 0) return -1; if (git_protocol_detect_caps(git_vector_get(&transport->refs, 0), &transport->caps) < 0) return -1; return 0; }
static int pack_entry_find_inner( struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid, struct git_pack_file *last_found) { size_t i; if (last_found && git_pack_entry_find(e, last_found, oid, GIT_OID_HEXSZ) == 0) return 0; for (i = 0; i < backend->packs.length; ++i) { struct git_pack_file *p; p = (git_pack_file*) git_vector_get(&backend->packs, i); if (p == last_found) continue; if (git_pack_entry_find(e, p, oid, GIT_OID_HEXSZ) == 0) { backend->last_found = p; return 0; } } return -1; }
int git_tree__writeback(git_tree *tree, git_odb_source *src) { size_t i; char filemode[8]; assert(tree && src); if (tree->entries.length == 0) return GIT_EMISSINGOBJDATA; git_vector_sort(&tree->entries); for (i = 0; i < tree->entries.length; ++i) { git_tree_entry *entry; entry = git_vector_get(&tree->entries, i); sprintf(filemode, "%06o ", entry->attr); git__source_write(src, filemode, strlen(filemode)); git__source_write(src, entry->filename, strlen(entry->filename) + 1); git__source_write(src, entry->oid.id, GIT_OID_RAWSZ); } return GIT_SUCCESS; }
int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_transfer_progress_cb progress_cb, void *progress_payload) { size_t i, writes = 0; int error = GIT_ERROR; assert(out && db); for (i = 0; i < db->backends.length && error < 0; ++i) { backend_internal *internal = (backend_internal *) git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; /* we don't write in alternates! */ if (internal->is_alternate) continue; if (b->writepack != NULL) { ++writes; error = b->writepack(out, b, db, progress_cb, progress_payload); } } if (error == GIT_PASSTHROUGH) error = 0; if (error < 0 && !writes) error = git_odb__error_unsupported_in_backend("write pack"); return error; }
static int detect_caps(transport_git *t) { git_vector *refs = &t->refs; git_pkt_ref *pkt; git_transport_caps *caps = &t->caps; const char *ptr; pkt = git_vector_get(refs, 0); /* No refs or capabilites, odd but not a problem */ if (pkt == NULL || pkt->capabilities == NULL) return 0; ptr = pkt->capabilities; while (ptr != NULL && *ptr != '\0') { if (*ptr == ' ') ptr++; if(!git__prefixcmp(ptr, GIT_CAP_OFS_DELTA)) { caps->common = caps->ofs_delta = 1; ptr += strlen(GIT_CAP_OFS_DELTA); continue; } /* We don't know this capability, so skip it */ ptr = strchr(ptr, ' '); } return 0; }
int git_odb_exists_prefix( git_oid *out, git_odb *db, const git_oid *short_id, size_t len) { int error = GIT_ENOTFOUND, num_found = 0; size_t i; git_oid key = {{0}}, last_found = {{0}}, found; assert(db && short_id); if (len < GIT_OID_MINPREFIXLEN) return git_odb__error_ambiguous("prefix length too short"); if (len > GIT_OID_HEXSZ) len = GIT_OID_HEXSZ; if (len == GIT_OID_HEXSZ) { if (git_odb_exists(db, short_id)) { if (out) git_oid_cpy(out, short_id); return 0; } else { return git_odb__error_notfound("no match for id prefix", short_id); } } /* just copy valid part of short_id */ memcpy(&key.id, short_id->id, (len + 1) / 2); if (len & 1) key.id[len / 2] &= 0xF0; for (i = 0; i < db->backends.length; ++i) { backend_internal *internal = (backend_internal *) git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; if (!b->exists_prefix) continue; error = b->exists_prefix(&found, b, &key, len); if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH) continue; if (error) return error; /* make sure found item doesn't introduce ambiguity */ if (num_found) { if (git_oid__cmp(&last_found, &found)) return git_odb__error_ambiguous("multiple matches for prefix"); } else { git_oid_cpy(&last_found, &found); num_found++; } } if (!num_found) return git_odb__error_notfound("no match for id prefix", &key); if (out) git_oid_cpy(out, &last_found); return 0; }
void test_checkout_conflict__report_progress(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_vector paths = GIT_VECTOR_INIT; char *path; size_t i; struct checkout_index_entry checkout_index_entries[] = { { 0100644, CONFLICTING_ANCESTOR_OID, 1, "conflicting-1.txt" }, { 0100644, CONFLICTING_OURS_OID, 2, "conflicting-1.txt" }, { 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting-1.txt" }, { 0100644, CONFLICTING_ANCESTOR_OID, 1, "conflicting-2.txt" }, { 0100644, CONFLICTING_OURS_OID, 2, "conflicting-2.txt" }, { 0100644, CONFLICTING_THEIRS_OID, 3, "conflicting-2.txt" }, { 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "conflicting-3.txt" }, { 0100644, AUTOMERGEABLE_OURS_OID, 2, "conflicting-3.txt" }, { 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "conflicting-3.txt" }, { 0100644, AUTOMERGEABLE_ANCESTOR_OID, 1, "conflicting-4.txt" }, { 0100644, AUTOMERGEABLE_OURS_OID, 2, "conflicting-4.txt" }, { 0100644, AUTOMERGEABLE_THEIRS_OID, 3, "conflicting-4.txt" }, }; opts.progress_cb = collect_progress; opts.progress_payload = &paths; create_index(checkout_index_entries, 12); git_index_write(g_index); cl_git_pass(git_checkout_index(g_repo, g_index, &opts)); cl_assert_equal_i(4, git_vector_length(&paths)); cl_assert_equal_s("conflicting-1.txt", git_vector_get(&paths, 0)); cl_assert_equal_s("conflicting-2.txt", git_vector_get(&paths, 1)); cl_assert_equal_s("conflicting-3.txt", git_vector_get(&paths, 2)); cl_assert_equal_s("conflicting-4.txt", git_vector_get(&paths, 3)); git_vector_foreach(&paths, i, path) git__free(path); git_vector_free(&paths); }
void test_network_remote_rename__symref_head(void) { int error; git_reference *ref; git_branch_t btype; git_branch_iterator *iter; git_strarray problems = {0}; char idstr[GIT_OID_HEXSZ + 1] = {0}; git_vector refs; cl_git_pass(git_reference_symbolic_create(&ref, _repo, "refs/remotes/test/HEAD", "refs/remotes/test/master", 0, NULL, NULL)); git_reference_free(ref); cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "renamed")); cl_assert_equal_i(0, problems.count); git_strarray_free(&problems); cl_git_pass(git_vector_init(&refs, 2, (git_vector_cmp) git_reference_cmp)); cl_git_pass(git_branch_iterator_new(&iter, _repo, GIT_BRANCH_REMOTE)); while ((error = git_branch_next(&ref, &btype, iter)) == 0) { cl_git_pass(git_vector_insert(&refs, ref)); } cl_assert_equal_i(GIT_ITEROVER, error); git_vector_sort(&refs); cl_assert_equal_i(2, refs.length); ref = git_vector_get(&refs, 0); cl_assert_equal_s("refs/remotes/renamed/HEAD", git_reference_name(ref)); cl_assert_equal_s("refs/remotes/renamed/master", git_reference_symbolic_target(ref)); git_reference_free(ref); ref = git_vector_get(&refs, 1); cl_assert_equal_s("refs/remotes/renamed/master", git_reference_name(ref)); git_oid_fmt(idstr, git_reference_target(ref)); cl_assert_equal_s("be3563ae3f795b2b4353bcce3a527ad0a4f7f644", idstr); git_reference_free(ref); git_vector_free(&refs); cl_git_fail_with(GIT_ITEROVER, git_branch_next(&ref, &btype, iter)); git_branch_iterator_free(iter); }
const git_reflog_entry * git_reflog_entry_byindex(const git_reflog *reflog, size_t idx) { assert(reflog); if (idx >= reflog->entries.length) return NULL; return git_vector_get( &reflog->entries, reflog_inverse_index(idx, reflog->entries.length)); }
int git_commit_parent(git_commit **parent, git_commit *commit, unsigned int n) { git_oid *parent_oid; assert(commit); parent_oid = git_vector_get(&commit->parent_oids, n); if (parent_oid == NULL) return git__throw(GIT_ENOTFOUND, "Parent %u does not exist", n); return git_commit_lookup(parent, commit->object.repo, parent_oid); }
static void clear_parents(git_commit *commit) { unsigned int i; for (i = 0; i < commit->parent_oids.length; ++i) { git_oid *parent = git_vector_get(&commit->parent_oids, i); free(parent); } git_vector_clear(&commit->parent_oids); }
git_tree_entry *git_tree_entry_byname(git_tree *tree, const char *filename) { int idx; assert(tree && filename); idx = git_vector_search(&tree->entries, filename); if (idx == GIT_ENOTFOUND) return NULL; return git_vector_get(&tree->entries, idx); }
static void check_backend_sorting(git_odb *odb) { unsigned int i; for (i = 0; i < odb->backends.length; ++i) { fake_backend *internal = *((fake_backend **)git_vector_get(&odb->backends, i)); cl_assert(internal != NULL); cl_assert(internal->position == (int)i); } }
git_vector_foreach(contents, i, ps) { /* skip if before start_stat or after end_stat */ cmp_len = min(start_len, ps->path_len); if (cmp_len && strncomp(ps->path, start_stat, cmp_len) < 0) continue; cmp_len = min(end_len, ps->path_len); if (cmp_len && strncomp(ps->path, end_stat, cmp_len) > 0) continue; git_buf_truncate(&full, prefix_len); if ((error = git_buf_joinpath(&full, full.ptr, ps->path)) < 0 || (error = git_path_lstat(full.ptr, &ps->st)) < 0) { if (error == GIT_ENOTFOUND) { /* file was removed between readdir and lstat */ char *entry_path = git_vector_get(contents, i); git_vector_remove(contents, i--); git__free(entry_path); } else { /* Treat the file as unreadable if we get any other error */ memset(&ps->st, 0, sizeof(ps->st)); ps->st.st_mode = GIT_FILEMODE_UNREADABLE; } giterr_clear(); error = 0; continue; } if (S_ISDIR(ps->st.st_mode)) { ps->path[ps->path_len++] = '/'; ps->path[ps->path_len] = '\0'; } else if (!S_ISREG(ps->st.st_mode) && !S_ISLNK(ps->st.st_mode)) { char *entry_path = git_vector_get(contents, i); git_vector_remove(contents, i--); git__free(entry_path); } }
static int write_entries(git_index *index, git_filebuf *file) { unsigned int i; for (i = 0; i < index->entries.length; ++i) { git_index_entry *entry; entry = git_vector_get(&index->entries, i); if (write_disk_entry(file, entry) < GIT_SUCCESS) return GIT_ENOMEM; } return GIT_SUCCESS; }
int git_patch_parsed_from_diff(git_patch **out, git_diff *d, size_t idx) { git_diff_parsed *diff = (git_diff_parsed *)d; git_patch *p; if ((p = git_vector_get(&diff->patches, idx)) == NULL) return -1; GIT_REFCOUNT_INC(p); *out = p; return 0; }
static void git_free(git_transport *transport) { transport_git *t = (transport_git *) transport; git_vector *refs = &transport->refs; unsigned int i; for (i = 0; i < refs->length; ++i) { git_pkt *p = git_vector_get(refs, i); git_pkt_free(p); } git_vector_free(refs); refs = &transport->common; for (i = 0; i < refs->length; ++i) { git_pkt *p = git_vector_get(refs, i); git_pkt_free(p); } git_vector_free(refs); git__free(t->parent.url); git__free(t); }
static commit_object *alloc_commit(git_revwalk *walk) { unsigned char *chunk; if (walk->chunk_size == COMMITS_PER_CHUNK) alloc_chunk(walk); chunk = git_vector_get(&walk->memory_alloc, walk->memory_alloc.length - 1); chunk += (walk->chunk_size * CHUNK_STEP); walk->chunk_size++; return (commit_object *)chunk; }
int git_config_set_string(git_config *cfg, const char *name, const char *value) { file_internal *internal; git_config_file *file; if (cfg->files.length == 0) return git__throw(GIT_EINVALIDARGS, "Cannot set variable value; no files open in the `git_config` instance"); internal = git_vector_get(&cfg->files, 0); file = internal->file; return file->set(file, name, value); }
const git_index_entry_unmerged *git_index_get_unmerged_bypath(git_index *index, const char *path) { int pos; assert(index && path); if (!index->unmerged.length) return NULL; if ((pos = git_vector_bsearch2(&index->unmerged, unmerged_srch, path)) < GIT_SUCCESS) return NULL; return git_vector_get(&index->unmerged, pos); }
int git_odb_open_wstream( git_odb_stream **stream, git_odb *db, size_t size, git_otype type) { size_t i, writes = 0; int error = GIT_ERROR; git_hash_ctx *ctx = NULL; assert(stream && db); for (i = 0; i < db->backends.length && error < 0; ++i) { backend_internal *internal = (backend_internal *) git_vector_get(&db->backends, i); git_odb_backend *b = internal->backend; /* we don't write in alternates! */ if (internal->is_alternate) continue; if (b->writestream != NULL) { ++writes; error = b->writestream(stream, b, size, type); } else if (b->write != NULL) { ++writes; error = init_fake_wstream(stream, b, size, type); } } if (error < 0) { if (error == GIT_PASSTHROUGH) error = 0; else if (!writes) error = git_odb__error_unsupported_in_backend("write object"); goto done; } ctx = (git_hash_ctx*) git__malloc(sizeof(git_hash_ctx)); GITERR_CHECK_ALLOC(ctx); if ((error = git_hash_ctx_init(ctx)) < 0) goto done; hash_header(ctx, size, type); (*stream)->hash_ctx = ctx; (*stream)->declared_size = size; (*stream)->received_bytes = 0; done: return error; }