William Giokas [off-list ref] writes:
All,
I've been using git for a while and this is the first time I've had to
use `git am` and I've got a 16 patch patchset that I'm looking to apply.
The files were copied to a separate maildir by mutt to keep things
clean, and then I ran `git am -i /path/to/maildir/` expecting things to
start from the patch with the subject
[PATCH 01/16] refactor common code in query_search/sync_search
But instead, it starts with the 16/16 patch and works backwards, which,
obviously, breaks the application process as the patches depend on each
other. I looked in the maildir directory just to see if the file names
were backwards, and that's not the issue. I talked to `gitster` on IRC
and he said to send in a bug report on this issue here. The patchset I'm
trying to apply can be found here[0].
Process to reproduce:
* find a multi-patch set with interdependent patches
* run `git am` on the maildir containing these patches
Expected result:
* Apply patches in [01..N] order
Actual result:
* Patches applied in [N N-1..01] order
Note to bystanders. This is coming from populate_maildir_list() in
builtin/mailsplit.c; the function claims to know what "maildir"
should look like, so it should be enforcing the ordering as
necessary by sorting the list, _if_ the implicit ordering given by
string_list_insert() is insufficient.
It also is likely that it is a user error to expect that patch
e-mails are received and stored in the maildir in the order they
were sent, or it could be "mutt" copying the mails in the order the
messages were originally received, or something silly like that.
[0]: https://mailman.archlinux.org/pipermail/pacman-dev/2013-March/016541.html
Thank you,
On Fri, Mar 01, 2013 at 02:27:32PM -0800, Junio C Hamano wrote:
quoted
I've been using git for a while and this is the first time I've had to
use `git am` and I've got a 16 patch patchset that I'm looking to apply.
The files were copied to a separate maildir by mutt to keep things
clean, and then I ran `git am -i /path/to/maildir/` expecting things to
start from the patch with the subject
[PATCH 01/16] refactor common code in query_search/sync_search
But instead, it starts with the 16/16 patch and works backwards, which,
obviously, breaks the application process as the patches depend on each
Note to bystanders. This is coming from populate_maildir_list() in
builtin/mailsplit.c; the function claims to know what "maildir"
should look like, so it should be enforcing the ordering as
necessary by sorting the list, _if_ the implicit ordering given by
string_list_insert() is insufficient.
It also is likely that it is a user error to expect that patch
e-mails are received and stored in the maildir in the order they
were sent, or it could be "mutt" copying the mails in the order the
messages were originally received, or something silly like that.
I think it is a property of the maildir format that it does not
technically define the message order. The order of items you get from
readdir is filesystem specific and not necessarily defined (and that is
what we use now). On my ext4 system, I do not even get them in backwards
order; it is jumbled.
We could sort based on the mtime of the file, but in some cases that
won't have sufficient resolution (e.g., with one second resolution,
they'll all probably have the same timestamp).
The maildir spec explicitly says that readers should not make
assumptions about the content of the filenames. Mutt happens to write
them as:
${epoch_seconds}.${pid}_${seq}.${host}
so in practice, sorting them kind of works. Except that a series written
out at once will all have the same timestamp and pid, and because ${seq}
is not zero-padded, you have to actually parse up to there and do a
numeric instead of byte-wise comparison. So we can add a mutt-specific
hack, but that's the best we can do. Other maildir writers (including
future versions of mutt) will not necessarily do the same thing.
I think maildir's philosophy is that ordering is not important, and the
contents of the messages themselves should define the order in which a
MUA presents them, anyway. It would make sense to me if we actually
parsed the '[PATCH n/m]' bit from the subject of each and sorted based
on that. That is blurring the line between git-mailsplit and
git-mailinfo, in that mailsplit would have to start parsing the files.
We could also sort based on the rfc822 "Date" header, but I don't think
that is a good idea. It represents the author timestamp, so patches
moved via "rebase -i" will have out-of-sequence dates with respect to
the actual history graph. You can encounter this if you "format-patch
--stdout" a series into a single mbox and load it into a MUA that sorts
by date (like mutt). The patches appear jumbled until you switch to
"unsorted" or "sort by subject".
-Peff
On Fri, Mar 01, 2013 at 05:52:31PM -0500, Jeff King wrote:
quoted
Note to bystanders. This is coming from populate_maildir_list() in
builtin/mailsplit.c; the function claims to know what "maildir"
should look like, so it should be enforcing the ordering as
necessary by sorting the list, _if_ the implicit ordering given by
string_list_insert() is insufficient.
[...]
I think it is a property of the maildir format that it does not
technically define the message order. The order of items you get from
readdir is filesystem specific and not necessarily defined (and that is
what we use now). On my ext4 system, I do not even get them in backwards
order; it is jumbled.
Hmph, sorry, I mistook string_list_insert for string_list_append. So we
do actually sort them by filename, not just random readdir order. But
due to this:
The maildir spec explicitly says that readers should not make
assumptions about the content of the filenames. Mutt happens to write
them as:
${epoch_seconds}.${pid}_${seq}.${host}
so in practice, sorting them kind of works. Except that a series written
out at once will all have the same timestamp and pid, and because ${seq}
is not zero-padded, you have to actually parse up to there and do a
numeric instead of byte-wise comparison. So we can add a mutt-specific
hack, but that's the best we can do. Other maildir writers (including
future versions of mutt) will not necessarily do the same thing.
That ordering is not necessarily useful.
So one strategy could be to try harder to sort numeric elements
numerically. That is, to treat:
1234.5678_90.foo
as the list
{1234, '.', 5678, '_', 90, "foo"}
for the purposes of sorting (even though we do not necessarily know what
each piece means). That works for mutt and similar schemes (dovecot, for
example, does something like "M${seq}P${pid}"), but some systems may put
random bytes in the middle (the point of it is to create a unique name).
So it is somewhat against the maildir spec, but I think in practice it
would help.
-Peff