Чи може "git pull" автоматично приховувати та виконувати зміни?


122

Я знаю, як це вирішити:

user@host$ git pull
Updating 9386059..6e3ffde
error: Your local changes to the following files would be overwritten by merge:
    foo.bar
Please, commit your changes or stash them before you can merge.
Aborting

Але чи не є спосіб , щоб git pullзробити stashі popтанець для мене?

Якщо ця команда має іншу назву, це нормально.

Створення псевдоніма оболонки для git stash; git pull; git stash pop- це рішення, але я шукаю кращого рішення.


що з псевдонімом git ?
Яої

20
Запускати git stash; git pull; git stash popпрограму небезпечно, тому що якщо нічого не потрібно приховувати, git stashце буде бездіяльність, але git stash popвиведе останню сховку (якщо така є), що майже точно не те, що ви хочете. Користувач torek має чудовий пост про це на стеку Overflow, але я не можу його знайти
jub0bs


1
@guettli Я не мав на увазі, що ваше запитання є дублікатом, я просто відповідав на коментар Джубобса.
VonC

2
Як крок далі, операція має бути успішною лише в тому випадку, якщо після потягування можна чітко нанести сховище. Якщо виникають конфлікти, то вся операція виходить з ладу атомно, щоб дерево не було змінено. Це те, що я хотів би зробити: або зніміть зміни зі своїми об’єднаними локальними, або ж не вдається з помилкою і дозвольте вручну вирішити, що робити далі. Чи можливий такий вид "трансакції" git?
Ед Евіс

Відповіді:


185

Для Git 2.6+ (випущений 28 вересня 2015 року)

The тільки git config Установка, яка була б цікава, це:

rebase.autoStash

(з Git 2.27, Q2 2020, тепер ви також є merge.autostash, див. нижче)

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

Однак використовуйте обережно: остаточне приховування програми після успішної бази даних може призвести до нетривіальних конфліктів. Типово встановлено значення false.

поєднайте це з:

pull.rebase

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

git config pull.rebase true
git config rebase.autoStash true

Цього було б достатньо для простої git pullроботи навіть у брудному дереві.
У цьому випадку жоден псевдонім не потрібен.


Див. Коміт 53c76dc (04 липня 2015) Кевіна Дадта ( Ikke) .
(Об’єднав Хуніо С Хамано - gitster- в комісії e69b408 , 17 серпня 2015 р.)

pull: дозволити брудне дерево при rebase.autostashвключенні

Rebase навчився приховувати зміни, коли стикається з брудним робочим деревом, але git pull --rebaseце не так.

Переконайтесь, чи працююче дерево забруднене, коли rebase.autostashйого не включено.


Примітка. Якщо ви хочете витягнути без автоматичного падіння (навіть якщо rebase.autoStash trueце встановлено), у вас є git 2.9 (червень 2016 року):

 pull --rebase --no-autostash

Див. Зробити 450dd1d , зробити 1662297 , здійснити 44a59ff , зробити 5c82bcd , зробити 6ddc97c , зробити eff960b , зробити efa195d (02 квітня 2016 р.) Та здійснити f66398e , здійснити c48d73b (21 березня 2016 р.) Мехулом Джаїном ( mehul2029) .
(Об’єднав Хуніо С Хамано - gitster- у комітеті 7c137bb , 13 квітня 2016 р.)

Зокрема, f66398e включає:

pull --rebase: додати --[no-]autostashпрапор

Якщо rebase.autoStashзмінна конфігурація встановлена, немає можливості її замінити для git pull --rebaseкомандного рядка.

Навчіть « git pull --rebase» --[no-]autostashлінія прапор команди , яка перекриває поточне значення rebase.autoStash, якщо він встановлений. Оскільки " git rebase" розуміє --[no-]autostashваріант, це лише питання передачі опції в основу " git rebase", коли " git pull --rebase" викликається.


Попередження: перед Git 2.14 (Q3 2017), " git pull --rebase --autostash" не автозахист, коли локальна історія швидко просувається вгору за течією.

Див. Комісію f15e7cf (01 червня 2017 р.) Від Tyler Brazier ( tylerbrazier) .
(Об’єднав Хуніо С Хамано - gitster- у комітеті 35898еа , 05 червня 2017 р.)

pull: ff --rebase --autostashпрацює в брудному репо

