Как "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), но без изменения рабочего каталога на более раннюю версию во время процесса.


@phi: Я не думаю, что это сработает, потому что я в деле newbranchи нечего прятать!
Malvineous

Я бы клонировал в новый каталог, объединял newbranch в master, объединял master обратно в newbranch, а затем git pull оттуда, где вы находитесь. Мастер и новая ветвь будут одинаковыми.
aet

@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

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


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ветку без переключения на него до тех пор , после того, как он был обновлен.


11
Это не делает того, что вы спросили, как это сделать.
jthill

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

1
Это абсолютно тот ответ, который я искал здесь :)
Sophistifunk

1
Не то, что хотел OP, но, честно говоря, мне помогло.
Марсель Бро

1
@anoniim, а не то, что хотел ОП? Вы имеете в виду OP, который только что ответил на этот вопрос?
smac89

12

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

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

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


Я понимаю ограничения использования 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 будут объединены с вашим мастером.
  • Если есть конфликты слияния, вам сначала нужно их решить.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.