Какой самый быстрый способ работы в git по медленному сетевому соединению? - PullRequest
14 голосов
/ 02 ноября 2011

Вот сценарий: на работе у нас довольно много веток, и мы не держим репо в таком чистом виде, как должны, время от времени добавляя / удаляя большие файлы или еще много чего, и редко удаляя мертвые ветки.

Итак, сегодня снежный день, и я должен работать из дома.У меня медленное VPN-соединение, и все, что мне нужно, - это самый быстрый способ добраться до одной ветки, о которой я забочусь, и начать работать, с возможностью возврата коммитов назад.

В SVN я бы только что обновилпути / файлы, которые мне были нужны и работали бы в кратчайшие сроки.Как и у большинства новичков в git, у меня есть только несколько доверенных команд, и мой запасной вариант git clone или git pull будет слишком медленным.

Так что, похоже, вопрос состоит из двух частей:

  1. Как мне клонировать репо, чтобы работать как можно быстрее, и
  2. Как вытащить / толкнуть из этого репо (редактировать, зафиксировать, вытащить, нажать)

Рабочий раствор (в соответствии с рекомендациями @ g19fanatic ниже):

> mkdir <project_name>
> cd <project_name>
> git clone -b <branchname> <repo_url> --depth=1
remote: Counting objects: 16679, done.
remote: Compressing objects: 100% (11926/11926), done.
remote: Total 16679 (delta 6936), reused 10919 (delta 3337)
Receiving objects: 100% (16679/16679), 628.12 MiB | 430 KiB/s, done.
Resolving deltas: 100% (6936/6936), done.
> git pull
Already up-to-date.

(внести небольшие изменения на другом компьютере, зафиксировать / нажать)

> git pull
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 5 (delta 0), reused 0 (delta 0)

Отлично,это сработало.

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

Первая неудачная попытка:

Часть 1. Кажется, лучше всего решитьпо:

Вместо того, чтобы git клонировал весь репо со всеми его ветками и историей, создайте новое, пустое репо и извлеките одну ветвь, которая мне нужна, с глубиной 1 (без истории):

mkdir <project_name>
cd <project_name>
git init
git fetch --depth=1 <repo_url> <branchname>:refs/remotes/origin/<branchname>
git checkout <branchname>

Это было здорово, так как он выполнял намного меньшую сетевую передачу, чем полный клон git или pull.

Но теперь у меня возникли проблемы с частью 2) вытягивание и толкание из этого мелководьярепозиторий.Мои коллеги вносят небольшие обновления в течение дня, как и я, поэтому должна быть возможность быстро вытянуть и протолкнуть эти небольшие постепенные изменения.Но когда я пытаюсь настроить ветку как отслеживание удаленного, git pull пытается вытащить всю историю.Кажется, что даже при запуске команды pull или fetch с параметром --depth 1 требуется снова передавать целые снимки (вместо небольших постепенных изменений).

Так что я могу сделать в такой ситуации?(Помимо очевидного - очистите репозиторий, удалив старые элементы истории и мертвые ветви.)

Вторая неудачная попытка (согласно рекомендациям @ g19fanatic ниже):

Идетпо предложению @ g19fanatic я создал репо, используя

> mkdir <project_name>
> cd <project_name>
> git init
> git remote add origin <repo_url>
> git pull origin <branchname> --depth=1
remote: Counting objects: 9403, done.
remote: Compressing objects: 100% (6675/6675), done.
remote: Total 9403 (delta 2806), reused 7217 (delta 2136)
Receiving objects: 100% (9404/9403), 325.63 MiB | 206 KiB/s, done.
Resolving deltas: 100% (2806/2806), done.
...

. Это создало отслеживающую ветвь и правильно извлекло только историю из 1 ветки (~ 9400 объектов, 325 МБ, тогда как полное репо составляет ~ 46k объектов).Тем не менее, опять же, я не могу показаться бесполезным, не извлекая больше информации, чем я считаю необходимым вытащить.Я думаю, что я должен быть в состоянии вытащить мои коллеги коммитов всего за несколько объектов и несколько килобайт.Но вот что я вижу:

> git pull origin <branchname>
remote: Counting objects: 45028, done.
remote: Compressing objects: ... ^C

Это собиралось вытянуть все объекты во всем репо, поэтому я сломал его.Я пробовал тянуть с аргументом --depth = 1:

> git pull origin <branchname> --depth=1
remote: Counting objects: 9870, done.
remote: Compressing objects: 100% (7045/7045), done.
Receiving objects:   4% (430/9870), 4.20 MiB | 186 KiB/s ^C

9k + объекты собирались быть похожими на первоначальное извлечение, но я дал ему немного, потому что думал, что некоторые из этих объектов уже будутсуществуют локальноОднако после того, как он перевел 4+ МБ, я нарушил эту команду, потому что она, кажется, снова выполняет всю передачу.Помните, я ожидаю небольших обновлений от своих коллег, и у меня нет времени каждый раз тратить 300 МБ.

Ответы [ 2 ]

10 голосов
/ 02 ноября 2011

Проведя небольшой тест здесь, я смог сделать следующее ...

У нас есть общий репозиторий --bare в сети

У меня удаленная настройка как git remote add origin <pathToSharedRepo>
я делаю git pull origin <branch> --depth=1 (не на git fetch, а git pull)

это успешно вытягивает только коммиты "HEAD + глубина" для этой ветви. Я могу сделать коммиты к этому и тому подобному, а затем нажать (git push должно работать нормально), вернуть его без проблем.

чтобы получить новые коммиты и ПРОСТО новые коммиты из общего репо, я должен явно набрать git pull origin <branch>. Поскольку именно так я и делал (явно), я должен сделать то же самое на этот раз ...

Это не должно сбрасывать больше истории, чем изначально заданная глубина (это не волнует)


Чтобы завершить, вы также можете выполнить настройку глубины при клонировании репо:
git clone -b <branch> <pathToRepo> --depth=<numCommitsWanted>

1 голос
/ 01 февраля 2019

Есть несколько способов уменьшить пропускную способность:

  • клонировать только нужную вам ветку (--single-branch)
  • клонируйте только самые последние версии файлов (--depth 1, как и вы). Это подразумевает --single-branch по умолчанию.
  • клонировать только те файлы, которые вам нужны (a.k.a. редкая проверка , например здесь )

Кроме того, если вытащить не удается, я использую скрипт bash, подобный этому, чтобы повторять попытки до успешного завершения:

#!/bin/bash

until $( git pull --depth=1 origin master ); do        # <-- pull command goes here
    echo "Pulling repository failed; retrying..."
done
...