Usuń wiele zdalnych oddziałów w git


128

Mam członka zespołu, który przypadkowo przesunął ponad 150 swoich lokalnych oddziałów do naszego centralnego repozytorium. Na szczęście wszystkie mają ten sam prefiks. Używając tego przedrostka, czy istnieje polecenie git lub fajny mały skrypt powłoki, którego mogę użyć, który usunie je wszystkie na raz?

Odpowiedzi:


150

Użyj następującego polecenia, aby usunąć wszystkie gałęzie z PREFIXprefiksem na serwerze zdalnym.

git branch -r | awk -F/ '/\/PREFIX/{print $2}' | xargs -I {} git push origin :{}

Możesz najpierw wykonać próbę uruchomienia, aby sprawdzić, czy to gałęzie, które chcesz usunąć:

git branch -r | awk -F/ '/\/PREFIX/{print $2}'

2
Podoba mi się to, ponieważ to jeden liner i mogę najpierw zrobić suchy bieg. Niestety, pojawia się błąd z tym komunikatem: $ git branch -r | awk -F/ '/\/APR/{print $2}' | xargs -I {} git push origin :{} error: unable to push to unqualified destination: APR-04-DPH The destination refspec neither matches an existing ref on the remote nor begins with refs/, and we are unable to guess a prefix based on the source ref. error: failed to push some refs to 'GIT_URL'
Jake A. Smith

Dzięki git branch -r | awk -F/ '/\/APR/{print $2}', można zobaczyć cały kwiecień przedrostkiem nazwy oddziałów na liście?
neevek

1
OK, to dlatego, że APR-04-DPHgałąź została już usunięta. Spójrz na te odpowiedzi na pytania: to i to, a także to . Odpowiedzi na te pytania dotyczą tego samego problemu, możesz chcieć samodzielnie przetestować rozwiązania.
neevek

26
jeśli masz / w nazwach swoich gałęzi (jeśli używasz git-flow lub czegoś podobnego), zamiast tego wypisz {$ 2 "/" $ 3}
ajma

4
Używam msysgit w systemie Windows i działało dla mnie następujące polecenie (w połączeniu z komentarzem @ ajma dla nazw gałęzi zawierających ukośniki:git branch -r | awk -F/ '/\/PREFIX/{print $2"/"$3}' | xargs -I % git push origin --delete %
rikoe

96

Jeśli podoba Ci się prostsze podejście, na przykład usuń 3 lub 4 gałęzie:

git push origin --delete <branch1> <branch2> <branch3>

Ważne: działa tylko na Git 1.7.0 i nowszych.


6
Skończyło się na użyciugit branch -r | awk -F/ '/\/PATTERN/{print $2}' | xargs git push origin --delete
Aram Kocharyan

36

Podziękowania dla Neevek za świetne i eleganckie rozwiązanie!

Ale mam problemy z ukośnikami w nazwach gałęzi (używam Git Flow) z powodu awkseparatora pól /( -Fopcja)

Więc moje rozwiązanie jest oparte na Neevek , ale poprawnie analizuje nazwy gałęzi z /. W tym przypadku przypuszczam, że zadzwonił twój pilot origin. Polecenie do usuwania zdalnych gałęzi o nazwach zaczynających się od PATTERN:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}' | xargs -I {} git push origin :{}

I nie zapomnij sprawdzić, co zamierzasz usunąć:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}'

PRZYDATNA WSKAZÓWKA: Jeśli nazwy oddziałów (bez origin/przedrostków) są przechowywane w pliku tekstowym (jedna nazwa gałęzi w każdym wierszu), po prostu uruchom:

cat your_file.txt | xargs -I {} git push origin :{}

2
Użyj xargs -a file -Lzamiast cat file | xargs. Jeszcze prostsze xargs -a file git push --delete origin.
muzyka muzyczna

15

To może być podwójna odpowiedź, ale poniżej przetestowane i działało idealnie dla mnie.

  1. Wymuszenie usunięcia lokalnego oddziału

git branch -D nazwa-gałęzi

  1. Usuń oddział zdalny

git push origin --delete nazwa-gałęzi

  1. Usuń więcej niż 1 oddział lokalny

git branch -D nazwa-gałęzi1 nazwa-gałęzi2

  1. Usuń więcej niż 1 gałąź zdalną

git push origin --delete nazwa-gałęzi1 nazwa-gałęzi2

  1. Usuń oddział lokalny z prefiksem. Na przykład feature / *

git branch -D $ (git branch --list 'feature / *')

git branch -D backticks $ (git branch --list 'feature / *' backticks )

  1. Lista zdalnych gałęzi z prefiksem.

git branch -r | grep -Eo 'feature /.*'

  1. Usuń zdalną gałąź z prefiksem

git branch -r | grep -Eo 'feature /.*' | xargs -I {} git push origin: {}


2
myślę, że miałeś zamiar uciec przed lewicami w kroku 5
GPL

Jak dodać grawisy?
Naren

