¿Una alternativa Git para enviar files comprimidos y pedir parches se envíe de vuelta para un subproyecto?

Tengo un proyecto extenso que tiene dentro un subdirectory que en sí mismo es un proyecto.

Quiero administrar este subdirectory dentro del proyecto más grande que comparte las mismas twigs, tags, etc., por simplicidad. La integridad del proyecto más grande y la capacidad de rastrearlo como un repository git monolítico es muy importante para mí.

Pero también quiero publicar y aceptar requestes de extracción de contribuyentes en el proyecto más pequeño (subdirectory), sin exponerlos a mi proyecto más grande. El subproyecto requiere algunos files auxiliares (como un proyecto. Eclipse) en su padre para ser completamente autónomo.

He investigado el submodule, la combinación de subtree y la comprobación de dispersión, pero no he podido encontrar la manera de hacerlo. Como una medida provisional, envío un file tar del subdirectory y solicito parches a cambio.

¿Alguna idea de cómo mejorar esto con un flujo de trabajo centrado en git?

Ok, esa no es una configuration perfecta, pero debería ser lo suficientemente buena.

La idea es tener una twig en la que se elimine todo lo que no sea ese subdirectory y los files comunes (quiero decir: no existan para nada), y aceptar requestes de extracción para esa twig (puede crear un nuevo repository que contenga solo esa twig) )

Es un poco retorcido, así que voy a mostrarlo a través de un ejemplo. Digamos que su proyecto fue creado con comas como este:

mkdir bigproj cd bigproj git init echo "common file" >common mkdir subproj echo "subproj content" >subproj/content mkdir other echo "other content" >other/content git add common subproj other git commit -m 'Initial commit' git commit --allow-empty -m 'Some history' 

Tiene un file common dentro, un subdirectory subproj con algún contenido y el other subdirectory con otro contenido. Árbol:

 . ├── common ├── other │  └── content └── subproj └── content 

Ahora vamos a crear una twig que contenga solo common y subproj sin historial:

 git checkout --orphan subproj-branch git rm -rf . # clear the index git checkout master -- common subproj # put `common` and `subproj` back to index git commit -m 'Initial commit for subproj-branch' 

Árbol resultante:

 . ├── common └── subproj └── content 

Vuelva a fusionar esta twig en el master para evitar posibles conflictos falsos:

 git checkout master git merge subproj-branch # obviously no conflicts 

Ahora podemos publicar subproj-branch en algún repository dedicado:

 git remote add subproj-repo <some url> git push subproj-repo subproj-branch:master --set-upstream # -f may be needed. # And remote branch doesn't have to be named master, of course. 

El repository está publicado, tenemos algunos parches. Ahora podemos fusionarlos:

 git checkout subproj-branch git pull git checkout master git merge subproj-branch 

Ese es el flujo base, que permite hacer cambios en subproj-repo e incorporarlos al repository principal. Ahora, hacerlo al revés es un poco más problemático, pero posible. Hay a las posibilidades:

  1. Los cambios solo tocan subproj / common . Podemos tomarlos "tal como son":

     git checkout subproj-branch git cherry-pick master # replace master with anything you actually need git checkout master git merge subproj-branch git push subproj-repo subproj-branch:master 
  2. Los cambios tocan subproj / common y otros files. Puede subproj-branch manualmente cada file modificado en subproj-branch luego confirmar y fusionar de nuevo a maestro (para evitar falsos conflictos en el futuro). Eso no es perfecto, y es posible que desee alterar ese paso de alguna manera.

     git checkout subproj-branch git checkout master -- common subproj git commit -m 'Some changes' git checkout master git merge subproj-branch git push subproj-repo subproj-branch:master 

Parte importante aquí es fusionar los cambios a master. Eso puede parecer absurdo, pero puede evitar que ocurran algunos conflictos.

Whoa, esa es una respuesta larga. Espero que sea útil: P

Encontré la respuesta oculta en ¿Cómo combino un subdirectory en git?

