Pro Git

Предговор от Скот Чейкън

Добре дошли във второто издание на Pro Git. Първото издание бе публикувано преди повече от четири години. (Второто издание се появява през 2014 – бел. прев.) Оттогава много неща се промениха, но и много важни неща са си същите. Повечето от вградените команди могат да се ползват по същия начин и днес, тъй като основният екип от разработчици на Гит върши чудесна работа по обратната съвместимост. Същевременно се появиха много добавки и промени в общността около Гит. Второто издание на тази книга засяга тези промени и обновява съдържанието, така че книгата да бъде по-полезна за начинаещия потребител.

Когато писах първото издание, Гит бе все още сравнително трудна за използване и приета само в някои "по-хакерски" среди. Тя започна да става по-известна в някои общности, но все още далеч от днешната си вездесъщност. Постепенно почти всеки проект с отворен код започна да я ползва. Гит постигна невероятен успех под Windows. Наблюдаваме бум от графични интерфейси за нея на всички платформи. Почти всяка развойна среда (IDE) вече предлага поддръжка за Гит. Почти всеки бизнес ползва Гит. Pro Git отпреди четири години не познаваше тази действителност. Една от главните цели на това ново издание е да засегнем всички тези нови достижения.

Общността на отворения код също се разрасна неимоверно. Когато седнах да пиша книгата преди почти пет години (отне ми известно време, докато пусна първото издание), тъкмо бях започнал работа в малка, никому неизвестна компания, която разработваше сайт за хостване на Гит-хранилища, наречена GitHub (ГитХъб). По време на публикуването имахме само няколко хиляди потребителя и по сайта работехме само четирима души. Сега, докато пиша това въведение, GitHub обявява десетмилионния хостван проект с около пет милиона потребителски сметки за разработчици. Служителите ни са двеста и тридесет. Без значение дали това ви харесва, GitHub промени общността на отворения код по начин, който никой не можеше да си представи, когато пишех първото издание.

В първото издание на книгата посветих малка част от една глава на GitHub, като пример за хостван Гит. Все се чувствах неудобно от това. Не ми харесваше особено, че пиша книга, която смятам за източник на знания от и за общността, и в нея пиша за компанията, в която работя. Макар все още да не харесвам този конфликт на интереси, значението на GitHub в общността на Гит е очевидно. Вместо само да споменавам GitHub, реших да превърна тази част от книгата в по-задълбочено описание на GitHub като услуга и как да се ползва ефективно. Ако ще се учите как да ползвате Гит, то знанието как се ползва GitHub ще ви помогне да станете част от тази огромна общност. Това е ценно, независимо кой Гит хостинг доставчик решите да ползвате за кода си.

Другата голяма промяна от времето на първото издание до сега бе разработката и навлизането на HTTP протокола за мрежови транзакции на Гит. Повечето от примерите бяха променени вместо SSH да ползват HTTP, понеже е толкова по-прост.

Невероятно бе да се наблюдава през последните години как Гит израства от сравнително неясно средство за управление на версиите до доминираща комерсиална и с отворен код система. Щастлив съм, че Pro Git се представи толкова добре, че се превърна в една от малкото книги с техническа насоченост на пазара, едновременно успешна и с отворен код.

Надявам се да харесате това обновено издание на Pro Git.

Предговор от Бен Строб

Първото издание на тази книга ме спечели за Гит. Въведе ме в начин на правене на софтуер, по-естествен от всичко, което бях виждал. По онова време вече се занимавах с програмиране от няколко години, и тази книга се оказа повратна за мен. Тя ме насочи към по-интересен път на развитие.

Сега, години по-късно, помагам в една голяма реализация на Гит, работил съм в най-голямата компания за хостинг на Гит проекти и съм пътувал по света да преподавам уроци как се ползва Гит. Когато Скот ме попита дали искам да работя по второто издание, дори не се замислих.

За мен бе удоволствие и привилегия да работя по тази книга. Надявам се да ви помогне, както помогна и на мен.

Предговор към българското издание

Някъде през 2001-ва май беше, на едно изложение по информационни технологии разглеждахме щандовете с шефа ми. Лепнах се на един щанд за книги. Не знам колко време съм стоял, но чух шефа да ме пита: "Искаш ли я?".

Отговорих "Да! Искам книгата!" Бях щастлив, че мога да науча нещо толкова непонятно на пръв поглед на моя роден език. Трябваше поне горе-долу да знам как работи един сайт. В книгата имаше глави "Въведение в CGI" и "Perl и Бази Данни" – доколкото разбирах тогава, все неща, свързани по някакъв начин с работата на сайта.

Ако мислиш с непонятни за тебе думи, как ще разбираш какво правиш?

Ако трябваше първо да учим английски, само за да се научим да програмираме – зле. Тогава отродяването е много вероятно. Както е било при католическите свещеници. Слава Богу, Св. Св. Кирил и Методий са се погрижили за нас. Дали са ни четмо и писмо, да можем да познаем Бог и да не се погубим.

Днес бих се радвал да си помогнем да бъдем самостоятелни занаятчии, да не оставаме безроден обслужващ персонал в транснационални комании някъде по света. Да не презираме наследството си за паница леща, както сторил Исав. С превода на тази книга се стремя към това.

Хранилището на превода се намира на адрес https://github.com/kberov/progit2-bg. Помогнете за превода както можете. Клонирайте хранилището и прочете препоръките. Преведете някоя глава, поправете грешки в правописа и препинателните знаци на вече преведеното. Готово копие на текущия превод може да намерите на http://i-can.eu/progit2-bg/progit.html. Когато цялата книга е преведена, ще я преместим на https://git-scm.com/book/bg/v2, където ѝ е мястото.

Гит е вездесъща система за управление на версиите. Владеенето ѝ те прави по-добър програмист. Книгата Pro Git дава почти всички необходими знания. Преведох я, за да се усвоят знанията без посредник. За да се разбира за какво иде реч.

Красимир Беров

Посвещения

На жена ми Беки, без която това приключение не би започнало никога. – Бен

Това издание е посветено на моите момичета. На жена ми Джесика, която ме подкрепяше през всичките тези години, и на дъщеря ми Жозефин, която ще ми помага, когато остарея дотолкова, че няма да знам къде се намирам. – Скот

На всички българи, които предпочитат да мислят на родния си език. – Краси Беров

Сътрудници

Тъй като това е книга с отворен код, получихме забележки и предложения за промeни през годините. Тук са споменати всички хора, допринесли за английската версия на Pro Git. Благодарим на всички, които помогнаха това да стане една по-добра книга за всички.

 2  Aaron Schumacher
 4  Aggelos Orfanakos
 4  Alec Clews
 1  Alex Moundalexis
 2  Alexander Harkness
 1  Alexander Kahn
 1  Andrew McCarthy
 1  AntonioK
 1  Benjamin Bergman
 1  Brennon Bortz
 2  Brian P O'Rourke
 1  Bryan Goines
 1  Cameron Wright
 1  Chris Down
 1  Christian Kluge
 1  Christoph Korn
 2  Ciro Santilli
 2  Cor
 1  Dan Croak
 1  Dan Johnson
 1  Daniel Kay
 2  Daniel Rosen
 1  DanielWeber
 1  Dave Dash
10  Davide Fiorentino lo Regio
 2  Dilip M
 1  Dimitar Bonev
 1  Emmanuel Trillaud
 1  Eric-Paul Lecluse
 1  Eugene Serkin
 1  Fernando Dobladez
 2  Gordon McCreight
 1  Helmut K. C. Tessarek
31  Igor Murzov
 1  Ilya Kuznetsov
 1  Jason St. John
 1  Jay Taggart
 1  Jean Jordaan
51  Jean-Noël Avila
 1  Jean-Noël Rouvignac
 1  Jed Hartman
 1  Jeffrey Forman
 1  John DeStefano
 1  Junior
 1  Kieran Spear
 1  Larry Shatzer, Jr
 1  Linquize
 1  Markus
 7  Matt Deacalion Stevens
 1  Matthew McCullough
 1  Matthieu Moy
 1  Max F. Albrecht
 1  Michael Schneider
 8  Mike D. Smith
 1  Mike Limansky
 1  Olivier Trichet
 1  Ondrej Novy
 6  Ori Avtalion
 1  Paul Baumgart
 1  Peter Vojtek
 1  Philipp Kempgen
 2  Philippe Lhoste
 1  PowerKiKi
 1  Radek Simko
 1  Rasmus Abrahamsen
 1  Reinhard Holler
 1  Ross Light
 1  Ryuichi Okumura
 1  Sebastian Wiesinger
 1  Severyn Kozak
 1  Shane
 2  Shannen
 8  Sitaram Chamarty
 5  Soon Van
 4  Sven Axelsson
 2  Tim Court
 1  Tuomas Suutari
 1  Vlad Gorodetsky
 3  W. Trevor King
 1  Wyatt Carss
 1  Włodzimierz Gajda
 1  Xue Fuqiao
 1  Yue Lin Ho
 2  adelcambre
 1  anaran
 1  bdukes
 1  burningTyger
 1  cor
 1  iosias
 7  nicesw123
 1  onovy
 2  pcasaretto
 1  sampablokuper

Лиценз

Тази работа е лицензирана като "Признание-Некомерсиално-Споделяне на споделеното 3.0". За да видите копие на лиценза, посетете https://creativecommons.org/licenses/by-nc-sa/3.0/deed.bg или изпратете писмо до Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

Увод

Ще прекарате няколко часа от живота си в четене за Гит. Да отделим няколко минути и да обясним какво сме ви приготвили. Ето кратко обобщение на десетте глави и трите приложения от тази книга.

В Глава 1 ще разгледаме Системите за Управление на Версии (СУВ) и основи на Гит. Без технически подробности, просто какво представлява Гит, защо се появи при наличието на толкова много СУВ, какво я отличава и защо я ползват толкова много хора. След това ще обясним как да свалите Гит и да я настроите за първи път, в случай че все още я нямате инсталирана.

В Глава 2 ще се спрем на най-простата употреба на Гит – как да ползвате Гит в 80% от случаите, с които ще се сблъсквате най-често. След прочитането на тази глава ще можете да клонирате хранилище, да разглеждате историята на проекта, да променяте файлове и да подавате промени. И ако книгата изведнъж избухне в пламъци вече ще сте овладели достатъчно, за да се справите със задачите докато си набавите ново копие.

Глава 3 обяснява модела на разклоняване, често описван като, най-доброто предимство на Гит. Тук ще научите какво наистина отличава Гит от останалите. Като свършите с тази глава, ще ви се прииска да поразмишлявате над това как сте могли да живеете без разклоняването в Гит.

Глава 4 покрива Гит на сървъра. Тази глава е за тези, които искат да използват Гит в организацията или на ваш личен сървър за сътрудничество. Ще разгледаме и някои възможности за хостинг, ако предпочитате някой друг да се занимава с това.

Глава 5 разглежда напълно подробно различните разпределени начини на работа (workflows) и как да ги извършвате с Гит. Приключвайки с тая глава, ще можете да работите изкусно с няколко отдалечени хранилища наведнъж, ще знаете как да ползвате Гит в електронната си поща, и сръчно ще боравите с множество отдалечени клони и кръпки от помощници.

Глава 6 представя в дълбочина услугата за хостване на Гит хранилища GitHub и нейните инструменти. Разгледани са записването и управлението на сметката ви там, създаване и използване на Гит хранилища, често срещани начини за допринасяне към проекти и как да приемате сътрудници във вашия проект. Отделено е място за множество малки съвети, с които да улесните работата си.