Коли git pull --rebase --autostashв брудному сховищі було зроблено швидке перемотування вперед, нічого не було автоматизовано, а витяг не вдався.
Це було пов’язано із ярликом, щоб уникнути запуску бази даних, коли ми можемо перемотатись вперед, але автозавантаження ігнорується на цьому кодовому шляху.


Оновлення: Маріуш Павельський задає в коментарях цікаве запитання:

Тому всі пишуть про те, autostashколи ви робите ребауз (або pull --rebase).

Але ніхто не займається автоматичним натисканням назовні, коли ви робите звичайне тягнення зі злиттями .
Так що для цього немає автоматичного вимикача? Або я щось пропускаю? Я вважаю за краще робити, git pull --rebaseале ОП запитав про " стандартне " потягнення git

Відповідь:

Вихідний потік обговорювати цю autostash функцію, вона була реалізована спочатку як для git pull(злиття) і git pull --rebase.

Але ... Хуніо С Хамано (технічний супровід Git) зазначив, що:

Якщо це pull-mergeбуло б щось, що могло б викликати "роздратування", яке викликало цю тему, за визначенням, локальна зміна перекривається злиттям, і ця внутрішня "скрипка поп" торкнеться шляхів, до яких торкнулося злиття, і це, швидше за все, не призведе до "Відкинутого "але залишати подальші конфлікти для вирішення.

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

Рівняння дещо інше для "pull-rebase", оскільки "rebase" наполягає на тому, щоб ви почали з чистого робочого дерева, тому "скачати, а потім зупинити" роздратування відчуває себе більшим. У мене є підозра, що послаблення може бути більш продуктивним виправленням реальної проблеми.

Отож, щодо класичного підтягування, краще:

спонукайте користувача задуматися над природою WIP у робочому дереві перед запуском " git pull" .
Це занадто складний звір, який може перешкоджати тому, що роблять інші, або це тривіальна зміна, що він може приховати і відкинути його назад?

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

Якщо останній, йому краще робити:

  • " git pull",
  • виявивши це конфліктами, біжіть
    • git stash,
    • git merge FETCH_HEAD і
    • git stash pop

Це було сказано, що з Git 2.27 (Q2 2020), " git pull" навчився попереджати, коли не pull.rebaseіснує жодної конфігурації, і ні, --[no-]rebaseні --ff-onlyдається (що призведе до злиття).

Див. Комісію d18c950 (10 березня 2020 р.) Від Алекса Генрі ( alexhenrie) .
(Об’єднав Хуніо С Хамано - gitster- у комітеті 1c56d6f , 27 березня 2020 р.)

pull: Попередити, якщо користувач не сказав, чи потрібно перезавантажувати або об’єднувати

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

Часто початківці користувачі Git забувають сказати " pull --rebase" і закінчуються непотрібним злиттям вгору за течією.

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

Видайте попереджувальне повідомлення, коли не вказано жодної --[no-]rebaseопції з командного рядка та pull.rebaseзмінної конфігурації.
Це доставить незручності тим, хто ніколи не хоче " pull --rebase", кому не довелося робити нічого особливого, але вартість незручностей виплачується лише один раз на кожного користувача, що має бути розумною вартістю для допомоги ряду нових користувачів.


З Git 2.27 (Q2 2020), " git merge" дізнається " --autostash" варіант та нові merge.autostashналаштування.

