Pregunta ¿Puedo recuperar una rama después de su eliminación en Git?


Si corro git branch -d XYZ, ¿hay alguna forma de recuperar la rama? ¿Hay alguna manera de volver atrás como si no hubiera ejecutado el comando Eliminar rama?


765
2017-09-04 03:25


origen


Respuestas:


Sí, deberías poder hacer git reflog y encuentre el SHA1 para la confirmación en la punta de su rama eliminada, entonces solo git checkout [sha]. Y una vez que estás en ese compromiso, puedes simplemente git checkout -b [branchname] para recrear la rama desde allí.


1378
2017-09-04 03:43



La mayoría de las veces las confirmaciones inalcanzables están en el reflog. Asi que, lo primero que debe intentar es mirar el reflog usando el comando git reflog (que muestra el reflog para HEAD)

Quizás algo más sencillo si el commit fue parte de una rama específica que aún existe es usar el comando git reflog name-of-my-branch. Funciona también con un control remoto, por ejemplo, si forzó push.


Si sus confirmaciones no están en su reflog (tal vez porque fue eliminado por una herramienta de terceros que no escribe en el reflog), recuperé con éxito una rama al restablecer mi rama al sha de la confirmación encontrada usando un comando como ese (crea un archivo con todos los commits pendientes) )

git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt

Si debe usarlo más de una vez (o desea guardarlo en algún lugar), también puede crear un alias con ese comando ...

git config --global alias.rescue '!git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt'

y usarlo con git rescue

Para investigar confirmaciones encontradas, puede mostrar cada confirmación utilizando algunos comandos para examinarlas.

Para mostrar los metadatos de confirmación (autor, fecha de creación y mensaje de confirmación):

git cat-file -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

Para ver también las diferencias:

git log -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

Una vez que encontraste tu confirmación, crea una rama en esta confirmación con:

git branch commit_rescued 48540dfa438ad8e442b18e57a5a255c0ecad0560

98
2018-03-10 15:10



Si desea utilizar una GUI, puede realizar toda la operación con gitk.

gitk --reflog

Esto le permitirá ver el historial de confirmaciones de la sucursal como si la sucursal no se hubiera eliminado. Ahora simplemente haga clic derecho en la confirmación más reciente de la sucursal y seleccione la opción de menú Create new branch.


30
2018-06-02 14:28



La mejor solución votada en realidad es más de lo solicitado:

git checkout <sha>
git checkout -b <branch>

o

git checkout -b <branch> <sha>

moverlo a la nueva sucursal junto con todos los cambios recientes que haya olvidado realizar. Puede que esta no sea su intención, especialmente cuando se encuentra en el "modo de pánico" después de perder la rama.

UN solución más limpia (y más simple) parece ser un trazador de líneas (después de encontrar el <sha> con git reflog)

git branch <branch> <sha>

Ahora ni su rama actual ni los cambios sin compromiso se ven afectados. En su lugar, solo se creará una nueva rama hasta llegar al <sha>.

Si no es la sugerencia, funcionará y obtendrá una sucursal más corta, entonces puede volver a intentar con una nueva <sha> y un nuevo nombre de sucursal hasta que lo haga bien.

Finalmente, puede cambiar el nombre de la rama restaurada correctamente a la que se llamó o a cualquier otra cosa:

git branch -m <restored branch> <final branch>

Huelga decir que la clave del éxito fue encontrar el compromiso correcto <sha>, así que nombre sus compromisos sabiamente :)


15
2018-04-08 15:33



Añadiendo a tfe responder: también está el git-resurrect.sh script en el contrib/ área de las fuentes de Git (en el repositorio git.git), que podría ayudarte.

git-resurrect <name> intenta encontrar rastros de una sugerencia de rama   llamado <name>e intenta resucitarlo Actualmente, el reflog es   buscó mensajes de pago, y con -r también fusionar mensajes. Con    -m y -t, se escanea el historial de todos los árbitros Merge <name> into other/Merge <other> into <name> (respectivamente) comprometer sujetos, que   es bastante lento pero te permite resucitar el tema de otras personas   ramas


13
2017-09-06 19:39



Si no tiene un reflog, por ej. Debido a que está trabajando en un repositorio vacío que no tiene habilitado el reflog y se creó recientemente el compromiso que desea recuperar, otra opción es buscar objetos de commit recientemente creados y examinarlos.

Desde el interior .git/objects ejecución de directorio:

find . -ctime -12h -type f | sed 's/[./]//g' | git cat-file --batch-check | grep commit

Encuentra todos los objetos (confirmaciones, archivos, etiquetas, etc.) creados en las últimas 12 horas y los filtra para mostrar solo confirmaciones. Verificar estos es entonces un proceso rápido.

Probaría el script git-ressurect.sh mencionado en La respuesta de Jakub primero sin embargo.


8
2018-05-13 11:26



Usé los siguientes comandos para encontrar y recuperar mi rama eliminada. Los primeros pasos son de la descripción de gcb.

$ git fsck --full --no-reflogs --unreachable --lost-found > lost
$ cat lost | cut -d\  -f3 > commits
$ cat commits | xargs -n 1 git log -n 1 --pretty=oneline

Ahora busca la ID de commit de git (GIT-SHA) basada en los comentarios de confirmación y úsala en el siguiente comando. Pagar una nueva rama llamada NEW-BRANCH con el GIT-SHA previamente encontrado:

$ git checkout -b NEW-BRANCH GIT-SHA

6
2017-11-14 13:28



Según tengo entendido, si otra rama puede acceder a la rama que va a eliminar, puede eliminarla de forma segura utilizando

git branch -d [branch]

y tu trabajo no está perdido. Recuerde que una rama no es una instantánea, sino un puntero a una. Entonces, cuando elimina una rama, elimina un puntero.

Ni siquiera perderá trabajo si elimina una rama que no puede ser alcanzada por otra. Por supuesto, no será tan fácil como consultar el hash de confirmación, pero aún puedes hacerlo. Es por eso que Git no puede eliminar una rama a la que no se puede llegar utilizando -d. En cambio, debes usar

git branch -D [branch]

Esto es parte de un video que debe ver Scott Chacon sobre Git. Compruebe el minuto 58:00 cuando habla sobre las sucursales y cómo eliminarlas.

Introducción a Git con Scott Chacon de GitHub


5
2017-08-11 21:04



por GitHub usuarios sin Git instalado:

Si quieres restaurarlo desde GitHub sitio web, puedes Cortar su página web ;)

• En primer lugar, encuentre esos SHA (hash de confirmación):

curl -i https://api.github.com/repos/PublicUser/PublicRepo/events

... o para repositorios privados:

curl -su YourUserName https://api.github.com/repos/YourUserName/YourProject/events

... (se le pedirá la contraseña)

• Luego, ve a GitHub y crea una nueva rama temporal que se eliminará para siempre (Cromo es preferible).

• Ir a sucursales y eliminar ese.

En la misma página, sin recargar, abra DevTools, panel de red. Ahora prepara ...

• Haz clic en restaurar. Notarás una nueva "línea". Haga clic derecho sobre él y seleccione "Copiar como cURL" y guarde este texto en algún editor.

• Agregar al final de la línea de código copiada, esta: -H "Cookie=".

Deberías obtener ahora algo así:

curl 'https://github.com/UserName/ProjectName/branches?branch=BranchSHA&name=BranchName' -H 'Cookie:' -H 'Origin: https://github.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US' -H 'User-Agent: User-Agent' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Accept: */*' -H 'Referer: https://github.com/UserName/ProjectName/branches' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data 'utf8=%E2%9C%93&authenticity_token=token' --compressed

• Paso final: reemplace "BranchSHA" con su SHA-hash y BranchName con el nombre deseado (por cierto, es un gran hack cambiar el nombre de la sucursal de la web). Si no fue demasiado lento, debe hacer esta solicitud de todos modos. Por ejemplo, solo copie y pegue en una terminal.

PD

Lo sé, no es una solución muy simple o una solución correcta, pero por si alguien, sin una contraseña de root y una máquina virtual, durante el hackathon tendrá que hacer algo tan extraño como eso ... Es totalmente real, así que gracias por tomarte tu tiempo y buena suerte :)

ACTUALIZAR

Ahaha, estoy tan emocionado por el hecho de que alguien en la World Wide Web encontró mi respuesta y, en realidad, después de leerla, la encontró divertida o útil y superó mi alucinante respuesta de práctica: "Es un mundo maravilloso" y nosotros, programadores y codificadores, somos una de las partes más locas de ella <3


4
2017-08-26 05:01



Volví a configurar una rama desde el control remoto para tratar de borrar algunas confirmaciones que no quería y que iba a seleccionar cuidadosamente las correctas que quería. Por supuesto que escribí los SHA mal ...

Así es como los encontré (sobre todo una interfaz / interacción más fácil de las respuestas aquí):

Primero, genere una lista de confirmaciones sueltas en su registro. Haga esto lo antes posible y deje de trabajar, ya que el recolector de basura puede tirarlos.

git fsck --full --no-reflogs --unreachable --lost-found > lost

Esto crea un lost archivo con todos los compromisos que tendrá que mirar. Para simplificar nuestra vida, cortemos solo el SHA de ella:

cat lost | cut -d\  -f3 > commits

Ahora tienes un commits archivo con todos los commits que tiene que mirar.

Asumiendo que estás usando Bash, el último paso:

for c in `cat commits`; do  git show $c; read; done

Esto le mostrará la información de diff y commit para cada uno de ellos. Y espera a que presiones Entrar. Ahora anota todos los que quieras, y luego guárdalos. Después de que hayas terminado, solo presiona Ctrl-C.


3
2017-12-10 06:40