X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/b4bddc068e5440e8b747329df4db841a14483d85..e4f41f5d393b5f1e83a39a42a5f204efb6ef7ea6:/stgit/git.py diff --git a/stgit/git.py b/stgit/git.py index 1f5a129..9d8cdf0 100644 --- a/stgit/git.py +++ b/stgit/git.py @@ -91,6 +91,14 @@ def get_conflicts(): else: return None +def _input(cmd, file_desc): + p = popen2.Popen3(cmd) + for line in file_desc: + p.tochild.write(line) + p.tochild.close() + if p.wait(): + raise GitException, '%s failed' % str(cmd) + def _output(cmd): p=popen2.Popen3(cmd) string = p.fromchild.read() @@ -265,7 +273,7 @@ def commit(message, files = [], parents = [], allowempty = False, raise GitException, 'No changes to commit' # check for unresolved conflicts - if not first and len(filter(lambda x: x[0] not in ['M', 'N', 'D'], + if not first and len(filter(lambda x: x[0] not in ['M', 'N', 'A', 'D'], cache_files)) != 0: raise GitException, 'Commit failed: unresolved conflicts' @@ -283,7 +291,7 @@ def commit(message, files = [], parents = [], allowempty = False, rm_files=[] m_files=[] for f in cache_files: - if f[0] == 'N': + if f[0] in ['N', 'A']: add_files.append(f[1]) elif f[0] == 'D': rm_files.append(f[1]) @@ -356,6 +364,7 @@ def status(files = [], modified = False, new = False, deleted = False, if modified: filestat.append('M') if new: + filestat.append('A') filestat.append('N') if deleted: filestat.append('D') @@ -410,31 +419,65 @@ def files(rev1, rev2): return str.rstrip() -def checkout(files = [], force = False): +def checkout(files = [], tree_id = None, force = False): """Check out the given or all files """ - git_flags = 'git-checkout-cache -q -u' + if tree_id and __run('git-read-tree -m', [tree_id]) != 0: + raise GitException, 'Failed git-read-tree -m %s' % tree_id + + checkout_cmd = 'git-checkout-cache -q -u' if force: - git_flags += ' -f' + checkout_cmd += ' -f' if len(files) == 0: - git_flags += ' -a' + checkout_cmd += ' -a' else: - git_flags += ' --' + checkout_cmd += ' --' - if __run(git_flags, files) != 0: + if __run(checkout_cmd, files) != 0: raise GitException, 'Failed git-checkout-cache' def switch(tree_id): """Switch the tree to the given id """ - to_delete = filter(lambda x: x[0] == 'N', __tree_status(tree_id = tree_id)) - - if __run('git-read-tree -m', [tree_id]) != 0: - raise GitException, 'Failed git-read-tree -m %s' % tree_id + to_delete = filter(lambda x: x[0] in ['N', 'A'], + __tree_status(tree_id = tree_id)) - checkout(force = True) + checkout(tree_id = tree_id, force = True) __set_head(tree_id) # checkout doesn't remove files for fs in to_delete: os.remove(fs[1]) + +def pull(location, head = None, tag = None): + """Fetch changes from the remote repository. At the moment, just + use the 'git fetch' scripts + """ + args = [location] + if head: + args += [head] + elif tag: + args += ['tag', tag] + + if __run('git pull', args) != 0: + raise GitException, 'Failed "git fetch %s"' % location + +def apply_patch(filename = None): + """Apply a patch onto the current index. There must not be any + local changes in the tree, otherwise the command fails + """ + os.system('git-update-cache --refresh > /dev/null') + + if filename: + if __run('git-apply --index', [filename]) != 0: + raise GitException, 'Patch does not apply cleanly' + else: + _input('git-apply --index', sys.stdin) + +def clone(repository, local_dir): + """Clone a remote repository. At the moment, just use the + 'git clone' script + """ + if __run('git clone', [repository, local_dir]) != 0: + raise GitException, 'Failed "git clone %s %s"' \ + % (repository, local_dir)