2010-04-06 15 views
66

¿Es posible clonar solo una rama (o una confirmación dada) en Git y Mercurial? Quiero decir, quiero clonar un repositorio central pero, como es enorme, me gustaría obtener solo una parte y poder contribuir con mis cambios. ¿Es posible? Al igual, solo quiero desde Tag 130 en adelante o algo así?Clon parcial con Git y Mercurial

Si es así, ¿cómo?

Respuesta

67

En Git tierra que estamos hablando de tres diferentes tipos de clones parciales:

  • clones poco profundas: Quiero la historia de la revisión del punto X en adelante.

    Uso git clone --depth <n> <url> para eso, pero por favor recuerde que los clones de poca profundidad son un tanto limitados en la interacción con otros repositorios. Podrías generar parches y enviarlos por correo electrónico.

  • clon parcial por vía de archivo: Quiero toda la historia historial de revisiones en algún directorio /path.

    No es posible en Git. Con Git moderno, aunque puede tener check out disperso, es decir, tiene todo el historial, pero echa un vistazo (tiene en el área de trabajo) solo un subconjunto de todos los archivos.

  • clonación sólo determinada rama: I desea clonar solamente una rama (o subconjunto seleccionado de ramas).

    posible y

    antes de Git 1.7.10 no es simple: lo que se necesita para hacer lo que hace el clon de forma manual, es decir git init [<directory>], entonces git remote add origin <url>, editar .git/config reemplazando * en remote.origin.fetch solicitado por rama (probablemente 'maestro '), luego git fetch.

    as of git 1.7.10git clone ofrece la opción --single-branch que parece que se ha agregado solo para este propósito, y parece bastante fácil.

    Sin embargo, tenga en cuenta que debido a que las sucursales generalmente comparten la mayor parte de su historial, la ganancia de clonar solo un subconjunto de ramas podría ser menor de lo que cree.

También puede hacer un clon superficial del único subconjunto de ramas seleccionado.

Si sabe cómo la gente querrá dividir las cosas por filepath (proyectos múltiples en el mismo repositorio) puede usar submódulos (tipo svn: externals) para dividir previamente el repositorio en partes clonables por separado.

+0

Entonces, si clono la rama "XX", obtendrá todas las confirmaciones principales de "maestro", ¿verdad? ¿O solo la única confirmación que hice en esa rama? – pablo

+1

Si clona (busca) solo la rama "XX", obtendrá todas sus confirmaciones, incluidas las confirmaciones que la rama "XX" tiene en común con la rama "principal". En Git commits no '* belong *' a una rama. –

+0

Ok, entonces no es un clon parcial de todos modos ya que obtienes todos los padres y por lo tanto todos los repos (ok, la parte más grande que está en el maestro) – pablo

41

En tierra mercurial que estamos hablando de tres diferentes tipos de clones parciales:

  • clones poco profundas: Quiero la historia de la revisión del punto X en adelante utilizan los clones parciales remotefilelog extension
  • por vía de archivo: Quiero todo el historial de revisión en el directorio/ruta con experimental narrowhg extension o quiero que solo los archivos en el directorio/ruta estén en mi directorio de trabajo con extensión dispersa experimental (enviado desde la versión 4.3, ver hg help sparse).
  • clones parciales por rama: Quiero que todos historial de revisiones en la rama Y: uso clon -r

Si sabe cómo la gente va a querer romper las cosas por vía de archivo (múltiples proyectos en el mismo repo (Que pena por ti)) puedes usar subrepositorios (algo así como svn externals) para dividir previamente el repositorio en porciones clonables por separado

Además, en cuanto a "tan grande me gustaría obtener solo una parte" : Realmente solo tienes que hacer eso una vez. Solo clonalo mientras almuerzas, y luego lo tienes para siempre. A continuación, puede pull y obtener deltas de manera eficiente en el futuro. Y si quieres otro clon, clona tu primer clon. Dónde obtienes un clon no importa (y los clones locales no ocupan espacio adicional en el disco ya que son enlaces duros bajo las sábanas).

+1

también las etiquetas no son lo mismo que las ramas a diferencia de algunos VCS por lo que esto viene bajo el primer punto –

+0

Hay el historial de recorte (http://mercurial.selenic.com/wiki/TrimmingHistory) y el clon superficial (http://mercurial.selenic.com/wiki/ShallowClone) complementos para mercurial. Sin embargo, no sé lo buenos que son. – panzi

+8

Ambos son propuestas rechazadas sin implementaciones. –

-1

En mercurial, usted debe ser capaz de lo que algunos de esto usando:

hg convert --banchmap FILE SOURCEDEST REVMAP 

Usted también puede querer:

--config convert.hg.startrev=REV 

La fuente puede ser git, mercurial, o una variedad de otros sistemas.

No lo he probado, pero convertir es bastante rico.

+3

Convertir la extensión reescribe los hashes, por lo tanto, esto no es parcial clon del repositorio existente, sino uno nuevo. Lo que significa que será un repositorio separado que no puede extraer o empujar del original. – Priit

5

Este método crea un archivo no versionado sin subrepositories:

hg clone -U ssh://machine//directory/path/to/repo/project projecttemp 

cd projecttemp 

hg archive -r tip ../project-no-subrepos 

El código fuente sin versión sin las subrepositoies está en el directorio del proyecto-no-subrepos

2

En cuanto a Git que podría ser de una importancia histórica que Linus Torvalds respondió a esta pregunta desde la perspectiva conceptual en 2007 en una charla que fue grabada y está disponible en línea.

La pregunta es si es posible verificar solo algunos archivos de un repositorio de Git.

Tech Talk: Linus Torvalds on git t=43:10

Para resumir, dijo que una de las decisiones de diseño de Git que lo diferencia de otros sistemas de gestión de la fuente (que cita Bitkeeper y SVN) es que Git administra el contenido, no los archivos. Las implicaciones son que, p. una diferencia de un subconjunto de archivos en dos revisiones se calcula tomando primero la diferencia completa y luego limitándola solo a los archivos que se solicitaron. Otra es que debes verificar toda la historia; de una manera todo o nada. Por esta razón, sugiere dividir componentes poco relacionados entre múltiples repositorios y menciona un esfuerzo en curso para implementar una interfaz de usuario para administrar un repositorio que está estructurado como un superproyecto que contiene repositorios más pequeños.

Por lo que sé, esta decisión de diseño fundamental todavía manzanas hoy. El súper proyecto probablemente se convirtió en lo que ahora es submodules.

+1

Conozco la publicación ... Originalmente la envié a slashdot: P – pablo

6

La respuesta seleccionada proporciona una buena visión general, pero carece de un ejemplo completo.

Minimizar la descarga y la salida huella (a), (b):

git clone --no-checkout --depth 1 --single-branch --branch (name) (repo) (folder) 
cd (folder) 
git config core.sparseCheckout true 
echo "target/path/1" >>.git/info/sparse-checkout 
echo "target/path/2" >>.git/info/sparse-checkout 
git checkout 

Periódicamente optimizar su huella repositorio local (c) (opcional, utilizar con cuidado):

git clean --dry-run # consider and tweak results then switch to --force 
git gc 
git repack -Ad 
git prune 

Véase también : How to handle big repositories with git

+0

Muy buen ejemplo/mejor práctica. +1 – VonC

Cuestiones relacionadas