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

« back to all changes in this revision

Viewing changes to contrib/NGit/NGit.Api/TagCommand.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.IO;
 
46
using NGit;
 
47
using NGit.Api;
 
48
using NGit.Api.Errors;
 
49
using NGit.Revwalk;
 
50
using Sharpen;
 
51
 
 
52
namespace NGit.Api
 
53
{
 
54
        /// <summary>
 
55
        /// A class used to execute a
 
56
        /// <code>Tag</code>
 
57
        /// command. It has setters for all
 
58
        /// supported options and arguments of this command and a
 
59
        /// <see cref="Call()">Call()</see>
 
60
        /// method
 
61
        /// to finally execute the command.
 
62
        /// </summary>
 
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>
 
66
        {
 
67
                private RevObject id;
 
68
 
 
69
                private string name;
 
70
 
 
71
                private string message;
 
72
 
 
73
                private PersonIdent tagger;
 
74
 
 
75
                private bool signed;
 
76
 
 
77
                private bool forceUpdate;
 
78
 
 
79
                /// <param name="repo"></param>
 
80
                protected internal TagCommand(Repository repo) : base(repo)
 
81
                {
 
82
                }
 
83
 
 
84
                /// <summary>
 
85
                /// Executes the
 
86
                /// <code>tag</code>
 
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
 
90
                /// call to
 
91
                /// <see cref="Call()">Call()</see>
 
92
                /// )
 
93
                /// </summary>
 
94
                /// <returns>
 
95
                /// a
 
96
                /// <see cref="NGit.Revwalk.RevTag">NGit.Revwalk.RevTag</see>
 
97
                /// object representing the successful tag
 
98
                /// </returns>
 
99
                /// <exception cref="NGit.Api.Errors.NoHeadException">when called on a git repo without a HEAD reference
 
100
                ///     </exception>
 
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>
 
105
                /// . Expect only
 
106
                /// <code>IOException's</code>
 
107
                /// to be wrapped.
 
108
                /// </exception>
 
109
                /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"></exception>
 
110
                /// <exception cref="NGit.Api.Errors.InvalidTagNameException"></exception>
 
111
                public override RevTag Call()
 
112
                {
 
113
                        CheckCallable();
 
114
                        RepositoryState state = repo.GetRepositoryState();
 
115
                        ProcessOptions(state);
 
116
                        try
 
117
                        {
 
118
                                // create the tag object
 
119
                                TagBuilder newTag = new TagBuilder();
 
120
                                newTag.SetTag(name);
 
121
                                newTag.SetMessage(message);
 
122
                                newTag.SetTagger(tagger);
 
123
                                // if no id is set, we should attempt to use HEAD
 
124
                                if (id == null)
 
125
                                {
 
126
                                        ObjectId objectId = repo.Resolve(Constants.HEAD + "^{commit}");
 
127
                                        if (objectId == null)
 
128
                                        {
 
129
                                                throw new NoHeadException(JGitText.Get().tagOnRepoWithoutHEADCurrentlyNotSupported
 
130
                                                        );
 
131
                                        }
 
132
                                        newTag.SetObjectId(objectId, Constants.OBJ_COMMIT);
 
133
                                }
 
134
                                else
 
135
                                {
 
136
                                        newTag.SetObjectId(id);
 
137
                                }
 
138
                                // write the tag object
 
139
                                ObjectInserter inserter = repo.NewObjectInserter();
 
140
                                try
 
141
                                {
 
142
                                        ObjectId tagId = inserter.Insert(newTag);
 
143
                                        inserter.Flush();
 
144
                                        RevWalk revWalk = new RevWalk(repo);
 
145
                                        try
 
146
                                        {
 
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)
 
155
                                                {
 
156
                                                        case RefUpdate.Result.NEW:
 
157
                                                        case RefUpdate.Result.FORCED:
 
158
                                                        {
 
159
                                                                return revTag;
 
160
                                                        }
 
161
 
 
162
                                                        case RefUpdate.Result.LOCK_FAILURE:
 
163
                                                        {
 
164
                                                                throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, tagRef.GetRef
 
165
                                                                        (), updateResult);
 
166
                                                        }
 
167
 
 
168
                                                        default:
 
169
                                                        {
 
170
                                                                throw new JGitInternalException(MessageFormat.Format(JGitText.Get().updatingRefFailed
 
171
                                                                        , refName, newTag.ToString(), updateResult));
 
172
                                                        }
 
173
                                                }
 
174
                                        }
 
175
                                        finally
 
176
                                        {
 
177
                                                revWalk.Release();
 
178
                                        }
 
179
                                }
 
180
                                finally
 
181
                                {
 
182
                                        inserter.Release();
 
183
                                }
 
184
                        }
 
185
                        catch (IOException e)
 
186
                        {
 
187
                                throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfTagCommand
 
188
                                        , e);
 
189
                        }
 
190
                }
 
191
 
 
192
                /// <summary>Sets default values for not explicitly specified options.</summary>
 
193
                /// <remarks>
 
194
                /// Sets default values for not explicitly specified options. Then validates
 
195
                /// that all required data has been provided.
 
196
                /// </remarks>
 
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
 
199
                ///     </exception>
 
200
                /// <exception cref="System.NotSupportedException">if the tag is signed (not supported yet)
 
201
                ///     </exception>
 
