วิธีการทำเครื่องหมายคอมไพล์ลบและไฟล์ใหม่เป็นไฟล์ย้าย?


505

ฉันย้ายไฟล์ด้วยตนเองแล้วฉันจะแก้ไขมัน ตาม Git มันเป็นไฟล์ใหม่และไฟล์ที่ลบ มีวิธีใดที่จะบังคับให้ Git จัดการกับไฟล์ดังกล่าวได้หรือไม่?


3
สำหรับไฟล์ที่กำหนดold_file.txtแล้วgit mv old_file.txt new_file.txtจะเทียบเท่ากับgit rm --cached old_file.txt, ,mv old_file.txt new_file.txt git add new_file.txt
Jarl

3
Jarl: ไม่หรอก หากมีการเปลี่ยนแปลงภายในไฟล์git mvจะไม่เพิ่มลงในแคช แต่git addจะ ฉันต้องการย้ายไฟล์กลับเพื่อให้สามารถใช้งานgit mvได้แล้วgit add -pเพื่อตรวจสอบชุดการเปลี่ยนแปลงของฉัน
dhardy

โปรดชำระเงินสคริปต์ของฉันgithub.com/Deathangel908/python-tricks/blob/master/…
deathangel908


Git ได้รับการปรับปรุงในช่วง 8 ปีที่ผ่านมาหากเป็นเพียงไฟล์เดียวคำตอบยอดเยี่ยมstackoverflow.com/a/433142/459ไม่ได้ทำอะไรเลย… แต่คุณสามารถติดตามstackoverflow.com/a/1541072/459เพื่อรับการปรับปรุง / ปรับปรุง เป็น mv / แก้ไขสถานะ
dlamblin

คำตอบ:


435

Git จะตรวจจับการย้าย / เปลี่ยนชื่อโดยอัตโนมัติหากการดัดแปลงของคุณไม่รุนแรงเกินไป เพียงgit addไฟล์ใหม่และgit rmไฟล์เก่า git statusจะแสดงว่าตรวจพบการเปลี่ยนชื่อหรือไม่

นอกจากนี้สำหรับการย้ายไปรอบ ๆ ไดเรกทอรีคุณอาจต้อง:

  1. cd ไปที่ด้านบนของโครงสร้างไดเรกทอรีนั้น
  2. วิ่ง git add -A .
  3. เรียกใช้git statusเพื่อตรวจสอบว่า "ไฟล์ใหม่" เป็นไฟล์ "เปลี่ยนชื่อ" แล้ว

หากสถานะ git ยังคงแสดง "ไฟล์ใหม่" และไม่ใช่ "เปลี่ยนชื่อ" คุณจะต้องทำตามคำแนะนำของแฮงค์เกย์และทำการย้ายและแก้ไขในสองคอมมิชชันแยกกัน


75
การชี้แจง: 'ไม่รุนแรงเกินไป' หมายความว่าไฟล์ใหม่และไฟล์เก่านั้นมีค่า> 50% 'ที่คล้ายกัน' ขึ้นอยู่กับดัชนีความคล้ายคลึงกันที่ git ใช้
pjz

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

19
เป็นมูลค่าการกล่าวขวัญว่าเมื่อพูดถึง " Git จะตรวจจับการย้าย / เปลี่ยนชื่อโดยอัตโนมัติ " มันไม่ได้ในเวลาที่คุณใช้git status, git logหรือgit diff, ไม่ได้ในเวลาที่คุณทำgit add, หรือgit mv git rmการพูดเพิ่มเติมเกี่ยวกับการตรวจจับการเปลี่ยนชื่อนั้นเหมาะสมสำหรับไฟล์ staged เท่านั้น ดังนั้นgit mvตามด้วยการเปลี่ยนแปลงในไฟล์อาจดูgit statusราวกับว่ามันคิดว่าเป็นrenameแต่เมื่อคุณใช้git stage(เหมือนgit add) บนไฟล์มันจะกลายเป็นที่ชัดเจนว่าการเปลี่ยนแปลงมีขนาดใหญ่เกินไปที่จะตรวจพบว่าเปลี่ยนชื่อ
Jarl

