Git — е разпределена система за контрол на версиите с отворен код, създадена от Линус Торвалдс през 2005 г. за разработка на ядрото на Linux. За разлика от централизираните системи като SVN, Git съхранява пълно копие на хранилището на всяко устройство на разработчика, което позволява работа без постоянна връзка със сървъра. Според данни на Git SCM, 2024, Git се използва в повече от 90% от всички търговски проекти за разработка на софтуер.
Основни точки
Git — е разпределена система за контрол на версиите (VCS), която проследява промените във файловете и позволява на няколко разработчика да работят едновременно по един проект. За разлика от централизираните системи, в Git всеки разработчик има пълно копие на хранилището, включително цялата история на промените, което прави системата устойчива на загуба на данни и не изисква постоянна връзка с централния сървър.
Историята на Git започва през 2005 г., когато Линус Торвалдс създава нова VCS, след като компанията BitKeeper оттегля безплатния лиценз за своята система за разработчиците на ядрото на Linux. Целите бяха: скорост, простота на архитектурата, поддръжка на нелинейна разработка чрез клонове и пълна разпределеност. За 3 месеца Торвалдс написва ядрото на Git, а след една година проектът преминава към самоуправление под ръководството на Джунио Хамано.
Според проучване на Stack Overflow (2024), 93,9% от професионалните разработчици използват Git, което го прави доминиращата система за контрол на версиите в индустрията. Най-близкият конкурент — Subversion (SVN) — се използва само в 5,2% от проектите, предимно в големи корпоративни среди с централизирани процеси.
Git хранилище — директория, в която Git проследява промените на всички файлове. Вътре в директорията се намира скрита папка .git, където се съхраняват всички обекти на системата: комити, дървета, блокове и референции. Когато разработчик създаде комит, Git не копира файловете изцяло — той създава моментна снимка (snapshot) на състоянието и запазва референция към нея.
Всеки комит съдържа: уникален SHA-1 хеш (40 символа), референция към предишния комит (parent), автор, дата, съобщение на комита и референция към дърво (tree), което описва състоянието на файловете в момента на комита. Веригата от комити образува насочен ацикличен граф, където всеки комит сочи към един или повече родители.
# Инициализиране на хранилище
git init my-project
cd my-project
# Създаване на комит
echo "Hello, Git" > README.md
git add README.md
git commit -m "Initial commit"
# Преглед на история
git log --oneline --graph --all
Git използва три основни области: working directory (файлове на диска), staging area (индекс, където попадат подготвените файлове) и repository (история на комитите). Командата git add премества промените от работната директория в staging, а git commit записва съдържанието на staging в хранилището. Това разделение позволява на разработчика да състави смислен комит от набор от промени, без да записва всяка корекция поотделно.
Основните команди на Git покриват 90% от ежедневните операции на разработчика. Командата git clone създава локално копие на отдалечено хранилище, git pull изтегля промени от сървъра и ги слива с текущия клон, а git push изпраща локални комити на сървъра. Тези три команди формират основния цикъл на работа с Git.
За преглед на състоянието се използва git status — показва кои файлове са променени, кои са добавени в staging и кои не се проследяват. git diff показва конкретни промени във файловете преди добавяне в staging. По-долу е таблица с най-често използваните команди:
| Команда | Действие | Пример |
|---|---|---|
| git clone | Копира отдалечено хранилище | git clone https://example.com/repo |
| git add | Добавя файлове в staging | git add src/main.kt |
| git commit | Записва промените в историята | git commit -m "Fix login bug" |
| git push | Изпраща комити на сървъра | git push origin main |
| git pull | Изтегля промени от сървъра | git pull origin feature |
За отмяна на промени Git предлага няколко опции. git reset премества указателя на клона към зададен комит и може да нулира staging или работната директория. git revert създава нов комит, който отменя промените на посочения комит — това е безопасен начин за отмяна за споделени клонове, тъй като историята не се презаписва.
Клоновете в Git — леки преместваеми указатели към определен комит. Създаването на нов клон не копира файлове, а само създава нов указател, което прави разклоняването практически моментално. Клонът main (преди master) — основният клон на проекта, който съдържа стабилен, готов за издаване код.
Стандартната практика е използването на Git Flow или GitHub Flow. В Git Flow се използват клонове: main (код за издаване), develop (интеграционен клон), feature/* (нови функции), release/* (подготовка на издания) и hotfix/* (спешни корекции). GitHub Flow е по-прост: само main и feature клонове, а всички промени се доставят чрез Pull Request.
# Създаване и превключване на клон
git branch feature-auth
git checkout feature-auth
# или с една команда:
git checkout -b feature-auth
# Списък на клонове
git branch --list
git branch -a # все ветки, включая удалённые
# Изтриване на клон
git branch -d feature-auth
Важно свойство на клоновете в Git — възможността за cherry-pick: прехвърляне на отделен комит от един клон в друг с командата git cherry-pick <hash>. Това е полезно, когато трябва да прехвърлите корекция на грешка от feature клон в release без сливане на целия клон. Git също поддържа rebase и интерактивен rebase (git rebase -i) за слепване, пренареждане и редактиране на комити.
Merge (сливане) създава специален merge-комит, който има двама родители. Този комит записва факта на обединяване на два клона и запазва пълната история — вижда се къде и кога е станало сливането. Merge запазва историята във вида, в който е създадена, което опростява одита, но прави графа на комитите по-сложен.
Rebase (пребазиране) вместо да създава merge-комит, премества комитите на текущия клон върху върха на целевия клон. Историята става линейна — създава се впечатление, че разработката е протичала последователно. Въпреки това, rebase презаписва историята, променяйки SHA-1 хешовете на комитите, което го прави опасен за споделени клонове, до които имат достъп други разработчици.
Препоръка за избор: използвайте merge за публични клонове, където историята се вижда от други разработчици (feature → develop), и rebase за локална работа, когато трябва да приложите свежи промени от main във вашия feature клон преди създаване на Pull Request. Правилото е просто: ако комит вече е изпратен на сървъра — не го пребазирайте.
Конфликт при сливане възниква, когато Git не може автоматично да обедини промените в един файл. Git маркира конфликтните участъци във файла със специални маркери: <<<<<<< (нашите промени), ======= (разделител), >>>>>>> (техните промени). Разработчикът ръчно редактира файла, избира желания вариант или комбинира и двата, и завършва сливането с комит.
Отдалечено хранилище (remote) — копие на Git хранилище, което се намира на сървър. GitHub, GitLab и Bitbucket са най-популярните платформи за хостинг на отдалечени хранилища. Те предоставят уеб интерфейс за преглед на код, управление на достъпа, преглед на код и интеграция с CI/CD системи.
В Git могат да се конфигурират няколко отдалечени хранилища за един проект. По подразбиране основното remote се нарича origin. Командата git remote add добавя ново remote, git fetch изтегля промени без сливане, а git pull е съкращение за git fetch + git merge. За работа с код чрез Pull Request, разработчикът създава fork на хранилището, клонира го, работи във feature клон и изпраща заявка за сливане в оригиналното хранилище.
# Добавяне на отдалечено хранилище
git remote add origin https://github.com/user/repo.git
# Преглед на отдалечени хранилища
git remote -v
# Изпращане на клон към сървъра
git push -u origin feature-auth
# Изтегляне на промени от отдалечен клон
git pull origin main
Отдалечените хранилища поддържат етикетиране за маркиране на версии за издаване. Етикетите могат да бъдат леки (просто указател към комит) и анотирани (съдържат метаданни: автор, дата, съобщение). Анотираните етикети се препоръчват за версии за издаване, тъй като предават пълна информация за версията и могат да бъдат подписани с GPG ключ за верификация на авторството.
Git Worktree позволява едновременна работа с няколко клона в различни директории без превключване между тях. Командата git worktree add ../feature-auth feature-auth създава нова работна директория feature-auth, където можете да пишете код без да сменяте клона в основната директория. Worktree е полезен за бързи корекции в release клон, когато основната директория е заета с дългосрочна разработка.
Git Submodules — механизъм за включване на едно Git хранилище в друго. Подмодулът съхранява референция към фиксиран комит на външно хранилище, което гарантира възпроизводимост на компилацията. Командата git submodule add https://github.com/example/lib.git добавя външна библиотека като подмодул. При клониране на проект с подмодули трябва да се изпълни git submodule update --init --recursive за зареждане на всички зависимости.
Често задавани въпроси
Git — разпределена VCS с локална история и възможност за офлайн работа. SVN — централизирана система, изискваща постоянна връзка със сървъра за всички операции освен преглед на файлове.
Използвайте git revert HEAD за безопасно отмяна (създава се нов комит). Ако комитът все още не е изпратен на сървъра, можете да използвате git reset --soft HEAD~1.
.gitignore — файл, в който са изброени модели на файлове и директории, които Git трябва да игнорира. Използва се за изключване на временни файлове, компилации и IDE конфигурации от хранилището.
git fetch изтегля промени от сървъра, но не ги слива с текущия клон. git pull прави fetch и веднага изпълнява merge. За контрол използвайте fetch + преглед на diff, след това ръчен merge.
Използвайте git commit --amend — тази команда отваря редактор за промяна на съобщението на комита. Ако комитът вече е на сървъра, ще е необходимо git push --force, което е опасно за споделени клонове.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също