Làm cách nào để Git bỏ qua thay đổi chế độ tệp (chmod)?


2311

Tôi có một dự án trong đó tôi phải thay đổi chế độ của tệp chmodthành 777 trong khi phát triển, nhưng không nên thay đổi trong repo chính.

Git chọn chmod -R 777 .và đánh dấu tất cả các tệp là thay đổi. Có cách nào để làm cho Git bỏ qua các thay đổi chế độ đã được thực hiện cho các tệp không?


17
Điều này hữu ích khi làm việc với git trên Windows + Bash trên Ubuntu trên Windows
Elazar

4
Đối với những ai chỉ muốn bỏ qua những thay đổi sự cho phép cho một invocation cụ thể của git diff, và những người do đó không muốn thay đổi file cấu hình Git của họ: bạn có thể sử dụng git diff -G.mỗi Zed của câu trả lời ở đây .
sampablokuper

Câu trả lời:


3823

Thử:

git config core.fileMode false

Từ 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ác -clá cờ có thể được sử dụng để thiết lập tùy chọn này cho một lần lệnh:

git -c core.fileMode=false diff

--globalcờ sẽ làm cho nó trở thành hành vi mặc định cho người dùng đã đăng nhập.

git config --global core.fileMode false

Thay đổi của cài đặt toàn cầu sẽ không được áp dụng cho các kho lưu trữ hiện có. Thêm vào đó, git clonegit initrõ ràng thiết lập core.fileModeđể truetrong cấu hình repo như đã thảo luận trong Git core.fileMode toàn cầu giả ghi đè cục bộ trên bản sao

Cảnh báo

core.fileModekhông phải là thực hành tốt nhất và nên được sử dụng cẩn thận. Cài đặt này chỉ bao gồm bit thực thi của chế độ và không bao giờ các bit đọc / ghi. Trong nhiều trường hợp, bạn nghĩ rằng bạn cần cài đặt này vì bạn đã làm một cái gì đó như thế chmod -R 777, làm cho tất cả các tệp của bạn có thể thực thi được. Nhưng trong hầu hết các dự án, hầu hết các tệp không cần và không thể thực thi được vì lý do bảo mật .

Cách thích hợp để giải quyết loại tình huống này là xử lý riêng quyền thư mục và tệp, với nội dung như:

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

Nếu bạn làm điều đó, bạn sẽ không bao giờ cần sử dụng core.fileMode, ngoại trừ trong môi trường rất hiếm.


203
Nếu bạn làm git config --global core.filemode falsebạn sẽ chỉ cần làm điều này một lần cho tất cả các repos.
Greg

13
điều này không hiệu quả với tôi cho đến khi tôi sửa trường hợp đó là fileMode thay vì filemode
tishma

8
@tishma: Phần cấu hình Git và tên biến không phân biệt chữ hoa chữ thường theo tài liệu, xem phần TẬP TIN CẤU HÌNH , vì vậy nếu cách trên không hiệu quả với bạn thì đó là vì một lý do khác.
Greg Hewgill

11
@donquixote: git configLệnh ghi cài đặt vào tệp cấu hình chính xác ( .git/configchỉ cho kho lưu trữ hiện tại hoặc ~/.gitconfignếu được sử dụng với --global).
Greg Hewgill

8
@ zx1986: Không thành vấn đề. Từ git config : "Tên biến không phân biệt chữ hoa chữ thường, ..."
Greg Hewgill

277

hoàn tác thay đổi chế độ trong cây làm việc:

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

Hoặc trong 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
Trên OS X Lion, bỏ qua -d'\n'phần xargsnày vì đây là một đối số bất hợp pháp (và không cần thiết).
Pascal

9
Bạn có thể bỏ qua mọi lỗi về "chmod: thiếu toán hạng sau` + x '"
Casey Watson

5
cái này có cập nhật không? Tôi nhận được 'chmod: quá ít đối số' trong mingw
hammett

7
@Pascal @pimlottc -d chỉ định dấu phân cách là dòng mới thay vì bất kỳ khoảng trắng nào. Các xargs BSD không có tùy chọn đó, nhưng thay vào đó, bạn có thể dẫn đầu ra qua tr '\n' '\0'và sau đó sử dụng -0arg to xargs để sử dụng NUL làm dấu phân cách.
Đánh dấu Aufflick

10
Thật tuyệt, trđiều đã làm việc! Đây là lệnh đầy đủ cho OSX:git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x
K.-Michael Aye

