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>

트레이스를 통한 Git 디버깅

Git에는 Git 명령 디버깅을 위한 전체 트레이스 세트가 포함되어 있습니다. 예를 들어:

  • GIT_TRACE_PERFORMANCE=1: 각 특정 git 호출이 소요되는 시간을 보여주는 성능 데이터 트레이싱을 활성화합니다.
  • GIT_TRACE_SETUP=1: git이 상호작용하는 리포지토리 및 환경에 대해 검색하고 있는 내용을 트레이싱합니다.
  • GIT_TRACE_PACKET=1: 네트워크 작업을 위한 패킷 수준의 트레이싱을 활성화합니다.

git push에서의 파이프 손상 오류

원격 리포지토리에 푸시하려고 할 때 ‘파이프 손상’ 오류가 발생할 수 있습니다.

푸시할 때 보통 다음과 같은 오류 메시지를 볼 수 있습니다:

Write failed: Broken pipe
fatal: The remote end hung up unexpectedly

이 문제를 해결하기 위해 가능한 해결 방법은 다음과 같습니다.

Git에서 POST 버퍼 크기 증가

HTTPS를 통해 대형 리포지토리를 푸시하려고 할 때 다음과 같은 오류 메시지가 표시될 수 있습니다:

fatal: pack has bad object at offset XXXXXXXXX: inflate returned -5

이 문제를 해결하려면:

  • 로컬 Git 구성에서 http.postBuffer 값을 증가시킵니다. 기본 값은 1MB입니다. 예를 들어, 500MB 리포지토리를 클론할 때 git clone이 실패하면 다음을 수행하십시오:

    1. 터미널 또는 명령 프롬프트를 엽니다.
    2. http.postBuffer 값을 증가시킵니다:

       # http.postBuffer 크기를 바이트 단위로 설정
       git config http.postBuffer 524288000
      

로컬 구성이 문제를 해결하지 못하면, 서버 구성을 수정해야 할 수도 있습니다.

이는 신중하게 수행해야 하며 서버 접근 권한이 있는 경우에만 진행해야 합니다.

  • 서버 측에서 http.postBuffer를 증가시킵니다:

    1. 터미널 또는 명령 프롬프트를 엽니다.
    2. GitLab 인스턴스의 gitlab.rb 파일을 수정합니다:

       gitaly['configuration'] = {
         # ...
         git: {
           # ...
           config: [
             # http.postBuffer 크기를 바이트 단위로 설정
             {key: "http.postBuffer", value: "524288000"},
           ],
         },
       }
      
    3. 구성 변경 사항을 적용합니다:

       sudo gitlab-ctl reconfigure
      

스트림 0이 깔끔하게 닫히지 않았습니다

이 오류가 발생하면 느린 인터넷 연결 때문에 발생할 수 있습니다:

RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)

SSH 대신 HTTP를 통해 Git을 사용하는 경우, 다음과 같은 해결 방법 중 하나를 시도해 보십시오:

  • git config http.postBuffer 52428800로 Git 구성에서 POST 버퍼 크기를 증가시킵니다.
  • git config http.version HTTP/1.1HTTP/1.1 프로토콜로 전환합니다.

어느 방법도 오류를 수정하지 못할 경우, 다른 인터넷 서비스 제공업체를 이용해야 할 수도 있습니다.

SSH 구성 확인

SSH를 통해 푸시할 경우, 먼저 ‘Broken pipe’ 오류가 SSH(인증과 같은)에서 발생하는 기본적인 문제로 인해 발생할 수 있으니 SSH 구성을 확인하세요. SSH가 올바르게 구성되었는지 확인하려면 SSH 문제 해결 문서의 지침을 따르세요.

서버 접근 권한이 있는 GitLab 관리자라면, 클라이언트나 서버에서 SSH keep-alive를 구성하여 세션 시간 초과를 방지할 수 있습니다.

note
클라이언트와 서버 모두에서 구성을 설정할 필요는 없습니다.

클라이언트 측에서 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)을 실행 중이라면, >= 2.9로 업그레이드하는 것을 고려하세요(참고: Git 저장소로 푸시할 때의 Broken pipe).

ssh_exchange_identification 오류

사용자들은 SSH를 통해 Git으로 푸시하거나 풀 할 때 다음 오류를 경험할 수 있습니다:

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입니다.

호스트의 sshd 로그를 검토하여 확인할 수 있습니다. Debian 계열 시스템의 경우 /var/log/auth.log를 참조하고, RHEL 계열의 경우 다음 오류를 확인하기 위해 /var/log/secure를 확인하세요:

sshd[17242]: error: beginning MaxStartups throttling
sshd[17242]: drop connection #1 from [CLIENT_IP]:52114 on [CLIENT_IP]:22 past MaxStartups

