2012-08-15 12 views
7

Me pregunto qué sucede cuando se hace una horquilla en github.Explicación de la horquilla Github y cómo almacenan los archivos

Por ejemplo, cuando trabajo un proyecto, ¿hace una copia en el servidor github de todo ese código, o simplemente crea un enlace a él?

Otra pregunta: En git, ya que contiene todos los archivos al agregar el mismo archivo, no es necesario volver a almacenar el contenido del archivo porque el hash ya estará en el sistema, ¿correcto?

¿Es github como este? Entonces, si subo exactamente el mismo fragmento de código que otro usuario, cuando github gits lo hace, básicamente solo crea un enlace a ese archivo, ya que tendría el mismo hash, ¿o guardará todos sus contenidos de nuevo por separado?

Cualquier aclaración sería genial, gracias!

Respuesta

4

github.com es exactamente la misma semántica que git, pero con una interfaz gráfica de usuario basada en la web envuelta alrededor de ella.

Storage: "Git almacena cada revisión de un archivo como un objeto blob única"
Así que cada archivo se almacena de forma única, pero utiliza un hash SHA-1 para determinar los cambios de un archivo a otro.

En cuanto a github, un tenedor es esencialmente un clon. Esto significa que una nueva horquilla es una nueva área de almacenamiento en sus servidores, con una referencia a su ORIGEN. De ninguna manera establecería enlaces entre los dos, porque git por naturaleza puede rastrear los controles remotos. Cada tenedor sabe el upstream.

Cuando dice "si subo el mismo código exacto que otro usuario", el término "cargar" es un poco vago en el sentido "git". Si está trabajando en el mismo repositorio y git incluso le permite enviar el mismo archivo, eso significa que fue diferente y se verificó en esa revisión. Pero si te refieres a trabajar en un clon/tenedor de otro repositorio, sería la misma situación, pero tampoco se realizarían enlaces en el sistema de archivos al otro repositorio.

No puedo afirmar tener ningún conocimiento íntimo de qué optimizaciones Github podría estar haciendo bajo el capó, en su sistema interno. Posiblemente podrían estar haciendo operaciones personalizadas intermedias para ahorrar espacio en el disco. Pero cualquier cosa que harían sería transparente para usted y no importaría mucho, ya que efectivamente debería funcionar siempre bajo la semántica git esperada.

Un desarrollador en github wrote a blog post acerca de cómo internamente hacen su propio flujo de trabajo de git. Si bien no se refiere a su pregunta sobre cómo administrar el flujo de efectivo del servicio, creo que esta cita de la conclusión es bastante informativo:

Git en sí es bastante complejo de entender, por lo que el flujo de trabajo que lo utilizas con más complejidad de la necesaria simplemente agregando más sobrecarga mental a todos los días. Siempre recomendaría usar el sistema más simple posible que funcionará para su equipo y hacerlo hasta que no funcione más y luego agregue la complejidad solo como absolutamente necesario.

Lo que llevo de esto, es que reconocen la complejidad de Git es por sí mismo, lo que muy probablemente se llevan el toque más ligero posible para envolver alrededor de ella para prestar el servicio, y dejar que git haga lo que hace mejor forma nativa .

+1

Es posible que github utilice algún tipo de optimización, como enlaces duros, mientras crea la horquilla, pero para todos los fines prácticos, es solo una clonación en el propio servidor github. –

+0

@NoufalIbrahim: Claro. Definitivamente es posible que se esfuercen por hacer una optimización interna para ahorrar espacio en el disco hasta que un tenedor realmente comprometa una revisión del archivo. Pero eso sería transparente para los usuarios realmente. Buen punto sin embargo. – jdi

+0

@NoufalIbrahim: Aunque como lo pienso más, podría ser una situación complicada, porque como sabemos, cuando el repositorio de subida recibe nuevas confirmaciones, no tiene ningún efecto sobre las horquillas. Ellos son responsables de buscar aguas abajo de forma individual. – jdi

1

No sé exactamente cómo lo hace GitHub, pero aquí hay una manera posible. Requiere cierto conocimiento de la forma en que git almacena sus datos.

La respuesta corta es que los repos pueden compartir la base de datos objects pero cada uno tiene sus propias referencias.
Incluso podemos simularlo localmente para una prueba de concepto.

