git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Jeff King <peff@peff.net>
Cc: Michael J Gruber <git@drmicha.warpmail.net>,
	Johannes Schindelin <Johannes.Schindelin@gmx.de>,
	Caleb Cushing <xenoterracide@gmail.com>,
	git@vger.kernel.org
Subject: Re: Fwd: git status options feature suggestion
Date: Sun, 12 Oct 2008 01:10:01 -0700	[thread overview]
Message-ID: <7v1vymgrom.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <20081012064512.GA32597@coredump.intra.peff.net> (Jeff King's message of "Sun, 12 Oct 2008 02:45:13 -0400")

Jeff King <peff@peff.net> 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().

  reply	other threads:[~2008-10-12  8:11 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-09  5:34 git status options feature suggestion Caleb Cushing
2008-10-09  6:11 ` Jeff King
     [not found]   ` <81bfc67a0810082327p421ca4e9v84f4b33023bc6fe6@mail.gmail.com>
2008-10-09  6:27     ` Fwd: " Caleb Cushing
2008-10-09  9:03       ` Johannes Schindelin
2008-10-09 15:12         ` Michael J Gruber
2008-10-10  2:20           ` Caleb Cushing
2008-10-10  4:25           ` Elijah Newren
2008-10-10 11:13           ` Johannes Schindelin
2008-10-12  4:49           ` Jeff King
2008-10-12  6:41             ` Junio C Hamano
2008-10-12  6:45               ` Jeff King
2008-10-12  8:10                 ` Junio C Hamano [this message]
2008-10-13  1:04                   ` Jeff King
2008-10-13  1:30                     ` Shawn O. Pearce
2008-10-26  1:47                   ` Junio C Hamano
2008-10-26  4:59                     ` Jeff King
2008-10-12 18:05                 ` Shawn O. Pearce
2008-10-13  1:06                   ` Jeff King
2008-10-12  9:07               ` Jakub Narebski
2008-10-12 10:47               ` Wincent Colaiuta
2008-10-12 11:40                 ` Teemu Likonen
2008-10-12 13:52                   ` Andreas Ericsson
2008-10-12  8:26             ` Fwd: " Jeff King
2008-10-12  9:58               ` Junio C Hamano
2008-10-13  0:59                 ` Jeff King
2008-10-09 21:23         ` ls-files [Was: Re: Fwd: git status options feature suggestion] James Cloos
2008-10-09 21:41           ` Shawn O. Pearce
2008-10-09 22:13             ` Jeremy Ramer
2008-10-09 22:52             ` ls-files James Cloos
  -- strict thread matches above, loose matches on Subject: below --
2008-10-12 10:09 Fwd: git status options feature suggestion Leo Razoumov
2008-10-18  0:19 ` Fyn Fynn

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=7v1vymgrom.fsf@gitster.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@drmicha.warpmail.net \
    --cc=git@vger.kernel.org \
    --cc=peff@peff.net \
    --cc=xenoterracide@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).