1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import os
17
18 from twisted.internet import defer
19
20 from buildslave.commands.base import SourceBaseCommand
21 from buildslave import runprocess
22 from buildslave.commands.base import AbandonChain
23
24
25 -class Git(SourceBaseCommand):
26 """Git specific VC operation. In addition to the arguments
27 handled by SourceBaseCommand, this command reads the following keys:
28
29 ['repourl'] (required): the upstream GIT repository string
30 ['branch'] (optional): which version (i.e. branch or tag)
31 to retrieve. Default: "master".
32 ['submodules'] (optional): whether to initialize and update
33 submodules. Default: False.
34 ['ignore_ignores'] (optional): ignore ignores when purging changes.
35 ['reference'] (optional): use this reference repository
36 to fetch objects.
37 ['gerrit_branch'] (optional): which virtual branch to retrieve.
38 ['progress'] (optional): have git output progress markers,
39 avoiding timeouts for long fetches;
40 requires Git 1.7.2 or later.
41 """
42
43 header = "git operation"
44
46 SourceBaseCommand.setup(self, args)
47 self.repourl = args['repourl']
48 self.branch = args.get('branch')
49 if not self.branch:
50 self.branch = "master"
51 self.sourcedata = "%s %s\n" % (self.repourl, self.branch)
52 self.submodules = args.get('submodules')
53 self.ignore_ignores = args.get('ignore_ignores', True)
54 self.reference = args.get('reference', None)
55 self.gerrit_branch = args.get('gerrit_branch', None)
56
59
64
66 return os.path.isdir(os.path.join(self._fullSrcdir(), ".git"))
67
68 - def _dovccmd(self, command, cb=None, **kwargs):
79
80
81
82
83
84
86 try:
87 olddata = self.readSourcedata()
88 if not olddata.startswith(self.repourl+' '):
89 return False
90 except IOError:
91 return False
92 return True
93
95 command = ['submodule', 'foreach', 'git', 'clean', '-d', '-f']
96 if self.ignore_ignores:
97 command.append('-x')
98 return self._dovccmd(command)
99
101 return self._dovccmd(['submodule', 'update'], self._cleanSubmodules)
102
104 if self.submodules:
105 return self._dovccmd(['submodule', 'init'], self._updateSubmodules)
106 else:
107 return defer.succeed(0)
108
110
111
112 command = ['branch', '-M', self.branch]
113 return self._dovccmd(command, self._initSubmodules)
114
116 if self.revision:
117 head = self.revision
118 else:
119 head = 'FETCH_HEAD'
120
121
122
123 command = ['reset', '--hard', head]
124 return self._dovccmd(command, self._didHeadCheckout)
125
127
128
129 if hasattr(self.command, 'stderr'):
130 if "Couldn't find remote ref" in self.command.stderr:
131 raise AbandonChain(-1)
132
133
134
135
136
138 try:
139
140 diffbranch = self.sourcedata != self.readSourcedata()
141 except IOError:
142 diffbranch = False
143 if diffbranch:
144 command = ['clean', '-f', '-d']
145 if self.ignore_ignores:
146 command.append('-x')
147 return self._dovccmd(command, self._didClean)
148 return self._didClean(None)
149
151
152
153 command = ['fetch', '-t', self.repourl, '+%s' % branch]
154
155
156
157
158 if self.args.get('progress'):
159 command.append('--progress')
160 self.sendStatus({"header": "fetching branch %s from %s\n"
161 % (branch, self.repourl)})
162 return self._dovccmd(command, self._didFetch, keepStderr=True)
163
165 branch = self.gerrit_branch or self.branch
166
167
168 if self.revision:
169
170 d = self._dovccmd(['reset', '--hard', self.revision],
171 self._initSubmodules)
172
173
174 d.addErrback(self._doFetch, branch)
175 return d
176 else:
177
178 return self._doFetch(None, branch)
179
181
182
183 if self.reference:
184 git_alts_path = os.path.join(self._fullSrcdir(), '.git', 'objects', 'info', 'alternates')
185 git_alts_file = open(git_alts_path, 'w')
186 git_alts_file.write(os.path.join(self.reference, 'objects'))
187 git_alts_file.close()
188 return self.doVCUpdate()
189
191 git = self.getCommand("git")
192
193
194
195 if not self.args.get('revision') and self.args.get('shallow'):
196 cmd = [git, 'clone', '--depth', '1']
197
198 if self.reference:
199 cmd.extend(['--reference', self.reference])
200 cmd.extend([self.repourl, self._fullSrcdir()])
201 c = runprocess.RunProcess(self.builder, cmd, self.builder.basedir,
202 sendRC=False, timeout=self.timeout,
203 maxTime=self.maxTime, usePTY=False)
204 self.command = c
205 cmdexec = c.start()
206 cmdexec.addCallback(self._didInit)
207 return cmdexec
208 else:
209 os.makedirs(self._fullSrcdir())
210 return self._dovccmd(['init'], self._didInit)
211
213 command = ['rev-parse', 'HEAD']
214 def _parse(res):
215 hash = self.command.stdout.strip()
216 if len(hash) != 40:
217 return None
218 return hash
219 return self._dovccmd(command, _parse, keepStdout=True)
220