1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.transport;
45
46 import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_ATOMIC;
47 import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_REPORT_STATUS;
48
49 import java.io.IOException;
50 import java.io.InputStream;
51 import java.io.OutputStream;
52
53 import org.eclipse.jgit.errors.UnpackException;
54 import org.eclipse.jgit.lib.Constants;
55 import org.eclipse.jgit.lib.Repository;
56 import org.eclipse.jgit.transport.ReceiveCommand.Result;
57 import org.eclipse.jgit.transport.RefAdvertiser.PacketLineOutRefAdvertiser;
58
59
60
61
62 public class ReceivePack extends BaseReceivePack {
63
64 private PreReceiveHook preReceive;
65
66
67 private PostReceiveHook postReceive;
68
69
70 private boolean reportStatus;
71
72 private boolean echoCommandFailures;
73
74
75
76
77
78
79
80 public ReceivePack(final Repository into) {
81 super(into);
82 preReceive = PreReceiveHook.NULL;
83 postReceive = PostReceiveHook.NULL;
84 }
85
86
87 public PreReceiveHook getPreReceiveHook() {
88 return preReceive;
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 public void setPreReceiveHook(final PreReceiveHook h) {
106 preReceive = h != null ? h : PreReceiveHook.NULL;
107 }
108
109
110 public PostReceiveHook getPostReceiveHook() {
111 return postReceive;
112 }
113
114
115
116
117
118
119
120
121
122
123
124 public void setPostReceiveHook(final PostReceiveHook h) {
125 postReceive = h != null ? h : PostReceiveHook.NULL;
126 }
127
128
129
130
131
132
133
134
135 public void setEchoCommandFailures(boolean echo) {
136 echoCommandFailures = echo;
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 public void receive(final InputStream input, final OutputStream output,
158 final OutputStream messages) throws IOException {
159 init(input, output, messages);
160 try {
161 service();
162 } finally {
163 try {
164 close();
165 } finally {
166 release();
167 }
168 }
169 }
170
171 @Override
172 protected void enableCapabilities() {
173 reportStatus = isCapabilityEnabled(CAPABILITY_REPORT_STATUS);
174 super.enableCapabilities();
175 }
176
177 private void service() throws IOException {
178 if (isBiDirectionalPipe()) {
179 sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut));
180 pckOut.flush();
181 } else
182 getAdvertisedOrDefaultRefs();
183 if (hasError())
184 return;
185 recvCommands();
186 if (hasCommands()) {
187 enableCapabilities();
188
189 Throwable unpackError = null;
190 if (needPack()) {
191 try {
192 receivePackAndCheckConnectivity();
193 } catch (IOException err) {
194 unpackError = err;
195 } catch (RuntimeException err) {
196 unpackError = err;
197 } catch (Error err) {
198 unpackError = err;
199 }
200 }
201
202 if (unpackError == null) {
203 boolean atomic = isCapabilityEnabled(CAPABILITY_ATOMIC);
204 validateCommands();
205 if (atomic && anyRejects())
206 failPendingCommands();
207
208 preReceive.onPreReceive(this, filterCommands(Result.NOT_ATTEMPTED));
209 if (atomic && anyRejects())
210 failPendingCommands();
211 executeCommands();
212 }
213 unlockPack();
214
215 if (reportStatus) {
216 if (echoCommandFailures && msgOut != null) {
217 sendStatusReport(false, unpackError, new Reporter() {
218 void sendString(final String s) throws IOException {
219 msgOut.write(Constants.encode(s + "\n"));
220 }
221 });
222 msgOut.flush();
223 try {
224 Thread.sleep(500);
225 } catch (InterruptedException wakeUp) {
226
227 }
228 }
229 sendStatusReport(true, unpackError, new Reporter() {
230 void sendString(final String s) throws IOException {
231 pckOut.writeString(s + "\n");
232 }
233 });
234 pckOut.end();
235 } else if (msgOut != null) {
236 sendStatusReport(false, unpackError, new Reporter() {
237 void sendString(final String s) throws IOException {
238 msgOut.write(Constants.encode(s + "\n"));
239 }
240 });
241 }
242
243 if (unpackError != null) {
244
245
246 try {
247 postReceive.onPostReceive(this, filterCommands(Result.OK));
248 } catch (Throwable e) {
249 }
250 throw new UnpackException(unpackError);
251 }
252 postReceive.onPostReceive(this, filterCommands(Result.OK));
253 }
254 }
255
256 @Override
257 protected String getLockMessageProcessName() {
258 return "jgit receive-pack";
259 }
260 }