8000 Teach Repository to Checkout paths · SkightTeam/libgit2sharp@7e5bbbf · GitHub
[go: up one dir, main page]

Skip to content

Commit 7e5bbbf

Browse files
jamillnulltoken
authored andcommitted
Teach Repository to Checkout paths
1 parent 01dfa28 commit 7e5bbbf

File tree

9 files changed

+260
-99
lines changed

9 files changed

+260
-99
lines changed

LibGit2Sharp.Tests/CheckoutFixture.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,74 @@ public void CanCheckoutDetachedHead()
922922
}
923923
}
924924

925+
[Theory]
926+
[InlineData("master", "6dcf9bf", "readme.txt", FileStatus.Added)]
927+
[InlineData("master", "refs/tags/lw", "readme.txt", FileStatus.Added)]
928+
[InlineData("master", "i-do-numbers", "super-file.txt", FileStatus.Added)]
929+
[InlineData("i-do-numbers", "diff-test-cases", "numbers.txt", FileStatus.Staged)]
930+
public void CanCheckoutPath(string originalBranch, string checkoutFrom, string path, FileStatus expectedStatus)
931+
{
932+
string repoPath = CloneStandardTestRepo();
933+
using (var repo = new Repository(repoPath))
934+
{
935+
// Set the working directory to the current head
936+
ResetAndCleanWorkingDirectory(repo);
937+
938+
repo.Checkout(originalBranch);
939+
Assert.False(repo.Index.RetrieveStatus().IsDirty);
940+
941+
repo.CheckoutPaths(checkoutFrom, new string[] { path }, CheckoutModifiers.None, null, null);
942+
943+
Assert.Equal(expectedStatus, repo.Index.RetrieveStatus(path));
944+
Assert.Equal(1, repo.Index.RetrieveStatus().Count());
945+
}
946+
}
947+
948+
[Fact]
949+
public void CanCheckoutPaths()
950+
{
951+
string repoPath = CloneStandardTestRepo();
952+
var checkoutPaths = new[] { "numbers.txt", "super-file.txt" };
953+
954+
using (var repo = new Repository(repoPath))
955+
{
956+
// Set the working directory to the current head
957+
ResetAndCleanWorkingDirectory(repo);
958+
Assert.False(repo.Index.RetrieveStatus().IsDirty);
959+
960+
repo.CheckoutPaths("i-do-numbers", checkoutPaths, CheckoutModifiers.None, null, null);
961+
962+
foreach (string checkoutPath in checkoutPaths)
963+
{
964+
Assert.Equal(FileStatus.Added, repo.Index.RetrieveStatus(checkoutPath));
965+
}
966+
}
967+
}
968+
969+
[Theory]
970+
[InlineData("new.txt")]
971+
[InlineData("1.txt")]
972+
public void CanCheckoutPathFromCurrentBranch(string fileName)
973+
{
974+
string repoPath = CloneStandardTestRepo();
975+
976+
using (var repo = new Repository(repoPath))
977+
{
978+
// Set the working directory to the current head
979+
ResetAndCleanWorkingDirectory(repo);
980+
981+
Assert.False(repo.Index.RetrieveStatus().IsDirty);
982+
983+
Touch(repo.Info.WorkingDirectory, fileName, "new text file");
984+
985+
Assert.True(repo.Index.RetrieveStatus().IsDirty);
986+
987+
repo.CheckoutPaths("HEAD", new string[] { fileName }, CheckoutModifiers.Force, null, null);
988+
989+
Assert.False(repo.Index.RetrieveStatus().IsDirty);
990+
}
991+
}
992+
925993
/// <summary>
926994
/// Helper method to populate a simple repository with
927995
/// a single file and two branches.

LibGit2Sharp/BranchCollectionExtensions.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@ public static Branch Add(this BranchCollection branches, string name, string com
2020
Ensure.ArgumentNotNullOrEmptyString(name, "name");
2121
Ensure.ArgumentNotNullOrEmptyString(committish, "committish");
2222

23-
var commit = (Commit)branches.repo.Lookup(committish, GitObjectType.Any,
24-
LookUpOptions.ThrowWhenNoGitObjectHasBeenFound |
25-
LookUpOptions.DereferenceResultToCommit |
26-
LookUpOptions.ThrowWhenCanNotBeDereferencedToACommit);
23+
var commit = branches.repo.LookupCommit(committish);
2724

2825
return branches.Add(name, commit, allowOverwrite);
2926
}

