~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to contrib/NGit/NGit.Api/PushCommand.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
This code is derived from jgit (http://eclipse.org/jgit).
 
3
Copyright owners are documented in jgit's IP log.
 
4
 
 
5
This program and the accompanying materials are made available
 
6
under the terms of the Eclipse Distribution License v1.0 which
 
7
accompanies this distribution, is reproduced below, and is
 
8
available at http://www.eclipse.org/org/documents/edl-v10.php
 
9
 
 
10
All rights reserved.
 
11
 
 
12
Redistribution and use in source and binary forms, with or
 
13
without modification, are permitted provided that the following
 
14
conditions are met:
 
15
 
 
16
- Redistributions of source code must retain the above copyright
 
17
  notice, this list of conditions and the following disclaimer.
 
18
 
 
19
- Redistributions in binary form must reproduce the above
 
20
  copyright notice, this list of conditions and the following
 
21
  disclaimer in the documentation and/or other materials provided
 
22
  with the distribution.
 
23
 
 
24
- Neither the name of the Eclipse Foundation, Inc. nor the
 
25
  names of its contributors may be used to endorse or promote
 
26
  products derived from this software without specific prior
 
27
  written permission.
 
28
 
 
29
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 
30
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 
31
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
32
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
33
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 
34
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
35
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
36
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
37
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
38
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
39
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
40
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
41
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
42
*/
 
43
 
 
44
using System;
 
45
using System.Collections.Generic;
 
46
using System.IO;
 
47
using NGit;
 
48
using NGit.Api;
 
49
using NGit.Api.Errors;
 
50
using NGit.Errors;
 
51
using NGit.Transport;
 
52
using Sharpen;
 
53
 
 
54
namespace NGit.Api
 
55
{
 
56
        /// <summary>
 
57
        /// A class used to execute a
 
58
        /// <code>Push</code>
 
59
        /// command. It has setters for all
 
60
        /// supported options and arguments of this command and a
 
61
        /// <see cref="Call()">Call()</see>
 
62
        /// method
 
63
        /// to finally execute the command.
 
64
        /// </summary>
 
65
        /// <seealso><a href="http://www.kernel.org/pub/software/scm/git/docs/git-push.html"
 
66
        /// *      >Git documentation about Push</a></seealso>
 
67
        public class PushCommand : GitCommand<Iterable<PushResult>>
 
68
        {
 
69
                private string remote = Constants.DEFAULT_REMOTE_NAME;
 
70
 
 
71
                private readonly IList<RefSpec> refSpecs;
 
72
 
 
73
                private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;
 
74
 
 
75
                private string receivePack = RemoteConfig.DEFAULT_RECEIVE_PACK;
 
76
 
 
77
                private bool dryRun;
 
78
 
 
79
                private bool force;
 
80
 
 
81
                private bool thin = NGit.Transport.Transport.DEFAULT_PUSH_THIN;
 
82
 
 
83
                private int timeout;
 
84
 
 
85
                private CredentialsProvider credentialsProvider;
 
86
 
 
87
                /// <param name="repo"></param>
 
88
                protected internal PushCommand(Repository repo) : base(repo)
 
89
                {
 
90
                        refSpecs = new AList<RefSpec>(3);
 
91
                }
 
92
 
 
93
                /// <summary>
 
94
                /// Executes the
 
95
                /// <code>push</code>
 
96
                /// command with all the options and parameters
 
97
                /// collected by the setter methods of this class. Each instance of this
 
98
                /// class should only be used for one invocation of the command (means: one
 
99
                /// call to
 
100
                /// <see cref="Call()">Call()</see>
 
101
                /// )
 
102
                /// </summary>
 
103
                /// <returns>
 
104
                /// an iteration over
 
105
                /// <see cref="NGit.Transport.PushResult">NGit.Transport.PushResult</see>
 
106
                /// objects
 
107
                /// </returns>
 
108
                /// <exception cref="NGit.Api.Errors.InvalidRemoteException">when called with an invalid remote uri
 
109
                ///     </exception>
 
110
                /// <exception cref="NGit.Api.Errors.JGitInternalException">
 
111
                /// a low-level exception of JGit has occurred. The original
 
112
                /// exception can be retrieved by calling
 
113
                /// <see cref="System.Exception.InnerException()">System.Exception.InnerException()</see>
 
114
                /// .
 
115
                /// </exception>
 
116
                public override Iterable<PushResult> Call()
 
117
                {
 
118
                        CheckCallable();
 
119
                        AList<PushResult> pushResults = new AList<PushResult>(3);
 
120
                        try
 
121
                        {
 
122
                                if (refSpecs.IsEmpty())
 
123
                                {
 
124
                                        Ref head = repo.GetRef(Constants.HEAD);
 
125
                                        if (head != null && head.IsSymbolic())
 
126
                                        {
 
127
                                                refSpecs.AddItem(new RefSpec(head.GetLeaf().GetName()));
 
128
                                        }
 
129
                                }
 
130
                                if (force)
 
131
                                {
 
132
                                        for (int i = 0; i < refSpecs.Count; i++)
 
133
                                        {
 
134
                                                refSpecs.Set(i, refSpecs[i].SetForceUpdate(true));
 
135
                                        }
 
136
                                }
 
137
                                IList<NGit.Transport.Transport> transports;
 
138
                                transports = NGit.Transport.Transport.OpenAll(repo, remote, NGit.Transport.Transport.Operation.PUSH
 
139
                                        );
 
140
                                foreach (NGit.Transport.Transport transport in transports)
 
141
                                {
 
142
                                        if (0 <= timeout)
 
143
                                        {
 
144
                                                transport.SetTimeout(timeout);
 
145
                                        }
 
146
                                        transport.SetPushThin(thin);
 
147
                                        if (receivePack != null)
 
148
                                        {
 
149
                                                transport.SetOptionReceivePack(receivePack);
 
150
                                        }
 
151
                                        transport.SetDryRun(dryRun);
 
152
                                        if (credentialsProvider != null)
 
153
                                        {
 
154
                                                transport.SetCredentialsProvider(credentialsProvider);
 
155
                                        }
 
156
                                        ICollection<RemoteRefUpdate> toPush = transport.FindRemoteRefUpdatesFor(refSpecs);
 
157
                                        try
 
158
                                        {
 
159
                                                PushResult result = transport.Push(monitor, toPush);
 
160
                                                pushResults.AddItem(result);
 
161
                                        }
 
162
                                        catch (TransportException e)
 
163
                                        {
 
164
                                                throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPushCommand
 
165
                                                        , e);
 
166
                                        }
 
167
                                        finally
 
168
                                        {
 
169
                                                transport.Close();
 
170
                                        }
 
171
                                }
 
172
                        }
 
173
                        catch (URISyntaxException)
 
174
                        {
 
175
                                throw new InvalidRemoteException(MessageFormat.Format(JGitText.Get().invalidRemote
 
176
                                        , remote));
 
177
                        }
 
178
                        catch (NotSupportedException e)
 
179
                        {
 
180
                                throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPushCommand
 
181
                                        , e);
 
182
                        }
 
183
                        catch (IOException e)
 
184
                        {
 
185
                                throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPushCommand
 
186
                                        , e);
 
187
                        }
 
188
                        return pushResults.AsIterable ();
 
189
                }
 
