git push --force-with-पट्टे बनाम --force


182

मैं इसके बीच के अंतर को समझने की कोशिश कर रहा हूं

git push --force

तथा

git push --force-with-lease

मेरा अनुमान है कि बाद वाला केवल रिमोट को धक्का देता है यदि रिमोट में ऐसा नहीं होता है कि स्थानीय शाखा के पास नहीं है ?


"स्थानीय रिमोट ट्रैकिंग शाखा "। मूल रूप से रिमोट को यह देखना होता है कि आपका ग्राहक क्या पसंद करता है। git help pushउपयोग-मामलों को इसके उद्देश्य की व्याख्या करने के लिए (मूल रूप से आपको किसी व्यक्ति को सिर्फ धक्का देने वाले परिवर्तन को कुचलने से बचाने के लिए रखा गया है)। मेरे लिए थोड़ा अस्पष्ट है कि रिमोट ट्रैकिंग शाखा कैसे काम करती है। लेकिन आम तौर पर आमतौर पर यह देखने की आवश्यकता होती है कि आपने पिछली बार ऐसा कैसे देखा था fetchया आपने pullकोई नया काम नहीं किया था ।
zzxyz

4
@zzxyz: का वास्तविक कार्यान्वयन --force-with-leaseआधुनिक सीपीयू पर तुलना-और-अदला-बदली निर्देशों के समान है: जो चाहता है कि स्वैप को अपेक्षित मूल्य और नए मूल्य की आपूर्ति हो। स्वैप करने वाली प्रणाली वास्तविक वर्तमान मूल्य के साथ अपेक्षित मूल्य की तुलना करती है, और स्वैप करती है अगर और केवल अगर दोनों समान हैं। git pushदूरस्थ-ट्रैकिंग नाम में जो कुछ भी है, उसके साथ अपेक्षित मूल्य, उदाहरण के लिए, नए वांछित मूल्य के साथ git push --force-with-lease origin Xअपना खुद का भेजता है origin/X; originयह आपको बताता है कि यह एक्सचेंज ने किया या नहीं।
torek

1
अगर Git originने एक्सचेंज किया, तो आप कर रहे हैं। यदि नहीं, तो आप नए वर्तमान मूल्य git fetch originको लेने के लिए चला सकते हैं , यदि आवश्यक हो तो अपने परिवर्तनों को पुनः प्राप्त कर सकते हैं, और फिर से प्रयास करने के लिए एक और बल-के साथ पट्टे की तुलना-और-स्वैप चला सकते हैं।
तायार्क

जवाबों:


172

force आपकी स्थानीय शाखा के साथ एक दूरस्थ शाखा को अधिलेखित करता है।

--force-with-leaseएक सुरक्षित विकल्प है जो दूरस्थ शाखा पर किसी भी कार्य को अधिलेखित नहीं करेगा यदि दूरस्थ शाखा (किसी अन्य टीम के सदस्य या सहकर्मी या आपके पास क्या है) से अधिक हिट जोड़े गए थे। यह सुनिश्चित करता है कि आप किसी को बल द्वारा धक्का देकर काम को अधिलेखित न करें।

मुझे लगता है कि कमांड के आसपास आपका सामान्य विचार सही है। यदि दूरस्थ शाखा का आपके स्थानीय मशीन पर दूरस्थ शाखा के समान मूल्य है - तो आप दूरस्थ को अधिलेखित कर देंगे। यदि इसका समान मूल्य नहीं है- तो यह उस परिवर्तन को इंगित करता है जब आप अपने कोड पर काम कर रहे थे और किसी अन्य व्यक्ति को दूरस्थ शाखा में किया गया था और इस प्रकार वह किसी भी कोड को अधिलेखित नहीं करेगा। जाहिर है कि अगर रिमोट में अतिरिक्त कमिट होते हैं तो मान समान नहीं होंगे।

