Как да премахнем всички клонове на git, които са били обединени?

Имам много клони на git. Как да изтрия клонове, които вече са обединени? Има ли лесен начин да ги премахнете, вместо да ги изтривате един по един?

1394
25 мая '11 в 18:54 2011-05-25 18:54 Nyambaa е поставен на 25 май '11 в 18:54 2011-05-25 18:54
@ 40 отговора
  • 1
  • 2

UPDATE:

Можете да добавите други клонове, за да ги изключите като master и dev, ако вашият работен поток ги има като възможен прародител. Обикновено забранявам началния маркер за спринт и капитанът, dev и qa не са предци.

За да изтриете всички местни клонове, които вече са обединени в текущия маркиран бранш:

 git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d 

Можете да видите, че капитанът и устройството са изключени, ако са предци.


Можете да изтриете обединен местен клон с:

 git branch -d branchname 

Ако не е обединена, използвайте:

 git branch -d branchname 
border=0

За да го премахнете от конзолата в по-стари версии на Git, използвайте:

 git push origin :branchname 

В по-късните версии на Git използвайте:

 git push --delete origin branchname 

След като изтриете клон от отдалечено устройство, можете да отрежете, за да се отървете от клоновете за дистанционно проследяване с:

 git remote prune origin 

или изрязване на отделни клонове на дистанционно проследяване, както е предложено от друг отговор, като се използва:

 git branch -dr branchname 

Надявам се това да помогне.

2352
25 мая '11 в 19:40 2011-05-25 19:40 отговорът е даден от Адам Dymitruk на 25 май '11 в 19:40 2011-05-25 19:40

За да изтриете всички клонове на отдалечен сървър, които вече са обединени:

 git branch -r --merged | grep -v master | sed 's/origin\//:/' | xargs -n 1 git push origin 
border=0

В по-късните версии на Git

 git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin 
340
09 авг. отговорът е даден kuboon 09 aug. 2013-08-09 11:45 '13 в 11:45 ч. 2013-08-09 11:45

Просто разширявам Адам малко:

Добавете го към конфигурацията на git config -e --global

 [alias] cleanup = "!git branch --merged | grep -v '\\*\\|master\\|develop' | xargs -n 1 git branch -d" 

След това можете да премахнете всички местни обединени клонове, като git cleanup обикновен git cleanup .

140
18 февр. отговорът е даден real_ate 18 февруари . 2014-02-18 18:08 '14 в 18:08 2014-02-18 18:08

Той също така ви позволява да изтриете всички обединени клонове, с изключение на master.

 git branch --merged | grep -v '^* master$' | grep -v '^ master$' | xargs git branch -d 
73
07 февр. Отговорът е даден от Ismael Abreu 07 Feb. 2013-02-07 04:06 '13 в 4:06 2013-02-07 04:06

Искате да изключите master клонове и да се develop от тези команди.

Локално почистване:

 git branch --merged | grep -v '\*\|master\|develop' | xargs -n 1 git branch -d 

Отдалечено пречистване на git:

 git branch -r --merged | grep -v '\*\|master\|develop' | sed 's/origin\///' | xargs -n 1 git push --delete origin 

Синхронизирайте локалния регистър на отдалечените клонове:

 git fetch -p 
60
03 июля '14 в 19:18 2014-07-03 19:18 отговорът е даден от Guido Bouman на 03 юли 14 в 19:18 2014-07-03 19:18

За тези от вас, които са в Windows и предпочитат скриптове на PowerShell, това изтрива локалните обединени клонове:

 function Remove-MergedBranches { git branch --merged | ForEach-Object { $_.Trim() } | Where-Object {$_ -NotMatch "^\*"} | Where-Object {-not ( $_ -Like "*master" )} | ForEach-Object { git branch -d $_ } } 
36
10 июня '14 в 17:00 2014-06-10 17:00 Отговорът е даден от Klas Mellbourn на 10 юни 14 часа в 17:00 часа 2014-06-10 17:00 часа

Git Sweep се справя с това.

19
04 февр. отговорът е даден paul 04 Feb. 2013-02-04 16:53 '13 в 16:53 2013-02-04 16:53

Можете да добавите ангажимент към опцията-зареден. По този начин можете да се уверите, че само клоновете, които са свързани, т.е.

Следната команда ще премахне обединени клонове от вашия източник.

 git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete 

Можете да проверите кои клонове ще бъдат изтрити, като замените началото на git push -delete с ехо

 git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo 
13
08 июля '14 в 9:28 2014-07-08 09:28 Отговорът е даден от Jörn Reimerdes на 08 юли 14 в 9:28 2014-07-08 09:28

Използване на Git версия 2.5.0:

 git branch -d `git branch --merged` 
12
14 сент. отговорът се дава drautb 14 sep . 2015-09-14 19:20 '15 в 19:20 2015-09-14 19:20

Използвам следния скрипт на Ruby за премахване на вече обединени локални и отдалечени клонове. Ако направя това за хранилище с няколко отдалечени устройства и просто искам да го премахна от него, просто добавям оператора select към списъка с отдалечени компютри, за да получа само отдалечени отдалечени модули.

11
28 сент. Отговорът е даден от mmrobins 28 септември 2012-09-28 02:41 '12 в 2:41 ч. 2012-09-28 02:41

Отговор kuboon пропусна изтриване на клонове, които имат името на думата в името на клона. Следният подобрява отговора му:

 git branch -r --merged | grep -v "origin/master$" | sed 's/\s*origin\///' | xargs -n 1 git push --delete origin 

Разбира се, той не изтрива "главния" :)

8
04 окт. отговорът е даден в параграф 04 окт. 2013-10-04 09:05 '13 в 9:05 2013-10-04 09:05

Премахнете обединените клонове в конзолата PowerShell

 git branch --merged | %{git branch -d $_.Trim()} 

Вижте GitHub за Windows

8
27 янв. отговор, даден от Константин Таркус 27 януари 2015-01-27 17:17 '15 в 17:17 2015-01-27 17:17

В Git няма команда, която да прави това автоматично. Но можете да напишете скрипт, който използва Git команди, за да ви даде това, от което имате нужда. Това може да бъде направено по различни начини в зависимост от използвания модел на бранша.

Ако трябва да знаете дали клонът е бил обединен с главния, следната команда няма да работи, ако myTopicBranch е обединено (т.е. можете да го изтриете)

 $ git rev-list master | grep $(git rev-parse myTopicBranch) 

Можете да използвате командата Git на клона и да анализирате всички клонове в Bash и да изпълните for цикъл на всички клонове. В този цикъл проверете с командата по-горе, ако можете да изтриете клон или не.

7
26 мая '11 в 10:41 2011-05-26 10:41 отговорът е даден ralphtheninja 26 май '11 в 10:41 2011-05-26 10:41

git branch --merged | grep -Ev '^(. master|\*)' | xargs -n 1 git branch -d git branch --merged | grep -Ev '^(. master|\*)' | xargs -n 1 git branch -d ще изтрие всички локални клонове, с изключение на текущо публикувания клон и / или master .

Ето една полезна статия за тези, които искат да разберат тези команди: Git Clear: изтриване на вече обединени клонове, от Стивън Харман .

6
24 окт. отговор, даден styger 24 окт. 2014-10-24 00:06 '14 в 0:06 2014-10-24 00:06

Използвал съм отговорите на Адам от много години. Но има моменти, когато той не се държеше така, както очаквах:

  1. клоновете, съдържащи думата "майстор", бяха игнорирани, например "notmaster" или "masterful", а не само водещият клон
  2. клоновете, съдържащи думата "dev", бяха игнорирани, например "dev-test", а не само dev раздела
  3. изтриване на клонове, достигани от HEAD на текущия клон (което не е задължително да води)
  4. в отделно състояние HEAD, изтриване на всеки клон, достъпен от текущия ангажимент

1 и 2 са просто адресирани, само с промяна в регулярния израз. 3 зависи от контекста на това, което искате (т.е. изтриване на клонове, които не са обединени в главен или срещу текущия ви клон). 4 може да бъде катастрофално (въпреки че се възстановява с git reflog ), ако по невнимание git reflog е в отделно състояние HEAD.

И накрая, исках всичко да бъде в един слой, за който не е необходим отделен (Bash | Ruby | Python) скрипт.

TL; DR

Създайте git-псевдоним "sweep", който приема опционалния флаг -f :

 git config --global alias.sweep '!f(){ git branch --merged $([[ $1 != "-f" ]] \  git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \ | xargs git branch -d; }; f' 

и се обадете с:

 git sweep 

или:

 git sweep -f 

Дълъг, подробен отговор

Най-лесно ми беше да създам пример за git repo с някои клонове и да се ангажирам да проверява за правилно поведение:

