1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-06-09 22:16:14 +02:00

Merge branch 'vd/for-each-ref-sort-with-formatted-timestamp'

"git branch" and friends learned to use the formatted text as
sorting key, not the underlying timestamp value, when the --sort
option is used with author or committer timestamp with a format
specifier (e.g., "--sort=creatordate:format:%H:%M:%S").

* vd/for-each-ref-sort-with-formatted-timestamp:
  ref-filter.c: sort formatted dates by byte value
This commit is contained in:
Junio C Hamano 2024-02-12 13:16:11 -08:00
commit d4833b22ab
3 changed files with 57 additions and 3 deletions

View File

@ -359,9 +359,11 @@ In any case, a field name that refers to a field inapplicable to
the object referred by the ref does not cause an error. It
returns an empty string instead.
As a special case for the date-type fields, you may specify a format for
the date by adding `:` followed by date format name (see the
values the `--date` option to linkgit:git-rev-list[1] takes).
As a special case for the date-type fields, you may specify a format for the
date by adding `:` followed by date format name (see the values the `--date`
option to linkgit:git-rev-list[1] takes). If this formatting is provided in
a `--sort` key, references will be sorted according to the byte-value of the
formatted string rather than the numeric value of the underlying timestamp.
Some atoms like %(align) and %(if) always require a matching %(end).
We call them "opening atoms" and sometimes denote them as %($open).

View File

@ -1611,6 +1611,12 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam
if (formatp) {
formatp++;
parse_date_format(formatp, &date_mode);
/*
* If this is a sort field and a format was specified, we'll
* want to compare formatted date by string value.
*/
v->atom->type = FIELD_STR;
}
if (!eoemail)

View File

@ -1356,6 +1356,52 @@ test_expect_success '--no-sort without subsequent --sort prints expected refs' '
test_cmp expected actual
'
test_expect_success 'set up custom date sorting' '
# Dates:
# - Wed Feb 07 2024 21:34:20 +0000
# - Tue Dec 14 1999 00:05:22 +0000
# - Fri Jun 04 2021 11:26:51 +0000
# - Mon Jan 22 2007 16:44:01 GMT+0000
i=1 &&
for when in 1707341660 945129922 1622806011 1169484241
do
GIT_COMMITTER_DATE="@$when +0000" \
GIT_COMMITTER_EMAIL="user@example.com" \
git tag -m "tag $when" custom-dates-$i &&
i=$(($i+1)) || return 1
done
'
test_expect_success 'sort by date defaults to full timestamp' '
cat >expected <<-\EOF &&
945129922 refs/tags/custom-dates-2
1169484241 refs/tags/custom-dates-4
1622806011 refs/tags/custom-dates-3
1707341660 refs/tags/custom-dates-1
EOF
git for-each-ref \
--format="%(creatordate:unix) %(refname)" \
--sort=creatordate \
"refs/tags/custom-dates-*" >actual &&
test_cmp expected actual
'
test_expect_success 'sort by custom date format' '
cat >expected <<-\EOF &&
00:05:22 refs/tags/custom-dates-2
11:26:51 refs/tags/custom-dates-3
16:44:01 refs/tags/custom-dates-4
21:34:20 refs/tags/custom-dates-1
EOF
git for-each-ref \
--format="%(creatordate:format:%H:%M:%S) %(refname)" \
--sort="creatordate:format:%H:%M:%S" \
"refs/tags/custom-dates-*" >actual &&
test_cmp expected actual
'
test_expect_success 'do not dereference NULL upon %(HEAD) on unborn branch' '
test_when_finished "git checkout main" &&
git for-each-ref --format="%(HEAD) %(refname:short)" refs/heads/ >actual &&