Як "git pull" у гілку, яка не є поточною?


126

Коли ви біжите git pullна masterгілці, вона, як правило, тягне звідти origin/master. Я перебуваю в іншій філії називається newbranch, але мені потрібно запустити команду , яка робить git pullз origin/masterв , masterале я не можу запустити git checkout, щоб змінити вибрану гілку , поки після втягування завершення. Чи є спосіб це зробити?

Щоб отримати деяку інформацію, сховище зберігає веб-сайт. Я вніс деякі зміни в newbranchі розгорнув їх, перейшовши на веб-сайт newbranch. Тепер ці зміни були об'єднані вище за течією у masterвідділенні, я намагаюся переключити веб-сайт назад до masterгілки. На даний момент, newbranchі origin/masterідентичні, але masterвідстає origin/masterі потребує оновлення. Проблема полягає в тому, якщо я це роблю традиційним способом:

$ git checkout master
   # Uh oh, production website has now reverted back to old version in master
$ git pull
   # Website is now up to date again

Мені потрібно домогтися того ж, що вище ( git checkout master && git pull), але не змінюючи робочий каталог на попередню версію під час процесу.


@phi: Я не думаю, що це спрацює, тому що я newbranchтам, і немає чого заховати!
Malvineous

Я б клонував у новий каталог, з’єднав нову галузь у головну, з’єднав би магістра назад у нову галузь, а потім git тягнуть туди, де ти є. Майстер і нова галузь будуть однаковими.
ает

@aet Він міг просто зробити це зараз у своєму поточному каталозі, роблячи git fetch; git merge origin/masterзсередини newbranch. Немає користі від клонування всієї другої копії сховища.
meagar


Відповіді:


5

У вас є робоче дерево, яке не хочеться чіпати, тому використовуйте інше. Клон дешевий, він побудований для цього.

git fetch origin master       # nice linear tree
git clone . ../wip -b master  # wip's `origin/master` is my `master`
cd ../wip                     # .
git pull origin origin/master # merge origin's origin/master
git push origin master        # job's done, turn it in.
cd ../main
rm -rf ../wip                 # wip was pushed here, wip's done

git checkout master           # payload

Проблема з усіма іншими відповідями тут полягає в тому, що вони насправді не спрацьовують. Якщо вам потрібне злиття або відновлення, для якого вам встановлено тягнення, вам потрібна ще одна робоча ялинка та вищезазначена процедура. Інакше просто git fetch; git checkout -B master origin/masterзроблять.


2
Під час запуску git checkout masterви перевірите стару masterгілку, оскільки ви не зробили git pullв mainпапці, щоб синхронізувати її з початком / master. Це я намагаюся уникати.
Malvineous

Замовлення, зроблене клоном, є старим майстром, але цей замовлення знаходиться в каталозі, на який веб-сервер не дивиться. Головний замовлення в кінці є повністю об'єднаним майстром, який був відтіснений назад від wip.
jthill

У рядку 6 ви masterповертаєте об'єднаний (оновлений) назад origin, але я не вірю, що ваш остаточний замовлення є оновленим master. Немає git pullоновлення masterгілки в mainкаталозі, тому, якщо я не пропускаю чогось, ваші команди нічим не відрізняються від простого запуску git checkout masterсамостійно та отримання старого masterдерева. Якщо ви придивитесь уважніше, ви не виконуєте жодних команд у mainкаталозі, які повідомляють вище (за винятком рядка 1, який запускається до того, як ви внесли будь-які зміни у
репортаж

добре, ви можете спробувати це на тестовому репо або переглянути push-документи.
1313

1
@jwg порівняно з чим, будь ласка? Не забудьте задовольнити всі заявлені потреби ОП.
jthill

163

Відразу: оновлення від віддаленої гілки до поточно не перевіреного головного відділення :

git fetch origin master:master

де походження ваш пульт , і ви в даний час перевіряється в якій - то галузі , наприклад , Dev .

Якщо ви хочете оновити свою поточну гілку на додаток до вказаної гілки за один раз:

git pull origin master:master

