Git 기초 2(remote add, push, pull, clone)

KDG: First things first!·2024년 7월 19일

Git

목록 보기
3/8

이번 포스팅의 주제인 git push와 git pull에 대해서 설명하기 위해서는 로컬 레포지토리와 리모트 레포지토리(원격 저장소)에 대한 이해가 필수적이기 때문에 우선 두 저장소에 대해 설명하겠다. 또한 깃의 init, add, commit에 대한 개념이 필요하기 때문에 만약 해당 개념들에 대한 이해도가 부족하다면 이전 포스팅인 깃 기초(init, add, commit) 1을 참고하고 돌아오는 것을 권장한다.



로컬 레포지토리 vs 리모트 레포지토리

로컬 레포지토리(Local Repository)란 쉽게 말해 내 컴퓨터에 존재하는 사용자가 깃이 관리하는 폴더에 대한 버전을 저장할 때마다 저장 당시의 버전들이 저장되어 관리되는 공간(저장소)이다. 컴퓨터에서 프로젝트의 파일들을 관리하고 저장하는 디렉토리를 생성 후 해당 경로에서 git init 커맨드를 입력하면 .git이라는 숨겨진 파일이 생성되는데 이 파일이 바로 커밋 순간의 모습들을 저장하는 로컬 레포지토리이다.

리모트 레포지토리(Remote Repository, 원격 저장소)란 깃허브 사이트에서 생성한 레포지토리이다. 주로 로컬 레포지토리의 복제본으로 사용한다.

쉽게 말해 로컬 레포지토리는 내 컴퓨터의 해당 디렉토리 안에 들어있는 저장소이고, 리모트 레포지토리는 깃허브 서버에 있는 원격 레포지토리이다.



로컬 레포지토리와 리모트 레포지토리 연결

워킹 디렉토리(프로젝트가 저장된 디렉토리를 의미)에 git init 커맨드를 사용하여 로컬 레포지토리를 만들고 깃허브 사이트로 이동하여 New Repository 버튼을 클릭하여 새로운 리모트 레포티조리를 만든 후
git remote add origin [해당 레포지토리의 URL.git] 커맨드를 입력하면 두 레포지토리간의 연결이 완료된다. 연결이 성공했는지 확인하고 싶으면 git remote -v 커맨드를 통해 확인할 수 있다.

시험용으로 만든 로컬 레포지토리와 리모트 레포지토리가 성공적으로 연결된 것을 확인할 수 있다.

참고로 git remote add origin [해당 레포지토리의 URL.git] 커맨드에서 remote는 리모트 레포지토리에 관한 커맨드 키워드이고 add origin는 로컬 레포지토리와 연결되는 새로운 리모트 레포지토리를 'origin'이라는 이름으로 등록하겠다는 뜻이다. origin이 아니라 다른 이름으로 지정해도 동작하는 데에는 오류가 없지만 origin라는 이름을 사용하는 게 전 세계적인 관행이어서 해당 이름을 사용할 것을 권장한다.




아니면 그냥 원격 저장소를 만들고 나서 바로 뜨는 페이지의 두 방식 중 한 방식을 선택해 복사 버튼을 클릭해서 붙여넣기해서 원타임으로 해결해도 된다.

첫 번째 방식은 로컬 레포지토리를 만들 커밋을 한 후에 깃허브에 업로드 했을 때 적용하는 방식이고, 두 번째 방식은 이미 만든 로컬 레포지토리를 깃허브에 업로드 하는 방식이다.

다만 두 방식 모두 복붙하면 push 커맨드가 포함되었기 때문에 내가 내 로컬 레포지토리에서 만들었던 파일과 디렉토리들이 전부 리모트 레포지토리에 올라가게 된다는 점을 인지해야 한다.


만약 두 저장소간의 연결을 해제하고 싶다면 git remote remove origin 커맨드를 입력해주면 된다.

연결이 정상적으로 해제되어 연결에 대한 아무 정보도 나오지 않는 것을 확인할 수 있다.


