~ubuntu-branches/ubuntu/raring/monodevelop/raring

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Mitchell
  • Date: 2011-06-29 06:56:25 UTC
  • mfrom: (1.8.1 upstream) (1.3.11 experimental)
  • Revision ID: james.westby@ubuntu.com-20110629065625-7xx19c4vb95j65pl
Tags: 2.5.92+dfsg-1ubuntu1
* Merge from Debian experimental:
 - Dropped patches & changes to debian/control for Moonlight
   + debian/patches/remove_support_for_moonlight.patch,
   + debian/patches/dont_add_moonlight_to_core_addins.patch,
 - Remaining patches:
   + debian/patches/no_appmenu:

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.Collections.Generic;
 
45
using System.IO;
 
46
using NGit;
 
47
using NGit.Api;
 
48
using NGit.Api.Errors;
 
49
using NGit.Dircache;
 
50
using NGit.Merge;
 
51
using NGit.Revwalk;
 
52
using NGit.Treewalk;
 
53
using Sharpen;
 
54
 
 
55
namespace NGit.Api
 
56
{
 
57
        /// <summary>
 
58
        /// A class used to execute a
 
59
        /// <code>revert</code>
 
60
        /// command. It has setters for all
 
61
        /// supported options and arguments of this command and a
 
62
        /// <see cref="Call()">Call()</see>
 
63
        /// method
 
64
        /// to finally execute the command. Each instance of this class should only be
 
65
        /// used for one invocation of the command (means: one call to
 
66
        /// <see cref="Call()">Call()</see>
 
67
        /// )
 
68
        /// </summary>
 
69
        /// <seealso><a
 
70
        /// *      href="http://www.kernel.org/pub/software/scm/git/docs/git-revert.html"
 
71
        /// *      >Git documentation about revert</a></seealso>
 
72
        public class RevertCommand : GitCommand<RevCommit>
 
73
        {
 
74
                private IList<Ref> commits = new List<Ref>();
 
75
 
 
76
                private IList<Ref> revertedRefs = new List<Ref>();
 
77
 
 
78
                /// <param name="repo"></param>
 
79
                protected internal RevertCommand(Repository repo) : base(repo)
 
80
                {
 
81
                }
 
82
 
 
83
                /// <summary>
 
84
                /// Executes the
 
85
                /// <code>revert</code>
 
86
                /// command with all the options and parameters
 
87
                /// collected by the setter methods (e.g.
 
88
                /// <see cref="Include(NGit.Ref)">Include(NGit.Ref)</see>
 
89
                /// of this
 
90
                /// class. Each instance of this class should only be used for one invocation
 
91
                /// of the command. Don't call this method twice on an instance.
 
92
                /// </summary>
 
93
                /// <returns>
 
94
                /// on success the
 
95
                /// <see cref="NGit.Revwalk.RevCommit">NGit.Revwalk.RevCommit</see>
 
96
                /// pointed to by the new HEAD is
 
97
                /// returned. If a failure occurred during revert <code>null</code>
 
98
                /// is returned. The list of successfully reverted
 
99
                /// <see cref="NGit.Ref">NGit.Ref</see>
 
100
                /// 's can
 
101
                /// be obtained by calling
 
102
                /// <see cref="GetRevertedRefs()">GetRevertedRefs()</see>
 
103
                /// </returns>
 
104
                /// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
 
105
                public override RevCommit Call()
 
106
                {
 
107
                        RevCommit newHead = null;
 
108
                        CheckCallable();
 
109
                        RevWalk revWalk = new RevWalk(repo);
 
110
                        try
 
111
                        {
 
112
                                // get the head commit
 
113
                                Ref headRef = repo.GetRef(Constants.HEAD);
 
114
                                if (headRef == null)
 
115
                                {
 
116
                                        throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
 
117
                                                );
 
118
                                }
 
119
                                RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId());
 
120
                                newHead = headCommit;
 
121
                                // loop through all refs to be reverted
 
122
                                foreach (Ref src in commits)
 
123
                                {
 
124
                                        // get the commit to be reverted
 
125
                                        // handle annotated tags
 
126
                                        ObjectId srcObjectId = src.GetPeeledObjectId();
 
127
                                        if (srcObjectId == null)
 
128
                                        {
 
129
                                                srcObjectId = src.GetObjectId();
 
130
                                        }
 
131
                                        RevCommit srcCommit = revWalk.ParseCommit(srcObjectId);
 
132
                                        // get the parent of the commit to revert
 
133
                                        if (srcCommit.ParentCount != 1)
 
134
                                        {
 
135
                                                throw new MultipleParentsNotAllowedException(JGitText.Get().canOnlyRevertCommitsWithOneParent
 
136
                                                        );
 
137
                                        }
 
138
                                        RevCommit srcParent = srcCommit.GetParent(0);
 
139
                                        revWalk.ParseHeaders(srcParent);
 
140
                                        ResolveMerger merger = (ResolveMerger)((ThreeWayMerger)MergeStrategy.RESOLVE.NewMerger
 
141
                                                (repo));
 
142
                                        merger.SetWorkingTreeIterator(new FileTreeIterator(repo));
 
143
                                        merger.SetBase(srcCommit.Tree);
 
144
                                        if (merger.Merge(headCommit, srcParent))
 
145
                                        {
 
146
                                                if (AnyObjectId.Equals(headCommit.Tree.Id, merger.GetResultTreeId()))
 
147
                                                {
 
148
                                                        continue;
 
149
                                                }
 
150
                                                DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache
 
151
                                                        (), merger.GetResultTreeId());
 
152
                                                dco.SetFailOnConflict(true);
 
153
                                                dco.Checkout();
 
154
                                                string newMessage = "Revert \"" + srcCommit.GetShortMessage() + "\"" + "\n\n" + "This reverts commit "
 
155
                                                         + srcCommit.Id.GetName() + "\n";
 
156
                                                newHead = new Git(GetRepository()).Commit().SetMessage(newMessage).Call();
 
157
                                                revertedRefs.AddItem(src);
 
158
                                        }
 
159
                                        else
 
160
                                        {
 
161
                                                return null;
 
162
                                        }
 
163
                                }
 
164
                        }
 
