Skip to content

Commit 0580f36

Browse files
committed
Make repo.Reset() accept ResetOptions.Hard
1 parent 815086d commit 0580f36

File tree

4 files changed

+57
-2
lines changed

4 files changed

+57
-2
lines changed

LibGit2Sharp.Tests/ResetHeadFixture.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.IO;
3+
using System.Linq;
34
using LibGit2Sharp.Tests.TestHelpers;
45
using Xunit;
56
using Xunit.Extensions;
@@ -152,5 +153,38 @@ public void MixedResetInABareRepositoryThrows()
152153
Assert.Throws<BareRepositoryException>(() => repo.Reset(ResetOptions.Mixed));
153154
}
154155
}
156+
157+
[Fact]
158+
public void HardResetInABareRepositoryThrows()
159+
{
160+
using (var repo = new Repository(BareTestRepoPath))
161+
{
162+
Assert.Throws<BareRepositoryException>(() => repo.Reset(ResetOptions.Hard));
163+
}
164+
}
165+
166+
[Fact]
167+
public void HardResetUpdatesTheContentOfTheWorkingDirectory()
168+
{
169+
var clone = BuildTemporaryCloneOfTestRepo(StandardTestRepoWorkingDirPath);
170+
171+
using (var repo = new Repository(clone.DirectoryPath))
172+
{
173+
var names = new DirectoryInfo(repo.Info.WorkingDirectory).GetFileSystemInfos().Select(fsi => fsi.Name).ToList();
174+
names.Sort(StringComparer.Ordinal);
175+
176+
File.Delete(Path.Combine(repo.Info.WorkingDirectory, "README"));
177+
File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, "WillBeRemoved.txt"), "content\n");
178+
179+
Assert.True(names.Count > 4);
180+
181+
repo.Reset(ResetOptions.Hard, "HEAD~3");
182+
183+
names = new DirectoryInfo(repo.Info.WorkingDirectory).GetFileSystemInfos().Select(fsi => fsi.Name).ToList();
184+
names.Sort(StringComparer.Ordinal);
185+
186+
Assert.Equal(new[] { ".git", "README", "branch_file.txt", "new.txt" }, names);
187+
}
188+
}
155189
}
156190
}

LibGit2Sharp/LibGit2Sharp.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
<Compile Include="Configuration.cs" />
6969
<Compile Include="ConfigurationEntry.cs" />
7070
<Compile Include="ContentChanges.cs" />
71+
<Compile Include="Core\GitCheckoutOpts.cs" />
72+
<Compile Include="Core\GitIndexerStats.cs" />
7173
<Compile Include="Core\Proxy.cs" />
7274
<Compile Include="ReferenceCollectionExtensions.cs" />
7375
<Compile Include="TagCollectionExtensions.cs" />

LibGit2Sharp/Repository.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,18 @@ public Branch Checkout(Branch branch)
429429
return branch;
430430
}
431431

432+
private void CheckoutTreeForce(ObjectId treeId)
433+
{
434+
var opts = new GitCheckoutOpts
435+
{
436+
checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_CREATE_MISSING |
437+
CheckoutStrategy.GIT_CHECKOUT_OVERWRITE_MODIFIED |
438+
CheckoutStrategy.GIT_CHECKOUT_REMOVE_UNTRACKED
439+
};
440+
441+
Proxy.git_checkout_tree(handle, treeId, opts, null);
442+
}
443+
432444
/// <summary>
433445
/// Sets the current <see cref = "Head" /> to the specified commit and optionally resets the <see cref = "Index" /> and
434446
/// the content of the working tree to match.
@@ -437,7 +449,7 @@ public Branch Checkout(Branch branch)
437449
/// <param name = "commitish">A revparse spec for the target commit object.</param>
438450
public void Reset(ResetOptions resetOptions, string commitish = "HEAD")
439451
{
440-
Ensure.ArgumentNotNullOrEmptyString(commitish, "commitOrBranchSpec");
452+
Ensure.ArgumentNotNullOrEmptyString(commitish, "commitish");
441453

442454
if (resetOptions.Has(ResetOptions.Mixed) && Info.IsBare)
443455
{
@@ -463,7 +475,7 @@ public void Reset(ResetOptions resetOptions, string commitish = "HEAD")
463475
return;
464476
}
465477

466-
throw new NotImplementedException();
478+
CheckoutTreeForce(commit.Tree.Id);
467479
}
468480

469481
/// <summary>

LibGit2Sharp/ResetOptions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,12 @@ public enum ResetOptions
1515
/// to the tree recorded by the commit.
1616
/// </summary>
1717
Mixed,
18+
19+
/// <summary>
20+
/// Moves the branch pointed to by HEAD to the specified commit object, resets the index
21+
/// to the tree recorded by the commit and updates the working directory to match the content
22+
/// of the index.
23+
/// </summary>
24+
Hard,
1825
}
1926
}

0 commit comments

Comments
 (0)