Когда удалять ветки в Git?

284

Предположим, у нас есть стабильное приложение.

Завтра кто-то сообщит о большой старой ошибке, которую мы решили исправить сразу. Таким образом, мы создаем ветку для этого исправления из «master», мы называем его «2011_Hotfix» и поднимаем его, чтобы все разработчики могли совместно исправлять его.

Мы исправляем ошибку и объединяем «2011_Hotfix» с «master», а также с текущей веткой разработки. И нажать «мастер».

Что мы делаем с «2011_Hotfix» сейчас? Должно ли оно оставаться вечным до конца времени как ветвь, или теперь мы должны удалить его, поскольку он выполнил свою задачу? Кажется нечистым просто оставлять ветки повсюду, так как список ветвей, вероятно, станет очень длинным, большинство из которых больше не нужны.

Если он будет удален, что будет с его историей? Будет ли это поддерживаться, даже если фактическая ветвь больше не доступна? Кроме того, как мне удалить удаленную ветку?

Энтони Комптон
источник
33
Это часто помогает думать о ветвях как об идеях. Довольно хорошее практическое правило заключается в том, что если вы закончили работать над идеями, которые представляет ветвь - включая завершенное тестирование и включение этих изменений (объединение их в master) - вы закончили с самой веткой.
Каскабель
3
Что я хотел бы знать: если удаленное исправление удаляется, будет ли оно удалено локально для всех разработчиков, которые сотрудничали? Если не; как это сделать? Я думаю, что один человек переносит исправление на master, но после этого оно должно быть также очищено для всех соавторов, чтобы они не могли добавлять коммиты в эту ветку.
Rolandow
1
Вы не можете влиять на локальные репозитории компьютеров ваших коллег. Вы должны либо сказать ему, чтобы он удалял ветку локально, либо вы также можете применить эту сторону сервера с помощью git hooks / security branch, чтобы предотвратить выталкивания из вашей ветки, которые вы хотите сохранить удаленными
srz2

Ответы:

183

Вы можете безопасно удалить ветку с помощью git branch -d yourbranch. Если он содержит неоплаченные изменения (т. Е. Вы потеряете коммиты, удалив ветку), git сообщит вам и не удалит его.

Таким образом, удаление объединенной ветви дешево и не заставит вас потерять историю.

Чтобы удалить удаленную ветку, используйте git push origin :mybranch, предполагая, что ваше удаленное имя является источником, а удаленная ветка, которую вы хотите удалить, называется mybranch.

Artefact2
источник
35
«Удалить объединенную ветвь - это дешево», но так оно и есть. Нет существенного снижения производительности с точки зрения использования времени или пространства Git, если вы сохраните его. Тем не менее, я бы удалил ветку, потому что все коммиты уже есть в истории master, так что это делает вещи намного чище.
MatrixFrog
22
Одна из причин, по которой я хочу удалить ветви: мы делаем много изменений в ветвях (фактически, все изменения), поэтому в конечном итоге вы получаете длинный список при использовании команды 'git branch'. Для обзора я хочу сократить этот список. Так что старые ветки будут удалены. Реальные выпуски помечены, поэтому не для меня.
michel.iamit
7
Хотя я согласен с удалением веток, которые уже были объединены, если вы хотите увидеть список ветвей, которые не были объединены с вашей текущей веткой, вы можете использовать: git branch --no-merged
lsklyut
51
@MatrixFrog Дешево хранить с точки зрения мерзавца, однако человеческие затраты могут дорого обойтись. Я только что вошел в проект с около 40 ветками, все с числовыми названиями веток. Я понятия не имею, что к чему, и почти каждая из этих ветвей устарела. Затраты на поиск в этих ветках и выяснение того, что утомительно и занимает много времени. Так что да, технически это дешево, но на самом деле это не так. Мне нравится сохранять форму корабля Git Repo. Если он не находится в активном dev и был объединен, удалите его. Но это только мое МО, и я уважаю, что другие могут сделать что-то другое.
dudewad
1
Какая команда сделать --no-mergedпо умолчанию? Я попытался, git config --global --add branch.noMerged trueи это было добавлено, но это не имело никакого значения.
Крейг Сильвер
55

