int git_transaction_commit(git_transaction *tx) { transaction_node *node; git_strmap_iter pos; int error = 0; assert(tx); for (pos = kh_begin(tx->locks); pos < kh_end(tx->locks); pos++) { if (!git_strmap_has_data(tx->locks, pos)) continue; node = git_strmap_value_at(tx->locks, pos); if (node->reflog) { if ((error = tx->db->backend->reflog_write(tx->db->backend, node->reflog)) < 0) return error; } if (node->ref_type != GIT_REF_INVALID) { if ((error = update_target(tx->db, node)) < 0) return error; } } return 0; }
void git_transaction_free(git_transaction *tx) { transaction_node *node; git_pool pool; git_strmap_iter pos; assert(tx); /* start by unlocking the ones we've left hanging, if any */ for (pos = kh_begin(tx->locks); pos < kh_end(tx->locks); pos++) { if (!git_strmap_has_data(tx->locks, pos)) continue; node = git_strmap_value_at(tx->locks, pos); if (node->committed) continue; git_refdb_unlock(tx->db, node->payload, false, false, NULL, NULL, NULL); } git_refdb_free(tx->db); git_strmap_free(tx->locks); /* tx is inside the pool, so we need to extract the data */ memcpy(&pool, &tx->pool, sizeof(git_pool)); git_pool_clear(&pool); }
static int submodules_from_index(git_strmap *map, git_index *idx) { int error; git_iterator *i; const git_index_entry *entry; if ((error = git_iterator_for_index(&i, idx, 0, NULL, NULL)) < 0) return error; while (!(error = git_iterator_advance(&entry, i))) { khiter_t pos = git_strmap_lookup_index(map, entry->path); git_submodule *sm; if (git_strmap_valid_index(map, pos)) { sm = git_strmap_value_at(map, pos); if (S_ISGITLINK(entry->mode)) submodule_update_from_index_entry(sm, entry); else sm->flags |= GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE; } else if (S_ISGITLINK(entry->mode)) { if (!submodule_get_or_create(&sm, git_index_owner(idx), map, entry->path)) { submodule_update_from_index_entry(sm, entry); git_submodule_free(sm); } } } if (error == GIT_ITEROVER) error = 0; git_iterator_free(i); return error; }
static int submodule_get_or_create(git_submodule **out, git_repository *repo, git_strmap *map, const char *name) { int error = 0; khiter_t pos; git_submodule *sm = NULL; pos = git_strmap_lookup_index(map, name); if (git_strmap_valid_index(map, pos)) { sm = git_strmap_value_at(map, pos); goto done; } /* if the submodule doesn't exist yet in the map, create it */ if ((error = submodule_alloc(&sm, repo, name)) < 0) return error; pos = kh_put(str, map, sm->name, &error); /* nobody can beat us to adding it */ assert(error != 0); if (error < 0) { git_submodule_free(sm); return error; } git_strmap_set_value_at(map, pos, sm); done: GIT_REFCOUNT_INC(sm); *out = sm; return 0; }
/* lookup submodule or return ENOTFOUND if it doesn't exist */ static int submodule_lookup( git_submodule **out, git_submodule_cache *cache, const char *name, const char *alternate) { khiter_t pos; /* lock cache */ pos = git_strmap_lookup_index(cache->submodules, name); if (!git_strmap_valid_index(cache->submodules, pos) && alternate) pos = git_strmap_lookup_index(cache->submodules, alternate); if (!git_strmap_valid_index(cache->submodules, pos)) { /* unlock cache */ return GIT_ENOTFOUND; /* don't set error - caller will cope */ } if (out != NULL) { git_submodule *sm = git_strmap_value_at(cache->submodules, pos); GIT_REFCOUNT_INC(sm); *out = sm; } /* unlock cache */ return 0; }
GIT_INLINE(git_attr_file_entry *) attr_cache_lookup_entry( git_attr_cache *cache, const char *path) { khiter_t pos = git_strmap_lookup_index(cache->files, path); if (git_strmap_valid_index(cache->files, pos)) return git_strmap_value_at(cache->files, pos); else return NULL; }
static int find_locked(transaction_node **out, git_transaction *tx, const char *refname) { git_strmap_iter pos; transaction_node *node; pos = git_strmap_lookup_index(tx->locks, refname); if (!git_strmap_valid_index(tx->locks, pos)) { giterr_set(GITERR_REFERENCE, "the specified reference is not locked"); return GIT_ENOTFOUND; } node = git_strmap_value_at(tx->locks, pos); *out = node; return 0; }
int git_submodule_lookup( git_submodule **sm_ptr, /* NULL if user only wants to test existence */ git_repository *repo, const char *name) /* trailing slash is allowed */ { int error; khiter_t pos; assert(repo && name); if ((error = load_submodule_config(repo)) < 0) return error; pos = git_strmap_lookup_index(repo->submodules, name); if (!git_strmap_valid_index(repo->submodules, pos)) { error = GIT_ENOTFOUND; /* check if a plausible submodule exists at path */ if (git_repository_workdir(repo)) { git_buf path = GIT_BUF_INIT; if (git_buf_joinpath(&path, git_repository_workdir(repo), name) < 0) return -1; if (git_path_contains_dir(&path, DOT_GIT)) error = GIT_EEXISTS; git_buf_free(&path); } giterr_set(GITERR_SUBMODULE, (error == GIT_ENOTFOUND) ? "No submodule named '%s'" : "Submodule '%s' has not been added yet", name); return error; } if (sm_ptr) *sm_ptr = git_strmap_value_at(repo->submodules, pos); return 0; }
bool git_attr_cache__is_cached( git_repository *repo, git_attr_file_source source, const char *filename) { git_attr_cache *cache = git_repository_attr_cache(repo); git_strmap *files; khiter_t pos; git_attr_file_entry *entry; if (!cache || !(files = cache->files)) return false; pos = git_strmap_lookup_index(files, filename); if (!git_strmap_valid_index(files, pos)) return false; entry = git_strmap_value_at(files, pos); return entry && (entry->file[source] != NULL); }
int git_strmap_next( void **data, git_strmap_iter* iter, git_strmap *map) { if (!map) return GIT_ERROR; while (*iter != git_strmap_end(map)) { if (!(git_strmap_has_data(map, *iter))) { ++(*iter); continue; } *data = git_strmap_value_at(map, *iter); ++(*iter); return GIT_OK; } return GIT_ITEROVER; }
static int git_diff_driver_load( git_diff_driver **out, git_repository *repo, const char *driver_name) { int error = 0; git_diff_driver_registry *reg; git_diff_driver *drv = NULL; size_t namelen = strlen(driver_name); khiter_t pos; git_config *cfg; git_buf name = GIT_BUF_INIT; const git_config_entry *ce; bool found_driver = false; if ((reg = git_repository_driver_registry(repo)) == NULL) return -1; pos = git_strmap_lookup_index(reg->drivers, driver_name); if (git_strmap_valid_index(reg->drivers, pos)) { *out = git_strmap_value_at(reg->drivers, pos); return 0; } drv = git__calloc(1, sizeof(git_diff_driver) + namelen + 1); GITERR_CHECK_ALLOC(drv); drv->type = DIFF_DRIVER_AUTO; memcpy(drv->name, driver_name, namelen); /* if you can't read config for repo, just use default driver */ if (git_repository_config_snapshot(&cfg, repo) < 0) { giterr_clear(); goto done; } if ((error = git_buf_printf(&name, "diff.%s.binary", driver_name)) < 0) goto done; switch (git_config__get_bool_force(cfg, name.ptr, -1)) { case true: /* if diff.<driver>.binary is true, just return the binary driver */ *out = &global_drivers[DIFF_DRIVER_BINARY]; goto done; case false: /* if diff.<driver>.binary is false, force binary checks off */ /* but still may have custom function context patterns, etc. */ drv->binary_flags = GIT_DIFF_FORCE_TEXT; found_driver = true; break; default: /* diff.<driver>.binary unspecified or "auto", so just continue */ break; } /* TODO: warn if diff.<name>.command or diff.<name>.textconv are set */ git_buf_truncate(&name, namelen + strlen("diff..")); git_buf_put(&name, "xfuncname", strlen("xfuncname")); if ((error = git_config_get_multivar_foreach( cfg, name.ptr, NULL, diff_driver_xfuncname, drv)) < 0) { if (error != GIT_ENOTFOUND) goto done; giterr_clear(); /* no diff.<driver>.xfuncname, so just continue */ } git_buf_truncate(&name, namelen + strlen("diff..")); git_buf_put(&name, "funcname", strlen("funcname")); if ((error = git_config_get_multivar_foreach( cfg, name.ptr, NULL, diff_driver_funcname, drv)) < 0) { if (error != GIT_ENOTFOUND) goto done; giterr_clear(); /* no diff.<driver>.funcname, so just continue */ } /* if we found any patterns, set driver type to use correct callback */ if (git_array_size(drv->fn_patterns) > 0) { drv->type = DIFF_DRIVER_PATTERNLIST; found_driver = true; } git_buf_truncate(&name, namelen + strlen("diff..")); git_buf_put(&name, "wordregex", strlen("wordregex")); if ((error = git_config__lookup_entry(&ce, cfg, name.ptr, false)) < 0) goto done; if (!ce || !ce->value) /* no diff.<driver>.wordregex, so just continue */; else if (!(error = regcomp(&drv->word_pattern, ce->value, REG_EXTENDED))) found_driver = true; else { /* TODO: warn about bad regex instead of failure */ error = giterr_set_regex(&drv->word_pattern, error); goto done; } /* TODO: look up diff.<driver>.algorithm to turn on minimal / patience * diff in drv->other_flags */ /* if no driver config found at all, fall back on AUTO driver */ if (!found_driver) goto done; /* store driver in registry */ git_strmap_insert(reg->drivers, drv->name, drv, error); if (error < 0) goto done; error = 0; *out = drv; done: git_buf_free(&name); git_config_free(cfg); if (!*out) { int error2 = git_diff_driver_builtin(out, reg, driver_name); if (!error) error = error2; } if (drv && drv != *out) git_diff_driver_free(drv); return error; }