2017-10-20 4 views
0

모든 .cpp 파일에 대해 git 커밋 전에 코드 스타일 서식을 설정하고 싶습니다. 나는이 작업을 수행하는 작은 스크립트 (이름 codeformat)를 만들어쉘 스 크립트를 통해 .cpp 파일을 처리하기 위해 smudge/clean 필터를 사용하는 git 속성. 파일 이름을 찾을 수 없습니다.

(또한 $ 1 %의 F를 replaing 시도)

#! /bin/bash 
clang-format -style=file %f | diff %f -** 
if [ $? -ne 0 ]; then 
    echo "ERROR: codeformat not correct" 
    exit 1 
fi 

한 설정 자식 설정과 * .CPP 필터 = codeformat와 업데이트 .gitattributes,

git config --global filter.codeformat.clean codeformat 
git config --global filter.codeformat.smudge codeformat 

스크립트가 실행중인 것처럼 보이지만 파일 이름을 가져 오지 못했습니다. 왜 이런거야?

답변

1

%f 지시문이 잘못된 위치에 있습니다. (%f에 대한 검색) the gitattributes documentation에 나타낸 바와 같이

:

따라서

Sequence "%f" on the filter command line is replaced with the name of the file the filter is working on. A filter might use this in keyword substitution. For example:

[filter "p4"] 
     clean = git-p4-filter --clean %f 
     smudge = git-p4-filter --smudge %f 

이 파일의 경로 이름을 얻으려면, 당신은 codeformat %f에, 예를 들어, filter.codeformat.clean을 설정해야합니다.

대체 인수 구문이 실제로 $1이므로이 시점에서 bash 스크립트를 수정해야합니다. 그러나, gitattributes 문서에서 바로 다음 단락 읽기 :

Note that "%f" is the name of the path that is being worked on. Depending on the version that is being filtered, the corresponding file on disk may not exist, or may have different contents. So, smudge and clean commands should not try to access the file on disk, but only act as filters on the content provided to them on standard input.

여기서 강조 광산이다, 그러나 이것은 단순히 디스크의 파일을 열고 읽을 수 없음을 말하고있다. 표준 입력 만 필터링하여 표준 출력을 제공해야합니다.

( As it turns out, clang-format is designed to do just that. DIFF하지만,하지 않습니다.)


편집 작업을 예를 추가 :

$ cat ~/scripts/dotest 
#! /bin/sh 
echo "dotest run with $# arguments:" >>/tmp/dotest_log 
for i do 
    printf '%s\n' "$i" 
done >>/tmp/dotest_log 
cat 
$ which dotest 
[path edited]/scripts/dotest 
$ cat .git/config 
[core] 
     repositoryformatversion = 0 
     filemode = true 
     bare = false 
     logallrefupdates = true 
[filter "testfilter"] 
     clean = dotest %f 
     smudge = dotest %f 
$ cat .gitattributes 
*.test filter=testfilter 
$ echo 'bar.test' > bar.test 
$ git add bar.test 
$ cat /tmp/dotest_log 
dotest run with 1 arguments: 
bar.test 
+0

참조 추가 예제를 작업. 난 당신이 다른 짓을하지만, 내 스크립트 파일로 호출 모르겠어요 name :/tmp의 로그 파일에 표시된대로. – torek

+0

이것은 이전에 git config를 실행하는 데 실패했습니다. git config - global을 실행했지만, 전역 적으로 "git config"만 실행하여 .git/config에서 업데이트를 얻지 않으면 ~ /에서 업데이트됩니다. gitconfig. 지금, 그 파일 이름을 인쇄, 나는 지금 내 코드 형식의 명령을 가지고 놀 필요가있다. – Ramana

+0

우리는 화면에 오류 메시지를 쓸 수 있습니까?,/tmp/dotest_log에서 내용을 말할 수 있습니까? 내가 로그에 리디렉션 대신 에코 명령을 가지고, 그것은 로그를 작성하지 않습니다, 그것은 단지 메시지 오류 필터를 제공합니다 ... 목표는 사용자가 따라갈 수있는 메시지를 제공하는 것입니다 또한, 스크립트 내부 종료 자식 작동, 내 자식 add가 성공하더라도 스크립트가 실패하더라도 계속 고칠 때까지 git add 명령을 실패 할 수 있습니까? – Ramana

0

%fgit에 의해 해석되고 gitconfig에 있어야합니다. 쉘 스크립트를 사용 $1에서 :

의미
git config --global filter.codeformat.clean 'codeformat %f' 
git config --global filter.codeformat.smudge 'codeformat %f' 

#! /bin/bash 
clang-format -style=file $1 | diff $1 -** 
if [ $? -ne 0 ]; then 
    echo "ERROR: codeformat not correct" 
    exit 1 
fi 
+0

나는 그것을 시도했다, 도움이되지 않았다, 더 많은 세부 사항을 아래에서 보라. – Ramana

0

, 난 파일 이름을 얻을 수 없다?, 난 여전히 파일 이름을 얻을하지 않습니다, 자식 설정 자체 및 변경 스크립트 $ 1을 사용하는 f 제어 %을 시도했다. (아래) 내가 명령 줄에서 실행하는 경우

cat ~/.gitconfig 

[filter "codeformat"] 
     clean = codeformat %f 
     smudge = codeformat %f 

cat .gitattributes 
    #clang code style format 
    *.cpp       filter=codeformat 

cat codeformat 
    #! /bin/bash 
    clang-format -i -style=file $1 - 
    echo "file/path accessed is _____ $1 ____" > log_output 2>&1 

git add src/sample.cpp 

    cat log_output 
    file/path accessed is _____ ____ 

같은 명령을 자식으로

clang-format -i -style=file src/sample.cpp 

그것이 오류 파일 이름 때문에 다른 오류를 얻을 수 추가, 잘 작동 : 읽을 때 -i를 사용할 수 없습니다 stdin에서.

주이 시간, 난, DIFF 명령을 제거 "직접 소스 파일을 대체 -i를 사용

관련 문제