135

Nếu bạn muốn đặt tùy chọn này cho tất cả các repos của mình, hãy sử dụng --globaltùy chọn.

git config --global core.filemode false

Nếu điều này không hoạt động, có lẽ bạn đang sử dụng phiên bản git mới hơn, vì vậy hãy thử --addtùy chọn.

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

Nếu bạn chạy nó mà không có tùy chọn --global và thư mục làm việc của bạn không phải là repo, bạn sẽ nhận được

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

5
Có vẻ như sau này GIT sử dụng --add, như tronggit config --add --global core.filemode false
mgaert

14
Nếu cấu hình cục bộ của repo đã có filemode = true thì việc thay đổi cấu hình chung sẽ không giúp ích vì cấu hình cục bộ sẽ ghi đè cấu hình chung. Sẽ phải thay đổi cấu hình cục bộ của mỗi repo của máy một lần
Rakib

3
XIN VUI LÒNG: Cập nhật câu trả lời này với cảnh báo của syedrakib! Tất cả mọi thứ cảm thấy điên rồ trước khi tôi tìm thấy nó, và có ý nghĩa hoàn hảo sau.
jerclarke

88

Nếu

git config --global core.filemode false

không làm việc cho bạn, hãy làm thủ công:

cd into yourLovelyProject folder

cd vào thư mục .git:

cd .git

chỉnh sửa tập tin cấu hình:

nano config

thay đổi thành sai

[core]
        repositoryformatversion = 0
        filemode = true

->

[core]
        repositoryformatversion = 0
        filemode = false

lưu, thoát, vào thư mục trên:

cd ..

nhắc lại git

git init

Bạn xong việc rồi!


11
Thay vì chỉnh sửa .git/config, một đơn giản git config core.fileMode falsetrong thư mục gốc của dự án của bạn là đủ. Nếu bạn chỉnh sửa tệp cấu hình, tốt hơn hết bạn nên xóa hoàn toàn lệnh, để chọn toàn cục.
Felix

6
-1 nếu git config --global không hoạt động, điều đó có nghĩa là bạn không có quyền làm điều đó ở cấp hệ thống, globaltùy chọn xóa thực hiện chính xác giống như chỉnh sửa thủ công .git / config
CharlesB

@CharlesB không chính xác - câu trả lời đã cung cấp một cách giải quyết bằng cách đặt tùy chọn trực tiếp trong dự án, làm cho nó trở thành dự án cụ thể. Điều này sẽ không hoạt động với các dự án git khác mà bạn thực hiện / thanh toán trong tương lai, nhưng hoạt động cho dự án bạn đang làm. (hãy chắc chắn rằng chúng tôi định hướng ~/.gitconfig~/project/.git/config)
ddavison

Một khi điều này đã chạy, git initchúng ta có nên đặt lại tên tệp thành đúng không?
Jordan

53

Thêm vào câu trả lời của Greg Hewgill (sử dụng core.fileModebiến cấu hình):

Bạn có thể sử dụng --chmod=(-|+)xtùy chọn git update-index (phiên bản cấp thấp của "git add") để thay đổi quyền thực thi trong chỉ mục, từ đó sẽ được chọn nếu bạn sử dụng "git commit" (chứ không phải "git commit -a ").


2
Điều này đáng lẽ phải được chỉnh sửa thành câu trả lời của Greg Hewgill thay vì được thêm vào dưới dạng một câu trả lời riêng biệt, do đó tạo ra một câu trả lời tối cao với một đại diện rõ ràng duy nhất.
Greg

6
@Greg: Một người cần có đủ điểm để chỉnh sửa câu trả lời không riêng; Tôi nghĩ rằng tôi không có đủ quyền chỉnh sửa tại thời điểm đó.
Jakub Narębski

1
@Jakub Tôi nghĩ bạn đã có đủ danh tiếng rồi :) Lệnh này sẽ trông như thế nào đối với một tệp ví dụ?
Alex Hall

38

Bạn có thể định cấu hình nó trên toàn cầu:

git config --global core.filemode false

Nếu cách trên không phù hợp với bạn, lý do có thể là cấu hình cục bộ của bạn ghi đè lên cấu hình toàn cầu.

Xóa cấu hình cục bộ của bạn để làm cho cấu hình toàn cầu có hiệu lực:

git config --unset core.filemode

