Git: простое решение для нажатия между рабочими копиями
Что я хочу сделать: На моем (ssh удаленно доступном) университетском компьютере я работаю над проектом, который я поставил под git контролем источника (git init
, затем git commit -a
после каждое изменение, все отлично работает). Теперь я хочу захотеть работать над этим проектом на своей частной машине дома. Должно быть легко, так как git является распределенным vcs, правильно?
Я прочитал git учебник, в котором предлагается сделать git pull
в университете, чтобы получить изменения, выполненные дома. Это не сработает, поскольку моя машина дома недоступна. Поэтому я подумал, что я сделаю git push
дома. Это работает, но это сложно (требуется git reset
в университете впоследствии и т.д.), поскольку не-голые репозитории не предназначены для нажатия.
Вопрос 1: Есть ли более простой способ, чем добавление дополнительного голого репозитория в мою установку (что означало бы, что у меня было: (1) "основной" голый репозиторий, (2) университет рабочая копия, (3) домашняя рабочая копия)?
<Rant> Если мне действительно нужна эта настройка, я мог бы остаться с SVN. </Rant>
Вопрос 2: Если эта настройка действительно нужна, как мне создать этот голый репозиторий (git clone --bare
, я думаю) и сделать его "основным" репозиторием, то есть сообщить рабочим копиям что git push
предполагается туда.
PS: Я знаю, что вокруг него появляется плакат post-receive, который позволяет вам входить в не-голые репозитории. Я попробовал, но это не сработало, так как версия git на университетском компьютере довольно старая (1.5.5.6) и пропускает некоторые команды, используемые крюком. Обновление не является вариантом, и я предпочел бы решение без сторонних скриптов.
Ответы
Ответ 1
Вам действительно не следует нажать на отмеченную ветку, поскольку она эффективно вытаскивает коврик из-под удаленной рабочей копии. Трудно это понять, если рабочее дерево изменено, поскольку головка ветки перемещена или были локальные изменения, которые были бы потеряны с помощью reset --hard
.
Самое простое - это нажать на другую ветку. Затем вы можете объединить это в ветку проверки рабочей копии (или переустановить локальную ветвь на нее), когда у вас есть доступ к удаленному компьютеру, и вам нужно работать над ней.
Из дома:
git push origin HEAD:from-home
От "работы":
git merge from-home
Вы можете настроить свою конфигурацию по умолчанию на конкретный push refspec.
например.
git config remote.origin.push +master:from-home
Голый репозиторий часто более естественен. Вы можете либо клонировать его из существующего репозитория, либо, что я обычно делаю, инициализировать новый репозиторий и нажимать главную ветвь, которую я хочу использовать, из существующего репозитория.
Еще лучше, если вы собираетесь использовать рабочие копии в каждом месте, следует использовать этот трюк для непосредственного изменения удаленных пультов, а не специально переименованного ветки.
Итак, по происхождению создайте удаленный вызов "home" - вы, очевидно, не можете извлечь из него из-за своей сетевой конфигурации. Это не имеет значения.
На домашней странице скажите: "Когда я нажимаю на источник, обновите ли он источник с именем home:
git config remote.origin.push +master:home/master
Теперь все становится очень гладко. Из дома запустите git push origin
и перейдите к началу координат и запустите git status
или git branch -a -v
. То, что вы увидите, это что-то вроде: "Мастер находится за домом/мастером на 3 фиксации и может быть быстро перенаправлен".
Другими словами, использование дома для перехода к исходному удалённому имени с именем home, функционально такое же, как использование источника для извлечения из дома.
Единственным недостатком здесь является то, что вам нужно постоянно выполнять новые настройки конфигурации git при создании дополнительных ветвей на дому. Это накладные расходы, которые вы платите за настройку сети. К счастью, это просто и происходит только один раз для каждой ветки.
Ответ 2
-
Этот вопрос подводит итог моему опыту с попыткой синхронизировать две рабочие копии. В конце концов я понял, что было более естественным и простым иметь голый репозиторий. Это не "основной" репозиторий в смысле SVN. Например, вы можете иметь один в uni и один дома, например, и push-pull между ними.
-
Кто-то, вероятно, опубликует правильный способ установки голого репозитория в качестве целевой цели, но, не глядя на документы, я просто удалю рабочую копию и снова клонирую ее из голого репозитория.
Ответ 3
Я решил эту проблему с помощью git-bundle. На моем ноутбуке я делаю git pull
, чтобы получить изменения в апстриме. Это работает над SSH, как и ожидалось. Затем я делаю git bundle
, чтобы поместить свои локальные изменения в пакет, копирую файл пакета на удаленный сервер, а затем ssh на сервер и делаю git pull
из файла пакета.
Из документации:
Некоторые рабочие процессы требуют, чтобы одна или несколько веток разработки на одном компьютере были реплицированы на другом компьютере, но эти два компьютера не могут быть соединены напрямую, и поэтому интерактивные протоколы Git (git, ssh, http) не могут использоваться. Эта команда предоставляет поддержку для работы git fetch и git pull, упаковывая объекты и ссылки в архив на исходной машине, а затем импортируя их в другое хранилище, используя git fetch и git pull после перемещения архива некоторыми способами (например, с помощью sneakernet), Поскольку прямого соединения между репозиториями не существует, пользователь должен указать базу для пакета, который содержится в целевом хранилище: пакет предполагает, что все объекты в базе уже находятся в целевом хранилище.
Мой репозиторий достаточно мал, чтобы я мог добавить все дерево git в комплект, используя --all
. Однако, если ваш репозиторий больше, вы можете добавить в пакет только последние изменения (например, с помощью --since=10.days master
, чтобы получить последние 10 дней). В документах есть еще много примеров.
Вот мой код. В этом случае и ноутбук, и сервер располагают хранилище в одном и том же месте: ~/src/
(это хранилище с непокрытой поверхностью, т.е. рабочая копия). Каталог ~/tmp существует как на сервере, так и на ноутбуке.
TMPDIR=~/tmp
cd ~/src
git pull $server:~/src/
git bundle create $TMPDIR/bundle --all
rsync $TMPDIR/bundle $server:$TMPDIR
ssh $server "cd ~/src;git pull $TMPDIR/bundle"