Mercurial > hg-stable
changeset 25297:3966e39fea98
changelog: fix bug in heads computation
This patch refactors the native computation of heads. It fixes a bug where
filtered heads in the pending index could be returned by the native code
despite their filtering.
author | Laurent Charignon <lcharignon@fb.com> |
---|---|
date | Tue, 26 May 2015 12:09:04 -0700 |
parents | 260fb5968de0 |
children | 3f6b54ef4d41 |
files | mercurial/parsers.c tests/test-obsolete.t |
diffstat | 2 files changed, 38 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/parsers.c Tue May 26 12:08:50 2015 -0700 +++ b/mercurial/parsers.c Tue May 26 12:09:04 2015 -0700 @@ -1194,7 +1194,7 @@ static PyObject *index_headrevs(indexObject *self, PyObject *args) { - Py_ssize_t i, len, addlen; + Py_ssize_t i, j, len; char *nothead = NULL; PyObject *heads = NULL; PyObject *filter = NULL; @@ -1237,9 +1237,9 @@ if (nothead == NULL) goto bail; - for (i = 0; i < self->raw_length; i++) { - const char *data; - int parent_1, parent_2, isfiltered; + for (i = 0; i < len; i++) { + int isfiltered; + int parents[2]; isfiltered = check_filter(filter, i); if (isfiltered == -1) { @@ -1253,49 +1253,11 @@ continue; } - data = index_deref(self, i); - parent_1 = getbe32(data + 24); - parent_2 = getbe32(data + 28); - - if (parent_1 >= 0) - nothead[parent_1] = 1; - if (parent_2 >= 0) - nothead[parent_2] = 1; - } - - addlen = self->added ? PyList_GET_SIZE(self->added) : 0; - - for (i = 0; i < addlen; i++) { - PyObject *rev = PyList_GET_ITEM(self->added, i); - PyObject *p1 = PyTuple_GET_ITEM(rev, 5); - PyObject *p2 = PyTuple_GET_ITEM(rev, 6); - long parent_1, parent_2; - int isfiltered; - - if (!PyInt_Check(p1) || !PyInt_Check(p2)) { - PyErr_SetString(PyExc_TypeError, - "revlog parents are invalid"); - goto bail; + index_get_parents(self, i, parents); + for (j = 0; j < 2; j++) { + if (parents[j] >= 0) + nothead[parents[j]] = 1; } - - isfiltered = check_filter(filter, i); - if (isfiltered == -1) { - PyErr_SetString(PyExc_TypeError, - "unable to check filter"); - goto bail; - } - - if (isfiltered) { - nothead[i] = 1; - continue; - } - - parent_1 = PyInt_AS_LONG(p1); - parent_2 = PyInt_AS_LONG(p2); - if (parent_1 >= 0) - nothead[parent_1] = 1; - if (parent_2 >= 0) - nothead[parent_2] = 1; } for (i = 0; i < len; i++) {
--- a/tests/test-obsolete.t Tue May 26 12:08:50 2015 -0700 +++ b/tests/test-obsolete.t Tue May 26 12:09:04 2015 -0700 @@ -886,3 +886,33 @@ #endif +Test heads computation on pending index changes with obsolescence markers + $ cd .. + $ cat >$TESTTMP/test_extension.py << EOF + > from mercurial import cmdutil + > from mercurial.i18n import _ + > + > cmdtable = {} + > command = cmdutil.command(cmdtable) + > @command("amendtransient",[], _('hg amendtransient [rev]')) + > def amend(ui, repo, *pats, **opts): + > def commitfunc(ui, repo, message, match, opts): + > return repo.commit(message, repo['.'].user(), repo['.'].date(), match) + > opts['message'] = 'Test' + > opts['logfile'] = None + > cmdutil.amend(ui, repo, commitfunc, repo['.'], {}, pats, opts) + > print repo.changelog.headrevs() + > EOF + $ cat >> $HGRCPATH << EOF + > [extensions] + > testextension=$TESTTMP/test_extension.py + > EOF + $ hg init repo-issue-nativerevs-pending-changes + $ cd repo-issue-nativerevs-pending-changes + $ mkcommit a + $ mkcommit b + $ hg up ".^" + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo aa > a + $ hg amendtransient + [1, 3]