git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Guido Martínez via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Guido Martínez" <mtzguido@gmail.com>,
	"Guido Martínez" <mtzguido@gmail.com>
Subject: [PATCH] ls-files: add an --exclude-links option
Date: Wed, 21 Jun 2023 06:08:04 +0000	[thread overview]
Message-ID: <pull.1549.git.1687327684909.gitgitgadget@gmail.com> (raw)

From: =?UTF-8?q?Guido=20Mart=C3=ADnez?= <mtzguido@gmail.com>

Add an option to exclude symlinks from the listed files. This is useful
in case we are listing the files in order to process the contents,
for instance to do some text replacement with `sed -i`. In that case,
there is no point in processing the links, and it could even be
counterproductive as some tools (like sed) will replace the link with a
fresh regular file.

This option enables a straightforward implementation of a `git sed`:

    #!/bin/bash
    git ls-files --exclude-links -z | xargs -0 -P $(nproc) -- sed -i -e "$@"

Signed-off-by: Guido Martínez <mtzguido@gmail.com>
---
    ls-files: add an --exclude-links option
    
    Hi, not sure if this is desirable, but I found it very useful to
    implement the git sed shown in the commit message to do some
    replacements in a big repo. I placed the option right after
    --exclude-standard and (I think) updated the relevant docs. The flag
    applies to all modes: -c, -d, -m and -o, though I think it's mostly
    useful on the default -c.
    
    Also is there interest in a standard git sed?

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1549%2Fmtzguido%2Fls_files_exclude_links-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1549/mtzguido/ls_files_exclude_links-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1549

 Documentation/git-ls-files.txt |  5 ++++-
 builtin/ls-files.c             | 10 ++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index 1bc0328bb78..138ba49bd8c 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -18,7 +18,7 @@ SYNOPSIS
 		[-x <pattern>|--exclude=<pattern>]
 		[-X <file>|--exclude-from=<file>]
 		[--exclude-per-directory=<file>]
-		[--exclude-standard]
+		[--exclude-standard] [--exclude-links]
 		[--error-unmatch] [--with-tree=<tree-ish>]
 		[--full-name] [--recurse-submodules]
 		[--abbrev[=<n>]] [--format=<format>] [--] [<file>...]
@@ -126,6 +126,9 @@ OPTIONS
 	Add the standard Git exclusions: .git/info/exclude, .gitignore
 	in each directory, and the user's global exclusion file.
 
+--exclude-links::
+	Do not list symbolic links.
+
 --error-unmatch::
 	If any <file> does not appear in the index, treat this as an
 	error (return 1).
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 72012c0f0f7..0826e89a496 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -46,6 +46,7 @@ static int show_eol;
 static int recurse_submodules;
 static int skipping_duplicates;
 static int show_sparse_dirs;
+static int exclude_links;
 
 static const char *prefix;
 static int max_prefix_len;
@@ -171,6 +172,11 @@ static void show_other_files(struct index_state *istate,
 		struct dir_entry *ent = dir->entries[i];
 		if (!index_name_is_other(istate, ent->name, ent->len))
 			continue;
+		if (exclude_links) {
+			struct stat st;
+			if (!lstat(ent->name, &st) && S_ISLNK(st.st_mode))
+				continue;
+		}
 		show_dir_entry(istate, tag_other, ent);
 	}
 }
@@ -451,6 +457,8 @@ static void show_files(struct repository *repo, struct dir_struct *dir)
 			continue;
 		if (ce->ce_flags & CE_UPDATE)
 			continue;
+		if (exclude_links && S_ISLNK(ce->ce_mode))
+			continue;
 		if ((show_cached || show_stage) &&
 		    (!show_unmerged || ce_stage(ce))) {
 			show_ce(repo, dir, ce, fullname.buf,
@@ -780,6 +788,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 			N_("add the standard git exclusions"),
 			PARSE_OPT_NOARG | PARSE_OPT_NONEG,
 			option_parse_exclude_standard),
+		OPT_BOOL(0, "exclude-links", &exclude_links,
+			 N_("do not print symbolic links")),
 		OPT_SET_INT_F(0, "full-name", &prefix_len,
 			      N_("make the output relative to the project top directory"),
 			      0, PARSE_OPT_NONEG),

base-commit: 6640c2d06d112675426cf436f0594f0e8c614848
-- 
gitgitgadget

             reply	other threads:[~2023-06-21  6:08 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-21  6:08 Guido Martínez via GitGitGadget [this message]
2023-06-21  8:17 ` [PATCH] ls-files: add an --exclude-links option Jeff King
2023-06-21 15:19   ` Guido Martínez
2023-06-21 16:08   ` Junio C Hamano
2023-06-21 17:54     ` Guido Martínez
2023-06-21 19:47       ` Junio C Hamano
2023-06-21 20:02         ` Guido Martínez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=pull.1549.git.1687327684909.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=mtzguido@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).