165
                        catch (IOException e)
 
166
                        {
 
167
                                throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionCaughtDuringExecutionOfRevertCommand
 
168
                                        , e), e);
 
169
                        }
 
170
                        finally
 
171
                        {
 
172
                                revWalk.Release();
 
173
                        }
 
174
                        return newHead;
 
175
                }
 
176
 
 
177
                /// <param name="commit">
 
178
                /// a reference to a commit which is reverted into the current
 
179
                /// head
 
180
                /// </param>
 
181
                /// <returns>
 
182
                /// 
 
183
                /// <code>this</code>
 
184
                /// </returns>
 
185
                public virtual NGit.Api.RevertCommand Include(Ref commit)
 
186
                {
 
187
                        CheckCallable();
 
188
                        commits.AddItem(commit);
 
189
                        return this;
 
190
                }
 
191
 
 
192
                /// <param name="commit">the Id of a commit which is reverted into the current head</param>
 
193
                /// <returns>
 
194
                /// 
 
195
                /// <code>this</code>
 
196
                /// </returns>
 
197
                public virtual NGit.Api.RevertCommand Include(AnyObjectId commit)
 
198
                {
 
199
                        return Include(commit.GetName(), commit);
 
200
                }
 
201
 
 
202
                /// <param name="name">a name given to the commit</param>
 
203
                /// <param name="commit">the Id of a commit which is reverted into the current head</param>
 
204
                /// <returns>
 
205
                /// 
 
206
                /// <code>this</code>
 
207
                /// </returns>
 
208
                public virtual NGit.Api.RevertCommand Include(string name, AnyObjectId commit)
 
209
                {
 
210
                        return Include(new ObjectIdRef.Unpeeled(RefStorage.LOOSE, name, commit.Copy()));
 
211
                }
 
212
 
 
213
                /// <returns>
 
214
                /// the list of successfully reverted
 
215
                /// <see cref="NGit.Ref">NGit.Ref</see>
 
216
                /// 's. Never
 
217
                /// <code>null</code> but maybe an empty list if no commit was
 
218
                /// successfully cherry-picked
 
219
                /// </returns>
 
220
                public virtual IList<Ref> GetRevertedRefs()
 
221
                {
 
222
                        return revertedRefs;
 
223
                }
 
224
        }
 
225
}