5
คีย์จริงดูเหมือนว่าจะเพิ่มทั้งตำแหน่งใหม่และเก่าในแบบเดียวกันgit addซึ่งตามที่ @ jrhorn424 แนะนำอาจเป็นเพียง repo ทั้งหมดในครั้งเดียว
ไบรอัน

4
สิ่งนี้ไม่ผิดพลาดโดยเฉพาะอย่างยิ่งหากไฟล์มีการเปลี่ยนแปลงและมีขนาดเล็ก มีวิธีการบอกคอมไพล์เกี่ยวกับการย้ายโดยเฉพาะหรือไม่?
Rebs

112

ทำการเคลื่อนย้ายและการแก้ไขในกระทำแยกต่างหาก


12
ฉันเข้าใจว่า Git สามารถจัดการการเคลื่อนไหวและการปรับเปลี่ยนได้ในเวลาเดียวกัน เมื่อการเขียนโปรแกรมใน Java และใช้ IDE การเปลี่ยนชื่อคลาสเป็นการดัดแปลงและการย้าย ฉันเข้าใจว่า Git แม้จะสามารถคิดออกได้โดยอัตโนมัติเมื่อมีการเคลื่อนไหว (จากการลบและการสร้าง)
pupeno

1
Perl ต้องการสิ่งนี้เช่นกันและฉันไม่เคยมี Git ตรวจพบการย้าย / เปลี่ยนชื่อ
jrockway

10
@ ร็อคเวย์ฉันมี เกิดขึ้นกับไฟล์ขนาดเล็กได้อย่างง่ายดายฉันคิดว่าพวกเขา "กลายเป็น 'แตกต่าง' เกินไปที่จะหมายถึงการย้าย"
Aneves

2
มีวิธีใดที่จะทำสิ่งนี้โดยอัตโนมัติหรือไม่? ฉันมีไฟล์จำนวนมากในดัชนีต้องการที่จะยอมรับการย้ายและจากนั้นการเปลี่ยนแปลง แต่มันยากที่จะทำด้วยตนเอง
ReDetection

5
สิ่งหนึ่งที่ควรทราบคือถ้าgit diffไม่รู้จักการเปลี่ยนชื่อในการคอมมิชชันหนึ่งการคอมมิทนั้นจะไม่รับรู้ในการคอมมิทสองครั้ง คุณจะต้องใช้-Mอาคา--find-renamesเพื่อทำเช่นนั้น ดังนั้นหากแรงจูงใจที่นำคุณมาสู่คำถามนี้คือการเห็นการเปลี่ยนชื่อในคำขอดึง (พูดจากประสบการณ์) การแยกมันออกเป็นสองคอมมิชชันจะไม่ทำให้คุณไปสู่เป้าหมายนั้นอีก
mattliu

44

มันคือทั้งหมดที่รับรู้ โดยทั่วไป Git นั้นค่อนข้างดีในการจดจำการเคลื่อนไหวเนื่องจากGITเป็นเครื่องมือติดตามเนื้อหา

ทั้งหมดนั้นขึ้นอยู่กับว่า "สถิติ" ของคุณแสดงไว้อย่างไร ข้อแตกต่างที่นี่คือแฟล็ก -M

บันทึก git --stat -M

commit 9c034a76d394352134ee2f4ede8a209ebec96288
Author: Kent Fredric
Date:   Fri Jan 9 22:13:51 2009 +1300


        Category Restructure

     lib/Gentoo/Repository.pm                |   10 +++++-----
     lib/Gentoo/{ => Repository}/Base.pm     |    2 +-
     lib/Gentoo/{ => Repository}/Category.pm |   12 ++++++------
     lib/Gentoo/{ => Repository}/Package.pm  |   10 +++++-----
     lib/Gentoo/{ => Repository}/Types.pm    |   10 +++++-----
     5 files changed, 22 insertions(+), 22 deletions(-)

git log --stat

