Status Git mengabaikan akhir baris / file identik / windows & lingkungan linux / dropbox / mled

113

Bagaimana cara membuatnya

status git

abaikan perbedaan akhir baris?

Info latar belakang:

Saya menggunakan Windows dan Linux secara acak untuk mengerjakan proyek. Proyek ini ada di Dropbox.

Saya menemukan banyak hal tentang bagaimana membuat git diff mengabaikan akhiran baris. Karena saya menggunakan meld git diff membuka gabungan untuk setiap file. Dan berbaur mengatakan "file identik".

Jadi bagaimana cara menghindarinya. Git seharusnya hanya membuka gabungan untuk file yang diubah. Dan status git seharusnya tidak melaporkan file sebagai diubah jika hanya akhiran file yang berbeda.

EDIT: Penyebab:

Ini terjadi karena pengaturan ini di Windows

core.autocrlf benar

Jadi saya memeriksa copy pekerjaan di Linux dan mengatur core.autocrlf false di Windows.

Alangkah baiknya mengetahui cara membuat status git mengabaikan baris baru yang berbeda.

Thorsten Niehues
sumber
3
Jika Anda membagikan file menggunakan dropbox pada platform yang berbeda, Anda akan mengalami hal ini kecuali Anda secara eksplisit memberi tahu git untuk memperlakukan semua file sebagai biner. Solusi yang tepat adalah tidak menggunakan dropbox untuk repositori git
Petesh
ingat: stackoverflow.com/questions/2825428/… - ini mungkin sedikit membantu
Petesh
Saya menemukan cara kerjanya yang bagus dengan Dropbox: dengan menyetel core.autocrlf false
Thorsten Niehues
3
AFAIK memberi tahu git untuk memperlakukan file sebagai biner juga memiliki efek samping mengubah cara ia membedakan file. Solusi yang tepat adalah memberi tahu git untuk mengabaikan akhir baris. 2 hal yang paling tidak saya sukai: berurusan dengan masalah akhiran baris dan FUD yang tidak perlu tentang cara orang mengatur repos mereka :)
ChrisM
Wow, butuh waktu lama bagi saya karena masalah ini core.autocrlfadalah akar masalah di Windows, tetapi juga obatnya di Linux. Masalahnya adalah, autocrlfbersifat global pada Windows, dan repo tidak memiliki pengaturan itu .git/config. Dengan menjalankan lokal git config core.autocrlf truesaya menyingkirkan perubahan palsu pada copy pekerjaan NTFS saya yang dikloning di Windows tetapi diakses di Linux. (sekarang hanya ada perubahan palsu dengan symlink - symlink NTFS BERFUNGSI pada tunggangan fuseblk, tetapi Git melihatnya sebagai modifikasi ...)
Tomasz Gandor

Jawaban:

104

Coba tetapkan nilai core.autocrlf seperti ini:

git config --global core.autocrlf true
Saša Šijak
sumber
7
@ThorstenNiehues Saya menggunakan pengaturan itu pada beberapa proyek kerja. Saat bekerja saya harus menggunakan windows, home saya menggunakan mac dan linux. Sebelum ini saya memiliki masalah yang sama dengan Anda, setelah itu pengaturan semuanya baik-baik saja.
Saša Šijak
1
Aneh karena checkout di windows memiliki akhir baris \ r \ n di Linux saja \ n Apakah Anda memiliki kedua copy pekerjaan di Dropbox (atau serupa)?
Thorsten Niehues
1
@ThorstenNiehues Tidak, repositori git ada di github. Hmm, mungkin dropbox entah bagaimana mengacaukan ujung baris saat menyinkronkan file? Tampaknya aneh menggunakan dropbox untuk git. Coba gunakan bitbucket (ini memiliki repositori pribadi gratis), cukup buat satu repo kecil dan uji pada 2 mesin Anda dengan beberapa file teks kecil.
Saša Šijak
1
1. Salinan pekerjaan dan repo lokal ada di Dropbox (saya tidak memerlukan penyimpanan publik) itu mungkin perbedaannya
Thorsten Niehues
3
Di Windows: core.autocrlf trueadalah pengaturan yang berfungsi di CygWin. core.safecrlf falseadalah pengaturan yang berfungsi di git bash atau mingw
DrumM
43

Gunakan .gitattributes sebagai gantinya, dengan pengaturan berikut:

# Ignore all differences in line endings
*        -crlf

.gitattributes akan ditemukan di direktori yang sama dengan .gitconfig global Anda. Jika .gitattributes tidak ada, tambahkan ke direktori itu. Setelah menambahkan / mengubah .gitattributes Anda harus melakukan hard reset repositori agar berhasil menerapkan perubahan ke file yang ada.

Tukang sampah, petugas kebersihan
sumber
Ini berfungsi untuk saya di satu aliran, tetapi ketika saya mencoba membuatnya di aliran lain untuk proyek yang sama, itu masih menunjukkan perbedaan Newline.
pfernandom
1
@pfernandom, apakah Anda mungkin memiliki beberapa .gitattributes dalam proyek Anda? Ini akan melihat versi paling "lokal" terlebih dahulu, jadi jika Anda memilikinya di direktori lokal di mana file-file itu berada, itu akan menggunakan versi itu di atas versi lebar proyek Anda.
Trashman
Apakah harus ada 8 spasi sebelum -crlf?
Igonato
Seharusnya tidak masalah
Trashman
Ini lebih dari sekedar mengabaikan akhir baris untuk git status. Ini benar-benar mengubah cara file diperiksa ke dalam repositori. ref: git-scm.com/docs/gitattributes#_code_text_code
Vince
31

