git 롤백 - git revert, reset
커밋을 되돌리기위해 사용하는 명령어는 revert, reset 두가지이다.
git reset
git reset은 커밋 history 자체를 뒤로 돌린다. ( 돌아갈 커밋으로 되돌린다.)
git reset
# 커밋 history를 이전으로 되돌린다.
로컬에만 커밋이 머물러 있거나, 원격 저장소에 push를 했어도 나만 사용하는 게
확실한 브랜치라면 reset을 써도 상관없다.
하지만 다른 사람들과 공유하고 있는 브랜치라면 서로의 커밋 history가 달라지기 때문에
서로를 위해서도 하지 않는 게 좋다.
원격 저장소에 올라간 커밋을 reset 하면?
원격 저장소에 올라간 커밋을 되돌리면 원격 저장소와 로컬 저장소의 커밋 history가 다르기 때문에
push 할 때 오류가 난다.
이 때는 --force 옵션을 줘서 강제로 원격 저장소의 커밋 history를
로컬 저장소의 커밋 history로 덮어씌워야 한다.
다른 사람들과 공유하고 있는 원격 저장소라면 공유중인 다른 사람들에게도 모두 오류가 발생하기 때문에
왠만하면 사용하지 않는 게 좋다.
부득이하게 사용한 경우라면 팀원들에게 상황을 공유하고 모두의 커밋 history를 강제로 맞추는 작업을 해야 한다.
reset을 사용하는 경우
-커밋을 원격 저장소에 올리지 않고 로컬 저장소에만 올린 경우
-원격 저장소에 올려도 나만 사용하는 브랜치인게 확실한 경우
-치명적인 오류를 포함하고 있어 커밋 자체를 아예 삭제해야 하는 경우
git에서 롤백하려고 할때 reset사용을 지양해야한다.
git revert
revert는 커밋을 삭제하는 게 아니라 이전의 변경 사항을 불러와서 새로운 커밋을 추가한다.
reset이 타임 머신을 타고 과거로 돌아가는 거라면,
revert는 내 시간은 그대로고 과거의 사람을 현재로 불러오는 느낌?
reset처럼 history가 꼬일 일이 잘 없기 때문에 더 안전한 방법이라고 할 수 있다.
git revert HEAD
# 바로 이전 커밋으로 되돌린다.
git revert 커밋아이디
# 특정 커밋해쉬로 되돌린다.
git revert -m 1 HEAD
# 마지막 커밋이 merge라면, 마지막 커밋으로 되돌린다.
git revert --no-commit 커밋아이디
# revert한 결과가 stage에는 올라가지만 commit하지는 않은 상태를 유지한다.
즉 선택한 커밋해쉬에 해당하는 내용이 삭제된다.
이전 커밋에서 memo.txt에 "롤백될 텍스트 추가"를 추가하고 커밋하였는데
그 수정사항을 지운다.
git branch
git branch - 현재 브랜치 조회
git branch 브랜치이름
-> 브랜치 생성
git checkout 브랜치이름
-> 해당 브랜치로 이동
HEAD란
HEAD는 현재 체크아웃된 브랜치의 가장 최신커밋을 가리킵니다.
따라서 branch를 변경하게되면, 변경한branch의 가장 최신commit을 가리키게 됩니다.
HEAD는 현재 내가 바라보고있는 commit을 가리킨다.
git checkout main으로해서 main브랜치로 이동후 로그확인시
브랜치를 나눠서 파일을 관리중이므로 main브랜치에서는 test브랜치에서의 수정사항이 보이지않는다.
git merge 병합할브랜치이름
branch를 병합하기 위해선 병합을 해줄 브랜치로 가주어야 한다.
test를 main에 합치고 싶으니까 main브랜치로 가야한다.
원하는 브랜치로 이동 후 , 현재 브랜치와 병합을 원하는 브랜치를 merge해주면 된다.
HEAD가 main,test를 가리키는것을 확인할 수 있다.
( = HEAD는 현재 작업중인 브랜치의 가장 최근 커밋을 가리키는데 해당 커밋은 main,test브랜치에 존재한다는 뜻이다.))
현재 브랜치의 내역을 원격저장소로 push하려면 다음과 같이 진행한다.
git push 원격저장소이름 원격저장소브랜치이름
원격저장소에 해당 브랜치가 없다면 생성되면서 push된다.
pull request
test브랜치에서 새로운 커밋을 진행하고, 원격저장소 test브랜치로 push하였다.
test브랜치에서 수정한 내역을 main브랜치에서 병합해보자.
어떤 branch에서 pull request를 신청하는지 (compare) -> 내역을 pull할곳은 어디인지 (base)
pull request 내역이 생성되고 , 그 안에서 어떤 커밋이 있는지 , 각 커밋에서 수정,추가된 코드는 무엇인지 파일에서 변경점은 무엇인지 등 자세하게 확인할 수 있다.
merge를 허용하면 다음과 같이 pull request 내역이 이미지가 바뀌면서 close로 바뀐다.
git fetch
원격저장소에 있는 변경사항들을 로컬저장소에 가져오기 전에 변경내용을 확인하고 싶은경우에 사용하는 명령어
원격저장소에 변경사항이 생겼다(새로운 커밋내역이 존재)
git fetch 원격저장소별칭
fetch를 하고 나면 해당 브랜치로 checkout 해주어야한다.
fetch 명령어를 치면 fetch를 확인 할 수 있는 브랜치 내역들이 나온다.
origin/main이라고 나온부분.
detached HEAD는 HEAD가 현재 브랜치를 가리키는 것이 아니라, 직접적으로 특정 커밋을 가리키는 상태를 의미한다.
그 커밋은 f70c843라는 커밋해쉬를 가진 커밋이라고 결과에 나와있다.
이 브랜치에 있으면 현재 원격저장소에 있는 변경사항을 확인할 수 있다.
변경사항을 확인후 특정 브랜치에 merge 하고싶다면 원하는 브랜치로 이동후 merge를 진행하면된다.
또는 pull로 원격저장소 내용을 가져오면된다.
git rebase
merge는 커밋히스토리가 지저분해질수있다.
rebase를 이용해서 커밋히스토리를 깔끔하게 유지할 수 있다.
rebase는 베이스를 재정의하여 커밋 히스토리를 조작한다.
rebase는 현재 브랜치의 베이스를 재설정해서 합치겠다는뜻
master 브랜치와 develop브랜치가 있을때
develop브랜치를 master브랜치에 merge하는 경우
rebase를 하는 경우에는
develop 브랜치에서 master 브랜치로 rebase가 발생하면 master 브랜치의 가장 최근 커밋내역으로
delveop브랜치의 base가 재정의된다.
그리고 develop 브랜치의 커밋들이 새로 재정의된 base 뒤로 순차적으로 새롭게 커밋이 쌓인다.
develop브랜치는 가장뒤의 커밋을 가리킬것이고
master 브랜치는 HEAD가 아직 base를 가리키기 때문에 master 브랜치로 가서
git merge develop을 해줌으로써 fast-forward 해준다.
merge의 경우 2개의 브랜치가 하나로 병합되는 모습을 보이는 반면
rebase는 마치 하나의 브랜치에서 모든작업이 일어난것처럼 보인다. ( 깔끔해진다.)
ttest라는 새로운 브랜치 생성 , 이 브랜치의 base는 main브랜치
test브랜치는 main브랜치의 가장 최신 커밋으로 base를 지정하고 test브랜치의 예전 base 이후의 커밋을 복사해서 새로운 base 이후에 붙여넣는다. [ 주의할점은 커밋이 복사되어 붙여질때 커밋 해쉬의값은 원래 커밋과 달라진다.]
[ 주의할점은 커밋이 복사되어 붙여질때 커밋 해쉬의값은 원래 커밋과 달라진다.]
ttest브랜치도 rebase를 해보자.
-> ttest브랜치로 이동후 rebase main 하고 main브랜치로 돌아와서 git merge ttest를 해준결과
ttest브랜치에서 rebase main을 하면 main의 가장 최신 커밋내역을 base로 잡고
그 이후로 원래 base 이후에 생긴 자신의 커밋들을 이어 붙인다.
main브랜치는 이어 붙인 결과를 받아와야하므로 git merge ttest를 해준다.
https://kyounghwan01.github.io/blog/etc/git/git-reset-revert/#revert
https://www.youtube.com/watch?v=b72mDco4g78&ab_channel=%EC%9A%B0%EC%95%84%ED%95%9C%ED%85%8C%ED%81%AC
'git > git 연습' 카테고리의 다른 글
git stash, cherry-pick (2) | 2024.03.22 |
---|---|
1 - Git 기초 (0) | 2024.03.06 |
댓글