- if 'text' in kwargs:
- raise ValueError("You can provide only text or patch - not both")
- patch = kwargs['patch']
-
- author = kwargs.get('author', None)
- author_desc = kwargs.get('author_desc', None)
-
- old_head = self.head
- if parent != old_head:
- change = parent.make_merge_child(patch, author=author,
- author_desc=author_desc,
- description=kwargs.get('description', ''))
- # not Fast-Forward - perform a merge
- self.head = old_head.merge_with(change, author=author,
- author_desc=author_desc)
+ return parent_ca
+
+ if parent_ca is None or parent_ca.created_at < merge_parent_ca.created_at:
+ return merge_parent_ca
+
+ return parent_ca
+
+ def get_ancestors(self):
+ revs = set()
+ if self.parent is not None:
+ revs.add(self.parent)
+ revs.update(self.parent.get_ancestors())
+ if self.merge_parent is not None:
+ revs.add(self.merge_parent)
+ revs.update(self.merge_parent.get_ancestors())
+ return revs
+
+
+@python_2_unicode_compatible
+class Ref(models.Model):
+ """A reference pointing to a specific revision."""
+
+ revision = models.ForeignKey(
+ Revision, null=True, blank=True, default=None, verbose_name=_('revision'),
+ help_text=_("The document's revision."), editable=False)
+
+ def __str__(self):
+ return "ref:{0}->rev:{1}".format(self.id, self.revision_id)
+
+ def merge_text(self, base, local, remote):
+ """Override in subclass to have different kinds of merges."""
+ files = []
+ for f in local, base, remote:
+ temp = NamedTemporaryFile(delete=False)
+ temp.write(f)
+ temp.close()
+ files.append(temp.name)
+ p = Popen(['/usr/bin/diff3', '-mE', '-L', 'old', '-L', '', '-L', 'new'] + files, stdout=PIPE)
+ result, errs = p.communicate()
+
+ for f in files:
+ os.unlink(f)
+ return result.decode('utf-8')
+
+ def merge_with(self, revision, author=None, author_name=None, author_email=None, description="Automatic merge."):
+ """Merges a given revision into the ref."""
+ if self.revision is None:
+ fast_forward = True
+ self.revision = revision
+ elif self.revision.pk == revision.pk or self.revision.is_descendant_of(revision):
+ # Already merged.
+ return
+ elif revision.is_descendant_of(self.revision):
+ # Fast forward.
+ fast_forward = True
+ self.revision = revision