LibGit2Sharp/Core/GitCheckoutOpts.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ internal delegate void progress_cb(
9595
IntPtr payload);
9696

9797
[StructLayout(LayoutKind.Sequential)]
98-
internal struct GitCheckoutOpts
98+
internal struct GitCheckoutOpts :IDisposable
9999
{
100100
public uint version;
101101

@@ -113,9 +113,19 @@ internal struct GitCheckoutOpts
113113
public progress_cb progress_cb;
114114
public IntPtr progress_payload;
115115

116-
public UnSafeNativeMethods.git_strarray paths;
116+
public GitStrArrayIn paths;
117117

118118
public IntPtr baseline;
119119
public IntPtr target_directory;
120+
121+
public void Dispose()
122+
{
123+
if (paths == null)
124+
{
125+
return;
126+
}
127+
128+
paths.Dispose();
129+
}
120130
}
121131
}

LibGit2Sharp/Core/GitDiff.cs

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -113,52 +113,6 @@ internal enum GitDiffOptionFlags
113113
GIT_DIFF_IGNORE_FILEMODE = (1 << 17),
114114
}
115115

116-
[StructLayout(LayoutKind.Sequential)]
117-
internal class GitStrArrayIn : IDisposable
118-
{
119-
public IntPtr strings;
120-
public uint size;
121-
122-
public static GitStrArrayIn BuildFrom(FilePath[] paths)
123-
{
124-
var nbOfPaths = paths.Length;
125-
var pathPtrs = new IntPtr[nbOfPaths];
126-
127-
for (int i = 0; i < nbOfPaths; i++)
128-
{
129-
var s = paths[i].Posix;
130-
pathPtrs[i] = FilePathMarshaler.FromManaged(s);
131-
}
132-
133-
int dim = IntPtr.Size * nbOfPaths;
134-
135-
IntPtr arrayPtr = Marshal.AllocHGlobal(dim);
136-
Marshal.Copy(pathPtrs, 0, arrayPtr, nbOfPaths);
137-
138-
return new GitStrArrayIn { strings = arrayPtr, size = (uint)nbOfPaths };
139-
}
140-
141-
public void Dispose()
142-
{
143-
if (size == 0)
144-
{
145-
return;
146-
}
147-
148-
var nbOfPaths = (int)size;
149-
150-
var pathPtrs = new IntPtr[nbOfPaths];
151-
Marshal.Copy(strings, pathPtrs, 0, nbOfPaths);
152-
153-
for (int i = 0; i < nbOfPaths; i ++)
154-
{
155-
Marshal.FreeHGlobal(pathPtrs[i]);
156-
}
157-
158-
Marshal.FreeHGlobal(strings);
159-
}
160-
}
161-
162116
internal delegate int diff_notify_cb(
163117
IntPtr diff_so_far,
164118
IntPtr delta_to_add,
@@ -191,8 +145,6 @@ public void Dispose()
191145
}
192146

193147
PathSpec.Dispose();
194-
195-
PathSpec.size = 0;
196148
}
197149
}
198150

LibGit2Sharp/Core/GitStrArrayIn.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.InteropServices;
5+
using System.Text;
6+
7+
namespace LibGit2Sharp.Core
8+
{
9+
[StructLayout(LayoutKind.Sequential)]
10+
internal class GitStrArrayIn : IDisposable
11+
{
12+
public IntPtr strings;
13+
public uint size;
14+
15+
public static GitStrArrayIn BuildFrom(FilePath[] paths)
16+
{
17+
var nbOfPaths = paths.Length;
18+
var pathPtrs = new IntPtr[nbOfPaths];
19+
20+
for (int i = 0; i < nbOfPaths; i++)
21+
{
22+
var s = paths[i].Posix;
23+
pathPtrs[i] = FilePathMarshaler.FromManaged(s);
24+
}
25+
26+
int dim = IntPtr.Size * nbOfPaths;
27+
28+
IntPtr arrayPtr = Marshal.AllocHGlobal(dim);
29+
Marshal.Copy(pathPtrs, 0, arrayPtr, nbOfPaths);
30+
31+
return new GitStrArrayIn { strings = arrayPtr, size = (uint)nbOfPaths };
32+
}
33+
34+
public void Dispose()
35+
{
36+
if (size == 0)
37+
{
38+
return;
39+
}
40+
41+
var nbOfPaths = (int)size;
42+
43+
var pathPtrs = new IntPtr[nbOfPaths];
44+
Marshal.Copy(strings, pathPtrs, 0, nbOfPaths);
45+
46+
for (int i = 0; i < nbOfPaths; i++)
47+
{
48+
Marshal.FreeHGlobal(pathPtrs[i]);
49+
}
50+
51+
Marshal.FreeHGlobal(strings);
52+
size = 0;
53+
}
54+
}
55+
}

