Чи є підводні камені, щоб помістити $ HOME в git замість того, щоб символізувати точкові файли?


38

У мене протягом багатьох років весь $HOMEкаталог перевірявся на підрив. Сюди ввійшли всі мої dotfiles та профілі додатків, безліч скриптів, інструментів і хаків, мою вподобану базову структуру домашнього каталогу, не декілька дивних проектів і склад, що вартує випадкових даних. Це було добре. Поки це тривало.

Але це вийшло з рук. Основна каса є однаковою для десятків систем, але не всі ці речі підходять для всіх моїх машин. Навіть не всі добре грають з різними дистрибутивами.

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

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

Читаючи в Інтернеті, багато людей, здається, роблять це за допомогою підходу symlink: клонують у підкаталог, а потім створюють посилання з $HOMEсховища. Отримавши мій $HOMEконтроль над повною версією більше десятиліття, мені не подобається ідея цього заходу, і я не можу зрозуміти, чому люди здаються такими протилежними методом прямої каси. Чи є підводні камені, про які я повинен знати конкретно, gitяк замовлення вищого рівня $HOME?

PS Частково як вправа з хорошим кодуванням, я також планую оприлюднити свою кореневу касу на Github. Страшно, скільки інформації, що стосується безпеки, я дозволив збирати у файли, які, мабуть, не можна поміркувати без жодної думки! Пароль Wi-Fi, непрохідні ключі RSA тощо. Eeek!


5
Цікаво, що призводить до переконання, що $ HOME має бути спільним без другої думки‽ Навіть зашифровані приватні ключі RSA не повинні ділитися.
дероберт

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

@derobert: Я це добре знаю. Я не говорив про оприлюднення $ HOME, просто дотфайли та зручні сценарії. Саме там я знайшов речі, які не належать. І так, я повинен мати можливість поділитися своїм .zshrc,.vimrc і тому подібні речі , НЕ дезінфікувати їх першими!
Калеб

4
Якщо ви цього ще не бачили, перегляньте вікі -домашні вікі та списки розсилки, в основному люди обговорюють саме це - як тримати ваш $ HOME під контролем редагування.
Джим Парис

Я не знаю, наскільки ви можете змінити поведінку git, але принаймні те, як це працює поза-debian-сховищем, це дуже жадібно, коли справа стосується пошуку відслідковуваних / не відстежуваних / модифікованих файлів, і це автоматично відчуває відповідальність за кожен файл. mrb це вже заявив. Іноді мене дратує ця жадібна поведінка навіть у відносно невеликих проектах, я б не хотів цього в своєму домашньому довіднику. Чому хочеться використовувати git? Я також використовую систему версій для синхронізації моїх файлів конфігурації між хостами, і я дуже задоволений CVS, тому що це так просто! Git - дуже (занадто!) Потужний для цього
Bananguin

Відповіді:


17

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

За замовчуванням Git є як жадібним, так і рекурсивним .

Subversion буде наївно ігнорувати все, про що вона не знає, і зупиняє обробку папок вгору чи вниз від вашого каси, коли вона досягне тієї, про яку вона не знає (або належить до іншого сховища). З іншого боку, Git постійно повторюється у всіх дочірніх каталогах, роблячи вкладені перевірки дуже складними через проблеми з простором імен. Оскільки ваш домашній каталог, швидше за все, також є місцем, де ви перевіряєте та працюєте над різними іншими сховищами git, ваш домашній каталог в git майже напевно зробить ваше життя неможливим безладом.

Як виявляється, це головна причина, коли люди перевіряють свої точкові файли в ізольовану папку, а потім посилаються на неї. Це не дозволяє Git уникати будь-яких речей у будь-якому дочірньому каталозі $HOME. Хоча це суто питання переваги, якщо перевірка вашого будинку на підрив, це стає справою необхідності при використанні git.

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

Щоб цей трюк протікав трохи гладше, є кілька чудових інструментів. Список розсилки vcs-home виглядає як місце для дефакто, щоб почати, і на сторінці about є зручна інформація про практичний досвід та досвід людей. По дорозі є кілька чудових інструментів, таких як vcsh , mr . Якщо ви хочете тримати свій домашній каталог безпосередньо в git, vcsh - це майже обов'язковий інструмент. Якщо ви в кінцевому підсумку розділите домашній каталог на кілька репозиторій за кадром, комбінуйте vcshїх mrдля швидкого і не дуже брудного способу керувати цим усім відразу.


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

@ALiX: Тому що gitінструменти все ще вважають, що ви працюєте над домашнім репо-репором, навіть якщо ви знаходитесь в якомусь підкаталозі, який був окремим git repo для якогось проекту. Це рішення призведе до того, що весь ваш домашній каталог буде вимкнено для всіх інших роботи з git.
Калеб

5
але "*" у вашому .gitignore означає, що всі файли, які не перебувають у домашньому режимі, ігноруються. і коли ви перевіряєте нову git repo в якомусь підкаталозі, все має працювати як слід (я думаю). Наскільки мені відомо, інструменти git шукатимуть перший .git каталог під час руху вгору по ієрархії каталогів. Отже, під час роботи в підкаталозі буде використано правильне сховище git. Звичайно, якщо ви використовуєте змінні середовища git, я думаю, що речі можуть стати брудними. Але в іншому випадку я не бачу, чому це не спрацює.
ALiX

@ALiX має рацію. Здається, що вкладені git repos спрацьовують нормально до тих пір, поки ви не вкажете їх у батьківському репо. Цікаво, які недоліки цього дуже простого підходу, окрім можливих проблем зі змінними середовища середовища git.
evanrmurphy

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

14

Я не хотів би, щоб весь мій домашній каталог перевірявся на контроль версій просто тому, що це означає, що кожен підкаталог, в який я входжу, мав би контекст управління версією мого домашнього dir. У таких випадках такі команди, як git checkoutнасправді, викликають проблеми, якщо я випадково запускаю щось із неправильного каталогу, чи то щось gitсаме, чи сценарій, який викликає git.

Це також робить більш імовірним додати щось до репо, що ви не хочете, що не було б проблемою, коли ви все перевірили, але тепер це стає проблемою. Що робити, якщо ви випадково додаєте файл приватного ключа (можливо, за звичкою) і натисніть його на github?

Сказавши це, я думаю, що основні недоліки насправді не є технічними - просто хочу врятувати мене від себе.

Що стосується символічного посилання: Ви можете клонувати репортаж у підкаталог та мати сценарій, який оновлює будь-які посилання, які потребують оновлення. Обсяг технічного обслуговування, необхідний для цього сценарію, може перевершити переваги, якщо він взагалі є; симлінування може виявитися меншою роботою.

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

Щось на зразок:

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команди, які я запускаю, будуть або для домашнього каталогу, або будуть поховані принаймні однією глибиною в зафіксованому NON каталогу. Використання svnцієї однієї папки є досить ефективною і не спричинило мені проблем через десятиліття. Ваш перший абзац вказує щось інше. Це насправді різниця в способі gitроботи?
Калеб

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

3
Ізоляція в одній папці насправді не ізолюється git- не впевнено svn- але, наприклад, git init foo && mkdir -p foo/bar/baz/spam && cd foo/bar/baz/spam && git status(або інші команди git) показують, що ви все ще перебуваєте в fooконтексті управління версіями.
мрб

Конфігурації та сценарії: Не всі dotfiles підтримують умовні умови, тому я запропонував альтернативний підхід. Це все причини, які, на мою думку, люди вважають за краще не використовувати контроль версій для $HOME- і версія не дуже корисна для dotfiles imo - але в кінцевому підсумку це ваш домашній каталог, тому якщо ви віддаєте перевагу використовувати git, і це не для вас проблем, дій!
мрб

Дякуємо за інформацію. Насправді ваш коментар про git, що не дозволяє ізолювати, є найбільш корисним бітом. Ви можете це помітно помітити у своїй відповіді. Субверсія в цьому випадку поводиться дуже по-різному і є її суттєвою для даного випадку використання.
Калеб

