Git pull después de una actualización forzada
Simplemente aplasté algunas confirmaciones git rebase
e hice una git push --force
(lo cual es malo, lo sé).
Ahora los otros ingenieros de software tienen una historia diferente y cuando hagan un git pull
, Git se fusionará. ¿Hay alguna forma de solucionar este problema, excepto hacer un rm my-repo; git clone [email protected]:my-repo.git
?
Necesito algo parecido a lo contrario git push --force
, pero git pull --force
no me dio los resultados esperados.
Para recibir los nuevos commits
git fetch
Reiniciar
Puede restablecer la confirmación de una sucursal local usando git reset
.
Para cambiar el compromiso de una sucursal local:
git reset origin/main --hard
Sin embargo, tenga cuidado, como dice la documentación:
Restablece el índice y el árbol de trabajo. Cualquier cambio en los archivos rastreados en el árbol de trabajo desde <commit> se descarta.
Si realmente desea conservar los cambios que tenga localmente, reinicie --soft
. Lo que actualizará el historial de confirmaciones de la rama, pero no cambiará ningún archivo en el directorio de trabajo (y luego podrá confirmarlos).
Rebase
Puede reproducir sus confirmaciones locales además de cualquier otra confirmación/rama usando git rebase
:
git rebase -i origin/main
Esto invocará el rebase en modo interactivo donde puede elegir cómo aplicar cada confirmación individual que no esté en el historial sobre el que está rebase.
Si las confirmaciones que eliminó (con git push -f
) ya se incluyeron en el historial local, se enumerarán como confirmaciones que se volverán a aplicar; deberán eliminarse como parte de la rebase o simplemente se volverán a incluir en el historial. para la sucursal y reaparecerá en el historial remoto en el siguiente impulso.
Utilice la ayuda git command --help
para obtener más detalles y ejemplos sobre cualquiera de los comandos anteriores (u otros).
Tirar con rebase
Una extracción normal es buscar + fusionar, pero lo que quieres es buscar + rebase. Esta es una opción con el pull
comando:
git pull --rebase
En su caso particular, se eliminaron las confirmaciones que no desea que se vuelvan a aplicar. Esto debe hacerse manualmente. Por lo tanto, la rebase debe ser interactiva para que se puedan omitir estas confirmaciones:
git pull --rebase=interactive
o a partir de Git 2.26 se puede acortar a:
git pull --rebase=i
Esto no solucionará las ramas que ya tienen el código que no desea (consulte a continuación cómo hacerlo), pero si han extraído alguna rama y ahora quieren que esté limpia (y no "por delante" de origen/alguna rama) entonces simplemente:
git checkout some-branch # where some-branch can be replaced by any other branch
git branch base-branch -D # where base-branch is the one with the squashed commits
git checkout -b base-branch origin/base-branch # recreating branch with correct commits
Nota: Puedes combinarlos todos poniendo && entre ellos
Nota 2: Florian mencionó esto en un comentario, pero ¿quién lee los comentarios cuando busca respuestas?
Nota 3: Si tiene ramas contaminadas, puede crear otras nuevas basadas en la nueva "rama tonta" y simplemente seleccionar las confirmaciones.
Ex:
git checkout feature-old # some branch with the extra commits
git log # gives commits (write down the id of the ones you want)
git checkout base-branch # after you have already cleaned your local copy of it as above
git checkout -b feature-new # make a new branch for your feature
git cherry-pick asdfasd # where asdfasd is one of the commit ids you want
# repeat previous step for each commit id
git branch feature-old -D # delete the old branch
¡Ahora la característica nueva es tu rama sin las confirmaciones adicionales (posiblemente malas)!
Para recuperar cambios del repositorio remoto a su repositorio local:
git fetch --all
Cambie el nombre de la rama de seguimiento:
git branch -m <old-branch-name> <new-name>
Cree una nueva sucursal local que rastree la sucursal remota:
git checkout <old-branch-name>
TLDR:
git switch master
git pull
git branch -D featureBranch // careful! FORCE DELETE
git switch featureBranch
Entonces, en su caso, las sucursales ya tienen un seguimiento local. Asegúrese de que el maestro esté retirado. En master git pull
es suficiente actualizar todas sus ramas, incluida su rama de funciones. Puedes echar un vistazo git branch -vv
para ver la sucursal donde git push --force
sucedió, verás algo como...ahead 2, behind 7...
Ahora, git branch -D featureBranch
force la eliminación de su rama de funciones local.
Último paso: git switch featureBranch
, que verifica localmente nuevamente la rama de función extraída anteriormente y la configura para rastrear la rama remota.