Jawaban ini tampaknya relevan karena OP mengacu pada kebutuhan solusi multi-OS. Artikel bantuan Github ini menjelaskan pendekatan yang tersedia untuk menangani garis akhiran lintas OS. Ada pendekatan global dan per repo untuk mengelola akhiran garis lintas-os.

Pendekatan global

Konfigurasikan penanganan ujung baris Git di Linux atau OS X:

git config --global core.autocrlf input

Konfigurasi penanganan ujung baris Git di Windows:

git config --global core.autocrlf true

Pendekatan per repo:

Di root repo Anda, buat .gitattributesfile dan tentukan setelan akhir baris untuk file proyek Anda, baris demi baris dalam format berikut: di path_regex line-ending-settingsmana line-ending-settingssalah satu dari berikut ini:

  • teks
  • binary (file yang tidak boleh diubah oleh Git di akhir baris - karena ini dapat menyebabkan beberapa jenis gambar seperti PNG tidak dirender di browser)

The textnilai dapat dikonfigurasi lebih lanjut untuk menginstruksikan Git tentang bagaimana untuk menangani akhir baris untuk file yang cocok:

  • text - Mengubah akhir baris ke akhir baris asli OS.
  • text eol=crlf- Mengubah akhiran baris menjadi CRLFsaat checkout.
  • text eol=lf- Mengubah akhiran baris menjadi LFsaat checkout.
  • text=auto - Default yang masuk akal yang membiarkan pegangan garis tergantung pada kebijaksanaan Git.

Berikut adalah isi dari contoh file .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

Lebih lanjut tentang cara menyegarkan repo Anda setelah mengubah pengaturan akhir baris di sini . Tldr:

cadangkan file Anda dengan Git, hapus setiap file di repositori Anda (kecuali direktori .git), lalu pulihkan semua file sekaligus. Simpan file Anda saat ini di Git, agar tidak ada pekerjaan Anda yang hilang.

git add . -u

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

Hapus indeks dan paksa Git untuk memindai ulang direktori kerja.

rm .git/index

Tulis ulang indeks Git untuk mengambil semua akhir baris baru.

git reset

Tampilkan file yang ditulis ulang dan dinormalisasi.

Dalam beberapa kasus, hanya ini yang perlu dilakukan. Orang lain mungkin perlu menyelesaikan langkah tambahan berikut:

git status

Tambahkan kembali semua file yang diubah, dan persiapkan untuk komit. Ini adalah kesempatan Anda untuk memeriksa file mana, jika ada, yang tidak diubah.

git add -u

Sangat aman untuk melihat banyak pesan di sini yang bertuliskan "peringatan: CRLF akan diganti dengan LF dalam file."

Tulis ulang file .gitattributes.

git add .gitattributes

Lakukan perubahan ke repositori Anda.

git commit -m "Normalize all the line endings"

pengguna4603841
sumber
18

Masalah terkait perintah git di sistem operasi Windows:

$ git add --all

peringatan: LF akan diganti oleh CRLF di ...

File tersebut akan memiliki akhiran baris aslinya di direktori kerja Anda.

Resolusi :

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

Tidak ada pesan peringatan yang muncul.

winstonhong
sumber
Anda harus melakukan ini di semua OS yang Anda gunakan, yaitu: di windows dan di linux. Rember setiap OS memiliki file .git / config globalnya sendiri, jadi Anda perlu membuat pengaturan tersebut simlar. Inilah mengapa @Thorsten Anda mengalami masalah. Tapi saya menyetel benderanya ke true, bukan false.
Emmanuel Mahuni
Solusi ini juga berfungsi di linux (jawaban @ SašaŠijak tidak berhasil untuk saya)
juliocesar
4

Saya membuat skrip untuk mengabaikan perbedaan akhir baris:

Ini akan menampilkan file yang tidak ditambahkan ke daftar komit dan telah dimodifikasi (setelah mengabaikan perbedaan akhir baris). Anda dapat menambahkan argumen "tambah" untuk menambahkan file tersebut ke komit Anda.

#!/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`;
        }
    }
}

Kode sumber: https://github.com/lepe/scripts/blob/master/gitdiff.pl

Pembaruan :

  • perbaiki oleh evandro777: Ketika file memiliki ruang di nama file atau direktori
lepe
sumber
Terima kasih! Itulah satu-satunya cara saya bisa mendapatkan perbedaan yang nyata. Hanya ada masalah yang terjadi dengan 3 baris yang dicetak, menunjukkan kesalahan ini: sh: 1: Kesalahan sintaks: string kutipan tidak
dihentikan
1
Perbaikan untuk masalah skrip: Masalah: Ketika file memiliki ruang dalam nama file direktori ou, git akan menggunakan "", sehingga skrip rusak. Cara mengatasinya adalah dengan mengubah baris ini: my @mods = git status --porcelain 2>/dev/null | grep '^ M ' | awk '{ print \$2 }'; untuk ini: my @mods = git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-;
evandro777
@ evandro777: Terima kasih! Saya telah memperbarui keduanya, jawaban dan kode gitnya.
lepe
3

Saya menggunakan windows dan linux, tetapi solusinya core.autocrlf truetidak membantu saya. Aku bahkan tidak berubah setelah itu git checkout <filename>.

Jadi saya menggunakan solusi untuk mengganti 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

Saya baru saja membandingkan md5sumfile dan saudaranya di repositori.

Contoh keluaran:

$ ./gitstatus.sh
application/script.php NOT IDENTICAL
application/storage/logs/laravel.log NOT IDENTICAL
shukshin.ivan
sumber
2
mungkin Anda dapat menggunakan "git diff -b" untuk setiap file untuk memeriksa perubahan excel whitespace changes
Ivan