git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Jacob Keller <jacob.e.keller@intel.com>
Cc: git@vger.kernel.org, Stefan Beller <sbeller@google.com>,
	Jacob Keller <jacob.keller@gmail.com>
Subject: Re: [PATCH RFC v2] diff: add SUBMODULE_DIFF format to display submodule diff
Date: Tue, 09 Aug 2016 20:37:13 -0700	[thread overview]
Message-ID: <xmqqtwet70ra.fsf@gitster.mtv.corp.google.com> (raw)
In-Reply-To: <20160810002315.25236-1-jacob.e.keller@intel.com> (Jacob Keller's message of "Tue, 9 Aug 2016 17:23:15 -0700")

Jacob Keller <jacob.e.keller@intel.com> writes:

> +void show_submodule_diff(FILE *f, const char *path,
> +		const char *line_prefix,
> +		unsigned char one[20], unsigned char two[20],
> +		unsigned dirty_submodule, const char *meta,
> +		const char *reset)
> +{
> +	struct child_process cp = CHILD_PROCESS_INIT;
> +	struct strbuf sb = STRBUF_INIT;
> +	struct strbuf submodule_git_dir = STRBUF_INIT;
> +	const char *git_dir, *message = NULL;
> +	int create_dirty_diff = 0;
> +	FILE *diff;
> +	char c;
> +
> +	if ((dirty_submodule & DIRTY_SUBMODULE_UNTRACKED) ||
> +	    (dirty_submodule & DIRTY_SUBMODULE_MODIFIED))
> +		create_dirty_diff = 1;
> +
> +	strbuf_addf(&sb, "%s%sSubmodule %s %s..", line_prefix, meta, path,
> +			find_unique_abbrev(one, DEFAULT_ABBREV));
> +	strbuf_addf(&sb, "%s:%s\n", !create_dirty_diff ?
> +		    find_unique_abbrev(two, DEFAULT_ABBREV) : "", reset);
> +	fwrite(sb.buf, sb.len, 1, f);
> +
> +	strbuf_addf(&submodule_git_dir, "%s/.git", path);
> +	git_dir = read_gitfile(submodule_git_dir.buf);
> +	if (!git_dir)
> +		git_dir = submodule_git_dir.buf;
> +	if (!is_directory(git_dir)) {
> +		strbuf_reset(&submodule_git_dir);
> +		strbuf_addf(&submodule_git_dir, ".git/modules/%s", path);
> +		git_dir = submodule_git_dir.buf;
> +	}
> +
> +	cp.git_cmd = 1;
> +	if (!create_dirty_diff)
> +		cp.dir = git_dir;
> +	else
> +		cp.dir = path;
> +	cp.out = -1;
> +	cp.no_stdin = 1;
> +	argv_array_push(&cp.args, "diff");
> +	argv_array_pushf(&cp.args, "--src-prefix=a/%s/", path);
> +	argv_array_pushf(&cp.args, "--dst-prefix=b/%s/", path);

I think this is wrong.  Imagine when the caller gave you prefixes
that are different from a/ and b/ (think: the extreme case is that
you are a sub-sub-module, and the caller is recursing into you with
its own prefix, perhaps set to a/sub and b/sub).  Use the prefixes
you got for a/ and b/ instead of hardcoding them and you'd be fine,
I'd guess.

> +	argv_array_push(&cp.args, sha1_to_hex(one));
> +
> +	/*
> +	 * If the submodule has untracked or modified contents, diff between
> +	 * the old base and the current tip. This had the advantage of showing
> +	 * the full difference of the submodule contents.
> +	 */
> +	if (!create_dirty_diff)
> +		argv_array_push(&cp.args, sha1_to_hex(two));
> +
> +	if (start_command(&cp))
> +		die("Could not run 'git diff' command in submodule %s", path);
> +
> +	diff = fdopen(cp.out, "r");
> +
> +	c = fgetc(diff);
> +	while (c != EOF) {
> +		fputc(c, f);
> +		c = fgetc(diff);
> +	}
> +
> +	fclose(diff);
> +	finish_command(&cp);

I do not think you need to do this.  If "f" is already a FILE * to
which the output must go, then instead of reading from the pipe and
writing it, you can just let the "diff" spit out its output to the
same file descriptor, by doing something like:

	fflush(f);
        cp.out = dup(fileno(f));
        ... other setup ...
        run_command(&cp);

no?  I do not offhand recall run_command() closes cp.out after done,
and if it doesn't you may have to close it yourself after the above
sequence.

While I personally do not want to see code to access submodule's
object store by temporarily adding it as alternates, the "show
left-right log between the commits" code already does so, so I
should point out that running "diff" internally without spawning it
as a subprocess shouldn't be too hard.  The diff API is reasonably
libified and there shouldn't be additional "libification" preparation
work required to do this, if you really wanted to.

  parent reply	other threads:[~2016-08-10  3:37 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-10  0:23 [PATCH RFC v2] diff: add SUBMODULE_DIFF format to display submodule diff Jacob Keller
2016-08-10  0:53 ` Stefan Beller
2016-08-10  6:49   ` Jacob Keller
2016-08-10  3:37 ` Junio C Hamano [this message]
2016-08-10  6:52   ` Jacob Keller
2016-08-10 17:10     ` Junio C Hamano

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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=xmqqtwet70ra.fsf@gitster.mtv.corp.google.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=jacob.e.keller@intel.com \
    --cc=jacob.keller@gmail.com \
    --cc=sbeller@google.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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).