190
 
 
191
                /// <summary>The remote (uri or name) used for the push operation.</summary>
 
192
                /// <remarks>
 
193
                /// The remote (uri or name) used for the push operation. If no remote is
 
194
                /// set, the default value of <code>Constants.DEFAULT_REMOTE_NAME</code> will
 
195
                /// be used.
 
196
                /// </remarks>
 
197
                /// <seealso cref="NGit.Constants.DEFAULT_REMOTE_NAME">NGit.Constants.DEFAULT_REMOTE_NAME
 
198
                ///     </seealso>
 
199
                /// <param name="remote"></param>
 
200
                /// <returns>
 
201
                /// 
 
202
                /// <code>this</code>
 
203
                /// </returns>
 
204
                public virtual NGit.Api.PushCommand SetRemote(string remote)
 
205
                {
 
206
                        CheckCallable();
 
207
                        this.remote = remote;
 
208
                        return this;
 
209
                }
 
210
 
 
211
                /// <returns>the remote used for the remote operation</returns>
 
212
                public virtual string GetRemote()
 
213
                {
 
214
                        return remote;
 
215
                }
 
216
 
 
217
                /// <summary>The remote executable providing receive-pack service for pack transports.
 
218
                ///     </summary>
 
219
                /// <remarks>
 
220
                /// The remote executable providing receive-pack service for pack transports.
 
221
                /// If no receive-pack is set, the default value of
 
222
                /// <code>RemoteConfig.DEFAULT_RECEIVE_PACK</code> will be used.
 
223
                /// </remarks>
 
224
                /// <seealso cref="NGit.Transport.RemoteConfig.DEFAULT_RECEIVE_PACK">NGit.Transport.RemoteConfig.DEFAULT_RECEIVE_PACK
 
225
                ///     </seealso>
 
226
                /// <param name="receivePack"></param>
 
227
                /// <returns>
 
228
                /// 
 
229
                /// <code>this</code>
 
230
                /// </returns>
 
