Re: Fwd: git status options feature suggestion

3 messages, 3 authors, 2016-06-15 · open the first message on its own page

Re: Fwd: git status options feature suggestion

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:45:28

Jeff King [off-list ref] writes:
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?
Sorry, I don't.
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.
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 happen");
			d = e->util;
                        d->index_to_worktree_status = fp->status;
                }
	}

	void git_st_inspect(struct string_list *git_st_list)
        {
        	struct rev_info rev;

		git_st_list->items = NULL;
                git_st_list->nr = git_st_list->alloc = 0;
                git_st_list->strdup_strings = 1;

		/*
                 * run "diff-index -B -M HEAD" and keep the result in a
                 * string list, keyed by the path in the index.
                 */
                init_revisions(&rev, NULL);
                setup_revisions(0, NULL, &rev, "HEAD");
                rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
                rev.diffopt.format_callback = git_st_inspect_index_cb;
                rev.diffopt.format_callback_data = git_st_list;
                rev.diffopt.detect_rename = 1;
                rev.diffopt.rename_limit = 200;
                rev.diffopt.break_opt = 0;
                run_diff_index(&rev, 1);

		/*
                 * run "diff-files" and update the previous with the result.
		 */
		init_revisions(&rev, NULL);
                setup_revisions(0, NULL, &rev, NULL);
                rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
                rev.diffopt.format_callback = git_st_inspect_file_cb;                
                rev.diffopt.format_callback_data = git_st_list;
                run_diff_files(&rev, 0);

		/*
                 * sort the string-list entries in HEAD path order
                 */
		qsort(git_st_list->items, git_st_list->nr,
                      sizeof(struct string_list_item),
                      cmp_head_path);
	}

Then git_st_inspect() can also be called by wt_status_print(), making it
unnecessary to do the equivalent of the above in wt_status_print_updated()
and wt_status_print_changed().

Re: Fwd: git status options feature suggestion

From: Jeff King <hidden>
Date: 2016-06-15 22:45:28

On Sun, Oct 12, 2008 at 01:10:01AM -0700, Junio C Hamano wrote:
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.
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
different than what diffcore does with the output queue.
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.
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

Re: Fwd: git status options feature suggestion

From: Shawn O. Pearce <hidden>
Date: 2016-06-15 22:45:28

Jeff King [off-list ref] wrote:
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. :)
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.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help