Что вам нужно сделать, это пометить все, что вы выпускаете. Держите ветви вокруг, когда вы активно развиваетесь.

Удалить старые ветви с

git branch -d branch_name

Удалить их с сервера с

git push origin --delete branch_name

или старый синтаксис

git push origin :branch_name

который читается как «ничего не вставлять в имя_в ветви в источнике».

Тем не менее, до тех пор, пока DAG (направленный ациклический граф) может указывать на него, коммиты будут в истории.

Google "git-flow", и это может дать более глубокое понимание управления выпусками, ветвлениями и тегами.

Адам Димитрук
источник
31

Поскольку в вопросе есть тег «github», я бы также добавил следующее: в частности, в Github , если вы извлекаете запрос на ветку, и она объединяется (либо через пользовательский интерфейс, либо путем объединения ветви запроса извлечения), вы не будете потерять данные запроса на получение (включая комментарии), даже если вы удалите ветку .

Следствие этого: если вы включаете запросы на получение данных как часть вашего рабочего процесса (который прекрасно сочетается с обзорами кода), вы можете безопасно удалять ветви, как только они объединяются. Это настолько распространенное явление, что недавно Github добавил (приятную) функцию, которая нажимает кнопку «удалить ветку» сразу после объединения запроса на извлечение.

Но стоит отметить, что каждая группа должна принять рабочий процесс, который подходит ей лучше всего (и это может или не может привести к удалению таких ветвей). Моя текущая рабочая группа, например, удаляет все ветви, которые не являются основными или не связаны с развертыванием (например, производство, подготовка и т. Д.), Как только их запросы извлечения объединяются, и у нас все еще есть полное отслеживание того, как сформировались соответствующие коммиты. каждое постепенное улучшение каждого продукта.

Конечно, никакое управление историей (запросы на извлечение или иное) не заменяет надлежащую маркировку версий (которую предпочтительно автоматизировать с помощью того же инструмента / скрипта, который развертывает / упаковывает версию), поэтому вы всегда можете быстро переключиться на то, что происходит у ваших пользователей. в данный момент. Пометка также является ключом к решению вашей первоначальной проблемы: если вы установили, что любая ветка, слитая с «рабочими» ветвями, может и должна быть удалена, а любая ветка с тегом версии, «производственная» и т. Д. Не должна вы всегда будете иметь исправления, пока они не будут интегрированы в будущую версию.

chesterbr
источник
2
Спасибо за объяснение, почему Github показывал мне кнопку «Удалить ветку».
Тодд Оуэн
Мы используем sourcetree, и он дает возможность оставить открытыми локальную ветку исправлений и удаленную ветку исправлений. Я думал, что закрытие ветки исправлений означает удаление, и вы не можете использовать его повторно. Например, нам нужно ежедневно устанавливать исправления ежедневно в течение следующих 5 дней. Тогда мы закрываем это. Но скажем, на 6-й день нам нужно другое исправление. Создаем ли мы новую ветку исправлений?
Danger14
Это то, что люди обычно делают. Если назвать их по отдельности невозможно, вы можете назвать их по дням или по справочной системе управления билетами (если таковые имеются). Конечно, рабочие процессы git должны применяться «на основе того, что лучше всего подходит для вашей команды», поэтому не беспокойтесь, если вы решите работать по-другому.
Честербрул
7

Я бы добавил, что недостатком удаления веток является то, что вы нарушаете любые гиперссылки на эти ветки на GitHub (этот вопрос помечен как github). Вы получите 404 Not Foundошибку для этих ссылок. Вот почему я изменяю свои ссылки, чтобы они указывали на коммит или тег после удаления ветки на GitHub.

Поскольку некоторые ссылки не могут быть изменены, например, по электронной почте, я теперь избегаю гиперссылок на ветви GitHub целиком и ссылок на коммит или тег с первого дня.

Я предпочитаю удалять ветви после их объединения. Это предотвращает визуальный беспорядок длинного списка веток в вашем хранилище. Эти ветви также распространяются на все вилки хранилища.

Сначала я удаляю свою локальную ветку. Это предотвращает его случайное нажатие позже.

git branch -d branchName

Затем я удаляю ветку удаленного отслеживания

git branch -dr remoteName\branchName

Затем я удаляю ветку на GitHub. Я использую веб-интерфейс, но эквивалентная команда ниже.

git push remoteName :branchName

Даже если ветвь никогда не объединяется, обычно я хотел бы сохранить коммиты для потомков. Однако я все еще люблю удалять ветку. Чтобы распространить коммиты и предотвратить их использование сборщиком мусора, я делаю аннотированный тег, указывающий на тот же коммит, что и удаленная ветвь.

git tag -a tagName commitOrBranchName

Затем я нажимаю тег на GitHub

git push remoteName tagName
Марк Ф Герра
источник
Когда сборщик мусора съест коммиты филиала? Вам нужно пометить и нажать метку перед удалением ветки?
Джаред Тирск
4

Кажется, вы хотите удалить 2011_Hotfixветку, не потеряв ее историю. Я буду обсуждать удаление первого и историю второго.

Обычные gitметоды удаления веток уже были описаны выше, и они работают как положено. gitне имеет команды из одного или двух слов, которая означает: «Эй git, удалите как локальную, так и удаленную ветку». Но это поведение можно имитировать с помощью сценария оболочки. Например, возьмите сценарий оболочки Зака ​​Холмана «git-nuke» . Это очень просто:

#!/bin/sh
git branch -D $1
git push origin :$1

Поместите это в исполняемый файл (например, git-nuke) в одном из ваших $PATHкаталогов. Если вы не в 2011_Hotfixветке, вы просто работаете git-nuke 2011_Hotfix, удалит как локальную, так и удаленную ветки. Это намного быстрее и проще - хотя, возможно, более опасно - чем стандартные gitкоманды.

Ваша забота о сохранении истории хороша. В этом случае вам не нужно беспокоиться. После слияния 2011_Hotfixна masterвсе коммиты из 2011_Hotfixбудут добавлены к master«s история коммитов. Короче говоря, вы не потеряете историю от простого слияния.

Я хочу добавить еще одно слово, которое, возможно, выходит за рамки вашего вопроса, но, тем не менее, уместно. Давайте представим, что есть 20 крошечных «незавершенных» коммитов 2011_Hotfix; однако вы хотите, 2011_Hotfixчтобы в masterисторию добавлялся только один полный коммит . Как объединить все 20 маленьких коммитов в один большой коммит? К счастью, gitпозволяет объединить несколько коммитов в один коммит с помощью git-rebase. Я не буду объяснять здесь, как это работает; хотя, если вам интересно, документация наgit-rebase отлично. Обратите внимание, что git rebaseпереписывает историю, поэтому она должна использоваться разумно, особенно если вы новичок в этом. Наконец, ваш 2011_Hotfixсценарий о команде разработчиков, а не об одиночном. Если члены команды проекта используютgit rebaseДля команды целесообразно иметь четкие руководящие указания по использованию git rebase, чтобы какой-нибудь ковбойский разработчик в команде невольно не повредил gitисторию проекта .

jfmercer
источник
3

Если он был успешно объединен и, возможно, даже помечен, я бы сказал, что он больше не нужен. Так что можете смело делать git branch -d branchname.

Михаэль Фюрстенберг
источник
2

Если вы хотите удалить локальные ветви, которые были удалены из источника, вы также можете удалить, используя git fetch

git fetch --prune
хучь
источник
0

Вы можете удалить ветки во всех основных веб-интерфейсах, таких как github, BitBucket. После удаления ветки онлайн вы можете удалить локальную ветку, используя

git remote prune origin
tkruse
источник