diff options
Diffstat (limited to 'branch.c')
| -rw-r--r-- | branch.c | 100 |
1 files changed, 47 insertions, 53 deletions
@@ -1,10 +1,16 @@ #include "git-compat-util.h" -#include "cache.h" +#include "advice.h" #include "config.h" #include "branch.h" +#include "environment.h" +#include "gettext.h" +#include "hex.h" +#include "object-name.h" +#include "path.h" #include "refs.h" #include "refspec.h" #include "remote.h" +#include "repository.h" #include "sequencer.h" #include "commit.h" #include "worktree.h" @@ -32,7 +38,7 @@ static int find_tracked_branch(struct remote *remote, void *priv) if (!remote_find_tracking(remote, &tracking->spec)) { switch (++tracking->matches) { case 1: - string_list_append(tracking->srcs, tracking->spec.src); + string_list_append_nodup(tracking->srcs, tracking->spec.src); tracking->remote = remote->name; break; case 2: @@ -228,7 +234,7 @@ static int inherit_tracking(struct tracking *tracking, const char *orig_ref) return -1; } - tracking->remote = xstrdup(branch->remote_name); + tracking->remote = branch->remote_name; for (i = 0; i < branch->merge_nr; i++) string_list_append(tracking->srcs, branch->merge_name[i]); return 0; @@ -328,7 +334,7 @@ static void setup_tracking(const char *new_ref, const char *orig_ref, if (!skip_prefix(tracking.srcs->items[0].string, "refs/heads/", &tracked_branch) || strcmp(tracked_branch, new_ref)) - return; + goto cleanup; } if (tracking.srcs->nr < 1) @@ -364,10 +370,14 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name) */ int validate_branchname(const char *name, struct strbuf *ref) { - if (strbuf_check_branch_ref(ref, name)) - die(_("'%s' is not a valid branch name"), name); + if (strbuf_check_branch_ref(ref, name)) { + int code = die_message(_("'%s' is not a valid branch name"), name); + advise_if_enabled(ADVICE_REF_SYNTAX, + _("See `man git check-ref-format`")); + exit(code); + } - return ref_exists(ref->buf); + return refs_ref_exists(get_main_ref_store(the_repository), ref->buf); } static int initialized_checked_out_branches; @@ -414,9 +424,9 @@ static void prepare_checked_out_branches(void) wt_status_state_free_buffers(&state); if (wt_status_check_bisect(wt, &state) && - state.branch) { + state.bisecting_from) { struct strbuf ref = STRBUF_INIT; - strbuf_addf(&ref, "refs/heads/%s", state.branch); + strbuf_addf(&ref, "refs/heads/%s", state.bisecting_from); old = strmap_put(¤t_checked_out_branches, ref.buf, xstrdup(wt->path)); @@ -465,7 +475,7 @@ int validate_new_branchname(const char *name, struct strbuf *ref, int force) if ((path = branch_checked_out(ref->buf))) die(_("cannot force update the branch '%s' " - "checked out at '%s'"), + "used by worktree at '%s'"), ref->buf + strlen("refs/heads/"), path); return 1; @@ -475,9 +485,12 @@ static int check_tracking_branch(struct remote *remote, void *cb_data) { char *tracking_branch = cb_data; struct refspec_item query; + int res; memset(&query, 0, sizeof(struct refspec_item)); query.dst = tracking_branch; - return !remote_find_tracking(remote, &query); + res = !remote_find_tracking(remote, &query); + free(query.src); + return res; } static int validate_remote_tracking_branch(char *ref) @@ -531,7 +544,7 @@ static void dwim_branch_start(struct repository *r, const char *start_name, explicit_tracking = 1; real_ref = NULL; - if (get_oid_mb(start_name, &oid)) { + if (repo_get_oid_mb(r, start_name, &oid)) { if (explicit_tracking) { int code = die_message(_(upstream_missing), start_name); advise_if_enabled(ADVICE_SET_UPSTREAM_FAILURE, @@ -541,7 +554,8 @@ static void dwim_branch_start(struct repository *r, const char *start_name, die(_("not a valid object name: '%s'"), start_name); } - switch (dwim_ref(start_name, strlen(start_name), &oid, &real_ref, 0)) { + switch (repo_dwim_ref(r, start_name, strlen(start_name), &oid, + &real_ref, 0)) { case 0: /* Not branching from any existing branch */ if (explicit_tracking) @@ -609,11 +623,12 @@ void create_branch(struct repository *r, msg = xstrfmt("branch: Reset to %s", start_name); else msg = xstrfmt("branch: Created from %s", start_name); - transaction = ref_transaction_begin(&err); + transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), + &err); if (!transaction || ref_transaction_update(transaction, ref.buf, &oid, forcing ? NULL : null_oid(), - 0, msg, &err) || + NULL, NULL, 0, msg, &err) || ref_transaction_commit(transaction, &err)) die("%s", err.buf); ref_transaction_free(transaction); @@ -632,9 +647,10 @@ void dwim_and_setup_tracking(struct repository *r, const char *new_ref, const char *orig_ref, enum branch_track track, int quiet) { - char *real_orig_ref; + char *real_orig_ref = NULL; dwim_branch_start(r, orig_ref, track, &real_orig_ref, NULL); setup_tracking(new_ref, real_orig_ref, track, quiet); + free(real_orig_ref); } /** @@ -723,7 +739,7 @@ static int submodule_create_branch(struct repository *r, } void create_branches_recursively(struct repository *r, const char *name, - const char *start_commitish, + const char *start_committish, const char *tracking_name, int force, int reflog, int quiet, enum branch_track track, int dry_run) @@ -733,8 +749,8 @@ void create_branches_recursively(struct repository *r, const char *name, struct object_id super_oid; struct submodule_entry_list submodule_entry_list; - /* Perform dwim on start_commitish to get super_oid and branch_point. */ - dwim_branch_start(r, start_commitish, BRANCH_TRACK_NEVER, + /* Perform dwim on start_committish to get super_oid and branch_point. */ + dwim_branch_start(r, start_committish, BRANCH_TRACK_NEVER, &branch_point, &super_oid); /* @@ -757,7 +773,7 @@ void create_branches_recursively(struct repository *r, const char *name, submodule_entry_list.entries[i].submodule->name); if (advice_enabled(ADVICE_SUBMODULES_NOT_UPDATED)) advise(_("You may try updating the submodules using 'git checkout --no-recurse-submodules %s && git submodule update --init'"), - start_commitish); + start_committish); exit(code); } @@ -772,7 +788,7 @@ void create_branches_recursively(struct repository *r, const char *name, name); } - create_branch(the_repository, name, start_commitish, force, 0, reflog, quiet, + create_branch(r, name, start_committish, force, 0, reflog, quiet, BRANCH_TRACK_NEVER, dry_run); if (dry_run) return; @@ -806,8 +822,9 @@ void remove_merge_branch_state(struct repository *r) unlink(git_path_merge_rr(r)); unlink(git_path_merge_msg(r)); unlink(git_path_merge_mode(r)); - unlink(git_path_auto_merge(r)); - save_autostash(git_path_merge_autostash(r)); + refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE", + NULL, REF_NO_DEREF); + save_autostash_ref(r, "MERGE_AUTOSTASH"); } void remove_branch_state(struct repository *r, int verbose) @@ -820,40 +837,17 @@ void remove_branch_state(struct repository *r, int verbose) void die_if_checked_out(const char *branch, int ignore_current_worktree) { struct worktree **worktrees = get_worktrees(); - const struct worktree *wt; - - wt = find_shared_symref(worktrees, "HEAD", branch); - if (wt && (!ignore_current_worktree || !wt->is_current)) { - skip_prefix(branch, "refs/heads/", &branch); - die(_("'%s' is already checked out at '%s'"), branch, wt->path); - } - free_worktrees(worktrees); -} - -int replace_each_worktree_head_symref(const char *oldref, const char *newref, - const char *logmsg) -{ - int ret = 0; - struct worktree **worktrees = get_worktrees(); - int i; - - for (i = 0; worktrees[i]; i++) { - struct ref_store *refs; - - if (worktrees[i]->is_detached) - continue; - if (!worktrees[i]->head_ref) - continue; - if (strcmp(oldref, worktrees[i]->head_ref)) + for (int i = 0; worktrees[i]; i++) { + if (worktrees[i]->is_current && ignore_current_worktree) continue; - refs = get_worktree_ref_store(worktrees[i]); - if (refs_create_symref(refs, "HEAD", newref, logmsg)) - ret = error(_("HEAD of working tree %s is not updated"), - worktrees[i]->path); + if (is_shared_symref(worktrees[i], "HEAD", branch)) { + skip_prefix(branch, "refs/heads/", &branch); + die(_("'%s' is already used by worktree at '%s'"), + branch, worktrees[i]->path); + } } free_worktrees(worktrees); - return ret; } |
