(Podés ver una charla basada en esto en Youtube)
Problema: en Github existía un commit e31886ff58fd334a0627bd672983b6e1de83ecb7
que no podíamos fetchear pero lo veíamos (es un repo privado, vas a tener que creerme).
$ git fetch origin e31886ff58fd334a0627bd672983b6e1de83ecb7
error: Server does not allow request for unadvertised object e31886ff58fd334a0627bd672983b6e1de83ecb7
El autor era yo, así que era probable que el commit existiera en mi repo local.
$ git show e31886ff58fd334a0627bd672983b6e1de83ecb7
commit e31886ff58fd334a0627bd672983b6e1de83ecb7
Author: Matias Garcia Isaia <[email protected]>
Date: Fri Feb 24 10:43:26 2017 -0300
483 - Linking Crystal in Waj's bio
Fixes #483
[...]
Listemos todos los commits locales que no son accesibles desde ningún branch o referencia: # https://stackoverflow.com/q/3765234/641451
$ git fsck --no-reflogs --unreachable | grep commit | cut -d ' ' -f 3 > dangling_commits.txt
$ wc -l < dangling_commits.txt
730
Ahora busquemos en esa lista cuáles son descendientes del commit que me interesa: # https://stackoverflow.com/a/18345268/641451
$ while IFS='' read -r line || [[ -n "$line" ]]; do git merge-base --is-ancestor e31886ff58fd334a0627bd672983b6e1de83ecb7 "$line" && echo "$line"; done < dangling_commits.txt
e31886ff58fd334a0627bd672983b6e1de83ecb7
0099839ba2cc24383941007946811c8a95f458cb
841c76ea9ccd1c72d7e53192b0340035816d2185
00284b477be89c3460b1e8fc89ed1dedfe43faaf
30b054f9d1fabecae4d4f4ea1c66480c0b08f4d0
7879abca8ff6fe72391ce11a4f62faf465f86cb5
De todos esos, busquemos si hay uno que sea el descendiente de todos, o si son ramas distintas:
$ git merge-base --is-ancestor 0099839ba2cc24383941007946811c8a95f458cb 841c76ea9ccd1c72d7e53192b0340035816d2185
$ git merge-base --is-ancestor 0099839ba2cc24383941007946811c8a95f458cb 841c76ea9ccd1c72d7e53192b0340035816d2185 && echo si
$ git merge-base --is-ancestor 841c76ea9ccd1c72d7e53192b0340035816d2185 0099839ba2cc24383941007946811c8a95f458cb && echo si
si
$ git merge-base --is-ancestor 00284b477be89c3460b1e8fc89ed1dedfe43faaf 0099839ba2cc24383941007946811c8a95f458cb && echo si
si
$ git merge-base --is-ancestor 30b054f9d1fabecae4d4f4ea1c66480c0b08f4d0 0099839ba2cc24383941007946811c8a95f458cb && echo si
si
$ git merge-base --is-ancestor 7879abca8ff6fe72391ce11a4f62faf465f86cb5 0099839ba2cc24383941007946811c8a95f458cb && echo si
$ git merge-base --is-ancestor 0099839ba2cc24383941007946811c8a95f458cb 7879abca8ff6fe72391ce11a4f62faf465f86cb5 && echo si
si
(probablemente se pueda mejorar esto, pero eran 5 commits, no valía la pena calentarse tanto)
Encontré que el commit 7879abca8ff6fe72391ce11a4f62faf465f86cb5
era el descendiente más joven de todos. Le clavé un branch y lo pusheé a Github. 🎉
$ git branch legacy/including-e31886ff 7879abca8ff6fe72391ce11a4f62faf465f86cb5
$ git push origin legacy/including-e31886ff
Gracias @aeatencio por ayudarme a aprender cosas 😊