Skip to content

Expose libgit2 fetch functionality. #206

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

Closed
wants to merge 1 commit into from
Closed
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
13 changes: 13 additions & 0 deletions LibGit2Sharp.Tests/BranchFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,19 @@ public void CanListAllBranchesIncludingRemoteRefs()
}
}

[Fact]
public void CanResolveTrackedRemote()
{
using (var repo = new Repository(StandardTestRepoPath))
{
Branch master = repo.Branches["master"];
Assert.Equal(repo.Remotes["origin"], master.ResolveTrackedRemote());

Branch test = repo.Branches["test"];
Assert.Null(test);
}
}

[Fact]
public void CanLookupABranchByItsCanonicalName()
{
Expand Down
29 changes: 28 additions & 1 deletion LibGit2Sharp/Branch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,31 @@ public virtual ICommitLog Commits
get { return repo.Commits.QueryBy(new Filter { Since = this }); }
}

/// <summary>
/// Gets the <see cref="Remote"/> tracking this branch
/// </summary>
/// <returns>The <see cref="Remote"/> tracking this branch if one exists, otherwise returns null.</returns>
public virtual Remote ResolveTrackedRemote()
{
if (IsTracking)
{
string trackedRemoteName = ResolveTrackedRemoteName();
if (string.IsNullOrEmpty(trackedRemoteName))
{
return null;
}

return repo.Remotes[trackedRemoteName];
}
else
{
return null;
}
}

