Skip to content

Commit d75bb73

Browse files
committed
Merge branch 'jc/am-state-fix'
Recent reimplementation of "git am" changed the format of state files kept in $GIT_DIR/rebase-apply/ without meaning to do so, primarily because write_file() API was cumbersome to use and it was easy to mistakenly make text files with incomplete lines. Update write_file() interface to make it harder to misuse. * jc/am-state-fix: write_file(): drop caller-supplied LF from calls to create a one-liner file write_file_v(): do not leave incomplete line at the end write_file(): drop "fatal" parameter builtin/am: make sure state files are text builtin/am: introduce write_state_*() helper functions
2 parents 2ba6183 + 1f76a10 commit d75bb73

File tree

10 files changed

+80
-44
lines changed

10 files changed

+80
-44
lines changed

builtin/am.c

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,27 @@ static inline const char *am_path(const struct am_state *state, const char *path
194194
return mkpath("%s/%s", state->dir, path);
195195
}
196196

197+
/**
198+
* For convenience to call write_file()
199+
*/
200+
static int write_state_text(const struct am_state *state,
201+
const char *name, const char *string)
202+
{
203+
return write_file(am_path(state, name), "%s", string);
204+
}
205+
206+
static int write_state_count(const struct am_state *state,
207+
const char *name, int value)
208+
{
209+
return write_file(am_path(state, name), "%d", value);
210+
}
211+
212+
static int write_state_bool(const struct am_state *state,
213+
const char *name, int value)
214+
{
215+
return write_state_text(state, name, value ? "t" : "f");
216+
}
217+
197218
/**
198219
* If state->quiet is false, calls fprintf(fp, fmt, ...), and appends a newline
199220
* at the end.
@@ -363,7 +384,7 @@ static void write_author_script(const struct am_state *state)
363384
sq_quote_buf(&sb, state->author_date);
364385
strbuf_addch(&sb, '\n');
365386

366-
write_file(am_path(state, "author-script"), 1, "%s", sb.buf);
387+
write_state_text(state, "author-script", sb.buf);
367388

368389
strbuf_release(&sb);
369390
}
@@ -1001,13 +1022,10 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
10011022
if (state->rebasing)
10021023
state->threeway = 1;
10031024

1004-
write_file(am_path(state, "threeway"), 1, state->threeway ? "t" : "f");
1005-
1006-
write_file(am_path(state, "quiet"), 1, state->quiet ? "t" : "f");
1007-
1008-
write_file(am_path(state, "sign"), 1, state->signoff ? "t" : "f");
1009-
1010-
write_file(am_path(state, "utf8"), 1, state->utf8 ? "t" : "f");
1025+
write_state_bool(state, "threeway", state->threeway);
1026+
write_state_bool(state, "quiet", state->quiet);
1027+
write_state_bool(state, "sign", state->signoff);
1028+
write_state_bool(state, "utf8", state->utf8);
10111029

10121030
switch (state->keep) {
10131031
case KEEP_FALSE:
@@ -1023,9 +1041,8 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
10231041
die("BUG: invalid value for state->keep");
10241042
}
10251043

1026-
write_file(am_path(state, "keep"), 1, "%s", str);
1027-
1028-
write_file(am_path(state, "messageid"), 1, state->message_id ? "t" : "f");
1044+
write_state_text(state, "keep", str);
1045+
write_state_bool(state, "messageid", state->message_id);
10291046

10301047
switch (state->scissors) {
10311048
case SCISSORS_UNSET:
@@ -1040,24 +1057,23 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
10401057
default:
10411058
die("BUG: invalid value for state->scissors");
10421059
}
1043-
1044-
write_file(am_path(state, "scissors"), 1, "%s", str);
1060+
write_state_text(state, "scissors", str);
10451061

10461062
sq_quote_argv(&sb, state->git_apply_opts.argv, 0);
1047-
write_file(am_path(state, "apply-opt"), 1, "%s", sb.buf);
1063+
write_state_text(state, "apply-opt", sb.buf);
10481064

10491065
if (state->rebasing)
1050-
write_file(am_path(state, "rebasing"), 1, "%s", "");
1066+
write_state_text(state, "rebasing", "");
10511067
else
1052-
write_file(am_path(state, "applying"), 1, "%s", "");
1068+
write_state_text(state, "applying", "");
10531069

10541070
if (!get_sha1("HEAD", curr_head)) {
1055-
write_file(am_path(state, "abort-safety"), 1, "%s", sha1_to_hex(curr_head));
1071+
write_state_text(state, "abort-safety", sha1_to_hex(curr_head));
10561072
if (!state->rebasing)
10571073
update_ref("am", "ORIG_HEAD", curr_head, NULL, 0,
10581074
UPDATE_REFS_DIE_ON_ERR);
10591075
} else {
1060-
write_file(am_path(state, "abort-safety"), 1, "%s", "");
1076+
write_state_text(state, "abort-safety", "");
10611077
if (!state->rebasing)
10621078
delete_ref("ORIG_HEAD", NULL, 0);
10631079
}
@@ -1067,9 +1083,8 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
10671083
* session is in progress, they should be written last.
10681084
*/
10691085

