2012-09-19 15 views
5

En mi sistema de archivos local, quiero solo clonar el jefe de git repo (A) para que no haya ningún historial en un nuevo git repo (B). Pero quiero los beneficios de los enlaces duros para los archivos ahora en B para ahorrar espacio. ¿Hay alguna forma de hacer esto? ¿Los enlaces duros incluso ayudan una vez que el repositorio A cambia?Clonación de git poco profunda local con enlaces duros

Gracias!

Respuesta

6

Parece que es imposible hacer una clonación local superficial con enlaces duros entre bases de datos de objetos, al menos desde git 1.7.12. git clone --depth 1 --single-branch advierte explícitamente que --depth se ignora en los clones locales, y para usar file://. Por lo tanto, deberá elegir entre enlaces duros y clonación superficial.

Los enlaces duros funcionan incluso cuando el repositorio cambia, al menos por un tiempo, porque git agrega nuevos objetos a los archivos nuevos, y nunca modifica los archivos existentes. Sin embargo, ocasionalmente vuelve a empaquetar la base de datos de objetos para su eficiencia, y no veo cómo se podrían preservar los enlaces duros.

Si elige clonación superficial, puede crear el clon con las opciones git clone --single-branch --depth 1 file://old_repo_dir. Me resulta molesto que --depth 1 signifique 1 elemento de historial, por lo que obtendrá no solo la última confirmación, sino también su padre (o sus padres si se trata de una fusión). El padre obtiene el mensaje de confirmación del repositorio original, pero el mensaje de confirmación se encuentra porque la confirmación en realidad contiene la creación de todo el árbol.

Prefiero comenzar con una confirmación simple con un mensaje de confirmación de mi elección que crea el árbol inicial. Esto se obtiene creando primero una nueva rama sin historial en el repositorio anterior y luego insertando esa rama en el nuevo repositorio vacío. Probé esto en un repo enorme con una base de datos de objetos de 664MB con objetos de 673k (el repositorio bzr de Emacs convertido a git). Cuando el nuevo repositorio recibió la extracción, tenía una base de datos de objetos de 36MB con 3477 objetos, por lo que el contenido excedente aparentemente fue eliminado. Estos son los pasos exactos:

# at the old repo: 
git checkout --orphan tmp-snapshot 
git commit -m "Initial commit." 

# at the new repo location: 
git init 
git pull OLD_REPO_DIR tmp-snapshot:master 

# back at the old repo: 
git branch -D tmp-snapshot # no longer serves a purpose 

Ahora la rama master de la nueva operación contiene una única confirmación con un árbol idéntico al árbol de la edad de recompra, y sin ninguna historia.

+0

¿Qué le sucede a la sucursal en el padre? – Jeff

+0

Nada; te deshaces de él con 'git branch -D' si no lo necesitas. Esa rama no requiere espacio adicional en el repositorio principal, ya que consiste en una única confirmación que apunta a un árbol que (obviamente) ya existe en el repositorio. – user4815162342

+0

En las versiones actuales de git '--depth' [implica] (https://www.git-scm.com/docs/git-clone)' --single-branch'. – sphakka

2

Puede clonarlo y luego volver a crear el compromiso de la cabeza despojando a los padres. Teniendo en cuenta que los objetos de su repositorio original probablemente estén en paquetes, de todos modos enlazará más de lo que desee. Y sí, los enlaces duros permanecerán intactos por un tiempo, pero una vez que comiences a hacer gc o algo así, el efecto probablemente desaparecerá. También puede usar alternativas en lugar de enlaces duros.

Busque los documentos para git commit-tree para crear una confirmación del árbol, no puedo decirle la sintaxis exacta.

+2

'git checkout --orphan' seguido de' git commit' crea una confirmación del árbol sin recurrir a la fontanería. – user4815162342

+0

@ user4815162342, gracias, no lo sabía. –

Cuestiones relacionadas