Как заменить локальную ветку на удаленную в Git?

779

У меня есть две ветви:

  1. местный филиал (тот, с которым я работаю)
  2. удаленная ветка (общедоступная, туда идут только проверенные коммиты)

Недавно я серьезно испортил свой местный филиал.

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

Я уже искал SO, и проверка на удаленную ветку локально не имеет никакого эффекта.

YemSalat
источник
1
Я знаю, что за принятый ответ набрано 1280 голосов, но вам стоит подумать об изменении принятого ответа на @TTT.
Джейми

Ответы:

1289
  1. Убедитесь, что вы проверили заменяемую ветку (из комментария Золтана ).
  2. Предполагая, что master - это локальная ветвь, которую вы заменяете, и что origin / master - это удаленная ветвь, в которую вы хотите сбросить:

    git reset --hard origin/master
    

Это обновит вашу локальную ветку HEAD так, чтобы она была той же ревизией, что и origin / master, и --hardсинхронизирует это изменение с индексом и рабочей областью.

araqnid
источник
4
Спасибо за ваше предложение, я просто так «напуган» использованием --hard и --force, поэтому я просто выбрал решение, которое не использует их.
YemSalat
13
@KonstantinLevin: ах, да, названия этих опций довольно раздражающие. git resetпо умолчанию переписывает вашу текущую ветку и синхронизирует индекс. --softпропустит обновление индекса, --hardтакже синхронизирует рабочее пространство. Мой собственный опыт использует --hardбольшую часть времени, за исключением случаев, когда я хочу отменить последний коммит (который просто git reset HEAD^)
araqnid
9
Имея больше опыта работы с git, я уверен, что это лучшее решение, спасибо.
YemSalat
24
вероятно, вам нужно будет сначала получить:git fetch origin remote_branch
b1r3k
53
Вы должны заметить, что это заменит ту ветку, на которой вы сейчас находитесь, содержимым мастера . Так, если вы, например, находитесь в ветке feature, она заменит все свои коммиты master, поэтому убедитесь, что вы проверили ветку, которую заменяете в первую очередь.
Золтан
218

Это так просто, как три шага:

  1. Удалить ваше местное отделение: git branch -d local_branch
  2. Получить последнюю удаленную ветку: git fetch origin remote_branch
  3. Перестройте локальную ветку на основе удаленной: git checkout -b local_branch origin/remote_branch
Адам Смит
источник
7
На самом деле то, что сказал @araqnid, является правильным и более кратким. Я проверил это, и вы можете попробовать это тоже.
Адамсмит
Ух ты, git checkout -b local_branch origin / remote_branch великолепен! Я всегда делал это двумя отдельными командами. Спасибо!
кендепельчин
11
Возможно, вам придется сделать git branch -D local_branchна первом шаге, если ваша ветвь не объединена.
Сзериф
спасибо, у меня были трудные времена при использовании gitflow, после публикации ветки и ее завершения, я хотел перейти в удаленную ветку, и ваше решение было единственным, которое работало, pull не работает .. или я не справился не использовать это хорошо -
Decebal
2
мы должны убедиться, что текущая ветвь не та, которую нужно удалить.
a_secenthusiast
43
git branch -D <branch-name>
git fetch <remote> <branch-name>
git checkout -b <branch-name> --track <remote>/<branch-name>
Sailesh
источник
Что делает часть --track?
эонист
3
@ GitSync, это то, что git help branchговорит о --track. When creating a new branch, set up branch.<name>.remote and branch.<name>.merge configuration entries to mark the start-point branch as "upstream" from the new branch. This configuration will tell git to show the relationship between the two branches in git status and git branch -v. Furthermore, it directs git pull without arguments to pull from the upstream when the new branch is checked out. Я исправил эту команду в ответе. Спасибо, что подняли вопрос.
Sailesh
Итак, с точки зрения непрофессионала: он добавляет удаленный URL в новую ветку. Таким образом, они синхронизированы навсегда. Так сказать.
эонист
2
Вы можете сказать, что это просто для удобства. Если вы это сделаете git status, он сообщит, находится ли ваша локальная ветвь впереди или позади удаленной, если они у вас есть. Кроме того, вы можете сделать git pull(или push) вместо полной, git pull <remote> <branch>если вы уже настроили свою ветку для отслеживания <remote/branch>.
Sailesh
22

Заменить все на удаленную ветку; но только из того же коммита ваша локальная ветка включена:

git reset --hard origin/some-branch

ИЛИ , получите последнюю версию из удаленной ветки и замените все:

git fetch origin some-branch
git reset --hard FETCH_HEAD

Кроме того, если необходимо, вы можете удалить неотслеживаемые файлы и каталоги, которые вы еще не добавили:

git clean -fd
немного меньше
источник
Команда git cleanсделала это для меня. git reset hard origin/masterне уничтожайте неотслеживаемые файлы. Спасибо!
Морнор
9

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

git stash
git merge --abort
git rebase --abort
git branch -M yourBranch replaced_yourBranch
git fetch origin yourBranch:yourBranch
git checkout yourBranch

stashЛиния сохраняет изменения , которые вы не совершали. branchЛиния движется вашу ветку с другим именем, освобождая оригинальное название. fetchСтрока извлекает последнюю копию пульта дистанционного управления. checkoutЛиния воссоздает исходную ветвь в качестве отслеживания отрасли.

Или как функция bash:

replaceWithRemote() {
    yourBranch=${1:-`git rev-parse --abbrev-ref HEAD`}
    git stash
    git merge --abort
    git rebase --abort
    git branch -M ${yourBranch} replaced_${yourBranch}_`git rev-parse --short HEAD`
    git fetch origin ${yourBranch}:${yourBranch}
    git checkout ${yourBranch}
}

который переименовывает текущую ветку во что-то вроде replace_master_98d258f.

Джошуа С
источник
Возможно, захотите включить git stash popв этот рабочий процесс. Если вы хотите повторно применить ваши спрятанные файлы.
эонист
Что вы делаете с припрятанной веткой? Боюсь, что это снова появится где-то в будущем, после того, как я забуду, для чего это было.
Скотт Биггс
1
@ScottBiggs Если вы хотите удалить спрятанную ветку, используйте «git stash clear».
Марк А. Дарем
5

Я немного удивлен, что никто еще не упомянул об этом; Я использую это почти каждый день

git reset --hard @{u}

По сути, @{u}это просто сокращение для ветки upstream, которую отслеживает ваша текущая ветка. Например, это обычно приравнивается к origin/[my-current-branch-name]. Это приятно, потому что это отраслевой агностик.

Обязательно git fetchсначала получите самую последнюю копию удаленной ветки.

ТТТ
источник
1
это выглядит действительно хорошо, я устал от копирования и вставки названия ветви для сброса!
pedroct92
1
У меня было несколько случаев, когда я добавлял ответы на старые вопросы, и мои ответы продвигались вверх по списку лидеров. Я надеюсь, что это делает.
Джейми
3

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

1) Сбросить сильно

Если вы работаете из удаленной ветки разработки, вы можете сбросить HEAD до последнего коммита в удаленной ветке, как показано ниже:

git reset --hard origin/develop

2) Удалить текущую ветку и снова оформить заказ из удаленного хранилища.

Учитывая, что вы работаете над веткой разработки в локальном репо, которая синхронизируется с удаленной веткой / веткой разработки, вы можете сделать следующее:

git branch -D develop
git checkout -b develop origin/develop

3) Прервать слияние

Если вы находитесь в промежутке между неудачным слиянием (ошибочно сделанным с неправильной ветвью) и хотите избежать слияния, чтобы вернуться к последней ветке, как показано ниже:

git merge --abort

4) Отменить ребаз

