Чи видалення гілки в git видаляє її з історії?


190

Походить зі svn, тільки починає знайомитися з git.

Коли гілку видаляють у git, чи її видаляють з історії?

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

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

Відповіді:


251

Гілки - це лише вказівки на здійснення в git. У git кожен фільтр має повне дерево-джерело, це зовсім інша структура від svn, де всі гілки та теги (за умовою) живуть в окремих "папках" сховища поряд зі спеціальним "стволом".

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

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

Коміти все ще зберігатимуться у сховищі, і їх можна відновити відразу після видалення, але з часом вони будуть зібрані сміття.


3
Дякую за відповідь. Чи можете ви пояснити, що ви маєте на увазі під "кожним комітом має повне дерево джерела"? Як я розумію, кожне введення в git - це набір дельт, що посилаються на батьківський комітет, а не на ціле дерево.
Кен Лю

2
@Ken Liu: Комісія містить вказівники на нуль або більше батьківських комітетів, деревооб'єкт та деякі метадані про коміти. Таким чином, команда однозначно ідентифікує як пару вихідних дерев, так і, якщо дивитися на його батьків (и), зміни, які він вніс.
CB Bailey

9
@Ken Liu: Це залежить від того, що саме було у вас "містити", але так, по суті, кожен комітет містить повне дерево. У об'єктній базі даних об’єкти індексуються id, тому об'єкти діляться між усіма об'єктами (деревами та комісіями), на які посилаються, тому накладні накладні сховища не такі погані, як це спочатку звучить. git також має ефективну оптимізацію пам’яті (пакує файли), що дозволяє ще більш ефективно використовувати простір на диску.
CB Bailey

22
"зрештою вони будуть зібрані сміття" - Зрештою, коли?
BadHorsie

7
@BadHorsie, це залежить .
AliOli

86

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

Зауважте, що git branch -dвідмовитись у видаленні гілки, якщо вона не може бути впевнена, що її видалення не залишить недоступних зобов'язань. Вам потрібно використовувати сильніший, git branch -Dщоб примусити видалити гілку, якщо це може залишити недоступні коміти.

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

---- O ---- * ---- * ---- / M ---- * <- майстер <- ГОЛОВА
     \ /
      \ -. ---- .-- / - x --- y <- видалена гілка

лише фіксує "x" і "y" стане недосяжним після видалення гілки.

Якщо ви працювали над видаленою гілкою протягом gc.reflogExpireперіоду, за замовчуванням 90 днів, у вас буде остання порада видаленої гілки, записана в рефлозі HEAD (див. git reflog show HEADАбо git log --oneline --walk-reflogs HEAD). Ви повинні мати змогу використовувати регламент HEAD для відновлення видаленого вказівника. Зауважте також, що в цьому випадку недосяжні зобов’язання лише у видаленій гілці захищатимуться б від обрізки (видалення) протягом gc.reflogExpireUnreachableперіоду, який за замовчуванням становить 30 днів.

Якщо ви не можете знайти підказку щойно видаленої гілки в рефлозі для HEAD, ви можете спробувати скористатися, git fsckщоб знайти "недоступний фіксатор <sha1>", і вивчити їх (через git show <sha1>або git log <sha1>), щоб знайти кінчик видаленої гілки.

Незалежно від того, як ви знайдете кінчик видаленої гілки, ви можете скасувати видалення або, скоріше, заново створити щойно видалену гілку за допомогою

git branch <deleted-branch> <found-sha1-id>

Зауважте, що рефлог для філії буде втрачено.


Існує також скрипт git-resurrect.sh, в contrib/якому допомагає знайти сліди кінчика гілки з вказаним іменем та воскресити (відновити).


1
Дивовижно! git reflog show HEADперерахував комісію, і я створив нову гілку так само, як ви сказали, ідеально.
Стівен Альмерот

2

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

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