6

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

  • git status є свого роду контрольним списком "робити, чистити".

  • У мене є ~/tmpтимчасові речі, які оскаржуються.

  • Мені подобається бачити що- git statusнебудь, що нещодавно встановлене програмне забезпечення наважилося додати до свого $ HOME і часто видаляти ці файли або навіть видаляти винуватців.

  • Я додаю вручну дійсно корисні локальні файли та файли .gitignore, в яких є "знати, що ви робите, коли встановлюєте речі".

  • Якщо я будую новий VM або встановлюю новий ПК, я просто клоную свій віддалений будинок до $ HOME і одразу маю під рукою все, що потрібно.

  • Такі речі, як vundle для плагінів vim, більше не потрібні.

Мені не подобається складність. Коли я налаштовую будь-який rcfile, я просто це роблю, виконую чи виконую. Потім, як рефлекс, я збираюсь в $ HOME через день і завжди маю останню конфігурацію. Це так просто.

Машини, які зараз перебувають під цим режимом: Домашній ноутбук, робочий ПК, робочий VM, плюс 3 або 4 віддалені сервери.


Чи є у вас інші будинки, які вкладені в будинок?
Калеб

Ні, я розміщую інші речі в каталозі / work і не клоную маленькі інструменти, як vim pugins.
гб.

1
У мене є робота в ~ / Сайтах, і я також займаюся цим підходом, немає проблем із вкладеними
репортажами в

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

5

Я спробував і те, і інше віддав перевагу підходу symlink :

  • Перевірте куди завгодно
  • make install
  • Вийдіть і знову ввійдіть, щоб завантажити налаштування X

Недоліки:

  • Необхідно перемістити файли до репо перед тим, як додати їх
  • Доведеться підтримувати список символічних посилань у Makefile

Переваги:

  • Немає необхідності у масовому .gitignore(у мене ~на скромному полі Ubuntu у мене 133 точкових файлів )
  • Може зберігати сценарії технічного обслуговування та інші ~пов'язані з ними речі (наприклад, Makefileта cleanup.sh) з шляху
  • Може версія керувати персональними та загальнодоступними налаштуваннями окремо

Обмеження:

  • На відміну від @mrb, я створюю лише посилання в ~. Це забезпечує простоту мислення і робить тривіальним помічати нові файли, наприклад ~/.vim, ціною дуже рідкісного .gitignoreобслуговування.

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

Єдине додаток, з якого я знаю (або, принаймні, мав) проблеми з поводженням з посиланнями, - це Pidgin - він переписував мої посилання на звичайні файли.


Дякуємо за ваш внесок щодо плюсів і мінусів кожного підходу. У ході моєї подальшої роботи я виявив, що є третій підхід, який може зробити найкраще з обох світів, якщо ви добре налаштуєте додаткову проводку для початку роботи.
Калеб

3

Ось один: Якщо ви спробуєте зробити це, git rebase -i --rootі ви зареєструвались у .gitconfigпершій комісії у сховищі, git тимчасово видалить.gitconfig файл, що, у свою чергу, не зможе закінчити операцію ребайна, оскільки для цього потрібно ваше ім’я та електронний лист. ті, які зберігаються у цьому файлі.

Ви можете налаштувати їх знову і зробити git rebase --continue , але після того, як я це зробив і закінчив операцію ребайки, мій сховище 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 без проблем, належні захищені дозволи зберігаються. Те, що не робиться в базовій конфігурації, - це збереження права власності або часових позначок; але якщо будь-який з цих питань є проблемою для конкретного випадку використання, є плагіни, які можуть зробити обробку цих додаткових властивостей частиною регулярного робочого процесу (див. метастора або git-cache-meta).
Калеб

Навіть якщо він не зберігає їх, як це гірше, ніж просто мати домашній каталог не в документах? git не збирається активно перезаписувати mtimes, якщо ви не попросите його змінити файл.
poolie

-1

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


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