※ 현재 24년 7월 기준으로 깃에서의 기본 브랜치는 master이고 깃허브의 기본 브랜치는 main인 상황이다.(브랜치의 개념에 대해서는 차후 포스팅에서 설명하겠다.) 작업 시작 단계에서는 브랜치를 통일해야지 번거롭지 않으므로 git branch -M main 커맨드를 입력하여 기본 브랜치를 main 브랜치로 바꾸어주자.




리모트 레포지토리를 사용하는 이유

굳이 왜 번거롭게 리모트 레포지토리를 사용하는 것일까?


리모트 레포지토리를 사용하는 첫 번째 이유는 안정성 때문이다.
만약 내 컴퓨터나 작업 파일에 문제가 생겨 로컬 레포지토리가 날라가더라도 리모트 레포지토리에서 다시 작업본을 가져와 복구시켜버리면 그만이기 때문에 단지 로컬 레포지토리으로만 작업을 진행하는 것보다 훨씬 안정적이다.

리모트 레포지토리를 사용하는 두 번째 이유는 협업이 용이해지기 때문이다. 내가 여태까지 작업한 워킹 디렉토리를 리모트 레포지토리에 올리면 다른 팀원이 나의 리모트 레포지토리 안의 파일들을 본인의 컴퓨터로 가져와 작업한 후 commit-push하면 새로운 리모트 레포지토리의 내용을 pull하여 내 워킹 디렉토리에 합친 후 작업하는 과정을 반복한다. 이러한 방식을 통해 여러 명의 개발자들간의 협업이 리모트 레포지토리를 작업의 중간 경유물로 공유함으로써 용이하게 이루어질 수 있다는 장점이 존재한다.




git push: 로컬 레포지토리의 커밋 내용(변경 사항)을 리모트 레포지토리에 전송

만약 컴퓨터의 워킹 디렉토리에서 작업을 하고 add, commit을 하면 현재 작업물의 추가, 변경 사항이 내 로컬 레포지토리에만 저장되어 있고 리모트 레포지토리에는 저장되어 있지 않은 상황이다. 이럴 때 리모트 레포지토리에 로컬 레포지토리의 커밋을 보내고 싶다면 git push 커맨드를 입력해야 한다.


이미지를 보면 add와 commit을 수행한 후 git push -u origin main 커맨드를 입력하여 내 로컬 레포지토리에 추가된 파일인 TestFile을 깃허브의 리모트 레포지토리에도 성공적으로 전송된 것을 확인할 수 있다.

※ 맨 처음 push할 때에만 -u origin main을 붙이면 이후부터는 main 브랜치에 push할 때에는 git push 커맨드만 입력해도 된다. 만약 -u 옵션을 붙이지 않았다면 자동으로 연결하고 추적하는 tracking connection이 설정되지 않은 상태이기 때문에 push할 때마다 git push origin main(push할 브랜치 이름) 형식을 사용해야 한다.

여기서 -u는 --set -upstream의 줄임말로 이 옵션을 주면 로컬 레포지토리의 현재 브랜치와 리모트 해당 레포지토리를 자동으로 연결하여 추적한다(tracking)는 뜻이기 때문에 이후부터는 origin main같이 브랜치 이름을 생략해도 되는 것이다.




git pull: 리모트 레포지토리의 커밋 내용(변경 사항)을 로컬 레포지토리에 전송

이번에는 완전히 반대의 경우이다. 만약 깃허브의 리모트 레포지토리에서 직접 README.md 파일을 커밋했다거나 다른 팀원이 작업한 내용을 리모트 레포지토리에 업로드하여 리모트 레포지토리에만 새로운 내용이 추가된 상황이라면 리모트 레포지토리의 커밋 내용을 나의 로컬 레포지토리에 전송하여야 원활한 작업이 가능할 것이다.


이 때 리모트 레포지토리의 커밋 내용을 로컬 레포지토리로 전송하는 커맨드가 바로 git pull 커맨드이다.

