क्या मैं गिट के साथ पहले से ही विभाजित हंक को विभाजित कर सकता हूं?


204

मैंने हाल ही patchमें addकमांड के लिए git का विकल्प खोजा है , और मुझे कहना होगा कि यह वास्तव में एक शानदार विशेषता है। मुझे यह भी पता चला कि sकुंजी को मारकर एक बड़े हंक को छोटे-छोटे हिस्सों में विभाजित किया जा सकता है , जो कमिट की शुद्धता को जोड़ता है। लेकिन क्या होगा अगर मैं और भी अधिक सटीक चाहता हूं, अगर विभाजन हंक पर्याप्त छोटा नहीं है?

उदाहरण के लिए, इस पहले से विभाजित हंक पर विचार करें:

@@ -34,12 +34,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

मैं केवल अगली टिप्पणी में सीएसएस टिप्पणी को कैसे हटा सकता हूं? sविकल्प अब उपलब्ध नहीं है!

जवाबों:


253

यदि आप उपयोग कर रहे हैं git add -pऔर यहां तक ​​कि विभाजन के बाद भी s, आपके पास एक छोटा सा पर्याप्त परिवर्तन नहीं है, तो आप eसीधे पैच को संपादित करने के लिए उपयोग कर सकते हैं ।

यह थोड़ा भ्रामक हो सकता है, लेकिन यदि आप संपादक विंडो में दिए गए निर्देशों का ध्यानपूर्वक पालन ​​करते हैं जो दबाने के बाद खुल जाएंगे eतो आप ठीक हो जाएंगे। आपके द्वारा उद्धृत मामले में, आप -इन पंक्तियों की शुरुआत में एक स्थान के साथ बदलना चाहेंगे :

-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {

... और निम्न पंक्ति को हटा दें, अर्थात जो शुरू होता है +। यदि आप अपने संपादक से बचते हैं और बाहर निकलते हैं, तो बस CSS टिप्पणी को हटाने का मंचन किया जाएगा।


9
शांत समाधान! मैंने देखा कि लेकिन गलत समझा ... मैं हालांकि परिवर्तन भी काम के पेड़ से हटा दिया जाएगा।
greg0ire

7
वास्तव में, यह मदद पाठ से बहुत स्पष्ट नहीं है। मैं खुद को इसका भरपूर उपयोग कर पाता हूं, वास्तव में, क्योंकि मुझे लगता है कि git वास्तव में आपको प्रत्येक वचन को यथासंभव सटीक और सुंदर बनाने के लिए प्रोत्साहित करता है :)
Mark Longair

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

3
मैं कारण का अनुमान लगा रहा हूं कि आप '-' के साथ लाइनों को हटाते हैं और '+' को एक स्थान के साथ प्रतिस्थापित करते हैं, तो आप एक पैच बना रहे हैं जहां '-' के साथ उन पंक्तियों को पहले ही हटा दिया गया है और रेखाएं ' + पहले ही जोड़ दिए गए हैं (पैच की आंख में)। या इसे देखने का एक और तरीका है, क्या आप वास्तव में यह क्रिया करते हैं कि उन वर्णों (-, +) को दर्शाते हैं (एक पंक्ति को जोड़ते हैं या इसे हटाते हैं)। केवल 'और' और '+' वाली शेष पंक्तियों को परिवर्तन के रूप में दर्ज किया गया है और शेष "फ़ाइल कैसे है"।
एटोमिक्टोम

3
@Filype: मुझे नहीं पता कि ऐसा क्यों हुआ होगा, मुझे डर है - अगर आप दौड़ रहे थे git add -pऔर उसके साथ एक हंक संपादित eकिया गया था, जो केवल मंचन को प्रभावित करे, न कि आपके काम करने वाले पेड़ को।
मार्क लॉन्गेयर

60

आइए बताते हैं आपके example.cssलुक इस तरह:

.classname {
  width: 440px;
}

/*#field_teacher_id {
  display: block;
} */

form.table-form #field_teacher + label,
form.table-form #field_producer_distributor + label {
  width: 300px;
}

.another {
  width: 420px;
}

अब हम बीच के ब्लॉक में स्टाइल सेलेक्टर्स को बदलते हैं, और जब हम उस पर होते हैं, तो कुछ पुराने कमेंट-आउट स्टाइल को हटा देते हैं, जिनकी हमें अब और आवश्यकता नहीं है।

.classname {
  width: 440px;
}

#user-register form.table-form .field-type-checkbox label {
  width: 300px;
}

.another {
  width: 420px;
}

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

पुराने कोड को हटाना अन्य शैली चयनकर्ता परिवर्तन से तार्किक रूप से अलग है। हमें दो अलग-अलग कमिट की आवश्यकता है, तो आइए पैच के लिए जोड़ जोड़ते हैं।

git add --patch
diff --git a/example.css b/example.css
index 426449d..50ecff9 100644
--- a/example.css
+++ b/example.css
@@ -2,12 +2,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