Если вы находитесь между неудачной перебазировкой, вы можете прервать запрос на перебазирование, как показано ниже:

git rebase --abort
Амит Канерия
источник
2

Вы можете сделать, как сказал @Hugo из @Laurent, или вы можете использовать git rebaseдля удаления коммиты, от которых хотите избавиться, если знаете, какие. Я склонен использовать git rebase -i head~N(где N - число, позволяющее вам манипулировать последними N коммитами) для такого рода операций.

ksol
источник
На самом деле, это была команда 'git rebase', которая все испортила, затем некоторые принудительные слияния и аппаратные сбросы. В любом случае, я искал простой способ извлечь весь репо с удаленного сервера без слияния.
YemSalat
2

Выбранный ответ является абсолютно правильным , однако он не оставил меня с последней фиксацией / толчков ...

Итак, для меня:

git reset --hard dev/jobmanager-tools
git pull  ( did not work as git was not sure what branch i wanted)

Так как я знаю, что хочу временно установить свою ветвь upstream на несколько недель на определенную ветку (такую ​​же, как та, на которую я переключился / проверил ранее и сделал полный сброс)

Так ПОСЛЕ сброса

git branch --set-upstream-to=origin/dev/jobmanager-tools
git pull
git status    ( says--> on branch  dev/jobmanager-tools 
Том Стиккель
источник
1

Если вы хотите обновить ветку, которая в данный момент не извлечена, вы можете сделать:

git fetch -f origin rbranch:lbranch
kqr
источник
0

Как указано в выбранном объяснении, сброс git хорош. Но в настоящее время мы часто используем подмодули: репозитории внутри репозиториев. Например, если вы используете ZF3 и jQuery в своем проекте, вы, скорее всего, захотите, чтобы они были клонированы из своих исходных репозиториев. В таком случае сброса мерзавца недостаточно. Нам нужно обновить подмодули до той точной версии, которая определена в нашем репозитории:

git checkout master
git fetch origin master
git reset --hard origin/master
git pull

git submodule foreach git submodule update

git status

это то же самое, что вы (cd) рекурсивно попадете в рабочий каталог каждого подмодуля и запустите:

git submodule update

И это очень отличается от

git checkout master
git pull

потому что подмодули указывают не на ветвление, а на фиксацию.

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

git submodule foreach git pull
Евгений Кауров
источник
Пожалуйста, предоставьте объяснение, особенно когда отвечаете на старые вопросы. Ваш ответ не полезен как есть.
Эрик,
Принятый ответ уже предлагает git reset --hard. Это добавляет мало значения.
Флорисла
0
git reset --hard
git clean -fd

Это сработало для меня - очистка показала все файлы, которые были удалены. Если он говорит вам, что вы потеряете изменения, вам нужно спрятать.

Трэвис Хитер
источник
-6

Уродливый, но более простой способ: удалите свою локальную папку и снова клонируйте удаленный репозиторий.

Хьюго
источник
10
Или просто удалите ветку и проверьте ее снова.
Лоран
Да, я думаю, это то, что я собираюсь сделать, если я не найду, как сделать это менее «уродливо»
YemSalat
2
Гадкий иногда полезно знать. Мне бы очень хотелось, чтобы люди не отрицали вещи просто потому, что они не являются общепринятым способом: должна быть более рациональная причина для голосования ... и это должно быть дано. Git - вещь, которая достигает результатов. Это не какой-то священный текст.
Майк Грызун
3
Я не понимаю downvotes :-( Да, это некрасиво, и т.д. , но он может работать лучше в некоторых случаях ... извините @Hugo
silverdr
@Хуго, согласен. Что-то загадочное и вонючее произошло с моим локальным отделом разработки, и руководитель группы и инженерный менеджер предложили, среди более элегантных решений, просто (сжать, скопировать и сохранить мою функциональную работу, а затем) разорвать местный репо и откатываться.
AmitaiB