Глава 7 представя Гит команди за напреднали. Ще овладеете неща като плашещата команда reset, използване на двоично търсене за откриване на програмни грешки, промяна на историята, подробен избор на версии и много други. Със знанията, придобити в тази глава ставате истински майстор.

В Глава 8 ще се научите да настройвате ваша собствена среда за Гит. Това включва настройване на скриптове, които се стартират при определени събития (hook scripts) за налагане и насърчаване на отделни политики, и използване на настройки на средата, така че да можете да работите по желания начин. Ще разгледаме също изграждането на набор от собствени скриптове, за налагане на собствена политика на подаване на промените.

Глава 9 се занимава с Гит и други СУВ. Тя включва използване на Гит в света на Subversion (SVN) и превръщане на проекти от други СУВ в Гит проекти. Много организации все още използват SVN и нямат намерение да променят това, но до този момент, ще сте научили как да ползвате невероятната мощ на Гит. Тази глава ви показва как да се справите ако все пак трябва да ползвате SVN сървър. Също показваме как да внасяте проекти от няколко различни системи, в случай че сте убедили всички да се хвърлят надолу с главата в Гит.

Глава 10 се заравя дълбоко в тъмните но красиви дебри на Гит. Сега, след като знаете всичко за Гит и владеейки я до съвършенство, можете да разберете как Гит съхранява обектите си, какъв е обектния ѝ модел, подробности относно т.нар. пакетни файлове (packfiles), сървърни протоколи и т.н. В цялата книга споменаваме части от тази глава, в случай че ви се прииска да задълбаете. Но ако сте като нас и искате да узнаете техническите подробности, може би ще искате да прочетете първо Глава 10. Решението е ваше.

В Приложение A разглеждаме примери за използване на Гит в различни среди. Отделяме внимание на различни графични интерфейси и среди за разработка, в които може би ще искате да ползвате Гит, и на какво можете да разчитате. Ако се интересувате от преглед на използването на Гит на командния ред, във Visual Studio или Eclipse, вижте това приложение.

В Приложение B разучаваме начините за създаване на разширения за Гит чрез инструменти като libgit2 и JGit. Ако се интересувате как да пишете сложни и бързи собствени инструменти и се нуждаете от достъп на ниско ниво до Гит, тук ви се отваря гледка.

Накрая в Приложение C преминаваме през всяка отделна главна команда в Гит и споменаваме къде сме я разгледали в книгата и какво сме правили с нея. Тук можете да видите къде в книгата коя команда сме ползвали.

Да започваме.

Да започваме

В тази глава ще ви покажем как да започнете с Гит. Отначало ще обясним основни положения при средствата за управление на версиите. След това ще видим как се инсталира и изпълнява Гит. Накрая ще покажем как да я настроите и да започнете работа с нея. В края на тази глава вече ще разбирате защо Гит съществува, защо ви е да я ползвате, и ще сте готови да започнете.

За управлението на версии

Какво е "управление на версии" и защо би трябвало да ви интересува? Управление на версиите (version control) е система, която записва промените в един файл или набор от файлове с течение на времето, така че можете да се върнете към определена версия по-късно. За примерите в тази книга ще използвате файлове с програмен изходен код, въпреки че в действителност можете да запазвате версии на почти всякакви файлове.

Ако сте графичен или уеб-дизайнер и искате да пазите всяка версия на някоя картинка или изложение (което най-вероятно желаете), да ползвате Система за Управление на Версиите (СУВ) (Version Control System – VCS) е мъдро решение. Тя ви позволява да връщате файлове или цял проект до предишното им състояние, да сравнявате промените с течение на времето, да видите кой последно е променял нещо, което създава проблеми, кой е направил грешка и много други неща. Използването на СУВ също означава, че ако оплескате работата или загубите файлове, можете лесно да възстановите загубите. И всичко това без много усилия.

Самостоятелни системи за управление на версиите

За много хора предпочитаният начин за управление на версиите на техните файлове е да ги копират в друга папка (с бележка за датата, ако са умни). Този подход е много разпространен, тъй като е толкова прост, но същевременно е невероятно податлив на грешки. Лесно се забравя в коя папка се намирате в момента, лесно е да запишете грешния файл или да копирате върху файлове без да си искате.

Поради този проблем програмистите отдавна вече са разработили самостоятелни СУВ, които разполагат с проста база от данни, която съхранява направените промени във файловете.

Диаграма на самостоятелно управление на версиите
Figure 1. Самостоятелно управление на версиите.

Една от най-известните СУВ бе RCS (Revision Control System). Тя е разпространена на много компютри и днес. Дори всеизвестната операционна система Mac OS X включва rcs, когато инсталирате "Инструментите за Разработчици". RCS съхранява набори от кръпки (разликите между файловете) в специален формат на диска. Дадена версия може да се пресъздаде, като се приложат всички нужни кръпки.

Централизирани системи за управление на версиите

Следващият голям проблем, с който хората се сблъскват, е необходимостта да си сътрудничат с други разработчици. За справяне с това затруднение бяха разработени Централизирани Системи за Управление на Версиите (Centralized Version Control Systems – CVCS). Такива системи (като CVS, Subversion и Perforce) представляват съвкупност от централен сървър, където се съхраняват всички файлове с техните версии, и определен брой клиенти, които отписват файлове от централния сървър, за да работят с тях. В продължение на много години това беше стандартът за управление на версии.

Диаграма на Централизирано управление на версиите
Figure 2. Централизирано управление на версиите.

Този начин на работа предлага много предимства, особено в сравнение със самостоятелните СУВ. Всеки знае общо взето какво правят другите по проекта. Администраторите имат контрол върху настройките (кой какво може да прави) и е много по-лесно да се управлява централизирана СУВ, отколкото да се работи със самостоятелни бази данни на всеки клиент (отделен компютър).

Все пак и тук има сериозни недостатъци. Най-очевидният е зависимостта на всички от централния сървър. Ако той се счупи за около час, никой не може да си сътрудничи с никой друг или да записва нови версии на нищо от това, върху което работи. Ако твърдият диск на централния сървър излезе от строя, и няма архивни копия, губите абсолютно всичко – цялата история на проекта освен това, което разработчиците имат на компютрите си. Самостоятелните СУВ страдат от същия проблем – имате ли цялата история на проекта само на едно място, рискувате да загубите всичко.

Разпределени системи за управление на версиите

И тук идва ред на Разпределените Системи за Управление на Версиите (Distributed Version Control Systems – DVCSs). При РСУВ (каквито са Git, Mercurial, Bazaar или Darcs), клиентите не просто отписват последното изображение на файловете – те създават напълно огледален образ на хранилището. Така, ако някой сървър умре, и различни системи са работели заедно чрез него, всеки от клиентите може да бъде копиран обратно на централния сървър и работата да бъде възстановена. Всяко копие е пълен архив на всички данни.

Диаграма за Разпределено управление на версиите
Figure 3. Разпределено управление на версиите.

Нещо повече, много от тези системи се справят чудесно с това да имат няколко отдалечени хранилища, с които работят, така че да можете да си сътрудничите с различни групи хора по различни начини едновременно в един проект. Това ви дава възможност да настроите няколко начина на взаимодействие с другите (йерархични модели например), което е невъзможно при централизираните СУВ.

Кратка история на Гит

Както много велики открития в живота ни, Гит се появи с известно количество съзидателна разрушителност и горещи противоречия.

Ядрото на Линукс е проект с отворен код с изключително голям обхват. През по-голямата част от живота на проекта (1991–2002) промените се прилагаха чрез кръпки и архивни файлове. През 2002 проектът започна да ползва частна СУВ, наречена BitKeeper.

През 2005 отношенията между общността, която работеше по ядрото на Линукс, и търговската компания, която разработваше BitKeeper, се разпаднаха и разрешението да се ползва безплатно системата бе прекратено. Това накара общността, разработваща Линукс (и в частност Линус Торвалдс, създателят на Линукс) да създадат свое собствено средство, стъпвайки на научените уроци при ползването на BitKeeper. Някои от целите на новата система бяха:

  • Бързина;

  • Простота;

  • Силна поддръжка на едновременна разработка (хиляди успоредни разклонения);

  • Напълно разпределена;

  • Способна да се справя ефикасно (по отношение на бързината и размера на данните) с големи проекти, какъвто е Ядрото на Линукс.

От своето зараждане през 2005 системата Гит се разви и стана лесна за употреба, като същевременно запази първоначалните си качества. Тя е невероятно бърза. Твърде подходяща е за големи проекти и има невероятна система за създаване на клони при работа на много хора едновременно (Вижте [_git_branching]).

Основи на Гит

Е, какво е Гит всъщност? Това е важно да се разбере, защото, ако знаете какво е Гит и как работи в общи линии, то може би ще ви бъде по-лесно да я ползвате ефективно. Като изучавате Гит, се опитайте да изчистите съзнанието си от нещата, които знаете за други СУВ (като Subversion и Perforce). Така ще избегнете излишни обърквания, докато ползвате системата. Гит съхранява и възприема данните по различен начин, макар потребителският интерфейс да е подобен. Разбирането на разликите ще ви спести неудобства, докато ползвате системата.

Снимки, не разлики

Главната разлика между Гит и всяка друга СУВ (Subversion и приятели включително) е начининът, по който Гит възприема данните си. Повечето други системи съхраняват данните си като списък от промени върху файлове. Тези системи (CVS, Subversion, Perforce, Bazaar и т.н.) възприемат данните, които съхраняват, като набор от файлове и промени, направени върху всеки от тези файлове в течение на времето.

Съхраняване на данни като промени върху една първична версия на всеки файл.
Figure 4. Съхраняване на данни като промени върху една първична версия на всеки файл.

Гит нито възприема данните си, нито ги съхранява по този начин. Вместо това Гит гледа на данните като на набор от състояния на малка файлова система. Всеки път, когато подадете файлове или запишете състоянието на вашия проект в Гит, тя всъщност прави снимка на вашите файлове в момента и съхранява указател към това състояние. Ако няма променени файлове, Гит не записва файла отново, а съхранява само връзка към предишното състояние на същия файл, който вече е съхранила. Това се прави с цел ефективност. Гит разглежда данните си като поток от моментни снимки (състояния).

Съхраняване на данните като снимки на проекта във времето.
Figure 5. Съхраняване на данните като снимки на проекта във времето.

Това е важна разлика между Гит и почти всички други СУВ. Гит преразглежда почти всяко положение от управлението на версиите, докато повечето системи копират от предното поколение. Това превръща Гит по-скоро в мини-файлова система с набор от изключително мощни инструменти, нежели обичайна СУВ. Ще разгледаме някои от предимствата на това да се възприемат данните по този начин, когато обсъждаме разклоняването в [_git_branching].

Почти всяко действие е самостоятелно

Повечето действия в Гит се нуждаят само от файлове и ресурси на вашия компютър – като цяло няма нужда от каквато и да е информация извън него. Ако сте свикнали със СУВ, където почти всяко действие зависи от мрежата, тази страна на Гит ще ви накара да си мислите, че боговете на скоростта са я благословили с неописуема мощ. Повечето действия се изпълняват мигновено, защото цялата история на проекта е на вашия твърд диск.

Например, ако разглеждате историята на проекта, Гит не трябва да прави заявка към сървър, за да вземе историята и да ви я покаже. Тя просто я чете от собствената си база данни. Като следствие виждате историята почти мигновено. Ако искате да видите направените промени в даден файл отпреди месец, Гит поглежда състоянието на файла отпреди месец и изчислява разликите, вместо да прави заявка към отдалечен сървър за това или да взема стара версия на файла от сървъра, за да го сравни с текущата версия на вашия компютър.

