ฉันจะถ่ายโอนพื้นที่เก็บข้อมูล Git ส่วนตัวจากกล่อง win32 ไปยัง Ubuntu แม้ว่าฉันจะสามารถทำ dos2unix ขั้นสุดท้ายได้ แต่ฉันต้องการที่จะเขียนประวัติทั้งหมดดังนั้น Git GUI บางอย่างจะแสดง log / diff อย่างถูกต้อง เช่นgitgจะแทรกบรรทัดว่างสำหรับแต่ละ CR / LF
ฉันจะถ่ายโอนพื้นที่เก็บข้อมูล Git ส่วนตัวจากกล่อง win32 ไปยัง Ubuntu แม้ว่าฉันจะสามารถทำ dos2unix ขั้นสุดท้ายได้ แต่ฉันต้องการที่จะเขียนประวัติทั้งหมดดังนั้น Git GUI บางอย่างจะแสดง log / diff อย่างถูกต้อง เช่นgitgจะแทรกบรรทัดว่างสำหรับแต่ละ CR / LF
คำตอบ:
คุณสามารถใช้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) อาจจะง่ายกว่า
แก้ไข: มีการแปลงกลับรายการเป็นครั้งแรก
git filter-branch --prune-empty --tree-filter 'git add --renormalize .' -- --all
คำตอบของมาตตอกประเด็นไว้ที่หัว น่าเสียดายที่ 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
และไม่มีเครื่องมือเพิ่มเติมใด ๆ (เช่น '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')"'$//' {} \;
sed
การขอร้องที่เกี่ยวข้องสามารถถูกแทนที่ด้วยอันที่สั้นกว่า:sed -n -e "s/\(.*\): .*text.*/\1/p"
git filter-branch --tree-filter 'git ls-files -z | xargs -0 dos2unix' -- --all
. ตั้งค่าสถานะ-z
และ-0
บอกgit ls-files
และxargs
เพื่อพิมพ์และตีความnull
เมื่อสิ้นสุดบรรทัด