static const char *setup_discovered_git_dir(const char *gitdir, struct strbuf *cwd, int offset, int *nongit_ok) { if (check_repository_format_gently(gitdir, nongit_ok)) return NULL; /* --work-tree is set without --git-dir; use discovered one */ if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) { if (offset != cwd->len && !is_absolute_path(gitdir)) gitdir = xstrdup(real_path(gitdir)); if (chdir(cwd->buf)) die_errno("Could not come back to cwd"); return setup_explicit_git_dir(gitdir, cwd, nongit_ok); } /* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */ if (is_bare_repository_cfg > 0) { set_git_dir(offset == cwd->len ? gitdir : real_path(gitdir)); if (chdir(cwd->buf)) die_errno("Could not come back to cwd"); return NULL; } /* #0, #1, #5, #8, #9, #12, #13 */ set_git_work_tree("."); if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT)) set_git_dir(gitdir); inside_git_dir = 0; inside_work_tree = 1; if (offset == cwd->len) return NULL; /* Make "offset" point to past the '/', and add a '/' at the end */ offset++; strbuf_addch(cwd, '/'); return cwd->buf + offset; }
/* * Try to read the location of the git directory from the .git file, * return path to git directory if found. */ const char *read_gitfile(const char *path) { char *buf; char *dir; const char *slash; struct stat st; int fd; ssize_t len; if (stat(path, &st)) return NULL; if (!S_ISREG(st.st_mode)) return NULL; fd = open(path, O_RDONLY); if (fd < 0) die_errno("Error opening '%s'", path); buf = xmalloc(st.st_size + 1); len = read_in_full(fd, buf, st.st_size); close(fd); if (len != st.st_size) die("Error reading %s", path); buf[len] = '\0'; if (!starts_with(buf, "gitdir: ")) die("Invalid gitfile format: %s", path); while (buf[len - 1] == '\n' || buf[len - 1] == '\r') len--; if (len < 9) die("No path in gitfile: %s", path); buf[len] = '\0'; dir = buf + 8; if (!is_absolute_path(dir) && (slash = strrchr(path, '/'))) { size_t pathlen = slash+1 - path; size_t dirlen = pathlen + len - 8; dir = xmalloc(dirlen + 1); strncpy(dir, path, pathlen); strncpy(dir + pathlen, buf + 8, len - 8); dir[dirlen] = '\0'; free(buf); buf = dir; } if (!is_git_directory(dir)) die("Not a git repository: %s", dir); path = real_path(dir); free(buf); return path; }
struct worktree *find_worktree(struct worktree **list, const char *prefix, const char *arg) { struct worktree *wt; char *path; if ((wt = find_worktree_by_suffix(list, arg))) return wt; arg = prefix_filename(prefix, strlen(prefix), arg); path = real_pathdup(arg); for (; *list; list++) if (!fspathcmp(path, real_path((*list)->path))) break; free(path); return *list; }
static int add_one_reference(struct string_list_item *item, void *cb_data) { char *ref_git; const char *repo; struct strbuf alternate = STRBUF_INIT; /* Beware: read_gitfile(), real_path() and mkpath() return static buffer */ ref_git = xstrdup(real_path(item->string)); repo = read_gitfile(ref_git); if (!repo) repo = read_gitfile(mkpath("%s/.git", ref_git)); if (repo) { free(ref_git); ref_git = xstrdup(repo); } if (!repo && is_directory(mkpath("%s/.git/objects", ref_git))) { char *ref_git_git = mkpathdup("%s/.git", ref_git); free(ref_git); ref_git = ref_git_git; } else if (!is_directory(mkpath("%s/objects", ref_git))) { struct strbuf sb = STRBUF_INIT; if (get_common_dir(&sb, ref_git)) die(_("reference repository '%s' as a linked checkout is not supported yet."), item->string); die(_("reference repository '%s' is not a local repository."), item->string); } if (!access(mkpath("%s/shallow", ref_git), F_OK)) die(_("reference repository '%s' is shallow"), item->string); if (!access(mkpath("%s/info/grafts", ref_git), F_OK)) die(_("reference repository '%s' is grafted"), item->string); strbuf_addf(&alternate, "%s/objects", ref_git); add_to_alternates_file(alternate.buf); strbuf_release(&alternate); free(ref_git); return 0; }
/* * Normalize "path", prepending the "prefix" for relative paths. If * remaining_prefix is not NULL, return the actual prefix still * remains in the path. For example, prefix = sub1/sub2/ and path is * * foo -> sub1/sub2/foo (full prefix) * ../foo -> sub1/foo (remaining prefix is sub1/) * ../../bar -> bar (no remaining prefix) * ../../sub1/sub2/foo -> sub1/sub2/foo (but no remaining prefix) * `pwd`/../bar -> sub1/bar (no remaining prefix) */ char *prefix_path_gently(const char *prefix, int len, int *remaining_prefix, const char *path) { const char *orig = path; char *sanitized; if (is_absolute_path(orig)) { const char *temp = real_path(path); sanitized = xmalloc(len + strlen(temp) + 1); strcpy(sanitized, temp); if (remaining_prefix) *remaining_prefix = 0; } else { sanitized = xmalloc(len + strlen(path) + 1); if (len) memcpy(sanitized, prefix, len); strcpy(sanitized + len, path); if (remaining_prefix) *remaining_prefix = len; } if (normalize_path_copy_len(sanitized, sanitized, remaining_prefix)) goto error_out; if (is_absolute_path(orig)) { size_t root_len, len, total; const char *work_tree = get_git_work_tree(); if (!work_tree) goto error_out; len = strlen(work_tree); root_len = offset_1st_component(work_tree); total = strlen(sanitized) + 1; if (strncmp(sanitized, work_tree, len) || (len > root_len && sanitized[len] != '\0' && sanitized[len] != '/')) { error_out: free(sanitized); return NULL; } if (sanitized[len] == '/') len++; memmove(sanitized, sanitized + len, total - len); } return sanitized; }
static int add_one_reference(struct string_list_item *item, void *cb_data) { char *ref_git; struct strbuf alternate = STRBUF_INIT; /* Beware: real_path() and mkpath() return static buffer */ ref_git = xstrdup(real_path(item->string)); if (is_directory(mkpath("%s/.git/objects", ref_git))) { char *ref_git_git = xstrdup(mkpath("%s/.git", ref_git)); free(ref_git); ref_git = ref_git_git; } else if (!is_directory(mkpath("%s/objects", ref_git))) die(_("reference repository '%s' is not a local directory."), item->string); strbuf_addf(&alternate, "%s/objects", ref_git); add_to_alternates_file(alternate.buf); strbuf_release(&alternate); free(ref_git); return 0; }
static std::string computeExecutablePath() { std::string path = ""; #if defined(WIN32) std::vector<TCHAR> lpFilename(MAX_PATH); int ret = GetModuleFileName(NULL, /* NULL --> executable of the current process */ &lpFilename[0], MAX_PATH); if (ret == 0 || ret == MAX_PATH) { msg_error("Utils::computeExecutablePath()") << Utils::GetLastError(); } else { path = Utils::narrowString(std::wstring(&lpFilename[0])); } #elif defined(__APPLE__) std::vector<char> buffer(PATH_MAX); std::vector<char> real_path(PATH_MAX); uint32_t size = buffer.size(); if (_NSGetExecutablePath(&buffer[0], &size) != 0) { msg_error("Utils::computeExecutablePath()") << "_NSGetExecutablePath() failed"; } if (realpath(&buffer[0], &real_path[0]) == 0) { msg_error("Utils::computeExecutablePath()") << "realpath() failed"; } path = std::string(&real_path[0]); #else // Linux std::vector<char> buffer(PATH_MAX); if (readlink("/proc/self/exe", &buffer[0], buffer.size()) == -1) { int error = errno; msg_error("Utils::computeExecutablePath()") << strerror(error); } else { path = std::string(&buffer[0]); } #endif return FileSystem::cleanPath(path); }
/* Update gitfile and core.worktree setting to connect work tree and git dir */ void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir) { struct strbuf file_name = STRBUF_INIT; struct strbuf rel_path = STRBUF_INIT; const char *real_work_tree = xstrdup(real_path(work_tree)); /* Update gitfile */ strbuf_addf(&file_name, "%s/.git", work_tree); write_file(file_name.buf, "gitdir: %s", relative_path(git_dir, real_work_tree, &rel_path)); /* Update core.worktree setting */ strbuf_reset(&file_name); strbuf_addf(&file_name, "%s/config", git_dir); git_config_set_in_file(file_name.buf, "core.worktree", relative_path(real_work_tree, git_dir, &rel_path)); strbuf_release(&file_name); strbuf_release(&rel_path); free((void *)real_work_tree); }
int launch_editor(const char *path, struct strbuf *buffer, const char *const *env) { const char *editor = git_editor(); if (!editor) return error("Terminal is dumb, but EDITOR unset"); if (strcmp(editor, ":")) { const char *args[] = { editor, real_path(path), NULL }; struct child_process p = CHILD_PROCESS_INIT; int ret, sig; p.argv = args; p.env = env; p.use_shell = 1; if (start_command(&p) < 0) return error("unable to start editor '%s'", editor); sigchain_push(SIGINT, SIG_IGN); sigchain_push(SIGQUIT, SIG_IGN); ret = finish_command(&p); sig = ret - 128; sigchain_pop(SIGINT); sigchain_pop(SIGQUIT); if (sig == SIGINT || sig == SIGQUIT) raise(sig); if (ret) return error("There was a problem with the editor '%s'.", editor); } if (!buffer) return 0; if (strbuf_read_file(buffer, path, 0) < 0) return error("could not read file '%s': %s", path, strerror(errno)); return 0; }
void setup_work_tree(void) { const char *work_tree, *git_dir; static int initialized = 0; if (initialized) return; work_tree = get_git_work_tree(); git_dir = get_git_dir(); if (!is_absolute_path(git_dir)) git_dir = real_path(get_git_dir()); if (!work_tree || chdir(work_tree)) die("This operation must be run in a work tree"); /* * Make sure subsequent git processes find correct worktree * if $GIT_WORK_TREE is set relative */ if (getenv(GIT_WORK_TREE_ENVIRONMENT)) setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1); set_git_dir(remove_leading_path(git_dir, work_tree)); initialized = 1; }
/* * Return a string with ~ and ~user expanded via getpw*. If buf != NULL, * then it is a newly allocated string. Returns NULL on getpw failure or * if path is NULL. * * If real_home is true, real_path($HOME) is used in the expansion. */ char *expand_user_path(const char *path, int real_home) { struct strbuf user_path = STRBUF_INIT; const char *to_copy = path; if (path == NULL) goto return_null; if (path[0] == '~') { const char *first_slash = strchrnul(path, '/'); const char *username = path + 1; size_t username_len = first_slash - username; if (username_len == 0) { const char *home = getenv("HOME"); if (!home) goto return_null; if (real_home) strbuf_addstr(&user_path, real_path(home)); else strbuf_addstr(&user_path, home); #ifdef GIT_WINDOWS_NATIVE convert_slashes(user_path.buf); #endif } else { struct passwd *pw = getpw_str(username, username_len); if (!pw) goto return_null; strbuf_addstr(&user_path, pw->pw_dir); } to_copy = first_slash; } strbuf_addstr(&user_path, to_copy); return strbuf_detach(&user_path, NULL); return_null: strbuf_release(&user_path); return NULL; }
int init_db(const char *git_dir, const char *real_git_dir, const char *template_dir, unsigned int flags) { int reinit; int exist_ok = flags & INIT_DB_EXIST_OK; char *original_git_dir = real_pathdup(git_dir, 1); if (real_git_dir) { struct stat st; if (!exist_ok && !stat(git_dir, &st)) die(_("%s already exists"), git_dir); if (!exist_ok && !stat(real_git_dir, &st)) die(_("%s already exists"), real_git_dir); set_git_dir(real_path(real_git_dir)); git_dir = get_git_dir(); separate_git_dir(git_dir, original_git_dir); } else { set_git_dir(real_path(git_dir)); git_dir = get_git_dir(); } startup_info->have_repository = 1; /* Just look for `init.templatedir` and `core.hidedotfiles` */ git_config(git_init_db_config, NULL); safe_create_dir(git_dir, 0); init_is_bare_repository = is_bare_repository(); /* Check to see if the repository version is right. * Note that a newly created repository does not have * config file, so this will not fail. What we are catching * is an attempt to reinitialize new repository with an old tool. */ check_repository_format(); reinit = create_default_files(template_dir, original_git_dir); create_object_directory(); if (get_shared_repository()) { char buf[10]; /* We do not spell "group" and such, so that * the configuration can be read by older version * of git. Note, we use octal numbers for new share modes, * and compatibility values for PERM_GROUP and * PERM_EVERYBODY. */ if (get_shared_repository() < 0) /* force to the mode value */ xsnprintf(buf, sizeof(buf), "0%o", -get_shared_repository()); else if (get_shared_repository() == PERM_GROUP) xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_GROUP); else if (get_shared_repository() == PERM_EVERYBODY) xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_EVERYBODY); else BUG("invalid value for shared_repository"); git_config_set("core.sharedrepository", buf); git_config_set("receive.denyNonFastforwards", "true"); } if (!(flags & INIT_DB_QUIET)) { int len = strlen(git_dir); if (reinit) printf(get_shared_repository() ? _("Reinitialized existing shared Git repository in %s%s\n") : _("Reinitialized existing Git repository in %s%s\n"), git_dir, len && git_dir[len-1] != '/' ? "/" : ""); else printf(get_shared_repository() ? _("Initialized empty shared Git repository in %s%s\n") : _("Initialized empty Git repository in %s%s\n"), git_dir, len && git_dir[len-1] != '/' ? "/" : ""); } free(original_git_dir); return 0; }
static const char *setup_explicit_git_dir(const char *gitdirenv, struct strbuf *cwd, int *nongit_ok) { const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT); const char *worktree; char *gitfile; int offset; if (PATH_MAX - 40 < strlen(gitdirenv)) die("'$%s' too big", GIT_DIR_ENVIRONMENT); gitfile = (char*)read_gitfile(gitdirenv); if (gitfile) { gitfile = xstrdup(gitfile); gitdirenv = gitfile; } if (!is_git_directory(gitdirenv)) { if (nongit_ok) { *nongit_ok = 1; free(gitfile); return NULL; } die("Not a git repository: '%s'", gitdirenv); } if (check_repository_format_gently(gitdirenv, nongit_ok)) { free(gitfile); return NULL; } /* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */ if (work_tree_env) set_git_work_tree(work_tree_env); else if (is_bare_repository_cfg > 0) { if (git_work_tree_cfg) { /* #22.2, #30 */ warning("core.bare and core.worktree do not make sense"); work_tree_config_is_bogus = 1; } /* #18, #26 */ set_git_dir(gitdirenv); free(gitfile); return NULL; } else if (git_work_tree_cfg) { /* #6, #14 */ if (is_absolute_path(git_work_tree_cfg)) set_git_work_tree(git_work_tree_cfg); else { char *core_worktree; if (chdir(gitdirenv)) die_errno("Could not chdir to '%s'", gitdirenv); if (chdir(git_work_tree_cfg)) die_errno("Could not chdir to '%s'", git_work_tree_cfg); core_worktree = xgetcwd(); if (chdir(cwd->buf)) die_errno("Could not come back to cwd"); set_git_work_tree(core_worktree); free(core_worktree); } } else if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) { /* #16d */ set_git_dir(gitdirenv); free(gitfile); return NULL; } else /* #2, #10 */ set_git_work_tree("."); /* set_git_work_tree() must have been called by now */ worktree = get_git_work_tree(); /* both get_git_work_tree() and cwd are already normalized */ if (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */ set_git_dir(gitdirenv); free(gitfile); return NULL; } offset = dir_inside_of(cwd->buf, worktree); if (offset >= 0) { /* cwd inside worktree? */ set_git_dir(real_path(gitdirenv)); if (chdir(worktree)) die_errno("Could not chdir to '%s'", worktree); strbuf_addch(cwd, '/'); free(gitfile); return cwd->buf + offset; } /* cwd outside worktree */ set_git_dir(gitdirenv); free(gitfile); return NULL; }
/* * Try to read the location of the git directory from the .git file, * return path to git directory if found. * * On failure, if return_error_code is not NULL, return_error_code * will be set to an error code and NULL will be returned. If * return_error_code is NULL the function will die instead (for most * cases). */ const char *read_gitfile_gently(const char *path, int *return_error_code) { const int max_file_size = 1 << 20; /* 1MB */ int error_code = 0; char *buf = NULL; char *dir = NULL; const char *slash; struct stat st; int fd; ssize_t len; if (stat(path, &st)) { error_code = READ_GITFILE_ERR_STAT_FAILED; goto cleanup_return; } if (!S_ISREG(st.st_mode)) { error_code = READ_GITFILE_ERR_NOT_A_FILE; goto cleanup_return; } if (st.st_size > max_file_size) { error_code = READ_GITFILE_ERR_TOO_LARGE; goto cleanup_return; } fd = open(path, O_RDONLY); if (fd < 0) { error_code = READ_GITFILE_ERR_OPEN_FAILED; goto cleanup_return; } buf = xmalloc(st.st_size + 1); len = read_in_full(fd, buf, st.st_size); close(fd); if (len != st.st_size) { error_code = READ_GITFILE_ERR_READ_FAILED; goto cleanup_return; } buf[len] = '\0'; if (!starts_with(buf, "gitdir: ")) { error_code = READ_GITFILE_ERR_INVALID_FORMAT; goto cleanup_return; } while (buf[len - 1] == '\n' || buf[len - 1] == '\r') len--; if (len < 9) { error_code = READ_GITFILE_ERR_NO_PATH; goto cleanup_return; } buf[len] = '\0'; dir = buf + 8; if (!is_absolute_path(dir) && (slash = strrchr(path, '/'))) { size_t pathlen = slash+1 - path; dir = xstrfmt("%.*s%.*s", (int)pathlen, path, (int)(len - 8), buf + 8); free(buf); buf = dir; } if (!is_git_directory(dir)) { error_code = READ_GITFILE_ERR_NOT_A_REPO; goto cleanup_return; } update_linked_gitdir(path, dir); path = real_path(dir); cleanup_return: if (return_error_code) *return_error_code = error_code; else if (error_code) { switch (error_code) { case READ_GITFILE_ERR_STAT_FAILED: case READ_GITFILE_ERR_NOT_A_FILE: /* non-fatal; follow return path */ break; case READ_GITFILE_ERR_OPEN_FAILED: die_errno("Error opening '%s'", path); case READ_GITFILE_ERR_TOO_LARGE: die("Too large to be a .git file: '%s'", path); case READ_GITFILE_ERR_READ_FAILED: die("Error reading %s", path); case READ_GITFILE_ERR_INVALID_FORMAT: die("Invalid gitfile format: %s", path); case READ_GITFILE_ERR_NO_PATH: die("No path in gitfile: %s", path); case READ_GITFILE_ERR_NOT_A_REPO: die("Not a git repository: %s", dir); default: assert(0); } } free(buf); return error_code ? NULL : path; }
bool ArdbConfig::Parse(const Properties& props) { conf_props = props; conf_get_string(props, "home", home); if (home.empty()) { home = "../ardb"; } make_dir(home); int err = real_path(home, home); if (0 != err) { ERROR_LOG("Invalid 'home' config:%s for reason:%s", home.c_str(), strerror(err)); return false; } err = access(home.c_str(), R_OK | W_OK); if (0 != err) { err = errno; ERROR_LOG("Invalid 'home' config:%s for reason:%s", home.c_str(), strerror(err)); return false; } setenv("ARDB_HOME", home.c_str(), 1); replace_env_var(const_cast<Properties&>(props)); conf_get_string(props, "pidfile", pidfile); conf_get_int64(props, "thread-pool-size", thread_pool_size); if (thread_pool_size <= 0) { thread_pool_size = available_processors(); } conf_get_int64(props, "hz", hz); if (hz < CONFIG_MIN_HZ) hz = CONFIG_MIN_HZ; if (hz > CONFIG_MAX_HZ) hz = CONFIG_MAX_HZ; conf_get_int64(props, "tcp-keepalive", tcp_keepalive); conf_get_int64(props, "timeout", timeout); //conf_get_int64(props, "unixsocketperm", unixsocketperm); conf_get_int64(props, "slowlog-log-slower-than", slowlog_log_slower_than); conf_get_int64(props, "slowlog-max-len", slowlog_max_len); conf_get_int64(props, "maxclients", max_clients); if(max_clients <= 0) { max_clients = 10000; } for (int i = 0;; i++) { char config_key[256]; sprintf(config_key, "server[%d].listen", i); ListenPoint lp; std::string address; if (!conf_get_string(props, config_key, address)) { break; } if (address.find(":") == std::string::npos) { lp.host = address; } else { std::vector<std::string> ss = split_string(address, ":"); uint32 port; if (ss.size() < 2 || !string_touint32(ss[ss.size() - 1], port) || port > 65535) { ERROR_LOG("Invalid listen address %s", address.c_str()); return false; } lp.host = address.substr(0, address.size() - ss[ss.size() - 1].size() - 1); lp.port = port; } sprintf(config_key, "server[%d].qps-limit", i); conf_get_int64(props, config_key, lp.qps_limit); sprintf(config_key, "server[%d].unixsocketperm", i); conf_get_int64(props, config_key, lp.qps_limit); servers.push_back(lp); } if (servers.empty()) { ListenPoint lp; lp.host = "0.0.0.0"; lp.port = 16379; servers.push_back(lp); } if (strcasecmp(engine.c_str(), "rocksdb") == 0) { conf_get_string(props, "rocksdb.compaction", rocksdb_compaction); conf_get_bool(props, "rocksdb.disableWAL", rocksdb_disablewal); conf_get_bool(props, "rocksdb.scan-total-order", rocksdb_scan_total_order); } conf_get_string(props, "engine", engine); conf_get_string(props, "data-dir", data_base_path); conf_get_string(props, "backup-dir", backup_dir); conf_get_string(props, "repl-dir", repl_data_dir); make_dir(repl_data_dir); make_dir(backup_dir); err = real_path(repl_data_dir, repl_data_dir); if (0 != err) { ERROR_LOG("Invalid 'repl-dir' config:%s for reason:%s", repl_data_dir.c_str(), strerror(err)); return false; } std::string backup_file_format; conf_get_string(props, "backup-file-format", backup_file_format); if (!strcasecmp(backup_file_format.c_str(), "redis")) { backup_redis_format = true; } conf_get_string(props, "zookeeper-servers", zookeeper_servers); conf_get_string(props, "zk-clientid-file", zk_clientid_file); conf_get_string(props, "loglevel", loglevel); conf_get_string(props, "logfile", logfile); conf_get_bool(props, "daemonize", daemonize); conf_get_int64(props, "repl-backlog-size", repl_backlog_size); conf_get_int64(props, "repl-backlog-cache-size", repl_backlog_cache_size); conf_get_int64(props, "repl-ping-slave-period", repl_ping_slave_period); conf_get_int64(props, "repl-timeout", repl_timeout); conf_get_int64(props, "repl-backlog-sync-period", repl_backlog_sync_period); conf_get_int64(props, "repl-backlog-ttl", repl_backlog_time_limit); conf_get_int64(props, "min-slaves-to-write", repl_min_slaves_to_write); conf_get_int64(props, "min-slaves-max-lag", repl_min_slaves_max_lag); conf_get_bool(props, "slave-serve-stale-data", repl_serve_stale_data); conf_get_int64(props, "max-slave-worker-queue", max_slave_worker_queue); if(max_slave_worker_queue <= 0) { max_slave_worker_queue = 1024; } conf_get_bool(props, "repl-disable-tcp-nodelay", repl_disable_tcp_nodelay); conf_get_int64(props, "lua-time-limit", lua_time_limit); conf_get_int64(props, "snapshot-max-lag-offset", snapshot_max_lag_offset); conf_get_int64(props, "maxsnapshots", maxsnapshots); if(maxsnapshots == 0) { maxsnapshots = 1; } if (snapshot_max_lag_offset > repl_backlog_size / 2) { snapshot_max_lag_offset = repl_backlog_size / 2; } conf_get_int64(props, "hll-sparse-max-bytes", hll_sparse_max_bytes); conf_get_bool(props, "slave-read-only", slave_readonly); conf_get_bool(props, "slave-serve-stale-data", slave_serve_stale_data); conf_get_int64(props, "slave-priority", slave_priority); conf_get_bool(props, "slave-ignore-expire", slave_ignore_expire); conf_get_bool(props, "slave-ignore-del", slave_ignore_del); conf_get_bool(props, "slave-cleardb-before-fullresync", slave_cleardb_before_fullresync); conf_get_int64(props, "statistics-log-period", statistics_log_period); if (statistics_log_period <= 0) { statistics_log_period = DEFAULT_STAT_LOG_PERIOD_SECS; } std::string slaveof; if (conf_get_string(props, "slaveof", slaveof)) { std::vector<std::string> ss = split_string(slaveof, ":"); if (ss.size() == 2) { master_host = ss[0]; if (!string_touint32(ss[1], master_port)) { master_host = ""; WARN_LOG("Invalid 'slaveof' config."); } } else { WARN_LOG("Invalid 'slaveof' config."); } } conf_get_string(props, "masterauth", masterauth); if (data_base_path.empty()) { data_base_path = "."; } make_dir(data_base_path); err = real_path(data_base_path, data_base_path); if (0 != err) { ERROR_LOG("Invalid 'data-dir' config:%s for reason:%s", data_base_path.c_str(), strerror(err)); return false; } conf_get_string(props, "requirepass", requirepass); Properties::const_iterator fit = props.find("rename-command"); if (fit != props.end()) { rename_commands.clear(); const ConfItemsArray& cs = fit->second; ConfItemsArray::const_iterator cit = cs.begin(); while (cit != cs.end()) { if (cit->size() != 2) { ERROR_LOG("Invalid 'rename-command' config with %u args.", cit->size()); } else { rename_commands[cit->at(0)] = cit->at(1); } cit++; } } conf_get_int64(props, "reply-pool-size", reply_pool_size); conf_get_int64(props, "slave-client-output-buffer-limit", slave_client_output_buffer_limit); conf_get_int64(props, "pubsub-client-output-buffer-limit", pubsub_client_output_buffer_limit); conf_get_string(props, "redis-compatible-version", redis_compatible_version); conf_get_bool(props, "redis-compatible-mode", redis_compatible); conf_get_bool(props, "compact-after-snapshot-load", compact_after_snapshot_load); conf_get_int64(props, "qps-limit-per-host", qps_limit_per_host); conf_get_int64(props, "qps-limit-per-connection", qps_limit_per_connection); conf_get_int64(props, "range-delete-min-size", range_delete_min_size); conf_get_int64(props, "stream-lru-cache-size", stream_lru_cache_size); //trusted_ip.clear(); Properties::const_iterator ip_it = props.find("trusted-ip"); if (ip_it != props.end()) { const ConfItemsArray& cs = ip_it->second; for (uint32 i = 0; i < cs.size(); i++) { //trusted_ip.insert(cs[i][0]); } } if (!verify_config(*this)) { return false; } ArdbLogger::SetLogLevel(loglevel); return true; }
int validate_worktree(const struct worktree *wt, struct strbuf *errmsg, unsigned flags) { struct strbuf wt_path = STRBUF_INIT; char *path = NULL; int err, ret = -1; strbuf_addf(&wt_path, "%s/.git", wt->path); if (is_main_worktree(wt)) { if (is_directory(wt_path.buf)) { ret = 0; goto done; } /* * Main worktree using .git file to point to the * repository would make it impossible to know where * the actual worktree is if this function is executed * from another worktree. No .git file support for now. */ strbuf_addf_gently(errmsg, _("'%s' at main working tree is not the repository directory"), wt_path.buf); goto done; } /* * Make sure "gitdir" file points to a real .git file and that * file points back here. */ if (!is_absolute_path(wt->path)) { strbuf_addf_gently(errmsg, _("'%s' file does not contain absolute path to the working tree location"), git_common_path("worktrees/%s/gitdir", wt->id)); goto done; } if (flags & WT_VALIDATE_WORKTREE_MISSING_OK && !file_exists(wt->path)) { ret = 0; goto done; } if (!file_exists(wt_path.buf)) { strbuf_addf_gently(errmsg, _("'%s' does not exist"), wt_path.buf); goto done; } path = xstrdup_or_null(read_gitfile_gently(wt_path.buf, &err)); if (!path) { strbuf_addf_gently(errmsg, _("'%s' is not a .git file, error code %d"), wt_path.buf, err); goto done; } ret = fspathcmp(path, real_path(git_common_path("worktrees/%s", wt->id))); if (ret) strbuf_addf_gently(errmsg, _("'%s' does not point back to '%s'"), wt->path, git_common_path("worktrees/%s", wt->id)); done: free(path); strbuf_release(&wt_path); return ret; }
int cmd_clone(int argc, const char **argv, const char *prefix) { int is_bundle = 0, is_local; struct stat buf; const char *repo_name, *repo, *work_tree, *git_dir; char *path, *dir; int dest_exists; const struct ref *refs, *remote_head; const struct ref *remote_head_points_at; const struct ref *our_head_points_at; struct ref *mapped_refs; struct strbuf key = STRBUF_INIT, value = STRBUF_INIT; struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT; struct transport *transport = NULL; char *src_ref_prefix = "refs/heads/"; int err = 0; struct refspec *refspec; const char *fetch_pattern; junk_pid = getpid(); argc = parse_options(argc, argv, prefix, builtin_clone_options, builtin_clone_usage, 0); if (argc > 2) usage_msg_opt("Too many arguments.", builtin_clone_usage, builtin_clone_options); if (argc == 0) usage_msg_opt("You must specify a repository to clone.", builtin_clone_usage, builtin_clone_options); if (option_mirror) option_bare = 1; if (option_bare) { if (option_origin) die("--bare and --origin %s options are incompatible.", option_origin); option_no_checkout = 1; } if (!option_origin) option_origin = "origin"; repo_name = argv[0]; path = get_repo_path(repo_name, &is_bundle); if (path) repo = xstrdup(absolute_path(repo_name)); else if (!strchr(repo_name, ':')) die("repository '%s' does not exist", repo_name); else repo = repo_name; is_local = path && !is_bundle; if (is_local && option_depth) warning("--depth is ignored in local clones; use file:// instead."); if (argc == 2) dir = xstrdup(argv[1]); else dir = guess_dir_name(repo_name, is_bundle, option_bare); strip_trailing_slashes(dir); dest_exists = !stat(dir, &buf); if (dest_exists && !is_empty_dir(dir)) die("destination path '%s' already exists and is not " "an empty directory.", dir); strbuf_addf(&reflog_msg, "clone: from %s", repo); if (option_bare) work_tree = NULL; else { work_tree = getenv("GIT_WORK_TREE"); if (work_tree && !stat(work_tree, &buf)) die("working tree '%s' already exists.", work_tree); } if (option_bare || work_tree) git_dir = xstrdup(dir); else { work_tree = dir; git_dir = xstrdup(mkpath("%s/.git", dir)); } if (!option_bare) { junk_work_tree = work_tree; if (safe_create_leading_directories_const(work_tree) < 0) die_errno("could not create leading directories of '%s'", work_tree); if (!dest_exists && mkdir(work_tree, 0755)) die_errno("could not create work tree dir '%s'.", work_tree); set_git_work_tree(work_tree); } junk_git_dir = git_dir; atexit(remove_junk); sigchain_push_common(remove_junk_on_signal); setenv(CONFIG_ENVIRONMENT, mkpath("%s/config", git_dir), 1); if (safe_create_leading_directories_const(git_dir) < 0) die("could not create leading directories of '%s'", git_dir); set_git_dir(real_path(git_dir)); if (0 <= option_verbosity) printf("Cloning into %s%s...\n", option_bare ? "bare repository " : "", dir); init_db(option_template, INIT_DB_QUIET); /* * At this point, the config exists, so we do not need the * environment variable. We actually need to unset it, too, to * re-enable parsing of the global configs. */ unsetenv(CONFIG_ENVIRONMENT); git_config(git_default_config, NULL); if (option_bare) { if (option_mirror) src_ref_prefix = "refs/"; strbuf_addstr(&branch_top, src_ref_prefix); git_config_set("core.bare", "true"); } else { strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin); } strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf); if (option_mirror || !option_bare) { /* Configure the remote */ strbuf_addf(&key, "remote.%s.fetch", option_origin); git_config_set_multivar(key.buf, value.buf, "^$", 0); strbuf_reset(&key); if (option_mirror) { strbuf_addf(&key, "remote.%s.mirror", option_origin); git_config_set(key.buf, "true"); strbuf_reset(&key); } } strbuf_addf(&key, "remote.%s.url", option_origin); git_config_set(key.buf, repo); strbuf_reset(&key); if (option_reference) setup_reference(git_dir); fetch_pattern = value.buf; refspec = parse_fetch_refspec(1, &fetch_pattern); strbuf_reset(&value); if (is_local) { refs = clone_local(path, git_dir); mapped_refs = wanted_peer_refs(refs, refspec); } else { struct remote *remote = remote_get(option_origin); transport = transport_get(remote, remote->url[0]); if (!transport->get_refs_list || !transport->fetch) die("Don't know how to clone %s", transport->url); transport_set_option(transport, TRANS_OPT_KEEP, "yes"); if (option_depth) transport_set_option(transport, TRANS_OPT_DEPTH, option_depth); transport_set_verbosity(transport, option_verbosity, option_progress); if (option_upload_pack) transport_set_option(transport, TRANS_OPT_UPLOADPACK, option_upload_pack); refs = transport_get_remote_refs(transport); if (refs) { mapped_refs = wanted_peer_refs(refs, refspec); transport_fetch_refs(transport, mapped_refs); } } if (refs) { clear_extra_refs(); write_remote_refs(mapped_refs); remote_head = find_ref_by_name(refs, "HEAD"); remote_head_points_at = guess_remote_head(remote_head, mapped_refs, 0); if (option_branch) { struct strbuf head = STRBUF_INIT; strbuf_addstr(&head, src_ref_prefix); strbuf_addstr(&head, option_branch); our_head_points_at = find_ref_by_name(mapped_refs, head.buf); strbuf_release(&head); if (!our_head_points_at) { warning("Remote branch %s not found in " "upstream %s, using HEAD instead", option_branch, option_origin); our_head_points_at = remote_head_points_at; } } else our_head_points_at = remote_head_points_at; } else { warning("You appear to have cloned an empty repository."); our_head_points_at = NULL; remote_head_points_at = NULL; remote_head = NULL; option_no_checkout = 1; if (!option_bare) install_branch_config(0, "master", option_origin, "refs/heads/master"); } if (remote_head_points_at && !option_bare) { struct strbuf head_ref = STRBUF_INIT; strbuf_addstr(&head_ref, branch_top.buf); strbuf_addstr(&head_ref, "HEAD"); create_symref(head_ref.buf, remote_head_points_at->peer_ref->name, reflog_msg.buf); } if (our_head_points_at) { /* Local default branch link */ create_symref("HEAD", our_head_points_at->name, NULL); if (!option_bare) { const char *head = skip_prefix(our_head_points_at->name, "refs/heads/"); update_ref(reflog_msg.buf, "HEAD", our_head_points_at->old_sha1, NULL, 0, DIE_ON_ERR); install_branch_config(0, head, option_origin, our_head_points_at->name); } } else if (remote_head) { /* Source had detached HEAD pointing somewhere. */ if (!option_bare) { update_ref(reflog_msg.buf, "HEAD", remote_head->old_sha1, NULL, REF_NODEREF, DIE_ON_ERR); our_head_points_at = remote_head; } } else { /* Nothing to checkout out */ if (!option_no_checkout) warning("remote HEAD refers to nonexistent ref, " "unable to checkout.\n"); option_no_checkout = 1; } if (transport) { transport_unlock_pack(transport); transport_disconnect(transport); } if (!option_no_checkout) { struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); struct unpack_trees_options opts; struct tree *tree; struct tree_desc t; int fd; /* We need to be in the new work tree for the checkout */ setup_work_tree(); fd = hold_locked_index(lock_file, 1); memset(&opts, 0, sizeof opts); opts.update = 1; opts.merge = 1; opts.fn = oneway_merge; opts.verbose_update = (option_verbosity > 0); opts.src_index = &the_index; opts.dst_index = &the_index; tree = parse_tree_indirect(our_head_points_at->old_sha1); parse_tree(tree); init_tree_desc(&t, tree->buffer, tree->size); unpack_trees(1, &t, &opts); if (write_cache(fd, active_cache, active_nr) || commit_locked_index(lock_file)) die("unable to write new index file"); err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1), sha1_to_hex(our_head_points_at->old_sha1), "1", NULL); if (!err && option_recursive) err = run_command_v_opt(argv_submodule, RUN_GIT_CMD); } strbuf_release(&reflog_msg); strbuf_release(&branch_top); strbuf_release(&key); strbuf_release(&value); junk_pid = 0; return err; }
static int add_worktree(const char *path, const char *refname, const struct add_opts *opts) { struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT; struct strbuf sb = STRBUF_INIT; const char *name; struct stat st; struct child_process cp = CHILD_PROCESS_INIT; struct argv_array child_env = ARGV_ARRAY_INIT; int counter = 0, len, ret; struct strbuf symref = STRBUF_INIT; struct commit *commit = NULL; int is_branch = 0; if (file_exists(path) && !is_empty_dir(path)) die(_("'%s' already exists"), path); /* is 'refname' a branch or commit? */ if (!opts->detach && !strbuf_check_branch_ref(&symref, refname) && ref_exists(symref.buf)) { is_branch = 1; if (!opts->force) die_if_checked_out(symref.buf, 0); } commit = lookup_commit_reference_by_name(refname); if (!commit) die(_("invalid reference: %s"), refname); name = worktree_basename(path, &len); git_path_buf(&sb_repo, "worktrees/%.*s", (int)(path + len - name), name); len = sb_repo.len; if (safe_create_leading_directories_const(sb_repo.buf)) die_errno(_("could not create leading directories of '%s'"), sb_repo.buf); while (!stat(sb_repo.buf, &st)) { counter++; strbuf_setlen(&sb_repo, len); strbuf_addf(&sb_repo, "%d", counter); } name = strrchr(sb_repo.buf, '/') + 1; junk_pid = getpid(); atexit(remove_junk); sigchain_push_common(remove_junk_on_signal); if (mkdir(sb_repo.buf, 0777)) die_errno(_("could not create directory of '%s'"), sb_repo.buf); junk_git_dir = xstrdup(sb_repo.buf); is_junk = 1; /* * lock the incomplete repo so prune won't delete it, unlock * after the preparation is over. */ strbuf_addf(&sb, "%s/locked", sb_repo.buf); if (!opts->keep_locked) write_file(sb.buf, "initializing"); else write_file(sb.buf, "added with --lock"); strbuf_addf(&sb_git, "%s/.git", path); if (safe_create_leading_directories_const(sb_git.buf)) die_errno(_("could not create leading directories of '%s'"), sb_git.buf); junk_work_tree = xstrdup(path); strbuf_reset(&sb); strbuf_addf(&sb, "%s/gitdir", sb_repo.buf); write_file(sb.buf, "%s", real_path(sb_git.buf)); write_file(sb_git.buf, "gitdir: %s/worktrees/%s", real_path(get_git_common_dir()), name); /* * This is to keep resolve_ref() happy. We need a valid HEAD * or is_git_directory() will reject the directory. Any value which * looks like an object ID will do since it will be immediately * replaced by the symbolic-ref or update-ref invocation in the new * worktree. */ strbuf_reset(&sb); strbuf_addf(&sb, "%s/HEAD", sb_repo.buf); write_file(sb.buf, "%s", sha1_to_hex(null_sha1)); strbuf_reset(&sb); strbuf_addf(&sb, "%s/commondir", sb_repo.buf); write_file(sb.buf, "../.."); fprintf_ln(stderr, _("Preparing %s (identifier %s)"), path, name); argv_array_pushf(&child_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf); argv_array_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path); cp.git_cmd = 1; if (!is_branch) argv_array_pushl(&cp.args, "update-ref", "HEAD", oid_to_hex(&commit->object.oid), NULL); else argv_array_pushl(&cp.args, "symbolic-ref", "HEAD", symref.buf, NULL); cp.env = child_env.argv; ret = run_command(&cp); if (ret) goto done; if (opts->checkout) { cp.argv = NULL; argv_array_clear(&cp.args); argv_array_pushl(&cp.args, "reset", "--hard", NULL); cp.env = child_env.argv; ret = run_command(&cp); if (ret) goto done; } is_junk = 0; FREE_AND_NULL(junk_work_tree); FREE_AND_NULL(junk_git_dir); done: if (ret || !opts->keep_locked) { strbuf_reset(&sb); strbuf_addf(&sb, "%s/locked", sb_repo.buf); unlink_or_warn(sb.buf); } /* * Hook failure does not warrant worktree deletion, so run hook after * is_junk is cleared, but do return appropriate code when hook fails. */ if (!ret && opts->checkout) { const char *hook = find_hook("post-checkout"); if (hook) { const char *env[] = { "GIT_DIR", "GIT_WORK_TREE", NULL }; cp.git_cmd = 0; cp.no_stdin = 1; cp.stdout_to_stderr = 1; cp.dir = path; cp.env = env; cp.argv = NULL; argv_array_pushl(&cp.args, absolute_path(hook), oid_to_hex(&null_oid), oid_to_hex(&commit->object.oid), "1", NULL); ret = run_command(&cp); } } argv_array_clear(&child_env); strbuf_release(&sb); strbuf_release(&symref); strbuf_release(&sb_repo); strbuf_release(&sb_git); return ret; }
int main(int argc, char **argv) { if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) { char *buf = xmalloc(PATH_MAX + 1); int rv = normalize_path_copy(buf, argv[2]); if (rv) buf = "++failed++"; puts(buf); return 0; } if (argc >= 2 && !strcmp(argv[1], "real_path")) { while (argc > 2) { puts(real_path(argv[2])); argc--; argv++; } return 0; } if (argc >= 2 && !strcmp(argv[1], "absolute_path")) { while (argc > 2) { puts(absolute_path(argv[2])); argc--; argv++; } return 0; } if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) { int len; struct string_list ceiling_dirs = STRING_LIST_INIT_DUP; char *path = xstrdup(argv[2]); /* * We have to normalize the arguments because under * Windows, bash mangles arguments that look like * absolute POSIX paths or colon-separate lists of * absolute POSIX paths into DOS paths (e.g., * "/foo:/foo/bar" might be converted to * "D:\Src\msysgit\foo;D:\Src\msysgit\foo\bar"), * whereas longest_ancestor_length() requires paths * that use forward slashes. */ if (normalize_path_copy(path, path)) die("Path \"%s\" could not be normalized", argv[2]); string_list_split(&ceiling_dirs, argv[3], PATH_SEP, -1); filter_string_list(&ceiling_dirs, 0, normalize_ceiling_entry, NULL); len = longest_ancestor_length(path, &ceiling_dirs); string_list_clear(&ceiling_dirs, 0); free(path); printf("%d\n", len); return 0; } if (argc >= 4 && !strcmp(argv[1], "prefix_path")) { char *prefix = argv[2]; int prefix_len = strlen(prefix); int nongit_ok; setup_git_directory_gently(&nongit_ok); while (argc > 3) { puts(prefix_path(prefix, prefix_len, argv[3])); argc--; argv++; } return 0; } if (argc == 4 && !strcmp(argv[1], "strip_path_suffix")) { char *prefix = strip_path_suffix(argv[2], argv[3]); printf("%s\n", prefix ? prefix : "(null)"); return 0; } if (argc == 3 && !strcmp(argv[1], "mingw_path")) { puts(argv[2]); return 0; } if (argc == 4 && !strcmp(argv[1], "relative_path")) { struct strbuf sb = STRBUF_INIT; const char *in, *prefix, *rel; normalize_argv_string(&in, argv[2]); normalize_argv_string(&prefix, argv[3]); rel = relative_path(in, prefix, &sb); if (!rel) puts("(null)"); else puts(strlen(rel) > 0 ? rel : "(empty)"); strbuf_release(&sb); return 0; } fprintf(stderr, "%s: unknown function name: %s\n", argv[0], argv[1] ? argv[1] : "(there was none)"); return 1; }
bool ArdbConfig::Parse(const Properties& props) { conf_props = props; conf_get_string(props, "home", home); if (home.empty()) { home = "../ardb"; } make_dir(home); int err = real_path(home, home); if (0 != err) { ERROR_LOG("Invalid 'home' config:%s for reason:%s", home.c_str(), strerror(err)); return false; } err = access(home.c_str(), R_OK | W_OK); if (0 != err) { err = errno; ERROR_LOG("Invalid 'home' config:%s for reason:%s", home.c_str(), strerror(err)); return false; } setenv("ARDB_HOME", home.c_str(), 1); replace_env_var(const_cast<Properties&>(props)); conf_get_string(props, "pidfile", pidfile); conf_get_int64(props, "tcp-keepalive", tcp_keepalive); conf_get_int64(props, "timeout", timeout); conf_get_int64(props, "unixsocketperm", unixsocketperm); conf_get_int64(props, "slowlog-log-slower-than", slowlog_log_slower_than); conf_get_int64(props, "slowlog-max-len", slowlog_max_len); conf_get_int64(props, "maxclients", max_clients); Properties::const_iterator listen_it = props.find("listen"); if (listen_it != props.end()) { const ConfItemsArray& cs = listen_it->second; for (uint32 i = 0; i < cs.size(); i++) { if (cs[i].size() != 1) { WARN_LOG("Invalid config 'listen'"); } else { const std::string& str = cs[i][0]; listen_addresses.push_back(str); } } } if (listen_addresses.empty()) { listen_addresses.push_back("0.0.0.0:16379"); } Properties::const_iterator tp_it = props.find("thread-pool-size"); if (tp_it != props.end()) { const ConfItemsArray& cs = tp_it->second; for (uint32 i = 0; i < cs.size(); i++) { uint32 size = 0; if (cs[i].size() != 1 || !string_touint32(cs[i][0], size)) { WARN_LOG("Invalid config 'thread-pool-size'"); } else { thread_pool_sizes.push_back((int64) size); } } } Properties::const_iterator qp_it = props.find("qps-limit"); if (qp_it != props.end()) { const ConfItemsArray& cs = qp_it->second; for (uint32 i = 0; i < cs.size(); i++) { uint32 limit = 0; if (cs[i].size() != 1 || !string_touint32(cs[i][0], limit)) { WARN_LOG("Invalid config 'qps-limit'"); } else { qps_limits.push_back((int64) limit); } } } thread_pool_sizes.resize(listen_addresses.size()); qps_limits.resize(listen_addresses.size()); conf_get_string(props, "data-dir", data_base_path); conf_get_string(props, "backup-dir", backup_dir); conf_get_string(props, "repl-dir", repl_data_dir); make_dir(repl_data_dir); make_dir(backup_dir); err = real_path(repl_data_dir, repl_data_dir); if (0 != err) { ERROR_LOG("Invalid 'repl-dir' config:%s for reason:%s", repl_data_dir.c_str(), strerror(err)); return false; } std::string backup_file_format; conf_get_string(props, "backup-file-format", backup_file_format); if (!strcasecmp(backup_file_format.c_str(), "redis")) { backup_redis_format = true; } conf_get_string(props, "zookeeper-servers", zookeeper_servers); conf_get_string(props, "loglevel", loglevel); conf_get_string(props, "logfile", logfile); conf_get_bool(props, "daemonize", daemonize); conf_get_int64(props, "repl-backlog-size", repl_backlog_size); conf_get_int64(props, "repl-ping-slave-period", repl_ping_slave_period); conf_get_int64(props, "repl-timeout", repl_timeout); conf_get_int64(props, "repl-state-persist-period", repl_state_persist_period); conf_get_int64(props, "repl-backlog-ttl", repl_backlog_time_limit); conf_get_bool(props, "repl-disable-tcp-nodelay", repl_disable_tcp_nodelay); conf_get_int64(props, "lua-time-limit", lua_time_limit); conf_get_int64(props, "hash-max-ziplist-entries", hash_max_ziplist_entries); conf_get_int64(props, "hash_max-ziplist-value", hash_max_ziplist_value); conf_get_int64(props, "set-max-ziplist-entries", set_max_ziplist_entries); conf_get_int64(props, "set-max-ziplist-value", set_max_ziplist_value); conf_get_int64(props, "list-max-ziplist-entries", list_max_ziplist_entries); conf_get_int64(props, "list-max-ziplist-value", list_max_ziplist_value); conf_get_int64(props, "zset-max-ziplist-entries", zset_max_ziplist_entries); conf_get_int64(props, "zset_max_ziplist_value", zset_max_ziplist_value); conf_get_int64(props, "L1-zset-max-cache-size", L1_zset_max_cache_size); conf_get_int64(props, "L1-set-max-cache-size", L1_set_max_cache_size); conf_get_int64(props, "L1-hash-max-cache-size", L1_hash_max_cache_size); conf_get_int64(props, "L1-list-max-cache-size", L1_list_max_cache_size); conf_get_int64(props, "L1-string-max-cache-size", L1_string_max_cache_size); conf_get_bool(props, "L1-zset-read-fill-cache", L1_zset_read_fill_cache); conf_get_bool(props, "L1-zset-seek-load-cache", L1_zset_seek_load_cache); conf_get_bool(props, "L1-set-read-fill-cache", L1_set_read_fill_cache); conf_get_bool(props, "L1-set-seek-load-cache", L1_set_seek_load_cache); conf_get_bool(props, "L1-hash-read-fill-cache", L1_hash_read_fill_cache); conf_get_bool(props, "L1-hash-seek-load-cache", L1_hash_seek_load_cache); conf_get_bool(props, "L1-list-read-fill-cache", L1_list_read_fill_cache); conf_get_bool(props, "L1-list-seek-load-cache", L1_list_seek_load_cache); conf_get_bool(props, "L1-string-read-fill-cache", L1_string_read_fill_cache); conf_get_int64(props, "hll-sparse-max-bytes", hll_sparse_max_bytes); conf_get_bool(props, "slave-read-only", slave_readonly); conf_get_bool(props, "slave-serve-stale-data", slave_serve_stale_data); conf_get_int64(props, "slave-priority", slave_priority); conf_get_bool(props, "slave-ignore-expire", slave_ignore_expire); conf_get_bool(props, "slave-ignore-del", slave_ignore_del); std::string slaveof; if (conf_get_string(props, "slaveof", slaveof)) { std::vector<std::string> ss = split_string(slaveof, ":"); if (ss.size() == 2) { master_host = ss[0]; if (!string_touint32(ss[1], master_port)) { master_host = ""; WARN_LOG("Invalid 'slaveof' config."); } } else { WARN_LOG("Invalid 'slaveof' config."); } } std::string include_dbs, exclude_dbs; repl_includes.clear(); repl_excludes.clear(); conf_get_string(props, "replicate-include-db", include_dbs); conf_get_string(props, "replicate-exclude-db", exclude_dbs); if (0 != split_uint32_array(include_dbs, "|", repl_includes)) { ERROR_LOG("Invalid 'replicate-include-db' config."); repl_includes.clear(); } if (0 != split_uint32_array(exclude_dbs, "|", repl_excludes)) { ERROR_LOG("Invalid 'replicate-exclude-db' config."); repl_excludes.clear(); } if (data_base_path.empty()) { data_base_path = "."; } make_dir(data_base_path); err = real_path(data_base_path, data_base_path); if (0 != err) { ERROR_LOG("Invalid 'data-dir' config:%s for reason:%s", data_base_path.c_str(), strerror(err)); return false; } conf_get_string(props, "additional-misc-info", additional_misc_info); conf_get_string(props, "requirepass", requirepass); Properties::const_iterator fit = props.find("rename-command"); if (fit != props.end()) { rename_commands.clear(); StringSet newcmdset; const ConfItemsArray& cs = fit->second; ConfItemsArray::const_iterator cit = cs.begin(); while (cit != cs.end()) { if (cit->size() != 2 || newcmdset.count(cit->at(1)) > 0) { ERROR_LOG("Invalid 'rename-command' config."); } else { rename_commands[cit->at(0)] = cit->at(1); newcmdset.insert(cit->at(1)); } cit++; } } conf_get_int64(props, "compact-min-interval", compact_min_interval); conf_get_int64(props, "compact-max-interval", compact_max_interval); conf_get_int64(props, "compact-after-write", compact_trigger_write_count); conf_get_bool(props, "compact-enable", compact_enable); conf_get_int64(props, "reply-pool-size", reply_pool_size); conf_get_bool(props, "replace-all-for-multi-sadd", replace_for_multi_sadd); conf_get_bool(props, "replace-all-for-hmset", replace_for_hmset); conf_get_int64(props, "slave-client-output-buffer-limit", slave_client_output_buffer_limit); conf_get_int64(props, "pubsub-client-output-buffer-limit", pubsub_client_output_buffer_limit); conf_get_bool(props, "scan-redis-compatible", scan_redis_compatible); conf_get_int64(props, "scan-cursor-expire-after", scan_cursor_expire_after); conf_get_int64(props, "max-string-bitset-value", max_string_bitset_value); conf_get_int64(props, "databases", maxdb); conf_get_bool(props, "lua-exec-atomic", lua_exec_atomic); trusted_ip.clear(); Properties::const_iterator ip_it = props.find("trusted-ip"); if (ip_it != props.end()) { const ConfItemsArray& cs = ip_it->second; for (uint32 i = 0; i < cs.size(); i++) { trusted_ip.insert(cs[i][0]); } } if (!verify_config(*this)) { return false; } ArdbLogger::SetLogLevel(loglevel); return true; }
int cmd_rev_parse(int argc, const char **argv, const char *prefix) { int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0; int did_repo_setup = 0; int has_dashdash = 0; int output_prefix = 0; struct object_id oid; unsigned int flags = 0; const char *name = NULL; struct object_context unused; struct strbuf buf = STRBUF_INIT; if (argc > 1 && !strcmp("--parseopt", argv[1])) return cmd_parseopt(argc - 1, argv + 1, prefix); if (argc > 1 && !strcmp("--sq-quote", argv[1])) return cmd_sq_quote(argc - 2, argv + 2); if (argc > 1 && !strcmp("-h", argv[1])) usage(builtin_rev_parse_usage); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "--")) { has_dashdash = 1; break; } } /* No options; just report on whether we're in a git repo or not. */ if (argc == 1) { setup_git_directory(); git_config(git_default_config, NULL); return 0; } for (i = 1; i < argc; i++) { const char *arg = argv[i]; if (!strcmp(arg, "--local-env-vars")) { int i; for (i = 0; local_repo_env[i]; i++) printf("%s\n", local_repo_env[i]); continue; } if (!strcmp(arg, "--resolve-git-dir")) { const char *gitdir = argv[++i]; if (!gitdir) die("--resolve-git-dir requires an argument"); gitdir = resolve_gitdir(gitdir); if (!gitdir) die("not a gitdir '%s'", argv[i]); puts(gitdir); continue; } /* The rest of the options require a git repository. */ if (!did_repo_setup) { prefix = setup_git_directory(); git_config(git_default_config, NULL); did_repo_setup = 1; } if (!strcmp(arg, "--git-path")) { if (!argv[i + 1]) die("--git-path requires an argument"); strbuf_reset(&buf); puts(relative_path(git_path("%s", argv[i + 1]), prefix, &buf)); i++; continue; } if (as_is) { if (show_file(arg, output_prefix) && as_is < 2) verify_filename(prefix, arg, 0); continue; } if (!strcmp(arg,"-n")) { if (++i >= argc) die("-n requires an argument"); if ((filter & DO_FLAGS) && (filter & DO_REVS)) { show(arg); show(argv[i]); } continue; } if (starts_with(arg, "-n")) { if ((filter & DO_FLAGS) && (filter & DO_REVS)) show(arg); continue; } if (*arg == '-') { if (!strcmp(arg, "--")) { as_is = 2; /* Pass on the "--" if we show anything but files.. */ if (filter & (DO_FLAGS | DO_REVS)) show_file(arg, 0); continue; } if (!strcmp(arg, "--default")) { def = argv[++i]; if (!def) die("--default requires an argument"); continue; } if (!strcmp(arg, "--prefix")) { prefix = argv[++i]; if (!prefix) die("--prefix requires an argument"); startup_info->prefix = prefix; output_prefix = 1; continue; } if (!strcmp(arg, "--revs-only")) { filter &= ~DO_NOREV; continue; } if (!strcmp(arg, "--no-revs")) { filter &= ~DO_REVS; continue; } if (!strcmp(arg, "--flags")) { filter &= ~DO_NONFLAGS; continue; } if (!strcmp(arg, "--no-flags")) { filter &= ~DO_FLAGS; continue; } if (!strcmp(arg, "--verify")) { filter &= ~(DO_FLAGS|DO_NOREV); verify = 1; continue; } if (!strcmp(arg, "--quiet") || !strcmp(arg, "-q")) { quiet = 1; flags |= GET_OID_QUIETLY; continue; } if (opt_with_value(arg, "--short", &arg)) { filter &= ~(DO_FLAGS|DO_NOREV); verify = 1; abbrev = DEFAULT_ABBREV; if (!arg) continue; abbrev = strtoul(arg, NULL, 10); if (abbrev < MINIMUM_ABBREV) abbrev = MINIMUM_ABBREV; else if (40 <= abbrev) abbrev = 40; continue; } if (!strcmp(arg, "--sq")) { output_sq = 1; continue; } if (!strcmp(arg, "--not")) { show_type ^= REVERSED; continue; } if (!strcmp(arg, "--symbolic")) { symbolic = SHOW_SYMBOLIC_ASIS; continue; } if (!strcmp(arg, "--symbolic-full-name")) { symbolic = SHOW_SYMBOLIC_FULL; continue; } if (opt_with_value(arg, "--abbrev-ref", &arg)) { abbrev_ref = 1; abbrev_ref_strict = warn_ambiguous_refs; if (arg) { if (!strcmp(arg, "strict")) abbrev_ref_strict = 1; else if (!strcmp(arg, "loose")) abbrev_ref_strict = 0; else die("unknown mode for --abbrev-ref: %s", arg); } continue; } if (!strcmp(arg, "--all")) { for_each_ref(show_reference, NULL); continue; } if (skip_prefix(arg, "--disambiguate=", &arg)) { for_each_abbrev(arg, show_abbrev, NULL); continue; } if (!strcmp(arg, "--bisect")) { for_each_fullref_in("refs/bisect/bad", show_reference, NULL, 0); for_each_fullref_in("refs/bisect/good", anti_reference, NULL, 0); continue; } if (opt_with_value(arg, "--branches", &arg)) { handle_ref_opt(arg, "refs/heads/"); continue; } if (opt_with_value(arg, "--tags", &arg)) { handle_ref_opt(arg, "refs/tags/"); continue; } if (skip_prefix(arg, "--glob=", &arg)) { handle_ref_opt(arg, NULL); continue; } if (opt_with_value(arg, "--remotes", &arg)) { handle_ref_opt(arg, "refs/remotes/"); continue; } if (skip_prefix(arg, "--exclude=", &arg)) { add_ref_exclusion(&ref_excludes, arg); continue; } if (!strcmp(arg, "--show-toplevel")) { const char *work_tree = get_git_work_tree(); if (work_tree) puts(work_tree); continue; } if (!strcmp(arg, "--show-superproject-working-tree")) { const char *superproject = get_superproject_working_tree(); if (superproject) puts(superproject); continue; } if (!strcmp(arg, "--show-prefix")) { if (prefix) puts(prefix); else putchar('\n'); continue; } if (!strcmp(arg, "--show-cdup")) { const char *pfx = prefix; if (!is_inside_work_tree()) { const char *work_tree = get_git_work_tree(); if (work_tree) printf("%s\n", work_tree); continue; } while (pfx) { pfx = strchr(pfx, '/'); if (pfx) { pfx++; printf("../"); } } putchar('\n'); continue; } if (!strcmp(arg, "--git-dir") || !strcmp(arg, "--absolute-git-dir")) { const char *gitdir = getenv(GIT_DIR_ENVIRONMENT); char *cwd; int len; if (arg[2] == 'g') { /* --git-dir */ if (gitdir) { puts(gitdir); continue; } if (!prefix) { puts(".git"); continue; } } else { /* --absolute-git-dir */ if (!gitdir && !prefix) gitdir = ".git"; if (gitdir) { puts(real_path(gitdir)); continue; } } cwd = xgetcwd(); len = strlen(cwd); printf("%s%s.git\n", cwd, len && cwd[len-1] != '/' ? "/" : ""); free(cwd); continue; } if (!strcmp(arg, "--git-common-dir")) { strbuf_reset(&buf); puts(relative_path(get_git_common_dir(), prefix, &buf)); continue; } if (!strcmp(arg, "--is-inside-git-dir")) { printf("%s\n", is_inside_git_dir() ? "true" : "false"); continue; } if (!strcmp(arg, "--is-inside-work-tree")) { printf("%s\n", is_inside_work_tree() ? "true" : "false"); continue; } if (!strcmp(arg, "--is-bare-repository")) { printf("%s\n", is_bare_repository() ? "true" : "false"); continue; } if (!strcmp(arg, "--is-shallow-repository")) { printf("%s\n", is_repository_shallow() ? "true" : "false"); continue; } if (!strcmp(arg, "--shared-index-path")) { if (read_cache() < 0) die(_("Could not read the index")); if (the_index.split_index) { const unsigned char *sha1 = the_index.split_index->base_sha1; const char *path = git_path("sharedindex.%s", sha1_to_hex(sha1)); strbuf_reset(&buf); puts(relative_path(path, prefix, &buf)); } continue; } if (skip_prefix(arg, "--since=", &arg)) { show_datestring("--max-age=", arg); continue; } if (skip_prefix(arg, "--after=", &arg)) { show_datestring("--max-age=", arg); continue; } if (skip_prefix(arg, "--before=", &arg)) { show_datestring("--min-age=", arg); continue; } if (skip_prefix(arg, "--until=", &arg)) { show_datestring("--min-age=", arg); continue; } if (show_flag(arg) && verify) die_no_single_rev(quiet); continue; } /* Not a flag argument */ if (try_difference(arg)) continue; if (try_parent_shorthands(arg)) continue; name = arg; type = NORMAL; if (*arg == '^') { name++; type = REVERSED; } if (!get_oid_with_context(name, flags, &oid, &unused)) { if (verify) revs_count++; else show_rev(type, &oid, name); continue; } if (verify) die_no_single_rev(quiet); if (has_dashdash) die("bad revision '%s'", arg); as_is = 1; if (!show_file(arg, output_prefix)) continue; verify_filename(prefix, arg, 1); } strbuf_release(&buf); if (verify) { if (revs_count == 1) { show_rev(type, &oid, name); return 0; } else if (revs_count == 0 && show_default()) return 0; die_no_single_rev(quiet); } else show_default(); return 0; }
static const char *setup_explicit_git_dir(const char *gitdirenv, char *cwd, int len, int *nongit_ok) { const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT); const char *worktree; char *gitfile; if (PATH_MAX - 40 < strlen(gitdirenv)) die("'$%s' too big", GIT_DIR_ENVIRONMENT); gitfile = (char*)read_gitfile_gently(gitdirenv); if (gitfile) { gitfile = xstrdup(gitfile); gitdirenv = gitfile; } if (!is_git_directory(gitdirenv)) { if (nongit_ok) { *nongit_ok = 1; free(gitfile); return NULL; } die("Not a git repository: '%s'", gitdirenv); } if (check_repository_format_gently(gitdirenv, nongit_ok)) { free(gitfile); return NULL; } /* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */ if (work_tree_env) set_git_work_tree(work_tree_env); else if (is_bare_repository_cfg > 0) { if (git_work_tree_cfg) /* #22.2, #30 */ die("core.bare and core.worktree do not make sense"); /* #18, #26 */ set_git_dir(gitdirenv); free(gitfile); return NULL; } else if (git_work_tree_cfg) { /* #6, #14 */ if (is_absolute_path(git_work_tree_cfg)) set_git_work_tree(git_work_tree_cfg); else { char core_worktree[PATH_MAX]; if (chdir(gitdirenv)) die_errno("Could not chdir to '%s'", gitdirenv); if (chdir(git_work_tree_cfg)) die_errno("Could not chdir to '%s'", git_work_tree_cfg); if (!getcwd(core_worktree, PATH_MAX)) die_errno("Could not get directory '%s'", git_work_tree_cfg); if (chdir(cwd)) die_errno("Could not come back to cwd"); set_git_work_tree(core_worktree); } } else /* #2, #10 */ set_git_work_tree("."); /* set_git_work_tree() must have been called by now */ worktree = get_git_work_tree(); /* both get_git_work_tree() and cwd are already normalized */ if (!strcmp(cwd, worktree)) { /* cwd == worktree */ set_git_dir(gitdirenv); free(gitfile); return NULL; } if (!prefixcmp(cwd, worktree) && cwd[strlen(worktree)] == '/') { /* cwd inside worktree */ set_git_dir(real_path(gitdirenv)); if (chdir(worktree)) die_errno("Could not chdir to '%s'", worktree); cwd[len++] = '/'; cwd[len] = '\0'; free(gitfile); return cwd + strlen(worktree) + 1; } /* cwd outside worktree */ set_git_dir(gitdirenv); free(gitfile); return NULL; }