Удалить локальные ветки Git после удаления их в удаленном репо

162

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

После проверки запроса на загрузку на GitHub я объединяю и удаляю свою ветку там (удаленно). Как я могу получить эту информацию в своем локальном репозитории и заставить Git удалить мою локальную версию ветки?

sf89
источник
Вы хотите удалить свои удаленные ветви отслеживания, локальные ветви или оба? На самом деле вы можете написать псевдоним (bash или git), который будет принимать все удаленные удаленные ветви, а также находить локальные копии для удаления, все в одной команде.
Может быть, попробуйте использовать следующие команды, чтобы придумать что-то, git ls-remoteи git show-ref.
Кроме того, вы можете проверить git symbolic-refи git update-ref.
спасибо за вашу помощь, я нашел ответ где-то еще. Смотрите мой ответ.
sf89
3
Возможный дубликат удаления веток больше не будет удаленным
amaechler

Ответы:

180

Быстрый способ

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

NB: если вы не включены master, это может удалить ветку. Продолжайте читать для «лучшего пути».

Убедитесь, что мы держим хозяина

Вы можете убедиться, что master, или любая другая ветка в этом отношении, не будет удалена с помощью greping для большего. В этом случае вы бы пошли:

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
sf89
источник
Вы можете поместить команды в псевдоним и сделать его одной командой. Однако, поскольку branchэто фарфор, а не сантехническая команда , следите за изменениями пользовательского интерфейса в будущих версиях Git, которые могут его сломать.
1
Отлично! Обратите внимание, что после Github Workflow локальная ветвь masterбудет удалена.
Рубенс Мариуццо
Нет, почти уверен, что он остается там (я использую его каждый день, и, похоже, он этого не делает).
sf89
4
К вашему сведению, если вы хотите сохранить несколько веток, вы можете использовать один grep, например так: 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: передайте имя команде удаления

Примечание: если вы предпочитаете, вы можете использовать -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

Alessio
источник
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
отличный
Обратите внимание, что branch -vvпоказано последнее сообщение о коммите из ветви. Если бы вы оказались в этом сообщении, то grep goneтакже попали бы в эту ветку. Так что, grep ": gone]"возможно, немного безопаснее в использовании.
chawkinsuf
1
Это фактический ответ на вопрос. Спасибо.
Андрей Гладкий
1
Еще лучше:awk '$3 $4 ~ /:gone]$/ { print $1 }'
Якуб Боченски
3
Помимо необходимости -Dвместо -dэтого это идеальный ответ!
Cas
72

пытаться:

git pull --prune

который удаляет вашу локальную ветку, если удалена соответствующая удаленная ветка.

Обновлено:

Вышеприведенное утверждение не так правильно.

На самом деле, бег git pull --pruneбудет только удалить удаленное отслеживание ветвей , такие как

пульты дистанционного управления / происхождение / FFF
пультов ДУ / происхождение / DEV
пультов ДУ / происхождение / мастер

Затем вы можете запустить git branch -rпроверку удаленных веток на вашем компьютере. Предположим, что левые ветви:

Происхождение / DEV
Происхождение / мастер

что означает, что ветвь 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можете удалить их все.

nicky_zs
источник
42
Этот ответ не совсем правильный. --pruneФлаг будет удалять только дистанционное отслеживание ветвей, а не местные отделения.
3
Согласился с @Cupcake здесь, это не достигает того, что я ищу здесь.
sf89
6
Не собираюсь повышать голос, но это то, что мне нужно после удаления локальных веток и последующего удаления из GitHub, но они все еще существуют как удаленные в моей команде git remote -v.
Spechal
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

Для людей, использующих PowerShell, это эквивалентно ответу выше :

git branch -vv | Select-String -Pattern ': gone]' | ForEach-Object{($_ -split "\s+")[1]} | %{ git branch -D $_ }
  1. Отфильтруйте все ветви, отмеченные как пропавшие
  2. Звоните git branch -Dв каждую из найденных веток
amaechler
источник
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

Очень простое решение: удалите локальное хранилище и заново клонируйте удаленное. Может показаться не очень элегантным, но это просто, и вы точно поймете, что делаете, не читая man-страниц :-).


источник
1
Почему так много голосов? Я имею в виду явно неэффективный, особенно с большими репо, но он делает то, что просил OP. Есть ли другая причина не делать этого?
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
ks1322
источник
это перечисляет меня masterтоже, это не работает, как ожидалось; будь осторожен
Энрико
1

Я просто делаю это, чтобы удалить объединенные локальные ветви:

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

и если вы хотите удалить несуществующие трекинг тоже:

git pull --prune
alacambra
источник
1

Если вы только что добавили свою ветку в master, выполните следующее в git bash:

git branch -d branch_name_to_delete

Если вы в данный момент находитесь в этой ветке, она вернет вас к мастеру. На данный момент сделать тягу с

git pull
Джошуа Шлихтинг
источник
-2

Голосовавший ответ действительно может удалить мастера. Рассмотрим приведенный ниже практический пример.

У меня было две ветки функций hemen_README и hemen_BASEBOX, которые были объединены в разработку, а затем разработка была объединена в мастер. Ветви объектов 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

Обратите внимание, что он также показывает мастер, который в конечном итоге будет удален.

В любом случае я смог это сделать. Я делюсь с вами своим журналом сеансов о том, как я этого достиг.

    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