git github 처음부터 다시 배우기 - 4. commit 디테일
📗 좋은 커밋
1. 하나의 커밋에는 한 단위의 작업을 가져야한다.
- 한 작업을 여러 버전에 걸쳐 커밋하지 않습니다.
- 여러 작업을 한 버전에 커밋하지 않습니다.
2. 커밋 메시지는 어떤 작업이 이뤄졌는지 명확해야한다.
- 팀원들과 소통이 제일 중요하다
커밋 메시지 컨벤션
※ 널리 사용되는 커밋 메시지 작성방식 스타일
type: subject
body (optional)
...
...
...
footer (optional)
※ 예시
feat: 압축파일 미리보기 기능 추가
사용자의 편의를 위해 압축을 풀기 전에
다음과 같이 압축파일 미리보기를 할 수 있도록 함
- 마우스 오른쪽 클릭
- 윈도우 탐색기 또는 맥 파인더의 미리보기 창
Closes #125
Type
타입 | 설명 |
---|---|
feat | 새로운 기능 추가 |
fix | 버그 수정 |
docs | 문서 수정 |
style | 공백, 세미콜론 등 스타일 수정 |
refactor | 코드 리팩토링 |
perf | 성능 개선 |
test | 테스트 추가 |
chore | 빌드 과정 또는 보조 기능(문서 생성기능 등) 수정 |
Subject
커밋의 작업 내용 간략히 설명
Body
길게 설명할 필요가 있을 시 작성
Footer
- Breaking Point 가 있을 때
- 특정 이슈에 대한 해결 작업일 때
Gitmoji
- 이모티콘으로 의미를 부여하는 방식
📕hunk 단위 스테이징 및 커밋
1. hunk별 스테이징 진행
- hunk 단위로 스테이징시 기존과 다르게 A 파일의 내용중 일부만 수정했기때문에 스테이징 목록과 Working directory 에 A 파일이 다른 형태로 존재할 수 있다. (당연한 소리)
git add -p
- 옵션
- 변경내역(hunk) 선택 : y, n,
- 나가기 : q
- 옵션 설명 : ?
2. 변경사항을 확인하고 커밋하기
# 변경사항 확인
git diff --staged
# 변경사항 확인 후 커밋
git commit -v
📘 임시로 파일변경내역 저장 해두기
1. Staging area 변경사항을 명령어로 치워두기
git stash
# 원하는 것만 stash
git stash -p
# 메시지와 함께 스태시
git stash -m 'Add Stash3'
2. stash 내용 활용
# 치워둔 마지막 항목(번호 없을 시) 적용
git stash apply
# 치워둔 마지막 항목(번호 없을 시) 삭제
git stash drop
# 적용 및 내역 삭제
git stash pop
# 새 브랜치를 생성하여 pop
git stash branch (브랜치명)
# 치워둔 모든 항목들 비우기
git stash clear
3. stash 목록 보기
git stash list
📗 커밋 수정하기
1. 커밋 메시지 변경
# 커밋 메시지 변경하는 창이 뜸
git commit --amend
# 커밋에 변화 추가
# 변화된 내용을 스테이징하고 마찬가지로 명령어를 통해 마지막 커밋에 포함
git commit --amend
# 커밋 메시지 한 줄로 변경
git commit --amend -m 'Add members to Panthers and Pumas'
2. 과거의 커밋들을 수정, 삭제, 병합
- 과거로 돌아가 rebase 방식으로 다시 커밋을 쌓는 방식
git rebase -i (대상 바로 이전 커밋)
# 특정 커밋에서 부터 커밋들 수정
git rebase -i (커밋 해쉬)
# 작업 마무리후 입력
git rebase --continue
옵션
명령어 | 설명 |
---|---|
p, pick | 커밋 그대로 두기 |
r, reword | 커밋 메시지 변경 |
e, edit | 수정을 위해 정지 |
d, drop | 커밋 삭제 |
s, squash | 이전 커밋에 합치기 |
※ e, edit 디테일 : 명령어 입력후 reset
을 사용해 커밋을 되돌리고 변경 내용을 새로 작성하여 새로 스테이징 하고 커밋할 수 있다.
Rebase 의 위험성
이미 공개 저장소에 Push 한 커밋을 Rebase 하지 마라 - 공식문서
Rebase는 기존의 커밋을 그대로 사용하는 것이 아니라 내용은 같지만 다른 커밋을 새로 만든다.
커밋을 git rebase
로 바꿔서 Push
해버리면 동료가 다시 Push
했을 때 동료는 다시 Merge
해야 한다. 그리고 동료가 다시 Merge
한 내용을 Pull
하면 내 코드는 정말 엉망이 된다.
📙 Git의 Tag
- 특정 시점을 키워드로 저장하고 싶을 때
- 커밋에 버전 정보를 붙이고자 할 때
tag 종류
- lightweight : 특정 커밋을 가리키는 용도
- annotated : 작성자 정보와 날짜, 메시지, GPG 서명 포함 가능
기본 명령어
# 마지막 커밋에 태그 달기 (lightweight)
git tag v2.0.0
# 현존하는 태그 확인
git tag
# 원하는 태그의 내용 확인
git show v2.0.0
# 태그 삭제
git tag -d v2.0.0
# 마지막 커밋에 태그 달기 (annotated)
# 이후 메시지 등록
git tag -a v2.0.0
# `-m` 태그가 `-a` 태그를 포함하고 메시지 작성까지 진행
git tag v2.0.0 -m '자진모리 버전'
# 원하는 커밋에 태그 달기
git tag (태그명) (커밋 해시) -m (메시지)
# 원하는 패턴으로 필터링하기
git tag -l 'v1.*'
# 원하는 버전으로 체크아웃
# `switch`로 이전 브랜치로 복귀
git checkout v1.2.1
원격 태그 동기화
# 특정 태그 원격에 올리기
# github 에서 확인가능
git push (원격명) (태그명)
# 특정 태그 원격에서 삭제
git push --delete (원격명) (태그명)
# 로컬의 모든 태그 원격에 올리기
git push --tags
GitHub의 release
- GitHub에서 태그 목록으로
- 원하는 태그에서
Create release
- 제목과 내용(마크다운) 입력 후
Publish release
2023-02-10 추가된 내용
📒 cherry-pick
다른 브랜치의 원하는 커밋 가져오기
git cherry-pick (커밋 해시)
다른 브랜치에서 파생된 브랜치 옮겨붙이기
git rebase --onto (도착 브랜치) (출발 브랜치) (이동할 브랜치)
※ (출발 브랜치) 의 의미가 헷갈린다면 : 다른 브랜치로 파생된 내용을 붙이는 작업이므로 가지의 시작 지점과 끝나는 지점을 알아야한다 가지의 시작지점은 어떤 브랜치와 갈라지는 부분 즉 공통되는 부분의 커밋을 의미하므로 그 브랜치를 (출발 브랜치) 로 지정하고 끝나는 지점은 가져오고자 하는 브랜치 (이동할 브랜치) 로 지정해 가져온다
rebase --onto를 되돌리려면?
rebase --onto
명령어를 진행 이후 git reflog
를 사용해서 내역을 보면
rebase --onto
가 여러 동작들을 포함한다는 것을 확인할 수 있다
rebase --onto
로 영향을 받은 모든 브랜치들에서 리셋을 진행해주어야 합니다.reset
은 브랜치별로 이뤄지므로 하나하나 처리해야 합니다
혹은 다시 옮겨붙이는 방법도 있죠.
예시
1. main 브랜치
main
은 citrus
로 fastforward
된 것이 마지막 액션이므로 reflog
의 기록상에서 그 이전 기록으로 reset --hard
를 이전으로 돌리고 (lemon과 lime이 추가되기 전으로 돌아감)
2. citrus 브랜치
방법 A
그리고 citrus
브랜치는 해당 브랜치가 옮겨지기 전 마지막 커밋인 commit: Lime
부분을 reflog
에서 찾아 그리로 reset --hard
하면 됩니다.
방법 B
다시 rebase --onto
를 사용해서 citrus
의 커밋들을 main
으로부터 도로 fruit
브랜치의 orange
부분으로 재구성하는 방식
orange
커밋으로 checkout
한 다음 그곳에서 새 브랜치를 만들고 (temp
)
git rebase --onto temp main citrus
위 명령어로 citrus
의 두 커밋들을 해당 위치로 옮겨붙인 뒤 temp
브랜치를 삭제하면 된다