2016-03-30 11 views
6

Ich muss den letzten Autor einer bestimmten Zeile im Git-Verlauf mit C# programmgesteuert abrufen. Ich versuchte libgit2sharp mit:Programmatisch tun "Git Schuld -w" in 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 

Aber das ist das Äquivalent des Befehls

git blame <file>

Und in der Tat muss ich

git blame -w <file> (zu Leerzeichen ignorieren beim Vergleich)

Libgit2sharp stellen Sie den -w Schalter nicht ein und stellen Sie keinen Parameter/keine Option zum Einstellen bereit. Was sind meine Optionen? Kennen Sie eine andere Bibliothek, die mit dem -w-Schalter des Befehls blame kompatibel ist?

+0

Nur um zu verdeutlichen, dass Sie NGit ausprobiert haben? –

+0

@ Jeremy: gar nicht, ich kannte NGit nicht. Ich habe so viel Zeit mit dieser Frage verbracht, dass ich mich lieber nach Feedback erkundigte. – JYL

+0

Cool, das ist eine wirklich gute Feature-Anfrage für das LibGit2Sharp-Entwickler-Team :) Wenn Sie sie bitten, einen Link zu diesem Q höflich zu referenzieren, können Sie eines der Kern-Teams oder einen Mitwirkenden ermutigen, es hinzuzufügen, solange dieses Q ein aktives Kopfgeld hat befestigt ... Ansonsten sollte Evk es bekommen (+1). Daumen drücken, das reicht, um zu überzeugen, denn dann müssten Sie sich nicht auf 2 Bibliotheken verlassen. –

Antwort

2

Wenn ich ähnliche erweiterte Szenarien treffe, wo die git lib es nicht schneidet, schalte ich nur aus, indem ich den Startprozess zur echten Git-Befehlszeile verwende. Es ist nicht sexy, aber es ist mächtig effektiv.

+0

Ich dachte darüber nach, aber ich muss dies für etwa 2000 Dateien in meiner Lösung tun, und befürchtete die Leistung. Ich werde es als letzten Ausweg versuchen. – JYL

+0

In der Tat ist dieser Weg wirklich schneller als mit libGit2Sharp in meinem Fall. Mit einem Test-Repository von 818 Dateien (4570 Commits), mit einer Schuld für jede Datei: mit direktem Prozess: durchschnittlich 181 ms. pro Schuld; mit ligGit2Sharp: durchschnittlich 1235 ms pro Schuld. – JYL

2

Vielleicht hilft die Verwendung der NGIT-Bibliothek. Das ist der direkte (automatische) Port der Java-JGIT-Bibliothek. Installieren via NuGet Paket ist, dann:

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(); 
    } 

Hinweis SetTextComparator (RawTextComparator.WS_IGNORE_ALL) Teil.

+0

Danke für die Antwort, ich werde das nächste Woche versuchen. – JYL

+0

Keine Möglichkeit, dies zum Laufen zu bringen. Einige Commits sind nett und einige andere sind einfach null. Vor allem wenn es Leerzeichen gibt. Ich weiß nicht, ob ich eine falsche oder fehlende Option habe, oder ob es nur wegen der veralteten Quellen von ngit (im Vergleich zu jgit) ist. Ich gebe auf, ich gehe zurück zu den Grundlagen (robrich solution). – JYL

+0

Trotzdem gebe ich Ihnen das Kopfgeld, weil die Antwort theoretisch korrekt ist und mit einem entsprechenden Codebeispiel gegeben ist. Vielen Dank. – JYL

0

Leider ist libgit2sharp zu langsam bei der Entschlüsselung von Vorwürfen und die Verwendung dieser Funktion ist in realen Szenarien unpraktisch. Daher denke ich am besten, ein Powershell-Skript zu verwenden, um das zugrunde liegende superschnelle native Git zu verwenden. Und leiten Sie das Ergebnis dann an Ihre Anwendung weiter.

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']}}