Видаліть локальні гілки Git після видалення їх на віддаленому репо


162

Я хочу, щоб мої локальні та віддалені сховища завжди синхронізувалися з точки зору гілок.

Після огляду запиту на GitHub я зливаю і видаляю там свою гілку (віддалено). Як я можу отримати цю інформацію в моєму локальному сховищі та змусити Git також видалити свою локальну версію гілки?


Ви хочете видалити гілки віддаленого відстеження, локальні гілки чи обидва? Насправді ви можете написати псевдонім (bash або git), який займе всі видалені віддалені гілки, і знайти локальні копії для видалення, також все в одній команді.

Можливо, спробуйте скористатися наступними командами, щоб придумати щось, git ls-remoteі git show-ref.

Також ви можете перевірити git symbolic-refі git update-ref.

дякую за вашу допомогу, я знайшов відповідь десь ще. Дивіться мою відповідь.
sf89

Відповіді:


180

Швидкий шлях

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

NB: якщо ви не ввімкнено master, це може потенційно видалити гілку. Продовжуйте читати на "кращий шлях".

Переконайтеся, що ми тримаємо господаря

Ви можете переконатися, що masterабо будь-яка інша галузь з цього питання не буде видалена за допомогою grepдодаткової інформації. У такому випадку ви підете:

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

Отже, якби ми хотіли зберегти master, developі, stagingнаприклад, ми пішли:

git branch --merged | grep -v "\*" | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d

Зробіть це псевдонімом

Оскільки це трохи довго, ви можете додати псевдонім до свого .zshrcабо .bashrc. Шахта називається gbpurge(для git branches purge):

alias gbpurge='git branch --merged | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d'

Потім перезавантажте своє .bashrcабо .zshrc:

. ~/.bashrc

або

. ~/.zshrc

Ви можете помістити команди в псевдонім і зробити його єдиною командою. Однак, оскільки branchце фарфор, а не сантехнічна команда , слідкуйте за будь-якими змінами інтерфейсу в майбутніх версіях Git, які можуть його порушити.

1
Ідеально! Зауважте, що після робочого процесу Github локальна гілка masterбуде видалена.
Рубенс Маріуццо,

Немає впевненості, що він залишається там (я використовую його щодня, і, здається, це не роблять).
sf89

4
FYI, якщо ви хочете зберегти кілька гілок, ви можете використовувати один греп, наприклад: grep -Ev '(\*|master|important-branch)'
Ендрю Бернс

4
Якщо ви хочете поставити це ~/.gitconfigзамість цього, додайте до [alias]розділу наступне : gbpurge = !"git branch --merged | grep -Ev '\\*|master|develop|staging' | xargs -n 1 git branch -d"(не потрібно використовувати () у виразі grep).
dskrvk

82

Я використовую той самий потік з GitHub, і не знайшов попередніх відповідей, що задовольняли мене, оскільки git branch --mergedперелічує гілки, які були об'єднані, але не кожна з них була видалена віддалено в моєму випадку. Отже, це працювало для мене:

git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d

де:

  • git fetch --all -p: оновлення статусу місцевих відділень
  • git branch -vv: перелік стану місцевих відділень
  • grep ": gone]": фільтруйте видалені
  • awk '{ print $1 }': витягнути їх назви
  • xargs -n 1 git branch -d: передайте ім'я команді delete

Примітка: якщо ви хочете, ви можете використовувати -D замість -d, що примушує видалити.

Наприклад:

someUsr@someHost:~/repo$ git branch -a
basic-testing
integration-for-tests
* master
origin
playground-for-tests
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services

someUsr@someHost:~/repo$ git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d
Fetching origin
Deleted branch integration-for-tests (was fbc609a).
Deleted branch playground-for-tests (was 584b900).

someUsr@someHost:~/repo$ git branch -a
basic-testing
* master
origin
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services

Довідка:

http://git-scm.com/book/en/v2/Git-Branching-Remote-Branches


