Was Sie im Folgenden erwartet
gisten:
Warum sollte jemand diesen langen Beitrag lesen wollen? Denn während die vorherigen Antworten das Problem das Problem mit der ursprünglichen Frage verstehen, sie nicht zu korrekten/aussagekräftigen Ergebnissen führen; oder eine genaue Lösung verschiedene Problem.
Sie können auch nur den ersten Abschnitt lesen; er löst das Problem des "etwas finden" und sollte den Umfang des Problems hervorheben. Für manche mag das ausreichend sein.
Dies zeigt Ihnen einen Weg, wie Sie korrekte und aussagekräftige Ergebnisse aus Git zu extrahieren zu extrahieren (die Sie vielleicht nicht mögen), und demonstriert einen Weg, um Ihr Wissen über Ihre Konventionen auf diese Ergebnisse anzuwenden um das zu erhalten, wonach Sie wirklich suchen.
Die folgenden Abschnitte behandeln:
- Eine unvoreingenommene Frage & Lösung :
- die nächsten Git-Zweige mit
git show-branch
.
- wie die erwarteten Ergebnisse aussehen sollten
- Beispielgrafik & Ergebnisse
- Dosierung von Filialen : Arbeit um die Grenzen von
git show-branch
- Eine voreingenommene Frage & Lösung : Einführung von (Benennungs-)Konventionen zur Verbesserung der Ergebnisse
Das Problem mit der Frage
Wie bereits erwähnt, verfolgt Git keine Beziehungen zwischen Zweigen; Zweige sind einfach Namen, die auf einen Commit verweisen. In der offiziellen Git-Dokumentation und anderen Quellen finden wir oft etwas irreführende Diagramme wie z. B.:
A---B---C---D <- master branch
\
E---F <- work branch
Ändern wir die Form des Diagramms und die hierarchisch anmutenden Namen, um ein entsprechendes Schaubild zu erstellen:
E---F <- jack
/
A---B
\
C---D <- jill
Der Graph (und damit auch Git) sagt uns absolut nichts darüber, welcher Zweig zuerst erstellt wurde (und damit, welcher Zweig vom anderen abgezweigt wurde).
Das master
ist ein Elternteil von work
in der ersten Grafik ist eine Frage der Konvention.
Deshalb
- einfache Werkzeuge werden Antworten produzieren, die die Verzerrung ignorieren
- Bei komplexeren Werkzeugen werden Konventionen (Vorurteile) berücksichtigt.
Eine unvoreingenommene Frage
Zunächst muss ich vor allem die Antwort von Joe Chrysler, andere Antworten hier und die vielen Kommentare/Vorschläge rundherum würdigen; Sie haben mich inspiriert und mir den Weg gewiesen!
Erlauben Sie mir, Joes Formulierung neu zu formulieren und dabei mehrere Zweige zu berücksichtigen, die mit dem nächsten Commit verbunden sind (das kommt vor!):
"Welches ist der nächste Commit, der sich auf einem anderen Zweig als dem aktuellen Zweig befindet, und welcher Zweig ist das?"
Oder mit anderen Worten:
Q1
Angesichts einer Verzweigung B
: die Übergabe berücksichtigen C
am nächsten bei B'HEAD
( C
sein könnte B'HEAD
) die auch von anderen Branchen genutzt wird: Welche Zweige, außer B
haben C
in ihrer Commit-Historie?
Eine unvoreingenommene Lösung
Ich entschuldige mich im Voraus; es scheint, dass die Leute Einzeiler bevorzugen. Sie können gerne (lesbare/wartbare) Verbesserungen vorschlagen!
#!/usr/local/bin/bash
# git show-branch supports 29 branches; reserve 1 for current branch
GIT_SHOW_BRANCH_MAX=28
CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
if (( $? != 0 )); then
echo "Failed to determine git branch; is this a git repo?" >&2
exit 1
fi
##
# Given Params:
# EXCEPT : $1
# VALUES : $2..N
#
# Return all values except EXCEPT, in order.
#
function valuesExcept() {
local except=$1 ; shift
for value in "$@"; do
if [[ "$value" != "$except" ]]; then
echo $value
fi
done
}
##
# Given Params:
# BASE_BRANCH : $1 : base branch; default is current branch
# BRANCHES : [ $2 .. $N ] : list of unique branch names (no duplicates);
# perhaps possible parents.
# Default is all branches except base branch.
#
# For the most recent commit in the commit history for BASE_BRANCH that is
# also in the commit history of at least one branch in BRANCHES: output all
# BRANCHES that share that commit in their commit history.
#
function nearestCommonBranches() {
local BASE_BRANCH
if [[ -z "${1+x}" || "$1" == '.' ]]; then
BASE_BRANCH="$CURRENT_BRANCH"
else
BASE_BRANCH="$1"
fi
shift
local -a CANDIDATES
if [[ -z "${1+x}" ]]; then
CANDIDATES=( $(git rev-parse --symbolic --branches) )
else
CANDIDATES=("$@")
fi
local BRANCHES=( $(valuesExcept "$BASE_BRANCH" "${CANDIDATES[@]}") )
local BRANCH_COUNT=${#BRANCHES[@]}
if (( $BRANCH_COUNT > $GIT_SHOW_BRANCH_MAX )); then
echo "Too many branches: limit $GIT_SHOW_BRANCH_MAX" >&2
exit 1
fi
local MAP=( $(git show-branch --topo-order "${BRANCHES[@]}" "$BASE_BRANCH" \
| tail -n +$(($BRANCH_COUNT+3)) \
| sed "s/ \[.*$//" \
| sed "s/ /_/g" \
| sed "s/*/+/g" \
| egrep '^_*[^_].*[^_]$' \
| head -n1 \
| sed 's/\(.\)/\1\n/g'
) )
for idx in "${!BRANCHES[@]}"; do
## to include "merge", symbolized by '-', use
## ALT: if [[ "${MAP[$idx]}" != "_" ]]
if [[ "${MAP[$idx]}" == "+" ]]; then
echo "${BRANCHES[$idx]}"
fi
done
}
# Usage: gitr [ baseBranch [branchToConsider]* ]
# baseBranch: '.' (no quotes needed) corresponds to default current branch
# branchToConsider* : list of unique branch names (no duplicates);
# perhaps possible (bias?) parents.
# Default is all branches except base branch.
nearestCommonBranches "${@}"
Wie es funktioniert
Unter Berücksichtigung der Ausgabe von: git show-branch
Für git show-branch --topo-order feature/g hotfix master release/2 release/3 feature/d
würde die Ausgabe etwa so aussehen:
! [feature/g] TEAM-12345: create X
* [hotfix] TEAM-12345: create G
! [master] TEAM-12345: create E
! [release/2] TEAM-12345: create C
! [release/3] TEAM-12345: create C
! [feature/d] TEAM-12345: create S
------
+ [feature/g] TEAM-12345: create X
+ [feature/g^] TEAM-12345: create W
+ [feature/d] TEAM-12345: create S
+ [feature/d^] TEAM-12345: create R
+ [feature/d~2] TEAM-12345: create Q
...
+ [master] TEAM-12345: create E
* [hotfix] TEAM-12345: create G
* [hotfix^] TEAM-12345: create F
*+ [master^] TEAM-12345: create D
+*+++ [release/2] TEAM-12345: create C
+*++++ [feature/d~8] TEAM-12345: create B
Ein paar Punkte:
- der ursprüngliche Befehl führte N (6) Verzweigungsnamen in der Befehlszeile auf
- diese Zweignamen erscheinen in der Reihenfolge der ersten N Zeilen der Ausgabe
- die Zeilen nach dem Header stellen Commits dar
- die ersten N Spalten der Commit-Zeilen stellen (als Ganzes) ein " Verzweigungs-/Befehlsmatrix ", wobei ein einzelnes Zeichen in der Spalte
X
zeigt die Beziehung (oder das Fehlen einer Beziehung) zwischen einem Zweig (Kopfzeile X
) und die aktuelle Übertragung.
Primäre Schritte
- Angesichts einer
BASE_BRANCH
- Gegeben eine geordnete Menge (eindeutig)
BRANCHES
die nicht enthalten sind BASE_BRANCH
- Der Einfachheit halber sei
N
sein BRANCH_COUNT
, das ist die Größe von BRANCHES
; Sie umfasst nicht BASE_BRANCH
git show-branch --topo-order $BRANCHES $BASE_BRANCH
:
- Seit
BRANCHES
enthält nur eindeutige Namen (die als gültig angesehen werden) die Namen werden 1-1 mit den Kopfzeilen der Ausgabe übereinstimmen, und entsprechen den ersten N Spalten der Branch/Commit-Matrix.
- Seit
BASE_BRANCH
ist nicht in BRANCHES
wird die letzte der Kopfzeilen sein, und entspricht der letzten Spalte der Branch/Commit-Matrix.
tail
: Beginn mit Zeile N+3
die erste wegwerfen N+2
Zeilen: N Zweige + Basiszweig + Trennungszeile ---..
.
sed
Diese könnten in einem zusammengefasst werden, sind aber aus Gründen der Übersichtlichkeit getrennt.
- alles nach der Branch/Commit-Matrix entfernen
- Leerzeichen durch Unterstriche '_' ersetzen; mein Hauptgrund war, potenzielle Probleme bei der IFS-Analyse zu vermeiden und für die Fehlersuche/Lesbarkeit.
- ersetzen.
*
avec +
Die Basisverzweigung steht immer in der letzten Spalte, und das ist ausreichend. Außerdem, wenn man es allein lässt, geht es durch bash
Erweiterung des Pfadnamens, und das macht immer Spaß mit *
egrep
: grep für Commits, die mindestens einem Branch zugeordnet sind ( [^_]
) UND zur BASE_BRANCH ( [^_]$
). Vielleicht sollte das Grundmuster der Verzweigung lauten \+$
?
head -n1
: Nehmen Sie die erste verbleibende Übertragung
sed
: Trennen Sie jedes Zeichen der Verzweigungs-/Bindungsmatrix in separaten Zeilen.
- Erfassen der Zeilen in einem Array
MAP
dann haben wir zwei Arrays:
BRANCHES
: Länge N
MAP
: Länge N+1
: zuerst N
Elemente 1-1 mit BRANCHES
, und das letzte Element, das dem BASE_BRANCH
.
- Iterieren über
BRANCHES
(das ist alles, was wir wollen, und es ist kürzer) und prüfen Sie das entsprechende Element in MAP
: Ausgang BRANCH[$idx]
si MAP[$idx]
ist +
.
Beispielgrafik & Ergebnisse
Betrachten Sie das folgende, etwas konstruierte Beispieldiagramm:
- Es werden voreingenommene Namen verwendet, da sie (mir) helfen, die Ergebnisse abzuwägen und zu berücksichtigen.
- Gehen Sie davon aus, dass Zusammenführungen existieren und ignoriert werden.
-
Die Grafik versucht im Allgemeinen, Verzweigungen als solche hervorzuheben (Gabelung), ohne visuell eine Präferenz/Hierarchie zu suggerieren; ironischerweise master
fällt auf, nachdem ich mit dieser Sache fertig war.
J <- feature/b
/
H
/ \
/ I <- feature/a
/
D---E <- master
/ \
/ F---G <- hotfix
/
A---B---C <- feature/f, release/2, release/3
\ \
\ W--X <- feature/g
\
\ M <- support/1
\ /
K---L <- release/4
\
\ T---U---V <- feature/e
\ /
N---O
\
P <- feature/c
\
Q---R---S <- feature/d
Unverzerrte Ergebnisse für die Beispielgrafik
Angenommen, das Skript ist eine ausführbare Datei gitr
und dann ausführen:
gitr <baseBranch>
Für verschiedene Branchen B
erhalten wir die folgenden Ergebnisse:
GESCHENKT B
Gemeinsames Commit C
Zweige !B mit C in ihrer Geschichte?
Merkmal/a
H
Merkmal/b
Merkmal/b
H
Merkmal/a
Merkmal/c
P
Merkmal/d
Merkmal/d
P
Merkmal/c
feature/e
O
Merkmal/c, Merkmal/d
Merkmal/f
C
Merkmal/a, Merkmal/b, Merkmal/g, Hotfix, Master, Release/2, Release/3
Merkmal/g
C
Merkmal/a, Merkmal/b, Merkmal/f, Hotfix, Master, Release/2, Release/3
Hotfix
D
Merkmal/a, Merkmal/b, Master
Meister
D
Merkmal/a, Merkmal/b, Hotfix
Freigabe/2
C
Merkmal/a, Merkmal/b, Merkmal/f, Merkmal/g, Hotfix, Master, Release/3
Freigabe/3
C
Merkmal/a, Merkmal/b, Merkmal/f, Merkmal/g, Hotfix, Master, Release/2
Freigabe/4
L
Merkmal/c, Merkmal/d, Merkmal/e, Unterstützung/1
Unterstützung/1
L
Merkmal/c, Merkmal/d, Merkmal/e, Release/4
Dosierung von Filialen
[Zu diesem Zeitpunkt vorgelegt weil es zu diesem Zeitpunkt am besten in das endgültige Drehbuch passt. Dieser Abschnitt ist nicht obligatorisch, Sie können ihn einfach überspringen. ]
git show-branch
beschränkt sich auf 29 Zweige. Das mag für manche ein Hindernis sein (kein Urteil, ich sage es nur!).
In manchen Situationen können wir die Ergebnisse verbessern, indem wir Zweige in Stapeln gruppieren.
- BASE_BRANCH muss bei jeder Verzweigung angegeben werden.
- Wenn es eine große Anzahl von Zweigen in einem Repo gibt kann dies für sich genommen von begrenztem Wert sein.
- Es kann mehr Nutzen bringen, wenn Sie andere Wege finden um die Verzweigungen zu begrenzen (die gestapelt werden würden).
- Der vorherige Punkt trifft auf meinen Anwendungsfall zu, also laden Sie vor!
Dieser Mechanismus ist NICHT perfekt, wenn sich die Ergebnisgröße dem Maximum (29) nähert, ist mit einem Fehlschlag zu rechnen. Details unten
Batch-Lösung
#
# Remove/comment-out the function call at the end of script,
# and append this to the end.
##
##
# Given:
# BASE_BRANCH : $1 : first param on every batch
# BRANCHES : [ $2 .. $N ] : list of unique branch names (no duplicates);
# perhaps possible parents
# Default is all branches except base branch.
#
# Output all BRANCHES that share that commit in their commit history.
#
function repeatBatchingUntilStableResults() {
local BASE_BRANCH="$1"
shift
local -a CANDIDATES
if [[ -z "${1+x}" ]]; then
CANDIDATES=( $(git rev-parse --symbolic --branches) )
else
CANDIDATES=("$@")
fi
local BRANCHES=( $(valuesExcept "$BASE_BRANCH" "${CANDIDATES[@]}") )
local SIZE=$GIT_SHOW_BRANCH_MAX
local COUNT=${#BRANCHES[@]}
local LAST_COUNT=$(( $COUNT + 1 ))
local NOT_DONE=1
while (( $NOT_DONE && $COUNT < $LAST_COUNT )); do
NOT_DONE=$(( $SIZE < $COUNT ))
LAST_COUNT=$COUNT
local -a BRANCHES_TO_BATCH=( "${BRANCHES[@]}" )
local -a AGGREGATE=()
while (( ${#BRANCHES_TO_BATCH[@]} > 0 )); do
local -a BATCH=( "${BRANCHES_TO_BATCH[@]:0:$SIZE}" )
AGGREGATE+=( $(nearestCommonBranches "$BASE_BRANCH" "${BATCH[@]}") )
BRANCHES_TO_BATCH=( "${BRANCHES_TO_BATCH[@]:$SIZE}" )
done
BRANCHES=( "${AGGREGATE[@]}" )
COUNT=${#BRANCHES[@]}
done
if (( ${#BRANCHES[@]} > $SIZE )); then
echo "Unable to reduce candidate branches below MAX for git-show-branch" >&2
echo " Base Branch : $BASE_BRANCH" >&2
echo " MAX Branches: $SIZE" >&2
echo " Candidates : ${BRANCHES[@]}" >&2
exit 1
fi
echo "${BRANCHES[@]}"
}
repeatBatchingUntilStableResults "$@"
exit 0
Wie es funktioniert
Wiederholen Sie den Vorgang, bis sich die Ergebnisse stabilisieren.
- Pause
BRANCHES
in Partien von GIT_SHOW_BRANCH_MAX
(alias SIZE
) Elemente
- aufrufen
nearestCommonBranches BASE_BRANCH BATCH
- Aggregieren der Ergebnisse zu einer neuen (kleineren?) Gruppe von Zweigen
Wie sie scheitern kann
Übersteigt die Anzahl der aggregierten Zweige die max. SIZE
und eine weitere Dosierung/Verarbeitung kann diese Zahl nicht verringern dann entweder:
- die aggregierten Zweige sind die Lösung, aber das kann nicht überprüft werden durch
git show-branch
, oder
- jede Charge wird nicht kleiner; möglicherweise würde eine Verzweigung von einem Stapel helfen, einen anderen zu reduzieren (diff merge base); der derzeitige Algo gibt sich geschlagen und versagt.
Alternative in Betracht ziehen
Einzelnes Paaren eines Basiszweigs mit jedem anderen Zweig von Interesse, Bestimmung eines Commit-Knotens (Merge-Basis) für jedes Paar; Sortieren der Menge der Merge-Basen in der Reihenfolge der Commit-Historie, Auswahl des nächstgelegenen Knotens, Bestimmung aller mit diesem Knoten verbundenen Zweige.
Ich sage das aus einer Position der Rückschau. Es ist wahrscheinlich wirklich der richtige Weg. Ich gehe vorwärts; vielleicht gibt es einen Wert außerhalb des aktuellen Themas.
Eine voreingenommene Frage
Sie haben vielleicht bemerkt, dass die Kernfunktion nearestCommonBranches
in dem früheren Skript beantwortet mehr als die Frage Q1 stellt. Vielmehr beantwortet die Funktion eine allgemeinere Frage:
Q2
Angesichts einer Verzweigung B
und eine geordnete Menge (keine Duplikate) P
von Zweigen ( B
nicht in P
): die Übergabe berücksichtigen C
am nächsten bei B'HEAD
( C
sein könnte B'HEAD
) die von Zweigen in P
: Welche Zweige in P haben C in ihrer Commit-Historie, in der Reihenfolge von P?
Auswahl von P
eine Voreingenommenheit vermittelt oder eine (begrenzte) Konvention beschreibt. Um alle Merkmale Ihrer Voreingenommenheit/Konvention zu erfassen, sind möglicherweise zusätzliche Hilfsmittel erforderlich, was den Rahmen dieser Diskussion sprengen würde.
Modellierung einfacher Verzerrungen/Konventionen
Voreingenommenheit ist je nach Organisation und Praxis unterschiedlich, und das Folgende ist möglicherweise nicht für Ihre Organisation geeignet. Vielleicht helfen Ihnen aber einige der hier vorgestellten Ideen Ihnen helfen, eine Lösung für Ihre Bedürfnisse zu finden.
Eine voreingenommene Lösung; Voreingenommenheit durch die Namenskonvention der Branche
Vielleicht kann die Voreingenommenheit in die Namenskonvention eingeordnet und aus ihr extrahiert werden, der verwendeten Benennungskonvention.
Voreingenommenheit durch P
(Diese anderen Branchenbezeichnungen)
Das brauchen wir für den nächsten Schritt, also sehen wir uns an, was wir tun können, indem wir die Namen der Verzweigungen mit regex filtern.
Die Kombination aus dem früheren und dem neuen Code ist verfügbar als gist: gitr
#
# Remove/comment-out the function call at the end of script,
# and append this to the end.
##
##
# Given Params:
# BASE_BRANCH : $1 : base branch
# REGEXs : $2 [ .. $N ] : regex(s)
#
# Output:
# - git branches matching at least one of the regex params
# - base branch is excluded from result
# - order: branches matching the Nth regex will appear before
# branches matching the (N+1)th regex.
# - no duplicates in output
#
function expandUniqGitBranches() {
local -A BSET[$1]=1
shift
local ALL_BRANCHES=$(git rev-parse --symbolic --branches)
for regex in "$@"; do
for branch in $ALL_BRANCHES; do
## RE: -z ${BSET[$branch]+x ... ; presumes ENV 'x' is not defined
if [[ $branch =~ $regex && -z "${BSET[$branch]+x}" ]]; then
echo "$branch"
BSET[$branch]=1
fi
done
done
}
##
# Params:
# BASE_BRANCH: $1 : "." equates to the current branch;
# REGEXS : $2..N : regex(es) corresponding to other to include
#
function findBranchesSharingFirstCommonCommit() {
if [[ -z "$1" ]]; then
echo "Usage: findBranchesSharingFirstCommonCommit ( . | baseBranch ) [ regex [ ... ] ]" >&2
exit 1
fi
local BASE_BRANCH
if [[ -z "${1+x}" || "$1" == '.' ]]; then
BASE_BRANCH="$CURRENT_BRANCH"
else
BASE_BRANCH="$1"
fi
shift
local REGEXS
if [[ -z "$1" ]]; then
REGEXS=(".*")
else
REGEXS=("$@")
fi
local BRANCHES=( $(expandUniqGitBranches "$BASE_BRANCH" "${REGEXS[@]}") )
## nearestCommonBranches can also be used here, if batching not used.
repeatBatchingUntilStableResults "$BASE_BRANCH" "${BRANCHES[@]}"
}
findBranchesSharingFirstCommonCommit "$@"
Verzerrte Ergebnisse für das Beispieldiagramm
Betrachten wir die geordnete Menge
P = { ^release/.*$ ^support/.*$ ^master$ }
Angenommen, das Skript (alle Teile) befindet sich in einer ausführbaren Datei gitr
und dann ausführen:
gitr <baseBranch> '^release/.*$' '^support/.*$' '^master$'
Für verschiedene Branchen B
erhalten wir die folgenden Ergebnisse:
GESCHENKT B
Gemeinsames Commit C
Zweige P mit C in ihrer Geschichte (in Reihenfolge)
Merkmal/a
D
Meister
Merkmal/b
D
Meister
Merkmal/c
L
Freigabe/4, Unterstützung/1
Merkmal/d
L
Freigabe/4, Unterstützung/1
feature/e
L
Freigabe/4, Unterstützung/1
Merkmal/f
C
Freigabe/2, Freigabe/3, Master
Merkmal/g
C
Freigabe/2, Freigabe/3, Master
Hotfix
D
Meister
Meister
C
Freigabe/2, Freigabe/3
Freigabe/2
C
Freigabe/3, Master
Freigabe/3
C
Freigabe/2, Master
Freigabe/4
L
Unterstützung/1
Unterstützung/1
L
Freigabe/4
Das kommt einer endgültigen Antwort schon näher; die Antworten für die Versionszweige sind nicht ideal. Lassen Sie uns noch einen Schritt weiter gehen.
Voreingenommenheit durch BASE_NAME
et P
Eine Richtung, in die dies gehen könnte, wäre die Verwendung verschiedener P
für verschiedene Basisnamen. Lassen Sie uns einen Entwurf dafür ausarbeiten.
Konventionen
DISCLAIMER: Ein Git-Flow-Purist bin ich nicht, macht bitte Nachsicht mit mir
- Ein Unterstützungszweig soll vom Master abzweigen.
- Es wird KEINE zwei Support-Zweige geben, die eine gemeinsame Commit haben.
- Ein Hotfix-Zweig muss von einem Support- oder Master-Zweig abzweigen.
- Ein Versionszweig muss von einem Support- oder Masterzweig abzweigen.
- Es kann mehrere Versionszweige geben, die sich einen gemeinsamen Commit teilen; d.h. zur gleichen Zeit von Master abgezweigt.
- Ein Bugfix-Zweig soll von einem Release-Zweig abzweigen.
- Ein Feature-Zweig kann von einem Feature, Release, Support oder Master abzweigen:
- im Sinne von "übergeordnet", kann ein Merkmalszweig nicht festgelegt werden als als übergeordnetes Merkmal über einen anderen festgelegt werden (siehe die anfängliche Diskussion).
- daher: Feature-Zweige überspringen und suchen Sie nach "Eltern" in den Release-, Support- und/oder Master-Zweigen.
- jeder andere Zweigname, der als Arbeitszweig betrachtet wird, mit den gleichen Konventionen wie ein Funktionszweig.
Mal sehen, wie weit wir git
damit:
Base Branch Pattern
Übergeordnete Zweige, geordnet
Kommentar(e)
^master$
k.A.
kein Elternteil
^support/.*$
^master$
^hotfix/.*$
^support/.*$ ^master$
einen Support-Zweig gegenüber dem Master-Zweig bevorzugen (Reihenfolge)
^Freigabe/.*$
^support/.*$ ^master$
einen Support-Zweig gegenüber dem Master-Zweig bevorzugen (Reihenfolge)
^bugfix/.*$
^Freigabe/.*$
^feature/.*$
^release/.*$ ^support/.*$ ^master$
^.*$
^release/.*$ ^support/.*$ ^master$
Redundant, aber Designbelange getrennt halten
Drehbuch
Die Kombination aus dem früheren und dem neuen Code ist verfügbar als gist: gitp
#
# Remove/comment-out the function call at the end of script,
# and append this to the end.
##
# bash associative arrays maintain key/entry order.
# So, use two maps, values correlated by index:
declare -a MAP_BASE_BRANCH_REGEX=( "^master$" \
"^support/.*$" \
"^hotfix/.*$" \
"^release/.*$" \
"^bugfix/.*$" \
"^feature/.*$" \
"^.*$" )
declare -a MAP_BRANCHES_REGEXS=("" \
"^master$" \
"^support/.*$ ^master$" \
"^support/.*$ ^master$" \
"^release/.*$" \
"^release/.*$ ^support/.*$ ^master$" \
"^release/.*$ ^support/.*$ ^master$" )
function findBranchesByBaseBranch() {
local BASE_BRANCH
if [[ -z "${1+x}" || "$1" == '.' ]]; then
BASE_BRANCH="$CURRENT_BRANCH"
else
BASE_BRANCH="$1"
fi
for idx in "${!MAP_BASE_BRANCH_REGEX[@]}"; do
local BASE_BRANCH_REGEX=${MAP_BASE_BRANCH_REGEX[$idx]}
if [[ "$BASE_BRANCH" =~ $BASE_BRANCH_REGEX ]]; then
local BRANCHES_REGEXS=( ${MAP_BRANCHES_REGEXS[$idx]} )
if (( ${#BRANCHES_REGEXS[@]} > 0 )); then
findBranchesSharingFirstCommonCommit $BASE_BRANCH "${BRANCHES_REGEXS[@]}"
fi
break
fi
done
}
findBranchesByBaseBranch "$1"
Verzerrte Ergebnisse für das Beispieldiagramm
Angenommen, das Skript (alle Teile) befindet sich in einer ausführbaren Datei gitr
und dann ausführen:
gitr <baseBranch>
Für verschiedene Branchen B
erhalten wir die folgenden Ergebnisse:
GESCHENKT B
Gemeinsames Commit C
Zweige P mit C in ihrer Geschichte (in Reihenfolge)
Merkmal/a
D
Meister
Merkmal/b
D
Meister
Merkmal/c
L
Freigabe/4, Unterstützung/1
Merkmal/d
L
Freigabe/4, Unterstützung/1
feature/e
L
Freigabe/4, Unterstützung/1
Merkmal/f
C
Freigabe/2, Freigabe/3, Master
Merkmal/g
C
Freigabe/2, Freigabe/3, Master
Hotfix
D
Meister
Meister
(leer, kein Wert)
Freigabe/2
C
Meister
Freigabe/3
C
Meister
Freigabe/4
L
Unterstützung/1
Unterstützung/1
L
Meister
Refactor for the Win!
Möglichkeiten!
In diesem letzten Beispiel hat der Release-Zweig eine gemeinsame Übergabe mit mehreren anderen Zweigen: Release-, Support- oder Master-Zweig.
Wir sollten die verwendeten Konventionen "überarbeiten" oder neu bewerten und sie ein wenig straffen.
Bedenken Sie dies git
Verwendungskonvention:
Wenn Sie einen neuen Versionszweig erstellen: Erstellen Sie sofort einen neuen Commit; aktualisieren Sie vielleicht eine Version oder die README-Datei. Dies stellt sicher, dass Feature/Arbeitszweige für die Version (die von der Version abgezweigt sind) den Commit mit dem Versionszweig gemeinsam haben vor dem Commit für den zugrundeliegenden Support- oder Master-Branc liegt (und nicht mit diesem geteilt wird). Support- oder Master-Zweig.
Zum Beispiel:
G---H <- feature/z
/
E <- release/1
/
A---B---C---D <- master
\
F <- release/2
Ein Feature, das von Release/1 abzweigt, kann keinen gemeinsamen Commit haben haben, das release/1 (seine Eltern) und master oder release/2 umfasst.
Damit steht für jede Verzweigung ein Ergebnis, das übergeordnete Ergebnis, zur Verfügung, mit diesen Konventionen.
FERTIG! Mit Tools und Konventionen kann ich in einer OCD-freundlichen, strukturierten Git-Welt leben.
Ihre Erfahrungen können variieren!
Abschiedsgedanken
- gists
-
Vor allem: Ich bin zu dem Schluss gekommen, dass, über das hinaus, was hier dargelegt wurde, irgendwann akzeptieren muss, dass es möglicherweise mehrere Zweigen zu tun haben.
- Vielleicht könnten alle potenziellen Zweige validiert werden; Regeln wie "mindestens einer" oder "alle" oder ?? könnten angewendet werden.
- Es sind Wochen wie diese, in denen ich denke, dass es wirklich an der Zeit ist, Python zu lernen.