Git-mv का उद्देश्य क्या है?


287

मुझे जो समझ में आया है, Git को वास्तव में फ़ाइल का नाम बदलने / स्थानांतरित करने / कॉपी संचालन को ट्रैक करने की आवश्यकता नहीं है , इसलिए git mv का वास्तविक उद्देश्य क्या है ? मैन पेज विशेष रूप से वर्णनात्मक नहीं है ...

क्या यह अप्रचलित है? क्या यह एक आंतरिक कमांड है, जिसका उपयोग नियमित उपयोगकर्ताओं द्वारा नहीं किया जाता है?

जवाबों:


390
git mv oldname newname

के लिए बस आशुलिपि है:

mv oldname newname
git add newname
git rm oldname

यानी यह स्वचालित रूप से पुराने और नए दोनों रास्तों के लिए अनुक्रमणिका को अद्यतन करता है।


38
इसके अलावा इसमें कुछ
सिटिज़ भी

6
धन्यवाद @CharlesBailey - क्या git तब newNameFile और oldNameFile को अलग-अलग मानती है? यदि हाँ, तो क्या होगा यदि हम उनका विलय करना चाहते हैं? मान लीजिए कि हम शाखा A पर एक चींटी परियोजना की शाखा बनाते हैं और B की शाखाएँ बनाते हैं तो B. पर प्रोजेक्ट्स को नामांकित करें। फ़ाइल नाम समान हैं लेकिन जैसे ही प्रोजेक्ट पथ परिवर्तित होता है, विभिन्न पथों पर डाल दिया जाता है। यूं कहें कि दोनों शाखाएं समानांतर में कुछ समय के लिए बढ़ीं। कुछ बिंदु पर अगर हम परियोजनाओं का विलय करना चाहते हैं, तो यह कैसे पता चलेगा कि यह उसी फ़ाइल का नाम है जिसका नाम बदलकर यह पथ है? (अगर "git mv" == "git add + git rm")
रोज़

2
@SergeyOrshanskiy यदि ऑटो का पता लगाना गलत है mv oldname newname; git add newname; git rm oldname, तो यह भी गलत होगा git mv oldname newname( इस उत्तर को देखें )।
Ajedi32

5
ध्यान दें कि इसमें git mvसे थोड़ा अलग है mv oldname newname; git add newname; git rm oldname, अगर आपने git mvआईएनजी से पहले फ़ाइल में परिवर्तन किया है, तो उन परिवर्तनों का मंचन तब तक नहीं किया जाएगा जब तक आप git addनई फ़ाइल नहीं बनाते ।
Ajedi32

2
git mv कुछ अलग कर रहा है, क्योंकि यह फ़ाइल नाम मामले में परिवर्तन (foo.txt से Foo.txt) को संभालता है, जबकि वे कमांड व्यक्तिगत रूप से चलते हैं (OSX पर)
greg.kindel

66

से आधिकारिक GitFaq :

Git का नाम बदलने की आज्ञा है git mv, लेकिन यह सिर्फ एक सुविधा है। प्रभाव फ़ाइल को हटाने और अलग नाम और एक ही सामग्री के साथ एक और जोड़ने से अप्रभेद्य है


8
तो क्या आप फ़ाइल इतिहास को ढीला करते हैं? मुझे लगता है कि नाम बदलने के लिए उस निर्देशिका के लिए पुराने इतिहास रखना होगा ...
Hancock

17
खैर, हाँ और नहीं। नाम बदलने के बारे में ऊपर दिए गए आधिकारिक GitFaq लिंक को पढ़ें, और फिर लाइनस टॉर्वाल्ड्स के बारे में पढ़ें कि वह एक SCM टूल ट्रैकिंग फ़ाइलों की धारणा क्यों पसंद नहीं करता है: permalink.gmane.org/gmane.comp.version-control.git/ 217
एडम नोफ़िंगर

