원격 저장소와 GitHub


지금까지 이 핸드북에서 다룬 모든 저장소는 한 곳에만 있었습니다: 바로 당신의 컴퓨터입니다. 이것은 노트북이 고장 났을 때 백업이 필요하거나, 다른 컴퓨터에서 프로젝트를 계속하거나, 다른 사람이 코드를 건드려야 할 때까지는 잘 작동합니다. 필요한 것은 관련된 모든 컴퓨터가 접근할 수 있는 곳에 저장소의 복사본을 두는 것입니다. 이 복사본을 원격 저장소(remote)라고 하며, GitHub는 대부분의 개발자가 이를 두는 곳입니다.
원격 저장소란 무엇인가 (그리고 GitHub는 어디에 들어맞는가)
**원격 저장소**는 당신의 컴퓨터가 아닌 다른 곳, 대부분 GitHub에 호스팅된 저장소의 복사본입니다. 저장소를 복제할 때, Git은 이미 하나를 설정해 주며, 기본값으로 origin이라는 이름을 붙입니다. git remote -v 명령을 실행하면 (이 -v 플래그는 URL뿐만 아니라 이름도 보여줍니다) 이를 볼 수 있습니다:
$ git remote -v
origin https://github.com/mara-chen/weather-app.git (fetch)
origin https://github.com/mara-chen/weather-app.git (push)Git이 알고 있는 모든 원격 저장소는 두 번씩 나열됩니다. 하나는 가져오기용이고, 하나는 밀어넣기용입니다. 이론상 두 주소가 다를 수도 있기 때문입니다. 실제로는 거의 항상 같습니다. origin은 복제할 때 Git이 자동으로 할당하는 별칭입니다. 이름을 바꾸거나 다른 곳을 가리키는 두 번째 원격 저장소를 추가할 수 있지만, 대부분의 프로젝트의 주 원격 저장소는 origin이라고 부릅니다.
이것은 초보자를 혼동시키는 구분을 다시 강조할 좋은 시점입니다: Git과 GitHub는 같은 것이 아닙니다. Git은 당신의 컴퓨터에서 실행되는 버전 관리 도구로, 아무것도 연결되어 있지 않더라도 커밋을 기록합니다. GitHub는 저장소의 복사본을 호스팅하고 밀어넣기와 가져오기를 할 수 있는 원격 저장소를 제공하는 웹사이트입니다. git remote, git push, git pull은 이 둘을 연결하는 명령어입니다. 이 명령어들은 당신의 노트북에서 실행되는 Git이 GitHub 서버에 있는 저장소와 통신하는 방식입니다.
origin이라고 부릅니다. 언제든지 git remote -v를 실행하면 저장소가 알고 있는 모든 원격 저장소를 볼 수 있습니다. Git과 GitHub는 같은 것이 아닙니다: Git은 당신의 컴퓨터에 있는 도구이고, GitHub는 당신의 원격 저장소가 있는 곳입니다. 이 구분을 일찍 명확히 하면 나중에 많은 혼동을 피할 수 있습니다. 원격 저장소를 호스팅할 곳: GitHub와 그 외의 선택지
원격 저장소가 하는 모든 것은 순수한 Git이며, 이는 중요한 결과를 가져옵니다: 다른 쪽 끝의 호스트는 바꿀 수 있습니다. Git의 관점에서 모든 호스트는 설정의 URL이며, git push, git pull, git fetch는 모든 호스트에 대해 동일하게 작동합니다. 호스트가 추가하는 것은 한 단계 위에 있습니다: 코드의 웹 보기, 리뷰 흐름, 이슈 추적, 접근 제어입니다. 장단점을 명확히 하면서 현황을 소개합니다:
- **GitHub**는 단연 가장 크며 오픈소스 작업의 대다수를 호스팅합니다. 강점은 네트워크입니다: 기여하고 싶은 프로젝트들이 이미 여기 있고, 튜토리얼들이 이를 가정하며, 고용주들이 당신의 프로필을 여기서 찾습니다. 트레이드오프는 폐쇄형 플랫폼(Microsoft의 소유)이며, Git 호스팅 이상의 기능에 의존할수록 이 플랫폼에 더 묶이게 됩니다.
- **GitLab**은 가장 가까운 완전한 대안으로, 약간 다른 이름의 동일한 핵심 기능을 가지고 있습니다 (풀 리퀘스트는 여기서 "merge request"라고 합니다). 돋보이는 점은 자신의 서버에서 실행할 수 있는 자체 관리 버전으로, 코드를 사내에 보관하는 회사들이 이를 많이 선택하는 이유입니다. 트레이드오프는 많은 것을 번들로 제공하며, 플랫폼이 당신이 찾는 코드 호스팅보다 더 무거울 수 있다는 점입니다.
- **Bitbucket**은 Atlassian의 호스트로, 프로젝트 추적 및 문서 도구인 Jira와 Confluence 옆에 앉도록 만들어졌습니다. 팀이 이미 이 도구들을 사용하고 있다면 완벽하게 맞아떨어집니다. 이 생태계 밖에서는 세 개 중 가장 작은 커뮤니티를 가지고 있으며 오픈소스 존재감이 거의 없습니다.
- **Codeberg**는 오픈소스 플랫폼 Forgejo에서 운영되는 오픈소스 프로젝트를 위한 비영리 호스트입니다. 매력은 어떤 회사도 호스트를 소유하지 않으며 플랫폼 자체가 오픈소스라는 것입니다. 트레이드오프는 규모입니다: 더 적은 통합, 작은 커뮤니티, 개인 팀 작업보다는 오픈소스에 집중합니다.
- 자체 호스팅은 모든 것의 기반입니다: Forgejo 또는 Gitea를 실행합니다. 둘 다 무료이고 오픈소스이거나, GitLab의 자체 관리 버전을 당신이 제어하는 하드웨어에서 실행합니다. 완전한 제어와 프라이버시를 얻을 수 있습니다. 트레이드오프는 이를 계속 실행하는 것이 당신의 책임이 된다는 점입니다.
이 핸드북은 대부분의 오픈소스 작업을 호스팅하고 당신이 먼저 협업할 가능성이 가장 높기 때문에 예시에서 GitHub를 사용합니다. 이 장의 모든 명령어는 다른 호스트로 변경 없이 전송됩니다: URL을 바꾸면 일상적인 루틴은 같습니다. 차이점은 한 단계 위에 있으며, 각 사이트의 작업 검토 및 병합 웹 인터페이스에 있습니다. 이것이 다음 장의 풀 리퀘스트 흐름이 들어오는 곳입니다.
당신의 작업을 보내고 받기: git push와 git pull
원격 저장소가 있으면, 두 개의 명령어로 대부분의 일상 작업이 가능합니다. git push는 로컬 커밋을 원격 저장소로 보냅니다. git pull은 다른 곳에서 만들어진 커밋을 가져와 현재 브랜치에 병합합니다.
$ git push origin main
Enumerating objects: 5, done.
Writing objects: 100% (3/3), 312 bytes | 312.00 KiB/s, done.
To https://github.com/mara-chen/weather-app.git
9f8e7d6..a1b2c3d main -> mainorigin은 원격 저장소이고, main은 당신이 보내는 브랜치입니다. 마지막 줄이 읽을 가치가 있는 부분입니다: 원격의 main이 한 커밋에서 다음 커밋으로 이동하는 것을 보여줍니다.
당기기는 같은 방식으로, 반대로 작동합니다:
$ git pull origin main
remote: Enumerating objects: 4, done.
Unpacking objects: 100% (4/4), done.
Updating a1b2c3d..b7c9e21
Fast-forward
src/index.js | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)이것이 다른 사람과 함께 한 프로젝트에서 일하기 위한 전체 루프입니다: 시작하기 전에 변경된 것을 모두 가져오고, 자신의 작업을 하고 커밋하고, 다시 밀어 올리세요. 다른 사람과 브랜치를 공유할 때마다 밀어 올리기 전에 당겨오세요. 당기기를 건너뛰면 당신의 푸시가 당신이 본 적 없는 커밋 위에 떨어질 수 있으며, Git은 누군가의 작업을 잃을 위험을 무릅쓰기보다는 거부합니다.
git push는 커밋을 원격 저장소로 보내고, git pull은 다른 곳에서 만들어진 커밋을 가져와 당신의 브랜치에 병합합니다. 작업을 시작하기 전에 당겨오고 끝났을 때 밀어 올리면, 프로젝트를 건드리는 다른 누구와도 동기화 상태를 유지합니다. 당기기를 건너뛰는 것이 푸시가 거부되는 가장 일반적인 이유입니다. git fetch 대 git pull
git pull은 두 가지를 한 단계에서 합니다: 원격에서 변경된 사항을 다운로드한 다음 즉시 그 변경 사항을 현재 브랜치에 병합합니다. git fetch는 첫 번째 반만 합니다. 새 커밋을 다운로드하지만 브랜치에 병합하지 않습니다. 현재 브랜치와 작업 파일은 Git을 병합하거나 당기라고 지시할 때까지 정확히 같은 곳에 머물러 있습니다.
거의 모든 사람이 적어도 한 번은 이 함정에 빠집니다: git fetch를 실행하고, 어디든 눈에 띄는 변화를 보지 못하고, 원격에서 아무것도 일어나지 않았다고 가정합니다. 뭔가 일어났습니다: fetch는 아직 당신의 작업 브랜치를 건드리지 않았습니다. 무엇이 내려왔는지 보려면, 이 장의 앞부분의 원격 추적 브랜치를 봅니다: git log origin/main은 원격에 있지만 로컬 main에 도달하지 않은 커밋을 보여줍니다. 이를 가져올 준비가 되면, git merge origin/main이 이를 수행하거나, git pull은 한 명령에서 fetch와 그 병합을 실행합니다.
git pull은 새 커밋을 다운로드하고 한 단계에서 브랜치에 병합합니다. git fetch는 다운로드하고만 원격이 어디에 서 있는지에 대한 Git의 기억을 업데이트합니다. 당신의 브랜치는 당신이 병합할 때까지 머물러 있습니다. fetch 이후 파일에서 눈에 띄는 변화를 보지 못하는 것은 예상된 것입니다. 새 커밋은 원격 추적 브랜치에서 기다리고 있습니다. 이것이 당신을 어디에 두는지
Push, pull, 그리고 fetch는 커밋을 공유 원격 저장소로 가져가고 다시 가져오는데, 이는 Git의 일상적인 협업에서 필요로 하는 대부분을 다룹니다. 여기의 모든 것은 커밋 루프에 기반합니다: 당신은 여전히 로컬에서 먼저 단계별로 진행하고 커밋하며, 원격 저장소는 그 커밋들이 어디로 여행할 수 있는지만 변경합니다. 다음 부분은 GitHub 자체를 통해 그 협업을 수행하는 것으로, 변경 사항을 제안하고 병합되기 전에 검토를 받는 것입니다. 풀 리퀘스트 흐름은 정확히 그곳을 선택합니다. 이 장의 용어가 여전히 불안정하다면, 원격 추적 브랜치, refspec, 업스트림, 용어집은 각각에 대한 순수 정의를 가지고 있으며, Git이란 무엇인가는 자체적으로 Git-versus-GitHub 구분을 두 번 봐볼 가치가 있습니다.

