Git को सूचीबद्ध करना और हटाना, बिना शाखा (झूलने) के हैं?


146

मुझे बहुत सारे कमिट्स के साथ Git रिपॉजिटरी मिली है जो किसी विशेष शाखा के अंतर्गत नहीं हैं, मैं git showउन्हें कर सकता हूं, लेकिन जब मैं उन शाखाओं को सूचीबद्ध करने की कोशिश करता हूं जिनमें उन्हें शामिल किया गया है, तो यह कुछ भी वापस नहीं करता है।

मैंने सोचा कि यह झूलने वाले कमिट / ट्री इश्यू (-ड ब्रांच के परिणामस्वरूप) है, इसलिए मैंने रेपो को काट दिया, लेकिन उसके बाद भी मुझे वही व्यवहार दिखाई देता है:

$ git fetch origin

$ git fsck --unreachable
$ git fsck

कोई आउटपुट नहीं, कुछ भी झूलने (सही?) नहीं। लेकिन कमिट मौजूद है

$ git show 793db7f272ba4bbdd1e32f14410a52a412667042
commit 793db7f272ba4bbdd1e32f14410a52a412667042
Author: ...

और यह किसी भी शाखा के माध्यम से उपलब्ध नहीं है

$ git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042

कोई आउटपुट नहीं देता।

वास्तव में उस वचन की स्थिति क्या है? मैं सभी समान राज्यों में कैसे सूचीबद्ध कर सकता हूं? मैं उन लोगों की तरह कैसे हटा सकता हूं?


जवाबों:


75

कोई आउटपुट नहीं, झूलने वाला (सही?)

ध्यान दें कि आपके रिफ्लॉग से संदर्भित कॉम्प्लेक्स को पहुंच योग्य माना जाता है।

वास्तव में उस वचन की स्थिति क्या है? मैं समान राज्य के साथ सभी प्रकारों को कैसे सूचीबद्ध कर सकता हूं

उन्हें आपको दिखाने के --no-reflogsलिए मनाने के git fsckलिए पास करें ।

मैं उन लोगों की तरह कैसे हटा सकता हूं?

एक बार जब आपकी रिफ्लॉग प्रविष्टियां समाप्त हो जाती हैं, तो उन वस्तुओं को भी साफ किया जाएगा git gc

समाप्ति द्वारा नियंत्रित किया जाता gc.pruneexpire, gc.reflogexpireहै, और gc.reflogexpireunreachableसेटिंग्स। सी एफ git help config

चूक सभी काफी उचित हैं।


2
इसलिए आप मूल रूप से कह रहे हैं कि कमिंग झूलने के लिए प्रतिक्षेप थोड़ी देर बाद स्वचालित रूप से हटा दिया जाएगा?
मोरालकोड

2
मूल रूप से: हाँ - सिवाय इसके कि सवाल थोड़ा उलझा हुआ है। मैं कह रहा हूं कि थोड़ी देर के बाद सभी रिफ्लॉग प्रविष्टियां अपने आप हटा दी जाती हैं, लेकिन आप इसे कॉन्फ़िगरेशन सेटिंग्स के माध्यम से बदल सकते हैं। और क्योंकि एक प्रतिबद्ध केवल कहा जाता है झूलते जब यह है कुछ भी नहीं है यह की ओर इशारा करते - reflog प्रविष्टियों सहित -, "प्रतिबद्ध झूलते के लिए reflogs" नहीं एक बात कर रहे हैं। वे " पहुंच से बाहर आने के लिए reflogs " होगा।
अरस्तू पगलतज़िस

'वे "पहुंच से बाहर आने के लिए reflogs" होगा।' लेकिन आपने कहा कि "आपके रिफ्लेक्ट से संदर्भित कमेंट्स को पहुंच योग्य माना जाता है।" तो कैसे "पहुंच से बाहर होने के लिए reflogs" एक बात हो सकती है? मैं बहुत उलझन में हूँ।
लार्श

1
हाँ, मैं सुसंगत नहीं था। आम तौर पर लोग रिफ्लग के बारे में नहीं सोचते हैं, और जब वे कहते हैं कि "अप्राप्य" यह तात्पर्य "एक रेफरी" से है। यहां तक git help glossaryकि इसे इस तरह परिभाषित किया गया है ... जबकि "पहुंच" के लिए इसकी परिभाषा उस तरह से संकुचित नहीं है, इसलिए वे विरोधाभासी हैं। मजेदार - तो मैंने जो कहा वह वास्तव में भ्रम की स्थिति के अनुरूप है gitglossary... यह ऐसी अवधारणाएं नहीं हैं जो भ्रामक हैं, हालांकि, बस शब्दावली। मुद्दा यह है कि "झूलना" कमिटिंग वे हैं जो और कुछ नहीं बताते हैं। अगर मैं कहूँ तो यह मदद करेगा " अन्यथा अप्राप्य के लिए फिर से शुरू होता है" ...?
अरस्तू पगलतज़िस

यह सब बहुत भ्रामक है। चलो इसे सरल बनाते हैं। जब शाखा पर master, आप करते हैं git commit, और एक प्रतिबद्धता प्राप्त करते हैं 000001। फिर तुम करते हो git commit --amend, जो तुम्हें वचन देता है 000002। अब तक कोई भी टैग या शाखाएँ 000001नहीं हैं, और आप इसे --reflogविकल्प के बिना अपने लॉग में नहीं देख सकते हैं , लेकिन यदि आप चाहें, तो आप अभी भी इसके साथ मिल सकते हैं git checkout 000001। अब सवाल है, है 000001एक झूलने के लिए प्रतिबद्ध है, या एक नहीं पहुंचा जा सकता प्रतिबद्ध, या कोई भी, या दोनों?
छरवे की

264

सभी झूलने वाले कमेंट्स को हटाने के लिए और रिफ्लेक्स से आने वाले लोग ऐसा करते हैं:

git reflog expire --expire-unreachable=now --all
git gc --prune=now

लेकिन निश्चित रहें कि आप यही चाहते हैं। मैं आपको मैन पेजों को पढ़ने की सलाह देता हूं, लेकिन यहां जिक्र है:

git gcअप्राप्य वस्तुओं (कमिट्स, ट्रीज, ब्लब्स (फाइल)) को हटा देता है। यदि यह किसी शाखा के इतिहास का हिस्सा नहीं है, तो एक वस्तु उपलब्ध नहीं है। वास्तव में यह थोड़ा अधिक जटिल है:

git gc कुछ अन्य चीजें करता है, लेकिन वे यहां प्रासंगिक नहीं हैं और खतरनाक नहीं हैं।

--prune=nowअगम्य वस्तुएं जो दो सप्ताह से छोटी हैं, उन्हें हटाया नहीं जाता है इसलिए हम इसका उपयोग करते हैं जिसका अर्थ है "अब पहले बनाई गई अगम्य वस्तुओं को हटा दें"।

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

तो हम भी वास्तव में एक शाखा से पहुंच योग्य नहीं है सब कुछ को हटाने के लिए reflogs को हटाने के लिए है। हम --allरिफ्लेक्स को समाप्त करके ऐसा करते हैं । फिर से git यूजर्स की सुरक्षा के लिए कुछ रिफ्लेक्स रखता है इसलिए हमें फिर से यह बताना होगा कि ऐसा न करें --expire-unreachable=now:।

चूंकि मैं मुख्य रूप से विनाशकारी संचालन से उबरने के --expire=nowलिए रिफ्लग का उपयोग करता हूं , जो आमतौर पर इसके बजाय मैं उपयोग करता हूं , जो कि रिफ्लॉग्स को पूरी तरह से रोक देता है।


1
मैं आपको बताता हूं कि कौन सी कमांड का उपयोग करना स्पष्ट नहीं है - क्या जीसी पर्याप्त नहीं होना चाहिए? यदि आपने पहले कभी भी git-reflog का उपयोग नहीं किया है तो आपको पता नहीं चलेगा। तो अब आप जानते हैं कि आपको किन आदेशों का उपयोग करना है, आपको उनके मैन पेजों में उल्लिखित विकल्पों को देखना चाहिए। बेशक मैं इसके बजाय बस वहां से उस जानकारी को कॉपी कर सकता था ...
tarsius

1
वास्तव में मैं वास्तव में यह कहता हूं कि यह क्या करता है: "सभी झूलने वाले कमिट हटा दें और जो लोग रिफ्लेक्स से पहुंच रहे हैं"। यदि आप नहीं जानते कि क्या रिफ्लेक्स हैं: फिर से मैनुअल पढ़ें।
तारसियस

7
हालांकि दिया गया उत्तर सही हो सकता है, @ erikb85 यह इंगित करने में सही है कि आपके द्वारा क्या करने के लिए कहा जा रहा है, इसके बारे में कोई शिक्षा नहीं थी। RTFM के साथ अनुसरण करना और भी कम सहायक है। हाँ, हम सभी को प्रलेखन के सभी पढ़ना चाहिए। कुछ मामलों में शायद खोज करने वाला व्यक्ति दस्तावेज़ीकरण को यह जानने के लिए पर्याप्त नहीं करता है कि क्या हो रहा है। इसलिए, थोड़ी सी शिक्षा जो कमांड कर रही है, वह उन सभी के लिए मददगार होगी जो इस उत्तर को बाद में खोजते हैं।
ली सेफेराइट

@LeeSaferite उम्मीद है कि अब सब खुश हैं :-)
tarsius

12
git reflog expire --expire-unreachable=now --allअपने सभी बाधाओं को छोड़ देता है!
वेस्वोलॉड गोलोवानोव

22

मेरे पास एक ही मुद्दा था, फिर भी इस सूत्र में सभी सलाह का पालन करने के बाद:

git reflog expire --expire-unreachable=now --all
git gc --prune=now
git fsck --unreachable --no-reflogs   # no output
git branch -a --contains <commit>     # no output
git show <commit>                     # still shows up

यदि यह एक रिफ्लॉग नहीं है और एक शाखा नहीं है, ... यह एक टैग होना चाहिए !

git tag                             # showed several old tags created before the cleanup

मैंने टैग्स को हटा दिया git tag -d <tagname>और सफाई को फिर से शुरू कर दिया, और पुराने कमिट चले गए।


टैग ( stackoverflow.com/a/37335660/450127 ) के बारे में पहले से ही एक उत्तर है , और ऐसा नहीं लगता है कि यह नया जोड़ता है। क्या पहले के उत्तर के पक्ष में इसे नहीं हटाया जाना चाहिए?
इयान डन

दरअसल, किसी तरह मैंने उस जवाब को नजरअंदाज कर दिया। हालांकि 4 लोगों को मेरा जवाब मददगार लगा, इसलिए शायद यह बेकार नहीं है? इसके अलावा, मैंने सभी संभावनाओं को एक संक्षिप्त जवाब में वर्गीकृत किया।
याकूब .g

1
यहां तक ​​कि अगर डुप्लिकेट किया गया है, तो यह पृष्ठ Google परिणाम में दिखाई दे सकता है, और यह तुरंत एक ही समस्या वाले लोगों की मदद करता है, जो लोगों को बार-बार लिंक को फिर से लिंक करने से बेहतर है जो सही उत्तर दे सकते हैं।
अलेक्जेंड्रे टी।

14
git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042

शायद बस होने की जरूरत है

git branch -a --contains 793db7f272ba4bbdd1e32f14410a52a412667042

रीमोट से शाखाओं पर रिपोर्ट करने के लिए भी


धन्यवाद, अब मुझे मेरे रिमोज़ / ओरिजिन / नेक्स्ट मिला जो अभी भी यह कमिट है। इसे कैसे निकालें? git push -d origin nextमदद नहीं करता है।
इरा


धन्यवाद - git fetch --pruneचाल चली। लेकिन सभी उत्तरों में मुझे उन टैग्स के लिए एक चेक याद आ रहा है जो इस कमिट को संदर्भित कर रहे हैं। मुझे अभी भी पता नहीं है कि कमिट के साथ टैग्स की जांच कैसे की जाती है (मैंने सभी को हटा दिया)।
आईआरएस

लेकिन ... क्या इसका मतलब यह है कि जो केवल दूरस्थ शाखाओं (और कोई स्थानीय शाखाएं) से पहुंच योग्य हैं, उन्हें पहुंच योग्य नहीं माना जाता है, और इसलिए git fsck --unreachableवास्तव में रिमोट के साथ नेटवर्क पर संचार किया जाता है ताकि पता लगाया जा सके कि कौन से आवागमन योग्य हैं?
लार्स

1
मेरे स्वयं के प्रश्न का उत्तर दिया ... हाँ, यह मानता है कि केवल दूरस्थ शाखाओं (और कोई स्थानीय शाखाएं) से पहुंच योग्य नहीं हैं, जिन्हें पहुंच योग्य नहीं माना जाता है; लेकिन git fsck --unreachableयह पता लगाने के लिए रिमोट के साथ नेटवर्क पर संवाद करने की आवश्यकता नहीं है कि कौन सी दूरस्थ शाखाएं शामिल हैं जो कमिट करती हैं। दूरस्थ शाखा की जानकारी स्थानीय रूप से संग्रहीत की जाती है, उदाहरण के लिए .git/refs/remotes/origin(या packed-refs)।
लार्स

8

मेरा मुद्दा भी ऐसा ही था। मैं भागा git branch --contains <commit>, और यह सवाल की तरह कोई आउटपुट नहीं लौटा।

लेकिन दौड़ने के बाद भी

git reflog expire --expire-unreachable=now --all
git gc --prune=now

मेरी प्रतिबद्धता अभी भी सुलभ थी git show <commit>। ऐसा इसलिए था क्योंकि इसकी अलग / खतरे वाली "शाखा" में से एक को टैग किया गया था। मैंने टैग हटा दिया, ऊपर दिए गए आदेशों को फिर से चलाया, और मैं सुनहरा था। git show <commit>लौटा fatal: bad object <commit>- ठीक वही जो मुझे चाहिए था। उम्मीद है कि यह किसी और की मदद करता है जो मैं था के रूप में अटक गया।


आपने टैग कैसे हटाया?
बापर्स

@bapors सभी टैग्स की सूची बनाएं, उस एक को ढूंढें जो प्रश्न में कमिट को संदर्भित करता है, और फिर इसे हटा दें। stackoverflow.com/questions/5480258/…
एंड्रयू लार्सन

4

मैंने गलती से उसी स्थिति को मारा और पाया कि मेरे स्टैड्स में अगम्य कमिट का संदर्भ है, और इस तरह प्रकल्पित अप्राप्य प्रतिबद्धताओं को स्टैचेस से पुनः प्राप्त किया जा सकता था।

ये वही थे जो मैंने इसे वास्तव में अगम्य बनाने के लिए किया था।

git stash clear
git reflog expire --expire-unreachable=now --all
git fsck --unreachable
git gc --prune=now

2

git gc --prune=<date>दो हफ़्ते पहले की पुरानी वस्तुओं को कम करने के लिए चूक। आप अधिक हाल की तिथि निर्धारित कर सकते हैं। लेकिन, git कमांड जो ढीली वस्तुओं का निर्माण करती हैं, वे आमतौर पर git gc --auto चलाएंगी (जो ढीली वस्तुओं को दबाती हैं यदि उनकी संख्या कॉन्फ़िगरेशन चर gc.auto के मान से अधिक है)।

क्या आप वाकई इन कमिट को हटाना चाहते हैं? gc.auto की डिफ़ॉल्ट सेटिंग यह सुनिश्चित करेगी कि ढीली वस्तुएं स्मृति की अनुचित मात्रा में न लें, और कुछ समय के लिए ढीली वस्तुओं को संग्रहीत करना आम तौर पर एक अच्छा विचार है। इस तरह, यदि आपको कल पता चलता है कि आपकी डिलीट की गई शाखा में आपकी ज़रूरत का कमिटमेंट है, तो आप उसे रिकवर कर सकते हैं।

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