Ich erstelle eine C # -Anwendung und verwende Git als Versionskontrolle.
Gibt es eine Möglichkeit, den letzten Commit-Hash beim Erstellen meiner Anwendung automatisch in die ausführbare Datei einzubetten?
Das Drucken des Commit-Hashs auf die Konsole sieht beispielsweise folgendermaßen aus:
class PrintCommitHash
{
private String lastCommitHash = ?? // What do I put here?
static void Main(string[] args)
{
// Display the version number:
System.Console.WriteLine(lastCommitHash );
}
}
Beachten Sie, dass dies zur Erstellungszeit und nicht zur Laufzeit erfolgen muss , da für meine bereitgestellte ausführbare Datei das Git-Repo nicht verfügbar ist.
Eine verwandte Frage zu C ++ finden Sie hier .
EDIT
Pro @ mattanja Verlangen Ich poste das git Haken Skript , das ich in meinen Projekten verwenden. Die Einrichtung:
- Die Hooks sind Linux-Shell-Skripte, die unter: path_to_project \ .git \ hooks abgelegt werden
- Wenn Sie msysgit verwenden , enthält der Hooks- Ordner bereits einige Beispielskripte. Entfernen Sie die Erweiterung '.sample' aus dem Skriptnamen, damit git sie aufruft.
- Die Namen der Hook-Skripte stimmen mit dem Ereignis überein, das sie aufruft. In meinem Fall habe ich Post-Commit und Post-Merge geändert .
- Meine AssemblyInfo.cs- Datei befindet sich direkt unter dem Projektpfad (dieselbe Ebene wie der .git- Ordner). Es enthält 23 Zeilen und ich benutze git, um die 24. zu generieren.
Da mein Linux-Shelling etwas verrostet ist, liest das Skript einfach die ersten 23 Zeilen von AssemblyInfo.cs in eine temporäre Datei, gibt den Git-Hash in die letzte Zeile zurück und benennt die Datei wieder in AssemblyInfo.cs um . Ich bin sicher, es gibt bessere Möglichkeiten, dies zu tun:
#!/bin/sh
cmt=$(git rev-list --max-count=1 HEAD)
head -23 AssemblyInfo.cs > AssemblyInfo.cs.tmp
echo [assembly: AssemblyFileVersion\(\"$cmt\"\)] >> AssemblyInfo.cs.tmp
mv AssemblyInfo.cs.tmp AssemblyInfo.cs
Hoffe das hilft.
git rev-parse HEAD
Das würde dir den Hash bringen, aber ich bin kein C # -Entwickler, also weiß ich nicht, wie du es erreichen kannst.Antworten:
Wir verwenden Tags in Git, um Versionen zu verfolgen.
Sie können die Version mit Hash von git erhalten über:
Unser Erstellungsprozess fügt den Git-Hash in das AssemblyInformationalVersion-Attribut der AssemblyInfo.cs-Datei ein:
Nach dem Kompilieren können Sie die Version im Windows Explorer anzeigen:
Sie können es auch programmgesteuert über Folgendes abrufen:
Dabei ist YOURTYPE ein beliebiger Typ in der Assembly, der das Attribut AssemblyInformationalVersion hat.
quelle
GlobalAssemblyInfo.*
Dateien zur Kompilierungszeit für C # - und C ++ - Projekte: Standardmäßig enthält die generierte Assemblyversion: den Commit-Hash, ein Flag, das lokale Änderungen signalisiert, und einen Inkrementieren der Anzahl der Festschreibungen vom Repository-Stamm bis zur aktuellen Festschreibung.Sie können eine version.txt- Datei in die ausführbare Datei einbetten und dann die version.txt aus der ausführbaren Datei lesen . Verwenden Sie zum Erstellen der Datei version.txt
git describe --long
Hier sind die Schritte:
Verwenden Sie ein Build-Ereignis, um git aufzurufen
Klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie Eigenschaften
Fügen Sie unter Build-Ereignisse ein Pre-Build-Ereignis hinzu, das Folgendes enthält (beachten Sie die Anführungszeichen):
"C: \ Programme \ Git \ bin \ git.exe" beschreiben --long> "$ (ProjectDir) \ version.txt"
Dadurch wird eine version.txt- Datei in Ihrem Projektverzeichnis erstellt.
Betten Sie die version.txt in die ausführbare Datei ein
Lesen Sie die Versionszeichenfolge der eingebetteten Textdatei
Hier ist ein Beispielcode zum Lesen der Versionszeichenfolge für eingebettete Textdateien:
quelle
git describe --dirty
, was ein Flag hinzufügt, wenn Entwickler mit einem schmutzigen Arbeitsbaum arbeiten.git describe --always
, um Tags zu verwenden oder auf einen abgekürzten Hash zurückzugreifenAKTUALISIEREN:
Die Dinge haben sich weiterentwickelt, seit ich diese Frage ursprünglich beantwortet habe. Das
Microsoft.NET.Sdk
(dh Sie müssen ein Projekt im SDK-Stil verwenden) unterstützt jetzt das Hinzufügen des Commit-Hashs sowohl zur Assembly-Informationsversion als auch zu den Metadaten des Nuget-Pakets, wenn einige Bedingungen erfüllt sind:<SourceRevisionId>
Eigenschaft muss definiert werden. Dies kann durch Hinzufügen eines Ziels wie folgt erfolgen:Dieses Ziel führt einen Befehl aus,
SourceRevisionId
der als abgekürzter (8 Zeichen) Hash festgelegt wird. Die BeforeTargets bewirken, dass dies ausgeführt wird, bevor die Assembly-Informationsversion erstellt wird.Um den Hash in die Metadaten des Nuget-Pakets aufzunehmen,
<RepositoryUrl>
muss auch der Hash definiert werden.<SourceControlInformationFeatureSupported>
Eigenschaft muss seintrue
, dies bewirkt, dass die Nuget-Pack-Task auch die SourceRevisionId aufnimmt.Ich würde Leute davon abhalten, das MSBuildGitHash-Paket zu verwenden, da diese neue Technik sauberer und beständiger ist.
ORIGINAL:
Ich habe ein einfaches Nuget-Paket erstellt, das Sie in Ihr Projekt aufnehmen können und das dies für Sie erledigt: https://www.nuget.org/packages/MSBuildGitHash/
Dieses Nuget-Paket implementiert eine "reine" MSBuild-Lösung. Wenn Sie sich nicht auf ein Nuget-Paket verlassen möchten, können Sie diese Ziele einfach in Ihre csproj-Datei kopieren. Der Git-Hash sollte als benutzerdefiniertes Assembly-Attribut enthalten sein:
Hier gibt es zwei Ziele. Der erste, "GetGitHash", lädt den Git-Hash in eine MSBuild-Eigenschaft namens BuildHash. Dies geschieht nur, wenn BuildHash noch nicht definiert ist. Auf diese Weise können Sie es in der Befehlszeile an MSBuild übergeben, wenn Sie dies bevorzugen. Sie können es wie folgt an MSBuild weitergeben:
MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL
Das zweite Ziel, "WriteGitHash", schreibt den Hashwert in eine Datei im temporären Ordner "obj" mit dem Namen "CustomAssemblyInfo.cs". Diese Datei enthält eine Zeile, die wie folgt aussieht:
[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]
Diese CustomAssemblyInfo.cs-Datei wird in Ihre Assembly kompiliert, sodass Sie mithilfe der Reflektion nach der
AssemblyMetadata
Laufzeit suchen können . Der folgende Code zeigt, wie dies durchgeführt werden kann, wenn dieAssemblyInfo
Klasse in derselben Assembly enthalten ist.Einige Vorteile dieses Designs sind, dass es keine Dateien in Ihrem Projektordner berührt. Alle mutierten Dateien befinden sich im Ordner "obj". Ihr Projekt wird auch in Visual Studio oder über die Befehlszeile identisch erstellt. Es kann auch einfach an Ihr Projekt angepasst werden und wird zusammen mit Ihrer csproj-Datei quellgesteuert.
quelle
Assembly.GetExecutingAssembly()
und dann die Baugruppe untersuchenCustomAttributes
.GitHash
? Ich kann sehen, dass dieser Wert existiert, aber gibt es eine reine Methode, um ein benutzerdefiniertes Attribut nach Namen zu erhalten? Es scheint, dass ich lange Where-Select-Abfragen schreiben mussCustomAttributes
, danke.CustomAttributes
. Hier ist zum Beispiel die Funktion, mit der ich die Hash-Zeichenfolge extrahiere: pastebin.com/nVKGLhJCEine andere Möglichkeit, dies zu tun, besteht darin, das NetRevisionTool mit etwas On-Board Visual Studio-Magie zu verwenden. Ich werde dies hier für Visual Studio 2013 Professional Edition vorstellen, aber dies wird auch mit anderen Versionen funktionieren.
Laden Sie also zuerst das NetRevisionTool herunter. Sie fügen die Datei NetRevisionTool.exe in Ihren PATH ein oder checken sie in Ihr Repository ein, erstellen eine Visual Studio-Vor- und eine Nacherstellungsaktion und ändern Ihre AssemblyInfo.cs.
Ein Beispiel, das Ihren Git-Hash zu Ihrer AssemblyInformationVersion hinzufügen würde, wäre das Folgende: In Ihren Projekteinstellungen:
In den AssemblyInfo.cs Ihres Projekts ändern / fügen Sie die folgende Zeile hinzu:
[Assembly: AssemblyInformationalVersion ("1.1. {dmin: 2015}. {chash: 6} {!} - {branch}")]
Im gezeigten Screenshot habe ich in NetRevisionTool.exe im Ordner External / bin nachgesehen
Wenn Sie nach dem Erstellen mit der rechten Maustaste auf Ihre Binärdatei klicken und zu den Eigenschaften wechseln, sollte Folgendes angezeigt werden:
Hoffe das hilft jemandem da draußen
quelle
Ich denke, diese Frage ist es wert, Schritt für Schritt vollständig beantwortet zu werden. Die Strategie hierfür besteht darin, ein Powershell-Skript aus den Pre-Build-Ereignissen auszuführen, das eine Vorlagendatei aufnimmt und eine AssemblyInfo.cs-Datei mit den enthaltenen Informationen zum Git-Tag + Commit-Anzahl generiert.
Schritt 1: Erstellen Sie eine AssemblyInfo_template.cs-Datei im Ordner Project \ Properties, basierend auf Ihrer ursprünglichen AssemblyInfo.cs-Datei, die jedoch Folgendes enthält:
Schritt 2: Erstellen Sie ein Powershell-Skript mit dem Namen InjectGitVersion.ps1, dessen Quelle lautet:
Schritt 3: Speichern Sie die Datei InjectGitVersion.ps1 in Ihrem Lösungsverzeichnis in einem BuildScripts-Ordner
Schritt 4: Fügen Sie den Pre-Build-Ereignissen des Projekts die folgende Zeile hinzu
Schritt 5: Erstellen Sie Ihr Projekt.
Schritt 6: Fügen Sie optional AssemblyInfo.cs zu Ihrer Git-Ignorierdatei hinzu
quelle
AssemblyInfo.cs
zu verwenden, könnte man sieAssemblyInfo.cs
an Ort und Stelle ändern , erstellen und dannAssemblyInfo.cs
auf die zuletzt festgeschriebene Version zurücksetzen. Im Repo würde es also immer gebenAssemblyInfo.cs
, wobei$..$
nur die Bauzeit ersetzt wird.git describe --match "v[0-9]*" --long --always --dirty
nach bestimmten Tags gefiltert (die eine Versionsnummer enthalten) und angegeben, ob der Arbeitsbaum sauber war.$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
Da in der anderen Antwort bereits das Git-Bit erwähnt wird, können Sie nach dem SHA die
AssemblyInfo.cs
Datei Ihres Projekts in einem Pre-Build-Hook generieren .Eine Möglichkeit, dies zu tun, besteht darin, eine
AssemblyInfo.cs.tmpl
Vorlagendatei mit einem Platzhalter für Ihre SHA in beispielsweise $$ GITSHA $$ zu erstellen, zIhr Pre-Build-Hook muss dann diesen Platzhalter ersetzen und die AssemblyInfo.cs-Datei ausgeben, damit der C # -Compiler sie abrufen kann.
In dieser Antwort erfahren Sie, wie dies mit SubWCRev für SVN möglich ist . Es sollte nicht schwer sein, etwas Ähnliches für Git zu tun.
Andere Möglichkeiten wären eine "Make Stage", wie erwähnt, dh das Schreiben einer MSBuild-Aufgabe, die etwas Ähnliches tut. Eine weitere Möglichkeit besteht darin, die DLL irgendwie nachzubearbeiten (z. B. ildasm + ilasm), aber ich denke, die oben genannten Optionen sind wahrscheinlich am einfachsten.
quelle
Mit .NET Revision Task für MSBuild und der Arbeit mit Visual Studio 2019 ist dies jetzt sehr einfach .
Installieren Sie einfach das NuGet- Paket Unclassified.NetRevisionTask und konfigurieren Sie die gewünschten Informationen in der
AssemblyInfo.cs
Datei wie in der GitHub-Dokumentation beschrieben .Wenn Sie nur den Hash des letzten Commits (Länge = 8) möchten:
Erstellen Sie Ihr Projekt / Ihre Lösung und Sie haben ungefähr Folgendes:
quelle
PropertyGroup
zur .csproj- Datei hinzu, wie in der README-Datei github.com/ygoe/NetRevisionTask/blob/master/README.mdFür eine vollautomatische und flexible Methode checken Sie https://github.com/Fody/Stamp . Wir haben dies erfolgreich für unsere Git-Projekte verwendet (sowie diese Version für SVN-Projekte).
Update: Dies ist veraltet, da Stamp.Fody nicht mehr gepflegt wird
quelle
Sie können einen Powershell-Einzeiler verwenden, um alle Assemblyinfo-Dateien mit dem Commit-Hash zu aktualisieren.
quelle
Wie von @ learath2 angegeben, erhalten Sie bei der Ausgabe von
git rev-parse HEAD
einen einfachen Hash.Wenn Sie Tags im Git-Repository verwenden (und Tags verwenden, ist dies nicht aussagekräftiger und lesbarer als
git rev-parse
), kann die Ausgabe von empfangen werdengit describe
(während sie später auch erfolgreich verwendet wirdgit checkout
).Sie können rev-parse | description aufrufen in:
quelle
Ich verwende eine Kombination aus der akzeptierten Antwort und einer kleinen Ergänzung. Ich habe die AutoT4-Erweiterung installiert ( https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4 ), um die Vorlagen vor dem Erstellen erneut auszuführen.
Version von GIT bekommen
Ich habe
git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt"
in meinem Pre-Build-Event Projekteigenschaften. Das Hinzufügen von git_version.txt und VersionInfo.cs zu .gitignore ist eine gute Idee.Einbettung der Version in Metadaten
Ich habe
VersionInfo.tt
meinem Projekt eine Vorlage hinzugefügt :Jetzt habe ich mein Git-Tag + Hash in "ProductVersion".
quelle
Unter Bezugnahme auf die andere Antwort ( https://stackoverflow.com/a/44278482/4537127 ) habe ich auch die
VersionInfo.tt
Textvorlage verwendet, umAssemblyInformationalVersion
ohne AutoT4 zu generieren .(Mindestens funktioniert in meiner C # WPF-Anwendung)
Das Problem war, dass die Pre-Build-Ereignisse nach Vorlagentransformationen ausgeführt wurden. Nach dem Klonen war die
git_version.txt
Datei nicht vorhanden und der Build schlägt fehl. Nachdem es manuell erstellt wurde, damit die Transformation einmal bestanden werden kann, wurde es nach der Transformation aktualisiert und war immer ein Commit dahinter .Ich musste zwei Anpassungen an der .csproj-Datei vornehmen (dies gilt zumindest für Visual Studio Community 2017).
1) Importieren Sie die Texttransformationsziele und führen Sie Vorlagentransformationen durch, die bei jedem Build ausgeführt werden sollen: (Siehe https://msdn.microsoft.com/en-us/library/ee847423.aspx )
und danach
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
2)
git describe
Führen Sie den Lauf vor den Template-Transformationen durch (damit er vorhandengit_version.txt
ist, wenn erVersionInfo.tt
transformiert wird):..Und den C # -Code, um den zu erhalten
AssemblyInformationalVersion
(Ref https://stackoverflow.com/a/7770189/4537127 )..Und fügen Sie die generierten Dateien zu .gitignore hinzu
quelle
Eine andere Möglichkeit wäre, eine Version.cs-Datei aus einem Pre-Build-Schritt zu generieren. Ich habe dies in einem kleinen Proof-of-Concept-Projekt untersucht, in dem der aktuelle Commit-Hash ausgedruckt wird.
Das Projekt wird auf https://github.com/sashoalm/GitCommitHashPrinter hochgeladen .
Der Stapelcode, der die Datei Version.cs erstellt, lautet wie folgt:
quelle
Platz
im
YOUR_PROJECT_NAME.csproj
quelle