dirstate-tags format (branch6) doesn't support branching from a merged revision

Bug #115343 reported by Christopher Armstrong
2
Affects Status Importance Assigned to Milestone
Bazaar
Fix Released
Medium
John A Meinel

Bug Description

It seems branching from a revision ID that is part of a merge doesn't work when you're trying to branch it from a branch6-format branch.

radix@naota ~/test% bzr init A
radix@naota ~/test% cd A
radix@naota ~/test/A% touch README.txt
radix@naota ~/test/A% bzr add; bzr commit -m "1"
added README.txt
added README.txt
Committed revision 1.
radix@naota ~/test/A% cd ..
radix@naota ~/test% bzr branch A B
cdBranched 1 revision(s).
radix@naota ~/test% cd B
radix@naota ~/test/B% echo "hi" > README.txt; bzr commit -m "2"; echo "there" > README.txt; bzr commit -m "3"
modified README.txt
Committed revision 2.
modified README.txt
Committed revision 3.
radix@naota ~/test/B% cd ..
radix@naota ~/test% cd A
radix@naota ~/test/A% bzr merge ../B
 M README.txt
All changes applied successfully.
radix@naota ~/test/A% bzr commit -m "merge"
modified README.txt
cdCommitted revision 2.
radix@naota ~/test/A% cd ..
radix@naota ~/test% bzr log A |grep merged
    merged: <email address hidden>
    merged: <email address hidden>
radix@naota ~/test% bzr branch A -r revid:<email address hidden> C
Branched 3 revision(s).
radix@naota ~/test% cd A
radix@naota ~/test/A% bzr upgrade --dirstate-tags
starting upgrade of file:///home/radix/test/A/
making backup of tree history
file:///home/radix/test/A/.bzr has been backed up to file:///home/radix/test/A/.bzr.backup
if conversion fails, you can move this directory back to .bzr
if it succeeds, you can remove this directory if you wish
finished
radix@naota ~/test/A% cd ..
radix@naota ~/test% bzr branch A -r revid:<email address hidden> D
bzr: ERROR: The branch A has no revision <RevisionSpec_revid revid:<email address hidden>>.

Related branches

Revision history for this message
Martin Pool (mbp) wrote :

Thanks for the reproduction.

Changed in bzr:
importance: Undecided → Medium
status: Unconfirmed → Confirmed
Revision history for this message
John A Meinel (jameinel) wrote :

Is this '--dirstate-tags' specific? I would have thought it would be true for any branch format.

However, it could be that the code is being extra sensitive about whether the revision is in Branch.revision_history() rather than just checking that the revision is in the repository. (I'm not really sure why it would care about Branch6 other than it has to generate revision_history() in a different way)

Revision history for this message
John A Meinel (jameinel) wrote :

In tracking through the code it seems to occurring in:

 BzrDir.sprout()
  Branch.sprout()
    Branch.copy_content_into()
      Branch6._synchronize_history()

The reason is that Branch5._sync... does:
  try:
    new_history = revision_history[:revision_history.index(revision_id)]
  except IndexError:
    new_history = self.generate_history(revision_id)

Which means that if necessary it will regenerate a revision history for that id.

However, Branch6 uses:

        if revision_id is None:
            revno, revision_id = self.last_revision_info()
        else:
            revno = self.revision_id_to_revno(revision_id)
        destination.set_last_revision_info(revno, revision_id)

With no fallback in the case that revision_id doesn't exist in the revision_history.

The difficulty is that 'set_last_revision_info()' needs to know the revno for the given revision. Which in general means creating the full history for it, and finding it's left-hand distance to null (revno).

A simple fix is:

  rev = self.repository.get_revision(revision_id)
  new_history = rev.get_history(self.repository)[1:]
  revno = len(new_history)

Another possibility is:

  revno = len(list(self.repository.iter_reverse_revision_history(revision_id)))

It would be nice if we could figure this stuff out without traversing the whole graph, but
a) Revisions don't record their revno at commit time (though they could)
b) revno is distance to null, so you have to walk back to null to find the distance.

Revision history for this message
John A Meinel (jameinel) wrote :

working on it in the assosiated branch

Changed in bzr:
assignee: nobody → jameinel
status: Confirmed → In Progress
John A Meinel (jameinel)
Changed in bzr:
status: In Progress → Fix Committed
Revision history for this message
Martin Pool (mbp) wrote :

It looks like this fix was released in 0.17

Changed in bzr:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.