简体   繁体   English

删除所有本地 git 分支

[英]Delete all local git branches

I follow a development process where I create a new local branch for every new feature or story card.我遵循一个开发过程,为每个新功能或故事卡创建一个新的本地分支。 When finished I merge the branch into master and then push.完成后,我将分支合并到 master 然后推送。

What tends to happen over time due to a combination of laziness or forgetfulness, is that I end up with a large list of local branches, some of which (such as spikes) may not have been merged.由于懒惰或健忘,随着时间的推移往往会发生的情况是,我最终得到了大量本地分支,其中一些(例如尖峰)可能尚未合并。

I know how to list all my local branches and I know how to remove a single branch but I was wondering if there was a git command that allows me to delete all my local branches?我知道如何列出所有本地分支,也知道如何删除单个分支,但我想知道是否有 git 命令允许我删除所有本地分支?

Below is the output of the git branch --merged command.下面是git branch --merged命令的输出。

user@machine:~/projects/application[master]$ git branch --merged
  STORY-123-Short-Description
  STORY-456-Another-Description
  STORY-789-Blah-Blah
* master

All attempts to delete branches listed with grep -v \* (as per the answers below) result in errors:所有尝试删除用grep -v \*列出的分支(根据下面的答案)都会导致错误:

error: branch 'STORY-123-Short-Description' not found.
error: branch 'STORY-456-Another-Description' not found.
error: branch 'STORY-789-Blah-Blah' not found.

I'm using:我在用着:

git 1.7.4.1  
ubuntu 10.04  
GNU bash, version 4.1.5(1)-release  
GNU grep 2.5.4  

The 'git branch -d' subcommand can delete more than one branch. 'git branch -d' 子命令可以删除多个分支。 So, simplifying @sblom's answer but adding a critical xargs:因此,简化@sblom 的答案,但添加一个关键的 xargs:

git branch -D `git branch --merged | grep -v \* | xargs`

or, further simplified to:或者,进一步简化为:

git branch --merged | grep -v \* | xargs git branch -D 

Importantly, as noted by @AndrewC, using git branch for scripting is discouraged.重要的是,正如@AndrewC 所指出的,不鼓励使用git branch编写脚本。 To avoid it use something like:为了避免它使用类似的东西:

git for-each-ref --format '%(refname:short)' refs/heads | grep -v "master\|main" | xargs git branch -D

Caution warranted on deletes!删除需谨慎!

$ mkdir br
$ cd br; git init
Initialized empty Git repository in /Users/ebg/test/br/.git/
$ touch README; git add README; git commit -m 'First commit'
[master (root-commit) 1d738b5] First commit
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README
$ git branch Story-123-a
$ git branch Story-123-b
$ git branch Story-123-c
$ git branch --merged
  Story-123-a
  Story-123-b
  Story-123-c
* master
$ git branch --merged | grep -v \* | xargs
Story-123-a Story-123-b Story-123-c
$ git branch --merged | grep -v \* | xargs git branch -D
Deleted branch Story-123-a (was 1d738b5).
Deleted branch Story-123-b (was 1d738b5).
Deleted branch Story-123-c (was 1d738b5).

The simpler way to delete all branches but keeping others like "develop" and "master" is the following:删除所有分支但保留“develop”和“master”等其他分支的更简单方法如下:

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D

very useful !很有用 !

I found a nicer way in a comment on this issue on github :在 github 上对此问题的评论中找到了更好的方法:

git branch --merged master --no-color | grep -v "master\|stable\|main" | xargs git branch -d

Edit : Added no-color option and excluding of stable branch (add other branches as needed in your case)编辑:添加了无颜色选项并排除了稳定分支(根据需要添加其他分支)

Parsing the output of git branch is not recommended, and not a good answer for future readers on Stack Overflow.不建议解析git branch的输出,对于 Stack Overflow 上的未来读者来说也不是一个好的答案。

  1. git branch is what is known as a porcelain command. git branch是所谓的瓷器命令。 Porcelain commands are not designed to be machine parsed and the output may change between different versions of Git. Porcelain 命令不是为机器解析而设计的,输出可能会在不同版本的 Git 之间发生变化。
  2. There are user configuration options that change the output of git branch in a way that makes it difficult to parse (for instance, colorization).有一些用户配置选项会以难以解析的方式更改git branch的输出(例如,着色)。 If a user has set color.branch then you will get control codes in the output, this will lead to error: branch 'foo' not found.如果用户设置了color.branch ,那么您将在输出中获得控制代码,这将导致error: branch 'foo' not found. if you attempt to pipe it into another command.如果您尝试将其通过管道传输到另一个命令中。 You can bypass this with the --no-color flag to git branch , but who knows what other user configurations might break things.您可以使用--no-color标志绕过它到git branch ,但谁知道其他用户配置可能会破坏什么。
  3. git branch may do other things that are annoying to parse, like put an asterisk next to the currently checked out branch git branch可能会做其他令人讨厌的解析,比如在当前签出的分支旁边放一个星号

