Чому git комісії не містять назви гілки, на якій вони були створені?


20

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

Приклад:

Скажімо, існувала функція гілки функції / make-coffee , і виправлення помилок продовжувалось на master паралельно гілці функції.

Історія може виглядати так:

*     merge feature/make-coffee
|\
| *   small bugfix
| |
* |    fix bug #1234
| |
| *    add milk and sugar
| |
* |    improve comments
| |
* |    fix bug #9434
| |
| *    make coffe (without milk or sugar)
| |
* |    improve comments
|/
*

Проблема

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

Навпаки, в Subversion це значно простіше, тому що назва гілки є частиною історії - тому я можу відразу сказати, що спочатку було зроблено зобов’язання щодо "функції / зробити каву".

Git може полегшити це, включивши ім'я поточної гілки у метадані фіксації під час створення комісії (разом із автором, датою тощо). Однак git цього не робить.

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


1
Пов'язаний питання: Finding якій гілці зробити прийшла . Йдеться про те, як знайти цю інформацію, незважаючи на те, що git явно не записує її.
sleske

1
Примітка для себе: Цікаво, що в Mercurial фіксація дійсно містить ім'я гілки. Тож, здається, Меркурійські розробники прийняли інше дизайнерське рішення, ніж гіт-деви. Детальніше дивіться, наприклад, felipec.wordpress.com/2012/05/26/… .
sleske

Відповіді:


14

Можливо, тому, що назви філій мають значення лише в одному сховищі. Якщо я в make-coffeeкоманді і подаю всі свої зміни через воротаря, моя masterгілка може потрапити до гілки воротаря make-coffee-gui, яку він об'єднає зі своєю make-coffee-backendгілкою, перш ніж перейти до гілки, яка об'єднається make-coffeeв центральну masterгілку.

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

Як нагадав CodeGnome, git має чітку філософію дизайну, щоб не вносити щось у дані, якщо це не потрібно. Очікується, що користувачі використовуватимуть параметри в git logта git diffвидавати дані на свій смак після факту. Я рекомендую спробувати декілька, поки ви не знайдете формат, який краще підійде для вас. git log --first-parentнаприклад, не відображатиметься комісій з об'єднання філії.


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

1
@JanHudec: Власне, це залежить :-). Якщо людина, яка виконує роботу, об'єднує її, то так. Якщо злиття відбудеться пізніше, можливо, після огляду, то більш ймовірно, що рецензент перевірив майстер і об'єднає галузь функції в головну, перевіряє її і натискає.
sleske

5

Відстеження історії філії с --no-ff

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

Команди Git не несуть інформацію про філії, оскільки вони не потрібні для історії Git. Однак злиття, які не є швидкими вперед, безумовно, можуть містити додаткову інформацію про те, яку галузь було об'єднано. Ви можете гарантувати, що ваша історія містить цю інформацію, завжди передаючи --no-ffпрапор у ваші злиття. git-merge (1) говорить:

   --no-ff
       Create a merge commit even when the merge resolves as a
       fast-forward. This is the default behaviour when merging an
       annotated (and possibly signed) tag.

Це, як правило, створює повідомлення про злиття, подібне до такого Merge branch 'foo', тому типово можна знайти інформацію про "гілки предків" за рядком, подібним до наступного:

$ git log --regexp-ignore-case --grep 'merge branch'

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

1
@sleske Я думаю, що моя відповідь була чуйною: Git не відстежує її, оскільки історія Git не потрібна; Я не думаю, що це стає більш принциповим, ніж це. Вам доведеться подивитися на джерело для конкретних даних, але історія ефективно обчислюється назад від кінця поточної гілки. Ви завжди можете порівнювати це з деякими іншими DVCS, які розглядають гілки як першокласні об'єкти і бачать, чи вам більше подобається ця філософія дизайну. YMMV.
CodeGnome

1
Останнє має бути git log --merges.
Dan

3

Найпростіша відповідь - назви гілок ефемерні. Що робити, якщо ви, скажімо, перейменували гілку ( git branch -m <oldname> <newname>)? Що буде з усіма домовленостями проти цієї галузі? Або що, якщо двоє людей мають відділення з однаковою назвою в різних локальних сховищах?

Єдине, що має значення в git, - це контрольна сума самої фіксації. Це основна одиниця відстеження.

Інформація є там, ви її просто не запитуєте, і її точно немає.

Git зберігає контрольну суму керівника кожного відділення в .git/refs/heads. Наприклад:

... /. git / refs / heads $ ls тест 
-rw-rw-r-- 1 michealt michealt 41 30 вересня 11:50 тест
... /. git / refs / heads $ тест на коти 
87111111111111111111111111111111111111d4

(так, я приховую свої контрольні суми git, це не особливе, але вони є приватними сховищами, на які я дивлюсь, що момент, у якому не потрібно, щоб щось випадково просочилося).

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

Зберігання там, де конкретно назва гілки (яка може змінюватися, як згадувалося вище) комісія, є самою коміттю, є додатковою витратою на коміт, яка не допомагає їй. Зберігати батьків (ів) зобов’язання та його користь.

Ви можете бачити гілки, виконавши команду журналу git з відповідним прапором.

git log --branches --source --pretty = oneline --graph
git log --all - джерело --pretty = oneline --graph

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

* 87111111111111111111111111111111111111d4 тест Злиття гілки 'test1' у тест
| \  
| * 42111111111111111111111111111111111111e8 test1 оновлення: додайте речі
* | dd11111111111111111111111111111111111159 тест Об’єднати гілку 'test3' у тест
| \ \  

Це "тест", "тест1" та "тест2" - це галузі, на які вони були зобов'язані.

Зауважте, що документація з журналу git величезна, і з неї цілком можна отримати майже все, що завгодно.


3

Чому git-комісії не містять назви гілки, на якій вони були створені?

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

Після катастрофи BitKeeper Лінус Торвальдс розробив git, щоб відповідати процесу розробки ядра Linux. Там, доки патч не буде прийнято, він переглядається, редагується, відшліфовується кілька разів (все через пошту), підписується (= редагує комісію), вибирає вишню, блукаючи до гілок лейтенанта, можливо, часто відновлюється, більше редагувань, вишня -кипи тощо, поки вони нарешті не злилися Лінусом.

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

Можливо, таке дизайнерське рішення трапилося випадково, але воно точно відповідає процесу розробки ядра Linux.


2

Тому що в Git такі об'єкти, як "зробити каву", вважаються частиною обох гілок, коли галузь функції об'єднується. Навіть є команда перевірити це:

% git branch --contains @
  feature/make-coffee
  master

Також гілки дешеві, місцеві та ефірні; їх можна легко додавати, видаляти, перейменовувати, натискати та видаляти з сервера.

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

Скажімо, я був у відділенні "майстер", і я зробив два прийоми: "приготувати каву" та "додати молоко та цукор", тоді я вирішую використовувати для цього нову гілку, тому я повернув "майстер" назад до "походження" / майстер '. Не проблема, вся історія все ще є чистою: "приготувати каву" та "додати молоко та цукор" не є частиною майстра, лише функція / приготування кави.

Меркуріал - навпаки; він не хоче змінювати речі. Гілки постійні, історія перезапису нахмурена, ви не можете просто видалити гілку з сервера.

Коротше кажучи: Git дозволяє вам робити все, Mercurial хоче полегшити справи (і робить це дуже важко дозволити вам робити те, що ви хочете).

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