1070-
write_file(am_path(state, "next"), 1, "%d", state->cur);
1071-
1072-
write_file(am_path(state, "last"), 1, "%d", state->last);
1086+
write_state_count(state, "next", state->cur);
1087+
write_state_count(state, "last", state->last);
10731088

10741089
strbuf_release(&sb);
10751090
}
@@ -1102,12 +1117,12 @@ static void am_next(struct am_state *state)
11021117
unlink(am_path(state, "original-commit"));
11031118

11041119
if (!get_sha1("HEAD", head))
1105-
write_file(am_path(state, "abort-safety"), 1, "%s", sha1_to_hex(head));
1120+
write_state_text(state, "abort-safety", sha1_to_hex(head));
11061121
else
1107-
write_file(am_path(state, "abort-safety"), 1, "%s", "");
1122+
write_state_text(state, "abort-safety", "");
11081123

11091124
state->cur++;
1110-
write_file(am_path(state, "next"), 1, "%d", state->cur);
1125+
write_state_count(state, "next", state->cur);
11111126
}
11121127

11131128
/**
@@ -1480,8 +1495,7 @@ static int parse_mail_rebase(struct am_state *state, const char *mail)
14801495
write_commit_patch(state, commit);
14811496

14821497
hashcpy(state->orig_commit, commit_sha1);
1483-
write_file(am_path(state, "original-commit"), 1, "%s",
1484-
sha1_to_hex(commit_sha1));
1498+
write_state_text(state, "original-commit", sha1_to_hex(commit_sha1));
14851499

14861500
return 0;
14871501
}
@@ -1783,7 +1797,7 @@ static void am_run(struct am_state *state, int resume)
17831797
refresh_and_write_cache();
17841798

17851799
if (index_has_changes(&sb)) {
1786-
write_file(am_path(state, "dirtyindex"), 1, "t");
1800+
write_state_bool(state, "dirtyindex", 1);
17871801
die(_("Dirty index: cannot apply patches (dirty: %s)"), sb.buf);
17881802
}
17891803

builtin/branch.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ static int edit_branch_description(const char *branch_name)
776776
" %s\n"
777777
"Lines starting with '%c' will be stripped.\n",
778778
branch_name, comment_line_char);
779-
if (write_file(git_path(edit_description), 0, "%s", buf.buf)) {
779+
if (write_file_gently(git_path(edit_description), "%s", buf.buf)) {
780780
strbuf_release(&buf);
781781
return error(_("could not write branch description template: %s"),
782782
strerror(errno));

builtin/init-db.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ static void separate_git_dir(const char *git_dir)
378378
die_errno(_("unable to move %s to %s"), src, git_dir);
379379
}
380380

381-
write_file(git_link, 1, "gitdir: %s\n", git_dir);
381+
write_file(git_link, "gitdir: %s", git_dir);
382382
}
383383

384384
int init_db(const char *template_dir, unsigned int flags)

builtin/worktree.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ static int add_worktree(const char *path, const char *refname,
238238
* after the preparation is over.
239239
*/
240240
strbuf_addf(&sb, "%s/locked", sb_repo.buf);
241-
write_file(sb.buf, 1, "initializing\n");
241+
write_file(sb.buf, "initializing");
242242

