[DevOps] Git 히스토리 이관
예전에 진행하던 시스템에서 TO-BE Repository에 AS-IS Repository의 히스토리를 이관하고 싶다는 요청이 들어왔다. 단순 커밋메세지를 복사하는 것으로는 안된다. 왜냐? Git은 해시값 기반으로 형상관리되어 무결성 원칙이 깨질 수 있기 때문이다.
그럼 할 수 있냐 없냐? 물론 할 수 있다. 그 방법을 포스팅하고자 한다
둘 중에 하나만 골라?
(Yes or Yes!)
1. 신규 파일이 생겼거나 파일 내용에 변경점이 없다 ⇒ Confilct X
merge하는 파일에 conflict가 없다면 그냥 아래 방법대로 진행하면 된다
2. 파일 내용에 변경점이 있다 ⇒ Confilct O
그러나 merge하는 파일에 conflict가 있을 경우가 문제다
보통 conflict가 발생하면 파일 내용에 아래와 같이 입력되어 있어서 수동으로 수정해줘야 한다
<<<<<<< HEAD
현재 브랜치 내용
=======
merge하는 브랜치 내용
>>>>>>>
한 두가지 파일이면 무리 없어도 몇백개(?) 정도는 힘들지 않을까..
처음부터 히스토리까지 같이 이관하도록 하자!
본격적으로 히스토리를 이관하는 방법
-
AS-IS Repository에서 TO-BE Repository로 이관 후, “first commit” 하고 나서 일부러 파일 내용 하나 바꿔봤다
$ git add . $ git commit -m "first commit" $ git remote get-url origin https://github.com/gain-yoo/git-history-mv.git $ git push -u origin main $ vi README.md $ git add . $ git commit -m "README 수정" $ git push -u origin main
-
AS-IS Repository의 히스토리를 이관하기 위해 remote로 AS-IS Repository를 추가하고 fetch한다
$ git remote add old_git_remote https://github.com/gain-yoo/terraform-study.git $ git fetch old_git_remote remote: Enumerating objects: 81, done. remote: Counting objects: 100% (81/81), done. remote: Compressing objects: 100% (61/61), done. remote: Total 81 (delta 26), reused 60 (delta 10), pack-reused 0 Unpacking objects: 100% (81/81), 68.81 KiB | 224.00 KiB/s, done. From https://github.com/gain-yoo/terraform-study * [new branch] main -> old_git_remote/main
-
merge 하면 refuse 당한다 ⇒
--allow-unrelated-histories
옵션 사용해라이 옵션은 allow merging unrelated histories 라고 설명되어 있다.
덧붙이자면, 이미 존재하는 두 프로젝트의 기록(history)을 저장하는 드문 상황에 사용된다고 한다. 즉, git에서는 서로 관련 기록이 없는 이질적인 두 프로젝트를 병합할 때 기본적으로 거부하는데, 이것을 허용해 주는 것이다. (라고 아래 블로그를 참고했다)
Git push가 안되는 경우 (fatal: refusing to merge unrelated histories)
$ git merge old_git_remote/main fatal: refusing to merge unrelated histories $ git merge old_git_remote/main --allow-unrelated-histories Auto-merging README.md CONFLICT (add/add): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result.
하지만 conflict로 인해 바로 merge되지는 않는다.
-
(바로 merge되는 경우) 아래 파일 내용이 뜨고
:wq
로 저장하면 merge 성공!Merge remote-tracking branch 'old_remote/main' # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
$ git merge old_remote/main --allow-unrelated-histories Merge made by the 'ort' strategy.
$ git push -u origin main Enumerating objects: 56, done. Counting objects: 100% (56/56), done. Delta compression using up to 8 threads Compressing objects: 100% (43/43), done. Writing objects: 100% (47/47), 5.33 KiB | 779.00 KiB/s, done. Total 47 (delta 21), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (21/21), completed with 6 local objects. To https://github.com/gain-yoo/git-h-mv-2.git e467138..118a8ed main -> main branch 'main' set up to track 'origin/main'.
-
-
conflict 생긴 파일 수정 후 commit & push
conflict 파일을 수정하고 나니 아까 merge 했던 것도 같이 적용된다. 이제 remote 서버에 push하면 이전 히스토리 내역까지 같이 push된걸 확인할 수 있다
$ vi README.md $ git merge old_git_remote/main --allow-unrelated-histories error: Merging is not possible because you have unmerged files. hint: Fix them up in the work tree, and then use 'git add/rm <file>' hint: as appropriate to mark resolution and make a commit. fatal: Exiting because of an unresolved conflict. $ git add README.md $ git commit -m "test1" [main c4fe410] test1 $ git merge old_git_remote/main --allow-unrelated-histories Already up to date. $ git push -u origin main
- AS-IS Repository 히스토리 이관 완료!!!
-
파일 conflict 나는 경우, conflict난 파일 수정된 커밋메세지(”
test1
”)와 함께 히스토리 이관 성공 -
파일 conflict 없이 바로 merge되는 경우,
Merge remote-tracking branch ‘old_remote/main’
커밋 내역이 생성되니 참고바란다!
-
-
AS-IS Repository와 TO-BE Repository의 커밋내역을 비교하면 이전 커밋내역의 해시값도 동일하게 이관된 것을 확인할 수 있었다! 이것이 git에서의 무결성!
Leave a comment