สถานะ Git ละเว้นการสิ้นสุดบรรทัด / ไฟล์ที่เหมือนกัน / สภาพแวดล้อม windows & linux / dropbox / mled


113

ฉันจะทำอย่างไร

สถานะคอมไพล์

ไม่สนใจความแตกต่างของการสิ้นสุดบรรทัด?

ข้อมูลเบื้องหลัง:

ฉันใช้ Windows และ Linux แบบสุ่มเพื่อทำงานในโครงการ โครงการอยู่ใน Dropbox

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

ดังนั้นฉันจะหลีกเลี่ยงสิ่งนี้ได้อย่างไร Git ควรเปิด meld สำหรับไฟล์ที่เปลี่ยนแปลงเท่านั้น และสถานะ git ไม่ควรรายงานไฟล์ว่ามีการเปลี่ยนแปลงหากมีเพียงส่วนท้ายของไฟล์ที่แตกต่างกัน

แก้ไข: สาเหตุ:

สิ่งนี้เกิดขึ้นเนื่องจากการตั้งค่านี้ใน Windows

core.autocrlf จริง

ดังนั้นฉันจึงตรวจสอบสำเนาที่ใช้งานได้บน Linux และตั้งค่า core.autocrlf false บน Windows

คงจะดีไม่น้อยหากทราบวิธีทำให้สถานะคอมไพล์ไม่สนใจบรรทัดใหม่ที่แตกต่างกัน


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

mind you: stackoverflow.com/questions/2825428/… - อาจช่วยได้บ้าง
Petesh

ฉันพบว่ามันทำงานได้ดีกับ Dropbox อย่างไร: โดยการตั้งค่า core.autocrlf false
Thorsten Niehues

3
AFAIK บอกให้คอมไพล์จัดการไฟล์เป็นไบนารีก็มีผลข้างเคียงจากการเปลี่ยนวิธีที่แตกต่างของไฟล์ วิธีแก้ปัญหาที่เหมาะสมคือบอกให้คอมไพล์ละเว้นการลงท้ายบรรทัด 2 สิ่งที่ฉันชอบน้อยที่สุด: การจัดการกับปัญหาการสิ้นสุดบรรทัดและ FUD ที่ไม่จำเป็นเกี่ยวกับวิธีที่ผู้คนตั้งค่า repos ของพวกเขา :)
ChrisM

ว้าวฉันใช้เวลาสักพักสำหรับปัญหานี้core.autocrlfเป็นสาเหตุหลักของ Windows แต่ยังแก้ปัญหาบน Linux ได้ด้วย ปัญหาคือเกิดขึ้นautocrlfทั่วโลกใน Windows และ repo ไม่มีการตั้งค่า.git/configนั้น โดยการเรียกใช้โลคัลgit config core.autocrlf trueฉันได้กำจัดการเปลี่ยนแปลงปลอมในสำเนาการทำงาน NTFS ของฉันที่โคลนบน Windows แต่เข้าถึงได้บน Linux (ตอนนี้มีการเปลี่ยนแปลงปลอม ๆ เท่านั้นกับ symlinks - NTFS symlinks DO WORK บน fuseblk mounts แต่ Git เห็นว่ามีการแก้ไข ... )
Tomasz Gandor

คำตอบ:


105

ลองตั้งค่า core.autocrlf ดังนี้:

git config --global core.autocrlf true

7
@ThorstenNiehues ฉันใช้การตั้งค่านั้นในโครงการงานบางอย่าง ในการทำงานฉันต้องใช้ windows ที่บ้านฉันใช้ mac และ linux ก่อนหน้านี้ฉันมีปัญหาเดียวกับคุณหลังจากนั้นการตั้งค่าทุกอย่างก็โอเค
SašaŠijak

1
เป็นเรื่องแปลกเพราะการชำระเงินบน windows มี \ r \ n การสิ้นสุดบรรทัดบน Linux เท่านั้น \ n คุณมีสำเนาที่ใช้งานได้ทั้งใน Dropbox (หรือคล้ายกัน) หรือไม่?
Thorsten Niehues