commit 9c034a76d394352134ee2f4ede8a209ebec96288
Author: Kent Fredric
Date:   Fri Jan 9 22:13:51 2009 +1300

    Category Restructure

 lib/Gentoo/Base.pm                |   36 ------------------------
 lib/Gentoo/Category.pm            |   51 ----------------------------------
 lib/Gentoo/Package.pm             |   41 ---------------------------
 lib/Gentoo/Repository.pm          |   10 +++---
 lib/Gentoo/Repository/Base.pm     |   36 ++++++++++++++++++++++++
 lib/Gentoo/Repository/Category.pm |   51 ++++++++++++++++++++++++++++++++++
 lib/Gentoo/Repository/Package.pm  |   41 +++++++++++++++++++++++++++
 lib/Gentoo/Repository/Types.pm    |   55 +++++++++++++++++++++++++++++++++++++
 lib/Gentoo/Types.pm               |   55 -------------------------------------
 9 files changed, 188 insertions(+), 188 deletions(-)

คอมไพล์บันทึกความช่วยเหลือ

   -M
       Detect renames.

   -C
       Detect copies as well as renames. See also --find-copies-harder.

76
ขออภัยถ้ามันดูค่อนข้างเชื่องช้า แต่ "โดยทั่วไป Git ค่อนข้างดีในการจดจำการเคลื่อนไหวเนื่องจาก GIT เป็นตัวติดตามเนื้อหา" ดูเหมือนว่าจะไม่ใช่ตัวฉัน มันเป็นตัวติดตามเนื้อหาใช่และบางทีมันอาจจะดีในการตรวจจับการเคลื่อนไหว แต่คำสั่งเดียวไม่ได้ติดตามกันเลย เพียงเพราะมันเป็นเครื่องติดตามเนื้อหาการตรวจจับการเคลื่อนไหวไม่จำเป็นต้องดี อันที่จริงแล้วตัวติดตามเนื้อหาไม่สามารถตรวจจับการเคลื่อนไหวได้เลย
Laurence Gonsalves

1
@WarrenSeine เมื่อคุณเปลี่ยนชื่อไดเรกทอรี SHA1 ของไฟล์ในไดเรกทอรีนั้นจะไม่เปลี่ยนแปลง สิ่งที่คุณมีคือวัตถุ TREE ใหม่ที่มี SHA1 เดียวกัน ไม่มีเหตุผลที่การเปลี่ยนชื่อไดเรกทอรีจะทำให้เกิดการเปลี่ยนแปลงข้อมูลที่สำคัญ
Kent Fredric

1
@KentFredric คุณแสดงให้เห็นว่าการใช้ -M กับ "git log" เราสามารถตรวจสอบว่าไฟล์ถูกเปลี่ยนชื่อหรือไม่และฉันลองและทำงานได้ดี แต่เมื่อฉันโพสต์รหัสของฉันเพื่อตรวจสอบและดูไฟล์นั้นใน gerrit ( gerritcodereview.com ) มันแสดงให้เห็นว่าไฟล์จะถูกเพิ่มใหม่และก่อนหน้านี้ถูกลบ ดังนั้นจะมีตัวเลือกใน "git กระทำ" โดยใช้ที่ฉันจะกระทำและ gerrit แสดงอย่างถูกต้อง
Patrick

1
ไม่ฉันไม่ได้แสดงอะไรเลย ฉันพบ Git เป็นความสามารถในการทำท่าเป็น add + Delete เป็นเปลี่ยนชื่อเนื่องจากมีเนื้อหาที่เป็นแบบเดียวกัน ไม่มีทางที่จะรู้ว่าเกิดอะไรขึ้นและมันก็ไม่สนใจ การจำคอมไพล์ทั้งหมดคือ "เพิ่ม" และ "ลบแล้ว" "Renamed" จะไม่ถูกบันทึก
Kent Fredric

1
ตัวอย่างเช่นฉันทำ "คัดลอก + แก้ไข" จำนวนมากเมื่อเร็ว ๆ นี้ วิธีการดูส่วนใหญ่จะเห็นเฉพาะ "ไฟล์ใหม่" แต่ถ้าคุณผ่านgit log -M1 -C1 -B1 -D --find-copies-harderGit สามารถ "ค้นหา" ว่าไฟล์ใหม่อาจถูกคัดลอกมาก่อน บางครั้งมันทำถูกต้องในบางครั้งก็พบว่าไฟล์ที่ไม่เกี่ยวข้องทั้งหมดที่เกิดขึ้นมีเนื้อหาเหมือนกัน
Kent Fredric

36

git diff -Mหรือgit log -Mควรตรวจจับการเปลี่ยนแปลงดังกล่าวโดยอัตโนมัติเช่นเปลี่ยนชื่อด้วยการเปลี่ยนแปลงเล็กน้อยตราบเท่าที่พวกเขาเป็นจริง หากการเปลี่ยนแปลงเล็กน้อยของคุณไม่ได้เล็กน้อยคุณสามารถลดความคล้ายคลึง threashold ที่คล้ายคลึงกันเช่น

$ git log -M20 -p --stat

เพื่อลดจากค่าเริ่มต้น 50% เป็น 20%


13
เป็นไปได้หรือไม่ที่จะกำหนดเกณฑ์ในการกำหนดค่า?
ReDetection

34

นี่เป็นวิธีที่รวดเร็วและสกปรกสำหรับไฟล์หนึ่งหรือสองสามไฟล์ที่ถูกเปลี่ยนชื่อและแก้ไขซึ่งไม่มีข้อผูกมัด

สมมติว่าไฟล์นั้นมีชื่อfooแล้วและตอนนี้ก็ตั้งชื่อbar:

  1. เปลี่ยนชื่อbarเป็นชื่อชั่วคราว:

    mv bar side
    
  2. ชำระเงินfoo:

    git checkout HEAD foo
    
  3. เปลี่ยนชื่อfooเป็นbarGit:

    git mv foo bar
    
  4. barตอนนี้เปลี่ยนชื่อไฟล์กลับชั่วคราวของคุณจะ

    mv side bar
    

ขั้นตอนสุดท้ายคือสิ่งที่ทำให้เนื้อหาที่คุณเปลี่ยนแปลงกลับเข้าสู่ไฟล์

ขณะนี้สามารถใช้งานได้หากไฟล์ที่ย้ายแตกต่างจากเนื้อหาจากคอมไพล์ดั้งเดิมจะพิจารณาว่ามีประสิทธิภาพมากขึ้นในการตัดสินใจว่านี่เป็นวัตถุใหม่ ให้ฉันสาธิต:

$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    renamed:    README -> README.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README.md
    modified:   work.js

$ git add README.md work.js # why are the changes unstaged, let's add them.
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    deleted:    README
    new file:   README.md
    modified:   work.js

$ git stash # what? let's go back a bit
Saved working directory and index state WIP on dir: f7a8685 update
HEAD is now at f7a8685 update
$ git status
On branch workit
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    .idea/

nothing added to commit but untracked files present (use "git add" to track)
$ git stash pop
Removing README
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    new file:   README.md

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)

    deleted:    README
    modified:   work.js

Dropped refs/stash@{0} (1ebca3b02e454a400b9fb834ed473c912a00cd2f)
$ git add work.js
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    new file:   README.md
    modified:   work.js

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)

    deleted:    README

$ git add README # hang on, I want it removed
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    deleted:    README
    new file:   README.md
    modified:   work.js

$ mv README.md Rmd # Still? Try the answer I found.
$ git checkout README
error: pathspec 'README' did not match any file(s) known to git.
$ git checkout HEAD README # Ok the answer needed fixing.
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    new file:   README.md
    modified:   work.js

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)

    deleted:    README.md
    modified:   work.js

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    Rmd

$ git mv README README.md
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    renamed:    README -> README.md
    modified:   work.js

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   work.js

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    Rmd

$ mv Rmd README.md
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    renamed:    README -> README.md
    modified:   work.js

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README.md
    modified:   work.js

$ # actually that's half of what I wanted; \
  # and the js being modified twice? Git prefers it in this case.

27
กระบวนการนี้ไม่มีวัตถุประสงค์ git ไม่ได้เพิ่มข้อมูลเมตาใด ๆ สำหรับการเปลี่ยนชื่อgit mvเป็นเพียงความสะดวกสบายสำหรับgit rm/ git addคู่ หากคุณได้ทำ 'mv bar foo' เรียบร้อยแล้วสิ่งที่คุณต้องทำคือตรวจสอบให้แน่ใจว่าคุณgit add fooและgit rm barก่อนที่จะลงมือทำ สิ่งนี้สามารถทำได้เช่นเดียวกับgit add -Aคำสั่งเดียวหรืออาจเป็นgit add foo; git commit -aลำดับ
CB Bailey

