ฉันจะทำให้ Git เพิกเฉยต่อโหมดไฟล์ (chmod) ได้อย่างไร?


2309

ฉันมีโครงการที่ฉันต้องเปลี่ยนโหมดของไฟล์ด้วยchmod777 ในขณะที่กำลังพัฒนา แต่ไม่ควรเปลี่ยนใน repo หลัก

Git เลือกchmod -R 777 .และทำเครื่องหมายไฟล์ทั้งหมดว่ามีการเปลี่ยนแปลง มีวิธีในการเปลี่ยนแปลงการเพิกเฉยโหมด Git ที่ทำกับไฟล์หรือไม่?


17
สิ่งนี้มีประโยชน์เมื่อทำงานกับ git บน Windows + Bash บน Ubuntu บน Windows
Elazar

4
สำหรับทุกคนที่เพียงแค่ต้องการที่จะไม่สนใจการเปลี่ยนแปลงอนุญาตสำหรับการภาวนาที่เฉพาะเจาะจงของgit diffและผู้ที่จึงไม่ต้องการที่จะปรับเปลี่ยนการตั้งค่าไฟล์ Git ของพวกเขาคุณสามารถใช้git diff -G.ต่อZed ของคำตอบที่นี่
sampablokuper

คำตอบ:


3821

ลอง:

git config core.fileMode false

จากgit-config (1) :

core.fileMode
    Tells Git if the executable bit of files in the working tree
    is to be honored.

    Some filesystems lose the executable bit when a file that is
    marked as executable is checked out, or checks out a
    non-executable file with executable bit on. git-clone(1)
    or git-init(1) probe the filesystem to see if it handles the 
    executable bit correctly and this variable is automatically
    set as necessary.

    A repository, however, may be on a filesystem that handles
    the filemode correctly, and this variable is set to true when
    created, but later may be made accessible from another
    environment that loses the filemode (e.g. exporting ext4
    via CIFS mount, visiting a Cygwin created repository with Git
    for Windows or Eclipse). In such a case it may be necessary
    to set this variable to false. See git-update-index(1).

    The default is true (when core.filemode is not specified
    in the config file).

การ-cตั้งค่าสถานะสามารถใช้เพื่อตั้งค่าตัวเลือกนี้สำหรับคำสั่งแบบครั้งเดียว:

git -c core.fileMode=false diff

และการ--globalตั้งค่าสถานะจะทำให้มันเป็นพฤติกรรมเริ่มต้นสำหรับผู้ใช้ที่เข้าสู่ระบบ

git config --global core.fileMode false

การเปลี่ยนแปลงการตั้งค่าส่วนกลางจะไม่ถูกนำไปใช้กับที่เก็บข้อมูลที่มีอยู่ นอกจากนี้git cloneและgit initกำหนดอย่างชัดเจนcore.fileModeในการtrueในการตั้งค่า repo ที่กล่าวไว้ในGit core.fileMode โลกแทนที่เท็จไว้ในโคลน

คำเตือน

core.fileModeไม่ใช่วิธีปฏิบัติที่ดีที่สุดและควรใช้อย่างระมัดระวัง การตั้งค่านี้ครอบคลุมเฉพาะบิตของโหมดที่ใช้งานได้และจะไม่มีบิตสำหรับอ่าน / เขียน ในหลายกรณีคุณคิดว่าคุณต้องการการตั้งค่านี้เพราะคุณทำสิ่งที่ต้องการchmod -R 777ทำให้ไฟล์ทั้งหมดของคุณสามารถเรียกใช้งานได้ แต่ในโครงการส่วนใหญ่ไฟล์ส่วนใหญ่ไม่จำเป็นและไม่ควรปฏิบัติสำหรับเหตุผลด้านความปลอดภัย

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

find . -type d -exec chmod a+rwx {} \; # Make folders traversable and read/write
find . -type f -exec chmod a+rw {} \;  # Make files read/write

หากคุณทำเช่นนั้นคุณจะไม่จำเป็นต้องใช้core.fileModeยกเว้นในสภาพแวดล้อมที่หายากมาก


203
หากคุณทำgit config --global core.filemode falseคุณจะต้องทำเช่นนี้เพียงครั้งเดียวสำหรับ repos ทั้งหมด
Greg

13
นี้ไม่ได้ผลสำหรับฉันจนกว่าฉันจะได้รับการแก้ไขในกรณีที่มันควรจะเป็น fileMode แทน filemode
Tishma

8
@tishma: ส่วนการกำหนดค่า Git และชื่อตัวแปรนั้นไม่คำนึงถึงตัวพิมพ์เล็กและตัวใหญ่ตามเอกสารประกอบให้ดูที่ส่วนการกำหนดค่าไฟล์ดังนั้นหากข้อมูลข้างต้นไม่ได้ผลสำหรับคุณก็เป็นเพราะเหตุผลอื่น
Greg Hewgill

11
@donquixote: git configคำสั่งจะเขียนการตั้งค่าไปยังไฟล์กำหนดค่าที่ถูกต้อง ( .git/configสำหรับที่เก็บปัจจุบันหรือ~/.gitconfigหากใช้กับ--global)
Greg Hewgill

8
@ zx1986: ไม่เป็นไร จากการตั้งค่าgit : "ชื่อตัวแปรไม่คำนึงถึงขนาดตัวพิมพ์, ... "
Greg Hewgill

277

การเปลี่ยนโหมดเลิกทำในแผนผังการทำงาน:

git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -d'\n' chmod +x
git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -d'\n' chmod -x

หรือใน mingw-git

git diff --summary | grep  'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -e'\n' chmod +x
git diff --summary | grep  'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -e'\n' chmod -x

42
บน OS X Lion ให้ละเว้น-d'\n'ส่วนxargsนี้เนื่องจากเป็นอาร์กิวเมนต์ที่ผิดกฎหมาย (และไม่จำเป็น)
Pascal

9
คุณสามารถละเว้นข้อผิดพลาดเกี่ยวกับ "chmod: ตัวถูกดำเนินการที่หายไปหลังจาก` + x '"
Casey Watson

5
นี้ทันสมัยหรือไม่ ฉันได้รับ 'chmod: การโต้เถียงน้อยเกินไป' ใน mingw
hammett

7
@Pascal @pimlottc -d ระบุตัวคั่นเป็นบรรทัดใหม่แทนช่องว่างใด ๆ BSD xargs ไม่มีตัวเลือกนั้น แต่คุณสามารถไพพ์เอาต์พุตผ่านtr '\n' '\0'และใช้-0arg to xargs เพื่อใช้ NUL เป็นตัวคั่น
Mark Aufflick

10
เยี่ยมtrเลยสิ่งนี้ใช้ได้ผล! นี่คือคำสั่งแบบเต็มสำหรับ OSX:git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x
K. -Michael Aye

135

หากคุณต้องการตั้งค่าตัวเลือกนี้สำหรับ repos ทั้งหมดของคุณให้ใช้--globalตัวเลือก

git config --global core.filemode false

หากวิธีนี้ใช้ไม่ได้ผลคุณอาจใช้ git รุ่นใหม่ลองใช้--addตัวเลือก

git config --add --global core.filemode false

หากคุณเรียกใช้โดยไม่มีตัวเลือก - global และไดเรกทอรีการทำงานของคุณไม่ใช่ repo คุณจะได้รับ

error: could not lock config file .git/config: No such file or directory

5
ดูเหมือนว่าภายหลังการใช้งาน GIT --addในขณะที่git config --add --global core.filemode false
mgaert

14
หากการกำหนดค่าท้องถิ่นของ repo มี filemode = true อยู่แล้วการเปลี่ยนการกำหนดค่าทั่วโลกจะไม่ช่วยได้เนื่องจากการกำหนดค่าในท้องถิ่นจะแทนที่การกำหนดค่าส่วนกลาง จะต้องเปลี่ยนการตั้งค่าท้องถิ่นของแต่ละ repo ของเครื่องหนึ่งครั้ง
Rakib

3
โปรด: อัปเดตคำตอบนี้ด้วยคำเตือนของ syedrakib! ทุกสิ่งรู้สึกวิกลจริตก่อนที่ฉันจะพบมันและทำให้รู้สึกสมบูรณ์แบบหลังจากนั้น
jerclarke

88

ถ้า

git config --global core.filemode false

ไม่ทำงานสำหรับคุณทำด้วยตนเอง:

cd into yourLovelyProject folder

cd ลงในโฟลเดอร์. git:

cd .git

แก้ไขไฟล์กำหนดค่า:

nano config

เปลี่ยนจริงเป็นเท็จ

[core]
        repositoryformatversion = 0
        filemode = true

->

[core]
        repositoryformatversion = 0
        filemode = false

บันทึกออกไปที่โฟลเดอร์ด้านบน:

cd ..

เสริมแต่งคอมไพล์

git init

คุณทำเสร็จแล้ว!