4
Гм, здається, це не завжди працює; Мене щойно запропонували об'єднатись із моєю гілкою WIP.
підкреслюйте_d

@underscore_d те саме для мене.
Грег

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

2
Як це має працювати? Це не працює для мене, він просто намагається об'єднати походження / master у мою філію, яка наразі перевіряється.
mhogerheijde

3
Це втягує майстра в поточну гілку. Це, безумовно, НЕ, про що просять. Якщо ви зміните потяг на прийом, то це саме те, що просять.
Джефф Вольський

90

На це відповідає тут: Об’єднайте, оновіть та потягніть гілки Git без використання кас

# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master

# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo

2
Це найкраще, оскільки це працює з непоміченими локальними змінами.
Томаш Гандор

2
Якщо ви просто хочете наздогнати останні зміни, які ви зробили б git fetch origin master:master. git fetchсам по собі припустив би, що ви мали намір оновити поточну гілку, а не якусь іншу гілку.
Джон Лейдегрен

2
Це найпростіша і найпряміша відповідь. Це має бути прийнятою відповіддю ІМО.
Кіего

@JohnLeidegren - за винятком того, що він не завжди працює за призначенням. Дивіться коментарі до відповіді stackoverflow.com/a/42902058/274579 .
ysap

22

Як виявляється, відповідь оманливо проста:

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Це дозволяє оновлювати masterгілку, не перемикаючись на неї до моменту її оновлення.


11
Це не робить те, що ви запитали, як це зробити.
jthill

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

1
Це абсолютно відповідь, яку я прийшов сюди шукати :)
Sophistifunk

1
Не те, що хотіла ОП, але допомогло мені, чесно кажучи.
Marcel Bro

1
@anoniim, не те, чого хотів ОП? Ви маєте на увазі ОП, яка щойно відповіла на це питання?
smac89

12

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

Оскільки ви фактично не вводите код у виробничому середовищі (сподіваюся), вам насправді не потрібно перевіряти відділення. Ви можете просто виконати git fetchоновлення віддалених записів, а потім git checkout origin/masterперенести робочий каталог безпосередньо на комісію, на яку вказує даний момент origin/master. Це переведе вас у відокремлений головний стан, але знову ж таки, оскільки ви не здійснюєте код, це не має значення.

Це найменша діра, яку ви збираєтеся отримати, але, як я вже сказав, дірка все ще існує; checkoutне є атомним.


Я розумію обмеження використання git для розгортання. Проблема полягає в тому, що отвір у цьому випадку буде тривати хвилин замість менше однієї секунди. Хороша ідея про перевірку, origin/masterхоча це може просто зробити трюк.
Malvineous

Що робить отвір "хвилин" довгим? Перетягування даних через мережу? Просто зробіть git fetchперед тим, як зробити що-небудь інше, і перешкодите фактичній передачі даних.
meagar

Минуло кілька хвилин, тому що (зараз) файл, що не відслідковується, буде перезаписаний попереднім фіксацією. Тому я повинен скопіювати файл, зробити git речі, а потім повернути його назад. "Хвилина" походить від моєї швидкості набору тексту. (Так, я міг би це сценарій, але це було просто для того, щоб сказати, що мати git робити все самому швидше.)
Malvineous

3

Для цього можна скористатися оновленням ref:

git fetch
git update-ref refs/heads/master origin/master
git checkout master

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


Це було б рівнозначно git branch --force master origin/master? Це змушує місцевого голови masterвказати на голову originsmaster
Keego

2

Рішення Malvineous працює для мене

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Просто в помилці


warning: not deleting branch 'master' that is not yet merged to
         'refs/remotes/origin/master', even though it is merged to HEAD.
error: The branch 'master' is not fully merged.
If you are sure you want to delete it, run 'git branch -D master'.

Тому я запускаю з опцією -D

Дякую


0

git fetch origin master:master

  • "Тягне" (насправді забирає) master.
  • Якщо у вас є зміни, masterякі ще не натиснуті, origin/masterоб'єднується з вашим господарем.
  • Якщо виникають конфлікти злиття, вам доведеться їх вирішити спочатку.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.