Създайте ново хранилище на git с едно обвързване

 mkdir sweep-test  cd sweep-test  git init echo "hello" > hello git add .  git commit -am "initial commit" 

Създаване на нови клонове

 git branch foo  git branch bar  git branch develop  git branch notmaster  git branch masterful git branch --list 
  bar develop foo * master masterful notmaster 

Желано поведение: изберете всички обединени клонове, с изключение на: master, develop или current

Оригиналният регулярен израз пропуска клоновете "майсторски" и "notmaster":

 git checkout foo git branch --merged | egrep -v "(^\*|master|dev)" 
  bar 

С актуализирания регулярен израз (който сега изключва "develop", а не "dev"):

 git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)" 
 bar masterful notmaster 

Преминете към foo клон, направете нов ангажимент, след това проверете новия клон на foobar на базата на foo:

 echo "foo" > foo git add .  git commit -am "foo" git checkout -b foobar echo "foobar" > foobar git add .  git commit -am "foobar" 

Сегашният ми клон е foobar и ако повторя горната команда за списъка с клонове, които искам да изтрия, клонът "foo" е активиран, въпреки че не е бил обединен с съветника:

 git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)" 
  bar foo masterful notmaster 

Ако обаче изпълня една и съща команда на капитана, клонът "foo" не се включва:

 git checkout master  git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)" 
  bar masterful notmaster 

И това е просто, защото git branch --merged default отговаря на HEAD на текущия клон, освен ако не е посочено друго. Поне за моя работен процес не искам да изтривам локални клонове, ако не бяха обединени в главен, затова предпочитам следната опция:

 git checkout foobar git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" 
  bar masterful notmaster 

Отделно състояние HEAD

Позоваването на поведението по подразбиране на git branch --merged има дори по-значителни последствия в отделно състояние HEAD:

 git checkout foobar git checkout HEAD~0 git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)" 
  bar foo foobar masterful notmaster 

Това ще премахне клона, на който бях, "foobar" заедно с "foo", което почти със сигурност не е желаният резултат. С преработения ни екип обаче:

 git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" 
  bar masterful notmaster 

Един ред, включително действителното изтриване

 git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" | xargs git branch -d 

Всички псевдоними „sweep“ от git-wrapped:

 git config --global alias.sweep '!f(){ git branch --merged $([[ $1 != "-f" ]] \  git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \ | xargs git branch -d; }; f' 

Псевдонимът приема допълнителен флаг -f . По подразбиране се използва само изтриване на клонове, които са обединени в master, но флагът -f премахва клоновете, които са обединени в текущия клон.

 git sweep 
 Deleted branch bar (was 9a56952). Deleted branch masterful (was 9a56952). Deleted branch notmaster (was 9a56952). 
 git sweep -f 
 Deleted branch foo (was 2cea1ab). 
6
20 июля '18 в 9:48 2018-07-20 09:48 Отговорът е даден от вихровете на 20 юли 1818 г. в 9:48 ч. 2018-07-20 09:48

Версията за псевдоним на Адам актуализира отговор :

 [alias] branch-cleanup = "!git branch --merged | egrep -v \"(^\\*|master|dev)\" | xargs git branch -d #" 

Също така вижте този отговор за полезни съвети за защита на сложни псевдоними.

5
30 сент. Отговорът е даден на Елиот 30 септември. 2016-09-30 22:54 '16 в 22:54 ч. 2016-09-30 22:54

Можете да използвате инструмента git-del-br .

 git-del-br -a 

Можете да го инсталирате чрез pip

 pip install git-del-br 

PS: Аз съм автор на инструмента. Всички предложения / обратна връзка са добре дошли.

5
19 июля '16 в 21:50 2016-07-19 21:50 отговорът е даден tusharmakkar08 19 юли '16 в 21:50 2016-07-19 21:50

