परिवर्तन टाइमस्टैम्प बदलने के बिना गिट रिबेट


157

यह git rebaseप्रतिबद्ध टाइमस्टैम्प को संरक्षित करते समय प्रदर्शन करने के लिए समझ में आता है ?

मेरा मानना ​​है कि परिणाम यह होगा कि नई शाखा के लिए जरूरी नहीं है कि वे कालानुक्रमिक रूप से तिथियां तय करें। क्या यह सैद्धांतिक रूप से संभव है? (जैसे प्लंबिंग कमांड का उपयोग करना; बस यहाँ उत्सुक)

यदि यह सैद्धांतिक रूप से संभव है, तो क्या रिबेस के साथ अभ्यास संभव है, टाइमस्टैम्प को बदलना नहीं है?

उदाहरण के लिए, मान लें कि मेरे पास निम्नलिखित पेड़ हैं:

master <jun 2010>
  |
  :
  :
  :     oldbranch <feb 1984>
  :     /
oldcommit <jan 1984>

अब, अगर मैं रिबास oldbranchकरता हूं, तो कमिटमेंट masterकी तारीख feb 1984 से jun 2010 तक बदल जाती है। क्या उस व्यवहार को बदलना संभव है ताकि कमिटमस्टैम्प को न बदला जाए? अंत में मैं इस प्रकार प्राप्त करूंगा:

      oldbranch <feb 1984>
      /
 master <jun 2010>
    |
    :

क्या इसका कोई मतलब होगा? क्या इतिहास में भी ऐसा करने की अनुमति दी गई है जहां एक पुरानी प्रतिबद्धता में माता-पिता के रूप में अधिक हाल ही में प्रतिबद्ध है?


3
यह मजेदार है कि प्रश्न का उत्तर वास्तव में है "आपको कुछ भी करने की आवश्यकता नहीं है - यही कारण है कि यह डिफ़ॉल्ट रूप से काम करता है"। लेकिन अब मान लीजिए कि आप रिबास करते समय उचित तिथि क्रम में क्रमबद्ध होना चाहते हैं (यदि आप इसके बारे में सोचते हैं तो यह बहुत ही प्राकृतिक परिदृश्य है)। अब, मुझे यह पता नहीं चल पाया कि इसे कैसे प्राप्त किया जा सकता है, और मेरी q को stackoverflow.com/questions/12270357/really-flatten-a-git-merge
pfalcon

1
डेविड ने कमेंट डेट को रीसेट करने के लिए एक अन्य विकल्प का उल्लेख किया है git rebase --committer-date-is-author-date SHA:। देखें नीचे मेरी संपादित जवाब
VonC

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

जवाबों:


149

