Как "git pull" перейти в ветку, которая не является текущей?

126

При запуске git pullна masterветке, он обычно тянет с origin/master. Я нахожусь в другой ветке с именем newbranch, но мне нужно запустить команду, которая выполняет операцию git pullfrom 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), но без изменения рабочего каталога на более раннюю версию во время процесса.

Malvineous
источник
@phi: Я не думаю, что это сработает, потому что я в деле newbranchи нечего прятать!
Malvineous
Я бы клонировал в новый каталог, объединял newbranch в master, объединял master обратно в newbranch, а затем git pull оттуда, где вы находитесь. Мастер и новая ветвь будут одинаковыми.
aet
@aet Он мог бы просто сделать это сейчас в своем текущем каталоге, сделав это git fetch; git merge origin/masterизнутри newbranch. Клонирование всей второй копии репозитория не дает никаких преимуществ.
meagar
3
тесно связаны: stackoverflow.com/questions/3216360/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Ответы:

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

Проблема со всеми остальными ответами здесь в том, что они на самом деле не работают. Если вам нужно слияние или перебазирование, для которого вы настроили pull, вам понадобится другое рабочее дерево и описанная выше процедура. В противном случае просто git fetch; git checkout -B master origin/masterподойдет.

jthill
источник
2
Когда вы запустите, git checkout masterвы проверите старую masterветку, потому что вы не сделали git pullв mainпапке, чтобы синхронизировать ее с origin / master. Это то, чего я пытаюсь избежать.
Malvineous
Проверка, выполненная клоном, относится к старому мастеру, но эта проверка находится в каталоге, на который веб-сервер не смотрит. Основная проверка в конце - это полностью объединенный мастер, который был оттеснен из очистки.
jthill
В строке 6 вы отправляете объединенный (обновленный) masterобратно origin, но я не верю, что ваша окончательная проверка обновлена master. Нет git pullнеобходимости обновлять masterветку в mainкаталоге, поэтому, если я что-то не упускаю, ваши команды ничем не отличаются от простого запуска git checkout masterи получения старого masterдерева. Если вы присмотритесь, вы не выполняете никаких команд в mainкаталоге, которые обмениваются данными с восходящим
потоком
ну, вы можете попробовать это на тестовом репо или проверить push-документы.
jth
1
@jwg по сравнению с чем, пожалуйста? Обязательно учитывайте все заявленные потребности OP.
jthill
163

Прямолинейно: обновление из удаленной ветки в еще не извлеченную мастер -ветку :

git fetch origin master:master

где происхождение - ваш пульт, и вы в настоящее время выписаны из какой-то ветки, например dev .

Если вы хотите обновить текущую ветку в дополнение к указанной ветке за один раз:

git pull origin master:master
Мартин Питер
источник
4
Хм, похоже, это не всегда работает; Мне только что было предложено объединиться с моей веткой WIP.
underscore_d
@underscore_d мне тоже.
Грег
1
Сработало для меня ... если он предлагает объединить, то я предполагаю, что в вашей ветке, которую вы обновляете, есть изменения, которые не
бегло
2
Как это должно работать? У меня это не работает, он просто пытается объединить origin / master в мою текущую проверенную ветку.
mhogerheijde
3
Это втягивает мастер в текущую ветку. Это определенно НЕ то, о чем просят. Если вы измените pull на fetch, то это будет именно то, о чем вас просят.
Джефф Вольски
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
Это лучший вариант, так как он работает с незафиксированными локальными изменениями.
Tomasz Gandor
2
Если вы просто хотите быть в курсе последних изменений, вы бы это сделали git fetch origin master:master. git fetchсам по себе предполагает, что вы хотите обновить текущую ветку, а не какую-то другую.
Джон Лейдегрен
2
Это самый простой и прямой ответ. Это должен быть принятый ответ ИМО.
Keego
@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ветку без переключения на него до тех пор , после того, как он был обновлен.

Malvineous
источник
11
Это не делает того, что вы спросили, как это сделать.
jthill
Как говорится в комментарии выше, вопрос, который вы задали, на самом деле не тот вопрос, на который вы ответили. Вам следует обновить свой вопрос так, чтобы он менее конкретно касался слияния с веткой без проверки, а больше о переходе непосредственно к новейшей версии ветки, доступной на удаленном компьютере, без предварительной проверки старой версии.
meagar
1
Это абсолютно тот ответ, который я искал здесь :)
Sophistifunk
1
Не то, что хотел OP, но, честно говоря, мне помогло.
Марсель Бро
1
@anoniim, а не то, что хотел ОП? Вы имеете в виду OP, который только что ответил на этот вопрос?
smac89
12

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

Поскольку вы на самом деле не фиксируете код в своей производственной среде (я надеюсь), вам не нужно проверять ветку. Вы можете просто выполнить a, git fetchчтобы обновить свои удаленные ссылки, а затем git checkout origin/masterпереместить рабочий каталог непосредственно в коммит, на который в данный момент указывает origin/master. Это переведет вас в состояние отдельной головы, но, опять же, поскольку вы не фиксируете код, это не имеет значения.

Это самая маленькая дыра, которую вы собираетесь получить, но, как я уже сказал, дыра все еще существует; checkoutне атомарен.

Meagar
источник
Я понимаю ограничения использования git для развертывания, проблема в том, что дыра в этом случае будет длиться несколько минут, а не менее одной секунды. Хорошая идея о выезде origin/master, это может просто помочь.
Malvineous
Что делает дырку "минутной" длинной? Передача данных по сети? Просто сделайте следующее, git fetchпрежде чем делать что-либо еще, и избавьтесь от фактической передачи данных.
meagar
Это занимает несколько минут, потому что (сейчас) неотслеживаемый файл будет перезаписан более ранней фиксацией. Так что мне нужно скопировать файл, сделать что-то вроде git, а затем вернуть его. «Минуты» - это результат моей скорости набора текста. (Да, я мог бы
написать
3

Для этого вы можете использовать update-ref:

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

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

Филип Бебер
источник
Будет ли это эквивалентно git branch --force master origin/master? Это заставляет местную голову masterуказывать на голову originsmaster
Киго
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 будут объединены с вашим мастером.
  • Если есть конфликты слияния, вам сначала нужно их решить.
Luzian
источник