En el anuario de un acuerdo de recompra desnudo (o en el .git/ subdirectorio si no es desnudo) hay tres cosas que son el mínimo para un acuerdo de recompra a trabajar:

  • la objects/ subdirectorio, que almacena todos los objetos (commits, trees, blobs ...). Se almacenan individualmente como archivos con nombres iguales al hash del objeto o en los archivos .pack.
  • subdirectorio refs/, que almacena archivos simples como refs/heads/master cuyo contenido es el hash del objeto al que hace referencia.
  • el archivo HEAD, que dice cuál es la confirmación actual. Su valor es un hash puro (que corresponde a un cabeza separada, es decir, no estamos en ninguna rama con nombre) o un enlace de texto a un ref donde se puede encontrar el hash real (por ejemplo ref: refs/heads/master), eso significa que estamos en rama master)

Supongamos que alguien crea su cesión temporal original (no se bifurcan) orig en Github.
Para simular, localmente hacemos

$ git init --bare github_orig 

Nos imaginamos que lo anterior ocurre en los servidores de Github. Ahora hay un repositorio github vacío. A continuación, nos imaginamos que a partir de nuestra propia PC clonamos el repositorio GitHub:

$ git clone github_orig local_orig 

Por supuesto, en la vida real en lugar de github_orig usaremos https://github.... Ahora hemos clonado el repositorio de github en local_orig.

$ cd local_orig/ 
$ echo zzz > file 
$ git add file 
$ git commit -m initial 
$ git push 
$ cd .. 

Después object dir este github_orig 's contendrá nuestra empujado cometer objeto, un objeto blob para file y un objeto árbol. El archivo refs/heads/master contendrá el hash de confirmación.

Ahora imaginemos qué podría estar pasando cuando alguien presione el botón Fork. Vamos a crear un repositorio git, pero a mano:

$ mkdir github_fork 
$ cd github_fork/ 
$ cp ../github_orig/HEAD . 
$ cp -r ../github_orig/refs . 
$ ln -s ../github_orig/objects 
$ cd .. 

en cuenta que nos copiamos HEAD y refs pero hacer un enlace simbólico para objects. Como podemos ver, hacer una horquilla es muy barata. Incluso si tenemos decenas de ramas, cada una de ellas es simplemente un archivo en el directorio refs/heads que contiene un hash hexadecimal simple (40 bytes). Para objects solo vinculamos al directorio de objetos original, ¡no copiamos nada!

Ahora simulamos que el usuario que realiza la tenedor, los clones del repo bifurcada localmente:

$ git clone github_fork local_fork 
$ cd local_fork 
$ # ls 
.git/ file 

podemos ver que hemos clonado con éxito a pesar de que el repositorio que clonar no tiene sus propios objects pero los enlaces a la del repositorio original.
Ahora el usuario de horquilla puede hacer ramas, confirmaciones y luego empujarlas al github_fork. Los objetos se insertarán en el directorio objects, que es el mismo para github_orig. Pero refs y HEAD se modificarán y ya no coincidirán con los del github_orig.

Por lo tanto, la conclusión es que todos los repos que pertenecen al mismo árbol de bifurcación comparten un fondo común de objetos , mientras que cada repositorio contiene sus propias referencias. Cualquiera que empuje commits a su propio repositorio bifurcado modifica sus propias referencias pero coloca los objetos en un grupo compartido.

Por supuesto, para ser realmente utilizable algunas cosas más hay que tener cuidado de - lo más importante es el colector git basura debe no ser invocada a menos que la cesión temporal en el que se invoca en cuenta el conocimiento de todos referencias - no sólo su propio. De lo contrario, podría descartar objetos en el grupo compartido que no son accesibles desde sus referencias pero que podrían ser accesibles desde otros reposs refs.

0

Según https://enterprise.github.com/releases/2.2.0/notes GitHub Empresa (y supongo que GitHub) de alguna manera comparte objetos entre horquillas para reducir el uso de espacio en disco:

Esta versión cambia la forma en GitHub Enterprise almacena los repositorios, que reduce el uso del disco mediante el intercambio de Git los objetos entre las horquillas y mejoran el rendimiento del almacenamiento en caché al leer los datos del repositorio.

También hay más detalles acerca de cómo lo hacen en https://githubengineering.com/counting-objects.

Cuestiones relacionadas