Stage this hunk [y,n,q,a,d,/,e,?]?

वूप्स, लगता है कि परिवर्तन बहुत करीब हैं, इसलिए गिट ने उन्हें एक साथ हंक किया है।

यहां तक ​​कि इसे दबाकर विभाजित करने का प्रयास करने sका एक ही परिणाम होता है क्योंकि विभाजन हमारे सटीक परिवर्तनों के लिए पर्याप्त रूप से दानेदार नहीं है। परिवर्तन लाइनों के बीच अपरिवर्तित लाइनों की आवश्यकता होती है, जिससे गिट को स्वचालित रूप से पैच को विभाजित करने में सक्षम होना चाहिए।

तो, आइए इसे मैन्युअल रूप से दबाकर संपादित करेंe

Stage this hunk [y,n,q,a,d,/,e,?]? e

git हमारी पसंद के संपादक में पैच खोलेगा।

# Manual hunk edit mode -- see bottom for a quick guide
@@ -2,12 +2,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging. If it does not apply cleanly, you will be given
# an opportunity to edit again. If all lines of the hunk are removed,
# then the edit is aborted and the hunk is left unchanged.

आइए लक्ष्य की समीक्षा करें:

मैं केवल अगली टिप्पणी में सीएसएस टिप्पणी को कैसे हटा सकता हूं?

हम इसे दो कमिट में विभाजित करना चाहते हैं:

  1. पहली प्रतिबद्ध में कुछ लाइनें हटाना (टिप्पणी निकालना) शामिल है।

    टिप्पणी की गई लाइनों को हटाने के लिए, बस उन्हें अकेला छोड़ दें, वे पहले से ही संस्करण नियंत्रण में विलम्ब को ट्रैक करने के लिए चिह्नित हैं जैसे हम चाहते हैं।

    -/*#field_teacher_id {
    - display: block;
    -} */

  2. दूसरा वचन एक परिवर्तन है, जिसे विलोपन और परिवर्धन दोनों को रिकॉर्ड करके ट्रैक किया जाता है:

    • हटाए गए पुराने चयनकर्ता रेखाएं)

      पुरानी चयनकर्ता लाइनें रखने के लिए (इस कमिट के दौरान उन्हें डिलीट न करें), हम चाहते हैं ...

      '-' लाइनों को हटाने के लिए, उन्हें '' बनाएं

      ... जिसका शाब्दिक अर्थ है कि अंतरिक्ष वर्ण के साथ ऋण -चिह्न की जगह

      तो ये तीन लाइन ...

      -
      -form.table-form #field_teacher + label,
      -form.table-form #field_producer_distributor + label {

      ... ( सभी 3 पंक्तियों में पहले स्थान पर एक ही सूचना देगा ):


      form.table-form #field_teacher + label,
      form.table-form #field_producer_distributor + label {

    • अतिरिक्त (नई चयनकर्ता लाइन जोड़ी गई)

      इस कमिट के दौरान जोड़ी गई नई चयनकर्ता लाइन पर ध्यान नहीं देने के लिए, हम चाहते हैं ...

      '+' लाइनें निकालने के लिए, उन्हें हटा दें।

      ... जिसका शाब्दिक अर्थ है पूरी पंक्ति को हटाना:

      +#user-register form.table-form .field-type-checkbox label {

      (बोनस: यदि आप अपने संपादक के रूप में विम का उपयोग कर रहे हैं, तो ddएक पंक्ति हटाने के लिए दबाएँ । नैनो उपयोगकर्ता Ctrl+ दबाएं K)

जब आप सहेजते हैं तो आपके संपादक को इस तरह दिखना चाहिए:

# Manual hunk edit mode -- see bottom for a quick guide
@@ -2,12 +2,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */

 form.table-form #field_teacher + label,
 form.table-form #field_producer_distributor + label {
   width: 300px;
 }

# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging. If it does not apply cleanly, you will be given
# an opportunity to edit again. If all lines of the hunk are removed,
# then the edit is aborted and the hunk is left unchanged.

अब हम कमिट करें।

git commit -m "remove old code"

और बस यह सुनिश्चित करने के लिए, चलो अंतिम प्रतिबद्ध से परिवर्तन देखें।

git show
commit 572ecbc7beecca495c8965ce54fbccabdd085112
Author: Jeff Puckett <jeff@jeffpuckett.com>
Date:   Sat Jun 11 17:06:48 2016 -0500

    remove old code

diff --git a/example.css b/example.css
index 426449d..d04c832 100644
--- a/example.css
+++ b/example.css
@@ -2,9 +2,6 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */

 form.table-form #field_teacher + label,
 form.table-form #field_producer_distributor + label {

बिल्कुल सही - आप देख सकते हैं कि उस परमाणु प्रतिबद्धता में केवल विलोपन शामिल किए गए थे। अब काम खत्म करते हैं और बाकी काम करते हैं।

