Сбросить/вернуть целую ветку в состояние другой ветки?

У меня есть ветвь A и ветвь B (и некоторые другие ветки).

Предположим, что история фиксации выглядит так:

  • commit 5
  • commit 4
  • commit 3
  • ...

И история фиксации B:

  • некоторые другие фиксации
  • commit 4
  • слияние другого материала с ветки C (в ветку B)
  • commit 3
  • ...

В основном я хочу "удалить" все изменения, сделанные коммитами, некоторые другие фиксации и слияние других вещей из ветки C в ветвь B.

Я хочу, чтобы рабочее дерево ветки B было точно таким же, как ветвь. Рабочее дерево.

Как мне это достичь?

Ответ 1

Один из способов добиться этого - через git reset. Находясь на ветке B, выполните

git reset --hard A

После этого ветвь B указывает на головной коммит A. Опция --hard сбрасывает индекс и рабочее дерево, поэтому все отслеживаемые файлы сбрасываются до версии в ветки A. Старый идентификатор фиксации HEAD A хранится в .git/ORIG_HEAD, чтобы можно было отменить изменение.

В качестве альтернативы - пока вы не находитесь на ветке B - вы можете удалить ветку B и воссоздать ее следующим образом:

git branch -d B     # delete branch B
git branch B A      # re-create branch B and let it point to the commit of branch A

Кроме первого предложения, индекс и рабочее дерево останутся нетронутыми.

Ответ 2

Если вы хотите, чтобы ваша ветка B выглядела точно так же, как ветвь A. Вы можете просто сделать reset --hard

git checkout branch-B

git reset --hard branch-A

Будьте осторожны, вы потеряете фиксации в этом случае. Ваша ветка-B будет выглядеть точно так же, как ветвь-A, любые фиксации, которые были сделаны для ветки-B, которые отсутствовали в ветке-A, будут потеряны. Кроме того, если ветвь-B делится с другими людьми, ее не рекомендуется выполнять эту операцию.

В этом случае вы можете попытаться вернуть те коммиты, которые не нужны в ветке-B

git revert <sha-of-"some other commit">
git revert <sha-of-"merge of other stuff from branch C (into branch B)"> 

Вторая фиксация выглядит как фиксация слияния, поэтому вам, возможно, придется передать и родительский.

 git revert <sha-of-"merge of other stuff from branch C (into branch B)"> -m1

Ответ 3

Для завершения, давайте добавим этот очень простой способ добиться этого:

git branch -f branchB branchA

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