HAMA DEVELOP

오늘 또 잘못 커밋해 버리고 말았다...

August 29, 2021

git은 이제 개발자들이 피해갈수 없는 버젼관리 시스템이다. 문서.진짜진짜최종_수정(1) 에서 개발자들을 구원해내었다.

이런 고마운 git이지만, 종종 git을 사용하다 실수들이 발생한다. 커밋을 잘못하거나, 푸시를 잘못하거나, 커밋 메시지를 잘못적거나 등등의 실수 말이다.

이런 실수가 자주 일어나는 편은 아니라서 그때 그때 구글링을 하면 어떻게 답을 찾을 수는 있지만, 한번 정리해 두면 미래의 나와 다른 사람에게 도움이 될 수 있을것 같아서 정리해 둔다.

아직 푸시되지 않은 커밋 메시지 고치기

푸시하기 전에는 커밋메시지를 확인 하는 것이 좋다. 푸시 해버린 커밋을 고치는 것은 아무래도 까다롭다. git log --oneline 등의 명령어로 나의 로컬에 들어 있는 커밋 메시지를 확인하자.

이때 커밋 메시지가 잘못 들어갔음이 확인 되었다면,

git commit --amend -m "새로운 메시지" 를 입력해 주자.

커밋된 파일은 하나도 바뀌지 않고 대신 커밋 메시지를 바꿀 수 있다.

이미 작성한 커밋에 파일 추가하기

앗, 이미 커밋을 해버렸는데 이 커밋에 포함되면 좋을것 같은 작업이 추가되어 버렸다. 당황하지 말고 일단 수정사항을 스테이지으로 올린다. git add -A

그리고 나서는 메시지를 고치는 것과 동일한 커맨드를 쓰면된다. git commit --amend -m "새로운 작업을 포함한 커밋 메시지" 이러면 기존 커밋에 새로운 작업이 포함된다.

스테이지에 올린 파일 취소하기

스테이지에 파일을 잘 못 포함시켜 버렸다. 어떻게 다시 뼈면 좋을까? 간단하다.

git reset HEAD "빼고 싶은 파일명"

을 입력해 주면 해당 파일의 상태가 untracked로 바뀐다.

푸시 하기전에 커밋 취소하기

알고보니 이미 커밋한 작업들에 실수가 들어있었다. 어떻게 취소할 수 있을까?

git reset HEAD~1 혹은 git reset "커밋 해시"

숫자는 HEAD 로부터 초기화 시키고 싶은 커밋간의 거리다. 최신 커밋은 1, 3번전 커밋은 3…이런식으로 구성된다.

커밋 해시는 git log --oneline등의 커맨드를 통해서 취고하고 싶은 커밋의 커밋 해시를 알아내서 넣으면 된다.

커밋을 취소하는 방식에는 --hard, --soft, --mixed 세가지 방식이 있다. 각각의 특성은 아래와 갔다.

  • --hard

--hard 는 제일 위험한 옵션이다. 마치 그런 변화가 없었던 것처럼 처리하는 것이다. 파일의 변동사항 자체를 지워버린다.

예를 들어서 내가 커밋에 index.md에 ‘수정사항’ 이라는 문구를 추가했다고 해보자. --hard 옵션을 넣어서 git reset을 하면 내 로컬에서조차 ‘수정사항’이 지워진다.

커밋과 변화 자체를 없애 버리는 것이니까 제일 위험한 방식이다. 가급적이면 쓰지 말자.

  • --soft

--soft 를 쓰면 커밋한 이력이 없어지고 스테이지에 올라간 상태가 된다.

위의 예시를 그대로 이어서, 생각하면 로컬에서는 ‘수정사항’이 남아있고 깃은 더이상 이 커밋을 기억하지 않는다. 대신 해당 수정 사항은 스테이지에 남아있어서 다음에 커밋을 하면 바로 포함 시킬 수 있다.

  • --mixed

--mixed는 커밋한 이력도 없어지고 스테이지에서도 내려가지만, untracked로 변동사항만은 남아 있다.