231
                public virtual NGit.Api.PushCommand SetReceivePack(string receivePack)
 
232
                {
 
233
                        CheckCallable();
 
234
                        this.receivePack = receivePack;
 
235
                        return this;
 
236
                }
 
237
 
 
238
                /// <returns>the receive-pack used for the remote operation</returns>
 
239
                public virtual string GetReceivePack()
 
240
                {
 
241
                        return receivePack;
 
242
                }
 
243
 
 
244
                /// <param name="timeout">the timeout used for the push operation</param>
 
245
                /// <returns>
 
246
                /// 
 
247
                /// <code>this</code>
 
248
                /// </returns>
 
249
                public virtual NGit.Api.PushCommand SetTimeout(int timeout)
 
250
                {
 
251
                        CheckCallable();
 
252
                        this.timeout = timeout;
 
253
                        return this;
 
254
                }
 
255
 
 
256
                /// <returns>the timeout used for the push operation</returns>
 
257
                public virtual int GetTimeout()
 
258
                {
 
259
                        return timeout;
 
260
                }
 
261
 
 
262
                /// <returns>the progress monitor for the push operation</returns>
 
263
                public virtual ProgressMonitor GetProgressMonitor()
 
264
                {
 
265
                        return monitor;
 
266
                }
 
267
 
 
268
                /// <summary>The progress monitor associated with the push operation.</summary>
 
269
                /// <remarks>
 
270
                /// The progress monitor associated with the push operation. By default, this
 
271
                /// is set to <code>NullProgressMonitor</code>
 
272
                /// </remarks>
 
273
                /// <seealso cref="NGit.NullProgressMonitor">NGit.NullProgressMonitor</seealso>
 
274
                /// <param name="monitor"></param>
 
275
                /// <returns>
 
276
                /// 
 
277
                /// <code>this</code>
 
278
                /// </returns>
 
279
                public virtual NGit.Api.PushCommand SetProgressMonitor(ProgressMonitor monitor)
 
280
                {
 
281
                        CheckCallable();
 
282
                        this.monitor = monitor;
 
283
                        return this;
 
284
                }
 
285
 
 
286
                /// <returns>the ref specs</returns>
 
287
                public virtual IList<RefSpec> GetRefSpecs()
 
288
                {
 
289
                        return refSpecs;
 
290
                }
 
291
 
 
292
                /// <summary>The ref specs to be used in the push operation</summary>
 
293
                /// <param name="specs"></param>
 
294
                /// <returns>
 
295
                /// 
 
296
                /// <code>this</code>
 
297
                /// </returns>
 
298
                public virtual NGit.Api.PushCommand SetRefSpecs(params RefSpec[] specs)
 
299
                {
 
300
                        CheckCallable();
 
301
                        this.refSpecs.Clear();
 
302
                        Sharpen.Collections.AddAll(refSpecs, specs);
 
303
                        return this;
 
304
                }
 
305
 
 
306
                /// <summary>The ref specs to be used in the push operation</summary>
 
307
                /// <param name="specs"></param>
 
308
                /// <returns>
 
309
                /// 
 
310
                /// <code>this</code>
 
311
                /// </returns>
 
312
                public virtual NGit.Api.PushCommand SetRefSpecs(IList<RefSpec> specs)
 
313
                {
 
314
                        CheckCallable();
 
315
                        this.refSpecs.Clear();
 
316
                        Sharpen.Collections.AddAll(this.refSpecs, specs);
 
317
                        return this;
 
318
                }
 
319
 
 
320
                /// <summary>Push all branches under refs/heads/*.</summary>
 
321
                /// <remarks>Push all branches under refs/heads/*.</remarks>
 
322
                /// <returns>{code this}</returns>
 
323
                public virtual NGit.Api.PushCommand SetPushAll()
 
324
                {
 
325
                        refSpecs.AddItem(NGit.Transport.Transport.REFSPEC_PUSH_ALL);
 
326
                        return this;
 
327
                }
 
328
 
 
329
                /// <summary>Push all tags under refs/tags/*.</summary>
 
330
                /// <remarks>Push all tags under refs/tags/*.</remarks>
 
331
                /// <returns>{code this}</returns>
 
332
                public virtual NGit.Api.PushCommand SetPushTags()
 
333
                {
 
334
                        refSpecs.AddItem(NGit.Transport.Transport.REFSPEC_TAGS);
 
335
                        return this;
 
336
                }
 
337
 
 
338
                /// <summary>Add a reference to push.</summary>
 
339
                /// <remarks>Add a reference to push.</remarks>
 
340
                /// <param name="ref">the source reference. The remote name will match.</param>
 
341
                /// <returns>
 
342
                /// 
 