3
Я взяв на себе сміливо переконатися, що я завжди буду це робити проти господаря, тому: git checkout master; git pull origin master; git fetch --all -p; git branch -vv | grep gone | awk '{ print $1 }' | xargs -n 1 git branch -d Чудовий сценарій та пояснення, дякую за це :)
Miguelgraz

Зверніть увагу, що branch -vvпоказує останнє повідомлення про фіксацію з гілки. Якщо вам трапилося "піти" у цьому повідомленні, воно також grep goneпотрапило б у цю гілку. Тож, grep ": gone]"мабуть, трохи безпечніше використовувати.
chawkinsuf

1
Це фактична відповідь на питання. Дякую.
Андрій Гладкий

1
Ще краще:awk '$3 $4 ~ /:gone]$/ { print $1 }'
Якуб Боченський

3
Крім необхідності -Dзамість -dцього, це ідеальна відповідь!
Кас

72

спробуйте:

git pull - батон

яка видаляє вашу локальну гілку, якщо її відповідна віддалена гілка видалена.

Оновлено:

Зазначене твердження не є таким правильним.

Насправді, біг git pull --pruneбуде тільки видалити віддалене відстеження гілок , такі як

видалення / походження / fff
віддалення / походження / дев
пульти / походження / майстер

Потім ви можете запустити, git branch -rщоб перевірити гілки віддаленого відстеження, що залишилися на вашій машині. Припустимо, ліві гілки:

походження / дев
походження / майстер

що означає гілку origin/fffвидалено.

Отже, після запуску git pull --pruneпросто запустіть:

git branch --merged | grep -vFf <(git branch -r | cut -d'/' -f2-)

Ви можете дізнатися всі місцеві відділення, які:

  1. більше не мають підкореневих віддалених гілок;
  2. можна безпечно видалити.

тоді, <the command above> | xargs git branch -dможна видалити всі.


42
Ця відповідь не зовсім коректна. --pruneПрапор буде видаляти тільки дистанційне відстеження гілок, а не місцеві відділення.

3
Погоджений з @Cupcake тут, це не досягає того, що я шукаю тут.
sf89

6
Не збираюсь оновлювати, але це те, що мені потрібно було після видалення локальних гілок, а потім видалення з GitHub, але вони все ще існують як віддалені в моїй команді git remote -v.
Виступ

8
Ви також можете це зробити git fetch --prune, це мій спосіб вибору
e_m0ney

1
Ще одна помилка Git із порад, знайдених щодо переповнення стека ... git pull --pruneпризвела до "Ви попросили витягнути з віддаленого" --prune ", але не вказали гілку. Оскільки це не віддалений з конфігурацією за замовчуванням для вашої поточної гілки, ви повинна вказати гілку в командному рядку. "
jww

23

Це повинно працювати, щоб уникнути видалення головних та галузей розробки прийнятим рішенням:

git branch --merged | egrep -v "^\*|master|development" | xargs -n 1 git branch -d

16

Для людей, що користуються повноваженнями, це еквівалент відповіді вище :

git branch -vv | Select-String -Pattern ': gone]' | ForEach-Object{($_ -split "\s+")[1]} | %{ git branch -D $_ }
  1. Відфільтруйте всі гілки, які позначені як пропалі
  2. Зателефонуйте git branch -Dна кожну із знайдених гілок

6

Нічого цього не працювало для мене. Мою іншу відповідь можна побачити тут: https://stackoverflow.com/a/34969726/550454

Але по суті, я маю це в своєму ~/.gitconfig:

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -d

5

Дуже просте рішення: видаліть місцеве репо і знову клонуйте віддалений. Може здатися не дуже елегантним, але це просто і ви точно зрозумієте, що робите, не читаючи чоловічих сторінок :-).


1
Чому так багато знищених? Я маю на увазі, очевидно, неефективний, особливо з репостними репортажами, але це робить те, що просив ОП. Чи є якась інша причина, щоб цього не зробити?
3оцен

