Git та жорсткі посилання


97

Беручи до уваги, що Git не розпізнає символічні посилання, які вказують поза сховищем, чи є якісь проблеми із використанням жорстких посилань?

Чи міг би їх зламати Гіт? Чи можете ви, будь ласка, вказати мені детальну інформацію?


2
Що ви намагаєтесь зробити і чому? Жорстке посилання нічим не відрізняється від звичайного файлу. Якби ви коли-небудь витягнули нову версію з іншого сховища, вона перезаписала б ту, яку ви мали - який сенс посилатися на щось поза репо?
Carl Norum,

2
Git розпізнає символічні посилання, які вказують на шлях поза сховищем.
mipadi

Ніякого міпаді, єдиний спосіб - це розмахування файлами в репо та символічними посиланнями в їх "справжньому" розташуванні
Альфредо Палхарес

Відповіді:


88

Об'єкт "дерево", що представляє каталоги у Git, зберігає ім'я файлу та дозволи (підмножина). Він не зберігає номер inode (або інший тип ідентифікатора файлу). Тому жорсткі посилання не можуть бути представлені в git , принаймні, без сторонніх інструментів, таких як metastore або git-cache-meta (і я не впевнений, що це можливо навіть за допомогою цих інструментів).

Git намагається не торкатися файлів, які йому не потрібно оновлювати, але ви повинні врахувати, що git не намагається зберегти жорсткі посилання, тому їх може порушити git.


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


4
Символьні посилання на шляхи поза репо можуть бути корисними. Я використовував їх у веб-додатках для вказівки на файли бази даних або медіафайли, не відстежувані репо. Таким чином, файл конфігурації веб-програми може вказувати на статичний шлях, але фактичне розташування цього шляху може відрізнятися між локальною розробкою та серверними середовищами.
міпаді,

@mipadi: BTW. Сучасний gitweb має спеціальний футляр для відображення символьних посилань, що ведуть після нормалізації поза сховищем.
Якуб Нарембський,

6
Так, символічні посилання за межами репо - це нормально. Я використовував їх, щоб вказати на величезний каталог даних, який мені не потрібен (або я хочу) версій. Як правило, я використовую відносні посилання. Отже, у випадку, якщо репо та каталог даних повинні були знаходитись поруч у якомусь батьківському каталозі. Ви можете робити дивовижні трюки із символічними посиланнями на ../foo.
Адріан Ратнапала,

На жаль, сховище Git для metastore (git: //git.hardeman.nu/metastore.git) більше недоступне.
Дерек Махар

1
github.com/danny0838/git-store-meta є альтернативою git-cache-meta .
Дерек Махар

22

Я з’ясував, що за допомогою хуків ви можете захопити git pullподію (коли є що тягнути ...), записавши обробник події сценарію у .git/hooks/post-mergeфайл.

По-перше, ви повинні chmod +xце зробити.

Потім помістіть lnкоманди всередину, щоб відтворити жорсткі посилання при кожному натисканні. Акуратно га!

Це працює, мені просто потрібно було це для мого проекту і ls -iпоказує, що файли автоматично зв’язувались після pull.


Мій приклад .git/hooks/post-merge:

#!/bin/sh
ln -f $GIT_DIR/../apresentacao/apresentacao.pdf $GIT_DIR/../capa/apresentacao.pdf
ln -f $GIT_DIR/../avaliacoesMono/avaliacao_monografias_2011_Nilo.pdf $GIT_DIR/../capa/avaliacoes.pdf
ln -f $GIT_DIR/../posters/poster_Nilo_sci.pdf $GIT_DIR/../capa/poster.pdf
ln -f $GIT_DIR/../monografia/monografia_Nilo.pdf $GIT_DIR/../capa/monografia_Nilo.pdf

ВАЖЛИВО: Як бачите, шлях до будь-якого файлу у вашому сховищі повинен починатися з $GIT_DIR, а потім додати частковий відносний шлях до файлу.

Також важливо: -fнеобхідний, оскільки ви відтворюєте файл призначення.

РЕДАГУВАТИ

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

$ mkdir tmp
$ cd tmp
$ git --version
git version 2.24.3 (Apple Git-128)
$ git init .
Initialized empty Git repository in /Users/teixeira/tmp/.git/
$ mkdir x
$ cd x
$ echo 123 > original
$ cat original
123
$ cd ..
$ ln -s x/original symlink
$ cat symlink
123
$ ln x/original hardlink
$ cat hardlink
123
$ git add .
$ git commit -m 'Symlink and hardlink commit'
[master (root-commit) 8df3134] Symlink and hardlink commit
 3 files changed, 3 insertions(+)
 create mode 100644 hardlink
 create mode 120000 symlink
 create mode 100644 x/original

Клонування з локального сховища git

$ cd
$ git clone tmp/ teste_tmp
Cloning into 'teste_tmp'...
done.
$ cd teste_tmp/
$ ls
hardlink  symlink  x
$ cat symlink
123
$ cat hardlink
123

Клонування з віддаленого сховища

$ cd ~/tmp
$ git remote add origin https://github.com/myUser/myRepo.git
$ git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (5/5), 361 bytes | 361.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To https://github.com/myUser/myRepo.git
 + 964dfce...8df3134 master -> master
$ cd ../
$ git clone https://github.com/myUser/myRepo.git
Cloning into 'myRepo'...
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
$ cd myRepo/
$ cat symlink
123
$ cat hardlink
123

https://github.com/mokacoding/symlinks також вказує на важливу річ: символічні посилання повинні бути визначені відносно.


11
Отже, виглядає так, що кожного разу, коли ви додаєте жорстке посилання до свого репо, вам також потрібно вручну додати рядок до вашого сценарію підключення після злиття. Було б непогано, якби ваш хук перед фіксацією зробив це повністю автоматичним - виявляючи жорсткі (і символічні) посилання у вашому коміті та записуючи відповідні рядки у ваш файл після об’єднання. Git не потрібно буде зберігати інформацію inode в репо, він буде зберігати її біти в хуках! Але який безлад, якби зв’язаний файл відстежувався в іншому репозиторії git ... чи буде редагування файлу в одному місці плавно розповсюджуватися на інше репо? Постійні злиття з круговою петлею push / pull?
конфорки

Розумний підхід, але прикро, що Git не відстежує жорсткі посилання, навіть потенційно представляючи їх як копії у файлових системах, які не підтримують жорсткі посилання.
Дерек Махар,

1
@hobs вибачте, що знадобився 7 років, щоб відповісти :) Ви маєте рацію. Якби файл поза сховищем був зв’язаний двома різними репозиторіями, я думаю, що зміна посилання в одному репо просто не побачила б в іншому.
Niloct

8

З цього випуску msysgit

Точки з'єднання не є символічними посиланнями; отже, символічні посилання просто не підтримуються в msysGit.

Крім того, Git ніколи не відстежував жорсткі посилання .

Проблема була орієнтована на Windows (оскільки мова йде про msysgit) та дискусія щодо потенційної підтримки symlink.
Але коментар щодо жорстких посилань стосується Git загалом.


2

Google "git зберігає жорсткі посилання" і показує, що git не знає, як зберегти структуру жорстких посилань AFAIK, можливо, за задумом.

Веб-проекти шахти використовують жорсткі посилання наступним чином:

www/products/index.php
www/products/dell_latitude_id577/index.php #(hard linked to above)
www/products/dell_inspiron_id323/index.php #(hard linked again to above)

me@server:www/products$ ls -l index.php
-rwxr-xr-x 3 me me 1958 Aug 22 22:10 index.php*

Якщо я хотів внести зміни до index.php, я міняю його в одному місці, і жорсткі посилання (сторінки з інформацією про товар) вказують на зміни - крім git не зберігає цих відносин під час клонування та перетягування на інших комп'ютерах.

me@server:www$ git pull

на іншій машині створить новий index.php для кожного жорсткого посилання.


7
Ви повинні реалізувати якусь маршрутизацію у своєму веб-додатку. Жорсткі зв'язки химерні.
Nowaker

5
Так, принаймні використовуйте символічні посилання. :)
Андрес Ріофріо

2
Це власне те, що я хочу, я не хочу, щоб git зберігав жорсткі посилання. У мене є каталог Дженкінса з безліччю каталогів робочої області, і через багатогалузеві конвеєри багато дублювання. Так що у мене є робота , яка щоночі працює hardlink --ignore-timeна /var/lib/jenkins, щоб повернути частину дискового простору. Протягом дня деякі файли знову отримують беззв’язок після git pullабо, mvn compileале це нормально, я сподіваюся, що це станеться. Якби git зберігав жорсткі посилання, то моя стратегія переробки дискового простору не працювала б.
Amedee Van Gasse
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.