เขียนประวัติคอมไพล์ใหม่เพื่อแทนที่ CRLF เป็น LF ทั้งหมดหรือไม่


32

ฉันจะถ่ายโอนพื้นที่เก็บข้อมูล Git ส่วนตัวจากกล่อง win32 ไปยัง Ubuntu แม้ว่าฉันจะสามารถทำ dos2unix ขั้นสุดท้ายได้ แต่ฉันต้องการที่จะเขียนประวัติทั้งหมดดังนั้น Git GUI บางอย่างจะแสดง log / diff อย่างถูกต้อง เช่นgitgจะแทรกบรรทัดว่างสำหรับแต่ละ CR / LF

คำตอบ:


25

คุณสามารถใช้git filter-branchสิ่งนั้นพร้อมกับ--tree-filterตัวเลือกและระบุ--allสาขา

นี่คือตัวอย่าง (เริ่มในไดเรกทอรีว่างด้วยไฟล์ข้อความแบบ Unix:

เตรียม:

$ hexdump -C testfile 
00000000  61 0d 0a 62 0d 0a 63 0d  0a                       |a..b..c..|
00000009

$ git init
Initialized empty Git repository in /home/seigneur/tmp/a/.git/

$ git add testfile && git commit -m "dos file checked in"
[master (root-commit) df4970f] dos file checked in
 1 files changed, 3 insertions(+), 0 deletions(-)
 create mode 100644 testfile

คำสั่ง:

$ git filter-branch --tree-filter 'git ls-files -z | xargs -0 dos2unix' -- --all

เอาท์พุท:

Rewrite df4970f63e3196216d5986463f239e51eebb4014 (1/1)dos2unix: converting file testfile to Unix format ...

Ref 'refs/heads/master' was rewritten

$ hexdump -C testfile 
00000000  61 0a 62 0a 63 0a                                 |a.b.c.|
00000006

ผมขอแนะนำให้ทำก่อนการสำรองข้อมูลทั้งหมด การเรียกใช้จากเครื่องลีนุกซ์ของคุณ (ยกเว้นว่าคุณมีการตั้งค่าเชลล์ที่ดีในระบบ Windows) อาจจะง่ายกว่า

แก้ไข: มีการแปลงกลับรายการเป็นครั้งแรก


1
ขอบคุณโพสต์นี้ช่วยฉันได้มาก ฉันมีไฟล์สองสามไฟล์ที่มีช่องว่างในชื่อของพวกเขาการเปลี่ยนแปลงคำสั่งเดิมเล็กน้อยก็แก้ไขได้: git filter-branch --tree-filter 'git ls-files -z | xargs -0 dos2unix' -- --all. ตั้งค่าสถานะ-zและ-0บอกgit ls-filesและxargsเพื่อพิมพ์และตีความnullเมื่อสิ้นสุดบรรทัด
Ivan

ทางเลือกในการสั่ง dos2unix ก็คือการพึ่งพาคอมไพล์ตัวเอง:git filter-branch --prune-empty --tree-filter 'git add --renormalize .' -- --all
Vilmantas Baranauskas

6

คำตอบของมาตตอกประเด็นไว้ที่หัว น่าเสียดายที่ Ubuntu Linux เริ่มต้นด้วยรุ่น 10.04 (Lucid Lynx) คำสั่ง dos2unix / unix2dos ไม่มีให้บริการอีกต่อไปและถูกแทนที่ด้วย fromdos / todos นอกจากนี้ชุดคำสั่งการแปลงทั้งสองชุดมีระดับความไม่รู้ต่าง ๆ กับการมีอยู่ของไฟล์ไบนารีดังนั้นหากพื้นที่เก็บข้อมูลของคุณมีภาพแบบอักษรและอื่น ๆ พวกเขากำลังจะได้รับความเสียหายจากกระบวนการนี้

ฉันสามารถหาวิธีแก้ปัญหาสำหรับปัญหาไฟล์ไบนารีเสียหายที่ใช้คำสั่ง 'ไฟล์' ของ Linux เพื่อระบุและประมวลผลไฟล์ข้อความเท่านั้นที่แสดงด้านล่าง คำสั่งด้านล่างใช้ตัวเลือก --tag-name-filter เพื่อรักษาแท็กที่มีอยู่โดยการย้ายไปยังคอมมิทที่แก้ไขใหม่ นอกจากนี้ยังใช้ - บังคับใช้ธงเพื่อให้แน่ใจว่าคำสั่งจะทำงานในกรณีที่คุณเรียกใช้ tree-filter บนที่เก็บของคุณมาก่อน

git filter-branch --force --tree-filter 'git ls-files | xargs file | sed -n -e "/.*: .*text.*/s/\(.*\): .*/\1/p" | xargs fromdos' --tag-name-filter cat -- --all

3

และไม่มีเครื่องมือเพิ่มเติมใด ๆ (เช่น 'fromdos', 'dos2unix' ฯลฯ ):

git filter-branch --force --tree-filter 'git ls-files | xargs file | sed -n -e "/.*: .*text.*/s/\(.*\): .*/\1/p" | xargs -0 sed -i"" -e "s/"$(printf "\015")"$//"' --tag-name-filter cat -- --all

Crossplatform (OS X, FreeBSD, Linux) แอนะล็อกที่มีประโยชน์ 'fromdos', 'dos2unix':

sed -i'' -e 's/'"$(printf '\015')"'$//'

อาจเป็นประโยชน์ 'unix2dos':

sed -i '' -e 's|$|'"`printf '\015'`"'|' file.name

หากคุณกำลังทำสิ่งที่ไร้ค่าคุณสามารถใช้คำสั่งอินไลน์แบบง่าย ๆ เพื่อลบ "/ r" จากไฟล์ทั้งหมดในไดเรกทอรีปัจจุบัน ".":

find . -type f -exec sed -i'' -e 's/'"$(printf '\015')"'$//' {} \;

1
เปลี่ยน \ r \ n เป็น \ n แทนที่จะลบ \ r เท่านั้น
xdevs23

ฉันคิดว่าsedการขอร้องที่เกี่ยวข้องสามารถถูกแทนที่ด้วยอันที่สั้นกว่า:sed -n -e "s/\(.*\): .*text.*/\1/p"
dma_k
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.