अपडेट जून 2014: डेविड फ्रेजर ने टिप्पणी में एक समाधान का भी वर्णन किया है जो " परिवर्तन टाइमस्टैम्प को बदलें , गिट शाखा को रीबास करते हुए ", विकल्प का उपयोग करते हुए --committer-date-is-author-date(शुरू में जनवरी 2009 में 3f01ad6 में।

ध्यान दें कि --committer-date-is-author-dateविकल्प लेखक टाइमस्टैम्प को छोड़ने के लिए लगता है, और कमेंट टाइमस्टैम्प को मूल लेखक टाइमस्टैम्प के समान ही सेट करता है, जो कि ओपी ओलिवर वेरडियर चाहता था।

मैंने सही तारीख के साथ आखिरी कमिटमेंट पाया और किया:

git rebase --committer-date-is-author-date SHA

देखें git am:

--committer-date-is-author-date

डिफ़ॉल्ट रूप से कमांड ई-मेल संदेश से दिनांक को लेखक की दिनांक के रूप में दर्ज करता है, और कमिट तिथि के रूप में प्रतिबद्ध निर्माण के समय का उपयोग करता है।
यह उपयोगकर्ता को लेखक की तारीख के समान मूल्य का उपयोग करके कमिटर तारीख के बारे में झूठ बोलने की अनुमति देता है


(मूल उत्तर, जून 2012)

आप कोशिश कर सकते हैं, एक गैर-इंटरैक्टिव रिबेस के लिए

git rebase --ignore-date

(इस एसओ जवाब से )

यह पारित किया जाता है git am, जिसमें उल्लेख किया गया है:

 --ignore-date

डिफ़ॉल्ट रूप से कमांड ई-मेल संदेश से दिनांक को लेखक की दिनांक के रूप में दर्ज करता है, और कमिट तिथि के रूप में प्रतिबद्ध निर्माण के समय का उपयोग करता है।
यह उपयोगकर्ता को कमेंट दिनांक के समान मान का उपयोग करके लेखक की तारीख के बारे में झूठ बोलने की अनुमति देता है।

इसके लिए git rebase, यह विकल्प "इन-एक्टिवटेबल विकल्प के साथ असंगत" है।

चूँकि आप पुरानी प्रतिबद्ध तारीख (समय के साथ git filter-branch) के टाइमस्टैम्प में बदल सकते हैं , मुझे लगता है कि आप अपने जीआईटी इतिहास को जिस भी तारीख के आदेश के साथ व्यवस्थित कर सकते हैं उसे आप चाहते हैं / आवश्यकता है, यहां तक ​​कि इसे भविष्य में सेट करें!


जैसा कि ओलिवियर ने अपने प्रश्न में उल्लेख किया है, लेखक की तारीख को एक विद्रोह द्वारा कभी नहीं बदला जाता है;
से प्रो Git बुक :

  • लेखक वह व्यक्ति है जिसने मूल रूप से काम लिखा है,
  • जबकि कमिट वह व्यक्ति है जिसने अंतिम बार कार्य को लागू किया है।

इसलिए, यदि आप किसी प्रोजेक्ट में पैच भेजते हैं और कोर सदस्यों में से एक पैच लागू करता है, तो आप दोनों को क्रेडिट मिलता है।

अतिरिक्त उदाहरण के लिए, इस उदाहरण में, ओलिवियर टिप्पणियों के रूप में:

--ignore-dateमैं क्या हासिल करने की कोशिश कर रहा था की विपरीत है !
अर्थात्, यह लेखक के टाइमस्टैम्प को मिटा देता है और उन्हें कमिट टाइमस्टैम्प से बदल देता है!
इसलिए मेरे प्रश्न का सही उत्तर है:
कुछ भी मत करो, क्योंकि git rebase वास्तव में लेखकों के टाइमस्टैम्प डिफ़ॉल्ट रूप से नहीं बदलते हैं।



1
मनमानी करने की तारीखों के बारे में दिलचस्प। हालांकि, git rebase --ignore-dateकाम नहीं करता है। यह विद्रोही कमिट की तारीखों को बदल देता है।
ओलिवियर वर्डियर

@Olivier: अजीब: क्या आपने एक गैर- निरोधात्मक छूट बना ली है ? और लेखक की तारीख और कमेटी की तारीख के बीच, क्या हम "सही" तारीख की निगरानी करना सुनिश्चित करते हैं?
वॉनज

1
धन्यवाद VonC, लेखक और कमिट टाइमस्टैम्प के बीच का अंतर, यही वह है जो इसे अचानक स्पष्ट करता है। मैंने अपने प्रश्न का उत्तर अपनी पोस्ट में लिखा है, लेकिन बेझिझक अपना उत्तर दें ताकि वह प्रतिबिंबित हो सके।
ओलिवियर वर्डियर

4
अधिक सटीक होने के लिए: जो मैं प्राप्त करने की कोशिश कर रहा था --ignore-dateउसके विपरीत है! अर्थात्, यह लेखक के टाइमस्टैम्प को मिटा देता है और उन्हें कमिट टाइमस्टैम्प से बदल देता है! इसलिए मेरे प्रश्न का सही उत्तर है: कुछ भी मत करो, क्योंकि git rebaseवास्तव में डिफ़ॉल्ट रूप से लेखकों के टाइमस्टैम्प नहीं बदलते हैं।
ओलिवियर वर्डियर

5
ध्यान दें कि --committer-date-is-author-dateविकल्प लेखक टाइमस्टैम्प को छोड़ने लगता है, और कमिटर टाइमस्टैम्प को मूल लेखक टाइमस्टैम्प के समान सेट करता है, जो कि ओलिवियर चाहता था ...
डेविड फ्रेजर

118

यदि आपने पहले ही प्रतिबद्ध तारीखें (शायद एक छूट के साथ) खराब कर दी हैं और उन्हें अपनी संबंधित लेखक तारीखों में रीसेट करना चाहते हैं, तो आप चला सकते हैं:

git filter-branch --env-filter 'GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; export GIT_COMMITTER_DATE'


1
मैंने बस यही कोशिश की, लेकिन कोई असर नहीं हुआ। मुझे फोलोइंग आउटपुट मिला WARNING: Ref 'refs/heads/master' is unchanged:। मैं लिनक्स पर 64.9.5 git संस्करण का उपयोग कर रहा हूँ (64 बिट)
मार्कस एन।

20
यदि आप पहले से ही खराब हो गए हैं, तो मैं एक और दृष्टिकोण जोड़ना चाहता हूं, लेकिन पूरे इतिहास के माध्यम से पुनरावृत्ति नहीं करना चाहता: git rebase --committer-date-is-author-date <base_branch> इस तरह, जीआईटी केवल <आधार_ब्रांच> (जो संभवत: लागू किए गए कमिट के लिए है) उसी शाखा का नाम जिसका उपयोग आपने तब किया था जब आप खराब हो गए थे)।
बोलने वाला

