Reglas de juego
- Use la
~
mayor parte del tiempo: para retroceder varias generaciones, generalmente lo que desea
- Usar
^
en confirmaciones de combinación, porque tienen dos o más padres (inmediatos)
Mnemotécnica:
- Tilde
~
es casi lineal en apariencia y quiere ir hacia atrás en línea recta.
- Caret
^
sugiere un segmento interesante de un árbol o una bifurcación en el camino
Tilde
La sección "Especificación de revisiones" de la git rev-parse
documentación define ~
como
<rev>~<n>
, Por ejemplomaster~3
un sufijo ~<n>
a un parámetro de revisión significa que el objeto que es el commit n º antepasado generación del llamado cometer objeto, después de sólo la primera padres. Por ejemplo, <rev>~3
es equivalente a lo <rev>^^^
que es equivalente a <rev>^1^1^1
...
Puede llegar a los padres de cualquier compromiso, no solo HEAD
. También puede retroceder de generación en generación: por ejemplo, master~2
significa el abuelo de la punta de la rama maestra, favoreciendo al primer padre en los compromisos de fusión.
Signo de intercalación
El historial de Git es no lineal: un gráfico acíclico dirigido (DAG) o un árbol. Para un compromiso con un solo padre, rev~
y rev^
significa lo mismo. El selector de intercalación se vuelve útil con los compromisos de fusión porque cada uno es hijo de dos o más padres, y daña el lenguaje tomado de la biología.
HEAD^
significa el primer padre inmediato de la punta de la rama actual. HEAD^
es la abreviatura de HEAD^1
, y también puede abordar, HEAD^2
etc., según corresponda. La misma sección de la git rev-parse
documentación lo define como
<rev>^
, por ejemplo HEAD^
,v1.5.1^0
un sufijo ^
para un parámetro de revisión significa el primer padre de ese objeto de confirmación. ^<n>
significa que el n º padre ([ por ejemplo ] <rev>^
es equivalente a <rev>^1
). Como regla especial, <rev>^0
significa el compromiso en sí y se usa cuando <rev>
es el nombre del objeto de una etiqueta que se refiere a un objeto de compromiso.
Ejemplos
Estos especificadores o selectores se pueden encadenar arbitrariamente, por ejemplo , topic~3^2
en inglés es el segundo padre de la confirmación de fusión que es el bisabuelo (tres generaciones atrás) de la punta actual de la rama topic
.
La sección de la git rev-parse
documentación mencionada anteriormente traza muchos caminos a través de una historia git nocional. El tiempo fluye generalmente hacia abajo. Los commits D, F, B y A son commits de fusión.
Aquí hay una ilustración, de Jon Loeliger. Ambos nodos de confirmación B y C son padres del nodo de confirmación A. Las confirmaciones principales se ordenan de izquierda a derecha.
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
Ejecute el siguiente código para crear un repositorio git cuyo historial coincida con la ilustración citada.
#! /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'";
Se agrega alias de la nueva operación de usar y tirar sólo por git lol
ygit lola
para que puedas ver la historia como en
$ 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
Tenga en cuenta que en su máquina los nombres de los objetos SHA-1 diferirán de los anteriores, pero las etiquetas le permiten abordar las confirmaciones por nombre y verificar su comprensión.
$ 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
La sección "Especificación de revisiones" en la git rev-parse
documentación está llena de gran información y merece una lectura en profundidad. Vea también Herramientas Git - Selección de revisión del libro Pro Git .
Orden de los padres se comprometen
El commit 89e4fcb0dd del propio historial de git es un commit de fusión, como se git show 89e4fcb0dd
indica con la línea de encabezado Merge que muestra los nombres de objeto de los antepasados inmediatos.
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 […]
Podemos confirmar el pedido pidiendo git rev-parse
que se muestren en secuencia los padres inmediatos de 89e4fcb0dd.
$ git rev-parse 89e4fcb0dd^1 89e4fcb0dd^2 89e4fcb0dd^3
c670b1f876521c9f7cd40184bf7ed05aad843433
649bf3a42f344e71b1b5a7f562576f911a1f7423
b67d40adbbaf4f5c4898001bf062a9fd67e43368
Consultar al cuarto padre inexistente da como resultado un error.
$ 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>...]'
Si solo desea extraer los padres, use un formato bonito %P
para los hashes completos
$ git log -1 --pretty=%P 89e4fcb0dd
c670b1f876521c9f7cd40184bf7ed05aad843433 649bf3a42f344e71b1b5a7f562576f911a1f7423 b67d40adbbaf4f5c4898001bf062a9fd67e43368
o %p
para padres abreviados.
$ git log -1 --pretty=%p 89e4fcb0dd
c670b1f876 649bf3a42f b67d40adbb