Использование Git в нескольких системах без доступа к сети


84

Я хочу использовать контроль версий, но из-за соображений безопасности сервер, на котором я работаю, не имеет доступа к Интернету: я могу перемещать файлы только с USB-накопителя. Могу ли я использовать Git с этой настройкой? Могу ли я создать небольшие патчи, которые я могу применить к Git-репозиторию?


65
Ваш заголовок говорит, что нет доступа к сети, ваш вопрос говорит, что нет доступа в интернет; огромная разница.
tkausl

7
@TutuKaeen У вас может быть локальная сеть, которая не подключена к Интернету. Таким образом, вместо github.com вы устанавливаете git-сервер, например, на. 192.168.1.100 и все остальное работает так же.
Agent_L

12
@TutuKaeen: критический вопрос заключается в том, возможна ли прямая (или косвенная) сетевая связь между двумя компьютерами. Таким образом, в вашем случае обе машины объединены в сеть, но сети разделены? В этом случае, пожалуйста, отредактируйте эту информацию в своем вопросе.
слеске

15
@TutuKaeen Ваш вопрос остается неясным. Вы говорите, что хотите использовать контроль версий, но в ваших комментариях вам требуется, чтобы он помог вам развернуть в производство. Эти проблемы не всегда совпадают. Я думаю, что у вас есть хорошие ответы ниже, но в будущем было бы полезно, если бы ваш вопрос был более полным о ваших требованиях: «Я хочу использовать контроль версий, у моей машины для разработки нет доступа в Интернет, у него есть доступ к сети, но нет рабочего компьютера, и я хочу знать, как вывести код из системы контроля версий на рабочий компьютер ».
DavidS

4
Просто кажется странным использовать термин serverдля машины, не подключенной к какой-либо сети. Это может быть просто локальная сеть, даже без доступа к Интернету, но, тем не менее, это сеть.
Патрик Грегорио

Ответы:


157

Конечно, в Git нет ничего, что требовало бы определенного протокола. Просто из коробки стандартный клиент поддерживает HTTP (S), SSH, протокол пользовательских Git и, что важно, местный протокол. Это просто берет путь к локальному .gitкаталогу, который может быть в рабочем каталоге ( /path/to/project/.git) или просто в пустом каталоге ( /path/to/project.git), хотя именование - это просто соглашение.

Это означает, что вы можете, конечно, добавить флешку в качестве пульта:

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

или в Windows:

git remote add origin F:\foo.git

Или даже добавьте его как дополнительный пульт с другим именем (если вы предпочитаете originуказывать на интернет-сервер где-то):

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

Затем вы можете просто нажать / вытащить в / из этого пульта, как и любой другой.

Если вы прочитаете документацию , вы заметите, что есть file://протокол, который ведет себя немного по-другому. Рекомендуется использовать локальный путь, так как он будет использовать некоторые дополнительные оптимизации - если вы используете file://протокол, то git будет использовать некоторые стандартные сетевые компоненты (для связи с локальным диском), что медленнее.


50
Чтобы добавить к этому исключительному ответу - может также стоить исследовать использование «пустого» репозитория на флэш-накопителе. «голые» репозитории не имеют рабочего дерева и поэтому исключают категорию потенциальных проблем при использовании в качестве общей «точки авторитета», что звучит как сценарий использования ОП.
Железный Кремль

5
Это file://также немного более гибко. Это позволяет вам использовать некоторые функции (например, мелкие клоны), которые вы не можете использовать с локальным путем.
Остин Хеммельгарн

1
@IronGremlin Не могли бы вы расширить эту концепцию "общего авторитета"? Я не эксперт Git, и мне любопытно, что вы подразумеваете под этим.
Гонки

2
@LightnessRacesinOrbit - это довольно плотная тема, но, в основном, git распространяется, поэтому у каждого своя история. A может спросить B об их версии истории, но C не узнает об этом, пока кто-нибудь не скажет им. Наличие единого хранилища для хранения «авторитетной» истории означает, что D выступает в качестве центра обмена историями. Таким образом, A сообщает D об изменениях, а B и C знают, что нужно поговорить с D, чтобы оставаться в курсе, а не делать побочные действия между собой. Например, если сервером OP является C, а флешкой - D, это гарантирует, что сервер не останется в стороне от A / B-взаимодействий.
Железный Кремль

6
@LightnessRacesinOrbit Важно отметить, что «голый» не обязательно означает «авторитетный», он просто полезен в этом контексте. Например, это также полезно, потому что, из-за отсутствия рабочего дерева, это занимает меньше места на диске (или пропускной способности). Раньше это было намного важнее, чем сейчас, но все же приходит в голову.
Железный Кремль

46

На одном компьютере ничего особенного не требуется. Запустите git initнужный каталог и работайте с Git, как обычно.

Для синхронизации хранилища на нескольких компьютерах существует несколько способов.

Метод 1a (сети вообще нет). Вы можете создать «пустой репозиторий» на USB-накопителе, затем нажать на него и извлечь из него, как если бы это было с любым другим удаленным репозиторием. Другими словами, операции с хранилищем через локальные пути ничем не отличаются от операций через URL-адреса SSH или HTTPS.

  1. Создайте «удаленный» репозиторий:

    $ git init --bare /mnt/Stick/Repositories/Large_Project.git
    
  2. В компьютере 1 нажмите на него все:

    $ cd ~/Large_Project
    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git push usb master
    
  3. В компе 2 ну так же как всегда.

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

(Вы также можете нажать / извлечь / извлечь из URL или пути напрямую.)

