git 내에서 파일과 디렉토리의 권한을 수정 한 경우 어떻게 복원합니까?


278

자식 체크 아웃이 있습니다. 모든 파일 권한은 git이 생각 해야하는 것과 다르므로 모두 수정 된 것으로 표시됩니다.

파일의 내용을 만지지 않고 (권한을 수정하고 싶습니다) 모든 파일 권한을 git가 생각하는 것으로 어떻게 설정합니까?


답변:


572

Git은 파일 권한을 추적하고를 사용하여 패치를 만들 때 권한 변경 사항을 노출합니다 git diff -p. 따라서 필요한 것은 다음과 같습니다.

  1. 역패를 만들다
  2. 권한 변경 사항 만 포함
  3. 작업 복사본에 패치를 적용하십시오

원 라이너로 :

git diff -p -R --no-ext-diff --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-ext-diff --no-color | grep -E "^(diff|(old|new) mode)" --color=never | git apply'

... 그리고 다음을 통해 호출 할 수 있습니다.

git permission-reset

shell is 인 경우 에 따옴표 대신 따옴표 bash를 사용해야 합니다 . 그렇지 않으면 마지막으로 실행 한 명령으로 대체됩니다 .'"!gitgit

단순히 -Ron을 사용 git diff하여 번거로운 sed명령이 더 이상 필요하지 않다는 점을 지적한 @Mixologic에 대한 것입니다 .


3
OS X에 있는데 작동하지 않습니다. 문제가 자식 적용에 있음을 확인했습니다. 파일 권한 변경 사항은 적용되지 않습니다.
pepper_chico

15
오, 그것은 작동했습니다. 저는 저장소 루트와 다른 디렉토리에서 적용하려고했습니다. 자식 적용은 거기에서만 작동합니다.
pepper_chico

6
sed를 뒤집는 대신 "git diff -p -R"을하지 않는 이유가 있습니까?
Mixologic

6
@RobQuist muhqu의 명령을 사용할 때 로컬 변경 사항이 제거되지 않았습니다.
logion

17
나는오고있다fatal: unrecognized input
Tieme

120

시험 git config core.fileMode false

로부터 git config매뉴얼 페이지

core.fileMode

False이면 인덱스와 작업 복사본 간의 실행 비트 차이가 무시됩니다. FAT와 같은 손상된 파일 시스템에 유용합니다. git-update-index (1)을 참조하십시오 .

git-clone (1) 또는 git-init (1)이 리포지토리가 생성 될 때 적절한 경우 core.fileMode를 검사하고 설정하는 것을 제외하고 기본값은 true입니다.


고마워, 이것이 내가 한 일입니다. cvs가 권한을 추적하지 않으므로 매우 효과적입니다.
데일 포레스터

3
@ shovas : 이것이 도움이되어 기쁩니다. Linux와 Windows간에 저장소를 공유 할 때 비슷한 문제가 발생했습니다. BTW : 질문에 대한 답변이 올 바르면 응답을 올바른 것으로 표시하십시오.
Tim Henigan

그것은 가능성이 git checkout origin/master세트 파일 권한 내 로컬 작업 복사본을 서버에 최선을 다하고? ArangoDB 용 V8을 빌드 할 때마다 파일 권한이 변경되어 전체 빌드 폴더에 대한 액세스가 거부됩니다 (높은 권한으로도 Windows 7 이상). 빌드 프로세스를 계속하려면 모든 로컬 파일 권한을 수정해야합니다. core.filemode false그것도 고칠 수 있습니까 ? git이 내 Windows 컴퓨터에서 Linux 권한을 설정 한 것으로 의심됩니다. 빌드 스크립트는 그것들을 보존하고 새로 생성 된 파일에 동일한 권한을 적용 할 수 있습니다 ...
CodeManX

설정에 어떤 단점이 있는지 임 궁금 filemode으로가 false!
kevoroid

11

