Używanie Git w wielu systemach bez dostępu do sieci

84

Chcę używać kontroli wersji, ale ze względów bezpieczeństwa serwer, na którym pracuję, nie ma dostępu do Internetu: mogę przenosić pliki tylko na dysku flash USB. Czy nadal mogę używać Git w tej konfiguracji? Czy mogę tworzyć małe łatki, które mogę zastosować w repozytorium Git?

Tutu Kaeen
źródło
65
Twój tytuł mówi brak dostępu do sieci, twoje pytanie mówi o braku dostępu do Internetu; ogromna różnica.
tkausl
7
@TutuKaeen Możesz mieć sieć lokalną, która nie jest połączona z Internetem. Zamiast github.com konfigurujesz serwer git np. 192.168.1.100 i wszystko inne działa tak samo.
Agent_L
12
@TutuKaeen: Krytycznym pytaniem jest, czy możliwa jest bezpośrednia (lub pośrednia) komunikacja sieciowa między dwoma komputerami. Więc w twoim przypadku oba komputery są połączone w sieć, ale sieci są rozdzielone? W takim przypadku edytuj te informacje w swoim pytaniu.
sleske
15
@TutuKaeen Twoje pytanie pozostaje niejasne. Mówisz, że chcesz użyć kontroli wersji, ale w swoich komentarzach potrzebujesz, aby pomogła Ci ona wdrożyć do produkcji. Te problemy nie zawsze się pokrywają. Myślę, że masz teraz dobre odpowiedzi, ale w przyszłości byłoby pomocne, gdyby twoje pytanie było bardziej wyczerpujące na temat twoich wymagań, które wyglądają tak: „Chcę używać kontroli wersji, moja maszyna programistyczna nie ma dostępu do Internetu, ma dostęp do sieci, ale nie ma dostępu do komputera produkcyjnego, i chcę wiedzieć, jak uzyskać kod z kontroli wersji na maszynę produkcyjną. ”
DavidS,
4
Po prostu dziwnie jest używać tego terminu serverdla maszyny niepodłączonej do żadnej sieci. Może to być tylko sieć lokalna, nawet bez dostępu do Internetu, ale mimo to jest to sieć.
Patrick Gregorio,

Odpowiedzi:

157

Jasne, w Git nie ma nic, co wymaga określonego protokołu. Zaraz po wyjęciu z pudełka standardowy klient obsługuje HTTP (S), SSH, niestandardowy protokół Git i, co ważne, protokół lokalny . To tylko pobiera ścieżkę do .gitkatalogu lokalnego , który może znajdować się w katalogu roboczym ( /path/to/project/.git) lub po prostu katalogu ( /path/to/project.git), choć nazewnictwo to tylko konwencja.

Oznacza to, że możesz oczywiście dodać dysk flash jako zdalny:

git remote add origin /mnt/flashdrive/foo.git

lub w systemie Windows:

git remote add origin F:\foo.git

Lub nawet dodaj go jako dodatkowego pilota o innej nazwie (jeśli wolisz originwskazywać gdzieś serwer internetowy):

git remote add flashdrive /mnt/flashdrive/foo.git

Następnie możesz po prostu nacisnąć / pociągnąć do / z tego pilota, tak jak każdy inny.

Jeśli przeczytasz dokumentację , zauważysz, że istnieje również file://protokół, który zachowuje się nieco inaczej. Zalecane jest użycie ścieżki lokalnej, ponieważ wykorzysta to dodatkowe optymalizacje - jeśli użyjesz file://protokołu, git użyje standardowych komponentów sieciowych (do rozmowy z dyskiem lokalnym), co jest wolniejsze.

