Git вытащить после принудительного обновления

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

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

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

Ответ 1

Чтобы получить новые коммиты

git fetch

Reset

Вы можете reset совершить фиксацию для локальной ветки с помощью git reset.

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

git reset origin/master --hard

Будьте осторожны, поскольку, как полагают документы,

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

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

Rebase

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

git rebase -i origin/master

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

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

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

Ответ 2

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

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: Если у вас есть зараженные ветки, вы можете создавать новые, основанные на новой "немой ветке", и только зацикливание вишни.

Пример:

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

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