मुझे लगता है कि --force-with-leaseजब मैं टीम के किसी भी कोड को अधिलेखित नहीं करना चाहता हूं, तो मैं इसका उपयोग करने के विकल्प के रूप में सोचता हूं। मेरी कंपनी की बहुत सी टीमें --force-with-leaseअसफल-सुरक्षित के लिए डिफ़ॉल्ट विकल्प के रूप में उपयोग करती हैं। अधिकांश परिस्थितियों में इसका अनावश्यक होना, लेकिन अगर आप किसी ऐसी चीज को अधिलेखित करने के लिए होते हैं जो किसी अन्य व्यक्ति ने रिमोट में योगदान दिया है, तो आपको बहुत सारे सिरदर्द से बचाएंगे।

मुझे यकीन है कि आपने डॉक्स को देखा था, लेकिन इसमें कुछ और चिंताजनक व्याख्या हो सकती है:

https://git-scm.com/docs/git-push


38

विश्वसनीय और / या आधिकारिक स्रोतों से एक उत्तर ड्राइंग की तलाश में।

"तुलना और स्वैप" ने उल्लेख किया torek में टिप्पणियां और में अपने दूसरे सवाल का जवाब आगे के रूप में रेखांकित किया गया है Git के ही सूत्रों का कहना है

बाद वाला केवल रिमोट को धक्का देता है यदि रिमोट में ऐसा नहीं होता है कि स्थानीय शाखा के पास नहीं है?

यह फीचर इस कमिट में पेश किया गया था (दिसम्बर 2013, Git v1.8.5-rc0)

--force-with-lease उन सभी दूरस्थ रेफरी की सुरक्षा करेगा जो उनके वर्तमान मूल्य को कुछ उचित डिफ़ॉल्ट के समान होने तक अद्यतन करने जा रहे हैं, जब तक कि अन्यथा निर्दिष्ट न हो;

अभी के लिए, "कुछ उचित डिफ़ॉल्ट" को " रिमोट-ट्रैकिंग शाखा के मूल्य के रूप में परिभाषित किया गया है जो हमारे पास रिमोट के अपडेट होने के लिए अद्यतन है ", और यह एक त्रुटि है यदि हमारे पास ऐसी रिमोट-ट्रैकिंग शाखा नहीं है।

तो "पट्टा" का अर्थ है:

" force-with-lease": आप मानते हैं कि जब आपने रिवाइज्ड हिस्ट्री होनी चाहिए, यह तय करने के लिए आपने लीज़ को रेफ पर लिया था, और आप केवल तभी वापस पुश कर सकते हैं जब लीज़ को तोड़ा नहीं गया हो।

सूत्रों ने अभी भी "कैस" का उल्लेख किया है:

  • इस विकल्प को मूल रूप से " cas" और "तुलना और स्वैप" के लिए कहा जाता था ), वह नाम जिसे किसी ने पसंद नहीं किया क्योंकि यह बहुत तकनीकी था।
  • दूसरे प्रयास ने इसे "लॉकफियर" कहा (क्योंकि यह वैचारिक रूप से लॉक लेने के बाद धक्का देने जैसा है) लेकिन "लॉक" शब्द से नफरत थी क्योंकि इसका अर्थ था कि यह दूसरों द्वारा धक्का को अस्वीकार कर सकता है, जो इस विकल्प के काम करने का तरीका नहीं है।
  • यह दौर इसे "फोर्स-विद-लीज" कहता है।
    आप यह मान लेते हैं कि जब आपने रिवाइज्ड हिस्ट्री होनी चाहिए, यह तय करने के लिए आपने लीज़ को रेफ पर लिया था, और आप केवल तभी वापस पुश कर सकते हैं जब लीज़ नहीं तोड़ी गई हो।

तो: " git push --force-with-leaseबनाम --force"

जैसा कि मैंने " push --force-with-leaseडिफ़ॉल्ट रूप से ", Git 2.13 (Q2 2017) के रूप में उल्लेख किया है, कि विकल्प --force-with-leaseको अनदेखा किया जा सकता है यदि एक पृष्ठभूमि प्रक्रिया (जैसे कि आप एक जीआईटी प्लगइन के साथ आईडीई में पाते हैं) चलाता है git fetch origin
उस मामले में, --forceप्रबल है।


