tipos tag repositorio qué que existen etiquetas crear conflictos git github fork

tag - resolver conflictos git



Creando el repositorio de GitHub con solo un subconjunto del historial de un repositorio local (3)

La respuesta de Brian arriba parece completa y conocedora, aunque un tanto compleja.

La solución fácil (ier) sería mantener dos repositorios.

Un repositorio github privado en el que trabajas. Usted hace todos los empujones de historia completa a ese repositorio.

El segundo repositorio es un repositorio público de github al que usted publica solo cuando desea "lanzar" una nueva versión al público. Usted publica utilizando un parche diff + simple, y luego confirma + push.

El trasfondo: me estoy acercando para abrir un código de búsqueda personal en el que he estado trabajando durante más de dos años. Comenzó su vida como un repositorio SVN, pero me mudé a Git hace un año, y me gustaría compartir el código en GitHub. Sin embargo, acumuló una gran cantidad de cruxt durante los años, y preferiría que la versión pública comience su vida en su estado actual. Sin embargo, aún me gustaría contribuir e incorporar las posibles contribuciones de otras personas.

La pregunta es : ¿hay alguna manera de "bifurcar" un repositorio de git de modo que no se conserve ningún historial en la bifurcación (que vive en GitHub), pero que mi repositorio local todavía tenga un historial completo, y pueda extraer / enviar a GitHub?

No tengo ninguna experiencia en el extremo administrativo de grandes repositorios, por lo que los detalles son muy apreciados.


Una forma muy simple e interesante de hacer esto es la siguiente:

Digamos que tiene en REPO-A confirmaciones C1 a C10, donde C1 es la confirmación inicial y C10 es la última CABEZA. Y desea crear un nuevo REPO-B de modo que haya confirmado C4 a C8 (un subconjunto).

NOTA: El uso de este método cambiaría los SHA de confirmación (por ejemplo: C4 ''a C8'' en este caso) pero los cambios que realiza cada confirmación seguirán siendo los mismos, y su primer commit ahora comenzará con todos los cambios de sus compromisos anteriores hasta ese momento conjunto.

¿Qué hacer?

Copia recursivamente todo en tu máquina local

cp -R REPO-A REPO-B

Opcionalmente, elimine todos los controles remotos de su REPO-B, ya que lo más probable es que quiera usar esto como un repositorio separado.

cd REPO-B git remote -v git remote remove REMOTE_NAME

Mueva el puntero de la rama al extremo posterior de su subconjunto. Para el sujeto C4 a C8 eso sería C8. Pero lo más probable es que necesite subconjuntos hasta la CABEZA (por ejemplo, de C4 a C10 o C6 a C10) en cuyo caso no es necesario el paso siguiente.

git checkout -b temp git branch -f master C8 git checkout master git branch -D temp

Ingrese el SHA de confirmación del extremo anterior de su subconjunto en el directorio .git/info/grafts del archivo. En este caso, es el SHA de commit C4.

git rev-parse --verify C4 >> .git/info/grafts

Hacer un filtrado de rama git sin argumentos

git filter-branch

O eso no funciona

git filter-branch --all

Ahora puede enviar esto a un control remoto por separado / nuevo si desea

git remote add origin NEWREMOTE git push -u origin master

¿Cómo funciona?

Este enlace le dice cómo funciona en realidad: http://git.661346.n2.nabble.com/how-to-delete-the-entire-history-before-a-certain-commit-td5000540.html

Puede leer acerca de los injertos en la página de manual de git-filter-branch (1), en la descripción de diseño del repositorio gitrepository-layout (5) git, y en gitglossary (7) un gitário de git.

En resumen, cada línea en .git / info / injertos consiste en sha1 id de objeto, seguido de una lista separada por espacios de sus padres efectivos (injertados). Por lo tanto, para cortar el historial, por ejemplo, después de confirmar a3eb250f996bf5e, debe colocar una línea que contenga solo este SHA-1 en el archivo .git / info / injertos, por ejemplo:

$ git rev-parse --verify a3eb250f996bf5e >> .git / info / injertos


Puede crear una historia nueva y fresca con bastante facilidad en Git. Digamos que quieres que tu rama master sea ​​la que presionarás para GitHub, y tu historial completo para almacenar en old-master . Puedes simplemente mover tu rama master a old-master , y luego comenzar una nueva rama nueva sin historial usando la git checkout --orphan :

git branch -m master old-master git checkout --orphan master git commit -m "Import clean version of my code"

Ahora tiene una nueva rama master sin historial, que puede enviar a GitHub. Pero, como dices, te gustaría poder ver toda la historia anterior en tu repositorio local; y probablemente le gustaría que no se desconecte.

Puedes hacer esto usando git replace . Una referencia de reemplazo es una forma de especificar una confirmación alternativa cada vez que Git examina un compromiso determinado. Así que puedes decirle a Git que mire la última confirmación de tu antigua sucursal, en lugar de la primera confirmación de tu nueva sucursal, al mirar la historia. Para hacer esto, debe ingresar el historial desconectado del repositorio anterior.

git replace master old-master

Ahora tiene su nueva sucursal, en la que puede ver todo su historial, pero los objetos de compromiso reales están desconectados del historial antiguo, y así puede enviar los nuevos commit a GitHub sin los compromisos anteriores. Empuja tu rama master a GitHub, y solo los nuevos commits irán a GitHub. Pero eche un vistazo a la historia en gitk o git log , y verá el historial completo.

git push github master:master gitk --all

Gotchas

Si alguna vez basa nuevas ramas en las confirmaciones anteriores, deberá tener cuidado de mantener la historia separada; de lo contrario, las nuevas confirmaciones en esas sucursales realmente tendrán los compromisos anteriores en su historial, y por lo tanto, extraerás toda la historia si la haces subir a GitHub. Sin embargo, mientras mantenga todos sus nuevos compromisos basados ​​en su nuevo master , estará bien.

Si alguna vez ejecutas git push --tags github , eso empujará todas tus etiquetas, incluidas las antiguas, lo que provocará que todo tu historial git push --tags github . Podrías lidiar con esto eliminando todas tus etiquetas antiguas (etiqueta de git tag -d $(git tag -l) ), o nunca usando etiquetas de git push --tags pero solo empujando las etiquetas manualmente, o usando dos repositorios como se describe a continuación .

El problema básico que subyace a estos dos errores es que si alguna vez empuja cualquier referencia que se conecte a cualquier historial anterior (a no ser a través de las confirmaciones reemplazadas), usted empujará hacia arriba todo el historial antiguo. Probablemente, la mejor forma de evitar esto sea mediante el uso de dos repositorios, uno que contenga solo los nuevos commits y otro que contenga tanto el historial anterior como el nuevo, con el fin de inspeccionar el historial completo. Usted hace todo su trabajo, su compromiso, su empuje y extracción de GitHub, en el repositorio con solo los nuevos compromisos; de esa forma, no puedes presionar accidentalmente tus antiguos commits. A continuación, extrae todos sus nuevos compromisos en su repositorio que tiene el historial completo, siempre que necesite ver todo el asunto. Puede extraer de GitHub o de su otro repositorio local, lo que sea más conveniente. Será su archivo, pero para evitar publicar accidentalmente su historial anterior, nunca empujará a GitHub desde allí. Así es como puedes configurarlo:

~$ mkdir newrepo ~$ cd newrepo newrepo$ git init newrepo$ git pull ~/oldrepo master # now newrepo has just the new history; we can set up oldrepo to pull from it newrepo$ cd ~/oldrepo oldrepo$ git remote add newrepo ~/newrepo oldrepo$ git remote update oldrepo$ git branch --set-upstream master newrepo/master # ... do work in newrepo, commit, push to GitHub, etc. # Now if we want to look at the full history in oldrepo: oldrepo$ git pull

Si tienes Git anterior a 1.7.2

No tiene el git checkout --orphan , por lo que tendrá que hacerlo manualmente creando un repositorio nuevo a partir de la revisión actual de su repositorio existente, y luego ingresando su antiguo historial desconectado. Puedes hacer esto con, por ejemplo:

oldrepo$ mkdir ~/newrepo oldrepo$ cp $(git ls-files) ~/newrepo oldrepo$ cd ~/newrepo newrepo$ git init newrepo$ git add . newrepo$ git commit -m "Import clean version of my code" newrepo$ git fetch ~/oldrepo master:old-master

Si tienes Git anterior a 1.6.5

git replace y replace refs se agregaron en 1.6.5, por lo que tendrás que usar un mecanismo más antiguo, algo menos flexible, conocido como grafts , que te permite especificar padres alternativos para un compromiso determinado. En lugar del comando git replace , ejecuta:

echo $(git rev-parse master) $(git rev-parse old-master) >> .git/info/grafts

Esto hará que se vea, localmente, como si la confirmación master tuviera la confirmación del master old-master como su padre, por lo que verás una confirmación más de la que harías con la git replace .