Есть ли подводные камни для размещения $ HOME в git вместо символьных файлов точек?


38

В течение многих лет мой $HOMEкаталог проверялся на подрывную деятельность. Это включало все мои точечные файлы и профили приложений, множество скриптов, инструментов и хаков, мою предпочитаемую базовую структуру домашних каталогов, а не несколько странных проектов и хранилище случайных данных. Это было хорошо. Пока это продолжалось.

Но это вышло из-под контроля. Базовая проверка одинакова для десятков систем, но не все это подходит для всех моих машин. Даже не все хорошо играют с разными дистрибутивами.

Я нахожусь в процессе уборки дома - разделяю данные, где они принадлежат, разделяю некоторые скрипты на отдельные проекты, исправляю неработающие ссылки в материалах, которые должны быть автоматизированы, и т. Д.

Моя цель заключается в замену subversionс gitдля проверки верхнего уровня из $HOME, но я хотел бы, чтобы урезать это вниз только вещи , которые я хотел бы иметь на все мои системах, а это означает, точечные файлы несколько каталогов и некоторые основные пользовательские сценарии.

При чтении онлайн многие люди, кажется, делают это с помощью подхода символической ссылки: клонируют в подкаталог, а затем создают символические ссылки $HOMEв хранилище. Прошло уже $HOMEболее десяти лет с моим полным контролем версий, мне не нравится идея этого подхода, и я не могу понять, почему люди так не любят метод прямой проверки. Есть ли какие-либо подводные камни, о которых мне нужно знать, для чего нужно gitоформить заказ на верхнем уровне $HOME?

PS Частично, как упражнение по хорошему кодированию, я также планирую сделать публичную проверку своих прав на github. Страшно, сколько конфиденциальной информации, которую я разрешил собирать в файлах, которые должны быть разделены, не задумываясь! Пароль WiFi, нефразированные ключи RSA и т. Д.


5
Любопытно, что привело к убеждению, что $ HOME должен быть доступным, не задумываясь. Даже зашифрованные закрытые ключи RSA не должны передаваться.
Дероберт

3
если вы на самом деле говорите о том, чтобы поместить содержимое вашего домашнего каталога в git, просто обратите внимание: трудно (но не невозможно) копаться в истории git и постоянно удалять важные элементы (git предназначен для предотвращения потери), и также помните, что при переключении веток или извлечении более ранняя ревизия gitизменит права доступа к вашим файлам 644после извлечения, что плохо для таких вещей, как закрытые ключи ssh. однако etckeeperэто решение для использования git с разрешениями для / etc /
cwd

@derobert: Я хорошо это знаю. Я не говорил об обнародовании $ HOME, только о точечных файлах и вспомогательных скриптах. Вот где я нашел вещи, которые не принадлежат. И да, я должен быть в состоянии разделить мой .zshrc, .vimrcи тому подобные вещи , не дезинфицировать их первыми!
Калеб

4
Если вы еще этого не видели, посмотрите вики-списки vcs-home и списки рассылки, где в основном люди обсуждают именно это - как сохранить свой $ HOME под контролем версий.
Джим Пэрис

Я не знаю, насколько сильно вы можете изменить поведение git, но, по крайней мере, так, как он работает вне репозитория debian, это довольно жадно, когда дело доходит до поиска отслеживаемых / неотслеживаемых / измененных файлов и автоматически чувствует ответственность за каждый файл. MRB уже заявил об этом. Иногда меня раздражает это жадное поведение даже в относительно небольших проектах, которые я не хотел бы иметь в своем домашнем каталоге. Почему вы хотите использовать git? Я также использую систему управления версиями для синхронизации файлов конфигурации между хостами, и я очень доволен CVS, потому что это так просто! Git очень (тоже!) Мощный для этого
Bananguin

Ответы:


17

Да , при рассмотрении вопроса gitоб управлении домашним каталогом есть, по крайней мере, одна серьезная ошибка subversion.

Git является жадным и рекурсивным по умолчанию .

Subversion наивно игнорирует все, о чем не знает, и останавливает обработку папок вверх или вниз из вашей проверки, когда достигает той, о которой не знает (или которая принадлежит другому хранилищу). Git, с другой стороны, продолжает возвращаться во все дочерние каталоги, делая вложенные извлечения очень сложными из-за проблем с пространством имен. Поскольку ваш домашний каталог, скорее всего, также является местом, где вы извлекаете и работаете с различными другими git-репозиториями, наличие вашего домашнего каталога в git почти наверняка сделает вашу жизнь беспорядочным.

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

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

