Git 2.18 (Q2 2018) значно покращить --preserve-mergeваріант, додавши нову опцію.
" git rebase" навчився " --rebase-merges" пересаджувати всю топологію графіка фіксації в інше місце .
(Примітка: Git 2.22, Q2 2019, насправді застаріло --preserve-merge , а Git 2.25, Q1 2020, припиняє рекламувати його на git rebase --helpвиході " " )
Див здійснюють 25cff9f , здійснюють 7543f6f , здійснюють 1131ec9 , здійснюють 7ccdf65 , здійснюють 537e7d6 , здійснюють a9be29c , здійснюють 8f6aed7 , здійснюють 1644c73 , здійснюють d1e8b01 , здійснюють 4c68e7d , здійснюють 9055e40 , здійснюють cb5206e , здійснюють a01c2a5 , здійснюють 2f6b1d1 , здійснюють bf5c057 (25 апр 2018) від Johannes Schindelin ( dscho) .
Див. Комісію f431d73 (25 квітня 2018 р.) Від Стефана Беллера ( stefanbeller) .
Див. Коміт 2429335 (25 квітня 2018) від Phillip Wood ( phillipwood) .
(Об’єднав Хуніо С Хамано - gitster- у комітеті 2c18e6a , 23 травня 2018 р.)
pull: прийняти --rebase-mergesвідтворити топологію галузі
Подібно до preserveрежиму просто передачі --preserve-merges
опції rebaseкоманді, mergesрежим просто передає
--rebase-mergesопцію.
Це дозволить користувачам зручно переосмислити нетривіальні топології фіксації під час витягування нових комісій, не згладжуючи їх.
git rebaseНа цій сторінці man є повний розділ, присвячений оновленню історії злиттям .
Витяг:
Є законні причини, через які розробник може захотіти відтворити об'єднання об'єднань: зберігати структуру гілки (або "здійснювати топологію") під час роботи над декількома взаємопов'язаними гілками.
У наступному прикладі розробник працює на тематичній гілці, яка перетворює фактори визначення кнопок, і на іншій гілці теми, яка використовує цей рефакторинг для реалізації кнопки "Повідомити про помилку".
Вихід git log --graph --format=%s -5може виглядати так:
* Merge branch 'report-a-bug'
|\
| * Add the feedback button
* | Merge branch 'refactor-button'
|\ \
| |/
| * Use the Button class for all buttons
| * Extract a generic Button class from the DownloadButton one
Розробник може захотіти відновити ці зобов'язання на новіші master
, зберігаючи топологію гілки, наприклад, коли очікується, що перша галузь теми буде інтегрована в masterнабагато раніше, ніж друга, скажімо, для вирішення конфліктів злиття зі змінами
DownloadButtonкласу, який склав це в master.
Ця база даних може бути виконана за допомогою --rebase-mergesпараметра.
Див. Команду 1644c73 для невеликого прикладу:
rebase-helper --make-script: введіть прапор для відновлення злиття
Секвенсер щойно вивчив нові команди, призначені для відтворення структури гілок ( схожих за духом --preserve-merges, але з істотно менш розбитим дизайном ).
Давайте дозволяють rebase--helperгенерувати списки TODO використання цих команд, що запускаються з допомогою нової --rebase-mergesопції.
Для такої топології фіксації (де HEAD вказує на C):
- A - B - C (HEAD)
\ /
D
згенерований список тодо виглядатиме так:
# branch D
pick 0123 A
label branch-point
pick 1234 D
label D
reset branch-point
pick 2345 B
merge -C 3456 D # C
У чому різниця --preserve-merge?
Коміт 8f6aed7 пояснює:
Колись цей розробник думав: чи не було б приємно, якби, скажімо, патчі Git для Windows поверх ядра Git могли бути представлені у вигляді зарості гілок і переобладнані поверх ядра Git, щоб підтримувати вишневий набір накладних серій?
Оригінальна спроба відповісти на це: git rebase --preserve-merges.
Однак цей експеримент ніколи не задумувався як інтерактивний варіант, і він підтримувався лише підсиленням, git rebase --interactiveтому що виконання цієї команди виглядало вже дуже-дуже звично: її розробив той самий чоловік, який створив --preserve-merges: ваш справді.
І під «твоєю справді» автор посилається на себе: Йоганнес Шинделін ( dscho) , який є основною причиною (з кількома іншими героями - Ханнесом, Штеффен, Себастьяном, ...), що у нас є Git For Windows (навіть якщо ще в той день - 2009 - це було непросто ).
Він працює в Microsoft з вересня 2015 року , що має сенс враховувати, що Microsoft зараз активно використовує Git і потребує його послуг.
Ця тенденція почалася фактично у 2013 році з TFS . З того часу Microsoft управляє найбільшим сховищем Git на планеті ! І з жовтня 2018 року Microsoft придбала GitHub .
Ви можете побачити Йоганнеса, який виступає у цьому відео для Git Merge 2018 у квітні 2018 року.
Через деякий час інший розробник (я дивлюся на тебе, Андреас! ;-)) вирішив, що було б хорошою ідеєю дозволити --preserve-mergesпоєднувати з --interactive(із застереженнями!) Та підтримку Git (ну тимчасовий утримувач Git під час відсутності Джуніо, тобто) погодився, і саме тоді гламур --preserve-mergesдизайну почав розпадатися досить швидко і неслухняно.
Тут Джонатан говорить про Андреаса Шваба із Суза.
Деякі їх обговорення ви можете побачити ще у 2012 році .
Причина? У --preserve-mergesрежимі батьки об'єднання об'єднань (або з цього приводу будь-якого комітету ) не були вказані прямо, але мали на
увазі ім'я комітету, передане pickкоманді .
Це унеможливило, наприклад, переупорядкування комісій .
Не кажучи вже про переміщення комісій між гілками або, заборони божество, розділити гілки теми на дві частини.
На жаль, ці недоліки також заважали цьому режиму (початковою метою якого було обслуговувати Git для потреб Windows, з додатковою надією, що він може бути корисним і для інших) служити Git для потреб Windows.
П'ять років потому, коли стало справді безперебійним мати одну непросту, велику серію патчів hodge-podge з частково пов'язаними, частково не пов’язаними між собою патчами в Git для Windows, які час від часу перероблялися на основні теги Git (заробляючи незаслужений гнів розробника із злощасної git-remote-hgсерії, яка спочатку застаріла з Git для конкурентного підходу Windows, а лише пізніше її відмовилися без технічного
обслуговування), була справді непереборною, народилися " Ножиці садових ножиць " : сценарій, підписка на вершині інтерактивної бази даних, що спочатку визначило б топологію гілки патчів, які підлягають перебазуванню, створить псевдотодовий список для подальшого редагування, перетворить результат у справжній список тодо (використовуючи важке використанняexec команда "реалізувати" відсутні команди команд списку todo) і, нарешті, відтворити серію патчів поверх нової базової комісії.
(Скрипт ножиць Git garden посилається на цей патч у фіксації 9055e40 )
Це було в 2013 році.
І, щоб розробити дизайн та реалізувати його як сценарій поза деревом, знадобилося близько трьох тижнів. Потрібно сказати, що на реалізацію знадобилося досить багато років, щоб стабілізуватись, в той час як сама конструкція виявилася здоровою.
За допомогою цього пластиру сама доброта садових ножиць Git приходить до git
rebase -iсебе .
При передачі цього --rebase-mergesпараметра буде створено список todo, який можна легко зрозуміти, і де очевидно, як упорядкувати комісії .
Нові гілки можна ввести, вставляючи labelкоманди та викликаючи merge <label>.
І як тільки цей режим стане стабільним і загальновизнаним, ми можемо знехтувати помилку дизайну, яка була--preserve-merges .
Git 2.19 (Q3 2018) покращує новий --rebase-mergesваріант, змушуючи його працювати --exec.
" --exec" Варіант до " git rebase --rebase-merges" розміщував команди exec у неправильних місцях, що було виправлено.
Див. Комісію 1ace63b (09 серпня 2018 р.) Та фіксування f0880f7 (06 серпня 2018 р.) Йоганнеса Шинделіна ( dscho) .
(Об’єднав Хуніо С Хамано - gitster- в комітеті 750eb11 , 20 серпня 2018)
rebase --exec: змусити його працювати --rebase-merges
Ідея --exec- додавати execдзвінок після кожного pick.
З моменту введення fixup!/ с quash!фіксацій, ця ідея була розширена , щоб застосувати до «забрати, можливо супроводжуваного FixUp / сквош ланцюга», тобто Exec НЕ буде вставлений між а pickі будь-який з його відповідних
fixupабо squashліній.
Поточна реалізація використовує капость для досягнення цієї мети: вона передбачає , що тільки вибрати / Fixup / сквош команди, а потім
вставляє в execлінію перед будь-яким , pickале першим, і приєднує остаточну.
За допомогою списків todo, що генеруються git rebase --rebase-merges, ця проста реалізація показує свої проблеми: вона створює абсолютно неправильну річ, коли є label, resetі mergeкоманди.
Давайте змінимо реалізацію, щоб зробити саме те, що ми хочемо: шукаємо
pickлінії, пропускаємо будь-які ланцюги фіксації / сквош, а потім вставляємо exec
рядок . Натріть, промийте, повторіть.
Примітка: ми намагаємось вставити перед рядками коментарів, коли це можливо, оскільки порожні комірки представлені коментованими рядками вибору (і ми хочемо вставити попередній рядок виконання вибору перед таким рядком, а не після цього).
Перебуваючи в ньому, також додайте execрядки після mergeкоманд, оскільки вони за духом схожі на pickкоманди: вони додають нові коміти.
Git 2.22 (Q2 2019) фіксує використання refs / переписаної / ієрархії для зберігання проміжних станів ребаза, що по суті робить ієрархію на робочому дереві.
Див. Комісію b9317d5 , вчиняйте 90d31ff , фіксуйте 09e6564 (07 березня 2019 р.) Nguyễn Thái Ngọc Duy ( pclouds) .
(Об'єднано Хуніо С Хамано - gitster- в комісії 917f2cd , 09 квітня 2019 р.)
Переконайтеся, що refs / переписаний / є кожним робочим деревом
a9be29c (секвенсор: зробити refs, згенерований labelкомандою worktree-local, 2018-04-25, Git 2.19) додає refs/rewritten/як опорний простір для worktree.
На жаль (мені погано) є кілька місць, які потребують оновлення, щоб переконатися, що це дійсно на кожному рівні роботи.
- add_per_worktree_entries_to_dir()оновлюється, щоб переконатися, що перелік посилань переглядає per-worktree refs/rewritten/замість per-repo.
common_list[]оновлюється, щоб git_path()повернути правильне розташування. Сюди входить " rev-parse --git-path".
Цей безлад створений мною.
Я почав намагатися це виправити, вводячи refs/worktree,там, де всі рефлекси будуть працювати без роботи без спеціальних процедур.
Невдалі реф / переписані були раніше refs / worktree, тому це все, що ми можемо зробити.
З Git 2.24 (Q4 2019), " git rebase --rebase-merges" навчився керувати різними стратегіями злиття та передавати їм певні стратегічні варіанти.
Див. Коміт 476998d (04 вересня 2019 року) від Іллі Ньюрена ( newren) .
Див здійснюють e1fac53 , здійснює a63f990 , здійснює 5dcdd74 , здійснює e145d99 , здійснює 4e6023b , здійснює f67336d , здійснює a9c7107 , здійснюють b8c6f24 , здійснює d51b771 , здійснює c248d32 , здійснює 8c1e240 , здійснює 5efed0e , здійснює 68b54f6 , здійснює 2e7bbac , здійснює 6180b20 , здійснюють d5b581f (31 Липень 2019) відЙоганнес Шинделін ( dscho) .
(Об’єднав Хуніо С Хамано - gitster- у комітеті 917a319 , 18 вересня 2019 р.)
З Git 2.25 (Q1 2020) логіка, яка використовується для розбиття локальних і глобальних репозиторіїв робочого дерева, виправлена, щоб полегшити збереження-об'єднання.
Див. Комісію f45f88b , фіксування c72fc40 , фіксування 8a64881 , фіксування 7cb8c92 , фіксування e536b1f (21 жовтня 2019 р.) SZEDER Gábor ( szeder) .
(Об’єднав Хуніо С Хамано - gitster- в комісії db806d7 , 10 листопада 2019 р.)
path.c: не викликайте matchфункцію без значення вtrie_find()
Вихід із системи: SZEDER Gábor
'logs / refs' не є діючим деревом, але специфічний b9317d55a3 (переконайтеся, що refs / rewritten / is per-worktree, 2019-03-07, v2.22.0-rc0) ' git rev-parse --git-path' повертає помилковий шлях якщо замикає « /» присутній:
$ git -C WT/ rev-parse --git-path logs/refs --git-path logs/refs/
/home/szeder/src/git/.git/logs/refs
/home/szeder/src/git/.git/worktrees/WT/logs/refs/
Ми використовуємо trieструктуру даних для ефективного вирішення, належить чи шлях до загального режиму, чи працює дерево.
Як це буває, b9317d55a3 викликала помилку, яка є такою ж старою, як і trieсама реалізація, додана в 4e09cf2acf (" path: оптимізувати загальну перевірку режиму", 2015-08-31, Git v2.7.0-rc0 - злиття, вказане в пакеті №2 ).
Відповідно до опису коментаря trie_find(), він повинен викликати задану функцію відповідності "fn" лише за "/ -or- \ 0-припиненим префіксом ключа, для якого трие містить значення".
Це неправда: є три місця, де trie_find () викликає функцію відповідності, але в одному з них відсутня перевірка існування значення.
b9317d55a3 додав два нові ключі до trie:
- '
logs/refs/rewritten', і
- '
logs/refs/worktree', поруч із уже існуючим ' logs/refs/bisect'.
Це призвело до появи trieвузла з контуром ' logs/refs/', який раніше не існував і якому не додано значення.
Запит на ' logs/refs/' знаходить цей вузол, а потім потрапляє на той виклик matchфункції, який не перевіряє існування значення, і, таким чином, викликає matchфункцію NULLяк значення.
Коли matchфункція check_common()викликається NULLзначенням, вона повертає 0, що вказує на те, що запитуваний шлях не належить до загального каталогу, в кінцевому підсумку в результаті відображається помилковий шлях.
Додайте відсутню умову, щоб trie_find()вона ніколи не викликала функції збігу з неіснуючим значенням.
check_common() тоді більше не доведеться перевіряти, чи отримав воно значення, яке не має значення NULL, тому видаліть цю умову.
Я вважаю, що немає інших шляхів, які могли б спричинити подібні фальшиві результати.
AFAICT, єдиною іншою клавішею, що призводить до виклику функції відповідності зі NULLзначенням, є ' co' (через клавіші ' common' і ' config').
Однак, оскільки вони не знаходяться в каталозі, що належить до загальної директорії, очікується результат, що відповідає дереву.
git --rebase-mergesврешті-решт замінить стареgit --preserve-merges. Дивіться мою відповідь нижче