git tratando de enviar files inexistentes … después de borrar el caching

Tengo un número de shapefiles en mi repository que eran demasiado grandes, lo que hace que mi empuje a GitHub falle. Inicialmente intenté crear un file .gitignore que excluye la mayoría de las extensiones en packages de shapefile. Todavía intentó empujar los shapefiles. Después de algunas búsquedas, descubrí que tenía que borrar el caching:

 git rm -rf --cached . git add . 

Sin embargo, una vez que intenté comprometerme y luego presionar nuevamente, descubrí que esto no solucionaba el problema. El mismo shapefile colgaba cosas. Después de mucho perder el time, abandoné la idea y decidí mover todos los shapefiles del repository. Borré el caching de nuevo, agregué, me comprometí e intenté presionar a GitHub.

El empuje falló. El shapefile (que ya no está en el repository) era demasiado grande para un push. ¿Cómo puede suceder eso? Siento que los files que no están en el commit, porque no están en el repository, no deberían poder colgar el push. Cualquier comentario sobre lo que está sucediendo aquí sería muy apreciado.

ACTUALIZACIÓN : estado actual de las opciones de rebase …

 noop # Rebase 133c6ec..133c6ec onto 133c6ec # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # These lines can be re-ordenetworking; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out 

ACTUALIZACIÓN: Reflog >> todo comienza con 'Agregar muchas imágenes'

 133c6ec HEAD@{0}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{1}: rebase -i (start): checkout refs/remotes/origin/master 133c6ec HEAD@{2}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{3}: rebase -i (start): checkout refs/remotes/origin/master 133c6ec HEAD@{4}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{5}: rebase -i (start): checkout refs/remotes/origin/master 133c6ec HEAD@{6}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{7}: rebase -i (pick): still dealing with shp bs 0f81c71 HEAD@{8}: rebase -i (pick): Removing shapefiles 91cb472 HEAD@{9}: rebase -i (pick): Adding comments from Mullins consult - throu 83c1269 HEAD@{10}: rebase -i (pick): Adding comments from Mullins consult - thro 7677b3f HEAD@{11}: rebase -i (pick): Hopefully .gitignore is now working 97aa005 HEAD@{12}: rebase -i (pick): Adjusting gitignore 9e912cb HEAD@{13}: rebase -i (pick): Adjusting gitignore 06647c0 HEAD@{14}: rebase -i (squash): Adding many images 259d73b HEAD@{15}: rebase -i (squash): # This is a combination of 2 commits. 3b2d5e8 HEAD@{16}: rebase -i (start): checkout refs/remotes/origin/master a585f1d HEAD@{17}: rebase: aborting 7bc98a4 HEAD@{18}: rebase -i (start): checkout refs/remotes/origin/master a585f1d HEAD@{19}: rebase -i (finish): returning to refs/heads/master a585f1d HEAD@{20}: rebase -i (start): checkout 9f28970 a585f1d HEAD@{21}: rebase -i (finish): returning to refs/heads/master a585f1d HEAD@{22}: rebase -i (start): checkout refs/remotes/origin/master :...skipping... 133c6ec HEAD@{0}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{1}: rebase -i (start): checkout refs/remotes/origin/master 133c6ec HEAD@{2}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{3}: rebase -i (start): checkout refs/remotes/origin/master 133c6ec HEAD@{4}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{5}: rebase -i (start): checkout refs/remotes/origin/master 133c6ec HEAD@{6}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{7}: rebase -i (pick): still dealing with shp bs 0f81c71 HEAD@{8}: rebase -i (pick): Removing shapefiles 91cb472 HEAD@{9}: rebase -i (pick): Adding comments from Mullins consult - throu 83c1269 HEAD@{10}: rebase -i (pick): Adding comments from Mullins consult - thro 7677b3f HEAD@{11}: rebase -i (pick): Hopefully .gitignore is now working 97aa005 HEAD@{12}: rebase -i (pick): Adjusting gitignore 9e912cb HEAD@{13}: rebase -i (pick): Adjusting gitignore 06647c0 HEAD@{14}: rebase -i (squash): Adding many images 259d73b HEAD@{15}: rebase -i (squash): # This is a combination of 2 commits. 3b2d5e8 HEAD@{16}: rebase -i (start): checkout refs/remotes/origin/master a585f1d HEAD@{17}: rebase: aborting 7bc98a4 HEAD@{18}: rebase -i (start): checkout refs/remotes/origin/master a585f1d HEAD@{19}: rebase -i (finish): returning to refs/heads/master a585f1d HEAD@{20}: rebase -i (start): checkout 9f28970 a585f1d HEAD@{21}: rebase -i (finish): returning to refs/heads/master a585f1d HEAD@{22}: rebase -i (start): checkout refs/remotes/origin/master a585f1d HEAD@{23}: rebase: aborting :...skipping... 133c6ec HEAD@{0}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{1}: rebase -i (start): checkout refs/remotes/origin/master 133c6ec HEAD@{2}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{3}: rebase -i (start): checkout refs/remotes/origin/master 133c6ec HEAD@{4}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{5}: rebase -i (start): checkout refs/remotes/origin/master 133c6ec HEAD@{6}: rebase -i (finish): returning to refs/heads/master 133c6ec HEAD@{7}: rebase -i (pick): still dealing with shp bs 0f81c71 HEAD@{8}: rebase -i (pick): Removing shapefiles 91cb472 HEAD@{9}: rebase -i (pick): Adding comments from Mullins consult - through rev chapter 83c1269 HEAD@{10}: rebase -i (pick): Adding comments from Mullins consult - through rev chapter 7677b3f HEAD@{11}: rebase -i (pick): Hopefully .gitignore is now working 97aa005 HEAD@{12}: rebase -i (pick): Adjusting gitignore 9e912cb HEAD@{13}: rebase -i (pick): Adjusting gitignore 06647c0 HEAD@{14}: rebase -i (squash): Adding many images 259d73b HEAD@{15}: rebase -i (squash): # This is a combination of 2 commits. 3b2d5e8 HEAD@{16}: rebase -i (start): checkout refs/remotes/origin/master a585f1d HEAD@{17}: rebase: aborting 7bc98a4 HEAD@{18}: rebase -i (start): checkout refs/remotes/origin/master a585f1d HEAD@{19}: rebase -i (finish): returning to refs/heads/master a585f1d HEAD@{20}: rebase -i (start): checkout 9f28970 a585f1d HEAD@{21}: rebase -i (finish): returning to refs/heads/master a585f1d HEAD@{22}: rebase -i (start): checkout refs/remotes/origin/master a585f1d HEAD@{23}: rebase: aborting eaadebf HEAD@{24}: rebase -i (pick): Adding comments from Mullins consult - through rev chapter 7bc98a4 HEAD@{25}: rebase -i (start): checkout refs/remotes/origin/master a585f1d HEAD@{26}: commit: still dealing with shp bs 4bef02c HEAD@{27}: commit: Removing shapefiles cc061ac HEAD@{28}: commit: Adding comments from Mullins consult - through rev chapter 21c5ab7 HEAD@{29}: commit: Adding comments from Mullins consult - through rev chapter 9f28970 HEAD@{30}: commit: Hopefully .gitignore is now working a2bdbae HEAD@{31}: commit: Adjusting gitignore c3e5128 HEAD@{32}: commit: Adjusting gitignore 8f8b96e HEAD@{33}: commit: Adding gitignore to avoid tracking shapefiles 0c14e14 HEAD@{34}: commit: Adding gitignore to avoid tracking shapefiles 3b2d5e8 HEAD@{35}: commit: Adding many images 

