Git tire hasta un compromiso particular


96

Quiero hacer un git pullpero solo hasta un compromiso específico.

 A->B->C->D->E->F (Remote master HEAD)

así que suponga que mi local masterCABEZA apunta hacia B, y quiero tirar de la caja E. Qué tengo que hacer ?

Esto no implica una confirmación específica, sino una confirmación específica.



3
git fetchy git merge E.
empuje el

Actualmente estoy en B, por ejemplo, pero solo quiero sacar C, E y F. Quiero eliminar D. ¡Gracias!
Frenkey

@Frenkey puede fusionar el maestro, luego eliminar las últimas tres confirmaciones y luego seleccionar las dos últimas. También puede probar rebase -i para una fusión de git más controlada
Ninja420

¿Qué pasa si solo quiero obtener cambios de C, no incluir cambios de A y B solo C? ¿Cómo puedo hacer eso?
Vikas Chauhan

Respuestas:


113

git pullno es más que git fetchseguido de git merge. Entonces, lo que puedes hacer es

git fetch remote example_branch

git merge <commit_hash>


¿Qué se supone que es "Refer to this"?
developerbmw

@Brett se olvidó de publicar el enlace ... lo
eliminé por

@ unrealsoul007 esto fusionará solo esa confirmación específica, ¿verdad? Entonces, para tirar de B hacia E, el comando sería git merge <commit_hash C> <commit_hash D> <commit_hash E> ¿verdad?
Wim Feijen

6
@WimFeijen git merge Ese fusionará Econ todos sus antepasados Cy D(git lo sabe Ay Bno es necesario fusionarlos porque ya estaban en su rama). Si SOLO desea los cambios de Eentonces debería git cherry-pick Ehacerlo.
neXus

Gracias a todos por la respuesta, estaba buscando el mismo problema.
Akash Bisariya

21

Primero, obtenga las últimas confirmaciones del repositorio remoto. Esto no afectará a su sucursal local.

git fetch origin

Luego, consulte la rama de seguimiento remoto y haga un registro de git para ver las confirmaciones

git checkout origin/master
git log

Toma el hash de confirmación de la confirmación que deseas fusionar (o solo los primeros ~ 5 caracteres) y fusiona esa confirmación en maestro

git checkout master
git merge <commit hash>

1
Le voté en contra porque esto no funciona como se anuncia. En primer lugar, con su método "git fetch origin", obtiene todas las ramas remotas (esto debe señalarse explícitamente, especialmente para las personas que trabajan en proyectos con muchas ramas grandes). En segundo lugar, con este método "git merge <commit hash>" no fusiona su historial local con el compromiso deseado, si está de vuelta en el historial. Ejemplo: está localmente en el compromiso 100, desea obtener hasta 150, obteniendo todo (con HEAD remoto en 100).
Marcador de posición

8
@Placeholder debe leer el manual git fetchantes de escribir tales tonterías. Además de eso, debería leer la pregunta original y mi respuesta. Si sigue mi respuesta, no estará "de vuelta en la historia" como le indiqué explícitamente al usuario git checkout master. En general, no publiques cosas si no tienes claro al menos un 50% lo que haces.
developerbmw

1
En caso de que no sea obvio para nadie más, git fetch originbusca explícitamente el origen .
Daniel Farrell

2
Esto funciona perfectamente y se explica mejor que la respuesta aceptada.
walen

1
La mejor respuesta, funcionó perfectamente
Asfandyar Khan hace

13

También puede extraer la última confirmación y deshacerla hasta la confirmación que desee:

git pull origin master
git reset --hard HEAD~1

Reemplace mastercon la rama deseada.

Use git log para ver a qué confirmación le gustaría revertir:

git log

Personalmente, esto me ha funcionado mejor.

Básicamente, lo que hace es extraer la última confirmación y revertir manualmente las confirmaciones una por una. Utilice git log para ver el historial de confirmaciones.

Puntos positivos : funciona como se anuncia. No es necesario utilizar el hash de confirmación o extraer ramas innecesarias.

Puntos negativos: debe revertir las confirmaciones en una.

ADVERTENCIA: Confirme / guarde todos sus cambios locales, porque con --hardusted los perderá. ¡Úselo bajo su propio riesgo!


3
No sé por qué los votos negativos, esta parece la manera más limpia, y tan pronto como quieras ponerte al día, un simple tirón funcionará, a diferencia de algunas de las otras respuestas
Mauricio Pasquier Juan

Tampoco, por qué no más votos a favor, el único inconveniente es que debes ir al HEADantes de regresar, y no sé qué pasaría si tuvieras que resolver conflictos. Pero esta solución lo permite git pull --rebase, y al contrario de lo que se dice, puede restablecer directamente a las Nconfirmaciones anteriores con git reset --hard HEAD~N(es decir, para 3 confirmaciones git reset --hard HEAD~3).
Stock Overflaw

2

Si fusiona una confirmación en su rama, debería obtener todo el historial entre.

Observar:

$ git init ./
Repositorio Git vacío inicializado en /Users/dfarrell/git/demo/.git/
$ echo 'a'> letra
$ git añadir letra
$ git commit -m 'Letra inicial'
[master (root-commit) 6e59e76] Letra inicial
 1 archivo modificado, 1 inserción (+)
 modo de creación 100644 letra
$ echo 'b' >> letra
$ git agregar letra && git commit -m 'Agregar letra'
[master 7126e6d] Añadiendo letra
 1 archivo modificado, 1 inserción (+)
$ echo 'c' >> letra; git add letter && git commit -m 'Añadiendo letra'
[master f2458be] Añadiendo letra
 1 archivo modificado, 1 inserción (+)
$ echo 'd' >> letra; git add letter && git commit -m 'Añadiendo letra'
[master 7f77979] Añadiendo carta
 1 archivo modificado, 1 inserción (+)
$ echo 'e' >> letra; git add letter && git commit -m 'Añadiendo letra'
[master 790eade] Añadiendo letra
 1 archivo modificado, 1 inserción (+)
$ git log
cometer 790eade367b0d8ab8146596cd717c25fd895302a
Autor: Dan Farrell 
Fecha: Thu Jul 16 14:21:26 2015-0500

    Añadiendo letra

cometer 7f77979efd17f277b4be695c559c1383d2fc2f27
Autor: Dan Farrell 
Fecha: Thu Jul 16 14:21:24 2015-0500

    Añadiendo letra

cometer f2458bea7780bf09fe643095dbae95cf97357ccc
Autor: Dan Farrell 
Fecha: Thu Jul 16 14:21:19 2015-0500

    Añadiendo letra

cometer 7126e6dcb9c28ac60cb86ae40fb358350d0c5fad
Autor: Dan Farrell 
Fecha: Thu Jul 16 14:20:52 2015-0500

    Añadiendo letra

cometer 6e59e7650314112fb80097d7d3803c964b3656f0
Autor: Dan Farrell 
Fecha: Thu Jul 16 14:20:33 2015-0500

    Letra inicial
$ git checkout 6e59e7650314112fb80097d7d3803c964b3656f
$ git checkout 7126e6dcb9c28ac60cb86ae40fb358350d0c5fad
Nota: consulte '7126e6dcb9c28ac60cb86ae40fb358350d0c5fad'.

Estás en estado de 'CABEZA separada'. Puedes mirar a tu alrededor, hacer experimental
cambios y confirmarlos, y puede descartar cualquier compromiso que realice en este
Estado sin afectar a ninguna sucursal realizando otro pago

Si desea crear una nueva rama para retener las confirmaciones que crea, puede
hágalo (ahora o más tarde) usando -b con el comando checkout nuevamente. Ejemplo:

  git checkout -b new_branch_name

HEAD ahora está en 7126e6d ... Añadiendo letra
$ git checkout -b B 7126e6dcb9c28ac60cb86ae40fb358350d0c5fad
Cambiado a una nueva rama 'B'
$ git pull 790eade367b0d8ab8146596cd717c25fd895302a
fatal: '790eade367b0d8ab8146596cd717c25fd895302a' no parece ser un repositorio de git
fatal: no se pudo leer desde el repositorio remoto.

Asegúrese de tener los derechos de acceso correctos.
y el repositorio existe.
$ git fusionar 7f77979efd17f277b4be695c559c1383d2fc2f27
Actualizando 7126e6d..7f77979
Avance rápido
 carta | 2 ++
 1 archivo modificado, 2 inserciones (+)
$ carta de gato
una
segundo
C
re

1

Esto funciona para mi:

git pull origin <sha>

p.ej

[dbn src]$ git fetch
[dbn src]$ git status
On branch current_feature
Your branch and 'origin/master' have diverged,
and have 2 and 7 different commits each, respectively.
...
[dbn src]$ git log -3 --pretty=oneline origin/master
f4d10ad2a5eda447bea53fed0b421106dbecea66 CASE-ID1: some descriptive msg
28eb00a42e682e32bdc92e5753a4a9c315f62b42 CASE-ID2: I'm so good at writing commit titles
ff39e46b18a66b21bc1eed81a0974e5c7de6a3e5 CASE-ID2: woooooo
[dbn src]$ git pull origin 28eb00a42e682e32bdc92e5753a4a9c315f62b42
[dbn src]$ git status
On branch current_feature
Your branch and 'origin/master' have diverged,
and have 2 and 1 different commits each, respectively.
...

Esto extrae 28eb00, ff39e4 y todo lo anterior, pero no extrae f4d10ad. Permite el uso de pull --rebase y respeta la configuración de extracción en su gitconfig. Esto funciona porque básicamente está tratando 28eb00 como una rama.

Para la versión de git que estoy usando, este método requiere un hash de confirmación completo; no se permiten abreviaturas ni alias. Podrías hacer algo como:

[dbn src]$ git pull origin `git rev-parse origin/master^`
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.