The maintainer of git has this to say about scripting around git branch output git 的维护者对围绕git branch输出编写脚本有这样的说法

To find out what the current branch is, casual/careless users may have scripted around git branch, which is wrong.为了找出当前分支是什么,随意/粗心的用户可能已经围绕 git 分支编写了脚本,这是错误的。 We actively discourage against use of any Porcelain command, including git branch, in scripts, because the output from the command is subject to change to help human consumption use case.我们强烈反对在脚本中使用任何 Porcelain 命令,包括 git 分支,因为命令的输出可能会更改以帮助人类消费用例。

Answers that suggest manually editing files in the .git directory (like .git/refs/heads) are similarly problematic (refs may be in .git/packed-refs instead, or Git may change their internal layout in the future).建议手动编辑.git目录中的文件(如 .git/refs/heads)的答案同样有问题(参考可能在 .git/packed-refs 中,或者 Git 将来可能会更改其内部布局)。

Git provides the for-each-ref command to retrieve a list of branches. Git 提供了for-each-ref命令来检索分支列表。

Git 2.7.X will introduce the --merged option to so you could do something like the below to find and delete all branches merged into HEAD Git 2.7.X 将引入--merged选项,以便您可以执行以下操作来查找和删除合并到HEAD中的所有分支

for mergedBranch in $(git for-each-ref --format '%(refname:short)' --merged HEAD refs/heads/)
do
    git branch -d ${mergedBranch}
done

Git 2.6.X and older, you will need to list all local branches and then test them individually to see if they have been merged (which will be significantly slower and slightly more complicated). Git 2.6.X 及更早版本,您将需要列出所有本地分支,然后单独测试它们以查看它们是否已合并(这将明显变慢并且稍微复杂一些)。

for branch in $(git for-each-ref --format '%(refname:short)' refs/heads/)
do
    git merge-base --is-ancestor ${branch} HEAD && git branch -d ${branch}
done

Try the following shell command:尝试以下 shell 命令:

git branch | grep -v "master" | xargs git branch -D

Explanation:解释:

  • Get all branches (except for the master) via git branch | grep -v "master"通过git branch | grep -v "master"获取所有分支(master除外) git branch | grep -v "master" command git branch | grep -v "master"命令
  • Select every branch with xargs command使用xargs命令选择每个分支
  • Delete branch with xargs git branch -D使用xargs git branch -D删除分支

To delete every branch except the one that you currently have checked out:要删除除您当前已签出的分支之外的每个分支:

for b in `git branch --merged | grep -v \*`; do git branch -D $b; done

I would recommend changing git branch -D $b to an echo $b the first few times to make sure that it deletes the branches that you intend.我建议在前几次将git branch -D $b更改为echo $b以确保它删除了您想要的分支。

The below command will delete all the local branches except master branch.以下命令将删除除 master 分支之外的所有本地分支。

git branch | grep -v "master" | xargs git branch -D

The above command上面的命令

  1. list all the branches列出所有分支
  2. From the list ignore the master branch and take the rest of the branches从列表中忽略主分支并获取其余分支
  3. delete the branch删除分支

Just a note, I would upgrade to git 1.7.10.请注意,我会升级到 git 1.7.10。 You may be getting answers here that won't work on your version.您可能会在这里得到不适用于您的版本的答案。 My guess is that you would have to prefix the branch name with refs/heads/ .我的猜测是你必须在分支名称前加上refs/heads/

CAUTION, proceed with the following only if you made a copy of your working folder and .git directory.注意,仅当您制作了工作文件夹和 .git 目录的副本时,才继续执行以下操作。

