Коротка відповідь
Ви пропустили той факт, що ви бігли 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 заснований на ряді факторів, одним з яких є хеш коміту, який виходить перед ним.
Якщо ви будете упорядковувати комісії, ви зміните хеші фіксування; rebasing (коли він щось робить) змінить хеші фіксації. При цьому результат запущеного тексту 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
![Початковий набір лінійних комісій у сховищі](https://i.stack.imgur.com/rIXUz.png)
Потім ви переходите до зміни комітетів.
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
![Те саме відбувається з новими хешами](https://i.stack.imgur.com/kiPLf.png)
Тут важливо помітити, що хеші фіксації різні. Це очікувана поведінка, оскільки ви щось змінили (що-небудь) про них. Це нормально, АЛЕ:
![Журнал графіків, що показує, що майстер не синхронізується з дистанційним](https://i.stack.imgur.com/QaTVK.png)
Намагаючись натиснути, ви побачите помилку (і підкажете, що вам слід бігти 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
Або показано іншим способом:
![Журнал графіків, що показує об'єднання об'єднань](https://i.stack.imgur.com/K6hCb.png)
І тепер ми маємо дублікати комітетів на місцевому рівні. Якби ми запустили, 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
![Журнал Git, що відображає лінійні коміти над дублюючими комітами](https://i.stack.imgur.com/cQQ3i.png)
Або показано іншим способом:
![Графік журналу, що показує лінійні коміти над дублюються комітами](https://i.stack.imgur.com/GTS2A.png)
У цьому сценарії ми хочемо видалити дублікати комітетів, але зберігаємо ті елементи, які ми базуємо на них - ми хочемо зберегти 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