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 (default true)
36 ['reference'] (optional): use this reference repository
37 to fetch objects.
38 ['gerrit_branch'] (optional): which virtual branch to retrieve.
39 ['progress'] (optional): have git output progress markers,
40 avoiding timeouts for long fetches;
41 requires Git 1.7.2 or later.
42 ['shallow'] (optional): if true, use shallow clones that do not
43 also fetch history
44 """
45
46 header = "git operation"
47
49 SourceBaseCommand.setup(self, args)
50 self.repourl = args['repourl']
51 self.branch = args.get('branch')
52 if not self.branch:
53 self.branch = "master"
54 self.sourcedata = "%s %s\n" % (self.repourl, self.branch)
55 self.submodules = args.get('submodules')
56 self.ignore_ignores = args.get('ignore_ignores', True)
57 self.reference = args.get('reference', None)
58 self.gerrit_branch = args.get('gerrit_branch', None)
59
62
64 return os.path.isdir(os.path.join(self._fullSrcdir(), ".git"))
65
66 - def _dovccmd(self, command, cb=None, stopOnFail=True, **kwargs):
79
81
82
83
84
85
86 try:
87 self.readSourcedata()
88 except IOError:
89 return False
90 return True
91
93 command = ['submodule', 'foreach', 'git', 'clean', '-f', '-d']
94 if self.ignore_ignores:
95 command.append('-x')
96 return self._dovccmd(command)
97
99 return self._dovccmd(['submodule', 'update'], self._cleanSubmodules)
100
102 if self.submodules:
103 return self._dovccmd(['submodule', 'init'], self._updateSubmodules)
104 else:
105 return defer.succeed(0)
106
108
109
110 command = ['branch', '-M', self.branch]
111 return self._dovccmd(command, self._initSubmodules, False)
112
114 if self.revision:
115 head = self.revision
116 else:
117 head = 'FETCH_HEAD'
118
119
120
121 command = ['reset', '--hard', head]
122 return self._dovccmd(command, self._didHeadCheckout)
123
125
126
127 if hasattr(self.command, 'stderr'):
128 if "Couldn't find remote ref" in self.command.stderr:
129 raise AbandonChain(-1)
130
131
132
133
134
147
149
150
151 command = ['fetch', '-t', self.repourl, '+%s' % branch]
152
153
154
155
156 if self.args.get('progress'):
157 command.append('--progress')
158 self.sendStatus({"header": "fetching branch %s from %s\n"
159 % (branch, self.repourl)})
160 return self._dovccmd(command, self._didFetch, keepStderr=True)
161
163 branch = self.gerrit_branch or self.branch
164
165
166 if self.revision:
167
168 d = self._dovccmd(['reset', '--hard', self.revision],
169 self._initSubmodules)
170
171
172 d.addErrback(self._doFetch, branch)
173 return d
174 else:
175
176 return self._doFetch(None, branch)
177
179
180
181 if self.reference:
182 git_alts_path = os.path.join(self._fullSrcdir(), '.git', 'objects', 'info', 'alternates')
183 git_alts_content = os.path.join(self.reference, 'objects')
184 self.setFileContents(git_alts_path, git_alts_content)
185 return self.doVCUpdate()
186
188 git = self.getCommand("git")
189
190
191
192 if not self.args.get('revision') and self.args.get('shallow'):
193 cmd = [git, 'clone', '--depth', '1']
194
195 if self.reference:
196 cmd.extend(['--reference', self.reference])
197 cmd.extend([self.repourl, self._fullSrcdir()])
198 c = runprocess.RunProcess(self.builder, cmd, self.builder.basedir,
199 sendRC=False, timeout=self.timeout,
200 maxTime=self.maxTime, logEnviron=self.logEnviron,
201 usePTY=False)
202 self.command = c
203 cmdexec = c.start()
204 cmdexec.addCallback(self._didInit)
205 return cmdexec
206 else:
207 os.makedirs(self._fullSrcdir())
208 return self._dovccmd(['init'], self._didInit)
209
211 command = ['rev-parse', 'HEAD']
212 def _parse(res):
213 hash = self.command.stdout.strip()
214 if len(hash) != 40:
215 return None
216 return hash
217 return self._dovccmd(command, _parse, keepStdout=True)
218