मैंने अब सालों तक एडम के जवाब का इस्तेमाल किया है। उस ने कहा, कि कुछ मामले हैं जहां यह व्यवहार नहीं कर रहा था जैसा कि मुझे उम्मीद थी:
- जिन शाखाओं में "मास्टर" शब्द शामिल था, उन्हें केवल मास्टर शाखा के बजाय "नॉटमास्टर" या "मास्टरफुल" अनदेखा किया गया था
- शाखाओं जिसमें "देव" शब्द शामिल था, केवल देव शाखा के बजाय "देव-परीक्षण" को अनदेखा किया गया था
- उन शाखाओं को हटाना जो वर्तमान शाखा के HEAD से पहुंच रहे हैं (जो जरूरी नहीं कि मास्टर हों)
- अलग राज्य में, हर शाखा को वर्तमान प्रतिबद्ध से हटाने योग्य
रेगेक्स में केवल एक बदलाव के साथ, 1 और 2 पते के लिए सीधे थे। 3 इस बात पर निर्भर करता है कि आप क्या चाहते हैं (यानी केवल उन शाखाओं को हटा दें जिन्हें मास्टर में या आपकी वर्तमान शाखा में विलय नहीं किया गया है)। 4 में विनाशकारी होने की संभावना है (हालांकि इसके साथ पुनर्प्राप्त करने योग्य git reflog
), यदि आप अनजाने में अलग किए गए HEAD राज्य में चले गए।
अंत में, मैं चाहता था कि यह सब एक-लाइनर में हो, जिसे अलग (बश | रूबी | पायथन) स्क्रिप्ट की आवश्यकता नहीं थी।
टी एल; डॉ
एक वैकल्पिक उपनाम स्वीकार करता है कि एक "उपनाम" झाडू बनाएँ -f
:
git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'
और इसके साथ आह्वान करें:
git sweep
या:
git sweep -f
लंबा, विस्तृत जवाब
मेरे लिए कुछ शाखाओं के साथ एक उदाहरण git रेपो बनाना आसान था और सही व्यवहार का परीक्षण करने के लिए करता है:
एक सिंगल कमिट के साथ एक नया git रेपो बनाएं
mkdir sweep-test && cd sweep-test && git init
echo "hello" > hello
git add . && git commit -am "initial commit"
कुछ नई शाखाएँ बनाएँ
git branch foo && git branch bar && git branch develop && git branch notmaster && git branch masterful
git branch --list
bar
develop
foo
* master
masterful
notmaster
वांछित व्यवहार: मास्टर, विकास या वर्तमान : को छोड़कर सभी विलय की गई शाखाओं का चयन करें
मूल रेगेक्स "मास्टरफुल" और "नॉटमास्टर" शाखाओं को याद करता है:
git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"
bar
अपडेटेड रेगेक्स के साथ (जो अब "देव" के बजाय "विकसित" को बाहर करता है):
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster
ब्रांच फू में स्विच करें, एक नया कमिट करें, फिर एक नया ब्रांच चेकआउट करें, फू के आधार पर, फोबार,
echo "foo" > foo
git add . && git commit -am "foo"
git checkout -b foobar
echo "foobar" > foobar
git add . && git commit -am "foobar"
मेरी वर्तमान शाखा फ़ोबार है, और यदि मैं उन शाखाओं को सूचीबद्ध करने के लिए उपरोक्त कमांड को फिर से चलाता हूं जिन्हें मैं हटाना चाहता हूं, तो शाखा "फू" को शामिल किया गया है, भले ही इसे मास्टर में विलय नहीं किया गया हो:
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
foo
masterful
notmaster
हालाँकि, यदि मैं मास्टर पर एक ही कमांड चलाता हूं, तो शाखा "फू" शामिल नहीं है:
git checkout master && git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster
और यह केवल इसलिए है क्योंकि git branch --merged
वर्तमान शाखा के प्रमुख के लिए चूक अन्यथा निर्दिष्ट नहीं है। कम से कम मेरे वर्कफ़्लो के लिए, मैं स्थानीय शाखाओं को हटाना नहीं चाहता, जब तक कि उन्हें मास्टर में विलय नहीं किया गया है, इसलिए मैं निम्नलिखित संस्करण को पसंद करता हूं:
git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster
अलग राज्य
git branch --merged
अलग-थलग पड़ने के डिफ़ॉल्ट व्यवहार पर निर्भर राज्य में और भी अधिक महत्वपूर्ण परिणाम हैं:
git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
foo
foobar
masterful
notmaster
इससे मैं केवल "फू" के साथ "फोब्बर" पर लगी शाखा को हटा देता था, जो निश्चित रूप से वांछित परिणाम नहीं है। हमारे संशोधित आदेश के साथ, हालांकि:
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster
वास्तविक डिलीट सहित एक लाइन
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" | xargs git branch -d
सभी एक उर्फ "स्वीप" में लिपटे:
git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'
उपनाम एक वैकल्पिक -f
ध्वज को स्वीकार करता है । डिफ़ॉल्ट व्यवहार केवल उन शाखाओं को हटाने के लिए है जिन्हें मास्टर में विलय कर दिया गया है, लेकिन -f
ध्वज उन शाखाओं को हटा देगा जिन्हें वर्तमान शाखा में विलय कर दिया गया है।
git sweep
Deleted branch bar (was 9a56952).
Deleted branch masterful (was 9a56952).
Deleted branch notmaster (was 9a56952).
git sweep -f
Deleted branch foo (was 2cea1ab).
git branch -D
किसी भी शाखा को थोड़ा अधिक विशिष्ट हटा दिया जाना चाहे वह विलय हो गई हो या नहीं।