Git pull после принудительного обновления - PullRequest
269 голосов
/ 22 марта 2012

Я просто раздавил некоторые коммиты с помощью git rebase и выполнил git push --force (что, я знаю, зло).

Теперь другие разработчики программного обеспечения имеют другую историю, и когда они делают git pullГит слит.Есть ли способ исправить это, кроме выполнения rm my-repo; git clone git@example.org:my-repo.git?

Мне нужно что-то вроде противоположности git push --force, но git pull --force не дал ожидаемых результатов.

Ответы [ 2 ]

430 голосов
/ 22 марта 2012

Для получения новых коммитов

git fetch

Сброс

Вы можете сбросить коммит для локальной ветки, используя git reset.

Чтобы изменить коммит локальной ветки:

git reset origin/master --hard

Будьте осторожны, как сказано в документации:

Сбрасывает индекс и рабочее дерево. Любые изменения отслеживаемых файлов в рабочем дереве, начиная с , отбрасываются.

Если вы хотите сохранить какие-либо изменения, внесенные локально - вместо этого выполните --soft сброс. Который обновит историю коммитов для ветки, но не изменит какие-либо файлы в рабочем каталоге (и вы сможете потом их зафиксировать).

Rebase

Вы можете воспроизвести свои локальные коммиты поверх любого другого коммита / ветки, используя git rebase:

git rebase -i origin/master

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

Если удаленные вами коммиты (с git push -f) уже были внесены в локальную историю, они будут перечислены как коммиты, которые будут применены повторно - их нужно будет удалить как часть перебазирования или они просто повторно включается в историю для ветви - и снова появляется в удаленной истории при следующем нажатии.

Используйте справку git command --help для получения более подробной информации и примеров по любой из вышеперечисленных (или других) команд.

15 голосов
/ 29 августа 2013

Это не исправит ветки, в которых уже есть код, который вам не нужен (см. Ниже, как это сделать), но если они вытянули какую-то ветку и теперь хотят, чтобы она была чистой (а не впереди "origin / some-branch), то вы просто:

git checkout some-branch   # where some-branch can be replaced by any other branch
git branch base-branch -D  # where base-branch is the one with the squashed commits
git checkout -b base-branch origin/base-branch  # recreating branch with correct commits

Примечание. Вы можете объединить их, поставив && между ними

Примечание 2: Флориан упомянул об этом в комментарии, но кто читает комментарии при поиске ответов?

Примечание 3: Если у вас есть зараженные ветви, вы можете создавать новые на основе новой "тупой ветви" и просто выполнять коммиты cherry-pick.

Ex:

git checkout feature-old  # some branch with the extra commits
git log                   # gives commits (write down the id of the ones you want)
git checkout base-branch  # after you have already cleaned your local copy of it as above
git checkout -b feature-new # make a new branch for your feature
git cherry-pick asdfasd   # where asdfasd is one of the commit ids you want
# repeat previous step for each commit id
git branch feature-old -D # delete the old branch

Теперь новая функция - это ваша ветка без дополнительных (возможно, плохих) коммитов!

...