Community코딩 & 개발github.com

jijojohny/claude-skills

리포지토리를 푸시하기 전에 git/GitHub 설정을 읽기 전용으로 사전 점검합니다. 특히 첫 푸시 시 유용합니다. 어떤 GitHub 계정으로 인증되는지, 커밋 작성자(Author)는 누구인지, 리모트 URL이 insteadOf로 재작성되었는지, 브랜치와 리모트 상태가 푸시를 실제로 허용할지 보고합니다.

claude-skills란 무엇인가요?

이 스킬은 개발자가 새로운 리포지토리를 푸시할 때 흔히 겪는 실수를 사전에 방지해줍니다. `src refspec main does not match any` 같은 오류 메시지는 실제로는 커밋이 없어서 발생하는 경우가 많지만, 사용자는 브랜치 문제로 오해할 수 있습니다. 또, 여러 GitHub 계정을 사용하는 환경에서는 잘못된 계정으로 푸시가 성공해도 발견하기 어렵습니다. 이 스킬은 사용자의 git/GitHub 환경을 절대 변경하지 않고 오직 진단만 수행합니다. SSH와 HTTPS 모두를 지원하며, `ssh -T`로 GitHub에 인증된 계정을 확인하고, `git config`를 분석해 커밋 작성자 ID와 리모트 URL의 실제 값을 비교합니다. 또한, dry-run 푸시를 통해 인증과 참조 협상을 테스트합니다. 주요 용도는 '내 GitHub 설정 확인해줘', '푸시해도 될까?', '첫 푸시 전에' 같은 요청이나, 403, GH007, Permission denied 오류가 발생했을 때 자동으로 실행됩니다. 여러 GitHub 계정이나 SSH 호스트 별칭을 사용하는 환경에서 특히 유용하며, 조용히 잘못된 아이덴티티로 푸시되는 것을 방지합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jijojohny/claude-skills/tree/HEAD/github-preflight

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

GitHub Preflight (사전 점검)

새 리포지토리를 푸시하면 몇 가지 지루하고 반복적인 이유로 실패하는 경우가 많지만, 오류 메시지는 실제 원인을 제대로 가리키지 않습니다. src refspec main does not match any은 브랜치 문제처럼 들리지만, 보통은 커밋이 없기 때문입니다. 작업 계정으로 조용히 성공한 푸시는 올바르게 성공한 푸시와 똑같이 보입니다. 이 스킬은 사용자가 푸시를 날리기 전에 이러한 문제를 찾아냅니다.

핵심 원칙: 진단(진단)만 하고, 변경하지 않는다. 발견된 내용을 보고하고, 복사-붙여넣기로 해결할 수 있는 명령어를 알려줍니다. 사용자가 직접 실행합니다. 여러 계정을 유지하는 이유는 정확히 어떤 계정이 작업하는지에 신경을 쓰기 때문이므로, 사용자를 대신해 git config나 git remote set-url을 조용히 실행하는 것은 정확히 잘못된 접근입니다.

실행 방법

bash <skill-dir>/scripts/preflight.sh [리포지토리-경로] [리모트-이름]

두 인수 모두 선택 사항이며, 기본값은 현재 디렉토리와 origin입니다. 스크립트는 오직 다음 명령만 읽습니다: git config --get, ls-remote, ssh -T, push --dry-run. 절대 쓰지 않습니다.

어떤 이유로 스크립트를 실행할 수 없는 경우, 아래 각 검사는 한 줄 명령어로 직접 실행하고 같은 방식으로 해석할 수 있습니다.

검사 항목의 의미

스크립트는 PASS / WARN / FAIL 라인을 출력합니다. 원시 출력보다 해석이 더 중요하므로, 그대로 붙여넣지 말고 설명해야 합니다.

리포지토리/파일/커밋. 빈 디렉토리나 커밋이 없는 리포지토리는 푸시 시 src refspec <브랜치> does not match any을 발생시킵니다. Git은 빈 상태에서 커밋을 만들 수 없습니다. 이것이 첫 푸시 실패의 가장 흔한 원인이므로, 이 문제가 발생하면 가장 먼저 언급해야 합니다.

브랜치. 새 git init은 master 브랜치를 기본으로 하는 반면, 리모트는 main을 기대할 수 있습니다. 브랜치 이름 변경은 첫 커밋 이후에 안전합니다(git branch -M main) — unborn 브랜치에는 아직 이름을 바꿀 내용이 없기 때문에 명령 순서를 잘못 맞추면 한 번 더 시도해야 합니다.

