From 49fb3fc69881166d63056fadcdbaa1df0fdd45a4 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Fri, 3 Feb 2012 00:25:30 +0100 Subject: [PATCH] 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. --- LibGit2Sharp.Tests/BranchFixture.cs | 15 +++++++++++++++ LibGit2Sharp/Repository.cs | 20 ++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/LibGit2Sharp.Tests/BranchFixture.cs b/LibGit2Sharp.Tests/BranchFixture.cs index 481489ada..8870155b6 100644 --- a/LibGit2Sharp.Tests/BranchFixture.cs +++ b/LibGit2Sharp.Tests/BranchFixture.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using NUnit.Framework; @@ -167,6 +168,20 @@ public void CanListAllBranches() } } + [Test] + public void CanListAllBranchesWhenGivenWorkingDir() + { + TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo(StandardTestRepoWorkingDirPath); + using (var repo = new Repository(path.DirectoryPath)) + { + var expectedWdBranches = new[] { "master", "origin/HEAD", "origin/br2", "origin/master", "origin/packed-test", "origin/test" }; + + CollectionAssert.AreEqual(expectedWdBranches, repo.Branches.Select(b => b.Name).ToArray()); + + repo.Branches.Count().ShouldEqual(6); + } + } + [Test] public void CanListAllBranchesIncludingRemoteRefs() { diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index 11c3b70d5..9c23bebea 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using LibGit2Sharp.Core; using LibGit2Sharp.Core.Compat; @@ -22,13 +23,28 @@ public class Repository : IDisposable /// /// Initializes a new instance of the class. - /// For a standard repository, should point to the ".git" folder. For a bare repository, should directly point to the repository folder. + /// For a standard repository, should either point to the ".git" folder or to the working directory. For a bare repository, should directly point to the repository folder. /// - /// The path to the git repository to open. + /// + /// The path to the git repository to open, can be either the path to the git directory (for non-bare repositories this + /// would be the ".git" folder inside the working directory) or the path to the working directory. + /// public Repository(string path) { Ensure.ArgumentNotNullOrEmptyString(path, "path"); + // Check if the path points to the working directory instead of the git directory + // by checking if the directory contains a .git directory. The same test is done + // in libgit2 but if it gets to add .git to the path it will mess up the ref paths + // returned from git_reference_listall (and more?) by prefixing them with a '/' such + // that what would normally be refs/heads/master becomes /refs/heads/master and + // LibGit2Sharp doesn't expect that. This is a workaround. + // See https://github.com/libgit2/libgit2sharp/pull/108 + string gitDirPath = Path.Combine(path, ".git"); + + if (Directory.Exists(gitDirPath)) + path = gitDirPath; + int res = NativeMethods.git_repository_open(out handle, PosixPathHelper.ToPosix(path)); Ensure.Success(res);