Git i twarde linki


97

Biorąc pod uwagę, że Git nie rozpoznaje dowiązań symbolicznych, które wskazują poza repozytorium, czy jest jakiś problem z używaniem dowiązań twardych?

Czy Git może je złamać? Czy możesz wskazać mi szczegółowe informacje?


2
Co próbujesz zrobić i dlaczego? Twardy link nie różni się od zwykłego pliku. Gdybyś kiedykolwiek miał pobrać nową wersję z innego repozytorium, nadpisałaby ona tę, którą masz - jaki jest sens linkowania do czegoś poza repozytorium?
Carl Norum

2
Git rozpozna dowiązania symboliczne, które wskazują ścieżkę poza repozytorium.
mipadi

Bez mipadi, jedynym sposobem jest machanie plikami w repozytorium i symbolicznymi linkami w ich „prawdziwej” lokalizacji
Alfredo Palhares

Odpowiedzi:


88

Obiekt 'tree', reprezentujący katalogi w Git, przechowuje nazwę pliku i (podzbiór) uprawnień. Nie przechowuje numeru i-węzła (ani innego rodzaju identyfikatora pliku). Dlatego twarde linki nie mogą być reprezentowane w git , przynajmniej nie bez narzędzi innych firm, takich jak metastore lub git-cache-meta (i nie jestem pewien, czy jest to możliwe nawet z tymi narzędziami).

Git stara się nie dotykać plików, których nie musi aktualizować, ale musisz wziąć pod uwagę, że git nie próbuje zachować twardych linków, więc mogą zostać zerwane przez git.


O linkach symbolicznych wskazujących poza repozytorium : git nie ma z nimi problemów i powinien zachować zawartość linków symbolicznych ... ale użyteczność takich linków jest dla mnie wątpliwa, ponieważ to, czy te dowiązania symboliczne byłyby zepsute, czy nie, zależy od układu systemu plików poza repozytorium git i nie jest pod kontrolą git.


4
Przydatne mogą być odnośniki symboliczne do ścieżek poza repozytorium. Użyłem ich w aplikacjach internetowych, aby wskazać bazę danych lub pliki multimedialne, które nie są śledzone przez repozytorium. W ten sposób plik konfiguracyjny aplikacji internetowej może wskazywać na ścieżkę statyczną, ale rzeczywista lokalizacja tej ścieżki może się różnić w zależności od lokalnego środowiska programistycznego i środowiska serwera.
mipadi

@mipadi: BTW. Nowoczesny gitweb ma specjalny przypadek do wyświetlania linków symbolicznych prowadzących po normalizacji poza repozytorium.
Jakub Narębski

6
Tak, linki symboliczne poza repozytorium są w porządku. Użyłem ich do wskazania ogromnego katalogu danych, którego nie potrzebowałem (lub nie chciałem) wersjonować. Generalnie używam linków względnych. W takim przypadku repozytorium i katalog danych musiały znajdować się obok siebie w jakimś katalogu nadrzędnym. Możesz robić niesamowite sztuczki za pomocą linków symbolicznych do ../foo.
Adrian Ratnapala

Niestety repozytorium Git dla metastore (git: //git.hardeman.nu/metastore.git) nie jest już dostępne.
Derek Mahar

1
github.com/danny0838/git-store-meta to alternatywa dla git-cache-meta .
Derek Mahar

22

Dowiedziałem się, że za pomocą hooków można przechwycić git pullzdarzenie (gdy jest coś do ściągnięcia ...) zapisując obsługę zdarzeń skryptu do .git/hooks/post-mergepliku.

Po pierwsze, musisz to chmod +xzrobić.

Następnie umieść w nim lnpolecenia, aby odtworzyć twarde linki przy każdym pociągnięciu. Schludnie huh!

Działa, po prostu potrzebowałem tego do mojego projektu i ls -ipokazuje, że pliki zostały automatycznie połączone później pull.


Mój przykład .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

WAŻNE: Jak widzisz, ścieżka do dowolnego pliku w repozytorium powinna zaczynać się od $GIT_DIR, a następnie dodaj częściową ścieżkę względną do pliku.

Również ważne: -fjest to konieczne, ponieważ odtwarzasz plik docelowy.

EDYTOWAĆ

Nowoczesny klient git wydaje się w naturalny sposób obsługiwać dowiązania symboliczne i twarde w repozytorium, nawet podczas wypychania do zdalnej lokalizacji, a następnie klonowania z niej. Nigdy więcej nie musiałem łączyć się poza repozytorium 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

Klonowanie z lokalnego repozytorium 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

Klonowanie ze zdalnego repozytorium

$ 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 również wskazuje na ważną rzecz: linki symboliczne muszą być zdefiniowane względnie.


11
Wygląda więc na to, że za każdym razem, gdy dodajesz twarde łącze do repozytorium, musisz ręcznie dodać wiersz do skryptu przechwytującego po scaleniu. Byłoby miło, gdyby Twój punkt zaczepienia przed zatwierdzeniem uczynił to w pełni zautomatyzowanym - wykrywając twarde (i symboliczne) linki w zatwierdzeniu i zapisując odpowiednie wiersze do pliku po scaleniu. Git nie musiałby przechowywać informacji i-węzła w repozytorium, przechowałby jego fragmenty w hookach! Ale co za bałagan, gdyby linkowany plik był śledzony w innym repozytorium git ... czy edycja pliku w jednym miejscu byłaby płynnie przenoszona do drugiego repozytorium? Nieustannie łączy się z okrągłą pętlą push / pull?
płyty kuchenne

Sprytne podejście, ale szkoda, że ​​Git nie śledzi twardych linków, nawet potencjalnie reprezentując je jako kopie w systemach plików, które nie obsługują twardych linków.
Derek Mahar

1
@hobs przepraszam za 7 lat na odpowiedź :) Masz rację. Gdyby plik poza repozytorium był połączony przez 2 różne repozytoria, myślę, że zmiana linku w jednym repozytorium po prostu nie byłaby widoczna w drugim.
Niloct

8

Z tego wydania msysgit

Punkty połączeń nie są dowiązaniami symbolicznymi; dlatego dowiązania symboliczne po prostu nie są obsługiwane w msysGit.

Ponadto twarde linki nigdy nie były śledzone przez Git .

Problem dotyczył systemu Windows (ponieważ dotyczy msysgit) i debatowano nad potencjalnym wsparciem łącza symbolicznego.
Ale komentarz dotyczący twardego łącza dotyczy ogólnie Gita.


2

Google „git zachowaj twarde linki” i pokazuje, że git nie wie, jak zachować strukturę twardych linków AFAIK, być może zgodnie z projektem.

Moje projekty internetowe używają twardych linków w następujący sposób:

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*

Gdybym chciał wprowadzić zmiany w index.php, to zmieniam go w jednym miejscu, a twarde linki (strony ze szczegółami produktów) wskazują zmiany - poza tym, że git nie zachowuje tej relacji podczas klonowania i ściągania na innych komputerach.

me@server:www$ git pull

na innym komputerze utworzy nowy plik index.php dla każdego twardego łącza.


7
Powinieneś zaimplementować jakiś rodzaj routingu w swojej aplikacji internetowej. Twarde linkowanie jest dziwne.
Nowaker

5
Tak, przynajmniej używaj linków symbolicznych. :)
Andres Riofrio

2
Właśnie tego chcę, nie chcę, żeby dupek zachowywał twarde linki. Mam katalog Jenkins z mnóstwem katalogów obszarów roboczych, a ze względu na potoki wielobranżowe jest dużo duplikatów. Mam więc codzienną pracę, która polega hardlink --ignore-timena /var/lib/jenkinsodzyskaniu miejsca na dysku. W ciągu dnia niektóre pliki są ponownie odłączane po git pulllub mvn compileale to jest w porządku, spodziewam się, że tak się stanie. Gdyby git miał zachować twarde łącza, moja strategia recyklingu miejsca na dysku nie zadziałałaby.
Amedee Van Gasse
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.