실제 리모트 URL. 정확히 아는 것이 중요합니다. 잘못 확인하기 쉽기 때문입니다: git remote get-url은 이미 url.<base>.insteadOf를 확장하며, git ls-remote --get-url도 마찬가지입니다. 따라서 둘을 비교해도 아무것도 감지되지 않습니다. 원시 값은 git config --get remote.<이름>.url에만 남아 있으므로, 스크립트는 이것을 git remote get-url --push(--push 형식은 추가로 pushurl과 pushInsteadOf를 포함하며, 이것이 실제 푸시가 사용하는 것입니다)와 비교합니다. 두 값이 다를 경우, 사용자가 구성한 URL이 Git이 실제로 접속할 URL이 아닙니다. 전형적인 함정은 전역 url."https://github.com/".insteadOf = [email protected]: 설정으로, SSH를 HTTPS로 조용히 우회시켜 자격 증명 헬퍼가 보유한 계정(종종 사용자가 의도하지 않은 계정)으로 푸시되게 합니다. 항상 실제 URL을 보고하고, 차이점을 명시적으로 표시해야 합니다.

인증 계정. SSH의 경우 스크립트는 ssh -G로 호스트를 확인(github-personal 같은 호스트 별칭을 실제 호스트명과 키로 추적)한 다음, ssh -T로 GitHub에 직접 질의합니다. GitHub는 Hi <사용자명>!로 응답하고 종료 코드 1을 반환합니다 — 여기서 종료 코드 1은 실패가 아니라 성공 케이스입니다. HTTPS의 경우 활성 gh 계정을 읽습니다. 해당 계정을 URL의 소유자 세그먼트와 비교합니다: 일치하지 않으면 푸시가 403 오류를 발생시키거나 잘못된 네임스페이스에 도달합니다.

커밋 아이덴티티. 전역 설정에서 상속된 user.email이 조용한 실패입니다. 푸시는 한 계정으로 인증되지만 모든 커밋은 다른 주소로 작성됩니다 — 나중에 수정하려면 커밋을 수정하거나 히스토리를 다시 써야 합니다. 리모트가 다른 소유자에 속한 리포지토리에서 전역 범위의 아이덴티티를 발견하면, 기술적으로 아직 문제가 발생하지 않았더라도 WARN으로 눈에 띄게 표시해야 합니다.

리모트 상태. 빈 리모트는 첫 푸시가 깔끔함을 의미합니다. 기존 ref가 있으면 일반 푸시가 비-빨리감기(non-fast-forward)로 거부되며 사용자가 먼저 pull/rebase해야 함을 의미합니다 — 거부 메시지를 보기 전에 알려주세요. 여기서 오류가 발생하면 일반적으로 리포지토리가 존재하지 않거나 계정에 접근 권한이 없음을 의미합니다. GitHub는 의도적으로 둘 다 "찾을 수 없음"으로 보고하므로, 추측하지 말고 두 가지 설명을 모두 제공하세요.

Dry-run 푸시. 커밋이 존재할 때만 가능합니다. 이것이 실제 종단 간(end-to-end) 검사입니다 — 쓰지 않고 인증과 참조 협상을 테스트합니다. 사각지대를 명심하세요: GH007(이메일 프라이버시) 같은 서버 측 거부는 실제 수신 시에만 평가되므로 잡아낼 수 없습니다.

보고 방법

검사 항목의 짧은 테이블을 제공한 다음, 실패하거나 경고한 항목에 대해서만 수정에 필요한 정확한 명령어를 실행 가능한 순서로 알려주세요. 통과한 검사를 설명으로 늘어놓지 마세요. 사용자는 무엇이 잘못되었고 무엇을 입력해야 하는지 알고 싶어 합니다.

아이덴티티를 설정해야 할 때는 전역 설정을 건드리기보다 리포지토리 로컬 설정을 선호합니다. 이 리포지토리가 기계의 기본값과 다르다는 것이 핵심이기 때문입니다:

git config user.name  "<계정>"
git config user.email "<이메일>"

여러 리포지토리에 동일한 처리가 필요하다면, includeIf를 지속 가능한 해결책으로 언급하세요:

[includeIf "gitdir:~/personal/"]
    path = ~/.gitconfig-personal

그리고 푸시가 GH007로 거부되면, 개인 이메일 주소를 추측하지 말고 GitHub → 설정 → 이메일에 있는 @users.noreply.github.com 주소를 가리키세요 — 키 코멘트와 로컬 설정은 레이블일 뿐, 계정이 실제로 수락하는 주소에 대한 증거가 아닙니다.

관련 스킬