Git Rebase -> Почему при вытягивании происходит слияние? - PullRequest
1 голос
/ 24 октября 2019

Я создал ветку для разработки новой функции. Поскольку эта новая функция была разработана полностью как новый проект, единственным возможным источником конфликта может быть файл решения.

По мере разработки этой функции ветка master несколько раз обновлялась. Когда я закончил свою разработку и тестирование, я сделал:

git checkout master
git fetch
git pull
git checkout myFeature
git rebase master

Перебазирование (и все другие команды) прошло нормально, и о конфликтах / ошибках / проблемах не сообщалось. Мой следующий шаг был к git status, и результат был:

На ветке myFeature
Ваша ветка и 'origin / myFeature' разошлись, и у каждого по 7 и 5 разных коммитов соответственно. (используйте «git pull», чтобы объединить удаленную ветку с вашей)

Когда я git pull открыл слияние и посмотрел историю, мои коммиты были продублированы. Это дублирование, на мой взгляд, не должно было произойти. Я ожидал, что мои коммиты должны были быть повторно применены ПОСЛЕ последнего (в настоящее время) коммита на мастере.

Я делаю что-то не так или мои ожидания неверны?

Ответы [ 3 ]

4 голосов
/ 24 октября 2019

Почему существует коммит слияния

Когда вы делаете ребаз, вы меняете историю Git. Когда вы снова делаете тягу, Git пытается снова объединить обе истории. Поскольку по умолчанию git pull - это git fetch + git merge, это приведет к фиксации слияния.

Это не то, что вам нужно после изменения истории, поскольку она (частично) отменит ваши изменения истории,К сожалению, намек на git status немного вводит в заблуждение ...

Что вы должны делать после перебазирования / изменения истории

После изменения истории (например, перебазировки) вам нужно принудительное нажатие, чтобыВы также получите эту историю на пульте. Тогда вы говорите git: «История другая, но, поверьте мне, она предназначена».

Рекомендуется использовать «принудительный пуш с арендой»: git push --force-with-lease - см. git push -сила-с-аренды против --force .

Шаги, чтобы исправить текущее состояние

К счастью, вы можете вернуться до git pull, используя рефлог Git!

Это исправит неправильную тягу, и не будет никаких конфликтов, которые нужно решить:)

Итак, что нужно сделать:

  1. Найти правильный коммит в reflog git reflog, поэтому перед git pull (примечание: вы можете выйти из журнала, набрав q )
  2. Git сбросить до этого коммита, например git reset 327fb961e --hard
  3. Двойная проверкаи сделайте git push --force-with-lease.

Примечание: если вы допустили ошибку с git reset, вы можете снова использовать git reflog:)

Примечание 2: reflog только на вашем локальном компьютере

1 голос
/ 24 октября 2019

Предыдущий ответ выглядит великолепно. Просто пытаюсь наглядно проиллюстрировать, что происходит, в случае, если это полезно:

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

origin/ master :

A -> B -> C -> D -> E

yourbranch, origin / yourbranch:

A -> B -> F -> G -> H

После перебазировки yourbranch будет выглядеть следующим образом:

A -> B -> C -> D -> E -> F -> G -> H

Тогда, когда вы потянете origin / yourbranch , вы получите:

A -> B -> C -> D -> E -> F -> G -> H - I (merge commit)
      \                              /
        -> F -> G -> H -------------

Поскольку истории разные, они становятся нормальными, неускоренное слияние. По сути, ваши удаленные и локальные филиалы стали различными филиалами.

1 голос
/ 24 октября 2019

Этой части было достаточно для перебазирования с master ответвлением.

git checkout master
git fetch
git pull
git checkout myFeature
git rebase master

Однако вы можете просто использовать следующую команду вместо всех вышеперечисленных команд, чтобы сделать то же самое.

$ git pull origin master --rebase

После этого весь хэш коммита будет перезаписан, поэтому git status показал, что ваша ветвь разошлась.

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

$ git push origin HEAD -f

Во время перебазирования, если вы сталкиваетесь с конфликтами и не хотите продолжать перебазирование, вы можете просто запустить git rebase --abort, чтобы прервать перебазирование.

Вв любом случае, если вы оказались в середине какой-либо опасности, связанной с нежелательным коммитом, вы можете выполнить следующие шаги:

  • git reflog - найти последний совершенный коммит и отметить его хэш коммита
  • git reset --hard <commit-hash> - предоставить хэш последнего совершенного коммита

Он приведет вас к последнему идеальному коду репо.

...