Як бути з цим попередженням git? "Не рекомендується тягнути, не вказуючи, як узгодити різні гілки"


167

Після a git pull origin masterя отримую таке повідомлення:

warning: Pulling without specifying how to reconcile divergent branches is
discouraged. You can squelch this message by running one of the following
commands sometime before your next pull:

  git config pull.rebase false  # merge (the default strategy)
  git config pull.rebase true   # rebase
  git config pull.ff only       # fast-forward only

You can replace "git config" with "git config --global" to set a default
preference for all repositories. You can also pass --rebase, --no-rebase,
or --ff-only on the command line to override the configured default per
invocation.

remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 51.49 KiB | 850.00 KiB/s, done.

Тоді тяга була виконана успішно. Але все ж у мене є сумніви щодо цього повідомлення.
Що найкраще робити в цьому випадку?


1
Подайте звіт про помилку, що попередження заплутане. Один варіант слід «рекомендувати», а попередження повинно відображатися лише на запит, а не лише через те, що сталася зміна версії. Лот автоматичних сценаріїв може зламатися зараз із такою несподіваною поведінкою.
Wolfgang Fahl

1
@WolfgangFahl, попередження не повинно впливати на жодні сценарії, оскільки воно продовжує зберігати поведінку за замовчуванням, поки явно не зміниться. Це не повинно спричинити повернення ненульового коду виходу (якщо це попередження, а не помилка). Кілька сценаріїв CI / CD, які я розгорнув на різних серверах, продовжують працювати, не впливаючи на рівень успіху.
Qumber

@Qumber - дякую за коментар. Записи Crontab, наприклад, почнуть надсилати повідомлення електронної пошти, якщо з'явиться вихід, якого не було або його можна було відфільтрувати за допомогою простого grep. Несподіваний результат може мати всі види побічних ефектів.
Wolfgang Fahl

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

Відповіді:


197

У режимі за замовчуванням git pull - це скорочення для git fetch, за яким слідує git merge FETCH_HEAD.

Коли ви виконуєте a git pull origin master,
git pullвиконує злиття, яке часто створює коміт злиття. Тому за замовчуванням витягування з пульта дистанційного керування НЕ є нешкідливою операцією: воно може створити нову фіксацію ша, яка раніше не існувала. Така поведінка може заплутати користувача, оскільки те, що здається нешкідливою операцією завантаження, насправді змінює історію комітів непередбачуваними способами.

Щоб цього уникнути, потрібно

git pull --ff-only

(чи ні? читайте далі, щоб побачити, який з них відповідає вашим потребам)

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

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

git config --global pull.ff only

Примітка: --globalПрапор застосовує зміни до всіх сховищ на вашому комп'ютері. Якщо вам потрібна така поведінка лише для сховища, в якому ви перебуваєте, опустіть прапор.

Взято звідси



Це попередження було додано до Git 2.27, як зазначив Джо у своїй відповіді.

Ось як виглядає повне попередження:

Не рекомендується тягнути, не вказуючи, як узгодити різні гілки. Ви можете подавити це повідомлення, виконавши одну з наступних команд якось перед вашим наступним витягуванням:

git config pull.rebase false # merge (стратегія за замовчуванням)
git config pull.rebase true #
rebase git config pull.ff # тільки вперед

Ви можете замінити "git config" на "git config --global", щоб встановити налаштування за замовчуванням для всіх сховищ. Ви також можете передати --rebase, --no-rebase або --ff-only у командному рядку, щоб замінити налаштований за замовчуванням на виклик.

Попередження представляє три команди як опції, всі вони будуть придушувати попередження. Але вони служать різним цілям:

git config pull.rebase false     # merge (the default strategy)

Це зберігає поведінку за замовчуванням і придушує попередження.

git config pull.rebase true      # rebase

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

git config pull.ff only          # fast-forward only

Це виконує лише витяг, якщо локальну гілку можна перемотати вперед. Якщо ні, він просто перериває з повідомленням про помилку (і не створює жодних комітів).


Оновлення:

Якщо у вас є Git 2.29або вище, тепер ви можете встановити pull.ffна false, trueабо onlyпозбутися від попередження.

git config pull.ff true

true- Це поведінка за замовчуванням. Потягування, якщо це можливо, перемотується вперед, інакше воно зливається.

git config pull.ff false

false - Pull ніколи не перемотується вперед, і завжди створюється злиття.

git config pull.ff only

only - Потягнення перемотується вперед, якщо це можливо, інакше робота припиняється із повідомленням про помилку


9
Я ціную час і зусилля, які ви вкладаєте у свою відповідь, але, чесно кажучи, це все ще мені абсолютно незрозуміло.
Jared Nedzel

1
Як коментується тут , на попередження не впливає, чи гілка насправді розходиться чи ні . Початковий "Ваша гілка, ймовірно, розходиться". може ввести в оману.
Джо

3
Треба сказати, що три варіанти повідомлення не працювали для мене, щоб придушити повідомлення. Однак відповідь тут ( git config --global pull.ff only) зробив .
DiskJunky

1
Ага! Дякую @Qumber. Я вже пробував pull.rebase false, але це не працювало, як описано. Це завжди створювало коміт злиття, і ніколи не перемотування вперед. Першопричиною було те, що у мене було merge.ff falseналаштування. Після очищення цього налаштування він перемотує вперед, коли потрібно. Документи тут (майже ідентичні документам git pull )
stwr667

