2010-07-06 106 views
461

這是我的git工作流程。清理舊的遠程git分支

我從兩臺不同的計算機(A和B)工作,並將常用的git遠程存儲在收存箱目錄中。

假設我有兩個分支master和devel。兩者都在追蹤他們的遠程對手的起源/主人和起源/發展。

現在同時在計算機A上,我刪除支線devel的 - 本地和遠程的 - 如下:

git push origin :heads/devel 

git branch -d devel 

現在,如果我在計算機A上做git branch -a,我得到

master 
origin/HEAD 
origin/master 

我現在去電腦B.做git fetch。我可以刪除當地的Devel分支

git branch -d devel 

但我無法刪除遠程devel分支。

git push origin :heads/devel 

error: unable to push to unqualified destination: heads/proxy3d 
The destination refspec neither matches an existing ref on the remote nor 
begins with refs/, and we are unable to guess a prefix based on the source ref. 
fatal: The remote end hung up unexpectedly 

在做git branch -a仍然列出遠程分支的起源/發展。

如何清理機器B的devel遠程入口?

+3

我曾試過一個人告訴我,Dropbox文件夾中的git存儲庫有點脆弱(但沒有額外的細節)。 – 2013-04-19 09:23:36

+4

@ThorbjørnRavnAndersen可能是因爲您必須等待以確保它在您提交時完全同步,然後才能確保在另一臺計算機上使用它是安全的(並且即使此時還需要另一個同步)。 – ataulm 2013-08-01 14:54:08

回答

862

首先,機器B上的git branch -a的結果是什麼?

其次,你已經上origin刪除heads/devel,所以這就是爲什麼你不能從機器B.刪除

嘗試

git branch -r -d origin/devel 

git remote prune origin 

git fetch origin --prune 

並隨時在您的git語句末尾添加--dry-run以查看運行結果,而無需實際運行它。

+5

'git branch -r -d origin/devel'爲我工作。謝謝。現在我讀了'git remote prune'的manpage,我想這也應該起作用。下次試試吧。 – Jayesh 2010-07-07 06:35:38

+34

'git remote prune origin' for me =>'* [pruned] origin/my-old-branch' – 2012-05-19 16:28:19

+0

謝謝。當我試圖刪除遠程分支時,我收到以下消息:「目的地refspec既不匹配遠程的現有參考也不...」。然後我使用了'git branch -r -d origin/devel'並刪除了分支 – 2013-02-08 01:00:44

13

這是可以爲你做的bash腳本。它是http://snippets.freerobby.com/post/491644841/remove-merged-branches-in-git腳本的修改版本。我的修改使它能夠支持不同的遠程位置。

#!/bin/bash 

current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/') 
if [ "$current_branch" != "master" ]; then 
    echo "WARNING: You are on branch $current_branch, NOT master." 
fi 
echo -e "Fetching merged branches...\n" 

