Git: лучший способ для git вернуться без дополнительного исправления

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

В принципе, прямо сейчас у меня есть:

           D---E---F---G master

И я хочу:

             E---G topic
            /
           D master

Это должно быть как в моем локальном, так и в удаленном репозитории (есть только один, называемый источником).

Какой самый чистый способ получить это?

Кроме того, есть и другие люди, которые клонировали это репо и проверили мастер-ветку. Если бы я сделал такое изменение в удаленном репо, будет ли "git pull" работать для них, чтобы получить также одно и то же состояние?

Ответ 1

Если вы опубликовали то, вы правы, что не хотите переписывать историю master. Вы хотите опубликовать фиксацию, чтобы вернуть ее в состояние, которое было в D, сохраняя при этом текущую историю, чтобы другие пользователи могли легко или легко скомпилировать свою работу.

Если вы планируете в какой-то момент в будущем объединить topic в master, то то, что вы, вероятно, также хотите сделать, это создать новую общую базу между master и topic, так что когда вы это сделаете впоследствии слияние topic, вы не потеряете коммиты, которые были возвращены в master. Самый простой способ сделать это - сделать "повторную" фиксацию поверх фиксации "отменить", которая сбрасывает master обратно в исходное состояние и основывает новую ветвь topic поверх этого.

# checkout master branch (currently at G)
git checkout master

# Reset the index to how we want master to look like
git reset D

# Move the branch pointer back to where it should be, leaving the index
# looking like D
git reset --soft [email protected]{1}

# Make a commit (D') for the head of the master branch
git commit -m "Temporarily revert E, F and G"

# Create the new topic branch based on master.
# We're going to make it on top of master and the 'undo'
# commit to ensure that subsequent merges of master->topic
# or topic->master don't merge in the undo.
git checkout -b topic

# Revert the undo commit, making a redo commit (G').
git revert HEAD

В качестве альтернативы вы могли бы совершить коммиты E ', F' и G ', переделывая каждую часть отдельно, но поскольку E, F и G уже находятся в вашей опубликованной истории, это, вероятно, более понятно, если вы просто ссылаетесь на фиксацию' undo 'и скажите, что эта фиксация отменяется. Во всяком случае, это git revert.

По сути, вы знаете, что это.

D -- E -- F -- G -- D'      <-- master
                     \
                      \
                        G'  <-- topic

Важно то, что вы не переписали историю, а тема основана на главном, поэтому слияния не будут случайно применять какие-либо "отменить". Теперь вы можете безопасно нажимать на master и topic на удаленный репозиторий.

Ответ 2

Вы можете переписать свою историю, если хотите, но это плохая идея, если у кого-то еще есть копии истории. В этом случае вы, вероятно, используете интерактивную rebase: git rebase -i master topic. Это даст вам список коммитов от мастера к теме, с подсказками о том, как с ними играть. Вам просто нужно удалить строку, содержащую фиксацию, которую вы хотите удалить.

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

В разделе git -rebase man есть хороший раздел, который называется "восстановление из восходящей ребазы" , обсуждая, как с этим бороться, если вы действительно решаете.

Edit:

Для простой истории, общий сценарий был бы, после форсирования немедленного нажатия на центральное репо (push -f), другие разработчики:

  • создать резервную копию своего старого мастера: git branch -m master master_old
  • получить обновления и восстановить мастер из источника: git remote update origin; git branch master origin/master
  • переадресовать все темы ветвей на новый мастер: git rebase --onto master master_old topic

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

Ответ 3

Я нахожу git stash очень полезно

Просто откиньте его и больше не смотрите на него.