29

गिट पुश --फोर्स विनाशकारी है क्योंकि यह बिना किसी स्थानीय रूप से दूरस्थ रिपॉजिटरी को बिना शर्त के अधिलेखित कर देता है। git का पुश --force दृढ़ता से हतोत्साहित होता है क्योंकि यह पहले से ही साझा किए गए भंडार में धकेल दिए गए अन्य कमिट्स को नष्ट कर सकता है। बल धक्का के सबसे आम कारणों में से एक है जब हम एक शाखा को रिबेस करने के लिए मजबूर होते हैं।

उदाहरण के लिए। हमारे पास एक सुविधा शाखा के साथ एक परियोजना है जो ऐलिस और बॉब दोनों पर काम करने जा रही है। वे दोनों इस भंडार का क्लोन बनाते हैं और काम शुरू करते हैं। ऐलिस शुरू में फीचर का अपना हिस्सा पूरा करती है, और इसे मुख्य रिपॉजिटरी तक पहुंचाती है। यह पूरी तरह ठीक है और अच्छा है। बॉब अपना काम भी पूरा कर लेता है, लेकिन इसे आगे बढ़ाने से पहले उसने नोटिस किया कि कुछ बदलावों को मास्टर में मिला दिया गया था। एक साफ पेड़ रखना चाहते हैं, वह मास्टर शाखा के खिलाफ एक विद्रोह करता है। बेशक, जब वह इस विद्रोही शाखा को आगे बढ़ाने जाएगा तो इसे अस्वीकार कर दिया जाएगा। हालांकि यह एहसास नहीं है कि एलिस ने पहले से ही अपने काम को आगे बढ़ाया है, वह एक पुश -फोर्स करती है। दुर्भाग्य से, यह केंद्रीय भंडार में ऐलिस के परिवर्तनों के सभी रिकॉर्ड को मिटा देगा।

क्या --force-साथ-पट्टा करता है एक शाखा अद्यतन करने के लिए जब तक यह राज्य है कि हम उम्मीद करते हैं है कचरे है; यानी किसी ने भी शाखा को अपडेट नहीं किया है। व्यवहार में यह जाँच कर काम करता है कि अपस्ट्रीम रेफ क्या है जिसकी हम अपेक्षा करते हैं, क्योंकि रेफ में हैश होते हैं, और स्पष्ट रूप से माता-पिता की श्रृंखला को उनके मूल्य में शामिल करते हैं।

यहाँ git push --force और git push --force-with-पट्टे के बारे में एक अच्छी पोस्ट है।


2
मुझे समझ में नहीं आ रहा है - यदि आप मास्टर के साथ रिबेट करते हैं, तो आपको बिना धक्का दिए सक्षम होना चाहिए --force-with-lease? --force-with-leaseगुरु के साथ पुनरावृत्ति करने के बाद क्यों आवश्यक है?
अलेक्जेंडर मिल्स

3
@AlexanderMills में समस्या होने की कुछ संभावना हो सकती है। यदि आप अंतिम व्यक्ति हैं जो इसे मास्टर करने के लिए धक्का देते हैं तो कोई समस्या नहीं है लेकिन एक अन्य व्यक्ति है जो किसी अन्य कार्य के साथ काम कर रहा है तो यह गंभीर समस्या पैदा कर सकता है। पहले ए - बी - सी में कहें, मास्टर में, पहले ऐलिस इसे ए - बी - सी - डी - ई और उसी समय बॉब इसे ए - बी - सी - एफ - जी बनाते हैं। यदि एलिस अंतिम व्यक्ति धक्का है में मास्टर के बाद ए - बी - सी - डी - ई - एफ - जी किसी भी समस्या का कारण नहीं होगा, लेकिन एक अन्य व्यक्ति टॉम ए - बी - सी - डी - ई - आर को मास्टर आपदा में एक ही समय में धकेलने की कोशिश करेगा !! !
शाकिल

