일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 |
- java병렬처리
- @advice
- 테스트대역
- WebMvcConfigurationSupport
- js숫자체크
- 테스트더블
- reflection api
- 스프링부트 프로젝트 이름 변경
- MinorGC
- WebMvcConfigurer
- refelction API
- 자바디자인패턴
- 클린아키텍처
- 개발블로그
- MajorGC
- Spring
- 개발컨퍼런스
- 인텔리제이에서 프로젝트 이름 바꾸기
- 유스콘
- MappingJackson2HttpMessageConverter
- spring boot
- 멀티코어 프로그래밍
- test double
- java 멀티스레딩
- mustache함수
- 헥사고날
- 어댑터패턴
- GOF
- 동시요청
- Java
- Today
- Total
져니의 개발 정원 가꾸기
실수로 remote에 올린 git commit 삭제하기 본문
목차
배경
개발하던 중 아직 remote에 올라가면 안 될 commit들이 담긴 브랜치를 모르고 머지한 뒤 pull request를 올렸다. 이미 remote에 올라간 commit 내역들만 빼고 싶을 때 rebase를 쓰면 아주 간단하게 (근데 좀 위험함) commit들을 삭제할 수 있는데 어떻게 하는지 간단하게 기록해본다.
git rebase
git rebase란?
(re)base 는 베이스를 재설정한다는 뜻이다. 브랜치의 base라고 하면 코드를 수정하는 지점을 말하는데, 바로 이 지점을 재설정한다는 말이다. 브랜치를 병합할 때 쓰는 대표적인 git 명령어 두 가지가 merge, rebase인데, 둘의 차이는 다음과 같다.
- merge : 브랜치들의 히스토리를 개별적으로 보존하면서 히스트로리를 하나로 합침(통합)
- rebase : 특정 브랜치의 베이스를 재설정하여 다시 커밋을 적용시켜 이력을 재정렬
브랜치에서 코드 수정 시점을 재설정해 커밋의 이력을 재정렬한다는 것은 다시 말하면, 커밋 히스토리를 변경할 수 있다는 것이다.
이 때 사용하는 옵션은 -i (--interactivce)로 다음 명령어를 사용하면 된다.
git rebase -i HEAD~n // 현재 HEAD 부터 n개 까지의 커밋 이력
이 글에서는 삭제만 할 것이지만 이미 올라간 커밋 메시지를 수정하는 방법도 같은 순서를 따르니 잘 알아뒀다가 써먹으면 된다.
1. git rebase -i HEAD~n으로 리베이스 시작
해당 명령어를 치면 다음과 같이 vi 에디터가 나오고 n개의 커밋 이력이 한 줄씩 나온다.
커밋마다 앞에 pick이라는 키워드가 있는데, 이는 리베이스에서 커밋을 재조정할 때 사용하는 명령어라고 보면 되고, 모든 명령어들의 기본값이다.
커밋 이력 다음 줄부터는 이렇게 command 사용법이 나와있다.
아래처럼 명령어에 따라 실수로 들어간 커밋들은 삭제할 수 있도록 drop 명령어로 바꿔주고, esc 와 :wq 를 입력해 에디터를 종료한다. (수정의 경우는 edit 명령어를 쓰고 에디터를 종료한다. 삭제는 에디터 종료로 끝이지만, edit은 후에 git commit --ammend 와 git rebase --continue명령어를 실행해서 메시지를 수정하는 작업을 한다.
참고 - https://corykim0829.github.io/git/How-to-amend-commits-message/#)
2. git push -f 로 강제로 원격에 반영
그 후 아래 명령어로 remote에 있는 커밋 이력을 덮도록 강제 push 명령어를 사용하여 원격에 반영한다.
git push -f origin feature/a
그런데 왜 -f(강제)옵션이 필요한 것일까? 이는 local에서 재설정하여 달라진 feature/a 브랜치를 remote의 feature/a 브랜치와 동기화 시키려 할 때 충돌이 발생하기 때문에 -f 없이 push를 시도하면 실패하기 때문이다. rebase한 local 브랜치를 반영하고 현재 remote를 바꿔야하기 때문에 remote를 local 브랜치의 것으로 덮어쓰도록 해야한다. 그래서 강제 push 옵션이 붙는 것이다.
(이와 관련해서는 아래 블로그에서 잘 설명해주고 있다
참고 - https://velog.io/@pil0009/%EC%99%9C-git-rebase-%ED%9B%84%EC%97%90-git-push-f%EB%A5%BC-%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C)
결론
- git rebase는 실수로 remote에 올린 작업 내역을 수정할 때 유용하게 쓸 수 있다.
- 그러나 그만큼 조작할 수도 있다는 의미이기 때문에 다른 사람들과 협업할 때나 따르고 있는 깃 사용 정책에 따라 신중하게 사용하자.