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.
48
using NGit.Api.Errors;
55
/// A class used to execute a
57
/// command. It has setters for all
58
/// supported options and arguments of this command and a
59
/// <see cref="Call()">Call()</see>
61
/// to finally execute the command.
63
/// <seealso><a href="http://www.kernel.org/pub/software/scm/git/docs/git-tag.html"
64
/// * >Git documentation about Tag</a></seealso>
65
public class TagCommand : GitCommand<RevTag>
71
private string message;
73
private PersonIdent tagger;
77
private bool forceUpdate;
79
/// <param name="repo"></param>
80
protected internal TagCommand(Repository repo) : base(repo)
87
/// command with all the options and parameters
88
/// collected by the setter methods of this class. Each instance of this
89
/// class should only be used for one invocation of the command (means: one
91
/// <see cref="Call()">Call()</see>
96
/// <see cref="NGit.Revwalk.RevTag">NGit.Revwalk.RevTag</see>
97
/// object representing the successful tag
99
/// <exception cref="NGit.Api.Errors.NoHeadException">when called on a git repo without a HEAD reference
101
/// <exception cref="NGit.Api.Errors.JGitInternalException">
102
/// a low-level exception of JGit has occurred. The original
103
/// exception can be retrieved by calling
104
/// <see cref="System.Exception.InnerException()">System.Exception.InnerException()</see>
106
/// <code>IOException's</code>
109
/// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"></exception>
110
/// <exception cref="NGit.Api.Errors.InvalidTagNameException"></exception>
111
public override RevTag Call()
114
RepositoryState state = repo.GetRepositoryState();
115
ProcessOptions(state);
118
// create the tag object
119
TagBuilder newTag = new TagBuilder();
121
newTag.SetMessage(message);
122
newTag.SetTagger(tagger);
123
// if no id is set, we should attempt to use HEAD
126
ObjectId objectId = repo.Resolve(Constants.HEAD + "^{commit}");
127
if (objectId == null)
129
throw new NoHeadException(JGitText.Get().tagOnRepoWithoutHEADCurrentlyNotSupported
132
newTag.SetObjectId(objectId, Constants.OBJ_COMMIT);
136
newTag.SetObjectId(id);
138
// write the tag object
139
ObjectInserter inserter = repo.NewObjectInserter();
142
ObjectId tagId = inserter.Insert(newTag);
144
RevWalk revWalk = new RevWalk(repo);
147
RevTag revTag = revWalk.ParseTag(tagId);
148
string refName = Constants.R_TAGS + newTag.GetTag();
149
RefUpdate tagRef = repo.UpdateRef(refName);
150
tagRef.SetNewObjectId(tagId);
151
tagRef.SetForceUpdate(forceUpdate);
152
tagRef.SetRefLogMessage("tagged " + name, false);
153
RefUpdate.Result updateResult = tagRef.Update(revWalk);
154
switch (updateResult)
156
case RefUpdate.Result.NEW:
157
case RefUpdate.Result.FORCED:
162
case RefUpdate.Result.LOCK_FAILURE:
164
throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, tagRef.GetRef
170
throw new JGitInternalException(MessageFormat.Format(JGitText.Get().updatingRefFailed
171
, refName, newTag.ToString(), updateResult));
185
catch (IOException e)
187
throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfTagCommand
192
/// <summary>Sets default values for not explicitly specified options.</summary>
194
/// Sets default values for not explicitly specified options. Then validates
195
/// that all required data has been provided.
197
/// <param name="state">the state of the repository we are working on</param>
198
/// <exception cref="NGit.Api.Errors.InvalidTagNameException">if the tag name is null or invalid
200
/// <exception cref="System.NotSupportedException">if the tag is signed (not supported yet)
202
private void ProcessOptions(RepositoryState state)
206
tagger = new PersonIdent(repo);
208
if (name == null || !Repository.IsValidRefName(Constants.R_TAGS + name))
210
throw new InvalidTagNameException(MessageFormat.Format(JGitText.Get().tagNameInvalid
211
, name == null ? "<null>" : name));
215
throw new NotSupportedException(JGitText.Get().signingNotSupportedOnTag);
219
/// <param name="name">
220
/// the tag name used for the
225
/// <code>this</code>
227
public virtual NGit.Api.TagCommand SetName(string name)
234
/// <returns>the tag name used for the <code>tag</code></returns>
235
public virtual string GetName()
240
/// <returns>the tag message used for the <code>tag</code></returns>
241
public virtual string GetMessage()
246
/// <param name="message">
247
/// the tag message used for the
252
/// <code>this</code>
254
public virtual NGit.Api.TagCommand SetMessage(string message)
257
this.message = message;
261
/// <returns>whether the tag is signed</returns>
262
public virtual bool IsSigned()
267
/// <summary>If set to true the Tag command creates a signed tag object.</summary>
269
/// If set to true the Tag command creates a signed tag object. This
270
/// corresponds to the parameter -s on the command line.
272
/// <param name="signed"></param>
275
/// <code>this</code>
277
public virtual NGit.Api.TagCommand SetSigned(bool signed)
279
this.signed = signed;
283
/// <summary>Sets the tagger of the tag.</summary>
285
/// Sets the tagger of the tag. If the tagger is null, a PersonIdent will be
286
/// created from the info in the repository.
288
/// <param name="tagger"></param>
291
/// <code>this</code>
293
public virtual NGit.Api.TagCommand SetTagger(PersonIdent tagger)
295
this.tagger = tagger;
299
/// <returns>the tagger of the tag</returns>
300
public virtual PersonIdent GetTagger()
305
/// <returns>the object id of the tag</returns>
306
public virtual RevObject GetObjectId()
311
/// <summary>Sets the object id of the tag.</summary>
313
/// Sets the object id of the tag. If the object id is null, the commit
314
/// pointed to from HEAD will be used.
316
/// <param name="id"></param>
319
/// <code>this</code>
321
public virtual NGit.Api.TagCommand SetObjectId(RevObject id)
327
/// <returns>is this a force update</returns>
328
public virtual bool IsForceUpdate()
333
/// <summary>If set to true the Tag command may replace an existing tag object.</summary>
335
/// If set to true the Tag command may replace an existing tag object. This
336
/// corresponds to the parameter -f on the command line.
338
/// <param name="forceUpdate"></param>
341
/// <code>this</code>
343
public virtual NGit.Api.TagCommand SetForceUpdate(bool forceUpdate)
345
this.forceUpdate = forceUpdate;