Etc

Git 메모 모음 — svn 마이그레이션, 로컬 커밋 되돌리기, rebase 와 merge

목차

git 을 쓰면서 세 번에 나눠 올렸던 메모를 한 페이지로 합쳤다. svn 에서 옮겨오던 시절 명령어부터 rebase 를 이해하려고 애쓴 기록까지다.

svn 에서 git 으로 마이그레이션

1
2
git svn clone --stdlayout --no-metadata -A users.txt svn://example.com/repository/projectname
cd projectname

users.txt 는 svn 계정을 git 계정으로 매핑하는 파일이다. 아래 명령으로 만드는건데 perl 이 없어서 그런지 안 됐다.

1
svn log ^/ --xml | grep -P "^<author" | sort -u | \ perl -pe 's/<author>(.*?)<\/author>/$1 = /' > users.txt

ignore 파일 처리

1
git svn show-ignore -i trunk > .gitignore

remote 지정

1
git remote add origin git@git.example.com:group/projectname.git

tags 처리

svn 의 tags 는 git 에서 remote 브랜치로 들어온다. 진짜 태그로 바꿔준다.

1
git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git tag "$tagname" "tags/$tagname"; git branch -r -d "tags/$tagname"; done

branches 처리

1
git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/$branchname"; git branch -r -d "$branchname"; done

push

1
2
git push origin --all
git push origin --tags

GitLab 백업과 복원

1
sudo gitlab-rake gitlab:backup:create

가장 최근 걸로 복원.

1
sudo gitlab-rake gitlab:backup:restore

특정 시점으로 복원하려면 옵션을 준다. 안 해봤다.

1
BACKUP=timestamp_of_backup (required if more than one backup exists)

로컬 커밋 되돌리기

로컬에만 쌓인 커밋을 버리고 remote 기준으로 되감는다. 복구 대상 저장소를 지정하는 쪽이 확실하다. 아래는 현재 checkout 이 develop 인 경우다.

1
git reset --hard remotes/origin/develop

저장소를 지정하지 않으면 현재 checkout 된 remote 를 기준으로 revert 하는 것 같다.

1
git reset --hard

rebase 와 merge

rebasemerge 를 항상 헷갈렸다. 잘 모를 때 rebase 로 하다가 소스를 날려먹은 후로는 merge 만 써왔다.

찾아보니 rebase 는 branch 의 base 를 재배치한다는 의미라고 한다.

gitflow 를 쓰면서 feature 를 새로 만들어 작업하다가, 그동안 쌓인 develop 를 rebase 해봤다. feature 에서 작업하던 도중 쌓인 develop 의 커밋들이 local feature 밑으로 들어가는걸 확인했다.

히스토리가 꼬이지 않아서 좋다. 근데 문제가 하나 있다. feature 를 서버로 push 한 상태라면 feature 브랜치가 두 개가 생겨버린다. 로컬이 최신이므로 remote/origin 의 feature 를 삭제하고 새로 push 하면 해결되는 것 같다.

그림을 그려서 설명하면 참 좋겠지만 그림을 못 그린다.

rebase 할 때 컨플릭트는 local feature 에서 커밋한 걸 기준으로 한 번씩 단계적으로 resolve 해나간다. 이 과정에서 원하는 결과가 제대로 안 나올 수 있다. 파일 하나를 여러 번 resolve 해야 하는 상황이 생긴다.

그래서 rebase 를 쓰려면 되도록 주기를 짧게 가져가는게 좋을 것 같다. 오래 묵혀둘수록 중간 커밋이 쌓여서 resolve 횟수가 늘어난다.

정리

  • svn 마이그레이션은 git svn clone --stdlayout 후 tags/branches 를 손으로 정리
  • 로컬 커밋 되돌리기는 대상을 명시해서 git reset --hard remotes/origin/<branch>
  • rebase 는 base 재배치. 히스토리는 깨끗해지지만 push 한 브랜치면 두 개로 갈린다
  • rebase 주기는 짧게. 길어지면 같은 파일을 여러 번 resolve 하게 된다