тягнути / натискати з декількох віддалених місць


743

Короткий: чи є спосіб підключити git repo до списку віддалених репостів (а не одного "походження")?

Довге: у мене часто виникає ситуація, коли я розробляю додаток на кількох комп’ютерах, з різним підключенням - скажімо, ноутбук під час переїзду, комп’ютер "А", коли я перебуваю в певному місці, та інший комп'ютер "В" а на іншому. Крім того, ноутбук може мати з'єднання лише з "A" або "B", а іноді і з обома.

Мені хотілося б, щоб git завжди "витягувався" з усіх комп'ютерів, до яких він зараз може підключитися, "легше" перестрибувати з однієї машини на іншу і продовжувати працювати безперешкодно.


39
Примітка для нових відвідувачів, як в 2016 році: зараз правильний спосіб зробити це, санкціоноване першим клас gitфункціями, входить в malvineous «s відповіді нижче . Прийнята відповідь невірна.
ELLIOTTCABLE

@Zorzella: Чи можете ви оновити прийняту відповідь на це, це начебто заплутано те, що є зараз.
ntninja

Відповіді:


503

Ви можете налаштувати кілька віддалених сховищ за допомогою git remoteкоманди:

git remote add alt alt-machine:/path/to/repo

Щоб отримати з усіх конфігурованих віддалених та оновлених гілок відстеження, але не зливатися в них HEAD, виконайте:

git remote update

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

Щоб отримати головну гілку з alt і потягнути її в поточну голову, виконайте:

git pull alt master

Тож насправді git pullце майже скорочення git pull origin HEAD(насправді він шукає у конфігураційному файлі, щоб визначити це, але ви розумієте).

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


тож, про що ви говорите, це те, що "git remote add foo ssh: //foo.bar/baz" створює скорочену форму, але мені все одно потрібно перекинути їх на "git pull" або перекинути їх на "git" злиття "(який тут синтаксис, після" оновлення видалення git "?) Чи не буде це ім'я скорочення також працювати для" git push "? Тобто я не можу "git push foo" тощо (цикл)? Спасибі
Зорзелла

8
"git pull" - це в основному "git fetch" з подальшим "git merge". "git віддалене оновлення" просто виконує купу "git fetch" для вас. Тож залишається зробити біт "git merge". Ви можете сказати "git merge origin / master", і він об'єднає версію master master з вашою поточною HEAD. "master git origin origin" робить те саме, хоча це зробить спочатку (і якщо ви вже зробили віддалене оновлення git, то більше нічого не вийде, тому це зайве). Так, ви можете сказати "git push foo", і це підштовхне всі відповідні гілки до віддаленого під назвою "foo".
araqnid

IIUC ви не можете перейти в робочий сховище (адже ви можете натискати на несумісні / неперевірені / небажані зміни). Ми повинні проникати в голі сховища і отримувати оновлення лише тоді, коли ми тягнемо. Тож рішення потребує робочого та чистого сховища на кожній машині?
joeytwiddle

2
Мабуть , ви також можете мати один єдиний поштовх для декількох операцій РЕПО, перевірити цей відповідь для більш докладної інформації stackoverflow.com/questions/14290113 / ...
manei_cc

797

Робити це вручну більше не потрібно , з сучасними версіями git! Дивіться рішення Malvineous нижче.

Відтворено тут:

git remote set-url origin --push --add <a remote>
git remote set-url origin --push --add <another remote>

Оригінальна відповідь:

Це те, що я використовую досить довгий час без поганих наслідків, і запропонував Лінус Торвальдс у списку розсилки git .

