Skip to contentSkip to conversation

How to list versioned files with modification status

DISCUSSION Mark Burton 6 participants 9 messages Jun 15, 2016

lore
Share & tools
lore
#0 lore raw

Hi,

I would like to be able to easily find those files in a git tree that don't have pending modifications. Although ls-files can list the files that are modified, it can't list those that aren't or list all files with their modification status.

Thanks,

Mark

Signature · 2 lines
Smart Avionics Ltd. -- producer of innovative avionics for homebuilt
aircraft.
#1 lore raw
Quoted 4 lines · Mark Burton

I would like to be able to easily find those files in a git tree that don't have pending modifications. Although ls-files can list the files that are modified, it can't list those that aren't

Well, it is a rather unusual task to have a special option devoted to it, and you always combine a few commands together like that:

comm -3 <(git ls-files|sort) <(git ls-files -m|sort)

Dmitry

#2 lore raw
In reply to Mark Burton

2008/10/4 Mark Burton <[email protected]>:

Quoted 4 lines

I would like to be able to easily find those files in a git tree that don't have pending modifications. Although ls-files can list the files that are modified, it can't list those that aren't or list all files with their modification status.

Maybe if you look at git diff and diff-index, you will find something what suits you better? Because "modification" is just a difference between a known (recorded in a commit or index) state and your working tree.

#3 lore raw
Quoted 7 lines · Alex Riesen <raa.lkml <at> gmail.com> writes:

2008/10/4 Mark Burton <markb <at> smartavionics.com>:

Quoted 4 lines

I would like to be able to easily find those files in a git tree that don't have pending modifications. Although ls-files can list the files that are modified, it can't list those that aren't or list all files with their modification status.

Quoted 5 lines

Maybe if you look at git diff and diff-index, you will find something what suits you better? Because "modification" is just a difference between a known (recorded in a commit or index) state and your working tree.

'git diff --name-status' looks useful but it only shows the files that have changed - I would like to see the names of the files that haven't changed. Even svn could do that (svn status).

Thanks,

Mark

#4 lore raw

2008/10/5 Mark Burton <[email protected]>:

Quoted 7 lines
Quoted 6 lines · Alex Riesen <raa.lkml <at> gmail.com> writes:

2008/10/4 Mark Burton <markb <at> smartavionics.com>:

Quoted 4 lines

I would like to be able to easily find those files in a git tree that don't have pending modifications. Although ls-files can list the files that are modified, it can't list those that aren't or list all files with their modification status.

Quoted 7 lines
Quoted 4 lines

Maybe if you look at git diff and diff-index, you will find something what suits you better? Because "modification" is just a difference between a known (recorded in a commit or index) state and your working tree.

'git diff --name-status' looks useful but it only shows the files that have changed - I would like to see the names of the files that haven't changed.

There is nothing to do something like that, but...

Quoted 1 line

Even svn could do that (svn status).

what exactly are trying to achieve? It is just strange that no one asked for something like this before...

#5 lore raw
Quoted 16 lines · Alex Riesen

2008/10/5 Mark Burton <[email protected]>:

Quoted 7 lines
Quoted 6 lines · Alex Riesen <raa.lkml <at> gmail.com> writes:

2008/10/4 Mark Burton <markb <at> smartavionics.com>:

Quoted 4 lines

I would like to be able to easily find those files in a git tree that don't have pending modifications. Although ls-files can list the files that are modified, it can't list those that aren't or list all files with their modification status.

Quoted 7 lines
Quoted 4 lines

Maybe if you look at git diff and diff-index, you will find something what suits you better? Because "modification" is just a difference between a known (recorded in a commit or index) state and your working tree.

'git diff --name-status' looks useful but it only shows the files that have changed - I would like to see the names of the files that haven't changed.

Quoted 6 lines

There is nothing to do something like that, but...

Quoted 1 line

Even svn could do that (svn status).

what exactly are trying to achieve? It is just strange that no one asked for something like this before...

Apologies for the duplicate message; fighting between gmail and vger.kernel.org.

Here's a terrible way to do this:

$ GIT_EDITOR=: git commit -a -m 'throwaway' >/dev/null
$ (git ls-tree -r HEAD; git ls-tree -r HEAD~1) \
| sort | uniq -d | sed -e 's/^[^ ]* [^ ]* [^\t]*\t//'
$ git reset HEAD~1 >/dev/null

Deskin Miller

#6 lore raw
In reply to Alex Riesen
Quoted 10 lines
Quoted 3 lines

'git diff --name-status' looks useful but it only shows the files that have changed - I would like to see the names of the files that haven't changed.

There is nothing to do something like that, but...

Quoted 1 line

Even svn could do that (svn status).

what exactly are trying to achieve? It is just strange that no one asked for something like this before...