1
@ThorstenNiehues ไม่ git repository อยู่ใน github อืมบางทีดรอปบ็อกซ์อาจกำลังคาดเดากับการสิ้นสุดบรรทัดเมื่อซิงค์ไฟล์? ดูเหมือนจะแปลกที่จะใช้ดรอปบ็อกซ์สำหรับคอมไพล์ ลองใช้ bitbucket (มีที่เก็บส่วนตัวฟรี) เพียงสร้าง repo ขนาดเล็กและทดสอบบนเครื่อง 2 เครื่องของคุณด้วยไฟล์ข้อความขนาดเล็ก
SašaŠijak

1
1. สำเนาที่ใช้งานได้และพื้นที่เก็บข้อมูลในเครื่องอยู่ใน Dropbox (ฉันไม่ต้องการที่เก็บสาธารณะ) นั่นอาจเป็นความแตกต่าง
Thorsten Niehues

3
ใน Windows: core.autocrlf trueเป็นการตั้งค่าการทำงานใน CygWin core.safecrlf falseเป็นการตั้งค่าการทำงานใน git bash หรือ mingw
DrumM

43

ใช้. gitattributes แทนด้วยการตั้งค่าต่อไปนี้:

# Ignore all differences in line endings
*        -crlf

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


มันใช้ได้ผลสำหรับฉันในสตรีมเดียว แต่เมื่อฉันพยายามสร้างในสตรีมอื่นสำหรับโปรเจ็กต์เดียวกันก็ยังคงแสดงความแตกต่างของ Newline
pfernandom

1
@pfernandom คุณอาจมี. gitattributes หลายรายการในโครงการของคุณหรือไม่? มันจะดูเวอร์ชัน "โลคัล" ส่วนใหญ่ก่อนดังนั้นหากคุณมีไฟล์อยู่ในโลคัลไดเร็กทอรีที่มีไฟล์อยู่ไฟล์นั้นจะใช้เวอร์ชันนั้นกับโปรเจ็กต์ของคุณ
Trashman

จำเป็นต้องมี 8 ช่องว่างก่อน -crlf หรือไม่?
Igonato

ไม่ควรสำคัญ
Trashman

git statusนี้ไม่มากกว่าเพียงแค่ไม่สนใจตอนจบบรรทัดสำหรับ มันเปลี่ยนวิธีการตรวจสอบไฟล์ในที่เก็บ อ้างอิง: git-scm.com/docs/gitattributes#_code_text_code
Vince

31

คำตอบนี้ดูเหมือนจะเกี่ยวข้องเนื่องจาก OP อ้างถึงความต้องการโซลูชันหลายระบบปฏิบัติการ บทความช่วยเหลือ Github นี้ให้รายละเอียดเกี่ยวกับแนวทางที่ใช้ได้สำหรับการจัดการบรรทัดที่ลงท้ายข้ามระบบปฏิบัติการ มีวิธีการทั่วโลกและต่อ repo ในการจัดการการสิ้นสุดบรรทัดข้ามระบบปฏิบัติการ

แนวทางระดับโลก

กำหนดค่าการจัดการการสิ้นสุดบรรทัด Git บน Linux หรือ OS X:

git config --global core.autocrlf input

กำหนดค่าการจัดการการสิ้นสุดบรรทัด Git บน Windows:

git config --global core.autocrlf true

แนวทางต่อ repo:

ในรากของ repo ของคุณสร้าง.gitattributesไฟล์และกำหนดการตั้งค่าบรรทัดสิ้นสุดลงสำหรับไฟล์โครงการของคุณหนึ่งบรรทัดในเวลาในรูปแบบต่อไปนี้: path_regex line-ending-settingsที่line-ending-settingsเป็นหนึ่งต่อไปนี้:

  • ข้อความ
  • ไบนารี (ไฟล์ที่ Git ไม่ควรแก้ไขส่วนท้ายบรรทัดเนื่องจากอาจทำให้รูปภาพบางประเภทเช่น PNG ไม่แสดงผลในเบราว์เซอร์)

textค่าสามารถกำหนดค่าต่อการออกคำสั่ง Git เกี่ยวกับวิธีการจัดการกับปลายสายสำหรับไฟล์ที่ตรงกับ:

  • text - เปลี่ยนการสิ้นสุดบรรทัดเป็นการสิ้นสุดบรรทัดเนทีฟของ OS
  • text eol=crlf- แปลงการสิ้นสุดบรรทัดเป็นCRLFเมื่อชำระเงิน
  • text eol=lf- แปลงการสิ้นสุดบรรทัดเป็นLFเมื่อชำระเงิน
  • text=auto - ค่าเริ่มต้นที่สมเหตุสมผลซึ่งปล่อยให้บรรทัดจัดการตามดุลยพินิจของ Git

นี่คือเนื้อหาของไฟล์. gitattributes ตัวอย่าง:

# Set the default behavior for all files.
* text=auto

# Normalized and converts to 
# native line endings on checkout.
*.c text
*.h text

# Convert to CRLF line endings on checkout.
*.sln text eol=crlf

# Convert to LF line endings on checkout.
*.sh text eol=lf

# Binary files.
*.png binary
*.jpg binary

เพิ่มเติมเกี่ยวกับวิธีการฟื้นฟู repo ของคุณหลังจากเปลี่ยนการตั้งค่าตอนจบบรรทัดที่นี่ Tldr:

สำรองไฟล์ของคุณด้วย Git ลบทุกไฟล์ในที่เก็บของคุณ (ยกเว้นไดเร็กทอรี. git) จากนั้นกู้คืนไฟล์ทั้งหมดในครั้งเดียว บันทึกไฟล์ปัจจุบันของคุณใน Git เพื่อไม่ให้งานของคุณสูญหาย

git add . -u

git commit -m "Saving files before refreshing line endings"

ลบดัชนีและบังคับให้ Git สแกนไดเร็กทอรีการทำงานอีกครั้ง

rm .git/index

เขียนดัชนี Git ใหม่เพื่อรับส่วนท้ายบรรทัดใหม่ทั้งหมด

git reset

แสดงไฟล์ที่เขียนซ้ำและทำให้เป็นมาตรฐาน

ในบางกรณีนี่คือสิ่งที่ต้องทำ คนอื่น ๆ อาจต้องทำตามขั้นตอนเพิ่มเติมดังต่อไปนี้:

git status

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

git add -u

ปลอดภัยอย่างยิ่งที่จะเห็นข้อความจำนวนมากที่อ่าน [s] "คำเตือน: CRLF จะถูกแทนที่ด้วย LF ในไฟล์"

เขียนไฟล์. gitattributes ใหม่

git add .gitattributes

ยอมรับการเปลี่ยนแปลงที่เก็บของคุณ

git commit -m "Normalize all the line endings"


18

ปัญหาที่เกี่ยวข้องกับคำสั่ง git บนระบบปฏิบัติการ Windows:

$ git add --all

คำเตือน: LF จะถูกแทนที่ด้วย CRLF ใน ...

ไฟล์จะมีการลงท้ายบรรทัดเดิมในไดเร็กทอรีการทำงานของคุณ

ความละเอียด :

$ git config --global core.autocrlf false     
$ git add --all 

ไม่มีข้อความเตือนใด ๆ ขึ้นมา


คุณควรทำสิ่งนี้ในระบบปฏิบัติการทั้งหมดที่คุณใช้เช่นใน windows และใน linux บันทึกแต่ละระบบปฏิบัติการมีไฟล์. git / config ส่วนกลางของตัวเองดังนั้นคุณต้องทำให้การตั้งค่าเหล่านั้นง่ายขึ้น นี่คือสาเหตุที่ @Thorsten คุณประสบปัญหา แต่ฉันตั้งค่าสถานะเป็นจริงแทนที่จะเป็นเท็จ
Emmanuel Mahuni

