91
};
92
93
struct branch_info {
94
- const char *name; /* The short name used */
95
- const char *path; /* The full name of a real branch */
94
+ char *name; /* The short name used */
95
+ char *path; /* The full name of a real branch */
96
struct commit *commit; /* The named commit */
97
char *refname; /* The full name of the ref being checked out. */
98
struct object_id oid; /* The object ID of the commit being checked out. */
103
char *checkout;
104
};
105
106
+static void branch_info_release(struct branch_info *info)
107
+{
108
+ free(info->name);
109
+ free(info->path);
110
+ free(info->refname);
111
+ free(info->checkout);
112
+}
113
+
114
static int post_checkout_hook(struct commit *old_commit, struct commit *new_commit,
115
int changed)
116
{
696
repo_get_oid_committish(the_repository, branch->name, &branch->oid);
697
698
strbuf_branchname(&buf, branch->name, INTERPRET_BRANCH_LOCAL);
691
- if (strcmp(buf.buf, branch->name))
699
+ if (strcmp(buf.buf, branch->name)) {
700
+ free(branch->name);
701
branch->name = xstrdup(buf.buf);
702
+ }
703
strbuf_splice(&buf, 0, 0, "refs/heads/", 11);
704
+ free(branch->path);
705
branch->path = strbuf_detach(&buf, NULL);
706
}
707
905
opts->new_branch_log,
906
opts->quiet,
907
opts->track);
897
- new_branch_info->name = opts->new_branch;
908
+ free(new_branch_info->name);
909
+ free(new_branch_info->refname);
910
+ new_branch_info->name = xstrdup(opts->new_branch);
911
setup_branch_path(new_branch_info);
912
}
913
1075
struct branch_info *new_branch_info)
1076
{
1077
int ret = 0;
1065
- struct branch_info old_branch_info;
1066
- void *path_to_free;
1078
+ struct branch_info old_branch_info = { 0 };
1079
struct object_id rev;
1080
int flag, writeout_error = 0;
1081
int do_merge = 1;
1083
trace2_cmd_mode("branch");
1084
1085
memset(&old_branch_info, 0, sizeof(old_branch_info));
1074
- old_branch_info.path = path_to_free = resolve_refdup("HEAD", 0, &rev, &flag);
1086
+ old_branch_info.path = resolve_refdup("HEAD", 0, &rev, &flag);
1087
if (old_branch_info.path)
1088
old_branch_info.commit = lookup_commit_reference_gently(the_repository, &rev, 1);
1089
if (!(flag & REF_ISSYMREF))
1078
- old_branch_info.path = NULL;
1090
+ FREE_AND_NULL(old_branch_info.path);
1091
1080
- if (old_branch_info.path)
1081
- skip_prefix(old_branch_info.path, "refs/heads/", &old_branch_info.name);
1092
+ if (old_branch_info.path) {
1093
+ const char *const prefix = "refs/heads/";
1094
+ const char *p;
1095
+ if (skip_prefix(old_branch_info.path, prefix, &p))
1096
+ old_branch_info.name = xstrdup(p);
1097
+ else
1098
+ BUG("should be able to skip past '%s' in '%s'!",
1099
+ prefix, old_branch_info.path);
1100
+ }
1101
1102
if (opts->new_orphan_branch && opts->orphan_from_empty_tree) {
1103
if (new_branch_info->name)
1104
BUG("'switch --orphan' should never accept a commit as starting point");
1105
new_branch_info->commit = NULL;
1087
- new_branch_info->name = "(empty)";
1106
+ new_branch_info->name = xstrdup("(empty)");
1107
do_merge = 1;
1108
}
1109
1110
if (!new_branch_info->name) {
1092
- new_branch_info->name = "HEAD";
1111
+ new_branch_info->name = xstrdup("HEAD");
1112
new_branch_info->commit = old_branch_info.commit;
1113
if (!new_branch_info->commit)
1114
die(_("You are on a branch yet to be born"));
1121
if (do_merge) {
1122
ret = merge_working_tree(opts, &old_branch_info, new_branch_info, &writeout_error);
1123
if (ret) {
1105
- free(path_to_free);
1124
+ branch_info_release(&old_branch_info);
1125
return ret;
1126
}
1127
}
1132
update_refs_for_switch(opts, &old_branch_info, new_branch_info);
1133
1134
ret = post_checkout_hook(old_branch_info.commit, new_branch_info->commit, 1);
1116
- free(path_to_free);
1135
+ branch_info_release(&old_branch_info);
1136
+
1137
return ret || writeout_error;
1138
}
1139
1165
struct tree **source_tree = &opts->source_tree;
1166
struct object_id branch_rev;
1167
1148
- new_branch_info->name = arg;
1168
+ new_branch_info->name = xstrdup(arg);
1169
setup_branch_path(new_branch_info);
1170
1171
if (!check_refname_format(new_branch_info->path, 0) &&
1172
!read_ref(new_branch_info->path, &branch_rev))
1173
oidcpy(rev, &branch_rev);
1154
- else {
1155
- free((char *)new_branch_info->path);
1156
- new_branch_info->path = NULL; /* not an existing branch */
1157
- }
1174
+ else
1175
+ /* not an existing branch */
1176
+ FREE_AND_NULL(new_branch_info->path);
1177
1178
new_branch_info->commit = lookup_commit_reference_gently(the_repository, rev, 1);
1179
if (!new_branch_info->commit) {
1593
1594
static int checkout_main(int argc, const char **argv, const char *prefix,
1595
struct checkout_opts *opts, struct option *options,
1577
- const char * const usagestr[])
1596
+ const char * const usagestr[],
1597
+ struct branch_info *new_branch_info)
1598
{
1579
- struct branch_info new_branch_info;
1599
int parseopt_flags = 0;
1600
1582
- memset(&new_branch_info, 0, sizeof(new_branch_info));
1601
opts->overwrite_ignore = 1;
1602
opts->prefix = prefix;
1603
opts->show_progress = -1;
1706
opts->track == BRANCH_TRACK_UNSPECIFIED &&
1707
!opts->new_branch;
1708
int n = parse_branchname_arg(argc, argv, dwim_ok,
1691
- &new_branch_info, opts, &rev);
1709
+ new_branch_info, opts, &rev);
1710
argv += n;
1711
argc -= n;
1712
} else if (!opts->accept_ref && opts->from_treeish) {
1715
if (get_oid_mb(opts->from_treeish, &rev))
1716
die(_("could not resolve %s"), opts->from_treeish);
1717
1700
- setup_new_branch_info_and_source_tree(&new_branch_info,
1718
+ setup_new_branch_info_and_source_tree(new_branch_info,
1719
opts, &rev,
1720
opts->from_treeish);
1721
1735
* Try to give more helpful suggestion.
1736
* new_branch && argc > 1 will be caught later.
1737
*/
1720
- if (opts->new_branch && argc == 1 && !new_branch_info.commit)
1738
+ if (opts->new_branch && argc == 1 && !new_branch_info->commit)
1739
die(_("'%s' is not a commit and a branch '%s' cannot be created from it"),
1740
argv[0], opts->new_branch);
1741
1784
strbuf_release(&buf);
1785
}
1786
1769
- UNLEAK(opts);
1787
if (opts->patch_mode || opts->pathspec.nr)
1771
- return checkout_paths(opts, &new_branch_info);
1788
+ return checkout_paths(opts, new_branch_info);
1789
else
1773
- return checkout_branch(opts, &new_branch_info);
1790
+ return checkout_branch(opts, new_branch_info);
1791
}
1792
1793
int cmd_checkout(int argc, const char **argv, const char *prefix)
1806
OPT_END()
1807
};
1808
int ret;
1809
+ struct branch_info new_branch_info = { 0 };
1810
1811
memset(&opts, 0, sizeof(opts));
1812
opts.dwim_new_local_branch = 1;
1837
options = add_checkout_path_options(&opts, options);
1838
1839
ret = checkout_main(argc, argv, prefix, &opts,
1822
- options, checkout_usage);
1840
+ options, checkout_usage, &new_branch_info);
1841
+ branch_info_release(&new_branch_info);
1842
+ clear_pathspec(&opts.pathspec);
1843
FREE_AND_NULL(options);
1844
return ret;
1845
}
1860
OPT_END()
1861
};
1862
int ret;
1863
+ struct branch_info new_branch_info = { 0 };
1864
1865
memset(&opts, 0, sizeof(opts));
1866
opts.dwim_new_local_branch = 1;
1880
cb_option = 'c';
1881
1882
ret = checkout_main(argc, argv, prefix, &opts,
1862
- options, switch_branch_usage);
1883
+ options, switch_branch_usage, &new_branch_info);
1884
+ branch_info_release(&new_branch_info);
1885
FREE_AND_NULL(options);
1886
return ret;
1887
}
1903
OPT_END()
1904
};
1905
int ret;
1906
+ struct branch_info new_branch_info = { 0 };
1907
1908
memset(&opts, 0, sizeof(opts));
1909
opts.accept_ref = 0;
1919
options = add_checkout_path_options(&opts, options);
1920
1921
ret = checkout_main(argc, argv, prefix, &opts,
1899
- options, restore_usage);
1922
+ options, restore_usage, &new_branch_info);
1923
+ branch_info_release(&new_branch_info);
1924
FREE_AND_NULL(options);
1925
return ret;
1926
}