17
สิ่งที่ฉันรู้ก็คือก่อนที่ฉันจะทำมัน Git ไม่รู้จักเป็นการเคลื่อนไหว หลังจากที่ฉันทำสิ่งนี้ Git ก็จำได้ว่ามันเป็นการเคลื่อนไหว

8
มันจดจำได้ว่าเป็นการเคลื่อนไหว แต่มันก็มีการเปลี่ยนแปลงเหมือนเป็นการเปลี่ยนแปลงแบบไม่สเตจในตอนนี้ เมื่อคุณaddไฟล์อีกครั้งคอมไพล์แบ่งการย้าย / แก้ไขเป็นลบ / เพิ่มอีกครั้ง
Michael Piefel

4
กระบวนการนี้จะทำงานหากคุณgit commitหลังจากขั้นตอนที่ 3 มิฉะนั้นจะไม่ถูกต้อง นอกจากนี้ @CharlesBailey ถูกต้องคุณสามารถทำmv blah fooขั้นตอนปกติได้อย่างง่ายดายในขั้นตอนที่ 3 ตามด้วยการคอมมิทและรับผลลัพธ์เดียวกัน
DaFlame

5
"กระบวนการนี้ไม่มีจุดประสงค์" - มีวัตถุประสงค์เมื่อ git สับสนและคิดว่าไฟล์ถูกลบไปแล้วและมีการเพิ่มไฟล์อื่น วิธีนี้จะช่วยลดความสับสนของ Git และทำเครื่องหมายไฟล์ว่าถูกย้ายอย่างชัดเจนโดยไม่ต้องทำคอมมิทระดับกลาง
Danack


11

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

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

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

คำถามเดียวกันนี้เกิดขึ้นที่นี่: https://tortoisegit.org/issue/1389และได้รับการบันทึกเป็นข้อบกพร่องในการแก้ไขที่นี่: https://tortoisegit.org/issue/1440 ปรากฎว่าเป็นปัญหาการแสดงผลที่มีการกระทำของ TortoiseGit ไดอะล็อกและประเภทของการมีอยู่ในสถานะ git หากคุณยังไม่ได้เพิ่มไฟล์ใหม่


2
คุณถูกต้องแม้ว่า TortoiseGit จะแสดงการลบ + เพิ่มแม้ว่าสถานะ git จะแสดงการลบ + เพิ่มแม้ว่า git กระทำ --dry-run แสดงการลบ + เพิ่มหลังจากคอมไพล์ฉันเห็นฉันเปลี่ยนชื่อและไม่ลบ + เพิ่ม
โทมัสคุเบช

1
ผมค่อนข้างมั่นใจว่าการตรวจสอบการเปลี่ยนชื่อโดยอัตโนมัติเกิดขึ้นในระหว่างการดึงประวัติศาสตร์ ; ในการคอมมิชชันมันจะเพิ่ม + ลบเสมอ นั่นยังอธิบายถึงพฤติกรรมของโรคจิตเภทที่คุณอธิบาย ดังนั้นตัวเลือกที่นี่: stackoverflow.com/a/434078/155892
Mark Sowul

10

หรือคุณอยากลองตอบคำถามนี้ที่นี่โดยอำพัน ! หากต้องการอ้างถึงอีกครั้ง:

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

$ git reset path/to/newfile
$ mv path/to/newfile path/to/oldfile

จากนั้นใช้ Git เพื่อย้ายไฟล์:

$ git mv path/to/oldfile path/to/newfile

แน่นอนว่าถ้าคุณยอมรับการย้ายแบบแมนนวลคุณอาจต้องการรีเซ็ตเป็นการแก้ไขก่อนที่จะย้ายแทนและจากนั้นเพียงแค่คอมไพล์ mv จากที่นั่น


7

ใช้git mvคำสั่งเพื่อย้ายไฟล์แทนคำสั่งการย้าย OS: https://git-scm.com/docs/git-mv