1
@Naren: problem polega na tym, że formatowanie przeceny zamienia twoje lewe znaczniki w polecenie stylizacji. Zastąpiłem je inną metodą podstawiania poleceń (np. „$ (Polecenie)” jest równoważne z „polecenie”, ale nie jest tłumaczone przez przecenę na coś dziwnego.) Inną rzeczą, którą możesz zrobić, jest uniknięcie znaku „\”
Stabledog

13

To samo z grep: git branch -r | grep -Eo 'PREFIX/.*' | xargs -i git push origin :{}.

branch -rpokazuje origin/prefix/branchname. Więc to zajmie prefix/branchname.


Myślę, że masz na myśli xargs -I {} git push origin :{}, nie -i.
jojo

1
@jojo, AFAIK, -iponieważ używa domyślnego zamiennika, {}ale z -Itobą możesz zadeklarować własny. ... właśnie znalazłem w instrukcji:-i ... the same as -I{}
Kirby

10

Rozwiązanie Neevek jest eleganckie, ale może być lepsze: proponowane rozwiązanie wywołuje „git push” raz na oddział, co oznacza dodatkową sieć w obie strony na oddział do usunięcia. Ponieważ i tak używasz awk, dlaczego nie użyć go do przedrostka „:”, a wtedy xargs może wywołać „git push” dokładnie raz i usunąć wszystkie gałęzie naraz:

Uruchom na sucho, aby wyświetlić gałęzie, które zostaną usunięte:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}'

Ostateczne rozwiązanie, aby faktycznie wypchnąć usunięte:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}' | xargs git push origin

2
Działa doskonale w sytuacji, gdy nie możesz użyć opcji "-I" dla xargs, gdy masz niższą wersję bash lub używasz git bash w wersji Windows.
zchholmes

Miałem xargs: replstr may not be emptyrozwiązanie Neevek, może wersję git .. git version 1.9.5Ale to zadziałało świetnie. Dzięki wam obojgu
IamFace

8

zasób https://coderwall.com/p/eis0ba

    1 - List all your remote branches:

    $ git branch -r

    2 - Filter the branches by some regular expression. In this case I'm interested in deleting any branch with the 'feature-' prefix:

    $ git branch -r | awk -F/ '/\/feature-/{print $2}'
    3 - Pipe the last command to git push to delete them:
    # **Edit** - Removed extra colon, which is not needed
    $ git branch -r | awk -F/ '/\/feature-/{print $2}' | xargs -I {} git push origin {}
    4 - Grab a beer.

    5 - Remove any local reference to those branches:

    $ git remote prune origin

Dzięki, to zadziałało dla mnie. W przypadku mu mogłem usunąć wiele lokalnych oddziałów. Dzięki!
Prashant Kabade

5

Dzięki Steve'owi i Neevekowi znalazłem rozwiązanie, które działało całkiem nieźle i uznałem, że warto się nim podzielić:

Rozwiązanie Steve'a zadziałało dla mnie z jedną drobną korektą. Moje piloty zostały nazwane, origin/feature/some-feature-namewięc przyciąłem twoje awk:

git branch -r | awk -Forigin/ '/\/feature/ {print $2 $3}' | xargs -I {} git push origin :{}

Teraz robi ładny mały przepływ usuwania:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
To github.com:project/project-name.git
- [deleted]         feature/search-placeholder
To github.com:project/project-name.git
- [deleted]         feature/server-error-message
To github.com:project/project-name.git
- [deleted]         feature/six-point-asterisk

Zastanawiałem się, czy ktoś miałby jakieś pomysły na bardziej eleganckie rozwiązanie, które mogłoby wypisać coś takiego (moje skrypty CLI są dość kiepskie, więc zajęłoby mi trochę czasu, zanim to zrozumiałem):

git push origin :feature/search-min-chars :feature/search-placeholder :feature/server-error-message :feature/six-point-asterisk

Dałoby to ładne pojedyncze wyjście z jednym żądaniem sieciowym:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
- [deleted]         feature/search-placeholder
- [deleted]         feature/server-error-message
- [deleted]         feature/six-point-asterisk

4

Dzięki Neevek. To działało dobrze po ponownej konfiguracji dla moich celów:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2 "/" $3}' | xargs -I {} git push origin :{}

Musiałem również wziąć pod uwagę strukturę folderów. Moje gałęzie funkcji są w strukturze folderów, takiej jak pochodzenie / funkcja / PREFIX-FEATURENUMBER. Musiałem więc zbudować swój wzór z 2 $ = folder + 3 $ = nazwa gałęzi.


4

Wszyscy używają awk, nie wiem dlaczego. Czuję, że to bardziej złożone. Oto, czego używam, aby usunąć wszystkie zdalne gałęzie na moim forkpilocie:

$ git branch -r --list 'fork/*' | sed 's/fork\///' | xargs git push --delete fork

