Git, 그게 뭔데 (2)

소정·2024년 1월 1일
0

멋쟁이사자처럼

목록 보기
13/20
post-thumbnail

이틀동안 미친듯이 달렸던 git 특강 ... 그 마침표를 찍어본다 ... (Git.)
Git, 그게 뭔데 1편 : 초기세팅, CLI, Git 명령어와 flow

3/4 정도 완료했는데 글이 날아가서 위에 2줄이 남았다 .. (ㅠ) 슬픔은 이제 그만 ,,,
더 제대로 기억할 수 있는 좋은 기회로 ! 생각하고 다시 작성 가보자고 ~!

저장이 잘 되었는지 주기적으로 확인하자 ^____^


gitignore

git 프로젝트는 모든 파일의 변경점이 감시된다.
이때 ! 변경점 관리를 하고 싶지 않은 파일이 있다면 ? (두둥)
gitignore를 통해 관리 대상을 관리할 수 있다. (관.대.관 ~)

gitignore 파일을 작성하는 여러 가지 방법을 알아보자 !

1. npm

npm (Node Package Manager)노드 패키지를 관리할 수 있는 도구이다.
npm install을 통해 패키지를 설치하면 node_modules 폴더 내 저장된다.
install 명령어가 변경될 수 있어, npm 사이트를 참고하면 좋다.

  1. npm install gitignore -g
    -g : 전역으로 패키지 설치
  2. gitignore -types
    예시) gitignore typescript

package.json 파일 내에 dependencies 등의 옵션으로 내역이 남는다.
노드 폴더가 프로젝트에 남는게 싫다면 아래의 npx 방법을 활용할 수 있다.

2. npx

npx (Node Package Runner)는 npm 패키지를 더 쉽게 설치하고 관리하도록 도와주는 CLI 도구이다. 패키지의 최신 파일을 설치 및 실행 후 패키지를 알아서 제거한다.

리액트와 관련된 create-react-app와 같이,
업데이트가 잦은 패키지라면 npx 방법이 훨씬 권장된다.

  1. npx add-gitignore -types
    예시) npx add-gitignore node,windows,osx,visualstudiocode
    (노드, 윈도우, 맥, 비주얼 스튜디오 관련 파일 무시)

한 줄로 손쉽게 gitignore 파일이 생성되었다.
위의 이미지를 참고하면, 생성된 gitignore 파일이 꽤나 방대한데 ..!
이게 넘 복잡시럽다고 생각된다면 이번엔 3번째, mrm 방법을 활용하면 좋다.

3. mrm

mrm (Merge Request Manager)은 node.js 패키지 실행을 쉽게 도와주는 도구이다.
npm을 통해 설치할 수 있는 패키지이며, 프로젝트 설정이나 구성 파일 등 반복적인 작업을 자동화하고 표준화하는데 주로 사용한다.

gitignoreeslint 등을 설치할 때 자주 사용된다.
npx 설치 방식보다 더 간결한 gitignore를 설치할 수 있다.

  1. npx mrm@latest gitignore

    # 생성된 gitignore 내용 (되게 간단하다)
    node_modules/
    .DS_Store
    Thumbs.db
    .idea/
    .vscode/
    *.sublime-project
    *.sublime-workspace
    *.log

4. 수동 작성

위의 모든 방법이 귀찮거나 어렵다면 ! 물론 직접 작성할 수 있다.
하지만 사실 이게 더 번거로운 방법이고 CLI 명령어로 설치하면 꽤 멋져보이기 때문에 위의 방법을 추천한다.

  1. .gitignore 파일 생성
  2. 변경점을 감시하지 않을 확장자, 또는 폴더명 작성

Branch, Checkout, Merge

이제 ! 본격적으로 git 활용을 해보자. 협업에 능한 멋진 프엔이 되기 위해선,
pull, add, commit, push만 하면 안된다. 사실 내 얘기 ~

특히 협업시엔 꼭 꼭 알아야할 개념이니 한번 가보자고 !

1. Branch

branch는 새로운 브랜치를 생성하고 관리할 수 있는 명령어다.
보통 협업을 할 때, 새로운 브랜치를 생성하여 작업 후 기준이 되는 main 브랜치에 합치는 방식으로 진행된다.

