본문으로 바로가기

Git 공부

category Core Computing/Git 2024. 4. 24. 09:39

여러 컴퓨터에서 프로젝트 진행상황에 맞게 개발을 하기위해 깃허브를 사용하곤 한다.

하지만 커밋하다보면 굉장히 곤란한 상황에 놓이는 경우가 많다.

예를 들면, 실수로 push를 안한 상태로 다른 곳에서 커밋을 해버린 적이 있다..ㅠㅠ

무엇을 위해 공부해야하는지 몰라 건들지 않고 있었던 Git이었는데, 막히는 상황들을 포함해서 이유를 찾을 수 있지 않을까 생각한다. 또, 아무래도 "프로그래머들이 자주 사용하는 git에는 분명 다 방법이 있을 것"이라는 생각이 든다.

그래서 한번 git 공부를 시작해본다.


이번 공부에 도움을 준 책은 [모두의 깃&깃허브] 이다.

https://product.kyobobook.co.kr/detail/S000061450151

 

모두의 깃&깃허브 | 강민철 - 교보문고

모두의 깃&깃허브 | 557개 일러스트와 그림으로 배우는 가장 쉬운 깃&깃허브 입문서!여러 사람과 협업하고 있는데, 코드 관리는 어떻게 해야 하지? 내 코드를 예전 버전으로 되돌리고 싶어! 코드

product.kyobobook.co.kr


우선 github를 이용하며 가장 헷갈렸던, Discard 와 Ignore의 차이이다.

Discard (버리기) : 변경 사항을 '버리는' 것을 의미 - 즉, 변경된 파일을 이전 상태로 되돌리거나, 아직 커밋되지 않은 변경 사항을 제거합니다. 변경 사항을 저장하지 않고 버립니다.

Ignore (무시) : 특정 파일 또는 디렉토리를 Git의 추적 대상에서 제외하는 것을 의미합니다.

 

만약, push하지않은채, 다른 곳에서 같은 내용에 push를 하여 충돌이 일어난 상황인데 저장되지 안해도 되는 작업이었다면 Discard를 할 수 있다. 반대로 저장이 꼭 필요한 내용이라면? 병합후 충돌처리를 해주면 된다.

Ignore는 수정사항에서 제외된다 .gitignore파일에 들어가는 것을 의미!

 

병합충돌이 생기면 이런 내용이 뜨는데, 

<<<<<<< HEAD 
Master          : 현재 (체크아웃한)브랜치 내용 
======= 
foo             : foo 브랜치 내용 
>>>>>>> foo

<<<<<<< 와 ======= 사이의 내용을 선택할지=======와 >>>>>>> 사이의 내용을 선택할지 '수동으로' 고르라는 표기이다. 

 

하나하나 봐야하는 경우가 아닌, 한쪽 파일을 선택해도 된다면

위 사진과 같이 둘 중 하나의 파일로 적용시켜도 좋다!

 

 

위 내용을 아무것도 모른 상태로 push하지 않은 commit이 남은 상태로 pull을 했을때, 가장 먼저 Stash를 볼 수 있는데,

Stash란 임시 저장 기능으로  변경 사항을 모두 임시로 저장해놓고 변경 전의 상태로 돌린다, 새롭게 추가된 파일(untracked)은 stash할 수 없다.

임시 저장해 놓은 것과 후에 병합처리가 가능하다!

 

지금까진 혼자 진행시의 문제였으나 협업시에도 비슷한 형태로 흘러가는듯하다.

 

우선 협업을 진행하려면 나뭇가지라는 뜻의 Branch를 알아야 한다.

Branch란 버전을 여러 흐름으로 나누어 관리할 수 있는 방법이며, Branch를 나눌때마다 버전의 분기 생기는 형태이다.

협업시엔 나누어진 각자의 브랜치에서만 작업한다.

Head는 현재 브랜치의 최신 커밋을 가르키는데, 분기가 나뉘고 각자의 작업이 다르면 Head가 어디에 있냐에 따라 커밋의 개수와 내용이 달라진다.

특정 브랜치에서 작업하도록 바꾸는 것을 체크아웃이라고 하는데, 이것은 Head의 위치를 바꾸는 것과 같다!

 

각자의 브랜치들을 병합하는 방식으로 협업을 하곤 하는데, 다른 브랜치의 선택한 커밋까지 병합이 가능하다. 또, 브랜치를 재배치하여 분기를 변경하는 Rebase (브랜치의 재배치) 방법도 있다.

 

그렇다면 여기 또 다른 문제 하나가 있다.

리포지토리는 분명 각자 가지고 있는건데 어떻게해야 남의 계정에 커밋할 수 있는가?

첫번쨰 방법으론 Collaborator, 푸시 권한을 주는 방법이 있다. 잘 권장하지 않는 방법으로ㅡ 저장소 주인의 의사와 관계없이 변경 사항들이 계속 추가되는 상황이 발생한다. 

그래서 다음 방법을 많이 쓰는데,

두번째 방법으로 Pull request, 저장소 복제 및 커밋 후, 저장소 주인에게 pull요청을 보내는 것이다.

이 과정에서 중요한 것은 Fork(복제)하기, 브랜치 생성 및 작업 커밋 후, 잊지말고 Pull Request 보내기 이다. 

또한 깃허브에서 Fork시, 기존 저장소와 연결하고 싶냐고 물어보는데 잘 보고 설정해야 하는 듯 하다

+ 협업을 진행할 때 주의할 점 : Unity의 버전 통일, Asset 직렬화 방식 (github에 저장되는 파일의 직렬화 방식이 같아야 한다), Version Control

Unity 엔진에서 파일을 저장하는 방법은 '바이너리', '텍스트', 그리고 이 두가지를 섞어서 사용하는 혼합 방식이 있다. 'Edit → Project Settings → Editor → Asset Serialization Mode'에서 선택 가능.
'Edit → Project Settings →  Version Control → Version Control Mode'가 서로 다를 경우, pull / push 할 때 문제가 발생할 수 있다. 별도의 다른 버전 컨트롤 프로그램을 사용하는 것이 아니라면 'Visible Meta Files'로 사용하길 권장

 

그 외에 아직 사용할지 잘 모르겠는 기능

Revert (돌아가다) : 되돌린 버전 상태에 대한 새로운 버전(커밋)을 만드는 방식

Reset (초기화) : 되돌아갈 버전 상태까지 완전하게 되돌아가는 방식, 해당 버전 이후의 버전은 삭제

reset에는 크게 세 종류 (soft, mixed, hard)

soft reset : 커밋만 (스테이지에 돌아온다.)
mixed reset : 스테이지와 커밋만 (작업 디렉터리 내 변경 사항으로 돌아온다.)
hard reset : 작업 디렉터리 내 변경 사항까지 통째로 (전 버전으로 돌아온다.)

 

마지막으로 [깃 명령어] 정리

git config --global user.name " ~~ " : 이름등록

git config user.name : 등록 이름 확인           (.email도 가능)

git init :  로컬 저장소 만들기                          ($ cd C:\test 명령어로 원하는 경로로 이동 가능)

git status : 작업 디렉터리 상태 확인

git add : 스테이지에 올리기                           (파일명 or . (현재 디렉터리에 있는 모든 사항))

git commit : 커밋하기                                  (--message "커밋 메세지(제목)", 내용 적고 싶다면 a또는 i로 입력모드 전환 후 세번째 줄에 내용 추가 가능 + esc로 빠져나오기  :wq 입력)

git commit -am "커밋메세지" : 스테이지에 올리기 + 커밋하기 (tracked 파일에만 사용가능 == 새 파일엔 불가능)

git log : 커밋 조회

git log --gragh : 소스트리의 커밋그래프와 유사하게 생성, 브랜치별 커밋의 가독성을 높임

git log --branches : 모든 브랜치의 커밋 목록을 조회할 수 있는 옵션

git tag : 태그 추가/조회/삭제

git diff : 최근 커밋과 현재 작업 디렉터리 비교

git diff --staged : 최근 커밋과 스테이지 비교

git diff <커밋> <커밋> / <브랜치> <브랜치> : 커밋, 브랜치 끼리 비교, 짧은 커밋 해시를 이용하면 됨 (첫번째 기준으로 두번째가 달라진 점을 알려준다, Head를 기준으로 비교도 가능하다'HEAD^^,HEAD^,HEAD' or 'HEAD~2,HEAD~1,HEAD')

git reset <되돌아갈 커밋> : 역시 마찬가지로 soft, mixed, hard 세가지로 나뉜다.(뒤에 --soft, mixed, hard를 추가)

git revert <취소할 커밋> : reset과 달리 해당 커밋을 취소한 새로운 커밋을 추가하는 방식

git stash : 미리 배웠던 것과 마찬가지로 tracked 상태의 파일만 해당된다. (-m "메세지" or --message "<메세지>" 명령으로 간단한 메시지와 함께 임시 저장도 가능하다.)

git stash list : 임시 저장된(stash) 작업을 조회 

git stash apply <스태시> : 임시 저장된 작업을 적용, stash@{n} 으로 표시되어있던 스태시를 불러와 적용시킨다. 

git stash drop <스태시> : 임시 저장된 작업을 삭제

  • 브랜치 관련

git branch : 깃 배시의 경로 옆 (괄호안에서) 현재 브랜치를 알 수 있다. 또는 git branch 명령으로 알 수 있다. 현재 작업 중인 브랜치가 *로 표시된다.

git branch <브랜치> : 브랜치 나누기, <브랜치>에 원하는 브랜치명을 적으면 된다!

git branch -d <브랜치> : 브랜치 삭제

git checkout <브랜치> : 체크아웃

git merge <브랜치> : 브랜치 병합, 체크아웃하고 있는 브랜치와 <브랜치>를 병합한다. (충돌시엔 브랜치 이름이 (현재 브랜치|MERGING)으로 표기 되는데, 파일을 열어보면 아까 위에 나왔던 것처럼 << == >> 으로 표기 되어 있어 이 부분을 수정해주면 된다!)

git rebase <브랜치> : 재배치

git clone <경로> : 복제, 주소(경로)를 가져와 깃 배시에 붙혀넣는다. (복제할 경로를 설정하고 싶다면 경로 입력 후 뒤에 <클론받을 경로>를 추가해주면 된다.) 

  • 깃허브와 연동

git remote / git remote -v / git remote --verbose : 원격 저장소 이름 / 이름 + 경로 조회

git remote add <원격 저장소 이름> <원격 저장소 경로> : 원격 저장소 추가 (로컬과 원격 저장소의 연결)

git remote rename <기존 저장소 이름> <바꿀 저장소 이름> : 원격 저장소 이름 변경

git remote remove <원격 저장소 이름> : 원격 저장소 삭제

 

git push : 저장소에 밀기

git fetch / git fetch <원격 저장소 이름> : 일단 가져오기 (가져온 후 git status ㅡ 커밋이 다르면 "Your branch is behind ' <원격 저장소 이름>/main' by 1 commit"이라는 메세지가 뜬다. + git diff main <원격 저장소 이름>/main ㅡ 로컬과 원격의 차이점을 볼 수 있다.)

git pull / git pull <원격 저장소 이름> : 가져와서 합치기

git <명령> --help : 메뉴얼 보기 (가장 신뢰도 높은 메뉴얼 페이지, 깃 공식 홈페이지의 Reference)

 

 

+ 깃 공식 홈페이지의 Book의 Pro Git , 좋은 참고 도서라고 한다! (한국어 지원됨)

+ 처음 원격 저장소로 푸시하는 경우

$ git remote add <원격 저장소 이름> <원격 저장소 경로>
$ git branch -M main				//브랜치 이름 변경
$ git push -u <원격 저장소 이름> main		//-u는 처음 푸시할때 한 번만 사용하면 됨

+ 태그는 특정 커밋에 붙일 수 있는 꼬리표, 릴리스 버전을 태그로 표시함

+ 소스트리와 깃허브 연동은 SSH통신방법을 사용하는데 개인키와 공용키를 만든 후 설정하면 사용이 가능하다.

+ pull request의 경우 원본 저장소의 새로운 커밋을 가져오려면? 깃허브 사이트에서 Fetch upstream - Fetch and Merge

 

 

정말 협업을 위한 모든 것을 갖추고 있는 것 같다. 나도 언젠가  협업의 기회가 생겨 써볼 상황이 오면 좋겠다.

또 앞으로 혼자 작업할때 막힐 일은 없을 것 같아.. git공부 시작하길 너무 잘한 것 같다!!