GIT 커밋(작업) 이동 팁, 연습 사이트

커밋 이동으로 Git 작업을 되돌린다든지, 브랜치들을 접목한다든지, 커밋에 이름을 지정해준다든지 등의 작업들을 진행해보려고 한다.

이를 연습할 수 있는 좋은 사이트가 있는데, 참고!


이전에 정리한 게시글이 2개 정도 있는데, 이를 먼저 보고 이해한 후 이 글을 보는 것을 권장한다. (좀 더 심화적인 내용이며 충돌(conflict) 관련 내용은 언급 안 하기 때문)



커밋 이동

기존 커밋 트리 구조 : HEAD -> main -> C1(커밋)

  • git checkout C1 적용 시 : HEAD -> C1
  • 이 부분은 커밋 이름(라벨 C1)로 checkout 시 HEAD가 변경
    => HEAD는 현재 상태를 의미한다는 걸 알 수 있음
    • 물론!! 이 커밋의 이름은 실제로 C1이 아니라 git log에서 보시다시피
      fed2da64c0efc5293610bdd892f82a58e8cbc5d8 이런 형태
    • 근데, git은 fed2 정도만 입력해도 알아서 알아듣습니다!


그래도 이건 귀찮은 작업이라 더 편한 게 여러 가지 있는데 “상대 참조”, “git tag” 소개

  • 상대 참조 : 캐럿(^) 연산자, 틸드(~) 연산자
    • 브랜치와 HEAD 둘 다 “상대 참조” 사용 가능
      • 예로 git checkout main^ 입력 시?? main 브랜치가 가리키는 커밋의 부모 커밋을 HEAD가 가리킴.
        근데, git checkout HEAD^도 가능. HEAD가 가리키는 커밋의 부모 커밋을 가리킴.
      • 예로 git checkout HEAD~4 입력 시?? HEAD가 가리키는 곳에서 4개 위로 올라가는 것임.
  • 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

  1. git cherry-pick C2 C4 -> 다른 브랜치의 커밋인 C2와 C4를 현재 포인터(브랜치)에 복사하는 아주 간편한 방법.
    => rebase로도 당연히 가능. 물론 이 방법은 커밋의 hash(이름)을 알아야겠죠.
  2. git rebase -i HEAD~4 -> 인터렉티브(-i)라고 해서 직접 트리 모형의 커밋 구조를 UI로 보고 우리가 마우스로도 수정할 수 있는 방식이다.
  3. 응용 : 커밋 딱 한 개만 가져오기
    -> git cherry-pick 커밋 1개
  4. 응용 : 서로 연관 있는 브랜치에서 이전의 기록 것을 조금 수정해야 할 때 어떻게? 우선 이전 커밋을 최신으로 순서를 바꿔주고 커밋 후(rebase, amend), 다시 원복해준다(rebase)
    git rebase -i HEAD~2 / git commit –amend / git rebase -i HEAD~2
  5. 응용 : 방금 한 것을 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 두 브랜치로 가정)
    1. git merge bugFix -> 현재 브랜치가 main이라 가정하고 merge 명령어를 했다면, 해당 bugFix 브랜치의 커밋과 현재 main 브랜치의 커밋 둘 다를 main이 화살표로 가리킨다. (merge가 된다.) => main이 bugFix의 커밋까지 내역을 이제 전부 포함
    2. git checkout bugFix / git merge main -> 현재 가리키는 포인터(main)를 bugFix로 변경하고, merge main을 진행 시 bugFix가 main 브랜치 쪽으로 이동하고 성공적으로 merge가 된다. => bugFix이 main의 커밋까지 내역을 이제 전부 포함
  • 실제론 두 기능을 따로 개발했지만, 마치 순서대로 개발한 것처럼 bugFix 브랜치 작업을 main 브랜치 위로 직접 옮기려고 할 때는? (현재 bugFix가 포인터)
    1. git rebase main -> main 위로 bugFix 작업 내용이 옮겨지면서 커밋 내용도 복사본으로 하나 추가된 상태
    2. git rebase bugFix -> 포인터를 main으로 옮긴 후 다시 rebase를 하면 bugFix 쪽으로 간단히 이동함



특정 브랜치의 특정 폴더만 가져와보기

git subtree merge --prefix=폴더_경로 다른_브랜치 명령어를 사용 (현재 main 브랜치라 가정)

  • 여기서 "폴더_경로"는 메인 브랜치로 가져오고자 하는 특정 폴더의 경로를 나타내며,
  • "다른_브랜치"는 병합하고자 하는 다른 브랜치의 이름입니다.

댓글남기기