git: ¿cómo me fusiono entre twigs mientras mantengo algunos sets de cambios exclusivos de una twig?

Hay un lugar especial en el infierno para las personas que codifican routes absolutas y cnetworkingenciales de bases de datos en múltiples lugares aleatorios en aplicaciones web. Lamentablemente, antes de ir al infierno están causando esgulps en la Tierra. Y tenemos que lidiar con su código.

Tengo que realizar algunos pequeños cambios en una de esas aplicaciones web. Creé nuevas features bifurcación y realicé un descubrimiento y reemploop global para actualizar las routes y cnetworkingenciales a mi entorno local. Lo cometo. También etiqueto esto como local .

Salto alegremente hacia la penitencia de hacking peligrosa, y después de cientos de parches desconcertantes, quiero fusionar mis cambios de features en la twig master , pero no quiero que el compromiso local se fusione.

En adelante, me fusionaré entre master y features , y me gustaría que los local permanezcan en las features , y nunca se muestren en master .

Idealmente, me gustaría que todo esto suceda mágicamente, con tan pocos parameters divertidos y todo lo que sea posible.

¿Hay una manera simple y obvia de hacerlo que me estoy perdiendo?

Puedo pensar en una pareja, pero todos me requieren que recuerde que no quiero comprometerme. Y definitivamente no es mi fuerte. Especialmente con progtwigs tan mal pirateados.

Si eso falla, estoy interesado en forms más complicadas y manuales para manejar la situación.

Mi solución a este problema utiliza rebase en lugar de combinar

Comenzando con un tree de commits como este:

 abc <-- master \ d <-- local \ efg <-- dev 

$ git rebase –onto master local dev

  master V abc-e'-f'-g' <-- dev \ d <-- local 

$ git checkout master

$ git merge dev

  master V abc-e'-f'-g' <-- dev \ d <-- local 

$ git rebase –to master master local

  master V abc-e'-f'-g' <-- dev \ d' <-- local 

$ git branch -f dev local

  master V abc-e'-f'-g' \ d' <-- local ^ dev 

Puedes usar git cherry pick para fusionar solo los parches que selects. Simplemente escoge cada compromiso, excepto el local en la twig principal.

Una solución técnica (Git) estaría usando git attributes , usando la combinación de attributes.

 merge 

La merge attributes afecta cómo se merge tres versiones de un file cuando es necesaria una fusión a nivel de file durante la git merge .

Encontrarás en la pregunta de SO " ¿Cómo le digo a Git que siempre select mi versión local para las fusiones en conflicto en un file específico? " Un ejemplo de uso de dicho atributo, para forzar el mantenimiento de la versión local de ciertos files cuando se fusiona con un determinado twig.

El problema con la configuration de los attributes de combinación es que los files que contienen las routes pueden contener otro código modificado, que deseo fusionar

No olvide que puede asociar cualquier tipo de script para administrar esas fusiones a través de los git attributes . Eso incluye una secuencia de commands capaz de mantener los cambios que desea locales, mientras combina el rest. Es más complicado escribir un "administrador de combinación", pero es un path hacia una solución automatizada ad-hoc.


Una solución less técnica sería separar los valores de configuration de los files de configuration :

  • el file de configuration contiene solo nombres para ser reemplazados
  • los valores de configuration son varios files (uno por entorno) con los valores reales para cada nombre.

Una secuencia de commands se utiliza para replace el nombre en el file de configuration real por los valores de uno de los files de valores de configuration necesarios para un entorno determinado.

De acuerdo. no se garantiza que esto funcione todas las veces, pero algo como esto puede funcionar (y en los casos que lo haga, tendrá cambios conflictivos que deben resolverse):

  • haz tu sucursal local
  • hacer cambios locales
  • continuar el desarrollo

al fusionarse con el maestro:

  • rebase -i master desde su twig y mueva el cambio solo local al FIN de la cadena de parches.
  • resolver cualquier conflicto en el process. Si el cambio solo local está en los files de configuration y no los está tocando en el desarrollo normal, entonces no tendrá problemas. Si, de lo contrario, tiene un conflicto, entonces este es un caso en el que realmente cambia en la misma área y necesita su atención para resolverlo de todos modos.
  • echa un vistazo a master
  • fusiona tu twig local -1

    git fusionar local ^

Esto te dejará con el maestro teniendo todos los cambios en el local, excepto el último.

Si tiene múltiples cambios locales =, le sugiero que los squash juntos durante la rebase.

Personalmente, si tuviera que hacer algo como esto y por alguna razón se me impidiera refaccionar las cnetworkingenciales a medida que avanzaba, agregaría dos twigs más, terminando con una disposition similar a la siguiente:

master : el código original que henetworkingó

localcnetworking : branch from master, y agrega solo el parche que cambia todas las cnetworkingenciales a lo que necesita localmente. Trate esta twig como de solo lectura en lo sucesivo (y posiblemente agregue un enlace para evitar confirmaciones accidentales).

feature : twig de la maestra, y todas las correcciones van aquí (y posiblemente agreguen un enlace para evitar la fusión con el parche en localcnetworking)