Това означава също, че можете да правите почти всичко, дори ако сте извън линия или извън вашата виртуална частна мрежа (ВЧМ). Ако сте в самолет или влак, можете да подавате промени спокойно и да качите промените, когато се доберете до мрежа. Ако сте вкъщи и не успеете да настроите ВЧМ, все пак можете да работите. При много други системи това е или невъзможно, или мъчително. С Perforce например не можете да направите много, ако не сте свързани със сървъра, а със Subversion и CVS можете да променяте файлове, но не можете да подадете промените в базата данни (защото сте извън линия). Това може и да ви изглежда, че не е кой знае какъв проблем, но ще се изненадате като усетите разликата.

Гит е цялостно решение

Преди да се съхрани каквото и да е в Гит, то получава хеш-сума (указател) и след това указателят се ползва за достъп до съхраненото. Това означава, че е невъзможно да промените съдържанието на файл или папка, без Гит да знае за това. Тази способност е вградена в Гит на най-ниско ниво и е неразделна част от философията на системата. Невъзможно е да загубите данни или да повредите файл, без Гит да засече това.

Механизмът, който Гит ползва за тези проверки, се нарича SHA-1 хеш. Това е низ, съставен от шестнадесетични знаци (от 0 до 9 и от a до f) с дължина 40 знака, и се изчислява върху съдържанието на файл или папка. Един SHA-1 хеш изглежда така:

24b9da6552252987aa493b52f8696cd6d3b00373

Ще виждате тези хеш-суми навсякъде в Гит, защото ситемата ги ползва изключително много. Всъщност, Гит съхранява всичко в базата си данни не като име на файл, а като хеш-сума на съдържанието на файла.

Гит само добавя данни

Когато изпълнявате някакво действие, Гит почти винаги само добавя данни към базата. Трудно ще се сблъскате с нещо, което не може да се отмени, или да накарате системата да изтрие данни по някакъв начин. Както при всички други СУВ, лесно се губят данни, които не сте подали (committed) все още, но след като подадете промените си, няма как да ги загубите, особено ако редовно ги изтласквате (push) към друго (отдалечено) хранилище.

Така ползването на Гит е просто радост за душата, защото знаем, че можем да експериментираме и няма как сериозно да оплескаме нещата. По-задълбочен поглед върху това, как Гит съхранява данните и как да възстановите данни, които изглеждат загубени, ще намерите в Отмяна на действия.

Трите състояния

А сега, внимавайте. Ако искате обучението ви да върви леко и нататък, най-важно е да запомните следното. В Гит вашите файлове са винаги в едно от следните три състояния: подаден (committed), променен (modified) и в индекса за подаване (staged).

"подаден" означава, че файлът е съхранен в базата данни на компютъра ви.

"променен" означава, че файлът е променен, но промяната все още не е в базата данни.

"в индекса за подаване" – добавили сте файла в индекса за подаване, след като сте го променили, и той ще отиде в базата със следващото подаване.

Тук стигаме до трите главни съставни части на всеки Гит проект: папката .git, работното дърво и индексът за подаване.

Работно дърво, индекс за подаване и папка на Гит.
Figure 6. Работно дърво, индекс за подаване и папка на Гит.

В папката .git Гит съхранява метаданните и обектната база данни на проекта ви. Това е най-важната част от Гит. Всъщност, само това се копира, когато клонирате едно хранилище от друг компютър.

Работното дърво е отделно отписване на една версия от проекта. Тези файлове са извадени от компресираната база данни в папката на Гит и са поставени на диска, за да бъдат ползвани и променяни от вас.

Индексът за подаване (staging area) е файл, намиращ се в директорията .git, който съдържа информация за това, какво ще влезе в следващото подаване. Понякога се нарича просто индекс. [1].

Основният начин на работа в Гит се състои от следните стъпки:

  1. Променяте файлове в работното дърво.

  2. Добавяте файлове към индекса за подаване – както ще изглеждат към момента на подаването.

  3. Подавате ги (commit). Файловете се подават така, както са изглеждали, когато сте ги добавили към индекса, и се записват за постоянно в Гит директорията ви.

Ако дадена версия на файл се намира в Гит папката, файлът се смята за подаден. Ако файлът е бил променен и добавен, той се смята за "добавен към индекса". И ако е бил променен, след като е бил отписан (checked out), но не е добавян пак, файлът се счита за променен. В главата Основи на Гит ще научите повече за тези състояния, как да се възползвате от тях и как да пропуснете добавянето изцяло.

Командният ред

Има много различни начини да се ползва Гит. Освен оригиналните инструменти за командния ред, съществуват много графични потребителски интерфейси с различни възможности. За целите на тази книга ще ползваме Гит на командния ред. Със сигурност командният ред е единственото място, където можете да изпълнявате всички Гит команди. Повечето графични приложения поддържат само част от възможностите на Гит с цел простота. Ако знаете как се изпълнява нещо на командния ред, най-вероятно ще се справите и с графичната версия, докато обратното невинаги е вярно. Също така, ако изборът на графичен интерфейс е въпрос на личен вкус, то инструментите за командния ред са винаги налице и достъпни за всички.

Така че очакваме да знаете как да си отворите терминал в Mac или команден прозорец, или Powershell в Windows. Ако не разбирате за какво говорим, трябва да спрете и да проучите набързо, та като се върнете, да можете да следвате примерите и описанията нататък в книгата.

Инсталиране на Гит

За да използвате Гит, трябва да я имате на компютъра си. Дори да е вече инсталирана, добра идея е да я обновите до последната версия. Можете да я инсталирате като пакет за вашата операционна система или чрез някакъв друг инсталатор, или да вземете изходния код и да си я компилирате сами.

Note

Тази книга е писана, когато Гит беше версия 2.0.0. Макар повечето команди да би трябвало да работят дори на стари версии, някои от тях може и да не работят или да се държат малко по-различно. И понеже Гит има прекрасна обратна съвместимост, всяка версия след 2.0 ще ви свърши чудесна работа.

Инсталиране на Linux

Ако искате да инсталирате основните Гит инструменти на Linux като прекомпилиран пакет, можете да го направите с инсталатора на пакети, който върви с вашата дистрибуция. Ако сте на Fedora например, можете да използвате yum:

$ sudo yum install git-all

Ако сте на някакъв вид Debian като Ubuntu, пробвайте с apt-get:

$ sudo apt-get install git-all

За повече възможности за инсталиране на различни Unix платформи, погледнете на сайта на Гит http://git-scm.com/download/linux.

Инсталиране на Mac

Има няколко начина да инсталирате Гит на Mac. Може би най-лесният е да инсталирате инструментите за командния ред на Xcode (Xcode Command Line Tools). На Mavericks (10.9) или следваща версия е достатъчно да се опитате да изпълните git в терминала. Ако я нямате, ще бъдете попитани дали да бъде инсталирана.

Ако искате по-скорошна версия, можете да я инсталирате като прекомпилиран пакет. Инсталационен пакет за OSX се поддържа и може да бъде намерен на http://git-scm.com/download/mac.

Инсталационен пакет на Гит за OS X.
Figure 7. Инсталационен пакет на Гит за OS X.

Също така можете да я инсталирате като част от пакета "GitHub for Mac". Техният графичен инструмент предлага възможност за инсталиране и на инструментите за командния ред. Можете да го свалите от сайта на GitHub за Mac, който е на адрес http://mac.github.com.

Инсталиране на Windows

И на Windows начините за инсталиране са няколко. Официалният пакет можете да намерите на сайта на Гит. Просто отидете на адрес http://git-scm.com/download/win и свалянето започва автоматично. Забележете, че този проект се нарича "Git for Windows", и е отделен от самата система Гит. За да научите повече, отидете на https://git-for-windows.github.io/.

Ако искате автоматизиран инсталационен процес, свалете си пакета Git Chocolatey. Обърнете внимание, че този пакет се поддържа само от общността.

Друг лесен начин да инсталирате Гит е като инсталирате "GitHub for Windows". Пакетът включва версия за командния ред, както и графичен вариант. Също така работи добре в Powershell, предоставя добро кеширане на потребителските данни и идва с разумни настройки за нови редове. За тези неща ще научим по-нататък. Засега стига да кажем, че искате всичко това. Можете да го свалите от сайта на GitHub за Windows на адрес http://windows.github.com.

Инсталация от изходен код.

Някои хора намират за полезно да инсталират Гит от пакет с изходен код, защото така могат да ползват най-скорошната версия. Прекомпилираните пакети обикновено са малко по-стари, въпреки че през последните години със стабилизирането на Гит това има все по-малко значение.

Ако искате да инсталирате Гит от изходния код, са ви необходими следните библиотеки: autotools, curl, zlib, openssl, expat и libiconv. Те са зависимости за Гит. Например, ако сте на система, която ползва средства за управление на пакети като yum (такава е Fedora) или apt-get (всички системи на основа Debian), можете да ползвате една от следните команди, за да компилирате и инсталирате най-малкото необходими зависимости:

$ sudo yum install dh-autoreconf curl-devel expat-devel gettext-devel \
  openssl-devel perl-devel zlib-devel
$ sudo apt-get install dh-autoreconf libcurl4-gnutls-dev libexpat1-dev \
  gettext libz-dev libssl-dev

За да добавите документацията в различни формати (doc, html, info), са нужни следните допълнителни зависимости (Важно: Потребителите на RHEL и RHEL-производни системи като CentOS и Scientific Linux ще трябва да включат хранилището EPEL, за да свалят пакета docbook2X):

$ sudo yum install asciidoc xmlto docbook2X getopt
$ sudo apt-get install asciidoc xmlto docbook2x getopt

Също така, ако ползвате Fedora/RHEL/RHEL-производни, трябва да изпълните следната команда, тъй като имената на командите се различават.

$ sudo ln -s /usr/bin/db2x_docbook2texi /usr/bin/docbook2x-texi

След като си набавите всички необходими зависимости, можете да свалите последната версия от няколко места. Можете да я вземете от сайта Kernel.org на адрес https://www.kernel.org/pub/software/scm/git или огледалото на сайта на GitHub – https://github.com/git/git/releases. На страницата на GitHub е малко по-ясно коя е последната версия, но пък на kernel.org има и подписи на изданията, ако искате да проверите какво сте свалили.

След това компилирайте и инсталирайте:

$ tar -zxf git-2.0.0.tar.gz
$ cd git-2.0.0
$ make configure
$ ./configure --prefix=/usr
$ make all doc info
$ sudo make install install-doc install-html install-info

След като свършите с това, може да вземете Гит, като използвате самата нея, и така да я обновявате:

$ git clone git://git.kernel.org/pub/scm/git/git.git

Първоначални настройки

Сега, като имате Гит на компютъра си, ще искате да настроите работната си среда. Това се прави само веднъж. Настройките си остават непроменени при обновяване на Гит. Също така можете да променяте тези настройки по всяко време, като изпълните командите отново.

Гит идва с инструмент, наречен git config, който ви позволява да преглеждате и задавате стойности на променливите в настройките. Тези променливи контролират поведението и изхода от изпълнението на командите. Те могат да се съхраняват на три различни места:

  1. Файлът /etc/gitconfig: Съдържа настройки за всички потребители на машината и всички техни хранилища. Ако подадете аргумента --system на git config, се чете или пише в този файл.

  2. Файловете ~/.gitconfig или ~/.config/git/config: Само за вашия потребител. Можете да накарате Гит да ползва този файл, като подадете --global.

  3. Файлът config в Гит директорията (т.е. .git/config) на хранилището, което използвате в момента: Важи само за това хранилище.

Всяко ниво е с приоритет пред по-общото, горно ниво. Стойностите в .git/config са с предимство пред тези от /etc/gitconfig.

