int main(int argc, char **argv) { if (argc == 5 && !strcmp(argv[1], "split")) { struct string_list list = STRING_LIST_INIT_DUP; int i; const char *s = argv[2]; int delim = *argv[3]; int maxsplit = atoi(argv[4]); i = string_list_split(&list, s, delim, maxsplit); printf("%d\n", i); write_list(&list); string_list_clear(&list, 0); return 0; } if (argc == 5 && !strcmp(argv[1], "split_in_place")) { struct string_list list = STRING_LIST_INIT_NODUP; int i; char *s = xstrdup(argv[2]); int delim = *argv[3]; int maxsplit = atoi(argv[4]); i = string_list_split_in_place(&list, s, delim, maxsplit); printf("%d\n", i); write_list(&list); string_list_clear(&list, 0); free(s); return 0; } if (argc == 4 && !strcmp(argv[1], "filter")) { /* * Retain only the items that have the specified prefix. * Arguments: list|- prefix */ struct string_list list = STRING_LIST_INIT_DUP; const char *prefix = argv[3]; parse_string_list(&list, argv[2]); filter_string_list(&list, 0, prefix_cb, (void *)prefix); write_list_compact(&list); string_list_clear(&list, 0); return 0; } if (argc == 3 && !strcmp(argv[1], "remove_duplicates")) { struct string_list list = STRING_LIST_INIT_DUP; parse_string_list(&list, argv[2]); string_list_remove_duplicates(&list, 0); write_list_compact(&list); string_list_clear(&list, 0); return 0; } fprintf(stderr, "%s: unknown function name: %s\n", argv[0], argv[1] ? argv[1] : "(there was none)"); return 1; }
static void filter_refs(struct fetch_pack_args *args, struct ref **refs, struct string_list *sought) { struct ref *newlist = NULL; struct ref **newtail = &newlist; struct ref *ref, *next; int sought_pos; sought_pos = 0; for (ref = *refs; ref; ref = next) { int keep = 0; next = ref->next; if (!memcmp(ref->name, "refs/", 5) && check_refname_format(ref->name + 5, 0)) ; /* trash */ else { while (sought_pos < sought->nr) { int cmp = strcmp(ref->name, sought->items[sought_pos].string); if (cmp < 0) break; /* definitely do not have it */ else if (cmp == 0) { keep = 1; /* definitely have it */ sought->items[sought_pos++].util = "matched"; break; } else sought_pos++; /* might have it; keep looking */ } } if (! keep && args->fetch_all && (!args->depth || prefixcmp(ref->name, "refs/tags/"))) keep = 1; if (keep) { *newtail = ref; ref->next = NULL; newtail = &ref->next; } else { free(ref); } } filter_string_list(sought, 0, non_matching_ref, NULL); *refs = newlist; }
/* * We cannot decide in this function whether we are in the work tree or * not, since the config can only be read _after_ this function was called. */ static const char *setup_git_directory_gently_1(int *nongit_ok) { const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT); struct string_list ceiling_dirs = STRING_LIST_INIT_DUP; static struct strbuf cwd = STRBUF_INIT; const char *gitdirenv, *ret; char *gitfile; int offset, offset_parent, ceil_offset = -1; dev_t current_device = 0; int one_filesystem = 1; /* * We may have read an incomplete configuration before * setting-up the git directory. If so, clear the cache so * that the next queries to the configuration reload complete * configuration (including the per-repo config file that we * ignored previously). */ git_config_clear(); /* * Let's assume that we are in a git repository. * If it turns out later that we are somewhere else, the value will be * updated accordingly. */ if (nongit_ok) *nongit_ok = 0; if (strbuf_getcwd(&cwd)) die_errno("Unable to read current working directory"); offset = cwd.len; /* * If GIT_DIR is set explicitly, we're not going * to do any discovery, but we still do repository * validation. */ gitdirenv = getenv(GIT_DIR_ENVIRONMENT); if (gitdirenv) return setup_explicit_git_dir(gitdirenv, &cwd, nongit_ok); if (env_ceiling_dirs) { int empty_entry_found = 0; string_list_split(&ceiling_dirs, env_ceiling_dirs, PATH_SEP, -1); filter_string_list(&ceiling_dirs, 0, canonicalize_ceiling_entry, &empty_entry_found); ceil_offset = longest_ancestor_length(cwd.buf, &ceiling_dirs); string_list_clear(&ceiling_dirs, 0); } if (ceil_offset < 0 && has_dos_drive_prefix(cwd.buf)) ceil_offset = 1; /* * Test in the following order (relative to the cwd): * - .git (file containing "gitdir: <path>") * - .git/ * - ./ (bare) * - ../.git * - ../.git/ * - ../ (bare) * - ../../.git/ * etc. */ one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0); if (one_filesystem) current_device = get_device_or_die(".", NULL, 0); for (;;) { gitfile = (char*)read_gitfile(DEFAULT_GIT_DIR_ENVIRONMENT); if (gitfile) gitdirenv = gitfile = xstrdup(gitfile); else { if (is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT)) gitdirenv = DEFAULT_GIT_DIR_ENVIRONMENT; } if (gitdirenv) { ret = setup_discovered_git_dir(gitdirenv, &cwd, offset, nongit_ok); free(gitfile); return ret; } free(gitfile); if (is_git_directory(".")) return setup_bare_git_dir(&cwd, offset, nongit_ok); offset_parent = offset; while (--offset_parent > ceil_offset && cwd.buf[offset_parent] != '/'); if (offset_parent <= ceil_offset) return setup_nongit(cwd.buf, nongit_ok); if (one_filesystem) { dev_t parent_device = get_device_or_die("..", cwd.buf, offset); if (parent_device != current_device) { if (nongit_ok) { if (chdir(cwd.buf)) die_errno("Cannot come back to cwd"); *nongit_ok = 1; return NULL; } strbuf_setlen(&cwd, offset); die("Not a git repository (or any parent up to mount point %s)\n" "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).", cwd.buf); } } if (chdir("..")) { strbuf_setlen(&cwd, offset); die_errno("Cannot change to '%s/..'", cwd.buf); } offset = offset_parent; } }
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; }
void string_list_remove_empty_items(struct string_list *list, int free_util) { filter_string_list(list, free_util, item_is_not_empty, NULL); }