Чтобы сделать этот трюк немного более плавным, есть несколько отличных инструментов. Список рассылки VCS-дома кажется, что де - факто место для начала, и о странице имеет удобный завернуть из HOWTOs и опыта людей. По пути есть некоторые изящные маленькие инструменты, такие как vcsh , mr . Если вы хотите сохранить свой домашний каталог непосредственно в git, vcsh - почти обязательный инструмент. Если вы в конечном итоге расщепление ваш домашний каталог на несколько repostories за кулисами, смешайте vcshс mrдля быстрой и не очень грязный способ управлять всем сразу.


2
но почему бы просто не добавить '*' в ваш файл .gitignore? Таким образом, git будет игнорировать все, кроме файлов, которые уже находятся в хранилище, и вы можете добавлять новые файлы с помощью git add -f <file>.
ALiX

@ALiX: Потому что gitинструменты все равно будут считать вас работающим над домашним репозиторием, даже если вы находитесь в каком-то подкаталоге, который был отдельным git-репо для какого-то проекта. Это решение сделает весь ваш домашний каталог недоступным для всей остальной работы git.
Калеб

5
но «*» в вашем .gitignore означает, что все файлы, не входящие в репозиторий home-dir, игнорируются. и когда вы проверяете новое git-репо в каком-то подкаталоге, все должно работать как положено (я думаю). Насколько я знаю, инструменты git будут искать первый каталог .git при перемещении вверх по иерархии каталогов. Таким образом, при работе в подкаталоге будет использоваться правильный репозиторий git. Конечно, если вы используете переменные окружения git, я думаю, что все может стать грязным. Но в остальном я не понимаю, почему это не сработает.
ALiX

@ALiX прав. Вложенные репозитории git работают нормально, если вы выполняете их в родительском репозитории. Интересно, каковы недостатки этого очень простого подхода, кроме возможных проблем с переменными среды git.
evanrmurphy