6
Тому що ви втратите всі свої місцеві гілки, сховища, нерозпущені зобов’язання ... це як риболовля динамітом.
sevenseacat

1
Те ж саме відбувається, коли ноутбук, над яким ви працюєте, якось пошкоджується, втрачається або викрадається, тому я, як правило, не зберігаю нічого важливого на місцях. Мені здається, краще просто створити гілку і натиснути її, навіть для невеликих функцій, і видалити її після того, як вона вже не корисна.

1

Я написав цей однокласник, щоб перерахувати всі локальні відділення, які не мають відповідної віддаленої гілки:

diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -

Після цього легко видалити ці локальні гілки за допомогою xargs:

diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -|xargs -r git branch -d

це я masterтакож перелічує , він не працює, як очікувалося; будьте обережні
Енріко

1

Я просто роблю це, щоб видалити об'єднані локальні гілки:

git branch -d $(git branch --merged)

і якщо ви хочете видалити неіснуючі відстеження:

git pull --prune

1

У випадку, якщо ви щойно натиснули та з’єднали свою гілку з master, виконайте наступне в git bash:

git branch -d branch_name_to_delete

Якщо ви зараз перебуваєте в цій гілці, це підштовхне вас до майстра. У цей момент зробіть тяг

git pull

-2

Відповідь, що проголосується, має можливість видалити майстер. Розгляньте нижченаведений практичний приклад.

У мене було дві функції гілок hemen_README і hemen_BASEBOX, які були об'єднані в development, а потім development були об'єднані в master. Гілки функцій hemen_README та hemen_BASEBOX видалено віддалено, але все ще відображаються локально. Крім того, я не на місцевому майстрі, а на розробці.

В такому разі

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                      671ad6c Merged in hemen_README (pull request #1)
        hemen_BASEBOX                a535c0f added global exec paths to puppet manifest
        hemen_README                 ba87489 Updated Readme with considerable details
        master                       8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop       671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/hemen_BASEBOX a535c0f added global exec paths to puppet manifest
        remotes/origin/hemen_README  ba87489 Updated Readme with considerable details
        remotes/origin/master        2f093ce Merged in develop (pull request #3)

Тож якщо я запускаю вищезазначену часткову команду

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch --merged | grep -v "\*"
        hemen_BASEBOX
        hemen_README
        master

Зауважте, що він також показує master, який згодом буде видалений.

У будь-якому випадку мені вдалося це зробити. Я ділюся з вами своїм журналом сеансів про те, як я цього досяг.

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin --dry-run
    Pruning origin
    URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
     * [would prune] origin/hemen_BASEBOX
     * [would prune] origin/hemen_README
    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin 
    Pruning origin
    URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
     * [pruned] origin/hemen_BASEBOX
     * [pruned] origin/hemen_README

Я просто перевірив, хто буде обрізаний, а потім обрізаний. дивлячись на команду гілки нижче, ми подбали про віддалені

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                671ad6c Merged in hemen_README (pull request #1)
        hemen_BASEBOX          a535c0f added global exec paths to puppet manifest
        hemen_README           ba87489 Updated Readme with considerable details
        master                 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/master  2f093ce Merged in develop (pull request #3)

Тепер продовжуйте і видаляйте місцеві гілки

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_BASEBOX 
    Deleted branch hemen_BASEBOX (was a535c0f).
    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_README
    Deleted branch hemen_README (was ba87489).

Добре зараз гілки як бажано.

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                671ad6c Merged in hemen_README (pull request #1)
        master                 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/master  2f093ce Merged in develop (pull request #3)

Звичайно, це має потенціал видалення майстра. Будь ласка, уважно прочитайте питання. Як я вже казав там, мені знадобився спосіб очищення речей на місцевих. Це означає видалення всіх гілок, які вже не існують на віддаленому. Якщо майстра вже немає, він зникне і на вашій локальній машині.
sf89
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.