Skip to content

Commit 49fb3fc

Browse files
committed
Workaround for reference slash prefix in libgit2.
When libgit2 is passed a path to a working directory instead of a git directory the names returned from git_reference_listall (and perhaps other similar methods) will be prefixed with a slash such that insteaf of refs/heads/master it'll return /refs/heads/master. LibGitSharp always does it's string prefix comparisons without a starting slash (which seems to be the correct thing to do). Includes test which verifies the problem by copying the sample working directory and performing the same test (CanListAllBranches) that's run for the bare repository. Update constructor documentation to reflect that it's possible to pass the path to a working directory.
1 parent e32dba4 commit 49fb3fc

2 files changed

Lines changed: 33 additions & 2 deletions

File tree

LibGit2Sharp.Tests/BranchFixture.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.IO;
23
using System.Linq;
34
using LibGit2Sharp.Tests.TestHelpers;
45
using NUnit.Framework;
@@ -167,6 +168,20 @@ public void CanListAllBranches()
167168
}
168169
}
169170

171+
[Test]
172+
public void CanListAllBranchesWhenGivenWorkingDir()
173+
{
174+
TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo(StandardTestRepoWorkingDirPath);
175+
using (var repo = new Repository(path.DirectoryPath))
176+
{
177+
var expectedWdBranches = new[] { "master", "origin/HEAD", "origin/br2", "origin/master", "origin/packed-test", "origin/test" };
178+
179+
CollectionAssert.AreEqual(expectedWdBranches, repo.Branches.Select(b => b.Name).ToArray());
180+
181+
repo.Branches.Count().ShouldEqual(6);
182+
}
183+
}
184+
170185
[Test]
171186
public void CanListAllBranchesIncludingRemoteRefs()
172187
{

LibGit2Sharp/Repository.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.IO;
23
using LibGit2Sharp.Core;
34
using LibGit2Sharp.Core.Compat;
45

@@ -22,13 +23,28 @@ public class Repository : IDisposable
2223

2324
/// <summary>
2425
/// Initializes a new instance of the <see cref = "Repository" /> class.
25-
/// <para>For a standard repository, <paramref name = "path" /> should point to the ".git" folder. For a bare repository, <paramref name = "path" /> should directly point to the repository folder.</para>
26+
/// <para>For a standard repository, <paramref name = "path" /> should either point to the ".git" folder or to the working directory. For a bare repository, <paramref name = "path" /> should directly point to the repository folder.</para>
2627
/// </summary>
27-
/// <param name = "path">The path to the git repository to open.</param>
28+
/// <param name = "path">
29+
/// The path to the git repository to open, can be either the path to the git directory (for non-bare repositories this
30+
/// would be the ".git" folder inside the working directory) or the path to the working directory.
31+
/// </param>
2832
public Repository(string path)
2933
{
3034
Ensure.ArgumentNotNullOrEmptyString(path, "path");
3135

36+
// Check if the path points to the working directory instead of the git directory
37+
// by checking if the directory contains a .git directory. The same test is done
38+
// in libgit2 but if it gets to add .git to the path it will mess up the ref paths
39+
// returned from git_reference_listall (and more?) by prefixing them with a '/' such
40+
// that what would normally be refs/heads/master becomes /refs/heads/master and
41+
// LibGit2Sharp doesn't expect that. This is a workaround.
42+
// See https://github.com/libgit2/libgit2sharp/pull/108
43+
string gitDirPath = Path.Combine(path, ".git");
44+
45+
if (Directory.Exists(gitDirPath))
46+
path = gitDirPath;
47+
3248
int res = NativeMethods.git_repository_open(out handle, PosixPathHelper.ToPosix(path));
3349
Ensure.Success(res);
3450

0 commit comments

Comments
 (0)