What I am trying to achieve is to list the versioned files that have no pending modifications (didn't I say that in the original posting?)

Strange, perhaps, but not completely useless in that it does tell you something about the state of the current working set of files.

BTW - and sorry for posting the same question in two different emails, I thought the first one had not made it onto the list - I shall be more patient in the future.

Mark

#7 lore raw
In reply to Mark Burton
Quoted 4 lines · Mark Burton

'git diff --name-status' looks useful but it only shows the files that have changed - I would like to see the names of the files that haven't changed. Even svn could do that (svn status).

Nobody has ever asked for such a crazy thing, but here's a test-patch to teach 'git ls-files' the '--unmodified' flag.

It's strictly bigger than need be, partly because ls-files is a horror, partly because it needed that 'name_status()' helper function to make it not turn into something even worse.

I also fixed a git ls-files buglet: a deleted file implies modification, so if you ask for --deleted _and_ --modified at the same time, you'll see a deleted file listed twice. Use '-v' to see the type. This makes it only show it once - as deleted if you asked for that information, otherwise as modified.

So with something like this, you can do

	git ls-files -v --modified --deleted --unmodified

and you'll see all files with a tag in front (the tag for unmodified is empty).

Not very well tested (aka "Hey, it's a patch from Linus, caveat emptor!")

Linus

---
 builtin-ls-files.c |   48 +++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 39 insertions(+), 9 deletions(-)
builtin-ls-files.c +39 -9
index 068f424..27a318a 100644
@@ -18,6 +18,7 @@ static int show_others;
 static int show_stage;
 static int show_unmerged;
 static int show_modified;
+static int show_unmodified;
 static int show_killed;
 static int show_valid_bit;
 static int line_terminator = '\n';
@@ -35,6 +36,7 @@ static const char *tag_removed = "";
 static const char *tag_other = "";
 static const char *tag_killed = "";
 static const char *tag_modified = "";
+static const char *tag_unmodified = "";
 
 
 /*
@@ -218,6 +220,20 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
 	write_name_quoted(ce->name + offset, stdout, line_terminator);
 }
 
+enum show_state {
+	unmodified, deleted, modified
+};
+
+static enum show_state name_status(struct cache_entry *ce)
+{
+	struct stat st;
+	int err = lstat(ce->name, &st);
+
+	if (err)
+		return deleted;
+	return ce_modified(ce, &st, 0) ? modified : unmodified;
+}
+
 static void show_files(struct dir_struct *dir, const char *prefix)
 {
 	int i;
@@ -248,19 +264,27 @@ static void show_files(struct dir_struct *dir, const char *prefix)
 			show_ce_entry(ce_stage(ce) ? tag_unmerged : tag_cached, ce);
 		}
 	}
-	if (show_deleted | show_modified) {
+	if (show_deleted | show_modified | show_unmodified) {
 		for (i = 0; i < active_nr; i++) {
 			struct cache_entry *ce = active_cache[i];
-			struct stat st;
-			int err;
 			int dtype = ce_to_dtype(ce);
 			if (excluded(dir, ce->name, &dtype) != dir->show_ignored)
 				continue;
-			err = lstat(ce->name, &st);
-			if (show_deleted && err)
-				show_ce_entry(tag_removed, ce);
-			if (show_modified && ce_modified(ce, &st, 0))
-				show_ce_entry(tag_modified, ce);
+			switch (name_status(ce)) {
+			default:
+				if (show_unmodified)
+					show_ce_entry(tag_unmodified, ce);
+				break;
+			case deleted:
+				if (show_deleted) {
+					show_ce_entry(tag_removed, ce);
+					break;
+				}
+				/* Fall through */
+			case modified:
+				if (show_modified)
+					show_ce_entry(tag_modified, ce);
+			}
 		}
 	}
 }
@@ -457,6 +481,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 			tag_modified = "C ";
 			tag_other = "? ";
 			tag_killed = "K ";
+			tag_unmodified = "  ";
 			if (arg[1] == 'v')
 				show_valid_bit = 1;
 			continue;
@@ -474,6 +499,11 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 			require_work_tree = 1;
 			continue;
 		}
+		if (!strcmp(arg, "--unmodified")) {
+			show_unmodified = 1;
+			require_work_tree = 1;
+			continue;
+		}
 		if (!strcmp(arg, "-o") || !strcmp(arg, "--others")) {
 			show_others = 1;
 			require_work_tree = 1;
@@ -593,7 +623,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 
 	/* With no flags, we default to showing the cached files */
 	if (!(show_stage | show_deleted | show_others | show_unmerged |
-	      show_killed | show_modified))
+	      show_killed | show_modified | show_unmodified))
 		show_cached = 1;
 
 	read_cache();
#8 lore raw
Quoted 4 lines · Linus Torvalds <torvalds <at> linux-foundation.org> writes:

Nobody has ever asked for such a crazy thing, but here's a test-patch to teach 'git ls-files' the '--unmodified' flag.

...

Many thanks for the patch, it does exactly what I wanted. Thanks also to the other people who contributed suggestions.

Mark