Kok
źródło
50
Aby dodać do tej wyjątkowej odpowiedzi - warto również zbadać, używając „nagiego” repozytorium na dysku flash. „nagie” repozytoria nie mają działającego drzewa, dlatego też należy wykluczyć kategorię potencjalnych problemów, gdy są używane jako wspólny „punkt upoważnienia”, co brzmi jak przypadek użycia PO.
Iron Gremlin
5
file://Jest nieco bardziej elastyczną. Umożliwia korzystanie z niektórych funkcji (takich jak płytkie klony), których nie można użyć w przypadku lokalnej ścieżki.
Austin Hemmelgarn
1
@IronGremlin Czy mógłbyś rozwinąć to pojęcie „wspólnego punktu władzy”? Nie jestem ekspertem od Gita i jestem ciekawy, co masz na myśli.
Wyścigi lekkości na orbicie
2
@LightnessRacesinOrbit - To dość gęsty temat, ale zasadniczo git jest rozpowszechniany, więc każdy ma swoją własną historię. A może poprosić B o swoją wersję historii, ale C nie wie o tym, chyba że ktoś im to powie. Posiadanie jednego repozytorium do przechowywania „autorytatywnej” historii oznacza, że ​​D działa jako izba rozliczeniowa dla historii. A więc A mówi D o zmianach, a B i C wiedzą, aby porozmawiać z D, aby być na bieżąco, zamiast robić rzeczy między sobą. W tym przypadku, jeśli serwer OP to C, a dysk flash to D, zapewnia, że ​​serwer nie zostanie pominięty w wyniku interakcji A / B.
Iron Gremlin
6
@LightnessRacesinOrbit Ważne, aby zauważyć, że gołe nie musi oznaczać autorytatywnego, jest po prostu przydatne w tym kontekście. Jest to na przykład przydatne, ponieważ bez działającego drzewa jest to mniejszy obszar na dysku (lub przepustowości). Kiedyś było to o wiele ważniejsze niż obecnie, ale wciąż się pojawia.
Iron Gremlin,
46

Na jednym komputerze nic specjalnego nie jest potrzebne. Uruchom git initw wybranym katalogu i pracuj z Git tak jak zwykle.

Istnieje kilka metod synchronizacji repozytorium na wielu komputerach.

Metoda 1a (w ogóle brak sieci): Możesz utworzyć „puste repozytorium” na pamięci USB, a następnie pchnąć do niego i wyciągnąć z niego, tak jak w przypadku każdego innego zdalnego repozytorium. Innymi słowy, operacje repozytorium za pośrednictwem lokalnych ścieżek nie różnią się niczym od operacji za pośrednictwem adresów URL SSH lub HTTPS.

  1. Utwórz „zdalne” repozytorium:

    $ git init --bare /mnt/Stick/Repositories/Large_Project.git
    
  2. Na komputerze 1 wepchnij wszystko do niego:

    $ cd ~/Large_Project
    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git push usb master
    
  3. Na komputerze 2, tak samo jak zawsze.

    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git pull usb
    

(Możesz również push / fetch / pull bezpośrednio z adresu URL lub ścieżki).

Metoda 1b (sieć wewnętrzna): Jeśli masz wewnętrzny serwer z SSH i jeśli jest zainstalowany Git, możesz zrobić to samo, co powyżej , po prostu podaj adres SSH za pomocą składni [user@]host:pathlub ssh://[user@]host/path.

  1. Utwórz „zdalne” repozytorium, uruchamiając je git init --bare <somepath.git>na wyznaczonym serwerze (przez SSH).

  2. Na komputerze 1 w taki sam sposób, jak pokazano wcześniej.

    $ git remote add origin myserver.example.com:Gits/Large_Project.git
    

    Lub jeśli wolisz:

    $ git remote add origin ssh://myserver.example.com/Gits/Large_Project.git
    
  3. Na komputerze 2 ponownie to samo co metoda 1a.


Metoda 2: Możesz utworzyć „pakiety transferu”, które archiwizują podaną listę zatwierdzeń w jednym pliku.