На компютри с Windows Гит търси файла .gitconfig в папката $HOME (обикновено C:\Users\$USER). Гледа се и в /etc/gitconfig, макар пътят да е относителен (в кореновата папка на MSys). Това е мястото, където сте инсталирали Гит. Ако ползвате Гит версия 2.x или следваща на Windows, се чете също системния файл с настройки C:\Documents and Settings\All Users\Application Data\Git\config (на Windows XP). На Windows Vista и следващи се ползва C:\ProgramData\Git\config. Този файл може да бъде променян само чрез командата git config -f <file>, изпълнена като потребител admin.

Вашата самоличност

Първото нещо, което трябва да направите, след като инсталирате Гит, е да зададете потребителското си име и адрес за електронна поща. Това е важно, защото Гит използва тази информация при всяко подаване (commit) на промени. Тази информация се записва във всяко следващо подаване, без възможност за промяна по-късно.

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

Да повторим – това се прави само веднъж, ако подадете аргумента --global. Така Гит ще използва тази информация за всички проекти на вашия системен потребител. Ако искате да промените тези данни за отделен проект, можете да изпълните командата отново без аргумента --global, докато сте в папката на дадения проект.

Много от инструментите с графичен интерфейс ще ви помогнат да свършите това, когато ги пуснете за първи път.

Вашият текстов редактор

След като сте задали настройки за самоличност, можете да настроите текстовия редактор по подразбиране, който ще бъде ползван, когато трябва да въведете съобщение. Ако не е зададен, Гит ползва системния текстов редактор по подразбиране.

Ако искате да ползвате друг, да речем Emacs, можете да направите следното:

$ git config --global core.editor emacs

На Windows, за да ползвате друг редактор, например Notepad++, направете следното:

На 32-битова система

$ git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -nosession"

На 64-битова система

$ git config --global core.editor "'C:/Program Files (x86)/Notepad++/notepad++.exe' -multiInst -nosession"
Note

Vim и Emacs са известни текстови редактори, които често се използват на Unix-подобни системи като Linux и OS X. Notepad++ се ползва често в Windows. Ако не сте на ти с никой от тях, трябва да потърсите съвети за настройване на вашия редактор за ползване с Гит

Warning

Ако не свършите тази работа сега, после може много да се чудите какво става. В Windows например, може Гит внезапно да спре насред някакво действие, опитвайки се да зареди текстовия редактор.

Проверка на настройките

За да проверите какви са настройките ви, можете да ползвате командата git config --list. Тя показва списък със всички настройки на Гит, които се ползват в момента:

$ git config --list
user.name=John Doe
user.email=johndoe@example.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...

Някои от ключовете може да видите многократно, защото Гит чете ключовете от различни файлове (например /etc/gitconfig и ~/.gitconfig). В такива случаи знайте, че Гит ползва последната стойност, която виждате на някой повтарящ се ключ.

Също така може да проверите каква е текущата стойност на отделен ключ, като напишете git config <key>:

$ git config user.name
John Doe

Намиране на помощ

Ако някога ви потрябва помощ при ползването на Гит, има три начина да видите помощната страница (manpage) за която и да е команда на Гит:

$ git help <действие>
$ git <действие> --help
$ man git-<действие>

Например, може да видите помощната страница за командата config, като изпълните

$ git help config

Всички тези страници са достъпни и когато сте извън линия. Ако наръчниците и тази книга не са ви достатъчни и се нуждаете от повече напътствия, можете да пробвате каналите #git или #github на IRC съръвъра на Freenode (irc.freenode.net). В тези канали редовно висят стотици хора, които са много запознати с Гит и често помагат.

Note

С появата си сайтът stackoverflow.com стана предпочитано място за намиране на помощ по най-различни въпроси от света на програмирането. Въпросите с етикет git се намират на адрес http://stackoverflow.com/questions/tagged/git. Бел. прев.

Обобщение

Сега би трябвало да разбирате общо взето какво е Гит и по какво се различава от централизираните системи за управление на версиите, които вероятно сте ползвали преди това. Също така вече би трябвало да имате работеща версия на Гит на компютъра си, с настройки, включващи ваши лични данни. Време е да научим някои основни команди.

Основи на Гит

Ако трябва да прочетете само една глава, за да започнете да ползвате Гит, това е тя. Тази глава покрива всички основни команди, които ви трябват, за да правите повечето неща в Гит. В края на главата ще можете да настройвате и създавате хранилище, да започвате и спирате следенето на файлове, да добавяте и подавате промени. Също така ще ви покажем как да настроите Гит да пренебрегва някои файлове, упоменати по име или по образец; как да отменяте лесно и бързо промени, направени погрешка; как да разглеждате историята на проекта и промените, направени между две подавания; как да изтегляте от отдалечени хранилища и как да изтласквате към тях.

Да си направим Гит хранилище

Можете да създадете Гит проект по два начина. Първият е като вземете съществуващ проект или папка и ги внесете в Гит. Вторият се състои в клониране на съществуващо Гит хранилище от сървър.

Създаване на хранилище в съществуваща папка

Ако започвате да следите промените в съществуващ проект, трябва да отидете в папката на проекта. Ако никога не сте правили това, ето как изглежда на различните операционни системи:

на Linux:

$ cd /home/потребител/хранилище

на Mac:

$ cd /Users/потребител/хранилище

на Windows:

$ cd /c/потребител/хранилище

и въведете:

$ git init

Тази команда създава нова папка с име .git, която съдържа всичките необходими за хранилището файлове – скелетът на едно Гит хранилище. Сега все още нищо не се следи. (Вижте [_git_internals], за да разберете какви точно файлове се създават в папката .git, която създадохте току-що.)

Ако искате да започнете да управлявате версиите на съществуващите файлове, трябва да започнете да следите тези файлове и да ги подадете първоначално. Това се постига с няколко команди git add, като укажете файловете, които искате да следите и след това изпълните git commit.

$ git add *.c
$ git add LICENSE
$ git commit -m 'първа версия на проекта'

Ще видим какво правят тези команди след малко. Сега имате Гит хранилище, в което файловете се следят и са подадени за първи път.

Клониране на съществуващо хранилище

Ако искате да вземете копие на съществуващо хранилище – да речем проект, към който искате да се присъедините – ви трябва командата git clone. В случай че сте запознати с други СУВ като Subversion, ще ви направи впечатление, че командата е "clone" (клонирай), а не "checkout" (отпиши). Това е важна разлика – вместо просто работно копие, Гит взима пълно копие на почти всички данни, с които сървърът разполага. По подразбиране се взима всяка версия на всеки файл, когато изпълните git clone. Всъщност ако данните от диска на сървъра се повредят, можете да ползвате почти всяко копие на всеки от клиентите, за да възстановите състоянието им до момента на клонирането от съответния клиент. Може да загубите някои скриптове, настроени да се изпълняват при определени събития (hooks) и други, но всички данни за версиите ще са запазени. Вижте [_git_on_the_server] за повече подробности.

Хранилище се клонира с git clone [url]. Например ако искате да клонирате Гит като библиотека (името ѝ е libgit2), можете да го направите така:

$ git clone https://github.com/libgit2/libgit2

Това създава папка с име “libgit2”, папка .git в нея, изтегля всички данни за хранилището и отписва (checkout) работно копие на последната версия. Ако отидете в папката libgit2, там ще видите файловете от проекта, готови за промяна. Ако пък искате да клонирате хранилището в папка с друго име, можете да укажете името като допълнителен параметър:

$ git clone https://github.com/libgit2/libgit2 mylibgit

Тази команда прави същото като предната, но целевата папка (в която се клонира) се нарича mylibgit.

Гит може да ползва няколко протокола за пренос на данни. Предните примери ползват https://, но някъде можете да видите да се ползват също git:// или user@server:path/to/repo.git, който ползва протокола SSH. [_git_on_the_server] ще ви запознае с всички възможни настройки на сървъра за достъп до хранилището както и предимствата и недостатъците на всяка от тях.

Запис на промени в хранилището

Имате си истинско хранилище и отписано работно копие на файловете в проекта. Всеки път, когато проектът ви е в състояние, което бихте искали да запишете, след като сте направили някакви промени, трябва да подадете текущото състояние на файловете в хранилището.

Запомнете, че всеки файл в работната папка може да бъде в състояние "следен" (tracked) или "неследен" (untracked). Следени са файловете, които са били в последното подаване. Те могат да бъдат променени, непроменени или в индекса за подаване. Неследените файлове са всички останали – всеки файл в работната папка, който не е бил в предишното подаване и не е в индекса за подаване. Когато за първи път клонирате хранилище, всичките файлове ще бъдат следени и непроменени, защото Гит току що ги е отписала, а вие не сте променяли никой от тях.

Ако промените някой файл след последното подаване, Гит започва да го вижда като променен. Добавяте променените файлове в индекса и ги подавате, след това цикълът се повтаря.

The lifecycle of the status of your files.
Figure 8. Жизнен цикъл на състоянието на файловете.

Проверка на състоянието на файловете

Командадта git status е главното средство за проверка състоянието на файловете. Ако изпълните тази команда непосредствено след клониране, ще видите нещо подобно на следното:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
Note

Ако терминалът ви е локализиран, това съобщение ще бъде на български. В Unix-подобни системи това става като зададете следната стойност на променливата $LANG=bg_BG.UTF-8. Това обикновено е така, ако сте настроили графичната си среда на български. Ето как изглежда в моя терминал. (Бел. Прев.)

$ git status
На клон master
Вашият клон е актуализиран както «origin/master».
липсват каквито и да е промени, работното дърво е чисто

Това означава, че работната папка е чиста – с други думи, никой от следените файлове не е променян. Освен това, Гит не вижда никакви неследени файлове. Иначе биха били показани. Също така командата казва, на кой клон се намирате и, че той не се различава от клона със същото име на сървъра. В нашия случай този клон е “master”. Това е клонът по подразбиране. Не го мислете засега. В [_git_branching] ще разгледаме клоните и указателите в подробности.

Да речем, че добавите нов файл към проекта – обикновен файл README. Ако файлът не е съществувал преди, и изпълните git status, виждате неследения файл по следния начин:

$ echo 'My Project' > README
$ git status
На клон master
Вашият клон е актуализиран както «origin/master».
Неследени файлове:
  (използвайте „git add ФАЙЛ…“, за да определите какво включвате в подаването)

    README

към индекса за подаване не са добавени промени, но има нови файлове (използвайте „git add“, за да започне тяхното следене)

Виждате, че новият файл е неследен. Намира се под заглавието “Неследени файлове:” в изхода от git status. Неследен означава, че Гит вижда файл, който не присъства в предишното подаване. Гит няма да започне да го добавя, докато вие не ѝ кажете изрично. Това е така, за да не започнете без да си искате да добавяте създадени двоични или други файлове. Сега искате да започнете да добавяте файла README, така че нека започнем да го следим.

Следене на нови файлове

За да започнете следенето на нов файл, използвате командата git add. За да започнете следенето на файла README, изпълнете:

$ git add README

Ако изпълните отново командата git status, ще видите, че файлът сега е следен и добавен в индекса за подаване.

$ git status
На клон master
Вашият клон е актуализиран както «origin/master».
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

    нов файл:   README

Разбирате, че е добавен, защото се намира под заглавието “Промени, които ще бъдат подадени:”. Ако подадете сега, в историята ще се запише файлът в състоянието, в което е бил, когато сте изпълнили git add. Може би си спомняте, че след като изпълнихте git init, изпълнихте git add (ФАЙЛове). С това действие започнахте да следите файловете в папката. Командата git add приема път до файл или папка. Ако е папка, командата добавя всички файлове в нея в дълбочина.