โปรดทราบว่าgit mvคำสั่งนั้นมีอยู่ใน Git เวอร์ชัน 1.8.5 ขึ้นไปเท่านั้น ดังนั้นคุณอาจต้องอัพเดต Git ของคุณเพื่อใช้คำสั่งนี้


3

ฉันมีปัญหานี้เมื่อเร็ว ๆ นี้เมื่อมีการย้าย (แต่ไม่ได้แก้ไข) บางไฟล์

ปัญหาคือ Git เปลี่ยนจุดสิ้นสุดบรรทัดเมื่อฉันย้ายไฟล์และไม่สามารถบอกได้ว่าไฟล์เหมือนกัน

ใช้git mvแยกออกปัญหา แต่ใช้งานได้กับไฟล์ / ไดเรกทอรีเดียวและฉันมีไฟล์จำนวนมากในรูทของพื้นที่เก็บข้อมูลที่ต้องทำ

วิธีหนึ่งในการแก้ไขปัญหานี้จะเป็นกับ bash / magic batch

อีกวิธีคือ

  • ย้ายไฟล์และ git commitย้ายไฟล์และสิ่งนี้อัพเดตจุดสิ้นสุดบรรทัด
  • ย้ายไฟล์กลับไปที่ตำแหน่งเดิมขณะนี้พวกเขามีจุดสิ้นสุดบรรทัดใหม่และ git commit --amend
  • git commit --amendย้ายไฟล์อีกครั้งและ ไม่มีการเปลี่ยนแปลงในตอนท้ายของบรรทัดในครั้งนี้ดังนั้น Git จึงมีความสุข

1

สำหรับฉันมันทำงานเพื่อสะสมบันทึกการเปลี่ยนแปลงทั้งหมดก่อนที่จะกระทำและ pop พวกเขาออกมาอีกครั้ง สิ่งนี้ทำให้คอมไพล์วิเคราะห์ไฟล์ที่เพิ่ม / ลบใหม่และทำเครื่องหมายว่าถูกย้ายอย่างถูกต้อง


0

อาจมีวิธี "command line" ที่ดีกว่าในการทำเช่นนี้และฉันรู้ว่านี่คือการแฮ็ก แต่ฉันไม่เคยพบทางออกที่ดีเลย

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

  1. ตรวจสอบสิ่งที่คุณทำในพื้นที่
  2. ตรวจสอบการเปลี่ยนแปลงขนาดเล็กหนึ่งบรรทัดในการส่งครั้งที่ 2
  3. ไปที่ GIT log ในคอมไพล์เต่า
  4. เลือกคอมมิททั้งสองคลิกขวาแล้วเลือก“ รวมเป็นคอมมิตเดียว”

การคอมมิทใหม่จะแสดงการเปลี่ยนชื่อไฟล์อย่างถูกต้อง…ซึ่งจะช่วยรักษาประวัติไฟล์ที่เหมาะสม


0

เมื่อฉันแก้ไขเปลี่ยนชื่อและย้ายไฟล์ในเวลาเดียวกันโซลูชันเหล่านี้ไม่ทำงาน การแก้ปัญหาคือการทำมันในสองกระทำ (แก้ไขและเปลี่ยนชื่อ / ย้ายแยก) จากนั้นfixupสองกระทำผ่านที่git rebase -iจะมีในหนึ่งกระทำ


0

วิธีที่ฉันเข้าใจคำถามนี้คือ "วิธีทำให้ git รู้จักการลบไฟล์เก่าและการสร้างไฟล์ใหม่เป็นการย้ายไฟล์"

ใช่ในไดเรกทอรีทำงานเมื่อคุณลบไฟล์เก่าและแทรกไฟล์เก่าgit statusจะพูดว่า " deleted: old_file" และ " Untracked files: ... new_file"

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

git add new_file
git rm old_file

หากเนื้อหาของไฟล์มีความคล้ายคลึงกัน 50% หรือมากกว่านั้นการรันgit statusคำสั่งควรให้คุณ:

renamed: old_file -> new_file

1
git statusจะพูดว่า " deleted: old_file" และ " Untracked files: ... new_file": ไม่ตั้งแต่ Git 2.18: stackoverflow.com/a/50573107/6309
VonC
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.