이 경우 다시 커밋을 하고 싶으면 git add 를 통해서 해당 파일을 스테이지에 올려 놓아야 한다. 아무런 옵션을 넣지 않는경우 --mixed가 기본동작이다.

reset —hard로 지워진 커밋 복구하기

앗, 잘못해서 git reset --hard 옵션을 써 버렸다. 그동안 공들인 작업물이 날라갔다. 어떻게 복구할 수 있을까? 아직 garbage collection이 되지 않았다면, 기회는 남아 있다.

git reflog를 쓰면 그동안의 커밋들을 볼 수 있다.

여기서 맨왼쪽에 해당 커밋의 해시가 1ee9701 처럼 나온다.

git reset --hard "살리고 싶은 커밋 해시" 처럼 입력해 주면 해당 커밋이 살아난다.

이미 푸시한 커밋 취소하기

잘못 푸시해 버렸다. 이경우에는 reset을 해도 내 로컬에서만 취소가 된다. 이렇게 커밋을 수정한뒤 푸시를 할려고 하면 히스토리가 꼬여서 푸시가 제대로 되지 않는다.

이때 -f 옵션을 넣어서 푸시를 하면 로컬의 히스토리로 원격이 덮어씌워진다. 취소하는 방법중 하나라고 할 수는 있지만, 이미 잘못 올린 커밋을 pull 해서 쓰고 있는 팀원이 있다면 그사람의 히스토리와도 엇나가게 되므로 권장하는 방식은 아니다.

대신, git revert "취소하고 싶은 커밋 해시를 한 다음에 push 하면 해당 커밋을 지우는 커밋이 올라간다. 이 커밋이 올라가면, 다른 팀원들도 취소 커밋을 내려받게 되기 때문에 히스토리가 꼬일 일이 없다.

가급적이면 푸시가 된 커밋을 취소할 때는 git revert를 쓰자.

다른 브랜치의 커밋 복사하기 (가져오기)

다른 브랜치의 커밋을 사용하고 싶은 경우가 있다. 동일한 내용이 다른 브랜치에 필요한 경우도 있고, 그냥 커밋을 잘못했을 수도 있다. 이 경우 다른 브랜치의 커밋을 가져와야 한다.

일단 제일 먼저 해야 할 작업은 가져오고 싶은 커밋 해시를 알아내는 것이다. 가져오고 싶은 커밋이 있는 브랜치에서 git log --oneline 등의 커맨드를 이용하여, 해당 커밋의 해시를 알아내자.

그뒤 해당 커밋을 적용하고 싶은 브랜치로 이동한뒤 아래의 커맨드를 입력한다.

git cherry-pick "복사하고 싶은 커밋 해시"

과거 커밋에서 다시 시작하기

과거의 특정 커밋으로 되돌아 가서 거기부터 다시 작업을 해야 할듯 하다. 이럴떄는 어쩌면 좋을까?

일단 특정 커밋으로 되돌아간다.

git checkout "돌아가고 싶은 커밋 해시"

그리고 그 커밋에서 새로운 브랜치를 만들어서 작업을 시작한다.

git checkout -b "새로운 브랜치 이름"

이미 push 된 파일 git ignore 하기

git ignore 해야 하는 파일인데 실수로 이미 push가 되어 버렸다. 이럴떈 어떻하면 좋을까?

일단 .gitignore 파일을 올바르게 고친 뒤 git rm -r --cached . 를 한다.

그리고 git add -A 를 해준다. 기존에 깃이 읽어야 한다고 알고 있는 파일 목록을 초기화 하고 다시 추가해 주는 작업을 하는 것이다.

그리고 커밋 후 push해주면 된다.

하지만, 이미 올라간 과거 커밋 이력에는 해당 파일의 내용이 남아 있다는 점에 주의해야 한다.


충분히 일어날 수 있는 실수들 이지만 해결볍은 그리 어렵지 않다. pull, commit, push 밖에 쓸줄 몰랐던 과거의 나 같은 주니어들에게 도움이 되기를 바란다.

tags: