Skip to content

Clone #223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 12, 2012
Merged

Clone #223

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions LibGit2Sharp.Tests/RepositoryFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
using System.Linq;
using LibGit2Sharp.Tests.TestHelpers;
using Xunit;
using Xunit.Extensions;

namespace LibGit2Sharp.Tests
{
public class RepositoryFixture : BaseFixture
{
private const string commitSha = "8496071c1b46c854b31185ea97743be6a8774479";
private const string TestRepoUrl = "git://github.com/libgit2/TestGitRepository";

[Fact]
public void CanCreateBareRepo()
Expand Down Expand Up @@ -465,5 +467,72 @@ public void CanDetectIfTheHeadIsOrphaned()
Assert.False(repo.Info.IsHeadOrphaned);
}
}

[Theory]
[InlineData("http://github.com/libgit2/TestGitRepository")]
[InlineData("https://github.com/libgit2/TestGitRepository")]
[InlineData("git://github.com/libgit2/TestGitRepository")]
//[InlineData("git@github.com:libgit2/TestGitRepository")]
public void CanClone(string url)
{
var scd = BuildSelfCleaningDirectory();
using (Repository repo = Repository.Clone(url, scd.RootedDirectoryPath))
{
string dir = repo.Info.Path;
Assert.True(Path.IsPathRooted(dir));
Assert.True(Directory.Exists(dir));

Assert.NotNull(repo.Info.WorkingDirectory);
Assert.Equal(Path.Combine(scd.RootedDirectoryPath, ".git" + Path.DirectorySeparatorChar), repo.Info.Path);
Assert.False(repo.Info.IsBare);

Assert.True(File.Exists(Path.Combine(scd.RootedDirectoryPath, "master.txt")));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be reasonable to assert the current branch / head commit are as expected?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it would! Fixed!

Assert.Equal(repo.Head.Name, "master");
Assert.Equal(repo.Head.Tip.Id.ToString(), "49322bb17d3acc9146f98c97d078513228bbf3c0");
}
}

[Theory]
[InlineData("http://github.com/libgit2/TestGitRepository")]
[InlineData("https://github.com/libgit2/TestGitRepository")]
[InlineData("git://github.com/libgit2/TestGitRepository")]
//[InlineData("git@github.com:libgit2/TestGitRepository")]
public void CanCloneBarely(string url)
{
var scd = BuildSelfCleaningDirectory();
using (Repository repo = Repository.Clone(url, scd.RootedDirectoryPath, bare:true))
{
string dir = repo.Info.Path;
Assert.True(Path.IsPathRooted(dir));
Assert.True(Directory.Exists(dir));

Assert.Null(repo.Info.WorkingDirectory);
Assert.Equal(scd.RootedDirectoryPath + Path.DirectorySeparatorChar, repo.Info.Path);
Assert.True(repo.Info.IsBare);
}
}

[Fact]
public void WontCheckoutIfAskedNotTo()
{
var scd = BuildSelfCleaningDirectory();
using (Repository repo = Repository.Clone(TestRepoUrl, scd.RootedDirectoryPath, checkout:false))
{
Assert.False(File.Exists(Path.Combine(scd.RootedDirectoryPath, "master.txt")));
}
}

[Fact]
public void CallsTransferProgress()
{
bool wasCalled = false;

var scd = BuildSelfCleaningDirectory();
using (Repository repo = Repository.Clone(TestRepoUrl, scd.RootedDirectoryPath,
onTransferProgress: (_) => wasCalled = true))
{
Assert.True(wasCalled);
}
}
}
}
17 changes: 17 additions & 0 deletions LibGit2Sharp/Core/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,23 @@ internal static extern int git_checkout_head(
RepositorySafeHandle repo,
GitCheckoutOpts opts);

[DllImport(libgit2)]
internal static extern int git_clone(
out RepositorySafeHandle repo,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))] string origin_url,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(FilePathMarshaler))] FilePath workdir_path,
git_transfer_progress_callback transfer_callback,
IntPtr transfer_payload,
GitCheckoutOpts checkout_opts);

[DllImport(libgit2)]
internal static extern int git_clone_bare(
out RepositorySafeHandle repo,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))] string url,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(FilePathMarshaler))] FilePath destination,
git_transfer_progress_callback transfer_callback,
IntPtr transfer_payload);

[DllImport(libgit2)]
internal static extern IntPtr git_commit_author(GitObjectSafeHandle commit);

Expand Down
33 changes: 33 additions & 0 deletions LibGit2Sharp/Core/Proxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,39 @@ public static void git_checkout_head(RepositorySafeHandle repo, GitCheckoutOpts

#endregion

#region git_clone_

public static RepositorySafeHandle git_clone(
string url,
string workdir,
NativeMethods.git_transfer_progress_callback transfer_cb,
GitCheckoutOpts checkoutOptions)
{
using (ThreadAffinity())
{
RepositorySafeHandle repo;
int res = NativeMethods.git_clone(out repo, url, workdir, transfer_cb, IntPtr.Zero, checkoutOptions);
Ensure.Success(res);
return repo;
}
}

public static RepositorySafeHandle git_clone_bare(
string url,
string workdir,
NativeMethods.git_transfer_progress_callback transfer_cb)
{
using (ThreadAffinity())
{
RepositorySafeHandle repo;
int res = NativeMethods.git_clone_bare(out repo, url, workdir, transfer_cb, IntPtr.Zero);
Ensure.Success(res);
return repo;
}
}

#endregion

#region git_commit_

public static Signature git_commit_author(GitObjectSafeHandle obj)
Expand Down
35 changes: 35 additions & 0 deletions LibGit2Sharp/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,41 @@ public static string Discover(string startingPath)
return discoveredPath.Native;
}

/// <summary>
/// Clone with specified options.
/// </summary>
/// <param name="sourceUrl">URI for the remote repository</param>
/// <param name="workdirPath">Local path to clone into</param>
/// <param name="bare">True will result in a bare clone, false a full clone.</param>
/// <param name="checkout">If true, the origin's HEAD will be checked out. This only applies
/// to non-bare repositories.</param>
/// <param name="onTransferProgress">Handler for progress information</param>
/// <returns></returns>
public static Repository Clone(string sourceUrl, string workdirPath,
bool bare = false,
bool checkout = true,
TransferProgressHandler onTransferProgress = null)
{
GitCheckoutOpts nativeOpts = null;
if (checkout)
{
nativeOpts = new GitCheckoutOpts
{
checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_CREATE_MISSING
};
}

NativeMethods.git_transfer_progress_callback cb =
TransferCallbacks.GenerateCallback(onTransferProgress);

RepositorySafeHandle repo = bare
? Proxy.git_clone_bare(sourceUrl, workdirPath, cb)
: Proxy.git_clone(sourceUrl, workdirPath, cb, nativeOpts);
repo.SafeDispose();

return new Repository(workdirPath);
}

/// <summary>
/// Checkout the specified <see cref = "Branch" />, reference or SHA.
/// </summary>
Expand Down