main은 나무의 기둥, 여기에 여러 branch를 생성하여 프로젝트를 빌드업 하는 느낌이다.
아래의 브랜치 관련 명령어를 확인해보자.

  • git branch <브랜치 이름> 브랜치 생성
    • git checkout <브랜치 이름> 브랜치 이동
    • git switch <브랜치 이름> 브랜치 이동
    • git checkout -b <브랜치 이름> 브랜치 생성 & 이동
    • git switch -c <브랜치 이름> 브랜치 생성 & 이동
  • git branch 브랜치 목록 (로컬)
    • git branch -a 브랜치 목록 확인 (원격 저장소 브랜치 포함 목록)
  • git branch -d 브랜치 삭제 (안전 삭제)
  • git branch -D 브랜치 삭제 (강제 삭제)
  • git branch -m <현재 이름> <변경 이름> 브랜치 이름 변경
  • git log --oneline --graph --all 가시화된 브랜치 목록 그래프로 확인

' checkout ' vs ' switch '

  • checkout git 2.23 버전 이하에서 브랜치 이동을 위해 사용하던 명령어
  • switch git 2.23 버전 이후 브랜치 변경을 위해 새로 등장한 명령어

checkout은 명령어가 세분화되기 이전에, 여기 저기 사용되던 명령어다.
(아래 2번 내용에서 더 자세히 기술 예정)

브랜치 변경 전용 명령어인 switch를 사용하자.

' branch -d ' vs ' branch -D '

브랜치를 삭제할 땐 두 종류의 명령어가 존재한다.
브랜치에서 작업한 내역이 있다면, 병합 여부에 따라 사용할 수 있는 명령어가 다르다.

  • branch -d 커밋 후 병합된 브랜치만 삭제
  • branch -D 커밋 후 병합 전 브랜치도 삭제

위와 같이, 병합된 브랜치를 안전하게 삭제할 수 있는 -d 옵션이 있고
병합 여부와 관계 없이 사용할 수 있는 -D 옵션이 있다.

error: The branch 'test' is not fully merged.
If you are sure you want to delete it, run 'git branch -D test'.

병합되지 않은 브랜치를 -d 옵션으로 삭제한다면 위의 메시지가 리턴된다.
병합 여부를 한번 더 확인할 수 있기 때문에 안전 삭제라고도 불린다.

병합한 줄 알고 브랜치를 삭제해서 다시 돌아갈 수 없는 강을 건너지 말고 !
-d 옵션을 사용하자.

2. checkout

위의 branch 내용에서 살짝 언급되었던 checkout 명령어다.
여기 저기 사용되던 명령어라는 표현을 했었는데, 아래와 같다.

  1. git checkout <브랜치 이름> 브랜치 변경 (switch 사용 권장)
  2. git checkout -- <파일 이름> 파일 복원 (restore 사용 권장)
  3. git checkout <커밋 해시> 커밋 간 이동

git 2.23 버전 이후, 브랜치 변경 담당 switch
파일 복원 담당 restore 명령어가 새롭게 등장했다.
그렇기 때문에 checkout커밋 간 이동을 담당으로 구분하여 사용하자 !

커밋 간 이동은 타임머신의 개념으로 생각하면 이해가 더 쉽다.
커밋 이동 후 새로운 브랜치를 생성하여 테스트를 할 수도 있고,

  • git checkout HEAD~2 2개 이전 커밋으로 이동
  • git checkout <hash> 특정 커밋으로 이동

reset 이전 내역이 살아있는 타임머신(checkout)과 다르게 아예 초기화 후 이동함 (아래 상세 기술)

hash

커밋을 할 때마다 절대 중복되지 않는 hash 값이 부여된다.
hash는 커밋에 부여된 ID와 비슷하다.
커밋 메시지 좌측의 7자리의 숫자와 영문 조합이 hash다.

  • git log --oneline

3. merge

  • git merge develop develpo 브랜치를 main 브랜치에 병합

드디어 등장하신 merge ! mergebranch 작업 후 병합을 위해 사용하는 명령어다.
깃 초보는 초큼 어려울 수 있으나 누구에게나 처음은 있다 ! 자신감 있게 가보자고 !

merge를 활용한 병합은 2가지의 방식으로 진행된다.

fast-forward 방식

  • 짜장이는 base 브랜치인 main 브랜치에서 작업중
  • 테스트를 위해 dev1 브랜치를 생성하여 작업 후 커밋 완료
    ** main 브랜치 변경 내역 없음
  • dev1 브랜치 작업 내용이 맘에 들어 main으로 병합 시도 !