Добавяне на променени файлове

Да променим файл, който вече се следи. Ако промените вече следен файл, на име CONTRIBUTING.md, и след това изпълните git status, ще видите нещо подобно:

$ git status
На клон master
Вашият клон е актуализиран както «origin/master».
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

	нов файл:          README

Промени, които не са в индекса за подаване:
  (използвайте „git add ФАЙЛ…“, за да обновите съдържанието за подаване)
  (използвайте „git checkout -- ФАЙЛ…“, за да отхвърлите промените в работното дърво)

	    променен:   CONTRIBUTING.md

Файлът CONTRIBUTING.md се появява под заглавието “Промени, които не са в индекса за подаване:”, което означава, че е променен вече следен файл, но все още не е добавен в индекса за подаване. За да го добавите, изпълнявате командата git add. git add е многоцелева команда – използва се за започване следенето на нови файлове, за добавяне на следени файлове и за други неща като означаване на файлове като готови в случай на конфликт при сливане. Добре е да мислите за нея като за средство за добавяне на съдържание към следващото подаване отколкото като команда за добавяне на файлове към проекта. Да изпълним git add сега, за да добавим в индекса файла CONTRIBUTING.md и след това да изпълним отново git status:

$ git add CONTRIBUTING.md
$ git status
На клон master
Вашият клон е актуализиран както «origin/master».
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

	променен:          CONTRIBUTING.md
	нов файл:          README.md

И двата файла са в индекса и ще отидат в следващото подаване. Да си представим, че сега се сещате за нещо, което искате да промените в CONTRIBUTING.md, преди да го подадете. Отново го отваряте и правите промяната си. Да изпълним за всеки случай git status отново.

$ vim CONTRIBUTING.md
$ git status
На клон master
Вашият клон е актуализиран както «origin/master».
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

	променен:          CONTRIBUTING.md
	нов файл:          README.md

Промени, които не са в индекса за подаване:
  (използвайте „git add ФАЙЛ…“, за да обновите съдържанието за подаване)
  (използвайте „git checkout -- ФАЙЛ…“, за да отхвърлите промените в работното дърво)

	променен:          CONTRIBUTING.md

К’во става, бе? Сега CONTRIBUTING.md е и в списъка за подаване, и в списъка на недобавените. Как е възможно това? Оказва се, че Гит добавя файла точно в състоянието, в което той се намира, когато изпълните git add. Ако подадете сега версията на CONTRIBUTING.md в състоянието, в което се е намирал, когато за последно сте изпълнили git add, така и ще отиде в подаването. Файлът няма да бъде записан в хранилището в текущото си състояние, когато изпълните git commit. Ако промените файл след като сте изпълнили git add, ще трябва да изпълните git add отново, за да добавите новото състояние в индекса.

$ git add CONTRIBUTING.md
$ git status
На клон master
Вашият клон е актуализиран както «origin/master».
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

	променен:          CONTRIBUTING.md
	нов файл:          README

Съкратено състояние

Изходът от git status е подробен и многословен. Гит има също настройка за съкратено показване на състоянието и така можете да да го видите в по-съкратен вид. Ако изпълните git status -s или git status --short виждате по-сбит изход:

$ git status -s
 M README
MM Rakefile
A  lib/git.rb
M  lib/simplegit.rb
?? LICENSE.txt

Новите, неследени файлове се показват с ?? до тях, ново добавените имат A, променените файлове M и т.н. В изхода виждаме две еднобуквени колони отляво на имената на файловете – лявата показва състоянието на индекса за добавяне, а дясната – състоянието на работното дърво. Така например файлът README е променен в работната папка, но все още не е добавен, докато lib/simplegit.rb е променен и вече добавен. Rakefile е бил променен, добавен и отново променен. В него има промени, които са вече добавени и такива, които не са.

Пренебрегване на файлове

Често ще имате видове файлове, които не искате Гит да добавя автоматично и дори да не ги показва като неследени. Това обикновено са автоматично създадени файлове, като файлове за отчети или такива, произведени от системата за изграждане на проекта ви. В такива случаи можете да създадете файл със списък от образци (шаблони), наречен .gitignore. Ето примерен .gitignore файл:

$ cat .gitignore
*.[oa]
*~

Първият ред казва на Гит да пренебрегва файлове, завършващи на “.o” или “.a”.Това са обектни и архивни файлове – изход от компилирането на кода ви. Вторият ред казва на Гит да пренебрегва всички файлове, чието име завършва с вълнообразна чертица (~). Те се използват от много текстови редактори като Emacs за съхранение на временна информация. Може да включите също папки с имена log, tmp, или pid, автоматично създадена документация и т.н. Хубаво е да имате .gitignore още преди да сте започнали проекта, за да не би случайно да подадете файлове, които наистина не искате в хранилището.

Правилата за образците от заместващи знаци, които можете да поставите в .gitignore са следните:

  • Празните редове или такива, започващи с # се пропускат.

  • Стандартни образци (шаблони) от заместващи знаци.

  • Можете да започвате образци с наклонена черта (/), за да избегнете повторно съвпадение в дълбочина.

  • Можете да завършвате образци с наклонена черта (/), за да укажете папка.

  • Можете да създадете отрицаващ шаблон като го започнете с удивителен знак (!).

Образците от заместващи знаци са опростени изрази за намиране на съвпадения, използвани от различните обвивки на операционните системи. Звездата (*) съвпада с един или повече знаци; [abc] съвпада с всеки знак в квадратните скоби (в този случай a, b, или c); въпросителният знак (?) дава съвпадение с отделен знак; а квадратните скоби, ограждащи знаци разделени със съединителна чертица ([0-9]) съвпадат с всеки между тях включително (в този случай от 0 до 9). Можете също да ползвате две звездички, за да укажете няколко папки една в друга. a/**/z ще съвпадне с a/z, a/b/z, a/b/c/z и т.н.

Ето друг примерен .gitignore файл:

# без файлове, завършващи на .a
*.a

# но да се следи lib.a, дори ако се пренебрегват всички, завършващи на .a файлове горе
!lib.a

# пренебрегваме файла TODO само в текущата папка, а не подпапка/TODO
/TODO

# да се пренебрегват всички файлове в папка build/
build/

# да се пренебрегва doc/notes.txt, но не и doc/server/arch.txt
doc/*.txt

# пренебрегване на всички .pdf файлове в папка doc/
doc/**/*.pdf
Tip

GitHub поддържа доста обстоен списък с добри примерни .gitignore файлове за десетки видове проекти и езици. Адресът, на който ще ги намерите е https://github.com/github/gitignore. Ползвайте ги като отправна точка в своите проекти.

Разглеждане на добавените и недобавените промени

Ако git status ви се струва недостатъчна – искате да видите какво точно е променено, не само кои файлове са променени – можете да ползвате командата git diff. Ще разгледаме подробно git diff по-късно. Засега е достатъчно да знаете, че тази команда ви отговаря, в повечето случаи, на следните въпроси: Какво сте променили и все още не сте добавили? И какво сте добавили в индекса за подаване. Макар git status да отговаря на тези въпроси, като ви показва списък с файлове, git diff ви показва самите редове, които са махнати или добавени – самата кръпка, такава каквато е.

Да кажем че промените и добавите файла README, а след това промените файла CONTRIBUTING.md, без да го добавяте. Ако изпълните командата git status, ще видите следното:

$ git status
На клон master
Клонът е актуализиран към „origin/master“.
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

        променен:   README

Промени, които не са в индекса за подаване:
  (използвайте „git add ФАЙЛ…“, за да обновите съдържанието за подаване)
  (използвайте „git checkout -- ФАЙЛ…“, за да отхвърлите промените в работното дърво)

        променен:   CONTRIBUTING.md

За да видите какво сте променили, но все още не сте добавили, изпълнете git diff без никакви допълнителни аргументи:

$ git diff
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
 Please include a nice description of your changes when you submit your PR;
 if we have to read the whole diff to figure out why you're contributing
 in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.

 If you are starting to work on a particular area, feel free to submit a PR
 that highlights your work in progress (and note in the PR title that it's

Тази команда сравнява промените в работното дърво с всичко, намиращо се в индекса за подаване. Изходът ѝ показва промените, които все още не сте добавили.

Ако искате да видите промените, които вече сте добавили в индекса и ще бъдат подадени, използвайте git diff --staged. Тази команда сравнява добавените промени с последното подаване.

$ git diff --staged
diff --git a/README b/README
new file mode 100644
index 0000000..03902a1
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+My Project

Важно е да отбележим, че git diff сама по себе си не показва всички промени, направени след последното подаване, а само тези, които все още не са добавени в индекса. Това може да ви обърка, защото ако сте добавили всичките си промени, git diff няма да изведе нищо на екрана.

Друг пример. Ако добавите CONTRIBUTING.md и след това го промените отново, можете да ползвате git diff, за да видите добавените и недобавените промени. Ако средата ни изглежда по следния начин:

$ git add CONTRIBUTING.md
$ echo '# test line' >> CONTRIBUTING.md
$ git status
На клон master
Клонът е актуализиран към „origin/master“.
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

	променен:   CONTRIBUTING.md

Промени, които не са в индекса за подаване:
  (използвайте „git add ФАЙЛ…“, за да обновите съдържанието за подаване)
  (използвайте „git checkout -- ФАЙЛ…“, за да отхвърлите промените в работното дърво)

	променен:   CONTRIBUTING.md

Сега с git diff можете да видите все още недобавените си промени:

$ git diff
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 643e24f..87f08c8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -119,3 +119,4 @@ at the
 ## Starter Projects

 See our [projects list](https://github.com/libgit2/libgit2/blob/development/PROJECTS.md).
+# test line

А с git diff --cached можете да видите вече добавените промени (--staged и --cached са синоними):

$ git diff --cached
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
 Please include a nice description of your changes when you submit your PR;
 if we have to read the whole diff to figure out why you're contributing
 in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.

 If you are starting to work on a particular area, feel free to submit a PR
 that highlights your work in progress (and note in the PR title that it's
Note
Git Diff във външна програма

Ще продължим да използваме git diff по различни начини до края на книгата. Има и друг начин да се разглеждат разликите, в случай че предпочитате програма с графично взаимодействие. Ако изпълните git difftool вместо git diff, можете да видите разликите в програми като "emerge", "vimdiff" и много други (включително платени продукти). Изпълнете git difftool --tool-help, за да видите наличните възможности.

Подаване на Промените

Сега, след като сте добавили всичко, което искате, можете да подадете промените си. Помнете, че всичко, което е извън индекса – всички нови или променени файлове, върху които не сте изпълнили git add, след като сте ги променили – няма да отидат с подаването. Те ще останат като променени файлове на диска. Да кажем, че последният път като изпълнихте git status всичко е било добавено в индекса и сте готов да подадете промените. Най-простият начин за подаване на промени е като изпълните git commit:

$ git commit

Това ще пусне предпочитаният от вас редактор. (Предпочитанието е зададено в променливата на обкръжението $EDITOR – обикновено vim или emacs, но може да го презапишете с каквото искате като изпълните командата git config --global core.editor както показахме в Да започваме).

Текстовият редактор показва следния текст (примерът тук е екран на Vim):

# Въведете съобщението за подаване на промените. Редовете, които започват
# с „#“, ще бъдат пропуснати, а празно съобщение преустановява подаването.
# На клон master
# Клонът е актуализиран към „origin/master“.
#
# Промени, които ще бъдат подадени:
#	нов файл:   README
#	променен:   CONTRIBUTING.md
#
~
~
~
".git/COMMIT_EDITMSG" 9L, 283C

Виждате, че подразбиращото се съобщение при подаване се състои от коментиран последният изход от git status и празен ред най-горе. Може да махнете коментара и да напишете съобщението си за подаването или да го оставите, за да ви напомня какво подавате. (За да виждате по-подробно какво точно подавате, добавете -v към git commit. Това добавя и разликите в прозореца на текстовия редактор, така че виждате всяка промяна.) Когато напуснете редактора, Гит подава промените със съобщението, което сте въвели. Коментарите и разликите не се добавят към съобщението ви.

Също така можете да напишете съобщението към подаването, когато изпълнявате командата commit, като добавите след нея -m (за message), ето така:

$ git commit -m "Story 182: Fix benchmarks for speed"
[master 463dc4f] Story 182: Fix benchmarks for speed
 2 files changed, 2 insertions(+)
 create mode 100644 README

Направихте първото си подаване! Виждате, че командата показва на екрана информация за себе си: В кой клон е отишло подаването; какъв е SHA-1 номерът на подаването (463dc4f); колко файла са променени; както и статистика за това колко редове са добавени и премахнати.

Запомнете, че подаването записва снимка на това, което сте добавили в индекса. Всичко недобавено си стои в работното дърво променено. Можете да направите друго подаване, за да го добавите в историята. Всеки път, когато подавате, записвате снимка на състоянието на проекта, което можете да върнете или сравните по-късно с друго състояние.

Пропускане на добавянето в индекса

Въпреки че е твърде полезно да нагаждате подаванията точно както искате, понякога работата с индекса е ненужно усложнение. Ако искате да пропуснете тази стъпка, Гит ви предоставя пряк път. Добавяйки -a към командата git commit, карате Гит да добавя автоматично всеки вече следен файл преди подаването. По този начин пропускате стъпката git add:

$ git status
На клон master
Вашият клон е актуализиран както «origin/master».
Промени, които не са в индекса за подаване:
  (използвайте „git add ФАЙЛ…“, за да обновите съдържанието за подаване)
  (използвайте „git checkout -- ФАЙЛ…“, за да отхвърлите промените в работното дърво)

	променен:          CONTRIBUTING.md

към индекса за подаване не са добавени промени (използвайте „git add“ и/или „git commit -a“)
$ git commit -a -m 'added new benchmarks'
[master 83e38c7] added new benchmarks
 1 file changed, 5 insertions(+), 0 deletions(-)

Забележете, че не беше нужно да изпълнявате git add за CONTRIBUTING.md преди да го подадете. Това е защото флагът -a добавя всички променени файлове. Това е удобно, но внимавайте. Може да се окаже, че сте включили нежелани промени.

Премахване на файлове

За да премахнете файл от хранилището, трябва да го премахнете от следените файлове (по-точно да го премахнете от индекса за подаване) и след това да подадете промените. Командата git rm прави това, като също премахва файла и от работната папка, така че вече няма да го виждате като неследен.

Ако просто изтриете файла, той ще се появи в раздела “Changed but not updated” (тоест недобавен) в изхода на git status:

$ rm PROJECTS.md
$ git status
На клон master
Вашият клон е актуализиран както «origin/master».
Промени, които не са в индекса за подаване:
  (използвайте „git add/rm ФАЙЛ…“, за да обновите съдържанието за подаване)
  (използвайте „git checkout -- ФАЙЛ…“, за да отхвърлите промените в работното дърво)

	изтрит:    PROJECTS.md

към индекса за подаване не са добавени промени (използвайте „git add“ и/или „git commit -a“)

След това, ако изпълните git rm, ще добавите файла в списъка за премахване:

$ git rm PROJECTS.md
rm 'PROJECTS.md'
$ git status
На клон master
Вашият клон е актуализиран както «origin/master».
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

	изтрит:    PROJECTS.md

При следващото подаване файлът ще изчезне и няма да се следи повече. Ако сте променили файла след като сте го добавили в списъка (индекса) за изтриване, трябва да "насилите" изтриването като подадете допълнително -f (force). Това е свойство на Гит за предпазване от случайна загуба на данни, които все още не са записани във версия и които не могат да бъдат възстановени.

Друго полезно нещо, което може би ще искате да направите е да запазите файла в работното дърво, но да го премахнете от списъка за подаване. Може да искате да запазите файла на диска си, но да не бъде вече следен от Гит. Това е особено полезно ако сте забравили да добавите някой файл в .gitignore и го добавите погрешка, да речем някой голям файл-отчет или куп компилирани .a файлове. За да премахнете файл по този начин, използвайте допълнителния параметър --cached:

$ git rm --cached README

Може да подавате файлове, папки или образци със заместващи знаци като аргументи на git rm. Тоест можете да направите нещо като следното:

$ git rm log/\*.log

Обърнете внимание на обратно наклонената черта (\) пред *. Избягването с обратно наклонена черта е необходимо, тъй като Гит прави свое собствено заместване на знаци, освен заместването на знаци от командния ви ред. Тази команда премахва всички файлове с разширение .log в папката log/. Или пък можете да направите нещо като това:

$ git rm \*~

Тази команда премахва всички файлове, чиито имена завършват с ~.

Преместване на файлове

За разлика от много други СУВ, Гит не следи изрично преместването на файлове. Ако преименувате файл, Гит не пази метаданни за преименуването на файла. Въпреки това, Гит е достатъчно умна в това отношение. Ще се занимаем с това след малко.

Така се оказва малко объркващо, че Гит има команда mv. Ако искате да преименувате файл, трябва да изпълните следното:

$ git mv file_from file_to

и то работи както очаквате. Всъщност ако сега погледнете състоянието, ще видите, че Гит смята файла за преименуван.

$ git mv README.md README
$ git status
На клон master
Вашият клон е актуализиран както «origin/master».
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

	преименуван:    README.md -> README

Обаче това е същото като да изпълните следните команди:

$ mv README.md README
$ git rm README.md
$ git add README

Гит се усеща, че става въпрос за преименуване, така че няма значение дали преименувате файл по първия начин или ползвате самата команда mv. Единствената разлика е, че git mv е една команда вместо три. Това е удобно свойство. Важното е, че можете да ползвате каквото си искате за преименуване на файлове и после съчетанието от add/rm преди да подадете файла.

Преглед на историята

След като сте подали промени няколко пъти или сте клонирали хранилище със съществуваща история, вероятно ще искате да видите предишните промени. Най-простият и мощен начин е да ползвате командата git log.

Следните примери ползват простичък проект “simplegit”. За да вземете проекта, изпълнете

$ git clone https://github.com/schacon/simplegit-progit

Като изпълните git log в този проект, ще видите изход, подобен на следния:

$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

Ако не подадете никакви аргументи git log показва по подразбиране списък с подаванията в обратен ред, последните подавания са най-отгоре. Както се вижда, тази команда извежда на екрана списък с подаванията с техните SHA-1-суми, името на автора, електронната му поща, датата и съобщението.

git log предоставя множество възможности за показване на точно каквото искате да видите. Тук ще ви покажем някои от най-използваните опции.

Един от най-полезните опции е -p. Тя показва промените, направени при всяко подаване. Можете да подадете допълнително -2, за да ограничите изхода до последните две подавания:

$ git log -p -2
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

diff --git a/Rakefile b/Rakefile
index a874b73..8f94139 100644
--- a/Rakefile
+++ b/Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
 spec = Gem::Specification.new do |s|
     s.platform  =   Gem::Platform::RUBY
     s.name      =   "simplegit"
-    s.version   =   "0.1.0"
+    s.version   =   "0.1.1"
     s.author    =   "Scott Chacon"
     s.email     =   "schacon@gee-mail.com"
     s.summary   =   "A simple gem for using Git in Ruby code."

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index a0a60ae..47c6340 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -18,8 +18,3 @@ class SimpleGit
     end

 end
-
-if $0 == __FILE__
-  git = SimpleGit.new
-  puts git.show
-end
\ No newline at end of file

Тази опция показва същата информация, но с промените, направени при всяко подаване. Това е много полезно при преглед на кода или бързо разглеждане на поредица от подавания на някой сътрудник. Можете също да подадете обобщаващи опции на git log. Например, за да видите съкратена статистика за всяко подаване, използвайте --stat.

$ git log --stat
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

 Rakefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

 lib/simplegit.rb | 5 -----
 1 file changed, 5 deletions(-)

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

 README           |  6 ++++++
 Rakefile         | 23 +++++++++++++++++++++++
 lib/simplegit.rb | 25 +++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

Както виждате, опцията --stat след всяко подаване извежда списък с променените файлове и колко реда са добавени или премахнати във всеки файл. Също така накрая се показва обобщение на промените.

Друга наистина полезна възможност е --pretty. Тази опция променя изхода на отчета по различен начин от подразбиращия се. Можете да използвате няколко различни стойности за --pretty. oneline извежда всяко подаване на един ред само. Това е полезно ако разглеждате голям брой подавания. Също така short, full, и fuller показват изхода по подобен начин но с по-малко или повече информация съответно:

$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit

Най-интересната стойност е format. Тя ви позволява да укажете ваш собствен изглед на отчета. Това е особено полезно когато създавате изход за автоматичен разбор. Тъй като вие сте задали изгледа изрично, знаете, че той няма да се промени при обновяване на Гит:

$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : changed the version number
085bb3b - Scott Chacon, 6 years ago : removed unnecessary test
a11bef0 - Scott Chacon, 6 years ago : first commit

Полезни стойности за git log --pretty=format изрежда някои от най-полезните стойности, които приема format.

Table 1. Полезни стойности за git log --pretty=format
Стойност Описание на Изхода

%H

Пълна SHA-1 сума на подаването

%h

Съкратена SHA-1 сума на подаването

%T

SHA-1 сума на дървото

%t

Съкратена SHA-1 сума на дървото

%P

Родителски SHA-1 суми

%p

Съкратени родителски SHA-1 суми

%an

Име на автора

%ae

Е-поща на автора

%ad

Дата на автора (изходът е съобразен с --date=стойност)

%ar

Дата на автора, относителна

%cn

Име на подаващия

%ce

Е-поща на подаващия

%cd

Дата на подаващия

%cr

Дата на подаващия, относителна

%s

Предмет (съобщение) на подаването

Може би се питате каква е разликата между автор и подаващ. Авторът е този, който първоначално е създал съдържанието, докато подаващ е този, който прилага промените. Така ако изпратите кръпка до някой проект и някой от участниците в проекта приложи вашата кръпка, всеки бива уважен – вие като автор и основния член на отбора като подаващ. Ще обърнем повече внимание на тази разлика в [_distributed_git].

Опциите oneline и format са особено полезни с друга една опция на командата log. Това е --graph. Този аргумент показва приятна ASCII графика с информация за историята на разклоняването и сливането:

$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 ignore errors from SIGCHLD on trap
*  5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
*  11d191e Merge branch 'defunkt' into local

Този изглед ще стане по-интересен, когато преминем към разклоняването и сливането в следващата глава.

Засегнахме само някои прости възможности за нагласяване изгледа на git log – има много повече. Често използвани възможности на git log изрежда възможностите, които засегнахме дотук, както и някои други общоизвестни и полезни възможности заедно с това как те променят изхода от командата log.

Table 2. Често използвани възможности на git log
Възможност Описание

-p

Показва кръпките, добавени с подаванията.

--stat

Показва статистика за променените файлове във всяко подаване.

--shortstat

Показва само променените/добавени/изтрити редове от командата --stat.

--name-only

Показва списък с променените файлове след съобщението за подаване.

--name-status

Показва списък с променените файлове и техните състояния – добавен/променен/изтрит.

--abbrev-commit

Показва само първите няколко знака от SHA-1 чексумата вместо всичките 40.

--relative-date

Показва датата в относителен формат (например, “преди 2 седмици”) вместо пълния формат за дата.

--graph

Показва ASCII графика на сливанията и клоновете отстрани на изхода от отчета за подаванията.

--pretty

Показва подаванията форматирани по различен начин. Възможностите са oneline, short, full, fuller, и format (в този случай указвате ваш формат).

Ограничаване изхода от отчета

Освен опциите за форматиране на изхода git log приема и някои опции за ограничаване на изхода, т.е за показване само на определен брой подавания. Вече видяхте една такава – опцията -2, която указва колко подавания да се изведат на екрана. Можете да зададете -<n>, където n е цяло число, за да покажете последните n. В действителност едва ли ще ползвате тази опция често, тъй като Гит прекарва изхода си през странираща програма и виждате само по една страница наведнъж.

От друга страна опциите за ограничаване по време --since и --until са много полезни. Следващата команда например показва списък с подаванията за последните две седмици.

$ git log --since=2.weeks

Тази команда работи с много формати. Можете да укажете отделна дата "2008-01-15" или относителна дата като "2 years 1 day 3 minutes ago".

Можете също да получите списък от подавания по някакъв критерий за търсене. Опцията --author ви позволява да изведете списък с подаванията на отделен автор, а опцията --grep ви дава възможност да търсите по ключови думи в съобщенията на подаванията. Забележете, че ако подадете и двете опции (--author и --grep) трябва да добавите също --all-match иначе командата ще изведе подаванията, които съответстват само на едната или само на другата.

Друг наистина полезен филтър е опцията -S, която приема низ като стойност и показва само подаванията, където е добавен или премахнат този низ. Например, ако желаете да намерите подаване, което добавя или премахва извикване на някоя функция, можете да напишете:

$ git log -Sfunction_name

Последното от полезните свойства на git log е възможността за подаване на път. Ако укажете папка или име на файл, ограничавате изхода от отчета до подавания, в които са променяни само файловете в указания път. Пътят се подава винаги последен и обикновено се предхожда с двойно тире (--), за да се отдели от опциите.

В Опции за ограничаване на изхода от git log показваме списък с тези и други опции, които можете да ползвате.

Table 3. Опции за ограничаване на изхода от git log
Опция Описание

-(n)

Показват се само последните n подавания.

--since, --after

Ограничаване на подаванията до направените след указаната дата.

--until, --before

Ограничаване на подаванията до направените преди указаната дата.

--author

Показват се само подавания, които съвпадат по поле „author“.

--committer

Показват се само подавания, които съвпадат по поле „committer“.

--grep

Показват се само подавания, чието съобщение съдържа търсения низ.

-S

Показват се само подавания, чиито промени съдържат търсения низ.

Например, ако искате да видите кои подавания, променящи файлове с изпитания (тестове) в изходния код на Гит са направени от Junio Hamano през октомври 2008, можете да изпълните следната команда:

$ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \
   --before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch

От около 40,000 подавания в историята на изходния код на Гит, тази команда показва шестте, съответстващи на заявката.

Отмяна на действия

По всяко време може да ви се прииска да отмените (undo) направена промяна. Тук ще разгледаме някои основни средства за отмяна на направени промени. Бъдете внимателни, защото не винаги ще можете да отмените отмените. Това е един от малкото случаи, в които можете да загубите част от свършената работа, ако подходите неправилно.

Едно от действията, които често бихте искали да отмените е, когато подадете файлове твърде рано и се сетите, че сте забравили да добавите някой файл към подаването. Друг случай е когато искате да промените съобщението в подаването. Ако искате да направите подаването отново, можете да изпълните командата commit с опцията --amend:

$ git commit --amend

Тази команда използва индекса за подаване. Ако не сте променяли нищо след последното подаване, то моментната снимка на проекта ви ще изглежда по същия начин и единственото, което ще промените, е съобщението.

Появява се същия редактор за промяна на съобщението, но вече съдържащ съобщението от последното подаване. Можете да промените съобщението. Това ще презапише предишното подаване.

Например, ако след като подадете, откриете, че сте забравили да добавите някои промени, можете да направите следното:

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

Сега имате само едно подаване – второто подаване замества първото изцяло.

Премахване на файл от индекса за подаване

Следващите две секции показват как да работите с индекса за подаване и промените в работната папка. Хубавото е, че командата, която използвате за определяне на състоянието на тези две области, също така ви подсказва как да отмените промените в тях. Да речем, че сте променили два файла и искате да ги подадете поотделно, но по погрешка написвате git add * и добавяте и двата. Как да извадите единия от индекса? Командата git status ви напомня.

$ git add *
$ git status
На клон master
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

    renamed:    README.md -> README
    modified:   CONTRIBUTING.md

Точно под текста “Промени, които ще бъдат подадени” се казва (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса). И така, да последваме съвета и да извадим CONTRIBUTING.md:

$ git reset HEAD CONTRIBUTING.md
Промени извън индекса след зануляването:
M	CONTRIBUTING.md
$ git status
На клон master
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

    renamed:    README.md -> README

Промени, които не са в индекса за подаване:
  (използвайте „git add ФАЙЛ…“, за да обновите съдържанието за подаване)
  (използвайте „git checkout -- ФАЙЛ…“, за да отхвърлите промените в работното дърво)

    modified:   CONTRIBUTING.md

Командата е малко странна, но работи. Файлът CONTRIBUTING.md остава променен но вече не е добавен за подаване.

Note

Командата git reset може да бъде опасна, но само ако добавите опцията --hard. В нашия случай файлът остава недокоснат от Гит. Просто внимавайте какви опции подавате.

Засега това заклинание с git reset ви стига. Ще засегнем подробно командата reset [_git_reset]. Там ще се научите на интересни хитрини с нея.

Отмяна на промени в променени файлове

Какво ще направите, ако не искате да запазите промените в CONTRIBUTING.md? Как ще го върнете лесно в първоначалното му състояние? За щастие git status отново ви казва как.

Промени, които не са в индекса за подаване:
  (използвайте „git add ФАЙЛ…“, за да обновите съдържанието за подаване)
  (използвайте „git checkout -- ФАЙЛ…“, за да отхвърлите промените в работното дърво)

    modified:   CONTRIBUTING.md

Обяснено е изрично как да премахнете направените промени. Да направим както казва:

$ git checkout -- CONTRIBUTING.md
$ git status
На клон master
Промени, които ще бъдат подадени:
  (използвайте „git reset HEAD ФАЙЛ…“, за да извадите ФАЙЛа от индекса)

    renamed:    README.md -> README

Виждате, че промените ги няма.

Important

Важно е да се разбере, че git checkout -- <file> е опасна команда. Всички промени, направени в този файл изчезват – Гит просто копира друг файл (последната подадена версия на същия – бел. прев.) върху него. Не използвайте тази команда освен ако със сигурност знаете, че не искате файла.

Ако искате да запазите промените, но да разкарате файла засега, ще обясним скатаването и създаването на клони в [_git_branching]. Те са по-добри начини за целта.

Запомнете, всичко подадено в Гит, почти винаги може да бъде възстановено. Дори подавания, във вече изтрити клони, или такива, които са променени с помощта на --amend, може да се възстановят (вижте [_data_recovery], за да узнаете как да възстановявате данни). Но всичко, което загубите, без да сте подали, няма как да възстановите.

Работа с отдалечени хранилища

За да работите с други хора по какъвто и да е проект в Гит, трябва да знаете как да управлявате отдалечените си хранилища. Те са версии на на проекта, намиращи се някъде в мрежата. Може да имате няколко такива, всяко от които е настроено само за четене или за писане и четене от вас. Да си сътрудничите с другите, означава да управлявате тези хранилища, като изтегляте и изтласквате подавания, когато искате да споделяте свършена работа. Сътрудничеството също изисква знания как да добавяте отдалечени хранилища и да ги премахвате, когато вече са ненужни, да управлявате отдалечени клонове и да ги указвате като следени или не, и т.н. В този раздел ще засегнем някои от тези умения.

Показване на отдалечените хранилища

За да видите кои отдалечени сървъри сте настроили, изпълнете git remote command. Тази команда показва списък с кратки имена за всяко хранилище. Ако сте клонирали текущото хранилище, би трябвало да видите поне origin – това е името, което Гит дава по подразбиране на хранилището, от което сте клонирали проекта:

$ git clone https://github.com/schacon/ticgit
Клониране и създаване на хранилище в „ticgit“…
remote: Counting objects: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0), pack-reused 1857
Получаване на обекти: 100% (1857/1857), 331.41 KiB | 184.00 KiB/s, действието завърши.
Откриване на съответните разлики: 100% (837/837), действието завърши.
$ cd ticgit
$ git remote
origin

Можете също да укажете -v. Така ще видите и адресите, съответстващи на краткото име и използвани за писане и четене от хранилището:

$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)

Ако имате повече от едно хранилище, командата показва всичките. Например проект с няколко отдалечени хранилища за работа с няколко сътрудници изглежда така.

$ cd grit
$ git remote -v
bakkdoor  https://github.com/bakkdoor/grit (fetch)
bakkdoor  https://github.com/bakkdoor/grit (push)
cho45     https://github.com/cho45/grit (fetch)
cho45     https://github.com/cho45/grit (push)
defunkt   https://github.com/defunkt/grit (fetch)
defunkt   https://github.com/defunkt/grit (push)
koke      git://github.com/koke/grit.git (fetch)
koke      git://github.com/koke/grit.git (push)
origin    git@github.com:mojombo/grit.git (fetch)
origin    git@github.com:mojombo/grit.git (push)

Това означава, че можем да изтегляме подавания от всеки един от тези потребители. Може би имаме разрешения и за изтласкване на наши подавания към тях, но изхода на командата не ни казва това.

Забележете, че тези хранилища използват различни протоколи. Ще научим повече за това в [_git_on_the_server].

Добавяне на отдалечени хранилища

Вече споменахме и показахме как командата clone мълчаливо добавя хранилището origin. Ето сега как да добавим ново далечно хранилище изрично. За да добавите ново хранилище с кратко име, което да използвате за улеснение, изпълнете git remote add <краткоиме> <адрес>:

$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)
pb	https://github.com/paulboone/ticgit (fetch)
pb	https://github.com/paulboone/ticgit (push)