Под заявката работи за мен

 for branch in 'git branch -r --merged | grep -v '\*\|master\|develop'|awk 'NR > 0 {print$1}'|awk '{gsub(/origin\//, "")}1'';do git push origin --delete $branch; done 

и ще филтрира всеки клон в канала grep.

Работи добре на http клонинг, но не е толкова добър за SSH връзки.

4
19 янв. отговорът е даден от user1460965 19 януари. 2018-01-19 13:50 '18 в 13:50 ч. 2018-01-19 13:50

Опитайте следната команда:

git branch -d $(git branch --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

Използвайки git rev-parse , ще получите името на текущия клон, за да го изключите. Ако получите грешка, това означава, че местните клонове не се изтриват.

За да направите същото и с отдалечените клонове (променете origin си на дистанционното си име), опитайте:

git push origin -vd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD) | cut -d/ -f2)

Ако имате няколко дистанционни управления, добавете grep origin | да cut за филтриране само на origin .

Ако командата по-горе не се изпълни, опитайте първо да изтриете обединените клонове за дистанционно проследяване:

git branch -rd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

След това git fetch премахва отново и отново използва предишната git push -vd .

Ако го използвате често, помислете за ~/.gitconfig псевдоними към файла ~/.gitconfig .

Ако сте изтрили няколко грешки по погрешка, използвайте git reflog да откриете загубени ангажименти.

4
17 дек. отговорът е даден kenorb 17 dec. 2016-12-17 15:17 '16 в 15:17 2016-12-17 15:17

Въз основа на някои от тези отговори направих свой собствен баш скрипт да направя и това !

Той използва git branch --merged и git branch -d да премахне клоновете, които са обединени, и изисква всеки клон преди изтриване.

 merged_branches(){ local current_branch=$(git rev-parse --abbrev-ref HEAD) for branch in $(git branch --merged | cut -c3-) do echo "Branch $branch is already merged into $current_branch." echo "Would you like to delete it? [Y]es/[N]o " read REPLY if [[ $REPLY =~ ^[Yy] ]]; then git branch -d $branch fi done } 
4
15 окт. отговора, даден на слушалки 15 октомври. 2013-10-15 20:13 '13 в 20:13 2013-10-15 20:13

Използвам схемата за именуване на git -flow esque, така че за мен е много безопасно:

 git branch --merged | grep -e "^\s\+\(fix\|feature\)/" | xargs git branch -d 

По принцип, тя търси обединени коммити, започващи с fix/ или feature/ .

4
23 авг. Отговорът е даден Чад М 23 август. 2016-08-23 04:15 '16 в 4:15 ч. 2016-08-23 04:15

Ако искате да изтриете всички местни клонове, които вече са били обединени в клона, в който се намирате сега, аз измислих сигурна команда за това, въз основа на по-ранни отговори:

 git branch --merged | grep -v \* | grep -v '^\s*master$' | xargs -t -n 1 git branch -d 

Тази команда няма да засегне текущия ви клон или клон. Той също така ще ви каже какво прави, преди да го направи, използвайки флага -t xargs.

4
23 янв. отговорът е даден chrismendis 23 януари 2014-01-23 19:24 '14 в 19:24 2014-01-23 19:24

Напишете скрипт, в който Git проверява всички клонове, които са обединени с главния.

След това стартирайте git checkout master .

И накрая, изтрийте обединените клонове.

 for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///") echo branch-name: $branchnew git checkout $branchnew done git checkout master for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///") echo branch-name: $branchnew git push origin --delete $branchnew done 
3
09 авг. Отговорът е даден Komu 09 aug. 2017-08-09 16:42 '17 в 16:42 2017-08-09 16:42

Решението е доста добро, но има един проблем: той премахва и локалните клонове, които все още не са обединени в отдалечени.

Ако погледнете резултата, ще видите нещо подобно

 $ git branch --merged master -v api_doc 3a05427 [gone] Start of describing the Java API bla 52e080a Update wording. branch-1.0 32f1a72 [maven-release-plugin] prepare release 1.0.1 initial_proposal 6e59fb0 [gone] Original proposal, converted to AsciiDoc. issue_248 be2ba3c Skip unit-for-type checking. This needs more work. (#254) master be2ba3c Skip unit-for-type checking. This needs more work. (#254) 

Клонове bla и issue_248 са локални клонове, които ще бъдат изтрити тихо.

Но можете да видите и думата [gone] , която показва клоновете, които са били кликнали върху дистанционното (което вече е изчезнало) и по този начин показват клоните, които могат да бъдат изтрити.

По този начин първоначалният отговор може да бъде променен на (разделен на многоредов за по-къса дължина на низа)

 git branch --merged master -v | \ grep "\\[gone\\]" | \ sed -e 's/^..//' -e 's/\S* .*//' | \ xargs git branch -d 

за защита на все още не сливащи се клонове. Също така grepping не се изисква за съветника, за да го защити, тъй като има конзола по произход и не се появява като ляво.

2
15 июня '18 в 11:53 2018-06-15 11:53 Отговорът е даден от Heiko Rupp на 15 юни 18 в 11:53 2018-06-15 11:53

Към 2018.07

Добавете го в секцията [alias] на вашия ~/.gitconfig :

 sweep = !"f() { git branch --merged | egrep -v \"(^\\*|master|dev)\" || true | xargs git branch -d; }; f" 

Сега можете просто да извикате git sweep да направите необходимото почистване.

1
01 июля '18 в 10:49 2018-07-01 10:49 отговорът е даден сорин 01 юли, 18 в 10:49 2018-07-01 10:49

В Windows можете да инсталирате Cygwin и да изтриете всички изтрити клонове, като използвате следната команда:

 git branch -r --merged | "C:\cygwin64\bin\grep.exe" -v master | "C:\cygwin64\bin\sed.exe" 's/origin\///' | "C:\cygwin64\bin\xargs.exe" -n 1 git push --delete origin 
1
09 сент. отговор, даден от Seyed Morteza Mousavi Sep 09 2018-09-09 10:17 '18 в 22:17 часа 2018-09-09 10:17

За да избегнете случайно стартиране на команда от друг клон, различен от съветника, използвам следния скрипт bash. В противен случай, стартирайте git branch --merged | grep -v "\*" | xargs -n 1 git branch -d git branch --merged | grep -v "\*" | xargs -n 1 git branch -d git branch --merged | grep -v "\*" | xargs -n 1 git branch -d от клон, който е бил обединен с помощника, може да премахне основния клон.

 #!/bin/bash branch_name="$(git symbolic-ref HEAD 2>/dev/null)" || branch_name="(unnamed branch)" # detached HEAD branch_name=${branch_name##refs/heads/} if [[ $branch_name == 'master' ]]; then read -r -p "Are you sure? [y/N] " response if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then git branch --merged | grep -v "\*" | xargs -n 1 git branch -d fi else echo "Refusing to delete branches that are not merged into '$branch_name'. Checkout master first." fi 
1
20 янв. Отговор, даден от Robert Kajic на 20 януари 2014-01-20 20:05 '14 в 20:05 2014-01-20 20:05

Моят принос Bash скрипт се основава на mmrobin отговор .

Необходимо е да се посочат някои полезни параметри, включително и изключващи, или за проверка / изтриване само на локални или отдалечени клонове, вместо на тях.

Да кажем, че има дистанционно, наречено upstream и произход (GitHub стил, моят plug е началото, нагоре).

Не искам да изтривам НИКАКВИ майстори, HEAD или нищо от нагоре по веригата. Аз също не искам да изтривам клона за развитие, тъй като това е нашият общ клон, от който създаваме ПР.

Списък на всички отдалечени клонове, филтрирани от тези, които са били обединени

 git branch -r 

Премахнете редовете от този списък, съдържащи думи, които познавам в имената на клоновете, които не искам да изтрия:

 sed '/develop\|master\|HEAD\|upstream/d' 

Премахване на изтритото име от името на връзката (произходът / някое клонче се превръща в някакво клонче)

 sed 's/.*\///' 

Използвайте xargs за извикване на интерфейс с една линия:

 xargs git push --delete origin 

Сложете всичко заедно:

 git branch -r --merged | sed '/develop\|master\|HEAD\|upstream/d' | sed 's/.*\///' | xargs git push --delete origin 

Това ще ме остави само с някои от клоновете, върху които съм работил, но не се сля. След това можете да ги изтриете един по един, тъй като не трябва да има толкова много от тях.

Намерете клоновете, които вече не са необходими:

 git branch -ar 

Да кажем, че намирате клон 1, клон 2 и клон 3, които искате да изтриете:

 git push --delete origin branch1 branch2 branch3 
0
02 июля '15 в 11:54 2015-07-02 11:54 отговорът е даден miigotu 02 юли '15 в 11:54 2015-07-02 11:54

Ако използвате разклонен модел, като HubFlow или GitFlow, можете да използвате тази команда, за да премахнете обединени клонове на функции:

git branch --merged | grep feature.* | grep -v "\*" | xargs -n 1 git branch -d

0
26 февр. Отговорът е даден на 26 февруари. 2015-02-26 17:02 '15 в 17:02 2015-02-26 17:02
  • 1
  • 2

Други въпроси относно тагове или задайте въпрос