删除跟踪分支不再在远程

时间:2011-10-11 13:37:35

标签: git git-branch

是否有一种简单的方法可以删除远程等效项不再存在的所有跟踪分支?

示例:

分支(本地和远程)

  • 起源/主
  • 起源/错误修复-A
  • 起源/错误修复-B
  • 起源/错误修复-C

在当地,我只有一个主分支。现在我需要处理 bug-fix-a ,所以我检查它,处理它,并将更改推送到远程。接下来我用 bug-fix-b 做同样的事。

分支(本地和远程)

  • 错误修复-A
  • 错误修复-B
  • 起源/主
  • 起源/错误修复-A
  • 起源/错误修复-B
  • 起源/错误修复-C

现在我有本地分支 master bug-fix-a bug-fix-b 。 Master分支维护者将我的更改合并到 master 并删除他已经合并的所有分支。

所以现在的状态是:

分支(本地和远程)

  • 错误修复-A
  • 错误修复-B
  • 起源/主
  • 起源/错误修复-C

现在我想调用一些命令删除分支(在本例中为 bug-fix-a bug-fix-b ),这些分支不再代表在远程存储库中。

它类似于现有命令git remote prune origin,但更像是git local prune origin

42 个答案:

答案 0 :(得分:914)

git remote prune origin修剪跟踪不在遥控器上的分支。

git branch --merged列出已合并到当前分支的分支。

xargs git branch -d删除标准输入上列出的分支。

小心删除git branch --merged列出的分支。该列表可能包含master或您不想删除的其他分支。

为了让您自己有机会在删除分支之前编辑列表,您可以在一行中执行以下操作:

git branch --merged >/tmp/merged-branches && vi /tmp/merged-branches && xargs git branch -d </tmp/merged-branches

答案 1 :(得分:403)

命令后

git fetch -p
运行

时,

删除远程引用

git branch -vv

它会显示'已离开'作为远程状态。例如,

$ git branch -vv
  master                 b900de9 [origin/master: behind 4] Fixed bug
  release/v3.8           fdd2f4e [origin/release/v3.8: behind 2] Fixed bug
  release/v3.9           0d680d0 [origin/release/v3.9: behind 2] Updated comments
  bug/1234               57379e4 [origin/bug/1234: gone] Fixed bug

因此,您可以编写一个简单的脚本来删除已启用遥控器的本地分支:

git fetch -p && for branch in `git branch -vv | grep ': gone]' | awk '{print $1}'`; do git branch -D $branch; done

答案 2 :(得分:235)

这些答案中的大多数实际上并未回答原始问题。我做了一堆挖掘,this是我找到的最干净的解决方案。这是答案的一个稍微透彻的版本:

  1. 查看您的默认分支。通常是git checkout master
  2. 运行git fetch -p && git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
  3. <强>解释

    通过修剪您的跟踪分支然后删除显示它们已经消失的本地分支来实现工作#34;在git branch -vv

    备注:

    如果您的语言设置为英语以外的其他语言,则需要将gone更改为相应的字词。不会触及仅限本地的分支。已在远程删除但未合并的分支将显示通知但不会在本地删除。如果您要删除这些内容,请将-d更改为-D

答案 3 :(得分:111)

我通常不会回答已经有16个答案的问题,但所有其他答案都是错误的,正确的答案是如此简单。问题是,“是否有一种简单的方法可以删除远程等效不再存在的所有跟踪分支?”

如果“简单”意味着不脆弱,没有危险,并且不依赖于并非所有读者都会拥有的工具,那么正确答案是:否。

有些答案很简单,但他们没有按照要求做。其他人做了所要求的,但并不简单:所有人都依赖于通过文本操作命令或脚本语言解析Git输出,这些语言可能不会出现在每个系统上。最重要的是,大多数建议使用瓷器命令,其输出不是设计为由脚本解析(“瓷器”是指用于人工操作的命令;脚本应使用较低级别的“管道”命令)。 / p>

进一步阅读:

如果您想安全地执行此操作,对于问题中的用例(垃圾收集跟踪分支已在服务器上删除但仍作为本地分支存在)并且仅使用高级Git命令,则必须

  • git fetch --prune(或git fetch -p,这是一个别名,或git prune remote origin在没有抓取的情况下执行相同的操作,可能不是您想要的大部分时间。
  • 请注意报告为已删除的所有远程分支。或者,稍后查找它们git branch -v(任何孤立的跟踪分支都将标记为“[已消失]”)。
  • 每个孤立跟踪分支上的
  • git branch -d [branch_name]

如果您想为解决方案编写脚本,那么for-each-ref就是您的起点,就像Mark Longair's answer此处和this answer to another question一样,但我无法在不写作的情况下找到利用它的方法一个shell脚本循环,或使用xargs或其他东西。

背景说明

要了解正在发生的事情,您需要了解的是,在跟踪分支机构的情况下,您没有一个分支,而是三个分支。 (并且回想一下“分支”仅仅意味着指向提交的指针。)

给定跟踪分支feature/X,远程存储库(服务器)将具有此分支并将其称为feature/X。您的本地存储库有一个分支remotes/origin/feature/X,这意味着,“这是远程告诉我它的功能/ X分支是什么,上次我们谈过,”最后,本地存储库有一个分支feature/X指向您的最新提交,并配置为“跟踪”remotes/origin/feature/X,这意味着您可以拉动并推动它们保持一致。

在某些时候,有人删除了遥控器上的feature/X。从那一刻开始,你留下了你的本地feature/X(你可能不再需要了,因为功能X上的工作可能已经完成),而你的remotes/origin/feature/X肯定是无用的,因为它只有目的是记住服务器分支的状态。

Git会让你自动清理多余的remotes/origin/feature/X - 这就是git fetch --prune的作用 - 但出于某种原因,它不会让你自动删除自己的feature/X ...即使您的feature/X仍包含孤立的跟踪信息,因此它具有识别已完全合并的以前跟踪分支的信息。 (毕竟,它可以为提供让你自己手动操作的信息。)

答案 4 :(得分:50)

似乎解决方案就在这里 - https://stackoverflow.com/a/1072178/133986

简而言之,git remote prune可以实现神奇的

答案 5 :(得分:46)

我在这里找到答案: How can I delete all git branches which have been merged?

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

确保我们保持主人

您可以通过在第一个master之后添加另一个grep来确保不会删除git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d 或任何其他分支。在那种情况下你会去:

master

因此,如果我们想保留developstaginggit branch --merged | grep -v "\*" | grep -v "master" | grep -v "develop" | grep -v "staging" | xargs -n 1 git branch -d ,我们会选择:

.zshrc

将其设为别名

由于时间有限,您可能需要为.bashrcgbpurge添加别名。我叫git branches purgealias gbpurge='git branch --merged | grep -v "\*" | grep -v "master" | grep -v "develop" | grep -v "staging" | xargs -n 1 git branch -d' ):

.bashrc

然后重新加载.zshrc. ~/.bashrc

. ~/.zshrc


private final Map<String, Predicate> searchMap = new HashMap<>();

private void initSearchMap() {
    Predicate<Person> allDrivers = p -> p.getAge() >= 16;
    Predicate<Person> allDraftees = p -> p.getAge() >= 18
            && p.getAge() <= 25
            && p.getGender() == Gender.MALE;
    Predicate<Person> allPilots = p -> p.getAge() >= 23
            && p.getAge() <=65;

    searchMap.put("allDrivers", allDrivers);
    searchMap.put("allDraftees", allDraftees);
    searchMap.put("allPilots", allPilots);
}

答案 6 :(得分:27)

删除已合并为master的所有分支,但不要尝试删除master本身:

git checkout master && git pull origin master && git fetch -p && git branch -d $(git branch --merged | grep master -v)

或添加别名:

alias gitcleanlocal="git checkout master && git pull origin master && git fetch -p && git branch -d $(git branch --merged | grep master -v)"

说明:

git checkout master结帐主分行

git pull origin master确保本地分支已合并所有远程更改

git fetch -p删除对已删除的远程分支的引用

