git push - force-with-lease vs. --force


182

Я намагаюся зрозуміти різницю між

git push --force

і

git push --force-with-lease

Я здогадуюсь, що останній лише натискає на пульт, якщо у віддаленого немає комітетів, яких немає у місцевої гілки ?


"місцева гілка дистанційного відстеження ". В основному сенс дистанційного керування повинен виглядати так, як очікує ваш клієнт. git help pushмає випадки використання, що пояснюють його мету (в основному, щоб уникнути того, щоб змінити зміни, когось просто підштовхнули). Що мені трохи незрозуміло - це те, як працює відділення віддаленого відстеження. Але, мабуть, зазвичай потрібно буде точно виглядати, як це виглядало минулого разу, коли ви робили fetchчи pullне мали нових зобов’язань.
zzxyz

4
@zzxyz: реальна реалізація --force-with-leaseподібна до інструкцій порівняння та заміни на сучасних процесорах: той, хто хоче, щоб відбувся замін, надає очікуване значення та нове значення. Система, що здійснює своп, порівнює очікуване значення з справжнім поточним значенням, і робить своп тоді і тільки тоді, коли обидва рівні. З git push, очікуване значення - це те, що є в імені віддаленого відстеження, наприклад, git push --force-with-lease origin Xнадсилає своє власне origin/Xразом з новим потрібним значенням; origin's Git повідомляє вам, чи робив обмін, чи ні.
torek

1
Якщо Git at originздійснив обмін, ви закінчили. Якщо ні, ви можете запустити, git fetch originщоб забрати нове поточне значення, переробити зміни, якщо це потрібно, та запустіть інше примусово з орендою порівняти-поміняти, щоб спробувати ще раз.
торек

Відповіді:


172

force замінює віддалену гілку з вашою локальною гілкою.

--force-with-lease- це більш безпечний варіант, який не замінить будь-яку роботу на віддаленій гілці, якщо до віддаленої гілки було додано більше комісій (іншим членом команди або колегою чи тим, що у вас є). Це гарантує, що ви не перезаписуєте роботу інших людей силовим натисканням.

Я думаю, що ваша загальна ідея навколо команди є правильною. Якщо віддалена гілка має те саме значення, що й віддалена гілка на вашій локальній машині, ви заміните віддалену. Якщо воно не має однакового значення - воно вказує на зміну, яку внесено ще хтось у віддалену гілку, поки ви працювали над своїм кодом, і таким чином не буде замінено жоден код. Очевидно, що якщо у віддалених передачах є додаткові коміти, значення не будуть однаковими.

Я просто думаю --force-with-lease, що це варіант використовувати, коли я хочу переконатися, що я не перезаписую жоден код товаришів по команді. Багато команд в моїй компанії використовують --force-with-leaseяк варіант за замовчуванням для відмови. Це непотрібно в більшості випадків, але позбавить вас від головного болю, якщо вам трапиться переписати щось, що інша людина сприяла віддаленій роботі.

Я впевнений, що ви подивилися на документи, але тут може бути ще одне багатослівне пояснення:

https://git-scm.com/docs/git-push


38

Шукаєте відповідь на основі достовірних та / або офіційних джерел.

Згадане Тореком "порівняння та обмін" у коментарях та іншій його відповіді додатково пояснюється джерелами самого Git .

остання лише натискає на пульт, якщо в пульті немає зобов'язань, яких немає в локальній гілці?

Ця особливість була введена в цьому комітеті (грудень 2013, Git v1.8.5-rc0)

--force-with-lease захистить всі віддалені рефлекси, які збираються оновити, вимагаючи, щоб їх поточне значення було таким самим, як деякий розумний дефолт, якщо не вказано інше;

Наразі "деякий розумний дефолт" орієнтовно визначається як " значення гілки віддаленого відстеження, яке ми маємо для посилання віддаленого оновлення ", і це помилка, якщо у нас немає такої гілки віддаленого відстеження.

Отже, "оренда" означає:

" force-with-lease": Ви припускаєте, що ви взяли оренду на ліцензію, коли ви взяли рішення, щоб вирішити, якою має бути історія знижок, і ви можете відштовхуватися, лише якщо оренда не була порушена.

У джерелах досі згадується "cas":

  • Цей варіант спочатку називався "cas " (для "порівняння та заміни"), ім'я, яке нікому не сподобалось, оскільки воно було надто технічним.
  • Друга спроба назвала це "lockref" (тому що це концептуально як натискання після зняття блокування), але слово "замок" було ненависно, оскільки це означало, що воно може відхиляти натискання іншими, а це не такий спосіб, як ця опція працює.
  • Цей раунд називає це "силою з орендою".
    Ви припускаєте, що ви взяли оренду на оплату, коли ви взяли рішення, щоб вирішити, якою має бути історія знижок, і ви можете відштовхуватися, лише якщо оренда не була порушена.

Отже: " git push --force-with-leaseпроти --force"

Як я вже згадував у " push --force-with-leaseза замовчуванням ", як згадується в Git 2.13 (Q2 2017), що цю опцію --force-with-leaseможна ігнорувати, якщо запускається фоновий процес (як той, який ви знайдете в IDE з плагіном Git) git fetch origin.
У цьому випадку --forceпереважає.


29

git push --force є руйнівним, оскільки він безумовно перезаписує віддалене сховище з будь-якими локальними. git push --force сильно не рекомендується, оскільки це може знищити інші комісії, які вже перенесені до спільного сховища. Однією з найпоширеніших причин силових натискань є те, коли ми змушені переглядати гілку.

Наприклад. У нас є проект з галуззю, над якою працюють і Аліса, і Боб. Вони обидва клонують це сховище і починають роботу. Аліса спочатку завершує свою частину функції, і підштовхує це до основного сховища. Це все добре і добре. Боб також закінчує свою роботу, але перш ніж підштовхувати її, він помічає, що деякі зміни були об'єднані в майстра. Бажаючи зберегти чисте дерево, він виконує відновлення проти ведучої гілки. Звичайно, коли він піде просунути цю відновлювану гілку, вона буде відхилена. Однак не усвідомлюючи, що Аліса вже підштовхнула її роботу, він виконує натиск. На жаль, це видалить усі записи про зміни Аліси в центральному сховищі.

Що - примусово з орендою - це відмова від оновлення філії, якщо це не такий стан, якого ми очікуємо; тобто ніхто не оновлював гілку вище за течією. На практиці це працює, перевіряючи, чи є те, що ми очікуємо, що реф. По течії є те, що ми вважаємо хешами, і неявно кодує ланцюжок батьків у їхню цінність.

Ось хороший пост щодо git push --force та git push --force-with-lease.


2
що я не розумію - якщо ви перезавантажуєтеся з господарем, то ви повинні мати можливість просуватися без --force-with-lease ? Чому це --force-with-leaseпотрібно після звільнення з господарем?
Олександр Міллс

3
@AlexanderMills може бути певна можливість, яка може викликати проблеми. Якщо ви є останньою людиною, яка підштовхує це до оволодіння, тоді немає жодної проблеми, але є інша людина, яка працює з іншим завданням, то це може спричинити серйозні проблеми. Скажіть, спочатку A - B - C був господарем, спочатку Аліса зробила це A - B - C - D - E і тоді ж Боб зробив A - B - C - F - G. Якщо Аліса - остання людина у майстра після звільнення A - B - C - D - E - F - G не спричинить жодних проблем, але інша людина Том спробує підштовхнути A - B - C - D - E - R одночасно у головній катастрофі станеться !! !
Шакіль

3
--forceне втрачає комісій, він просто від'єднує їх. Вони можуть бути воскрешені їх хешами, як у git checkout <SHA>або git reset --hard <SHA>, якщо припускати, що обслуговуючий персонал віддаленого РЕПО не виконує жодних операцій з ремонту або обрізки.
Кіт Рассел

1
"git push --force сильно перешкоджає, оскільки це може знищити інші комісії, які вже передані до спільного сховища", це твердження ґрунтується на думці. Здійснення натискання є частиною звичайного робочого процесу з перегляду коду git. Також, як уже згадувалося, ви можете отримати комісії навіть після цього.
Етьєнн

9

Якщо припустити, що будь-які гачки попереднього отримання на сервері приймають натиск, це завжди вдасться:

git push --force

Беручи до уваги, що це стосується певної перевірки на стороні клієнта, перш ніж продовжувати:

git push --force-with-lease

Ви можете запустити конкретну перевірку самостійно. Ось алгоритм "перевірки оренди":

  1. З’ясуйте свою поточну галузь.

  2. Біжи git for-each-ref refs/remotes. Візьміть на замітку ідентифікатор фіксації, який ваш клієнт git вважає, відповідає стані поточного відділення.

Наприклад, якщо ви перебуваєте у гілці "foo", врахуйте ID-код, пов'язаний з "refs / remotes / origin / foo".

  1. Визначте фактичний ідентифікатор комісії віддаленої гілки на upstream git-сервері прямо зараз.

  2. Дозвольте "git push" продовжуватись лише тоді, коли зобов'язання, витягнуті з кроку 2 та кроку 3, погоджуються. Іншими словами, продовжуйте лише якщо поняття вашого локального git-клону вгору за течією погоджується з фактичним вище за течією.

Тут є сумний сенс: оскільки git fetchоновлюється всі рефлекси в "refs / remotes / origin / *" до їх останніх версій, ця комбінація команд по суті ідентичнаgit push --force :

git fetch

# The command below behaves identically to "git push --force"
# if a "git fetch" just happened!

git push --force-with-lease

Щоб обійти цю притаманну git push --force-with-leaseмені слабкість, я намагаюся ніколи не бігати git fetch. Натомість я завжди запускаю, git pull --rebaseколи мені потрібно синхронізуватись із висхідним потоком, оскільки git pullоновлює лише одну посилання під refs / remote, зберігаючи "оренду" --force-with-leaseкорисного.


1
якщо чек на стороні клієнта, чи є потенціал для перегонів? тобто хтось інший підштовхує зміни після перевірки, але перед вимушеним натисканням?
craq

2

Примусовий оренди не завжди є безпечним. Це просто працює, як сказала Сільві. Одна примітка: У git гілка - це лише вказівник на коміт. І здійснює точку до нуля або більше батьківських комітів. Навіть якщо ви повністю змінили гілку за допомогою жорсткого скидання git та примусового натискання чи натискання з - - примусово з орендою, не бажаючи цього, це не обов'язково велика проблема. Ви можете скористатись місцевим рефлоктом git, щоб побачити, як змінився ваш локальний наконечник на гілках (Де в той час була HEAD?), А також скинути та знову натиснути гілку. Тоді ви лише втрачаєте нові комісії на віддаленому відділенні, але навіть вони можуть бути відновлені членами команди.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.