Un escenario común cuando desarrollo es que el código base tendrá varios archivos de configuración que requieren configuraciones específicas de la máquina. Estos archivos se registrarán en Git y otros desarrolladores siempre los verificarán accidentalmente y romperán la configuración de otra persona.
Una solución simple para esto sería simplemente no registrarlos en Git, o incluso agregarles una entrada .gitignore. Sin embargo, encuentro que es mucho más elegante tener algunos valores predeterminados sensibles en el archivo que el desarrollador puede modificar para satisfacer sus necesidades.
¿Existe una forma elegante de hacer que Git funcione bien con estos archivos? Me gustaría poder modificar un archivo de configuración específico de la máquina y luego poder ejecutar "git commit -a" sin registrar ese archivo.
fuente
Respuestas:
Haga que su programa lea un par de archivos de configuración para su configuración. Primero, debería leer un
config.defaults
archivo que se incluiría en el repositorio. Luego, debería leer unconfig.local
archivo que debería estar listado en.gitignore
Con esta disposición, las nuevas configuraciones aparecen en el archivo de valores predeterminados y entran en vigencia tan pronto como se actualice. Solo variarán en sistemas particulares si se anulan.
Como una variación de esto, podría tener solo un
config
archivo general que envíe en control de versiones y hacer que haga algo comoinclude config.local
traer los valores específicos de la máquina. Esto introduce un mecanismo más general (versus una política) en su código y, en consecuencia, permite configuraciones más complicadas (si eso es deseable para su aplicación). La extensión popular de esto, que se ve en muchos software de código abierto a gran escala, es toinclude conf.d
, que lee la configuración de todos los archivos en un directorio.Vea también mi respuesta a una pregunta similar.
fuente
Puedes intentarlo
git update-index --skip-worktree filename
. Esto le dirá a git que finja que los cambios locales en el nombre del archivo no existen, por lo quegit commit -a
lo ignorará. Tiene la ventaja adicional de resistirgit reset --hard
, por lo que no perderá accidentalmente sus cambios locales. Además, las fusiones automáticas fallarán sin problemas si el archivo se cambia en sentido ascendente (a menos que la copia del directorio de trabajo coincida con la copia del índice, en cuyo caso se actualizará automáticamente). La desventaja es que el comando debe ejecutarse en todas las máquinas involucradas, y es difícil hacerlo automáticamente. Consulte tambiéngit update-index --assume-unchanged
una versión sutilmente diferente de esta idea. Los detalles de ambos se pueden encontrar congit help update-index
.fuente
--skip-worktree
en este caso.Otro enfoque es mantener los cambios locales en los archivos de configuración comunes en otra sucursal privada. Hago esto para algunos proyectos que requieren varios cambios locales. Es posible que esta técnica no sea aplicable a todas las situaciones, pero me funciona en algunos casos.
Primero creo una nueva rama basada en la rama maestra (en este caso particular estoy usando git-svn, así que necesito confirmar desde la maestra, pero eso no es muy importante aquí):
Ahora modifique los archivos de configuración según sea necesario y confirme. Normalmente pongo algo distintivo en el mensaje de confirmación como "NOCOMMIT" o "PRIVATE" (esto será útil más adelante). En este punto, puede trabajar en su rama privada usando su propio archivo de configuración.
Cuando desee impulsar su trabajo de nuevo en sentido ascendente, seleccione cada cambio de su
work
rama al maestro. Tengo un script para ayudar a hacer esto, que se parece a esto:Esto primero comprueba para asegurarse de que estoy en la
master
rama (comprobación de cordura). Luego, enumera cada confirmaciónwork
, filtra las que mencionan la palabra clave NOCOMMIT, invierte el orden y finalmente selecciona cada confirmación (ahora desde la más antigua primero) enmaster
.Finalmente, después de impulsar los cambios en el maestro aguas arriba, vuelvo a cambiar de
work
base:Git volverá a aplicar cada una de las confirmaciones en la
work
rama, omitiendo efectivamente las que ya se han aplicado amaster
través de la selección. Lo que debería quedarse es solo las confirmaciones locales de NOCOMMIT.Esta técnica hace que el proceso de inserción requiera un poco más de tiempo, pero me resolvió un problema, así que pensé en compartirlo.
fuente
git commit -a
sin preocupaciones en el mundo?git rebase --onto
ygit fetch
para hacer lo mismoUna posibilidad es tener los archivos reales en su .gitignore, pero verifique las configuraciones predeterminadas con una extensión diferente. Un ejemplo típico de una aplicación Rails sería el archivo config / database.yml. Verificaríamos config / database.yml.sample, y cada desarrollador crea su propia config / database.yml que ya es .gitignored.
fuente
Verifique una configuración predeterminada con una extensión diferente (por ejemplo. lo que se registra es config.default).
Además, escriba un script de instalación rápida que configure los enlaces simbólicos para toda su aplicación.
Usamos un enfoque similar en una empresa anterior. El script de instalación detectó automáticamente el entorno en el que estaba ejecutando (sandbox, desarrollo, control de calidad, producción) y automáticamente haría lo correcto. Si tuviera un archivo config.sandbox y estuviera ejecutando desde el sandbox, lo vincularía (de lo contrario, solo vincularía el archivo .defaults). El procedimiento común era copiar .defaults y cambiar la configuración según fuera necesario.
Escribir el script de instalación es más fácil de lo que imagina y le brinda mucha flexibilidad.
fuente
Estoy de acuerdo con la mejor respuesta pero también me gustaría agregar algo. Utilizo un script ANT para eliminar y modificar archivos del repositorio GIT, así que estoy seguro de que no se sobrescriben archivos de producción. Hay una buena opción en ANT para modificar los archivos de propiedades de Java. Esto significa poner sus variables de prueba locales en un archivo de propiedades de estilo java y agregar código para procesarlo, pero le brinda la oportunidad de automatizar la construcción de su sitio antes de enviarlo por FTP en línea. Normalmente, pondría su información de producción en el archivo site.default.properties y dejaría que ANT administre la configuración. Su configuración local estaría en site.local.properties.
luego úsalo:
Su site.default.properties se vería así:
y su site.local.properties se vería así (observe la diferencia entre el entorno y los módulos habilitados):
Y sus instrucciones ANT: ($ d {deploy} es su directorio de destino de implementación)
fuente
Hoy en día (2019) utilizo ENV vars, por ejemplo, en python / django, también puede agregarles valores predeterminados. En el contexto de la ventana acoplable, puedo guardar las vars ENV en un archivo docker-compose.yml o en un archivo adicional que se ignora en el control de versiones.
fuente
La solución más simple es editar el archivo a los valores predeterminados, confirmarlo y luego agregarlo a su archivo
.gitignore
. De esta manera, los desarrolladores no lo confirmarán accidentalmente cuando lo hagangit commit -a
, pero aún pueden hacerlo en el caso (presumiblemente raro) en el que desee cambiar sus valores predeterminadosgit add --force
.Sin embargo, tener un
.default
.local
archivo y config es en última instancia la mejor solución, ya que esto permite que cualquier persona con una configuración específica de la máquina cambie los valores predeterminados, sin tener que romper su propia configuración.fuente
.gitignore
posteriormente, los cambios aún se controlan.Lo hago como se recomienda aquí con archivos de configuración locales y predeterminados. Para administrar mis archivos de configuración locales que están en los proyectos
.gitignore
, hice un repositorio de git~/settings
. Allí administro todas mis configuraciones locales de todos los proyectos. Se crea, por ejemplo, una carpetaproject1
en~/settings
y poner todo el paquete de configuración local para este proyecto en él. Después de eso, puede enlazar simbólicamente esos archivos / carpeta a suproject1
.Con ese enfoque, puede realizar un seguimiento de sus archivos de configuración locales y no ponerlos en el repositorio de código fuente normal.
fuente
Sobre la base de la respuesta de @Greg Hewgill, puede agregar una confirmación específica con sus cambios locales y etiquetarla como localchange:
Luego proceda a agregar las confirmaciones de su función. Después de terminar el trabajo, puede fusionar esta rama de nuevo a master sin el compromiso localchange haciendo esto:
Estos comandos:
1) Vuelva a basar su rama de características en maestra, ignorando la confirmación de cambio local. 2) Avance rápido del maestro sin salir de la rama de características 3) Agregue el compromiso de cambio local en la parte superior de la rama de características para que pueda continuar trabajando en ella. Puede hacer esto en cualquier otra rama en la que desee seguir trabajando. 4) Restablezca la etiqueta localchange a esta confirmación elegida con precisión para que podamos usarla
rebase --onto
nuevamente de la misma manera.Esto no pretende reemplazar la respuesta aceptada como la mejor solución general, sino como una forma de pensar fuera de la caja sobre el problema. Básicamente, evita fusionar accidentalmente los cambios locales con el maestro simplemente reajustando de
localchange
afeature
y el maestro de avance rápido.fuente