Конфузний біт тут:
Git ніколи не сприймає їх як окремі файли. Гіт вважає все повноцінним змістом.
Git часто використовує 160-бітові хеші на місці об'єктів у власній репо-репортажі. Дерево файлів - це в основному список імен та хешей, пов’язаних із вмістом кожного (плюс деякі метадані).
Але 160-бітний хеш однозначно ідентифікує вміст (всередині бази даних git). Отже дерево з хешами як вміст включає вміст у своєму стані.
Якщо ви зміните стан вмісту файлу, його хеш зміниться. Але якщо його хеш змінюється, змінюється і хеш, пов’язаний із вмістом імені файлу. Що в свою чергу змінює хеш "дерева каталогів".
Коли база даних git зберігає дерево каталогів, це дерево каталогів має на увазі і включає весь вміст усіх підкаталогів та всіх файлів у ньому .
Він організований у структурі дерева з (непорушними, багаторазовими) покажчиками на цвітіння чи інші дерева, але логічно це єдиний знімок всього вмісту всього дерева. Подання в базі даних мерзотника не плоский зміст даних, але логічно це все його дані і нічого іншого.
Якщо ви серіалізували дерево у файловій системі, видалили всі .git папки та наказали git додати дерево назад у свою базу даних, ви б у кінцевому підсумку нічого не додавали до бази даних - елемент уже був би там.
Це може допомогти розглянути хитові хеші як посилання, що зараховується до незмінних даних.
Якщо ви створили додаток навколо цього, документ являє собою купу сторінок, які мають шари, групи, які мають об'єкти.
Коли ви хочете змінити об'єкт, ви повинні створити для нього абсолютно нову групу. Якщо ви хочете змінити групу, вам потрібно створити новий шар, для чого потрібна нова сторінка, для чого потрібен новий документ.
Кожен раз, коли ви змінюєте один об'єкт, він породжує новий документ. Старий документ продовжує існувати. Новий і старий документ поділяють більшу частину свого вмісту - вони мають однакові сторінки (крім 1). На одній сторінці є однакові шари (крім 1). Цей шар має ті самі групи (крім 1). Ця група має однакові об'єкти (крім 1).
І тим самим я маю на увазі логічно копію, але в міру реалізації це просто ще один посилання, що зараховується вказівником на той самий незмінний об'єкт.
Git repo - багато подібного.
Це означає, що заданий набір змін git містить своє повідомлення фіксації (як хеш-код), воно містить його робоче дерево, а також його батьківські зміни.
Ці батьківські зміни містять зміни батьківських змін, все назад.
Частина git repo, яка містить історію, - це ланцюжок змін. Цей ланцюжок змінює його на рівні вище дерева "каталогу" - з дерева "каталогу" ви не можете однозначно дістатися до набору змін та ланцюга змін.
Щоб дізнатися, що відбувається з файлом, ви починаєте з цього файлу в наборі змін. Цей набір змін має свою історію. Часто в цій історії існує один і той же названий файл, іноді з тим самим вмістом. Якщо вміст однаковий, файл не змінився. Якщо це інакше, є зміни, і потрібно зробити роботу, щоб вирішити саме те, що.
Іноді файл відсутній; але у дерева "каталогу" може бути інший файл з тим самим вмістом (той самий хеш-код), тому ми можемо відстежувати його таким чином (зверніть увагу; саме тому ви хочете перенести файл окремо від "виконувати" -edit). Або те саме ім'я файлу, і після перевірки файл досить схожий.
Таким чином, git може скріплювати "історію файлів".
Але ця історія файлів походить від ефективного розбору "всього набору змін", а не від посилання однієї версії файлу на іншу.