सवाल क्या गिट में फ़ाइलों को स्थानांतरित / पुनर्नामित करना और उनका इतिहास बनाए रखना संभव है?


मैं गिट में एक प्रोजेक्ट सबट्री का नाम बदलना / स्थानांतरित करना चाहता हूं

/project/xyz

सेवा मेरे

/components/xyz

अगर मैं एक सादा का उपयोग करता हूं git mv project components, तो सभी के लिए प्रतिबद्धता इतिहास xyz project भाड़ में जाओ। क्या ऐसा करने का कोई तरीका है कि इतिहास बनाए रखा जाए?


552
2018-02-22 22:11


मूल


के बारे में git mv: stackoverflow.com/questions/1094269/whats-the-purpose-of-git-mv - cregox
मैं सिर्फ यह ध्यान रखना चाहता हूं कि मैंने फाइल सिस्टम के माध्यम से फ़ाइलों को स्थानांतरित करने का परीक्षण किया है, और इंटेलिज के माध्यम से (मैं इंटेलिज के माध्यम से) पूरे इतिहास को देख सकता हूं (इतिहास में जब यह एक अलग स्थान पर था) इतिहास को देखकर (फिर इंटेलिज में)। मुझे लगता है कि इंटेलिज ऐसा करने के लिए विशेष रूप से विशेष नहीं कर रहा है, इसलिए यह जानना अच्छा लगता है कि कम से कम इतिहास का पता लगाया जा सकता है। - B T
निर्देशिका नाम का पता लगाने के दौरान गिट के नियमों के लिए, देखें नीचे मेरा जवाब - VonC


जवाब:


गिट प्रतिबद्धता के साथ संचालन को बनाए रखने के बजाए नामों का पता लगाता है, इसलिए आप इसका उपयोग करते हैं या नहीं git mv या mv कोई फर्क नहीं पड़ता।

लॉग कमांड एक लेता है --follow तर्क जो नाम बदलने से पहले इतिहास जारी रखता है, यानी, यह हेरिस्टिक्स का उपयोग करके समान सामग्री की खोज करता है:

http://git-scm.com/docs/git-log

पूर्ण इतिहास देखने के लिए, निम्न आदेश का उपयोग करें:

git log --follow ./path/to/file

561
2018-02-22 22:26



मुझे संदेह है कि यह एक प्रदर्शन विचार है। अगर आपको पूर्ण इतिहास की आवश्यकता नहीं है, तो यह निश्चित रूप से सामग्री स्कैन करने में अधिक समय लगेगा। उपनाम सेट अप करना सबसे आसान तरीका है git config alias.logf "log --follow" और बस लिखें git logf ./path/to/file। - Troels Thomsen
@TroelsThomsen यह ईमेल लिनस Torvalds द्वारा, से जुड़ा हुआ है यह जवाब, इंगित करता है कि यह गिट की जानबूझकर डिज़ाइन पसंद है क्योंकि यह कथित रूप से नाम बदलने आदि की तुलना में अधिक शक्तिशाली है। - Emil Lundberg
यह जवाब थोड़ा भ्रामक है। गिट "नामों का पता लगाता है," लेकिन खेल में बहुत देर हो चुकी है; सवाल यह पूछ रहा है कि आप गिट ट्रैक नामों को कैसे सुनिश्चित करते हैं, और इसे पढ़ने वाला कोई व्यक्ति आसानी से अनुमान लगा सकता है कि गिट उन्हें स्वचालित रूप से आपके लिए पहचानता है और इसके बारे में ध्यान देता है। ऐसा नहीं होता। गिट के पास नामों का कोई वास्तविक प्रबंधन नहीं है, और इसके बदले विलय / लॉग टूल्स हैं जो यह पता लगाने का प्रयास करते हैं कि क्या हुआ - और शायद ही कभी इसे सही लगे। लिनस के पास एक गलत लेकिन जोरदार तर्क है कि क्यों गिट को इसे सही तरीके से नहीं करना चाहिए और स्पष्ट रूप से नामों को ट्रैक करना चाहिए। तो, हम यहाँ फंस गए हैं। - Chris Moschini
महत्वपूर्ण: यदि आप किसी निर्देशिका का नाम बदलते हैं, उदाहरण के लिए जावा पैकेज का नाम बदलने के दौरान, 'git mv {old} {new}' कमांड के लिए पहले दो काम निष्पादित करना सुनिश्चित करें, दूसरी जावा फ़ाइलों के अपडेट के लिए दूसरा पैकेज निर्देशिका बदल दी। अन्यथा git --follow पैरामीटर के साथ भी व्यक्तिगत फ़ाइलों को ट्रैक नहीं कर सकता है। - nn4l
हालांकि लिनस शायद बहुत कम गलतियां करता है, यह एक प्रतीत होता है। बस एक फ़ोल्डर का नाम बदलने से गिटहब पर भारी डेल्टा अपलोड किया जा सकता है। जो मुझे अपने फ़ोल्डर्स का नाम बदलने के बारे में सतर्क करता है ... लेकिन यह प्रोग्रामर के लिए एक बहुत बड़ा सीधा जैकेट है। कभी-कभी, मुझे कुछ के अर्थ को फिर से परिभाषित करना पड़ता है, या चीजों को वर्गीकृत करने के तरीके को बदलना पड़ता है। लिनस: "दूसरे शब्दों में, मैं सही हूं। मैं हमेशा सही हूं, लेकिन कभी-कभी मैं दूसरी बार से अधिक सही हूं। और जब मैं कहता हूं कि 'फाइलें कोई फर्क नहीं पड़ता', मैं वास्तव में वास्तव में सही हूं ( टीएम)। " ... मुझे इसके बारे में मेरा संदेह है। - Gabe Halsmer


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

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