Dodaj grepmiędzy xargsa, sedjeśli chcesz przefiltrować listę tylko do podzbioru zdalnych gałęzi.


1
Wielkie dzięki. Ten faktycznie działał dla mnie spośród wszystkich rozwiązań .. grep zwracał również pełną gałąź ze zdalną nazwą origin/blaprefix_anotherbla. Ale użycie sedporadziło sobie z tym dobrze. Kolejną zaletą tego podejścia jest to, że używam Bitbucket i nie muszę ręcznie wprowadzać hasła uwierzytelniającego dla każdego usunięcia gałęzi. Ten usuwa wszystkie gałęzie w jednej partii.
Madhur Bhaiya

Aby usunąć wszystkie gałęzie greenkeepergit branch -r | egrep 'origin/greenkeeper' | sed 's/origin\///' | xargs -I {} git push origin --delete {}
abhisekp

4

Zdaję sobie sprawę, że jest to dla polecenia git, ale jeśli szukasz alternatywnego rozwiązania, aby zrobić podobny lub taki sam wynik:

Możesz to zrobić tutaj (Git Remove Remote Branches):

Następnie wybierz żądane gałęzie:

Upewnij się, że masz uprawnienia do usuwania zdalnych gałęzi.


To powinna być najlepsza odpowiedź, jest niezależna od platformy.
karmington

Jakie jest oprogramowanie i czy jest dostępne dla systemu Linux?
abhisekp

1

Github ma również fajny interfejs użytkownika i mechanizm szybkiego usuwania gałęzi, jeśli wolisz używać interfejsu użytkownika


1
Tak, jest to tutaj udokumentowane , ale nadal musisz kliknąć raz dla każdego oddziału. Rozwiązanie z największą liczbą głosów to najlepszy sposób na zrobienie wielu gałęzi, do których możesz napisać wyrażenie regularne.
thewoolleyman

0

Próbowałem usunąć wszystkie zdalne gałęzie pochodzenia / wydania / r1-1 *, dlatego następujący wiersz poleceń działał dobrze.

git branch -r | awk -Forigin/ '/\/*r1-1/ {print $2}' |  xargs -I {} git push origin :{}

0

Nie mogłem użyć awk, ponieważ używamy struktury ukośnika dla nazw naszych gałęzi.

git branch -r | grep "origin/users/YOURNAME" | sed -r 's/^.{9}//'| xargs -i  sh -c 'git push origin --delete {}'

Spowoduje to pobranie wszystkich gałęzi zdalnych, pobranie tylko jednego dla jednego użytkownika, zdalne sterowanie ciągiem „origin /” i wykonanie usunięcia na każdym z nich.


0

Próba:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} echo {}

Usuń zdalne oddziały:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Usuń tylko w pełni połączone zdalne gałęzie:

git branch -r --merged --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Wyjaśnienie:

sed "s/origin\///"usunie origin/z nazwy oddziału. Bez zdejmowania tego otrzymałem:remote ref does not exist


0

Poprzednie odpowiedzi pomogły mi usunąć wszystkie gałęzie wydań z 2018 r. Uruchomiłem to w wierszu polecenia systemu Windows 10. Zainstalowałem brzęk , więc polecenia podobne do Linuksa działają dla mnie.

Próba:

git branch -a | grep -o "release-.*2018" | xargs -I {} echo {}

Jeśli próba pokazuje gałęzie, które nie są zdalne / pochodzenia. Uruchom poniżej polecenie git prune, aby naprawić i sprawdzić ponownie.

git remote prune origin

Usuń, jeśli jesteś zadowolony z powyższego wyniku:

git branch -a | grep -o "release-.*2018" | xargs -I {} git push origin --delete {}

Jeśli widzisz: error: unable to delete 'release-...2018': remote ref does not exist. Następnie uruchom poprzednie polecenie czyszczenia i spróbuj ponownie.


-4

Ostrzeżenie: spowoduje to usunięcie wszystkich zdalnych gałęzi. Używaj ostrożnie.

Myślę, że mój sposób usuwania zdalnych oddziałów jest najlepszy.

git branch -r | grep -v master | sed 's/origin\//:/'| xargs git push

Ostrzeżenie: spowoduje to usunięcie wszystkich zdalnych gałęzi. Używaj ostrożnie.


4
Negowany jako oczywisty troll. Usunąłbym, gdybym miał prawa.
Jake A. Smith

gdzie znalazłeś trolling?
Dmytro Gorpynenko

2
to nie jest poprawne, brakuje ci kilku ważnych argumentów dla xargs, a to nie odpowiada na pytanie.
Rob

@ JakeA.Smith Jake, myślę, że ten kod usunie zdalnego mastera - co nie ma miejsca, ponieważ grep -v master znajduje wszystko oprócz master.
Vadim Samokhin

@Rob, co jest tutaj nieprawidłowe? Ostatecznie wykonana instrukcja będzie czymś takim jak git push: some_branch: another_branch, co jest absolutnie poprawne.
Vadim Samokhin
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.