Niestety polecenia pakietu nie zapamiętują automatycznie tego, co było już w pakiecie ostatnim razem, dlatego konieczne jest ręczne tagowanie lub zapisywanie notatek. Po prostu wezmę przykłady z podręcznika git-bundle.

  1. Na komputerze 1 utwórz pakiet całej gałęzi:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle master
    $ git tag -f last-bundled master
    
  2. Na komputerze 2 wyciągnij z pakietu, jakby to było repozytorium:

    $ cd ~/Large_Project
    $ git pull /mnt/Stick/Project.bundle
    

Kolejne pakiety nie muszą pakować całości master- mogą last-bundled..masterzamiast tego spakować tylko nowo dodane commity .

  1. Na komputerze 1 utwórz pakiet nowo dodanych zatwierdzeń:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle last-bundled..master
    $ git tag -f last-bundled master
    
  2. Jak powyżej.

grawitacja
źródło
właściwie to nie byłoby złe dla moich celów, również w git nic nie jest „podstawowe”, ponieważ każde repozytorium ma całą historię, więc możesz go odtworzyć za każdym razem, gdy coś pójdzie nie tak
Tutu Kaeen
manual tagging or note-keeping is needed, jedna opcja, chyba że repo jest bardzo duże, to: git bundle create my.bundle --allpowinna zawierać wszystko
pająka ptaka
Bardziej podoba mi się ta odpowiedź, ponieważ jest bardziej ilustracyjna, mimo że zaakceptowana odpowiedź i to mówi to samo.
Rystraum
Jakie znaczenie ma opcja „goła”?
Wyścigi lekkości na orbicie
1
Tworzy repozytorium, które jest tylko bazą danych (co zwykle znajduje się w .git/ukrytym folderze), bez „działającego drzewa” (plików edytowalnych). Jest to preferowana forma repozytoriów git push.
grawity
20

git bundle create

Jedną z metod jest użycie pamięci zewnętrznej do wymiany danych między repozytoriami to pakiet git . W ten sposób masz tylko pojedyncze pliki dla każdego transferu, a nie pośrednie repozytoria Git.

Każde „git push” zmienia się w tworzenie pliku, „git fetch” pobiera rzeczy z tego pliku.

Sesja demonstracyjna

Utworzenie pierwszego repozytorium i wykonanie pierwszego „push”

gitbundletest$ mkdir repo1

gitbundletest$ cd repo1

repo1$ git init
Initialized empty Git repository in /tmp/gitbundletest/repo1/.git/
repo1$ echo 1 > 1 && git add 1 && git commit -m 1
[master (root-commit) c8b9ff9] 1
 1 file changed, 1 insertion(+)
 create mode 100644 1

repo1$ git bundle create /tmp/1.bundle master HEAD
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 384 bytes | 384.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)

„klonowanie” do drugiego repozytorium (tj. drugiego komputera):

gitbundletest$ git clone /tmp/1.bundle repo2
Cloning into 'repo2'...
Receiving objects: 100% (3/3), done.

gitbundletest$ cd repo2/

repo2$ cat 1
1

Wprowadzanie pewnych zmian i „wypychanie” ich do innego pliku pakietu:

repo2$ echo 2 > 1 && git add 1 && git commit -m 2
[master 250d387] 2
 1 file changed, 1 insertion(+), 1 deletion(-)

repo2$ git bundle create /tmp/2.bundle origin/master..master origin/HEAD..HEAD
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 415 bytes | 415.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)

„ściąganie” zmian do pierwszego repozytorium:

repo2$ cd ../repo1

repo1$ git pull /tmp/2.bundle 
Receiving objects: 100% (3/3), done.
From /tmp/2.bundle
 * branch            HEAD       -> FETCH_HEAD
Updating c8b9ff9..250d387
Fast-forward
 1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

repo1$ cat 1
2

W przeciwieństwie do pierwszego pakietu, drugi zawiera tylko częściową historię Git i nie można go bezpośrednio klonować:

repo1$ cd ..

