- 디버깅
-
git push
에서의 ‘broken pipe’ 오류 ssh_exchange_identification
오류git push
/git pull
중 시간 초과git clone
에서transfer closed with outstanding read data remaining
오류가 발생하는 HTTP 실패- SSH를 통한 Git fetch에서 비밀번호 만료 오류
- Git fetch 오류: “HTTP 기본: 액세스 거부됨”
git clone
중 기록된401
오류- HTTP를 통한 Git 작업 시
403
오류 발생
Git 문제 해결
Git을 사용할 때 의도한 대로 작동하지 않거나 예상대로 작동하지 않을 때가 있습니다. 다음은 Git 문제 해결과 문제 해결에 대한 팁입니다.
디버깅
Git 문제 해결 시 다음 디버깅 기술을 시도해보세요.
Git 명령에 사용자 정의 SSH 키 사용
GIT_SSH_COMMAND="ssh -i ~/.ssh/gitlabadmin" git <command>
클론 문제 해결
SSH를 통한 Git의 경우:
GIT_SSH_COMMAND="ssh -vvv" git clone <git@url>
HTTPS를 통한 Git의 경우:
GIT_TRACE_PACKET=1 GIT_TRACE=2 GIT_CURL_VERBOSE=1 git clone <url>
추적(traces)을 사용하여 Git 디버깅
Git은 각각의 트레이스를 통해 Git 명령의 디버깅을 포함하고 있습니다. 예를 들어:
-
GIT_TRACE_PERFORMANCE=1
: 각각의git
호출이 얼마나 오래 걸리는지 보여주는 성능 데이터 추적을 활성화합니다. -
GIT_TRACE_SETUP=1
:git
이 상호 작용하는 리포지터리와 환경에 대해 발견하는 것을 추적합니다. -
GIT_TRACE_PACKET=1
: 네트워크 작업의 패킷 수준 추적을 활성화합니다.
git push
에서의 ‘broken pipe’ 오류
‘Broken pipe’ 오류는 원격 리포지터리로 푸시를 시도할 때 발생할 수 있습니다. 보통 푸시할 때 다음과 같은 메시지가 표시됩니다:
Write failed: Broken pipe
fatal: The remote end hung up unexpectedly
이 문제를 해결하려면 가능한 해결책이 있습니다.
Git의 POST 버퍼 크기 증가
SSH 대신 Git을 HTTP를 통해 사용하는 경우, Git 구성에서 POST 버퍼 크기를 증가시켜 볼 수 있습니다.
클론 중에 오류가 발생하는 예시:
fatal: pack has bad object at offset XXXXXXXXX: inflate returned -5
터미널을 열고 다음을 입력하세요:
git config http.postBuffer 52428800
위 예에서 값은 바이트로 지정되어 있으며, 이 경우 버퍼 크기는 50MB로 설정되었습니다. 기본값은 1MB입니다.
0이 깨끗하게 닫히지 않은 스트림
이 오류가 표시되면 인터넷 연결이 느린 것으로 인한 것일 수 있습니다.
RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)
SSH 대신 Git을 HTTP를 통해 사용하는 경우 다음 중 하나를 시도해보세요:
-
git config http.postBuffer 52428800
를 사용하여 Git 구성에서 POST 버퍼 크기를 증가시킵니다. -
git config http.version HTTP/1.1
로HTTP/1.1
프로토콜로 전환합니다.
이러한 접근 방법 모두 오류를 수정하지 못하면 다른 인터넷 서비스 제공업체가 필요할 수 있습니다.
SSH 구성 확인
SSH를 통해 푸시하는 경우, ‘Broken pipe’ 오류가 때때로 SSH의 기본 문제(인증과 같은)로 인해 발생할 수 있습니다. SSH 구성이 올바로 되어 있는지 SSH 문제 해결 설명서의 지침을 따라 올바르게 구성되어 있는지 확인하세요.
서버 액세스 권한을 가진 GitLab 관리자인 경우, 클라이언트나 서버에서 SSH keep-alive
를 구성함으로써 세션 시간 초과를 방지할 수도 있습니다.
클라이언트 측에서 SSH를 구성하기 위해서:
-
UNIX의 경우,
~/.ssh/config
를 편집하세요(파일이 없으면 생성) 그리고 다음을 추가하거나 편집하세요:Host your-gitlab-instance-url.com ServerAliveInterval 60 ServerAliveCountMax 5
-
Windows의 경우, PuTTY를 사용하는 경우 세션 속성으로 들어가서 “Connection”으로 이동한 다음 “Sending of null packets to keep session active” 아래의
Seconds between keepalives (0 to turn off)
를60
으로 설정합니다.
서버 측에서 SSH를 구성하기 위해서, /etc/ssh/sshd_config
를 편집하고 다음을 추가하세요:
ClientAliveInterval 60
ClientAliveCountMax 5
git repack
실행
‘pack-objects’ 유형의 오류도 표시되는 경우, 원격 리포지터리로 다시 푸시하기 전에 git repack
을 실행해 볼 수 있습니다:
git repack
git push
Git 클라이언트 업그레이드
Git의 이전 버전(< 2.9)을 실행 중이라면, Git 리포지터리로 푸시할 때 broken pipe 발생을 참조하여 >= 2.9로 업그레이드를 고려해보세요.
ssh_exchange_identification
오류
Git을 SSH를 통해 푸시하거나 풀어야 할 때 다음과 같은 오류를 경험할 수 있습니다:
Please make sure you have the correct access rights
and the repository exists.
...
ssh_exchange_identification: read: Connection reset by peer
fatal: Could not read from remote repository.
또는
ssh_exchange_identification: Connection closed by remote host
fatal: The remote end hung up unexpectedly
또는
kex_exchange_identification: Connection closed by remote host
Connection closed by x.x.x.x port 22
이 오류는 보통 SSH 데몬의 MaxStartups
값이 SSH 연결을 제한하기 때문입니다. 이 설정은 SSH 데몬에 대한 최대 동시, 인증되지 않은 연결을 지정합니다. 이것은 모든 연결이 처음에는 ‘인증되지 않은’이기 때문에 적합한 인증 자격 증명(SSH 키)을 갖춘 사용자에게 영향을 미칩니다. 기본값은 10
입니다.
GitLab 서버의 MaxStartups
를 높이기 위해 /etc/ssh/sshd_config
에서 값을 추가하거나 수정하세요:
MaxStartups 100:30:200
100:30:200
은 제한 없이 최대 100개의 SSH 세션을 허용하고, 이후 30%의 연결이 절단되어 절대 최대 200개에 도달할 때까지입니다.
MaxStartups
의 값 수정 후, 구성에 오류가 없는지 확인하세요.
sudo sshd -t -f /etc/ssh/sshd_config
구성 확인이 오류 없이 실행되면, 변경 사항이 적용되도록 SSH 데몬을 재시작해야 합니다.
# Debian/Ubuntu
sudo systemctl restart ssh
# CentOS/RHEL
sudo service sshd restart
git push
/ git pull
중 시간 초과
소유하고 있는 리포지터리로부터 풀링/푸시가 50초 이상 소요되면, 시간 초과가 발생합니다. 아래 예시와 같이 수행된 작업의 수와 각 작업에 대한 시간 등을 로그에 포함합니다.
remote: Running checks for branch: master
remote: Scanning for LFS objects... (153ms)
remote: Calculating new repository size... (cancelled after 729ms)
이것은 어떤 작업이 잘 수행되지 않는지 더 깊게 조사하고 GitLab에 더 많은 정보를 제공할 수 있습니다.
git clone
에서 transfer closed with outstanding read data remaining
오류가 발생하는 HTTP 실패
때로는 오래된 또는 큰 리포지터리를 클론할 때 다음과 같은 오류가 발생할 수 있습니다:
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
이 문제는 Git 자체에서 발생하는데, 큰 파일이나 많은 파일을 처리할 수 없기 때문입니다. Git LFS는 이 문제를 해결하기 위해 만들어졌으나, 제한이 있습니다. 보통 다음 중 하나 때문입니다:
- 리포지터리의 파일 수
- 이력에서의 수정 수
- 리포지터리 안의 큰 파일의 존재
근본적인 원인이 다양하기 때문에 여러 가지 해결책이 있으며, 하나 이상 적용해야 할 수 있습니다:
-
이 오류가 큰 리포지터리를 클론할 때 발생하는 경우, 클론 깊이를
1
로 줄이기할 수 있습니다. 예를 들어:variables: GIT_DEPTH: 1
-
로컬 Git 구성에서 기본값 1MB보다 큰 값으로 http.postBuffer 값을 늘릴 수 있습니다. 예를 들어, 500MB 리포지터리를 클론할 때
git clone
에서 실패한다면,http.postBuffer
를524288000
으로 설정해야 합니다:# http.postBuffer 크기를 바이트 단위로 설정 git config http.postBuffer 524288000
-
서버 측에서
http.postBuffer
를 늘릴 수 있습니다:-
GitLab 인스턴스의
gitlab.rb
파일을 수정하세요:gitaly['configuration'] = { # ... git: { # ... config: [ # http.postBuffer 크기를 바이트 단위로 설정 {key: "http.postBuffer", value: "524288000"}, ], }, }
-
이 변경 사항을 적용한 후, 구성 변경을 적용하세요:
sudo gitlab-ctl reconfigure
-
리포지터리의 이력이 매우 긴데 큰 파일이 없는 경우, 깊이를 변경하는 것으로 문제를 해결할 수 있습니다. 그러나 리포지터리에 매우 큰 파일이 있는 경우에는 깊이가 1인 경우에도 충분하지 않을 수 있으므로 postBuffer
변경이 필요합니다.
로컬 postBuffer
를 늘렸지만 백엔드의 NGINX 값이 여전히 작으면 오류가 지속됩니다.
서버를 수정하는 것은 항상 선택사항은 아니며, 더 많은 잠재적인 위험을 수반하므로, 먼저 로컬 변경을 시도해보세요.
SSH를 통한 Git fetch에서 비밀번호 만료 오류
git fetch
를 실행하면 GitLab의 온프레미스 인스턴스에서 HTTP 403 금지됨
오류가 발생할 때, GitLab 데이터베이스의 해당 사용자의 비밀번호 만료 날짜(users.password_expires_at
)가 과거 날짜로 설정되어 있는 경우입니다:
비밀번호가 만료되었습니다. 비밀번호를 업데이트하려면 웹 브라우저에서 GitLab에 액세스하세요.
SSO(Single Sign-On) 계정을 사용하고 password_expires_at
이 null
이 아닌 경우 다음과 같은 오류가 발생합니다:
"403 금지됨 - 비밀번호가 만료되었습니다. 비밀번호를 업데이트하려면 웹 브라우저에서 GitLab에 액세스하세요."
이 문제를 해결하려면 비밀번호 만료를 업데이트할 수 있습니다. 방법은 다음과 같습니다:
-
gitlab-rails console
사용:gitlab-rails console user.update!(password_expires_at: nil)
-
gitlab-psql
사용:# gitlab-psql UPDATE users SET password_expires_at = null WHERE username='<USERNAME>';
이 버그는 이 이슈에서 보고되었습니다.
Git fetch 오류: “HTTP 기본: 액세스 거부됨”
HTTP(S)를 통해 Git을 사용할 때 HTTP 기본: 액세스 거부됨
오류가 발생하면 이중 인증 문제 해결 가이드를 참조하십시오.
git clone
중 기록된 401
오류
HTTP를 통해 리포지터리를 복제할 때, production_json.log
파일에 초기 상태로 401
(인가되지 않음)이 표시될 수 있으며 이 오류는 빠르게 200
으로 전환됩니다.
{
"method":"GET",
"path":"/group/project.git/info/refs",
"format":"*/*",
"controller":"Repositories::GitHttpController",
"action":"info_refs",
"status":401,
"time":"2023-04-18T22:55:15.371Z",
"remote_ip":"x.x.x.x",
"ua":"git/2.39.2",
"correlation_id":"01GYB98MBM28T981DJDGAD98WZ",
"duration_s":0.03585
}
{
"method":"GET",
"path":"/group/project.git/info/refs",
"format":"*/*",
"controller":"Repositories::GitHttpController",
"action":"info_refs",
"status":200,
"time":"2023-04-18T22:55:15.714Z",
"remote_ip":"x.x.x.x",
"user_id":1,
"username":"root",
"ua":"git/2.39.2",
"correlation_id":"01GYB98MJ0CA3G9K8WDH7HWMQX",
"duration_s":0.17111
}
Git 작업을 수행할 때마다 초기 401
로그 항목을 예상해야 합니다. 이는 HTTP 기본 인증 작동 방식으로 인해 발생합니다.
Git 클라이언트가 복제를 시작하면 GitLab에 보내는 초기 요청에는 인증 세부 정보가 제공되지 않습니다. GitLab은 해당 요청에 대해 401 Unauthorized
결과를 반환합니다. 그 후 몇 밀리초 후에 Git 클라이언트가 인증 세부 정보를 포함하는 후속 요청을 보냅니다. 이 두 번째 요청은 성공해야 하며 200 OK
로그 항목으로 나타납니다.
401
로그 항목이 해당하는 200
로그 항목이 없는 경우, Git 클라이언트는 다음 중 하나를 사용하는 것으로 보입니다:
- 잘못된 암호.
- 만료되었거나 취소된 토큰.
해당되지 않는 경우, 403 (금지됨) 오류가 발생할 수 있습니다.
HTTP를 통한 Git 작업 시 403
오류 발생
HTTP를 통해 Git 작업을 수행할 때, 403
(금지됨) 오류는 인증에 실패하여 IP 주소가 차단되었음을 나타냅니다:
fatal: unable to access 'https://gitlab.com/group/project.git/': The requested URL returned error: 403
production_json.log
에서 403
를 확인할 수 있습니다:
{
"method":"GET",
"path":"/group/project.git/info/refs",
"format":"*/*",
"controller":"Repositories::GitHttpController",
"action":"info_refs",
"status":403,
"time":"2023-04-19T22:14:25.894Z",
"remote_ip":"x.x.x.x",
"user_id":1,
"username":"root",
"ua":"git/2.39.2",
"correlation_id":"01GYDSAKAN2SPZPAMJNRWW5H8S",
"duration_s":0.00875
}
IP 주소가 차단된 경우, auth_json.log
에 해당하는 로그 항목이 있습니다:
{
"severity":"ERROR",
"time":"2023-04-19T22:14:25.893Z",
"correlation_id":"01GYDSAKAN2SPZPAMJNRWW5H8S",
"message":"Rack_Attack",
"env":"blocklist",
"remote_ip":"x.x.x.x",
"request_method":"GET",
"path":"/group/project.git/info/refs?service=git-upload-pack"}