for k in $(git branch -r --merged origin/master | cut -d" " -f 3); do
echo $k
done
我有一份GIT项目列表,想要清理旧的分支,希望能够列出并删除所有合并到主分支(master)的分支。是否有一种方法可以在不克隆每个仓库到本地的情况下完成上述操作?
git ls-remote
命令:
所以它的工作方式是:NAME
git-ls-remote
- List references in a remote repositorySYNOPSIS
git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>] [-q | --quiet] [--exit-code] [--get-url] [--symref] [<repository> [<refs>...]]
DESCRIPTION
Displays references available in a remote repository along with the associated commit IDs.
% git ls-remote origin
af51dfb080728117d898e1d0a10e3fe01ed67063 HEAD
6a60cc68a2953f1a62b0dca641eb29509b5b6e8c refs/heads/expdate-fix
af51dfb080728117d898e1d0a10e3fe01ed67063 refs/heads/master
4c42e43b4ccfd37074d115f6e9a694ddb8b70d55 refs/heads/redux
fd18a67bbc5cbf8aa6cda136afa4e5c20ed2d522 refs/heads/rest
7ad17cdf8b0dcd1a29a1795a363279fb3c76ac66 refs/tags/test.key
be0b2d6881902600fb3d6686c10d0a47f1e6751a refs/tags/test.pub
要仅获取分支(头),您需要缩小refspec范围:
% git ls-remote origin 'refs/heads/*'
6a60cc68a2953f1a62b0dca641eb29509b5b6e8c refs/heads/expdate-fix
af51dfb080728117d898e1d0a10e3fe01ed67063 refs/heads/master
4c42e43b4ccfd37074d115f6e9a694ddb8b70d55 refs/heads/redux
fd18a67bbc5cbf8aa6cda136afa4e5c20ed2d522 refs/heads/rest
git ls-remote origin 'refs/heads/*' | while read sha ref; do
# test if $sha is merged
done
git push origin :refs/heads/feature-x
请注意冒号左侧的空字符串,它定义了要推送到右侧内容的内容。
因此,我们得到类似于以下内容:
#!/bin/sh
set -e -u
git ls-remote origin 'refs/heads/*' | while read sha ref; do
# test if $sha is merged
E=`git cat-file -t "$sha" 2>&1`
test $? -ne 0 -a "${E#*git cat-file: *}" = "could not get object info" && continue
git branch --merged "$sha" && printf ':%s\0' "$ref"
done | xargs -0 git push origin
printf
shell内置来用ASCII NUL字符限定输出的引用名称,然后将-0
传递给xargs
以期望接收以NUL结尾的输入。这样我们就可以解决奇怪的ref名称(包含空格等)。git cat-file -t <object_sha1_name>
无法在本地存储库中找到具有指定SHA1名称的对象,则会退出非零退出代码并打印“fatal: git cat-file: could not get object info”到其stderr。
- 因此,为了测试远程ref指向的历史记录是否存在于本地存储库中,我们在它所指向的对象的SHA1名称上运行git cat-file -t
,抓取该命令的组合输出,然后测试它是否以非零退出代码退出($? -ne 0
),以及它的错误消息是否指示缺少对象(${VAR#PATTERN}
从变量VAR
的内容中删除与PATTERN
匹配的前缀,并返回结果值)。
- 如果远程ref指向的历史记录不存在于本地存储库中,则根据定义不能将其合并到任何本地ref中,因此如果我们检测到这样的ref,则跳过使用git branch --merged
进一步测试。git branch --merged
命令将无法给出正确的答案。这意味着你最好先运行 git fetch
命令,然后再进行本地操作。 - torekgit cat-file -t“$sha”
出现错误(在这里,使用Git 2.11.1,它会显示“无法获取对象信息”,并以代码128退出),则表示由该$sha
标识的引用未合并,因此不得从远程存储库中删除。 - kostixls-remote
和cat-file
,以及哪些分支已经合并到远程分支名称git branch --merged
)。然而,这并没有检查$sha
是否已合并到master
。 - Eric B.对于更多git知识的人可能可以详细解释,但今天我也遇到了相似的问题——我想删除多个仓库中的一个分支,但我不想在每个仓库中都克隆一次再删除这个分支。
事实证明,只要你在任何仓库中,git允许你删除另一个仓库中的分支。我不确定是否存在限制,例如它们必须指向同一个GitHub服务器等。
但是这对我有效:
cd to a repo dir you do not want to remove
git push git@server:path_to_repo.git :branch_you_want_to_delete
如果你仔细想一想,这实际上与以下内容相同:
git push origin :branch_you_want_delete
除非您将引用源替换为显式路径
git branch
命令查看分支,使用git branch -d <branch_name>
命令删除分支。 - phunsukwangdugit branch -d branch_name
来删除分支。是的,我想知道是否有一种方法可以在没有本地仓库副本的情况下完成此操作。 - A.Jac