Работая над фичей проекта, чаще всего мы создаём локальную ветку, фиксируем этапы работы в виде коммитов и периодически отправляем их на сервер, мы можем делать это после создания каждого коммита или отправлять несколько за раз. После отправки ветки на сервер там будет создана такая же ветка и эти изменения смогут получить другие разработчики. Будем называть такие, отправленные, ветки remote. Другие члены команды могут получить эту ветку и тоже начать создавать изменения, а так же отправлять их на сервер. Таким образом на вашем компьютере будет существовать какая-нибудь ваша ветка some_great_feature, а после отправки на удаленный сервер ещё и ветка слежения origin/some_great_feature, которая содержит "слепок" состояния remote ветки в момент последнего обмена данными с ним. Чтобы обновить состояние удаленных веток используйте очень известную команду
git fetch
Она актуализирует состояние ветки слежения, то есть обновит данные в вашей ветке origin/some_great_feature. Теперь вы можете обновить состояние локальной ветки в соответствии с веткой слежения. В конце концов работа над фичей когда-нибудь заканчивается и ветка сливается с веткой master, при этом очень часто gitlab или другой git-менеджер удаляет ветку фичи. Тема этого топика: как легко удалять такие ветки на своём компьютере если они больше не нужны? Начнём с того, что мы говорили про ветки слежения обеспечивающие связь локальной ветки и remote. Они очень легко удаляются с помощью команды:
git fetch --prune
Но мы хотим удалить ещё и наши, локальные, ветки. Git предлагает сделать это явно, например так:
git branch -d some_great_feature
Если ветка была "слита" с веткой master, то команда удалит локальную ветку на вашем компьютере. Обратите внимание на маленькую d, этот флаг удалит ветку которая уже есть в master, если ветка не попала туда, то вы получите предупреждение об этом и ветка останется цела. Git предложит вам использовать большую D чтобы удалить ветку без этих проверок. Но есть хороший способ удалить сразу все ветки которые уже есть в master:
git branch --merged | egrep -v "(^\*|master|ORIGIN_MASTER)" | xargs git branch -d
Это распространённый набор команд, вот что он делает:
- получает все "смерженые" ветки с помощью опции --merged
- выкидывает из этого списка ветки начинающиеся с master и текущую
- удаляет оставшиеся ветки с указанием маленькой d
Этот набор команд может быть полезен, но есть один случай, когда он не сработает: если gitlab "схлопнул" коммиты в один при слиянии с master. Тогда ваша ветка some_great_feature не будет считаться полностью слитой с master (не совпадают хеши коммитов в вашей ветке и в remote) и вам придется применить к ней команду:
git branch -D some_great_feature
то есть указать большую D но это не удобно для большого количества веток и на постоянной основе. Для такого случая я предлагаю использовать вот такой длинный набор команд:
git checkout -q master && git for-each-ref refs/heads/ "--format=%(refname:short)" | while read branch; do mergeBase=$(git merge-base master $branch) && [[ $(git cherry master $(git commit-tree $(git rev-parse $branch\^{tree}) -p $mergeBase -m _)) == "-"* ]] && git branch -D $branch; done
Очень удобно создать псевдоним для этой команды чтобы её использование выглядело более эстетично. Лично я нашел эту последовательность команд на github в этом репозитории. Выражаю ему свою благодарность за проделанный труд, потому что меня этот способ ни разу не подводил.