Рішення araqnid є правильним для введення коду у ваше сховище ... але коли у вас, як і у мене, є кілька еквівалентних авторитетних вхідних потоків (я зберігаю деякі мої більш критичні проекти, клоновані як до приватного верхів'я, GitHub, так і до Codaset), це може бути болем підштовхувати зміни до кожного, щодня.

Короткий виклад короткої історії, git remote addусі ваші git config -eвіддалені програми окремо…, а потім додайте об'єднаний дистанційний. Якщо припустимо, що у вас є це сховище config:

[remote "GitHub"]
    url = git@github.com:elliottcable/Paws.o.git
    fetch = +refs/heads/*:refs/remotes/GitHub/*
[branch "Master"]
    remote = GitHub
    merge = refs/heads/Master
[remote "Codaset"]
    url = git@codaset.com:elliottcable/paws-o.git
    fetch = +refs/heads/*:refs/remotes/Codaset/*
[remote "Paws"]
    url = git@github.com:Paws/Paws.o.git
    fetch = +refs/heads/*:refs/remotes/Paws/*

… Щоб створити об'єднаний віддалений для, "Paws"і "Codaset"я можу додати наступне після всіх цих:

[remote "Origin"]
    url = git@github.com:Paws/Paws.o.git
    url = git@codaset.com:elliottcable/paws-o.git

Як тільки я це зробив, коли я git push Origin Master, це підштовхне до обох Paws/Masterі Codaset/Masterпослідовно, полегшуючи життя.


104
git config -eвідкриває .git/configфайл у вибраному редакторі.
Річард

3
Про всяк випадок. Підтвердження того, що наявність пульта з двома URL-адресами все-таки виконують роботу 1.7.12.4. Дякую.
foobar

26
Я назвав "походження" віддаленим "всім", щоб дати йому трохи більш чисту семантику
ErichBSchulz

1
@JamesWomack див. Відповідь @ Malvineous нижче. Зараз "правильніше", оскільки gitкомандний рядок підтримує це спочатку, з git remote set-url ... --add.
ELLIOTTCABLE

1
Під [branch "Master"]набором remote = Originі git pullвикористовуватиме обидва пульта.
Бенгт

264

З git 1.8 (жовтень 2012) ви можете це зробити з командного рядка:

git remote set-url origin --push --add user1@repo1
git remote set-url origin --push --add user2@repo2
git remote -v

Потім git pushнатисніть на user1 @ repo1, потім натисніть на user2 @ repo2.


19
Я настійно раджу проти цього рішення. Ми використовували його в нашій компанії і потрапили в серйозні проблеми, коли гачки вийшли з ладу в одному сховищі, а не в іншому. Набори змін тоді були лише в одному сховищі.
Michael Schmeißer

4
@ MichaelSchmeißer: Імовірно, ви могли бачити повідомлення про помилки під час натискання, проте, виправте проблему, а потім натисніть знову, щоб повернути все до чистого стану?
Malvineous

7
Проблема полягає в тому, що виправлення відхиленого поштовху передбачає зміну комітетів, які вже були передані іншому репо. Отже, якщо хтось уже базується на цих зобов'язаннях до моменту їх фіксації, справи стають справді неприємними, що було в нашому офісі.
Michael Schmeißer

9
Ага так, це може стати складним. Однак мені здається, що гачки потрібно переробити. Невдалий поштовх не ламає git звичайно, тому введення нової точки відмови (що також заважає вам використовувати витончену функцію git), мабуть, не найкраще рішення. Звичайно, я кажу це, не знаючи, які ваші вимоги ...
Malvineous

3
Ні. Після написання запитання я читав інші публікації в Інтернеті, а потім перевіряв цю річ. Читаючи інші публікації, у мене з’явилася підозра, що використовується лише перший рядок. Я щойно перевірив це: дійсно, перевіряється лише URL-адреса з першого рядка git fetch. (З огляду на це, я не розумію, яка мета git remote set-url --addможе бути без --push.)
imz - Іван Захарящев

34

Ці псевдоніми я додав до мого ~ / .bashrc:

alias pushall='for i in `git remote`; do git push $i; done;'
alias pullall='for i in `git remote`; do git pull $i; done;'

6
Це круто! У мене з'явився псевдонім Git: git config alias.pushall '!for i in git remote; do git push $i; done;'
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

Я думаю, що я віддаю перевагу рішення псевдоніму перед створенням нового пульта. Дивіться також stackoverflow.com/questions/41372919 / ...
donquixote

1
Невелика запропонована настройка:alias pushall='for i in `git remote`; do echo "Pushing to " $i; git push $i; done;'
Скотт C Вілсон

25

Ви можете додавати пульти за допомогою:

git remote add a urla
git remote add b urlb

Тоді для оновлення всіх репостів зробіть:

git remote update

15

Ось мій приклад із скриптом bash у .gitconfigрозділі псевдоніму

[alias]
        pushall = "!f(){ for i in `git remote`; do git push $i; done; };f"

7

Я додав два окремих pushurl до віддаленого "походження" у файлі .git congfig. Коли я запускаю, git push origin "branchName"тоді він буде пробігати і натискати на кожен URL. Не впевнений, чи є простіший спосіб досягти цього, але це працює для мене, щоб перейти до вихідного коду Github і одночасно перейти до вихідного коду My.visualStudio.

[remote "origin"]
  url = "Main Repo URL"
  fetch = +refs/heads/*:refs/remotes/origin/*
  pushurl = "repo1 URL"
  pushurl = "reop2 URl"

4

Я взяв на себе сміливість розширити відповідь від nona-urbiz; просто додайте це до свого ~ / .bashrc:

git-pullall () { for RMT in $(git remote); do git pull -v $RMT $1; done; }    
alias git-pullall=git-pullall

git-pushall () { for RMT in $(git remote); do git push -v $RMT $1; done; }
alias git-pushall=git-pushall

Використання:

git-pullall master

git-pushall master ## or
git-pushall

Якщо ви не надаєте жодного аргументу гілки для git-pullall, витягнути з віддалених за замовчуванням віддалених файлів не вдасться; залишила таку поведінку такою, якою вона є, оскільки вона аналогічна git.


3

Вам знадобиться сценарій, щоб пропустити їх. Git не забезпечує "push all". Теоретично можна зробити поштовх у декількох потоках, але нативний метод недоступний.

Витягнути ще складніше, і я рекомендую робити це лінійно.

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


2
Проблема полягає в тому, що, як я описав, немає центральної завжди доступної коробки. Якщо мені доведеться писати циклічний баш-скрипт, нехай буде, але смішно, що розподілений VC мені тут більше не допоможе ...
Zorzella,

2
Розподіляючи, це передбачає, що далеко не всі є доступними або хотіли, щоб їх підштовхнули. Він також стосується різних сховищ, що знаходяться в різних станах, і припущення, що інші працюють над ними одночасно. Порядок, який ви натискаєте та витягуєте з набору сховищ, впливає на стан різних сховищ, і вам доведеться зробити кілька пропусків, щоб усі вони справді були синхронізовані. Ось чому немає "тягнути / натиснути всіх". Тоді виникають конфлікти ...;)
Джефф Ферланд

3

Для оновлення віддалених пристроїв (тобто pullвипадку) все стало простіше.

Заява Лінуса

На жаль, немає навіть жодного способу підробити це псевдонімом git.

у посиланні, вказаному в списку розсилки Git у відповіді elliottcable, більше не відповідає дійсності.

git fetchвивчив --allпараметр десь у минулому, що дозволяє за один раз отримати всі віддалені.

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


3

Я хотів попрацювати у VSO / TFS, після чого відкрито натисніть на GitHub, коли буде готовий. Початкова репо створена в приватному VSO. Коли прийшов час додати до GitHub, я зробив:

git remote add mygithubrepo https://github.com/jhealy/kinect2.git
git push -f mygithubrepo master

Працював як чемпіон ...

Для перевірки стану безпеки видайте "git remote -v", щоб перелічити сховища, пов'язані з проектом.

C:\dev\kinect\vso-repo-k2work\FaceNSkinWPF>git remote -v
githubrepo      https://github.com/jhealy/kinect2.git (fetch)
githubrepo      https://github.com/jhealy/kinect2.git (push)
origin  https://devfish.visualstudio.com/DefaultCollection/_git/Kinect2Work (fetch)
origin  https://devfish.visualstudio.com/DefaultCollection/_git/Kinect2Work (push)

Простий спосіб, працював для мене ... Сподіваюся, це комусь допомагає.


4
Бігати git push -fбез причини, наприклад, невдачі git pushабо точному знанню того, що хтось робить, є поганою ідеєю, яка може бути шкідливою. Це також не відповідає на питання, але як додати другий пульт.
Карл Ріхтер

2

додайте псевдонім у глобальний gitconfig (/home/user/.gitconfig) з командою нижче.

git config --global alias.pushall '!f(){ for var in $(git remote show); do echo "pushing to $var"; git push $var; done; }; f'

Після введення коду, ми кажемо

git push

натиснути на початкове значення за замовчуванням. Після вище псевдоніма, ми можемо сказати

git pushall

і код буде оновлюватися на всі віддалені файли, включаючи віддалений вихідний код.


1

Додавання allпульта дистанційного керування стає трохи стомлювальним, оскільки вам доведеться налаштувати на кожній машині, яку ви використовуєте.

Крім того, надані псевдонімиbash і всі git псевдоніми передбачають, що ви будете натискати на всі віддалені . (Приклад: У мене є вилка sshag. , Що я підтримую на GitHub і GitLab у мене вище віддаленого додало, але у мене немає дозволу , щоб підштовхнути до нього.)

Ось git псевдонім, який підштовхується до віддалених файлів із URL-адресою push, яка включає @.

psall    = "!f() { \
    for R in $(git remote -v | awk '/@.*push/ { print $1 }'); do \
    git push $R $1; \
    done \
    }; f"

-3

Додавання нового пульта

git remote add upstream https://github.com/example-org/example-repo.git

git remote -vv

Отримати форму з декількох місць

git fetch --all

Натисніть на місця

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