GitHub 속 git 저장소 Clone 방법 세 가지 (HTTPS , SSH , GitHub CLI)

저장소 하나 만들어놓고 초록색 Code 버튼을 눌렀더니 탭이 셋 나옵니다. 셋 다 처음 보면 왜 저 이름이고 왜 저렇게 생겼는지 알 수가 없지요. git이 뭔지부터 시작해서, 이름의 유래와 주소가 저 모양이 된 이유를 순서대로 뜯어봅니다.
1. 깃허브 저장소 상단의 Code 버튼을 누르면 Local 탭 아래에 Clone 방식이 세 개 나옴. HTTPS, SSH, GitHub CLI 순임.
2.각 탭이 내주는 것은 아래 셋임.
HTTPS — https://github.com/tsusaikang/winutil.git
SSH — git@github.com:tsusaikang/winutil.git
GitHub CLI — gh repo clone tsusaikang/winutil
3. 이걸 처음 본 사람이 대개 던지는 질문은 "셋 중에 뭐가 제일 좋냐"임.
4. 그런데 셋은 같은 층위에 놓인 세 개의 선택지가 아님. 앞의 둘은 데이터를 실어 나르는 프로토콜이고, 셋째는 그 둘 중 하나를 대신 골라주는 프로그램임.
5. 왜 그런지 보려면 git부터 알아야 함. git은 파일이 바뀌어온 내력을 통째로 기록해두는 프로그램임. 리눅스를 만든 리누스 토르발스가 2005년에 리눅스 커널 개발에 쓰려고 직접 만들었음.
6. 흔히 "버전 관리 도구"라고 부르는데, 한마디로 "언제 누가 무엇을 왜 바꿨는지를 파일 옆에 같이 쌓아두는 것"임. 보고서_최종.docx, 보고서_최종_진짜최종.docx 하는 식으로 이름을 바꿔가며 사본을 늘려놓던 짓을 프로그램이 대신 해준다고 보면 됨. 다른 점은 사본을 늘리지 않고 바뀐 부분만 기록하며, 아무 시점으로나 되돌아갈 수 있다는 것임.
7. 그렇게 쌓인 기록 뭉치를 저장소(repository)라고 부름. 작업 폴더 안에 .git이라는 숨은 폴더가 생기는데, 그 안이 저장소임.
8. 여기까지는 전부 내 컴퓨터 안에서만 일어나는 일이고 인터넷이 필요 없음. git은 중앙 서버를 전제하지 않는 분산형이라, 참여자 각자가 이력 전체의 사본을 들고 있음.
9. 그래서 git과 깃허브(GitHub)는 같은 것이 아님. 깃허브는 그 사본 하나를 남들이 접근할 수 있는 자리(인터넷)에 얹어두고 웹 화면과 부가 기능을 붙여 파는 회사의 서비스임. git은 깃허브 없이도 그대로 돌아감.
10. 그 얹혀 있는 사본을 내 컴퓨터로 가져오는 명령이 git clone임. 최신 파일만 받는 게 아니라 첫 기록부터 지금까지의 이력을 통째로 복제함.
11. 그러려면 두 가지가 필요함. 어느 컴퓨터의 어느 저장소인지(주소), 그리고 그 컴퓨터와 어떤 방식으로 대화할지(프로토콜)임. Clone 탭이 내주는 문자열은 이 두 가지를 한 줄에 적어놓은 것임.
12. git이 원래 지원하는 운반 방식은 네 가지임. 같은 컴퓨터 안의 경로(local), SSH, HTTP(S), 그리고 git://으로 시작하는 전용 프로토콜임.
13. 이 중 git://은 깃허브에서 2022년 3월 15일부로 완전히 차단됐음. 암호화도 인증도 없어서 중간에서 내용을 바꿔치기해도 받는 쪽이 알 방법이 없는 방식이었음.※ 출처: GitHub Changelog, "Removed unencrypted Git protocol and certain SSH keys" (2022.03.15)
14. 그래서 지금 남은 게 셋임. 정확히는 프로토콜 둘에, 도구 하나가 얹혀 있는 것임.