Сега можете да използвате низа pb на командния ред вместо пълния адрес. Например, ако искате да доставите всички промени от Павел, които все още нямате във вашето хранилище, можете да изпълните git fetch pb:

$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
 * [new branch]      master     -> pb/master
 * [new branch]      ticgit     -> pb/ticgit

Главния клон master на Павел сега е достъпен при нас като pb/master – можете да го влеете в някой от вашите клони, или да го отпишете, за да го разгледате. (Ще разгледаме работата с клони по-подробно в [_git_branching].)

Доставяне и изтегляне от отдалечени хранилища

Току що видяхте, че за да вземете данни от отдалечено проекти, можете да изпълните:

$ git fetch [remote-name]

Командата отива и изтегля всички данни от отдалечения проект, който все още нямате. След като направите това, имате локален достъп до всички клони от това хранилище. Можете да ги слеете с ваши клони или да ги разглеждате по всяко време.

Ако клонирате хранилище, командата автоматично присвоява на хранилището името “origin”. Така git fetch origin доставя всичко ново, което е изтласкано към сървъра откакто сте клонирали (или сте доставили последния път). Важно е да се отбележи, че git fetch само доставя/сваля данните – тя не ги слива автоматично с вашата работа, нито пък променя файловете, по които работите в момента. Трябва ръчно да ги слеете, когато сте готови.

Ако текущият ви клон е настроен да следи отдалечен клон (вижте следващия раздел и [_git_branching]) можете да използвате git pull, за да доставите и автоматично да слеете отдалечения клон с текущия. Това е може би по-лесен или удобен начин на работа за вас. Освен това, git clone настройва главния ви клон да следи главния клон (както и да се нарича) на отдалеченото хранилище. Като изпълнявате командата git pull тя доставя данните и се опитва автоматично да слее новите промени с файловете, върху които работите.

Изтласкване към отдалечени хранилища

Когато проектът ви е в състояние, подходящо за споделяне, трябва да го изтласкате нагоре. Командата е проста: git push [remote-name] [branch-name]. Ако искате да изтласкате клона master към сървъра origin (при клонирането автоматично се създават тези имена), можете да изпълните следната команда, за да закарате всички подавания, които сте направили обратно към сървъра:

$ git push origin master

Тази команда работи само когато сте клонирали от сървър, до който имате достъп за писане и никой не е изтласкал междувременно. Ако вие и други клонирате хранилището и междувременно някой от тях изтласка натам, вашето изтласкване ще бъде отхвърлено. Ще ви се наложи първо да доставите тяхната работа и да я слеете с вашата, преди да ви бъде разрешено да изтласкате. Вижте [_git_branching] за подробности как се изтласква към отдалечени сървъри.

Разглеждане на отдалечено хранилище

Ако искате да видите повече относно някое хранилище, може да използвате командата git remote show [remote-name]. Ако изпълните командата с кратко име, получавате нещо подобно на следното:

$ git remote show origin
● отдалечено хранилище „origin“
  Адрес за доставяне: https://github.com/schacon/ticgit
  Адрес за изтласкване: https://github.com/schacon/ticgit
  клон сочен от HEAD: master
  Отдалечени клони:
    master следен
    ticgit следен
  Локални клони настроени за издърпване чрез „git pull“:
    master сливане с отдалечения клон „master“
    ticgit сливане с отдалечения клон „ticgit“
  Локалните указатели, настроени за „git push“:
    master изтласква към master (актуален)
    ticgit изтласква към ticgit (актуален)

Показват се адреса на отдалеченото хранилище и ведомост за следените клони. Командата услужливо ви казва, че ако се намирате на клона master и изпълните git pull, тя ще достави всички отдалечени указатели и влее в клона master отдалеченото му съответствие. Също така показва списък с всички доставени отдалечени указатели.

Това е прост пример, с които е възможно да се сблъскате. Когато използвате Гит повече обаче, най-вероятно изходът от git remote show ще е доста по-обемен:

$ git remote show origin
● отдалечено хранилище „origin“
  Адрес за доставяне: git@github.com:kberov/perl6intro.git
  Адрес за изтласкване: git@github.com:kberov/perl6intro.git
  клон сочен от HEAD: master
  Отдалечени клони:
    Modules         следен
    Parallel        следен
    RegEx           следен
    Unicode         следен
    master          следен
    updates-2017-01 следен
  Локални клони настроени за издърпване чрез „git pull“:
    master          сливане с отдалечения клон „master“
    updates-2017-01 сливане с отдалечения клон „updates-2017-01“
  Локалните указатели, настроени за „git push“:
    master          изтласква към master          (може да се превърти)
    updates-2017-01 изтласква към updates-2017-01 (актуален)

Тази команда показва кой клон ще бъде автоматично изтласкан ако изпълните git push докато сте на съответния клон. Също така показва кои отдалечени клони нямате все още, кои клони са на компютъра ви, но вече са премахнати на сървъра и клони, които можете да слеете автоматично със следените съответни отдалечени клони, когато изпълните git pull.

Премахване и преименуване на отдалечени хранилища

Можете да изпълните git remote rename, за да промените краткото име на отдалечено хранилище. Например ако искате да преименувате pb на paul, можете да го направите чрез git remote rename:

$ git remote rename pb paul
$ git remote
origin
paul

Трябва да отбележим, че това променя и имената на отдалечените клони. Това, което е указвано до сега с pb/master сега е paul/master.

Ако по някаква причина искате да премахнете някое отдалечено хранилище – преместили сте сървъра или повече не използвате дадено огледало, или пък някои сътрудник се е оттеглил – можете да използвате git remote remove или git remote rm.

$ git remote remove paul
$ git remote
origin

Отбелязване

Както повечето СУВ, Гит може да отбелязва (tag) отделни етапи в историята като важни. Обикновено тази способност се използва за отбелязване на издания (v1.0,v1.1 и т.н.). В този раздел ще научите как да показвате списък с наличните отбелязвания (етикети), как да създавате нови и какви са различните типове етикети.

Извеждане на списък с етикети

Да видите списъка с наличните етикети е лесно. Просто напишете git tag:

$ git tag
v0.1
v1.3

Тази команда извежда списък с етикетите в азбучен ред. Редът, в който се показват, няма особено значение.

Можете също да търсите етикети по определен образец. Хранилището на Гит има над 500 етикета. Ако искате да видите само поредицата от 1.8.5, изпълнете следното:

$ git tag -l "v1.8.5*"
v1.8.5
v1.8.5-rc0
v1.8.5-rc1
v1.8.5-rc2
v1.8.5-rc3
v1.8.5.1
v1.8.5.2
v1.8.5.3
v1.8.5.4
v1.8.5.5

Създаване на етикети

Гит използва два главни типа етикети: леки (lightweight) и с бележки (annotated).

Лекият етикет е като клон, който не се променя – представлява просто указател към определено подаване.

Етикетите с бележки пък се съхраняват като пълни обекти в базата данни на Гит. Те имат чек-суми. Съдържат името на човека, създал етикета, адресът му за електронна поща и дата. Също така съдържат съобщение и могат да бъдат подписани с GNU Privacy Guard (GPG). Като цяло се препоръчва да се създават етикети с бележки, за да имате цялата ведомост. Ако все пак искате да създадете само временен етикет или по някаква причина не ви трябва нищо повече, леките етикети вършат работа.

Етикети с бележки (анотирани)

Създаването на етикет с бележки е лесно. Най-лесно е да добавите опцията -a, когато изпълнявате командата tag:

$ git tag -a v1.4 -m "my version 1.4"
$ git tag
v0.1
v1.3
v1.4

-m задава съобщение (message), което се съхранява с етикета. Ако не зададете съобщение, Гит пуска редактор, за да ви даде възможност да го въведете.

Можете да видите данните за етикета, като използвате командата`git show`:

$ git show v1.4
tag v1.4
Tagger: Ben Straub <ben@straub.cc>
Date:   Sat May 3 20:19:12 2014 -0700

my version 1.4

commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

Виждат се ведомостта за етикетиращия, датата, когато подаването е етикетирано и съобщението на бележката, преди направените промени.

Леки етикети

Друг начин да се отбележат подавания е чрез лек етикет. Състои се само от чек-сумата на подаването, записана във файл. Нищо повече не се пази. За да създадете лек етикет, не предоставяйте опциите -a, -s или -m.

$ git tag v1.4-lw
$ git tag
v0.1
v1.3
v1.4
v1.4-lw
v1.5

Сега, ако изпълните git show с името на етикета, не се показва нищо повече. Виждаме само подаването:

$ git show v1.4-lw
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

Отбелязване по-късно

Можете да отбележите подавания, след като сте направили други. Да речем, че историята ви изглежда така:

$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
4682c3261057305bdd616e23b64b0857d832627b added a todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme

Да предположим, че сте забравили да отбележите версията v1.2, която е подаването “updated rakefile”. Можете да направите това по-късно. За да отбележите подаването, указвате чек-сумата (или част от нея) в края на командата.

$ git tag -a v1.2 9fceb02

Виждате, че сте отбелязали подаването:

$ git tag
v0.1
v1.2
v1.3
v1.4
v1.4-lw
v1.5

$ git show v1.2
tag v1.2
Tagger: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Feb 9 15:32:16 2009 -0800

version 1.2
commit 9fceb02d0ae598e95dc970b74767f19372d61af8
Author: Magnus Chacon <mchacon@gee-mail.com>
Date:   Sun Apr 27 20:43:35 2008 -0700

    updated rakefile
...

Споделяне на етикети

По подразбиране git push не качва етикетите на отдалечения сървър. Трябва изрично да изтласкате етикетите към споделения сървър, след като ги създадете. Това действие е същото като споделянето на отдалечени клони. Изпълнете git push origin [tagname].

$ git push origin v1.5
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 2.05 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
 * [new tag]         v1.5 -> v1.5

Ако имате много етикети, които искате да изтласкате наведнъж, можете да използвате опцията --tags към командата git push. Това ще занесе всички етикети (които не са вече там) на отдалечения сървър.

$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 160 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
 * [new tag]         v1.4 -> v1.4
 * [new tag]         v1.4-lw -> v1.4-lw

Сега, когато някой изтегли от вашето хранилище, ще получи и етикетите.

Отписване на етикети

Всъщност, да се отпише (check out) етикет в Гит, е невъзможно, тъй като етикетите не могат да бъдат променяни. Ако искате да вземете някоя версия, която изглежда като определен етикет, в работната си папка, можете да създадете нов клон от дадения етикет чрез git checkout -b [branchname] [tagname]:

$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'

Разбира се, ако подадете промени, клонът version2 ще се различава от v2.0.0, така че бъдете внимателни.

Псевдоними в Гит

Като завършек на главата "Основи на Гит", остана един малък съвет, който ще опрости и улесни опита ви с Гит – псевдонимите (aliases). Няма да ги използваме нататък, нито ще очакваме вие да ги използвате, но най-вероятно трябва да знаете как.

Гит не отгатва автоматично командата, ако не сте я дописали. Ако не искате да пишете целия текст на командите, можете да настроите псевдоними за всички команди чрез git config. Ето няколко примера, които може да ви харесат:

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status

Така, вместо да пишете git commit, ще можете да напишете само git ci. По-нататък сигурно ще ползвате и други команди често. Не се колебайте да си направите псевдоними и за тях.

Този прийом може да бъде използван и за команди, които смятате, че е добре да съществуват. Например, за да обезопасите премахването на файлове от индекса за подаване, може да създадете команда unstage:

$ git config --global alias.unstage 'reset HEAD --'

Това прави следните две команди еднакви:

$ git unstage fileA
$ git reset HEAD -- fileA

Така ви става по-ясно какво правите. Често се създава и командата last. Ето така:

$ git config --global alias.last 'log -1 HEAD'

По този начин лесно разглеждате последното подаване:

$ git last
commit 66938dae3329c7aebe598c2246a8e6af90d04646
Author: Josh Goebel <dreamer3@example.com>
Date:   Tue Aug 26 19:48:51 2008 +0800

    test for current head

    Signed-off-by: Scott Chacon <schacon@example.com>

Както виждате, Гит просто замества новата команда с истинската. Понякога може да искате да изпълните външна команда вместо подкоманда на Гит. В този случай започвате командата с удивителен знак – !. Това е полезно, когато разработвате ваши собствени средства за управление на хранилища. Ето пример как да заместите gitk с git visual:

$ git config --global alias.visual '!gitk'
Note

Обстойно описание и съвети относно създаването на псевдоними и ваши собствени команди можете да намерите на адрес https://git.wiki.kernel.org/index.php/Aliases (бел. прев.).

Обобщение

Сега владеете всички основни действия в Гит – създаване или клониране на хранилище, правене на промени, добавяне и подаване на промените, както и да разглеждате историята на промените в хранилището. В следващата глава ще се запознаем с най-важната отличителна черта на Гит – моделът за разклоняване.


1. На английски понятията са "staging area" и "index". (бел. прев.)