git branch -d $(git branch master --merged | grep master -v)删除已合并为master的所有分支,但不要尝试删除master本身

答案 7 :(得分:24)

Windows解决方案

对于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 $_}

git checkout master切换到主分支

git remote update origin --prune修剪远程分支

git branch -vv获取所有分支(git reference

的详细输出

Select-String -Pattern ": gone]"仅获取已从远程删除的记录。

% { $_.toString().Trim().Split(" ")[0]}获取分支名称

% {git branch -d $_}删除分支

答案 8 :(得分:18)

TL; DR:

删除所有不在远程的本地分支

git fetch -p && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -D

删除所有不在远程上且完全合并且未使用的本地分支,如之前许多答案所述。

git fetch -p && git branch --merged | grep -v '*' | grep -v 'master' | xargs git branch -d

说明

  • git fetch -p将修剪远程不再存在的所有分支
  • git branch -vv将打印本地分支,修剪后的分支将被标记为gone
  • grep ': gone]'仅选择已消失的分支
  • awk '{print $1}'过滤输出以仅显示分支的名称
  • xargs git branch -D将遍历所有行(分支)并强行删除此分支

为什么要用git branch -D而不是git branch -d来处理未完全合并的分支。

error: The branch 'xxx' is not fully merged.

答案 9 :(得分:17)

git fetch -p

这将删除未远程跟踪的所有分支。

答案 10 :(得分:16)

在大多数其他解决方案中,“消失”的模式匹配对我来说有点吓人。为了更安全,它使用--format标志来提取每个分支的上游跟踪状态。

我需要一个Windows友好版本,所以这将使用Powershell删除列为“已消失”的所有分支:

git branch --list --format "%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)" | 
    ? { $_ -ne "" } | 
    % { git branch -D $_ }

第一行列出了上游分支“已消失”的本地分支的名称。下一行删除空白行(对于未“消失”的分支输出),然后将分支名称传递给命令以删除分支。

答案 11 :(得分:15)

还有一个答案,因为这些解决方案都不符合我对优雅和跨平台性的需求:

删除不在远程上的本地分支的命令:

for b in $(git for-each-ref --format='%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)' refs/heads); do git branch -d $b; done

要将其与gitconfig集成,以便可以与git branch-prune一起运行:

重击

git config --global alias.branch-prune '!git fetch -p && for b in $(git for-each-ref --format='\''%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)'\'' refs/heads); do git branch -d $b; done'

PowerShell

git config --global alias.branch-prune '!git fetch -p && for b in $(git for-each-ref --format=''%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)'' refs/heads); do git branch -d $b; done'

(需要帮助为PowerShell和bash查找通用命令)

为什么这个答案是最好的?

  • 提供一个完整的解决方案:向您的git中添加一个git branch-prune命令
  • 在Windows PowerShell中运行正常
  • 核心思想是@jason.rickmanbulletproof method使用git for-each-ref
  • 使用--filter进行解析和过滤,因此无需外部依赖项

说明:

  • 为您的~\.gitconfig添加新的别名。执行完此操作后,您只需执行git branch-prune
  • 在此别名内:
    • 使用--prune标志获取分支,该标志“修剪不再位于远程的远程跟踪分支”
    • 使用git for-each-ref--filter获取[gone](无远程)分支列表
    • 浏览此列表并安全删除分支

答案 12 :(得分:13)

这将删除除本地主引用和当前正在使用的引用之外的所有合并本地分支:

git branch --merged | grep -v "*" | grep -v "master" | xargs git branch -d

这将删除已经从&#34; origin &#34;引用的远程存储库中删除的所有分支,但仍然在&#34; 中本地可用遥控器/原点&#34;

git remote prune origin

答案 13 :(得分:12)

您可以这样做:

git branch -vv | grep 'origin/.*: gone]' | awk '{print $1}' | xargs git branch -d

答案 14 :(得分:12)

我认为没有内置命令可以执行此操作,但执行以下操作是安全的:

git checkout master
git branch -d bug-fix-a