1. 먼저 HTTPS임. HyperText Transfer Protocol Secure의 약자로, 브라우저가 웹페이지를 받아올 때 쓰는 바로 그 프로토콜임. 뒤의 S는 통신 내용을 암호로 감싼다는 뜻임.
2. 소스코드를 받는데 왜 웹페이지용 프로토콜을 쓰냐는 의문이 들 수 있음. 답은 포트임. 회사망이나 학교망은 대개 바깥으로 나가는 통로를 몇 개만 열어두는데, 웹이 쓰는 443번 포트는 사실상 어디서나 열려 있음. 웹을 막아버리면 업무가 안 되기 때문임. 그러니 웹 통로에 얹어 보내면 거의 모든 환경에서 통함.
3. 주소를 쪼개보면 https://(어떻게) + github.com(어느 컴퓨터) + /tsusaikang/winutil.git(그 안의 어디) 세 토막임. 브라우저 주소창에 넣는 주소와 사실상 같은 모양이고, 깃허브가 이 탭에 "Clone using the web URL"이라고 써놓은 게 그 뜻임.
4. 그러면 같은 주소인데 브라우저는 웹페이지를 받고 git은 저장소를 받는 게 이상해 보일 것임. 실제로는 요청이 다름. git은 저 주소 뒤에 /info/refs?service=git-upload-pack 같은 꼬리를 붙여 요청하고, 자기가 git이라는 것을 요청 헤더에 밝힘. 서버는 상대가 브라우저인지 git인지 보고 다른 것을 내줌. 이 방식을 Smart HTTP라고 부름.
5. 끝의 .git은 서버에 저장소 디렉터리를 만들 때 붙이는 오래된 관례임. 작업 파일 없이 이력 데이터만 담아둔 저장소를 bare repository라고 하는데, 여기에 프로젝트명.git이라는 이름을 붙여왔음. 7번에서 말한 숨은 .git 폴더의 내용물만 따로 떼어놓은 것이 이것임. 깃허브는 .git을 떼고 요청해도 받아주지만, 그 주소가 웹페이지가 아니라 저장소를 가리킨다는 표시라 붙여서 내줌.
6. HTTPS의 대가는 인증임. 깃허브는 2021년 8월 13일부로 계정 비밀번호를 더 이상 받지 않음. 대신 개인용 액세스 토큰(PAT) 같은 토큰을 써야 함. ※ 출처: GitHub Changelog, "Git password authentication is shutting down" (2021.08.12)
7. 토큰이 비밀번호보다 나은 지점은 세 개임. 권한 범위를 좁게 잘라 발급할 수 있고, 만료일을 걸 수 있고, 하나가 새면 그것만 폐기하면 됨. 계정 비밀번호는 이 셋 중 아무것도 안 됨.

1. 다음은 SSH임. Secure SHell의 약자이고, 원래 용도는 파일 전송이 아니라 원격 컴퓨터에 로그인해서 명령을 실행하는 것임. 옛날에 쓰던 telnet이 통신 내용을 그대로 흘려보내서, 그걸 암호로 감싼 대체품으로 나온 것임.
2. 그런데 SSH 탭이 내주는 git@github.com:tsusaikang/winutil.git에는 ://이 없음. 이건 URL이 아님.
3. 이 모양은 scp 문법임. 원격 컴퓨터로 파일을 복사하는 명령이 scp 파일 사용자@호스트:경로 형태인데, 저 주소는 그 뒷부분을 그대로 가져온 것임. SSH로 남의 컴퓨터에 말을 걸어온 사람들이 수십 년간 써온 표기라 git이 따로 만들지 않고 그대로 받아 씀.
4. 앞의 git@은 github.com이라는 컴퓨터에 실제로 존재하는 계정 이름임. 전 세계 사용자가 전부 git이라는 계정 하나로 로그인함.
5. 그러면 누가 접속했는지 어떻게 구분하느냐는 문제가 남음. 열쇠로 구분함.
6. SSH 접속에서는 내가 만든 열쇠 한 쌍 중 공개키를 미리 깃허브 계정에 올려두고, 접속할 때 짝이 맞는 개인키를 가졌는지 증명함. 깃허브는 그때 쓰인 키가 누구 계정에 등록된 키인지를 보고 사람을 알아냄. 계정 이름이 주소에 들어갈 자리가 없는 이유가 이것임.
7. 로그인은 되지만 셸은 안 열림. git 계정은 git 명령만 실행하도록 묶여 있어서, 접속을 시험해보면 이런 답이 옴. "Hi tsusaikang! You've successfully authenticated, but GitHub does not provide shell access."
8. : 뒤의 tsusaikang/winutil.git이 슬래시로 시작하지 않는 것도 scp 문법을 따른 결과임. 서버가 자기 저장소 보관 위치를 기준으로 알아서 해석해줌.
9. 이 탭에 "Use a password-protected SSH key"라고 적혀 있는 데는 이유가 있음. 개인키 파일은 그 자체가 나를 증명하는 물건이라, 파일이 새어나가면 가져간 사람이 곧 나임. 비밀번호와 달리 다시 입력할 일이 없어 새어나간 것을 눈치채기도 어려움. 그래서 키 파일 자체에 암호를 걸어두라는 것임.
10. SSH가 쓰는 22번 포트는 443번만큼 관대하게 열려 있지 않음. 막힌 망에서는 ssh.github.com의 443번 포트로 우회하는 경로를 깃허브가 따로 제공함.

