9 output
= fd
.readlines()
11 return [x
.strip() for x
in output
]
14 rc
= os
.system("%s > /dev/null 2>&1" % cmd
)
18 class YapError(Exception):
19 def __init__(self
, msg
):
25 def takes_options(options
):
27 func
.options
= options
32 def _add_new_file(self
, file):
33 repo
= get_output('git rev-parse --git-dir')[0]
34 dir = os
.path
.join(repo
, 'yap')
39 files
= self
._get
_new
_files
()
41 path
= os
.path
.join(dir, 'new-files')
42 pickle
.dump(files
, open(path
, 'w'))
44 def _get_new_files(self
):
45 repo
= get_output('git rev-parse --git-dir')[0]
46 path
= os
.path
.join(repo
, 'yap', 'new-files')
48 files
= pickle
.load(file(path
))
55 if get_output("git ls-files --cached '%s'" % f
) != []:
60 def _remove_new_file(self
, file):
61 files
= self
._get
_new
_files
()
62 files
= filter(lambda x
: x
!= file, files
)
64 repo
= get_output('git rev-parse --git-dir')[0]
65 path
= os
.path
.join(repo
, 'yap', 'new-files')
66 pickle
.dump(files
, open(path
, 'w'))
68 def _clear_new_files(self
):
69 repo
= get_output('git rev-parse --git-dir')[0]
70 path
= os
.path
.join(repo
, 'yap', 'new-files')
73 def _assert_file_exists(self
, file):
74 if not os
.access(file, os
.R_OK
):
75 raise YapError("No such file: %s" % file)
77 def _get_staged_files(self
):
78 if run_command("git rev-parse HEAD"):
79 files
= get_output("git ls-files --cached")
81 files
= get_output("git diff-index --cached --name-only HEAD")
84 def _get_unstaged_files(self
):
85 files
= self
._get
_new
_files
()
86 files
+= get_output("git ls-files -m")
89 def cmd_clone(self
, url
, directory
=""):
91 # XXX: implement in terms of init + remote add + fetch
92 os
.system("git clone '%s' %s" % (url
, directory
))
97 def cmd_add(self
, file):
99 self
._assert
_file
_exists
(file)
100 x
= get_output("git ls-files '%s'" % file)
102 raise YapError("File '%s' already in repository" % file)
103 self
._add
_new
_file
(file)
106 def cmd_rm(self
, file):
108 self
._assert
_file
_exists
(file)
109 if get_output("git ls-files '%s'" % file) != []:
110 os
.system("git rm --cached '%s'" % file)
111 self
._remove
_new
_file
(file)
114 def cmd_stage(self
, file, quiet
=False):
116 self
._assert
_file
_exists
(file)
117 os
.system("git update-index --add '%s'" % file)
121 def cmd_unstage(self
, file):
123 self
._assert
_file
_exists
(file)
124 if run_command("git rev-parse HEAD"):
125 os
.system("git update-index --force-remove '%s'" % file)
127 os
.system("git diff-index -p HEAD '%s' | git apply -R --cached" % file)
130 def cmd_status(self
):
131 branch
= get_output("git symbolic-ref HEAD")[0]
132 branch
= branch
.replace('refs/heads/', '')
133 print "Current branch: %s" % branch
135 print "Files with staged changes:"
136 files
= self
._get
_staged
_files
()
142 print "Files with unstaged changes:"
143 files
= self
._get
_unstaged
_files
()
149 def cmd_unedit(self
, file):
151 self
._assert
_file
_exists
(file)
152 os
.system("git checkout-index -f '%s'" % file)
156 def cmd_commit(self
, **flags
):
157 if '-a' in flags
and '-d' in flags
:
158 raise YapError("Conflicting flags: -a and -d")
160 if '-d' not in flags
and self
._get
_unstaged
_files
():
161 if '-a' not in flags
and self
._get
_staged
_files
():
162 raise YapError("Staged and unstaged changes present. Specify what to commit")
163 os
.system("git diff-files -p | git apply --cached 2>/dev/null")
164 for f
in self
._get
_new
_files
():
165 self
.cmd_stage(f
, True)
167 if not self
._get
_staged
_files
():
168 raise YapError("No changes to commit")
170 tree
= get_output("git write-tree")[0]
172 parent
= get_output("git rev-parse HEAD 2> /dev/null")[0]
174 if os
.environ
.has_key('YAP_EDITOR'):
175 editor
= os
.environ
['YAP_EDITOR']
176 elif os
.environ
.has_key('GIT_EDITOR'):
177 editor
= os
.environ
['GIT_EDITOR']
178 elif os
.environ
.has_key('EDITOR'):
179 editor
= os
.environ
['EDITOR']
183 fd
, tmpfile
= tempfile
.mkstemp("yap")
185 if os
.system("%s '%s'" % (editor
, tmpfile
)) != 0:
186 raise YapError("Editing commit message failed")
188 commit
= get_output("git commit-tree '%s' -p '%s' < '%s'" % (tree
, parent
, tmpfile
))
190 commit
= get_output("git commit-tree '%s' < '%s'" % (tree
, tmpfile
))
192 raise YapError("Commit failed; no log message?")
194 os
.system("git update-ref HEAD '%s'" % commit
[0])
197 def cmd_uncommit(self
):
198 tree
= get_output("git rev-parse HEAD^")
199 os
.system("git read-tree '%s'" % tree
[0])
202 def cmd_version(self
):
203 print "Yap version 0.1"
206 print >> sys
.stderr
, "usage: %s <command>" % sys
.argv
[0]
207 print >> sys
.stderr
, " valid commands: version"
209 def main(self
, args
):
217 debug
= os
.getenv('YAP_DEBUG')
220 meth
= self
.__getattribute
__("cmd_"+command
)
222 if "options" in meth
.__dict
__:
223 flags
, args
= getopt
.getopt(args
, meth
.options
)
229 except (TypeError, getopt
.GetoptError
):
232 print "%s %s %s" % (sys
.argv
[0], command
, meth
.__doc
__)
234 print >> sys
.stderr
, e
236 except AttributeError: