Git 명령어 심화

심화 명령어

이전 페이지에선 기본 명령어와 응용 명령어를 다루어 보았습니다.
이번 페이지에서는 심화 명령어를 다루어 보도록 하겠습니다.

3-way merge

일반적인 병합 방식
병합할 두 브랜치(branch)와 공통의 조상(ancestor) 커밋을 이용하여 병합하는 방식입니다. 이 방식은 가장 일반적인 병합 방식으로, 자동으로 처리됩니다
병합할 두 브랜치 : m4, f2
공통의 조상 : m2
Merge 전
Merge 후

사용법

git merge # 현재 브랜치와 병합 대상의 관계가 Fast-forward관계 여부와 상관없이 # Merge 커밋을 생성하여 병합한다. git merge —-no-ff
Markdown
복사
결과 이미지

fast-forward merge (빨리감기 병합)

새로운 브랜치(branch)를 만들고, 해당 브랜치에서 변경사항을 추가(commit)한 후에, 메인 브랜치(main branch)에 그대로 적용하는 병합 방법입니다.
이때 메인 브랜치가 새로운 커밋을 추가하지 않은 경우에만 가능합니다.
Merge 전
Merge 후
이 방법은 commit 히스토리를 깔끔하게 유지할 수 있습니다.
하지만, 기존의 커밋 히스토리가 사라질 수 있어서 주의해야합니다.

사용법

git merge # 현재 브랜치와 병합할 브랜치가 Fast-forward 관계일 경우 Fast-forward 병합을 진행하고, # 그렇지 않은 경우에는 3-way-merge를 진행하여 Merge 커밋을 생성하여 병합합니다. # git merge --ff <브랜치명> git merge --ff feature #현재 브랜치와 병합할 브랜치가 Fast-forward 관계인 경우에만 병합을 진행하고, # 그렇지 않은 경우에는 병합을 진행하지 않는다는 명령입니다 # git merge --ff-only {병합할 브랜치 명} git merge --ff-only feature
Markdown
복사
결과 이미지

squash and merge (squash : 으깨다, 으끄러지다)

새브랜치의 커밋기록을 으깨서 메인브랜치에 하나로 넣는다.
Merge 전
Merge 후

사용법

# 병합 대상 브랜치의 모든 커밋을 하나의 커밋으로 squash(압축)해서 현재 브랜치로 가져옵니다. # 이때 Merge 커밋 없이 실제 작업이 이루어지는 따로의 커밋은 존재하지 않습니다. # git merge --squash <브랜치명> git merge -squash feature
Markdown
복사
결과 이미지

rebase & merge (rebase: base를 재설정한다)

3-Way로만 merge를 하면 브랜치 줄이 다양해집니다.
그래서 간단한 브랜치들은 rebase를 하게 됩니다.
Merge 전
Merge 후
rebase는 fast forward와 달리 main branch에 commit 이 있어도 merge 가 가능한 장점이 있습니다.
하지만, 이어붙이는것이기 때문에 conflict이 뜰 수 있다는 단점 또한 존재합니다.
rebase 명령어는 새로 생성한 브랜치에서 명령을 하는 것이고, merge 명령어는 기존 브랜치(통합하려고 하는)에서 명령을 하는 것입니다.
상황에 맞는 명령어를 사용해야합니다.

사용법

git checkout 새로운브랜치 git rebase "브랜치명" git checkout "브랜치명" git merge 새로운브랜치
Bash
복사
결과 이미지

git restore (restore: 복구하다)

작업 디렉토리의 파일 상태를 복구할 때 사용하는 명령어 (commit하지 않은 변경사항을 마지막 상태로 되돌림)

사용법

# git restore 파일명 # 특정시점으로 해당파일을 복구한다 # git restore --source <commit id> <파일명> # 스테이지 취소 # git restore --staged <파일명>
Markdown
복사
결과 이미지

git revert (돌아가는것)

되돌아가는데 되돌아간다는 기록이 남아있음

사용법

# 지정한 commit에서 변경된 내용을 되돌립니다. 이를 통해 이전 커밋으로 되돌아갈 수 있습니다. # git revert <커밋아이디> # 여러 개의 커밋에서 변경된 내용을 모두 되돌립니다. # git revert <commit id 1> <commit id 2> # 직전의 커밋 변경 내용을 되돌립니다. # git revert HEAD # Merge 커밋을 취소합니다. # git revert HEAD
Markdown
복사
결과 이미지

git reset (0의 상태로 되돌리는 것.)

작업하던 곳을 이전 상태로 다시 되돌려주는 기능
협업 시에는 잘 사용하지 않습니다. 사용에 있어 매우 주의를 요합니다!

사용법

# 업 디렉토리, 스테이징 영역, 커밋을 모두 지우고 지정한 커밋으로 돌아가는 방법 # git reset —hard 커밋아이디 # 변경 지우지 않고 커밋아이디이후 변경한것은 stageing area에 올려놓은 상태로 돌아가는 방법 # git reset —soft 커밋아이디 # 변경 지우지 않고 커밋아이디이후 변경한 것은 unstage해놓은 상태로 돌아가는 방법 # git reset —mixed 커밋아이디
Markdown
복사
결과 이미지

알아두면 좋은 정보

.gitignore 파일

.gitignore 파일은 Git으로 버전 관리를 하지 않을 파일이나 디렉토리를 지정하는 파일입니다.
.gitignore 파일에 지정된 파일이나 디렉토리는 Git으로 관리되지 않습니다.
언어, ide, 프로젝트마다 관리하면 안되는 파일들이 다 다릅니다.
그렇기에 구글에 내 상황을 적어서 검색하는게 제일 좋습니다.

예시

현재 상황 언어: javascript ide : vscode > ’javascript vscode .gitignore file example’ 로 검색
유저가 업로드한 ‘프로필 이미지’나 ‘영상’ 들은 개발자가 생성한 코드가 아니기에 git으로 관리하지 않기도 합니다. 그럴 경우 아래와 같이 예외처리를 하는 경우도 있습니다.
# JPEG *.jpg *.jpeg *.jpe *.jif *.jfif *.jfi
Markdown
복사

커밋 메시지 작성

커밋 메세지는 어떻게 작성하는게 좋을까요?
명확하고 간결하게 작성합니다. 제목과 본문은 분리합니다. 제목은 50글자로 제한하고 , 본문은 개조식으로 작성하여 명확성을 높입니다.

예시

[closed #1] 게시글 목록 조회 오류 수정 or [JIRA-123] 게시글 목록 조회 오류 수정 - 인덱스 범위 오류 수정함. - 리스트 접근 조건문 추가하여 안전하게 접근하도록 변경함. - 사용자 테스트 중 보고된 ㅇㅇ 문제 해결을 위해 수정함.
HTML
복사

origin, upstream

이 두 용어는 Git에서 코드의 흐름과 관계를 나타내는 중요한 개념입니다.
그런데 이 용어들을 제대로 이해하기 위해서는 먼저 '위치'라는 개념에 대해 생각을 해봐야합니다.
'위치'는 상대적인 것으로, 어떤 것이 어디에 위치해 있는지는 관점에 따라 달라집니다.
예를 들어, 어떤 Git 저장소(repository)에서 다른 저장소로 코드를 복사해오는 과정을 'fork'라고 합니다.
이후, 복사된 코드를 개인 컴퓨터(로컬 환경)에서 수정하는 작업을 진행합니다.
이 예시에서 'upstream'과 'origin'의 위치는 '기준점'에 따라 달라집니다.
기준점이 로컬 환경이라면, 'origin'은 로컬 환경에서 작업 중인 저장소를 가리키는 원격 저장소를 의미합니다.
보통 이는 본인이 작업하고 있는 프로젝트의 GitHub 저장소와 같습니다.
'upstream'은 이 'origin'이 fork된 원본 저장소를 의미합니다.
즉, 본래의 코드가 존재하는 원격 저장소입니다.
이렇게 설정된 'upstream'과 'origin'은 Git 작업 흐름에서 중요한 역할을 합니다.
'origin'은 본인의 작업이 반영되는 원격 저장소를 의미하고
'upstream'은 변경사항을 가져오거나 비교할 기준점이 되는 원본 저장소를 의미합니다.
push 하기전에 --set-upstream 옵션으로 원격저장소 브랜치를 연결하지 않나요? 그러면 개인 계정 레포지토리를 upstream이라고 말하는 것이 맞나요?
답변
네, 아래와 같이 원격저장소의 브랜치와 내 로컬저장소의 브랜치를 연결하는 것이 맞습니다. 이 설정은 향후 git pushgit pull을 실행할 때 원격 저장소와 브랜치명을 생략할 수 있게 해줍니다.
git push -u origin main
Plain Text
복사
여기서 u 옵션은 -set-upstream의 약자입니다.
upstream은 명사로 ‘상류’이고, 형용사로 ‘흐름을 거슬러 오르는’라는 뜻을 가지고 있습니다.
--set-upstream이라는 옵션에 "upstream"이라는 용어가 사용되는 이유는, Git의 데이터 흐름의 방향성을 나타내는 데서 유래합니다. "upstream"은 말 그대로 상류를 의미합니다. 이 컨텍스트에서 보면, 로컬 브랜치가 데이터의 변경사항을 보내는 대상 원격 브랜치를 '상류'로 간주할 수 있습니다. 로컬 브랜치의 변경사항이 '흐름을 따라' 상류로 향하도록 설정하는 것이죠. 이는 변경사항이 로컬에서 시작하여 상류(원격 저장소의 특정 브랜치)로 흘러가는 구조를 묘사합니다.
일반적으로, 조직 계정의 레포지토리를 복제하여 개인 계정의 레포지토리를 만드는 경우, 조직 계정의 레포지토리는 원본 레포지토리로 간주되어 'upstream'으로 불리고, 개인 계정의 레포지토리는 이를 포크해온 결과이기 때문에 'origin'으로 지칭됩니다. 따라서 개인 계정의 레포지토리를 'upstream'이라고 부르는 것은 일반적이지 않습니다.

Git 브랜치 전략 (git-flow)

전략은 단지 하나의 접근 방식에 불과하며, 모든 상황에 정답이 되지는 않습니다.
각각의 상황에 맞게 유연하게 적용할 필요가 있습니다.
기본적으로, 모든 배포는 별도의 격리된 브랜치에서 작업을 완료한 후, PR을 통해 배포를 위한 브랜치에 머지해야 합니다.
브랜치는 중요도에 따라 세 가지 주요 유형으로 구분됩니다.
1.
Master / Main : 배포 브랜치
안정성이 보장되며, 운영 중 발생할 수 있는 치명적인 문제에 대비해 롤백할 수 있는 커밋 집합을 유지합니다.
2.
Develop (Staging) : 테스트 브랜치
로컬에서의 테스트와 개발을 마친 후 최종적인 테스트가 이루어지는 브랜치입니다.
별도의 Staging Zone용 브랜치를 만드는 것은 가능하지만, 과도한 조치일 수 있습니다.
3.
Feature : 개발 브랜치 - Develop 브랜치를 기점으로 새 브랜치를 만들어 개발
a.
feature/jira-001 : 기획과 디자인에 따라 개발자에게 발행된 티켓으로 브랜치명
b.
feature/login-with-session : 어떤 작업인지 바로 알 수 있도록, 기능 내용에 대한 요약 브랜치명
c.
void/login-with-session : 브랜치명에 개발자 명을 붙여넣기도함
로컬에서 개발을 완료한 경우 Develop 브랜치에 PR 요청을 하여 마지막 테스트를 준비한다.
PR 요청을 통해 로컬에서 완료한 개발 코드를 개발자들에게 최초 노출하여 코드 리뷰를 받을 수 있음
PR 요청을 통해 Github Workflow 로 CI (테스팅) 파이프라인을 연결하였다면, 코드 유효성 테스트 가능

github에서 PR하는 법 (컨트리뷰터)

github에서 PR하는 법 (회사)

git flow 좋은 글

브랜치별 역할 설명