Насколько я понимаю, кто-то выдвинул коммиты на master
в вашем центральном хранилище (origin
), которые вам там не нужны, и вы хотите (а) исправить это в своем локальном хранилище, а затем (б) протолкнуть фиксированные ветви обратно в центральное хранилище. ответ adymitruk рассказывает, как принудительно протолкнуть основную ветвь - часть (b), но также стоит немного рассказать о (a).Последнее и самое неловкое соображение: (c): как другие люди, использующие репозиторий, будут иметь дело с переписанной веткой master
.
Во-первых, я думаю, стоит подумать, будет ли это нормальнопросто отменить коммиты, которые не должны быть на мастере.Эта опция будет меньше всего мешать другим людям, которые уже вышли из master
, и даст вам меньше работы, чтобы объяснить людям, как поступить с результатом - часть (с).Однако, если вы решили, что в ветке master
не должно быть этих коммитов, за которыми следуют возвраты, выполните следующие шаги:
(a) Локальное исправление мастера
Этот бит довольно прост.Как обычно с git, убедитесь, что статус git чистый.Затем:
# Make sure you're on master:
git checkout master
# Create a branch at this point for the commits that your co-worker should
# have put on a topic branch:
git branch ill-advised-experiment
# Reset your master branch to the last good commit:
git reset --hard <SHA1-OF-LAST-GOOD-COMMIT>
(b) Нажатие на пересмотренную ветвь мастера и темы
Ваш мастер теперь не содержит полной истории, которая есть в мастере источника, поэтому вам нужно «принудительно нажать»:
git push -f origin master
... но вы, конечно, можете нажать на новую ветку темы как обычно:
git push origin ill-advised-experiment
(c) Сообщать другим людям, что они должны делать
Риск после того, как вы принудительно нажали переписанную ветку master
, состоит в том, что кто-то уже сделал git pull
или git pull --rebase
, поэтому у него есть случайные коммиты в их основной ветке.Если этот человек затем нажимает master
на origin
, плохие коммиты вернутся в ветку master
, и вы вернетесь к исходной точке.Итак, предположим, что у самого раннего плохого коммита есть имя объекта (SHA1sum) f414f3l
, вы можете попросить людей проверить:
git branch -a --contains f414f3l
Если они получат ошибку, значит, этот коммит не находится в их хранилище по адресувсе, и все в порядке.
Если они видят, что only origin/master
ветвь удаленного отслеживания содержит этот коммит, опять же, все просто - им нужно просто запустить git fetch origin
для обновленияих ветвь удаленного отслеживания.
Однако, если оба master
и origin/master
содержат этот коммит, пользователь должен быть немного более осторожным.Во-первых, пользователь должен спрятать или зафиксировать всю свою работу, чтобы убедиться, что git status
чист.Тогда я бы предложил следующее:
# Leave a branch pointing to your old master, just to make it easy to find
# commits from there:
git checkout master
git branch old-master
# Now update all the remote-tracking branches from origin (you should see
# a "forced update" message for master):
git fetch origin
# Now reset the master branch to the right remote version:
git reset --hard origin/master
Теперь, если у этого пользователя было только несколько неустановленных и незафиксированных изменений, он может затем просто git stash apply
и продолжить.
Если они 'Я только что сделал один или два новых коммита, вероятно, проще всего найти имена объектов этих коммитов из git log old-master
и сделать git cherry-pick <SHA1sum-OF-MY-COMMIT>
для каждого.Затем они могут продолжать в обычном режиме.
Наконец, если они выполнили много коммитов, вероятно, проще всего использовать интерактивную перебазировку для применения этих коммитов к новому мастеру и пропуска плохих коммитов.Это будет включать:
# To be extra cautious, create a new branch based on "old-master" for
# rebasing and switch to that:
git checkout -b old-master-for-rebasing old-master
# Start an interactive rebase:
git rebase -i master
# At this stage, delete every line that refers to a bad commit or anything
# that shouldn't be in master now. Leave everything else in the file, as
# a line beginning with "pick".
# If all went well, this branch can now be merged into master, which should
# be a fast-forward merge:
git checkout master
git merge old-master-for-rebasing
Я надеюсь, что это будет полезно.