Git은 실행 가능한 스크립트 이외의 파일 권한을 저장하지 않습니다. git-cache-meta 와 같은 것을 사용하여 파일 소유권과 권한을 저장하십시오.

Git은 755 (실행 가능)와 644 (실행 불가능)의 두 가지 모드 만 저장할 수 있습니다. 파일이 444 git이면 저장하면 644입니다.


14
죄송하지만이 내용은 잘못되었습니다. Git은 실제로 권한을 추적합니다.
Will

4
대략 정확합니다 ( git.wiki.kernel.org/index.php/ContentLimitations 참조) . 서버 및 클라이언트 및 umask구성 설정 에 따라 설정된 정확한 권한 은 stackoverflow.com/a/12735291/125150을 참조하십시오 .
Motti Strom

12
@ 아니, 그렇지 않습니다. 귀하의 의견에 너무 많은 의견이 있다고 믿을 수 없습니다.
EIS

@ 윌, 이것은 대략 맞습니다. 당 워드 프로세서 ...a mode of 100644, which means it’s a normal file. Other options are 100755, which means it’s an executable file; and 120000, which specifies a symbolic link. The mode is taken from normal UNIX modes but is much less flexible — these three modes are the only ones that are valid for files (blobs) in Git (although other modes are used for directories and submodules).
에스 마일

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

대부분의 경우 작동하지만 meld와 같은 외부 diff 도구가 설치되어 있으면 --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

Windows에서 cygwin의 git을 사용하면 git apply솔루션이 작동하지 않습니다. 여기 내 솔루션이 있습니다 chmod. 모든 파일 에서 실행 하여 권한을 재설정하십시오.

#!/bin/bash
IFS=$'\n'
for c in `git diff -p |sed -n '/diff --git/{N;s/diff --git//g;s/\n/ /g;s# a/.* b/##g;s/old mode //g;s/\(.*\) 100\(.*\)/chmod \2 \1/g;p}'`
do
        eval $c
done
unset IFS


-1

git diff -pmuhqu의 답변에 사용 된 모든 내용이 일치하지 않을 수 있습니다.

  • Cygwin에서 내가 소유하지 않은 파일을 보았습니다.
  • 경우 모드 변경이 완전히 무시되고 core.filemode있다 false(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)

비 생산 등급의 1 라이너 (마스크를 완전히 대체) :

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 로 이동합니다 )


-2

가장 쉬운 방법은 권한을 다시 변경하는 것입니다. @kroger가 지적했듯이 git은 실행 비트 만 추적합니다. 따라서 chmod -x filename문제를 해결하기 위해 실행해야 할 수도 있습니다 (또는 +x필요한 경우).


여기에서의 예이다 git show: DIFF --git A / OpenWatch / SRC / 조직 / ALE / openwatch / FB / FBUtils.java B / OpenWatch / SRC / 조직 / ALE / openwatch / FB / FBUtils.java 인덱스 cd6fa6a..e5b0935 100,644 그 굵은 글씨로 파일 사용 권한이 있습니다.
Conrado

이것은 나에게 가장 쉬운 것처럼 보였다. 불행히도 Conrado와 동일한 문제가 발생하여 권한을에서 (으) 100644로 변경할 수 없습니다 100755. 나는 당신이 공감대를받을 자격이 없다고 생각합니다. 힘내는 투표를 받아야합니다. 그것은 많은 다른 수준에서 너무나 많은 방식으로 깨졌습니다 ...
jww

-2

etckeeper도구 는 다음을 사용하여 권한을 처리 할 수 ​​있습니다.

etckeeper init -d /mydir

이외의 다른 디렉토리에 사용할 수 있습니다 /etc.

패키지 관리자를 사용하여 설치하거나 위 링크에서 소스를 얻으십시오.


4
권한을 무엇으로 설정합니까? Git 메타 데이터를 읽지 않거나 Git을 호출하면 OP가 요청한 작업을 수행하지 않습니다.
ivan_pozdeev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.