I sometimes just go ahead and delete the branches I don't want straight from .git/refs/heads .有时我会直接从.git/refs/heads中删除我不想要的分支。 All these branches are text files that contain the 40 character sha-1 of the commit they point to.所有这些分支都是文本文件,其中包含它们指向的提交的 40 个字符的 sha-1。 You will have extraneous information in your .git/config if you had specific tracking set up for any of them.如果您为其中任何一个设置了特定的跟踪,您的.git/config中将包含无关信息。 You can delete those entries manually as well.您也可以手动删除这些条目。

To delete all local branches in linux except the one you are on删除linux 中的所有本地分支,除了你所在的分支

// hard delete

git branch -D $(git branch)

I found it easier to just use text editor and shell.我发现只使用文本编辑器和 shell 更容易。

  1. Type git checkout <TAB> in shell.在 shell 中输入git checkout <TAB> Will show all local branches.将显示所有本地分支机构。
  2. Copy them to a text editor, remove those you need to keep.将它们复制到文本编辑器,删除您需要保留的那些。
  3. Replace line breaks with spaces.用空格替换换行符。 (In SublimeText it's super easy.) (在 SublimeText 中非常简单。)
  4. Open shell, type git branch -D <PASTE THE BRANCHES NAMES HERE> .打开外壳,输入git branch -D <PASTE THE BRANCHES NAMES HERE>

That's it.而已。

在 Windows 命令行中,使用以下命令删除除当前签出分支之外的所有内容:

for /f "tokens=*" %f in ('git branch ^| find /v "*"') do git branch -D %f

If you want to delete all your local branches, here is the simple command:如果要删除所有本地分支,请使用以下简单命令:

git branch -D `git branch`

Note: This will delete all the branches except the current checked out branch注意:这将删除除当前签出分支之外的所有分支

I had a similar kind of situation and recently found the following command useful.我有类似的情况,最近发现以下命令很有用。

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep>/) printf "%s", $0 }'`

If you want to keep multiple branches, then如果你想保留多个分支,那么

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep1>|<Branch_You_Want_to_Keep2>/) printf "%s", $0 }'`

hope this helps someone.希望这可以帮助某人。

Here's the Powershell solution for anyone running on a Windows machine这是适用于在 Windows 机器上运行的任何人的 Powershell 解决方案

git checkout master # by being on the master branch, you won't be able to delete it
foreach($branch in (git branch))
{
    git branch -D $branch.Trim()
}

If you work with NodeJS, I wrote this command :如果你使用 NodeJS,我写了这个命令

npx git-clear-branch

The command clears all of your local branch except master and current branch.该命令清除除 master 和 current 分支之外的所有本地分支。

git branch -l |grep -v master | xargs git branch -D

But what care deleting branch ;但是在乎删除分支; just remove the workspace and re clone it if it t is a small repository !!如果它是一个小存储库,只需删除工作区并重新克隆它!

If you don't need to go through Git itself, you can also delete heads under .git/refs/heads manually or programmatically.如果您不需要通过 Git 本身,您也可以手动或以编程方式删除.git/refs/heads下的头。 The following should work with minimal tweaking under Bash:以下内容应在 Bash 下进行最少的调整:

shopt -s extglob
rm -rf .git/refs/heads/!(master)

This will delete every local branch except your master branch.这将删除除您的主分支之外的每个本地分支。 Since your upstream branches are stored under .git/refs/remotes , they will remain untouched.由于您的上游分支存储在.git/refs/remotes下,它们将保持不变。

If you are not using Bash, or want to recurse a lot of Git repositories at once, you can do something similar with GNU find:如果您不使用 Bash,或者想一次递归大量 Git 存储库,您可以使用 GNU find 执行类似的操作:

find . \
    -path remotes -path logs -prune -o \
    -wholename \*.git/refs/heads/\* \! -name master -print0 |
xargs -0 rm -rf

The find solution is probably more portable, but pruning paths and filenames is tricky and potentially more error-prone. find 解决方案可能更便携,但修剪路径和文件名很棘手,并且可能更容易出错。

None of the answers satisfied my needs fully, so here we go:没有一个答案完全满足我的需求,所以我们开始吧:

git branch --merged | grep -E "(feature|bugfix|hotfix)/" | xargs git branch -D && git remote prune origin

This will delete all local branches which are merged and starting with feature/ , bugfix/ or hotfix/ .这将删除所有合并并以feature/bugfix/hotfix/开头的本地分支。 Afterwards the upstream remote origin is pruned (you may have to enter a password).之后上游远程origin被修剪(您可能必须输入密码)。

