Edgewall Software
Modify

Opened 15 years ago

Closed 13 years ago

#8628 closed enhancement (fixed)

Considering revision 0 as oldest revision in TracMercurial.

Reported by: olemis+trac@… Owned by: Christian Boos
Priority: normal Milestone: plugin - mercurial
Component: plugin/mercurial Version: none
Severity: normal Keywords: mercurial, versioncontrol
Cc: Branch:
Release Notes:
API Changes:
Internal Changes:

Description

This message is about an issue I find annoying. I've even needed to patch a few code I've written so far as a workaround for the problems presented below. That's why I'd like you to consider this in order to either review the ordering of revisions defined by TracMercurial. I'd really wanna know why it is correct and possible workarounds (if any).

Firstly I'll mention part of the contract I consider valid for ANY VCS connector (e.g. SVN) and I'll use → sign to establish an implication relationship and r variable to refer to an instance of the repository connector:

  1. An ordering (total ordering ? partial ordering ?) of revisions should be implemented. This partially means that :
    1. If a revision is older than another then there's no way that the later be part of the former's ancestors. IOW, let previous_revs be written as follows:
      def previous_revs(r, rev):
       rev = r.normalize_rev(rev)
       while (rev):
         yield rev
         rev = r.previous_rev(rev)
      

then :

 r.rev_older_than(rev1, rev2) ->
     not any(rev == r.normalize_rev(rev2) for rev in previous_revs(r, rev1))
  1. If a revision has a parent then its parent has a child i.e.
 r.normalize_rev(rev1) == r.previous_rev(rev2) -> r.next_rev(rev1) is not None

Everything is about revision -1:000000000000. The root cause for all the issues mentionned below is that this revision is considered in practice as both the oldest and the youngest revision in the Hg repository, i.e.

>>> r.oldest_rev
'-1:000000000000'
>>> r.normalize_rev(r.oldest_rev)
'27:046049125132'
>>> r.youngest_rev
'27:046049125132'
>>> r.normalize_rev(r.oldest_rev) == r.youngest_rev
True

Here you have a practical example showing how both clauses are not satisfied by TracMercurial

# This confirms that 1a. is not satisfied because revision 14 is
# younger than revision 7 and still 14 seems to be an
# ancestor of revision 7.
>>> r.rev_older_than('7', '14')
True
>>> any(rev == r.normalize_rev('14') for rev in previous_revs(r, '7'))
True

# This one confirms that 1b. is not satisfied either
>>> r.normalize_rev('-1')
'27:046049125132'
>>> r.normalize_rev(r.previous_rev('0'))
'27:046049125132'
>>> r.normalize_rev(r.previous_rev('0')) == r.normalize_rev('-1')
True
>>> r.next_rev(r.previous_rev('0')) is None
True

… but they are satisfied by SVN connector

# This is not always true, but it is in the target SVN repos
>>> allrevs = range(0, r.youngest_rev + 1)
>>> allrevs
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

>>> implies = lambda a, b: not a or b
>>> def previous_revs(r, rev):
...   rev = r.normalize_rev(rev)
...   while (rev):
...     yield rev
...     rev = r.previous_rev(rev)
...

# 1a. is satisfied
>>> all(implies( \
...                     r.rev_older_than(rev1, rev2),
...                     not any(rev == r.normalize_rev(rev2) for rev
in previous_revs(r, rev1)) \
...             ) for rev1 in allrevs \
...                     for rev2 in allrevs)
True

# 1b. is satisfied
>>> all(implies( \
...                     r.normalize_rev(rev1) == r.previous_rev(rev2), \
...                     r.next_rev(rev1) is not None \
...             ) for rev1 in allrevs \
...                     for rev2 in allrevs)
True

After all this being said, my proposal is to implement get_oldest_rev in TracMercurial connector as follows.

def get_oldest_rev(self):
   return self.normalize_rev('0')

PS: I know that previous_rev in TracMercurial follows the first parent and next_rev a single child.

Implication a → b :

a b result
True True True
True False False
False True True
False False True

Attachments (0)

Change History (2)

comment:1 by Christian Boos, 14 years ago

Milestone: not applicablemercurial-plugin

Well yes, r.normalize_rev(r.oldest_rev) == r.youngest_rev is certainly wrong.

comment:2 by Christian Boos, 13 years ago

Resolution: fixed
Status: newclosed

In r10519, r.oldest_rev is now directly 0 and normalization of this gives the corresponding hash.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Christian Boos.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Christian Boos to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.