-
1. Начало
- 1.1 За Version Control системите
- 1.2 Кратка история на Git
- 1.3 Какво е Git
- 1.4 Конзолата на Git
- 1.5 Инсталиране на Git
- 1.6 Първоначална настройка на Git
- 1.7 Помощна информация в Git
- 1.8 Обобщение
-
2. Основи на Git
-
3. Клонове в Git
-
4. GitHub
-
5. Git инструменти
- 5.1 Избор на къмити
- 5.2 Интерактивно индексиране
- 5.3 Stashing и Cleaning
- 5.4 Подписване на вашата работа
- 5.5 Търсене
- 5.6 Манипулация на историята
- 5.7 Мистерията на командата Reset
- 5.8 Сливане за напреднали
- 5.9 Rerere
- 5.10 Дебъгване с Git
- 5.11 Подмодули
- 5.12 Пакети в Git (Bundling)
- 5.13 Заместване
- 5.14 Credential Storage система
- 5.15 Обобщение
-
6. Настройване на Git
- 6.1 Git конфигурации
- 6.2 Git атрибути
- 6.3 Git Hooks
- 6.4 Примерна Git-Enforced политика
- 6.5 Обобщение
-
7. Git и други системи
- 7.1 Git като клиент
- 7.2 Миграция към Git
- 7.3 Обобщение
-
8. Git на ниско ниво
- 8.1 Plumbing и Porcelain команди
- 8.2 Git обекти
- 8.3 Git референции
- 8.4 Packfiles
- 8.5 Refspec спецификации
- 8.6 Транспортни протоколи
- 8.7 Поддръжка и възстановяване на данни
- 8.8 Environment променливи
- 8.9 Обобщение
-
9. Приложение A: Git в други среди
-
10. Приложение B: Вграждане на Git в приложения
- 10.1 Git от команден ред
- 10.2 Libgit2
- 10.3 JGit
- 10.4 go-git
- 10.5 Dulwich
-
A1. Приложение C: Git команди
- A1.1 Настройки и конфигурация
- A1.2 Издърпване и създаване на проекти
- A1.3 Snapshotting
- A1.4 Клонове и сливане
- A1.5 Споделяне и обновяване на проекти
- A1.6 Инспекция и сравнение
- A1.7 Дебъгване
- A1.8 Patching
- A1.9 Email команди
- A1.10 Външни системи
- A1.11 Административни команди
- A1.12 Plumbing команди
8.3 Git на ниско ниво - Git референции
Git референции
Ако искате да видите историята на хранилището си достъпна през къмит 1a410e
например, може да изпълните нещо като git log 1a410e
, но все пак трябва да сте запомнили, че именно 1a410e
е къмитът, който ви интересува.
Вместо това, би било по-лесно ако имахте файл, в който да съхраните тази SHA-1 стойност под някакво смислено име и след това да използвате това име като изходна точка.
В Git тези опростени имена се наричат “references” или просто “refs” и може да намерите файловете, които ги съхраняват в директорията .git/refs
.
В текущия ни проект тази директория не съдържа файлове, но съдържа проста структура:
$ find .git/refs
.git/refs
.git/refs/heads
.git/refs/tags
$ find .git/refs -type f
За да създадете проста референция, може да направите това:
$ echo 1a410efbd13591db07496601ebc7a059dd55cfe9 > .git/refs/heads/master
Сега можете да използвате head референцията, която току що създадохте вместо SHA-1 стойността в Git командите:
$ git log --pretty=oneline master
1a410efbd13591db07496601ebc7a059dd55cfe9 Third commit
cac0cab538b970a37ea1e769cbbde608743bc96d Second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d First commit
Не се препоръчва тези файлове да бъдат редактирани ръчно, вместо това Git предоставя по-безопасната команда git update-ref
:
$ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
Това в общи линии е един клон в Git: прост указател към head на линия работа. За да създадете клон от втория къмит:
$ git update-ref refs/heads/test cac0ca
Този клон сега ще съдържа само работата от този къмит назад:
$ git log --pretty=oneline test
cac0cab538b970a37ea1e769cbbde608743bc96d Second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d First commit
Сега Git базата данни концептуално изглежда така:
Когато изпълнявате команда като git branch <branch>
, Git всъщност изпълнява update-ref
за да добави SHA-1 чексумата на последния къмит на текущия клон в референцията, която искате да създадете.
HEAD
Сега изниква въпроса как при изпълнение на git branch <branch>
Git знае коя е SHA-1 стойността на последния къмит?
Отговорът е файла HEAD.
HEAD файлът е symbolic референция към текущия клон. Под symbolic референция се има предвид, че за разлика от нормалните референции, тя не съдържа SHA-1 стойност, а вместо това указател към друга референция.
В някои редки случаи обаче, HEAD файлът все пак може да съдържа SHA-1 стойност на git обект. Това се случва при извличане на таг, къмит или отдалечен клон, при което хранилището ви попада в "detached HEAD" състояние.
Ако погледнете файла, обикновено виждате нещо такова:
$ cat .git/HEAD
ref: refs/heads/master
Ако изпълним git checkout test
, Git обновява файла така:
$ cat .git/HEAD
ref: refs/heads/test
При изпълнение на git commit
се създава къмит обект и се указва, че родителят на този къмит обект съответства на SHA-1 стойността, към която сочи референцията в HEAD.
Можете и ръчно да редактирате този файл, но и тук съществува по-безопасна алтернатива под формата на командата git symbolic-ref
.
Можете да прочетете стойността на HEAD така:
$ git symbolic-ref HEAD
refs/heads/master
Със същата команда можете и да я промените:
$ git symbolic-ref HEAD refs/heads/test
$ cat .git/HEAD
ref: refs/heads/test
Не можете да направите symbolic референция извън стила на refs:
$ git symbolic-ref HEAD test
fatal: Refusing to point HEAD outside of refs/
Тагове
Току що разгледахме трите основни обектни типа в Git (blobs, trees и commits), но има и още един. Обектът tag е много подобен на commit обекта — съдържа информация за човека създал тага, дата, указател и съобщение. Основната разлика е, че таг обекта сочи към къмит, вместо към дърво. Това е подобно на branch референция, но никога не се премества — винаги сочи към един и същи къмит, но му дава по-информативно име.
Както видяхме в Основи на Git, има два вида тагове: annotated и lightweight. Можете да направите lightweight таг така:
$ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d
Това е lightweight тагът — референция, която не се мести.
Annotated таговете, обаче, са малко по-сложни.
Ако създадете annotated таг, Git създава таг обект и след това създава референция сочеща към него, вместо директно към къмита.
Може да видите това създавайки annotated таг (с опцията -a
):
$ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'Test tag'
Ето SHA-1 стойността на създадения обект:
$ cat .git/refs/tags/v1.1
9585191f37f7b0fb9444f35a9bf50de191beadc2
Сега, изпълнете git cat-file -p
върху тази стойност:
$ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
object 1a410efbd13591db07496601ebc7a059dd55cfe9
type commit
tag v1.1
tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700
Test tag
Отбележете как реда object сочи към SHA-1 стойността на къмита, който беше тагнат. Също така отбележете, че не е необходимо да сочи към къмит, можете да тагвате всеки Git обект. В сорс кода на Git например, поддържащият проекта разработчик е добавил своя GPG public key като blob обект и след това го е тагнал. Можете да видите публичния ключ изпълнявайки следното в клонирано хранилище:
$ git cat-file blob junio-gpg-pub
В хранилището на Linux ядрото също има таг обект, който не сочи към къмит — първият създаден таг сочи към първоначалното дърво на импорта на сорс кода.
Remotes
Третият тип референции са remote референциите.
Ако добавите remote и публикувате към него, Git записва последната публикувана стойност за всеки клон в директорията refs/remotes
.
Можете да добавите remote origin
и да публикувате master
клона в него:
$ git remote add origin git@github.com:schacon/simplegit-progit.git
$ git push origin master
Counting objects: 11, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 716 bytes, done.
Total 7 (delta 2), reused 4 (delta 1)
To git@github.com:schacon/simplegit-progit.git
a11bef0..ca82a6d master -> master
След това, можете да видите стойността за master
клона в отдалечената origin
референция последния път, когато сте комуникирали със сървъра във файла refs/remotes/origin/master
:
$ cat .git/refs/remotes/origin/master
ca82a6dff817ec66f44342007202690a93763949
Remote референциите се отличават от клоновете (refs/heads
референциите) основно по това, че се третират като read-only.
Можете да изпълните git checkout
към такава референция, но Git няма да насочи HEAD към нея, така че никога няма да я обновите с commit
команда.
Git ги управлява като bookmarks към последния известен статус на клоновете им в съответните сървъри.