diff mbox series

[v2,2/6] pathspec: add new function to parse file

Message ID 96697ba0724caee556f21ada3959c4190d80c0b9.1573055478.git.gitgitgadget@gmail.com (mailing list archive)
State New, archived
Headers show
Series Add --pathspec-from-file option for reset, commit | expand

Commit Message

John Passaro via GitGitGadget Nov. 6, 2019, 3:51 p.m. UTC
From: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>

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>
---
 pathspec.c | 38 ++++++++++++++++++++++++++++++++++++++
 pathspec.h | 10 ++++++++++
 2 files changed, 48 insertions(+)

Comments

Junio C Hamano Nov. 19, 2019, 5:59 a.m. UTC | #1
"Alexandr Miloslavskiy via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> +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 = NULL;

Useless initialization to NULL can be dropped here.

> +	if (!strcmp(file, "-"))
> +		in = stdin;
> +	else
> +		in = xfopen(file, "r");
Alexandr Miloslavskiy Nov. 19, 2019, 4:50 p.m. UTC | #2
On 19.11.2019 6:59, Junio C Hamano wrote:
>> +	FILE *in = NULL;
> 
> Useless initialization to NULL can be dropped here.

Changed in V3.
diff mbox series

Patch

diff --git a/pathspec.c b/pathspec.c
index 12c2b322b3..2e9b376318 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -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 = NULL;
+
+	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;
diff --git a/pathspec.h b/pathspec.h
index 1c18a2c90c..a27dc81ba2 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -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 *);