tag - git ver archivos modificados
Git: Ignorar archivos para repositorio público, pero no para privado (8)
Estoy implementando una aplicación Rails en Heroku (por ahora) a través de git, y también me gustaría tener una versión pública para que la gente la mire. Algunos archivos son confidenciales y solo deben enviarse y enviarse a la rama "heroku", pero no a la rama "pública". ¿Cuál es la mejor manera de hacerlo?
(Sé sobre las variables de configuración de Heroku, lo cual es genial como una solución temporal, pero no es divertido si necesito cambiar de host).
No es necesario sincronizar las dos ramas en todo momento: estoy de acuerdo con fusionar periódicamente la rama "principal" en la rama "pública" y empujarla a github por separado.
He intentado varias cosas:
archivos
.gitignore
separados y una estrategia de fusión "nuestra" - esto no funcionó al principio, y después de jugar con eso por un tiempo decidí que se estaba volviendo demasiado complicado solo para poder lograr una tarea aparentemente simpleutilizando un archivo de
exclude
personalizada y agregando lo siguiente a.git/config
... esto simplemente no funcionó:
.git / config
[branch "public"]
excludesfile = +info/exclude_from_public
¿Cuál es la mejor manera de tener un repositorio público y privado para compartir el mismo código, pero ignorar los archivos confidenciales en el repositorio público?
Puede suponer que no se ha confirmado o enviado ningún código, es decir, que se trata de un repositorio recién inicializado.
(Esta pregunta se ha formulado anteriormente en varias formas, pero ninguna de las respuestas fue directa o las respuestas parecían realmente hacky. Estoy aquí para preguntarle de una manera muy simple, y espero recibir una respuesta muy simple).
Aquí hay algunas otras preguntas y respuestas de a lo largo de la línea de "cómo se fusiona ignorando algunos archivos":
- Git: fusionando ramas públicas y privadas mientras se mantienen ciertos archivos intactos en ambas ramas
- git merge debe ignorar un directorio
- ¿Cómo fusionas archivos selectivos con git-merge?
- ¿Cómo haces que Git ignore los archivos sin usar .gitignore?
- Código público y privado en un único repositorio de Git
- ¿Cómo le digo a git que siempre seleccione mi versión local para las fusiones en conflicto en un archivo específico?
Lo más simple que puedo pensar es utilizar una combinación de alias
que eliminará los archivos privados antes de realizar la fusión. Esto funcionaría si estás dispuesto a vivir con fusiones no rápidas. Aquí está el alias
:
git config alias.merge-master-exclude-private ''!git merge --no-commit --no-ff master && (git diff --name-only HEAD..master | grep -f private_files | while read f; do git reset HEAD -- "$f"; rm -f "$f"; done; git commit -m "Merge master, excluding private files.")''
Luego edite el archivo private_files
y agregue patrones de archivos que sean privados; por ejemplo secret_file.*$
. Puede reemplazar private_files
en el alias con "$(git rev-parse --show-toplevel)"/private_files
para leer private_files
desde el directorio de nivel superior.
Use git merge-master-exclude-private
para hacer la fusión. Esto ejecutará una fusión sin avance rápido sin cometer, encontrará archivos que coincidan con los patrones en el archivo private_files
, reset
el índice de cualquier archivo privado encontrado, eliminará los archivos privados en el directorio de trabajo y luego confirmará. Esto debería manejar los archivos que tienen espacios en blanco en sus nombres.
Si no desea realizar la confirmación, dándole la oportunidad de editar el mensaje de confirmación, elimine -m "Merge master, excluding private files."
del alias
Crea 2 ramas. La única rama que tiene los archivos privados no se enviará al repositorio público. Después de una fusión, restaure los archivos en cuestión con git checkout HEAD^ -- files that should not have been merged
, rm other files
, git add -A
y git commit --amend -C HEAD
. No estoy seguro de cuál es la diferencia en los archivos en cuestión, pero entiendes la idea. Haga un pequeño script para esto y estará listo para comenzar. Incluso podría enviar una lista de archivos confidenciales que haya confirmado en la raíz y la secuencia de comandos podría actuar fuera de eso.
Parece que podrías usar el mine
.
Básicamente, le dice a git que se mantenga alejado de las cosas siguiendo el <file or directory>_mine_
la <file or directory>_mine_
y la herramienta en sí le brinda una función de snapshot
, clean
y restore
, no un versión de pleno derecho, pero para cosas personales hace el truco muy bien.
Todo el asunto es bastante conciso .
Puede crear un enlace precompromiso en su repositorio local, aquí puede escribir un guión para verificar la rama actualmente desprotegida y eliminar los archivos ofensivos si están presentes antes de que se procese el compromiso. Esto evita que los archivos se graben en el historial de Git de la sucursal incorrecta.
#!/bin/bash
current_branch="$(git branch | sed -e ''s/^*//'')"
if [ $current_branch != "heroku" ]; then
// Delete sensitive files before commit
rm -f dir1/dir2/exclude_from_public
rm -f dir1/dir2/exclude_from_public_also
fi
exit 0
Alternativamente, la secuencia de comandos solo podría verificar los archivos y devolver el código de salida "1", notificándole que la confirmación no puede continuar porque contiene archivos confidenciales.
La advertencia es que tendrá que entregar este script a cualquier persona que esté trabajando en la sucursal heroku "privilegiada", y siempre tenerlo incluido en su propio repositorio local.
Lo ideal sería tener este cheque hecho también en el servidor; pero, desafortunadamente, GitHub solo ofrece una variante Web del gancho posterior a la recepción, por lo tanto, a menos que sea su propio hosting repo, este enfoque solo puede realizarse localmente.
Sé que esto deja de lado la pregunta, pero simplemente tendría dos repositorios de git. Luego puede agregarlos permanentemente a la lista de ignorar en el repositorio público.
Puede tener un segundo repositorio para los archivos privados y un pequeño script para copiar los cambios en la ubicación correcta en el sistema de producción, al realizar su implementación.
Esto reduce el riesgo de que cuando se vaya de vacaciones y el nuevo pasante actualice el repositorio público, su información privada se filtre accidentalmente. ;-)
Secundaré la respuesta del submódulo, pero trato de proporcionar alguna aclaración. En primer lugar, git no se ocupa de los archivos, sino de los commits. No hay forma de filtrar archivos o rutas en una rama porque una rama es realmente un puntero a una confirmación. Cuando excluye o ignora, simplemente evita que los archivos se agreguen a su repositorio. ninguno de los archivos de "archivos confidenciales" está incluso en el repositorio, solo en su directorio de trabajo.
El submódulo es solo una referencia a otro repositorio almacenado en su repositorio, y una confirmación específica que ese repositorio revisado está rastreando. puedes decir actualizar usando
git submodule update --recursive sensitive-files
Para simplificar las cosas, puede asignar enlaces simbólicos en el lugar adecuado apuntando a la ruta del submódulo.
ln -sf sensitive-files/shadow passwd
A continuación, agregue el enlace simbólico como lo haría con cualquier otro archivo.
Recuerde que el submódulo es solo un repositorio git desprotegido, puede restringir fácilmente el acceso a ese repositorio real y hacer público el principal.
Actualizado:
Lamento haberme perdido la notificación, si todavía está trabajando en esto.
Puede tener múltiples enlaces simbólicos en su repositorio privado haciendo referencia al repositorio privado (submódulo) que está desprotegido en un subdirectorio. Cada una de las bases de datos o lo que sea que use la instancia de Rails podría ser un enlace simbólico a ese subdirectorio privado.
Además, no necesita un puntero remoto al repositorio privado, solo una entrada en el archivo .gitmodules que se mantiene automáticamente en el submódulo de git . Aún necesitaría proteger el repositorio privado para que solo su instancia de Heroku pueda acceder a él. Para eso, le sugiero que instale la gitosis en un servidor si puede o puede usar alguna otra solución privada de hospedaje de git. Agregue la clave pública ssh que coincida con la clave privada de su instancia a la lista de usuarios permitidos. (No estoy familiarizado con cómo hacer esto en Heroku).
Cuando insertas tus cambios en heroku debes descargar recursivamente todos los submódulos mencionados en el repositorio.
Un tipo llamado David Albert escribió una herramienta llamada Junk para resolver casi exactamente este problema. Permite que los archivos de un repositorio de "cajones de basura" por separado vivan junto a los que están en su repositorio principal.
Los archivos privados tendrán confirmaciones separadas de las públicas, pero podría hacer el trabajo.
Una forma de hacerlo sería colocar su (s) archivo (s) privado (s) en un submódulo , y hacer referencia a ese módulo desde su repositorio público. (Alternativamente, podría colocar sus archivos públicos en un submódulo y referirse a ese repositorio desde su repositorio privado).