Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 746ee21

Browse files
committed
Merge 'refs/rewritten/junio/next' into HEAD
2 parents 6978d61 + 997304a commit 746ee21

File tree

5 files changed

+106
-20
lines changed

5 files changed

+106
-20
lines changed

builtin/tag.c

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,38 +73,98 @@ static int in_commit_list(const struct commit_list *want, struct commit *c)
7373
return 0;
7474
}
7575

76-
static int contains_recurse(struct commit *candidate,
76+
enum contains_result {
77+
CONTAINS_UNKNOWN = -1,
78+
CONTAINS_NO = 0,
79+
CONTAINS_YES = 1,
80+
};
81+
82+
/*
83+
* Test whether the candidate or one of its parents is contained in the list.
84+
* Do not recurse to find out, though, but return -1 if inconclusive.
85+
*/
86+
static enum contains_result contains_test(struct commit *candidate,
7787
const struct commit_list *want)
7888
{
79-
struct commit_list *p;
80-
8189
/* was it previously marked as containing a want commit? */
8290
if (candidate->object.flags & TMP_MARK)
8391
return 1;
8492
/* or marked as not possibly containing a want commit? */
8593
if (candidate->object.flags & UNINTERESTING)
8694
return 0;
8795
/* or are we it? */
88-
if (in_commit_list(want, candidate))
96+
if (in_commit_list(want, candidate)) {
97+
candidate->object.flags |= TMP_MARK;
8998
return 1;
99+
}
90100

91101
if (parse_commit(candidate) < 0)
92102
return 0;
93103

94-
/* Otherwise recurse and mark ourselves for future traversals. */
95-
for (p = candidate->parents; p; p = p->next) {
96-
if (contains_recurse(p->item, want)) {
97-
candidate->object.flags |= TMP_MARK;
98-
return 1;
99-
}
100-
}
101-
candidate->object.flags |= UNINTERESTING;
102-
return 0;
104+
return -1;
103105
}
104106

105-
static int contains(struct commit *candidate, const struct commit_list *want)
107+
/*
108+
* Mimicking the real stack, this stack lives on the heap, avoiding stack
109+
* overflows.
110+
*
111+
* At each recursion step, the stack items points to the commits whose
112+
* ancestors are to be inspected.
113+
*/
114+
struct stack {
115+
int nr, alloc;
116+
struct stack_entry {
117+
struct commit *commit;
118+
struct commit_list *parents;
119+
} *stack;
120+
};
121+
122+
static void push_to_stack(struct commit *candidate, struct stack *stack)
123+
{
124+
int index = stack->nr++;
125+
ALLOC_GROW(stack->stack, stack->nr, stack->alloc);
126+
stack->stack[index].commit = candidate;
127+
stack->stack[index].parents = candidate->parents;
128+
}
129+
130+
static enum contains_result contains(struct commit *candidate,
131+
const struct commit_list *want)
106132
{
107-
return contains_recurse(candidate, want);
133+
struct stack stack = { 0, 0, NULL };
134+
int result = contains_test(candidate, want);
135+
136+
if (result != CONTAINS_UNKNOWN)
137+
return result;
138+
139+
push_to_stack(candidate, &stack);
140+
while (stack.nr) {
141+
struct stack_entry *entry = &stack.stack[stack.nr - 1];
142+
struct commit *commit = entry->commit;
143+
struct commit_list *parents = entry->parents;
144+
145+
if (!parents) {
146+
commit->object.flags |= UNINTERESTING;
147+
stack.nr--;
148+
}
149+
/*
150+
* If we just popped the stack, parents->item has been marked,
151+
* therefore contains_test will return a meaningful 0 or 1.
152+
*/
153+
else switch (contains_test(parents->item, want)) {
154+
case CONTAINS_YES:
155+
commit->object.flags |= TMP_MARK;
156+
stack.nr--;
157+
break;
158+
case CONTAINS_NO:
159+
entry->parents = parents->next;
160+
break;
161+
case CONTAINS_UNKNOWN:
162+
push_to_stack(parents->item, &stack);
163+
break;
164+
}
165+
}
166+
free(stack.stack);
167+
return contains_test(candidate, want);
108168
}
109169

110170
static void show_tag_lines(const unsigned char *sha1, int lines)

compat/poll/poll.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
605605

606606
if (!rc && timeout == INFTIM)
607607
{
608-
SwitchToThread();
608+
SleepEx (1, TRUE);
609609
goto restart;
610610
}
611611

config.mak.uname

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,16 +365,16 @@ ifeq ($(uname_S),Windows)
365365
compat/win32/pthread.o compat/win32/syslog.o \
366366
compat/win32/dirent.o
367367
COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
368-
BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
368+
BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE
369369
EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib
370370
PTHREAD_LIBS =
371371
lib =
372372
ifndef DEBUG
373-
BASIC_CFLAGS += -GL -Os -MT
373+
BASIC_CFLAGS += -GL -Os -MD
374374
BASIC_LDFLAGS += -LTCG
375375
AR += -LTCG
376376
else
377-
BASIC_CFLAGS += -Zi -MTd
377+
BASIC_CFLAGS += -Zi -MDd
378378
endif
379379
X = .exe
380380
endif

perl/Git/SVN.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,7 @@ sub get_untracked {
13211321
sub parse_svn_date {
13221322
my $date = shift || return '+0000 1970-01-01 00:00:00';
13231323
my ($Y,$m,$d,$H,$M,$S) = ($date =~ /^(\d{4})\-(\d\d)\-(\d\d)T
1324-
(\d\d)\:(\d\d)\:(\d\d)\.\d*Z$/x) or
1324+
(\d\d?)\:(\d\d)\:(\d\d)\.\d*Z$/x) or
13251325
croak "Unable to parse date: $date\n";
13261326
my $parsed_date; # Set next.
13271327

t/t7004-tag.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,4 +1380,30 @@ test_expect_success 'multiple --points-at are OR-ed together' '
13801380
test_cmp expect actual
13811381
'
13821382
1383+
run_with_limited_stack () {
1384+
(ulimit -s 64 && "$@")
1385+
}
1386+
1387+
test_lazy_prereq ULIMIT 'run_with_limited_stack true'
1388+
1389+
# we require ulimit, this excludes Windows
1390+
test_expect_success ULIMIT '--contains works in a deep repo' '
1391+
>expect &&
1392+
i=1 &&
1393+
while test $i -lt 4000
1394+
do
1395+
echo "commit refs/heads/master
1396+
committer A U Thor <[email protected]> $((1000000000 + $i * 100)) +0200
1397+
data <<EOF
1398+
commit #$i
1399+
EOF"
1400+
test $i = 1 && echo "from refs/heads/master^0"
1401+
i=$(($i + 1))
1402+
done | git fast-import &&
1403+
git checkout master &&
1404+
git tag far-far-away HEAD^ &&
1405+
run_with_limited_stack git tag --contains HEAD >actual &&
1406+
test_cmp expect actual
1407+
'
1408+
13831409
test_done

0 commit comments

Comments
 (0)