Works on Git 1.9.5.适用于 Git 1.9.5。

Although this isn't a command line solution, I'm surprised the Git GUI hasn't been suggested yet.尽管这不是命令行解决方案,但我很惊讶尚未建议使用Git GUI

I use the command line 99% of the time, but in this case its either far to slow (hence the original question), or you don't know what you are about to delete when resorting to some lengthy, but clever shell manipulation.我 99% 的时间都使用命令行,但在这种情况下,它要么太慢(因此是原始问题),要么在诉诸冗长但巧妙的 shell 操作时,您不知道要删除什么。

The UI solves this issue since you can quickly check off the branches you want removed, and be reminded of ones you want to keep, without having to type a command for every branch. UI 解决了这个问题,因为您可以快速检查要删除的分支,并提醒您要保留的分支,而无需为每个分支键入命令。

From the UI go to Branch --> Delete and Ctrl+Click the branches you want to delete so they are highlighted.从 UI 转到Branch --> DeleteCtrl+单击要删除的分支,以便突出显示它们。 If you want to be sure they are merged into a branch (such as dev ), under Delete Only if Merged Into set Local Branch to dev .如果您想确保将它们合并到一个分支中(例如dev ),请在“仅在合并到时删除”下将Local Branch设置为dev Otherwise, set it to Always to ignore this check.否则,将其设置为Always以忽略此检查。

GitUI:删除本地分支

基于此处的多个答案的组合-如果您想保留远程上存在的所有分支但删除其余分支,则以下 oneliner 可以解决问题:

git for-each-ref --format '%(refname:short)' refs/heads | grep -Ev `git ls-remote --quiet --heads origin | awk '{print substr($2, 12)}'| paste -sd "|" -` | xargs git branch -D

If you want to keep master, develop and all remote branches.如果您想保留 master、develop 和所有远程分支。 Delete all local branches which are not present on Github anymore.删除 Github 上不再存在的所有本地分支。

$ git fetch --prune

$ git branch | grep -v "origin" | grep -v "develop" | grep -v "master" | xargs git branch -D

1] It will delete remote refs that are no longer in use on the remote repository. 1] 它将删除远程存储库中不再使用的远程引用。

2] This will get list of all your branches. 2] 这将获得所有分支的列表。 Remove branch containing master, develop or origin (remote branches) from the list.从列表中删除包含 master、develop 或 origin(远程分支)的分支。 Delete all branches in list.删除列表中的所有分支。

Warning - This deletes your own local branches as well.警告 - 这也会删除您自己的本地分支。 So do this when you have merged your branch and doing a cleanup after merge, delete.因此,当您合并分支并在合并、删除后进行清理时,请执行此操作。

删除所有本地 git 分支但保留 main

git branch | grep -v "main" | xargs git branch -D 

git branch -d [branch name] for local delete git branch -d [branch name]用于本地删除

git branch -D [branch name] also for local delete but forces it git branch -D [branch name]也用于本地删除但强制它

For powershell, this will work:对于 powershell,这将起作用:

git branch --format '%(refname:lstrip=2)' --merged `
    | Where-Object { $_ -ne 'master' } `
    | ForEach-Object { git branch -d $_ }

I don't have grep or other unix on my box but this worked from VSCode's terminal:我的盒子上没有 grep 或其他 unix,但这在 VSCode 的终端上有效:

git branch -d $(git branch).trim()

I use the lowercase d so it won't delete unmerged branches.我使用小写的 d 所以它不会删除未合并的分支。

I was also on master when I did it, so * master doesn't exist so it didn't attempt deleting master.当我这样做时,我也在 master 上,所以* master不存在,所以它没有尝试删除 master。

I recommend a more moderate answer.我建议一个更温和的答案。 Many of the answers here use -D which is forced delete regardless of whether changes have been merged or not.这里的许多答案都使用-D强制删除,无论更改是否已合并。 Here is a one liner which leaves untouched the branches which have un-merged changes.这是一个单一的衬里,它使具有未合并更改的分支保持不变。

git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d

Or you can try other examples listed but just change the -D to -d .或者您可以尝试列出的其他示例,但只需将-D更改为-d I know the OP asked how to delete, but in most use cases, its safer to use -d .我知道 OP 询问如何删除,但在大多数用例中,使用-d更安全。

