Могу ли я хранить папку .git вне файлов, которые я хочу отслеживать? - PullRequest
129 голосов
/ 03 февраля 2009

У меня необычная идея использовать git в качестве системы резервного копирования. Допустим, у меня есть каталог ./backup/myfiles, и я хочу сделать резервную копию, используя git. Для сохранения чистоты я не хочу, чтобы в папке myfiles был каталог .git, поэтому я подумал, что могу создать ./backup/git_repos/myfiles. Просматривая git docs, я попытался сделать это:

$ 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

Вы можете увидеть сообщение об ошибке, которое я там получаю. Что я делаю не так?

Ответы [ 9 ]

161 голосов
/ 22 декабря 2011

Вам просто нужно убедиться, что хранилище знает, где находится рабочее дерево, и наоборот.

Чтобы сообщить хранилищу, где находится рабочее дерево, установите значение конфигурации core.worktree. Чтобы сообщить рабочему дереву, где находится каталог git, добавьте файл с именем .git (не папка!) И добавьте строку, например

gitdir: /path/to/repo.git

Начиная с git 1.7.5, команда init получила дополнительную опцию для этого.

Вы можете инициализировать новый отдельный репозиторий с помощью

git init --separate-git-dir /path/to/repo.git

Это инициализирует репозиторий git в отдельном каталоге и добавит файл .git в текущий каталог, который является рабочим каталогом нового репозитория.

Ранее для 1.7.5 вам приходилось использовать немного другие параметры и добавлять файл .git самостоятельно.

Чтобы инициализировать отдельный репозиторий, следующая команда связывает рабочее дерево с репозиторием:

git --git-dir=/path/to/repo.git --work-tree=. init && echo "gitdir: /path/to/repo.git" > .git

Ваш текущий каталог будет рабочим деревом, а git будет использовать репозиторий на /path/to/repo.git. Команда init автоматически установит значение core.worktree в соответствии с параметром --git-dir.

Вы можете даже добавить псевдоним для этого:

[alias]
    initexternal = !"f() { git --work-tree=. --git-dir=\"$1\" init && echo \"gitdir: $1\" >> .git; }; f"

Использование контроля версий git в рабочем каталоге, доступном только для чтения

Обладая знаниями выше, вы даже можете настроить контроль версий git для рабочего каталога, не имея прав на запись. Если вы используете --git-dir для каждой команды git или выполняете каждую команду из репозитория (вместо рабочего каталога), вы можете пропустить файл .git и, следовательно, не нужно создавать какие-либо файлы в рабочем каталоге. См. Также Leos answer

93 голосов
/ 03 февраля 2009
git --git-dir=../repo --work-tree=. add foo

Это будет делать то, что вы хотите, но, очевидно, будет отстой, когда вам нужно будет указать это с каждой командой git, которую вы когда-либо использовали.

Вы можете экспортировать GIT_WORK_TREE=. и GIT_DIR=../backup, и Git подберет их для каждой команды. Это только позволит вам удобно работать в одном репозитории на оболочку.

Я бы предпочел использовать символическую ссылку на каталог .git в другом месте или создать символическую ссылку на каталог .git из основного каталога резервного копирования.

56 голосов
/ 23 октября 2013

Опция --separate-git-dir для git initgit clone) может быть использована для этого в моей версии git (1.7.11.3). Опция отделяет репозиторий git от рабочего дерева и создает символическую ссылку git, независимую от файловой системы (в форме файла с именем .git), в корне рабочего дерева. Я думаю, что результат идентичен ответу Никса .

git init --separate-git-dir path/to/repo.git path/to/worktree
24 голосов
/ 05 ноября 2014

Мне проще поменять каталоги --work-tree и --git-dir, использованные в ответе Никса:

$ 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
        ...

У этого подхода есть два преимущества:

  • Это устраняет необходимость иметь какие-либо параметры командной строки или файлы .git. Вы просто работаете в обычном режиме из корня хранилища.
  • Позволяет создавать версии файловой системы, даже если она вам не принадлежит. Git будет писать только в хранилище.

Единственное предупреждение, с которым я столкнулся, это то, что вместо использования файла .gitignore вы редактируете info/exclude.

Затем вы можете использовать хранилище read_only_repos/foo в качестве удаленного в своих собственных хранилищах, даже если исходные файлы не находятся под контролем версий.

18 голосов
/ 03 февраля 2009

Обычно принято называть каталог, являющийся репозиторием git, рабочее дерево которого находится в необычном месте с расширением .git, очень похожим на пустой репозиторий.

mkdir ../git_repos/myfiles.git

Если бы вы указали опцию --work-tree во время инициализации, это автоматически настроило бы переменную конфигурации core.worktree, которая означает, что git будет знать, где найти рабочее дерево, когда вы укажете каталог git.

git --git-dir=../git_repos/myfiles.git --work-tree=. init

Но вы можете установить эту переменную и после факта.

git --git-dir=../git_repos/myfiles.git config core.worktree "$(pwd)"

Как только вы это сделаете, команда добавления должна работать как положено.

git --git-dir=../git_repos/myfiles.git add foo
4 голосов
/ 23 августа 2011

Использование git внутри репо:

cd ./backup/git_repos/myfiles
git init --bare
git config core.worktree ../myfiles
git config core.bare false

С этого момента вы можете использовать git внутри каталога ./backup/git_repos/myfiles, не задавая никаких переменных среды или дополнительных параметров.

1 голос
/ 23 марта 2009

Вы можете создать скрипт "nodgit" (No Dot GIT) с чем-то вроде

#!/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

Вы можете вызвать nodgit вместо git, и он при необходимости установит переменные, ища git-репо. Например, скажем, у вас есть (голое) хранилище в / usr / local / gits / __ home__foo_wibbles, и вы находитесь в / home / foo / wibbles / one, тогда он найдет правильный рабочий каталог (/ home / foo / wibbles) и репо .

О, вы также можете использовать "nodgit shell", чтобы получить оболочку с правильным набором переменных, чтобы вы могли использовать простые старые команды git.

0 голосов
/ 07 апреля 2017

Я создаю сценарии, которые выглядят как

~ / bin / ГИТ-слэш:

#!/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 $?

Излишне использовать --git_dir = $ GIT_DIR, но напоминает мне, что я также могу устанавливать переменные окружения вне скрипта.

Приведенный выше пример предназначен для отслеживания локальных изменений системных файлов cygwin.

Может сделать один такой скрипт для любого крупного проекта, который нуждается в этом, но / / / / это мое основное использование.

Вышеуказанное достаточно мало, чтобы создать псевдоним или функцию оболочки, если вы устраните избыточность.

Если бы я делал это достаточно часто, я бы восстановил отображение рабочей области в репозиторий

"Boxes, Links, and Parallel Trees: Elements of a Configuration Management System", 
in Workshop Proceedings of the Software Management Conference. 1989.

, ближайшим современным аналогом которого является Выполнение сопоставлений или представлений , поддержка частичных проверок, а также нераскрытие рабочего пространства и репо.

0 голосов
/ 03 февраля 2009

Предполагая, что ваши myfiles каталоги уже существуют и имеют некоторый контент, не могли бы вы жить с этим:

cd ~/backup
git init
git add myfiles

Каталог .git будет в backup, а не в myfiles.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...