Можно ли сохранить папку .git за пределами файлов, которые я хочу отслеживать?

У меня есть необычная идея использовать git как систему резервного копирования. Итак, скажем, у меня есть каталог. /backup/myfiles, и я хочу сделать это, используя git. Чтобы сохранить чистоту, я не хочу иметь каталог .git в папке myfiles, поэтому я думал, что могу создать. /backup/git _repos/myfiles. От взгляда на документы git я попытался сделать это:

$ 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

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

Ответ 1

git --git-dir=../repo --work-tree=. add foo

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

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

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

Ответ 2

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

Чтобы репозиторий знал, где находится дерево работы, задайте значение конфигурации 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

Ответ 3

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

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

Ответ 4

Мне проще изменить обратные каталоги --work-tree и --git-dir, используемые в ответе 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
        ...

Этот подход имеет два преимущества:

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

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

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

Ответ 5

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

mkdir ../git_repos/myfiles.git

Если вы указали параметр --work-tree во время init, тогда это автоматически установило бы переменную config 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)"

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

git --git-dir=../git_repos/myfiles.git add foo

Ответ 6

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

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

Теперь вы можете использовать git внутри каталога ./backup/git_repos/myfiles без установки каких-либо переменных среды или дополнительных параметров.

Ответ 7

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

cd ~/backup
git init
git add myfiles

Каталог .git будет находиться в backup, а не в myfiles.

Ответ 8

Вы можете создать "nodgit" script (No Dot GIT) с somet как

#!/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 "[email protected]"
        fi
      fi
      x=`testdir "$x/.."`
    done

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

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

Ответ 9

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

~/бен/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 "[email protected]"

exit $?

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

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

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

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

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

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

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