Git & Github

이한결·2024년 6월 9일

Software

목록 보기
1/5

Git

Git을 한마디로 정의하면 Fast version control system이다.
그러면 과연 Github과의 차이점은 무엇일까?
Github는 remote repository등 원격 저장소를 관리하는 Tool이다.
이와 달리 Git은 버전을 관리하므로 목적 자체가 다르다.

Centralized vs Distributed


해당 사진은 Centralized된 방식이다. 모든 worker들이 중앙 집중식으로 commit & update를 반복하면서 동작을 수행한다. 이와 달리 Git은 Distributed방식으로 작동한다

Distributed 작동 방식이 아마 Git이 사랑받는 이유중에 하나일거다.
장점들을 아래에 간단히 정리해보겠다.

  • 빠르다
  • 인터넷 없이도 작업이 가능하다
  • Main Repository에 영향을 미치기전에 개발자간 상의 후 작업
  • Crash(충돌) Safe

Git Struture

Git을 배우면 가장 먼저 그리고 가장 많이 들었을 내용일것이다. 이번기회에 확실히 정리해두고 넘어가자.

Working directory: 각 유저들이 작업하는 환경이다. 로컬 컴퓨터의 폴더라고 생각하면 편하다.
Staging area: 이제부터는 Git이 역할을 한다. Git은 staging area에 올라간 파일들에 대해서 추적한다. 이때 추적은 수정됐는지 삭제됐는지 변화들을 체크하는 것이다.
.git directory: 흔히 commit된 공간이라고 보면된다. 원격 저장소에 보내기전 최종 저장공간이라고 생각하면 편하다
Working directory -> (add) -> Staging area -> (commit) -> Repository(.git directory)

Git 명령어

위의 정보들만 알면 사실 git을 사용하면서 나머지 부분들을 이해하면된다. 하지만 git을 사용하기 위해서 간단한 명령어들은 알고 들어가는게 편하다. 아래 명령어들을 참고해서 많은 실습을 하면서 익숙해지는게 가장 좋다! 참고로 아래 명령어를 git --help를 치면 나오는 명령어들이다.
Clone: Remote repository(원격 저장소)에 있는 정보를 local repository로 가져온다

git clone address.git

init: 현재 디렉토리를 기준으로(명령어를 실행하는 디렉토리) git repository가 생성된다 -> .git 파일이 생성된다

git init

add: 위에서 봤던 구조 중 working directory에 있는 파일을 staging area에 보내는 명령어이다.

git add f1.txt

-> f1.txt라는 파일만 staging area로 보낼게요!

git add .

-> 내 local directory(현재 명령어를 실행중인 폴더)의 모든 파일을 staging area로 보낼게요!

mv: 파일명을 바꾸거나 위치를 바꾼다

git mv 현재파일명 바꿀파일명

-> 현재파일명을 바꿀파일명으로 바꿀게요!

git mv 현재파일위치 바꿀파일위치

-> 현재파일위치를 바꿀파일위치로 이동시킬게요!

restore: 최신 commit버전으로 파일을 다시 저장한다
cf. commit은 아래에서 다시 설명하겠지만 버전이라 생각하면 편하다. 내가 작업을 하다가 망쳤을 경우 restore를 통해서 가장 최신 버전으로 돌아가주세요! 라는 명령어라고 생각하면 편하다.

git restore 파일명

특정 파일명에 해당하는 파일만 최신버전으로 바꿔주세요!
rm: 파일 제거

git rm filename
git rm -f filename

-> 수정직후에는 파일삭제가 안돼서 force(-f) 추가

git rm -cached filename

-> 파일을 완전히 삭제하는게 아니라 staging area에 올라간걸 다시 local directory로 가져오기

bisect:최초의 bug를 발생시킨 commit 찾기

git bisect

diff: commit간의 차이를 보여준다

git diff

grep:특정 문자열을 검색한다

git grep "hello"

log: commit 기록들을 보여준다(history 쭉)

git log

show: 가장 최신의 commit 기록을 보여준다(log와 다르게 한개만 보여준다!)

git show

status: file들의 tracking상태보기. 파일이 수정됐는지 삭제됐는지...(가장 많이 쓴다)

git status

branch: 코드를 분리하고 관리하는데 사용되는 기능으로서 branch를 생성. 해당 부분은 추가 설명 예정

git branch branch_name

-> branch_name이라는 branch 만들어주세요!
commit: repository에서 변경된 사항을 기록한다

git commit -am "change file"

commit할 때 주로 어떤 변경사항이 있는지 message와 함께 기록한다. 그래서 -m(message)를 사용하고 -a는 add명령어이다. commit하는 파일들은 staging area에 있는 파일들만 commit할 수 있고 staging area로 올리기 위해서는 add명령어를 사용해야된다. 즉 이 일련의 과정들을 -a명령어로 commit할 때 수행할 수 있는거다. 단 -a명령어는 이전에 한번이라도 staging area에 올라간 파일들만 가능하다!

merge: branch들을 합칠 때 사용

git merge exp

-> exp라는 branch를 현재 branch와 합쳐주세요!
reabse: brnach의 base를 옮긴다. base? merge랑 머가다르지? 해당 부분도 추가 설명을 하겠다. 그냥 대장을 바꾼다고 생각하면 편하다.

git rebase exp

-> exp라는 branch의 대장을 바꿔주세요!

reset: commit이전의 상태로 돌린다. 이부분도 -hard -soft이런식으로 상태를 돌리는 정도를 설정할 수 있는데 추후에 설명하도록 하겠다.