git remote update --prune 
remote_branches=$(git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$") 
local_branches=$(git branch --merged | grep -v 'master$' | grep -v "$current_branch$") 
if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then 
    echo "No existing branches have been merged into $current_branch." 
else 
    echo "This will remove the following branches:" 
    if [ -n "$remote_branches" ]; then 
echo "$remote_branches" 
    fi 
    if [ -n "$local_branches" ]; then 
echo "$local_branches" 
    fi 
    read -p "Continue? (y/n): " -n 1 choice 
    echo 
    if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then 
    remotes=`echo "$remote_branches" | sed 's/\(.*\)\/\(.*\)/\1/g' | sort -u` 
# Remove remote branches 
for remote in $remotes 
do 
     branches=`echo "$remote_branches" | grep "$remote/" | sed 's/\(.*\)\/\(.*\)/:\2 /g' | tr -d '\n'` 
     git push $remote $branches 
done 

# Remove local branches 
git branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/origin\///g' | tr -d '\n'` 
    else 
echo "No branches removed." 
    fi 
fi 
+1

這打破了一個名爲「origin/feature/mybranch」的分支,我不知道爲什麼。 – 2014-05-06 12:07:45

+0

問題出在兩個「sed」中。用'sed's/\([^ /] * \)\/\(。* \)替換'sed's/\(。* \)\// \ 1/g'' – 2016-10-12 13:40:35

2

這裏是如何與SourceTree(V2.3.1)做到這一點:
1.單擊獲取
2.檢查 「修剪樹枝追蹤...」
3.按OK
4。

enter image description here

2
git push --all --prune --dry-run 

這將刪除所有分支機構從遠程回購不在您當地的回購。如果你喜歡你所看到的,請在沒有--dry-run的情況下再次運行命令。

迴應置評: 本質上,刪除行爲是危險的,因此可以隨意追加--dry-run並閱讀man git push

+7

該命令似乎很危險......它設法刪除我想要的(至少在上面四個答案中無法做到)。但它也刪除了其他四個開發分支。 Git絕對很爛... – jww 2016-09-30 05:42:59

+1

那些分支機構一定沒有在你的本地。然而,一切都不會丟失。 Git commit,Git reflog,然後git reset --hard 。你可以從字面上對任何提交(又名保存)和其他人。分支只是一個標籤,刪除標籤不會刪除保存...它將永遠有一個校驗和。讓我知道如果我可以幫助 – 2016-09-30 11:48:52

+2

當然,你會想很快恢復這些,因爲git的垃圾回收器最終會刪除未被分支引用的提交。 – Andrew 2016-10-28 20:46:45

5

此命令將「空運行」刪除所有遠程(origin)合併分支,但master除外。您可以更改,或者,主之後添加額外的分支:grep -v for-example-your-branch-here |

git branch -r --merged | 
  grep origin | 
  grep -v '>' | 
  grep -v master | 
  xargs -L1 | 
  awk '{sub(/origin\//,"");print}'| 
  xargs git push origin --delete --dry-run 

如果它看起來不錯,除去--dry-run。另外,您可能會首先嚐試在叉子上進行測試。

+0

不錯。我使用perl代替第一個xargs + awk進行調整: git branch -r --merged | grep origin | grep -v'>'| grep -v master | perl -lpe'($ junk,$ _)= split(/ \ //,$ _,2)'| xargs git push origin - 刪除 – Andrew 2016-10-28 21:06:13

29

考慮運行:

git fetch --prune 

進而在各回購定期刪除已跟蹤時會刪除的遠程分支(在遠程GIT回購不再存在)地方分支機構。

這可以通過

git config remote.origin.prune true 

進一步簡化,這是一個per-repo設置,這將使未來自動修剪

要爲用戶設置此,您也可以編輯全球的.gitconfig並添加

[fetch] 
    prune = true 

但是,它的建議,這是使用下面的命令來完成:

git config --global fetch.prune true 

或將其應用系統範圍內(不只是爲用戶)

git config --system fetch.prune true 
1

如果git branch -r笑WS很多,你是不感興趣的,你想只從本地刪除,請使用以下命令遠程跟蹤分行:

git branch -r | grep -Ev 'HEAD|master|develop' | xargs -r git branch -rd 

一個更安全的版本是,只除去合併的:

git branch -r --merged | grep -Ev 'HEAD|master|develop' | xargs -r git branch -rd 

這對於大型項目可能很有用,您不需要其他隊友的功能分支,但在初始克隆上獲取大量遠程追蹤分支。

而這一步本身並不完整,因爲那些被刪除的遠程追蹤分支會在下一個git fetch時再次出現。

要停止獲取你需要明確指定裁判的遠程跟蹤分支git的獲取/配置

[remote "origin"] 
    # fetch = +refs/heads/*:refs/remotes/origin/* 
    fetch = +refs/heads/master:refs/remotes/origin/master 
    fetch = +refs/heads/develop:refs/remotes/origin/develop 

在上面的例子中,我們只取masterdevelop分支機構,隨意並添加你的。