โซลูชันนี้ใช้งานได้ใน linux (คำตอบของ @ SašaŠijakไม่ได้ผลสำหรับฉัน)
juliocesar

4

ฉันสร้างสคริปต์เพื่อละเว้นความแตกต่างในส่วนท้ายบรรทัด:

จะแสดงไฟล์ที่ไม่ได้เพิ่มลงในรายการคอมมิตและถูกแก้ไข (หลังจากละเว้นความแตกต่างในส่วนท้ายบรรทัด) คุณสามารถเพิ่มอาร์กิวเมนต์ "add" เพื่อเพิ่มไฟล์เหล่านั้นในคอมมิตของคุณ

#!/usr/bin/perl

# Usage: ./gitdiff.pl [add]
#    add : add modified files to git

use warnings;
use strict;

my ($auto_add) = @ARGV;
if(!defined $auto_add) {
    $auto_add = "";
}

my @mods = `git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-`;
chomp(@mods);
for my $mod (@mods) {
    my $diff = `git diff -b $mod 2>/dev/null`;
    if($diff) {
        print $mod."\n";
        if($auto_add eq "add") {
            `git add $mod 2>/dev/null`;
        }
    }
}

ซอร์สโค้ด: https://github.com/lepe/scripts/blob/master/gitdiff.pl

อัปเดต :

  • แก้ไขโดย evandro777: เมื่อไฟล์มีที่ว่างในชื่อไฟล์หรือไดเร็กทอรี

ขอบคุณ! นั่นเป็นวิธีเดียวที่ฉันจะได้รับความแตกต่างที่แท้จริง มีเพียงปัญหาที่เกิดขึ้นเมื่อพิมพ์ 3 บรรทัดแสดงข้อผิดพลาดนี้: sh: 1: ข้อผิดพลาดทางไวยากรณ์: สตริงที่ยกมาที่ไม่
สิ้นสุด

1
การแก้ไขปัญหาสคริปต์: ปัญหา: เมื่อไฟล์มีที่ว่างในไดเร็กทอรีชื่อไฟล์ ou git จะใช้ "" ดังนั้นสคริปต์จึงหยุดทำงาน การแก้ไขคือการเปลี่ยนบรรทัดนี้: my @mods = git status --porcelain 2>/dev/null | grep '^ M ' | awk '{ print \$2 }'; ถึงสิ่งนี้: @mods ของฉัน = git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-;
evandro777

@ evandro777: ขอบคุณ! ฉันได้อัปเดตทั้งคำตอบและรหัสคอมไพล์แล้ว
lepe

3

ฉันใช้ทั้ง windows และ linux แต่วิธีแก้ปัญหาcore.autocrlf trueไม่ได้ช่วยฉัน git checkout <filename>ฉันยังมีอะไรที่เปลี่ยนไปหลังจาก

ดังนั้นฉันจึงใช้วิธีแก้ปัญหาเพื่อทดแทนgit status-gitstatus.sh

#!/bin/bash

git status | grep modified | cut -d' ' -f 4 | while read x; do
 x1="$(git show HEAD:$x | md5sum | cut -d' ' -f 1 )"
 x2="$(cat $x | md5sum | cut -d' ' -f 1 )"

 if [ "$x1" != "$x2" ]; then
    echo "$x NOT IDENTICAL"
 fi
done

ฉันแค่เปรียบเทียบmd5sumไฟล์กับพี่ชายของมันที่ที่เก็บ

ตัวอย่างผลลัพธ์:

$ ./gitstatus.sh
application/script.php NOT IDENTICAL
application/storage/logs/laravel.log NOT IDENTICAL

2
บางทีคุณอาจใช้ "git diff -b" สำหรับแต่ละไฟล์เพื่อตรวจสอบการเปลี่ยนแปลง excel การเปลี่ยนแปลงช่องว่าง
Ivan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.