내가 생각하기에 사람들이 Git을 이해하는데 어려워하는 부분이 몇가지 있는데
- Github를 설명할 때 Git의 기능과 Github의 기능을 명확하게 구분해 주지 않는다.
- 대부분의 개발자들이 가진 Subversion에 대한 이해가 오히려 Git을 이해하는데 방해가 된다. Git은 DVCS이고 SVN은 VCS이다. 앞에 Distribute가 붙은건 마케팅적으로 괜히 붙힌게 아니라 분산 저장소이기 때문이다. Git에서 이 분산저장소라는 것은 무척 중요하다.
이 과정은 도식화 하면 위처럼 된다. 좀 복잡해 보일 수 있는데 하나씩 살펴보자.
Fork
Github의 저장소를 보면 다음 화면처럼 3가지의 저장소 주소를 제공하고 있다.(Git에서 여러가지 프로토콜을 사용해서 저장소를 열어줄 수 있지만 Github가 제공하는 저장소가 이렇다.)
jQuery 저장소에는 쓰기 권한을 가지고 있지 않으므로(아무나 쓰기를 할 수 있다면 저장소는 당연히 엉망일 될 것이다.) 우측에 보듯이 Read-Only 권한만 있음을 알 수 있다. 만약에 지금 시나리오처럼 소스를 수정해서 적용할 것이 아니고 그냥 혼자 소스를 살펴보기만 할 것이라면 이 주소를 사용해서 git clone를 하면 로컬에 저장소를 내려받을 수 있다. 하지만 우리는 소스를 수정할 수 있는 저장소를 관리해야 하므로 Fork를 해야 한다. 저장소 관리자와 친분이 있다면 요청을 해서 해당 저장소에 Push할 수 있는 권한을 받을 수도 있겠지만 일반적으로는 Fork한 뒤에 나중에 Pull Request하는 방식으로 진행이 된다.
앞에서 본 다이어그램에서 위의 부분이다. jQuery의 저장소를 Fork받아서 내 저장소로 복사본을 만든다. 저장소의 우측상단을 보면 다음처런 Fork버튼을 볼 수 있다.
이 Fork버튼을 누르면 jQuery 저장소의 지금 상태 그대로를 복사해서 자신의 Github계정에 jQuery 저장소를 생성한다. 이 Fork는 git의 기능이 아니라 Github가 git의 기능을 추상화해서 제공하는 기능이므로 git fork같은 명령어는 없다. 간단히 생각하면 git clone을 github내에서 진행했다고 생각하면 된다.(내부 구현은 알 수 없지만....)
이제 자신의 계정에 jQuery저장소가 생겼고 저장소 주소에 Read+Write 권한이 있는 것을 볼 수 있다. 이제 이 저장소에는 소스를 수정해서 푸시를 할 수 있다. 이 저장소는 jQuery의 원래 저장소와 완전히 동일한(주소만 다른) 저장소이다. 분산저장소이기 때문에 저장소가 또 하나 생긴 것이고 다른 사람이 jQuery 원래 저장소 대신 내 저장소를 똑같이 Fork 받아서 수정하는 것도 당연히 가능하다 각 저장소는 모두 권한외에는 모두 동일한 기능을 가진다.
Clone
원격에서는 소스를 수정할 수 없으므로 이 저장소를 작업할 로컬 머신에 내려받아야 하는데 이 과정이 Clone이다.
Clone는 git을 잘 몰라도 대부분 알고 있는 git clone git@github.com:outsideris/jquery.git 명령어로 수행한다. SSH 주소를 사용한 것은 git 프로토콜이 HTTPS보다 훨씬 빠르고 Github에 SSH키를 등록해 놓으면 푸시할때 암호를 입력하지 않아도 되기 때문이다.
Clone을 받아오면 로컬에 jquery 폴더가 생기고 jquery 폴더안에 git 저장소를 내려받은 것을 볼 수 있다. 저장소 이름이 jquery이기 때문에 jquery 폴더가 생겼고 다름 폴더명을 사용하려면 git clone git@github.com:outsideris/jquery.git NEW_NAME과 같이 이름을 지정하면 된다. Fork가 Github내에서 저장소를 복사한 것이라면 clone은 원격 저장소를 로컬로 복사한 것이다.
Commit
이제 저장소를 로컬에 가져왔으므로 소스를 수정하는 작업을 해야한다. git에서는 관례적으로 메인 브랜치로 master 브랜치를 사용하지만 필요하다면 다른 브랜치를 메인으로 사용해도 아무런 문제가 없다. master는 그냥 관례적으로 약속한 브랜치일 뿐이다.
jQuery의 소스를 수정하기 위해서 master 브랜치를 수정해야 하는데 Subversion과는 다르게 Git에서는 브랜치를 생성하는 것을 권장하고 있고 일반적으로 master 브랜치에서 다른 브랜치를 생성해서 작업하는 것이 일반적이다. 여기서는 patched라는 브랜치를 생성한다.
git branch 명령어를 사용해서 현 브랜치에서 새로운 브랜치를 생성하고 해당 브랜치로 사용하는 브랜치를 바꾸었다. 여기서 hotfixes/patched라고 브랜치를 생성한 이유는 git-flow의 관례이고 그냥 브랜치명이 hotfixes/patched라고 지은것이고 계층적으로 구분하기 위해서 생성했다고 보면 된다. 위의 두 과정대신 git checkout -b hotfixes/patched를 사용하면 명령어 하나로 브랜치를 생성해서 바로 이동까지 할 수 있다. 사실 git을 사용하는 대부분의 과정은 이 단계에서 이루어지는데 기본적으로 소스를 수정하고 커밋할 소스를 git add한 후에 git commit을 한다. commit은 현재의 git 저장소에 소스를 적용해서 히스토리를 남긴 것으로 SVN의 commit과 다르게 원격저장소에 적용되는 것은 아니다.
이 포스팅은 Github를 이용하는 전체 흐름 이해하기 #2로 이어진다.
좋은 가이드 감사합니다. 매번 IDE 만 쓰다가 CLI 로 작업하려다 꼬여서 처음부터 다시 공부하고 있어요. 내용도 좋지만 mbpR 이 눈에 확!!! ^^
개인적으로 CLI로 배우는게 초반에만 좀 힘들고 더 좋다고 생각합니다. 이해하기도 좋고요.
어려운 부분이 있는데 조언 부탁드려요.
우선 프로젝트가 하나의 메인 프로젝트에 두개의 서브모듈이 포함되어 있는 상황입니다.
그 프로젝트를 클론하여 우선 제 레포지토리로 가져왔어요.
로컬로 다시 클론하고 서브모듈까지 가져온 후 브랜치를 따서 소스를 수정합니다.
수정하고 커밋 할 경우 서브모듈의 수정된 부분을 갱신하는데 문제가 있는데요.
즉, 수정할 내용이 원본 프로젝트에도 있고 서브프로젝트에도 있어요.
이 경우 서브 프로젝트까지 포함한 소스를 통째로 커밋할 방법이 있을까요?
아니면 어떤 방법을 사용해야할지 가이드 해주시면 감사하겠습니다. ^^
흠... git의 submodule 얘기하시는 거죠? 솔직히 submodule은 제가 직접 사용해서 개발해 본적은 없지만 다른 분들의 얘기를 좀 들어보면 다루기가 꽤 어려운 것으로 알고 있습니다. 제 추측으로는 submodule은 그냥 의존성에 대한 내용만 내려받은 것이므로 submodule에 바로 푸시는 할 수 없을 것으로 보입니다.(혹시 submodule로 내려받은 폴더가 별도의 git저장소로 설정되는지는 잘 모르겠네요. 이렇다면 가능도 할것 같은데요.)
어떤 프로젝트인지는 모르지만 주위분들 보면 submodule쓰다가 피곤해서 메이븐같은 의존성관리도구로 따로 관리하는 식으로 접근하고는 합니다. 분리된 모듈이라는 관점에서도 서브모듈들의 수정은 메인프로젝트와 별도로 이루어지는게 더 맞는듯 합니다.
넵 서브모듈을 따로 다시 포크하여 서브모듈 의존성을 제거하고 별도 프로젝트로 관리하는 방법을 선택했어요.
어짜피 최종 컴파일이 목적이니까 ^^
감사합니다~
예 의존성에 관련해서는 좀더 깔끔한 방법이 많이 연구되어야 할것 같습니다. ^^
좋은 글 감사합니다. 다만 SVN이 얼마나 구린지에 대한 설명이 부족해서
http://stackoverflow.com/questions/871/why-is-git-better-than-subversion
링크 추가 합니다. 제 생각으로는 GitHub 가 Git을 정말 잘 살린 케이스 같네요.
좋은 글 감사합니다. ㅎㅎㅎㅎ
얼마나 구린지를 설명하는 글은 아니라서요. ^^;;
Github 정말 최고죠... git을 얼마나 잘 이해하고 있는지를 서비스에서 확 느낄수 있죠.
궁금한게 있는데 fork를 여러번 시행을 할 수 없나요?
사용자별로 저장소명이 유일하기 때문에 포크를 여러번할수는 없습니다. 물론 지웠다하면 가능합니다.
감사합니다. 개인용 비공개 공부블러그에 좀만 퍼갈께요
감사합니다.
같이 공부하는 스터디 모임이 있는데 발표를 위해서 제 블로그에
github 구조 그림 살짝 퍼가도 될까요?
네 출처만 밝혀주시면 괜찮습니다.
정말 좋은 글 감사합니다.
제 블로그로 퍼 갑니다. 출처 꼭 밝히겠습니다. ^^
네 CCL에 따라 퍼가시면 됩니다.
블로그주소 라도 알려주시면 감사하겠습니다. ^^
잘보고 갑니다!! 이해가 쏙쏙되네요ㅋ
쉽게 이해하셨다니 다행이네요. ^^
정보 감사합니다.
자료에 대해 링크걸어서 사용할께요. 문제되면 알려주세요.
감사합니다.
CCL만 따라서 사용하시면 됩니다.
와우~ 좋은 정보 감사합니다^^
네 감사합니다 ^^
잘보고 두번째 글로 갑니다
잘 봤습니다. 잘 모르고 그냥 사용하던 기능들의 개념이 잘 이해되었습니다.
큰 도움 됐습니다.
좋은 정보 감사합니다! 출처밝히고 블로그에 담아갈께요!!
정말 잘 보고 갑니다 !
이리저리 둘러보다가 여기가 가장 쉽고 이해가 빨랐습니다.
블로그 내용에 출처를 남기고 참조하여 작성하겠습니다. 감사합니다!