Skip to content

Commit

Permalink
Teach Repository to Checkout paths
Browse files Browse the repository at this point in the history
  • Loading branch information
jamill authored and nulltoken committed Jul 20, 2013
1 parent 01dfa28 commit 7e5bbbf
Show file tree
Hide file tree
Showing 9 changed files with 260 additions and 99 deletions.
68 changes: 68 additions & 0 deletions LibGit2Sharp.Tests/CheckoutFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,74 @@ public void CanCheckoutDetachedHead()
}
}

[Theory]
[InlineData("master", "6dcf9bf", "readme.txt", FileStatus.Added)]
[InlineData("master", "refs/tags/lw", "readme.txt", FileStatus.Added)]
[InlineData("master", "i-do-numbers", "super-file.txt", FileStatus.Added)]
[InlineData("i-do-numbers", "diff-test-cases", "numbers.txt", FileStatus.Staged)]
public void CanCheckoutPath(string originalBranch, string checkoutFrom, string path, FileStatus expectedStatus)
{
string repoPath = CloneStandardTestRepo();
using (var repo = new Repository(repoPath))
{
// Set the working directory to the current head
ResetAndCleanWorkingDirectory(repo);

repo.Checkout(originalBranch);
Assert.False(repo.Index.RetrieveStatus().IsDirty);

repo.CheckoutPaths(checkoutFrom, new string[] { path }, CheckoutModifiers.None, null, null);

Assert.Equal(expectedStatus, repo.Index.RetrieveStatus(path));
Assert.Equal(1, repo.Index.RetrieveStatus().Count());
}
}

[Fact]
public void CanCheckoutPaths()
{
string repoPath = CloneStandardTestRepo();
var checkoutPaths = new[] { "numbers.txt", "super-file.txt" };

using (var repo = new Repository(repoPath))
{
// Set the working directory to the current head
ResetAndCleanWorkingDirectory(repo);
Assert.False(repo.Index.RetrieveStatus().IsDirty);

repo.CheckoutPaths("i-do-numbers", checkoutPaths, CheckoutModifiers.None, null, null);

foreach (string checkoutPath in checkoutPaths)
{
Assert.Equal(FileStatus.Added, repo.Index.RetrieveStatus(checkoutPath));
}
}
}

[Theory]
[InlineData("new.txt")]
[InlineData("1.txt")]
public void CanCheckoutPathFromCurrentBranch(string fileName)
{
string repoPath = CloneStandardTestRepo();

using (var repo = new Repository(repoPath))
{
// Set the working directory to the current head
ResetAndCleanWorkingDirectory(repo);

Assert.False(repo.Index.RetrieveStatus().IsDirty);

Touch(repo.Info.WorkingDirectory, fileName, "new text file");

Assert.True(repo.Index.RetrieveStatus().IsDirty);

repo.CheckoutPaths("HEAD", new string[] { fileName }, CheckoutModifiers.Force, null, null);

Assert.False(repo.Index.RetrieveStatus().IsDirty);
}
}

/// <summary>
/// Helper method to populate a simple repository with
/// a single file and two branches.
Expand Down
5 changes: 1 addition & 4 deletions LibGit2Sharp/BranchCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ public static Branch Add(this BranchCollection branches, string name, string com
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNullOrEmptyString(committish, "committish");

var commit = (Commit)branches.repo.Lookup(committish, GitObjectType.Any,
LookUpOptions.ThrowWhenNoGitObjectHasBeenFound |
LookUpOptions.DereferenceResultToCommit |
LookUpOptions.ThrowWhenCanNotBeDereferencedToACommit);
var commit = branches.repo.LookupCommit(committish);

return branches.Add(name, commit, allowOverwrite);
}
Expand Down
14 changes: 12 additions & 2 deletions LibGit2Sharp/Core/GitCheckoutOpts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ internal enum CheckoutStrategy
IntPtr payload);

[StructLayout(LayoutKind.Sequential)]
internal struct GitCheckoutOpts
internal struct GitCheckoutOpts :IDisposable
{
public uint version;

Expand All @@ -113,9 +113,19 @@ internal struct GitCheckoutOpts
public progress_cb progress_cb;
public IntPtr progress_payload;

public UnSafeNativeMethods.git_strarray paths;
public GitStrArrayIn paths;

public IntPtr baseline;
public IntPtr target_directory;

public void Dispose()
{
if (paths == null)
{
return;
}

paths.Dispose();
}
}
}
48 changes: 0 additions & 48 deletions LibGit2Sharp/Core/GitDiff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,52 +113,6 @@ internal enum GitDiffOptionFlags
GIT_DIFF_IGNORE_FILEMODE = (1 << 17),
}

[StructLayout(LayoutKind.Sequential)]
internal class GitStrArrayIn : IDisposable
{
public IntPtr strings;
public uint size;

public static GitStrArrayIn BuildFrom(FilePath[] paths)
{
var nbOfPaths = paths.Length;
var pathPtrs = new IntPtr[nbOfPaths];

for (int i = 0; i < nbOfPaths; i++)
{
var s = paths[i].Posix;
pathPtrs[i] = FilePathMarshaler.FromManaged(s);
}

int dim = IntPtr.Size * nbOfPaths;

IntPtr arrayPtr = Marshal.AllocHGlobal(dim);
Marshal.Copy(pathPtrs, 0, arrayPtr, nbOfPaths);

return new GitStrArrayIn { strings = arrayPtr, size = (uint)nbOfPaths };
}

public void Dispose()
{
if (size == 0)
{
return;
}

var nbOfPaths = (int)size;

var pathPtrs = new IntPtr[nbOfPaths];
Marshal.Copy(strings, pathPtrs, 0, nbOfPaths);

for (int i = 0; i < nbOfPaths; i ++)
{
Marshal.FreeHGlobal(pathPtrs[i]);
}

Marshal.FreeHGlobal(strings);
}
}

