/** * get the main worktree */ static struct worktree *get_main_worktree(void) { struct worktree *worktree = NULL; struct strbuf path = STRBUF_INIT; struct strbuf worktree_path = STRBUF_INIT; struct strbuf head_ref = STRBUF_INIT; int is_bare = 0; int is_detached = 0; strbuf_add_absolute_path(&worktree_path, get_git_common_dir()); is_bare = !strbuf_strip_suffix(&worktree_path, "/.git"); if (is_bare) strbuf_strip_suffix(&worktree_path, "/."); strbuf_addf(&path, "%s/HEAD", get_git_common_dir()); worktree = xcalloc(1, sizeof(*worktree)); worktree->path = strbuf_detach(&worktree_path, NULL); worktree->is_bare = is_bare; worktree->is_detached = is_detached; if (!parse_ref(path.buf, &head_ref, &is_detached)) add_head_info(&head_ref, worktree); strbuf_release(&path); strbuf_release(&worktree_path); strbuf_release(&head_ref); return worktree; }
static struct worktree *get_linked_worktree(const char *id) { struct worktree *worktree = NULL; struct strbuf path = STRBUF_INIT; struct strbuf worktree_path = STRBUF_INIT; if (!id) die("Missing linked worktree name"); strbuf_git_common_path(&path, the_repository, "worktrees/%s/gitdir", id); if (strbuf_read_file(&worktree_path, path.buf, 0) <= 0) /* invalid gitdir file */ goto done; strbuf_rtrim(&worktree_path); if (!strbuf_strip_suffix(&worktree_path, "/.git")) { strbuf_reset(&worktree_path); strbuf_add_absolute_path(&worktree_path, "."); strbuf_strip_suffix(&worktree_path, "/."); } strbuf_reset(&path); strbuf_addf(&path, "%s/worktrees/%s/HEAD", get_git_common_dir(), id); worktree = xcalloc(1, sizeof(*worktree)); worktree->path = strbuf_detach(&worktree_path, NULL); worktree->id = xstrdup(id); add_head_info(worktree); done: strbuf_release(&path); strbuf_release(&worktree_path); return worktree; }
static char *shell_prompt(const char *prompt, int echo) { const char *read_input[] = { /* Note: call 'bash' explicitly, as 'read -s' is bash-specific */ "bash", "-c", echo ? "test \"a$SHELL\" != \"a${SHELL%.exe}\" || exit 127; cat >/dev/tty &&" " read -r line </dev/tty && echo \"$line\"" : "test \"a$SHELL\" != \"a${SHELL%.exe}\" || exit 127; cat >/dev/tty &&" " read -r -s line </dev/tty && echo \"$line\" && echo >/dev/tty", NULL }; struct child_process child = CHILD_PROCESS_INIT; static struct strbuf buffer = STRBUF_INIT; int prompt_len = strlen(prompt), len = -1, code; child.argv = read_input; child.in = -1; child.out = -1; child.silent_exec_failure = 1; if (start_command(&child)) return NULL; if (write_in_full(child.in, prompt, prompt_len) != prompt_len) { error("could not write to prompt script"); close(child.in); goto ret; } close(child.in); strbuf_reset(&buffer); len = strbuf_read(&buffer, child.out, 1024); if (len < 0) { error("could not read from prompt script"); goto ret; } strbuf_strip_suffix(&buffer, "\n"); strbuf_strip_suffix(&buffer, "\r"); ret: close(child.out); code = finish_command(&child); if (code) { if (code != 127) error("failed to execute prompt script (exit code %d)", code); return NULL; } return len < 0 ? NULL : buffer.buf; }
static int refs_from_alternate_cb(struct alternate_object_database *e, void *data) { struct strbuf path = STRBUF_INIT; size_t base_len; struct alternate_refs_data *cb = data; if (!strbuf_realpath(&path, e->path, 0)) goto out; if (!strbuf_strip_suffix(&path, "/objects")) goto out; base_len = path.len; /* Is this a git repository with refs? */ strbuf_addstr(&path, "/refs"); if (!is_directory(path.buf)) goto out; strbuf_setlen(&path, base_len); read_alternate_refs(path.buf, cb->fn, cb->data); out: strbuf_release(&path); return 0; }
static struct worktree *get_linked_worktree(const char *id) { struct worktree *worktree = NULL; struct strbuf path = STRBUF_INIT; struct strbuf worktree_path = STRBUF_INIT; struct strbuf head_ref = STRBUF_INIT; int is_detached = 0; if (!id) die("Missing linked worktree name"); strbuf_git_common_path(&path, "worktrees/%s/gitdir", id); if (strbuf_read_file(&worktree_path, path.buf, 0) <= 0) /* invalid gitdir file */ goto done; strbuf_rtrim(&worktree_path); if (!strbuf_strip_suffix(&worktree_path, "/.git")) { strbuf_reset(&worktree_path); strbuf_add_absolute_path(&worktree_path, "."); strbuf_strip_suffix(&worktree_path, "/."); } strbuf_reset(&path); strbuf_addf(&path, "%s/worktrees/%s/HEAD", get_git_common_dir(), id); if (parse_ref(path.buf, &head_ref, &is_detached) < 0) goto done; worktree = xmalloc(sizeof(struct worktree)); worktree->path = strbuf_detach(&worktree_path, NULL); worktree->id = xstrdup(id); worktree->is_bare = 0; worktree->head_ref = NULL; worktree->is_detached = is_detached; worktree->is_current = 0; add_head_info(&head_ref, worktree); worktree->lock_reason = NULL; worktree->lock_reason_valid = 0; done: strbuf_release(&path); strbuf_release(&worktree_path); strbuf_release(&head_ref); return worktree; }
/** * get the main worktree */ static struct worktree *get_main_worktree(void) { struct worktree *worktree = NULL; struct strbuf path = STRBUF_INIT; struct strbuf worktree_path = STRBUF_INIT; struct strbuf head_ref = STRBUF_INIT; int is_bare = 0; int is_detached = 0; strbuf_add_absolute_path(&worktree_path, get_git_common_dir()); is_bare = !strbuf_strip_suffix(&worktree_path, "/.git"); if (is_bare) strbuf_strip_suffix(&worktree_path, "/."); strbuf_addf(&path, "%s/HEAD", get_git_common_dir()); if (parse_ref(path.buf, &head_ref, &is_detached) < 0) goto done; worktree = xmalloc(sizeof(struct worktree)); worktree->path = strbuf_detach(&worktree_path, NULL); worktree->id = NULL; worktree->is_bare = is_bare; worktree->head_ref = NULL; worktree->is_detached = is_detached; worktree->is_current = 0; add_head_info(&head_ref, worktree); worktree->lock_reason = NULL; worktree->lock_reason_valid = 0; done: strbuf_release(&path); strbuf_release(&worktree_path); strbuf_release(&head_ref); return worktree; }
static char *find_linked_symref(const char *symref, const char *branch, const char *id) { struct strbuf sb = STRBUF_INIT; struct strbuf path = STRBUF_INIT; struct strbuf gitdir = STRBUF_INIT; char *existing = NULL; /* * $GIT_COMMON_DIR/$symref (e.g. HEAD) is practically outside * $GIT_DIR so resolve_ref_unsafe() won't work (it uses * git_path). Parse the ref ourselves. */ if (id) strbuf_addf(&path, "%s/worktrees/%s/%s", get_git_common_dir(), id, symref); else strbuf_addf(&path, "%s/%s", get_git_common_dir(), symref); if (!strbuf_readlink(&sb, path.buf, 0)) { if (!starts_with(sb.buf, "refs/") || check_refname_format(sb.buf, 0)) goto done; } else if (strbuf_read_file(&sb, path.buf, 0) >= 0 && starts_with(sb.buf, "ref:")) { strbuf_remove(&sb, 0, strlen("ref:")); strbuf_trim(&sb); } else goto done; if (strcmp(sb.buf, branch)) goto done; if (id) { strbuf_reset(&path); strbuf_addf(&path, "%s/worktrees/%s/gitdir", get_git_common_dir(), id); if (strbuf_read_file(&gitdir, path.buf, 0) <= 0) goto done; strbuf_rtrim(&gitdir); } else strbuf_addstr(&gitdir, get_git_common_dir()); strbuf_strip_suffix(&gitdir, ".git"); existing = strbuf_detach(&gitdir, NULL); done: strbuf_release(&path); strbuf_release(&sb); strbuf_release(&gitdir); return existing; }
static void check_embedded_repo(const char *path) { struct strbuf name = STRBUF_INIT; if (!warn_on_embedded_repo) return; if (!ends_with(path, "/")) return; /* Drop trailing slash for aesthetics */ strbuf_addstr(&name, path); strbuf_strip_suffix(&name, "/"); warning(_("adding embedded git repository: %s"), name.buf); if (advice_add_embedded_repo) { advise(embedded_advice, name.buf, name.buf); /* there may be multiple entries; advise only once */ advice_add_embedded_repo = 0; } strbuf_release(&name); }
static int check_inbody_header(struct mailinfo *mi, const struct strbuf *line) { if (mi->inbody_header_accum.len && (line->buf[0] == ' ' || line->buf[0] == '\t')) { if (mi->use_scissors && is_scissors_line(line->buf)) { /* * This is a scissors line; do not consider this line * as a header continuation line. */ flush_inbody_header_accum(mi); return 0; } strbuf_strip_suffix(&mi->inbody_header_accum, "\n"); strbuf_addbuf(&mi->inbody_header_accum, line); return 1; } flush_inbody_header_accum(mi); if (starts_with(line->buf, ">From") && isspace(line->buf[5])) return is_format_patch_separator(line->buf + 1, line->len - 1); if (starts_with(line->buf, "[PATCH]") && isspace(line->buf[7])) { int i; for (i = 0; header[i]; i++) if (!strcmp("Subject", header[i])) { handle_header(&mi->s_hdr_data[i], line); return 1; } return 0; } if (is_inbody_header(mi, line)) { strbuf_addbuf(&mi->inbody_header_accum, line); return 1; } return 0; }