Dzięki git remote prune origin
mogę usunąć lokalne oddziały, które nie są już na pilocie.
Ale chcę również usunąć lokalne gałęzie, które zostały utworzone z tych zdalnych gałęzi (fajnie byłoby sprawdzić, czy nie są one połączone).
W jaki sposób mogę to zrobić?
npx git-removed-branches
(na sucho) lubnpx git-removed-branches --prune
(na serio). Musisz już mieć zainstalowany plik node.js. Zobacz odpowiedzi poniżej, aby uzyskać szczegółowe informacje.Odpowiedzi:
Po przycięciu możesz uzyskać listę zdalnych gałęzi za pomocą
git branch -r
. Listę oddziałów wraz ze zdalną gałęzią śledzenia można pobrać za pomocągit branch -vv
. Korzystając z tych dwóch list, możesz znaleźć gałęzie zdalnego śledzenia, których nie ma na liście pilotów.Ta linia powinna zrobić lewę (wymaga
bash
lubzsh
nie będzie działać ze standardową powłoką Bourne'a):git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d
Ten ciąg pobiera listę zdalnych gałęzi i przekazuje ją do
egrep
standardowego wejścia. I filtruje gałęzie, które mają zdalną gałąź śledzenia (używającgit branch -vv
i filtrując dla tych, które mająorigin
), a następnie uzyskuje pierwszą kolumnę tego wyniku, która będzie nazwą gałęzi. Na koniec przekazujemy wszystkie nazwy gałęzi do polecenia usuwania gałęzi.Ponieważ korzysta z tej
-d
opcji, nie usuwa gałęzi, które nie zostały scalone z gałęzią, w której się znajdujesz po uruchomieniu tego polecenia.Pamiętaj również, że musisz
git fetch --prune
najpierw uruchomić , w przeciwnym raziegit branch -r
nadal będą widoczne zdalne gałęzie.źródło
git fetch -p
nie zawsze wystarczy?sh.exe": cannot make pipe for process substitution: Function not implemented sh.exe": egrep -v -f /dev/fd/0: No such file or directory fatal: branch name required
Jakieś pomysły?alias git-remove-untracked='git fetch --prune && git branch -r | awk "{print \$1}" | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk "{print \$1}" | xargs git branch -d'
git branch -D
na końcu polecenia działało dla nas lepiej, ponieważ mamy tendencję do zgniatania zatwierdzeń podczas scalania, co powodujeThe branch x is not fully merged
błędy podczas uruchamiania-d
.Jeśli chcesz usunąć wszystkie lokalne gałęzie, które są już połączone w master, możesz użyć następującego polecenia:
Więcej informacji .
źródło
xargs -r git branch -d
, aby nic nie było uruchamiane, jeśli nie ma gałęzi do usunięcia. Pamiętaj, że-r
flaga może nie być dostępna wszędziegit branch --merged master --no-color | grep -v '^* master$' | xargs -n1 -r git branch -d
git branch --merged master
wyświetla listę gałęzi, które są scalone w master, następnie środkowa część grep wyklucza samego master (nie chcemy usuwać master!), A ostatnia część xargs wykonujegit branch -d
(usuń gałąź) na każdym wyniki. Lub możesz po prostu przeczytać link Więcej informacji podany w odpowiedzi;)git branch --merged master | egrep -v '^\s*\*?\s*master$' | xargs git branch -d
. Wyjście z git v2.10.1 wyświetli „* master”, gdy master jest wyewidencjonowany. Pozbywam się mistrza zarówno z gwiazdką, jak i bez niej.Wśród informacji przedstawionych przez
git help fetch
, jest ten mały przedmiot:Więc może
git fetch -p
jest to, czego szukasz?EDYCJA: Ok, dla tych, którzy wciąż debatują nad odpowiedzią 3 lata po fakcie, oto trochę więcej informacji na temat tego, dlaczego przedstawiłem tę odpowiedź ...
Po pierwsze, OP mówi, że chcą „usunąć również te lokalne gałęzie, które zostały utworzone z tych zdalnych gałęzi [których już nie ma na zdalnym]”. Nie jest to jednoznacznie możliwe w
git
. Oto przykład.Powiedzmy, że mam repozytorium na centralnym serwerze i ma on dwie gałęzie, zwane
A
iB
. Jeśli sklonuję to repozytorium do mojego lokalnego systemu, mój klon będzie miał lokalne odwołania (jeszcze nie rzeczywiste gałęzie)origin/A
iorigin/B
. Powiedzmy teraz, że wykonuję następujące czynności:Istotne fakty tutaj są takie, że z jakiegoś powodu postanowiłem utworzyć oddział w moim lokalnym repozytorium, który ma inną nazwę niż jego pochodzenie, a także mam oddział lokalny, który (jeszcze) nie istnieje w repozytorium źródłowym.
Powiedzmy teraz, że usuwam zarówno gałęzie, jak
A
iB
zdalne repozytorium i aktualizuję moje lokalne repozytorium (git fetch
jakiejś formy), co powoduje, że moje lokalne odwołaniaorigin/A
iorigin/B
znikają. Teraz mój lokalny repo ma trzy oddziały nadal,A
,Z
, iC
. Żadne z nich nie ma odpowiedniej gałęzi na zdalnym repozytorium. Dwa z nich zostały „utworzone z… odległych gałęzi”, ale nawet jeśli wiem, że kiedyś istniała gałąź wywoływanaB
na początku, nie mam sposobu, aby wiedzieć, żeZ
została utworzona zB
, ponieważ został przemianowany w tym procesie, prawdopodobnie z ważnego powodu. Tak naprawdę, bez pewnych zewnętrznych metadanych pochodzenia procesu rejestrowania gałęzi lub człowieka znającego historię, nie można stwierdzić, która z trzech gałęzi, jeśli w ogóle, OP stara się usunąć. Bez pewnych informacji zewnętrznych, któregit
nie są automatycznie utrzymywane dla ciebie,git fetch -p
jest tak blisko, jak to tylko możliwe, a każda automatyczna metoda dosłownej próby tego, o co poprosił PO, ryzykuje albo usunięcie zbyt wielu gałęzi, albo pominięcie niektórych, które w przeciwnym razie PO chcesz usunąć.Istnieją również inne scenariusze, na przykład gdy utworzę trzy oddzielne gałęzie,
origin/A
aby przetestować trzy różne podejścia do czegoś, a następnieorigin/A
znikną. Teraz mam trzy gałęzie, które oczywiście nie wszystkie pasują do nazwy, ale zostały utworzoneorigin/A
, więc dosłowna interpretacja pytania PO wymagałaby usunięcia wszystkich trzech. Może to jednak nie być pożądane, jeśli możesz nawet znaleźć niezawodny sposób na ich dopasowanie ...źródło
Spowoduje to usunięcie oddziałów lokalnych, dla których gałęzie zdalnego śledzenia zostały przycięte. (Upewnij się, że jesteś na
master
oddziale!)Detale:
git branch -vv
wyświetla „zniknął” dla lokalnych oddziałów, że pilot został przycięty.-d
sprawdzi, czy został scalony (-D
niezależnie od tego usunie)źródło
git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
git branch -d
porównuje gałęzieHEAD
.prunelocal = !sh -c \"git checkout -q master && git fetch -q --prune && git branch -vv | git grep ': gone]' | cut -d' ' -f3 | xargs git branch -d\"
Można skonfigurować Git, aby automatycznie pobierał odwołania do usuniętych zdalnych gałęzi podczas pobierania:
Podczas dzwonienia
git fetch
lubgit pull
później odniesienia do usuniętych zdalnych gałęzi są automatycznie usuwane.źródło
git branch -r
.Jest fajny pakiet NPM, który robi to za Ciebie (i powinien działać na różnych platformach).
Zainstaluj z:
npm install -g git-removed-branches
A następnie
git removed-branches
pokaże wszystkie przestarzałe lokalne oddziały igit removed-branches --prune
faktycznie je usunie.Więcej informacji tutaj.
źródło
npx git-removed-branches
działa jak sen.Rozwiązanie Windows
W przypadku programu Microsoft Windows Powershell:
git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
Wyjaśnienie
git checkout master
przechodzi do gałęzi mastergit remote update origin --prune
przycina odległe gałęziegit branch -vv
pobiera pełne wyjście wszystkich gałęzi ( referencja git )Select-String -Pattern ": gone]"
pobiera tylko te rekordy, w których zostały usunięte ze zdalnego.% { $_.toString().Split(" ")[0]}
uzyskać nazwę oddziału% {git branch -d $_}
usuwa gałąźźródło
git remote prune origin
, również select-string wydaje się nie pasować do najnowszej wersji git. Rozważ użycieConvertFrom-String -TemplateContent
git checkout master; git pull; git remote prune origin; git branch --merged | select-string -notmatch "master" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
Wyświetli listę lokalnych oddziałów, których gałąź zdalnego śledzenia została usunięta ze zdalnego
Jeśli chcesz usunąć odniesienia do tych lokalnych oddziałów z lokalnych, które nie są śledzone
źródło
Jak zauważa @tzacks ... istnieje przydatny do tego pakiet npm. Po prostu zrób:
(Skomentowałbym, ale za mało reputacji)
źródło
Jeśli używasz Windows i PowerShell, możesz użyć następujących poleceń, aby usunąć wszystkie lokalne oddziały, które zostały scalone z oddziałem aktualnie wyewidencjonowanym:
Wyjaśnienie
git
wyjściowych dla każdej pozostałej nazwy gałęziWarto
git branch --merged
najpierw uruchomić sam, aby upewnić się, że usunie tylko to, czego się spodziewasz.(Przeniesiony / zautomatyzowany z http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/ .)
źródło
Jeszcze krótszy i bezpieczniejszy jednowarstwowy:
Pamiętaj, aby przejść do kasy, która nie została jeszcze scalona, zanim ją uruchomisz. Ponieważ nie możesz usunąć oddziału, w którym jesteś aktualnie zalogowany.
źródło
git branch -d $(git branch --merged | cut -c 3- | grep -v master)
Chciałem czegoś, co wyczyści wszystkie lokalne gałęzie, które śledziły gałąź zdalną, w
origin
której usunięto gałąź zdalną (gone
). Nie chciałem usuwać lokalnych gałęzi, które nigdy nie zostały skonfigurowane do śledzenia gałęzi zdalnej (tj. Moich lokalnych gałęzi programistów). Chciałem też mieć prostą liniówkę, która po prostu używagit
lub inne proste narzędzia CLI, zamiast pisać własne skrypty. Skończyłem używać trochęgrep
i,awk
aby wykonać to proste polecenie, a następnie dodałem je jako alias w moim~/.gitconfig
.Oto
git config --global ...
polecenie umożliwiające łatwe dodanie tego jakogit prune-branches
:UWAGA: Użycie
-D
flagigit branch
może być bardzo niebezpieczne. Tak więc w powyższym poleceniu config używam-d
opcjigit branch
zamiast-D
; Używam-D
w mojej aktualnej konfiguracji. Używam,-D
ponieważ nie chcę słyszeć, jak Git narzeka na nieuporządkowane gałęzie, chcę tylko, żeby odeszły. Możesz także chcieć tę funkcjonalność. Jeśli tak, po prostu użyj-D
zamiast-d
na końcu tego polecenia config.źródło
Aby usunąć zdalne gałęzie:
Aby usunąć lokalne oddziały, które są już scalone:
źródło
Wydaje się, że nie ma bezpiecznej jednowierszowej, zbyt wielu przypadków na krawędziach (jak gałąź posiadająca „master” jako część swojej nazwy itp.). Najbezpieczniejsze są następujące kroki:
git branch -vv | grep 'gone]' > stale_branches.txt
awk '{print $1}' stale_branches.txt | xargs git branch -d
źródło
W oparciu o powyższe odpowiedzi używam tej krótszej linijki:
Ponadto, jeśli już przycinałeś i masz lokalne zwisające gałęzie, to wyczyści je:
źródło
/
w nichNie jestem pewien, jak to zrobić od razu, ale git
git branch -d <branchname>
usunie lokalny oddział TYLKO, jeśli zostanie całkowicie scalony. Zwróć uwagę na małe litery d.git branch -D <branchname>
(zwróć uwagę na wielką literę D) usunie lokalny oddział niezależnie od jego statusu scalenia.źródło
Możesz użyć tego polecenia:
Git Clean: usuwanie już połączonych gałęzi, w tym podział poleceń
źródło
Na podstawie powyższych odpowiedzi przyszedłem z tym rozwiązaniem jednoliniowym:
źródło
Korzystając z wariantu w odpowiedzi @ wisbucky, dodałem do mojego
~/.gitconfig
pliku alias :Dzięki temu prosty
git pruneitgood
wyczyści zarówno lokalne, jak i zdalne oddziały, które nie są już potrzebne po scaleniu.źródło
Wersja Powershell
git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d
git branch --merged master | %{ if($_ -notmatch '\*.*master'){ git branch -d "$($_.Trim())" }}
Spowoduje to usunięcie wszystkich lokalnych oddziałów, które zostały połączone w master, gdy jesteś w gałęzi master .
git checkout master
przełączyć.źródło
Wariant Schleisa nie działa dla mnie (Ubuntu 12.04), więc proponuję moje (jasne i błyszczące :) warianty:
Wariant 1 (wolałbym tę opcję):
Wariant 2:
za. Próba:
b. Usuń gałęzie:
źródło
Poniżej znajduje się adaptacja odpowiedzi @ wisbucky dla użytkowników systemu Windows:
for /f "tokens=1" %i in ('git branch -vv ^| findstr ": gone]"') DO git branch %i -d
Używam posh-git i niestety PS nie lubi nagich
for
, więc stworzyłem prosty skrypt poleceń o nazwie PruneOrphanBranches.cmd:Wywołaj go bez parametrów, aby wyświetlić listę, a następnie wywołaj go za pomocą „-d”, aby wykonać faktyczne usunięcie lub „-D” dla wszystkich gałęzi, które nie są w pełni scalone, ale i tak chcesz je usunąć.
źródło
:
lub:
(ze spacją)findstr
powodowało, że za każdym razem wszystko pasowało - prawie usunąłem master. Jednak użycie wyrażenia regularnego działało dobrze:git branch -vv ^| findstr /R " \[origin/[0-9]+: gone\] "
Wypróbuj to w git bash, aby pobrać i przyciąć odniesienia do usuniętych gałęzi, a następnie przyciąć lokalne gałęzie, które śledziły usunięte:
Pamiętaj, aby najpierw pobrać gałąź, która nie zostanie usunięta, aby nie blokowała usuwania gałęzi.
źródło
Przekształciłem przyjętą odpowiedź w solidny skrypt. Znajdziesz go w moim repozytorium rozszerzeń git .
źródło
Dotarłem do tej strony, szukając odpowiedzi „jak usunąć lokalnie wypisane gałęzie, które nie mają już gałęzi upstream”
Nie obchodziło mnie również, czy lokalny oddział został jeszcze włączony, ponieważ przesyłanie do niego
git branch -d
po prostu ostrzega zamiast usuwać nie połączone lokalne oddziały.źródło
W PowerShell :
źródło
Oto moje rozwiązanie:
-p oznacza usunięcie wszelkich odniesień do zdalnego śledzenia, które już nie istnieją na pilocie. Więc pierwszy krok usunie odniesienia do zdalnych gałęzi.
-vv służy do pokazania sha1 i zatwierdzenia wiersza tematu dla każdej głowy, wraz z powiązaniem z odgałęzieniem (jeśli występuje). Drugi krok spowoduje pobranie wszystkich lokalnych gałęzi, a polecenie grep odfiltruje gałęzie, które zostały usunięte.
źródło
Usuń każdą gałąź, która nie jest aktualna w Master
źródło
Jestem pewien, że
git remote prune origin
tego właśnie chcesz.Możesz uruchomić go,
git remote prune origin --dry-run
aby zobaczyć, co by zrobił bez wprowadzania jakichkolwiek zmian.źródło
Korzystasz z GUI? Procedura ręczna, ale szybka i łatwa.
Wybierz „Oddział -> Usuń”. Możesz wybrać wiele gałęzi za pomocą kliknięcia klawiszem Ctrl (Windows) i usunąć je wszystkie.
źródło