1
Ви включили опцію Git 2.29, про яку я згадав нижче, хороший момент. Прихильний.
VonC

65

Це нове попередження, додане в Git 2.27 :

 * "git pull" issues a warning message until the pull.rebase
   configuration variable is explicitly given, which some existing
   users may find annoying---those who prefer not to rebase need to
   set the variable to false to squelch the warning.

Щоб видалити попередження, встановіть одне із запропонованих значень для кращого поведінки по замовчуванням для , git pullякщо не вказати поведінку в командному рядку ( з допомогою --ff, --no-ff, --ff-only, --rebase). У всіх випадках gitспробує швидке перемотування вперед ( Що таке git перемотування вперед ? ), Якщо це можливо. Параметри управління , що відбувається , коли відбуваються зміни у вашій галузі , але НЕ присутні в віддаленому філії.

  git config pull.rebase false  # merge (the default strategy)

Це існуюча поведінка за замовчуванням; встановіть це для попередження та зміни поведінки; gitоб’єднає віддалену гілку з локальною.

  git config pull.rebase true   # rebase

Тут gitспробуємо перебазувати ваші зміни поверх віддаленої гілки. Див. Коли слід використовувати git pull --rebase? для більш детальної інформації про те, чому ви можете цього захотіти.

  git config pull.ff only       # fast-forward only

Якщо швидке злиття вперед неможливе, gitвідмовиться продовжувати. Як різниця між цитатами git pull --rebase та git pull --ff-only :

Відмовитися від об’єднання та виходу із ненульовим статусом, якщо поточний HEAD вже не оновлений, або об’єднання може бути вирішено як швидке перемотування вперед


20
Це насправді найбільш правильна відповідь, оскільки вона пояснює, чому люди (такі як я) раптом бачать це попередження після майже десятиліття використання git. Однак було б корисно, якби було дано деякі вказівки щодо запропонованих варіантів. наприклад, вказуючи, що встановлення функції pull.ff на "only" не заважає вам зробити "pull --rebase", щоб замінити його.
kdopen

Яка різниця між pull.rebase = trueта branch.autoSetupRebase = always?
текумара


1
"коли у вашій гілці є зміни, але у віддаленій гілці немає." Тоді мені здається, що git повинен викидати це попередження лише в тому випадку. Якщо я тягну свою основну лінію (і основна використовується належним чином), мені не слід турбуватися про це.
Кіт Тайлер

5
@Joe Мені подобається ваша відповідь, і я вважаю, що це правильна відповідь, але ви бачите це незалежно від того, чи справді щось зробив git . Я вважаю, що правильний час, щоб видати це попередження, - це якщо git повинен щось зробити , то з цим повідомленням це не вдасться. Не лише спам-користувачі з цим повідомленням завчасно. Ще одна річ, яка сприяє моїм стосункам любові / ненависті з git.
Джон V

7

git config pull.ff onlyабо еквівалентно git pull --ff-onlyє найбезпечнішим. Причина полягає в тому, що перебаза даних може перезаписати історію і може призвести до втрати комітів, якщо інший розробник примусово надсунув ту саму гілку.

Але всі вони дійсні.


3

Примітка: Раніше ми навчили " git pull" ( man ) попереджати, коли користувач не каже, що історії потрібно об'єднувати, перебазувати або приймає лише перемотування вперед, але попередження спрацьовує для тих, хто встановив pull.ffзмінну конфігурації.

Це вже не так (мається на увазі: більше не попереджати ) з Git 2.29 (Q4 2020).

Див. Коміс 54200ce (24 вересня 2020 р.) Алекса Генрі ( alexhenrie) .
(Об’єднано Junio ​​C Hamano - gitster- у комітеті 299deea , 29 вересня 2020)

pull: не попереджати, якщо pull.ffвстановлено

Підписав: Алекс Генрі

Користувач, який розуміє достатньо для налаштування pull.ff, не потребує додаткових інструкцій.


До Git 2.31 (Q1 2021), коли користувач не каже " git pull" ( man ) використовувати перебазування або злиття, команда видає гучне повідомлення, в якому повідомляється користувачеві про вибір між перебазуванням або злиттям, але все одно створює злиття, змушуючи користувачів, які хочу перебазувати, щоб повторити операцію.

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

Див. Коміт 7539fdc , коміт b044db9 (14 грудня 2020 р.) Хуніо С Хамано ( gitster) .
Див. Коміт c525de3 , коміт 278f4be , коміт 77a7ec6 (12 грудня 2020 р.) Феліпе Контрерас ( felipec) .
(Об’єднав Хуніо С Хамано - gitster- у коміті d3fa84d , 06 січня 2021)

pull: відображати попередження за замовчуванням, лише якщо значення не є ff

Пропозиції: Хуніо С Хамано
Підписав: Феліпе Контрерас

Не потрібно відображати настирливе попередження при кожному натисканні ... лише ті, які не перемотуються вперед.

Поточні тести попередження все ще проходять, але не через аргументи чи конфігурацію, а тому, що всі вони перемотуються вперед.

Нам зараз потрібно перевірити ситуації, що не перемотуються вперед.

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