일반적으로 다른 팀원들과 협업하여 작업을 하고 있으면 git pull 후 git push해야 되는 경우가 많다.
동시에 여러 명이 하나의 디렉토리에 대해서 작업하고 있고 서로 타인이 추가 및 변경한 코드들을 하나도 반영하지 않고 일한다면 협업의 의미도 없고 애초에 작업물이 아수라장이 될 것이다. 이런 경우를 방지하기 위해 공동 작업자가 push했고 내가 또 push를 하려고 하면 다음과 같은 에러가 발생한다.

해당 에러를 번역해보면 다른 사람이 이미 push를 한 상태이고 너의 작업물은 그 변화를 반영하지 않은 상태이기 때문에 리모트 레포지토리의 수정 사항을 반영하기 위해 push 전에 pull을 먼저 해서 변경 사항을 반영한 후 push하라는 의미이다.
시키는 대로 git pull을 수행한 후 git push를 진행하면 된다. 일반적으로 검증된 코드만 main 브랜치에 반영하므로 git pull origin main을 수행하면 현재 작업본에서 추가된 내용을 내 작업본에 반영할 수 있다.

또한 다음과 같은 에러도 발생할 수 있다.


pull을 진행하다 보면 해당 문구가 출력되는 상황이 종종 일어날 것이다. 새로운 브랜치가 생겨난 상황에서 ㅔpull을 하려면 merge를 해야 되는데 3가지 방식 merge, rebase, fast-foward only 중 하나를 선택하라는 것이다. 이런 경우 각 방식마다 장단점이 존재하기 때문에 팀원들간에 상의하거나 본인이 잘 선택해야 하지만 개인적으로 merge 방식인 git config pull.rebase false를 선택 입력한 후 다시 git pull한다.

git config pull.rebase false 입력한 후 git pull을 진행하여도

다음과 같은 경고문이 발생하는 경우가 있다. 깃에서는 기본적으로 서로 관련 history가 없는 두 프로젝트를 병합하려고 하면 거부하게 되어 있는데

git pull origin [브랜치 이름] --allow-unrelated-histories

커맨드를 통해 이를 허용할 수 있다.




push, pull시 conflict(충돌) 해결하기

git push, pull 커맨드를 입력하다 보면 해당 에러 문구와 자주 맞닥드리게 될 것이다.

이 문구가 출력된 이유는 push와 pull을 하면 내가 커밋과 다른 팀원들의 코드와 합치게 되는 경우가 많은데 같은 파일의 같은 위치에서 서로 다른 두 개의 내용을 합치려니까 깃이 어떤 코드를 우선해야 하는지 판단이 안 되어 내용 충돌이 발생했다고 알려주는 것이다.

예를 들어 리모트 레포지토리의 test1.txt의 파일의 내용은 다음과 같지만

<test1.txt>
aaaa

내가 push하거나 pull하려고 하는 상황에서 내 로컬 레포지토리의 test1.txt의 파일의 내용은 다음과 같다면

<test1.txt>
dddddddd

충돌이 발생할 것이다.


이런 경우 충돌이 발생한 부분으로 이동하여 <<<, ====, >>>>처럼 쓸데없는 부분은 지워버리고 내가 반영하고 싶은 내용으로 만든 뒤 다시 push, pull을 하면 된다.




git clone: 해당 리모트 레포지토리의 파일 전체 다운받기

특정 리모트 레포지토리 안에 있는 모든 파일들을 다운로드 받고 싶다면


현재 화면에서 Download ZIP을 통해 다운받아도 되고

저장하고 싶은 경로에서 git clone [레포지토리 URL] 커맨드를 입력하면 모든 파일들을 성공적으로 가져오는 것을 확인할 수 있다.



*해당 포스팅은 코드잇의 강의를 참고하였습니다.

profile
알고리즘, 자료구조 블로그: https://gyun97.github.io/

0개의 댓글