new "changes" command for listing unpushed commits
authorTimo Savola <tsavola@movial.fi>
Fri, 11 Apr 2008 18:07:00 +0000 (21:07 +0300)
committerTimo Savola <tsavola@movial.fi>
Fri, 11 Apr 2008 18:07:00 +0000 (21:07 +0300)
matrix/git.py
matrix/matrix.py
matrix/repositories.py

index 3457e27..172401c 100644 (file)
@@ -249,6 +249,12 @@ def cat_file(name, hash, blob=False, size=False):
 def log(name, options, fd=None):
        return call_output(['log'] + options + ['--'], workdir=name, fd=fd)
 
+def changes(name, commit):
+       spec = '%s..HEAD' % commit
+       cmd = ['log', '--pretty=format:%h %s', spec, '--']
+
+       return call_output(cmd, workdir=name)
+
 def exclude(name, lines):
        path = os.path.join(name, '.git', 'info', 'exclude')
 
index c6fb388..17de4f1 100644 (file)
@@ -57,6 +57,8 @@ def main():
                rebase(targets)
        elif command == 'pull':
                pull(targets)
+       elif command == 'changes':
+               changes(targets)
        elif command == 'source-dist':
                source_dist(targets)
        elif command == 'rootfs':
@@ -80,7 +82,7 @@ Options:
                        If this option is not given, the roots specified in the
                        components file will be used.  This option may be
                        specified multiple times.
-       -f              Build components with dirty files.
+       -f              Build (or be quiet about) components with dirty files.
        -k              Build as much as possible after an error.
        -j N            Execute N build jobs in parallel.
        -mj N           Run component builds with make -j N.
@@ -93,6 +95,7 @@ Commands and parameters:
                        repository directories.
        rebase          Update repositories from server by rebasing.
        pull            Update repositories from server by merging.
+       changes         Show commits which are not on the server.
        source-dist     Download and package the component sources.
        rootfs          Build a rootfs from the current target installation.
                -n              Do not clean env.faked and stripped directory.
@@ -200,22 +203,33 @@ def clone_component(c, overwrite=False):
                c.meta.clone()
 
 def clean(targets):
+       changed = False
+
        for name in targets:
                c = config.components[name]
                c.repo.clean()
                cache.remove(c)
 
-               for repo in (c.repo, c.meta):
-                       if repo.dirty_files():
-                               log.message('Dirty files left in %s' % \
-                                           repo.path)
+               if not config.force:
+                       changed = check_dirty(c)
+
+       if changed:
+               raise Error()
 
 def for_each_repository(func, targets=None):
+       ret = None
+
        for name in targets:
                c = config.components[name]
                if c.repo.exists():
-                       func(c.repo)
-               func(c.meta)
+                       value = func(c.repo)
+                       if value:
+                               ret = value
+               value = func(c.meta)
+               if value:
+                       ret = value
+
+       return ret
 
 def rebase(targets):
        for_each_repository(lambda repo: repo.rebase(), targets)
@@ -223,6 +237,37 @@ def rebase(targets):
 def pull(targets):
        for_each_repository(lambda repo: repo.pull(), targets)
 
+def changes(targets):
+       changed = False
+
+       for name in targets:
+               c = config.components[name]
+
+               if c.repo.exists():
+                       if check_changes(c.repo):
+                               changed = True
+
+               if check_changes(c.meta):
+                       changed = True
+
+               if not config.force and check_dirty(c):
+                       changed = True
+
+       if changed:
+               raise Error()
+
+def check_changes(repo):
+       ret = repo.changes()
+       if ret:
+               log.message('Changes in %s' % repo)
+       return ret
+
+def check_dirty(c):
+       ret = c.is_dirty()
+       if ret:
+               log.message('Dirty files in %s' % c.name)
+       return ret
+
 def source_dist(targets):
        location = 'dist'
        if not os.path.exists(location):
index 96629b6..4769db8 100644 (file)
@@ -142,3 +142,17 @@ class Repository(object):
                        git.log(self.path, [self.get_commit()], fd=fd)
                finally:
                        os.close(fd)
+
+       def changes(self):
+               print 'Comparing', self
+
+               output = git.changes(self.path, 'origin')
+               if output:
+                       print
+                       for line in output:
+                               print ' ', line
+                       print
+
+                       return True
+               else:
+                       return False