2010-03-25 48 views
194

我有一個git結帳。所有的文件權限都不同於git認爲他們應該是什麼,因此他們都顯示爲修改。如何恢復git認爲該文件應該是什麼文件權限?

沒有觸及文件的內容(只是想修改權限),我如何設置所有的文件權限git認爲他們應該是什麼?

+0

的[我如何刪除的文件說: 「舊的模式100755新模式100644」 從Git的不分階段的變化可能的複製?](http://stackoverflow.com/questions/1257592/how-do-i-remove-files-saying-old-mode-100755-new-mode-100644-from-unstaged-cha) – jww 2016-12-10 04:03:33

回答

394

的Git跟蹤的FilePermission的,並公開使用git diff -p創建補丁時,權限更改。因此,我們需要的是:

  1. 創建反向補丁
  2. 只包括權限更改
  3. 補丁應用到我們的工作拷貝

作爲一個班輪:

git diff -p -R --no-color \ 
    | grep -E "^(diff|(old|new) mode)" --color=never \ 
    | git apply 

你也可以添加它作爲你的git配置的別名...

git config --global --add alias.permission-reset '!git diff -p -R --no-color | grep -E "^(diff|(old|new) mode)" --color=never | git apply' 

...並且你可以通過調用它:

git permission-reset 

注意,如果外殼是bash,請務必使用!git周圍的'代替"引號,否則它就會跟你跑最後git命令取代。

Thx to @Mixologic指出,只需在git diff上使用-R,繁瑣的sed命令就不再需要了。

+2

我在OS X中,這是行不通的。我已經確定問題在於git apply。它不應用文件權限更改。 – 2012-08-28 21:36:07

+10

哦,它的工作原理,我試圖從一個不同於存儲庫根的目錄申請。 git只適用於那裏。 – 2012-08-28 22:06:32

+4

是否有某些原因,您不會僅僅執行「git diff -p -R」而不是執行sed來使其反轉? – Mixologic 2013-06-17 18:34:32

9

Git不存儲可執行腳本以外的文件權限。考慮使用類似git-cache-meta的文件來保存文件所有權和權限。

Git只能存儲兩種模式:755(可執行)和644(不可執行)。如果你的文件是444 git會存儲它有644.

+10

對不起,但是這個是不正確的。確實,Git確實會跟蹤權限。 – Will 2013-04-05 19:24:23

+3

大致精確,請參閱https://git.wiki.kernel.org/index.php/ContentLimitations。獲取設置的確切權限似乎基於服務器和客戶端umask以及配置設置,請參閱http://stackoverflow.com/a/12735291/125150。 – 2014-01-09 13:19:01

+6

@不,它不。不能相信你的評論有這麼多upvotes。 – eis 2017-02-22 06:45:44

0

最簡單的事情就是改回權限。正如@ kroger指出的,git只跟蹤可執行位。所以,你可能只需要運行chmod -x filename修復(或+x如果這是什麼需要

+0

下面是'git show'的例子: diff --git a/OpenWatch/src/org/ale/openwatch/fb/FBUtils.java b/OpenWatch/src/org/ale/openwatch/fb/FBUtils.java 索引cd6fa6a..e5b0935 ** 100644 ** 粗體位有文件權限。 – Conrado 2013-07-31 17:28:40

+0

這對我來說似乎也是最簡單的。不幸的是,我遇到了與Conrado相同的問題 - 我無法將權限從'100644'更改爲'100755'。我認爲你不應該得到一個倒退, Git應該被放棄投票。它在很多不同的層面被如此多種方式打破...... – jww 2016-12-10 03:55:11

85

嘗試git config core.fileMode false

注:core.fileMode區分大小寫

git config手冊頁:

core.fileMode

如果爲false,則會忽略索引和工作副本之間的可執行位差異;對破碎的文件系統如FAT很有用。請參閱git-update-index(1)

缺省值爲true,除非git-clone(1)或git-init(1)將在創建存儲庫時探測並設置core.fileMode爲false(如果適用)。

+0

謝謝,這就是我最終做的。很習慣CVS不跟蹤權限,所以這個工作。 – 2010-03-26 14:39:51

+1

@shovas:我很高興這有幫助。在Linux和Windows之間共享回購協議時遇到類似的問題。順便說一句:如果這回答了你的問題,請將回復標記爲正確。 – 2010-03-26 16:50:49

+0

'git checkout origin/master'是否可以將提交給服務器的文件權限設置爲我的本地工作副本?因爲每當我爲ArangoDB構建V8時,都會更改文件權限,以便整個構建文件夾的訪問都被拒絕(即使是提升權限; Windows 7+也是如此)。我需要修復所有本地文件權限,然後才能繼續構建過程。 'core.filemode false'也可以解決這個問題嗎?我懷疑git在我的Windows機器上設置Linux權限。構建腳本可能會保留它們,並將相同的權限應用於新創建的文件... – CoDEmanX 2015-08-17 17:04:48

4
git diff -p \ 
| grep -E '^(diff|old mode|new mode)' \ 
| sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \ 
| git apply 

在大多數情況下工作,但如果你有外部差異的工具,如MELD安裝必須添加--no-EXT-DIFF

git diff --no-ext-diff -p \ 
    | grep -E '^(diff|old mode|new mode)' \ 
    | sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \ 
    | git apply 

需要在我的處境

+0

感謝真棒的回答,祝你有個美好的一天;) – Stranger 2017-05-23 18:04:46

-2

etckeeper tool可以處理的權限和:

etckeeper init -d /mydir 

您可以將它用於除之外的其他目錄。

使用您的軟件包管理器進行安裝,或從上面的鏈接獲取源代碼。

+2

它設置了什麼權限?如果它不讀取Git元數據或調用Git,則它不執行OP請求的內容。 – 2017-03-26 07:25:14

-1

git diff -p用於muhqu's answer可能不會顯示所有的差異。

  • 看到這個Cygwin中的文件,我沒有自己
  • 模式的改變將被完全忽略,如果core.filemodefalse(這是MSysGit默認)

此代碼讀取元數據,而不是直接:

(set -o errexit pipefail nounset; 
git ls-tree HEAD -z | while read -r -d $'\0' mask type blob path 
do 
    if [ "$type" != "blob" ]; then continue; fi; 
    case "$mask" in 
    #do not touch other bits 
    100644) chmod a-x "$path";; 
    100755) chmod a+x "$path";; 
    *) echo "invalid: $mask $type $blob\t$path" >&2; false;; 
    esac 
done) 

一種非生產級的一行(取代完全掩模):

git ls-tree HEAD | perl -ne '/^10(0\d{3}) blob \S+\t(.+)$/ && { system "chmod",$1,$2 || die }' 

(貸記 「$ '\ 0'」 變爲http://transnum.blogspot.ru/2008/11/bashs-read-built-in-supports-0-as.html

相關問題