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
очень полезно
Просто откиньте его и больше не смотрите на него.