For this purpose, you can use git-extras为此,您可以使用git-extras

$ git delete-merged-branches
Deleted feature/themes (was c029ab3).
Deleted feature/live_preview (was a81b002).
Deleted feature/dashboard (was 923befa).

Deleting many local branches at once一次删除多个本地分支

# delete all local unmerged branches
git branch --no-merged | egrep -v "(^\*|master|dev)" | xargs git branch -D
# delete all local branches (merged and unmerged).
git branch | egrep -v "(^\*|master|dev)" | xargs git branch -D  

Deleting remote branches删除远程分支

# Deleting non-existent tracking branches
git remote prune <remote> --dry-run
# Deleting a single remote branch
git push <remote> --delete <branch>
# Deleting many remote branches at once
git branch -r --merged | egrep -v "(^\*|master|dev)" | sed 's/origin\///' | xargs -n 1 git push origin --delete

Source 资源

The following script deletes branches.以下脚本删除分支。 Use it and modify it at your own risk, etc. etc.使用它并自行承担修改等风险。

Based on the other answers in this question, I ended up writing a quick bash script for myself.基于这个问题的其他答案,我最终为自己编写了一个快速的 bash 脚本。 I called it "gitbd" (git branch -D) but if you use it, you can rename it to whatever you want.我称它为“gitbd”(git branch -D),但如果你使用它,你可以将它重命名为你想要的任何名称。

gitbd() {
if [ $# -le 1 ]
  then
    local branches_to_delete=`git for-each-ref --format '%(refname:short)' refs/heads/ | grep "$1"`
    printf "Matching branches:\n\n$branches_to_delete\n\nDelete? [Y/n] "
    read -n 1 -r # Immediately continue after getting 1 keypress
    echo # Move to a new line
    if [[ ! $REPLY == 'N' && ! $REPLY == 'n' ]]
      then
        echo $branches_to_delete | xargs git branch -D
    fi
else
  echo "This command takes one arg (match pattern) or no args (match all)"
fi
}

It will offer to delete any branches which match a pattern argument, if passed in, or all local branches when called with with no arguments.它将提供删除与模式参数匹配的任何分支(如果传入),或者在不带参数调用时删除所有本地分支。 It will also give you a confirmation step, since, you know, we're deleting things, so that's nice.它还会为您提供确认步骤,因为您知道,我们正在删除内容,这很好。

It's kind of dumb - if there are no branches that match the pattern, it doesn't realize it.这有点愚蠢——如果没有与模式匹配的分支,它就不会意识到这一点。

An example output run:示例输出运行:

$ gitbd test
Matching branches:

dummy+test1
dummy+test2
dummy+test3

Delete? [Y/n] 

I wrote a shell script in order to remove all local branches except develop我写了一个 shell 脚本来删除除develop之外的所有本地分支

branches=$(git branch | tr -d " *")
output=""
for branch in $branches 
do
  if [[ $branch != "develop" ]]; then
    output="$output $branch"
  fi
done
git branch -d $output

Above answers works fine.以上答案工作正常。 Here is another approach when we have lot of branches in local repo and we have to delete many branches except few which are lying in local machine.这是另一种方法,当我们在本地仓库中有很多分支并且我们必须删除许多分支,除了少数位于本地机器中的分支。

First git branch will list all the local branches.第一个git branch将列出所有本地分支。

To transpose the column of branch names into single row in file by running a unix command通过运行 unix 命令将分支名称列转换为文件中的单行
git branch > sample.txt
This will save it in sample.txt file.这会将其保存在sample.txt文件中。 And run并运行
awk 'BEGIN { ORS = " " } { print }' sample.txt
command in shell. shell中的命令。 This will transform the column to row and copy the list of branch names in single row.这会将列转换为行并将分支名称列表复制到单行中。

And then run然后运行
git branch -D branch_name(s) . git branch -D branch_name(s)
This will delete all listed branches present in local这将删除本地存在的所有列出的分支

最实用的方法:确保您没有在master上提交未提交的工作,如果需要则提交/推送,克隆存储库的新副本,以及删除旧的副本。

Make sure you do this first 确保先执行此操作

git fetch

Once you have all remote branches information, use the following command to remove every single branch except master 获得所有远程分支信息后,使用以下命令删除除master之外的每个分支

 git branch -a | grep -v "master" | grep remotes | sed 's/remotes\/origin\///g' | xargs git push origin --delete

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM