GIT 커밋(작업) 이동 팁, 연습 사이트
커밋 이동으로 Git 작업을 되돌린다든지, 브랜치들을 접목한다든지, 커밋에 이름을 지정해준다든지 등의 작업들을 진행해보려고 한다.
이를 연습할 수 있는 좋은 사이트가 있는데, 참고!
이전에 정리한 게시글이 2개 정도 있는데, 이를 먼저 보고 이해한 후 이 글을 보는 것을 권장한다. (좀 더 심화적인 내용이며 충돌(conflict) 관련 내용은 언급 안 하기 때문)
커밋 이동
기존 커밋 트리 구조 : HEAD -> main -> C1(커밋)
-
git checkout C1
적용 시 : HEAD -> C1 - 이 부분은 커밋 이름(라벨 C1)로 checkout 시 HEAD가 변경
=> HEAD는 현재 상태를 의미한다는 걸 알 수 있음- 물론!! 이 커밋의 이름은 실제로 C1이 아니라 git log에서 보시다시피
fed2da64c0efc5293610bdd892f82a58e8cbc5d8 이런 형태 - 근데, git은 fed2 정도만 입력해도 알아서 알아듣습니다!
- 물론!! 이 커밋의 이름은 실제로 C1이 아니라 git log에서 보시다시피
그래도 이건 귀찮은 작업이라 더 편한 게 여러 가지 있는데 “상대 참조”, “git tag” 소개
-
상대 참조 : 캐럿(^) 연산자, 틸드(~) 연산자
- 브랜치와 HEAD 둘 다 “상대 참조” 사용 가능
- 예로
git checkout main^
입력 시?? main 브랜치가 가리키는 커밋의 부모 커밋을 HEAD가 가리킴.
근데,git checkout HEAD^
도 가능. HEAD가 가리키는 커밋의 부모 커밋을 가리킴. - 예로
git checkout HEAD~4
입력 시?? HEAD가 가리키는 곳에서 4개 위로 올라가는 것임.
- 예로
- 브랜치와 HEAD 둘 다 “상대 참조” 사용 가능
-
git tag v0 C1 처럼 커밋에 태그 이름(=v0)를 임의로 지정 가능
- 이를 통해서 바로 git checkout v0도 가능
- git describe main으로 main 브랜치(커밋도 가능)에 가까운 태그 정보를 묘사(describe)해줌
- 출력은
<tag>_<numCommits>_g<hash>
형태- tag: 가장 가까운 부모 태그
- numCommits : 해당 태그가 얼마나 멀리 있는지
- hash : 묘사하고 있는 커밋의 해시(이름)
Git 작업 되돌리기
git reset, git revert
명령어 사용
- git reset HEAD~1 : HEAD의 바로 앞의 커밋으로 이동하는데, 히스토리를 고쳐쓰기 때문에 다른 사람과 작업하는 리모트 브랜치에는 사용 X
- git revert HEAD : 다른 사람과 작업하는 브랜치의 경우 이 방법을 사용해야 함. 이 방법은 아예 변경 내역 커밋을 새로 생성해주고, 이를 다른 사람들에게도 push(변경 내역 밀기)할 수 있음
정말 간단히 바로 앞 커밋으로 되돌리는 2줄(HEAD 기준)
- git reset HEAD^
- git push origin 브랜치명 -f
- -f는 force로서 강제 push를 도와주며, 이 경우 정말 실수로 GIT 저장소에 잘못 올린 경우에 사용할 것
- 히스토리 고쳐쓰는 문제로 인해 revert로 해결을 권장하긴 함
GIT 작업을 여기저기 이동해보기
사실 앞에서 작업 이동을 여러 가지 소개했는데, 이번엔 또 다른 명령어들을 소개한다.
이 부분은 조금 이해가 안 될 수도 있는데, 처음에 소개한 사이트에서 직접 실습을 진행해볼 것을 권장한다.
git cherry-pick, git rebase -i
- git cherry-pick C2 C4 -> 다른 브랜치의 커밋인 C2와 C4를 현재 포인터(브랜치)에 복사하는 아주 간편한 방법.
=> rebase로도 당연히 가능. 물론 이 방법은 커밋의 hash(이름)을 알아야겠죠. - git rebase -i HEAD~4 -> 인터렉티브(-i)라고 해서 직접 트리 모형의 커밋 구조를 UI로 보고 우리가 마우스로도 수정할 수 있는 방식이다.
- 응용 : 커밋 딱 한 개만 가져오기
-> git cherry-pick 커밋 1개 - 응용 : 서로 연관 있는 브랜치에서 이전의 기록 것을 조금 수정해야 할 때 어떻게? 우선 이전 커밋을 최신으로 순서를 바꿔주고 커밋 후(rebase, amend), 다시 원복해준다(rebase)
git rebase -i HEAD~2 / git commit –amend / git rebase -i HEAD~2 - 응용 : 방금 한 것을 git cherry-pick으로 해보겠음. 변경할 커밋은 C2로 하고, C3이 최신이라 보자.
git cherry-pick C2 / git commit –amend / git cherry-pick C3
브랜치 이동(접목,병합)
브랜치를 강제로 옮기는 일반적인 방법
- git branch -f main HEAD~3 : 강제(-f)로 브랜치를 이동(HEAD~3 위치로)
브랜치 병합하는 또 다른 방법
-
git merge, git rebase
명령어 사용 - 만약 두 브랜치에 서로 다른 독립된 커밋이 있을 경우 어떻게 합치는가?? (bugFix, main 두 브랜치로 가정)
- git merge bugFix -> 현재 브랜치가 main이라 가정하고 merge 명령어를 했다면, 해당 bugFix 브랜치의 커밋과 현재 main 브랜치의 커밋 둘 다를 main이 화살표로 가리킨다. (merge가 된다.) => main이 bugFix의 커밋까지 내역을 이제 전부 포함
- git checkout bugFix / git merge main -> 현재 가리키는 포인터(main)를 bugFix로 변경하고, merge main을 진행 시 bugFix가 main 브랜치 쪽으로 이동하고 성공적으로 merge가 된다. => bugFix이 main의 커밋까지 내역을 이제 전부 포함
- 실제론 두 기능을 따로 개발했지만, 마치 순서대로 개발한 것처럼 bugFix 브랜치 작업을 main 브랜치 위로 직접 옮기려고 할 때는? (현재 bugFix가 포인터)
- git rebase main -> main 위로 bugFix 작업 내용이 옮겨지면서 커밋 내용도 복사본으로 하나 추가된 상태
- git rebase bugFix -> 포인터를 main으로 옮긴 후 다시 rebase를 하면 bugFix 쪽으로 간단히 이동함
특정 브랜치의 특정 폴더만 가져와보기
git subtree merge --prefix=폴더_경로 다른_브랜치
명령어를 사용 (현재 main 브랜치라 가정)
- 여기서
"폴더_경로"
는 메인 브랜치로 가져오고자 하는 특정 폴더의 경로를 나타내며, -
"다른_브랜치"
는 병합하고자 하는 다른 브랜치의 이름입니다.
댓글남기기