summaryrefslogtreecommitdiff
path: root/trailer.c
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2016-01-14 16:57:55 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-01-14 20:22:17 (GMT)
commite1f898639e906158fec26bdf3111d6f623288fa1 (patch)
tree39d2eea730efc4fcf6473f19e09e05b500b15a7d /trailer.c
parentd0d2344ad84cde7fddedc1e141296607af673454 (diff)
downloadgit-e1f898639e906158fec26bdf3111d6f623288fa1.zip
git-e1f898639e906158fec26bdf3111d6f623288fa1.tar.gz
git-e1f898639e906158fec26bdf3111d6f623288fa1.tar.bz2
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 <tklauser@distanz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'trailer.c')
-rw-r--r--trailer.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/trailer.c b/trailer.c
index 176fac2..94b387b 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 <chriscool@tuxfamily.org>
@@ -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);
}