이해를 위해서 위와 같은 상황을 살펴보자.
나무의 기둥이 되는 (=base) main 브랜치에는 변경사항이 없고,
새롭게 등장한 dev1 브랜치의 내역을 main에 합쳐야 한다.

main 브랜치를 dev1 브랜치의 변경 내역까지 빨리 감기하는 것 처럼 보인다.
이 방식을 fast-forward 방식이라고 한다.

하지만, 여러 명이 동시에 작업하는 현업에선 main 브랜치에 변경 내역이 없는 경우가 보통 없다 (ㅎ)
그럼 그건 뭔지 아래의 경우를 살펴보자.

3-way 방식

  • 짜장이는 base 브랜치인 main 브랜치에서 작업중
  • 테스트를 위해 dev1 브랜치를 생성하여 작업 후 커밋 완료
  • 동시에 짬뽕이는 main 브랜치에서 다른 기능을 작업 후 커밋 완료
    ** main 브랜치 변경 내역 있음
  • 짜장이는 dev1 브랜치 작업 내용이 맘에 들어 main으로 병합 시도 !

이번엔 main 브랜치에도 변경 사항이 발생했다.
이 상황에서 병합을 하기 위해선, 1️⃣ base와 2️⃣ main 브랜치의 변경 내역, 3️⃣ dev1 브랜치의 변경 내역, 즉 3개의 변경점을 모두 확인해야 한다.

이런 방식을 3-way 방식이라고 한다. 이때, main 브랜치에서 변경한 파일과 dev1 브랜치에서 변경한 파일이 같다면 아주 무시무시한 충돌이 발생한다.

충돌 해결

실무에서 충돌이 발생하면 식은땀이 줄줄 난다.
내 실수로 선임의 코드를 날릴 수 있기 때문 ~ ㅎ (ㅠ)
충돌을 해결할 수 있는 방법을 차근차근 알아보자.

위에선 같은 README.md 파일을 수정 후 커밋하여, 병합 중 충돌이 발생하였다.
이 경우 터미널보단 VS코드로 충돌을 해결하는 것이 간편하다.
터미널에서 작업중인 경우, code .을 통해 바로 해당 충돌 파일로 이동할 수 있다.

  • Accept Current Change 현재 HEAD의 수정 사항 선택
  • Accept Incoming Change merge한 branch의 수정 사항 선택
  • Accenpt Both Changes 두 branch 모두의 수정 사항 선택
  • Compare Changes 충돌된 부분을 확인하기 위한 화면을 split 비교

내가 작업한 내역을 날리고 HEAD 수정 사항을 선택하려면 Current 옵션,
pull을 받지 않은 HEAD 수정 사항을 날리고 내 작업 내역을 선택하려면 Incoming 옵션을 선택한다.

만약 파일 내에 수정된 부분이 많아서 가늠이 잘 안된다면,
우선 내가 작업한 내역을 백업해두고 Current 옵션으로 병합한다.
이후 병합된 파일(Current 버전)과 백업 내역을 비교하여 다시 커밋하는 것이 좋다.

하지만 제일 중요한건, 작업 전에 pull을 잘 받고 수시로 commit과 push를 하는 것이다.
선임들이 작업한 내역을 날리지 말자 ... !

rebase

두 개의 브랜치를 하나로 합치는 merge와 다르게,
rebase는 최신 커밋을 가져와 다른 브랜치의 끝에 붙이며 브랜치의 기록을 다시 작성한다.

merge보다 히스토리가 깔끔하게 유지되고 새로운 커밋이 생성되지 않는다.
하지만 커밋 히스토리를 변경하기 때문에 혼란을 야기할 수 있고 어렵다 .. !

우선 이번 포스팅에선 넘어간다.


Remote, Pull, Push

pushpull은 내 컴퓨터인 로컬과 원격 저장소인 리모트 서버를 연결하는 명령어이다.

작업 내역을 내 로컬에서만 가지고 있으면, 정말 아무 일도 일어나지 않는다.
결과를 내기 위해 가장 중요한 pull, push에 대해 알아보자 !

1. remote

