threads / patch / 51952

patchgitignore: ignore comments on the same line as a pattern

Subject: [PATCH 0/1] gitignore: ignore comments on the same line as a pattern

## tl;dr

4 messages between Oct 2, 2019 and Oct 2, 2019. Diffs are folded; open one to read it.

replies: 3people: 2as markdown or json

Chris Zehner via GitGitGadget· Oct 2, 2019, 03:13 UTC · lore

Why make this change? =====================

Add the ability to use # to put comments after ignore patterns. This is useful for documenting the reason for particular ignore patterns inclusion and structure.

Right now a common convention in .gitignore files is to group patterns by similarity, using new lines beginning with one or more # characters as headings to explain these groupings. This works well when clarifying why broad classes of things are ignored, e.g. # build artifacts followed by several patterns.

When leaving comments about a particular pattern it can be difficult to distinguish comments about a single patterns from comments used for file organization.

Comments left after a pattern are unambiguously related to that line, and that line only.

What should this change do? ===========================

The entirety of a string after a non-escaped #, including the #, is removed from the pattern in a .gitignore file.

Why make the change this way? =============================

I don't normally write C, so I probably overlooked more idiomatic ways to do this. This is done similarly to the way trim_trailing_spaces removes extraneous spaces from patterns.

Potentially this change could be combined with the existing code for trim_trailing_spaces, but the logic is slightly different and it seems to me that the difference in naming aids readability by making it clear what the responsibilities are for each function.

How can we test this change works? ==================================

That's one area I'd like help with, please.
Test cases:

/pattern/to/match # Existing comment /pattern/with/comment # This comment is ignored /pattern/with/\#octothorpe # \#octothorpe is ignored

I wasn't sure where the correct place to add these would be, I didn't see (and potentially overlooked) any tests in /t/* that cover this functionality. Would someone be willing to provide a pointer to the correct place to add these tests?

Signed-off-by: Chris Zehner cbzehner@gmail.com [cbzehner@gmail.com]
Chris Zehner (1):
  gitignore: ignore comments on the same line as a pattern
 Documentation/gitignore.txt |  8 ++++++--
 dir.c                       | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 2 deletions(-)
base-commit: bc12974a897308fd3254cf0cc90319078fe45eea
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-370%2Fcbzehner%2Fgitignore-pattern-comment-oneline-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-370/cbzehner/gitignore-pattern-comment-oneline-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/370
-- 
gitgitgadget
Chris Zehner via GitGitGadget· Oct 2, 2019, 03:13 UTC · re: Chris Zehner via GitGitGadget · lore

[PATCH 1/1] gitignore: ignore comments on the same line as a pattern

From: Chris Zehner <cbzehner@gmail.com>
Signed-off-by: Chris Zehner <cbzehner@gmail.com>
---
 Documentation/gitignore.txt |  8 ++++++--
 dir.c                       | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 2 deletions(-)
Show changes to 2 files +39 −2

Documentation/gitignore.txt, dir.c

diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index d47b1ae296..1778cf1d38 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -74,8 +74,12 @@ PATTERN FORMAT
    for readability.
 
  - A line starting with # serves as a comment.
-   Put a backslash ("`\`") in front of the first hash for patterns
-   that begin with a hash.
+   Put a backslash ("`\`") in front of each hash for patterns
+   containing a hash.
+
+ - A # after a pattern will be treated as the start of a comment.
+   Put a backslash ("`\`") in front of each hash for patterns
+   containing a hash.
 
  - Trailing spaces are ignored unless they are quoted with backslash
    ("`\`").
diff --git a/dir.c b/dir.c
index cab9c2a458..aeefe142bc 100644
--- a/dir.c
+++ b/dir.c
@@ -658,6 +658,38 @@ void clear_pattern_list(struct pattern_list *pl)
 	memset(pl, 0, sizeof(*pl));
 }
 
+static void trim_trailing_comments(char *buf)
+{
+	char *p, *last_hash = NULL;
+	int escape_seq = 0;
+
+	for (p = buf; *p; p++)
+	{
+		if (!*p)
+			return;
+		switch (*p) {
+		case '#':
+			if (escape_seq)
+			{
+				escape_seq = 0;
+				p++;
+				break;
+			}
+			if (!last_hash)
+				last_hash = p;
+			break;
+		case '\\':
+			escape_seq = 1;
+			break;
+		default:
+			escape_seq = 0;
+		}
+	}
+
+	if (last_hash)
+		*last_hash = '\0';
+}
+
 static void trim_trailing_spaces(char *buf)
 {
 	char *p, *last_space = NULL;
@@ -859,6 +891,7 @@ static int add_patterns_from_buffer(char *buf, size_t size,
 		if (buf[i] == '\n') {
 			if (entry != buf + i && entry[0] != '#') {
 				buf[i - (i && buf[i-1] == '\r')] = 0;
+				trim_trailing_comments(entry);
 				trim_trailing_spaces(entry);
 				add_pattern(entry, base, baselen, pl, lineno);
 			}
-- 
gitgitgadget
Junio C Hamano· Oct 2, 2019, 07:02 UTC · re: Chris Zehner via GitGitGadget · lore

Re: [PATCH 1/1] gitignore: ignore comments on the same line as a pattern

"Chris Zehner via GitGitGadget" <gitgitgadget@gmail.com> writes:
Show 7 quoted lines
> -   that begin with a hash.
> +   Put a backslash ("`\`") in front of each hash for patterns
> +   containing a hash.
> +
> + - A # after a pattern will be treated as the start of a comment.
> +   Put a backslash ("`\`") in front of each hash for patterns
> +   containing a hash.

Besides being backward incompatible, this looks somewhat misdesigned by lacking a way to escape a backslash (i.e. what should a project do if they want a patttern with backslash followed by a hash literally in there?).

Show 15 quoted lines
> diff --git a/dir.c b/dir.c
> index cab9c2a458..aeefe142bc 100644
> --- a/dir.c
> +++ b/dir.c
> @@ -658,6 +658,38 @@ void clear_pattern_list(struct pattern_list *pl)
>  	memset(pl, 0, sizeof(*pl));
>  }
>  
> +static void trim_trailing_comments(char *buf)
> +{
> +	char *p, *last_hash = NULL;
> +	int escape_seq = 0;
> +
> +	for (p = buf; *p; p++)
> +	{

Style (see Documentation/CodingGuidelines). The opening parenthesis of a control structure like if/for/switch are placed on the same line, i.e.

	for (p = buf; *p; p++) {
Do we even need a separate 'p', instead of scanning with 'buf' itself?
> +		if (!*p)
> +			return;

What happens when an entry ends with '\' followed by an EOL? IOW, what if escape_seq is true here?

Show 14 quoted lines
> +		switch (*p) {
> +		case '#':
> +			if (escape_seq)
> +			{
> +				escape_seq = 0;
> +				p++;
> +				break;
> +			}
> +			if (!last_hash)
> +				last_hash = p;
> +			break;
> +		case '\\':
> +			escape_seq = 1;
> +			break;
Junio C Hamano· Oct 2, 2019, 06:51 UTC · re: Chris Zehner via GitGitGadget · lore

Re: [PATCH 0/1] gitignore: ignore comments on the same line as a pattern

"Chris Zehner via GitGitGadget" <gitgitgadget@gmail.com> writes:
Show 16 quoted lines
> Why make this change?
> =====================
>
> Add the ability to use # to put comments after ignore patterns. This is
> useful for documenting the reason for particular ignore patterns inclusion
> and structure.
>
> Right now a common convention in .gitignore files is to group patterns by
> similarity, using new lines beginning with one or more # characters as
> headings to explain these groupings. This works well when clarifying why
> broad classes of things are ignored, e.g. # build artifacts followed by
> several patterns.
>
> When leaving comments about a particular pattern it can be difficult to
> distinguish comments about a single patterns from comments used for file
> organization.

Not a good enough justification to break backward compatibility, I would have to say. If a single line is so tricky to deserve its own comment, perhaps a group of lines can be separated with the next group by a handful of blank lines for clarity (or the project can adopt a convention that differentiates between comments on a group and comments on an individual rule).

← back to recent threads