3
--forceकमिट नहीं करता है, यह सिर्फ उन्हें मिटा देता है। उन्हें अपने हैश द्वारा फिर से जीवित किया जा सकता है, जैसे git checkout <SHA>या git reset --hard <SHA>, दूरस्थ रेपो के अनुरक्षक को संभालने से कोई भी जीसी या प्रूनिंग ऑपरेशन नहीं करता है।
कीथ रसेल

1
"git का धक्का --force दृढ़ता से हतोत्साहित किया जाता है क्योंकि यह पहले से ही एक साझा भंडार में धकेल दिए गए अन्य कमिट्स को नष्ट कर सकता है" यह कथन दृढ़ता से राय आधारित है। एक बल धक्का करना एक सामान्य गिट रीबेस कोड समीक्षा वर्कफ़्लो का हिस्सा है। जैसा कि पहले ही उल्लेख किया गया है कि आप ऐसा करने के बाद भी कमियों को पुनः प्राप्त कर सकते हैं।
Éतिने

9

सर्वर पर किसी भी पूर्व-प्राप्त हुक को धक्का मानते हुए, यह हमेशा सफल होगा:

git push --force

जबकि यह आगे बढ़ने से पहले एक विशिष्ट क्लाइंट-साइड जाँच चलाता है:

git push --force-with-lease

आप विशिष्ट जांच स्वयं चला सकते हैं। यहां "लीज-चेकिंग" एल्गोरिदम है:

  1. अपनी वर्तमान शाखा का पता लगाएं।

  2. भागो git for-each-ref refs/remotes। कमिट-आईडी का ध्यान रखें कि आपका गिट क्लाइंट आपके वर्तमान ब्रांच के अपस्ट्रीम स्टेट से मेल खाता है।

उदाहरण के लिए, यदि आप शाखा "फू" पर हैं, तो "रेफ्स / रिमॉडेस / ओरिजिन / जू" से जुड़ी कमिट-आईडी पर ध्यान दें।

  1. अभी अपस्ट्रीम गिट सर्वर पर दूरस्थ शाखा की वास्तविक कमिट-आईडी का निर्धारण करें।

  2. यदि चरण 2 और चरण 3 से निकाले गए कमिट-आईडी आपको सहमत हैं तो केवल "गिट पुश" को आगे बढ़ने दें। दूसरे शब्दों में, केवल तभी आगे बढ़ें जब आपके स्थानीय गिट क्लोन की अपस्ट्रीम वास्तविक अपस्ट्रीम से सहमत हो।

यहाँ एक दुखद निहितार्थ है: चूंकि git fetchसभी अपडेट उनके नवीनतम संस्करणों के लिए "रिफ्स / रीमोट्स / ओरिजिन / *" के अंतर्गत आते हैं, इसलिए कमांड का यह संयोजन अनिवार्य रूप से समान है git push --force:

git fetch

# The command below behaves identically to "git push --force"
# if a "git fetch" just happened!

git push --force-with-lease

इस अंतर्निहित कमजोरी के आसपास काम git push --force-with-leaseकरने के लिए मैं कभी भी दौड़ने की कोशिश नहीं करता git fetch। इसके बजाय git pull --rebaseजब भी मुझे अपस्ट्रीम के साथ सिंक करने की आवश्यकता होती है तो मैं हमेशा रन करता हूं, क्योंकि git pullकेवल रीफ्स / रिमोज़ के तहत एक ही रेफरी को अपडेट करने से "लीज़" --force-with-leaseउपयोगी रहता है।


1
यदि चेक क्लाइंट-साइड है, तो क्या रेस की स्थिति की संभावना है? यानी चेक के बाद कोई और बदलाव करता है लेकिन जबरन धक्का देने से पहले?
क्रेक

2

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

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