본문으로 건너뛰기

Commit, Branch, Merge와 복구

중요도: 필수 · 원본 협업 가이드에서 이 주제에 필요한 내용을 모았습니다.

5. Commit​

좋은 Commit이란?​

Commit 하나에는 가능한 한 하나의 목적이 들어가는 것이 좋다.

좋은 예:

feat: add player dash input
fix: prevent turret targeting destroyed enemy
refactor: separate damage calculation

좋지 않은 예:

수정
작업
최종
진짜최종
asdf

Commit Message만 봐도 어느 정도 변경 내용을 추측할 수 있어야 한다.


Commit Hash​

각 Commit에는 고유한 식별값이 존재한다.

예:

a82f18c...

Git은 이 값을 이용해 특정 Commit을 정확히 가리킬 수 있다.


History​

Commit이 쌓여 만들어진 프로젝트의 변경 이력이다.

git log

Diff​

두 상태 사이에서 무엇이 변경되었는지 보여주는 차이다.

PR Code Review에서도 결국 Reviewer가 가장 많이 보는 것은 이 Diff다.

기존 코드
- speed = 5;

변경 코드
+ speed = 8;

6. Branch​

Branch는 다른 작업과 분리하여 개발할 수 있게 해주는 독립적인 작업 흐름이다.

main
│
├──── feat/player-dash
│
├──── feat/turret-system
│
└──── fix/enemy-target

왜 Branch를 사용할까?​

여러 명이 동시에 main을 직접 수정하면 서로의 코드가 계속 섞인다.

Branch를 사용하면:

  • 각자 독립적으로 개발할 수 있고
  • 작업이 끝난 뒤 검토할 수 있으며
  • 문제가 있는 코드를 main에 바로 넣지 않을 수 있다.

우리 팀에서는 대략 다음 Prefix를 사용할 수 있다.

feat/ 새로운 기능
fix/ 버그 수정
refactor/ 코드 구조 개선
chore/ 설정 및 기타 작업
docs/ 문서

예:

feat/player-dash
fix/turret-target
refactor/damage-system

7. HEAD​

HEAD는 현재 내가 바라보고 있는 Commit을 가리키는 포인터라고 생각하면 된다.

일반적인 상황에서는 현재 Branch의 최신 Commit을 가리킨다.

HEAD
↓
feat/player-dash
↓
Commit C

Git에서

"현재 나는 어디에 있는가?"

를 나타내는 중요한 개념이다.

처음에는 이 정도만 이해해도 충분하다.


8. Merge​

Merge는 서로 다른 Branch의 변경 사항을 하나로 합치는 작업이다.

feat/player-dash
↓
Merge
↓
main

하지만 우리 팀에서는 기능 개발자가 마음대로 main에 바로 Merge하는 것이 아니라,

Pull Request
→ Code Review
→ CI
→ Merge

과정을 거치는 것을 기본으로 한다.


9. Merge Conflict​

Git이 두 변경 사항 중 어떤 것을 선택해야 할지 판단할 수 없을 때 발생한다.

예를 들어 두 사람이 같은 줄을 서로 다르게 수정했다고 생각해보자.

A
speed = 10;

B
speed = 15;

Git은 어느 쪽이 맞는지 알 수 없다.

이때 Conflict가 발생한다.

<<<<<<< HEAD
speed = 10;
=======
speed = 15;
>>>>>>> feat/player

이 의미는:

"Git이 망가졌다"

가 아니라,

"어떤 변경을 사용할지 사람이 결정해 주세요"

에 가깝다.

Conflict Resolution​

일반적인 흐름은:

Conflict 확인
↓
올바른 코드 선택 또는 재작성
↓
Stage
↓
Merge 계속 진행

이다.

[!WARNING] Unity에서는 C# 코드뿐 아니라 Scene, Prefab, ScriptableObject 같은 Asset에서도 Conflict가 발생할 수 있다.
이런 파일은 사람이 읽기 어렵고 변경량도 커질 수 있어 같은 Scene/Prefab을 동시에 수정하지 않는 운영 규칙이 중요하다.


10. 변경을 되돌리는 방법​

비슷해 보이지만 역할이 다르다.

restore​

현재 작업 파일의 변경 내용을 되돌릴 때 사용한다.

아직 Commit하지 않은 작업을 취소할 때 주로 사용한다.


revert​

기존 Commit을 삭제하는 대신, 그 Commit의 변경을 반대로 수행하는 새로운 Commit을 만든다.

Commit A
Commit B
Commit C
Commit C를 취소하는 Commit D

공유된 History를 보존하기 때문에 팀 Repository에서는 비교적 안전한 방법이다.


reset​

Branch가 가리키는 위치 자체를 이전 Commit으로 이동시킬 수 있다.

History를 바꿀 수 있기 때문에 사용 시 주의가 필요하다.

특히:

git reset --hard

는 작업 내용까지 사라질 수 있다.

[!WARNING] 공유된 Branch의 History를 함부로 reset하고 Force Push하는 행동은 피한다.
이미 다른 사람이 사용하고 있는 History를 바꾸면 협업이 크게 꼬일 수 있다.


11. Stash​

아직 Commit하기 애매한 작업을 잠시 치워두고 싶을 때 사용한다.

예:

Player 기능 개발 중
↓
급하게 main의 Bug를 확인해야 함
↓
git stash
↓
다른 Branch에서 작업
↓
원래 Branch 복귀
↓
git stash pop
git stash
git stash pop

[!TIP] "Commit하기엔 애매한데 Branch는 바꿔야 한다"는 상황에서 유용하다.