当您使用-d时,git将拒绝删除分支,除非它完全合并到HEAD或其上游远程跟踪分支。因此,您始终可以循环git for-each-ref的输出并尝试删除每个分支。这种方法的问题在于我怀疑您可能不希望仅因为bug-fix-d包含其历史记录而删除origin/bug-fix-d。相反,您可以创建类似以下内容的脚本:

#!/bin/sh

git checkout master &&
for r in $(git for-each-ref refs/heads --format='%(refname:short)')
do
  if [ x$(git merge-base master "$r") = x$(git rev-parse --verify "$r") ]
  then
    if [ "$r" != "master" ]
    then
      git branch -d "$r"
    fi
  fi
done

警告:我没有测试过这个脚本 - 只能小心使用......

答案 15 :(得分:12)

可能对某些简单的一行有用,以清除除master和develop

之外的所有本地分支
git branch | grep -v "master" | grep -v "develop" | xargs git branch -D

答案 16 :(得分:7)

还有另一个答案,大量来自https://stackoverflow.com/a/48411554/2858703(我喜欢它,因为它似乎消除了gone]git branch输出中匹配的任何歧义)但添加* nix弯曲:

git branch --list --format "%(if:equals=[gone])%(upstream:track)%(then)%(refname)%(end)" \
  | sed 's,^refs/heads/,,;/^$/d' \
  | xargs git branch -D

我把它包含在我路径上的git-gone脚本中:

#!/usr/bin/env bash

action() {
  ${DELETE} && xargs git branch -D || cat
}

get_gone() {
  git branch --list --format "%(if:equals=[gone])%(upstream:track)%(then)%(refname)%(end)" \
    | sed 's,^refs/heads/,,;/^$/d'

}

main() {
  DELETE=false
  while [ $# -gt 0 ] ; do
    case "${1}" in
      (-[dD] | --delete) DELETE=true ;;
    esac
    shift
  done
  get_gone | action
}

main "${@}"

NB - --format选项似乎相当新;我需要将git从2.10.something升级到2.16.3才能获得它。

答案 17 :(得分:6)

基于Powershell的解决方案比这里的许多实现更清晰。

# prune deleted remoted branches
git fetch -p

# get all branches and their corresponding remote status
# deleted remotes will be marked [gone]
git branch -v |
  #find ones marked [gone], capture branchName
  select-string -Pattern '^  (?<branchName>\S+)\s+\w+ \[gone\]' | 
  foreach-object{ 
     #delete the captured branchname.
     git branch -D $_.Matches[0].Groups['branchName']
  }

答案 18 :(得分:6)

根据上述信息,这对我有用:

git br -d `git br -vv | grep ': gone] ' | awk '{print $1}' | xargs`

它会删除远程为': gone] '的所有本地分支。

答案 19 :(得分:5)

这些都不适合我。我想要一些能够清除跟踪远程分支的所有本地分支的东西,CASE,远程分支已被删除(Select CASE (WHEN date = min(date) Then status_update else null END)。我不想删除从未设置为跟踪远程分支的本地分支(即:我的本地开发分支)。此外,我想要一个简单的单线程,只使用origin或其他简单的CLI工具,而不是编写自定义脚本。我最终使用了一点gonegit来完成这个简单的命令。

这最终是我的grep

awk

这是一个~/.gitconfig命令,可以轻松将其添加为[alias] prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -D

git config --global ...

注意:在config命令中,我使用git prune-branches选项git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d' 而不是-d,就像我在实际配置中一样。我使用git branch,因为我不想听到Git抱怨未合并的分支。您可能也想要这个功能。如果是这样,只需在该config命令的末尾使用-D而不是-D

答案 20 :(得分:5)

grep gone <(git branch -v) | cut -d ' ' -f 3 | xargs git branch -d

以上命令可用于获取在远程中合并和删除的分支,并删除在远程中不再可用的本地分支

答案 21 :(得分:3)

一个更简单的解决方案,适用于 Windows 或其他不想/不能编写命令行脚本或不想打扰 PowerShell 的人。

将分支列表转储到文件中 git branch > branches.txt
(或 git branch --merged > branches.txt,如果您是腰带和吊带类型; git branch -d 将防止删除未合并的分支)

在编辑器中打开该文件并合并所有行(我使用了 sublime 文本,因此突出显示所有行并按 ctrl+j

在分支列表前添加 git branch -d

全选、复制并粘贴(在windows cmd窗口中右键单击)到命令行中。

答案 22 :(得分:2)

基于Git Tip: Deleting Old Local Branches,它看起来与jason.rickman's solution类似,为此我使用Bash实现了一个自定义命令git gone

$ git gone
usage: git gone [-pndD] [<branch>=origin]
OPTIONS
  -p  prune remote branch
  -n  dry run: list the gone branches
  -d  delete the gone branches
  -D  delete the gone branches forcefully

EXAMPLES
git gone -pn    prune and dry run
git gone -d     delete the gone branches

git gone -pn结合了修剪并列出了“已消失”的分支:

$ git gone -pn
  bport/fix-server-broadcast         b472d5d2b [origin/bport/fix-server-broadcast: gone] Bump modules
  fport/rangepos                     45c857d15 [origin/fport/rangepos: gone] Bump modules

然后,您可以使用git gone -dgit gone -D拉动触发器。

注释

  • 我使用的正则表达式为"$BRANCH/.*: gone]",其中$BRANCH通常为origin。如果您的Git输出已本地化为法语等,则此方法可能无效。
  • Sebastian Wiesner还为Windows用户将其移植到Rust。那也叫git gone

答案 23 :(得分:2)

真正的挑战是维护者何时压缩提交。然后,使用 git 内置功能(例如 --merged)的解决方案无济于事。

工具 git-delete-merged-branches 允许方便地删除分支。我特别喜欢交互模式。

安装(需要 python3):

pip install git-delete-merged-branches

然后执行

git-delete-merged-branches --effort=3

--effort=3 对于删除压扁的分支很重要。

替代方案

答案 24 :(得分:1)

这对我有用:

git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d

答案 25 :(得分:1)

我想出了这个bash脚本。它始终保留分支developqamaster

git-clear() {
  git pull -a > /dev/null

  local branches=$(git branch --merged | grep -v 'develop' | grep -v 'master' | grep -v 'qa' | sed 's/^\s*//')
  branches=(${branches//;/ })

  if [ -z $branches ]; then
    echo 'No branches to delete...'
    return;
  fi

  echo $branches

  echo 'Do you want to delete these merged branches? (y/n)'
  read yn
  case $yn in
      [^Yy]* ) return;;
  esac

  echo 'Deleting...'

  git remote prune origin
  echo $branches | xargs git branch -d
  git branch -vv
}

答案 26 :(得分:1)

在这里,我从number of other answers中大量汲取了以下内容(我认为,仅git 2.13及更高版本),在任何类似UNIX的外壳上工作:

git for-each-ref --shell --format='ref=%(if:equals=[gone])%(upstream:track)%(then)%(refname)%(end)' refs/heads | while read entry; do eval "$entry"; [ ! -z "$ref" ] && git update-ref -d "$ref" && echo "deleted $ref"; done

这特别是使用for-each-ref而不是branch(因为branch是为人类可读的输出而不是机器处理而设计的“瓷”命令),并使用了其{{1} }参数以获取正确的转义输出(这使我们不必担心引用名称中的任何字符)。

答案 27 :(得分:1)

我喜欢使用管道,因为它使命令更易于阅读。

这是我的解决方案,如果您想删除除master以外的所有分支。

git branch | grep -v master | xargs -n 1 git branch -D

要删除符合您条件的其他分支,请修改第一和第二块。

git branch --merged | grep feature_name | xargs -n 1 git branch -D

答案 28 :(得分:0)

这里的答案似乎都不适合我或完全按照我的意愿行事(删除不在远程的本地分支)。所以我写了这个,虽然有点啰嗦,但确实有效。

touch /tmp/remote-refs && touch /tmp/local-refs && touch /tmp/diff-refs;
while shortened=$(git for-each-ref refs/remotes) && echo ${${shortened}//"\/remotes\/origin"} > /tmp/remote-refs &&
shortened=$(git for-each-ref refs/heads | grep -v "master\|develop") && echo ${${shortened}//"\/heads"} > /tmp/local-refs &&
diff=$(comm -13 /tmp/remote-refs /tmp/local-refs) && echo ${${diff}##*refs/} > /tmp/diff-refs &&
xargs git branch -D </tmp/diff-refs; do :; done

只需确保先运行 git remote prune origin

答案 29 :(得分:0)

我最近发布了一个我已经使用了很长时间的解决方案,它依赖于分支命名来包含问题编号,您可以 see this answer 链接到我的 git_clean_branches 版本,这是一个用于删除问题已关闭的分支的交互式脚本(通常通过压缩合并)。

答案 30 :(得分:0)

虽然上述答案涵盖了如何手动修剪分支,但此答案增加了自动化来解决此问题。 git 现在有一个新设置,可以为每个 fetch 操作修剪不再位于遥控器上的陈旧分支。这很棒,因为我们不再需要在每次删除分支时手动调用 remote prunegit pull 也调用 git fetch)。

为每次获取启用修剪行为

要在全局配置中启用此功能:

git config --global fetch.prune true

让事情自动发生意味着您可以忘记在新机器上添加此设置。它只是有效。

为特定遥控器上的每次获取启用修剪行为

git config --global remote.<name>.prune true

本地自动修剪

我们也可以在没有 --global 标志的情况下对本地修剪应用相同的命令。

.gitconfig

以上命令适用于全局和局部 .gitconfig 如下:

...
[fetch]
    prune = true

我建议将其添加到 ansible 配置或您的 dotfiles 存储库 (.gitconfig) 中,以便为将来自动设置。

配置设置在每次获取时调用以下命令:

git remote prune <remote name>

总结

要将引用作为正常工作流程的一部分进行修剪而不需要记住运行它,请在配置中全局设置 fetch.prune 或按远程设置 remote.<name>.prune。见git-config

答案 31 :(得分:0)

可能是您想要的命令。

运行后:

git remote prune origin

然后运行:

diff <(git branch | sed -e 's/*/ /g') <(git branch -r | sed -e 's/origin\///g') | grep '^<'

这将显示不在(git branch -r)中但在(git branch)中的所有分支

此方法有问题,它还会在本地显示之前未推送的分支

答案 32 :(得分:0)

这是我用于鱼壳的解决方案。在Mac OS X 10.11.5fish 2.3.0git 2.8.3上进行了测试。

function git_clean_branches
  set base_branch develop

  # work from our base branch
  git checkout $base_branch

  # remove local tracking branches where the remote branch is gone
  git fetch -p

  # find all local branches that have been merged into the base branch
  # and delete any without a corresponding remote branch
  set local
  for f in (git branch --merged $base_branch | grep -v "\(master\|$base_branch\|\*\)" | awk '/\s*\w*\s*/ {print $1}')
    set local $local $f
  end

  set remote
  for f in (git branch -r | xargs basename)
    set remote $remote $f
  end

  for f in $local
    echo $remote | grep --quiet "\s$f\s"
    if [ $status -gt 0 ]
      git branch -d $f
    end
  end
end

一些注意事项:

确保设置正确的base_branch。在这种情况下,我使用develop作为基本分支,但它可以是任何东西。

这部分非常重要:grep -v "\(master\|$base_branch\|\*\)"。它确保您不会删除主分支或基本分支。

我使用git branch -d <branch>作为额外的预防措施,以便不删除任何尚未与上游或当前HEAD完全合并的分支。

一种简单的测试方法是将git branch -d $f替换为echo "will delete $f"

我想我还应该补充:自己承担使用风险!

答案 33 :(得分:0)

我已经使用GitPython编写了Python脚本来删除远程上不存在的本地分支。

    import git
    import subprocess
    from git.exc import GitCommandError
    import os

    def delete_merged_branches():
        current_dir = input("Enter repository directory:")
        repo = git.Repo(current_dir)
        git_command = git.Git(current_dir)

        # fetch the remote with prune, this will delete the remote references in local.
        for remote in repo.remotes:
            remote.fetch(prune=True)

        local_branches = [branch.name for branch in repo.branches]
        deleted_branches = []

        # deleted_branches are the branches which are deleted on remote but exists on local.
        for branch in local_branches:
            try:
                remote_name = 'origin/'+ branch
                repo.git.checkout(remote_name)
            except GitCommandError:
            # if the remote reference is not present, it means the branch is deleted on remote.
                deleted_branches.append(branch)

        for branch in deleted_branches:
            print("Deleting branch:"+branch)
            git_command.execute(["git", "branch", "-D",branch])


        # clean up the work flow.
        repo.git.checkout('master')
        repo.git.pull()

    if __name__ == '__main__':
        delete_merged_branches()

希望有人觉得它有用,如果我错过了任何事情,请添加评论。

答案 34 :(得分:0)

git pull -p 

如果我们将-p与pull一起使用,它将从本地删除所有已删除的分支。

答案 35 :(得分:0)

我用一个简短的方法来做这个技巧,我建议你做同样的事情,因为它可以节省一些时间和时间。为您提供更多的可见性

只需将以下代码段添加到.bashrc(macos上的.bashprofile)。

git-cleaner() { git fetch --all --prune && git branch --merged | grep -v -E "\bmaster|preprod|dmz\b" | xargs -n 1 git branch -d ;};
  
      
  1. 获取所有遥控器
  2.   
  3. 只从git获取合并的分支
  4.   
  5. 从此列表中删除“受保护/重要”分支
  6.   
  7. 删除其余部分(例如,干净和合并的分支)
  8.   

您必须编辑grep正则表达式才能满足您的需求(这里,它会阻止master,preprod和dmz的删除)

答案 36 :(得分:-1)

如果您使用安装了zsh的{​​{1}}外壳程序,那么安全地执行此操作的最简单方法是使用内置的自动完成功能。

首先确定要删除的分支:

Oh My Zsh

这将向您显示已合并分支的列表

在知道一些要删除的信息后,键入:

~ git branch --merged

  branch1
  branch2
  branch3
* master

所有您需要做的就是点击[tab],它会向您显示本地分支机构的列表。使用制表符完成功能或只需再次单击[制表符],即可循环浏览它们以选择[输入]分支。

选项卡反复选择分支,直到拥有要删除的分支列表为止:

~ git branch -d 

现在只需按Enter键即可删除您的分支机构集合。

如果您不在终端上使用zsh ... Get it here.

答案 37 :(得分:-1)

以下命令可以解决我的问题。

// To Delete Branch Locally
git branch -d localBranchName


// To Delete Branch Remotely
git push origin --delete remoteBranchName

答案 38 :(得分:-2)

以下是使用git客户端对我有用的简单答案:

从计算机上完全删除存储库,然后再次签出。

不要混入危险的脚本。

答案 39 :(得分:-3)

这将删除本地不存在的所有远程分支(在ruby中):

bs = `git branch`.split; bs2 = `git branch -r | grep origin`.split.reject { |b| bs.include?(b.split('/')[1..-1].join('/')) }; bs2.each { |b| puts `git  push origin --delete #{b.split('/')[1..-1].join('/')}` }

说明:

# local branches
bs = `git branch`.split
# remote branches
bs2 = `git branch -r | grep origin`.split
# reject the branches that are present locally (removes origin/ in front)
bs2.reject! { |b| bs.include?(b.split('/')[1..-1].join('/')) }
# deletes the branches (removes origin/ in front)
bs2.each { |b| puts `git  push origin --delete #{b.split('/')[1..-1].join('/')}` }

答案 40 :(得分:-4)

我使用这种方法,所以我可以有更多的控制权。

git branch -D $(git branch | grep -v "master" | grep -v "develop")

这将删除所有未命名的分支:masterdevelop

答案 41 :(得分:-16)

在这里回顾答案,我认为人们已经把这个复杂到了极点。这确实应该是命令内置的一行。

  1. 根据您的操作系统重命名文件夹(REPONAME_archive_YYYYMMDD)
  2. 再次从远程克隆存储库。
  3. 从所需的存档中复制所有未远程跟踪的文件。

#KISS