अब, चूंकि आप अभी भी मेरे साथ हैं, आप शायद एक पूरी तरह से पृथक फ़ाइल का नाम बदल रहे एकल डेवलपर हैं। चलो एक फाइल का उपयोग कर ले जाएँ filter-tree!

मान लीजिए कि आप एक फाइल ले जा रहे हैं old एक फ़ोल्डर में dir और इसे नाम दें new

यह साथ किया जा सकता है git mv old dir/new && git add -u dir/new, लेकिन यह इतिहास तोड़ता है।

बजाय:

git filter-branch --tree-filter 'if [ -f old ]; then mkdir dir && mv old dir/new; fi' HEAD

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

पूरा होने पर, फ़ाइल स्थानांतरित हो जाती है और लॉग बरकरार है। आप निंजा समुद्री डाकू की तरह महसूस करते हैं।

इसके अलावा, Mkdir dir केवल तभी जरूरी है जब आप फ़ाइल को नए फ़ोल्डर में ले जाएं। अगर आपकी फ़ाइल मौजूद होने की तुलना में इतिहास में पहले इस फ़ोल्डर के निर्माण से बचेंगी।


75
2018-02-28 11:59



एक जुनूनी गिट-लॉग-प्रेमी के रूप में, मैं इसके लिए नहीं जाऊंगा। फाइलों का नाम उन बिंदुओं पर नहीं था, इसलिए इतिहास एक अस्तित्वहीन स्थिति को दर्शाता है। कौन जानता है कि अतीत में कौन से परीक्षण टूट सकते हैं! पिछले संस्करणों को तोड़ने का जोखिम हर मामले में काफी हद तक नहीं है। - Vincent
@ विन्सेंट आप बिल्कुल सही हैं, और मैंने स्पष्ट होने की कोशिश की क्योंकि मैं इस समाधान की असंभवता के बारे में उचित हो सकता था। मुझे यह भी लगता है कि हम इस मामले में "इतिहास" शब्द के दो अर्थों के बारे में बात कर रहे हैं, मैं दोनों की सराहना करता हूं। - Øystein Steimler
मुझे लगता है कि ऐसी स्थितियां हैं जहां किसी को इसकी आवश्यकता हो सकती है। मान लें कि मैंने अपनी निजी शाखा में कुछ विकसित किया है, जिसे मैं अब अपस्ट्रीम मर्ज करना चाहता हूं। लेकिन मुझे पता चलता है कि फ़ाइल नाम अनुचित नहीं है, इसलिए मैं इसे अपनी पूरी व्यक्तिगत शाखा के लिए बदलता हूं। इस तरह से मैं एक साफ उचित इतिहास रख सकता हूं और शुरुआत से सही नाम रख सकता हूं। - user2291758
@ user2291758 यह मेरा उपयोग केस है। ये अधिक शक्तिशाली गिट कमांड खतरनाक हैं लेकिन इसका मतलब यह नहीं है कि उनके पास बहुत ही आकर्षक उपयोग के मामले नहीं हैं यदि आप जानते हैं कि आप क्या कर रहे हैं! - philix
यदि संभव हो तो, का उपयोग कर --index-filter नामों के लिए बहुत तेजी से होगा क्योंकि पेड़ की जांच नहीं की जाएगी और प्रत्येक प्रतिबद्धता पर वापस आना होगा। --index-filter प्रत्येक प्रतिबद्ध सूचकांक पर सीधे कार्य करता है। - Thomas Guyot-Sionnest