Ngoài ra, bạn có thể thay đổi cấu hình cục bộ của mình thành đúng giá trị:

git config core.filemode false


4
Nếu câu trả lời chính không giúp bạn - hãy thử câu này. Nếu bạn muốn kiểm tra cấu hình cục bộ của mình mà không sửa đổi nó, hãy kiểm tra git config -l(liệt kê cấu hình hiện tại - cả cục bộ và toàn cầu)
Krzysztof Bociurko

23

Nếu bạn đã sử dụng lệnh chmod rồi thì hãy kiểm tra sự khác biệt của tệp, Nó hiển thị chế độ tệp trước đó và chế độ tệp hiện tại, chẳng hạn như:

chế độ mới: 755

chế độ cũ: 644

Đặt chế độ cũ của tất cả các tệp bằng lệnh bên dưới

sudo chmod 644 .

bây giờ đặt core.fileMode thành false trong tệp cấu hình bằng cách sử dụng lệnh hoặc thủ công.

git config core.fileMode false

sau đó áp dụng lệnh chmod để thay đổi quyền của tất cả các tệp như

sudo chmod 755 .

và một lần nữa đặt core.fileMode thành true.

git config core.fileMode true

Đối với các thực tiễn tốt nhất, đừng giữ core.fileMode sai.


Bạn đang nói rằng toàn bộ dự án (đang phát triển, dàn dựng và sản xuất) phải là 755?
Daniel

@Daniel Tháng hai: Không. Chỉ thay đổi chế độ của các tệp cần thiết.
Kishor Vitekar

For best practises don't Keep core.fileMode false alwaysý bạn là gì, bạn nên giải thích điều đó
bg17aw

For best practises don't Keep core.fileMode false always.Một số hệ thống tệp (ví dụ: FAT) không hỗ trợ quyền truy cập tệp, do đó, HĐH sẽ báo cáo giá trị mặc định (766 trên hệ thống của tôi). Trong trường hợp này, thực core.filemodesự cần thiết trong cấu hình cục bộ, trừ khi bạn muốn làm
mờ

Ngoài ra, tại sao bạn lại bận tâm thay đổi perms trở lại? Nếu bạn đặt core.filemode=falsethì git sẽ bỏ qua các thay đổi bit thực thi, không cần thay đổi quyền cục bộ. Trừ khi bạn đã thêm các thay đổi quyền đối với chỉ mục, trong trường hợp đó, bạn thiếu bước mà bạn cần git addsau khi tắt core.filemode.
KevinOrr

18

Bằng cách xác định các bí danh sau (trong ~ / .gitconfig), bạn có thể dễ dàng vô hiệu hóa tạm thời tệp fileMode trên mỗi lệnh git:

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

Khi bí danh này được thêm tiền tố vào lệnh git, chế độ tệp thay đổi sẽ không hiển thị với các lệnh sẽ hiển thị chúng. Ví dụ:

git nfm status

14

Nếu bạn muốn đặt mã tên thành false trong tệp cấu hình đệ quy (bao gồm cả các mô hình con): find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'


4
Điều này sẽ không hoạt động nếu dòng đó không có trong tập tin cấu hình. Nếu bạn muốn thay đổi nó cho mô hình con, hãy thử điều này:git submodule foreach git config core.fileMode false
Courtlandj

4

Giải pháp đơn giản:

Nhấn lệnh Đơn giản này trong Thư mục dự án ( nó sẽ không xóa các thay đổi ban đầu của bạn) ... nó sẽ chỉ xóa các thay đổi đã được thực hiện trong khi bạn thay đổi quyền thư mục dự án

lệnh dưới đây:

git config core.fileMode sai

Tại sao tất cả các tệp không cần thiết này được sửa đổi: bởi vì bạn đã thay đổi quyền truy cập thư mục dự án với commend sudo chmod -R 777 ./yourProjectFolder

Khi nào bạn sẽ kiểm tra những thay đổi những gì bạn không làm? bạn tìm thấy như dưới đây trong khi sử dụng tên tệp git diff

old mode 100644
new mode 100755

1

Điều này làm việc cho tôi:

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

hoặc đảo ngược, tùy thuộc vào hệ điều hành của bạn

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

1
Điều này sẽ thay đổi các quyền của tệp, nhưng không làm cho git bỏ qua các quyền của tệp.
domdambrogia

Vâng, bạn đã đúng, điều đó không giải quyết git bỏ qua điều.
Martin Volek
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.