पुराने दूरस्थ गिट शाखाओं की सफाई


694

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

मान लीजिए कि मेरी दो शाखाएँ हैं, गुरु और देव। दोनों अपने दूरस्थ समकक्षों की उत्पत्ति / गुरु और उत्पत्ति / रहस्य पर नज़र रख रहे हैं।

अब कंप्यूटर ए पर, मैं स्थानीय और रिमोट पर, शाखा डेवेल को हटा देता हूं।

git push origin :heads/devel
git branch -d devel

git branch -aकंप्यूटर ए पर चल रहा है, मुझे शाखाओं की निम्नलिखित सूची मिलती है।

  • गुरुजी
  • मूल / HEAD
  • मूल / मास्टर

git fetchकंप्यूटर बी पर चल रहा है, मैं स्थानीय डेवेल शाखा को git branch -d develहटा सकता हूं, लेकिन मैं दूरस्थ डेवेल शाखा को नहीं हटा सकता।

git push origin :heads/devel निम्न त्रुटि संदेश देता है।

त्रुटि: अयोग्य गंतव्य को धक्का देने में असमर्थ: प्रमुख / प्रॉक्सी
3 डी गंतव्य रिफस्पेक न तो रिमोट पर एक मौजूदा रेफरी से मेल खाता है और न ही रेफ्स / के साथ शुरू होता है, और हम स्रोत रेफ के आधार पर एक उपसर्ग का अनुमान लगाने में असमर्थ हैं।
घातक: दूरस्थ अंत अप्रत्याशित रूप से लटका हुआ है

git branch -a अभी भी दूरस्थ शाखाओं में उत्पत्ति / रहस्य को सूचीबद्ध करता है।

मैं कंप्यूटर B से दूरस्थ शाखाओं को कैसे साफ कर सकता हूं?


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

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

जवाबों:


1240

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

दूसरा, आपने पहले ही डिलीट heads/develकर दिया है origin, इसलिए आप इसे मशीन B से हटा नहीं सकते हैं।

प्रयत्न

git branch -r -d origin/devel

या

git remote prune origin

या

git fetch origin --prune

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

के लिए डॉक्स git remote pruneऔर git branch


50
git remote prune originमेरे लिए काम किया>> * [pruned] origin/my-old-branch
हरि करम सिंह

126
git remote prune origin --dry-runआपको दिखाता है कि वास्तव में कर रहे w / o को क्या हटाया जाएगा।
वोल्फ्राम अर्नोल्ड

30
git fetch origin --pruneहटाए गए शाखाओं को हटाने के लिए एकदम सही था
सेबेस्टियन बारबेरि

10
यदि आपके पास एक स्थानीय शाखा है जो एक रिमोट ट्रैकिंग है, तो यह कुछ भी नहीं हटाएगा। उन लोगों के लिए, यह git branch -vvउसके बाद दिखाई देता है git branch -D branchnameऔर अंत में prune सबसे अच्छा तरीका है।
रोमन स्टार्कोव

7
आप निम्न विकल्प को सेट करके स्वचालित रूप से पुल / git config remote.origin.prune true
भ्रूण पर होने वाली प्रूनिंग

100

चलाने पर विचार करें:

git fetch --prune

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

इसे और सरल बनाया जा सकता है

git config remote.origin.prune true

यह एक ऐसी per-repoसेटिंग है जो किसी भी भविष्य git fetch or git pullको स्वचालित रूप से prune बनाने के लिए करेगी ।

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

[fetch]
    prune = true

हालाँकि, यह अनुशंसा की जाती है कि यह निम्नलिखित कमांड का उपयोग करके किया जाता है:

git config --global fetch.prune true

या इसे सिस्टम में लागू करने के लिए (न केवल उपयोगकर्ता के लिए)

git config --system fetch.prune true

14

यहां बैश स्क्रिप्ट है जो आपके लिए कर सकती है। यह 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
यह "मूल / सुविधा / mybranch" नामक एक शाखा पर टूट गया, मुझे यकीन नहीं है कि क्यों।
स्टावरोस कोरोकिथाकिस

समस्या दो sedएस में है। बदलें sed 's/\(.*\)\/\(.*\)/\1/g'द्वाराsed 's/\([^/]*\)\/\(.*\)/\1/g'
बेनोइट Latinier

14

यह कमांड 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। इसके अतिरिक्त, आप पहले कांटे पर यह परीक्षण करना पसंद कर सकते हैं।


अच्छा लगा। 1 xargs + awk के बजाय perl का उपयोग कर मेरा ट्वीक: git Branch -r --merged | grep उत्पत्ति | grep -v '>' | grep -v मास्टर | perl -lpe '($ कबाड़, $ _) = विभाजन (/ \ //, $ _, 2)' | xargs git push Origin --delete
एंड्रयू

6

यदि आपको git branch -rबहुत-सी दूरस्थ-ट्रैकिंग शाखाएँ दिखाई देती हैं, जिनमें आपकी रुचि नहीं है और आप उन्हें केवल स्थानीय से हटाना चाहते हैं, तो निम्न आदेश का उपयोग करें:

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 / config में लाने के लिए स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता है :

[remote "origin"]
  # fetch = +refs/heads/*:refs/remotes/origin/*    ### don't fetch everything
  fetch = +refs/heads/master:refs/remotes/origin/master
  fetch = +refs/heads/develop:refs/remotes/origin/develop
  fetch = +refs/heads/release/*:refs/remotes/origin/release/*

ऊपर के उदाहरण में हम केवल लाने master, developऔर जारी शाखाओं, जैसा कि आप की जरूरत है अनुकूलित करने के लिए स्वतंत्र लग रहा है।


1
धन्यवाद, पहले कमांड ने मेरे लिए काम किया। आप केवल एक शाखा प्राप्त कर सकते हैं git fetch origin branchnameया एक उपनाम बना सकते हैं जैसे ft = "!f() { git fetch origin $(git rev-parse --abbrev-ref HEAD);}; f"केवल वर्तमान शाखा (मेरा व्यक्तिगत पसंदीदा) लाने के लिए। चीयर्स।
गियोवन्मेरिनो

शायद OT लेकिन -rध्वज का क्या अर्थ है? मुझे लगता है xargsकि एक -Rतर्क है, लेकिन इसके बारे में कुछ नहीं मिला -r। मेरा मतलब है, सिद्धांत में अगर मुझे सही ढंग से याद है कि कैसे xargsकाम करता है, भले ही -rइसके बिना काम करना चाहिए।
एल्डो 'xoen' Giambelluca

मुझे यह उत्तर पसंद है। नोटों की एक जोड़ी (वास्तव में स्पष्ट बताते हुए)। यह संभव है कि "पूर्वावलोकन" किया जाए कि कौन सी शाखाएं अंतिम पाइप और अंतिम कमांड को हटाकर नष्ट होने जा रही हैं | xargs git branch -d। इसके अलावा, -rविकल्प को हटाने से ( --remotes) git branch -dहम केवल स्थानीय शाखाओं को साफ करते हैं (जो कि इस बात पर पर्याप्त विचार कर सकते हैं कि डिफ़ॉल्ट रूप से git branchवैसे भी दूरस्थ शाखाएं नहीं दिखती हैं)।
एल्डो 'जिओनी' गिएम्बेलुका

धन्यवाद! यह वही था जो मुझे चाहिए था। अन्य समाधान सुझाव देते हैं कि स्थानीय शाखाओं को दूर तक धकेलने के साथ-साथ उन्हें वहां से हटाया जाए, लेकिन जब रिमोट को हटा दिया जाता है या अधिक समय तक मौजूद रहने में मदद नहीं मिलती है। इस दृष्टिकोण ने उन दूरस्थ शाखाओं के स्थानीय संदर्भों को हटा दिया जिनकी अब मेरे पास पहुँच नहीं है।
सावधानी

@aldo, के बारे में xargs -r, अर्थात् --no-run-if-empty, यह एक GNU विस्तार का मतलब है, यहाँ एक अच्छी व्याख्या है
रेनस

4

विलोपन हमेशा एक चुनौतीपूर्ण कार्य है और खतरनाक हो सकता है !!! इसलिए, पहले कमांड को देखें कि क्या होगा:

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

ऊपर से ऐसा करके, git आपको यह सूची प्रदान करेगा कि यदि नीचे की कमान निष्पादित होती है तो क्या होगा।

फिर दूरस्थ रेपो से उन सभी शाखाओं को हटाने के लिए निम्नलिखित कमांड चलाएँ जो आपके स्थानीय रेपो में नहीं हैं:

git push --all --prune

10
यह आदेश खतरनाक प्रतीत होता है ... यह जो मैं चाहता था उसे हटाने में कामयाब रहा (और उपरोक्त उत्तरों में से कम से कम चार के साथ नहीं कर सका)। लेकिन इसने चार अन्य देव-शाखाओं को भी नष्ट कर दिया। पूरी तरह से चूसता है ...
jww

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

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

1
-nइस कमांड में जोड़ना (ड्राई रन) करना अच्छा है ताकि आप बदलावों का पूर्वावलोकन कर सकें और यदि सब कुछ ठीक है तो बिना दोबारा कॉल करें -n
mati865

1
@GuiWeinmann से सहमत - यह बहुत खतरनाक है, विशेष रूप से विशिष्ट कॉलआउट के बिना कम से कम इसे पहले ड्राई-रन में चलाएं।
विवेक एम। चावला

2

SourceTree (v2.3.1) के साथ यह कैसे करना है:
1. यहां क्लिक करें
2. चेक करें "Prune ट्रैकिंग शाखाएं ..."
3. ठीक दबाएं
4. it

यहाँ छवि विवरण दर्ज करें


1

मुझे यहां एक उत्तर जोड़ना होगा, क्योंकि अन्य उत्तर या तो मेरे मामले को कवर नहीं कर रहे हैं या अनावश्यक रूप से जटिल हैं। मैं अन्य डेवलपर्स के साथ जीथब का उपयोग करता हूं और मैं केवल उन सभी स्थानीय शाखाओं को चाहता हूं जिनके रिमोट (संभवतः मर्ज किए गए) और एक गिथब पीआर से हटाए गए हैं जो मेरी मशीन से एक बार में हटाए जाएंगे। नहीं, जैसी बातेंgit branch -r --merged उन शाखाओं को कवर नहीं करती हैं जिन्हें स्थानीय रूप से विलय नहीं किया गया था, या जिन्हें विलय नहीं किया गया था (परित्यक्त) आदि, इसलिए एक अलग समाधान की आवश्यकता है।

वैसे भी, पहला कदम मुझे अन्य उत्तरों से मिला:

git fetch --prune

का एक सूखा रन git remote prune origin ऐसा लग रहा था कि यह मेरे मामले में ऐसा ही करेगा, इसलिए मैं इसे सरल रखने के लिए सबसे छोटे संस्करण के साथ गया।

अब, git branch -vउन शाखाओं को चिह्नित करना चाहिए जिनके रिमोट के रूप में हटाए गए हैं [gone]। इसलिए, मुझे केवल इतना करना है:

git branch -v|grep \\[gone\\]|awk '{print $1}'|xargs -I{} git branch -D {}

जैसा कि सरल है, यह उपरोक्त परिदृश्य के लिए मेरे द्वारा वांछित सभी चीज़ों को हटा देता है।

कम आम xargsवाक्यविन्यास इतना है कि यह लिनक्स के अलावा मैक और बीएसडी पर भी काम करता है। सावधान, यह कमांड शुष्क रन नहीं है, इसलिए यह सभी शाखाओं को चिह्नित के रूप में हटा देगा [gone]। जाहिर है, यह कुछ भी नहीं किया जा रहा है हमेशा के लिए चला गया है, अगर आप शाखाओं को हटा दिया है कि आप याद रखें कि आप चाहते थे याद रखें कि आप हमेशा उन्हें हटाना रद्द कर सकते हैं (उपरोक्त आदेश ने विलोपन पर उनके हैश को सूचीबद्ध किया होगा, इसलिए एक सरल git checkout -b <branch> <hash>


0
# First use prune --dry-run to filter+delete the local branches
git remote prune origin --dry-run \
  | grep origin/ \
  | sed 's,.*origin/,,g' \
  | xargs git branch -D

# Second delete the remote refs without --dry-run
git remote prune origin

स्थानीय- और दूरस्थ- refs (से मेरे उदाहरण में origin) से एक ही शाखाओं को Prune करें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.