Lo primero que hay que recordar aquí es que git push commits . Si se incluye algún file, se trata simplemente de ser necesario para las confirmaciones que se envían.

La segunda cosa para recordar es que cuando haces git push , tu git y "su" git (un command git que se ejecuta en github, en este caso) generalmente tienen una pequeña conversación entre ellos, de la forma:

  • "He commit <SHA-1> Me gustaría darte, y luego me gustaría que configures tu branch master (o cualquier otra twig) para que apunte a ese SHA-1".

  • "Bueno, tengo <different SHA-1> para esa twig. Dime qué SHA-1s necesito para completar cualquier agujero entre lo que tengo y lo que tienes". (Hay más en esto que esto, y va en un order diferente, pero la esencia es un intercambio de quién-tiene-qué comprometer y otros ID de object.)

Una vez que saben qué identificaciones tiene cada uno, el remitente empaqueta "lo que sea necesario": se trata de una serie de confirmaciones (posiblemente vacías) y cualquier entidad, principalmente (pero no del todo limitada) files, que va con esos compromisos, que el receptor tampoco tiene. En este caso, el remitente es su git, el receptor es su git, y el package incluye algunos files grandes.

Decidiste que no querías enviar los files grandes. Esto significa que debe replace los commit (s) que le está pidiendo a su git que envíe, con algunos commit (s) nuevos que le pedirá a su git enviar. Si los nuevos commit (s) no se refieren a los files grandes, entonces cuando su git va a enviar los commits, su git tampoco pedirá los files, y su git no los enviará.

El libro de Pro Git tiene una sección sobre "reescribir la historia" que lo cubre bastante bien. Lo que falta (al less si solo lees la sección, hay otras secciones que lo cubren) es un diagtwig de lo que realmente hace una rebase.

(Por cierto, su git repo contendrá los files grandes, y continuará haciéndolo hasta que todas las references a esos files hayan desaparecido, incluido el tipo de references fantasmas que permanecen en los "reflogs" de git después de las operaciones de reescritura del historial. fantasmas que le permiten resucitar files si comete un error durante la reescritura del historial. Las inputs de Reflog persisten durante 30 días de forma pnetworkingeterminada, para estas inputs, al less, las inputs de reflog "más activas" persisten durante 90 días por defecto, pero a less que esté haciendo algo inusual, normalmente puedes dejar que caduque por sí solo).