3
@WillHancock मैंने अभी थोड़ा अधिक git का उपयोग किया है, और आप अधिक निश्चित रूप से उत्तर दे सकते हैं: आपके git क्लाइंट और इसके विकल्पों के आधार पर, आप फ़ाइल का नाम बदलकर अतीत का पता लगाने में सक्षम होंगे यदि फ़ाइल आंतरिक रूप से बहुत कम बदल जाती है जो कि इसे बदल देती है नाम बदलें। यदि आप फ़ाइल को बहुत अधिक बदल देते हैं और उसका नाम बदल देते हैं, तो git उसका पता नहीं लगाएगा - एक अर्थ में यह कह रहा है "नहीं, आप शायद इस पर विचार कर सकते हैं कि पूरी तरह से अलग फ़ाइल!"
एडम नोफ़्सिंगर

7
@AdamNofsinger कि लिंक मृत है। यहाँ एक दर्पण है: web.archive.org/web/20150209075907/http://…
कार्ल वॉल्श

2
क्या कोई आधिकारिक संदर्भ (यानी अधिक थ्रस्ट-योग्य है कि अक्सर पूछे जाने वाले प्रश्न) जो git mvमैनुअल और एप्रोच दृष्टिकोण के बीच समानता रखता है ? इससे स्पष्ट नहीं है git help mv
tvo

40

Git आपके लिए केवल अनुमान लगाने की कोशिश कर रहा है कि आप क्या करने की कोशिश कर रहे हैं। यह अखंड इतिहास को संरक्षित करने के लिए हर संभव प्रयास कर रहा है। बेशक, यह सही नहीं है। तो git mvआपको अपने इरादे से स्पष्ट होने और कुछ त्रुटियों से बचने की अनुमति देता है।

इस उदाहरण पर विचार करें। एक खाली रेपो के साथ शुरू,

git init
echo "First" >a
echo "Second" >b
git add *
git commit -m "initial commit"
mv a c
mv b a
git status

परिणाम:

# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   a
#   deleted:    b
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   c
no changes added to commit (use "git add" and/or "git commit -a")