343
                /// <code>this</code>
 
344
                /// .
 
345
                /// </returns>
 
346
                public virtual NGit.Api.PushCommand Add(Ref @ref)
 
347
                {
 
348
                        refSpecs.AddItem(new RefSpec(@ref.GetLeaf().GetName()));
 
349
                        return this;
 
350
                }
 
351
 
 
352
                /// <summary>Add a reference to push.</summary>
 
353
                /// <remarks>Add a reference to push.</remarks>
 
354
                /// <param name="nameOrSpec">any reference name, or a reference specification.</param>
 
355
                /// <returns>
 
356
                /// 
 
357
                /// <code>this</code>
 
358
                /// .
 
359
                /// </returns>
 
360
                /// <exception cref="NGit.Api.Errors.JGitInternalException">the reference name cannot be resolved.
 
361
                ///     </exception>
 
362
                public virtual NGit.Api.PushCommand Add(string nameOrSpec)
 
363
                {
 
364
                        if (0 <= nameOrSpec.IndexOf(':'))
 
365
                        {
 
366
                                refSpecs.AddItem(new RefSpec(nameOrSpec));
 
367
                        }
 
368
                        else
 
369
                        {
 
370
                                Ref src;
 
371
                                try
 
372
                                {
 
373
                                        src = repo.GetRef(nameOrSpec);
 
374
                                }
 
375
                                catch (IOException e)
 
376
                                {
 
377
                                        throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPushCommand
 
378
                                                , e);
 
379
                                }
 
380
                                if (src != null)
 
381
                                {
 
382
                                        Add(src);
 
383
                                }
 
384
                        }
 
385
                        return this;
 
386
                }
 
387
 
 
388
                /// <returns>the dry run preference for the push operation</returns>
 
389
                public virtual bool IsDryRun()
 
390
                {
 
391
                        return dryRun;
 
392
                }
 
393
 
 
394
                /// <summary>Sets whether the push operation should be a dry run</summary>
 
395
                /// <param name="dryRun"></param>
 
396
                /// <returns>
 
397
                /// 
 
398
                /// <code>this</code>
 
399
                /// </returns>
 
400
                public virtual NGit.Api.PushCommand SetDryRun(bool dryRun)
 
401
                {
 
402
                        CheckCallable();
 
403
                        this.dryRun = dryRun;
 
404
                        return this;
 
405
                }
 
406
 
 
407
                /// <returns>the thin-pack preference for push operation</returns>
 
408
                public virtual bool IsThin()
 
409
                {
 
410
                        return thin;
 
411
                }
 
412
 
 
413
                /// <summary>Sets the thin-pack preference for push operation.</summary>
 
414
                /// <remarks>
 
415
                /// Sets the thin-pack preference for push operation.
 
416
                /// Default setting is Transport.DEFAULT_PUSH_THIN
 
417
                /// </remarks>
 
418
                /// <param name="thin"></param>
 
419
                /// <returns>
 
420
                /// 
 
421
                /// <code>this</code>
 
422
                /// </returns>
 
423
                public virtual NGit.Api.PushCommand SetThin(bool thin)
 
424
                {
 
425
                        CheckCallable();
 
426
                        this.thin = thin;
 
427
                        return this;
 
428
                }
 
429
 
 
430
                /// <returns>the force preference for push operation</returns>
 
431
                public virtual bool IsForce()
 
432
                {
 
433
                        return force;
 
434
                }
 
435
 
 
436
                /// <summary>Sets the force preference for push operation.</summary>
 
437
                /// <remarks>Sets the force preference for push operation.</remarks>
 
438
                /// <param name="force"></param>
 
439
                /// <returns>
 
440
                /// 
 
441
                /// <code>this</code>
 
442
                /// </returns>
 
443
                public virtual NGit.Api.PushCommand SetForce(bool force)
 
444
                {
 
445
                        CheckCallable();
 
446
                        this.force = force;
 
447
                        return this;
 
448
                }
 
449
 
 
450
                /// <param name="credentialsProvider">
 
451
                /// the
 
452
                /// <see cref="NGit.Transport.CredentialsProvider">NGit.Transport.CredentialsProvider
 
453
                ///     </see>
 
454
                /// to use
 
455
                /// </param>
 
456
                /// <returns>
 
457
                /// 
 
458
                /// <code>this</code>
 
459
                /// </returns>
 
460
                public virtual NGit.Api.PushCommand SetCredentialsProvider(CredentialsProvider credentialsProvider
 
461
                        )
 
462
                {
 
463
                        CheckCallable();
 
464
                        this.credentialsProvider = credentialsProvider;
 
465
                        return this;
 
466
                }
 
467
        }
 
468
}