नहीं।

संक्षिप्त जवाब है नहीं, गिट में एक फ़ाइल का नाम बदलना और इतिहास को याद रखना संभव नहीं है। और यह एक दर्द है।

अफवाह यह है कि git log --follow--find-copies-harder काम करेगा लेकिन यह मेरे लिए काम नहीं करता है, भले ही फ़ाइल सामग्री में शून्य परिवर्तन हो, और चालें बनाई गई हैं git mv

(शुरुआत में मैंने ग्रहण का नाम बदलने और एक ऑपरेशन में पैकेज अपडेट करने के लिए किया था, जो भ्रमित गिट हो सकता है। लेकिन यह करना बहुत आम बात है। --follow ऐसा लगता है कि अगर केवल एक काम करता है mv किया जाता है और फिर ए commit और यह mv बहुत दूर नहीं है।)

लिनस का कहना है कि आपको व्यक्तिगत रूप से एक सॉफ्टवेयर प्रोजेक्ट की पूरी सामग्री को समझना है, व्यक्तिगत फ़ाइलों को ट्रैक करने की आवश्यकता नहीं है। खैर, दुख की बात है, मेरा छोटा मस्तिष्क ऐसा नहीं कर सकता है।

यह है वास्तव में गुस्से वाला कि इतने सारे लोगों ने बयान को दोहराया है कि गिट स्वचालित रूप से चाल को ट्रैक करता है। उन्होंने मेरा समय बर्बाद कर दिया है। गिट ऐसा कोई काम नहीं करता है। डिज़ाइन द्वारा (!) गिट चाल को ट्रैक नहीं करता है।

मेरा समाधान फ़ाइलों को उनके मूल स्थानों पर वापस नामित करना है। स्रोत नियंत्रण फिट करने के लिए सॉफ़्टवेयर बदलें। गिट के साथ आपको बस पहली बार इसे गिट करने की आवश्यकता होती है।

दुर्भाग्य से, यह ग्रहण को तोड़ता है, जो उपयोग में प्रतीत होता है --follow
git log --follow कभी-कभी जटिल नाम इतिहास के साथ फ़ाइलों का पूरा इतिहास नहीं दिखाता है    git log कर देता है। (मुझे नहीं पता क्यों।)

(कुछ बहुत चतुर हैक्स हैं जो वापस जाते हैं और पुराने काम की सिफारिश करते हैं, लेकिन वे बल्कि डरावने हैं। गिटहब-गीस्ट देखें: emiller / Git-mv-साथ-इतिहास।)


59
2017-09-28 05:46



मुझे लगता है आप सही हैं। मैं बस अपने लैरावेल 5 प्रोजेक्ट के स्रोत को दोबारा सुधारने के लिए php-cs-fixer का उपयोग करने की कोशिश कर रहा था, लेकिन यह ऐप फ़ोल्डर के लोअरकेस मान से मेल खाने के लिए नामस्थान खंडों के पूंजीकरण को बदलने पर जोर देता है। लेकिन नेमस्पेस (या संगीतकार ऑटोलोड) केवल कैमेलकेस के साथ काम करते हैं। मुझे फ़ोल्डर में पूंजीकरण को ऐप में बदलने की जरूरत है, लेकिन इससे मेरे परिवर्तन खो जाएंगे। यह उदाहरणों का सबसे छोटा है, लेकिन यह दिखाता है कि गिट हेरिस्टिक कैसे नाम परिवर्तनों में से सबसे सरल का पालन करने में सक्षम नहीं है (--follow और --find-copies-harder नियम होना चाहिए, अपवाद नहीं)। - Zack Morris
गिट -1, उपversण +1 - Cosmin


git log --follow [file]

आपको नामों के माध्यम से इतिहास दिखाएगा।


38
2018-02-22 22:25



ऐसा प्रतीत होता है कि फ़ाइल को संशोधित करने से पहले आपको केवल नाम बदलने की आवश्यकता है। यदि आप फ़ाइल (खोल में) ले जाते हैं और फिर इसे बदलते हैं, तो सभी दांव बंद हो जाते हैं। - yoyo
@Yoyo: ऐसा इसलिए है क्योंकि गिट नामों को ट्रैक नहीं करता है, यह उन्हें पहचानता है। ए git mvमूल रूप से एक करता है git rm && git add। जैसे विकल्प हैं -M90 / --find-renames=90 एक फ़ाइल को फिर से नामित करने पर विचार करें जब यह 90% समान है। - vdboor


मैं करता हूँ:

git mv {old} {new}
git add -u {new}

16
2017-11-24 19:07



-U मेरे लिए कुछ भी नहीं प्रतीत होता है, क्या यह इतिहास को अद्यतन करने का अनुमान है? - jeremy
यह फाइलें जोड़ता है, हालांकि यह इतिहास को अपडेट नहीं करता है ताकि 'गिट लॉग फ़ाइल नाम' पूर्ण इतिहास दिखाता है। यदि आप अभी भी --follow विकल्प का उपयोग करते हैं तो यह केवल पूर्ण इतिहास दिखाता है। - jeremy
ओह मैं समझा। क्षमा .... - James M. Greene
मैंने एक जटिल रिफैक्टर किया जो एक निर्देशिका को शामिल करता है (एमवी का उपयोग करके, जीआईटी एमवी नहीं) और फिर नामित फ़ाइलों के भीतर # अंतर्निहित पथों को बदल दिया। इतिहास को ट्रैक करने के लिए गिट को पर्याप्त समानता नहीं मिल सका। लेकिन गिट ऐड-यू सिर्फ वही चीज़ थी जिसकी मुझे आवश्यकता थी। गिट स्थिति अब "नामित" इंगित करती है जहां इसे "हटाया गया" और "नई फ़ाइल" दिखाए जाने से पहले। - AndyJost
एसओ पर बहुत सारे प्रश्न हैं जो इस उद्देश्य को संबोधित करते हैं git add -u। गिट डॉक्स अनुपयोगी होते हैं, और आखिरी जगह मैं देखना चाहता हूं। यहां एक पोस्ट दिखा रहा है git add -u कार्रवाई में: stackoverflow.com/a/2117202। - nobar


लक्ष्य

  • उपयोग git am  (से प्रेरित smar, से उधार Exherbo)
  • प्रतिलिपि / स्थानांतरित फ़ाइलों का प्रतिबद्ध इतिहास जोड़ें
  • एक निर्देशिका से दूसरे में
  • या एक भंडार से दूसरे में

सीमा

  • टैग और शाखाओं को नहीं रखा जाता है
  • पथ फ़ाइल नाम पर इतिहास काटा गया है (निर्देशिका का नाम बदलें)

सारांश

  1. ईमेल प्रारूप में इतिहास का उपयोग करें
    git log --pretty=email -p --reverse --full-index --binary
  2. फ़ाइल पेड़ को पुनर्गठित करें और फ़ाइल नाम अपडेट करें
  3. उपयोग कर नया इतिहास संलग्न करें
    cat extracted-history | git am --committer-date-is-author-date

