]> git.ipfire.org Git - thirdparty/git.git/commitdiff
pathspec: add new function to parse file
authorAlexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
Tue, 19 Nov 2019 16:48:51 +0000 (16:48 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 20 Nov 2019 04:01:53 +0000 (13:01 +0900)
This will be used to support the new option '--pathspec-from-file' in
`git add`, `git-commit`, `git reset` etc.

Note also that we specifically handle CR/LF line endings to support
Windows better.

To simplify code, file is first parsed into `argv_array`. This allows
to avoid refactoring `parse_pathspec()`.

I considered adding `nul_term_line` to `flags` instead, but decided
that it doesn't fit there.

The new code is mostly taken from `cmd_update_index()` and
`split_mail_conv()`.

Co-authored-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
pathspec.c
pathspec.h

index 12c2b322b30a59d2091d2c87df1bed88246d5950..128f27fcb7ae8c88b0f7143943ea8a7171a83c5d 100644 (file)
@@ -3,6 +3,8 @@
 #include "dir.h"
 #include "pathspec.h"
 #include "attr.h"
+#include "argv-array.h"
+#include "quote.h"
 
 /*
  * Finds which of the given pathspecs match items in the index.
@@ -613,6 +615,42 @@ void parse_pathspec(struct pathspec *pathspec,
        }
 }
 
+void parse_pathspec_file(struct pathspec *pathspec, unsigned magic_mask,
+                        unsigned flags, const char *prefix,
+                        const char *file, int nul_term_line)
+{
+       struct argv_array parsed_file = ARGV_ARRAY_INIT;
+       strbuf_getline_fn getline_fn = nul_term_line ? strbuf_getline_nul :
+                                                      strbuf_getline;
+       struct strbuf buf = STRBUF_INIT;
+       struct strbuf unquoted = STRBUF_INIT;
+       FILE *in;
+
+       if (!strcmp(file, "-"))
+               in = stdin;
+       else
+               in = xfopen(file, "r");
+
+       while (getline_fn(&buf, in) != EOF) {
+               if (!nul_term_line && buf.buf[0] == '"') {
+                       strbuf_reset(&unquoted);
+                       if (unquote_c_style(&unquoted, buf.buf, NULL))
+                               die(_("line is badly quoted: %s"), buf.buf);
+                       strbuf_swap(&buf, &unquoted);
+               }
+               argv_array_push(&parsed_file, buf.buf);
+               strbuf_reset(&buf);
+       }
+
+       strbuf_release(&unquoted);
+       strbuf_release(&buf);
+       if (in != stdin)
+               fclose(in);
+
+       parse_pathspec(pathspec, magic_mask, flags, prefix, parsed_file.argv);
+       argv_array_clear(&parsed_file);
+}
+
 void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
 {
        int i, j;
index 1c18a2c90c4148471f52e27c39685e80a9a414e1..a27dc81ba214f3ed553ff249494a93efba7783bb 100644 (file)
@@ -85,6 +85,16 @@ void parse_pathspec(struct pathspec *pathspec,
                    unsigned flags,
                    const char *prefix,
                    const char **args);
+/*
+ * Same as parse_pathspec() but uses file as input.
+ * When 'file' is exactly "-" it uses 'stdin' instead.
+ */
+void parse_pathspec_file(struct pathspec *pathspec,
+                        unsigned magic_mask,
+                        unsigned flags,
+                        const char *prefix,
+                        const char *file,
+                        int nul_term_line);
 void copy_pathspec(struct pathspec *dst, const struct pathspec *src);
 void clear_pathspec(struct pathspec *);