16. Git, част 2
1 декември 2014
Първи тест тази сряда
организация
- На 3 декември, вместо лекция, в зала 200
- Ще бъдете разделени на две групи
- Четни факултетни номера са от 19:00, нечетни - от 20:00
- Ако някой не може в дадения час, да ни пише, за да се уговорим друго
Първи тест тази сряда
структура
- 30 затворени въпроса
- 45 минути
- Верен отговор = 1 т.; грешен = 0 т.
- Има два теста, носят по максимум 30 точки всеки
- Вторият тест ще е в края на семестъра и/или по време на сесията
Първи тест - материал и подготовка
- Ще включва материал, предаден до днес, включително
- За подготовка, прочетете слайдовете внимателно
- Ако ви изскочи нещо, което не разбирате, питайте във форумите, или ни пишете
Следващи домашни
- Преди теста в сряда няма да ви даваме други домашни
- Тази седмица най-много да пуснем едно предизвикателство четвъртък-петък
- Следваща задача ще има следващата седмица
Оставащ материал
- Web с Ruby, Sinatra
- Може би Rails, ако има достатъчно желаещи - може да пуснем една анкета за/против
- Ruby core & stdlib
- Конкурентност и паралелно програмиране в Ruby
- Алтернативни Ruby имплементации
- Още code spelunking
- GUI, UI, Gosu, Shoes и каквото друго ви е интересно
- Вие като лектори?
Въпрос 1
За какво се използва staging областта?
Съхранява файловете, които ще бъдат добавени в следващия commit.
Въпрос 2
Как можем да видим списък от направените commit-и? Ами да разгледаме промените, направени в commit?
Въпрос 3
Можем ли да променим commit обект?
Не, защото ще му се промени хешът. Можем да създадем нов, който да заеме неговото място.
Въпрос 4
Какво е branch?
- Разклонение на кода
- История от commit-и
- Файл, съдържащ хеш на commit
Сливане на разклонения
git merge killer-feature
git merge --squash killer-feature
- Слива промени от (най-често) 2 клона
- Често създава нов commit
Различни стратегии на сливане. Основните са 2:
Fast-Forward стратегия
Просто премества указателя за клона
Fast-Forward стратегия
Просто премества указателя за клона
Recursive стратегия
Слива 2 разделили се клона с обща история.
Recursive стратегия
Жълтото e merge commit-a. Той съдържа промените и от двата клона.
Обновяване 2
git pull == git fetch && git merge origin/master
- Изтегля промените и ги слива с текущия бранч
Изтриване на branch
git branch -d killer-feature
git push origin --delete killer-feature # Ако сте го push-нали
git push origin :killer-feature # В по-стари версии
- Премахва само файла на branch-a, commit-ите се пазят
- Дори ако е останал commit, който е извън историята, пак може да се възстанови
- За възстановяване - след малко
Изтриване на branch
Типичен процес на работа
Заради "евтините" branch-ове на git можем да направим следното:
- Имаме два основни branch-a -
master
и develop
(internal
, unstable
или както го кръстите)
- Когато започваме нова функционалност, правим branch специално за тази промяна
- Когато приключим, я качваме в
develop
с git merge
- В
develop
нещата се тестват и след определено време се сливат с master
Типичен процес на работа
Типичен процес на работа
Резултат
- В
master
имаме само стабилни промени
- В
develop
имаме новите функции, които не са достатъчно тествани
- Ако две нови функции си пречат, това може да се поправи, преди да влязат в стабилната версия
- Ако трябва бързо да поправим нещо в стабилната версия на кода, можем директно да направим commit в
master
Машината на времето
Или как да върнем "безвъзвратно" загубените промени.
git reset
git checkout
git commit --amend
git revert
git reflog
Машината на времето
git reset <commit> <files>
git reset HEAD lectures/git.slim
- Променя файлове в staging областта, като ги взима от хранилището
- В случая
HEAD
указва от кой точно commit да се вземат файловете. Там може да има и хеш на commit
- Не променя файловете в работната директория
- Използва се, когато не искате да commit-вате файл, но да запазите локалните промени
- С
—hard
променя и работната директория
Машината на времето
git checkout <files>
git checkout <commit> <files>
git checkout <branch> <files>
- Променя файлове в работната директория, като ги взима от staging областта...
- ... или от определен commit.
- Внимание! Може да изгубите код!
Машината на времето
git commit --amend
git push --force # Ако вече сте push-нали
- Променя последния commit. А дали наистина?
- Всъщност създава нов commit със същия предшественик
- Старият commit все още може да бъде възстановен
- Удобно е за поправяне на грешки в съобщението или добавяне на изпуснати файлове
- Не е хубаво да се прави, ако вече сте push-нали, защото някой друг може да е направил pull и ще има конфликт
Машината на времето
- Премахва промените, направени от
commit
- Всъщност създава нов commit, който прави същото като
commit
, но наобратно
- Разбирайте, където има
+
в diff-a, става на -
и обратно
- Ако все пак решите, че искате тези промени, можете да revert-нете revert commit-a
Машината на времето
- Показва ви последните операции, които сте правили, заедно с ID-та на разни обекти
- Можете да намерите ID-тата на изгубени commit-и и да ги възстановите
- Понякога се чисти
Игнориране на файлове
.gitignore
- Често има файлове, които не искаме git да следи
- Например компилирани двоични файлове, временни файлове, конфигурационен файл с API ключове и т.н.
- Всеки ред в
.gitignore
е шаблон за файлове/директории, които трябва да бъдат игнорирани
- Това означава, че няма да се виждат в
git status
Игнориране на файлове
Формат на .gitignore
/bin # Файла/директорията bin в главната директория на проекта
bin # Всички файлове и директории с име bin
bin/ # Всички директории с име bin
compiled/*.html # Всички файлове с разширение html в compiled-lectures
lib/**/*.txt # Всички текстови файлове в lib или нейна поддиректория
*.exe # Всички изпълними файлове за Windows
Git rebase
Най-мощният инструмент за пренаписване на историята
git checkout killer-feature
git rebase master
git rebase -i master
git rebase -i HEAD~4
git pull --rebase
- Пресъздава промените от текущия branch, все едно са направени върху сегашното състояние на
master
- С -i ви позволява да си премахнете, промените или слеете (squash) commit-и от историята
- Трябва да направите
git push —force
, ако вече сте push-нали branch-a, който променяте
- Отново - избягвайте да го правите, ако промените вече са публикувани
Git blame
"Кой написа това?"
git blame lectures/index.yml
Акценти
git add
, git commit
git push
, git pull
git checkout
git merge
, git rebase -i
git reflog
Защо git по този начин?
- Елегантно решение на сложен проблем
- Научавайки как работи на по-ниско ниво, ще ви помогне да се ориентирате
- Конзолният интерфейс е сложен, но ще разбирате какво става "под капака"
Изводи
- Няма да минете без него...
- ...затова започвайте да го използвате...
- ...с терминала - научават се много неща.
- Може да ви се струва труден - не е
Искайте помощ:
git command —help
man git
man git-command
Графичен интерфейс
GitX
Графичен интерфейс
TortoiseGit
Графичен интерфейс
GitHub
Материали
- Добър туториал за начинаещи с терминалния интерфейс - Try git
- Безплатна книга с много подробни обяснения - Pro Git
- Инструкции за създаване на pull request в GitHub - Guide
- Интерактивна визуализация на команди - Explain Git (забележка: някои неща не са 1:1 с реален Git)
Въпроси по Git?
Сега е добър момент да ги зададете.