Див здійснювати d9f15d3 , здійснювати f8a1785 , здійснюють a03b555 , здійснюють 804fe31 , здійснюють 12b6e13 , здійснюють 0dd562e , здійснюють 0816f1d , здійснюють 9bb3dea , здійснюють 4d4bc15 , здійснюють b309a97 , здійснюють f213f06 , здійснюють 86ed00a , здійснюють facca7f , здійснюють be1bb60 , здійснюють efcf6cf , здійснюють c20de8b , зробити bfa50c2 , фіксувати 3442c3d , фіксувати 5b2f6d9 (07 квітня 2020 р.), виконувати 65c425a(04 квітня 2020 р.) Та виконувати fd6852c , здійснити 805d9ea (21 березня 2020 р.) Від Дентона Лю ( Denton-L) .
(Об'єднав Хуніо С Хамано - gitster- у комітеті bf10200 , 29 квітня 2020 р.)

pull: pass --автосташ для злиття

Вийшов із реєстрації: Дентон Лю

Раніше --autostashпрацював лише з git pull --rebase.

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

І:

rebase: використання apply_autostash()від ser.r.c

Вийшов із реєстрації: Дентон Лю

apply_autostash()Функція builtin/rebase.cподібна досить , щоб apply_autostash()функції в sequencer.cтому , що вони майже взаємозамінні, для типу Arg вони приймають за винятком. Зробіть sequencer.cверсію зовнішньою та використовуйте її в ребазі.

Версія ребаза була введена в 6defce2b02 ("вбудована ребаза: --autostashопція підтримки ", 2018-09-04, Git v2.20.0-rc0 - злиття, вказане в пакеті № 8 ) як частина оболонки в C перетворення.
Він вирішив дублювати функцію, оскільки на той час був ще один незавершений проект, який перетворював інтерактивну базу даних з оболонки на C, і вони не хотіли зіткнутися з ними шляхом рефакторингу sequencer.cверсії apply_autostash().
Оскільки обидва зусилля давно зроблені, ми можемо їх вільно поєднувати зараз.


Станом на 2.4.2, це ще не реалізовано. Можливо, якийсь день. rebase.autoStashзастосовується лише при використанні бази даних. pull.rebaseзастосовується лише при використанні тяг.
Рандал Шварц

"Цього було б достатньо для простого втягування в роботу навіть у брудному дереві". Як зауважив Рандал, це ще не так. Поточний майстер pull.c все ще вирішує die_on_unclean_work_tree.
Прадхан

1
@Pradhan Я згоден. Реалізація щойно потрапила в майстер сьогодні вранці, і вона повинна працювати на git 2.6. Я відредагував відповідь, щоб зробити це зрозумілим.
VonC

Я підтвердив, що автозапуск працює з git 2.5.5.
Джошуа Хоблітт

1
Тому всі пишуть про автозавантаження, коли ви робите rebase(або pull --rebase). Але ніхто не займається автоматичним зніманням, коли ви робите нормальне pullзлиття. Так що для цього немає автоматичного вимикача? Або я щось пропускаю? Я вважаю за краще займатися, git pull --rebaseале ОП запитав про "стандарт"git pull
Маріуш Павельський

41

Щоб заощадити кілька секунд для майбутніх дослідників, ось короткий опис (завдяки @VonC):

git pull --rebase --autostash

6
Справа в тому, що після git config pull.rebase trueі git config rebase.autoStash true- все, що вам коли-небудь знадобиться - це git pull. Просто git pull. Інші параметри не потрібні.
VonC

3
Здається, вам потрібно принаймні Git 2.9 для --autostashопції. -c rebase.autoStash=trueПрацює в Git 2.6 і далі.
ntc2

15

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

git fetch
git rebase --autostash FETCH_HEAD

Або встановіть його як псевдонім:

git config alias.pullr '!git fetch; git rebase --autostash FETCH_HEAD'

Потім зробіть:

git pullr

Звичайно, цей псевдонім можна перейменовувати за бажанням.


7

За допомогою Git 2.6+ ви можете скористатись такими:

alias gup='git -c rebase.autoStash=true pull --rebase'

Це --rebaseробить використання git-pull rebaseзамість merge, тому налаштування / параметри на зразок --ff-onlyне застосовуватимуться.

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


У чому головна відмінність між git pull --ff-onlyіgit pull pull --rebase --autostash
альпер

0

Як ви вже згадували, це спосіб зробити це. Ви можете використовувати його в псевдонімі, щоб заощадити набравши текст та скористатися ярликом, або ж ви можете використовувати його в одному рядку (може бути псевдонімом)

git stash && git pull --rebase && git stash pop

Це буде робити те саме, що ви робили, але в одному рядку (&&), і якщо ви встановите псевдонім, він буде навіть коротшим.

У наступних рядках відображатимуться вхідні / вихідні зміни, перш ніж потягнути / натиснути

git log ^master origin/master
git log master ^origin/master

8
Такий підхід небезпечний: якщо нічого не приховувати, перша команда нічого не зробить, а потім stash popвидалить деякі випадкові речі раніше.
Джон Цвінк

Щоб бути додатково зрозумілим: навіть якщо git stashнічого не приховує, він все ще не повертає код помилок, тому && продовжуватиметься git pullта додаватиме git stash popпопередній скрипт. Тож краще не користуйтеся цим, якщо ви не впевнені, що це щось приховає!
MoonLite
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.