11
แทนที่จะเป็นการแก้ไข.git/configง่าย ๆgit config core.fileMode falseในรูทของโครงการของคุณก็เพียงพอแล้ว หากคุณแก้ไขไฟล์กำหนดค่าคุณจะดีกว่าที่จะลบคำสั่งทั้งหมดเพื่อให้มีการเลือกคำสั่งโกลบอล
เฟลิกซ์

6
-1 ถ้า git config - global ใช้งานไม่ได้หมายความว่าคุณไม่มีสิทธิ์ทำในระดับระบบglobalตัวเลือกการลบจะเหมือนกับการแก้ไขด้วยตนเอง. git / config ด้วยตนเอง
CharlesB

@CharlesB ไม่ถูกต้อง - คำตอบที่ให้การแก้ปัญหาโดยการใส่ตัวเลือกในโครงการโดยตรงทำให้มันเฉพาะโครงการ สิ่งนี้จะไม่ทำงานกับโครงการ git อื่น ๆ ที่คุณสร้าง / เช็คเอาต์ในอนาคต แต่จะใช้ได้กับโครงการที่คุณกำลังทำอยู่ (ขอให้แน่ใจว่าเราแก้ความเข้าใจผิด~/.gitconfigและ~/project/.git/config)
ddavison

เมื่อสิ่งนี้ทำงานแล้วgit initเราควรจะตั้งค่าโหมดไฟล์กลับเป็นจริงหรือไม่?
Jordan

53

การเพิ่มคำตอบ Greg Hewgill (จากการใช้core.fileModeตัวแปร config):

คุณสามารถใช้--chmod=(-|+)xตัวเลือกของgit update-index (รุ่นระดับต่ำของ "git add") เพื่อเปลี่ยนการอนุญาตการใช้งานในดัชนีจากที่ที่มันจะถูกหยิบขึ้นมาถ้าคุณใช้ "git กระทำ" (และไม่ใช่ "git commit -a ")


2
สิ่งนี้ควรได้รับการแก้ไขเป็นคำตอบของ Greg Hewgill แทนที่จะเพิ่มเป็นคำตอบที่แยกต่างหากดังนั้นการสร้างคำตอบที่ดีที่สุดด้วยคำตอบเดียวที่ชัดเจน
เกร็ก

6
@ Greg: หนึ่งต้องมีคะแนนมากพอที่จะแก้ไขไม่ใช่คำตอบของตัวเอง; ฉันคิดว่าฉันมีสิทธิ์ไม่เพียงพอในการแก้ไขสิทธิ์ในเวลานั้น
Jakub Narębski

1
@Jakub ฉันคิดว่าคุณมีชื่อเสียงเพียงพอแล้วตอนนี้ :) คำสั่งนี้จะเป็นอย่างไรสำหรับไฟล์ตัวอย่าง?
Alex Hall

38

คุณสามารถกำหนดค่าได้ทั่วโลก:

git config --global core.filemode false

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

ลบการกำหนดค่าท้องถิ่นของคุณเพื่อให้การกำหนดค่าทั่วโลกมีผล:

git config --unset core.filemode

หรือคุณสามารถเปลี่ยนการกำหนดค่าท้องถิ่นของคุณเป็นค่าที่ถูกต้อง:

git config core.filemode false


4
หากคำตอบหลักไม่ช่วยคุณลองทำแบบนี้ หากคุณต้องการตรวจสอบการกำหนดค่าท้องถิ่นของคุณโดยไม่ต้องแก้ไขให้ตรวจสอบgit config -l(รายการการกำหนดค่าปัจจุบัน - ทั้งในระดับท้องถิ่นและระดับโลก)
Krzysztof Bociurko

23

หากคุณใช้คำสั่งchmodแล้วตรวจสอบความแตกต่างของไฟล์มันจะแสดงโหมดไฟล์ก่อนหน้าและโหมดไฟล์ปัจจุบันเช่น:

โหมดใหม่: 755

โหมดเก่า: 644

ตั้งค่าโหมดเก่าของไฟล์ทั้งหมดโดยใช้คำสั่งด้านล่าง

sudo chmod 644 .

ตอนนี้ตั้งค่า core.fileMode เป็น false ในไฟล์ปรับแต่งโดยใช้คำสั่งหรือด้วยตนเอง

git config core.fileMode false

จากนั้นใช้คำสั่ง chmod เพื่อเปลี่ยนการอนุญาตของไฟล์ทั้งหมดเช่น

sudo chmod 755 .

