Theodore Tso <tytso@xxxxxxx> writes: >> $ git format-patch a a > > Umm.... dare I ask why this works, or how someone would be expected to > know this? Or is the answer, "Meditate deeply on builtin-log.c, > grasshopper"? :-) Heh, deep magic ;-). Essentially, the traditional "single commit" behaviour is implemented as a special case that - has one and only one positive ref specified on the command line; - without -$count (or -n $count). Everything else uses the usual revision range parsing machinery, including the case you specify the same ref twice redundantly on the command line in duplicates. Even that counts as "not just one positive ref on the command line" and triggers the usual revision range semantics. As we discussed, "--root" trick would make this unneeded ;-) >> ... >> for the above example to work. Why not tweak the option parser >> so that: >> >> $ git format-patch --root a >> >> to do what you want? Without --root and with a single positive >> commit, it can keep doing the traditional "what I did since I >> forked from that guy's history". > > That seems to make a lot of sense; given the fact that the current > behaivor does make sense and is convenient, the big complaints were > always (1) not documenting clearly that this was an exception which > might be surprising (i.e., hanging a latern[1] on it), and (2) that > there wasn't a way to do the alternate expected behavior. --root > handles the second, and an explanation in the man page saying that > yes, this is a little non-standard wrt to git-rev-list, but it's > convenient, and let the user know that he should just give us a pass > on it the non-orthoganlity. So let's fix (1) and (2) like this. --- Documentation/git-format-patch.txt | 29 ++++++++++++++++++++++------- builtin-log.c | 13 ++++++++++--- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index c514fdd..5e6d537 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -16,21 +16,32 @@ SYNOPSIS [--in-reply-to=Message-Id] [--suffix=.<sfx>] [--ignore-if-in-upstream] [--subject-prefix=Subject-Prefix] - <since>[..<until>] + [ <since> | <revision range> ] DESCRIPTION ----------- -Prepare each commit between <since> and <until> with its patch in +Prepare each commit with its patch in one file per commit, formatted to resemble UNIX mailbox format. -If ..<until> is not specified, the head of the current working -tree is implied. For a more complete list of ways to spell -<since> and <until>, see "SPECIFYING REVISIONS" section in -gitlink:git-rev-parse[1]. - The output of this command is convenient for e-mail submission or for use with gitlink:git-am[1]. +There are two ways to specify which commits to operate on. + +1. A single commit, <since>, specifies that the commits leading + to the tip of the current branch that are not in the history + that leads to the <since> to be output. + +2. Generic <revision range> expression (see "SPECIFYING + REVISIONS" section in gitlink:git-rev-parse[1]) means the + commits in the specified range. A single commit, when + interpreted as a <revision range> expression, means + "everything that leads to that commit", but that is taken as + the special case above. If you want to format everything + since project inception to one commit, say "git format-patch + \--root <that-commit>", as showing the root commit as patch + requires \--root option anyway. + By default, each output file is numbered sequentially from 1, and uses the first line of the commit message (massaged for pathname safety) as the filename. With the --numbered-files option, the output file names @@ -153,6 +164,10 @@ git-format-patch origin:: not in the origin branch. For each commit a separate file is created in the current directory. +git-format-patch \--root origin:: + Extract all commits which that leads to 'origin' since the + inception of the project. + git-format-patch -M -B origin:: The same as the previous one. Additionally, it detects and handles renames and complete rewrites intelligently to diff --git a/builtin-log.c b/builtin-log.c index a381c75..fa81c25 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -585,12 +585,19 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) } if (rev.pending.nr == 1) { - if (rev.max_count < 0) { + if (rev.max_count < 0 && !rev.show_root_diff) { + /* + * This is traditional behaviour of "git format-patch + * origin" that prepares what the origin side still + * does not have. + */ rev.pending.objects[0].item->flags |= UNINTERESTING; add_head(&rev); } - /* Otherwise, it is "format-patch -22 HEAD", and - * get_revision() would return only the specified count. + /* + * Otherwise, it is "format-patch -22 HEAD", and/or + * "format-patch --root HEAD". The user wants + * get_revision() to do the usual traversal. */ } - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html