Метод 1b (внутренняя сеть): если у вас есть внутренний сервер с доступным SSH, и если на нем установлен Git, вы можете сделать то же, что и выше , просто укажите адрес SSH с помощью синтаксиса [user@]host:pathили ssh://[user@]host/path.

  1. Создайте «удаленный» репозиторий, запустив его git init --bare <somepath.git>на указанном сервере (через SSH).

  2. В компьютере 1 так же, как продемонстрировано ранее.

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

    Или, если вы предпочитаете:

    $ git remote add origin ssh://myserver.example.com/Gits/Large_Project.git
    
  3. В компьютере 2 опять то же самое, что и в методе 1а.


Способ 2: Вы можете создать «пакеты передачи», которые заархивируют данный список коммитов в один файл.

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

  1. На компьютере 1 создайте связку всей ветви:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle master
    $ git tag -f last-bundled master
    
  2. На компьютере 2 вытащите из пакета, как будто это хранилище:

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

Последующие пакеты не должны упаковывать все целиком master- last-bundled..masterвместо этого они могут упаковывать только что добавленные коммиты .

  1. На компьютере 1 создайте пакет недавно добавленных коммитов:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle last-bundled..master
    $ git tag -f last-bundled master
    
  2. То же, что и выше.


на самом деле это не было бы плохо для моих целей, также в git нет ничего «первичного», так как каждый репозиторий имеет всю историю, так что вы можете воссоздавать ее каждый раз, когда что-то идет не так
Туту Каин

manual tagging or note-keeping is needed, один вариант, если репо не очень большой, это:, git bundle create my.bundle --allон должен содержать все
birdpider

Мне больше нравится этот ответ, так как он более нагляден, хотя принятый ответ и говорит о том же.
Rystraum

Каково значение «голого» варианта?
Гонки

1
Он создает хранилище, которое представляет собой просто базу данных (то, что вы обычно находите в .git/скрытой папке), без «рабочего дерева» (редактируемые файлы). Это предпочтительная форма для репозиториев, что вы git push.
благодарность

20

git bundle create

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

Каждый «git push» превращается в создание файла, «git fetch» ​​выбирает вещи из этого файла.

Демо сессия

Создание первого репозитория и выполнение первого «толчка»

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)

«клонирование» во второй репозиторий (т.е. на второй компьютер):

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

gitbundletest$ cd repo2/

repo2$ cat 1
1

Делаем некоторые изменения и «помещаем» их в другой пакетный файл:

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)

«вытягивание» изменений в первый репозиторий:

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

В отличие от первого пакета, второй содержит только частичную историю Git и не может быть напрямую клонирован:

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

Недостатком использования пакетов является то, что вам нужно вручную указывать, какой диапазон коммитов должен содержать каждый пакет. В отличие от этого git push, git bundleне отслеживает то, что было в предыдущем пакете, вам нужно вручную настроить, refs/remotes/origin/masterиначе пакеты будут больше, чем могли бы быть.


Не забудьте упомянуть --allфлаг, чтобы получить все. Если репо достаточно мало, это самый простой процесс, так как вы просто все переносите каждый раз! Только не теряйте карту памяти - вероятно, самая большая проблема безопасности!
Филип Окли

7

Вам нужно сначала установить Git . Затем, чтобы создать новый репозиторий, запустите в папке, которую вы скопировали:

git init

Затем вы можете добавить файлы, для которых вы хотите управлять версиями git add(добавить -aдля всех файлов), и начать фиксировать изменения ( git commit).

Вам не нужно нажимать на какие-либо пульты, так как вы можете работать с вашей локальной историей ( git log).

Для получения дополнительной информации, проверьте:


Тяни / тянем без интернета

Используя git pushкоманду, можно передать SSH (используя локальное соединение, интранет):

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

или нажать в папку:

git push /mnt/usb/my_repo

Это предполагает, что у вас есть две копии вашего хранилища.

То же самое с потянув, например,

git pull /mnt/usb/my_repo

Заделка

Чтобы применить патчи, вы можете использовать patchкоманду или git apply.

Смотрите: Создайте файл патча или diff из репозитория git и примените его к другому другому репозиторию git .


5

Вы также можете использовать Git локально. Тогда ваши коммиты хранятся только локально, и у вас все еще есть контроль версий (и вы можете различать / объединять и т. Д.), Но вы просто не можете получить доступ к хранилищу с любого другого компьютера.

Вы можете запустить локальный Git-репозиторий, запустив его git initв локальной папке. Как описано здесь .


3
что я знаю, но я хочу работать на другом компьютере и применить его к файлам на сервере без доступа к Интернету
Туту Каин

2
@ TutuKaeen Я не вижу ничего плохого в том, что репозиторий находится на флеш-накопителе и просто клонируется / синхронизируется с жесткими дисками разных компьютеров. Тем не менее, «сервер без доступа в Интернет» звучит странно, цель сервера - предоставить услугу, чаще всего эта услуга связана с сетью (но не всегда, действительно).
AnonymousLurker

2
@dhae - Пожалуйста, уделите немного времени, чтобы предоставить более подробную информацию о том, как использовать Git локально. Только указание, что это может быть сделано, не так уж полезно для ответа.
Ramhound

2
@anonymousLurker служба обслуживает передачу данных в закрытую сеть в очень важном учреждении. Он просто ничего не дает широкому интернету, поскольку данные очень деликатны и предназначены только для сотрудников.
Туту Каин

1
@TutuKaeen: Если есть какой - либо доступ к сети, вы всегда можете запустить свой собственный сервер Git через SSH. Git - это больше, чем просто GitHub.
Гравитация
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.