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.
44
using System.Collections.Generic;
48
using NGit.Api.Errors;
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>
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>
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>
74
private IList<Ref> commits = new List<Ref>();
76
private IList<Ref> revertedRefs = new List<Ref>();
78
/// <param name="repo"></param>
79
protected internal RevertCommand(Repository repo) : base(repo)
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>
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.
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>
101
/// be obtained by calling
102
/// <see cref="GetRevertedRefs()">GetRevertedRefs()</see>
104
/// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
105
public override RevCommit Call()
107
RevCommit newHead = null;
109
RevWalk revWalk = new RevWalk(repo);
112
// get the head commit
113
Ref headRef = repo.GetRef(Constants.HEAD);
116
throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
119
RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId());
120
newHead = headCommit;
121
// loop through all refs to be reverted
122
foreach (Ref src in commits)
124
// get the commit to be reverted
125
// handle annotated tags
126
ObjectId srcObjectId = src.GetPeeledObjectId();
127
if (srcObjectId == null)
129
srcObjectId = src.GetObjectId();
131
RevCommit srcCommit = revWalk.ParseCommit(srcObjectId);
132
// get the parent of the commit to revert
133
if (srcCommit.ParentCount != 1)
135
throw new MultipleParentsNotAllowedException(JGitText.Get().canOnlyRevertCommitsWithOneParent
138
RevCommit srcParent = srcCommit.GetParent(0);
139
revWalk.ParseHeaders(srcParent);
140
ResolveMerger merger = (ResolveMerger)((ThreeWayMerger)MergeStrategy.RESOLVE.NewMerger
142
merger.SetWorkingTreeIterator(new FileTreeIterator(repo));
143
merger.SetBase(srcCommit.Tree);
144
if (merger.Merge(headCommit, srcParent))
146
if (AnyObjectId.Equals(headCommit.Tree.Id, merger.GetResultTreeId()))
150
DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache
151
(), merger.GetResultTreeId());
152
dco.SetFailOnConflict(true);
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);
165
catch (IOException e)
167
throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionCaughtDuringExecutionOfRevertCommand
177
/// <param name="commit">
178
/// a reference to a commit which is reverted into the current
183
/// <code>this</code>
185
public virtual NGit.Api.RevertCommand Include(Ref commit)
188
commits.AddItem(commit);
192
/// <param name="commit">the Id of a commit which is reverted into the current head</param>
195
/// <code>this</code>
197
public virtual NGit.Api.RevertCommand Include(AnyObjectId commit)
199
return Include(commit.GetName(), commit);
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>
206
/// <code>this</code>
208
public virtual NGit.Api.RevertCommand Include(string name, AnyObjectId commit)
210
return Include(new ObjectIdRef.Unpeeled(RefStorage.LOOSE, name, commit.Copy()));
214
/// the list of successfully reverted
215
/// <see cref="NGit.Ref">NGit.Ref</see>
217
/// <code>null</code> but maybe an empty list if no commit was
218
/// successfully cherry-picked
220
public virtual IList<Ref> GetRevertedRefs()