Как перенести в не-голый репозиторий Git?

Я обычно работаю на удаленном сервере через ssh (screen и vim), где у меня есть Git-репозиторий. Иногда я не в сети, поэтому на моем ноутбуке есть отдельный репозиторий (клонированный с моего пульта).

Тем не менее, я не могу извлечь из этого хранилища на удаленной стороне, потому что я обычно за брандмауэром или у меня нет общедоступного IP-адреса.

Я читал, что я должен нажать только на пустой репозиторий. Как мне затем отправить свои изменения в мой удаленный репозиторий?

5 ответов

Решение

receive.denyCurrentBranch updateInstead

Эта опция была добавлена в Git 2.3, и она заставляет сервер обновлять свое рабочее дерево, если оно чистое.

Таким образом, если вы гарантируете, что всегда выполняете коммит, прежде чем извлекать локально, и сохраняете чистое рабочее дерево на сервере (что вы должны делать, чтобы избежать конфликтов слияния), то этот вариант является хорошим решением.

Пример использования:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

Выход:

a
b

Лучший вариант

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

Давайте рассмотрим простейший случай и предположим, что в каждом репо есть только одна ветвь: master. Когда вы нажимаете на удаленное репо с вашего ноутбука, вместо нажатия мастер -> мастер, нажмите мастер -> ноутбук-мастер (или аналогичное имя). Таким образом, push не влияет на текущую извлеченную главную ветку в удаленном репо. Чтобы сделать это с ноутбука, команда довольно проста:

git push origin master:laptop-master

Это означает, что локальная главная ветвь будет помещена в ветку с именем "ноутбук-мастер" в удаленном хранилище. В вашем удаленном репо у вас будет новая ветка с именем "ноутбук-мастер", которую вы сможете объединить с вашим удаленным мастером, когда будете готовы.

Альтернативный вариант

Также возможно просто нажать master -> master, но обычно не рекомендуется отправка в текущую извлеченную ветвь непроигранного репо, потому что это может сбить с толку, если вы не понимаете, что происходит. Это потому, что нажатие на извлеченную ветвь не обновляет рабочее дерево, поэтому проверка git status в извлеченной ветке, которая была помещена в, будет отображаться противоположное отличие от того, что было добавлено совсем недавно. Было бы особенно запутанно, если бы дерево работ было грязным до того, как был сделан пуш, что является большой причиной, почему это не рекомендуется.

Если вы хотите просто нажать master -> master, то команда будет просто:

git push origin

Но когда вы вернетесь к удаленному репо, вы, скорее всего, захотите сделать git reset --hard HEAD чтобы синхронизировать рабочее дерево с содержимым, которое было передано. Это может быть опасно, потому что, если в удаленном рабочем дереве есть какие-либо незафиксированные изменения, которые вы хотели бы сохранить, оно уничтожит их. Убедитесь, что вы знаете, каковы последствия этого, прежде чем попробовать, или, по крайней мере, сначала сделайте резервную копию!

РЕДАКТИРОВАНИЕ Начиная с Git 2.3, вы можете использовать "push-to-deploy" git push: https://github.com/blog/1957-git-2-3-has-been-released. Но лучше перейти к отдельной ветви, а затем к слиянию, поскольку оно выполняет фактическое слияние (следовательно, работает с незафиксированными изменениями, как слияние).

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

Таким образом, вам не нужно беспокоиться о состоянии ветки, проверенной на рабочем репо сервера, при отправке изменений на сервер.

Другой вариант - настроить обратный ssh-туннель, чтобы вы могли тянуть вместо push.

# start the tunnel from the natted box you wish to pull from (local)
$ ssh -R 1234:localhost:22 user@remote

# on the other box (remote)
$ git remote add other-side ssh://user@localhost:1234/the/repo
$ git pull other-side

И если вы хотите, чтобы туннель работал в фоновом режиме

$ ssh -fNnR 1234:localhost:22 user@remote

Ты можешь сделать:

$git config --bool core.bare true

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

Если вы практикуете GIT, создавая центральное и не обнаженное репо на ПК, он может не показывать загруженные файлы на некоторых ПК, но он был перенесен. Вы можете проверить это, запустив.

$git log в центральном репо.

Если вы не нажмете на GitHub, он покажет файлы там.

Другие вопросы по тегам