repositorio - ¿Puedo guardar la carpeta.git fuera de los archivos que quiero rastrear?
git ver archivos modificados (9)
Suponiendo que sus directorios myfiles
ya existan y tengan algún contenido, ¿podría vivir con esto?
cd ~/backup
git init
git add myfiles
El directorio .git
estará en backup
, no en myfiles
.
Tengo la inusual idea de usar git como sistema de respaldo. Entonces digamos que tengo un directorio ./backup/myfiles y quiero respaldarlo usando git. Para mantener las cosas limpias, no quiero tener un directorio .git en la carpeta myfiles, así que pensé que podría crear ./backup/git_repos/myfiles. Al mirar los documentos de Git, intenté hacer esto:
$ cd backup/myfiles
$ mkdir ../git_repos/myfiles
$ git --git-dir=../git_repos/myfiles init
Initialized empty Git repository in backup/git_repos/myfiles/
$ git --git-dir="../git_repos/myfiles/" add foo
fatal: pathspec ''foo'' did not match any files
Puedes ver el mensaje de error que recibo allí. ¿Qué estoy haciendo mal?
Podrías crear un script "nodgit" (No Dot GIT) con algo como
#!/bin/sh
gits=/usr/local/gits
x=`pwd`
testdir() {( cd $1; pwd; )}
while [ "$x" != "/" ]; do
y=`echo $x|sed -e "s////__/g"`
if ([ -d "$gits/$y" ]); then
export GIT_DIR="$gits/$y"
export GIT_WORK_TREE="$x"
if ([ "$1" = "nodinit" ]); then
mkdir -p "$GIT_DIR"
git init --bare; exit $?
elif ([ "$1" = "shell" ]); then
bash; exit $?
else
exec git "$@"
fi
fi
x=`testdir "$x/.."`
done
Puedes llamar a nodgit en lugar de git y establecerá las variables según sea necesario buscando un git repo. Por ejemplo, supongamos que tiene un repositorio (vacío) en / usr / local / gits / __ home__foo_wibbles y está en / home / foo / wibbles / one y luego encontrará el directorio de trabajo correcto (/ home / foo / wibbles) y el repo .
Oh, también puedes usar "nodgit shell" para obtener un shell con el conjunto de vars correcto para que puedas usar comandos old git.
Use git
dentro del repositorio:
cd ./backup/git_repos/myfiles
git init --bare
git config core.worktree ../myfiles
git config core.bare false
A partir de ahora, puedes usar git
dentro del directorio ./backup/git_repos/myfiles
, sin establecer ninguna variable de entorno o parámetros adicionales.
Es convencional nombrar un directorio que es un repositorio git que tiene su árbol de trabajo en un lugar inusual con una extensión ''.git'', muy parecido a un repositorio simple.
mkdir ../git_repos/myfiles.git
Si hubiera proporcionado la opción --work-tree
en la hora de inicio, esto habría configurado automáticamente la variable de configuración core.worktree
, lo que significa que git sabrá dónde encontrar el árbol de trabajo una vez que especifique el directorio de git.
git --git-dir=../git_repos/myfiles.git --work-tree=. init
Pero también puedes establecer esta variable después del hecho.
git --git-dir=../git_repos/myfiles.git config core.worktree "$(pwd)"
Una vez que haya hecho esto, el comando agregar debería funcionar como se esperaba.
git --git-dir=../git_repos/myfiles.git add foo
Solo necesita asegurarse de que el repositorio sepa dónde está el árbol de trabajo y viceversa.
Para que el repositorio sepa dónde está el árbol de trabajo, establezca el valor de configuración core.worktree
. Para que el árbol de trabajo sepa dónde está el directorio de git, agregue un archivo llamado .git (¡no una carpeta!) Y agregue una línea como
gitdir: /path/to/repo.git
Desde git 1.7.5, el comando init aprendió una opción adicional para esto.
Puede inicializar un nuevo repositorio separado con
git init --separate-git-dir /path/to/repo.git
Esto inicializará el repositorio de git en el directorio separado y agregará el archivo .git en el directorio actual, que es el directorio de trabajo del nuevo repositorio.
Anteriormente a 1.7.5 , tenía que usar parámetros ligeramente diferentes y agregar el archivo .git usted mismo.
Para inicializar un repositorio separado, el siguiente comando vincula el árbol de trabajo con el repositorio:
git --git-dir=/path/to/repo.git --work-tree=. init && echo "gitdir: /path/to/repo.git" > .git
Su directorio actual será el árbol de trabajo y git usará el repositorio en /path/to/repo.git
. El comando init establecerá automáticamente el valor core.worktree
como se especifica con el parámetro --git-dir
.
Incluso podría agregar un alias para esto:
[alias]
initexternal = !"f() { git --work-tree=. --git-dir=/"$1/" init && echo /"gitdir: $1/" >> .git; }; f"
Utilice el control de versión git en un directorio de trabajo de solo lectura
Con el conocimiento anterior, incluso puede configurar el control de versión de git para un directorio de trabajo sin tener permisos de escritura. Si utiliza --git-dir
en cada comando de git o ejecuta cada comando desde el repositorio (en lugar del directorio de trabajo), puede omitir el archivo .git y, por lo tanto, no es necesario crear ningún archivo dentro del directorio de trabajo . Véase también la respuesta de Leos
Creo scripts que se parecen
~ / bin / git-slash:
#!/usr/bin/sh
export GIT_DIR=/home/Version-Control/cygwin-root.git/
export GIT_WORK_TREE=/
git --git-dir=$GIT_DIR --work-tree=$GIT_WORK_TREE "$@"
exit $?
Es redundante utilizar --git_dir = $ GIT_DIR, pero me recuerda que también puedo establecer variables de entorno fuera del script.
El ejemplo anterior es para hacer un seguimiento de los cambios locales en los archivos del sistema cygwin.
Puede hacer uno de esos guiones para cualquier proyecto importante que lo necesite, pero / sin /.git es mi principal uso.
Lo anterior es lo suficientemente pequeño como para crear un alias o función de shell, si elimina la redundancia.
Si hago esto con la suficiente frecuencia, reviviría el espacio de trabajo para mapeo de repositorios de
"Boxes, Links, and Parallel Trees: Elements of a Configuration Management System",
in Workshop Proceedings of the Software Management Conference. 1989.
cuya contraparte moderna más cercana son las asignaciones o vistas de Perforce , que respaldan los pagos parciales, así como la no colocación del espacio de trabajo y el repositorio.
La --separate-git-dir
para git init
(y git clone
) se puede usar para lograr esto en mi versión de git ( 1.7.11.3
). La opción separa el repositorio git del árbol de trabajo y crea un enlace simbólico git agnóstico del sistema de archivos (en forma de un archivo llamado .git
) en la raíz del árbol de trabajo. Creo que el resultado es idéntico a la respuesta de niks .
git init --separate-git-dir path/to/repo.git path/to/worktree
Me resulta más sencillo invertir los --work-tree
y --git-dir
utilizados en la respuesta de niks:
$ cd read_only_repos
$ git --work-tree=/some/readonly/location/foo/ --git-dir=foo init
$ cd foo
$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
.file_foo
bar
...
Este enfoque tiene dos ventajas:
- Elimina la necesidad de tener opciones de línea de comandos o archivos
.git
. Simplemente opera normalmente desde la raíz del repositorio. - Le permite versionar un sistema de archivos incluso si no lo posee. Git solo escribirá en la ubicación del repositorio.
La única advertencia que he encontrado es que, en lugar de utilizar un archivo .gitignore
, editas info/exclude
.
A continuación, puede usar el repositorio read_only_repos/foo
como un control remoto en sus propios repositorios, incluso si los archivos originales no están bajo control de versión.
git --git-dir=../repo --work-tree=. add foo
Esto hará lo que quieras, pero obviamente apestará cuando lo tengas que especificar con cada comando de git que uses.
Puede exportar GIT_WORK_TREE=.
y GIT_DIR=../backup
y Git los recogerá en cada comando. Sin embargo, eso solo le permitirá trabajar cómodamente en un solo repositorio por caparazón.
Prefiero sugerir un enlace simbólico del directorio .git a otro sitio, o crear un enlace simbólico al directorio .git desde tu directorio principal de respaldo.