La parte key de git magic es usar lo siguiente para sincronizar los dos subdirectorys comunes:

 git read-tree --prefix=MyHugeProprietaryWebApp/public_html/ -u contrib/master:MyOpenSubproject/public_html/ 

Dónde

  • MyHugeProprietaryWebApp es el directory de nivel superior del proyecto debajo de la raíz del repository (es decir, esta es la carpeta raíz del proyecto en Eclipse)
  • public_html es el subdirectory que contiene el código con el que quiero trabajar con queueboradores (en mi caso específico, este es un código de layout de PHP). Aparece dos veces en el command porque el subdirectory recibe el mismo nombre en ambos repositorys.
  • contrib es el repository en github (compartido con queueboradores) que he creado anteriormente usando git checkout --orphan y git push como lo sugiere Frax; No he probado posibles alternativas como --depth=1 .
  • MyOpenSubproject es la carpeta raíz del proyecto más pequeño y es lo que contiene el proyecto. Eclipse y otros files auxiliares que hacen que el subproyecto sea autónomo. Estos files auxiliares NO se comparten con el proyecto más grande e incluyen documentation adicional, testings, etc., que solo son relevantes para los queueboradores externos y no para los expertos que trabajan en el proyecto más grande.

Mi experiencia con este enfoque se ha limitado a algunas testings en seco, pero estoy contento con lo que veo hasta ahora. Todavía no he experimentado con el pull -s subtree -X path que podría necesitar en algún momento.

Esta no es exactamente una respuesta completa, pero trabajando desde la respuesta de @ Frax, encontré algunas cosas que no entendí, o que no funcionaron como esperaba, y tuve que modificarlo de la siguiente manera:

  • Primero utilicé filter-branch para crear una nueva twig que tenga solo el contenido del subdirectory común con historial. (* Evito hacer un repository separado porque tengo un límite en el número de repositorys privados en GitHub *). Esto simplificará todas las operaciones restantes ya que la mayoría de los commands de git funcionan naturalmente en el scope de una sucursal, pero me confundo cuando trato de hacer cosas en un scope de subtree.
  • Incluso esta historia filtrada está extremadamente hinchada, así que procedí a crear una twig sin historial usando la opción sugerida de --orphan . Excelente sugerencia.
  • Es importante hacer una git merge en la twig completa (no en la twig huérfana), esta dirección de fusión parece estar al revés en la respuesta de Frax, o simplemente no entiendo lo que estoy haciendo. El resultado es que el hash de confirmación de la nueva twig se puede ver en la twig de historial.
  • Finalmente, use submodule add –b branch para incorporar esta nueva twig tanto en el proyecto original como en el subproyecto.
  • Después de solo unos minutos de intentar usar esto, ya encontré limitaciones con el event handling submodules de Eclipse. Parece que la próxima alternativa es simplemente dividir los repos.

Algunas notas más

  • Esta pregunta parece ser muy similar: ¿Cómo puedo mantener una subcarpeta de un repository de git sincronizado con una subcarpeta de otro repository de git ? Acabo de ofrecer 100 puntos de recompensa por esa pregunta
  • Utilizar el checkout disperso para tomar un subdirectory de un repository y comprometerse con el otro "casi funciona", excepto que todo mi repository de 500MB se replica detrás de la escena aunque mi escaso checkout cubre solo un puñado de files de text.
  • Usar –depth = 1 era esperanzador, ¡excepto tratar de comprometerme con el segundo repository que obtuve ! [remote rejected] master -> master (shallow update not allowed) ! [remote rejected] master -> master (shallow update not allowed)
  • Otra pregunta similar (sin respuesta): repository de git hijo como subset de un repository principal
  • La respuesta de @Frax a continuación funciona bien si presiono una nueva twig nueva en el segundo control remoto. Pero quería que se integrara con el maestro remoto para que los files de soporte adicionales que son necesarios para ejecutar el subproyecto en modo independiente pudieran estar en la misma twig.