Merge branch 'jk/xstrfmt'

* jk/xstrfmt:
  setup_git_env(): introduce git_path_from_env() helper
  unique_path: fix unlikely heap overflow
  walker_fetch: fix minor memory leak
  merge: use argv_array when spawning merge strategy
  sequencer: use argv_array_pushf
  setup_git_env: use git_pathdup instead of xmalloc + sprintf
  use xstrfmt to replace xmalloc + strcpy/strcat
  use xstrfmt to replace xmalloc + sprintf
  use xstrdup instead of xmalloc + strcpy
  use xstrfmt in favor of manual size calculations
  strbuf: add xstrfmt helper
This commit is contained in:
Junio C Hamano
2014-07-09 11:34:05 -07:00
20 changed files with 121 additions and 162 deletions

View File

@ -1281,9 +1281,7 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct
*/ */
patch->def_name = git_header_name(line, len); patch->def_name = git_header_name(line, len);
if (patch->def_name && root) { if (patch->def_name && root) {
char *s = xmalloc(root_len + strlen(patch->def_name) + 1); char *s = xstrfmt("%s%s", root, patch->def_name);
strcpy(s, root);
strcpy(s + root_len, patch->def_name);
free(patch->def_name); free(patch->def_name);
patch->def_name = s; patch->def_name = s;
} }

View File

@ -1082,16 +1082,11 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
refs = xcalloc(argc + 1, sizeof(const char *)); refs = xcalloc(argc + 1, sizeof(const char *));
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
if (!strcmp(argv[i], "tag")) { if (!strcmp(argv[i], "tag")) {
char *ref;
i++; i++;
if (i >= argc) if (i >= argc)
die(_("You need to specify a tag name.")); die(_("You need to specify a tag name."));
ref = xmalloc(strlen(argv[i]) * 2 + 22); refs[j++] = xstrfmt("refs/tags/%s:refs/tags/%s",
strcpy(ref, "refs/tags/"); argv[i], argv[i]);
strcat(ref, argv[i]);
strcat(ref, ":refs/tags/");
strcat(ref, argv[i]);
refs[j++] = ref;
} else } else
refs[j++] = argv[i]; refs[j++] = argv[i];
} }

View File

@ -178,11 +178,8 @@ static int handle_line(char *line, struct merge_parents *merge_parents)
int len = strlen(origin); int len = strlen(origin);
if (origin[0] == '\'' && origin[len - 1] == '\'') if (origin[0] == '\'' && origin[len - 1] == '\'')
origin = xmemdupz(origin + 1, len - 2); origin = xmemdupz(origin + 1, len - 2);
} else { } else
char *new_origin = xmalloc(strlen(origin) + strlen(src) + 5); origin = xstrfmt("%s of %s", origin, src);
sprintf(new_origin, "%s of %s", origin, src);
origin = new_origin;
}
if (strcmp(".", src)) if (strcmp(".", src))
origin_data->is_local_branch = 0; origin_data->is_local_branch = 0;
string_list_append(&origins, origin)->util = origin_data; string_list_append(&origins, origin)->util = origin_data;

View File