และตั้งค่า core.fileMode เป็น true อีกครั้ง

git config core.fileMode true

สำหรับแนวทางปฏิบัติที่ดีที่สุดอย่าเก็บ core.fileMode เป็นเท็จเสมอ


คุณกำลังบอกว่าโครงการทั้งหมด (ในการพัฒนาการจัดเตรียมและการผลิต) ควรเป็น 755 หรือไม่?
แดเนียล

@Daniel Feb: ไม่เปลี่ยนโหมดของไฟล์ที่จำเป็นเท่านั้น
Kishor Vitekar

For best practises don't Keep core.fileMode false alwaysคุณหมายถึงอะไรคุณควรอธิบายว่า
bg17aw

For best practises don't Keep core.fileMode false always.ระบบไฟล์บางระบบ (เช่น FAT) ไม่รองรับการอนุญาตไฟล์ดังนั้นระบบปฏิบัติการจะรายงานค่าเริ่มต้น (766 บนระบบของฉัน) ในกรณีcore.filemodeนี้จำเป็นอย่างยิ่งในการกำหนดค่าท้องถิ่นเว้นแต่คุณต้องการขยายประวัติการกระทำด้วยการเปลี่ยนแปลงการอนุญาตที่ไม่จำเป็นและไม่ได้ตั้งใจ
KevinOrr

นอกจากนี้ทำไมคุณถึงต้องเปลี่ยนเพอร์เฟ็กต์กลับมาเลยล่ะ? หากคุณตั้งค่าcore.filemode=falseแล้ว git จะเพิกเฉยต่อการเปลี่ยนแปลงบิตไม่จำเป็นต้องเปลี่ยนการอนุญาตในระบบ ยกเว้นกรณีที่คุณได้เพิ่มสิทธิ์ในการเปลี่ยนแปลงดัชนีซึ่งในกรณีที่คุณกำลังขาดหายไปขั้นตอนที่คุณจะต้องหลังจากที่คุณปิดgit add core.filemode
KevinOrr

18

โดยการกำหนดนามแฝงต่อไปนี้ (ใน ~ / .gitconfig) คุณสามารถปิดการใช้งานโหมดคำสั่งต่อคำสั่ง git ชั่วคราว:

[alias]
nfm = "!f(){ git -c core.fileMode=false $@; };f"

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

git nfm status

14

หากคุณต้องการตั้งค่าโหมดไฟล์เป็นเท็จในไฟล์กำหนดค่าแบบเรียกซ้ำ (รวมถึง submodules): find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'


4
สิ่งนี้จะไม่ทำงานหากบรรทัดนั้นไม่อยู่ในไฟล์กำหนดค่า หากคุณต้องการเปลี่ยนเป็น submodules ลองสิ่งนี้:git submodule foreach git config core.fileMode false
courtlandj

4

วิธีแก้ปัญหาง่าย ๆ :

กดคำสั่งง่าย ๆนี้ในโฟลเดอร์โครงการ ( จะไม่ลบการเปลี่ยนแปลงดั้งเดิมของคุณ) ... มันจะลบการเปลี่ยนแปลงที่ทำในขณะที่คุณเปลี่ยนสิทธิ์การใช้โฟลเดอร์โครงการเท่านั้น

คำสั่งอยู่ด้านล่าง:

git config core.fileMode false

ทำไมไฟล์ที่ไม่จำเป็นทั้งหมดนี้ได้รับการแก้ไข: เนื่องจากคุณเปลี่ยนสิทธิ์ของโฟลเดอร์โปรเจคด้วยการยกย่อง sudo chmod -R 777 ./yourProjectFolder

คุณจะตรวจสอบการเปลี่ยนแปลงเมื่อไหร่ที่คุณไม่ได้ทำ? คุณพบว่าด้านล่างในขณะที่ใช้ชื่อไฟล์ git diff

old mode 100644
new mode 100755

1

สิ่งนี้ใช้ได้กับฉัน:

find . -type f -exec chmod a-x {} \;

หรือย้อนกลับขึ้นอยู่กับระบบปฏิบัติการของคุณ

find . -type f -exec chmod a+x {} \;

1
สิ่งนี้จะเปลี่ยนการอนุญาตของไฟล์ แต่ไม่ทำให้ git เพิกเฉยต่อการอนุญาตไฟล์ของไฟล์
domdambrogia

ดีคุณถูกต้องที่ไม่แก้ไขสิ่งที่ไม่สนใจคอมไพล์
Martin Volek
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.