1. 마지막이 GitHub CLI임. 여기만 내용물이 주소가 아니라 명령어 한 줄임. ://도 없고, github.com도 없고, .git도 없음.
gh는 git이 아니라 깃허브가 따로 만들어 배포하는 별도 프로그램임. 설치하지 않은 컴퓨터에서 저 줄을 붙여넣으면 명령을 못 찾겠다는 답만 옴.
2. github.com이 빠진 이유는 gh가 깃허브 전용 도구라서임. 갈 곳이 하나뿐이면 주소에 적을 이유가 없음. .git이 빠진 이유는 저 뒷부분이 주소가 아니라 소유자/저장소 형태의 식별자이기 때문임. 파일 경로가 아니니 디렉터리 이름 관례를 따를 까닭도 없음.
3. 그리고 gh가 내부에서 실제로 하는 일은, 저장해둔 인증 설정을 보고 HTTPS와 SSH 중 하나를 골라 git clone을 대신 실행하는 것임.
4. 그러니 GitHub CLI는 앞의 둘과 나란한 세 번째 선택지가 아니라, 앞의 둘 위에 얹혀서 고민을 대신 해주는 층임. 3번 항목의 질문이 틀린 질문인 이유가 여기임.
5. 세 탭에 붙은 설명 문구가 서로 결이 다른 것도 이 구조를 그대로 보여줌. 앞의 둘은 "웹 주소로 복제한다", "암호 걸린 키를 써라"처럼 주소와 그 대가를 설명하는데, 셋째만 "우리 공식 CLI로 빠르게 작업하세요"라는 도구 소개임.
요약.
git은 파일 이력을 기록하는 프로그램이고 깃허브는 그 기록 사본을 남에게 열어주는 서비스인데, Clone 탭 세 개는 그 사본을 내 컴퓨터로 끌어올 때 어떤 통로로 끌어올지를 고르는 자리임. 그런데 셋이 나란한 세 개의 통로가 아니라, 프로토콜 둘과 그 둘을 대신 골라주는 도구 하나임. HTTPS는 웹이 쓰는 통로에 얹혀 어디서든 통하는 대신 접속할 때마다 토큰을 대야 하고, SSH는 열쇠를 한 번 등록해두면 그 뒤가 조용한 대신 열쇠 파일 관리가 통째로 내 책임이 됨. 주소가 서로 다르게 생긴 것도 취향 문제가 아니라 출신이 달라서인데, 앞쪽은 웹 주소 규격을 그대로 쓴 것이고 뒤쪽은 원격 접속 도구들이 쓰던 표기를 물려받은 것임. 세 번째 탭은 그 차이를 몰라도 되게 덮어주는 물건이라 편하기는 하지만, 토큰이 새면 토큰을 폐기하고 키가 새면 키를 폐기해야 하는 만큼 지금 무엇으로 접속하고 있는지 정도는 알고 쓰는 편이 낫다고 생각함.