1
Экспериментировал с этим сегодня. Я думаю, что /*работает лучше, чем *потому, что он по-прежнему игнорирует все по умолчанию, но значительно упрощает добавление каталогов. Вместо этого git add -fя использую !шаблоны с префиксом, такие как !/.vimrcи !/.gitignore(для самого файла .gitignore), чтобы явно включать вещи в репозиторий.
evanrmurphy

14

Я бы не хотел, чтобы весь мой домашний каталог регистрировался в управлении версиями просто потому, что это означает, что каждый подкаталог, в который я захожу, будет иметь контекст управления версиями моего домашнего каталога. Команды like git checkoutв этом случае будут иметь реальное действие, вызывая проблемы, если я случайно запущу что-то из неправильного каталога, будь то что-то gitсамо по себе или скрипт, который вызывает git.

Это также повышает вероятность того, что вы добавите в репо что-то, что вам не нужно, что не было бы проблемой, когда вы все отметили, но теперь становится проблемой. Что если вы случайно добавите файл с закрытым ключом (возможно, по привычке) и отправите его в github?

Сказав это, я думаю, что основные недостатки на самом деле не технические, а просто желание спасти меня от самого себя.

Что касается символьных ссылок: Вы можете клонировать свое хранилище в подкаталог и иметь скрипт, который обновляет любые символические ссылки, которые необходимо обновить. Однако объем обслуживания, необходимый для этого сценария, может перевесить преимущества его наличия; символические ссылки могут оказаться менее трудоемкими.

С помощью символических ссылок вы также можете легко добавлять специфичные для дистрибутива (или даже хоста) дополнения, которые проверяются в git. Ваш скрипт symlink-update игнорирует файлы, предназначенные для несовместимых платформ или разных хостов, и обновляет только соответствующие.

Что-то типа:

HOMEREPO=$HOME/homerepo
HOST=$(hostname)
UNAME=$(uname)

for dotfile in $HOMEREPO/shared/* $HOMEREPO/host-$HOST/* $HOMEREPO/uname-$UNAME/*
do
    target=$HOME/$(basename $dotfile)
    [ ! -r $target ] && ln -s $dotfile $target
done

Лично: я использую символические ссылки, а не каталоги символических ссылок; только файлы внутри. Это дает мне некоторую гибкость для внесения локальных изменений в эти каталоги (т.е. добавление / удаление файлов). Настройка моей учетной записи в новой системе утомительна, потому что мне приходится заново создавать все символические ссылки вручную.


Любые gitкоманды, которые я запускаю, будут либо для самого домашнего каталога, либо будут похоронены, по крайней мере, одна глубоко в директории без коммитов. Использование svnэтой изоляции одной папки довольно эффективно и не доставило мне никаких проблем за десятилетие. Ваш первый абзац указывает на что-то еще. Это на самом деле разница в том, как gitработает?
Калеб

Кроме того, мои конфиги и сценарии уже имеют встроенную условную логику для разных хостов и платформ, поэтому использование сценария для настройки различных ссылок в качестве условных выражений не кажется большим преимуществом по сравнению gitс простыми в управлении ветвями. Все еще что-то, что я пропускаю или это будет сводиться к предпочтению?
Калеб

3
Изоляция одной папки на самом деле не изолирует ( gitне уверен), svnно, например, git init foo && mkdir -p foo/bar/baz/spam && cd foo/bar/baz/spam && git status(или другие команды git) показывают, что вы все еще находитесь в fooконтексте управления версиями.
mrb

Конфиги и сценарии: не все точечные файлы поддерживают условные выражения, поэтому я предложил альтернативный подход. Это все причины, по которым, я думаю, люди предпочитают не использовать контроль версий $HOME- а управление версиями не очень важно для dotfiles imo - но в конечном итоге это ваш домашний каталог, так что если вы предпочитаете использовать git, и это не проблема для вас, Действуй!
МРБ

Спасибо за информацию. На самом деле ваш комментарий о том, что git не допускает изоляции, является самым полезным. Вы можете внести это в свой ответ. Subversion ведет себя очень по-разному в этой точке, и это важно для этого варианта использования.
Калеб

6

Чтобы дать другую точку зрения: у меня есть мой $ HOME в git с тех пор, и с тех пор я не нашел никаких недостатков. Я, очевидно, не синхронизирую этот репозиторий git с github; Я использую сервис, который имеет частные репо. Я также не ставлю медиа-файлы, файлы для загрузки или пакеты под контроль git.

  • git status это своего рода «сделать, очистить» контрольный список.

  • У меня есть ~/tmpдля временных вещей, которые Gitignored.

  • Мне нравится видеть git statusчто-либо, что недавно установленное программное обеспечение осмелилось добавить в мой $ HOME, и часто удаляю эти файлы или даже удаляю преступников.

  • Я добавляю вручную действительно полезные локальные файлы и каталоги .gitignore, которые имеют преимущество «знай, что ты делаешь при установке».

  • Если я собираю новую виртуальную машину или устанавливаю новый компьютер, я просто клонирую свой удаленный дом в $ HOME и сразу же получаю все, что мне нужно.

  • Такие вещи, как vundle для плагинов vim больше не нужны.

Мне не нравится сложность. Когда я настраиваю любой rcfile, я просто делаю это, фиксирую и нажимаю. Затем, в качестве рефлекса, я получаю $ HOME через день и всегда получаю последнюю версию конфигурации. Это так просто.

Машины в настоящее время под этим режимом: домашний ноутбук, рабочий ПК, рабочая ВМ, а также 3 или 4 удаленных сервера.


Есть ли у вас дома какие-нибудь другие git-кассы?
Калеб

Нет, я помещаю другие вещи в каталог / work и не клонирую такие маленькие инструменты, как vim pugins.
Гб.

1
У меня есть работа внутри ~ / Sites, и я тоже использую этот подход, нет проблем с вложенными репозиториями git
philfreo

1
Я использовал эту настройку некоторое время. У меня есть «псевдоним sq = git status -uno», и я мало беспокоюсь о .gitignore (время от времени я смотрю на все это и говорю «ме»). У меня никогда не было проблем с вложенными репозиториями git. У меня есть личный сервер, на котором я git init --bareвыполняю команду, по которой я перехожу через ssh (хотя я не помещаю пароли в репозиторий, у меня там есть мои файлы заметок).
unhammer

5

Я попробовал оба, и в конце концов предпочел подход с символической ссылкой :

  • Проверьте, где
  • make install
  • Выйдите и снова войдите, чтобы загрузить настройки X

Недостатки:

  • Нужно переместить файлы в репо перед их добавлением
  • Приходится вести список символических ссылок в Makefile

Преимущества:

  • Нет необходимости в массивных .gitignore(у меня есть 133 точечных файла ~на моем скромном Ubuntu box)
  • Может держать скрипты обслуживания и другие ~связанные вещи (такие как Makefileи cleanup.sh) в стороне
  • Может контролировать версии личных и общедоступных настроек отдельно

Ограничения:

  • В отличие от @mrb, я создаю только символические ссылки в ~. Это делает символическую ссылку простой и упрощает, например ~/.vim, заметку новых файлов , за счет некоторого очень редкого .gitignoreобслуживания.

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

Единственное известное мне приложение, которое имело (или, по крайней мере, имело) проблемы с обработкой символических ссылок, было Pidgin - оно продолжало перезаписывать мои символические ссылки обычными файлами.


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

3

Вот один из них: Если вы попытаетесь это сделать git rebase -i --rootи зарегистрировались в .gitconfigпервом коммите в репозитории, git временно удалит .gitconfigфайл, что, в свою очередь, сделает невозможным завершение операции rebase, поскольку для этого требуется ваше имя и адрес электронной почты. то, что хранится в этом файле.

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

Я не знаю, что произойдет, если вы это сделаете git rebase -i <commit>, и .gitconfigпроверяется вместе с любым коммитом после <commit>.

Возможно, самое простое решение - воздержаться от добавления .gitconfigв репозиторий и вместо этого перечислить его в .gitignore.


2

Вот как я это делаю:

  1. установить чистый linux (не обязательно, но делает шаг более приятным на шаге 4)
  2. установить etckeeper
  3. беги git initв своем доме
  4. создайте .gitignore и добавьте все, что выглядит так, как будто оно вас не интересует или может многое изменить. Не забудьте добавить такие вещи, как *.cacheи *.lockт. Д. Я не рекомендую добавлять/*потому что вы не будете получать уведомления автоматически, когда что-то новое будет добавлено в ваш дом. Это подход черного списка против подхода белого списка, где я в основном хочу сохранить свой конфигурационный файл для всего программного обеспечения, за исключением изменчивого материала и некоторого программного обеспечения, которое меня не волнует. Когда вы позже объединяете, переносите или сравниваете системы, возможность различать все очень удобно. Вы можете настроить свои новые системы гораздо быстрее, чем если бы вы просто сохранили .bashrc и несколько других файлов точек. Таким образом вы сохраните конфигурацию, которую вы могли бы установить через графический интерфейс, и не будете знать, в каких точечных файлах хранятся настройки. (Если когда-нибудь окажется, что вы зафиксировали изменчивые файлы, вы все равно можете указать git принять без изменений)
  5. бег etckeeper init -d /home/username
  6. бег git commit -d /home/username
  7. настроить псевдонимы в вашей оболочке, чтобы сделать командную строку лучше, как homekeeper checkout

Причиной использования etckeeper является то, что он будет хранить метаданные, такие как разрешения для ваших файлов (довольно важно для определенных вещей, таких как ssh-ключи). Теперь у вас должен быть хук предварительной фиксации, который будет автоматически сохранять метаданные. Я не очень уверен насчет пост-проверки. Вы должны, вероятно, использовать etckeeper checkout xxx -d /home/userЯ посмотрю на это немного подробнее и разработаю этот ответ.


-1

Моя основная проблема с использованием Git в домашнем каталоге заключается в том, что Git не хранит атрибуты файлов, такие как права доступа к файлам и временные метки. Для меня важно знать, когда были созданы определенные файлы, это может или не может иметь место для вас. Кроме того, потеря разрешений для файлов и каталогов, таких как .sshпроблематично. Я понимаю, что вы планируете .sshне использовать Git, но в других местах разрешения могут иметь значение (например, несжатые резервные копии веб-сайтов).


Это вводит в заблуждение, если на самом деле не так. Git по умолчанию сохраняет множество атрибутов файла, включая права доступа. Я держу .sshв Git в течение некоторого времени без проблем, соответствующие безопасные разрешения сохраняются. Чего он не делает в базовой конфигурации, так это сохранения владельца или временных меток; тем не менее, если какой-либо из них является проблемой для конкретного варианта использования, существуют плагины, которые могут сделать обработку этих дополнительных свойств частью обычного рабочего процесса (см. metastore или git-cache-meta).
Калеб

Даже если он не хранит их, как это может быть хуже, чем просто иметь домашний каталог не в vcs? git не собирается активно перезаписывать mtimes, если вы не попросите его изменить файл.
пул

-1

Решение на основе git особенно полезно, если вам нужно развернуть файлы на разных компьютерах, и даже более того, если у вас есть части, общие для всех машин, и части, специфичные для некоторых машин. Вы можете создать несколько репозиториев и использовать такие инструменты, как multigit или vcsh, чтобы клонировать их в одном каталоге (в данном случае это ваш домашний каталог).


Спасибо, но, возможно, вы пропустили вопрос. Я хорошо знаю об использовании для этого (следовательно, почему я хотел сделать это в первую очередь), этот вопрос был о любых подводных камнях, которые кто-то новичок в этом с git (как я когда-то просил) может не знать , Это, кажется, не отвечает на этот вопрос вообще.
Калеб
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.