@ -33,10 +33,7 @@ static void name_rev(struct commit *commit,
return; return;
if (deref) { if (deref) {
char *new_name = xmalloc(strlen(tip_name)+3); tip_name = xstrfmt("%s^0", tip_name);
strcpy(new_name, tip_name);
strcat(new_name, "^0");
tip_name = new_name;
if (generation) if (generation)
die("generation: %d, but deref?", generation); die("generation: %d, but deref?", generation);

View File

@ -614,12 +614,9 @@ static void run_update_post_hook(struct command *commands)
argv[0] = hook; argv[0] = hook;
for (argc = 1, cmd = commands; cmd; cmd = cmd->next) { for (argc = 1, cmd = commands; cmd; cmd = cmd->next) {
char *p;
if (cmd->error_string || cmd->did_not_exist) if (cmd->error_string || cmd->did_not_exist)
continue; continue;
p = xmalloc(strlen(cmd->ref_name) + 1); argv[argc] = xstrdup(cmd->ref_name);
strcpy(p, cmd->ref_name);
argv[argc] = p;
argc++; argc++;
} }
argv[argc] = NULL; argv[argc] = NULL;

View File

@ -755,7 +755,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
} }
for (i = 0; i < reflog; i++) { for (i = 0; i < reflog; i++) {
char *logmsg, *m; char *logmsg;
const char *msg; const char *msg;
unsigned long timestamp; unsigned long timestamp;
int tz; int tz;
@ -770,11 +770,9 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
msg = "(none)"; msg = "(none)";
else else
msg++; msg++;
m = xmalloc(strlen(msg) + 200); reflog_msg[i] = xstrfmt("(%s) %s",
sprintf(m, "(%s) %s",
show_date(timestamp, tz, 1), show_date(timestamp, tz, 1),
msg); msg);
reflog_msg[i] = m;
free(logmsg); free(logmsg);
sprintf(nth_desc, "%s@{%d}", *av, base+i); sprintf(nth_desc, "%s@{%d}", *av, base+i);
append_ref(nth_desc, sha1, 1); append_ref(nth_desc, sha1, 1);

View File

@ -124,6 +124,12 @@ static char *expand_namespace(const char *raw_namespace)
return strbuf_detach(&buf, NULL); return strbuf_detach(&buf, NULL);
} }
static char *git_path_from_env(const char *envvar, const char *path)
{
const char *value = getenv(envvar);
return value ? xstrdup(value) : git_pathdup("%s", path);
}
static void setup_git_env(void) static void setup_git_env(void)
{ {
const char *gitfile; const char *gitfile;
@ -134,19 +140,9 @@ static void setup_git_env(void)
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT; git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
gitfile = read_gitfile(git_dir); gitfile = read_gitfile(git_dir);
git_dir = xstrdup(gitfile ? gitfile : git_dir); git_dir = xstrdup(gitfile ? gitfile : git_dir);
git_object_dir = getenv(DB_ENVIRONMENT); git_object_dir = git_path_from_env(DB_ENVIRONMENT, "objects");
if (!git_object_dir) { git_index_file = git_path_from_env(INDEX_ENVIRONMENT, "index");
git_object_dir = xmalloc(strlen(git_dir) + 9); git_graft_file = git_path_from_env(GRAFT_ENVIRONMENT, "info/grafts");
sprintf(git_object_dir, "%s/objects", git_dir);
}
git_index_file = getenv(INDEX_ENVIRONMENT);
if (!git_index_file) {
git_index_file = xmalloc(strlen(git_dir) + 7);
sprintf(git_index_file, "%s/index", git_dir);
}
git_graft_file = getenv(GRAFT_ENVIRONMENT);
if (!git_graft_file)
git_graft_file = git_pathdup("info/grafts");
if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT)) if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
check_replace_refs = 0; check_replace_refs = 0;
namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT)); namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT));

View File

