-
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 команди
3.6 Клонове в Git - Управление на проект
Управление на проект
След като разгледахме как се допринася в проект по ефективен начин, вероятно ще ви интересува и обратната страна, как да поддържаме собствен такъв.
Това може да включва приемане и прилагане на пачове генерирани през format-patch
и изпратени до вас или пък интегриране на промени в отдалечени клонове за хранилища добавени като remotes към проекта ви.
Независимо дали поддържате canonical хранилище или искате да помогнете проверявайки и одобрявайки пачове, трябва да знаете как да приемате работа от колегите ви по начин ясен за тях и удобен за вас във времето.
Работа в Topic клонове
Когато мислите да интегрирате новополучени промени, добра идея е да ги изпробвате в topic клон — временен такъв създаден специално за теста.
По такъв начин е лесно да поправите пач индивидуално и да го зарежете, ако той не работи, докато имате време да го разгледате по-подробно.
Ако създадете клон с име съответстващо на темата на изпратената работа, например ruby_client
или нещо подобно, можете лесно да го запомните и по-късно да се върнете в него.
Поддръжникът на Git проекта например, дори се стреми да използва namespaces за тези имена — като sc/ruby_client
, където sc
е съкращение за човека, който е изпратил работата.
Както помним, създаването на клон базиран на master
се прави така:
$ git branch sc/ruby_client master
Или, ако искате да превключите към него веднага, може да използвате checkout -b
варианта:
$ git checkout -b sc/ruby_client master
Сега сте готови да добавите новата работа, която сте получили, в този нов topic клон и да решите дали искате да я слеете в long-term клоновете си.
Прилагане на пачове от Email
Ако сте получили пач по имейл, ще трябва да го приложите в topic клона и да го изпробвате.
Това се прави с помощта на една от двете команди git apply
или git am
.
Прилагане на пач с apply
Ако сте получили пача от някого, който го е генерирал с git diff
или някакъв вариант на Unix diff
инструмента (което не е препоръчително, вижте следващата секция), можете да го приложите с командата git apply
.
Ако сте записали пача в /tmp/patch-ruby-client.patch
:
$ git apply /tmp/patch-ruby-client.patch
Това модифицира файловете в работната директория.
Командата е почти идентична на patch -p1
, въпреки че е по-параноична и приема по-малко fuzzy matches от patch.
Тя също така обработва добавянето, изтриването и преименуването на файлове, ако тези процеси са правилно описани в git diff
формата, нещо което patch
няма да направи.
Освен това git apply
използва модела “apply all or abort all”, където или всичко се прилага успешно или нищо не се прилага. За разлика от нея, patch
може да прилага частично patchfiles, оставяйки работната ви директория в странен статус.
git apply
като цяло е много по-консервативна от patch
.
Процесът няма автоматично да ви направи къмит — след като завърши ще трябва сами да индексирате и къмитнете промените.
Можете също да използвате git apply
за да видите дали пачът ще се приложи коректно преди в действителност да се изпълни, командата е git apply --check
с името на пача:
$ git apply --check 0001-see-if-this-helps-the-gem.patch
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply
Ако няма изход, тогава пачът би следвало да се приложи чисто. В допълнение, командата завършва с код за грешка, ако проверката установи неуспех, така че можете да я използвате и в скриптове, ако желаете.
Прилагане на пач с am
Ако работата идва от напреднал Git потребител, който е наясно с format-patch
, тогава работата ви се улеснява, защото пачът ще съдържа също и информация за автора и къмит съобщение.
Ако можете, окуражавайте сътрудниците ви да използват format-patch
вместо diff
, когато генерират пачове за вас.
Използвайте git apply
само за legacy пачове и неща като това (diff
генерирани).
За да приложите пач генериран с format-patch
, по-добрият вариант е да използвате git am
(наречена е am
понеже се използва за "apply a series of patches from a mailbox").
Технически, git am
е проектирана да чете mbox файл, който е plain-text формат за съхранение на едно или повече имейл съобщения в един файл.
Изглежда по подобен начин:
From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
From: Jessica Smith <jessica@example.com>
Date: Sun, 6 Apr 2008 10:17:23 -0700
Subject: [PATCH 1/2] Add limit to log function
Limit log functionality to the first 20
Това е началото на изхода от командата git format-patch
, който видяхме в предната секция, също валиден mbox имейл формат.
Ако някой ви е изпратил пача по пощата коректно с git send-email
и го запишете в mbox формат, тогава можете да подадете на git am
въпросния mbox файл и тя ще започне да прилага всички пачове, които намери.
Ако имате имейл клиент способен да записва множество съобщения в mbox формат, тогава можете да запишете цялата серия пачове в един файл и след това да пуснете git am
, която да ги приложи последователно.
Обаче, ако някой е качил пач файл генериран с git format-patch
към ticketing система или нещо подобно, можете да запишете файла локално и след това да го подадете на git am
да го приложи:
$ git am 0001-limit-log-function.patch
Applying: Add limit to log function
Може да видите, че той се е приложил чисто и автоматично се създава нов къмит за вас.
Информацията за автора е взета от хедърите From
и Date
на имейла, а къмит съобщението от Subject
хедъра и тялото му (частта преди пача).
Например, ако този пач беше приложен от mbox примера отгоре, генерираният къмит би изглеждал така:
$ git log --pretty=fuller -1
commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0
Author: Jessica Smith <jessica@example.com>
AuthorDate: Sun Apr 6 10:17:23 2008 -0700
Commit: Scott Chacon <schacon@gmail.com>
CommitDate: Thu Apr 9 09:19:06 2009 -0700
Add limit to log function
Limit log functionality to the first 20
Commit
реда индикира кой е човекът, който е приложил пача и времето, когато това е станало.
Author
от своя страна носи информация за създателя на пача и кога е създаден първоначално.
Възможно е обаче пачът да не се прилага чисто.
Може главният ви клон да се е разделил твърде много от клона, от който е направен пача или пък самият пач да зависи от друг такъв, който все още не сте приложили.
В подобен случай git am
ще прекъсне и ще ви попита как искате да продължите:
$ git am 0001-see-if-this-helps-the-gem.patch
Applying: See if this helps the gem
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply
Patch failed at 0001.
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".
Командата поставя маркери за конфликт в съответните файлове, както това става при конфликтно сливане или пребазиране.
Разрешаването на конфликтите също е аналогично — редактирате файла, индексирате го и след това изпълнявате git am --resolved
за да продължите цикъла със следващия пач:
$ (fix the file)
$ git add ticgit.gemspec
$ git am --resolved
Applying: See if this helps the gem
Ако искате Git да се опита да разреши конфликта по малко по-интелигентен начин, може да подадете флага -3
и Git ще се опита да направи three-way сливане.
Тази опция е забранена по подразбиране, защото няма да работи в случай, че пачът рапортува, че е базиран на къмит, който не присъства в хранилището ви.
Ако обаче имате този къмит (ако пачът например е базиран на публичен такъв), тогава -3
опцията е много по-гъвкава в прилагането на конфликтен пач:
$ git am -3 0001-see-if-this-helps-the-gem.patch
Applying: See if this helps the gem
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.
В този случай, без -3
флага пачът щеше се счита за конфликтен.
Но понеже той е подаден, пачът се прилага чисто.
Ако прилагате множество от пачове от mbox, можете също така да пуснете am
командата в интерактивен режим, при което тя ще спира на всеки пач и ще ви пита дали желаете да го приложи:
$ git am -3 -i mbox
Commit Body is:
--------------------------
See if this helps the gem
--------------------------
Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all
Това е полезно при много пачове, защото можете да видите всеки от тях, ако сте забравили за какво е или да го откажете, ако вече е приложен.
Когато всички пачове са приложени и къмитнати в topic клона, може да изберете дали и кога да ги интегрирате в long-term клон.
Извличане от отделечени клонове
Работата на вашите колеги може и да не идва по имейл. Те могат да имат свои собствени онлайн хранилища, да са извършили много промени и да са ви пратили URL до хранилището и клона, където промените се пазят. В случаи като този, можете да добавите отдалечените хранилища и да сливате локално вместо да пачвате.
Ако Jessica ви съобщи, че има нова функционалност в клона ruby-client
на хранилището ѝ, можете да тествате бързо добавяйки го като remote референция и извличайки клона локално:
$ git remote add jessica git://github.com/jessica/myproject.git
$ git fetch jessica
$ git checkout -b rubyclient jessica/ruby-client
Ако впоследствие тя ви съобщи за нова функционалност в отделен клон, можете директно да направите fetch
и checkout
, защото вече отдалеченото хранилище е конфигурирано при вас.
Това е най-полезно, ако работите сравнително често с даден колега. Ако някой иска да ви изпрати само единичен пач и няма намерение за продължително сътрудничество, тогава имейл методът вероятно е по-бързо решение и няма нужда колегата ви да поддържа онлайн хранилище. Освен това едва ли бихте искали да имате стотици remotes, всяко от които допринася само с един-два пача. Обаче, скриптовете и хостнатите публични услуги могат да улеснят това — зависи най-вече от това как разработвате вие и как колегите ви.
Друго предимство на този подход е, че получавате историята на къмитите.
Въпреки, че може да имате merge проблеми, вие все пак знаете на коя точка от историята ви е базирана работата на колегата и правилното three-way сливане е по подразбиране вместо да трябва да подавате -3
и да се надявате, че пачът е бил генериран на публичен къмит, до който имате достъп.
Ако не работите често с определен колега, но въпреки това искате да получавате работата му по този начин, можете да подадете на git pull
директно адреса на отдалеченото хранилище.
По този начин правите one-time pull и не съхранявате URL-а като remote референция:
$ git pull https://github.com/onetimeguy/project
From https://github.com/onetimeguy/project
* branch HEAD -> FETCH_HEAD
Merge made by the 'recursive' strategy.
Изследване на промените
Сега имате topic клон с новата работа от колега. На този етап може да определите какво бихте искали да правите с нея. Тази секция преглежда няколко команди, които ви помагат да разберете какво точно ще бъде въведено в главния клон, ако решите да направите сливане на topic клона.
Често е полезно да имате представа за всички къмити, които са налични във временния клон, но все още не са в главния.
Можете да извадите къмитите в master
клона добавяйки опцията --not
преди името му.
Това прави същото като формата master..contrib
, който видяхме по-рано.
Например, ако вашият колега ви изпрати два пача и създадете клон contrib
, в който сте ги приложили, може да изпълните това:
$ git log contrib --not master
commit 5b6235bd297351589efc4d73316f0a68d484f118
Author: Scott Chacon <schacon@gmail.com>
Date: Fri Oct 24 09:53:59 2008 -0700
See if this helps the gem
commit 7482e0d16d04bea79d0dba8988cc78df655f16a0
Author: Scott Chacon <schacon@gmail.com>
Date: Mon Oct 22 19:38:36 2008 -0700
Update gemspec to hopefully work better
Ако ви трябват и промените, които въвежда всеки къмит, можете да подадете флага -p
към git log
и тя ще ви изведе в допълнение diff информацията за всеки от къмитите.
За да видите пълен diff на това какво ще се случи, ако слеете този topic клон с друг, може да се наложи да използвате малък трик, за да получите коректните резултати. Може би си мислите за това:
$ git diff master
Командата действително извежда diff, но той може да е заблуждаващ.
Ако master
клонът се е придвижил напред след като сте създали topic клона от него, тогава ще получите изглеждащи странно резултати.
Това се случва, защото Git директно сравнява snapshot-а на последния къмит от topic клона, в който сте и snapshot-а на най-новия къмит от master
клона.
Ако например сте добавили ред във файл от master
след създаването на topic клона, директното сравнение на snapshot-ите ще изглежда така сякаш при сливане topic клона ще изтрие този ред.
Ако master
е директен родител на topic клона това не е проблем. Но ако двете истории са се разклонили, тогава diff изходът ще показва, че добавяте всичките нови промени от topic и изтривате всичко уникално за master
клона.
Но това, което наистина искате да видите, са промените добавени в topic — работата, която ще бъде въведена при сливането му в master
.
Начинът да получите този резултат е да накарате Git да сравни последния къмит в topic клона с първия общ предшественик от master
.
Технически това може да направите като изрично установите кой е този предшественик и след това изпълните diff към него:
$ git merge-base contrib master
36c7dba2c95e6bbb78dfa822519ecfec6e1ca649
$ git diff 36c7db
или по-съкратено:
$ git diff $(git merge-base contrib master)
И понеже нито един от тези два начина не е достатъчно удобен, Git осигурява още едно съкратено изписване за същия резултат: triple-dot синтаксиса.
В контекста на командата git diff
, можете да поставите три точки между имената на два клона и тогава Git ще изпълни diff
между последния къмит на клона отдясно в израза (contrib) и най-актуалния му общ предшественик от клона вляво (master):
$ git diff master...contrib
Така получавате само работата, която текущия topic клон въвежда от последния общ родителски къмит в master
.
Това е един много полезен синтаксис и си заслужава да се запомни наизуст.
Интегриране на получена работа
Когато работата в topic клона е готова да бъде изпратена към един или няколко mainline клонове, възниква въпроса как да го направите. Дръг въпрос е какъв да е принципния работен процес, който да използвате за поддръжка на проекта си? Има множество варианти и ще разгледаме някои от тях.
Merging работни процеси
Един простичък процес за действие е просто да слеете цялата нова работа директно в master
клона.
В такъв сценарий се предполага, че имате master
клон, който съдържа стабилен код.
Когато получите промени в topic клон и смятате, че той е готов за интегриране или пък когато сте получили и проверили работата на колега, просто сливате нещата в master
клона, изтривате topic клона и това се повтаря във времето.
Например, ако имаме хранилище с работа в два клона, ruby_client
и php_client
, изглеждащи като в История с няколко topic клона и слеем ruby_client
последван от php_client
, историята накрая ще изглежда като След сливане на topic клон.
Вероятно това е най-простият работен процес, но може да бъде проблематичен, ако си имате работа с по-големи или по-стабилни проекти, където искате да сте много внимателни с това, което въвеждате като промени.
Ако проектът е особено важен, може да искате да използвате двустъпков цикъл на сливане.
При такъв сценарий, имате два long-running клона, master
и develop
, при които master
се обновява само, когато излезе много стабилна версия на проекта и промените преди това са интегрирани успешно в develop
.
И двата клона редовно се публикуват в публично хранилище.
Всеки път, когато имате нов topic клон за сливане (Преди сливане на topic клон), вие го сливате в develop
(След сливане на topic клон), след което тагвате нова версия и правите fast-forward на master
към мястото, където сега е стабилния develop
(След нова версия на проекта).
По такъв начин, когато някой клонира хранилището, може да извлече или master
и да компилира последната стабилна версия, или develop
, който съдържа най-пресните новости.
Можете допълнително да разширите тази концепция с отделен integrate
клон, където цялата работа е слята заедно.
След това, когато кодът в него е стабилен и преминава тестовете, го сливате в develop
клона и ако времето покаже, че и той е наистина надежден, правите fast-forward на master
.
Large-Merging работни процеси
Проектът Git има четири long-running клона: master
, next
, и seen
(преди това известен като 'pu' — proposed updates) за нови промени, и maint
за maintenance backports.
Когато сътрудниците изпратят нова работа, тя се събира в topic клонове в хранилище на поддържащия проекта в маниер подобен на този, който описахме (вижте Управление на сложни серии от parallel contributed topic клонове.).
В този момент, topic клоновете се изпитват, за да се определи дали са безопасни и готови за използване или трябва да се поправят допълнително.
Ако са добре, те се сливат в next
и този клон се публикува, така че всички могат да изпробват новите промени както са интегрирани заедно.
Ако промените не са задоволителни, те вместо това се сливат в клона seen
.
Когато се установи, че са окончателно надеждни, промените биват интегрирани в master
.
След това next
и seen
се построяват отново от master
.
Това значи, че master
винаги се мести напред, next
от време на време се пребазира, а seen
се пребазира още по-често:
Когато даден topic клон най-сетне се слее в master
, той се изтрива от хранилището.
Проектът Git също има и клон maint
, който се прави от последната версия за да осигури backported пачове в случай, че се изисква maintenance release.
Така при клониране на Git хранилището, имате четири клона, които може да използвате за да пробвате проекта в различните му състояния на разработка, в зависимост от това колко актуален искате да бъде или как искате да допринасяте към него. А поддържащият проекта има структуриран работен процес за управление на новите промени.
Все пак, Git проектът е със специализиран работен процес.
За да го разберете напълно, можете да погледнете Git Maintainer’s guide.
Rebasing и Cherry-Picking работни процеси
Други мениджъри на проекти предпочитат да пребазират или cherry-pick-ват нови промени на базата на master
клона си, вместо да ги сливат. Целта е да поддържат почти линейна история.
Ако се установи, че промените в topic клона са подходящи за интегриране, превключвате към него и изпълнявате rebase командата, за да възпроизведете промените на базата на текущия master
клон (или от develop
и т.н.).
Ако това работи добре, можете да направите fast-forward на master
клона и да запазите линейната история на проекта.
Другият начин да преместите нова работа от един клон в друг е да я cherry-pick-нете. Процесът cherry-pick в Git е подобен на rebase за единичен къмит. Той взема пача, който е бил въведен в даден къмит и се опитва да го приложи повторно в текущия клон. Това е полезно, ако имате множество къмити в topic клон и искате да интегрирате само един от тях или ако къмитът е само един, но предпочитате да не изпълнявате rebase. Да кажем, че имате проект изглеждащ така:
Ако искате да издърпате къмита e43a6
в master
клона, можете да направите следното:
$ git cherry-pick e43a6
Finished one cherry-pick.
[master]: created a0a41a9: "More friendly message when locking the index fails."
3 files changed, 17 insertions(+), 3 deletions(-)
Това въвежда същата промяна от e43a6
, но получавате нов SHA-1 хеш за къмита, защото приложената дата е различна.
Сега историята изглежда така:
Сега можете да премахнете topic клона и да изоставите къмитите, които не желаете да въвеждате.
Rerere
Ако ви се налага да правите често сливания и пребазирания или ако поддържате topic клон с по-дълъг живот, Git предлага във ваша услуга опцията известна като “rerere”.
Терминът Rerere идва от “reuse recorded resolution” — това е начин за бързо прилагане на ръчно разрешаване на конфликти. Когато rerere е активна, Git ще съхранява набор от pre- и post-images от успешни сливания и ако установи, че е налице конфликт, който изглежда подобен на такъв, който е бил разрешен в миналото, автоматично ще използва записания начин за разрешаването му без да ви занимава с него.
Тази функционалност идва в две части: конфигурационна настройка и команда.
Настройката е rerere.enabled
и е достатъчно да имате следното в глобалната конфигурация:
$ git config --global rerere.enabled true
Сега след като направите ръчно разрешаване на конфликт, резолюцията ще бъде запомнена в кеша и ще бъде използвана в бъдеще.
Ако е необходимо, може да комуникирате с rerere кеша с командата git rerere
.
Когато тя се използва самостоятелно, Git проверява базата си данни с решения за конфликти и се опитва да намери съответствие (въпреки, че това се прави автоматично, ако rerere.enabled
е true
).
Също така има подкоманди за разглеждане на това какво ще се запише, за изтриване на конкретна резолюция от кеша и за изтриване на целия кеш.
Ще разгледаме детайлно rerere в Rerere.
Тагване на версии
Ако сте решили да обявите стабилна версия на проекта, вероятно бихте желали да присъедините таг към нея, така че ако се налага по-късно да можете да я пресъздадете отново. Как да създадете таг видяхме в Основи на Git. Ако решите и да подпишете тага, тогава командата може да изглежда така:
$ git tag -s v1.5 -m 'my signed 1.5 tag'
You need a passphrase to unlock the secret key for
user: "Scott Chacon <schacon@gmail.com>"
1024-bit DSA key, ID F721C45A, created 2009-02-09
Ако правите подписване, може да се наложи да се погрижите за евентуални проблеми свързани с разпространението на публичния PGP ключ, който се използва в процеса.
Поддържащият проекта на Git е решил това включвайки публичния си ключ директно като blob в хранилището и добавяйки таг, който сочи към него.
За да направите и вие нещо подобно, може да установите кой е желания ключ изпълнявайки gpg --list-keys
:
$ gpg --list-keys
/Users/schacon/.gnupg/pubring.gpg
---------------------------------
pub 1024D/F721C45A 2009-02-09 [expires: 2010-02-09]
uid Scott Chacon <schacon@gmail.com>
sub 2048g/45D02282 2009-02-09 [expires: 2010-02-09]
След това можете директно да импортирате ключа в базата данни на Git като го експортирате и прекарате през git hash-object
, което ще създаде и запише нов blob обект със съдържанието в Git и ще ви върне обратно SHA-1 хеша му:
$ gpg -a --export F721C45A | git hash-object -w --stdin
659ef797d181633c87ec71ac3f9ba29fe5775b92
След като вече имате съдържанието на ключа в Git, можете да създадете таг, който сочи директно към него посредством въпросната SHA-1 стойност:
$ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92
Ако изпълните git push --tags
, тогава тагът maintainer-pgp-pub
ще бъде публикуван и споделен с всички останали.
Ако някой от колегите ви желае да провери таг, може директно да извлече вашия PGP ключ като издърпа blob обекта от базата данни и го импортира в PGP:
$ git show maintainer-pgp-pub | gpg --import
Впоследствие този ключ може да се използва за проверка на всички подписани от вас тагове.
Също така, в таг съобщението може да включите инструкции за това как да се проверява тага и всеки би могъл да ги прочете изпълнявайки git show <tag>
.
Генериране на номера на версии
Git не увеличава монотонно числата в стил 'v123' или нещо подобно с всеки къмит. Ето защо, ако искате да имате нещо описателно с къмитите, бихте могли да изпълните git describe
върху съответните къмити.
В отговор, Git генерира стринг състоящ се от името на последния таг, който е по-ранен от този къмит, последвано от броя къмити след този таг и от частичната SHA-1 стойност на описвания къмит (добавя се и префиксът "g", означаващ Git):
$ git describe master
v1.6.2-rc1-20-g8c5b85c
Така можете да експортирате snapshot или компилирана версия и да я именувате с разбираемо за хората описание.
В действителност, ако компилирате Git от изходен код клониран от Git хранилището, git --version
ще ви връща нещо като горното.
Ако описвате къмит, който е бил тагнат директно, ще получите просто името на тага.
Командата git describe
по подразбиране изисква анотирани тагове (тези създадени с флаговете -a
или -s
). Ако искате да се възползвате от lightweight (не-анотирани) такива, подайте ѝ опцията --tags
.
Може да използвате този стринг с командите git checkout
или git show
, въпреки че това зависи от SHA-1 стойността в края и може да не е валидно завинаги.
Например, Linux kernel проекта напоследък премина от 8 на 10 символа за да гарантира SHA-1 уникалността на обектите и по този начин по-старите git describe
изходни имена станаха невалидни.
Подготовка за издаване на Release
Допускаме, че искате да публикувате готова версия на продукта.
Едно от нещата, които ще се наложи да направите, е да генерирате архив на най-новия snapshot за потребителите, които не ползват Git.
Командата за това е git archive
:
$ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz
$ ls *.tar.gz
v1.6.2-rc1-20-g8c5b85c.tar.gz
Ако някой отвори този tarball ще получи актуалния snapshot на проекта ви в директория project
.
Можете също да съдадете zip архив по подобен начин, подавайки --format=zip
опцията към git archive
:
$ git archive master --prefix='project/' --format=zip > `git describe master`.zip
Сега имате tarball и zip версии на проекта, които можете да качите в уебсайт или да изпратите по имейла.
Shortlog
Време е да информирате хората от мейлинг листата ви за промените в проекта ви.
Един удобен начин да получите бързо changelog на добавеното в проекта от последния път, когато сте изпратили известие, е командата git shortlog
.
Тя резюмира всички къмити в подадения ѝ обхват. Например, следното ще ви изведе обобщение на всички къмити от последния release насам, ако този release е бил наречен v1.0.1:
$ git shortlog --no-merges master --not v1.0.1
Chris Wanstrath (6):
Add support for annotated tags to Grit::Tag
Add packed-refs annotated tag support.
Add Grit::Commit#to_patch
Update version and History.txt
Remove stray `puts`
Make ls_tree ignore nils
Tom Preston-Werner (4):
fix dates in history
dynamic version method
Version bump to 1.0.2
Regenerated gemspec for version 1.0.2
Както се вижда, получавате доклад за всички къмити от v1.0.1 групирани по автор и можете да го изпратите на когото трябва.