จากสิ่งที่ฉันเข้าใจ Git ไม่จำเป็นต้องติดตามการเปลี่ยนชื่อไฟล์ / ย้าย / คัดลอกไฟล์ดังนั้นจุดประสงค์ที่แท้จริงของgit mvคืออะไร หน้าคนไม่บรรยายเป็นพิเศษ ...
มันล้าสมัยหรือไม่ มันเป็นคำสั่งภายในที่ไม่ได้มีไว้สำหรับผู้ใช้ทั่วไปหรือไม่?
จากสิ่งที่ฉันเข้าใจ Git ไม่จำเป็นต้องติดตามการเปลี่ยนชื่อไฟล์ / ย้าย / คัดลอกไฟล์ดังนั้นจุดประสงค์ที่แท้จริงของgit mvคืออะไร หน้าคนไม่บรรยายเป็นพิเศษ ...
มันล้าสมัยหรือไม่ มันเป็นคำสั่งภายในที่ไม่ได้มีไว้สำหรับผู้ใช้ทั่วไปหรือไม่?
คำตอบ:
git mv oldname newname
เป็นเพียงชวเลขสำหรับ:
mv oldname newname
git add newname
git rm oldname
เช่นอัปเดตดัชนีสำหรับเส้นทางเก่าและใหม่โดยอัตโนมัติ
git mvจะแตกต่างจากmv oldname newname; git add newname; git rm oldnameในกรณีที่คุณทำการเปลี่ยนแปลงไฟล์ก่อนgit mvที่จะทำการเปลี่ยนแปลงการเปลี่ยนแปลงเหล่านั้นจะไม่ถูกจัดทำจนกว่าคุณจะgit addเป็นไฟล์ใหม่
Git มีคำสั่งเปลี่ยนชื่อ
git mvแต่นั่นเป็นเพียงความสะดวกสบาย เอฟเฟ็กต์นั้นแยกไม่ออกจากการลบไฟล์และเพิ่มไฟล์อื่นที่มีชื่อแตกต่างกันและเนื้อหาเดียวกัน
git mvและวิธีการด้วยตนเองหรือไม่? git help mvมันไม่ได้เป็นที่เห็นได้ชัดจาก
Git กำลังพยายามเดาว่าคุณกำลังทำอะไรอยู่ มันกำลังพยายามทุกวิถีทางเพื่อรักษาประวัติศาสตร์ที่ไม่เสียหาย แน่นอนว่ามันไม่สมบูรณ์แบบ ดังนั้นgit mvช่วยให้คุณมีความชัดเจนด้วยความตั้งใจของคุณและเพื่อหลีกเลี่ยงข้อผิดพลาดบางอย่าง
ลองพิจารณาตัวอย่างนี้ เริ่มต้นด้วย repo ที่ว่างเปล่า
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
อัพ ... ตอนนี้ประวัติศาสตร์จะกลับไปเริ่มต้น aแทนค่าเริ่มต้น bซึ่งผิด ดังนั้นเมื่อเราทำการเคลื่อนย้ายครั้งละสองครั้ง Git ก็สับสนและไม่ได้ติดตามการเปลี่ยนแปลงอย่างถูกต้อง โดยวิธีการในการทดลองของฉันเหมือนที่เกิดขึ้นเมื่อฉันลบ / git mvไฟล์ที่สร้างขึ้นแทนการใช้ ดำเนินการต่อด้วยความระมัดระวัง คุณได้รับการเตือน ...
@Charles พูดว่าgit mvเป็นชวเลข
คำถามจริงที่นี่คือ "ระบบควบคุมเวอร์ชันอื่น ๆ (เช่นการโค่นล้มและ Perforce) ปฏิบัติต่อการเปลี่ยนชื่อไฟล์เป็นพิเศษทำไม Git ไม่?
Linus อธิบายที่http://permalink.gmane.org/gmane.comp.version-control.git/217พร้อมกับแทคพิเศษ:
โปรดหยุดอึ "track files" นี้ แทร็ค Git ว่าสิ่งที่สำคัญคือ "คอลเลกชันของแฟ้ม" ไม่มีอะไรเกี่ยวข้องและแม้แต่ คิดว่ามันมีความเกี่ยวข้องเพียง จำกัด มุมมองโลกของคุณ โปรดสังเกตว่าแนวคิดของ CVS "คำอธิบายประกอบ" มักจะจบลงด้วยการ จำกัด ว่าผู้คนใช้งานอย่างไร ฉันคิดว่ามันเป็นเรื่องไร้สาระโดยสิ้นเชิงและฉันได้อธิบายบางสิ่งบางอย่างที่ฉันคิดว่ามีประโยชน์มากกว่าล้านเท่าและมันก็หลุดออกมา อย่างแน่นอนเพราะฉันไม่ได้จำกัดความคิดของฉันในแบบจำลองที่ผิดของโลก
มีประโยชน์อื่นฉันgit mvไม่ได้กล่าวถึงข้างต้น
ตั้งแต่การค้นพบgit add -p(โหมดแก้ไขของ git add ดูที่http://git-scm.com/docs/git-add ) ฉันชอบที่จะใช้มันเพื่อตรวจสอบการเปลี่ยนแปลงเมื่อฉันเพิ่มลงในดัชนี ดังนั้นเวิร์กโฟลว์ของฉันกลายเป็น (1) ทำงานกับโค้ด (2) ตรวจสอบและเพิ่มลงในดัชนี (3) กระทำ
วิธีการที่ไม่git mvพอดี? หากการย้ายไฟล์โดยตรงจากการใช้git rmและgit addการเปลี่ยนแปลงทั้งหมดจะถูกเพิ่มเข้าไปในดัชนีและการใช้ git diff เพื่อดูการเปลี่ยนแปลงนั้นง่ายกว่า (ก่อนที่จะกระทำ) git mvอย่างไรก็ตามการใช้เพิ่มพา ธ ใหม่ไปยังดัชนี แต่ไม่ได้ทำการเปลี่ยนแปลงกับไฟล์ดังนั้นการอนุญาตgit diffและgit add -pการทำงานตามปกติ
มีกรณีเฉพาะที่git mvยังคงมีประโยชน์มากอยู่: เมื่อคุณต้องการเปลี่ยนปลอกของชื่อไฟล์ในระบบไฟล์แบบไม่คำนึงถึงขนาดตัวพิมพ์ ทั้ง APFS (mac) และ NTFS (windows) โดยค่าเริ่มต้นจะคำนึงถึงขนาดตัวพิมพ์
greg.kindel พูดถึงสิ่งนี้ในความคิดเห็นต่อคำตอบของ CB Bailey
สมมติว่าคุณกำลังทำงานกับ mac และมีไฟล์ที่Mytest.txtจัดการโดย git 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