Remote는 원격 저장소이다. github을 통해 원격 저장소를 생성할 수 있다.

  • git remote add origin <clone 코드> remote 연결
  • git remote -v remote 주소 확인
  • git remote rm origin remote 삭제
  • git remote update 커밋 내역 업데이트
  1. Github 개인 계정으로 로그인
  2. New Repository 생성
  3. Code 버튼을 선택하여 해당 저장소의 URL 복사
  1. Remote 서버 연결
    git remote add origin https://github.com/<Github 개인계정 ID>/<Remote 이름>.git

clone vs download

  • clone 로컬과 원격 저장소를 연결하여 git 변경점 관리
  • download 원격 저장소의 파일을 로컬로 다운로드, git 변경점 관리 불가능

clone 방식

  • HTTPS 대부분의 환경에서 기본적으로 지원되며, 쓰기 권한이 필요한 경우 매번 계정 인증 필요
  • SSH 보안 강력, SSH 키 인증 및 관리 필요
  • GitHub CLI 사용하기 위해 별도의 설치 필요

2. pull

Git에서 리모트 저장소의 변경 사항을 로컬 저장소로 가져오는 데 사용된다.

  • git pull = git fetch + git merge
  • git pull --set-upstream origin main 첫 pull시 사용
    --set-upstream 추적할 브랜치 설정, -u로 축약 가능
  • git pull 두번째 pull 부터 사용 가능

git fetch

fetch 명령어는 리모트 저장소의 최신 변경 사항을 로컬로 가져오는데 사용한다.

즉 로컬 저장소가 연결된 리모트 저장소의 최신 커밋과 데이터를 확인하고, 로컬로 다운로드한다. 하지만 로컬 저장소에 아무런 변경을 가하지 않기 때문에, merge가 필요하다.

3. push

Git에서 로컬 저장소의 변경 사항을 리모트 저장소로 전송하는데 사용된다.

  • git push --set-upstream origin main 첫 push시 사용
    --set-upstream 추적할 브랜치 설정, -u로 축약 가능
  • git push 두번째 push 부터 사용 가능

Pull request

리모트 저장소에서 병합 요청 보내서 코드 리뷰 받은 다음에 병합할 수 있는 방법이다.
CLI 방식이 아닌, 깃헙 페이지에서 GUI 방식으로 진행된다.

아래와 같이 push 후 pull request를 생성한다.
reviewers에는 보통 코드 리뷰를 받고자 하는 사수, 또는 팀원을 선택한다.

pull request를 생성하면 해당 요청에 포함된 커밋 내역을 확인할 수 있다. 요청이 완료되면, 병합이 완료되고 쓸모를 다한 브랜치는 삭제한다.


stash

stash는 변경된 내역을 임시로 보관, 즉 숨기는 명령어다.
커밋 없이 다른 브랜치로 이동할 때 활용하고 숨긴 내용은 언제든 다시 불러올 수 있다.

  • git stash 커밋 전 작업 내역 숨김
  • git stash list 숨김 목록 확인
  • git stash apply 최근 숨김 내역 꺼내기
  • git stash drop 숨김 내역 삭제
  • git stash pop 숨김 내역 적용 후 삭제

Reset

reset은 커밋을 취소하는데 사용하는 명령어다.

1. soft reset

  • git reset --soft HEAD~

리셋을 희망하는 커밋 시점 이후에 작업한 commit은 없어지지만,
변경 내역을 staging area에 남겨둔다.

add를 하지 않아도 커밋이 가능하다.

2. hard reset

  • git reset --hard HEAD~

리셋을 희망하는 시점 이후에 작업한 변경 내역이 모두 삭제된다.
삭제된 내역은 다시 살릴 수 없고 ( .. ) 협업시 트리도 망가지기 때문에 특히 더 주의해서 사용해야 한다.

3. mixed reset

  • git reset --mixed HEAD~

리셋을 희망하는 시점 이후에 작업한 변경 내역의 commit은 없어지지만,
변경 내역을 Working Directory에 남겨둔다.

add를 해야만 커밋이 가능하다.


참고자료

git ... 장장 이틀에 걸쳐 git과 친해져보았다.
pull, add, commit, push만 하던 git 초보자에서
이젠 git 용어를 나름 능숙하게 사용하지만 협업에선 어버버 사용자가 되었다. (ㅎ)

그래도 마냥 어렵기만 했던 git에 대한 감이 잡혀서 아주아주 상당히 ~ 뿌듯하다 !
그럼 끝 ~ !

profile
" 퍼블리셔에서 프론트엔드로 Level up 중 =3 "

0개의 댓글