Как получить содержимое файла в Git с помощью LibGit2Sharp?

Я проверил код в BlobFixture.cs и нашел несколько тестов на чтение содержимого файла, как показано ниже.

using (var repo = new Repository(BareTestRepoPath))
{
    var blob = repo.Lookup<Blob>("a8233120f6ad708f843d861ce2b7228ec4e3dec6");

    var contentStream = blob.GetContentStream();
    Assert.Equal(blob.Size, contentStream.Length);

    using (var tr = new StreamReader(contentStream, Encoding.UTF8))
    {
        string content = tr.ReadToEnd();
        Assert.Equal("hey there\n", content);
    }
}

Но я не могу найти тест, который получает содержимое файла на основе имени файла. Возможно ли это сделать, если да, то как?


person Anonymous    schedule 26.02.2014    source источник
comment
Добавьте :your/file/path.txt в конец строки SHA как @nulltoken указывает.   -  person Michael    schedule 13.02.2019


Ответы (1)


Каждый Tree содержит коллекцию TreeEntry. TreeEntry содержит некоторые метаданные (имя, режим, oid, ...) об указанном на GitObject. Доступ к GitObject можно получить через свойство Target экземпляра TreeEntry.

В большинстве случаев TreeEntry будет указывать на Blob или другое Tree.

Тип Tree предоставляет индексатор, который принимает путь для простого извлечения окончательного указателя на TreeEntry. Для удобства Commit также предоставляет такой индексатор.

Таким образом, ваш код может быть выражен таким образом.

using (var repo = new Repository(BareTestRepoPath))
{
    var commit = repo.Lookup<Commit>("deadbeefcafe"); // or any other way to retreive a specific commit
    var treeEntry = commit["path/to/my/file.txt");

    Debug.Assert(treeEntry.TargetType == TreeEntryTargetType.Blob);
    var blob = (Blob)treeEntry.Target;

    var contentStream = blob.GetContentStream();
    Assert.Equal(blob.Size, contentStream.Length);

    using (var tr = new StreamReader(contentStream, Encoding.UTF8))
    {
        string content = tr.ReadToEnd();
        Assert.Equal("hey there\n", content);
    }
}
person nulltoken    schedule 26.02.2014
comment
Был ли этот ответ полезен? - person nulltoken; 10.04.2014
comment
Такого рода работы и частично помогают мне, спасибо! Однако проблема здесь в том, что фиксация будет содержать только файлы, измененные в этой фиксации. Я все еще ищу способ получить определенный файл по указанному пути репо, независимо от того, когда он был проверен. У меня также нет возможности заранее узнать хэш sha1 для конкретного коммита, и меня это не волнует в этом сценарии. Я опубликую ответ, если найду его. - person Dan Csharpster; 09.12.2016
comment
Коммит — это не диффграмма. Это снимок. Таким образом, он содержит все файлы, которые находились в рабочем каталоге на момент его создания. - person nulltoken; 09.12.2016
comment
Из командной строки я узнал, как сделать то, что я хотел. Я могу сделать разреженную проверку подкаталога, а затем выполнить неглубокое клонирование с глубиной = 1, поэтому я получаю только историю ревизии головы. Я пишу несколько команд оболочки для вызова командной строки и опубликую их, когда это будет сделано. - person Dan Csharpster; 09.12.2016
comment
Отличный ответ. @DanCsharpster (которое, как я понимаю, вы, скорее всего, уже ушли в своей жизни) для меня фиксация ветки в верхней части — это то, что я всегда ищу, например: string trackedBranchName = ${ORIGIN_NAME}/{branchToCheckout}; Branch trackedBranch = m_repo.Branches[trackedBranchName]; строка currentBranchTipAtOrigin = trackedBranch.Tip.Id.ToString(); - person RoboYak; 09.02.2021