void install_branch_config(int flag, const char *local, const char *origin, const char *remote) { const char *shortname = remote + 11; int remote_is_branch = starts_with(remote, "refs/heads/"); struct strbuf key = STRBUF_INIT; int rebasing = should_setup_rebase(origin); if (remote_is_branch && !strcmp(local, shortname) && !origin) { warning(_("Not setting branch %s as its own upstream."), local); return; } strbuf_addf(&key, "branch.%s.remote", local); git_config_set(key.buf, origin ? origin : "."); strbuf_reset(&key); strbuf_addf(&key, "branch.%s.merge", local); git_config_set(key.buf, remote); if (rebasing) { strbuf_reset(&key); strbuf_addf(&key, "branch.%s.rebase", local); git_config_set(key.buf, "true"); } strbuf_release(&key); if (flag & BRANCH_CONFIG_VERBOSE) { if (remote_is_branch && origin) printf_ln(rebasing ? _("Branch %s set up to track remote branch %s from %s by rebasing.") : _("Branch %s set up to track remote branch %s from %s."), local, shortname, origin); else if (remote_is_branch && !origin) printf_ln(rebasing ? _("Branch %s set up to track local branch %s by rebasing.") : _("Branch %s set up to track local branch %s."), local, shortname); else if (!remote_is_branch && origin) printf_ln(rebasing ? _("Branch %s set up to track remote ref %s by rebasing.") : _("Branch %s set up to track remote ref %s."), local, remote); else if (!remote_is_branch && !origin) printf_ln(rebasing ? _("Branch %s set up to track local ref %s by rebasing.") : _("Branch %s set up to track local ref %s."), local, remote); else die("BUG: impossible combination of %d and %p", remote_is_branch, origin); } }
void install_branch_config(int flag, const char *local, const char *origin, const char *remote) { const char *shortname = skip_prefix(remote, "refs/heads/"); struct strbuf key = STRBUF_INIT; int rebasing = should_setup_rebase(origin); if (shortname && !strcmp(local, shortname) && !origin) { warning(_("Not setting branch %s as its own upstream."), local); return; } strbuf_addf(&key, "branch.%s.remote", local); git_config_set(key.buf, origin ? origin : "."); strbuf_reset(&key); strbuf_addf(&key, "branch.%s.merge", local); git_config_set(key.buf, remote); if (rebasing) { strbuf_reset(&key); strbuf_addf(&key, "branch.%s.rebase", local); git_config_set(key.buf, "true"); } strbuf_release(&key); if (flag & BRANCH_CONFIG_VERBOSE) { if (shortname) { if (origin) printf_ln(rebasing ? _("Branch %s set up to track remote branch %s from %s by rebasing.") : _("Branch %s set up to track remote branch %s from %s."), local, shortname, origin); else printf_ln(rebasing ? _("Branch %s set up to track local branch %s by rebasing.") : _("Branch %s set up to track local branch %s."), local, shortname); } else { if (origin) printf_ln(rebasing ? _("Branch %s set up to track remote ref %s by rebasing.") : _("Branch %s set up to track remote ref %s."), local, remote); else printf_ln(rebasing ? _("Branch %s set up to track local ref %s by rebasing.") : _("Branch %s set up to track local ref %s."), local, remote); } } }
static int pop_stash(int argc, const char **argv, const char *prefix) { int ret; int index = 0; int quiet = 0; struct stash_info info; struct option options[] = { OPT__QUIET(&quiet, N_("be quiet, only report errors")), OPT_BOOL(0, "index", &index, N_("attempt to recreate the index")), OPT_END() }; argc = parse_options(argc, argv, prefix, options, git_stash_pop_usage, 0); if (get_stash_info(&info, argc, argv)) return -1; assert_stash_ref(&info); if ((ret = do_apply_stash(prefix, &info, index, quiet))) printf_ln(_("The stash entry is kept in case " "you need it again.")); else ret = do_drop_stash(prefix, &info, quiet); free_stash_info(&info); return ret; }
static int delete_replace_ref(const char *name, const char *ref, const struct object_id *oid) { if (delete_ref(NULL, ref, oid, 0)) return 1; printf_ln(_("Deleted replace ref '%s'"), name); return 0; }
void list_commands(unsigned int colopts, struct cmdnames *main_cmds, struct cmdnames *other_cmds) { if (main_cmds->cnt) { const char *exec_path = git_exec_path(); printf_ln(_("available git commands in '%s'"), exec_path); putchar('\n'); pretty_print_cmdnames(main_cmds, colopts); putchar('\n'); } if (other_cmds->cnt) { printf_ln(_("git commands available from elsewhere on your $PATH")); putchar('\n'); pretty_print_cmdnames(other_cmds, colopts); putchar('\n'); } }
static int do_drop_stash(const char *prefix, struct stash_info *info, int quiet) { int ret; struct child_process cp_reflog = CHILD_PROCESS_INIT; struct child_process cp = CHILD_PROCESS_INIT; /* * reflog does not provide a simple function for deleting refs. One will * need to be added to avoid implementing too much reflog code here */ cp_reflog.git_cmd = 1; argv_array_pushl(&cp_reflog.args, "reflog", "delete", "--updateref", "--rewrite", NULL); argv_array_push(&cp_reflog.args, info->revision.buf); ret = run_command(&cp_reflog); if (!ret) { if (!quiet) printf_ln(_("Dropped %s (%s)"), info->revision.buf, oid_to_hex(&info->w_commit)); } else { return error(_("%s: Could not drop stash entry"), info->revision.buf); } /* * This could easily be replaced by get_oid, but currently it will throw * a fatal error when a reflog is empty, which we can not recover from. */ cp.git_cmd = 1; /* Even though --quiet is specified, rev-parse still outputs the hash */ cp.no_stdout = 1; argv_array_pushl(&cp.args, "rev-parse", "--verify", "--quiet", NULL); argv_array_pushf(&cp.args, "%s@{0}", ref_stash); ret = run_command(&cp); /* do_clear_stash if we just dropped the last stash entry */ if (ret) do_clear_stash(); return 0; }
static int create_stash(int argc, const char **argv, const char *prefix) { int ret = 0; struct strbuf stash_msg_buf = STRBUF_INIT; struct stash_info info; struct pathspec ps; /* Starting with argv[1], since argv[0] is "create" */ strbuf_join_argv(&stash_msg_buf, argc - 1, ++argv, ' '); memset(&ps, 0, sizeof(ps)); if (!check_changes_tracked_files(ps)) return 0; if (!(ret = do_create_stash(ps, &stash_msg_buf, 0, 0, &info, NULL, 0))) printf_ln("%s", oid_to_hex(&info.w_commit)); strbuf_release(&stash_msg_buf); return ret; }
void list_all_cmds_help(void) { struct string_list others = STRING_LIST_INIT_DUP; struct string_list alias_list = STRING_LIST_INIT_DUP; struct cmdname_help *aliases; int i, longest; printf_ln(_("See 'git help <command>' to read about a specific subcommand")); print_cmd_by_category(main_categories, &longest); list_all_other_cmds(&others); if (others.nr) printf("\n%s\n", _("External commands")); for (i = 0; i < others.nr; i++) printf(" %s\n", others.items[i].string); string_list_clear(&others, 0); git_config(get_alias, &alias_list); string_list_sort(&alias_list); for (i = 0; i < alias_list.nr; i++) { size_t len = strlen(alias_list.items[i].string); if (longest < len) longest = len; } if (alias_list.nr) { printf("\n%s\n", _("Command aliases")); ALLOC_ARRAY(aliases, alias_list.nr + 1); for (i = 0; i < alias_list.nr; i++) { aliases[i].name = alias_list.items[i].string; aliases[i].help = alias_list.items[i].util; aliases[i].category = 1; } aliases[alias_list.nr].name = NULL; print_command_list(aliases, 1, longest); free(aliases); } string_list_clear(&alias_list, 1); }
static int do_apply_stash(const char *prefix, struct stash_info *info, int index, int quiet) { int ret; int has_index = index; struct merge_options o; struct object_id c_tree; struct object_id index_tree; struct commit *result; const struct object_id *bases[1]; read_cache_preload(NULL); if (refresh_cache(REFRESH_QUIET)) return -1; if (write_cache_as_tree(&c_tree, 0, NULL)) return error(_("cannot apply a stash in the middle of a merge")); if (index) { if (oideq(&info->b_tree, &info->i_tree) || oideq(&c_tree, &info->i_tree)) { has_index = 0; } else { struct strbuf out = STRBUF_INIT; if (diff_tree_binary(&out, &info->w_commit)) { strbuf_release(&out); return error(_("could not generate diff %s^!."), oid_to_hex(&info->w_commit)); } ret = apply_cached(&out); strbuf_release(&out); if (ret) return error(_("conflicts in index." "Try without --index.")); discard_cache(); read_cache(); if (write_cache_as_tree(&index_tree, 0, NULL)) return error(_("could not save index tree")); reset_head(); } } if (info->has_u && restore_untracked(&info->u_tree)) return error(_("could not restore untracked files from stash")); init_merge_options(&o, the_repository); o.branch1 = "Updated upstream"; o.branch2 = "Stashed changes"; if (oideq(&info->b_tree, &c_tree)) o.branch1 = "Version stash was based on"; if (quiet) o.verbosity = 0; if (o.verbosity >= 3) printf_ln(_("Merging %s with %s"), o.branch1, o.branch2); bases[0] = &info->b_tree; ret = merge_recursive_generic(&o, &c_tree, &info->w_tree, 1, bases, &result); if (ret) { rerere(0); if (index) fprintf_ln(stderr, _("Index was not unstashed.")); return ret; } if (has_index) { if (reset_tree(&index_tree, 0, 0)) return -1; } else { struct strbuf out = STRBUF_INIT; if (get_newly_staged(&out, &c_tree)) { strbuf_release(&out); return -1; } if (reset_tree(&c_tree, 0, 1)) { strbuf_release(&out); return -1; } ret = update_index(&out); strbuf_release(&out); if (ret) return -1; discard_cache(); } if (quiet) { if (refresh_cache(REFRESH_QUIET)) warning("could not refresh index"); } else { struct child_process cp = CHILD_PROCESS_INIT; /* * Status is quite simple and could be replaced with calls to * wt_status in the future, but it adds complexities which may * require more tests. */ cp.git_cmd = 1; cp.dir = prefix; argv_array_push(&cp.args, "status"); run_command(&cp); } return 0; }
static int do_push_stash(struct pathspec ps, const char *stash_msg, int quiet, int keep_index, int patch_mode, int include_untracked) { int ret = 0; struct stash_info info; struct strbuf patch = STRBUF_INIT; struct strbuf stash_msg_buf = STRBUF_INIT; struct strbuf untracked_files = STRBUF_INIT; if (patch_mode && keep_index == -1) keep_index = 1; if (patch_mode && include_untracked) { fprintf_ln(stderr, _("Can't use --patch and --include-untracked" " or --all at the same time")); ret = -1; goto done; } read_cache_preload(NULL); if (!include_untracked && ps.nr) { int i; char *ps_matched = xcalloc(ps.nr, 1); for (i = 0; i < active_nr; i++) ce_path_match(&the_index, active_cache[i], &ps, ps_matched); if (report_path_error(ps_matched, &ps, NULL)) { fprintf_ln(stderr, _("Did you forget to 'git add'?")); ret = -1; free(ps_matched); goto done; } free(ps_matched); } if (refresh_cache(REFRESH_QUIET)) { ret = -1; goto done; } if (!check_changes(ps, include_untracked, &untracked_files)) { if (!quiet) printf_ln(_("No local changes to save")); goto done; } if (!reflog_exists(ref_stash) && do_clear_stash()) { ret = -1; if (!quiet) fprintf_ln(stderr, _("Cannot initialize stash")); goto done; } if (stash_msg) strbuf_addstr(&stash_msg_buf, stash_msg); if (do_create_stash(ps, &stash_msg_buf, include_untracked, patch_mode, &info, &patch, quiet)) { ret = -1; goto done; } if (do_store_stash(&info.w_commit, stash_msg_buf.buf, 1)) { ret = -1; if (!quiet) fprintf_ln(stderr, _("Cannot save the current status")); goto done; } if (!quiet) printf_ln(_("Saved working directory and index state %s"), stash_msg_buf.buf); if (!patch_mode) { if (include_untracked && !ps.nr) { struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; argv_array_pushl(&cp.args, "clean", "--force", "--quiet", "-d", NULL); if (include_untracked == INCLUDE_ALL_FILES) argv_array_push(&cp.args, "-x"); if (run_command(&cp)) { ret = -1; goto done; } } discard_cache(); if (ps.nr) { struct child_process cp_add = CHILD_PROCESS_INIT; struct child_process cp_diff = CHILD_PROCESS_INIT; struct child_process cp_apply = CHILD_PROCESS_INIT; struct strbuf out = STRBUF_INIT; cp_add.git_cmd = 1; argv_array_push(&cp_add.args, "add"); if (!include_untracked) argv_array_push(&cp_add.args, "-u"); if (include_untracked == INCLUDE_ALL_FILES) argv_array_push(&cp_add.args, "--force"); argv_array_push(&cp_add.args, "--"); add_pathspecs(&cp_add.args, ps); if (run_command(&cp_add)) { ret = -1; goto done; } cp_diff.git_cmd = 1; argv_array_pushl(&cp_diff.args, "diff-index", "-p", "--cached", "--binary", "HEAD", "--", NULL); add_pathspecs(&cp_diff.args, ps); if (pipe_command(&cp_diff, NULL, 0, &out, 0, NULL, 0)) { ret = -1; goto done; } cp_apply.git_cmd = 1; argv_array_pushl(&cp_apply.args, "apply", "--index", "-R", NULL); if (pipe_command(&cp_apply, out.buf, out.len, NULL, 0, NULL, 0)) { ret = -1; goto done; } } else { struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; argv_array_pushl(&cp.args, "reset", "--hard", "-q", NULL); if (run_command(&cp)) { ret = -1; goto done; } } if (keep_index == 1 && !is_null_oid(&info.i_tree)) { struct child_process cp_ls = CHILD_PROCESS_INIT; struct child_process cp_checkout = CHILD_PROCESS_INIT; struct strbuf out = STRBUF_INIT; if (reset_tree(&info.i_tree, 0, 1)) { ret = -1; goto done; } cp_ls.git_cmd = 1; argv_array_pushl(&cp_ls.args, "ls-files", "-z", "--modified", "--", NULL); add_pathspecs(&cp_ls.args, ps); if (pipe_command(&cp_ls, NULL, 0, &out, 0, NULL, 0)) { ret = -1; goto done; } cp_checkout.git_cmd = 1; argv_array_pushl(&cp_checkout.args, "checkout-index", "-z", "--force", "--stdin", NULL); if (pipe_command(&cp_checkout, out.buf, out.len, NULL, 0, NULL, 0)) { ret = -1; goto done; } } goto done; } else { struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; argv_array_pushl(&cp.args, "apply", "-R", NULL); if (pipe_command(&cp, patch.buf, patch.len, NULL, 0, NULL, 0)) { if (!quiet) fprintf_ln(stderr, _("Cannot remove " "worktree changes")); ret = -1; goto done; } if (keep_index < 1) { struct child_process cp = CHILD_PROCESS_INIT; discard_cache(); cp.git_cmd = 1; argv_array_pushl(&cp.args, "reset", "-q", "--", NULL); add_pathspecs(&cp.args, ps); if (run_command(&cp)) { ret = -1; goto done; } } goto done; } done: strbuf_release(&stash_msg_buf); return ret; }
int install_branch_config(int flag, const char *local, const char *origin, const char *remote) { const char *shortname = NULL; struct strbuf key = STRBUF_INIT; int rebasing = should_setup_rebase(origin); if (skip_prefix(remote, "refs/heads/", &shortname) && !strcmp(local, shortname) && !origin) { warning(_("Not setting branch %s as its own upstream."), local); return 0; } strbuf_addf(&key, "branch.%s.remote", local); if (git_config_set_gently(key.buf, origin ? origin : ".") < 0) goto out_err; strbuf_reset(&key); strbuf_addf(&key, "branch.%s.merge", local); if (git_config_set_gently(key.buf, remote) < 0) goto out_err; if (rebasing) { strbuf_reset(&key); strbuf_addf(&key, "branch.%s.rebase", local); if (git_config_set_gently(key.buf, "true") < 0) goto out_err; } strbuf_release(&key); if (flag & BRANCH_CONFIG_VERBOSE) { if (shortname) { if (origin) printf_ln(rebasing ? _("Branch %s set up to track remote branch %s from %s by rebasing.") : _("Branch %s set up to track remote branch %s from %s."), local, shortname, origin); else printf_ln(rebasing ? _("Branch %s set up to track local branch %s by rebasing.") : _("Branch %s set up to track local branch %s."), local, shortname); } else { if (origin) printf_ln(rebasing ? _("Branch %s set up to track remote ref %s by rebasing.") : _("Branch %s set up to track remote ref %s."), local, remote); else printf_ln(rebasing ? _("Branch %s set up to track local ref %s by rebasing.") : _("Branch %s set up to track local ref %s."), local, remote); } } return 0; out_err: strbuf_release(&key); error(_("Unable to write upstream branch configuration")); advise(_(tracking_advice), origin ? origin : "", origin ? "/" : "", shortname ? shortname : remote); return -1; }
int verify_bundle(struct bundle_header *header, int verbose) { /* * Do fast check, then if any prereqs are missing then go line by line * to be verbose about the errors */ struct ref_list *p = &header->prerequisites; struct rev_info revs; const char *argv[] = {NULL, "--all", NULL}; struct object_array refs; struct commit *commit; int i, ret = 0, req_nr; const char *message = _("Repository lacks these prerequisite commits:"); init_revisions(&revs, NULL); for (i = 0; i < p->nr; i++) { struct ref_list_entry *e = p->list + i; struct object *o = parse_object(e->sha1); if (o) { o->flags |= PREREQ_MARK; add_pending_object(&revs, o, e->name); continue; } if (++ret == 1) error("%s", message); error("%s %s", sha1_to_hex(e->sha1), e->name); } if (revs.pending.nr != p->nr) return ret; req_nr = revs.pending.nr; setup_revisions(2, argv, &revs, NULL); refs = revs.pending; revs.leak_pending = 1; if (prepare_revision_walk(&revs)) die(_("revision walk setup failed")); i = req_nr; while (i && (commit = get_revision(&revs))) if (commit->object.flags & PREREQ_MARK) i--; for (i = 0; i < req_nr; i++) if (!(refs.objects[i].item->flags & SHOWN)) { if (++ret == 1) error("%s", message); error("%s %s", sha1_to_hex(refs.objects[i].item->sha1), refs.objects[i].name); } clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS); free(refs.objects); if (verbose) { struct ref_list *r; r = &header->references; printf_ln(Q_("The bundle contains this ref:", "The bundle contains these %d refs:", r->nr), r->nr); list_refs(r, 0, NULL); r = &header->prerequisites; if (!r->nr) { printf_ln(_("The bundle records a complete history.")); } else { printf_ln(Q_("The bundle requires this ref:", "The bundle requires these %d refs:", r->nr), r->nr); list_refs(r, 0, NULL); } } return ret; }