internal delegate int diff_notify_cb(
IntPtr diff_so_far,
IntPtr delta_to_add,
Expand Down Expand Up @@ -191,8 +145,6 @@ public void Dispose()
}

PathSpec.Dispose();

PathSpec.size = 0;
}
}

Expand Down
55 changes: 55 additions & 0 deletions LibGit2Sharp/Core/GitStrArrayIn.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace LibGit2Sharp.Core
{
[StructLayout(LayoutKind.Sequential)]
internal class GitStrArrayIn : IDisposable
{
public IntPtr strings;
public uint size;

public static GitStrArrayIn BuildFrom(FilePath[] paths)
{
var nbOfPaths = paths.Length;
var pathPtrs = new IntPtr[nbOfPaths];

for (int i = 0; i < nbOfPaths; i++)
{
var s = paths[i].Posix;
pathPtrs[i] = FilePathMarshaler.FromManaged(s);
}

int dim = IntPtr.Size * nbOfPaths;

IntPtr arrayPtr = Marshal.AllocHGlobal(dim);
Marshal.Copy(pathPtrs, 0, arrayPtr, nbOfPaths);

return new GitStrArrayIn { strings = arrayPtr, size = (uint)nbOfPaths };
}

public void Dispose()
{
if (size == 0)
{
return;
}

var nbOfPaths = (int)size;

var pathPtrs = new IntPtr[nbOfPaths];
Marshal.Copy(strings, pathPtrs, 0, nbOfPaths);

for (int i = 0; i < nbOfPaths; i++)
{
Marshal.FreeHGlobal(pathPtrs[i]);
}

Marshal.FreeHGlobal(strings);
size = 0;
}
}
}
29 changes: 1 addition & 28 deletions LibGit2Sharp/Diff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,33 +65,6 @@ private static GitDiffOptions BuildOptions(DiffModifiers diffOptions, FilePath[]
return options;
}

private static FilePath[] ToFilePaths(Repository repo, IEnumerable<string> paths)
{
if (paths == null)
{
return null;
}

var filePaths = new List<FilePath>();

foreach (string path in paths)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentException("At least one provided path is either null or empty.", "paths");
}

filePaths.Add(repo.BuildRelativePathFrom(path));
}

if (filePaths.Count == 0)
{
throw new ArgumentException("No path has been provided.", "paths");
}

return filePaths.ToArray();
}

/// <summary>
/// Needed for mocking purposes.
/// </summary>
Expand Down Expand Up @@ -287,7 +260,7 @@ private static TreeComparisonHandleRetriever IndexToTree(Repository repo)
DiffModifiers diffOptions, IEnumerable<string> paths = null, ExplicitPathsOptions explicitPathsOptions = null, CompareOptions compareOptions = null)
{
var matchedPaths = new MatchedPathsAggregator();
var filePaths = ToFilePaths(repo, paths);
var filePaths = repo.ToFilePaths(paths);

using (GitDiffOptions options = BuildOptions(diffOptions, filePaths, matchedPaths, compareOptions))
using (DiffListSafeHandle diffList = comparisonHandleRetriever(oldTreeId, newTreeId, options))
Expand Down
13 changes: 13 additions & 0 deletions LibGit2Sharp/IRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,19 @@ public interface IRepository : IDisposable
/// <returns>The <see cref="Branch"/> that was checked out.</returns>
Branch Checkout(Commit commit, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions);

/// <summary>
/// Checkout files from the specified branch, reference or SHA.
/// <para>
/// This method does not switch branches or update the current repository HEAD.
/// </para>
/// </summary>
/// <param name="committishOrBranchSpec">A revparse spec for the commit or branch to checkout paths from.</param>
/// <param name="paths">The paths to checkout.</param>
/// <param name="checkoutOptions">Options controlling checkout behavior.</param>
/// <param name="onCheckoutProgress">Callback method to report checkout progress updates through.</param>
/// <param name="checkoutNotificationOptions"><see cref="CheckoutNotificationOptions"/> to manage checkout notifications.</param>
void CheckoutPaths(string committishOrBranchSpec, IList<string> paths, CheckoutModifiers checkoutOptions, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions);

/// <summary>
/// Try to lookup an object by its <see cref="ObjectId"/>. If no matching object is found, null will be returned.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions LibGit2Sharp/LibGit2Sharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
<Compile Include="CompareOptions.cs" />
<Compile Include="Core\GitRepositoryInitOptions.cs" />
<Compile Include="Core\HistoryRewriter.cs" />
<Compile Include="Core\GitStrArrayIn.cs" />
<Compile Include="Core\NativeDllName.cs" />
<Compile Include="CommitRewriteInfo.cs" />
<Compile Include="DiffModifiers.cs" />
Expand Down

0 comments on commit 7e5bbbf

Please sign in to comment.