Pregunta Git: Ignorar archivos para repositorio público, pero no para privado


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?

(YO hacer conocer las variables de configuración de Heroku, que es genial como una solución temporal, pero no es divertido si y cuando 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:

  • separar .gitignore archivos 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 simple

  • usando una costumbre exclude archivo 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 De Verdad hacky. Estoy aquí para preguntarle esto de una manera muy simple, y espero recibir una respuesta muy simple.)


32
2018-01-04 04:23


origen


Respuestas:


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 señalamiento remoto para el repositorio privado, solo una entrada en el archivo .gitmodules que se mantiene automáticamente por submódulo 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.


16
2018-01-14 03:23



Podrías crear un pre-commit hook en su repositorio local, aquí puede escribir una secuencia de comandos para verificar la rama actualmente desprotegida y eliminar los archivos ofensivos si están presentes antes de que se procese la confirmación. 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 debe incluirlo en su 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.


7
2018-01-13 17:47



Una forma de hacerlo sería colocar su (s) archivo (s) privado (s) en un submódulo, y refiérase a ese módulo desde su repositorio público. (Alternativamente, podrías poner tu público archivos en un submódulo, y se refieren a ese repositorio desde su repositorio privado).


2
2018-01-04 04:28



Aquí hay algunas otras preguntas y respuestas de StackOverflow a lo largo de la línea de "cómo se fusiona ignorando algunos archivos":

Lo más simple que puedo pensar es usar un alias'ed fusión que eliminará los archivos privados antes de hacer la fusión de compromiso. Esto funcionaría si estás dispuesto a vivir con fusiones no rápidas. Aquí esta la 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 edita el private_files archivar y agregar patrones de archivos que son privados; por ejemplo secret_file.*$. Usted podría reemplazar private_files en el alias con "$(git rev-parse --show-toplevel)"/private_files leer private_files desde el directorio de nivel superior.

Utilizar git merge-master-exclude-private para hacer la fusión Esto ejecutará una fusión sin avance rápido sin comprometer, buscar archivos que coincidan con los patrones en el private_files archivo, reset el índice de cualquier archivo privado encontrado, eliminar los archivos privados en el directorio de trabajo, luego confirmar. Esto debería manejar los archivos que tienen espacios en blanco en sus nombres.

Si no quiere hacer la confirmación, dándole la oportunidad de editar el mensaje de confirmación, elimine -m "Merge master, excluding private files." del alias


2
2018-01-13 21:28



Un tipo llamado David Albert escribió una herramienta llamada basura 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.


2
2018-01-19 17:25



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.


1
2018-01-04 06:24



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. ;-)


0
2018-01-17 07:25



Parece que podrías usar mine.

Básicamente, le dice a git que se mantenga alejado de las cosas siguiendo la convención <file or directory>_mine_ y la herramienta en sí te da snapshot, cleany restore función, no versiones de pleno derecho, pero para cosas personales hace el truco muy bien.

Todo es bastante conciso.


0
2017-08-05 03:31