Як перейти до неоголеного сховища Git?


150

Я зазвичай працюю на віддаленому сервері через ssh (екран та vim), де у мене є сховище Git. Іноді я не в Інтернеті, тому у мене на ноутбуці є окреме сховище (клоноване з мого пульта).

Однак я не можу витягнути з цього сховища віддалену сторону, тому що я зазвичай за брандмауером або не маю публічної IP-адреси.

Я читав, що мені слід натиснути просто на оголене сховище. Як я можу потім перенести зміни до мого віддаленого сховища?



3
мати 2 віддалених репо, голий і звичайний, і використовувати гачки. здається клопотом, але згідно з git готовими та офіційними вікі git , вам слід лише натиснути на оголене репо . це, мабуть, тому більшість хостів git repo (наприклад, GitHub, Bitbucket) містять гачки після отримання, тож ви можете розмістити URL на вашому сервері, який виконує сценарій, який виконується, наприклад git pull github master.
Джейк Бергер

Відповіді:


137

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

чи можна штовхати, не створюючи голий репо, як це робить
heroku

2
@ANinJa Я не розумію, чи не саме це робить мій приклад?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

є --localнеобов'язковим?
Yukulélé

@ Yukulélé --localвпливає лише на поточний каталог, --globalвпливає на всі git repos ~/.gitconfig, див man git-config.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

1
дякую @CiroSantilli 新疆 改造 中心 六四 事件 法轮功 після прочитання документа підтверджую, що це не потрібно "(можна сказати
місцевий,

146

Найкращий варіант

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

Давайте розглянемо найпростіший випадок і припустимо, що у вас є лише одна гілка в кожному репо: master. Коли ви натискаєте на віддалений репо від свого ноутбука, замість того, щоб натиснути майстер -> майстер, натиснути майстер -> ноутбук-майстер (або подібне ім'я). Таким чином, поштовх не впливає на поточну перевірену головну гілку у віддаленому репо. Для цього з ноутбука команда досить проста:

git push origin master:laptop-master

Це означає, що місцева гілка-майстер буде висунута до гілки з назвою "ноутбук-майстер" у віддаленому сховищі. У вашому віддаленому РЕПО з'явиться нова гілка під назвою "ноутбук-майстер", яку ви зможете потім об'єднати у віддаленого майстра, коли будете готові.

Черговий варіант

Можна також просто натиснути master -> master, але натискання на гілку, яка зараз перевіряється, не голий репо, як правило, не рекомендується, тому що це може заплутати, якщо ви не розумієте, що відбувається. Це пояснюється тим, що натискання на відмінену гілку не оновлює дерево роботи, тому перевірка git statusв відміненій гілці, в яку було висунуто, покаже прямо протилежні відмінності, як і те, що було нещодавно висунуто. Це стане особливо заплутаним, якщо робоче дерево забруднилося до того, як було зроблено натиск, що є великою причиною, чому це не рекомендується.

Якщо ви хочете спробувати просто натиснути master -> master, то команда просто:

git push origin

Але коли ви повернетесь до віддаленого репо, ви, швидше за все, захочете зробити це, git reset --hard HEADщоб синхронізувати робоче дерево з вмістом, який був висунутий. Це може бути небезпечно , оскільки якщо на віддаленому робочому дереві є якісь незапущені зміни, які ви хотіли зберегти, вони видалять їх. Будьте впевнені, що знаєте, які наслідки це, перш ніж спробувати, або хоча б спершу зробіть резервну копію!

EDIT Оскільки Git 2.3, ви можете використовувати "push-to-install" git push: https://github.com/blog/1957-git-2-3-has-been-released . Але натискання на окрему гілку, а потім злиття, як правило, краще, оскільки це фактичне злиття (отже, працює з невмілими змінами так само, як відбувається злиття).


1
Чи можливо автоматизувати розгалуження після натискання ноутбука-майстра?
rdoubleui

3
@rdoubleui: Ви мали на увазі "автоматизувати об'єднання "? Якщо так, ні, неможливо автоматизувати злиття, оскільки злиття не гарантовано неможливі без втручання людини. Можуть бути конфлікти, які потрібно розібратися.
Дан Ліплення

7
у пізніших версіях (?), git config receive.denyCurrentBranch ignoreце потрібно зробити перед тим, як натиснути на
неоголене репост

3
Чудова відповідь @DanMoulding, спасибі @rdoubleui: Ви завжди можете зберегти командний рядок на зразок наступного як функцію bash:git push origin master:laptop-master && ssh user@remotemachine 'cd repos_path && git merge laptop-master'
Rich

@rdoubleui для автоматизації злиття, ви можете використовувати gitolite і налаштувати його (трохи складніше), щоб змусити нечисте зробити все брудним і натиснути його на версію гітоліту (голою) за допомогою тригера pre git. Після цього, якщо злиття не вдасться вирішити в неоголеному, воно відхилить ваш поштовх, тож ви знаєте, що вам потрібно потягнути спочатку, вирішити злиття і натиснути знову. Я ще цього не налаштував, але я зараз перебуваю в процесі і думаю, що це може спрацювати.

17

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

Таким чином, вам не потрібно турбуватися про стан відділення, перевіреного на робочому сервері репо, під час натискання змін на сервері.


4

Інший варіант - встановити зворотний ssh-тунель, щоб ви могли потягнути замість натискання.

# 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

1

Ви можете зробити:

$git config --bool core.bare true

це можна зробити в голому або центральному сховищі, щоб він приймав будь-які файли, що висуваються з не голих сховищ. Якщо ви робите це в неоголеному сховищі, ми не можемо пересилати жодні файли з неоголеного до голого сховища.

Якщо ви практикуєте GIT, створюючи центральний та не голий репо на ПК, він може не показувати натиснуті файли на деяких ПК, але він був висунутий. ви можете перевірити це, запустивши.

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

Крім того, якщо ви натиснете на GitHub, він покаже там файли.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.