문제
- main 브랜치에 있는 코드를 삭제함.
왜 삭제했을까?
문제 상황 재현
- 기준이 되는 main 브랜치가 있음.

- main을 기준으로 a 브랜치를 만들고 새로운 기능 추가.

그리고 readme의 상태.

- main을 기준으로 b라는 또 다른 브랜치를 만들어 read me 수정. 이때 a 브랜치의 read me 3번 째줄과 충돌되는 내용을 작성.

- a와 b 브랜치 모두 remote에 push 후 b 브랜치에서 a 브랜치를 기준으로 pull 받음. 그럼 read me의 내용이 겹치기 때문에 conflict 발생.

- 이 때 staged changes를 discard 함. → a 브랜치 작업 내용 삭제

- changes를 discard하면 작업 내용이 사라지는 것이 아닌 merge가 취소된다고 생각함. 하지만 실제론 충돌이 되지 않고 merge가 이뤄진 상태였고 이때 changes를 discard하면 코드가 제거됨.
그렇다면 rebase는 왜 이 현상을 예방할 수 있을까?
- pull은 fetch와 merge의 과정을 한 번에 처리하는 것인데, 이 때 기준 브랜치가 내 현재 브랜치 b를 기준으로 merge를 실행함. 그래서 충돌이 났을 때 current change에는 b 브랜치 내용이, incomming change로 a 브랜치 내용이 존재함. 마찬가지로 b 브랜치에서 a 브랜치 내용이 새로운 changes에 있는 것임.
- rebase를 하면 기준으로 설정한 브랜치를 기준으로 로컬에 있는 commit 내역들을 새로 쌓음. 즉, base를 바꾸는 작업을 실행함. pull이 아닌
git rebase origin/feat/a
를 실행하면 다음과 같음.

a 브랜치 작업 내용을 기준으로 b 브랜치의 작업 내역을 새로 commit함.

이처럼 기존에 작성된 a 브랜치를 기준으로 base를 쌓아야 적어도 기존 코드에 대해 보호할 수 있는 확률이 높아짐.
결론
- pull을 받았을 때 생긴 changes를 discard 함. merge 행위 자체가 취소될 거라고 착각.
- 코드 병합에 있어 안정적인 방법인 rebase를 하지 않음.
부수적인 추가 원인
- PR 시 changes를 확인하지 않고 (당시 수정이 한 줄 이었기에 신중하게 보지 않음), master merge 당시에도 승인 요청을 유도함.
- 컨디션 조절 실패. 적은 수면 시간과 공복인 상태로 코드를 계속 보다 판단력이 흐려짐.
- 빨리 마감해야 한다는 생각에 논리적인 생각 없이 문제 상황만 쳐내는 식으로 개발함.
깨달은 점
- git에 대한 이해가 필요함.
- 무리하게 서두르면 될 것도 안 됨.
- PR 전에 merge 보다 rebase를 사용하는 것이 안전함.
- 추가로 master merge 시 squash merge가 아닌 일반 merge를 해야 함. squash merge는 꼬일 위험이 있어 master merge에선 위험함.