Git rebase-commit select en modo fork-point
github version-control (1)
Tienes razón en que
$fork_point
será
B3
.
Creo
que
la intención aquí es omitir
B3
como "no es su compromiso".
Creo que el diagrama que la gente de Git dibujó aquí no es tan bueno. Así es como volvería a dibujarlo y reescribirlo sin cambiarlo demasiado (aunque de todos modos probablemente volvería a escribir cada confirmación).
Comienza por clonar (o de lo contrario actualizar a) algún repositorio (
origin
) cuyo gráfico termina en commit
B3
, y crea una rama de tema y realiza algunos commit (s):
...--o---F---B3 <-- origin/master
/
G <-- topic
Con el tiempo, con
git fetch
-es y
git commit
s adicionales, su gráfico de compromiso ahora se ve así:
...--o---F---B3--B2--B1 <-- origin/master
/
G---H---I <-- topic
Pero, de repente, después de
otra
git fetch
, su propio gráfico de confirmación ahora se ve así:
o---B1'' <-- origin/foo
/
...o---F---B2''-o---o---o---B <-- origin/master
/
B3--G---H---I <-- topic
Es decir, Git ahora pensaría que commit B3 pertenece a su rama de tema, cuando de hecho,
su
trabajo comienza con commit
G
Las personas que poseen el repositorio llamado
origin
han declarado, en efecto, que cometer
B3
es terrible y debe desecharse.
(Conservaron una copia de
B2
como
B2''
en su
master
, y una de
B1
como
B1''
en su
foo
).
Si simplemente
git rebase
, copiará el commit
B3
original a la nueva copia
B3''
(al tiempo que copia
GHI
):
o---B1'' <-- origin/foo
/
...o---F---B2''-o---o---o---B <-- origin/master
/
B3''-G''--H''--I'' <-- topic
pero preferirías:
o---B1'' <-- origin/foo
/
...o---F---B2''-o---o---o---B <-- origin/master
/
G''--H''--I <-- topic
Para que
git rebase
haga esto, debe indicarle a Git que ubique commit
B3
.
Su reflog para
origin/master
tiene todos
F
,
B3
,
B2
y
B1
(debajo de al menos una entrada de reflog, incluido en este caso
origin/master@{1}
), mientras que su propio
topic
tiene
F
y
B3
, pero ni
B2
ni
B1
, también en él.
Por
--fork-point
tanto,
--fork-point
elige
B3
como el compromiso compartido más nuevo (más
--fork-point
), en lugar de
F
La oración clave / idea aquí es que los escritores del repositorio aguas arriba
pretendían descartar commit
B3
completo
.
(Cómo se supone que debe saber esto con certeza es un poco misterioso. Puede que no sea obvio que
B2''
y
B1''
son copias, si el rebase requiere, por ejemplo, descartar un archivo que nunca debería haberse cometido, y fue en
B1
, razón por la cual
B1
también se descartó. El hecho de que este archivo ahora se omita en
B2''
y
B3''
hace que no sean equivalentes a parches, por lo que obviamente no son copias).
(¡Tenga en cuenta que su propio
master
también apunta a
B3
!)
Leyendo la documentación de
git rebase
y
git merge-base
man:
Después de trabajar en la rama de tema creada con git checkout -b topic origin / master, el historial de la rama de seguimiento remoto / master puede haberse rebobinado y reconstruido, lo que lleva a un historial de esta forma:
o---B1 / ---o---o---B2--o---o---o---B (origin/master) / B3 / Derived (topic)
donde origin / master solía apuntar a commits B3, B2, B1 y ahora apunta a B, y su rama de tema se inició por encima cuando origin / master estaba en B3. Este modo utiliza el registro de origen / maestro para encontrar B3 como el punto de bifurcación, de modo que el tema pueda ser modificado en la parte superior del origen / maestro actualizado mediante:
$ fork_point=$(git merge-base --fork-point origin/master topic) $ git rebase --onto origin/master $fork_point topic
$fork_point
será (si lo entiendo correctamente) el objeto de confirmación
B3
y, por lo tanto, el tema de confirmaciones
B3..topic
se
B3..topic
en la rama de
origin/master
.
Q1
¿Por qué es útil omitir el commit
B3
?
Los commits de la rama de
topic
se construyen sobre el commit
B3
, por lo que omitirlo significaría que sus modificaciones faltarían en la historia de la rama de
origin/master
.
Rebasar el commit
B3
y
la rama
topic
conduciría a una historia más limpia, ¿no?
P2
¿Puede alguien vincular / describir brevemente casos prácticos de uso de la opción
--fork-point
en el flujo de trabajo de git?