git reset -hard

switch: 다른 branch로 이동. 내가 생성한 많은 branch(서버)들 중 하나로 이동한다!

git switch branch_name

개인적으로 checkout이라는 명령어를 branch와 switch대신 많이 사용한다. 이부분도 추후에 설명하도록 하겠다.
tag: 각 branch에 해당하는 별명. 주의: branch와 다르게 수정이 불가능!

git tag 1.1.0

Merge vs Rebase

위에 명령어를 보다가 merge rebase라는 명령어를 봤을 때 처음봤다면 갸우뚱 했을거다.
우선 해당 내용들을 설명하기전에 git의 branch를 간단하게 알아보고 가자!
branch는 한마디로 특정 시점에서 독립적으로 작업을 진행할 수 있게 하는 것이다.
여러 사람들이 작업을 하다보면 branch를 나눠서 작업하기도 하고 코드를 실행할 때 특정 함수 혹은 기능을 구현할 때 다른 branch에서 작업을 하다가 합치면 효율적이다. git이 사랑받는 가장 큰 이유이기도 하다.
이제 대강 branch에 대해서 이해했을것이다.(안됐다면 다른 자료들을 참고한 후 진행)
위에서 설명한 것처럼 각각의 branch에서는 아마도 다른 기능, 다른 코드가 존재할 것이다. 그렇다면 이것을 하나로 합쳐야되지않을까? 그때 사용하는 명령어가 Merge와 Rebase이다.

Master branch에서 br1이라는 branch를 생성한 후 파일 f1과 f2를 수정했다. master에서는 f1을 br1에서는 f2를 수정했고 이를 합치고 싶은 상태이다.
Merge는 가운데 그림처럼 br1의 내용을 master로 합치는 것이다.
하지만이와달리 rebase는 자신의 대장을 master의 마지막부분으로 수정하는 것이다. 이렇게되면 f1이 이미 수정된 상태에서 f2를 수정한 상태가 되는 것이다.

이해를 위해 하나의 이미지를 추가하면 A의 대장 A2를 B1이후에 붙이는것이다.

Fast-forward vs 3way merge



우선 Fast-forward는 master branch를 hotfix에 merge할 때 빨리감기처럼 merge하는 commit에 합병하는 방식이다. 그림만 보고도 어렵지 않게 이해할 수 있을 것이다. C2가 단지 C4로 움직였기 때문에 별도의 commit(C)를 생성하지 않아도 되는이유도 한눈에 알 수 있다!


3way merge를 한마디로 정리하면 fast-forward를 진행하지 못할 때 별도의 commit(C)를 생성해 2개의 branch를 합치는 방식이다. fast-forward를 진행하지 못하는 이유는 공통의 조상으로부터 각각 다른 작업을 진행했기때문이다.
이를 해결하기 위해서 공통의 조상은 C2를 찾고 별도의 commit(C6)을 생성해서 2개를 합친다.

만약 branch들을 합칠 때 동일한 파일에 대해서 서로 다르게 수정하면 어떻게 될까? 에러가 발생한다.
왜?? 한번 생각해보자. 당신에게 PPT10페이지에 그림1을 넣어주세요라는 요청과 그림2를 넣어주세요라는 요청이 동시에 왔다. 당신은 어떻게 하겠는가? 아무것도 하지못한다. 어떤게 옳은 요청인지 모르기 때문이다. 이처럼 같은 파일에 대해서 다르게 수정할 경우 Merge시 오류가 발생한다
오류의 내용은 아래와 같은 형식으로 출력되고 내용을 통일시킨 다음 다시 Merge를 해야한다.

<<<<<HEAD 
현재 branch내용
==========
타겟 branch내용
>>>>>타켓 branch 이름

Switch vs Checkout

명령어 설명하는 부분에서 내가 개인적으로 선호하는 명령어가 checkout이라고 했던 말이 기억날거다. 그렇다면 checkout과 switch는 어떻게 다를까?
checkout명령어는 switch + resotre 2개의 명령어를 합친거다. branch를 변경하고 staging area에 있는 파일로 복원하는 것이라고 생각하면 편하다.

main vs origin/main


처음에 github가 remote repository라고 했었다. remote repository에 대한 별명이 origin이라고 했을 때 해당 repository에 대한 main branch가 origin/main이고 내 로컬 브랜치가 main이다.
조금 어려운 설명인거같다. 협업을 하거나 남의 repository에서 파일을 가져오다보면 그사람이 작업을 미리 해둔 경우가 있다. 그사람의 별명이 origin이라고 하면 그사람이 작업중인 main branch가 origin/branch이고 내가 작업중인 main branch는 main이라고하면 이해가 쉬울거다. 이것도 이해가 안된다면 그냥 내가 짱이니까 나는 별명없어! 라고 생각하면된다.

fetech vs pull


fetch: commit point 오브젝트와 실제 data를 local repo로 가져오되 아직 local working directory의 파일 시스템에는 반영시키지 않음 → merge로 반영해야함

pull: fetch + merge를 동시에 진행

Github

git에 대해서 왕창 이야기했는데 github에대해서도 간단히 설명하겠다. github은 remote repository이다.

Fork: 타인의 프로젝트 소스+ commit + branch정보같은 remote repository의 구조를 그대로 복사하여 내 소유의 remote repository로 복제하는 것
→ Fork한 내용을 수정해도 원본은 변하지 않는다

Pull requset: 내가 수정한 Commit들을 원본에 반영해줄 것을 요청

profile
열정으로 가득할 페이지

0개의 댓글