IT/VCS

[git] 이미 발행된 커밋 고쳐 쓰기

심량 2022. 7. 26. 13:41
  • 고쳐쓰는 대상
    • 커밋 순서
    • 커밋 저자
    • 커밋 일시
  • 사전 작업
    • 수정 가능 여부 확인
      • 다른 작업자와 공유된 저장소이면 다음 여부를 확인하기
        • 이미 공유(push)된 커밋이면 절대 고치지 않습니다!!.
          • 그래도 고쳐야 한다면 다른 작업자의 현재 작업 내용을 수동으로 백업해놓고, 이 수정 작업 수행 후,  현재 저장소를 삭제(또는 백업)하고 저장소를 새로 내려받고 나서 이전 백업 내용을 복원해야 합니다.
          • 차라리 되돌려야 하는 부분이 있다면 revert 명령을 활용하세요.
          • 수정한 본인 제외하고 모두가 꼬입니다...
        • 아직 공유되지 않은 커밋이라도 수정 작업 중에 반영된 내용으로 이 후 커밋들과 충돌이 발생해서 회복하기 힘들게 꼬일 수 있습니다.
          • 현재 수정하는 부분이 이 후 커밋에서 다르게 수정된 경우
          • 파일 추가 삭제 등으로 추적(tracking)이 꼬이는 경우
          • 소중한(복구가 안되면 화가 나고, 눈물이 날 정도인) 저장소이고, 본인이 수정하려는 내용이 확실히 꼬이지 않는다고 확신하는 경험자(경험자도 꼬이는 때 있습니다... 저도 백업하고 실행합니다...)가 아니라면 반드시 현재 저장소를 백업(.git 포함) 해두세요. 두번 세번 강조합니다. 반드시 하세요.
    • 작업 위치 수집
      • 커밋의 해시코드(hashcode) 앞 7자(전체도 상관없음)를 다음 2개를 찾아 기록해놓기
        • 고치고자 하는 커밋의 해시코드 - 해시1
        • 고치고자 하는 커밋의 다음 커밋의 해시코드 - 해시2
        • 순서를 바꿀 예정이라면 이동할 위치의 앞 뒤 커밋의 해시코드 - 해시3, 해시4
        • 참고로 저장소 최초의 커밋은 이 방법으로는 수정이 안됨
    • 필요에 따라 작성자 정보를 준비하기
      • "name <email@address>". 예) honggildong <gildong@gmail.com>
    • 필요에 따라 시간 정보를 준비하기
      • 요일 월 일 시:분:초 연도 타임존추가시간
        • Mon Jul 11 16:03:45 2022 +0900
    • 작업 목표 분명히 하기
      • 이 커밋은 특정 커밋 다음으로 순서를 바꿀꺼야
        • 해시1, 해시2, 해시3, 해시4 확보
      • 이 커밋은 오타 때문에 코드를 살짝 바꿀꺼야
        • 해시1, 해시2
      • 이 커밋은 작성자를 바꿀꺼야
        • 해시1, 해시2, 작성자 정보
      • 이 커밋은 시간을 바꿀꺼야
        • 해시1, 해시2, 시간 정보
    • 완성된 순서 예상 그림화하기
      • 위의 작업 목표 분명화와 연결된 작업
      • 그림을 그리면서 목표가 뚜렸해지고 뭐가 필요한 지를 알 수 있게 됨
  • 작업 시나리오
    • 1. 커밋 순서 변경
      • 시작 환경
        • aaaa, bbbb, cccc 순서대로 커밋이 된 저장소의 커밋을 cccc, aaaa, bbbb 로 변경하고자 함
      • 작업 위치 수집
        • $ git log
          commit dddd (HEAD -> master)
          Author: gaetong <gaetong@gmail.com>
          Date:   Mon Jul 26 23:52:44 2022 +0900

              Refactor header

          commit cccc
          Author: gaetong <gaetong@gmail.com></gaetong@gmail.com>
          Date:   Mon Jul 25 23:46:01 2022 +0900

              Fix typos

          commit bbbb
          Author: gaetong <gaetong@gmail.com>
          Date:   Mon Jul 25 23:46:01 2022 +0900

              Add initial files for object detection

          commit aaaa
          Author: gaetong <gaetong@gmail.com>
          Date:   Tue Jul 24 09:48:30 2022 +0900

              Stablize source

          commit 9876
          Author: gaetong <gaetong@gmail.com>
          Date:   Tue Jul 23 09:48:30 2022 +0900

              Add missing resources
        • 고치고자 하는 커밋 해시1 - cccc
        • 고칠 커밋의 다음 커밋 해시2 - dddd
        • 옮기고 싶은 위치 커밋 해시3, 4 - 9876, aaaa
      • 작업내용
        • git rebase -i dddd~4
          pick cccc Fix typos
          pick bbbb Add initial files for object detection
          pick aaaa Stablize source
          pick 9876 Add missing resources

          # Rebase dddd..9876 onto 9876 (4 commands)
          #
          # Commands:
          # p, pick <commit> = use commit
          # r, reword <commit> = use commit, but edit the commit message
          # e, edit <commit> = use commit, but stop for amending
          # s, squash <commit> = use commit, but meld into previous commit
          # f, fixup <commit> = like "squash", but discard this commit's log message
          # x, exec <command> = run command (the rest of the line) using shell
        • 편집기에서 편집해서 실제로 저 순서를 아래와 같이 바꿈
          • pick bbbb Add initial files for object detection
            pick aaaa Stablize source
            pick cccc Fix typos
            pick 9876 Add missing resources

            # Rebase dddd..9876 onto 9876 (4 commands)
            #
            # Commands:
            # p, pick <commit> = use commit
            # r, reword <commit> = use commit, but edit the commit message
            # e, edit <commit> = use commit, but stop for amending
            # s, squash <commit> = use commit, but meld into previous commit
            # f, fixup <commit> = like "squash", but discard this commit's log message
            # x, exec <command> = run command (the rest of the line) using shell
          • 저장하고 나가면 끝
            • Successfully rebased and updated refs/heads/dev/test1.
    • 2. 커밋 작성자 변경
      • 1번 작업과 같이 대상을 골라 rebase 명령을 내리고 나온 편집기 화면의 원하는 커밋에서 pick 키워드를 edit 로 바꾸고 저장
      • git commit --amend --author="honggildong <gildong@gmail.com>"
      • git rebase --continue
    • 3. 커밋 날짜 변경
      • 1번 작업과 같이 대상을 골라 rebase 명령을 내리고 나온 편집기 화면의 원하는 커밋에서 pick 키워드를 edit 로 바꾸고 저장
      • git commit --amend --date="Mon Jul 11 16:03:45 2022 +0900"
      • git rebase --continue