Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions refs/ref-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ static int cache_ref_iterator_seek(struct ref_iterator *ref_iterator,
sort_ref_dir(dir);

slash = strchr(slash, '/');
len = slash ? (size_t)(slash - refname) : strlen(refname);
len = slash ? (size_t)(slash - refname + 1) : strlen(refname);

for (idx = 0; idx < dir->nr; idx++) {
cmp = strncmp(refname, dir->entries[idx]->name, len);
Expand All @@ -520,6 +520,8 @@ static int cache_ref_iterator_seek(struct ref_iterator *ref_iterator,
slash = slash + 1;

level->index = idx;
if (cmp > 0)
break;
if (dir->entries[idx]->flag & REF_DIR) {
/* push down a level */
dir = get_ref_dir(dir->entries[idx]);
Expand All @@ -532,7 +534,7 @@ static int cache_ref_iterator_seek(struct ref_iterator *ref_iterator,
level->prefix_state = PREFIX_CONTAINS_DIR;
} else {
/* reduce the index so the leaf node is iterated over */
if (cmp <= 0 && !slash)
if (cmp < 0 || (cmp == 0 && !slash))
level->index = idx - 1;
/*
* while the seek path may not be exhausted, our
Expand Down
55 changes: 55 additions & 0 deletions t/t6302-for-each-ref-filter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,61 @@ test_expect_success 'start after used with a pattern' '
test_cmp expect actual
'

for storage in loose packed mixed
do
test_expect_success "start after respects directory boundaries ($storage)" '
test_when_finished "rm -rf repo" &&
git init repo &&
(
cd repo &&
test_commit --no-tag base &&
git update-ref refs/tags/packed HEAD &&
if test "$storage" = mixed
then
git pack-refs --all || return 1
fi &&
git update-ref --stdin <<-\EOF &&
create refs/tags/a-leaf HEAD
create refs/tags/a/nested HEAD
create refs/tags/a0 HEAD
create refs/tags/b HEAD
create refs/tags/releases-z HEAD
create refs/tags/releases/v1 HEAD
create refs/tags/releases/v2 HEAD
EOF
if test "$storage" = packed
then
git pack-refs --all || return 1
fi &&
echo refs/tags/releases/v2 >expect &&
git for-each-ref --no-sort --format="%(refname)" \
--start-after=refs/tags/releases/v1 >actual &&
test_cmp expect actual &&
cat >expect <<-\EOF &&
refs/tags/a0
refs/tags/b
refs/tags/packed
refs/tags/releases-z
refs/tags/releases/v1
refs/tags/releases/v2
EOF
git for-each-ref --no-sort --format="%(refname)" \
--start-after=refs/tags/a/next >actual &&
test_cmp expect actual &&
tail -n 5 expect >expect-later &&
git for-each-ref --no-sort --format="%(refname)" \
--start-after=refs/tags/aa/missing >actual &&
test_cmp expect-later actual &&
for marker in refs/tags/zzzz refs/zzzz zzzz
do
git for-each-ref --no-sort --format="%(refname)" \
--start-after="$marker" >actual &&
test_must_be_empty actual || return 1
done
)
'
done

test_expect_success 'start after used with custom sort order' '
cat >expect <<-\EOF &&
fatal: cannot use --start-after with custom sort options
Expand Down
Loading