Estoy tratando de tomar una rama con cambios y hacer que vuelva a ser idéntica a la corriente arriba de la que divergió. Los cambios son locales y se han enviado a github, por lo que ninguno git reset
o git rebase
son realmente viables, ya que cambian el historial, lo cual es malo con una rama que ya se ha introducido.
También probé git merge
con varias estrategias, pero ninguna de ellas deshace los cambios locales, es decir, si hubiera agregado un archivo, una combinación podría traer otros archivos de nuevo a la línea, pero todavía tendré ese archivo que el upstream no tener.
Podría simplemente crear una nueva rama fuera del flujo ascendente, pero realmente me gustaría una fusión que, en términos de historial de revisión, aplique todos los cambios para tomar mi rama y hacerla idéntica al flujo ascendente nuevamente, para poder impulsar ese cambio de manera segura sin una historia aplastante. ¿Existe tal comando o serie de comandos?
fuente
Respuestas:
Puede fusionar su rama ascendente a su
dev
rama, con un controlador de fusión personalizado "keepTheirs" :consulte " "
git merge -s theirs
"necesario, pero sé que no existe ".En su caso, solo
.gitattributes
se requeriría uno y unkeepTheirs
script como:git merge --strategy=theirs
Simulación # 1Se muestra como una combinación, con upstream como primer padre.
Jefromi menciona (en los comentarios) el
merge -s ours
, fusionando su trabajo en el flujo ascendente (o en una rama temporal comenzando desde el flujo ascendente), y luego adelantando su rama al resultado de esa fusión:(Editar 2011):
Este flujo de trabajo ha sido informado en esta publicación de blog por el OP :
git merge --strategy=theirs
Simulación # 2Se muestra como una fusión, con el nuestro como primer padre.
(propuesto por jcwenger )
git merge --strategy=theirs
Simulación # 3Esta publicación de blog menciona :
git merge --strategy=theirs
Simulación # 4(misma publicación de blog)
git merge --strategy=theirs
Simulación # 5(propuesto por Barak A. Pearlmutter ):
git merge --strategy=theirs
Simulación # 6(propuesto por el mismo Michael Gebetsroither ):
git merge --strategy=theirs
Simulación # 7fuente
git checkout upstream; git merge -s ours downstream; git checkout downstream; git merge upstream
. (Utilice una rama temporal en sentido ascendente si es necesario). Esto tiene la ventaja de registrar el antecesor ascendente como el primer padre, de modo que la combinación significa "absorber esta rama de tema desactualizada" en lugar de "destruir esta rama de tema y reemplazarla con aguas arriba ".Me parece que solo necesitas hacer:
Si no hay ningún cambio para impulsar en sentido ascendente, y simplemente desea que la rama ascendente sea su rama actual, esto lo hará. No es perjudicial hacer esto localmente, pero perderá todos los cambios locales ** que no se hayan enviado a master.
** En realidad, los cambios aún existen si los ha realizado localmente, ya que las confirmaciones seguirán estando en su
git reflog
, generalmente durante al menos 30 días.fuente
Puede hacer esto con bastante facilidad ahora:
Esto sincroniza su repositorio local con el origen y conserva el historial.
fuente
git merge -s recursive -Xtheirs
no fusiona automáticamente archivos binarios, por lo que termina en una situación de conflicto que debe resolver manualmente. Los flujos de trabajo basados engit merge -s ours
no sufren de esto.git show
en un compromiso de fusión solo muestra resoluciones de conflictos, y no hay resoluciones de conflictos si-Xtheirs
se utilizan, obviamente.Otra simulación para
git merge -s theirs ref-to-be-merged
:Una alternativa al doble reinicio sería aplicar el parche inverso:
fuente
HEAD^2
) El método de parche funcionó.^
correctamente. A veces, otras pulsaciones de teclas como "ctrl-c" se muestran como "^ C". - Si realmente escribiste el "^" correcto, encontraste un error grave en tu versión de git.git reset --hard HEAD^^2; git reset --soft HEAD@{1}
También hay una forma con poca ayuda del comando de plomería: en mi humilde opinión, la más sencilla. Supongamos que desea emular "el suyo" para el caso de 2 ramas:
Esto fusiona un número arbitrario de cabezas (2 en el ejemplo anterior) usando el árbol de una de ellas (la barra en el ejemplo anterior, proporcionando el árbol 'suyo'), sin tener en cuenta cualquier problema de diferencias / archivo (el árbol de confirmación es un comando de bajo nivel, por lo que no le importan esos). Tenga en cuenta que la cabeza puede ser solo 1 (por lo que equivale a seleccionar "el suyo").
Tenga en cuenta que el encabezado principal que se especifica primero puede influir en algunas cosas (consulte, por ejemplo, el comando --first-parent of git-log), así que téngalo en cuenta.
En lugar de git-show, se puede usar cualquier otra cosa capaz de generar un árbol y confirmar hashes, cualquiera que esté acostumbrado a analizar (cat-file, rev-list, ...). Puede seguir todo con git commit --amend para embellecer interactivamente el mensaje de confirmación.
fuente
Mano dura, pero demonios, ¿qué puede salir mal?
cp -r .git /tmp
git checkout y
rm -rf .git && cp -r /tmp/.git
.fuente
cambie a la rama ascendente remota y realice una
git merge
con la estrategia de fusión establecida enours
.Todo el historial seguirá estando presente, pero tendrá una confirmación de fusión adicional. Lo importante aquí es comenzar desde la versión en la que desea estar y fusionarse
ours
con la rama en la que se encuentra realmente github.fuente
--strategy=theirs
, excepto que el más cercano--strategy=recursive -X=theirs
no hace eso.--strategy=theirs
es todo lo contrario de--strategy=ours
. Comienzas desde el extremo opuesto (así que comienza desde github y fusiona de la otra manera).--strategy=theirs
, que es el problema. Lo más cercano es--strategy=recursive -X theirs
cuál no es todo lo contrario, ya que no eliminará los cambios locales extraños si no entran en conflicto.git checkout dev; git merge origin/master --strategy=ours
ygit checkout origin/master; git merge dev --strategy=ours
ours
estrategia hace que sea completamente posible hacer unatheirs
estrategia.¡Usa git reset HACIA ATRÁS!
Puede hacer que una rama se parezca a cualquier otra confirmación con
git reset
, pero tiene que hacerlo de forma indirecta.Para hacer que una rama en la confirmación
<old>
parezca una confirmación<new>
, puede hacerpara hacer
<new>
el contenido del árbol de trabajo.Entonces hazlo
para cambiar la rama de nuevo a la confirmación original pero dejando el árbol de trabajo en el
<new>
estado .Luego, puede agregar y confirmar los cambios, para que su rama coincida exactamente con el contenido de la
<new>
confirmación.Es contrario a la intuición que para pasar del
<old>
estado al<new>
que necesita hacer ungit reset
desde<new>
hasta<old>
. Sin embargo, con la opción,--mixed
el árbol de trabajo se deja en<new>
y el puntero de rama se establece en<old>
, de modo que cuando se confirman los cambios, la rama se ve como queremos.Advertencia
No pierdas de vista tus confirmaciones, por ejemplo, olvídate de lo que
<old>
está haciendogit reset --hard <new>
.fuente
Seguí esos roles:
Obteniendo el origen, reinicio duro desde la rama, luego recursivo desde el suyo y luego forzado empujar a la rama
BAJO SU PROPIO RIESGO
fuente