243243
strbuf_addf(&sb_git, "%s/.git", path);
244244
if (safe_create_leading_directories_const(sb_git.buf))
@@ -248,8 +248,8 @@ static int add_worktree(const char *path, const char *refname,
248248

249249
strbuf_reset(&sb);
250250
strbuf_addf(&sb, "%s/gitdir", sb_repo.buf);
251-
write_file(sb.buf, 1, "%s\n", real_path(sb_git.buf));
252-
write_file(sb_git.buf, 1, "gitdir: %s/worktrees/%s\n",
251+
write_file(sb.buf, "%s", real_path(sb_git.buf));
252+
write_file(sb_git.buf, "gitdir: %s/worktrees/%s",
253253
real_path(get_git_common_dir()), name);
254254
/*
255255
* This is to keep resolve_ref() happy. We need a valid HEAD
@@ -260,10 +260,10 @@ static int add_worktree(const char *path, const char *refname,
260260
*/
261261
strbuf_reset(&sb);
262262
strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
263-
write_file(sb.buf, 1, "0000000000000000000000000000000000000000\n");
263+
write_file(sb.buf, "0000000000000000000000000000000000000000");
264264
strbuf_reset(&sb);
265265
strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
266-
write_file(sb.buf, 1, "../..\n");
266+
write_file(sb.buf, "../..");
267267

268268
fprintf_ln(stderr, _("Preparing %s (identifier %s)"), path, name);
269269

cache.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,8 +1577,9 @@ static inline ssize_t write_str_in_full(int fd, const char *str)
15771577
{
15781578
return write_in_full(fd, str, strlen(str));
15791579
}
1580-
__attribute__((format (printf, 3, 4)))
1581-
extern int write_file(const char *path, int fatal, const char *fmt, ...);
1580+
1581+
extern int write_file(const char *path, const char *fmt, ...);
1582+
extern int write_file_gently(const char *path, const char *fmt, ...);
15821583

15831584
/* pager.c */
15841585
extern void setup_pager(void);

daemon.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,7 @@ int main(int argc, char **argv)
13761376
sanitize_stdfds();
13771377

13781378
if (pid_file)
1379-
write_file(pid_file, 1, "%"PRIuMAX"\n", (uintmax_t) getpid());
1379+
write_file(pid_file, "%"PRIuMAX, (uintmax_t) getpid());
13801380

13811381
/* prepare argv for serving-processes */
13821382
cld_argv = xmalloc(sizeof (char *) * (argc + 2));

setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ static void update_linked_gitdir(const char *gitfile, const char *gitdir)
404404

405405
strbuf_addf(&path, "%s/gitfile", gitdir);
406406
if (stat(path.buf, &st) || st.st_mtime + 24 * 3600 < time(NULL))
407-
write_file(path.buf, 0, "%s\n", gitfile);
407+
write_file_gently(path.buf, "%s", gitfile);
408408
strbuf_release(&path);
409409
}
410410

submodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,7 @@ void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir)
10331033

10341034
/* Update gitfile */
10351035
strbuf_addf(&file_name, "%s/.git", work_tree);
1036-
write_file(file_name.buf, 1, "gitdir: %s\n",
1036+
write_file(file_name.buf, "gitdir: %s",
10371037
relative_path(git_dir, real_work_tree, &rel_path));
10381038

10391039
/* Update core.worktree setting */

transport.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ static int write_one_ref(const char *name, const struct object_id *oid,
291291

292292
strbuf_addstr(buf, name);
293293
if (safe_create_leading_directories(buf->buf) ||
294-
write_file(buf->buf, 0, "%s\n", oid_to_hex(oid)))
294+
write_file_gently(buf->buf, "%s", oid_to_hex(oid)))
295295
return error("problems writing temporary file %s: %s",
296296
buf->buf, strerror(errno));
297297
strbuf_setlen(buf, len);

wrapper.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -621,19 +621,18 @@ char *xgetcwd(void)
621621
return strbuf_detach(&sb, NULL);
622622
}
623623

624-
int write_file(const char *path, int fatal, const char *fmt, ...)
624+
static int write_file_v(const char *path, int fatal,
625+
const char *fmt, va_list params)
625626
{
626627
struct strbuf sb = STRBUF_INIT;
627-
va_list params;
628628
int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0666);
629629
if (fd < 0) {
630630
if (fatal)
631631
die_errno(_("could not open %s for writing"), path);
632632
return -1;
633633
}
634-
va_start(params, fmt);
635634
strbuf_vaddf(&sb, fmt, params);
636-
va_end(params);
635+
strbuf_complete_line(&sb);
637636
if (write_in_full(fd, sb.buf, sb.len) != sb.len) {
638637
int err = errno;
639638
close(fd);
@@ -652,6 +651,28 @@ int write_file(const char *path, int fatal, const char *fmt, ...)
652651
return 0;
653652
}
654653

654+
int write_file(const char *path, const char *fmt, ...)
655+
{
656+
int status;
657+
va_list params;
658+
659+
va_start(params, fmt);
660+
status = write_file_v(path, 1, fmt, params);
661+
va_end(params);
662+
return status;
663+
}
664+
665+
int write_file_gently(const char *path, const char *fmt, ...)
666+
{
667+
int status;
668+
va_list params;
669+
670+
va_start(params, fmt);
671+
status = write_file_v(path, 0, fmt, params);
672+
va_end(params);
673+
return status;
674+
}
675+
655676
void sleep_millisec(int millisec)
656677
{
657678
poll(NULL, 0, millisec);

0 commit comments

Comments
 (0)