1. ईमेल प्रारूप में इतिहास निकालें

उदाहरण: का इतिहास निकालें file3, file4 तथा file5

my_repo
├── dirA
│   ├── file1
│   └── file2
├── dirB            ^
│   ├── subdir      | To be moved
│   │   ├── file3   | with history
│   │   └── file4   | 
│   └── file5       v
└── dirC
    ├── file6
    └── file7

गंतव्य सेट / साफ करें

export historydir=/tmp/mail/dir       # Absolute path
rm -rf "$historydir"    # Caution when cleaning the folder

ईमेल प्रारूप में प्रत्येक फ़ाइल का इतिहास निकालें

cd my_repo/dirB
find -name .git -prune -o -type d -o -exec bash -c 'mkdir -p "$historydir/${0%/*}" && git log --pretty=email -p --stat --reverse --full-index --binary -- "$0" > "$historydir/$0"' {} ';'

दुर्भाग्य से विकल्प --follow या --find-copies-harder के साथ संयुक्त नहीं किया जा सकता है --reverse। यही कारण है कि फ़ाइल का नाम बदलते समय इतिहास काटा जाता है (या जब मूल निर्देशिका का नाम बदल दिया जाता है)।

ईमेल प्रारूप में अस्थायी इतिहास:

/tmp/mail/dir
    ├── subdir
    │   ├── file3
    │   └── file4
    └── file5

दान Bonachea इस पहले चरण में गिट लॉग जनरेशन कमांड के लूप को उलटा करने का सुझाव देता है: प्रति फ़ाइल एक बार गिट लॉग चलाने के बजाए, इसे कमांड लाइन पर फ़ाइलों की सूची के साथ एक बार चलाएं और एक एकीकृत एकीकृत लॉग उत्पन्न करें। इस तरह से कई फाइलें संशोधित होती हैं जो परिणाम में एक ही प्रतिबद्ध रहती हैं, और सभी नए काम अपने मूल सापेक्ष आदेश को बनाए रखते हैं। ध्यान दें कि (अब एकीकृत) लॉग में फ़ाइल नामों को फिर से लिखते समय इसे दूसरे चरण में परिवर्तन की आवश्यकता होती है।


2. फ़ाइल पेड़ को पुनर्गठित करें और फ़ाइल नाम अपडेट करें

मान लीजिए कि आप इन तीन फ़ाइलों को इस अन्य रेपो में ले जाना चाहते हैं (वही रेपो हो सकता है)।

my_other_repo
├── dirF
│   ├── file55
│   └── file56
├── dirB              # New tree
│   ├── dirB1         # from subdir
│   │   ├── file33    # from file3
│   │   └── file44    # from file4
│   └── dirB2         # new dir
│        └── file5    # from file5
└── dirH
    └── file77

इसलिए अपनी फाइलों को पुनर्गठित करें:

cd /tmp/mail/dir
mkdir -p dirB/dirB1
mv subdir/file3 dirB/dirB1/file33
mv subdir/file4 dirB/dirB1/file44
mkdir -p dirB/dirB2
mv file5 dirB/dirB2

आपका अस्थायी इतिहास अब है:

/tmp/mail/dir
    └── dirB
        ├── dirB1
        │   ├── file33
        │   └── file44
        └── dirB2
             └── file5

इतिहास के भीतर फ़ाइल नाम भी बदलें:

cd "$historydir"
find * -type f -exec bash -c 'sed "/^diff --git a\|^--- a\|^+++ b/s:\( [ab]\)/[^ ]*:\1/$0:g" -i "$0"' {} ';'

3. नया इतिहास लागू करें

आपका अन्य रेपो है:

my_other_repo
├── dirF
│   ├── file55
│   └── file56
└── dirH
    └── file77

अस्थायी इतिहास फ़ाइलों से काम लागू करें:

cd my_other_repo
find "$historydir" -type f -exec cat {} + | git am --committer-date-is-author-date

