ВАМ ПРИВЕТ
Advanced GIT :
Старое по новому
You are Ready?
Alexander Babenko (HuktoDev)
iOS Developer
Improve Digital
Зачем нам это нужно?
• Клиенты с GUI не всегда способны разрешить некоторые
кейсы
• Настройка Деплой-Машины (Jenkins)
• Создание shell script-ов (.sh)
• Абстракции бывают дырявы, и мы обязаны знать, что
там, под капотом (under the hood)
• Это круто, это для хардкорщиков ;)
Table of Contents :
1. Git Snapshotting (Git files)
2. Git Stash
3. Git Flow
4. Git Submodule
5. Git Remote
6. Git LFS
7. Git Reset/Revert
8. Git Flags
9. Git BONUS
GIT Files :
Work with index & git trees
Все файлы в репозитории делятся на 4 типа :
Наличие файла в папке еще не означает, что он отслеживается
VCS (прикреплен к репозиторию)
git add (добавление файла) (stage file в SourceTree)
git rm (удаление файла) (unstage file в SourceTree)
git mv (перемещение/переименование файла)
git status
git add
Используется в 2х случаях
• Мы создали новый файл, и хотим также добавить его в репозиторий, чтобы он был в
следующем commit-е
• Мы изменили файл (он теперь помечен, как modified), и хотим, чтобы изменения с ним
были в следующем commit-е
git rm
Используется в 2х случаях :
• Мы удалили файл физически на локальной машине, но к сожалению, файл в удаленном
репозитории не удалится автоматически при коммите. Нужно удалить файл и с помощью
команды git rm, чтобы у нас не плодились dummy-объекты
• Мы хотим перестать отслеживать файл, и внести его в .gitignore. В этом случае правильнее
предварительно его потереть из репозитория через git rm
git status
Используется в 1м случае :
- Мы хотим посмотреть на текущее состояния файлов репозитория. Нам покажет :
✦Какие файлы модифицированы, и изменения “подтверждены” для следующего commit-а
✦ Где произошли изменения, но они пока не добавлены в next commit
✦ Состояния других файлов
git stash
Наша файловая «заначка»
git stash
Наша файловая «заначка»
• git stash - быстро убираем все модифицированные файлы, но
сохраняем их в специальное место, чтобы их можно было
применить в другом месте
• git stash apply - применяем изменения в нужном месте (не
забываем про совместимость и мерджи)
• git stash apply $stashname - применяем конкретный
изменения
• git stash list - показать список «заначек»
• git stash show $stashname - смотрим, что находится в
конкретной заначке
• git stash drop - удаляем конкретную заначку
•
git stash pop $stashname - применяем изменения, и сназу
удаляем «заначку»
• git stash clear - удаление всех заначек
git stash
Extended capabilities
Автоматические stash-и имеют названия по типу stash@{x}
git stash branch $branchname $stashname - Создание новой ветки,
вместе с применением спрятанных файлов к ней
git stash —keep-index - Создание стэша без изменения индекса в
текущей ветке
git stash —include-untracked - Создание стэша, включая файлы, не
добавленные в индекс (к которым еще не был применен git add)
git stash —patch - Прикольный интерактивный режим, который
последовательно пройдется по всем hunk-ам, и спросит, что с
каждым конкретно делать
git stash save $identifyMessage - Создать стэш с собственным
сообщением (увы, название мы менять не можем)
git stash
Hints and Usage ways
Юзабельная последовательность команд, если забыл сделать pull remote branch, и
уже есть собственные изменения
git stash
git pull
git stash pop
• Можно хранить несколько вариантов конкретной фичи
• Перенос функциональности в другую ветку
• Один из способов отменить изменения в индексе (похоже на git reset —mixed
HEAD)
• Забыл сделать feature ветку, и делал изменения в develop-е
git flow
Rules for GoodStyle. Why?
• Выход на более высокие уровни абстракции -> 2У : Упрощение + Удобство
• git flow - это фасад с наиболее общими взаимодействиями
• Это и свод правил, и определенная философия разработки
git flow
Rules for GoodStyle. Why?
How use?
git flow инсталлится вручную с помощью пакетного менеджера :
brew install git-flow-avh
Набор эквивалентных команд для работы с git flow из командной строки :
git flow init
git flow feature start MYFEATURE
git flow feature finish MYFEATURE
git flow feature publish MYFEATURE
git flow feature pull origin MYFEATURE
Схожие наборы команд имеются для :
git flow release
git flow hotfix
Великолепная шпаргалка по git flow :
http://danielkummer.github.io/git-flow-cheatsheet/index.ru_RU.html
git submodule
Тайные зависимости вашего проекта
git submodule
Private dependencies in practice
• Один из способов управления зависимостями. Благодаря Cocoapods и Carthage
используется редко, но практически незаменим в случае приватных корпоративных
фреймворков и наборов утилит.
• Кроме того, не требует дополнительной настройки, по сравнению с созданием pod spec
файла
• Физически создается файл .gitmodules, который можно модифицировать (под
версионным контролем)
Родительский модуль не видит папку с содержимым подмодуля, он знает :
A.Ссылку на репозиторий с сабмодулем
B.Конкретный хэш коммита
C.Индекс (изменения, совершенные нами в сабмодуле)
• Один из ключевых плюсов сабмодуля - возможность гибко выбирать подходящий коммит
подпроекта
• Сабмодуль по-умолчанию использует свой указатель (detached HEAD) - чтобы при
клонировании родительского проекта другой разработчик мог получить идентичный
проект
• Совсем огонь, если хранить разные части проекта в разных репозиториях, и собирать все
это сабмодулями
• Если мы планируем какие-то изменения сабмодуля - переходим на свою ветку с помощью
git checkout -b $branchName
• Я не нашел внятного гайда по работу с проектом с multiple submodules
При добавлении сабмодуля первый раз
git submodule add $repoUrl $diskPath
После клонирования проекта другим разрабом
git submodule init
git submodule update (используется и для подтягивания последних
изменений в подпроекте)
git submodule status
git submodule deinit - детач конкретного сабмодуля
git submodule update
—merge/—rebase (так как это работает, как git pull - нужно иногда выбрать
соответствующую манипуляцию)
—init (можно подтянуть субпроект одной строкой)
git submodule sync - подтягивают изменения в .gitmodules и конфиг-файле
git submodule update —init —recursive —remote (полное обновление всех
сабмодулей, рекурсивно с сабмодулями сабмодулей)
git submodule foreach 'git stash’ - способ совершить какую-то команду,
применительно сразу ко всем сабмодулям (похоже на цикл из C#)
git remote
Мультирепозиторность
git remote
Мультирепозиторность
• - Удаленных репозиториев может быть больше, чем один
• - Основной удаленный всегда называется origin (оригинал)
• - Это одна из причин, почему с операциями push/pull/fetch так-же можно
указывать имя репозитория (по дефолту там - origin)
• Example : git push origin master или git push $repoName master
• Когда это может пригодиться :
• - Переезд оригинального репозитория на другой URL
• - Sync сразу с двумя репозиториями
• - Один репозиторий для READ, другой - для WRITE
• - Для огромных проектов и огромной команды возможна распределенная
система вторичных “узловых” репозиториев, которые периодически
мерджат, ревьюят и синхронизируют назначенные лиды в первичный origin
репозиторий
• - Вы использовали https, но хотите использовать SSH для большей
секьюрности, и хотите просто и быстро перебиндить URL-ы
• - GIT представляет набор команд для менеджмента набора репозиториев
(включая CRUD-интерфейс)
Команды git remote :
git remote -v
Посмотреть набор известных репозиториев
git remote add $repoName $url
Добавить информацию о новом удаленном репозитории
git remote rename/remove …
Переименование и удаление
git remote show $repoName
Показывает информацию о конкретном удаленном репозитории. Показывает то, какие
ветки у нас подтянуты в нашем репозитории, а какие нет, и др. инфо
git remote get-url $repoName
Получить текущий URL конкретного репозитория
git remote set-url (—add/—delete) $repoName $url
Изменить URL для конкретного репозитория (и еще некоторые странные операции)
git remote set-head
Устанавливает ветку по-умолчанию (чтобы не писать каждый раз git push origin
$branchName)
Git LFS
Великая сила - это великая ответственность и … множество
ограничений.
Git LFS
Великая сила - это великая ответственность и … множество
ограничений.
• Когда репозитории становятся большими, и их становится много - хорошей
идеей будет - снизить нагрузку на сервер с git-ом (большие затраты на
клонирование + big data). Рекомендуется начинать этим заниматься, если repo
> 1GB
• Когда вы хотите иметь более удобный интерфейс для управления
версионностью ресурсов
• Вы хотите оптимизировать выполнение операций
• Если вы пользуетесь Github-ом : он не позволяет иметь проекты > 200 МБ для
Free User-ов, и Git LFS входит в одно из его Premium предложений
- Позволяет быстро клонировать “огромные” проекты - выполнять операции по
типу git checkout, git add, git commit, git clone, git pull
Принцип работы :
• Создаются специальные pointer(reference)-файлы
• Используется специальный отдельный LFS Storage
• В некоторых случаях нужно в настройках веб-формы GIT-сервера включить
LFS
Имеются похожие аналоги : git annex , git fat
How to use :
Прежде всего - скачать :
brew install git-lfs
git lfs install / uninstall
Инициализировать LFS-репозиторий (или наоборот)
git lfs track / untrack $filePath
Добавить/Удалить файл из LFS (можно использовать маски)
git lfs ls-files / git lfs status
Команды для инспекции текущей ситуации
Кроме всего прочего - имеет набор команд по типу fetch /
checkout / clone / push / pull
git reset / git revert
Назад в будущее
Эмметт Браун: Это мой старый HEAD?
Марти МакФлай: Да, сейчас коммит 9e5e6a4.
Эмметт Браун: Прекрасно! Эксперимент удался! Оно
переместилось ровно на 2 коммита!
Марти МакФлай: Погоди-ка… минуточку, Док! Сейчас что,
9e5e6a4?
Эмметт Браун: Именно!
git reset / git revert
Казнить, нельзя помиловать
- Порой мы хотим отменить собственные или чужие
решения
git reset - отменяет изменения, удобным образом
работая с
а) HEAD-ом
б) индексом
в) текущим Workflow (песочницей)
git revert - выполняет commit, содержащий undo-
действия для конкретного выбранного другого
коммита. (Если мы создали файл - то revert удалит
его в новом коммите)
Твое лицо, когда ты узнал, что действия в git-е
можно обращать вспять :
git reset / git revert
Казнить, нельзя помиловать
git reset —soft / —mixed / —hard $commitName $filePath
- Можно даже сливать коммиты
- Использование флага hard - принудительно удаляет все
изменения после выбранного коммита на локальной машине
- Используется hard обычно вместе с git push —force origin
$branchName, чтобы удалить совершенные коммиты в
удаленном репозитории
- commitName можно посмотреть с помощью команды git reflog
- Есть интерактивный режим для селективного выбора hunk-ов -
(—patch)
git revert —no-edit $commitName
- Делает реверсивный коммит
- Если вы не хотите видеть vim - используйте —no-edit
- По сравнению с reset - оба commit-а остаются в истории
git flags
Strong stable repeated Idioms
—force
Принудительное выполнение
—dry-run
Тестовый прогон, превью результата
—no-edit / —edit
Похоже на добавление описания
—quiet
Не выводит никакой информации о выполнении
—verbose
Вывод детальной информации о выполнении
—prune
Удаление грязи, “выброс несвежих веток и коммитов”
—all
Действие сразу ко всем (git commit —all -m $commitDescr))
—tags / —no-tags
Относится к тэггированию коммитов
—depth
Число известных ревизий, сколько истории подгружаем
—recursive
Рекурсивный обход на любую глубину
—branch
К конкретной ветке
—interactive
Специальный интерактивный режим для некоторых комманд
—patch
Специальный режим для селективного обхода по hunk-ам для выбора подходящих
Когда прозреваешь от
количества флагов
Bonus :
diff between
git merge
git rebase
git cherry-pick
СПАСИБО ЗА ВНИМАНИЕ
Если у вас возникли вопросы, я с удовольствием
обсужу их с вами.
Alexander Babenko (HuktoDev)
iOS Developer
Improve Digital

Git presentation

  • 1.
  • 2.
    Advanced GIT : Староепо новому You are Ready? Alexander Babenko (HuktoDev) iOS Developer Improve Digital
  • 3.
    Зачем нам этонужно? • Клиенты с GUI не всегда способны разрешить некоторые кейсы • Настройка Деплой-Машины (Jenkins) • Создание shell script-ов (.sh) • Абстракции бывают дырявы, и мы обязаны знать, что там, под капотом (under the hood) • Это круто, это для хардкорщиков ;)
  • 4.
    Table of Contents: 1. Git Snapshotting (Git files) 2. Git Stash 3. Git Flow 4. Git Submodule 5. Git Remote 6. Git LFS 7. Git Reset/Revert 8. Git Flags 9. Git BONUS
  • 5.
    GIT Files : Workwith index & git trees Все файлы в репозитории делятся на 4 типа : Наличие файла в папке еще не означает, что он отслеживается VCS (прикреплен к репозиторию) git add (добавление файла) (stage file в SourceTree) git rm (удаление файла) (unstage file в SourceTree) git mv (перемещение/переименование файла) git status
  • 6.
    git add Используется в2х случаях • Мы создали новый файл, и хотим также добавить его в репозиторий, чтобы он был в следующем commit-е • Мы изменили файл (он теперь помечен, как modified), и хотим, чтобы изменения с ним были в следующем commit-е git rm Используется в 2х случаях : • Мы удалили файл физически на локальной машине, но к сожалению, файл в удаленном репозитории не удалится автоматически при коммите. Нужно удалить файл и с помощью команды git rm, чтобы у нас не плодились dummy-объекты • Мы хотим перестать отслеживать файл, и внести его в .gitignore. В этом случае правильнее предварительно его потереть из репозитория через git rm git status Используется в 1м случае : - Мы хотим посмотреть на текущее состояния файлов репозитория. Нам покажет : ✦Какие файлы модифицированы, и изменения “подтверждены” для следующего commit-а ✦ Где произошли изменения, но они пока не добавлены в next commit ✦ Состояния других файлов
  • 7.
  • 8.
    git stash Наша файловая«заначка» • git stash - быстро убираем все модифицированные файлы, но сохраняем их в специальное место, чтобы их можно было применить в другом месте • git stash apply - применяем изменения в нужном месте (не забываем про совместимость и мерджи) • git stash apply $stashname - применяем конкретный изменения • git stash list - показать список «заначек» • git stash show $stashname - смотрим, что находится в конкретной заначке • git stash drop - удаляем конкретную заначку • git stash pop $stashname - применяем изменения, и сназу удаляем «заначку» • git stash clear - удаление всех заначек
  • 9.
    git stash Extended capabilities Автоматическиеstash-и имеют названия по типу stash@{x} git stash branch $branchname $stashname - Создание новой ветки, вместе с применением спрятанных файлов к ней git stash —keep-index - Создание стэша без изменения индекса в текущей ветке git stash —include-untracked - Создание стэша, включая файлы, не добавленные в индекс (к которым еще не был применен git add) git stash —patch - Прикольный интерактивный режим, который последовательно пройдется по всем hunk-ам, и спросит, что с каждым конкретно делать git stash save $identifyMessage - Создать стэш с собственным сообщением (увы, название мы менять не можем)
  • 10.
    git stash Hints andUsage ways Юзабельная последовательность команд, если забыл сделать pull remote branch, и уже есть собственные изменения git stash git pull git stash pop • Можно хранить несколько вариантов конкретной фичи • Перенос функциональности в другую ветку • Один из способов отменить изменения в индексе (похоже на git reset —mixed HEAD) • Забыл сделать feature ветку, и делал изменения в develop-е
  • 11.
    git flow Rules forGoodStyle. Why? • Выход на более высокие уровни абстракции -> 2У : Упрощение + Удобство • git flow - это фасад с наиболее общими взаимодействиями • Это и свод правил, и определенная философия разработки
  • 12.
    git flow Rules forGoodStyle. Why? How use? git flow инсталлится вручную с помощью пакетного менеджера : brew install git-flow-avh Набор эквивалентных команд для работы с git flow из командной строки : git flow init git flow feature start MYFEATURE git flow feature finish MYFEATURE git flow feature publish MYFEATURE git flow feature pull origin MYFEATURE Схожие наборы команд имеются для : git flow release git flow hotfix Великолепная шпаргалка по git flow : http://danielkummer.github.io/git-flow-cheatsheet/index.ru_RU.html
  • 13.
  • 14.
    git submodule Private dependenciesin practice • Один из способов управления зависимостями. Благодаря Cocoapods и Carthage используется редко, но практически незаменим в случае приватных корпоративных фреймворков и наборов утилит. • Кроме того, не требует дополнительной настройки, по сравнению с созданием pod spec файла • Физически создается файл .gitmodules, который можно модифицировать (под версионным контролем) Родительский модуль не видит папку с содержимым подмодуля, он знает : A.Ссылку на репозиторий с сабмодулем B.Конкретный хэш коммита C.Индекс (изменения, совершенные нами в сабмодуле) • Один из ключевых плюсов сабмодуля - возможность гибко выбирать подходящий коммит подпроекта • Сабмодуль по-умолчанию использует свой указатель (detached HEAD) - чтобы при клонировании родительского проекта другой разработчик мог получить идентичный проект • Совсем огонь, если хранить разные части проекта в разных репозиториях, и собирать все это сабмодулями • Если мы планируем какие-то изменения сабмодуля - переходим на свою ветку с помощью git checkout -b $branchName • Я не нашел внятного гайда по работу с проектом с multiple submodules
  • 15.
    При добавлении сабмодуляпервый раз git submodule add $repoUrl $diskPath После клонирования проекта другим разрабом git submodule init git submodule update (используется и для подтягивания последних изменений в подпроекте) git submodule status git submodule deinit - детач конкретного сабмодуля git submodule update —merge/—rebase (так как это работает, как git pull - нужно иногда выбрать соответствующую манипуляцию) —init (можно подтянуть субпроект одной строкой) git submodule sync - подтягивают изменения в .gitmodules и конфиг-файле git submodule update —init —recursive —remote (полное обновление всех сабмодулей, рекурсивно с сабмодулями сабмодулей) git submodule foreach 'git stash’ - способ совершить какую-то команду, применительно сразу ко всем сабмодулям (похоже на цикл из C#)
  • 16.
  • 17.
    git remote Мультирепозиторность • -Удаленных репозиториев может быть больше, чем один • - Основной удаленный всегда называется origin (оригинал) • - Это одна из причин, почему с операциями push/pull/fetch так-же можно указывать имя репозитория (по дефолту там - origin) • Example : git push origin master или git push $repoName master • Когда это может пригодиться : • - Переезд оригинального репозитория на другой URL • - Sync сразу с двумя репозиториями • - Один репозиторий для READ, другой - для WRITE • - Для огромных проектов и огромной команды возможна распределенная система вторичных “узловых” репозиториев, которые периодически мерджат, ревьюят и синхронизируют назначенные лиды в первичный origin репозиторий • - Вы использовали https, но хотите использовать SSH для большей секьюрности, и хотите просто и быстро перебиндить URL-ы • - GIT представляет набор команд для менеджмента набора репозиториев (включая CRUD-интерфейс)
  • 18.
    Команды git remote: git remote -v Посмотреть набор известных репозиториев git remote add $repoName $url Добавить информацию о новом удаленном репозитории git remote rename/remove … Переименование и удаление git remote show $repoName Показывает информацию о конкретном удаленном репозитории. Показывает то, какие ветки у нас подтянуты в нашем репозитории, а какие нет, и др. инфо git remote get-url $repoName Получить текущий URL конкретного репозитория git remote set-url (—add/—delete) $repoName $url Изменить URL для конкретного репозитория (и еще некоторые странные операции) git remote set-head Устанавливает ветку по-умолчанию (чтобы не писать каждый раз git push origin $branchName)
  • 19.
    Git LFS Великая сила- это великая ответственность и … множество ограничений.
  • 20.
    Git LFS Великая сила- это великая ответственность и … множество ограничений. • Когда репозитории становятся большими, и их становится много - хорошей идеей будет - снизить нагрузку на сервер с git-ом (большие затраты на клонирование + big data). Рекомендуется начинать этим заниматься, если repo > 1GB • Когда вы хотите иметь более удобный интерфейс для управления версионностью ресурсов • Вы хотите оптимизировать выполнение операций • Если вы пользуетесь Github-ом : он не позволяет иметь проекты > 200 МБ для Free User-ов, и Git LFS входит в одно из его Premium предложений - Позволяет быстро клонировать “огромные” проекты - выполнять операции по типу git checkout, git add, git commit, git clone, git pull Принцип работы : • Создаются специальные pointer(reference)-файлы • Используется специальный отдельный LFS Storage • В некоторых случаях нужно в настройках веб-формы GIT-сервера включить LFS Имеются похожие аналоги : git annex , git fat
  • 21.
    How to use: Прежде всего - скачать : brew install git-lfs git lfs install / uninstall Инициализировать LFS-репозиторий (или наоборот) git lfs track / untrack $filePath Добавить/Удалить файл из LFS (можно использовать маски) git lfs ls-files / git lfs status Команды для инспекции текущей ситуации Кроме всего прочего - имеет набор команд по типу fetch / checkout / clone / push / pull
  • 22.
    git reset /git revert Назад в будущее Эмметт Браун: Это мой старый HEAD? Марти МакФлай: Да, сейчас коммит 9e5e6a4. Эмметт Браун: Прекрасно! Эксперимент удался! Оно переместилось ровно на 2 коммита! Марти МакФлай: Погоди-ка… минуточку, Док! Сейчас что, 9e5e6a4? Эмметт Браун: Именно!
  • 23.
    git reset /git revert Казнить, нельзя помиловать - Порой мы хотим отменить собственные или чужие решения git reset - отменяет изменения, удобным образом работая с а) HEAD-ом б) индексом в) текущим Workflow (песочницей) git revert - выполняет commit, содержащий undo- действия для конкретного выбранного другого коммита. (Если мы создали файл - то revert удалит его в новом коммите)
  • 24.
    Твое лицо, когдаты узнал, что действия в git-е можно обращать вспять :
  • 25.
    git reset /git revert Казнить, нельзя помиловать git reset —soft / —mixed / —hard $commitName $filePath - Можно даже сливать коммиты - Использование флага hard - принудительно удаляет все изменения после выбранного коммита на локальной машине - Используется hard обычно вместе с git push —force origin $branchName, чтобы удалить совершенные коммиты в удаленном репозитории - commitName можно посмотреть с помощью команды git reflog - Есть интерактивный режим для селективного выбора hunk-ов - (—patch) git revert —no-edit $commitName - Делает реверсивный коммит - Если вы не хотите видеть vim - используйте —no-edit - По сравнению с reset - оба commit-а остаются в истории
  • 26.
    git flags Strong stablerepeated Idioms —force Принудительное выполнение —dry-run Тестовый прогон, превью результата —no-edit / —edit Похоже на добавление описания —quiet Не выводит никакой информации о выполнении —verbose Вывод детальной информации о выполнении —prune Удаление грязи, “выброс несвежих веток и коммитов” —all Действие сразу ко всем (git commit —all -m $commitDescr)) —tags / —no-tags Относится к тэггированию коммитов —depth Число известных ревизий, сколько истории подгружаем —recursive Рекурсивный обход на любую глубину —branch К конкретной ветке —interactive Специальный интерактивный режим для некоторых комманд —patch Специальный режим для селективного обхода по hunk-ам для выбора подходящих Когда прозреваешь от количества флагов
  • 27.
    Bonus : diff between gitmerge git rebase git cherry-pick
  • 28.
    СПАСИБО ЗА ВНИМАНИЕ Еслиу вас возникли вопросы, я с удовольствием обсужу их с вами. Alexander Babenko (HuktoDev) iOS Developer Improve Digital