diff --git a/NEWS b/NEWS
index 544cd6d1..d0a79dcc 100644
--- a/NEWS
+++ b/NEWS
@@ -5,7 +5,7 @@
- fix and improve request list and show output
- new osc rremove command for remote source files removal
- handle _service\* files correctly
- - osc commit asks if some file has a '?' status
+ - osc commit asks if some file has a '?' status (can be skipped by --force option)
0.120:
- support "setlinkrev" for whole projects
diff --git a/osc/commandline.py b/osc/commandline.py
index 2fe1c4c2..d89f3ed5 100755
--- a/osc/commandline.py
+++ b/osc/commandline.py
@@ -1619,12 +1619,22 @@ Please submit there instead, or use --nodevelproject to force direct submission.
help='specify log message TEXT')
@cmdln.option('-F', '--file', metavar='FILE',
help='read log message from FILE')
+ @cmdln.option('-f', '--force', default=False, action="store_true",
+ help='force commit - do not tests a file list')
def do_commit(self, subcmd, opts, *args):
"""${cmd_name}: Upload content to the repository server
Upload content which is changed in your working copy, to the repository
server.
+ Checks the state of a working copy, if found a file with unknown state,
+ it requests an user input:
+ * skip - don't change anything, just move to another file
+ * remove - remove a file from dir
+ * edit file list - edit filelist using EDITOR
+ * commit - don't check anything and commit package
+ * abort - abort commit - this is default value
+
examples:
osc ci # current dir
osc ci
@@ -1653,17 +1663,8 @@ Please submit there instead, or use --nodevelproject to force direct submission.
pacs = findpacs(args)
- # warn if any of files has a ? status (usually a patch, or new source was not added to meta)
- for p in pacs:
- # no files given as argument? Take all files in current dir
- if not p.todo:
- p.todo = p.filenamelist + p.filenamelist_unvers
- p.todo.sort()
- for f in (f for f in p.todo if os.path.isfile(f)):
- if p.status(f) == '?':
- resp = raw_input("File `%s' is not in package meta. Would you like to continue? [y/N] "% (f, ))
- if resp not in ('y', 'Y'):
- return
+ if not opts.force:
+ check_filelist_before_commit(pacs)
if not msg:
# open editor for commit message
diff --git a/osc/core.py b/osc/core.py
index 52497279..41b9365d 100755
--- a/osc/core.py
+++ b/osc/core.py
@@ -1241,7 +1241,101 @@ rev: %s
#print ljust(p.name, 45), 'At revision %s.' % p.rev
print 'At revision %s.' % self.rev
-
+
+ def prepare_filelist(self):
+ """Prepare a list of files, which will be processed by process_filelist
+ method. This allows easy modifications of a file list in commit
+ phase.
+ """
+ if not self.todo:
+ self.todo = self.filenamelist + self.filenamelist_unvers
+ self.todo.sort()
+
+ ret = ""
+ for f in (f for f in self.todo if os.path.isfile(f)):
+ ret += "leave %s %s\n" % (self.status(f), f)
+
+ ret += """
+# Edit a filelist for package %s
+# Commands:
+# l, leave = leave a file as is
+# r, remove = remove a file
+# a, add = add a file
+#
+# If you remove file from a list, it will be unchanged
+# If you remove all, commit will be aborted"""
+
+ return ret
+
+ def edit_filelist(self):
+ """Opens a package list in editor for eediting. This allows easy
+ modifications of it just by simple text editing
+ """
+
+ import tempfile
+ tempdir = '/tmp'
+ if sys.platform[:3] == 'win':
+ tempdir = os.getenv('TEMP')
+
+ (fd, filename) = tempfile.mkstemp(prefix = 'osc-filelist', suffix = '.txt', dir = tempdir)
+ f = os.fdopen(fd, 'w')
+ f.write(self.prepare_filelist())
+ f.close()
+ mtime_orig = os.stat(filename).st_mtime
+
+ if sys.platform[:3] != 'win':
+ editor = os.getenv('EDITOR', default='vim')
+ else:
+ editor = os.getenv('EDITOR', default='notepad')
+ while 1:
+ subprocess.call('%s %s' % (editor, filename), shell=True)
+ mtime = os.stat(filename).st_mtime
+ if mtime_orig < mtime:
+ filelist = open(filename).readlines()
+ os.unlink(filename)
+ break
+ else:
+ raise oscerr.UserAbort()
+
+ return self.process_filelist(filelist)
+
+ def process_filelist(self, filelist):
+ """Process a filelist - it add/remove or leave files. This depends on
+ user input. If no file is processed, it raises an ValueError
+ """
+
+ loop = False
+ for line in (l.strip() for l in filelist if (l[0] != "#" or l.strip() != '')):
+
+ foo = line.split(' ')
+ if len(foo) == 4:
+ action, state, name = (foo[0], ' ', foo[3])
+ elif len(foo) == 3:
+ action, state, name = (foo[0], foo[1], foo[2])
+ else:
+ break
+ action = action.lower()
+ loop = True
+
+ if action in ('r', 'remove'):
+ if self.status(name) == '?':
+ os.unlink(name)
+ if name in self.todo:
+ self.todo.remove(name)
+ else:
+ self.delete_file(name, True)
+ elif action in ('a', 'add'):
+ if self.status(name) != '?':
+ print "Cannot add file %s with state %s, skipped" % (name, self.status(name))
+ else:
+ self.addfile(name)
+ elif action in ('l', 'leave'):
+ pass
+ else:
+ raise ValueError("Unknow action `%s'" % action)
+
+ if not loop:
+ raise ValueError("Empty filelist")
class RequestState:
"""for objects to represent the "state" of a request"""
@@ -4004,3 +4098,29 @@ def get_commit_message_template(pac):
template.append(line[1:])
return template
+
+def check_filelist_before_commit(pacs):
+
+ # warn if any of files has a ? status (usually a patch, or new source was not added to meta)
+ for p in pacs:
+ # no files given as argument? Take all files in current dir
+ if not p.todo:
+ p.todo = p.filenamelist + p.filenamelist_unvers
+ p.todo.sort()
+ for f in (f for f in p.todo if os.path.isfile(f)):
+ if p.status(f) == '?':
+ resp = raw_input("File `%s' is not in package meta. Would you like skip/remove/edit file lists/commit/abort? (s/r/e/c/A) "% (f, ))
+ if resp in ('s', 'S'):
+ continue
+ elif resp in ('r', 'R'):
+ p.process_filelist(['r ? %s' % (f, ), ])
+ elif resp in ('e', 'E'):
+ try:
+ p.edit_filelist()
+ except ValueError:
+ print >>sys.stderr, "Error during processiong of file list."
+ raise oscerr.UserAbort()
+ elif resp in ('c', 'C'):
+ break
+ else:
+ raise oscerr.UserAbort()