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
. Дивіться мою відповідь нижче