Stellen Sie sich folgende Geschichte vor:
c---e---g--- feature
/ \
-a---b---d---f---h--- master
Wie kann ich feststellen, wann Commit "c" mit Master zusammengeführt wurde (dh Merge Commit "h" finden)?
Stellen Sie sich folgende Geschichte vor:
c---e---g--- feature
/ \
-a---b---d---f---h--- master
Wie kann ich feststellen, wann Commit "c" mit Master zusammengeführt wurde (dh Merge Commit "h" finden)?
Antworten:
Ihr Beispiel zeigt, dass der Zweig featurenoch verfügbar ist.
In diesem Fall hist das letzte Ergebnis von:
git log master ^feature --ancestry-path
Wenn der Zweig featurenicht mehr verfügbar ist, können Sie die Zusammenführungs-Commits in der Verlaufszeile zwischen cund anzeigen master:
git log <SHA-1_for_c>..master --ancestry-path --merges
Dies zeigt jedoch auch alle Zusammenführungen an, die nach hund zwischen eund gan stattgefunden haben feature.
Vergleichen des Ergebnisses der folgenden Befehle:
git rev-list <SHA-1_for_c>..master --ancestry-path
git rev-list <SHA-1_for_c>..master --first-parent
gibt Ihnen die SHA-1 hals letzte gemeinsame Zeile.
Wenn Sie es zur Verfügung haben, können Sie es comm -1 -2für diese Ergebnisse verwenden. Wenn Sie mit msysgit arbeiten, können Sie den folgenden Perl-Code zum Vergleichen verwenden:
perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' file1 file2
(Perl-Code von http://www.cyberciti.biz/faq/command-to-display-lines-common-in-files/ , der von "jemandem in der Nachrichtengruppe comp.unix.shell" stammt).
Siehe Prozessersetzung, wenn Sie es zu einem Einzeiler machen möchten.
masterwurde in verschmolzen feature, dann sofort featureverschmolzen wird masterals Vorspulen (Spitze featureersetzt master). Würde dies dazu führen --first-parent, dass der falsche Elternteil zurückgegeben wird?
comm -1 -2aber es hat nicht funktioniert. commfunktioniert nur auf sortierten Zeilen. (Der Perl-Einzeiler funktioniert, obwohl ich ihn nicht lesen konnte.)
git find-merge h master(gibt nichts zurück, sollte aber h zurückgeben), git find-merge d master(gibt f zurück, sollte aber d zurückgeben), git find-merge c feature(gibt e zurück, sollte aber g zurückgeben).
Fügen Sie dies zu Ihrem hinzu ~/.gitconfig:
[alias]
find-merge = "!sh -c 'commit=$0 && branch=${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'"
show-merge = "!sh -c 'merge=$(git find-merge $0 $1) && [ -n \"$merge\" ] && git show $merge'"
Dann können Sie die Aliase wie folgt verwenden:
# current branch
git find-merge <SHA-1>
# specify master
git find-merge <SHA-1> master
Verwenden Sie, um die Nachricht des Zusammenführungs-Commits und andere Details anzuzeigen git show-merge dieselben Argumente, anzuzeigen.
(Basierend auf Gauthiers Antwort . Vielen Dank an Rosen Matev und Javabrett für die Behebung eines Problems mit sort.)
sort -k2 | uniq -f1 -d | sort -n | tail -1 | cut -f2die letzte gemeinsame Zeile nicht richtig gefunden wird. Hier ist ein Beispiel, wo es fehlschlägt.
16db9fef5c581ab0c56137d04ef08ef1bf82b0b7hier gefunden, wenn ich es auf Ihrer Paste ausführe. Wird das nicht erwartet? Auf welchem Betriebssystem bist du?
29c40c3a3b33196d4e79793bd8e503a03753bad1
git-get-merge sucht und zeigt das gesuchte Merge-Commit:
pip install git-get-merge
git get-merge <SHA-1>
Der Befehl folgt den untergeordneten Elementen des angegebenen Commits, bis eine Zusammenführung in einen anderen Zweig (vermutlich Master) gefunden wird.
Das heißt, um Gauthiers Beitrag zusammenzufassen:
perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' <(git rev-list --ancestry-path <SHA-1_for_c>..master) <(git rev-list --first-parent <SHA-1_for_c>..master) | tail -n 1
BEARBEITEN: Da hierfür die Prozessersetzung " <()" verwendet wird, ist es nicht POSIX-kompatibel und funktioniert möglicherweise nicht mit Ihrer Shell. Es funktioniert mit bashoder zshobwohl.
<()nicht POSIX-kompatibel. Sie verwenden müssen bash, zshoder ein Shell - Unterstützung Prozess Substitution . Ich habe meine Antwort entsprechend bearbeitet.
Ich musste das tun und fand es irgendwie git-when-merged(was tatsächlich auf diese SO-Frage verweist, aber Michael Haggerty hat hier nie einen Verweis auf sein sehr schönes Python-Skript hinzugefügt). Also jetzt habe ich.
Aufbauend auf Gauthiers großartiger Antwort müssen wir commdie Listen nicht vergleichen. Da wir nach dem letzten Ergebnis suchen, in --ancestry-pathdem auch enthalten ist --first-parent, können wir in der Ausgabe des ersteren einfach nach dem letzteren suchen :
git rev-list <SHA>..master --ancestry-path | grep -f <(git rev-list <SHA>..master --first-parent) | tail -1
Oder für etwas Bissiges und Wiederverwendbares, hier ist eine Funktion, in die Sie eintauchen können .bashrc:
function git-find-merge() {
git rev-list $1..master --ancestry-path | grep -f <(git rev-list $1..master --first-parent) | tail -1
}
commfunktionierte nicht, wenn die Eingaben nicht sortiert waren.
Ich benutze das folgende Bash-Skript, das ich am Pfad platziere ~/bin/git-find-merge. Es basiert auf Gauthiers Antwort und der Antwort von evilstreak mit wenigen Änderungen, um Eckfälle zu behandeln. commwird ausgelöst, wenn die Eingaben nicht sortiert sind. grep -ffunktioniert perfekt.
Eckfälle:
~/bin/git-find-merge Skript:
#!/bin/bash
commit=$1
if [ -z $commit ]; then
echo 1>&2 "fatal: commit is required"
exit 1
fi
commit=$(git rev-parse $commit)
branch=${2-@}
# if branch points to commit (both are same), then return commit
if [ $commit == $(git rev-parse $branch) ]; then
git log -1 $commit
exit
fi
# if commit is a merge commit on first-parent path of branch,
# then return commit
# if commit is a NON-merge commit on first-parent path of branch,
# then return branch as it's either a ff merge or commit is only on branch
# and there is not a good way to figure out the right commit
if [[ $(git log --first-parent --pretty='%P' $commit..$branch | \
cut -d' ' -f1 | \
grep $commit | wc -l) -eq 1 ]]; then
if [ $(git show -s --format="%P" $commit | wc -w) -gt 1 ]; then
# if commit is a merge commit
git log -1 $commit
else
# if commit is a NON-merge commit
echo 1>&2 ""
echo 1>&2 "error: returning the branch commit (ff merge or commit only on branch)"
echo 1>&2 ""
git log -1 $branch
fi
exit
fi
# 1st common commit from bottom of first-parent and ancestry-path
merge=$(grep -f \
<(git rev-list --first-parent $commit..$branch) \
<(git rev-list --ancestry-path $commit..$branch) \
| tail -1)
if [ ! -z $merge ]; then
git log -1 $merge
exit
fi
# merge commit not found
echo 1>&2 "fatal: no merge commit found"
exit 1
Was mich das machen lässt:
(master)
$ git find-merge <commit> # to find when commit merged to current branch
$ git find-merge <branch> # to find when branch merged to current branch
$ git find-merge <commit> pu # to find when commit merged to pu branch
Dieses Skript ist auch auf meinem Github verfügbar .
Meine Ruby-Version von @ robinsts Idee funktioniert zweimal schneller (was wichtig ist, wenn nach sehr alten Commits gesucht wird).
find-commit.rb
commit = ARGV[0]
master = ARGV[1] || 'origin/master'
unless commit
puts "Usage: find-commit.rb commit [master-branch]"
puts "Will show commit that merged <commit> into <master-branch>"
exit 1
end
parents = `git rev-list #{commit}..#{master} --reverse --first-parent --merges`.split("\n")
ancestry = `git rev-list #{commit}..#{master} --reverse --ancestry-path --merges`.split("\n")
merge = (parents & ancestry)[0]
if merge
system "git show #{merge}"
else
puts "#{master} doesn't include #{commit}"
exit 2
end
Sie können es einfach so verwenden:
ruby find-commit.rb SHA master
Sie können so etwas versuchen. Die Idee ist, alle Zusammenführungs-Commits zu durchlaufen und zu prüfen, ob das Commit "c" von einem von ihnen aus erreichbar ist:
$ git log --merges --format='%h' master | while read mergecommit; do
if git log --format='%h' $mergecommit|grep -q $c; then
echo $mergecommit;
break
fi
done
git rev-list <SHA-1_for_c>..master --ancestry-path --merges
Ich musste dies mehrmals tun (danke an alle, die diese Frage beantwortet haben!) Und schrieb schließlich ein Skript (nach Gauthiers Methode), das ich meiner kleinen Sammlung von Git-Dienstprogrammen hinzufügen konnte. Sie finden es hier: https://github.com/mwoehlke/git-utils/blob/master/bin/git-merge-point .