annotate hglib/hglib.py @ 0:79f88b4db15f

Initial commit
author Idan Kamara <idankk86@gmail.com>
date Wed, 20 Jul 2011 16:09:34 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
1 import subprocess, os, struct, cStringIO, collections
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
2 import error, util
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
3
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
4 HGPATH = 'hg'
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
5
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
6 def connect(path=None, encoding=None, configs=None):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
7 ''' starts a cmdserver for the given path (or for a repository found in the
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
8 cwd). HGENCODING is set to the given encoding. configs is a list of key, value,
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
9 similar to those passed to hg --config. '''
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
10 return hgclient(path, encoding, configs)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
11
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
12 class hgclient(object):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
13 inputfmt = '>I'
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
14 outputfmt = '>cI'
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
15 outputfmtsize = struct.calcsize(outputfmt)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
16 retfmt = '>i'
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
17
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
18 # XXX fix this hack
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
19 _stylesdir = os.path.join(os.path.dirname(__file__), 'styles')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
20 revstyle = ['--style', os.path.join(_stylesdir, 'rev.style')]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
21
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
22 revision = collections.namedtuple('revision', 'rev, node, tags, '
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
23 'branch, author, desc')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
24
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
25 def __init__(self, path, encoding, configs):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
26 args = [HGPATH, 'serve', '--cmdserver', 'pipe']
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
27 if path:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
28 args += ['-R', path]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
29 if configs:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
30 args += ['--config'] + configs
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
31 env = dict(os.environ)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
32 if encoding:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
33 env['HGENCODING'] = encoding
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
34
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
35 self.server = subprocess.Popen(args, stdin=subprocess.PIPE,
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
36 stdout=subprocess.PIPE, env=env)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
37
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
38 self._readhello()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
39 self._config = {}
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
40
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
41 def _readhello(self):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
42 """ read the hello message the server sends when started """
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
43 ch, msg = self._readchannel()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
44 assert ch == 'o'
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
45
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
46 msg = msg.split('\n')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
47
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
48 self.capabilities = msg[0][len('capabilities: '):]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
49 if not self.capabilities:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
50 raise error.ResponseError("bad hello message: expected 'capabilities: '"
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
51 ", got %r" % msg[0])
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
52
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
53 self.capabilities = set(self.capabilities.split())
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
54
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
55 # at the very least the server should be able to run commands
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
56 assert 'runcommand' in self.capabilities
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
57
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
58 self._encoding = msg[1][len('encoding: '):]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
59 if not self._encoding:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
60 raise error.ResponseError("bad hello message: expected 'encoding: '"
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
61 ", got %r" % msg[1])
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
62
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
63 def _readchannel(self):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
64 data = self.server.stdout.read(hgclient.outputfmtsize)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
65 if not data:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
66 raise error.ServerError()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
67 channel, length = struct.unpack(hgclient.outputfmt, data)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
68 if channel in 'IL':
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
69 return channel, length
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
70 else:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
71 return channel, self.server.stdout.read(length)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
72
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
73 def _parserevs(self, splitted):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
74 ''' splitted is a list of fields according to our rev.style, where each 6
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
75 fields compose one revision. '''
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
76 return [self.revision._make(rev) for rev in util.grouper(6, splitted)]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
77
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
78 def _eatlines(self, s, n):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
79 idx = 0
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
80 for i in xrange(n):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
81 idx = s.find('\n', idx) + 1
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
82
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
83 return s[idx:]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
84
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
85 def runcommand(self, args, inchannels, outchannels):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
86 def writeblock(data):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
87 self.server.stdin.write(struct.pack(self.inputfmt, len(data)))
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
88 self.server.stdin.write(data)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
89 self.server.stdin.flush()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
90
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
91 if not self.server:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
92 raise ValueError("server not connected")
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
93
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
94 self.server.stdin.write('runcommand\n')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
95 writeblock('\0'.join(args))
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
96
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
97 while True:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
98 channel, data = self._readchannel()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
99
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
100 # input channels
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
101 if channel in inchannels:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
102 writeblock(inchannels[channel](data))
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
103 # output channels
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
104 elif channel in outchannels:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
105 outchannels[channel](data)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
106 # result channel, command finished
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
107 elif channel == 'r':
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
108 return struct.unpack(hgclient.retfmt, data)[0]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
109 # a channel that we don't know and can't ignore
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
110 elif channel.isupper():
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
111 raise error.ResponseError("unexpected data on required channel '%s'"
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
112 % channel)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
113 # optional channel
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
114 else:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
115 pass
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
116
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
117 def outputruncommand(self, args, inchannels = {}, raiseonerror=True):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
118 ''' run the command specified by args, returning (ret, output, error) '''
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
119 out, err = cStringIO.StringIO(), cStringIO.StringIO()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
120 outchannels = {'o' : out.write, 'e' : err.write}
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
121 ret = self.runcommand(args, inchannels, outchannels)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
122 if ret and raiseonerror:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
123 raise error.CommandError(args, ret, out.getvalue(), err.getvalue())
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
124 return ret, out.getvalue(), err.getvalue()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
125
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
126 def close(self):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
127 self.server.stdin.close()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
128 self.server.wait()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
129 ret = self.server.returncode
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
130 self.server = None
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
131 return ret
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
132
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
133 @property
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
134 def encoding(self):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
135 """ get the servers encoding """
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
136 if not 'getencoding' in self.capabilities:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
137 raise CapabilityError('getencoding')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
138
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
139 if not self._encoding:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
140 self.server.stdin.write('getencoding\n')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
141 self._encoding = self._readfromchannel('r')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
142
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
143 return self._encoding
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
144
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
145 def config(self, refresh=False):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
146 if not self._config or refresh:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
147 self._config.clear()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
148
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
149 ret, out, err = self.outputruncommand(['showconfig'])
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
150 if ret:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
151 raise error.CommandError(['showconfig'], ret, out, err)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
152
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
153 for entry in cStringIO.StringIO(out):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
154 k, v = entry.rstrip().split('=', 1)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
155 section, name = k.split('.', 1)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
156 self._config.setdefault(section, {})[name] = v
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
157
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
158 return self._config
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
159
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
160 def status(self):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
161 ret, out = self.outputruncommand(['status', '-0'])
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
162
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
163 d = dict((c, []) for c in 'MARC!?I')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
164
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
165 for entry in out.split('\0'):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
166 if entry:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
167 t, f = entry.split(' ', 1)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
168 d[t].append(f)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
169
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
170 return d
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
171
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
172 def log(self, revrange=None):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
173 args = ['log'] + self.revstyle
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
174 if revrange:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
175 args.append('-r')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
176 args += revrange
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
177
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
178 out = self.outputruncommand(args)[1]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
179 out = out.split('\0')[:-1]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
180
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
181 return self._parserevs(out)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
182
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
183 def incoming(self, revrange=None, path=None):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
184 args = ['incoming'] + self.revstyle
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
185 if revrange:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
186 args.append('-r')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
187 args += revrange
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
188
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
189 if path:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
190 args += [path]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
191
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
192 ret, out, err = self.outputruncommand(args, raiseonerror=False)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
193 if not ret:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
194 out = self._eatlines(out, 2).split('\0')[:-1]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
195 return self._parserevs(out)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
196 elif ret == 1:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
197 return []
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
198 else:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
199 raise error.CommandError(args, ret, out, err)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
200
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
201 def outgoing(self, revrange=None, path=None):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
202 args = ['outgoing'] + self.revstyle
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
203 if revrange:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
204 args.append('-r')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
205 args += revrange
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
206
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
207 if path:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
208 args += [path]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
209
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
210 ret, out, err = self.outputruncommand(args, raiseonerror=False)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
211 if not ret:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
212 out = self._eatlines(out, 2).split('\0')[:-1]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
213 return self._parserevs(out)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
214 elif ret == 1:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
215 return []
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
216 else:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
217 raise error.CommandError(args, ret, out, err)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
218
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
219 def commit(self, message, addremove=False):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
220 args = ['commit', '-m', message]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
221
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
222 if addremove:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
223 args += ['-A']
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
224
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
225 self.outputruncommand(args)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
226
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
227 # hope the tip hasn't changed since we committed
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
228 return self.tip()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
229
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
230 def import_(self, patch):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
231 if isinstance(patch, str):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
232 fp = open(patch)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
233 else:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
234 assert hasattr(patch, 'read')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
235 assert hasattr(patch, 'readline')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
236
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
237 fp = patch
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
238
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
239 try:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
240 inchannels = {'I' : fp.read, 'L' : fp.readline}
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
241 self.outputruncommand(['import', '-'], inchannels)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
242 finally:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
243 if fp != patch:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
244 fp.close()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
245
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
246 def root(self):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
247 return self.outputruncommand(['root'])[1].rstrip()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
248
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
249 def clone(self, source='.', dest=None, branch=None, updaterev=None,
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
250 revrange=None):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
251 args = ['clone']
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
252
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
253 if branch:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
254 args += ['-b', branch]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
255 if updaterev:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
256 args += ['-u', updaterev]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
257 if revrange:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
258 args.append('-r')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
259 args += revrange
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
260 args.append(source)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
261
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
262 if dest:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
263 args.append(dest)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
264
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
265 self.outputruncommand(args)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
266
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
267 def tip(self):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
268 out = self.outputruncommand(['tip'] + self.revstyle)[1]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
269 out = out.split('\0')
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
270
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
271 return self._parserevs(out)[0]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
272
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
273 def branch(self, name=None):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
274 if not name:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
275 return self.outputruncommand(['branch'])[1].rstrip()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
276
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
277 def branches(self):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
278 out = self.outputruncommand(['branches'])[1]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
279 branches = {}
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
280 for line in out.rstrip().split('\n'):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
281 branch, revnode = line.split()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
282 branches[branch] = self.log(revrange=[revnode.split(':')[0]])[0]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
283
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
284 return branches
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
285
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
286 def paths(self, name=None):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
287 if not name:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
288 out = self.outputruncommand(['paths'])[1]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
289 if not out:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
290 return {}
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
291
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
292 return dict([s.split(' = ') for s in out.rstrip().split('\n')])
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
293 else:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
294 args = ['paths', name]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
295 ret, out, err = self.outputruncommand(args, raiseonerror=False)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
296 if ret:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
297 raise error.CommandError(args, ret, out, err)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
298 return out.rstrip()
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
299
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
300 def cat(self, files, rev=None, output=None):
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
301 args = ['cat']
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
302 if rev:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
303 args += ['-r', rev]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
304 if output:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
305 args += ['-o', output]
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
306
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
307 args += files
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
308 ret, out, err = self.outputruncommand(args)
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
309
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
310 if not output:
79f88b4db15f Initial commit
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
311 return out