2010-07-06 17 views
461

यहां मेरा गिट वर्कफ़्लो है।पुरानी रिमोट गिट शाखाओं की सफाई

मैं दो अलग-अलग कंप्यूटर (ए और बी) से काम करता हूं और ड्रॉपबॉक्स निर्देशिका में एक सामान्य गिट रिमोट स्टोर करता हूं।

मान लें कि मेरे पास दो शाखाएं मास्टर और डेवेल हैं। दोनों अपने रिमोट समकक्ष मूल/मास्टर और मूल/डेवेल को ट्रैक कर रहे हैं।

अब जबकि कंप्यूटर एक पर, मैं शाखा devel हटाना - दोनों स्थानीय और दूरस्थ - इस प्रकार है:

git push origin :heads/devel 

git branch -d devel 

अब अगर मैं कंप्यूटर एक पर git branch -a करते हैं, मैं

master 
origin/HEAD 
origin/master 

मैं अब मिल कंप्यूटर बी पर जाएं git fetch। मैं स्थानीय डेवेल शाखा को

git branch -d 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 करना अभी भी दूरस्थ शाखाओं में मूल/डेवेल सूचीबद्ध करता है।

मैं मशीन बी से डेवेल की दूरस्थ प्रविष्टि को कैसे साफ़ कर सकता हूं?

+3

मुझे यह कोशिश करने वाले व्यक्ति ने बताया है कि ड्रॉपबॉक्स फ़ोल्डर्स में गिट रिपोजिटरी थोड़ा नाजुक हैं (लेकिन अतिरिक्त विवरण के बिना)। –

+4

@ ThorbjørnRavnAndersen शायद क्योंकि आपको यह सुनिश्चित करने के लिए इंतजार करना है कि जब भी आप प्रतिबद्ध हों, यह पूरी तरह से समन्वयित हो जाए, इससे पहले कि आप सुनिश्चित कर सकें कि यह अन्य मशीन (और फिर भी एक और सिंक आवश्यक है) पर उपयोग करना सुरक्षित है। – ataulm

उत्तर

862

सबसे पहले, मशीन बी पर git branch -a का परिणाम क्या है?

दूसरा, आप पहले से ही origin पर heads/devel नष्ट कर दिया है, तो यही कारण है कि आप इसे मशीन बी से नहीं हटा सकते

प्रयास करें है

git branch -r -d origin/devel 

या

git remote prune origin 

या

git fetch origin --prune 

और अपने git कथन के अंत में --dry-run जोड़ने के लिए स्वतंत्र महसूस करें, इसे वास्तव में चलाने के बिना इसे चलाने का परिणाम देखने के लिए।

+5

'गिट शाखा -आर-डी मूल/डेवेल 'मेरे लिए काम किया। धन्यवाद। अब जब मैं 'गीट रिमोट प्रून' का मैनपेज पढ़ता हूं, तो मुझे लगता है कि यह भी काम करना चाहिए। अगली बार कोशिश करेंगे। – Jayesh

+34

'गिट रिमोट प्रून मूल' ने मेरे लिए काम किया => '* [छिड़काव] मूल/मेरी पुरानी शाखा ' –

+0

धन्यवाद। मुझे निम्न संदेश मिला "गंतव्य रीफस्पेक न तो रिमोट पर मौजूदा रेफ से मेल खाता है और न ही ..." जब मैंने रिमोट शाखा को हटाने की कोशिश की। तब मैंने 'गिट शाखा-आर-डी मूल/डेवेल' का उपयोग किया और शाखा को –

13

यहां बैश स्क्रिप्ट है जो आपके लिए यह कर सकती है। यह 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

यह "मूल/फीचर/माइब्रैंच" नामक शाखा पर टूट गया, मुझे यकीन नहीं है कि क्यों। –

+0

समस्या दो 'sed' में है। 'Sed' s/\ (। * \) \/\ (। * \)/\ 1/g'' को 'sed' s/\ ([^ /] * \) \/\ (। * \) से बदलें/\ 1/g'' –

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

यह आदेश खतरनाक प्रतीत होता है ... यह जो मैं चाहता था उसे हटाने में कामयाब रहा (और ऊपर दिए गए उत्तरों में से कम से कम चार के साथ नहीं कर सका)। लेकिन यह चार अन्य देव शाखाओं को भी हटा दिया। गिट बिल्कुल बेकार है ... – jww

+1

उन शाखाओं को आपके स्थानीय पर नहीं होना चाहिए। वैसे, सबकुछ नष्ट नहीं हुआ है। गिट प्रतिबद्ध, गिट रीफ्लॉग और फिर गिट रीसेट - हर्ड । आप सचमुच किसी भी प्रतिबद्धता (उर्फ सेव) और दूसरों के साथ कर सकते हैं। शाखा सिर्फ एक लेबल है, लेबल को हटाने से बचा नहीं जाता है ... यह हमेशा के लिए एक चेकसम होगा। अगर मुझे –

+2

मदद मिल सकती है तो मुझे बताएं बेशक, आप इन बहुत तेज़ी से ठीक करना चाहेंगे क्योंकि गिट के कचरा कलेक्टर अंततः शाखाओं द्वारा संदर्भित नहीं किए जाने वाले कामों को हटा देगा। – Andrew

5

यह आदेश master के अलावा सभी रिमोट (origin) विलय वाली शाखाओं को "सूखा चलाने" देगा। आपको लगता है कि बदल सकते हैं, या, गुरु के बाद अतिरिक्त शाखाओं जोड़ें: 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 को हटा दें। इसके अतिरिक्त, आप इसे पहले एक कांटा पर परीक्षण करना चाह सकते हैं।

git fetch --prune 

प्रत्येक रेपो में एक नियमित आधार पर स्थानीय शाखाओं कि कि हटा दी जाती है एक दूरस्थ शाखा (अब दूरस्थ GIT रेपो में मौजूद है) पर नज़र रखने की है दूर करने के लिए:

+0

अच्छा। पहली xargs के बजाय perl का उपयोग कर मेरा tweak + awk: गिट शाखा -r --merged | grep मूल | grep -v '>' | grep -v मास्टर | perl -lpe '($ जंक, $ _) = विभाजन (/ \ //, $ _, 2)' | xargs गिट पुश मूल --delete – Andrew

29

को चलाने के लिए पर विचार करें।

यह आगे से

git config remote.origin.prune true 

सरल किया जा सकता यह है कि स्वचालित रूप से छँटाई के लिए किसी भी भविष्य कर देगा एक per-repo सेटिंग है।

git config --global fetch.prune true 

या:

अपने उपयोगकर्ता के लिए इसे सेट करने के, आप भी वैश्विक .gitconfig को संपादित करने और

[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 पर फिर से दिखाई देंगी।/Config

.git में लाने के लिए उन रिमोट ट्रैकिंग शाखाओं आप स्पष्ट रूप से refs निर्दिष्ट करने की आवश्यकता को लाते समय को रोकने के लिए: ऊपर के उदाहरण में

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

हम केवल master और develop शाखाओं लाने, स्वतंत्र लग रहा है और अपना जोड़ें।

संबंधित मुद्दे