2013-09-25 5 views
85

Когда вы запустите git pull на ветке master, она обычно тянет от origin/master. Я нахожусь в другом ветви под названием newbranch, но мне нужно запустить команду, которая делает git pull от origin/master до master, но я не могу запустить git checkout, чтобы изменить выбранную ветвь до завершения потяжки. Есть ли способ сделать это?Как «git pull» в ветку, которая не является текущей?

Чтобы предоставить некоторый фон, хранилище хранит веб-сайт. Я внес некоторые изменения в 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), но без изменения рабочего каталога на более ранней ревизии в ходе процесса.

+1

как насчет 'stash'? – phi

+0

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

+0

Я бы клонировал в новый каталог, объединил newbranch в мастер, объединил мастера обратно в newbranch, затем git pull from where you. Мастер и новобранец будут одинаковыми. – aet

ответ

8

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

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 
+2

Когда вы запускаете 'git checkout master', вы будете проверять старую ветку' master', потому что вы еще не сделали 'git pull' в папке' main', чтобы синхронизировать его с именем origin/master. Это то, чего я пытаюсь избежать. – Malvineous

+0

Проверка, выполненная клоном, принадлежит старому хозяину, но эта проверка находится в каталоге, на котором веб-сервер не смотрит. Мастер-контроль в конце состоит из полностью объединенного мастера, который был отброшен обратно из wip. – jthill

+0

В строке 6 вы перетаскиваете объединенный (обновленный) 'master' обратно в' origin', но я не считаю, что ваша окончательная проверка этого обновленного 'master'. Не существует 'git pull', чтобы обновить ветвь' master' в каталоге 'main', поэтому, если мне не хватает чего-то, что ваши команды ничем не отличаются от просто запуска' git checkout master' самостоятельно и получения старого 'master' дерево. Если вы внимательно присмотритесь, вы не будете запускать какие-либо команды в каталоге 'main', которые свяжутся с восходящим потоком (кроме строки 1, которая запускается до внесения каких-либо изменений в восходящее репо.) – Malvineous

11

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

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

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

+0

Я понимаю ограничения использования git для развертывания, проблема в том, что отверстие в этом случае будет длиться минут, а не менее одной секунды. Хорошая идея о проверке «происхождение/мастер», хотя это может просто сделать трюк. – Malvineous

+0

Что делает отверстие «минут» длинным? Вытягивание данных по сети? Просто сделайте «git fetch», прежде чем делать что-либо еще и получить фактическую передачу данных. – meagar

+0

Это длится несколько минут, потому что (теперь) необработанный файл будет перезаписан более ранним фиксатором. Поэтому мне нужно скопировать файл, сделать git, а затем вернуть его обратно. «Длительность минут» - это скорость ввода. (Да, я мог бы написать сценарий, но просто нужно сказать, что git делает все сам по себе быстрее). – Malvineous

16

Как оказалось, ответ обманчиво прост:

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

+6

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

+0

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

+0

Мой вопрос был о том, как сделать притяжение перед кассой, что и получается. Я отредактирую вопрос для ясности, но перечитав вопрос, этот ответ делает именно то, что я просил! – Malvineous

70

Это отвечает здесь: Merge, update, and pull Git branches without using checkouts

# 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 
+1

Это лучшее, поскольку оно работает с незафиксированными локальными изменениями. –

+2

Если вы просто хотите догнать последние изменения, вы должны сделать «git fetch origin master: master». 'git fetch' сам по себе предполагал, что вы хотели обновить текущую ветку, а не какую-то другую ветку. –

+1

Это самый простой и самый прямой ответ. Это должен быть принятый ответ ИМО. – Keegomyneego

3

Вы можете использовать обновление-исх для этого:

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

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

+0

Будет ли это эквивалентно 'git branch -force master origin/master'? Это заставляет локальную голову 'master' указывать на голову' origin' 'master' – Keegomyneego

-1

Не это делать (если вы находитесь в этой ветке):

git pull origin master

Это будет тянуть последний мастер в текущую ветвь функций.

+2

Он хотел вытащить удаленный мастер в локальный мастер, который не был извлечен. –

66

Прямо вперед: вытягивать из удаленного филиала в настоящее время не извлеченного ветви мастер:

git pull origin master:master 

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

+12

Это должен быть принятый ответ, поскольку он точно соответствует тому, что задают! –

+3

Хм, похоже, он не всегда работает; Мне просто предложили объединиться с моей ветвью WIP. –

+0

@underscore_d то же самое для меня. – Greg

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

благодаря

Смежные вопросы