202
                private void ProcessOptions(RepositoryState state)
 
203
                {
 
204
                        if (tagger == null)
 
205
                        {
 
206
                                tagger = new PersonIdent(repo);
 
207
                        }
 
208
                        if (name == null || !Repository.IsValidRefName(Constants.R_TAGS + name))
 
209
                        {
 
210
                                throw new InvalidTagNameException(MessageFormat.Format(JGitText.Get().tagNameInvalid
 
211
                                        , name == null ? "<null>" : name));
 
212
                        }
 
213
                        if (signed)
 
214
                        {
 
215
                                throw new NotSupportedException(JGitText.Get().signingNotSupportedOnTag);
 
216
                        }
 
217
                }
 
218
 
 
219
                /// <param name="name">
 
220
                /// the tag name used for the
 
221
                /// <code>tag</code>
 
222
                /// </param>
 
223
                /// <returns>
 
224
                /// 
 
225
                /// <code>this</code>
 
226
                /// </returns>
 
227
                public virtual NGit.Api.TagCommand SetName(string name)
 
228
                {
 
229
                        CheckCallable();
 
230
                        this.name = name;
 
231
                        return this;
 
232
                }
 
233
 
 
234
                /// <returns>the tag name used for the <code>tag</code></returns>
 
235
                public virtual string GetName()
 
236
                {
 
237
                        return name;
 
238
                }
 
239
 
 
240
                /// <returns>the tag message used for the <code>tag</code></returns>
 
241
                public virtual string GetMessage()
 
242
                {
 
243
                        return message;
 
244
                }
 
245
 
 
246
                /// <param name="message">
 
247
                /// the tag message used for the
 
248
                /// <code>tag</code>
 
249
                /// </param>
 
250
                /// <returns>
 
251
                /// 
 
252
                /// <code>this</code>
 
253
                /// </returns>
 
254
                public virtual NGit.Api.TagCommand SetMessage(string message)
 
255
                {
 
256
                        CheckCallable();
 
257
                        this.message = message;
 
258
                        return this;
 
259
                }
 
260
 
 
261
                /// <returns>whether the tag is signed</returns>
 
262
                public virtual bool IsSigned()
 
263
                {
 
264
                        return signed;
 
265
                }
 
266
 
 
267
                /// <summary>If set to true the Tag command creates a signed tag object.</summary>
 
268
                /// <remarks>
 
269
                /// If set to true the Tag command creates a signed tag object. This
 
270
                /// corresponds to the parameter -s on the command line.
 
271
                /// </remarks>
 
272
                /// <param name="signed"></param>
 
273
                /// <returns>
 
274
                /// 
 
275
                /// <code>this</code>
 
276
                /// </returns>
 
277
                public virtual NGit.Api.TagCommand SetSigned(bool signed)
 
278
                {
 
279
                        this.signed = signed;
 
280
                        return this;
 
281
                }
 
282
 
 
283
                /// <summary>Sets the tagger of the tag.</summary>
 
284
                /// <remarks>
 
285
                /// Sets the tagger of the tag. If the tagger is null, a PersonIdent will be
 
286
                /// created from the info in the repository.
 
287
                /// </remarks>
 
288
                /// <param name="tagger"></param>
 
289
                /// <returns>
 
290
                /// 
 
291
                /// <code>this</code>
 
292
                /// </returns>
 
293
                public virtual NGit.Api.TagCommand SetTagger(PersonIdent tagger)
 
294
                {
 
295
                        this.tagger = tagger;
 
296
                        return this;
 
297
                }
 
298
 
 
299
                /// <returns>the tagger of the tag</returns>
 
300
                public virtual PersonIdent GetTagger()
 
301
                {
 
302
                        return tagger;
 
303
                }
 
304
 
 
305
                /// <returns>the object id of the tag</returns>
 
306
                public virtual RevObject GetObjectId()
 
307
                {
 
308
                        return id;
 
309
                }
 
310
 
 
311
                /// <summary>Sets the object id of the tag.</summary>
 
312
                /// <remarks>
 
313
                /// Sets the object id of the tag. If the object id is null, the commit
 
314
                /// pointed to from HEAD will be used.
 
315
                /// </remarks>
 
316
                /// <param name="id"></param>
 
317
                /// <returns>
 
318
                /// 
 
319
                /// <code>this</code>
 
320
                /// </returns>
 
321
                public virtual NGit.Api.TagCommand SetObjectId(RevObject id)
 
322
                {
 
323
                        this.id = id;
 
324
                        return this;
 
325
                }
 
326
 
 
327
                /// <returns>is this a force update</returns>
 
328
                public virtual bool IsForceUpdate()
 
329
                {
 
330
                        return forceUpdate;
 
331
                }
 
332
 
 
333
                /// <summary>If set to true the Tag command may replace an existing tag object.</summary>
 
334
                /// <remarks>
 
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.
 
337
                /// </remarks>
 
338
                /// <param name="forceUpdate"></param>
 
339
                /// <returns>
 
340
                /// 
 
341
                /// <code>this</code>
 
342
                /// </returns>
 
343
                public virtual NGit.Api.TagCommand SetForceUpdate(bool forceUpdate)
 
344
                {
 
345
                        this.forceUpdate = forceUpdate;
 
346
                        return this;
 
347
                }
 
348
        }
 
349
}