Faustregeln
- Verwenden Sie die
~
meiste Zeit - um eine Reihe von Generationen zurück zu gehen, normalerweise was Sie wollen
- Bei
^
Zusammenführungs-Commits verwenden - weil sie zwei oder mehr (unmittelbare) Eltern haben
Mnemonik:
- Tilde sieht
~
fast linear aus und möchte in einer geraden Linie rückwärts gehen
- Caret
^
schlägt ein interessantes Segment eines Baumes oder einer Weggabelung vor
Tilde
Der Abschnitt "Festlegen von Revisionen" in der git rev-parse
Dokumentation definiert ~
als
<rev>~<n>
ZBmaster~3
ein Suffix ~<n>
an eine Revisions Parameter bedeutet , dass das Objekt , das die Commit ist n - ten Generation Vorfahr des Objekts commit benannt folgenden nur die ersten Eltern. Zum Beispiel <rev>~3
ist äquivalent zu <rev>^^^
dem äquivalent zu <rev>^1^1^1
...
Sie können Eltern von jedem Commit erreichen, nicht nur HEAD
. Sie können auch über Generationen zurückgehen: Dies master~2
bedeutet beispielsweise, dass der Großelternteil der Spitze des Hauptzweigs den ersten Elternteil bei Zusammenführungs-Commits bevorzugt.
Caret
Der Git-Verlauf ist nichtlinear: ein gerichteter azyklischer Graph (DAG) oder Baum. Für ein Commit mit nur einem Elternteil rev~
und rev^
bedeuten dasselbe. Der Caret-Selektor wird bei Merge-Commits nützlich, da jeder das Kind von zwei oder mehr Elternteilen ist - und die aus der Biologie entliehene Sprache belastet.
HEAD^
bedeutet das erste unmittelbare Elternteil der Spitze des aktuellen Zweigs. HEAD^
ist die Abkürzung für HEAD^1
, und Sie können auch adressieren HEAD^2
und so weiter nach Bedarf. Der gleiche Abschnitt der git rev-parse
Dokumentation definiert es als
<rev>^
, Zum Beispiel HEAD^
,v1.5.1^0
ein Suffix ^
an einen Revisions Parameter bedeutet die ersten übergeordnet das Objekt begehen. ^<n>
bedeutet das n- te Elternteil ([ zB ] <rev>^
entspricht <rev>^1
). In der Regel <rev>^0
bedeutet dies das Festschreiben selbst und wird verwendet, wenn <rev>
der Objektname eines Tag-Objekts auf ein Festschreibungsobjekt verweist.
Beispiele
Diese Spezifizierer oder Selektoren können beliebig verkettet werden, z. B. ist topic~3^2
in Englisch das zweite übergeordnete Element des Zusammenführungs-Commits das Urgroßelternteil (vor drei Generationen) der aktuellen Spitze des Zweigs topic
.
Der oben erwähnte Abschnitt der git rev-parse
Dokumentation zeichnet viele Pfade durch eine fiktive Git-Geschichte nach. Die Zeit fließt im Allgemeinen nach unten. Commits D, F, B und A sind Merge-Commits.
Hier ist eine Illustration von Jon Loeliger. Beide Festschreibungsknoten B und C sind Eltern des Festschreibungsknotens A. Die übergeordneten Festschreibungen sind von links nach rechts angeordnet.
G H I J
\ / \ /
D E F
\ | / \
\ | / |
\|/ |
B C
\ /
\ /
A
A = = A^0
B = A^ = A^1 = A~1
C = A^2
D = A^^ = A^1^1 = A~2
E = B^2 = A^^2
F = B^3 = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2 = B^^2 = A^^^2 = A~2^2
I = F^ = B^3^ = A^^3^
J = F^2 = B^3^2 = A^^3^2
Führen Sie den folgenden Code aus, um ein Git-Repository zu erstellen, dessen Verlauf mit der angegebenen Abbildung übereinstimmt.
#! /usr/bin/env perl
use strict;
use warnings;
use subs qw/ postorder /;
use File::Temp qw/ mkdtemp /;
my %sha1;
my %parents = (
A => [ qw/ B C / ],
B => [ qw/ D E F / ],
C => [ qw/ F / ],
D => [ qw/ G H / ],
F => [ qw/ I J / ],
);
sub postorder {
my($root,$hash) = @_;
my @parents = @{ $parents{$root} || [] };
postorder($_, $hash) for @parents;
return if $sha1{$root};
@parents = map "-p $sha1{$_}", @parents;
chomp($sha1{$root} = `git commit-tree @parents -m "$root" $hash`);
die "$0: git commit-tree failed" if $?;
system("git tag -a -m '$sha1{$root}' '$root' '$sha1{$root}'") == 0 or die "$0: git tag failed";
}
$0 =~ s!^.*/!!; # / fix Stack Overflow highlighting
my $repo = mkdtemp "repoXXXXXXXX";
chdir $repo or die "$0: chdir: $!";
system("git init") == 0 or die "$0: git init failed";
chomp(my $tree = `git write-tree`); die "$0: git write-tree failed" if $?;
postorder 'A', $tree;
system "git update-ref HEAD $sha1{A}"; die "$0: git update-ref failed" if $?;
system "git update-ref master $sha1{A}"; die "$0: git update-ref failed" if $?;
# for browsing history - http://blog.kfish.org/2010/04/git-lola.html
system "git config alias.lol 'log --graph --decorate --pretty=oneline --abbrev-commit'";
system "git config alias.lola 'log --graph --decorate --pretty=oneline --abbrev-commit --all'";
Sie fügt hinzu , Aliase in der neuen Wegwerf - Repo nur für git lol
undgit lola
schauen Sie sich die Geschichte sehen können , wie in
$ git lol
* 29392c8 (HEAD -> master, tag: A) A
|\
| * a1ef6fd (tag: C) C
| |
| \
*-. \ 8ae20e9 (tag: B) B
|\ \ \
| | |/
| | * 03160db (tag: F) F
| | |\
| | | * 9df28cb (tag: J) J
| | * 2afd329 (tag: I) I
| * a77cb1f (tag: E) E
* cd75703 (tag: D) D
|\
| * 3043d25 (tag: H) H
* 4ab0473 (tag: G) G
Beachten Sie, dass sich die SHA-1-Objektnamen auf Ihrem Computer von den oben genannten unterscheiden. Mit den Tags können Sie jedoch Commits nach Namen adressieren und Ihr Verständnis überprüfen.
$ git log -1 --format=%f $(git rev-parse A^)
B
$ git log -1 --format=%f $(git rev-parse A~^3~)
I
$ git log -1 --format=%f $(git rev-parse A^2~)
F
Die „Spezifikation von Revisionen“ in der git rev-parse
Dokumentation enthält viele nützliche Informationen und ist eine eingehende Lektüre wert. Siehe auch Git Tools - Revisionsauswahl aus dem Buch Pro Git .
Reihenfolge der übergeordneten Commits
Das Commit 89e4fcb0dd aus dem eigenen Verlauf von git ist ein Merge-Commit, wie git show 89e4fcb0dd
in der Kopfzeile Merge angegeben, in der die Objektnamen der unmittelbaren Vorfahren angezeigt werden.
commit 89e4fcb0dd01b42e82b8f27f9a575111a26844df
Merge: c670b1f876 649bf3a42f b67d40adbb
Author: Junio C Hamano <gitster@pobox.com>
Date: Mon Oct 29 10:15:31 2018 +0900
Merge branches 'bp/reset-quiet' and 'js/mingw-http-ssl' into nd/config-split […]
Wir können die Bestellung bestätigen, indem wir darum bitten git rev-parse
, die unmittelbaren Eltern von 89e4fcb0dd nacheinander anzuzeigen.
$ git rev-parse 89e4fcb0dd^1 89e4fcb0dd^2 89e4fcb0dd^3
c670b1f876521c9f7cd40184bf7ed05aad843433
649bf3a42f344e71b1b5a7f562576f911a1f7423
b67d40adbbaf4f5c4898001bf062a9fd67e43368
Das Abfragen des nicht vorhandenen vierten übergeordneten Elements führt zu einem Fehler.
$ git rev-parse 89e4fcb0dd^4
89e4fcb0dd^4
fatal: ambiguous argument '89e4fcb0dd^4': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
Wenn Sie nur die Eltern extrahieren möchten, verwenden Sie ein hübsches Format %P
für die vollständigen Hashes
$ git log -1 --pretty=%P 89e4fcb0dd
c670b1f876521c9f7cd40184bf7ed05aad843433 649bf3a42f344e71b1b5a7f562576f911a1f7423 b67d40adbbaf4f5c4898001bf062a9fd67e43368
oder %p
für abgekürzte Eltern.
$ git log -1 --pretty=%p 89e4fcb0dd
c670b1f876 649bf3a42f b67d40adbb