Якщо натиснути коміт на сервері, а потім переписати цей коміт локально (за допомогою git reset
, git rebase
, git filter-branch
або будь-яку іншу історію маніпуляції), а потім штовхнули , що переписані фіксації назад на сервер, ви загвинчувати нікого , хто тягнув. Ось приклад; скажімо, що ви вчинили A, і перенесли його на сервер.
- * - * - A <- майстер
- * - * - A <- походження / головний
Тепер ви вирішили переписати A способом, про який ви згадали, скинувши та повторно зафіксувавши. Зверніть увагу, що це залишає звисаючий коміт A, який з часом буде зібраним сміттям, оскільки він недоступний.
- * - * - A
\
A '<- майстер
- * - * - A <- походження / головний
Якщо хтось інший, припустимо, Фред, тягне вниз master
з сервера, поки ви це робите, у них буде посилання на A, з якого вони можуть почати працювати:
- * - * - A '<- майстер
- * - * - A <- походження / головний
- * - * - AB <- fred / master
Тепер, якби ви змогли просунути ваш A 'до джерела / майстра, який створив би нешвидкий перемотування вперед, він би не мав A в своїй історії. Отже, якщо Фред спробує знову витягнути, йому раптом доведеться об’єднатись і повторно ввести коміт A:
- * - * - A '<- майстер
- * - * - A <- походження / головний
- * - * - AB- \
\ * <- fred / master
A '- /
Якщо Фред випадково це помітить, то він міг би зробити перебазу, яка запобігла б повторному появі коміту А. Але йому довелося б це помітити і пам’ятати це робити; і якщо у вас є більше, ніж одна людина, яка витягла A, їм усім довелося б перебазувати, щоб уникнути отримання зайвого A коміту в дереві.
Тож, як правило, не є гарною ідеєю змінювати історію на репо, з якого тягнуть інші люди. Якщо ви, однак, знаєте, що ніхто більше не тягне з цього репо (наприклад, це ваше власне приватне репо, або у вас є лише інший розробник, який працює над проектом, з яким ви можете легко координувати), тоді ви можете примусово оновити, запустивши:
git push -f
або
git push origin +master
Вони обидва ігноруватимуть перевірку на швидке просування вперед і оновлять те, що знаходиться на сервері, до вашої нової версії A ', відмовляючись від ревізії A, щоб врешті-решт збирати сміття.
Можливо, що примусові натискання повністю вимкнені за допомогою receive.denyNonFastForwards
опції config. Цей параметр увімкнено за замовчуванням у спільних сховищах. У цьому випадку, якщо ви дійсно, дійсно хочете змусити натиснути, найкращий варіант - видалити гілку та заново створити її за допомогою git push origin :master; git push origin master:master
. Однак denyNonFastForwards
опція включена з причини, яка описана вище; на спільному сховищі це означає, що тепер кожному, хто ним користується, потрібно переконатись, що вони перебазуються на новій історії.
У спільному сховищі, як правило, краще просто натискати нові коміти зверху, які виправляють будь-яку проблему; Ви можете використовувати git revert
для створення комітів, які скасовують зміни попередніх комітів.