--committer-date-is-author-date मूल प्रतिबद्धता समय-टिकटों को संरक्षित करता है (दान Bonacheaटिप्पणी है)।

आपका अन्य रेपो अब है:

my_other_repo
├── dirF
│   ├── file55
│   └── file56
├── dirB
│   ├── dirB1
│   │   ├── file33
│   │   └── file44
│   └── dirB2
│        └── file5
└── dirH
    └── file77

उपयोग git status धक्का देने के लिए तैयार काम की मात्रा देखने के लिए :-)


अतिरिक्त चाल: अपने रेपो के भीतर नामित / स्थानांतरित फ़ाइलों की जांच करें

नाम बदलने वाली फ़ाइलों को सूचीबद्ध करने के लिए:

find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow {} ';' | grep '=>'

अधिक अनुकूलन: आप आदेश को पूरा कर सकते हैं git log विकल्पों का उपयोग कर --find-copies-harder या --reverse। आप पहले दो कॉलम का उपयोग कर भी हटा सकते हैं cut -f3- और पूर्ण पैटर्न grepping '{। * =>। *}'।

find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow --find-copies-harder --reverse {} ';' | cut -f3- | grep '{.* => .*}'

12
2017-11-24 18:36



सावधानी: यह तकनीक अलग-अलग होती है जो 2 या अधिक फ़ाइलों को अलग खंडित-कमेट में बदलती है, और इसके बाद फ़ाइल नाम पर सॉर्ट करके अपने ऑर्डर को स्कैम्बल करता है (इसलिए एक मूल प्रतिबद्धता के टुकड़े रैखिक इतिहास में आसन्न नहीं होते हैं)। परिणामस्वरूप इतिहास फ़ाइल-दर-फ़ाइल आधार पर केवल "सही" है। यदि आप एक से अधिक फाइलों को स्थानांतरित कर रहे हैं, तो परिणामी इतिहास में नए कामों में से कोई भी मूल रेपो के इतिहास में कभी भी स्थानांतरित फ़ाइलों की एक सतत स्नैपशॉट का प्रतिनिधित्व नहीं करता है। - Dan Bonachea
हाय @ डैनबोनचे। आपकी दिलचस्प प्रतिक्रिया के लिए धन्यवाद। मैंने इस तकनीक का उपयोग करके कई फाइलों को सफलतापूर्वक माइग्रेट किया है (यहां तक ​​कि नामित फाइलों और फ़ाइलों के साथ निर्देशिकाओं में स्थानांतरित)। इस जवाब में बदलने के लिए आप क्या सुझाव देते हैं। क्या आपको लगता है कि हमें इस तकनीक की सीमाओं को समझाते हुए इस उत्तर के शीर्ष पर एक चेतावनी बैनर जोड़ना चाहिए? चियर्स - olibre
मैंने इस तकनीक को चरण 1 में गिट लॉग जनरेशन कमांड के लूपों को परिवर्तित करके समस्या से बचने के लिए अनुकूलित किया। प्रति फ़ाइल एक बार गिट लॉग चलाने के बजाए, इसे कमांड लाइन पर फ़ाइलों की सूची के साथ ठीक से चलाएं और एक एकीकृत एकीकृत लॉग उत्पन्न करें। इस तरह से 2 या अधिक फाइलों को संशोधित करने के परिणामस्वरूप एक ही प्रतिबद्धता बनी रहती है, और सभी नए काम अपने मूल सापेक्ष आदेश को बनाए रखते हैं। ध्यान दें कि (अब एकीकृत) लॉग में फ़ाइल नामों को फिर से लिखते समय चरण 2 में परिवर्तन की आवश्यकता होती है। मैंने मूल प्रतिबद्ध टाइमस्टैम्प को संरक्षित करने के लिए गिट एम - कमिटर-डेट-द-लेखक-डेट का भी उपयोग किया। - Dan Bonachea
आपके प्रयोग और साझा करने के लिए धन्यवाद। मैंने अन्य पाठकों के लिए थोड़ा सा जवाब अपडेट किया है। हालांकि मैंने आपके प्रसंस्करण का परीक्षण करने में समय लगाया है। यदि आप कमांड लाइनों के उदाहरण प्रदान करना चाहते हैं, तो कृपया इस उत्तर को संपादित करने के लिए स्वतंत्र महसूस करें। चीयर्स;) - olibre


गिट के मूल के दौरान, गिट नलसाजी नामों का ट्रैक नहीं रखती है, यदि आप गिट लॉग "पोर्सिलीन" के साथ प्रदर्शित इतिहास को पहचानते हैं तो उन्हें पहचान सकते हैं।

दिए हुए के लिए git log -एम विकल्प का उपयोग करें:

गिट लॉग -पी -एम

गिट के वर्तमान संस्करण के साथ।

यह अन्य आदेशों के लिए काम करता है जैसे git diff भी।

तुलना को कम या ज्यादा कठोर बनाने के विकल्प हैं। यदि आप एक ही समय में फ़ाइल में महत्वपूर्ण परिवर्तन किए बिना फ़ाइल का नाम बदलते हैं तो यह गिट लॉग और दोस्तों के नाम का पता लगाने में आसान बनाता है। इस कारण से कुछ लोग एक प्रतिबद्धता में फ़ाइलों का नाम बदलते हैं और उन्हें दूसरे में बदल देते हैं।

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

यदि आप हमेशा एक विशेष भंडार में नाम बदलने के साथ अपने इतिहास की रिपोर्ट करना चाहते हैं तो आप इसका उपयोग कर सकते हैं:

गिट कॉन्फ़िगर diff.renames 1

एक निर्देशिका से दूसरी निर्देशिका में चल रही फ़ाइलें है पता चला। यहां एक उदाहरण दिया गया है:

commit c3ee8dfb01e357eba1ab18003be1490a46325992
Author: John S. Gruber <JohnSGruber@gmail.com>
Date:   Wed Feb 22 22:20:19 2017 -0500

    test rename again

diff --git a/yyy/power.py b/zzz/power.py
similarity index 100%
rename from yyy/power.py
rename to zzz/power.py

commit ae181377154eca800832087500c258a20c95d1c3
Author: John S. Gruber <JohnSGruber@gmail.com>
Date:   Wed Feb 22 22:19:17 2017 -0500

    rename test

diff --git a/power.py b/yyy/power.py
similarity index 100%
rename from power.py
rename to yyy/power.py

कृपया ध्यान दें कि जब भी आप diff का उपयोग कर रहे हों, यह केवल तभी काम करता है git log। उदाहरण के लिए:

$ git diff HEAD c3ee8df
diff --git a/power.py b/zzz/power.py
similarity index 100%
rename from power.py
rename to zzz/power.py

एक परीक्षण के रूप में मैंने एक फीचर शाखा में एक फ़ाइल में एक छोटा सा परिवर्तन किया और इसे प्रतिबद्ध किया और फिर मास्टर शाखा में मैंने फ़ाइल का नाम बदल दिया, प्रतिबद्ध किया, और फिर फ़ाइल के दूसरे हिस्से में एक छोटा बदलाव किया और इसे स्वीकार किया। जब मैं फीचर शाखा में गया और मास्टर से विलय कर दिया तो विलय ने फ़ाइल का नाम बदल दिया और परिवर्तनों को विलय कर दिया। मर्ज से आउटपुट यहां दिया गया है:

 $ git merge -v master
 Auto-merging single
 Merge made by the 'recursive' strategy.
  one => single | 4 ++++
  1 file changed, 4 insertions(+)
  rename one => single (67%)

परिणाम फ़ाइल नाम के साथ एक कार्यशील निर्देशिका थी और दोनों पाठ परिवर्तन किए गए थे। तो इस तथ्य के बावजूद कि यह स्पष्ट रूप से नामों को ट्रैक नहीं करता है, गिट के लिए सही चीज करना संभव है।

यह पुराने प्रश्न का उत्तरदायी उत्तर है, इसलिए उस समय गिट संस्करण के लिए अन्य उत्तर सही हो सकते हैं।


