From e1f898639e906158fec26bdf3111d6f623288fa1 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 14 Jan 2016 17:57:55 +0100 Subject: interpret-trailers: add option for in-place editing Add a command line option --in-place to support in-place editing akin to sed -i. This allows to write commands like the following: git interpret-trailers --trailer "X: Y" a.txt > b.txt && mv b.txt a.txt in a more concise way: git interpret-trailers --trailer "X: Y" --in-place a.txt Signed-off-by: Tobias Klauser Signed-off-by: Junio C Hamano --- trailer.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'trailer.c') diff --git a/trailer.c b/trailer.c index 176fac2134..94b387b499 100644 --- a/trailer.c +++ b/trailer.c @@ -2,6 +2,7 @@ #include "string-list.h" #include "run-command.h" #include "commit.h" +#include "tempfile.h" #include "trailer.h" /* * Copyright (c) 2013, 2014 Christian Couder @@ -843,7 +844,38 @@ static void free_all(struct trailer_item **first) } } -void process_trailers(const char *file, int trim_empty, struct string_list *trailers) +static struct tempfile trailers_tempfile; + +static FILE *create_in_place_tempfile(const char *file) +{ + struct stat st; + struct strbuf template = STRBUF_INIT; + const char *tail; + FILE *outfile; + + if (stat(file, &st)) + die_errno(_("could not stat %s"), file); + if (!S_ISREG(st.st_mode)) + die(_("file %s is not a regular file"), file); + if (!(st.st_mode & S_IWUSR)) + die(_("file %s is not writable by user"), file); + + /* Create temporary file in the same directory as the original */ + tail = strrchr(file, '/'); + if (tail != NULL) + strbuf_add(&template, file, tail - file + 1); + strbuf_addstr(&template, "git-interpret-trailers-XXXXXX"); + + xmks_tempfile_m(&trailers_tempfile, template.buf, st.st_mode); + strbuf_release(&template); + outfile = fdopen_tempfile(&trailers_tempfile, "w"); + if (!outfile) + die_errno(_("could not open temporary file")); + + return outfile; +} + +void process_trailers(const char *file, int in_place, int trim_empty, struct string_list *trailers) { struct trailer_item *in_tok_first = NULL; struct trailer_item *in_tok_last = NULL; @@ -858,6 +890,9 @@ void process_trailers(const char *file, int trim_empty, struct string_list *trai lines = read_input_file(file); + if (in_place) + outfile = create_in_place_tempfile(file); + /* Print the lines before the trailers */ trailer_end = process_input_file(outfile, lines, &in_tok_first, &in_tok_last); @@ -872,5 +907,9 @@ void process_trailers(const char *file, int trim_empty, struct string_list *trai /* Print the lines after the trailers as is */ print_lines(outfile, lines, trailer_end, INT_MAX); + if (in_place) + if (rename_tempfile(&trailers_tempfile, file)) + die_errno(_("could not rename temporary file to %s"), file); + strbuf_list_free(lines); } -- cgit v1.2.1