¿Cómo seleccionar solo cambios en ciertos archivos?
Si quiero fusionar en una rama de Git los cambios realizados solo en algunos de los archivos modificados en una confirmación particular que incluye cambios en varios archivos, ¿cómo se puede lograr esto?
Supongamos que la confirmación de Git llamada stuff
tiene cambios en los archivos A
,,, y, pero solo quiero fusionar los cambios en los archivos y . Suena como un trabajo, pero solo sabe cómo fusionar confirmaciones completas, no un subconjunto de los archivos.B
C
D
stuff
A
B
git cherry-pick
cherry-pick
Lo haría con cherry-pick -n
( --no-commit
), que te permite inspeccionar (y modificar) el resultado antes de confirmar:
git cherry-pick -n <commit>
# unstage modifications you don't want to keep, and remove the
# modifications from the work tree as well.
# this does work recursively!
git checkout HEAD <path>
# commit; the message will have been stored for you by cherry-pick
git commit
Si la gran mayoría de las modificaciones son cosas que no desea, en lugar de verificar rutas individuales (el paso intermedio), puede restablecer todo y luego agregar lo que desee:
# unstage everything
git reset HEAD
# stage the modifications you do want
git add <path>
# make the work tree match the index
# (do this from the top level of the repo)
git checkout .
Los otros métodos no funcionaron para mí ya que la confirmación tuvo muchos cambios y conflictos con muchos otros archivos. Lo que se me ocurrió fue simplemente
git show SHA -- file1.txt file2.txt | git apply -
En realidad, no guarda add
los archivos ni realiza una confirmación por usted, por lo que es posible que deba realizar un seguimiento con
git add file1.txt file2.txt
git commit -c SHA
O si desea omitir el complemento, puede usar el --cached
argumento paragit apply
git show SHA -- file1.txt file2.txt | git apply --cached -
También puedes hacer lo mismo con directorios completos.
git show SHA -- dir1 dir2 | git apply -
Normalmente uso la -p
bandera con un git checkout de la otra rama, lo cual me parece más fácil y granular que la mayoría de los otros métodos que he encontrado.
En principio:
git checkout <other_branch_name> <files/to/grab in/list/separated/by/spaces> -p
ejemplo:
git checkout mybranch config/important.yml app/models/important.rb -p
Luego aparece un cuadro de diálogo que le pregunta qué cambios desea en los "blobs". Esto prácticamente funciona para cada fragmento de cambio continuo de código que luego puede indicar y
(Sí), n
(No), etc., para cada fragmento de código.
La opción -p
o patch
funciona para una variedad de comandos en git, incluido git stash save -p
el que le permite elegir lo que desea guardar de su trabajo actual.
A veces uso esta técnica cuando he trabajado mucho y me gustaría separarlo y comprometerme en más confirmaciones basadas en temas usando git add -p
y eligiendo lo que quiero para cada confirmación :)
La situación:
Estás en tu rama, digamos, master
y tienes tu compromiso en cualquier otra rama. Tienes que elegir sólo un archivo de esa confirmación en particular.
El enfoque:
Paso 1: Realizar el pago en la sucursal requerida.
git checkout master
Paso 2: asegúrese de haber copiado el hash de confirmación requerido.
git checkout commit_hash path\to\file
Paso 3: Ahora tienes los cambios del archivo requerido en la rama deseada. Sólo necesitas agregarlos y confirmarlos.
git add path\to\file
git commit -m "Your commit message"
Quizás la ventaja de este método sobre la respuesta de Jefromi es que no es necesario recordar qué comportamiento de git reset es el correcto :)
# Create a branch to throw away, on which we'll do the cherry-pick:
git checkout -b to-discard
# Do the cherry-pick:
git cherry-pick stuff
# Switch back to the branch you were previously on:
git checkout -
# Update the working tree and the index with the versions of A and B
# from the to-discard branch:
git checkout to-discard -- A B
# Commit those changes:
git commit -m "Cherry-picked changes to A and B from [stuff]"
# Delete the temporary branch:
git branch -D to-discard