@ -763,15 +763,13 @@ static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed)
if (tag_closed && ctx->cdata) { if (tag_closed && ctx->cdata) {
if (!strcmp(ctx->name, DAV_ACTIVELOCK_OWNER)) { if (!strcmp(ctx->name, DAV_ACTIVELOCK_OWNER)) {
lock->owner = xmalloc(strlen(ctx->cdata) + 1); lock->owner = xstrdup(ctx->cdata);
strcpy(lock->owner, ctx->cdata);
} else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) { } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) {
const char *arg; const char *arg;
if (skip_prefix(ctx->cdata, "Second-", &arg)) if (skip_prefix(ctx->cdata, "Second-", &arg))
lock->timeout = strtol(arg, NULL, 10); lock->timeout = strtol(arg, NULL, 10);
} else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) { } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) {
lock->token = xmalloc(strlen(ctx->cdata) + 1); lock->token = xstrdup(ctx->cdata);
strcpy(lock->token, ctx->cdata);
git_SHA1_Init(&sha_ctx); git_SHA1_Init(&sha_ctx);
git_SHA1_Update(&sha_ctx, lock->token, strlen(lock->token)); git_SHA1_Update(&sha_ctx, lock->token, strlen(lock->token));
@ -852,8 +850,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)
struct xml_ctx ctx; struct xml_ctx ctx;
char *escaped; char *escaped;
url = xmalloc(strlen(repo->url) + strlen(path) + 1); url = xstrfmt("%s%s", repo->url, path);
sprintf(url, "%s%s", repo->url, path);
/* Make sure leading directories exist for the remote ref */ /* Make sure leading directories exist for the remote ref */
ep = strchr(url + strlen(repo->url) + 1, '/'); ep = strchr(url + strlen(repo->url) + 1, '/');
@ -1125,7 +1122,7 @@ static void remote_ls(const char *path, int flags,
void (*userFunc)(struct remote_ls_ctx *ls), void (*userFunc)(struct remote_ls_ctx *ls),
void *userData) void *userData)
{ {
char *url = xmalloc(strlen(repo->url) + strlen(path) + 1); char *url = xstrfmt("%s%s", repo->url, path);
struct active_request_slot *slot; struct active_request_slot *slot;
struct slot_results results; struct slot_results results;
struct strbuf in_buffer = STRBUF_INIT; struct strbuf in_buffer = STRBUF_INIT;
@ -1141,8 +1138,6 @@ static void remote_ls(const char *path, int flags,
ls.userData = userData; ls.userData = userData;
ls.userFunc = userFunc; ls.userFunc = userFunc;
sprintf(url, "%s%s", repo->url, path);
strbuf_addf(&out_buffer.buf, PROPFIND_ALL_REQUEST); strbuf_addf(&out_buffer.buf, PROPFIND_ALL_REQUEST);
dav_headers = curl_slist_append(dav_headers, "Depth: 1"); dav_headers = curl_slist_append(dav_headers, "Depth: 1");
@ -1544,10 +1539,9 @@ static void update_remote_info_refs(struct remote_lock *lock)
static int remote_exists(const char *path) static int remote_exists(const char *path)
{ {
char *url = xmalloc(strlen(repo->url) + strlen(path) + 1); char *url = xstrfmt("%s%s", repo->url, path);
int ret; int ret;
sprintf(url, "%s%s", repo->url, path);
switch (http_get_strbuf(url, NULL, NULL)) { switch (http_get_strbuf(url, NULL, NULL)) {
case HTTP_OK: case HTTP_OK:
@ -1567,13 +1561,10 @@ static int remote_exists(const char *path)
static void fetch_symref(const char *path, char **symref, unsigned char *sha1) static void fetch_symref(const char *path, char **symref, unsigned char *sha1)
{ {
char *url; char *url = xstrfmt("%s%s", repo->url, path);
struct strbuf buffer = STRBUF_INIT; struct strbuf buffer = STRBUF_INIT;
const char *name; const char *name;
url = xmalloc(strlen(repo->url) + strlen(path) + 1);
sprintf(url, "%s%s", repo->url, path);
if (http_get_strbuf(url, &buffer, NULL) != HTTP_OK) if (http_get_strbuf(url, &buffer, NULL) != HTTP_OK)
die("Couldn't get %s for remote symref\n%s", url, die("Couldn't get %s for remote symref\n%s", url,
curl_errorstr); curl_errorstr);
@ -1682,8 +1673,7 @@ static int delete_remote_branch(const char *pattern, int force)
fprintf(stderr, "Removing remote branch '%s'\n", remote_ref->name); fprintf(stderr, "Removing remote branch '%s'\n", remote_ref->name);
if (dry_run) if (dry_run)
return 0; return 0;
url = xmalloc(strlen(repo->url) + strlen(remote_ref->name) + 1); url = xstrfmt("%s%s", repo->url, remote_ref->name);
sprintf(url, "%s%s", repo->url, remote_ref->name);
slot = get_active_slot(); slot = get_active_slot();
slot->results = &results; slot->results = &results;
curl_setup_http_get(slot->curl, url, DAV_DELETE); curl_setup_http_get(slot->curl, url, DAV_DELETE);

View File

@ -341,8 +341,7 @@ static void fetch_alternates(struct walker *walker, const char *base)
if (walker->get_verbosely) if (walker->get_verbosely)
fprintf(stderr, "Getting alternates list for %s\n", base); fprintf(stderr, "Getting alternates list for %s\n", base);
url = xmalloc(strlen(base) + 31); url = xstrfmt("%s/objects/info/http-alternates", base);
sprintf(url, "%s/objects/info/http-alternates", base);
/* /*
* Use a callback to process the result, since another request * Use a callback to process the result, since another request
@ -566,8 +565,7 @@ struct walker *get_http_walker(const char *url)
struct walker *walker = xmalloc(sizeof(struct walker)); struct walker *walker = xmalloc(sizeof(struct walker));
data->alt = xmalloc(sizeof(*data->alt)); data->alt = xmalloc(sizeof(*data->alt));
data->alt->base = xmalloc(strlen(url) + 1); data->alt->base = xstrdup(url);
strcpy(data->alt->base, url);
for (s = data->alt->base + strlen(data->alt->base) - 1; *s == '/'; --s) for (s = data->alt->base + strlen(data->alt->base) - 1; *s == '/'; --s)
*s = 0; *s = 0;

View File

@ -140,17 +140,12 @@ static void match_trees(const unsigned char *hash1,
goto next; goto next;
score = score_trees(elem, hash2); score = score_trees(elem, hash2);
if (*best_score < score) { if (*best_score < score) {
char *newpath;
newpath = xmalloc(strlen(base) + strlen(path) + 1);
sprintf(newpath, "%s%s", base, path);
free(*best_match); free(*best_match);
*best_match = newpath; *best_match = xstrfmt("%s%s", base, path);
*best_score = score; *best_score = score;
} }
if (recurse_limit) { if (recurse_limit) {
char *newbase; char *newbase = xstrfmt("%s%s/", base, path);
newbase = xmalloc(strlen(base) + strlen(path) + 2);
sprintf(newbase, "%s%s/", base, path);
match_trees(elem, hash2, best_score, best_match, match_trees(elem, hash2, best_score, best_match,
newbase, recurse_limit - 1); newbase, recurse_limit - 1);
free(newbase); free(newbase);

View File

@ -603,25 +603,36 @@ static int remove_file(struct merge_options *o, int clean,
return 0; return 0;
} }
/* add a string to a strbuf, but converting "/" to "_" */
static void add_flattened_path(struct strbuf *out, const char *s)
{
size_t i = out->len;
strbuf_addstr(out, s);
for (; i < out->len; i++)
if (out->buf[i] == '/')
out->buf[i] = '_';
}
static char *unique_path(struct merge_options *o, const char *path, const char *branch) static char *unique_path(struct merge_options *o, const char *path, const char *branch)
{ {
char *newpath = xmalloc(strlen(path) + 1 + strlen(branch) + 8 + 1); struct strbuf newpath = STRBUF_INIT;
int suffix = 0; int suffix = 0;
struct stat st; struct stat st;
char *p = newpath + strlen(path); size_t base_len;
strcpy(newpath, path);
*(p++) = '~';
strcpy(p, branch);
for (; *p; ++p)
if ('/' == *p)
*p = '_';
while (string_list_has_string(&o->current_file_set, newpath) ||
string_list_has_string(&o->current_directory_set, newpath) ||
lstat(newpath, &st) == 0)
sprintf(p, "_%d", suffix++);
string_list_insert(&o->current_file_set, newpath); strbuf_addf(&newpath, "%s~", path);
return newpath; add_flattened_path(&newpath, branch);
base_len = newpath.len;
while (string_list_has_string(&o->current_file_set, newpath.buf) ||
string_list_has_string(&o->current_directory_set, newpath.buf) ||
lstat(newpath.buf, &st) == 0) {
strbuf_setlen(&newpath, base_len);
strbuf_addf(&newpath, "_%d", suffix++);
}
string_list_insert(&o->current_file_set, newpath.buf);
return strbuf_detach(&newpath, NULL);
} }
static int dir_in_way(const char *path, int check_working_copy) static int dir_in_way(const char *path, int check_working_copy)
@ -971,14 +982,10 @@ merge_file_special_markers(struct merge_options *o,
char *side2 = NULL; char *side2 = NULL;
struct merge_file_info mfi; struct merge_file_info mfi;
if (filename1) { if (filename1)
side1 = xmalloc(strlen(branch1) + strlen(filename1) + 2); side1 = xstrfmt("%s:%s", branch1, filename1);
sprintf(side1, "%s:%s", branch1, filename1); if (filename2)
} side2 = xstrfmt("%s:%s", branch2, filename2);
if (filename2) {
side2 = xmalloc(strlen(branch2) + strlen(filename2) + 2);
sprintf(side2, "%s:%s", branch2, filename2);
}
mfi = merge_file_1(o, one, a, b, mfi = merge_file_1(o, one, a, b,
side1 ? side1 : branch1, side2 ? side2 : branch2); side1 ? side1 : branch1, side2 ? side2 : branch2);

42
merge.c
View File

@ -18,39 +18,23 @@ int try_merge_command(const char *strategy, size_t xopts_nr,
const char **xopts, struct commit_list *common, const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes) const char *head_arg, struct commit_list *remotes)
{ {
const char **args; struct argv_array args = ARGV_ARRAY_INIT;
int i = 0, x = 0, ret; int i, ret;
struct commit_list *j; struct commit_list *j;
struct strbuf buf = STRBUF_INIT;
args = xmalloc((4 + xopts_nr + commit_list_count(common) + argv_array_pushf(&args, "merge-%s", strategy);
commit_list_count(remotes)) * sizeof(char *)); for (i = 0; i < xopts_nr; i++)
strbuf_addf(&buf, "merge-%s", strategy); argv_array_pushf(&args, "--%s", xopts[i]);
args[i++] = buf.buf;
for (x = 0; x < xopts_nr; x++) {
char *s = xmalloc(strlen(xopts[x])+2+1);
strcpy(s, "--");
strcpy(s+2, xopts[x]);
args[i++] = s;
}
for (j = common; j; j = j->next) for (j = common; j; j = j->next)
args[i++] = xstrdup(merge_argument(j->item)); argv_array_push(&args, merge_argument(j->item));
args[i++] = "--"; argv_array_push(&args, "--");
args[i++] = head_arg; argv_array_push(&args, head_arg);
for (j = remotes; j; j = j->next) for (j = remotes; j; j = j->next)
args[i++] = xstrdup(merge_argument(j->item)); argv_array_push(&args, merge_argument(j->item));
args[i] = NULL;
ret = run_command_v_opt(args, RUN_GIT_CMD); ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
strbuf_release(&buf); argv_array_clear(&args);
i = 1;
for (x = 0; x < xopts_nr; x++)
free((void *)args[i++]);
for (j = common; j; j = j->next)
free((void *)args[i++]);
i += 2;
for (j = remotes; j; j = j->next)
free((void *)args[i++]);
free(args);
discard_cache(); discard_cache();
if (read_cache() < 0) if (read_cache() < 0)
die(_("failed to read the cache")); die(_("failed to read the cache"));

View File

@ -170,7 +170,6 @@ static struct branch *make_branch(const char *name, int len)
{ {
struct branch *ret; struct branch *ret;
int i; int i;
char *refname;
for (i = 0; i < branches_nr; i++) { for (i = 0; i < branches_nr; i++) {
if (len ? (!strncmp(name, branches[i]->name, len) && if (len ? (!strncmp(name, branches[i]->name, len) &&
@ -186,10 +185,7 @@ static struct branch *make_branch(const char *name, int len)
ret->name = xstrndup(name, len); ret->name = xstrndup(name, len);
else else
ret->name = xstrdup(name); ret->name = xstrdup(name);
refname = xmalloc(strlen(name) + strlen("refs/heads/") + 1); ret->refname = xstrfmt("refs/heads/%s", ret->name);
strcpy(refname, "refs/heads/");
strcpy(refname + strlen("refs/heads/"), ret->name);
ret->refname = refname;
return ret; return ret;
} }

View File

@ -361,18 +361,13 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
{ {
struct argv_array array; struct argv_array array;
int rc; int rc;
char *gpg_sign;
argv_array_init(&array); argv_array_init(&array);
argv_array_push(&array, "commit"); argv_array_push(&array, "commit");
argv_array_push(&array, "-n"); argv_array_push(&array, "-n");
if (opts->gpg_sign) { if (opts->gpg_sign)
gpg_sign = xmalloc(3 + strlen(opts->gpg_sign)); argv_array_pushf(&array, "-S%s", opts->gpg_sign);
sprintf(gpg_sign, "-S%s", opts->gpg_sign);
argv_array_push(&array, gpg_sign);
free(gpg_sign);
}
if (opts->signoff) if (opts->signoff)
argv_array_push(&array, "-s"); argv_array_push(&array, "-s");
if (!opts->edit) { if (!opts->edit) {

View File

@ -1240,10 +1240,7 @@ static void diagnose_invalid_sha1_path(const char *prefix,
die("Path '%s' exists on disk, but not in '%.*s'.", die("Path '%s' exists on disk, but not in '%.*s'.",
filename, object_name_len, object_name); filename, object_name_len, object_name);
if (errno == ENOENT || errno == ENOTDIR) { if (errno == ENOENT || errno == ENOTDIR) {
char *fullname = xmalloc(strlen(filename) char *fullname = xstrfmt("%s%s", prefix, filename);
+ strlen(prefix) + 1);
strcpy(fullname, prefix);
strcat(fullname, filename);
if (!get_tree_entry(tree_sha1, fullname, if (!get_tree_entry(tree_sha1, fullname,
sha1, &mode)) { sha1, &mode)) {

View File

@ -46,11 +46,7 @@ static int is_valid_cmd_name(const char *cmd)
static char *make_cmd(const char *prog) static char *make_cmd(const char *prog)
{ {
char *prefix = xmalloc((strlen(prog) + strlen(COMMAND_DIR) + 2)); return xstrfmt("%s/%s", COMMAND_DIR, prog);
strcpy(prefix, COMMAND_DIR);
strcat(prefix, "/");
strcat(prefix, prog);
return prefix;
} }
static void cd_to_homedir(void) static void cd_to_homedir(void)

View File

@ -600,3 +600,22 @@ char *xstrdup_tolower(const char *string)
result[i] = '\0'; result[i] = '\0';
return result; return result;
} }
char *xstrvfmt(const char *fmt, va_list ap)
{
struct strbuf buf = STRBUF_INIT;
strbuf_vaddf(&buf, fmt, ap);
return strbuf_detach(&buf, NULL);
}
char *xstrfmt(const char *fmt, ...)
{
va_list ap;
char *ret;
va_start(ap, fmt);
ret = xstrvfmt(fmt, ap);
va_end(ap);
return ret;
}

View File

@ -187,4 +187,13 @@ extern int fprintf_ln(FILE *fp, const char *fmt, ...);
char *xstrdup_tolower(const char *); char *xstrdup_tolower(const char *);
/*
* Create a newly allocated string using printf format. You can do this easily
* with a strbuf, but this provides a shortcut to save a few lines.
*/
__attribute__((format (printf, 1, 0)))
char *xstrvfmt(const char *fmt, va_list ap);
__attribute__((format (printf, 1, 2)))
char *xstrfmt(const char *fmt, ...);
#endif /* STRBUF_H */ #endif /* STRBUF_H */

View File

@ -56,17 +56,15 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
int i; int i;
const char **msgs = opts->msgs; const char **msgs = opts->msgs;
const char *msg; const char *msg;
char *tmp;
const char *cmd2 = strcmp(cmd, "checkout") ? cmd : "switch branches"; const char *cmd2 = strcmp(cmd, "checkout") ? cmd : "switch branches";
if (advice_commit_before_merge) if (advice_commit_before_merge)
msg = "Your local changes to the following files would be overwritten by %s:\n%%s" msg = "Your local changes to the following files would be overwritten by %s:\n%%s"
"Please, commit your changes or stash them before you can %s."; "Please, commit your changes or stash them before you can %s.";
else else
msg = "Your local changes to the following files would be overwritten by %s:\n%%s"; msg = "Your local changes to the following files would be overwritten by %s:\n%%s";
tmp = xmalloc(strlen(msg) + strlen(cmd) + strlen(cmd2) - 2); msgs[ERROR_WOULD_OVERWRITE] = msgs[ERROR_NOT_UPTODATE_FILE] =
sprintf(tmp, msg, cmd, cmd2); xstrfmt(msg, cmd, cmd2);
msgs[ERROR_WOULD_OVERWRITE] = tmp;
msgs[ERROR_NOT_UPTODATE_FILE] = tmp;
msgs[ERROR_NOT_UPTODATE_DIR] = msgs[ERROR_NOT_UPTODATE_DIR] =
"Updating the following directories would lose untracked files in it:\n%s"; "Updating the following directories would lose untracked files in it:\n%s";
@ -76,12 +74,9 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
"Please move or remove them before you can %s."; "Please move or remove them before you can %s.";
else else
msg = "The following untracked working tree files would be %s by %s:\n%%s"; msg = "The following untracked working tree files would be %s by %s:\n%%s";
tmp = xmalloc(strlen(msg) + strlen(cmd) + strlen("removed") + strlen(cmd2) - 4);
sprintf(tmp, msg, "removed", cmd, cmd2); msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = xstrfmt(msg, "removed", cmd, cmd2);
msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = tmp; msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = xstrfmt(msg, "overwritten", cmd, cmd2);
tmp = xmalloc(strlen(msg) + strlen(cmd) + strlen("overwritten") + strlen(cmd2) - 4);
sprintf(tmp, msg, "overwritten", cmd, cmd2);
msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = tmp;
/* /*
* Special case: ERROR_BIND_OVERLAP refers to a pair of paths, we * Special case: ERROR_BIND_OVERLAP refers to a pair of paths, we

View File

@ -253,7 +253,8 @@ int walker_fetch(struct walker *walker, int targets, char **target,
{ {
struct ref_lock **lock = xcalloc(targets, sizeof(struct ref_lock *)); struct ref_lock **lock = xcalloc(targets, sizeof(struct ref_lock *));
unsigned char *sha1 = xmalloc(targets * 20); unsigned char *sha1 = xmalloc(targets * 20);
char *msg; const char *msg;
char *to_free = NULL;
int ret; int ret;
int i; int i;
@ -285,21 +286,19 @@ int walker_fetch(struct walker *walker, int targets, char **target,
if (loop(walker)) if (loop(walker))
goto unlock_and_fail; goto unlock_and_fail;
if (write_ref_log_details) { if (write_ref_log_details)
msg = xmalloc(strlen(write_ref_log_details) + 12); msg = to_free = xstrfmt("fetch from %s", write_ref_log_details);
sprintf(msg, "fetch from %s", write_ref_log_details); else
} else { msg = "fetch (unknown)";
msg = NULL;
}
for (i = 0; i < targets; i++) { for (i = 0; i < targets; i++) {
if (!write_ref || !write_ref[i]) if (!write_ref || !write_ref[i])
continue; continue;
ret = write_ref_sha1(lock[i], &sha1[20 * i], msg ? msg : "fetch (unknown)"); ret = write_ref_sha1(lock[i], &sha1[20 * i], msg);
lock[i] = NULL; lock[i] = NULL;
if (ret) if (ret)
goto unlock_and_fail; goto unlock_and_fail;
} }
free(msg); free(to_free);
return 0; return 0;
@ -307,6 +306,7 @@ unlock_and_fail:
for (i = 0; i < targets; i++) for (i = 0; i < targets; i++)
if (lock[i]) if (lock[i])
unlock_ref(lock[i]); unlock_ref(lock[i]);
free(to_free);
return -1; return -1;
} }