Re: Fwd: git status options feature suggestion

Previous thread: [Gitk Patch 0/6] by Robin Rosenberg on Wednesday, October 8, 2008 - 11:09 pm. (15 messages)

Next thread: [StGit PATCH 1/2] Handle "git diff-tree --stdin" error by Samuel Tardieu on Thursday, October 9, 2008 - 2:01 am. (2 messages)
From: Caleb Cushing
Date: Wednesday, October 8, 2008 - 11:27 pm

> How about "git ls-files -o"?

doh... hadn't even heard of that command.

-- 
Caleb Cushing
--

From: Johannes Schindelin
Date: Thursday, October 9, 2008 - 2:03 am

Hi,


Which is good!  As ls-files is listed as plumbing.  Users should not need 
to call ls-files, so I like your idea about adding --new, --untracked etc. 
to "git status" (I do not agree with others that "git status" has to stay 
that non-existant "git commit --dry-run").

Could you list exactly which options you want implemented?

Ciao,
Dscho

--

From: Michael J Gruber
Date: Thursday, October 9, 2008 - 8:12 am

Requests for stuff like that keep appearing recently (I'm to blame
partially only ;) ). There are 3 issues at hand:

- people are used to "svn status [-v]" like output which can include
untracked as well as tracked unmodified files; there are other valid
reasons why you would want that info

- porc can't do it: git status can't show ignored files, doesn't use
status letters, can't show files with specific status; git diff
--name-status can't show ignored nor untracked files
[In fact, the description of "git diff" says "files which you could
add", which should include untracked files, but doesn't.]

- plumb uses conflicting letters: git ls-files output conflicts with git
diff --name-status output

So I guess it's time for a usability effort in this area. A few
questions before going about that:

- I think change of existing behaviour is unavoidable (make ls-files and
diff --name-status consistent). Is that something to do now or rather
before 1.7? Is porc (diff) supposed to be changed or plumb (ls-files)?

- How strong should the tie between git status and git commit be?
Current git status is basically git commit -n, with the usual meaning of
"-n" (such as for prune etc."), not with the current meaning of git
commit -n, sigh...

A few radical suggestions might be:

1. make ls-files and diff --name-status use compatible letters

2. rename git commit -n to git commit -b (as in bypass), make git commit
-n do what's expected ("--dry-run", n as in duNNo yet)

3. rename git status to git commit -n

4. make git status generate git diff --name-status like output

(3+4)'. make git status -l generate git diff --name-status like output
(l as in status Letter) as an alternative to 3+4

Michael
--

From: Caleb Cushing
Date: Thursday, October 9, 2008 - 7:20 pm

> Could you list exactly which options you want implemented?
--new --untracked --modified

I believe there are other states as well that I'm not thinking of off
the top of my head. Those should probably be included as well. another

all way over my head


-- 
Caleb Cushing
--

From: Elijah Newren
Date: Thursday, October 9, 2008 - 9:25 pm

On Thu, Oct 9, 2008 at 9:12 AM, Michael J Gruber
<git@drmicha.warpmail.net> wrote:

Ouch.  Please not -b.  I guess I need to get my other suggestions

I'd really prefer to be able to get staged vs. unstaged information
out of status.  And the single-letter output, like what cvs/svn/hg
have, is less descriptive here.  (Sure, git status could use some
cleanup IMO, but a word instead of a letter for modification status is
a usability improvement in git over those other systems for new VCS

That seems nicer.


And another radical suggestion (wasn't this brought up before too?):

5. Allow limiting the status output to a set of paths.  diff, log,
add, grep, etc. can all take a subdirectory name and limit their
operation to files recursively underneath that path, but git status
doesn't do so when you run 'git status DIR'.  I know why it currently
behaves as it does, but it sure seems like unnecessary UI
inconsistency.


Just my $0.02,
Elijah
--

From: Johannes Schindelin
Date: Friday, October 10, 2008 - 4:13 am

Hi,


ls-files and diff (at least partially) are plumbing.  Breaking backwards 
compatibility in these is out of the question.

Ciao,
Dscho
--

From: Jeff King
Date: Saturday, October 11, 2008 - 9:49 pm

A week or two ago I came across yet another git-status annoyance: it
needs write access to the repository to run (I was helping somebody with
a task on a shared box, and I wanted to run status in their repository
using my account).

I considered submitting a patch to fix this, but I think it is really
more fundamental. I use status to get an overview of what's going on in
a repo, but it is intimately related to a potential commit.

And this bleeds into other areas, too. Why should the "what's going on
in this repo" command prefix all lines with "#"? We would have more
freedom to change the format if it weren't required to be a comment
line in a commit message.

So I think it is probably reasonable to think about a new command (which
would not be called status) that shows this information. What do people
want to see? And in what format? Some things I would want or have seen
requested are:

 - staged and unstaged changes in --name-status format

 - files without changes (with a -v flag).

 - untracked files

 - current branch / detached HEAD (with relationship to tracked branch,
   if any)

And maybe after hashing it out, it turns out it's not that different
from "git status" and we should just stick with that. But I would be

I don't think you would want to just change the default; you would
probably add a new option to ls-files to use the --name-status letters,

I think the theoretical tool I mentioned would benefit from breaking
this connection. But I don't know whether it is prudent to take the
"status" name in doing so. Even if we decided to do so, it would
probably happen something like:

  1. Introduce git-wtf, a new status-like tool. Deprecate git-status in
     its current form.

  2. Wait a really long time.

  3. Rename git-wtf to git-status.

So either way, the first step is an alternative replacement command.

-Peff
--

From: Junio C Hamano
Date: Saturday, October 11, 2008 - 11:41 pm

I was going to suggest the same.  "git st" for people who come from "svn st"
so that "git status" can be kept as traditional "preview of 'git commit'".

And just make it mimic whatever folks accustomed to "svn st" would expect,
modulo we would need two status letters to signal difference between
(HEAD, index), and (index, worktree).  Perhaps three if you want to show
difference between (HEAD, worktree) while at it.

And no, I have not seen any argument good enough to change ls-files nor
diff-$lowlevel output and break people's existing scripts.
--

From: Jeff King
Date: Saturday, October 11, 2008 - 11:45 pm

I remember a long time ago you started on a parallel diff walker that
could diff the working tree, the index, and a tree at once. Do you
remember the issues with it?

I think that would be the right tool here to show each file only once,
but with multiple status flags. Something like:

  A M foo

to show that "foo" has been added since the last commit, but there are
modifications in the working tree that have not yet been staged.

-Peff
--

From: Junio C Hamano
Date: Sunday, October 12, 2008 - 1:10 am

One thing to keep in mind is what to do when you would want to detect
renames.  The parallel walk would be Ok but between HEAD and index there
could be renames involved, and at that point it would get quite tricky.
Once the index is in-core, I think it hurts us much to walk HEAD vs index
and index vs working tree in separate passes.

I think it is perfectly fine to run the diff-index first, and keep the
result from it in a string_list, and then run "diff-files" and annotate
the string_list with the output from it.

Something like...

	struct git_st_data {
        	const char *head_path;
                char head_to_index_status;
                char index_to_worktree_status;
	};

	static int cmp_head_path(const void *a_, const void *b_)
        {
		struct git_st_data *a = (struct git_st_data *)a_;
		struct git_st_data *b = (struct git_st_data *)b_;
		return strcmp(a->head_path, b->head_path);
        }

	static void git_st_inspect_index_cb(struct diff_queue_struct *q,
        			struct diff_options *opts, void *data)
	{
		struct string_list *git_st_list = data;
		int i;
		for (i = 0; i < q->nr; i++) {
                	struct git_st_data *d;
                        struct string_list_item *e;
			struct diff_filepair *fp = &q->queue[i];
			d = xcalloc(1, sizeof(*d));
                        d->head_path = xstrdup(fp->one->path);
                        e = string_list_insert(fp->two->path, git_st_list);
			e->util = d;
                        d->head_to_index_status = fp->status;
                }
	}

	static void git_st_inspect_file_cb(struct diff_queue_struct *q,
        			struct diff_options *opts, void *data)
	{
		struct string_list *git_st_list = data;
		int i;
		for (i = 0; i < q->nr; i++) {
                	struct git_st_data *d;
                        struct string_list_item *e;
			struct diff_filepair *fp = &q->queue[i];
			e = string_list_lookup(fp->one->path, git_st_list);
			if (!e)
                        	die("Oops -- shouldn't ...
From: Jeff King
Date: Sunday, October 12, 2008 - 6:04 pm

Assuming you meant "I _don't_ think it hurts us much" then OK, that
makes sense. I was just thinking it would be more elegant than holding
each list in memory and comparing, but really that is not all that

Thanks, I think that is a sane direction to go in. And I agree that any
solution should be totally split from the actual output format, so we
can reuse it in "git status" if desired.

However, now that Shawn has revealed the existence of his super-secret
status replacement, I am going to wait to see that before moving any
further. :)

-Peff
--

From: Shawn O. Pearce
Date: Sunday, October 12, 2008 - 6:30 pm

I'll talk about it more at the GitTogether.  I expect the sources
to be published and available for download between now and then.
I'll post a pointer to it here on the Git ML once the sources
go live.

So you shouldn't have to wait too much longer.

But as I said, it really is just a trivial redisplay of what
diff-files and diff-index produces.  Anyone could probably code up
the same result in 15 minutes in Perl or Python; or slightly longer
in C.

-- 
Shawn.
--

From: Junio C Hamano
Date: Saturday, October 25, 2008 - 6:47 pm

Because I was bored thinking about what to talk about in Gittogether and
lacked enough concentration to do anything productive, I did this that:

 (1) introduces the "find and summarize changes in a single string list"
     infrastructure;

 (2) rewrites wt_status_print_{updated,changed} to use it; and

 (3) adds "git shortstatus" that does not take any parameter (so it is not
     about "preview of commit with the same paths arguments" anymore) to
     give the status in:

        XsssY PATH1 -> PATH2

    format, where X is the diff status between HEAD and the index, sss is the
    rename/copy score of the change (if X is rename or copy --- otherwise
    it is blank), Y is the diff status between the index and the worktree.  
    PATH1 is the path in the HEAD, and " -> PATH2" part is shown only when
    PATH1 corresponds to a different path in the index/worktree.

This was done primarily for fun and killing-time, so I won't be committing
it to my tree, but it seems to pass all the existing tests.

If you apply this patch with "git apply" (no --index) and then

        $ git mv COPYING RENAMING

then you would see:

        $ ./git-shortstatus
        M     Makefile
        R100  COPYING -> RENAMING
            M builtin-commit.c
            M builtin-revert.c
            M builtin.h
            M git.c
            M wt-status.c
            M wt-status.h        

It is very much welcomed if somebody wants to build on top of this.  A few
obvious things, aside from bikeshedding to drop the score value (which I
just did as a sanity check measure and for nothing else --- I won't feel
hurt if we lost that field from the output) and such are:

 * We can also rewrite wt_status_print_untracked() using the collected
   data by making the collector pay attention to untracked files quite
   easily;

 * I did not bouther touching wt_status_print_initial() but I think it
   should be straightforward to produce its output from the collected
   data, as the collector ...
From: Jeff King
Date: Saturday, October 25, 2008 - 9:59 pm

I just skimmed the code, but it looks reasonably done. I don't have time
to work on this at the moment, but I think you have done most of the
work that requires a lot of git knowledge. Maybe somebody new can pick
this up as a nice starter project to get more involved in git.

-Peff
--

From: Shawn O. Pearce
Date: Sunday, October 12, 2008 - 11:05 am

I have a tool that I'll be open-sourcing later this year, but it does
something like that:

  project foo/                        branch master
   Am   foo
   M-   bar
   R-   orig => dest ( 95%)

Line coloring is red on lines with unstaged stuff in the working
directory (3rd column, lower case letters) and green on lines that
are fully staged (3rd column is a '-').

The tool is in Python, but I'm just scraping the output of
`diff-index -M --cached HEAD` and diff-files to get that
display.  The status letters are exactly those given out by
diff-index/diff-files, but the diff-files output is lowercased.

Scott Chacon has seen the tool output and likes it; there's a tech
talk that will be posted on YouTube soon where he and I are sort
of talking about it.

Sorry I can't say too much more about it yet.  But I'm trying to
say that both Scott and I like a denser display like this.

-- 
Shawn.
--

From: Jeff King
Date: Sunday, October 12, 2008 - 6:06 pm

I like what I saw, and I think a "denser" format is what I was trying to
suggest in my earlier message (I just didn't think of nearly as clear a
word). So count me in for your list of people who would like to see this
thing (and would even work on doing a pure-C version).

-Peff
--

From: Wincent Colaiuta
Date: Sunday, October 12, 2008 - 3:47 am

One of the first aliases I set up when I started using git was "st"  
for status, and I'd imagine that's a pretty common thing for people  
coming from other SCMs like svn and cvs. But I very quickly became  
used to git's notion of what "status" means and I wouldn't want "git  
st" to start giving me a different behaviour.

I think if you're introducing a different command then you should make  
sure it doesn't happen to be an abbreviation of an existing one. It  
would be better to give it some other name (info, foo, whatever). If  
svn people then want to make an "st" alias pointing to it they're free  
to do so.

Just my 2c.

Cheers,
Wincent



--

From: Teemu Likonen
Date: Sunday, October 12, 2008 - 4:40 am

In Subversion and Bazaar "info" command gives mostly information about
the repository itself. They don't talk about individual files at all.
"status" is the command (also in Mercurial) for getting information
about the current state of files in the tree.

I think it would be really sad if "git status" can't be extended to
match people's needs. I don't like the idea of a new name for such
status command. It's a kind of "why git people always invent new names
for familiar commands?" thing.
--

From: Andreas Ericsson
Date: Sunday, October 12, 2008 - 6:52 am

Well, the solution is fairly simple then. Just make it configurable and
set it in your ~/.gitconfig. It's not my itch to scratch though. I
loathe the sparse output from cvs/svn/whatnot and would be just as happy
if I never had to look at it again. I can understand its usefulness for
scripting, but 'git status' is porcelain so for that purpose it really
belongs somewhere else.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231
--

From: Jeff King
Date: Sunday, October 12, 2008 - 1:26 am

BTW, in case anybody is interested, here is the patch. Like I said, I
think we are better off with an alternative to "status", but maybe this
is useful to somebody anyway.

---
diff --git a/builtin-commit.c b/builtin-commit.c
index b01ad9f..8951364 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -217,7 +217,8 @@ static void create_base_index(void)
 		exit(128); /* We've already reported the error, finish dying */
 }
 
-static char *prepare_index(int argc, const char **argv, const char *prefix)
+static char *prepare_index(int argc, const char **argv, const char *prefix,
+		int status_only)
 {
 	int fd;
 	struct string_list partial;
@@ -270,7 +271,13 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
 	 * We still need to refresh the index here.
 	 */
 	if (!pathspec || !*pathspec) {
-		fd = hold_locked_index(&index_lock, 1);
+		fd = hold_locked_index(&index_lock, 0);
+		if (fd < 0) {
+			if (!status_only)
+				die("unable to lock index: %s",
+						strerror(errno));
+			return get_index_file();
+		}
 		refresh_cache(REFRESH_QUIET);
 		if (write_cache(fd, active_cache, active_nr) ||
 		    commit_locked_index(&index_lock))
@@ -869,7 +876,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
 
 	argc = parse_and_validate_options(argc, argv, builtin_status_usage, prefix);
 
-	index_file = prepare_index(argc, argv, prefix);
+	index_file = prepare_index(argc, argv, prefix, 1);
 
 	commitable = run_status(stdout, index_file, prefix, 0);
 
@@ -953,7 +960,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 
 	argc = parse_and_validate_options(argc, argv, builtin_commit_usage, prefix);
 
-	index_file = prepare_index(argc, argv, prefix);
+	index_file = prepare_index(argc, argv, prefix, 0);
 
 	/* Set up everything for writing the commit object.  This includes
 	   running hooks, writing the trees, and interacting with the user.  */
--

From: Junio C Hamano
Date: Sunday, October 12, 2008 - 2:58 am

You would probably want to refresh_cache() here even if you are not going
to write the resulting index out, so that you won't show the stat-only
differences to the end user.  Other than that, I think this is a good
change.

--

From: Jeff King
Date: Sunday, October 12, 2008 - 5:59 pm

That is a good point. However, I think this change is still not a good
one, because it is only halfway there. It makes "git status" work, but
not "git status path", which wants to write out the resulting cache. I
don't know what complications are involved with making that work.
Probably there is a way, but I haven't looked too closely, as I think a
better path forward is a new tool that is not so closely tied to commit.

-Peff
--

From: James Cloos
Date: Thursday, October 9, 2008 - 2:23 pm

Johannes> Which is good!  As ls-files is listed as plumbing.
Johannes> Users should not need to call ls-files,

That is a bug, then.  ls-files is one of the more important user-level
commands in git.

It is vastly more efficient than find(1) or a --recursive call to
grep(1).

Searching through a repository to find which file(s) define or use some
function, struct, class or similar is a common occurance.  Or to find
which dir(s) contain(s) file(s) matching a given regexp.  Or a number
of other uses.  (Tags might be useful if one does a lot of searching
in a given repo, but grep is quicker for infrequent searches and the
tags utils do not support all file types.)

ls-files is definitely dual-use.

-JimC
-- 
James Cloos <cloos@jhcloos.com>         OpenPGP: 1024D/ED7DAEA6
--

From: Shawn O. Pearce
Date: Thursday, October 9, 2008 - 2:41 pm

How about using "git grep" then?  No need for ls-files...

-- 
Shawn.
--

From: Jeremy Ramer
Date: Thursday, October 9, 2008 - 3:13 pm

I use git-grep for searching the contents of files in the repo, but it
seems to me that git ls-files is necessary for quickly parsing the
--

From: James Cloos
Subject: Re: ls-files
Date: Thursday, October 9, 2008 - 3:52 pm

Shawn> How about using "git grep" then?  No need for ls-files...

I often filter the list of files before passing them to xargs, so git
grep helps for some use cases, but not all.

Also, (at least as of 1.6.0.2.307.gc427), git grep does not support -P
(Perl compatible regexps) or --color.

-JimC
-- 
James Cloos <cloos@jhcloos.com>         OpenPGP: 1024D/ED7DAEA6
--

Previous thread: [Gitk Patch 0/6] by Robin Rosenberg on Wednesday, October 8, 2008 - 11:09 pm. (15 messages)

Next thread: [StGit PATCH 1/2] Handle "git diff-tree --stdin" error by Samuel Tardieu on Thursday, October 9, 2008 - 2:01 am. (2 messages)