ऑटोडेटेक्शन विफल :( या किया?

$ git add *
$ git commit -m "change"
$ git log c

commit 0c5425be1121c20cc45df04734398dfbac689c39
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:56 2013 -0400

    change

और फिर

$ git log --follow c

Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:56 2013 -0400

    change

commit 50c2a4604a27be2a1f4b95399d5e0f96c3dbf70a
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:45 2013 -0400

    initial commit

अब इसके बजाय प्रयास करें ( .gitप्रयोग करते समय फ़ोल्डर को हटाना याद रखें ):

git init
echo "First" >a
echo "Second" >b
git add *
git commit -m "initial commit"
git mv a c
git status

अब तक सब ठीक है:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    a -> c


git mv b a
git status

अब, कोई भी सही नहीं है:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   a
#   deleted:    b
#   new file:   c
#

वास्तव में? लेकिन निश्चित रूप से...

git add *
git commit -m "change"
git log c
git log --follow c

... और परिणाम ऊपर के समान है: केवल --followपूर्ण इतिहास दिखाता है।


अब, नाम बदलने के साथ सावधान रहें, क्योंकि या तो विकल्प अभी भी अजीब प्रभाव पैदा कर सकता है । उदाहरण:

git init
echo "First" >a
git add a
git commit -m "initial a"
echo "Second" >b
git add b
git commit -m "initial b"

git mv a c
git commit -m "first move"
git mv b a
git commit -m "second move"

git log --follow a

commit 81b80f5690deec1864ebff294f875980216a059d
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:35:58 2013 -0400

    second move

commit f284fba9dc8455295b1abdaae9cc6ee941b66e7f
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:34:54 2013 -0400

    initial b

इसके विपरीत:

git init
echo "First" >a
git add a
git commit -m "initial a"
echo "Second" >b
git add b
git commit -m "initial b"

git mv a c
git mv b a
git commit -m "both moves at the same time"

git log --follow a

परिणाम:

commit 84bf29b01f32ea6b746857e0d8401654c4413ecd
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:37:13 2013 -0400

    both moves at the same time

commit ec0de3c5358758ffda462913f6e6294731400455
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:36:52 2013 -0400

    initial a

अप्स ... अब इतिहास प्रारंभिक बी के बजाय प्रारंभिक पर वापस जा रहा है , जो गलत है। इसलिए जब हमने एक बार में दो चाल चलीं, तो गिट भ्रमित हो गए और परिवर्तनों को ठीक से ट्रैक नहीं किया। वैसे, मेरे प्रयोगों में वही हुआ जब मैंने उपयोग करने के बजाय फ़ाइलों को हटा दिया / बनाया । देखभाल के साथ आगे बढ़ें; आपको चेतावनी दी गई थी...git mv


5
विस्तृत विवरण के लिए +1। मैं उन समस्याओं की तलाश में हूं जो लॉग इतिहास में हो सकती हैं यदि फाइलें गिट में स्थानांतरित हो जाती हैं, तो आपका जवाब वास्तव में दिलचस्प था। धन्यवाद! Btw, क्या आप किसी अन्य नुकसान के बारे में जानते हैं, जिसे हमें फ़ाइलों को गिट में ले जाने से बचना चाहिए? (या कोई संदर्भ जो आप इंगित कर सकते हैं .... इसके लिए बहुत भाग्यशाली नहीं है)
pabrantes

1
खैर, मेरे उदाहरण निराशावादी हैं। जब फाइलें खाली होती हैं, तो परिवर्तनों को ठीक से व्याख्या करना अधिक कठिन होता है। मैं कल्पना करता हूं कि यदि आप नाम बदलने के हर सेट के बाद प्रतिबद्ध होते हैं, तो आपको ठीक होना चाहिए।
osa

27

जैसा कि @Charles कहते हैं, git mvएक आशुलिपि है।

यहाँ असली सवाल है "अन्य संस्करण नियंत्रण प्रणाली (उदाहरण के लिए तोड़फोड़ और कार्यबल) फ़ाइल का नाम विशेष रूप से मानते हैं। क्यों नहीं होता है?"

लीनुस पर बताते हैं http://permalink.gmane.org/gmane.comp.version-control.git/217 विशेषता चातुर्य के साथ:

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


9

एक और उपयोग है git mvजिसका मैंने ऊपर उल्लेख नहीं किया है।

चूँकि खोज git add -p(git add's पैच मोड; देखें http://git-scm.com/docs/git-add ), मैं इसका उपयोग बदलावों की समीक्षा करने के लिए करना पसंद करता हूं क्योंकि मैं उन्हें सूचकांक में जोड़ता हूं। इस प्रकार मेरा वर्कफ़्लो (1) कोड पर काम करता है, (2) समीक्षा और सूचकांक में जोड़ें, (3) प्रतिबद्ध।

git mvमें फिट कैसे होता है? यदि किसी फ़ाइल को सीधे ले जाया जाता है, तो उपयोग करना git rmऔर git add, सभी परिवर्तन सूचकांक में जुड़ जाते हैं, और परिवर्तन देखने के लिए गिट भिन्न का उपयोग करना कम आसान होता है (कमिट करने से पहले)। git mvहालाँकि, उपयोग करना सूचकांक में नया पथ जोड़ता है, लेकिन फ़ाइल में किए गए परिवर्तन नहीं, इस प्रकार अनुमति देना git diffऔर git add -pहमेशा की तरह काम करना।


5

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

greg.kindel ने सीबी बेली के जवाब पर एक टिप्पणी में इसका उल्लेख किया है।

मान लीजिए कि आप एक मैक पर काम कर रहे हैं और आपके पास Mytest.txtgit द्वारा प्रबंधित एक फाइल है । आप फ़ाइल का नाम बदलना चाहते हैं MyTest.txt

तुम कोशिश कर सकते हो:

$ mv Mytest.txt MyTest.txt
overwrite MyTest.txt? (y/n [n]) y
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

बाप रे। Git स्वीकार नहीं करता है कि फ़ाइल में कोई परिवर्तन हुआ है।

आप इसके साथ पूरी तरह से फ़ाइल का नाम बदलकर वापस नाम बदलकर काम कर सकते हैं:

$ mv Mytest.txt temp.txt
$ git rm Mytest.txt
rm 'Mytest.txt'
$ mv temp.txt MyTest.txt
$ git add MyTest.txt 
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    Mytest.txt -> MyTest.txt

हुर्रे!

या आप का उपयोग करके परेशान होने वाले सभी को बचा सकते हैं git mv:

$ git mv Mytest.txt MyTest.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

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