คำสั่ง git เพื่อย้ายโฟลเดอร์ภายในอีก


194

ฉันสร้างโฟลเดอร์ที่commonมีไฟล์และโฟลเดอร์มากมาย

ตอนนี้ฉันต้องการย้ายcommonโฟลเดอร์ไปไว้ในincludeโฟลเดอร์เพื่อให้ดูเหมือนinclude/common

ฉันลองสิ่งเหล่านี้:

  1. git add include

  2. git mv common/ include/

    แต่มันล้มเหลวด้วยข้อผิดพลาดนี้

    ร้ายแรง: แหล่งที่ไม่ดี, แหล่งที่มา = myrepo / common, ปลายทาง = myrepo / include

  3. ฉันพยายามgit mv common/ include/commonแต่ฉันได้รับข้อผิดพลาดเดียวกัน

ความคิดใด ๆ วิธีการบรรลุเป้าหมายนี้?

คำตอบ:


177

หนึ่งในสิ่งที่ดีที่สุดเกี่ยวกับคอมไพล์คือคุณไม่จำเป็นต้องติดตามการเปลี่ยนชื่อไฟล์อย่างชัดเจน Git จะคิดออกโดยการเปรียบเทียบเนื้อหาของไฟล์

ดังนั้นในกรณีของคุณอย่าทำงานหนัก:

$ mkdir include
$ mv common include
$ git rm -r common
$ git add include/common

การวิ่งgit statusควรแสดงบางอย่างเช่นนี้:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    common/file.txt -> include/common/file.txt
#

44
สิ่งนี้ใช้ไม่ได้สำหรับฉัน (ใช้ Windows 7, 1.7.6.msysgit.0) Git คิดว่าไฟล์เก่าถูกลบและมีการเพิ่มไฟล์ใหม่
บาร์ต

อืมบางที git ใช้ยูทิลิตี้ภายนอกเพื่อกำหนดความเหมือนของไฟล์ แต่มันไม่ทำงานบน Windows? นี่เป็นส่วนสำคัญของการใช้งานคอมไพล์
Andres Jaan Tack

13
@OliverF การแก้ไข: git mvเทียบเท่า
Andres Jaan Tack

25
"หนึ่งในสิ่งที่ดีที่สุดเกี่ยวกับคอมไพล์" - หนึ่งในข้อเสียของคุณสมบัติที่ดีนี้คือมันเริ่มต้นล้มเหลวเมื่อคุณแก้ไขไฟล์ที่ถูกเปลี่ยนชื่อในระดับมากซึ่งทำให้มองเห็นการลบและการเพิ่มไฟล์ใหม่ ดังนั้นฉันต้องการเปลี่ยนชื่อสนับสนุนอย่างชัดเจนแทน
Erik Kaplun

2
หาก git แปลงการสิ้นสุดบรรทัดผลลัพธ์ในปัญหาที่อธิบายโดย @Bart เพื่อให้ทำงานได้คุณต้องทำสิ่งต่อไปนี้: git config - global core.autocrlf false
Mariano Dupont

164
 git mv common include

ควรทำงาน.

จากgit mvหน้าคน :

git mv [-f] [-n] [-k] <source> ... <destination directory>

ในรูปแบบที่สองอาร์กิวเมนต์สุดท้ายจะต้องเป็นไดเรกทอรีที่มีอยู่ แหล่งที่มาที่กำหนดจะถูกย้ายไปยังไดเรกทอรีนี้
ดัชนีได้รับการอัปเดตหลังจากเสร็จสมบูรณ์ แต่การเปลี่ยนแปลงจะต้องยังคงมีผลอยู่

ไม่git addควรทำอะไรก่อนย้าย


หมายเหตุ: " git mv A B/", เมื่อBไม่มีอยู่ในไดเรกทอรีควรเกิดข้อผิดพลาด แต่ไม่มีอยู่

ดูคอมมิชชัน c57f628โดยMatthieu Moy (moy )สำหรับGit 1.9 / 2.0 (Q1 2014):

Git ใช้ในการตัดเครื่องหมายสแลชต่อท้ายและทำให้คำสั่งเทียบเท่ากับ ' git mv file no-such-dir' ซึ่งสร้างไฟล์no-such-dir(ในขณะที่สแลชต่อท้ายสแลชระบุอย่างชัดเจนว่ามันอาจเป็นไดเรกทอรีเท่านั้น)

โปรแกรมแก้ไขนี้ข้ามการกำจัดเครื่องหมายสแลชสำหรับเส้นทางปลายทาง
เส้นทางที่มีเครื่องหมายสแลชต่อท้ายจะถูกส่งผ่านไปยังเปลี่ยนชื่อ (2) ซึ่งมีข้อผิดพลาดออกมาพร้อมกับข้อความที่เหมาะสม:

$ git mv file no-such-dir/
fatal: renaming 'file' failed: Not a directory

2
ทำงานอย่างสมบูรณ์แบบ - และการใช้งานgit mvดูเหมือนเป็นวิธีที่ดีกว่ามาก!
Tomas Petricek

23

คำสั่ง:

$ git mv oldFolderName newFolderName

มันมักจะทำงานได้ดี

ข้อผิดพลาด "แหล่งที่มาไม่ดี ... " โดยทั่วไปจะระบุว่าหลังจากการส่งมอบครั้งล่าสุดมีการเปลี่ยนชื่อบางอย่างในไดเรกทอรีต้นทางและด้วยเหตุนี้ git mvไม่สามารถหาไฟล์ที่ต้องการได้

การแก้ปัญหาคือง่าย - git mvเพียงแค่กระทำก่อนที่จะใช้


15

ตรวจสอบให้แน่ใจว่าคุณได้เพิ่มการเปลี่ยนแปลงทั้งหมดของคุณไปยังพื้นที่การแสดงละครก่อนที่จะทำงาน

git mv oldFolderName newFoldername

คอมไพล์ล้มเหลวด้วยข้อผิดพลาด

fatal: bad source, source=oldFolderName/somepath/somefile.foo, destination=newFolderName/somepath/somefile.foo

หากมีไฟล์ใด ๆ ที่ไม่รองรับดังนั้นฉันเพิ่งค้นพบ


"ถ้ามีไฟล์ที่ไม่ได้แนบดังนั้นฉันเพิ่งค้นพบ" - ขอบคุณ!
cacoder

3

อีกวิธีในการย้ายไฟล์ทั้งหมดในไดเรกทอรีไปยังไดเรกทอรีย่อย (เก็บประวัติ git):

$ for file in $(ls | grep -v 'subDir'); do git mv $file subDir; done;


ระวัง: หากมีที่ว่างในโฟลเดอร์ / ชื่อไฟล์สิ่งนี้จะทำให้เกิดปัญหา!
dejoma

3

ฉันมีปัญหาคล้ายกันกับgit mvที่ฉันต้องการย้ายเนื้อหาของโฟลเดอร์หนึ่งไปยังโฟลเดอร์ที่มีอยู่และจบลงด้วยสคริปต์ "ง่าย" นี้:

pushd common; for f in $(git ls-files); do newdir="../include/$(dirname $f)"; mkdir -p $newdir; git mv $f $newdir/$(basename "$f"); done; popd

คำอธิบาย

  • git ls-files: ค้นหาไฟล์ทั้งหมด (ในcommonโฟลเดอร์) ที่ทำเครื่องหมายเป็น git
  • newdir="../include/$(dirname $f)"; mkdir -p $newdir;: สร้างโฟลเดอร์ใหม่ภายในincludeโฟลเดอร์โดยมีโครงสร้างไดเรกทอรีเหมือนกับcommon
  • git mv $f $newdir/$(basename "$f"): ย้ายไฟล์ไปยังโฟลเดอร์ที่สร้างขึ้นใหม่

เหตุผลในการทำเช่นนี้ดูเหมือนว่า git มีปัญหาในการย้ายไฟล์ไปยังโฟลเดอร์ที่มีอยู่และมันจะล้มเหลวเช่นกันหากคุณพยายามย้ายไฟล์ไปยังโฟลเดอร์ที่ไม่มีอยู่ (ด้วยเหตุนี้mkdir -p)

สิ่งที่ดีเกี่ยวกับวิธีการนี้คือเพียงสัมผัสไฟล์ที่ได้รับการตรวจสอบแล้วในคอมไพล์ เพียงแค่ใช้git mvเพื่อย้ายโฟลเดอร์ทั้งหมดและโฟลเดอร์นั้นมีการเปลี่ยนแปลงแบบไม่สเตจ git จะไม่รู้ว่าต้องทำอย่างไร

หลังจากย้ายไฟล์แล้วคุณอาจต้องการล้างพื้นที่เก็บข้อมูลเพื่อลบการเปลี่ยนแปลงที่ยังไม่ได้ดำเนินการใด ๆ ที่เหลือ - เพียงจำไว้ว่าให้รันก่อน

git clean -fd -n

ระวัง: หากมีที่ว่างในโฟลเดอร์ / ชื่อไฟล์สิ่งนี้จะทำให้เกิดปัญหา!
dejoma

2

ฉันขอโทษฉันไม่มีชื่อเสียงพอที่จะแสดงความคิดเห็น "คำตอบ" ของ "Andres Jaan Tack"

ฉันคิดว่า messege ของฉันจะถูกลบ ((แต่ฉันแค่ต้องการเตือน "lurscher" และคนอื่น ๆ ที่มีข้อผิดพลาดเดียวกัน: จงระวังทำ

$ mkdir include
$ mv common include
$ git rm -r common
$ git add include/common

อาจทำให้คุณไม่เห็นประวัติคอมไพล์ของโครงการในโฟลเดอร์ใหม่

ฉันลองแล้ว

$ git mv oldFolderName newFolderName

ได้รับ

fatal: bad source, source=oldFolderName/somepath/__init__.py, dest
ination=ESWProj_Base/ESWProj_DebugControlsMenu/somepath/__init__.py

ฉันทำ

git rm -r oldFolderName

และ

git add newFolderName

และฉันไม่เห็นประวัติคอมไพล์เก่าในโครงการของฉัน อย่างน้อยโครงการของฉันก็จะไม่สูญหาย ตอนนี้ฉันมีโครงการในชื่อโฟลเดอร์ใหม่ แต่ไม่มีประวัติ (

เพียงแค่ต้องการเตือนระวังด้วยการใช้คำแนะนำของ "Andres Jaan Tack" หากคุณไม่ต้องการเสียสติปัญญาของคุณ


ตรวจสอบให้แน่ใจว่าได้เพิ่มการเปลี่ยนแปลงทั้งหมดของคุณแล้ว Git ล้มเหลวในการพูดว่า "แหล่งที่มาไม่ดี" หากมีการเปลี่ยนแปลงที่ไม่ได้ปรับปรุงดังนั้นฉันเพิ่งค้นพบ
Kevin Pluck

0

ฉันมีปัญหาที่คล้ายกัน แต่ในโฟลเดอร์ที่ฉันต้องการย้ายฉันมีไฟล์ที่ไม่ได้ติดตาม

สมมติว่าฉันมีไฟล์

a/file1
a/untracked1
b/file2
b/untracked2

และฉันต้องการย้ายเฉพาะไฟล์ที่ถูกติดตามไปยังโฟลเดอร์ย่อยsubdirดังนั้นเป้าหมายคือ:

subdir/a/file1
subdir/a/untracked1
subdir/b/file2
subdir/b/untracked2

สิ่งที่ฉันทำคือ:

  • ฉันสร้างโฟลเดอร์ใหม่และย้ายไฟล์ทั้งหมดที่ฉันต้องการย้าย: mkdir tmpdir && mv a b tmpdir
  • ตรวจสอบไฟล์เก่า git checkout a b
  • สร้าง dir ใหม่และย้ายโฟลเดอร์ที่สะอาด (ไม่มีไฟล์ที่ไม่ได้ติดตาม) ไปยัง subdir ใหม่: mkdir subdir && mv a b subdir
  • เพิ่มไฟล์ทั้งหมดจาก subdir (ดังนั้น Git สามารถเพิ่มเฉพาะไฟล์ที่ติดตามก่อนหน้านี้ - มันเป็นบางส่วนของที่git add --updateมีเคล็ดลับการเปลี่ยนไดเรกทอรี): git add subdir(โดยปกตินี้จะเพิ่มแม้ไฟล์ที่ไม่ได้ติดตาม - นี้จะต้องสร้าง.gitignoreไฟล์)
  • git status แสดงตอนนี้เฉพาะไฟล์ที่ถูกย้าย
  • ย้ายไฟล์ที่เหลือจาก tmpdir ไปที่ subdir: mv tmpdir/* subdir
  • git statusดูเหมือนว่าเราดำเนินการgit mv:)

-1

ฉันแก้ไขมันใน windows โดยทำสิ่งนี้:

  • เปิดคอนโซล Power shell
  • วิ่ง dir
  • คลิก Alt และลากบนคอลัมน์ชื่อไฟล์ / โฟลเดอร์แล้วคัดลอก
  • วางเพื่อ notepad ++
  • เรียกใช้แทนที่ด้วย regex: แทนที่ (.*)ด้วยgit mv ".\\\1" ".\\<New_Folder_Here>\"
  • คัดลอกข้อความทั้งหมดจาก notepad ++ ไปยัง powershell
  • กด Enter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.