2
This code is derived from jgit (http://eclipse.org/jgit).
3
Copyright owners are documented in jgit's IP log.
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
12
Redistribution and use in source and binary forms, with or
13
without modification, are permitted provided that the following
16
- Redistributions of source code must retain the above copyright
17
notice, this list of conditions and the following disclaimer.
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.
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
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.
51
namespace NGit.Transport
53
/// <summary>Represent request and status of a remote ref update.</summary>
55
/// Represent request and status of a remote ref update. Specification is
56
/// provided by client, while status is handled by
57
/// <see cref="PushProcess">PushProcess</see>
59
/// being read-only for client.
61
/// Client can create instances of this class directly, basing on user
62
/// specification and advertised refs (
63
/// <see cref="Connection">Connection</see>
65
/// <see cref="Transport">Transport</see>
66
/// helper methods. Apply this specification on remote
68
/// <see cref="Transport.Push(NGit.ProgressMonitor, System.Collections.Generic.ICollection{E})
69
/// ">Transport.Push(NGit.ProgressMonitor, System.Collections.Generic.ICollection<E>)
74
public class RemoteRefUpdate
76
/// <summary>Represent current status of a remote ref update.</summary>
77
/// <remarks>Represent current status of a remote ref update.</remarks>
82
REJECTED_NONFASTFORWARD,
84
REJECTED_REMOTE_CHANGED,
85
REJECTED_OTHER_REASON,
91
private readonly ObjectId expectedOldObjectId;
93
private readonly ObjectId newObjectId;
95
private readonly string remoteName;
97
private readonly TrackingRefUpdate trackingRefUpdate;
99
private readonly string srcRef;
101
private readonly bool forceUpdate;
103
private RemoteRefUpdate.Status status;
105
private bool fastForward;
107
private string message;
109
private readonly Repository localDb;
111
/// <summary>Construct remote ref update request by providing an update specification.
114
/// Construct remote ref update request by providing an update specification.
115
/// Object is created with default
116
/// <see cref="Status.NOT_ATTEMPTED">Status.NOT_ATTEMPTED</see>
120
/// <param name="localDb">local repository to push from.</param>
121
/// <param name="srcRef">
122
/// source revision - any string resolvable by
123
/// <see cref="NGit.Repository.Resolve(string)">NGit.Repository.Resolve(string)</see>
124
/// . This resolves to the new
125
/// object that the caller want remote ref to be after update. Use
127
/// <see cref="NGit.ObjectId.ZeroId()">NGit.ObjectId.ZeroId()</see>
128
/// string for delete request.
130
/// <param name="remoteName">
131
/// full name of a remote ref to update, e.g. "refs/heads/master"
132
/// (no wildcard, no short name).
134
/// <param name="forceUpdate">
135
/// true when caller want remote ref to be updated regardless
136
/// whether it is fast-forward update (old object is ancestor of
139
/// <param name="localName">
140
/// optional full name of a local stored tracking branch, to
141
/// update after push, e.g. "refs/remotes/zawir/dirty" (no
142
/// wildcard, no short name); null if no local tracking branch
143
/// should be updated.
145
/// <param name="expectedOldObjectId">
146
/// optional object id that caller is expecting, requiring to be
147
/// advertised by remote side before update; update will take
148
/// place ONLY if remote side advertise exactly this expected id;
149
/// null if caller doesn't care what object id remote side
151
/// <see cref="NGit.ObjectId.ZeroId()">NGit.ObjectId.ZeroId()</see>
152
/// when expecting no
153
/// remote ref with this name.
155
/// <exception cref="System.IO.IOException">
156
/// when I/O error occurred during creating
157
/// <see cref="TrackingRefUpdate">TrackingRefUpdate</see>
158
/// for local tracking branch or srcRef
159
/// can't be resolved to any object.
161
/// <exception cref="System.ArgumentException">if some required parameter was null</exception>
162
public RemoteRefUpdate(Repository localDb, string srcRef, string remoteName, bool
163
forceUpdate, string localName, ObjectId expectedOldObjectId) : this(localDb, srcRef
164
, srcRef != null ? localDb.Resolve(srcRef) : ObjectId.ZeroId, remoteName, forceUpdate
165
, localName, expectedOldObjectId)
169
/// <summary>Construct remote ref update request by providing an update specification.
172
/// Construct remote ref update request by providing an update specification.
173
/// Object is created with default
174
/// <see cref="Status.NOT_ATTEMPTED">Status.NOT_ATTEMPTED</see>
178
/// <param name="localDb">local repository to push from.</param>
179
/// <param name="srcRef">source revision. Use null to delete.</param>
180
/// <param name="remoteName">
181
/// full name of a remote ref to update, e.g. "refs/heads/master"
182
/// (no wildcard, no short name).
184
/// <param name="forceUpdate">
185
/// true when caller want remote ref to be updated regardless
186
/// whether it is fast-forward update (old object is ancestor of
189
/// <param name="localName">
190
/// optional full name of a local stored tracking branch, to
191
/// update after push, e.g. "refs/remotes/zawir/dirty" (no
192
/// wildcard, no short name); null if no local tracking branch
193
/// should be updated.
195
/// <param name="expectedOldObjectId">
196
/// optional object id that caller is expecting, requiring to be
197
/// advertised by remote side before update; update will take
198
/// place ONLY if remote side advertise exactly this expected id;
199
/// null if caller doesn't care what object id remote side
201
/// <see cref="NGit.ObjectId.ZeroId()">NGit.ObjectId.ZeroId()</see>
202
/// when expecting no
203
/// remote ref with this name.
205
/// <exception cref="System.IO.IOException">
206
/// when I/O error occurred during creating
207
/// <see cref="TrackingRefUpdate">TrackingRefUpdate</see>
208
/// for local tracking branch or srcRef
209
/// can't be resolved to any object.
211
/// <exception cref="System.ArgumentException">if some required parameter was null</exception>
212
public RemoteRefUpdate(Repository localDb, Ref srcRef, string remoteName, bool forceUpdate
213
, string localName, ObjectId expectedOldObjectId) : this(localDb, srcRef != null
214
? srcRef.GetName() : null, srcRef != null ? srcRef.GetObjectId() : null, remoteName
215
, forceUpdate, localName, expectedOldObjectId)
219
/// <summary>Construct remote ref update request by providing an update specification.
222
/// Construct remote ref update request by providing an update specification.
223
/// Object is created with default
224
/// <see cref="Status.NOT_ATTEMPTED">Status.NOT_ATTEMPTED</see>
228
/// <param name="localDb">local repository to push from.</param>
229
/// <param name="srcRef">
230
/// source revision to label srcId with. If null srcId.name() will
233
/// <param name="srcId">
234
/// The new object that the caller wants remote ref to be after
235
/// update. Use null or
236
/// <see cref="NGit.ObjectId.ZeroId()">NGit.ObjectId.ZeroId()</see>
240
/// <param name="remoteName">
241
/// full name of a remote ref to update, e.g. "refs/heads/master"
242
/// (no wildcard, no short name).
244
/// <param name="forceUpdate">
245
/// true when caller want remote ref to be updated regardless
246
/// whether it is fast-forward update (old object is ancestor of
249
/// <param name="localName">
250
/// optional full name of a local stored tracking branch, to
251
/// update after push, e.g. "refs/remotes/zawir/dirty" (no
252
/// wildcard, no short name); null if no local tracking branch
253
/// should be updated.
255
/// <param name="expectedOldObjectId">
256
/// optional object id that caller is expecting, requiring to be
257
/// advertised by remote side before update; update will take
258
/// place ONLY if remote side advertise exactly this expected id;
259
/// null if caller doesn't care what object id remote side
261
/// <see cref="NGit.ObjectId.ZeroId()">NGit.ObjectId.ZeroId()</see>
262
/// when expecting no
263
/// remote ref with this name.
265
/// <exception cref="System.IO.IOException">
266
/// when I/O error occurred during creating
267
/// <see cref="TrackingRefUpdate">TrackingRefUpdate</see>
268
/// for local tracking branch or srcRef
269
/// can't be resolved to any object.
271
/// <exception cref="System.ArgumentException">if some required parameter was null</exception>
272
public RemoteRefUpdate(Repository localDb, string srcRef, ObjectId srcId, string
273
remoteName, bool forceUpdate, string localName, ObjectId expectedOldObjectId)
275
if (remoteName == null)
277
throw new ArgumentException(JGitText.Get().remoteNameCantBeNull);
279
if (srcId == null && srcRef != null)
281
throw new IOException(MessageFormat.Format(JGitText.Get().sourceRefDoesntResolveToAnyObject
286
this.srcRef = srcRef;
290
if (srcId != null && !srcId.Equals(ObjectId.ZeroId))
292
this.srcRef = srcId.Name;
301
this.newObjectId = srcId;
305
this.newObjectId = ObjectId.ZeroId;
307
this.remoteName = remoteName;
308
this.forceUpdate = forceUpdate;
309
if (localName != null && localDb != null)
311
trackingRefUpdate = new TrackingRefUpdate(localDb, localName, remoteName, true, newObjectId
316
trackingRefUpdate = null;
318
this.localDb = localDb;
319
this.expectedOldObjectId = expectedOldObjectId;
320
this.status = RemoteRefUpdate.Status.NOT_ATTEMPTED;
324
/// Create a new instance of this object basing on existing instance for
328
/// Create a new instance of this object basing on existing instance for
329
/// configuration. State (like
330
/// <see cref="GetMessage()">GetMessage()</see>
332
/// <see cref="GetStatus()">GetStatus()</see>
334
/// of base object is not shared. Expected old object id is set up from
335
/// scratch, as this constructor may be used for 2-stage push: first one
336
/// being dry run, second one being actual push.
338
/// <param name="base">configuration base.</param>
339
/// <param name="newExpectedOldObjectId">new expected object id value.</param>
340
/// <exception cref="System.IO.IOException">
341
/// when I/O error occurred during creating
342
/// <see cref="TrackingRefUpdate">TrackingRefUpdate</see>
343
/// for local tracking branch or srcRef
344
/// of base object no longer can be resolved to any object.
346
public RemoteRefUpdate(NGit.Transport.RemoteRefUpdate @base, ObjectId newExpectedOldObjectId
347
) : this(@base.localDb, @base.srcRef, @base.remoteName, @base.forceUpdate, (@base
348
.trackingRefUpdate == null ? null : @base.trackingRefUpdate.GetLocalName()), newExpectedOldObjectId
354
/// expectedOldObjectId required to be advertised by remote side, as
355
/// set in constructor; may be null.
357
public virtual ObjectId GetExpectedOldObjectId()
359
return expectedOldObjectId;
363
/// true if some object is required to be advertised by remote side,
364
/// as set in constructor; false otherwise.
366
public virtual bool IsExpectingOldObjectId()
368
return expectedOldObjectId != null;
371
/// <returns>newObjectId for remote ref, as set in constructor.</returns>
372
public virtual ObjectId GetNewObjectId()
377
/// <returns>true if this update is deleting update; false otherwise.</returns>
378
public virtual bool IsDelete()
380
return ObjectId.ZeroId.Equals(newObjectId);
383
/// <returns>name of remote ref to update, as set in constructor.</returns>
384
public virtual string GetRemoteName()
389
/// <returns>local tracking branch update if localName was set in constructor.</returns>
390
public virtual TrackingRefUpdate GetTrackingRefUpdate()
392
return trackingRefUpdate;
396
/// source revision as specified by user (in constructor), could be
397
/// any string parseable by
398
/// <see cref="NGit.Repository.Resolve(string)">NGit.Repository.Resolve(string)</see>
400
/// be null if specified that way in constructor - this stands for
403
public virtual string GetSrcRef()
409
/// true if user specified a local tracking branch for remote update;
412
public virtual bool HasTrackingRefUpdate()
414
return trackingRefUpdate != null;
418
/// true if this update is forced regardless of old remote ref
419
/// object; false otherwise.
421
public virtual bool IsForceUpdate()
426
/// <returns>status of remote ref update operation.</returns>
427
public virtual RemoteRefUpdate.Status GetStatus()
432
/// <summary>Check whether update was fast-forward.</summary>
434
/// Check whether update was fast-forward. Note that this result is
435
/// meaningful only after successful update (when status is
436
/// <see cref="Status.OK">Status.OK</see>
439
/// <returns>true if update was fast-forward; false otherwise.</returns>
440
public virtual bool IsFastForward()
446
/// message describing reasons of status when needed/possible; may be
449
public virtual string GetMessage()
454
internal virtual void SetStatus(RemoteRefUpdate.Status status)
456
this.status = status;
459
internal virtual void SetFastForward(bool fastForward)
461
this.fastForward = fastForward;
464
internal virtual void SetMessage(string message)
466
this.message = message;
469
/// <summary>Update locally stored tracking branch with the new object.</summary>
470
/// <remarks>Update locally stored tracking branch with the new object.</remarks>
471
/// <param name="walk">walker used for checking update properties.</param>
472
/// <exception cref="System.IO.IOException">when I/O error occurred during update</exception>
473
protected internal virtual void UpdateTrackingRef(RevWalk walk)
477
trackingRefUpdate.Delete(walk);
481
trackingRefUpdate.Update(walk);
485
public override string ToString()
487
return "RemoteRefUpdate[remoteName=" + remoteName + ", " + status + ", " + (expectedOldObjectId
488
!= null ? expectedOldObjectId.Name : "(null)") + "..." + (newObjectId != null ?
489
newObjectId.Name : "(null)") + (fastForward ? ", fastForward" : string.Empty) +
490
", srcRef=" + srcRef + (forceUpdate ? ", forceUpdate" : string.Empty) + ", message="
491
+ (message != null ? "\"" + message + "\"" : "null") + "]";