Update the README (mainly alignment)
[stgit] / stgit / git.py
index 1f5a129..9d8cdf0 100644 (file)
@@ -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)