स्वीकृत उत्तर 2016 में काम नहीं किया, लेकिन @ स्पीकमैन के उत्तर ने किया!
थियोडोर आर। स्मिथ

2
@ स्पीकमैन का जवाब अक्टूबर 2016 में काम नहीं किया, लेकिन एंडी ने किया!
8:55 बजे एमी वैन गेस

2
यह विंडोज पर काम नहीं करता है। मैं विंडोज बैश का उपयोग कर काम करने में सक्षम था।
19

33

वॉन सी के एक महत्वपूर्ण प्रश्न ने मुझे यह समझने में मदद की कि क्या चल रहा है: जब आपका रिबास, कमिटर का टाइमस्टैम्प बदलता है, लेकिन लेखक का टाइमस्टैम्प नहीं, जो अचानक सब समझ में आता है। इसलिए मेरा प्रश्न वास्तव में पर्याप्त सटीक नहीं था।

इसका उत्तर यह है कि रिबेस वास्तव में लेखक के टाइमस्टैम्प्स को नहीं बदलता है (आपको इसके लिए कुछ भी करने की आवश्यकता नहीं है), जो मुझे पूरी तरह से सूट करता है।


3
+1 - मेरे पास जगह में एक गट उर्फ ( कोडरवॉल.com/p/euwpig/a-better- git- log ) है जो जाहिरा तौर पर कमिटर के टाइमस्टैम्प का उपयोग करता है, जो मुझे भ्रमित कर रहा था। गिटक और गिट लॉग दोनों लेखक की टाइमस्टैम्प दिखाते हैं।
१६१५

15

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

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

रिबास से पहले, कमिटर के टाइमस्टैम्प, लेखक के टाइमस्टैम्प को रिकॉर्ड करें और सभी कमिट्स का संदेश दें, जो एक फाइल के लिए रीबेड किया जाएगा।

#NOTE: BASE is the commit where your rebase begins
git log --pretty='%ct %at %s' BASE..HEAD > hashlog

फिर, वास्तविक रीबेस को होने दें।

अंत में, हम वर्तमान कमिटर के टाइमस्टैम्प को फाइल में दर्ज किए गए एक के साथ बदल देते हैं यदि प्रतिबद्ध संदेश का उपयोग करके समान है git filter-branch

 git filter-branch --env-filter '__date=$(__log=$(git log -1 --pretty="%at %s" $GIT_COMMIT); grep -m 1 "$__log" ../../hashlog | cut -d" " -f1); test -n "$__date" && export GIT_COMMITTER_DATE=$__date || cat'

अगर कुछ गलत होता है, तो बस चेकआउट करें git reflogया सभी refs/original/रिफ।

फ्यूरोथर्मोर, आप लेखक के टाइमस्टैम्प के समान काम कर सकते हैं।

उदाहरण के लिए, यदि लेखक के टाइमस्टैम्प कुछ कमियों के क्रम से बाहर हैं, और इन कमानों को पुनर्व्यवस्थित किए बिना, हम बस लेखक के टाइमस्टैम्प को क्रम में दिखाना चाहते हैं, तो निम्नलिखित कमांड मदद करेंगे।

git log --pretty='%at %s' COMMIT1..COMMIT2 > hashlog
join -1 1 -2 1 <(cat hashlog | cut -f 1 | sort -nr | awk '{ print NR" "$1 }') <(cat hashlog | awk '{ print NR" "$0 }') | cut -d" " -f2,4- > hashlog_
mv hashlog_ hashlog
git filter-branch --env-filter '__date=$(__log=$(git log -1 --pretty="%s" $GIT_COMMIT); grep -m 1 "$__log" ../../hashlog | cut -d" " -f1); test -n "$__date" && export GIT_AUTHOR_DATE=$__date || cat'

यह एक महान चाल है! इसने मुझे अन्य उत्तरों के उपयोग से 1100+ के बजाय केवल 75 कमिट्स को फिर से लिखने की अनुमति दी।
ऑडियो

यह शानदार है! क्या स्क्रिप्ट को संशोधित करने के साथ-साथ मूल कमिटर को भी संरक्षित करने का कोई तरीका है?
डेविड डीमर

@DavidDeMar होना चाहिए, वही, बस मूल ईमेल को रिकॉर्ड करने के लिए git log --pretty बदलें, और तदनुसार स्क्रिप्ट को संशोधित करें।
weynhamz
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.