본문 바로가기
프로그래밍 놀이터/Tips

[도서 정리] 10. Git 의 내부 - ProGit

by 돼지왕왕돼지 2020. 1. 15.

[도서 정리] 10. Git 의 내부 - ProGit



-

git 이 얼마나 유연하고 강력한지 이해하려면 이 장의 내용을 꼭 알아야 한다.



-

git 은 기본적으로 content-addressable 파일 시스템이고, 그 위에 vcs 사용자 인터페이스가 있는 구조다.

git 초기에는 사용자 인터페이스가 훨씬 복잡했었다.

VCS 가 아니라 파일 시스템을 강조했었기 때문이다.





10.1. Plumbing 명령과 Porcelain 명령


-

매우 많은 저수준 명령어로 구성돼 있고 이 명령어들을 유닉스 스타일로 엮어서 실행하거나 스크립트로 만들어 사용하도록 설계되었다.

이런 저수준 명령어는 Plumbing 명령어라 부르고, 좀 더 사용자에게 친숙한 사용자용 명령어는 Porcelain 명령어라고 부른다.



-

Plumbing 명령어는 직접 커맨드라인에서 실행하기보다 새로운 도구를 만들거나 각자 필요한 스크립트를 작성할 때 사용한다.



-

.git 디렉터리의 구조는 아래와 같다.


HEAD

index

config

description

hooks/

info/

objects/

refs/

packed-refs


이 외에도 다른 파일들이 더 있지만, 기본적으로 위와 같다.



-

description 파일은 기본적으로 GitWeb 프로그램에서만 사용한다.

config 파일에는 해당 프로젝트에만 적용되는 설정 옵션이 들어 있다.

info 디렉터리는 .gitignore 파일처럼 무시할 파일의 패턴을 적어놓는다. 그러나 .gitignore 처럼 git 으로 관리되지 않는다.

hooks 디렉터리에는 클라 훅이나 서버 훅이 위치한다.



-

HEAD 파일, index 파일, objects 디렉터리, refs 디렉터리가 git 의 핵심이다.

objects 디렉터리는 모든 콘텐츠를 저장하는 db 이고, 

refs 디렉터리에는 커밋 개체의 포인터를 저장한다.

HEAD 파일은 현재 checkout 한 브랜치를 가리키고

index 파일은 staging area 정보를 저장한다.





10.2. git 개체


-

git 은 content-addressable 파일 시스템이다.

git 의 핵심은 단순한 key-value 데이터 저장소라는 것이다.

어떤 형식의 데이터라도 넣을 수 있고, 해당 key 로 데이터를 다시 가져올 수 있다.



-

git 은 init 명령으로 저장소를 초기화할 때 objects 디렉터리를 만들고 그 밑에 pack 과 info 디렉터리도 만든다.



-

$ echo ‘test content’ | git hash-object -w —stdin


표준입력으로 들어오는 데이터를 저장한다. -w 옵션을 줘야 실제로 저장한다.

-w 가 없으면 저장하지 않고 key 만 보여준다.

—stdin 대신 파일 경로를 줄 수도 있다.


hash-object 명령이 출력하는 것은 40자 길이의 체크섬 해시다.

이 해시는 헤더 정보와 데이터 모두에 대한 sha-1 해시이다.


objects 에 파일이 하나 생기고, 데이터는 새로 만든 파일에 저장하며, git 은 데이터를 저장할 때 데이터와 헤더로 생성한 sha-1 체크섬으로 파일 이름을 짓는다.

해시의 처음 두 글자를 따서 디렉터리 이름에 사용하고 나머지 38글자를 파일 이름에 사용한다.



-

cat-file 명령으로 저장한 데이터를 불러올 수 있다.

이 명령은 git 개체를 살펴보고 싶을 때 사용하며, -p 옵션을 주면 파일 내용이 출력된다.

$ git cat-file -p <file_name>



-

단지 파일 내용만 저장하는 개체를 blob 개체라 부른다.

cat-file -t 로 개체의 종류를 확인할 수 있다.




* Tree 개체


-

Tree 개체에 파일 이름을 저장한다.

파일 여러 개를 한꺼번에 저장할 수도 있다.

git 은 모든 것을 tree 와 blob 개체로 저장한다.

tree 는 유닉스의 디렉터리에 대응되고, blob 은 inode 나 blob 개체로 저장한다.



-

tree 개체 하나는 항목을 여러 개 가질 수 있다.

그리고 그 항목에는 blob 개체나 하위 tree 개체를 가리키는 sha-1 포인터, 파일 모드, 개체 타입, 파일 이름이 들어 있다.



-

$ git cat-file -p master^{tree}


이 구문은 master 브랜치가 가리키는 tree 개체를 보여준다.



-

git 은 일반적으로 staging area(index)의 상태대로 tree 개체를 만들고 기록한다.



-

$ git update-index —add —cacheinfo 100644 sha_1 test.txt


위 명령은 test.txt 파일을 index 에 인위적으로 추가한다.


100644 는 보통 파일이고, 실행파일이면  100755 로 지정한다. 심볼릭 링크라면 120000 으로 지정한다.

파일 모드는 유닉스에서 가져왔지만, 유닉스 모드를 전부 사용하지는 않는다.

blob 파일에는 이 세가지 모드를 사용하고, 디렉터리나 서브모듈에는 다른 모드를 사용한다.


db 에 있는 파일을 추가하는 것이기 때문에 --cacheinfo 옵션이 필요하다.



-

staging area 를 tree 개체로 저장할 때는 write-tree 명령을 사용한다.


$ git write-tree



-

tree 개체를 하위 디렉터리로 만들 수 있다.

read-tree 명령으로 tree 개체를 읽어 staging area 에 추가한다.

—prefix 옵션을 주면 tree 개체를 하위 디렉터리로 추가할 수 있다.

$ git read-tree —prefix=bak sha_1

$ git write-tree

$ git cat-file -p write_tree_sha1




* 커밋 개체


-

스냅샷을 누가, 언제, 왜 저장했는지에 대한 정보는 커밋 개체에 저장된다.

커밋 개체는 commit-tree 명령으로 만든다.

이 명령에 커밋 개체에 대한 설명과 tree 개체의 sha-1 값 한 개를 넘긴다.

$ echo ‘first commit’ | git commit-tree sha_1


해당 스냅샷에서 최상단 tree 를 하나 가르키게 된다.

그리고 user.name, user.email 설정에서 가져온 author/committer 정보, 시간 정보, 메시지 등이 들어간다.



-

$ echo ‘second commit’ | git commit-tree new_sha_1 -p prev_sha_1



-

git 은 변경된 파일을 blob 개체로 저장하고 현 index 에 따라서 tree 개체를 만든다.

그리고 이전 커밋 개체와 최상위 tree 개체를 참고해서 커밋 개체를 만든다.

즉, blob, tree, 커밋 개체가 git 의 주요 개체이고 이 개체는 전부 .git/objects 디렉터리에 저장된다.




* 개체 저장소


-

git 은 개체의 타입을 시작으로 헤더를 만든다.

그 다음에 공백 문자 하나, 내용의 크기, 마지막에 널 문자를 추가한다.


git 은 헤더와 원래 내용을 합쳐 sha-1 체크섬을 계산한다.

git 은 zlib 으로 내용을 압축한다.

마지막으로 zlib 으로 압축한 내용을 개체로 저장한다.

SHA-1 값 중 맨 앞에 있는 두 자를 가져다 하위 디렉터리 이름으로 사용하고 나머지 38자를 그 디렉터리 안에 있는 파일 이름으로 사용한다.





10.3. Git Refs


-

git log 1a410e 라고 하면 전체 히스토리를 볼 수 있지만, 여전히 1a410e 를 기억해야 한다.

SHA-1 값을 날로 사용하기보다 쉬운 이름으로 된 포인터가 있으면 그걸 사용하는 게 더 좋다.

외우기 쉬운 이름으로 된 파일에 sha-1 값을 저장한다.

git 에서는 이런 것을 references 또는 refs 라고 부른다.

sha-1 값이 든 파일은 .git/refs 디렉터리에 있다.



-

refs 가 있으면 커밋을 찾기 쉬워진다.

사실 내부는 아래처럼 단순하다.


$ echo “sha_1” > .git/refs/heads/master


update-ref 를 통해 ref 를 바꿀 수 있다.


$ git update-ref refs/heads/master new_sha_1


git 의 브랜치의 역할이 바로 이거다.

브랜치는 어떤 작업 중 마지막 작업을 가리키는 포인터 또는 refs 다.




* HEAD


-

HEAD 파일은 현 브랜치를 가리키는 간접(symbolic) refs 다.

간접 refs 라서 다른 것과 다르다.

이 Refs 는 다른 Refs 를 가리키는 것이라서 SHA-1 값이 없다.



-

아래 명령을 통해 HEAD 가 가리키는 녀석을 알 수 있다.

$ git symbolic-ref HEAD


HEAD 값을 변경할수도 있다.

$ git symbolic-ref HEAD refs/heads/test




* 태그


-

태그 개체는 커밋 개체랑 매우 비슷하다.

커밋 개체처럼 누가, 언제 태그를 달았는지 태그 메시지는 무엇이고 어떤 커밋을 가리키는지에 대한 정보가 포함된다.

태그 개체는 tree 개체가 아니라 커밋 개체를 가리키는 것이 그 둘의 차이다.

브랜치처럼 커밋 개체를 가리키지만 옮길 수는 없다.

한 개의 커밋만 가리킨다.



-

아래 명령으로 lightweight 태그를 만들 수 있다.

$ git update-ref refs/tags/v1.0 sha_1


annotated 태그를 만들면 git 은 태그 개체를 만들고 거기에 커밋을 가리키는 refs 를 저장한다.

annotated 태그는 커밋을 직접 가리키지 않고 태그 개체를 가리킨다. 

ex) 

$ git tag -a v1.1 sha_1 -m ‘test tag’


object 부분에 있는 sha-1 값이 실제로 태그가 가리키는 커밋이다.

커밋 개체뿐만 아니라 모든 git 개체에 태그를 달 수 있다.




* 리모트


-

리모트를 추가하고 push 하면 git 은 각 브랜치마다 push 한 마지막 커밋이 무엇인지 refs/remote 디렉터리에 저장한다.



-

refs/heads 에 있는 refs 인 브랜치와 달리 리모트 refs 는 checkout 할 수 없고 일기 용도로만 쓸 수 있는 브랜치이다.

이 리모트 refs 는 서버의 브랜치가 가리키는 커밋이 무엇인지 적어둔 일종의 북마크다.







10.4. Packfile


-

git 은 zlib 으로 파일 내용을 압축하기 때문에 저장 공간이 많이 필요치 않다.



-

git 이 처음 개체를 저장하는 형식은 loose 개체 포맷이라고 부른다.

나중에 이 개체를 파일 하나로 압축(Pack)할 수 있다.

이렇게 하여 공간을 절약하고 효율을 높일 수 있다.

git 은 loose 개체가 너무 많을 때, git gc 명령을 실행했을 때, 리모트 서버로 push 할 때 이렇게 압축한다.



-

git gc 를 수행하여 pack 이 되면...

pack 할 수 없는 녀석들은 objects 에 남는다. (dangling 개체)

그리고 할 수 있는 녀석은 objects/pack 폴더 안에 2개의 파일 형태로 생성된다.

새로 생긴 파일들은 Packfile 과 그 index 이다.

Index 파일에는 Packfile 에서 빠르게 찾을 수 있도록 오프셋이 들어 있다.



-

개체를 압축시키면 git 은 먼저 이름이나 크기가 비슷한 파일을 찾는다.

그리고 두 파일을 비교해서 한 파일은 다른 부분만 저장한다.

git 이 얼마나 공간을 절약해 주는지 packfile 을 열어 확인할 수 있다.


$ git verify-pack -v .git/objects/pack/pack_idx_file.idx


특이한 것은 원본을 저장하는 것이 첫번째가 아니라 두 번째 버전이라는 것이다.

첫 번째 버전은 차이점만 저장된다.

최신 버전에 접근할 때가 더 많고 최신 버전에 접근하는 속도가 더 빨라야 하기 때문에 이렇게 한다.



-

언제나 다시 압축할 수 있기에 이 기능은 정말 환상적이다.

git 은 가끔 자동으로 db 를 재압축해서 공간을 절약한다.

그리고 git gc 명령으로 직접 압축할 수도 있다.





10.5. Refspec


-

Refspec 형식은 + 와 <src>:<dest> 로 돼 있다.

+ 는 생략 가능하고, <src> 는 리모트 저장소의 refs 패턴이고 <dst> 는 매핑되는 로컬 저장소의 refs 패턴이다.

+ 는 fast-forward 가 아닌 업데이트를 허용하는 것이다.



-

기본적으로 git 은 git remote add 명령으로 생성한 설정을 참고하여 리모트 서버에서 refs/head/ 에 있는 refs 를 가져다 로컬의 refs/remotes/origin 에 기록한다.

로컬에서 서버에 있는 master 브랜치에 접근할 때 아래 3개의 명령은 같다.

$ git log origin/master

$ git log remotes/origin/master

$ git log refs/remotes/origin/master



-

master 브랜치만 가져올 수 있게 하려면 .git/config 의 refspec 을 고쳐야 한다.


# .git/config

[remote “origin”]

    url=https://github.com/myid/myproject

    fetch=+refs/heads/*;refs/remotes/origin/*

fetch 부분을 +refs/heads/master:refs/remotes/origin/master 로 바꿔야 한다.


fetch 를 할 때 option 을 줄 수도 있다.

$ git fetch origin master:refs/remotes/origin/mymaster

위 명령은 리모트 브랜치 master 를 로컬 브랜치 origin/mymaster 로 가져온다.


refspec 을 여러 개 넘겨도 된다.

그럼 한꺼번에 여러 개의 브랜치를 가져온다.




* Refspec Push 하기


-

master 브랜치를 리모트 저장소에 qa/master 로 push 하려면 아래와 같이 한다.

$ git push origin master:refs/heads/qa/master




* Refs 삭제하기


-

Refspec 으로 서버에 있는 Refs 를 삭제할 수 있다.


$ git push origin :topic


Refspec 의 형식은 <src>:<dst> 이니까 <src> 를 비우고 실행하면 <dst>를 비우라는 명령이 된다.

즉 위 명령은 topic 브랜치를 삭제한다.





10.6. 데이터 전송 프로토콜


-

git 에서 데이터를 전송할 때 멍청한 프로토콜과 스마트 프로토콜 이렇게 두 가지 종류의 프로토콜을 사용한다.




* 멍청한 프로토콜


-

읽기전용으로만 사용하는 HTTP 저장소를 clone 하거나 fetch 할 때가 멍청한 프로토콜을 사용하는 때이다.

멍청한 프로토콜이라 부르는 이유는 서버가 데이터를 전송할 때 git 에 최적화된 어떤 작업도 전혀 사용하지 않기 때문이다.

단지 fetch 과정은 http get 요청을 여러 번 보낼 뿐이다.



-

요즘은 멍청한 프로토콜을 사용하는 경우가 드물다.

멍청한 프로토콜을 사용하면 데이터 전송을 비밀스럽게 하기 어려워서 비공개용 저장소의 데이터를 전송하기에 적합하지 않다.

스마트 프로토콜을 사용하는 것이 좋다.




* 스마트 프로토콜


-

멍청한 프로토콜은 매우 단순하다는 장점이 있으나 데이터를 효율적으로 전송할 수 없다.

스마트 프로토콜을 사용하는 것이 더 일반적이나, 이 프로토콜은 리모트 서버에서 처리해야 할 작업이 있다.



-

리모트 서버로 데이터를 업로드하는 과정은 send-pack 과 receive-pack 과정으로 나눌 수 있다.

클라는 send-pack 을, 서버는 receive-pack 을 수행한다.

정보를 주고받을 때 클라 capability, sha-1, refs 이름을 담아 보낸다.



-

데이터를 내려 받는 것은 fetch-pack 과 upload-pack 과정으로 나뉜다.

클라는 fetch-pack 을, 서버는 upload-pack 을 수행한다.




* 프로토콜 요약





10.7. 운영 및 데이터 복구


* 운영


-

git 은 때가 되면 자동으로 auto gc 를 수행한다.

이 명령이 실행되는 경우 대부분은 아무런 일도 일어나지 않는다.

loose 개체가 너무 많거나 packfile 자체가 너무 많으면 git 은 그제야 진짜로 git gc 명령으로 일하게 한다.



-

git gc 명령은 loose 개체를 모아서 packfile 에 저장하거나 작은 packfile 을 모아서 하나의 큰 packfile 로 저장한다.

아무런 커밋도 가리키지 않는 개체가 있고 오랫동안(대략 몇 달쯤) 아무도 쓰지 않는다면 개체를 삭제한다.



-

git 이 gc 를 할지말지 자동으로 판단해서 처리하도록 아래와 같이 실행할 수 있다.


$ git gc --auto


loose 개체가 7천 개가 넘거나 packfile 이 0개가 넘지 않으면 git 은 실제로 gc 작업을 실행하지 않는다.

원한다면 gc.auto 나 gc.autopacklimit 설정으로 그 숫자를 조정할 수 있다.



-

gc 명령이 하는 일 중 하나는 refs 를 파일 하나로 압축하는 일이다.

여러개의 refs 파일을 .git/packed-refs 파일로 압축해서 효율을 늘린다.

압축된 상태에서 그 안에 들어있는 refs 파일을 수정하면, refs/heads 폴더에 파일을 새로 만든다

git 은 refs 가 가리키는 sha-1 값을 찾을 때 먼저 refs 디렉터리에서 찾고 없으면 packed-refs 파일에서 찾는다.




* 데이터 복구


-

보통 작업중인 브랜치를 강제로 삭제하거나, 어떤 커밋을 브랜치 밖으로 끄집어내 버렸거나, hard reset 하면 데이터를 잃어버리는 실수를 하곤 한다.

이 데이터들을 찾으려면 git reflog 명령을 사용하면 된다.


HEAD 가 가리키는 커밋이 바뀔 때마다 git 은 남몰래 자동으로 그 커밋이 무엇인지 기록한다.

새로 커밋하거나 브랜치를 바꾸면 reflog 도 늘어난다.

git reflog 명령은 발자취를 보여준다.



-

git update-ref 명령으로도 reflog 를 남길 수 있다.



-

reflog 를 자세히 보려면 git log -g 명령을 사용해야 한다. 이는 reflog 를 log 명령 형식으로 보여준다.

잃어버린 커밋을 찾으려면 git branch branch_name lost_commit_sha_1 으로 접근할 수 있다.

$ git log -g

$ git branch <branch_name> <lost_commit_sha_1>



-

.git/logs 가 제거되면 잃어버린 commit 에는 위의 방법으로는 도달하기 어렵다.

git fsck 명령으로 db 의 integrity 를 검사할 수 있다. --full 옵션을 주면 길 잃은 개체를 모두 보여준다.


$ git fsck --full


dangling 으로 마킹된 녀석이 잃어버린 커밋이므로, 해당 sha-1 을 이용하여 복구할 수 있다.




* 개체 삭제


-

git clone 할 때 히스토리를 전부 내려받는 것이 문제가 될 때가 있을 수 있다.

git 은 모든 파일의 모든 버전을 내려받는다.

이 파일이 모두 소스 코드라면 문제가 없다. git 이 최적화를 잘하기에 데이터를 잘 압축한다. 하지만 바이너리 파일을 넣어버리면 clone 할 때마다 그 파일을 내려받는다. 다음 커밋에서 그 파일을 삭제해도 히스토리에는 그대로 남기 때문에 clone 할 때마다 포함된다.


이 문제는 subversion 이나 perforce 저장소를 git 으로 변환할 때 큰 문제가 된다.



-

git count-objects -v 명령은 사용하는 용량이 얼마나 되는지 알려준다.

size-pack 의 단위는 KB 단위이다.

$ git count-objects -v


가장 큰 파일 3개만 골라낼 수 있다.

$ git verify-pack -v .git/objects/pack/pack-29..69.idx | sort -k 3 -n | tail -3 


rev-list 명령어 --objects  옵션을 추가하여 커밋의 sha-1, blob 개체의 파일 이름 등을 볼 수 있다.

$ git rev-list --objects --all | grep <sha_1>



-

히스토리에 있는 모든 tree 개체에서 삭제하고자 하는 파일을 삭제할 수 있다.

$ git log --oneline --branches -- <file_name>

파일이 조작된 commit 들의 output 이 나온다.


$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch <file_name>' -- <output_commit_sha_1>


이 명령은 이 commit 이후의 모든 커밋을 재작성시킨다.


reflog 나 filter-branch 에 남아있는 refs 도 제거하려면, 아래와 같이 해줘야 한다.

$ rm -Rf .git/refs/original

$ rm -Rf .git/logs/

$ git gc







10.8. 환경변수


-

git 은 bash 쉘 환경에서 동작한다.

셸 환경변수에 따라 git 의 동작이 달라진다.




* git 에 영향을 주는 변수


-

GIT_EXEC_PATH 변수는 git 의 여러 subprogram(git-commit, git-diff 등)이 어디에 있는지 설정한다.

현재 설정을 확인하려면 git --exec-path 명령을 실행한다.



-

HOME 변수는 일반적으로 변경하지 않는다.

git 이 이 변수에 영향을 받는 부분은 사용자(user)전체에 영향을 주는 git 환경설정 파일을 찾을 때이다.


PREFIX 변수도 비슷한 성격으로 시스템 수준의 환경설정 파일 위치를 설정한다.

git 이 찾을 위치는 $PREFIX/etc/gitconfig 이다.



-

GIT_CONFIG_NOSYSTEM 는 시스템 수준의 환경설정 파일을 적용하지 않는다.

이 변수는 시스템 수준의 환경설정 파일이 자꾸 방해되는데 고칠 권한이 없을 경우 설정하면 유용하다.



-

GIT_PAGER 변수는 git 이 화면에 출력할 내용이 한 화면이 넘어갈 때 사용할 프로그램을 설정한다.



-

GIT_EDITOR 변수는 커밋 내용을 입력하는 상황과 같이 git 이 사용자로부터 어떤 내용을 입력받는 경우 실행시킬 편집기를 설정하는 변수이다.




* 저장소 위치 관련 변수


-

GIT_DIR 변수는 .git 디렉터리의 위치를 설정하는 변수. 이 변수의 값을 설정하지 않으면 현재 디렉터리를 ~ 나 / 까지 한 단계씩 위로 올라가며 .git 디렉터리가 있는지 찾는다.



-

GIT_CEILING_DIRECTORIES 변수는 .git 디렉터리를 찾으려 한 단계씩 위로 올라가는 작업을 제어한다.

불필요하게 .git 디렉터리를 찾아 헤메는 과정을 제어할 수 있다.



-

GIT_WORK_TREE 변수는 git 저장소가 관리하는 실제 소스 코드와 같은 파일이 위치한 디렉터리를 설정한다.

bare 저장소가 아닌 경우에만 해당한다.

이 변수를 설정하지 않으면 $GIT_DIR 에 설정한 디렉터리의 상위 디렉터리를 사용한다.



-

GIT_INDEX_FILE 변수는 index 파일의 위치를 설정한다. bare 저장소가 아닌 경우에만 해당한다.



-

GIT_OBJECT_DIRECTORY 변수는 .git/objects 디렉터리 위치를 설정한다. base 저장소가 아닌 경우에만 해당한다.



-

GIT_ALTERNATE_OBJECT_DIRECTORIES 변수는 클론으로 구분된 디렉터리 리스트로 GIT_OBJECT_DIRECTORY 에서 찾을 수 없는 개체를 찾을 때 사용할 디렉터리를 설정한다.

크기가 아주 큰 파일을 여러 프로젝트에서 공유하고 있다면 이 변수를 적절히 사용한다.




* Pathspec 관련 변수


-

pathspec 은 git 을 쓸 때 파일이나 디렉터리의 경로(* 와 같은 와일드카드 포함)를 전달할 때 어떤 방식을 사용하는가에 대해 담고 있다.

.gitignore 파일에서도 사용하고 git 명령에서도 사용한다.



-

GIT_GLOB_PATHSPECS, GIT_NOGLOB_PATHSPECS 변수로는 pathspec 을 사용할 때 와일드카드 문자로 어떤 동작을 하게 할 지 설정한다.

GIT_GLOB_PATHSPECS 변수의 값을 1로 설정하면 와일드카드 문자는 보통 사용하듯 와일드카드 역할을 한다.

GIT_NOGLOB_PATHSPECS 변수의 값을 1로 하면 와일드카드로 동작하지 않는다.


환경변수에 독립적으로 각 명령에서 이를 선택하여 사용할 때는 :(glob) 또는 :(liternal)를 명시해서 사용할 수 있다.

ex) :(glob)*.c



-

GIT_LITERAL_PATHSPECS 변수를 설정하면 GLOB 관련된 설정 모두 적용하지 않는다.

와일드카드 문자는 쓸모가 없게 된다.



-

GIT_ICASE_PATHSPECS 변수를 설정하면 대소문자를 가리지 않는다.




* 커밋 관련 변수


-

GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE,  GIT_COMITTER_NAME, GIT_COMITTER_EMAIL, GIT_COMITTER_DATE 도 있다.




*  네트워크 관련 변수


-

Git 은 HTTP 프로토콜로 데이터를 전송할 때 curl 을 사용한다.

GIT_CURL_VERBOSE 변수를 설정하면 curl lib 이 출력하는 상세한 정보를 볼 수 있다. (curl -v 와 비슷하다.)



-

GIT_SSL_NO_VERIFY 를 설정하면 SSL 인증서를 확인하지 않는다.

self-signed 인증서를 사용할 때 이 변수를 사용한다.

또는 아직 인증서를 정상적으로 발급하진 않았지만, 테스트를 위해 테스트용 인증서를 사용하는 경우도 있겠다.



-

GIT_HTTP_LOW_SPEED_TIME 에 설정한 시간 동안 GIT_HTTP_LOW_SPEED_LIMIT 에 설정한 초당 전송 바이트 수에 미치지 못하는 HTTP 전송속도가 나오면 git 은 데이터 전송을 중지한다.

이는 http.lowSpeedLimit, http.lowSpeedTIme 보다 우선한다.



-

GIT_HTTP_USER_AGENT 변수는 사용자 agent 값으로 사용할 문자열을 설정한다.

기본값은 git/2.0.0 같은 형태다.




* Diff/Merge 관련 변수


-

GIT_DIFF_OPTS 변수는 git diff 명령을 실행했을 때 변경된 부분 아래위로 보여주는 라인의 개수를 조절한다.

옵션으로 사용할 때는 -u<n> 이나 --unified=<n> 로 사용한다.



-

GIT_EXTERNAL_DIFF 변수는 diff.external 설정보다 우선한다.



-

GIT_DIFF_PATH_COUNTER 나 GIT_DIFF_PATH_TOTAL 변수의 설정은 GIT_EXTERNAL_DIFF 또는 diff.external 에 설정된 프로그램 안에서 유용하게 상요한다.

total 변수는 diff 명령이 실행할 때 보여주는 모든 파일의 개수를 나타낸다.

counter 변수는 그 파일 중 지금 몇 번째 파일을 보여주고 있는지를 1로 시작하는 index 를 담고 있다.



-

GIT_MERGE_VERBOSITY 는 recursive merge 전략에 따른 메시지 출력을 제어한다.

자세한 사항은 생략한다.




* 디버그 관련 변수


-

GIT_TRACE, GIT_TRACE_PACK_ACCESS, GIT_TRACE_PACKET, GIT_TRACE_PERFORMANCE, GIT_TRACE_SETUP 등이 있다.




* 잡동사니 변수


-

GIT_SSH, GIT_ASKPASS, GIT_NAMESPACE, GIT_FLUSH, GIT_REFLOG_ACTION 등이 있다.




* 요약





댓글0