git add .
git commit -m "change selectors"
git show
commit 83ec3c16b73bca799e4ed525148cf303e0bd39f9
Author: Jeff Puckett <jeff@jeffpuckett.com>
Date:   Sat Jun 11 17:09:12 2016 -0500

    change selectors

diff --git a/example.css b/example.css
index d04c832..50ecff9 100644
--- a/example.css
+++ b/example.css
@@ -2,9 +2,7 @@
   width: 440px;
 }

-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

अंत में आप देख सकते हैं कि अंतिम प्रतिबद्ध में केवल चयनकर्ता परिवर्तन शामिल हैं।


1
बोनस # 2: यदि आप अपने संपादक के रूप में VIM का उपयोग करते हैं, तो आपको एक पंक्ति को हटाने के लिए अपने कीबोर्ड पर दो बार "d" दबाना होगा: D
Alexxus

3
इसके अलावा, बजाय जोड़ा लाइनों आप जोड़ना नहीं चाहते हैं को दूर करने के, आप बदल सकते हैं +के साथ #। परिणाम समान है, लेकिन हो सकता है कि आप हटाने (और वापस करने में असमर्थ) के साथ असहज हों या आप सहेजने से पहले प्रयोग करना चाहते हैं।
ob-ivan

और वह विम के r #लिए प्लस xD से अधिक है
aksh1618

लक्ष्य है "मैं सीएसएस टिप्पणी हटाने को केवल अगली प्रतिबद्ध में कैसे जोड़ सकता हूं?", लेकिन कदम वास्तव में क्या पूरा कर रहे हैं के रूप में भ्रमित कर रहे हैं। (हम कुछ पंक्तियों को केवल "हटाने" के लिए "" जोड़ना चाहते हैं।) तो बस यह कहना कि हटाना या जोड़ना बहुत भ्रामक है। प्रत्येक चरण में पूरा किया गया बताते हुए स्पष्ट करने में मदद मिलेगी।
अहानिबेकाड

9

यदि आप git gui का उपयोग कर सकते हैं, तो यह आपको लाइन के द्वारा परिवर्तन रेखा को स्टेज करने की अनुमति देता है। दुर्भाग्य से, मुझे नहीं पता कि इसे कमांड लाइन से कैसे किया जाए - या यहां तक ​​कि अगर यह संभव है।

एक अन्य विकल्प जो मैंने अतीत में उपयोग किया है वह परिवर्तन के पीछे के हिस्से (संपादक को खुला रखें) को रोल कर रहा है, जो बिट्स मैं चाहता हूं, उसे पूर्ववत करें और संपादक से फिर से सहेजें। बहुत सुंदर नहीं है, लेकिन काम हो जाता है। :)


EDIT (git-gui उपयोग):

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

कमिट करने के लिए, आप gui टूल या कमांड लाइन का उपयोग कर सकते हैं।


आपका दूसरा प्रस्ताव काफी स्पष्ट है, लेकिन पहले वाला दिलचस्प है, क्या आप थोड़ा और विस्तार कर सकते हैं? मैंने स्थापित किया, git-guiलेकिन मेरे पास कोई सुराग नहीं है कि आप जो वर्णन कर रहे हैं उसे कैसे प्राप्त करें।
greg0ire

बहुत धन्यवाद! यह काम! मैं उन पंक्तियों का चयन करने में सक्षम था, जिन्हें मैं एक क्लिक के साथ चरणबद्ध और अनुक्रमणित करना चाहता था।
greg0ire

0

इसे करने का एक तरीका यह है कि git addआप जिस चीज की आवश्यकता है, उसे चंक को छोड़ दें , और फिर चलाएंgit add । यदि यह एकमात्र हिस्सा है, तो आप इसे विभाजित कर पाएंगे।

यदि आप कमिट्स के आदेश के बारे में चिंतित हैं, तो बस उपयोग करें git rebase -i


यह वही है जो मैंने कोशिश की, और मेरे प्रश्न में हंक केवल एक ही है जब मैं git add -pफिर से दौड़ता हूं , लेकिन मैं इसे विभाजित नहीं कर सकता। मुझे यह मिलता है: Stage this hunk [y,n,q,a,d,/,e,?]?और फिर मारना मदद को छापता है। BTW, तुम्हारा मतलब है add patch, नहीं patch add? या क्या कोई git patchप्लगइन है जिसे मुझे स्थापित करना चाहिए?
greg0ire

इससे पहले कि आप इसे फिर से चलाने से पहले आप मंचन कर सकें? और नहीं, Mercurial में प्लगइन्स हैं, Git नहीं।
अबिज़र्न

नहीं, मैंने नहीं किया, मैं चाहता हूं कि वे भी उसी कमिटमेंट में रहें (लेकिन मुझे लगता है कि अगर आपका समाधान काम करता है, तो मैं इसे हासिल करने के लिए उपयोग कर सकता हूं)। मै उसे करने की एक कोशिश तो करूंगा।
greg0ire

के रूप में मेरा उत्तर कहा → git rebase -i। जो की तुलना में अधिक लचीला हैcommit --amend
Abizern
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.