La documentation de git rebase tiene algunos diagtwigs, como este:

  A---B---C topic / D---E---F---G master [becoming] A'--B'--C' topic / D---E---F---G master 

Las letras individuales significan confirmaciones, y la razón por la cual esto tiene A' lugar de A , y así sucesivamente, después de la rebase, es que la rebase no-no puede -realmente mover una confirmación, solo puede hacer una copy . Los commits originales todavía están ahí, simplemente no tienen una label como topic mantiene visibles. Si las copys son diferentes, y lo son, entonces tienen un SHA-1 nuevo y diferente. Son los SHA-1 los que realmente importan, al less durante el empuje (y recuperación).

En su caso, lo que quiere hacer cuando se rebase es hacer "copys deliberadamente defectuosas", donde los originales tienen los files grandes, y las copys "defectuosas" no. (De hecho, por supuesto, es "tener el file grande" el defecto, por lo que las copys que no son perfectas son las correctas, ¡son los originales los que están equivocados!)

La rebase interactiva tiene la capacidad adicional de "aplastar" una nueva confirmación en una confirmación existente, es decir, tomar la copy que va a realizar y modificarla en function de la próxima confirmación de la secuencia.

La otra gran diferencia entre lo que quieres hacer y lo que está en el diagtwig de arriba es que quieres que los nuevos commit (s) comiencen desde el mismo punto que los originales:

  H - I <-- master [in your repo] / ... - G <-- origin/master [ie, what's on github as master] 

Aquí commit H podría ser el defectuoso con los files adicionales, y podría ser el commit que elimina los files adicionales. Si pides que empujen a tu master a github y le pones a github como master , tu git y su git chatearán y decidirán que github necesita H e I y algunos files, incluidos, por H , los grandes.

Si reescribes tu propia historia para que en lugar de H y I tengas una sola H'I' nueva, vamos a llamar a esta J por simplicidad, entonces tendrás este diagtwig en su lugar:

  H - I [abandoned ghosts] / ... - G <-- origin/master [ie, what's on github as master] \ J <-- master 

Ahora puedes hacer que tu git invoque git de github y proponga enviar solo J , que no tiene los files grandes.

Tenga en count que hay dos keys para todo esto:

  • Commit G (como lo indica el origin/master ) no tiene los files grandes, pero está en su repository y en el repository en github. Es el punto de partida compartido para el push : es el primer compromiso que su lado deja fuera cuando empuja, porque su lado ya lo tiene.

  • Commit J (y / o cualquier otro compromiso que presione) tampoco debe tener los files grandes. De esa manera, cuando tu git habla con su git, tu git decidirá que lo que necesita enviar no incluye los files grandes.

Al final, no importa cuántos commits enviará tu lado en el push, lo que importa es qué hay en esos commits específicos. Puedes reescribir cosas que "solo tú tienes" con la frecuencia (o rara vez) que quieras, a tu gusto. Una vez que haya entregado exitosamente esos commits a otro repository, si los "reescribe" a copys nuevas ligeramente diferentes, el otro repo todavía tiene los originales y otros usuarios pueden haberlos obtenido también (si ese otro repository es generalmente accesible) )

(Todavía puede "reescribir el historial" y usar un --force push para pedirle al otro repo que descarte algunos commits, incluidos los originales que haya decidido que son malos. Tampoco hay nada inherentemente malo en esto, es solo que cualquiera queueborar con usted puede haber recogido esos "originales incorrectos" y pueden estar usándolos, por lo que también está haciendo más trabajo para esas personas).


Una última nota, sobre el hecho de que git rebase -i muestra una list vacía: esto sugiere que realmente has eliminado todas las confirmaciones que tenías y que no. Es decir, en lugar de pasar de:

  H - I <-- master / ... - G <-- origin/master 

a:

  J <-- master / ... - G <-- origin/master 

de alguna manera simplemente descartó H y I completo, de modo que su master señala que también debe comprometerse con G

Esto podría suceder si rebase -i una rebase -i y le rebase -i a git que squash I en H , y así fue, y el resultado fue exactamente el mismo file que se encuentra en commit G (Por ejemplo, si la única diferencia de G a H es "agregar file grande" y la única diferencia de H a I es "eliminar file grande", la combinación de los dos no tiene diferencia de G ). Git no permite una confirmación "vacía": una confirmación con autor, post, etc., como de costumbre, pero con el mismo tree que la confirmación anterior, pero por defecto, rebase asume que no quiere eso: simplemente elimina la cancelación se compromete por completo

Si tuviste otros commits que se han desvanecido, esos "commits fantasma" que mencioné anteriormente son justo lo que necesitas. Para encontrarlos, mira en los "reflogs":

 $ git reflog 

y:

 $ git reflog master 

Estos reflogs mantienen un historial de dónde han señalado HEAD y master (o cualquier otra twig) durante los últimos 90 días: los ID de SHA-1 sin procesar de ambas confirmaciones, ya sean confirmaciones regulares que se mantendrán para siempre. , o confirmaciones fantasma persistentes retenidas solo por las inputs de reflog.