이 오류가 없으면 SSH 데몬이 연결을 제한하지 않음을 나타내며, 기본 문제는 네트워크와 관련이 있을 수 있습니다.

인증되지 않은 동시 SSH 연결 수 증가

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을 사용할 때 다음과 같은 오류가 발생하면, 주로 네트워크 문제를 나타냅니다:

ssh: connect to host gitlab.com port 22: Operation timed out
fatal: Could not read from remote repository

근본적인 문제를 식별하는 데 도움이 되도록:

  • 다른 네트워크에 연결하세요 (예: Wi-Fi에서 셀룰러 데이터로 전환) 로컬 네트워크 또는 방화벽 문제를 배제합니다.
  • 다음 bash 명령을 실행하여 tracerouteping 정보를 수집합니다: mtr -T -P 22 <gitlab_server>.com. MTR에 대해 배우고 그 출력을 읽는 방법에 대해서는 Cloudflare 기사 What is My Traceroute (MTR)?를 참조하세요.

오류: 남은 읽기 데이터가 있는 전송 종료

때때로, 오래되거나 큰 저장소를 복제할 때 git clone을 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로 설정할 수 있습니다. 예를 들어:

이 접근 방식은 근본 원인을 해결하지는 않지만, 성공적으로 저장소를 복제할 수 있습니다.

복제 깊이를 1로 줄이려면 다음을 실행하세요:

variables:
  GIT_DEPTH: 1

Git fetch에서 SSH로 LDAP 사용자에 대한 비밀번호 만료 오류

git fetch가 GitLab의 자체 관리 인스턴스에서 HTTP 403 Forbidden 오류를 반환하는 경우, GitLab 데이터베이스 내에서 이 사용자의 비밀번호 만료 날짜(users.password_expires_at)가 과거의 날짜입니다:

비밀번호가 만료되었습니다. 웹 브라우저에서 GitLab에 접속하여 비밀번호를 업데이트하세요.

SSO 계정을 사용하고 password_expires_atnull이 아닌 경우 다음과 같은 오류가 발생합니다:

"403 Forbidden - 비밀번호가 만료되었습니다. 웹 브라우저에서 GitLab에 접속하여 비밀번호를 업데이트하세요."

이 문제를 해결하려면 다음 방법으로 비밀번호 만료를 업데이트할 수 있습니다:

  • GitLab Rails 콘솔을 사용하여 사용자 데이터를 확인하고 업데이트하세요:

    user = User.find_by_username('<USERNAME>')
    user.password_expired?
    user.password_expires_at
    user.update!(password_expires_at: nil)
    
  • gitlab-psql을 사용하세요:

    # gitlab-psql
    UPDATE users SET password_expires_at = null WHERE username='<USERNAME>';
    

버그는 이 문제에서 보고되었습니다.

Git fetch에서의 오류: “HTTP Basic: Access Denied”

Git을 HTTP(S)를 통해 사용할 때 HTTP Basic: Access denied 오류가 발생하면, 이중 인증 문제 해결 가이드를 참조하세요.

성공적인 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을 통해 수행되는 각 HTTP 작업에 대해 초기 401 로그 항목을 예상해야 합니다, HTTP Basic 인증이 작동하는 방식 때문에 그렇습니다.

Git 클라이언트가 클론을 시작할 때, GitLab에 보내는 초기 요청은 인증 세부 정보를 제공하지 않습니다. GitLab은 해당 요청에 대해 401 Unauthorized 결과를 반환합니다.

몇 밀리초 후, Git 클라이언트는 인증 세부 정보를 포함하는 후속 요청을 보냅니다. 이 두 번째 요청은 성공해야 하며, 200 OK 로그 항목을 발생시킵니다.

401 로그 항목이 해당하는 200 로그 항목을 누락하면, Git 클라이언트는 다음을 사용하고 있을 가능성이 높습니다:

  • 잘못된 비밀번호.
  • 만료되었거나 취소된 토큰.

이를 해결하지 않으면, 403 (Forbidden) 오류 를 겪을 수 있습니다.

403 오류가 발생할 때 Git 작업을 HTTP로 수행

HTTP로 Git 작업을 수행할 때, 403 (금지됨) 오류는 귀하의 IP 주소가 인증 실패로 인해 차단되었음을 나타냅니다:

fatal: 'https://gitlab.com/group/project.git/'에 접근할 수 없습니다: 요청된 URL이 오류를 반환했습니다: 403

403production_json.log에서 확인할 수 있습니다:

{
   "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"}

인증 실패 차단의 제한은 셀프 관리 인스턴스GitLab.com 사용에 따라 다릅니다.