Короткий ответ
Вы пропустили тот факт, что вы запустили git push, получили следующую ошибку и затем продолжили работу git pull:
To git@bitbucket.org:username/test1.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to 'git@bitbucket.org:username/test1.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Несмотря на то, что Git пытается быть полезным, его совет «git pull», скорее всего, не то, что вы хотите делать .
Если ты:
- Работая над «ответвлением новой функции» или «разработчик филиалом» только , то вы можете запустить ,
git push --forceчтобы обновить пульт с вашими после перебазирования фиксаций ( в соответствии с ответом user4405677 игровых ).
- Если вы работаете в ветке с несколькими разработчиками одновременно, вам, вероятно, не следует использовать его
git rebase в первую очередь. Чтобы обновить devс изменениями из master, вы должны вместо запуска git rebase master devзапускать git merge masterво время работы dev( согласно ответу Джастина ).
Немного более длинное объяснение
Каждый хэш фиксации в Git основан на нескольких факторах, один из которых - хэш предшествующей фиксации.
Если вы измените порядок коммитов, вы измените хеши коммитов; rebase (когда он что-то делает) изменит хеши коммитов. При этом результат выполнения git rebase master dev, с которым devне синхронизирован master, создаст новые коммиты (и, следовательно, хэши) с тем же содержанием, что и те, которые включены, devно с коммитами, masterвставленными перед ними.
Вы можете попасть в такую ситуацию разными способами. Я могу думать о двух способах:
- У вас могут быть коммиты, на
masterкоторых вы хотите основывать своиdev работу
- У вас могли быть коммиты
dev, которые уже были отправлены на удаленный компьютер, которые вы затем переходите к изменению (перефразируйте сообщения коммитов, переупорядочивайте коммиты, сквош-коммиты и т.
Давайте лучше разберемся, что произошло - вот пример:
У вас есть репозиторий:
2a2e220 (HEAD, master) C5
ab1bda4 C4
3cb46a9 C3
85f59ab C2
4516164 C1
0e783a3 C0

Затем вы переходите к изменению коммитов.
git rebase --interactive HEAD~3 # Three commits before where HEAD is pointing
(Здесь вам придется поверить мне на слово: есть несколько способов изменить коммиты в Git. В этом примере я изменил время C3, но вы будете вставлять новые коммиты, изменять сообщения коммитов, переупорядочивать коммиты, объединение коммитов и т. д.)
ba7688a (HEAD, master) C5
44085d5 C4
961390d C3
85f59ab C2
4516164 C1
0e783a3 C0

Здесь важно заметить, что хеши коммитов разные. Это ожидаемое поведение, поскольку вы что-то (что-то) в них изменили. Это нормально, НО:

Попытка нажать покажет вам ошибку (и намекнет, что вам следует запустить git pull).
$ git push origin master
To git@bitbucket.org:username/test1.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@bitbucket.org:username/test1.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Если мы запустим git pull, то увидим такой лог:
7df65f2 (HEAD, master) Merge branch 'master' of bitbucket.org:username/test1
ba7688a C5
44085d5 C4
961390d C3
2a2e220 (origin/master) C5
85f59ab C2
ab1bda4 C4
4516164 C1
3cb46a9 C3
0e783a3 C0
Или, как показано по-другому:

И теперь у нас есть дублирующиеся коммиты локально. Если бы мы запустили, git pushмы бы отправили их на сервер.
Чтобы не попасть на этот этап, мы могли бежать git push --force(там, где мы бежали git pull). Это без проблем отправило бы наши коммиты с новыми хешами на сервер. Чтобы решить проблему на этом этапе, мы можем вернуться к предыдущему состоянию git pull:
Посмотрите на reflog ( git reflog) , чтобы увидеть , что совершить хэш был до того мы побежали git pull.
070e71d HEAD@{1}: pull: Merge made by the 'recursive' strategy.
ba7688a HEAD@{2}: rebase -i (finish): returning to refs/heads/master
ba7688a HEAD@{3}: rebase -i (pick): C5
44085d5 HEAD@{4}: rebase -i (pick): C4
961390d HEAD@{5}: commit (amend): C3
3cb46a9 HEAD@{6}: cherry-pick: fast-forward
85f59ab HEAD@{7}: rebase -i (start): checkout HEAD~~~
2a2e220 HEAD@{8}: rebase -i (finish): returning to refs/heads/master
2a2e220 HEAD@{9}: rebase -i (start): checkout refs/remotes/origin/master
2a2e220 HEAD@{10}: commit: C5
ab1bda4 HEAD@{11}: commit: C4
3cb46a9 HEAD@{12}: commit: C3
85f59ab HEAD@{13}: commit: C2
4516164 HEAD@{14}: commit: C1
0e783a3 HEAD@{15}: commit (initial): C0
Выше мы видим, что это ba7688aбыла фиксация, в которой мы были до запуска git pull. Имея в руках этот хеш фиксации, мы можем вернуться к этому ( git reset --hard ba7688a) и затем запустить git push --force.
И мы закончили.
Но подождите, я продолжал основывать работу на дублированных коммитах.
Если вы каким-то образом не заметили, что коммиты были дублированы, и продолжили работать поверх повторяющихся коммитов, вы действительно навредили себе. Размер беспорядка пропорционален количеству коммитов, которые у вас есть поверх дубликатов.
Как это выглядит:
3b959b4 (HEAD, master) C10
8f84379 C9
0110e93 C8
6c4a525 C7
630e7b4 C6
070e71d (origin/master) Merge branch 'master' of bitbucket.org:username/test1
ba7688a C5
44085d5 C4
961390d C3
2a2e220 C5
85f59ab C2
ab1bda4 C4
4516164 C1
3cb46a9 C3
0e783a3 C0

Или, как показано по-другому:

В этом сценарии мы хотим удалить повторяющиеся коммиты, но сохранить основанные на них коммиты - мы хотим сохранить от C6 до C10. Как и в большинстве случаев, есть несколько способов сделать это:
Либо:
- Создайте новую ветку при последней дублированной фиксации 1 ,
cherry-pick каждую фиксацию (с C6 по C10 включительно) в эту новую ветку и рассматривайте эту новую ветвь как каноническую.
- Выполнить
git rebase --interactive $commit, где $commitнаходится фиксация перед обеими дублированными коммитами 2 . Здесь мы можем сразу удалить строки для дубликатов.
1 Не имеет значения , какой из двух вы выбираете, либо ba7688aили 2a2e220нормально работать.
2 В примере это было бы 85f59ab.
TL; DR
Набор advice.pushNonFastForwardдля false:
git config --global advice.pushNonFastForward false