2
2018-02-23 04:54





मैं गिट में एक प्रोजेक्ट सबट्री का नाम बदलना / स्थानांतरित करना चाहता हूं

/project/xyz

सेवा मेरे

/ घटकों / xyz

अगर मैं एक सादा का उपयोग करता हूं git mv project components, तो सभी के लिए प्रतिबद्धता इतिहास xyz परियोजना खो जाती है।

नहीं (8 साल बाद, गिट 2.1 9, क्यू 3 2018), क्योंकि गिट होगा निर्देशिका का नाम बदलें, और यह अब बेहतर दस्तावेज है।

देख b00bf1c प्रतिबद्ध करें, 1634688 प्रतिबद्ध करें, 0661e49 प्रतिबद्ध करें, 4 डी 34 डीएफ प्रतिबद्ध करें, 983f464 प्रतिबद्ध करें, c840e1a प्रतिबद्ध करें, 9929430 प्रतिबद्ध करें (27 जून 2018), और डी 4e8062 प्रतिबद्ध करें, 5dacd4a प्रतिबद्ध करें (25 जून 2018) द्वारा एलियाह न्यूरेन (newren)
(द्वारा विलय जूनियो सी हमानो - gitster- में 0ce5a69 प्रतिबद्ध करें, 24 जुलाई 2018) 

अब इसमें समझाया गया है Documentation/technical/directory-rename-detection.txt:

उदाहरण:

जब सब कुछ x/a, x/b तथा x/c चले गए हैं z/a, z/b तथा z/c, ऐसी संभावना है x/d इस बीच में भी जाना चाहते हैं z/d द्वारा   इस संकेत को लेकर कि पूरी निर्देशिका 'x' में ले जाया गया 'z'।

लेकिन वे कई अन्य मामले हैं, जैसे:

इतिहास के एक तरफ नाम बदलता है x -> z, और दूसरा कुछ फाइल का नाम बदलता है    x/e, एक विवादास्पद नाम करने के लिए विलय की आवश्यकता पैदा कर रहा है।

निर्देशिका को सरल बनाने के लिए पहचान का नाम बदलें, उन नियमों को गिट द्वारा लागू किया जाता है:

कुछ बुनियादी नियम कब सीमित करते हैं निर्देशिका का नाम बदलना लागू होता है:

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

आप देख सकते हैं बहुत परीक्षण में t/t6043-merge-rename-directories.sh, जो यह भी इंगित करता है कि:

  • ए) यदि नाम दो या दो से अधिक निर्देशिका में विभाजित करते हैं, तो अधिकांश नामों वाली निर्देशिका "जीतती है"।
  • बी) पथ के लिए निर्देशिका-नामकरण-पहचान से बचें, यदि वह पथ विलय के दोनों तरफ एक नाम का नाम है।
  • सी) दूसरी तरफ निर्देशिकाओं के लिए केवल निहित निर्देशिका नाम लागू करें   इतिहास का नाम बदल रहा है।

0
2017-07-30 19:37





मैं फ़ाइलों को स्थानांतरित करता हूं और फिर करता हूं

git add -A

जो सैटेलाइट क्षेत्र में सभी हटाए गए / नई फाइलों में डाल दिया गया है। यहां गिट को पता चलता है कि फ़ाइल ले जाया गया है।

git commit -m "my message"
git push

मुझे नहीं पता क्यों, लेकिन यह मेरे लिए काम करता है।


-1
2017-12-18 14:34



मेरे लिए काम नहीं कर रहा :( - dr0i
यहां की चाल यह है कि आपको एक भी अक्षर बदलने की ज़रूरत नहीं है, भले ही आप कुछ बदल दें और Ctrl + Z दबाएं, इतिहास टूटा जाएगा। तो उस मामले में यदि आप कुछ फ़ाइल को वापस लेते हैं, और इसे फिर से ले जाएं और इसके लिए एक ऐड-> प्रतिबद्ध करें। - Xelian
मेरे लिए काम नहीं कर रहा है :( - davey