private Branch ResolveTrackedBranch()
{
var trackedRemote = repo.Config.Get<string>("branch", Name, "remote", null);
string trackedRemote = ResolveTrackedRemoteName();
if (trackedRemote == null)
{
return null;
Expand All @@ -154,6 +176,11 @@ private Branch ResolveTrackedBranch()
return repo.Branches[remoteRefName];
}

private string ResolveTrackedRemoteName()
{
return repo.Config.Get<string>("branch", Name, "remote", null) as string;
}

private static string ResolveTrackedReference(string trackedRemote, string trackedRefName)
{
if (trackedRemote == ".")
Expand Down
10 changes: 10 additions & 0 deletions LibGit2Sharp/Core/GitDirection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;

namespace LibGit2Sharp.Core
{
internal enum GitDirection
{
Fetch = 0,
Push = 1
}
}
12 changes: 12 additions & 0 deletions LibGit2Sharp/Core/GitIndexerStats.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Runtime.InteropServices;

namespace LibGit2Sharp.Core
{
[StructLayout(LayoutKind.Sequential)]
internal struct GitIndexerStats
{
public uint total;
public uint processed;
}
}
12 changes: 12 additions & 0 deletions LibGit2Sharp/Core/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,18 @@ public static extern int git_remote_new(
[return : MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]
public static extern string git_remote_url(RemoteSafeHandle remote);

[DllImport(libgit2)]
public static extern int git_remote_connect(RemoteSafeHandle remote, GitDirection direction);

[DllImport(libgit2)]
public static extern void git_remote_disconnect(RemoteSafeHandle remote);

[DllImport(libgit2)]
public static extern int git_remote_download(RemoteSafeHandle remote, ref long bytes, ref GitIndexerStats stats);

[DllImport(libgit2)]
public static extern int git_remote_update_tips(RemoteSafeHandle remote, IntPtr cb);

[DllImport(libgit2)]
public static extern int git_remote_save(RemoteSafeHandle remote);

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

namespace LibGit2Sharp
{
/// <summary>
/// Contains data regarding fetch progress.
/// </summary>
public class FetchProgress : IndexerStats
{
/// <summary>
/// Fetch progress constructor.
/// </summary>
public FetchProgress()
{ }

/// <summary>
/// Bytes received.
/// </summary>
public long Bytes
{
get
{
return bytes;
}
}

internal override void Reset()
{
base.Reset();
bytes = 0;
}

#region Fields

internal long bytes;

#endregion
}
}
57 changes: 57 additions & 0 deletions LibGit2Sharp/IndexerStats.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LibGit2Sharp.Core
{
/// <summary>
/// Wrapper around git_indexer_stats
/// </summary>
public class IndexerStats
{
/// <summary>
/// Constructor
/// </summary>
public IndexerStats()
{
indexerStats = new GitIndexerStats();
}
/// <summary>
/// Total number of objects
/// </summary>
public long TotalObjectCount
{
get
{
return indexerStats.total;
}
}

/// <summary>
/// Number of objects processed.
/// </summary>
public long ProcessedObjectCount
{
get
{
return indexerStats.processed;
}
}

/// <summary>
/// Reset internal data
/// </summary>
internal virtual void Reset()
{
indexerStats.processed = 0;
indexerStats.total = 0;
}

#region Fields

internal GitIndexerStats indexerStats;

#endregion
}
}
4 changes: 4 additions & 0 deletions LibGit2Sharp/LibGit2Sharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@
<Compile Include="CommitLog.cs" />
<Compile Include="Configuration.cs" />
<Compile Include="ContentChanges.cs" />
<Compile Include="Core\GitIndexerStats.cs" />
<Compile Include="TagCollectionExtensions.cs" />
<Compile Include="Core\Compat\Environment.cs" />
<Compile Include="FetchProgress.cs" />
<Compile Include="Core\FilePath.cs" />
<Compile Include="Core\FilePathExtensions.cs" />
<Compile Include="Core\FilePathMarshaler.cs" />
Expand All @@ -79,6 +81,7 @@
<Compile Include="Core\GitBranchType.cs" />
<Compile Include="Core\GitDiff.cs" />
<Compile Include="Core\GitDiffExtensions.cs" />
<Compile Include="Core\GitDirection.cs" />
<Compile Include="Core\GitError.cs" />
<Compile Include="Core\GitErrorCategory.cs" />
<Compile Include="Core\GitNoteData.cs" />
Expand All @@ -93,6 +96,7 @@
<Compile Include="Core\Handles\OidSafeHandle.cs" />
<Compile Include="Core\Handles\TreeBuilderSafeHandle.cs" />
<Compile Include="Core\Handles\TreeEntrySafeHandle_Owned.cs" />
<Compile Include="IndexerStats.cs" />
<Compile Include="Core\ReferenceExtensions.cs" />
<Compile Include="Core\Handles\ReferenceSafeHandle.cs" />
<Compile Include="Core\Handles\SignatureSafeHandle.cs" />
Expand Down
39 changes: 38 additions & 1 deletion LibGit2Sharp/Remote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ public class Remote : IEquatable<Remote>
private static readonly LambdaEqualityHelper<Remote> equalityHelper =
new LambdaEqualityHelper<Remote>(new Func<Remote, object>[] { x => x.Name, x => x.Url });

private Repository repository;

/// <summary>
/// Needed for mocking purposes.
/// </summary>
protected Remote()
{ }

internal static Remote CreateFromPtr(RemoteSafeHandle handle)

internal static Remote CreateFromPtr(Repository repository, RemoteSafeHandle handle)
{
if (handle == null)
{
Expand All @@ -32,6 +35,7 @@ internal static Remote CreateFromPtr(RemoteSafeHandle handle)
{
Name = name,
Url = url,
repository = repository,
};

return remote;
Expand All @@ -47,6 +51,39 @@ internal static Remote CreateFromPtr(RemoteSafeHandle handle)
/// </summary>
public virtual string Url { get; private set; }

/// <summary>
/// Fetch updates from the remote.
/// </summary>
/// <param name="fetchProgress">The <see cref = "FetchProgress" /> to report current fetch progress.</param>
public virtual void Fetch(FetchProgress fetchProgress)
{
// reset the current progress object
fetchProgress.Reset();

using (RemoteSafeHandle remoteHandle = repository.Remotes.LoadRemote(Name, true))
{
try
{
int res = NativeMethods.git_remote_connect(remoteHandle, GitDirection.Fetch);
Ensure.Success(res);

int downloadResult = NativeMethods.git_remote_download(remoteHandle, ref fetchProgress.bytes, ref fetchProgress.indexerStats);
Ensure.Success(downloadResult);
}
finally
{
if (remoteHandle != null)
{
NativeMethods.git_remote_disconnect(remoteHandle);
}
}

// update references
int updateTipsResult = NativeMethods.git_remote_update_tips(remoteHandle, IntPtr.Zero);
Ensure.Success(updateTipsResult);
}
}

/// <summary>
/// Determines whether the specified <see cref = "Object" /> is equal to the current <see cref = "Remote" />.
/// </summary>
Expand Down
6 changes: 3 additions & 3 deletions LibGit2Sharp/RemoteCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private Remote RemoteForName(string name)
{
using (RemoteSafeHandle handle = LoadRemote(name, false))
{
return Remote.CreateFromPtr(handle);
return Remote.CreateFromPtr(repository, handle);
}
}

Expand Down Expand Up @@ -100,7 +100,7 @@ public virtual Remote Add(string name, string url)

using (handle)
{
return Remote.CreateFromPtr(handle);
return Remote.CreateFromPtr(repository, handle);
}
}

Expand Down Expand Up @@ -142,7 +142,7 @@ public virtual Remote Add(string name, string url, string fetchRefSpec)
res = NativeMethods.git_remote_save(handle);
Ensure.Success(res);

return Remote.CreateFromPtr(handle);
return Remote.CreateFromPtr(repository, handle);
}
}

Expand Down