30 Stimmen

Build-Sequenzierung bei verteilter Versionskontrolle

Im Moment verwenden wir Perforce für die Versionskontrolle. Es hat die praktische Funktion einer streng aufsteigenden Änderungsnummer, die wir verwenden können, um auf Builds zu verweisen, z. B. "Sie erhalten den Bugfix, wenn Ihr Build mindestens 44902 ist".

Ich würde gerne auf ein verteiltes System (wahrscheinlich git) umsteigen, um das Branching und die Arbeit von zu Hause aus zu erleichtern. (Beides ist mit Perforce durchaus möglich, aber der Git-Workflow hat einige Vorteile.) Obwohl die "tributary development" also verteilt wäre und sich nicht auf eine gemeinsame Revisionsreihenfolge beziehen würde, würden wir immer noch ein Master-Git-Repository unterhalten, in das alle Änderungen einfließen müssten, bevor ein Build erstellt wird.

Wie bewahrt man am besten strikt zunehmende Build-IDs? Der einfachste Weg, den ich mir vorstellen kann, ist, eine Art Post-Commit-Hook zu haben, der immer dann ausgelöst wird, wenn das Master-Repository aktualisiert wird, und der den Hash des neuen Tree-Objekts (oder Commit-Objekts? Ich bin neu in Git) in einer zentralen Datenbank registriert, die IDs vergibt. (Ich sage "Datenbank", aber ich würde es wahrscheinlich mit Git-Tags machen, und einfach nach der nächsten verfügbaren Tag-Nummer oder so etwas suchen. Die "Datenbank" wäre also eigentlich .git/refs/tags/build-id/.)

Das ist machbar, aber ich frage mich, ob es eine einfachere oder bereits implementierte oder standardisierte/"bewährte" Methode gibt, dies zu erreichen.

30voto

squadette Punkte 8069

Eine monoton ansteigende Zahl, die dem aktuellen Commit entspricht, könnte erzeugt werden mit

git log --pretty=oneline | wc -l

die eine einzelne Zahl zurückgibt. Sie können auch den aktuellen sha1 an diese Zahl anhängen, um die Eindeutigkeit zu erhöhen.

Dieser Ansatz ist besser als git describe da Sie keine Tags hinzufügen müssen und die Zusammenführung automatisch erfolgt.

Es könnte Probleme mit dem Rebasing geben, aber das Rebasing ist ohnehin ein "gefährlicher" Vorgang.

0 Stimmen

Das Problem bei diesem Ansatz ist, dass Sie die Zweige nicht unterscheiden können. Sie können den Namen des Zweigs aber auch zur Build-ID hinzufügen.

0 Stimmen

Sie erstellen bestimmte Binärdateien (wie -beta, -stable, -nightly) aus bestimmten Zweigen. Der Name des Zweigs ist also "extern" zur Build-Nummer.

28voto

Jörg W Mittag Punkte 349574

Ich schließe mich dem Vorschlag an, Folgendes zu verwenden git describe . Vorausgesetzt, Sie haben eine vernünftige Versionspolitik und machen keine verrückten Sachen mit Ihrem Repository, git describe ist immer monoton (zumindest so monoton, wie es möglich ist, wenn die Revisionshistorie ein DAG und kein Baum ist) und eindeutig.

Eine kleine Demonstration:

git init
git commit --allow-empty -m'Commit One.'
git tag -a -m'Tag One.' 1.2.3
git describe    # => 1.2.3
git commit --allow-empty -m'Commit Two.'
git describe    # => 1.2.3-1-gaac161d
git commit --allow-empty -m'Commit Three.'
git describe    # => 1.2.3-2-g462715d
git tag -a -m'Tag Two.' 2.0.0
git describe    # => 2.0.0

Die Ausgabe von git describe besteht aus den folgenden Komponenten:

  1. Das neueste Tag, das von der zu beschreibenden Übertragung aus erreichbar ist
  2. Die Anzahl der Commits zwischen dem Commit und dem Tag (falls ungleich Null)
  3. Die (abgekürzte) ID der Übertragung (wenn #2 ungleich Null ist)

Die Nummer 2 macht die Ausgabe monoton, die Nummer 3 macht sie einzigartig. #2 und #3 werden weggelassen, wenn die Übergabe ist den Tag, wodurch git describe auch für Produktionsfreigaben geeignet.

1 Stimmen

Tags behandeln keine Verzweigungen und Zusammenführungen. Der korrekte automatische Weg, um eine korrekte Sequenzierung hinzuzufügen, ist das Zählen einer Anzahl von Commits hinter dem aktuellen Commit. Dies wird in meiner Antwort unten erklärt.

8voto

joegiralt Punkte 310
    git rev-list BRANCHNAME --count

Dies ist viel weniger ressourcenintensiv als

    git log --pretty=oneline | wc -l

4voto

webmat Punkte 53996

git tag kann für Ihren Bedarf ausreichen. Wählen Sie ein Tag-Format, bei dem sich alle einig sind, dass es nicht anders geht.

Hinweis: Wenn Sie lokal markieren, wird ein git push werden die Tags auf dem Server nicht aktualisiert. verwenden git push --tags dafür.

2voto

CB Bailey Punkte 693084

Sie sollten Folgendes untersuchen git describe . Sie liefert eine eindeutige Zeichenkette, die den aktuellen Zweig (oder jede übergebene Commit-ID) in Bezug auf das letzte kommentierte Tag, die Anzahl der Commits seit diesem Tag und eine abgekürzte Commit-ID des Kopfes des Zweigs beschreibt.

Vermutlich haben Sie einen einzigen Zweig, von dem aus Sie kontrollierte Build-Releases durchführen. In diesem Fall würde ich einen frühen Commit mit einem bekannten Tag-Format markieren und dann git describe mit der Option --match verwenden, um den aktuellen HEAD relativ zu einem bekannten Tag zu beschreiben. Sie können dann das Ergebnis von git describe so verwenden, wie es ist, oder wenn Sie wirklich nur eine einzelne Zahl wollen, können Sie einen Regex verwenden, um die Zahl aus dem Tag herauszuschneiden.

Unter der Annahme, dass Sie den Zweig nie zurückspulen, wird die Anzahl der folgenden Übertragungen immer einen eindeutigen Punkt in der Geschichte des Zweigs identifizieren.

z.B. (mit bash oder ähnlich)

# make an annotated tag to an early build in the repository:
git tag -a build-origin "$some_old_commitid"

# describe the current HEAD against this tag and pull out a build number
expr "$(git describe --match build-origin)" : 'build-origin-\([0-9]*\)-g'

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X