[PATCH 2 of 2 V4] changelog: fix bug in heads computation
Augie Fackler
raf at durin42.com
Tue May 26 14:58:54 CDT 2015
On Tue, May 26, 2015 at 12:27:42PM -0700, Laurent Charignon wrote:
> # HG changeset patch
> # User Laurent Charignon <lcharignon at fb.com>
> # Date 1432667344 25200
> # Tue May 26 12:09:04 2015 -0700
> # Node ID dce4c1e501d0815dce167f7479226e9dc709186f
> # Parent 3e9c4885541a63af6743240c4ab1b8fbdf8f5d14
> changelog: fix bug in heads computation
These two are queued, thanks.
>
> 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.
>
> diff --git a/mercurial/parsers.c b/mercurial/parsers.c
> --- a/mercurial/parsers.c
> +++ b/mercurial/parsers.c
> @@ -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++) {
> diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
> --- a/tests/test-obsolete.t
> +++ b/tests/test-obsolete.t
> @@ -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]
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list