Почему git ломается, если '/' является корнем хранилища? - PullRequest
6 голосов
/ 23 декабря 2009

Мы бы хотели использовать git для поддержки конфигурации системы. Поскольку иногда данные конфигурации существуют вне / etc, мы начали делать что-то подобное в наших системах:

  # cd /
  # git init
  # git add etc
  # git add some/other/path
  # git commit -m 'initial import'

И так далее. Это работает, до определенного момента. Пока ваш cwd == '/', git ведет себя нормально. Однако, если вы попытаетесь, например, запустить git из подкаталога:

cd /etc
git status

Вы получаете мусор. В нашем случае тысячи строк списков «удалено:» для файлов, которые явно существуют. Такое поведение кажется исключительным для запуска git в /; делать то же самое в другом месте работает просто отлично.

Я могу «исправить» поведение следующим образом:

GIT_WORK_TREE=/ git status

И, эй, все работает так, как намеревался Линус ... но это боль. Я не хочу устанавливать его в среде в одностороннем порядке (потому что это может противоречить использованию git в других репозиториях), и я бы хотел избежать сценария-оболочки. У меня есть другие варианты?

Ответы [ 3 ]

4 голосов
/ 23 декабря 2009

Это полная догадка , которую вы могли бы использовать для дальнейшего изучения, но я подозреваю, что поведение git "найти каталог .git" взаимодействует с тем фактом, что / является его собственным родительским каталогом. , Может быть, логика «остановка в корне» содержит ошибку типа забора поста.

3 голосов
/ 23 декабря 2009

Настройка опции core.worktree в хранилище прекрасно справляется с этой задачей:

git config core.worktree /

Это работает намного лучше, чем установка GIT_WORK_TREE в среде. Ура!

0 голосов
/ 07 мая 2015

Это будет исправлено в Git 2.4.1+ (второй квартал 2015 года).
См. коммит 84ccad8 от Джефф Кинг (peff) и объединение в 7502b23 .

init: не устанавливать core.worktree при инициализации /.git

Если вы создаете git-репозиторий в корневом каталоге с помощью «git init /», мы ошибочно пишем запись core.worktree.
Это не неправильно , в том смысле, что можно установить core.worktree, когда нам это не нужно. Но излишне удивительно, если вы позже переместите каталог .git в другой путь (который обычно перемещает относительное рабочее дерево, но не работает, если есть явный набор рабочих деревьев).

Проблема заключается в том, что мы проверяем, нужно ли core.worktree, проверяя, можем ли мы создать git_dir путем конкатенации "/.git" к рабочему дереву .
Это привело бы к «//.git» в этом случае, но у нас фактически есть «/.git» (без двойной косой черты).

(Вот почему core.worktree здесь неправильно установлено, когда git init делается в корневой папке /)

Мы можем исправить это с помощью специального кожуха корневого каталога. Я также разделил логику на ее собственную функцию, чтобы сделать условное обозначение более читабельным (и использовал skip_prefix, который, как мне кажется, делает более понятным происходящее).

Никаких тестов, так как для этого нам нужно было бы написать «/».
Я вручную подтвердил, что:

sudo git init /
cd /
git rev-parse --show-toplevel
git config core.worktree

по-прежнему правильно находит верхний уровень (как "/"), а не устанавливает никакой переменной core.worktree .

...