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, **kwargs):
78
80
81
82
83
84
85 try:
86 self.readSourcedata()
87 except IOError:
88 return False
89 return True
90
92 command = ['submodule', 'foreach', 'git', 'clean', '-f', '-d']
93 if self.ignore_ignores:
94 command.append('-x')
95 return self._dovccmd(command)
96
98 return self._dovccmd(['submodule', 'update'], self._cleanSubmodules)
99
101 if self.submodules:
102 return self._dovccmd(['submodule', 'init'], self._updateSubmodules)
103 else:
104 return defer.succeed(0)
105
107
108
109 command = ['branch', '-M', self.branch]
110 return self._dovccmd(command, self._initSubmodules)
111
113 if self.revision:
114 head = self.revision
115 else:
116 head = 'FETCH_HEAD'
117
118
119
120 command = ['reset', '--hard', head]
121 return self._dovccmd(command, self._didHeadCheckout)
122
124
125
126 if hasattr(self.command, 'stderr'):
127 if "Couldn't find remote ref" in self.command.stderr:
128 raise AbandonChain(-1)
129
130
131
132
133
135 try:
136
137 diffbranch = self.sourcedata != self.readSourcedata()
138 except IOError:
139 diffbranch = False
140 if diffbranch:
141 command = ['clean', '-f', '-d']
142 if self.ignore_ignores:
143 command.append('-x')
144 return self._dovccmd(command, self._didClean)
145 return self._didClean(None)
146
148
149
150 command = ['fetch', '-t', self.repourl, '+%s' % branch]
151
152
153
154
155 if self.args.get('progress'):
156 command.append('--progress')
157 self.sendStatus({"header": "fetching branch %s from %s\n"
158 % (branch, self.repourl)})
159 return self._dovccmd(command, self._didFetch, keepStderr=True)
160
162 branch = self.gerrit_branch or self.branch
163
164
165 if self.revision:
166
167 d = self._dovccmd(['reset', '--hard', self.revision],
168 self._initSubmodules)
169
170
171 d.addErrback(self._doFetch, branch)
172 return d
173 else:
174
175 return self._doFetch(None, branch)
176
178
179
180 if self.reference:
181 git_alts_path = os.path.join(self._fullSrcdir(), '.git', 'objects', 'info', 'alternates')
182 git_alts_content = os.path.join(self.reference, 'objects')
183 self.setFileContents(git_alts_path, git_alts_content)
184 return self.doVCUpdate()
185
187 git = self.getCommand("git")
188
189
190
191 if not self.args.get('revision') and self.args.get('shallow'):
192 cmd = [git, 'clone', '--depth', '1']
193
194 if self.reference:
195 cmd.extend(['--reference', self.reference])
196 cmd.extend([self.repourl, self._fullSrcdir()])
197 c = runprocess.RunProcess(self.builder, cmd, self.builder.basedir,
198 sendRC=False, timeout=self.timeout,
199 maxTime=self.maxTime, logEnviron=self.logEnviron,
200 usePTY=False)
201 self.command = c
202 cmdexec = c.start()
203 cmdexec.addCallback(self._didInit)
204 return cmdexec
205 else:
206 os.makedirs(self._fullSrcdir())
207 return self._dovccmd(['init'], self._didInit)
208
210 command = ['rev-parse', 'HEAD']
211 def _parse(res):
212 hash = self.command.stdout.strip()
213 if len(hash) != 40:
214 return None
215 return hash
216 return self._dovccmd(command, _parse, keepStdout=True)
217