[Git/GitHub] Git을 배워보자 -2

SHark·2023년 4월 22일
0

졸업작품

목록 보기
7/8

Git은 GitHub과 합쳤을 때, 엄청난 시너지 효과가 나타나게 됩니다. 사실, 저번 글 까지의 Git은 Local (내 PC)에서 한 파일의 수정사항을 기록해서 되돌리거나, 계속 업데이트하는 기능을 했습니다. 이제, 이렇게 관리하던 파일을 여러 명이서 협업을 했을 때, 어떻게 할 수 있을지 생각해봅시다.

GitHub

GitHub은 원격저장소 입니다. 내 PC에 있는 파일을 GitHub서버의 일정 공간에 넣어두고 사용하는 예전에 N드라이브,DropBox 같은 느낌입니다. 실제로, GitHub 말고도, GitHub 대신 Bitbucket과 같은 저장소도 있습니다. Git을 쓰니까, Git의 단짝친구인 GitHub을 쓰는게 좋겠죠? 하지만, 자신의 상황에 맞게 유연하게 쓰면 됩니다.

GitHub 연결하기

우선, 원격저장소에 연결을 하는게 제일 첫 과정입니다. 그럴려면, GitHub이라는 서비스에 여러분의 공간을 만들어야 겠죠! 즉, GitHub의 회원이 되어야합니다.

GitHub에 회원가입 한 후에, GitHub Repo를 만들면 됩니다. 이 과정은 Google에 아주아주 자세하게 잘 나와있기 때문에 넘어가겠습니다.

이해가 되셨다면, 아래의 그림을 그릴 수 있어야 합니다. Local 영역인 내 PC와 GitHub의 저장소가 완전히 다른 거를 인식하는게 첫걸음이라고 생각합니다.

명령어

git remote add <name> <url>
예를들어, git remote add origin url~~ 이라고 하면, origin이라는 이름으로 해당 url에 있는 폴더를 인식하겠다는 겁니다.

원격 저장소에 내 코드 반영하기

이제, 연결을 했으니, local에 있던 내 소스코드들을 GitHub에 넣어주면 됩니다. 이 과정을 push한다라고 합니다. 원격저장소에 내 code들을 밀어넣어줘야, 비로소 저장이 되겠죠!

명령어

git push <name> <brach>

내가 현재있는 브렌치를 기준으로, remote에서 설정해준 이름의 폴더로 Push해준다는 의미입니다.
이때, Push되는 것은 Commit된 상태의 파일들을 Push해줍니다. 따라서, 파일을 Push해주기 전에 Commit은 필수과정입니다.

여러명이서 작업 시, 발생하는 문제점

혼자 작업을 한다면, 계속 Push만 해준다면, Error가 생길일이 전혀 없습니다. 왜냐하면 내 Local PC는 항상 최신 상태를 유지하고 있을테니까요. 하지만, Git의 탄생 이유는 협업 을 위해서 였습니다. 어떤 문제점들이 발생할 수 있을지 봅시다! 이 부분부터가 사실, Git/GitHub을 배워야하는 이유입니다.

내 PC에 있는 코드가 최신 코드가 아닐 수 있다.

세계관을 조금 확장시켜 보겠습니다. Sharkkk의 친구 Whale이 밤에 열심히 Front를 만들어서, 프로젝트에 반영을 했습니다. 근데, Sharkkk는 그런 것도 모르고 , 백엔드 코드를 열심히 짜서 , push를 하려고 했을 때 갑자기 Git이 퉤! 하고 뱉어버리는 경우가 생깁니다.

왜냐하면, GitHub에 있는 상태가 옳은 상태인지 , sharkkk가 밀어넣을 상태가 옳은 상태인지 컴퓨터는 판단을 할 수가 없습니다. 단지, 다르다라는 사실만 알 뿐이어서 개발자에게 판단을 요구합니다. sharkkk의 PC에 Commit된 상태에는 HTML파일이 없는데, 지금 GitHub에는 HTML 파일이 생겨버렸습니다.

이처럼, GitHub이 다른 작업자로 인해서 바뀌었는데, 내 Workspace에는 반영이 안되었을 때 GitHub과 동기화 시켜주는 명령어가 바로 Pull입니다. 직관적이죠? Github에 있는걸 "pull" 당겨 온다라는 의미입니다. 그래서, Pull은 push를 하기전에 필수작업 입니다.

명령어

git pull <name> <branch>
remote로 연결해준 name에 있는 원격저장소에서 내가 있는 branch로 자료를 당겨옵니다.

Flow(흐름) 관리하기

Pull,Push로 인해서, 원격저장소가 잘 관리가 된다면 정말 희망적이겠지만, 현실은 그렇지 않습니다. 예를들어, 실수로 작성한 코드를 실수로 Push한 경우 정확하지 않은 그 코드는 마치 전염병 처럼 모든 사람들의 코드를 먹통으로 만들 수 있습니다. 따라서, 실수로 Push를 했을 때 돌릴 수 있는 수단도 필요합니다.

즉, Push, Pull 과 같이 원격저장소가 업데이트 되면서 새로운 Version이 될 때, 그것들을 Graph형태(DAG)로 나타내면 아래와 같이 됩니다. 즉, 아래와 같이 Github이 변화하는 상태Flow라고 합니다. 원격저장소의 Flow를 관리하는 방법을 알아보겠습니다.

되돌리기 Revert

Git에서 파일을 되돌린 것 처럼, Github에서 push를 되돌리는 방법도 준비되어있습니다.
바로, Revert를 사용하면 됩니다. revert는 특이하게, Revert 자체가 커밋입니다.
무슨 의미인지 그림으로 보면 이해가 빠르게 됩니다. revert는 이미 퍼져버린 나쁜 코드들을 인정하고, 이전 버전을 새롭게 Commit을 하게됩니다.

공개처형하는 느낌도 들긴하지만, 이렇게 하는 이유는 Reset이라는 방법을 사용하게 되면 이미 v2.0을 가진 다른 프로그래머들과 reset을 한 Flow의 Commit갯수가 맞지 않게 되서 충돌이 일어나기 때문에, 새롭게 Commit을 해서 차라리 Pull을 하는게 충돌이 덜 된다는 개념입니다.

git revert <commit ID>

Branch

Git은 여러가지 흐름이 만들어질 수 있습니다. Main Branch만 있다고 생각해봅시다. 새로운 기능을 넣고 싶거나,버그수정이 필요할 때 Main Branch를 건드리게 된다면 그때마다 사용하고 있던걸 중단시켜야 하고, 또 테스트 하는데 만약 잘못된다면 또 시간이 더 걸리게 될 것입니다.


마치, 게임의 테스트 서버가 있는것 처럼 Git도 충분히 검증된 기능들이 Main에 와야합니다. 이 검증을 다른 Branch에서 하면 됩니다.

그러기 위한 기능들은 Git에 준비되어 있습니다. 바로 다른 흐름의 개념인 Branch와, 기존의 Branch에서 다른 Branch의 변경사항을 가져오는 Merge , rebase , 여러 변경 사항 중 원하는 것만 가져오는 cherry pick이 있습니다.

기존 프로젝트에 신기능을 추가하고 싶거나, 뭔가를 테스트 하고 싶을 때, 새로운 가지를 생성합니다. 보통, dev branch를 따로 생성해서, Main Branch에는 Product(상품)레벨에 것만 Push하도록 합니다.

명령어
git branch <name>
name으로 된 branch를 생성합니다. 예를들어, git branch dev 라고하면, dev branch가 생성됩니다.
git checkout <name>
name으로된 branch로 이동합니다. 예를들어, git checkout dev라고하면, dev branch로 이동합니다.

merge

자신이 있는 branch로 원하는 Branch의 변경사항을 땡겨옵니다. 받는 쪽에서 땡겨오는 개념입니다. 헷갈리면 안됩니다.

Merge에서 Confilct(충돌)이 많이 발생하게 됩니다. 이는 , Main Branch에 있던 파일과
다른 Branch에 있는 파일이 달라져서 그렇습니다. 아래의 상황을 보면서 이해를 해봅시다.
v2.0을 기준으로 신기능을 개발하고 있었는데, 심각한 오류가 발견되서 긴급패치를 했다고 합시다.

그러면, 신기능개발 Branch의 내부파일(새롭게 추가된 파일 x)과 Main에 있는 내부파일이 서로 수정되는 both Modified가 되게 됩니다.

그래서, 어떤 것이 맞는지 Git은 어떤게 맞는지 몰라, 개발자에게 판단을 요구합니다. 이때, 차이가 나는 부분을 git이 자동으로 알려줍니다. 따라서, 이 포인트에서는 직장의 사수나, 프로젝트 리더 등 사실확인이 가능한 사람에게 물어봅니다. 그 후,올바른 수정을 반영해서 git add 하고 commit 뒤 ,push를 해주면 됩니다.

명령어

git merge <branchname or CommitID> ,git merge --abort (실행취소)

Merge에 대한 더 자세한 내용을 알고싶다면, 공식문서를 참고해주세요! Merge는 다양한 옵션이 있습니다. 제가 설명한 것은 FF(기본옵션)를 기준으로 설명드렸습니다.

rebase - 개념은 좋았으나 , 원격저장소에 쓰지말 것!

rebase는 Merge랑 비슷한 기능인데 , Branch들을 좀 깔끔하게 해줍니다. 큰 기업이라면 수백,수천개의 Branch가 생길 수 있기 때문에, UI를 이용해서 프로젝트의 Git을 보고 싶을 때 괴로울 수 있습니다. 그래서 적당한 시기가 되면 Branch 또한 정리를 해주어야 합니다. Branch를 정리한 다음에, Merge를 해준다고 생각하면 됩니다.

예를들어, 신기능이 충분히 안정적이게 되었고 우리 서비스에 자리를 잡았다면 해당 Branch는 이미 Main에 반영이 되었으니 Main의 한 흐름으로 봐도 무방하지 않냐라는 개념입니다.

이것도 그림으로 한번 보시죠.


이렇게 되면, 여러개의 Branch를 생각보다 깔끔하게 볼 수 있을 겁니다.

절대 rebase를 원격저장소에 쓰지마 !

Rebase는 remote로 연결된 곳에 Push된 commit에 대해서는 하지 않는걸 추천한다고 git 공식에서 말하고 있습니다. rebase는 새롭게 commitID를 새로 생성하기 때문에, 다른 작업자들이 pull을 할 때, 새로운 commtID이기 때문에 새로운 Commit인줄 알고 git이 다 다시 pull을 하게 됩니다. 즉, Branch를 깔끔하게 하려고 했는데, History가 더러워지는 등가교환 법칙이 성립이 됩니다!

Rebase는 Local에서 내 History가 너무 더러울 때 (Commit을 뭔가 너무 많이 한 것 같다 혹은 내 Commit이 명확하지 않은 것 같다)는 생각이 들 때, 특정 Commit을 기점으로 정리를 하기 위한 용도로 쓰는게 적절합니다. . 내가 뭔가 많이 개발을 하고, 여러개의 branch를 쓴것 같다 싶으면 rebase로 히스토리를 깔끔하게 해주는 센스를 발휘하는게 좋다고 합니다.

GitHub과 통신할 때는 Merge를 사용하고 , 필요한 Commit만 하면 rebase를 사용할 일은 거의 없겠죠!

명령어

git rebase <commitID> , git rebase <branch>

cherry pick

Cherry Pick은 다른 Branch에서 내가 하고싶은 변화만 딱 집어서 현재 있는 branch에 반영하는
명령어입니다.

git cherryPick <commitID>를 이용해서, 기준 Branch로 당길 수 있습니다.

태그기능 git tag

CommitID를 매번 우리가 확인하기는 어렵다. 특히, 여러명이서 개발하는 큰 프로젝트는 확인하는데 더 시간이 걸릴 수 있다. 따라서, 큰 패치나, 중요한 업데이트 사항이 있다면개발자들의 편의를 위해서 tag를 달 수 있다.

위의 그림에서 계속 v2.0 , v1.1을 단 것이 tag기능을 사용할 수 있다는 떡밥이었다!

명령어

git tag [tag name] [commitID]

임시저장 기능 git stash

열심히 프로젝트를 수정하고 있었는데, 다른 브렌치 였다면 좀 애매할 것이다. 왜냐하면, 내가 열심히 수정한 것들을 날리기는 싫고, 다른 브렌치로 이동은 해야하할 것이다. 그럴때, stash(임시저장)소를 이용할 수 있다.

1. 내가 막 수정수정을 하다가 잠깐 다른 브렌치로 가고 싶을 때, 이용할 수 있다.
2. 내가 다른 브렌치에서 작업하는 걸 늦게 깨달았다. (다른 브렌치로 들고가서 적용하면 됨)

난 dev branch인줄 알았는데 main branch 였다면 얼른 dev branch로 가야한다. 그래서, stash로 변경사항을 저장한 뒤, dev branch로 변경한 뒤 git stash apply를 해주면 된다.

명령어

git stash , git stash apply

Git 전략

git의 flow를 관리하는 전략은 신입이 짜지는 않겠지만, 공부하는것 나쁘지 않습니다. 저희도 언젠가는 주니어가 되는거니까요! 물론, 신입이 잘하면 짤 수도 있죠! Git관리 전략은 다양한 방법들이 있습니다. 이건 자세하게는 다루지 않을 겁니다. 우리는 git을 잘 다루는것만에도 급급하니까요!

0개의 댓글