local : una twig (¡no una label!) que comenzará como una sucursal de localcnetworking , y luego fusionará cada vez que necesite ejecutar sus testings unitarias. Todas las testings se realizan desde aquí, pero aquí no ocurre ningún desarrollo. Además, esta twig es desechable, porque es posible que desee volver a establecer la base dentro de la feature , y la manera más rápida de lidiar con el resultado será eliminar la twig local , bifurcarla nuevamente de la function localcnetworking y fusionar antes de ejecutar las testings. Es probable que esto sea una operación bastante común en mi flujo de trabajo que buildía un alias para hacerlo repetidamente en solo unas pocas teclas, pero trabajo muchísimo con la eliminación de las twigs de Git, lo que asusta a algunas personas que mírame, entonces YMMV.

Cuando piense que sus correcciones están lists para su publicación, haga su rebase final de la feature para limpiar el historial, volcar y recrear local para su testing final, fusionar feature en master , y una vez que sea aceptado en sentido ascendente, fusionar master en localcnetworking y rebase su parche de cnetworkingenciales en la parte superior, luego volcar y recrear local y feature y jugar el juego de nuevo.

Si desea probar rápidamente una gran cantidad de pequeñas variaciones de código sin tener que comprometerse y fusionarse cada vez, realice el pago local , realice los cambios hasta que esté satisfecho, comprométalo y select inmediatamente de local en feature , luego suelte y recrear local.

¿Eso satisface tus necesidades?

Haría una rebase interactiva contra master y movería tu path-name-fixup-commit hasta el final. Entonces, puedes unirte al punto. Solo sigue moviendo tu compromiso especial hasta el final.

También puede encontrar el alijo útil. En lugar de comprometer las correcciones de nombre de ruta, puede savelas. Si testing este enfoque, es posible que desee verificar la pregunta sobre Cómo invertir un alijo .

Bueno, como hasta ahora ninguna respuesta ha proporcionado una solución directa, supongo que lo que quiero hacer es imposible, y lo agrego al montón de soluciones ocasionalmente útiles:

Si siempre está desarrollando en la twig de features , puede fusionar features para master , y luego, en master , git revert local . (Donde local es la label que hace reference al compromiso donde personalizó las routes, etc., para su entorno local).

Ahora nunca debe combinar las features master , porque eso fusionaría también la confirmación local inversa.

En este caso, el master convierte en una especie de twig de implementación, que solo recibe fusiones de otras twigs. (Idealmente, solo desde la twig de features ).

Esto va cuesta abajo muy fácilmente, solo agrega otro desarrollador al flujo de trabajo y las cosas se ponen realmente desorderadas. Todavía se puede solucionar mediante el uso de estrategias de fusión explícitas, pero en general es un dolor.

No sé si esto funcionaría, pero:

  1. Cree un compromiso que, dada la versión "maestra" de los files de configuration, los convierta en la versión que necesita localmente. Tenga en count el SHA-1. Lo llamaremos MAKE_LOCAL
  2. Cree un compromiso que, dada su versión local de los files de configuration, los convierta en la versión apropiada para el maestro. Tenga en count el SHA-1. Lo llamaremos MAKE_REMOTE
  3. Usando git hooks, cuando compromete:
    1. git cherry-pick MAKE_REMOTE (o use git diff y patch )
    2. Permitir que el compromiso comience
    3. git cherry-pick MAKE_LOCAL (o use git diff y patch )

Creo que hay una forma aún mejor de transformar files de esta manera, pero no recuerdo (si puedes encontrar la presentación de git de Shacon desde RubyConf, y puedes navegar a través de 800 diapositivas, está ahí con algunos buenos ejemplos).

La pregunta es antigua, pero todavía no he encontrado una buena respuesta. Actualmente estoy enfrentando el mismo problema y debajo está mi solución para enfrentarlo:

Hay dos twigs en mi repository local: master y local_settings . Al cortar la twig local_settings del master local_settings allí todas las routes locales, sin labelr ni tratar de recordarlas. Durante el desarrollo local, me cambian a la twig local_settings , por lo que puedo ejecutar una aplicación usando routes locales. Pero cuando es hora de comprometerlo escondo un estado actual y cambio a la twig master . Luego hago estallar el set de cambios escondido y lo envío al master . Y el último paso es volver a local_settings , fusionar desde el master y continuar el desarrollo. Para recapitular: me comprometo en la twig local_settings solo cambios que se mantendrán localmente y nunca entrarán en master; y no se fusiona de local_settings a master .

Ahora digamos que necesito agregar una modificación "buena" a un file con una ruta local añadida anteriormente, pero la modificación "buena" es deseada en la twig master . local_settings mis cambios cuando la copy de trabajo es una cabecera para local_settings , la local_settings y eche un vistazo a master . El alijo mantiene un set de cambios, que es relativo a local_settings , aunque ya estoy en el master . git stash pop aplica el set de cambios ocultos a la copy de trabajo y termina teniendo una diferencia relativa al maestro, pero solo con la modificación reciente excluyendo la ruta local que se había agregado anteriormente y que no formaba parte del set de cambios oculto recientemente. Por lo tanto, puede comprometerse sin desorderar paths en la twig master . Luego, una vez más, se fusionan de master a local_settings .