LibGit2Sharp/Diff.cs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -65,33 +65,6 @@ private static GitDiffOptions BuildOptions(DiffModifiers diffOptions, FilePath[]
6565
return options;
6666
}
6767

68-
private static FilePath[] ToFilePaths(Repository repo, IEnumerable<string> paths)
69-
{
70-
if (paths == null)
71-
{
72-
return null;
73-
}
74-
75-
var filePaths = new List<FilePath>();
76-
77-
foreach (string path in paths)
78-
{
79-
if (string.IsNullOrEmpty(path))
80-
{
81-
throw new ArgumentException("At least one provided path is either null or empty.", "paths");
82-
}
83-
84-
filePaths.Add(repo.BuildRelativePathFrom(path));
85-
}
86-
87-
if (filePaths.Count == 0)
88-
{
89-
throw new ArgumentException("No path has been provided.", "paths");
90-
}
91-
92-
return filePaths.ToArray();
93-
}
94-
9568
/// <summary>
9669
/// Needed for mocking purposes.
9770
/// </summary>
@@ -287,7 +260,7 @@ private TreeCh D7AE anges BuildTreeChangesFromComparer(
287260
DiffModifiers diffOptions, IEnumerable<string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null)
288261
{
289262
var matchedPaths = new MatchedPathsAggregator();
290-
var filePaths = ToFilePaths(repo, paths);
263+
var filePaths = repo.ToFilePaths(paths);
291264

292265
using (GitDiffOptions options = BuildOptions(diffOptions, filePaths, matchedPaths, compareOptions))
293266
using (DiffListSafeHandle diffList = comparisonHandleRetriever(oldTreeId, newTreeId, options))

LibGit2Sharp/IRepository.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,19 @@ public interface IRepository : IDisposable
152152
/// <returns>The <see cref="Branch"/> that was checked out.</returns>
153153
Branch Checkout(Commit commit, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions);
154154

155+
/// <summary>
156+
/// Checkout files from the specified branch, reference or SHA.
157+
/// <para>
158+
/// This method does not switch branches or update the current repository HEAD.
159+
/// </para>
160+
/// </summary>
161+
/// <param name="committishOrBranchSpec">A revparse spec for the commit or branch to checkout paths from.</param>
162+
/// <param name="paths">The paths to checkout.</param>
163+
/// <param name="checkoutOptions">Options controlling checkout behavior.</param>
164+
/// <param name="onCheckoutProgress">Callback method to report checkout progress updates through.</param>
165+
/// <param name="checkoutNotificationOptions"><see cref="CheckoutNotificationOptions"/> to manage checkout notifications.</param>
166+
void CheckoutPaths(string committishOrBranchSpec, IList<string> paths, CheckoutModifiers checkoutOptions, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions);
167+
155168
/// <summary>
156169
/// Try to lookup an object by its <see cref="ObjectId"/>. If no matching object is found, null will be returned.
157170
/// </summary>

LibGit2Sharp/LibGit2Sharp.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
<Compile Include="CompareOptions.cs" />
7575
<Compile Include="Core\GitRepositoryInitOptions.cs" />
7676
<Compile Include="Core\HistoryRewriter.cs" />
77+
<Compile Include="Core\GitStrArrayIn.cs" />
7778
<Compile Include="Core\NativeDllName.cs" />
7879
<Compile Include="CommitRewriteInfo.cs" />
7980
<Compile Include="DiffModifiers.cs" />

0 commit comments

Comments
 (0)
0