Angenommen, ich habe das folgende lokale Repository mit einem Commit-Baum wie diesem:
master --> a
\
\
develop c --> d
\
\
feature f --> g --> h
master
ist mein dies der letzte Version Code ist , develop
ist meine dies der ‚nächste‘ Freigabecode ist , und feature
ist eine neue Funktion für vorbereitetdevelop
.
Was ich mit Hooks auf meinem Remote-Repo tun möchte, ist, dass Pushs feature
abgelehnt werden, es sei denn, Commit f
ist ein direkter Nachkomme von develop
HEAD. dh der Baum wie folgt aussieht begehen , weil Funktion wurde git rebase
auf d
.
master --> a
\
\
develop c --> d
\
\
feature f --> g --> h
So ist es möglich:
- Identifizieren Sie den übergeordneten Zweig von
feature
? - Identifizieren Sie das Commit im übergeordneten Zweig, von dem
f
ein Nachkomme stammt.
Von dort aus würde ich überprüfen, was HEAD des übergeordneten Zweigs ist, und prüfen, ob der f
Vorgänger mit dem HEAD des übergeordneten Zweigs übereinstimmt, um festzustellen, ob das Feature neu basiert werden muss.
Antworten:
Angenommen, das Remote-Repository verfügt über eine Kopie des Entwicklungszweigs (Ihre ursprüngliche Beschreibung beschreibt sie in einem lokalen Repository, es scheint jedoch auch in der Remote vorhanden zu sein), sollten Sie in der Lage sein, das zu erreichen, was ich denke, aber den Ansatz ist ein bisschen anders als Sie es sich vorgestellt haben.
Die Geschichte von Git basiert auf einer DAG von Commits. Zweige (und „Refs“ im Allgemeinen) sind nur vorübergehende Bezeichnungen, die auf bestimmte Commits in der kontinuierlich wachsenden Commit-DAG verweisen. Daher kann die Beziehung zwischen Zweigen im Laufe der Zeit variieren, die Beziehung zwischen Commits jedoch nicht.
Es sieht so aus, als ob
baz
es auf (einer alten Version von) basiertbar
? Aber was ist, wenn wir löschenbar
?Jetzt sieht es so aus, als ob
baz
es auf basiertfoo
. Aber die Abstammung vonbaz
hat sich nicht geändert, wir haben nur ein Etikett entfernt (und das daraus resultierende baumelnde Commit). Und was ist, wenn wir bei ein neues Label hinzufügen4
?Jetzt sieht es so aus, als ob
baz
es auf basiertquux
. Die Abstammung änderte sich jedoch nicht, nur die Beschriftungen änderten sich.Wenn wir jedoch fragten: "Ist Commit
6
ein Nachkomme von Commit3
?" (vorausgesetzt ,3
und6
sind voll SHA-1 Namen begehen), dann wäre die Antwort „ja“ lautet, ob diebar
undquux
Etiketten vorhanden sind oder nicht.Sie könnten also Fragen stellen wie "Ist das Push-Commit ein Nachkomme der aktuellen Spitze des Entwicklungszweigs ?", Aber Sie können nicht zuverlässig fragen: "Was ist der übergeordnete Zweig des Push-Commits?".
Eine meist verlässliche Frage, die sich Ihren Wünschen zu nähern scheint, lautet:
Welches könnte implementiert werden als:
Dies wird einige der von Ihnen gewünschten Einschränkungen abdecken, aber möglicherweise nicht alles.
Als Referenz finden Sie hier eine erweiterte Beispielhistorie:
Der obige Code kann verwendet werden , um abzulehnen
H
undS
während der AnnahmeH'
,J
,K
, oderN
, aber es wäre auch zu akzeptieren ,L
undP
(sie beinhalten verschmilzt, aber sie verschmelzen nicht mit der Spitze entwickeln ).Um auch
L
und abzulehnenP
, können Sie die Frage ändern und stellenquelle
develop > release > feature
, ich würde mich wieder entwickeln und es erfordert die Kenntnis der Eltern. Die Lösung für mein Problem war stackoverflow.com/a/56673640/2366390Eine Umformulierung
Eine andere Möglichkeit, die Frage zu formulieren, lautet: "Was ist das nächste Commit, das sich in einem anderen Zweig als dem aktuellen Zweig befindet, und welcher Zweig ist das?"
Eine Lösung
Sie können es mit ein wenig Befehlszeilenmagie finden
Mit awk :
So funktioniert das:
Und das Ergebnis
Führen Sie den obigen Code aus
Wird Ihnen geben,
develop
wenn Sie es von Hmaster
ausführen und wenn Sie es von I ausführen.Der Code ist als Kern verfügbar
quelle
cannot handle more than 25 refs
ack
auf dem Mac nicht verfügbar ist (jemand vorschlug ersetztack
mitgrep
)git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'
git show-branch | sed "s/].*//" | grep "\*" | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed "s/^.*\[//"
parent = "!git show-branch | grep '*' | grep -v \"$(git rev-parse --abbrev-ref HEAD)\" | head -n1 | sed 's/.*\\[\\(.*\\)\\].*/\\1/' | sed 's/[\\^~].*//' #"
funktioniert für michSie können auch versuchen:
quelle
git log --graph --decorate --simplify-by-decoration
wo--graph
ist optional.git log --graph --decorate --simplify-by-decoration --oneline
Git Elternteil
Sie können den Befehl einfach ausführen
git parent
Um das übergeordnete Element des Zweigs zu finden, fügen Sie die Antwort von @Joe Chrysler als Git-Alias hinzu . Dies vereinfacht die Verwendung.
Öffnen Sie die gitconfig-Datei
"~/.gitconfig"
unter mit einem beliebigen Texteditor. (Für Linux). Und für Windows befindet sich der Pfad ".gitconfig" im Allgemeinen unterc:\users\your-user\.gitconfig
Fügen Sie der Datei den folgenden Alias-Befehl hinzu:
Speichern und beenden Sie den Editor.
Führen Sie den Befehl aus
git parent
Das ist es!
quelle
cannot handle more than 25 refs
Ausnahme.Ich habe eine Lösung für Ihr Gesamtproblem (stellen Sie fest, ob
feature
es von der Spitze von abstammtdevelop
), aber es funktioniert nicht mit der von Ihnen beschriebenen Methode.Sie können verwenden,
git branch --contains
um alle Zweige aufzulisten, die von der Spitze von abstammendevelop
, und dann verwendengrep
, um sicherzustellen, dass siefeature
zu ihnen gehören.Wenn es unter ihnen ist, wird es
" feature"
auf die Standardausgabe gedruckt und hat einen Rückkehrcode von 0. Andernfalls wird nichts gedruckt und ein Rückkehrcode von 1.quelle
<branch>
, wo ich aufgetreten bin :git checkout -b <branch-2>
von ... DAS ist die Antwort! Eigentlich keine Notwendigkeit für grep.git branch --contains <branch>
Das funktioniert gut für mich.
Mit freundlicher Genehmigung von: @droidbot und @Jistanidiot
quelle
*
ist kein richtiger Regex, um an grep weiterzugeben. Sollte verwendengrep -F '*'
odergrep '\*'
stattdessen. Ansonsten gute Lösung.Da keine der oben genannten Antworten in unserem Repository funktioniert hat, möchte ich meinen eigenen Weg mit den neuesten Zusammenführungen in
git log
: teilen.Fügen Sie es in ein Skript mit dem Namen ein
git-last-merges
, das auch einen Zweignamen als Argument (anstelle des aktuellen Zweigs) sowie anderegit log
Argumente akzeptiertAnhand der Ausgabe können wir die übergeordneten Zweige manuell anhand der eigenen Verzweigungskonventionen und der Anzahl der Zusammenführungen aus jedem Zweig erkennen.
BEARBEITEN: Wenn Sie
git rebase
häufig untergeordnete Zweige verwenden (und Zusammenführungen häufig vorgespult werden, damit nicht zu viele Zusammenführungs-Commits vorhanden sind), funktioniert diese Antwort nicht gut. Daher habe ich ein Skript geschrieben, um Commits im Voraus zu zählen (normal und Zusammenführen). und hinter Commits (es sollte keine Hinterzusammenführung im übergeordneten Zweig geben) in allen Zweigen im Vergleich zum aktuellen Zweig. Führen Sie einfach dieses Skript aus und lassen Sie mich wissen, ob es für Sie funktioniert oder nichtquelle
rebase
häufig verwenden (und Zusammenführungen werdenfast-forward
häufig bearbeitet ). Ich werde meine Antwort bearbeiten, wenn ich eine bessere Lösung gefunden habe.git log --oneline --merges "$@" | grep into | sed 's/.* into //g' | uniq --count | head -n 1 | cut -d ' ' -f 8
Eine Lösung
Die auf basierend basierende
git show-branch
Lösung hat bei mir nicht ganz funktioniert (siehe unten), daher habe ich sie mit der aufgit log
und basierenden Lösung kombiniert und am Ende Folgendes erhalten :Einschränkungen und Vorsichtsmaßnahmen
log
master
unddevelop
Ergebnisse (meist) in<SHA> Initial commit
Die Ergebnisse
Trotz der Existenz einer lokalen Verzweigung (z. B. nur
origin/topic
vorhanden, da das CommitO
direkt von der SHA ausgecheckt wurde) sollte das Skript wie folgt gedruckt werden:G
,H
,I
(Zweighotfix
) →master
M
,N
,O
(Zweigfeature/a
) →develop
S
,T
,U
(Zweigfeature/c
) →develop
P
,Q
,R
(Zweigfeature/b
) →feature/a
J
,K
,L
(Zweigdevelop
) →<sha> Initial commit
*B
,D
,E
,F
(Zweigmaster
) →<sha> Initial commit
* - oder
master
wenndevelop
die Commits über dem HEAD des Masters liegen (~ der Master kann schnell weiterentwickelt werden)Warum hat Show-Branch nicht für mich gearbeitet?
Die auf basierende
git show-branch
Lösung erwies sich für mich in folgenden Situationen als unzuverlässig:grep '\*' \
durch "grep"! \ - und das ist erst der Anfang aller Problememaster
unddevelop
führt zudevelop
bzw. ``master
Zweig (hotfix/
Zweige) enden mit demdevelop
als Elternteil, da ihr nächstermaster
Zweig Elternteil mit!
anstatt aus*
einem Grund markiert wurde .quelle
"!git log --decorate --simplify-by-decoration --oneline | grep -v '(HEAD' | head -n1 | sed 's/.* (\\(.*\\)) .*/\\1/' | sed 's/\\(.*\\), .*/\\1/' | sed 's/origin\\///'"
Denken Sie daran, dass Sie, wie unter "Git: Finden, von welchem Zweig ein Commit stammt" beschrieben sind , den Zweig, in dem dieser Commit durchgeführt wurde, nicht einfach bestimmen können (Zweige können umbenannt, verschoben, gelöscht ... werden), obwohl dies
git branch --contains <commit>
ein Anfang ist.git branch --contains <commit>
derfeature
Zweig und der Zweig nicht mehrdevelop
aufgelistet sind./refs/heads/develop
Wenn die beiden Commits übereinstimmen, können Sie loslegen (dies würde bedeuten, dass der
feature
Zweig seinen Ursprung im HEAD of hatdevelop
).quelle
JoeChryslers Befehlszeilenmagie kann vereinfacht werden. Hier ist Joes Logik: Der Kürze halber habe ich in beiden Versionen einen Parameter eingeführt, der
cur_branch
anstelle der Befehlssubstitution benannt wurde`git rev-parse --abbrev-ref HEAD`
. das kann so initialisiert werden:Dann ist hier Joes Pipeline:
Wir können dasselbe wie alle fünf dieser einzelnen Befehlsfilter in einem relativ einfachen
awk
Befehl erreichen:Das bricht so zusammen:
teilen Sie die Zeile in Felder auf
]
,^
,~
und[
Zeichen.Suchen Sie nach Zeilen, die ein Sternchen enthalten
... aber nicht der aktuelle Filialname
Wenn Sie eine solche Zeile finden, drucken Sie das zweite Feld (dh den Teil zwischen dem ersten und dem zweiten Vorkommen unserer Feldtrennzeichen). Bei einfachen Zweignamen ist dies genau das, was sich in den Klammern befindet. Bei Refs mit relativen Sprüngen ist dies nur der Name ohne Modifikator. Unser Satz von Feldtrennzeichen behandelt also die Absicht beider
sed
Befehle.Dann sofort beenden. Dies bedeutet, dass immer nur die erste übereinstimmende Zeile verarbeitet wird, sodass wir die Ausgabe nicht durchleiten müssen
head -n 1
.quelle
Hier ist eine PowerShell-Implementierung der Mark Reed-Lösung:
quelle
Ich sage nicht, dass dies ein guter Weg ist, um dieses Problem zu lösen, aber dies scheint für mich zu funktionieren.
git branch --contains $(cat .git/ORIG_HEAD)
Das Problem ist, dass das Cat'ing einer Datei in das Innenleben von Git hineinschaut, sodass dies nicht unbedingt vorwärtskompatibel (oder abwärtskompatibel) ist.quelle
Plattformübergreifende Implementierung mit Ant
quelle
@ Mark Reed: Sie sollten hinzufügen, dass die Festschreibungszeile nicht nur ein Sternchen enthalten sollte, sondern mit einem Sternchen beginnen sollte! Andernfalls werden Commit-Nachrichten, die ein Sternchen enthalten, ebenfalls in die übereinstimmenden Zeilen aufgenommen. So sollte es sein:
git show-branch -a | awk -F'[]^~[]' '/^\*/ && !/'"$current_branch"'/ {print $2;exit}'
oder die lange Version:
quelle
Erreicht die gleichen Ziele wie Mark Reeds Antwort, verwendet jedoch einen viel sichereren Ansatz, der sich in einer Reihe von Szenarien nicht schlecht verhält:
-
nicht angezeigt wird*
*
quelle
Wer dies heutzutage tun möchte - Die SourceTree-Anwendung von Atlassian zeigt Ihnen eine hervorragende visuelle Darstellung der Beziehung Ihrer Filialen zueinander, dh wo sie begonnen haben und wo sie sich derzeit in der Festschreibungsreihenfolge befinden (z. B. HEAD oder 4 Festschreibungen dahinter usw.). .
quelle
Wenn Sie den Quellbaum verwenden, sehen Sie sich Ihre Festschreibungsdetails> Eltern> an. Die Festschreibungsnummern sind unterstrichen (Links).
quelle
Eine Alternative:
git rev-list master | grep "$(git rev-list HEAD)" | head -1
Holen Sie sich das letzte Commit, das sowohl mein Zweig als auch
master
(oder welcher Zweig auch immer Sie angeben möchten) ist.quelle
Dies funktionierte nicht für mich, als ich so etwas getan hatte
develop > release-v1.0.0 > feature-foo
, es würde den ganzen Weg zurückgehen, um sich zu entwickeln. Beachten Sie, dass es sich um eine Rebase handelte, nicht sicher, ob dies mein Problem verschärft ...Das Folgende hat mir den richtigen Commit-Hash gegeben
quelle