2016-03-30 8 views
6

Мне нужно программно получить последний автор конкретной строки в истории Git с помощью C#. Я попытался с помощью libgit2sharp:Программно делать «Git bame -w» в C#

var repo = new LibGit2Sharp.Repository(gitRepositoryPath); 
string relativePath = MakeRelativeSimple(filename); 
var blameHunks = repo.Blame(relativePath); 
// next : find the hunk which overlap the desired line number 

Но это эквивалент команды

git blame <file>

А на самом деле мне нужно

git blame -w <file> (игнорировать пробелы при сравнении)

Libgit2sharp не устанавливайте переключатель -w и не устанавливайте параметр/параметр. Какие у меня варианты? Знаете ли вы какую-либо другую библиотеку, совместимую с переключателем -w команды blame?

+0

Просто, чтобы уточнить, что вы пробовали NGit? –

+0

@Jeremy: совсем нет, я не знал NGit. Я потратил столько времени на этот вопрос, что предпочитаю просить обратной связи. – JYL

+0

Прохладный, это действительно хороший запрос функции для команды LibGit2Sharp dev. Если вы попросите их вежливо ссылаться на ссылку на этот Q, вы можете рекомендовать одной из основной команды или вкладчика добавить ее, пока этот Q имеет активную награду прилагается ... В противном случае Evk должен получить его (+1). Пальцы пересекли это достаточно, чтобы убедить, потому что тогда вам не нужно будет полагаться на 2 библиотеки. –

ответ

2

Когда я сталкиваюсь с аналогичными расширенными сценариями, где git lib не разрезает его, я просто использую процесс запуска в реальной командной строке git. Это не сексуально, но это очень эффективно.

+0

Я хоть об этом раньше, но мне нужно сделать это примерно для 2000 файлов в моем решении и опасаться за производительность. Я попробую это в крайнем случае. – JYL

+0

На самом деле этот способ действительно быстрее, чем использование libGit2Sharp в моем случае. С тестовым хранилищем 818 файлов (4570 коммитов), с винами в каждом файле: с использованием прямого процесса: в среднем 181 мс. за вину; используя ligGit2Sharp: в среднем 1235 мс за вину. – JYL

2

Возможно, использование библиотеки NGIT поможет. Это прямой (автоматический) порт java-библиотеки java. Установка с помощью пакета NuGet, затем:

static void Main() { 
     var git = Git.Init().SetDirectory("C:\\MyGitRepo").Call();    
     string relativePath = "MyFolder/MyFile.cs";    
     var blameHunks = git.Blame().SetFilePath(relativePath).SetTextComparator(RawTextComparator.WS_IGNORE_ALL).Call(); 
     blameHunks.ComputeAll(); 
     var firstLineCommit = blameHunks.GetSourceCommit(0); 
     // next : find the hunk which overlap the desired line number 
     Console.ReadKey(); 
    } 

Примечание SetTextComparator (RawTextComparator.WS_IGNORE_ALL) часть.

+0

Спасибо за ответ, я попробую это на следующей неделе. – JYL

+0

Невозможно сделать это. Некоторые коммиты хороши, а некоторые другие просто нулевые. Особенно, когда есть различия в пробелах. Я не знаю, есть ли у меня неправильный или отсутствующий вариант, или это связано с устаревшими источниками ngit (по сравнению с jgit). Я сдаюсь, я возвращаюсь к основам (решение robrich). – JYL

+0

Тем не менее, я даю вам щедрость, потому что ответ теоретически правильный и дается с соответствующим образцом кода. Благодарю. – JYL

0

К сожалению, libgit2sharp слишком медленно извлекает вины, и использование этой функции непрактично в реальных сценариях. Итак, лучший способ, по-моему, использовать сценарий Powershell для использования базового сверхбыстрого родного git. А затем перенаправить результат в ваше приложение.

git blame -l -e -c {commit-sha} -- "{file-path}" | where { $_ -match '(?<sha>\w{40})\s+\(<(?<email>[\w\.\-][email protected][\w\-]+\.\w{2,3})>\s+(?<datetime>\d\d\d\d-\d\d-\d\d\s\d\d\:\d\d:\d\d\s-\d\d\d\d)\s+(?<lineNumber>\d+)\)\w*' } | 
foreach { new-object PSObject –prop @{ Email = $matches['email'];lineNumber = $matches['lineNumber'];dateTime = $matches['dateTime'];Sha = $matches['sha']}}