gitbundletest$ git clone /tmp/2.bundle repo3
Cloning into 'repo3'...
error: Repository lacks these prerequisite commits:
error: c8b9ff94942039469fa1937f6d38d85e0e39893a 
fatal: bad object 250d38747656401e15eca289a27024c61e63ed68
fatal: remote did not send all necessary objects

Wadą jest używanie pakietów, które wymagają ręcznego określania zakresu zatwierdzeń, które powinien zawierać każdy pakiet. W przeciwieństwie do tego git push, git bundlenie śledzi tego, co było w poprzednim pakiecie, musisz ręcznie dostosować, refs/remotes/origin/masterinaczej pakiety będą większe niż mogłoby być.

Vi.
źródło
Nie zapomnij wspomnieć o --allflagi, aby uzyskać wszystko. Jeśli repo jest wystarczająco małe, jest to najprostszy proces, ponieważ po prostu przenosisz wszystko za każdym razem! Tylko nie zgub karty pamięci - prawdopodobnie największy problem z bezpieczeństwem!
Philip Oakley,
7

Musisz najpierw zainstalować Git . Następnie, aby utworzyć nowe repozytorium, uruchom w skopiowanym folderze:

git init

Następnie możesz dodać pliki, które chcesz kontrolować wersję git add(dodaj -adla wszystkich plików) i zacznij zatwierdzać zmiany ( git commit).

Nie musisz naciskać na żaden pilot, ponieważ możesz pracować nad historią lokalną ( git log).

Aby uzyskać więcej informacji, sprawdź:


Pchanie / ciągnięcie bez internetu

Za pomocą git pushpolecenia można przesłać SSH (przy użyciu połączenia lokalnego, intranetu):

git remote add server ssh://[user@]host.xz[:port]/path/to/dev/repo.git/
git push server

lub wypychanie do folderu:

git push /mnt/usb/my_repo

Zakłada się, że masz dwie kopie swojego repozytorium.

To samo z ciągnięciem, np

git pull /mnt/usb/my_repo

Łatanie

Aby zastosować łaty, możesz użyć patchpolecenia lub git apply.

Zobacz: Utwórz plik poprawki lub pliku różnicowego z repozytorium git i zastosuj go do innego innego repozytorium git .

kenorb
źródło
5

Możesz także używać Git lokalnie. Wtedy twoje zatwierdzenia są przechowywane tylko lokalnie i nadal masz kontrolę nad wersją (i możesz różnicować / scalać itp.), Ale po prostu nie możesz uzyskać dostępu do repozytorium z innego komputera.

Możesz uruchomić lokalne repozytorium Git, uruchamiając je git initw folderze lokalnym. Jak opisano tutaj .

dhae
źródło
3
że wiem, ale chcę pracować na innym komputerze i zastosować go do plików na serwerze bez dostępu do Internetu
Tutu Kaeen
2
@TutuKaeen Nie widzę nic złego w posiadaniu repozytorium na dysku flash i klonowaniu / synchronizacji z dyskami twardymi różnych komputerów. Jednak „serwer bez dostępu do Internetu” brzmi dziwnie, celem serwera jest zapewnienie usługi, najczęściej usługa jest związana z siecią (ale nie zawsze tak naprawdę).
AnonymousLurker
2
@dhae - poświęć chwilę, aby podać więcej szczegółów na temat korzystania z Git lokalnie. Tylko wskazanie, że można to zrobić, nie jest pomocne w odpowiedzi.
Ramhound,
2
@anonymousLurker obsługujący podaje dane do zamkniętej sieci w bardzo ważnej instytucji. Po prostu nic nie służy szerokiemu internetowi, ponieważ dane są bardzo delikatne i tylko dla pracowników.
Tutu Kaeen
1
@TutuKaeen: Jeśli ma żadnego dostępu do sieci, zawsze można uruchomić własny serwer Git poprzez SSH. Git to coś więcej niż tylko GitHub.
grawity