Git In-Memory存储库更新目标

时间:2017-06-24 19:12:58

标签: libgit2 libgit2sharp

我对整个libgit2和libgit2sharp代码库仍然相当新,但我一直在努力解决In-Memory存储库和Refdb存储引用的问题。

我已经在我的新branch中完成了所有工作:

  1. 创建In-Memory存储库并将Refdb和Odb实例附加到其中。
  2. 创建初始提交并设置refs / heads / master的引用。
  3. 创建第二个提交...
  4. 我遇到的问题是将refs / heads / master更新为第二次提交。对refs / heads / master的UpdateTarget调用在git_reference_set_target中遇到错误:

    LibGit2Sharp.NameConflictException : config value 'user.name' was not found
       at LibGit2Sharp.Core.Ensure.HandleError(Int32 result) in \libgit2sharp\LibGit2Sharp\Core\Ensure.cs:line 154
       at LibGit2Sharp.Core.Ensure.ZeroResult(Int32 result) in \libgit2sharp\LibGit2Sharp\Core\Ensure.cs:line 172
       at LibGit2Sharp.Core.Proxy.git_reference_set_target(ReferenceHandle reference, ObjectId id, String logMessage) in \libgit2sharp\LibGit2Sharp\Core\Proxy.cs:line 2042
       at LibGit2Sharp.ReferenceCollection.UpdateDirectReferenceTarget(Reference directRef, ObjectId targetId, String logMessage) in \libgit2sharp\LibGit2Sharp\ReferenceCollection.cs:line 476
       at LibGit2Sharp.ReferenceCollection.UpdateTarget(Reference directRef, ObjectId targetId, String logMessage) in \libgit2sharp\LibGit2Sharp\ReferenceCollection.cs:line 470
       at LibGit2Sharp.ReferenceCollection.UpdateTarget(Reference directRef, String objectish, String logMessage) in \libgit2sharp\LibGit2Sharp\ReferenceCollection.cs:line 498
       at LibGit2Sharp.ReferenceCollection.UpdateTarget(String name, String canonicalRefNameOrObjectish, String logMessage) in \libgit2sharp\LibGit2Sharp\ReferenceCollection.cs:line 534
       at LibGit2Sharp.ReferenceCollection.UpdateTarget(String name, String canonicalRefNameOrObjectish) in \libgit2sharp\LibGit2Sharp\ReferenceCollection.cs:line 565
       at LibGit2Sharp.Tests.RepositoryFixture.CanCreateInMemoryRepositoryWithBackends() in \libgit2sharp\LibGit2Sharp.Tests\RepositoryFixture.cs:line 791
    

    我无法调试到libgit2级别,但我可以告诉问题是git_reference_create_matching call to git_reference__log_signature

    我是否缺少可以更新不需要签名的裸机库中的引用的电话?如果任何libgit2人知道如何在libgit2中执行此操作,我可以在C#端实现它。

    作为测试,我创建了两个unit tests,它们在内存和磁盘上执行相同的操作,并且在创建第二个提交后调用UpdateTarget时内存中失败。这遵循wiki

    上的代码
        private Commit CreateCommit(Repository repository, string fileName, string content, string message = null)
        {
            if (message == null)
            {
                message = "i'm a commit message :)";
            }
    
            Blob newBlob = repository.ObjectDatabase.CreateBlobFromContent(content);
    
            // Put the blob in a tree
            TreeDefinition td = new TreeDefinition();
            td.Add(fileName, newBlob, Mode.NonExecutableFile);
            Tree tree = repository.ObjectDatabase.CreateTree(td);
    
            // Committer and author
            Signature committer = new Signature("Auser", "auser@example.com", DateTime.Now);
            Signature author = committer;
    
            // Create binary stream from the text
            return repository.ObjectDatabase.CreateCommit(
                author,
                committer,
                message,
                tree,
                repository.Commits,
                true);
        }
    
        [Fact]
        public void CanCreateRepositoryWithoutBackends()
        {
            SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
    
            Repository.Init(scd.RootedDirectoryPath, true);
            ObjectId commit1Id;
            using (var repository = new Repository(scd.RootedDirectoryPath))
            {
                Commit commit1 = CreateCommit(repository, "filePath.txt", "Hello commit 1!");
                commit1Id = commit1.Id;
                repository.Refs.Add("refs/heads/master", commit1.Id);
                Assert.Equal(1, repository.Commits.Count());
                Assert.NotNull(repository.Refs.Head);
                Assert.Equal(1, repository.Refs.Count());
            }
    
            using (var repository = new Repository(scd.RootedDirectoryPath))
            {
                Commit commit2 = CreateCommit(repository, "filePath.txt", "Hello commit 2!");
                Assert.Equal(commit1Id, commit2.Parents.First().Id);
    
                repository.Refs.UpdateTarget("refs/heads/master", commit2.Sha);
                Assert.Equal(2, repository.Commits.Count());
                Assert.Equal(1, repository.Refs.Count());
                Assert.NotNull(repository.Refs.Head);
                Assert.Equal(commit2.Sha, repository.Refs.Head.ResolveToDirectReference().TargetIdentifier);
            }
        }
    
        [Fact]
        public void CanCreateInMemoryRepositoryWithBackends()
        {
            OdbBackendFixture.MockOdbBackend odbBackend = new OdbBackendFixture.MockOdbBackend();
            RefdbBackendFixture.MockRefdbBackend refdbBackend = new RefdbBackendFixture.MockRefdbBackend();
    
            ObjectId commit1Id;
            using (var repository = new Repository())
            {
                repository.Refs.SetBackend(refdbBackend);
                repository.ObjectDatabase.AddBackend(odbBackend, 5);
    
                Commit commit1 = CreateCommit(repository, "filePath.txt", "Hello commit 1!");
                commit1Id = commit1.Id;
                repository.Refs.Add("refs/heads/master", commit1.Id);
                Assert.Equal(1, repository.Commits.Count());
                Assert.NotNull(repository.Refs.Head);
                Assert.Equal(commit1.Sha, repository.Refs.Head.ResolveToDirectReference().TargetIdentifier);
    
                // Emulating Git, repository.Refs enumerable does not include the HEAD.
                // Thus, repository.Refs.Count will be 1 and refdbBackend.References.Count will be 2.
                Assert.Equal(1, repository.Refs.Count());
                Assert.Equal(2, refdbBackend.References.Count);
            }
    
            using (var repository = new Repository())
            {
                repository.Refs.SetBackend(refdbBackend);
                repository.ObjectDatabase.AddBackend(odbBackend, 5);
    
                Commit commit2 = CreateCommit(repository, "filePath.txt", "Hello commit 2!");
                Assert.Equal(commit1Id, commit2.Parents.First().Id);
                //repository.Refs.UpdateTarget(repository.Refs["refs/heads/master"], commit2.Id);
    
                //var master = repository.Refs["refs/heads/master"];
                //Assert.Equal(commit1Id.Sha, master.TargetIdentifier);
                repository.Refs.UpdateTarget("refs/heads/master", commit2.Sha); // fails at LibGit2Sharp.Core.Proxy.git_reference_set_target(ReferenceHandle reference, ObjectId id, String logMessage)
                //repository.Refs.Add("refs/heads/master", commit2.Id); // fails at LibGit2Sharp.Core.Proxy.git_reference_create(RepositoryHandle repo, String name, ObjectId targetId, Boolean allowOverwrite, String logMessage)
                Assert.Equal(2, repository.Commits.Count());
                Assert.Equal(1, repository.Refs.Count());
                Assert.NotNull(repository.Refs.Head);
                Assert.Equal(commit2.Sha, repository.Refs.Head.ResolveToDirectReference().TargetIdentifier);
            }
        }
    

0 个答案:

没有答案