From 7f953ac970c44464bbab4651fa5fa5b64e6684ef Mon Sep 17 00:00:00 2001
From: "James E. Blair" <jeblair@openstack.org>
Date: Wed, 7 May 2014 22:11:46 -0400
Subject: [PATCH] Sync parent changes

If a revision's parent commit is not in the db, searh for the
change associated with that parent and sync it.  Except, don't
do this if the revision in question is in a closed state (so
that we don't walk up the entire history).

This is in service of displaying change dependencies.

Change-Id: If1ecf7d82036255c742d4264f399b7f32ccd76b8
---
 gertty/sync.py | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/gertty/sync.py b/gertty/sync.py
index 0da70fa..966ce22 100644
--- a/gertty/sync.py
+++ b/gertty/sync.py
@@ -150,6 +150,24 @@ class SyncProjectTask(Task):
                     sync.submitTask(SyncChangeTask(c['id'], self.priority))
                     self.log.debug("Change %s update %s" % (c['id'], c['updated']))
 
+class SyncChangeByCommitTask(Task):
+    def __init__(self, commit, priority=NORMAL_PRIORITY):
+        super(SyncChangeByCommitTask, self).__init__(priority)
+        self.commit = commit
+
+    def __repr__(self):
+        return '<SyncChangeByCommitTask %s>' % (self.commit,)
+
+    def run(self, sync):
+        app = sync.app
+        with app.db.getSession() as session:
+            query = 'commit:%s' % self.commit
+            changes = sync.get('changes/?q=%s' % query)
+            self.log.debug('Query: %s ' % (query,))
+            for c in changes:
+                sync.submitTask(SyncChangeTask(c['id'], self.priority))
+                self.log.debug("Sync change %s for its commit %s" % (c['id'], self.commit))
+
 class SyncChangeTask(Task):
     def __init__(self, change_id, priority=NORMAL_PRIORITY):
         super(SyncChangeTask, self).__init__(priority)
@@ -198,6 +216,13 @@ class SyncChangeTask(Task):
                                                      remote_revision['commit']['message'], remote_commit,
                                                      remote_revision['commit']['parents'][0]['commit'])
                     new_revision = True
+                # TODO: handle multiple parents
+                parent_revision = session.getRevisionByCommit(revision.parent)
+                # TODO: use a singleton list of closed states
+                if not parent_revision and change.status not in ['MERGED', 'ABANDONED']:
+                    sync.submitTask(SyncChangeByCommitTask(revision.parent, self.priority))
+                    self.log.debug("Change %s revision %s needs parent commit %s synced" %
+                                   (change.id, remote_revision['_number'], revision.parent))
                 remote_comments = sync.get('changes/%s/revisions/%s/comments' % (self.change_id, revision.commit))
                 for remote_file, remote_comments in remote_comments.items():
                     for remote_comment in remote_comments: