Git
- *분산 *버전 관리 시스템(Version Control System, VCS)
- 분산 (모델) : 프로젝트에 참여하는 모든 클라이언트가 전체 저장소에 대한 개별적인 로컬 저장소를 갖고 작업하는 방식
- *클라이언트-서버 모델과 다르게 각 클라이언트는 로컬 저장소에서 파일의 모든 버전을 가지고 있으며, 다른 클라이언트의 변경 사항을 가져와 자신의 로컬 저장소에 병합한다.
- 클라이언트-서버 모델 : 하나의 중앙 서버로 여러 클라이언트들이 각자 필요한 것만 가져와서 작업을 하고 다시 중앙 서버로 보내서 통합하는 방식
- *클라이언트-서버 모델과 다르게 각 클라이언트는 로컬 저장소에서 파일의 모든 버전을 가지고 있으며, 다른 클라이언트의 변경 사항을 가져와 자신의 로컬 저장소에 병합한다.
- 버전 관리 : 여러 파일을 하나의 버전으로 묶어 관리하는 것
- 분산 (모델) : 프로젝트에 참여하는 모든 클라이언트가 전체 저장소에 대한 개별적인 로컬 저장소를 갖고 작업하는 방식
- 소스 코드 등의 변경 사항을 추적하고, 여러 명의 개발자가 동시에 작업을 할 수 있도록 지원하며, 이전 버전의 코드를 쉽게 복원하고 관리할 수 있다.
- Git 으로 파일을 관리하면 업데이트 이력이 저장된다.
- 만약 내가 올리려는 파일이 누군가 수정한 내용과 충돌한다면, 서버에 업로드할 때 경고 메시지가 발생하여 누군가의 수정 내용을 덮어써버리는 실수를 방지할 수 있다.
- 소스 코드가 변경된 이력을 쉽게 확인할 수 있고, 특정 시점에 저장된 버전과 비교하거나 특정 시점으로 되돌아갈 수도 있다.
- 컴퓨터 파일의 변경사항을 추적하고, 여러 명의 사용자들 간에 해당 파일들의 작업을 조율하기 위해 사용된다.
- 동시에 작업하는 사람들과 소스 코드를 직접 주고받을 필요가 없다.
- 같은 파일을 여러 명이 동시에 병렬 개발이 가능하다.
- 변동 과정을 체계적으로 관리할 수 있고, 언제든지 지난 시점의 버전으로 되돌릴 수 있다.
- 인터넷이 연결되지 않은 곳에서도 개발을 진행할 수 있고, 중앙 서버의 데이터가 유실되어도 다시 복구할 수 있다.
- 로컬에서 버전 관리 시스템을 운영하는 방식
- 데이터를 파일 시스템의 스냅샷의 연속(Stream)으로 취급하고 크기가 아주 작다.
- 커밋하거나 프로젝트의 상태를 저장할 때마다 파일이 존재하는 그 순간을 중요하게 여긴다.
- 파일이 달라지지 않았으면 Git 은 성능을 위해서 파일을 새로 저장하지 않는다.
- 단지 이전 상태의 파일에 대한 링크만 저장한다.
- 데이터를 저장하기 전에 항상 *체크섬을 구하고 그 체크섬으로 데이터를 관리하다.
- 체크섬 : Git에서 사용하는 가장 기본적인(Atomic) 데이터 단위이자 Git의 기본 철학.
- Git 없이는 체크섬을 다룰 수 없어서 파일의 상태도 알 수 없고 심지어 데이터를 잃어버릴 수도 없다.
- SHA-1 해시를 사용하여 체크섬을 만든다.
- 만든 체크섬은 40자 길이의 16진수 문자열이다.
- 파일의 내용이나 디렉토리 구조를 이용하여 체크섬을 구한다.
- 파일을 이름으로 저장하지 않고 해당 파일의 해시로 저장한다.
GitHub
- Git repository 를 위한 *호스팅 플랫폼
- 호스팅 : 서버 컴퓨터의 전체 또는 일정 공간을 이용할 수 있도록 임대해 주는 서비스
- 보통 Git 의 repository(저장소)는 자신의 컴퓨터(local computer) 안에 저장되어 있는데 *원격 저장소를 통해 협업과 관리가 용이하도록 원격 저장소를 제공해 주는 플랫폼
- 원격 저장소(Remote Repository) : 파일이 원격 저장소 전용 서버에서 관리되며 여러 사람과 함께 공유하기 위한 저장소
- 로컬 저장소(Local Repository) : 내 PC 에 파일이 저장되는 개인 전용 저장소
- 즉, Git repository 서버를 대신 유지 및 관리해 주는 서비스
- 클라우드 방식으로 관리되는 버전 관리 시스템(VCS)은 구글 드라이브와 같이 원격 저장소를 제공하여 파일을 안전하게 저장하고 관리할 수 있게 한다.
- 저장소를 GitHub 에서 제공해 주는 클라우드 서버를 이용하는 방식
Git Branch
- 독립적으로 어떤 작업을 진행하기 위한 개념
- 필요에 의해 만들어지는 각각의 Branch 는 다른 브랜치의 영향을 받지 않기 때문에, 여러 작업을 동시에 진행할 수 있다.
- 이렇게 만들어진 Branch 는 다른 Branch 와 Merge 함으로써, 작업한 내용을 다시 새로운 하나의 Branch 로 모을 수 있다.
- Branch 를 통해 하나의 프로젝트를 여러 갈래로 나누어서 관리할 수 있다.
- 각각의 독립된 Branch 에서 마음대로 소스코드를 변경하여 작업한 후 원래 버전과 비교하여 또 하나의 새로운 버전을 만들어 낼 수 있게 된다.
- *Gitflow Workflow 에서는 항상 유지되는 메인 브랜치인 Master, Develop 과 일정 기간 동안만 유지되는 보조 브랜치인 Feature, Release, Hotfix 을 포함하여 총 5가지의 브랜치를 사용한다.
- Gitflow Workflow : 여러 개발자가 하나의 저장소를 사용하는 환경에서 저장소를 효과적으로 활용하기 위한 work-flow
- 브랜치의 생성, 삭제, 병합 등 Git 의 유연한 구조를 활용해서, 각 개발자들의 혼란을 최대한 줄이며 다양한 방식으로 소스를 관리하는 역할을 한다.
- 즉, 브랜치 생성에 규칙을 만들어서 협업을 유연하게 하는 방법론
- Gitflow Workflow : 여러 개발자가 하나의 저장소를 사용하는 환경에서 저장소를 효과적으로 활용하기 위한 work-flow
Master Branch
- 제품으로 출시될 수 있는 브랜치
- 배포 이력을 관리하기 위해 사용된다.
- 즉, 배포 가능한 상태만을 관리한다.
Develop Branch
- 다음 출시 버전을 개발하는 브랜치
- 기능 개발을 위한 브랜치들을 병합하기 위해 사용된다.
- 즉, 모든 기능이 추가되고 버그가 수정되어 배포 가능한 안정적인 상태라면 develop 브랜치를 master 브랜치에 병합한다.
- 평소에는 이 브랜치를 기반으로 개발을 진행한다.
Feature Branch
- 기능을 개발하는 브랜치
- 새로운 기능 개발 및 버그 수정이 필요할 때마다 develop 브랜치로부터 분기한다.
- 해당 브랜치의 작업은 기본적으로 공유할 필요가 없기 때문에, 자신의 로컬 저장소에서 관리한다.
- 개발이 완료되면 develop 브랜치로 병합하여 다른 사람들과 공유한다.
Release Branch
- 이번 출시 버전을 준비하는 브랜치
- 배포를 위한 전용 브랜치를 사용함으로써 한 팀이 해당 배포를 준비하는 동안 다른 팀은 다음 배포를 위한 기능 개발을 계속할 수 있다.
- develop 브랜치에서 배포할 수 있는 수준의 기능이 모이면 또는 정해진 배포 일정이 되면, release 브랜치를 분기한다.
- release 브랜치를 만드는 순간부터 배포 사이클이 시작된다.
- 직접적으로 관련된 작업들을 제외하고는 release 브랜치에 새로운 기능을 추가로 병합(merge) 하지 않는다.
- release 브랜치에서 *배포 가능한 상태가 되면(배포 준비가 완료되면), master 브랜치에 병합한다. (이때, 병합한 커밋에 Release 버전 태그를 부여한다)
- 배포 가능한 상태 : 새로운 기능을 포함한 상태로 모든 기능이 정상적으로 동작하는 상태
- 배포를 준비하는 동안 release 브랜치가 변경되었을 수 있으므로 배포 완료 후 develop 브랜치에도 병합한다.
- 다음번 배포(Release)를 위한 개발 작업은 develop 브랜치에서 계속 진행해 나간다.
- release 브랜치 이름 정하기
- release-RB_* 또는 release-* 또는 release/* 처럼 이름 짓는 것이 일반적인 관례
- [release-* ] 형식을 추천 : 예시) release-1.2
Hotfix Branch
- 출시 버전에서 발생한 버그를 수정 하는 브랜치
- 배포한 버전에 긴급하게 수정을 해야 할 필요가 있을 경우, master 브랜치에서 분기한다.
- develop 브랜치에서 문제가 되는 부분을 수정하여 배포 가능한 버전을 만들기에는 시간도 많이 소요되고 안전성을 보장하기도 어려우므로 바로 배포가 가능한 master 브랜치에서 직접 브랜치를 만들어 필요한 부분만을 수정한 후 다시 master 브랜치에 병합하여 이를 배포해야 하는 것이다.
- hotfix 브랜치 이름 정하기 : [hotfix-* ] 형식을 추천 : 예시) hotfix-1.2.1
- 1. 배포한 버전에 긴급하게 수정을 해야 할 필요가 있을 경우, master’ 브랜치에서 hotfix 브랜치를 분기한다.
- hotfix 브랜치만 master 에서 바로 딸 수 있다.
- 2. 문제가 되는 부분만을 빠르게 수정한다.
- 다시 master 브랜치에 병합하여 이를 안정적으로 다시 배포한다.
- 새로운 버전 이름으로 태그를 매긴다.
- 3. hotfix 브랜치에서의 변경 사항은 develop 브랜치에도 병합한다.
Git 명령어 모음
fetch
- 원격 저장소의 데이터를 로컬 저장소에 가져오기만 한다.
- 단순히 원격 저장소의 내용을 확인만 하고 로컬 데이터와 병합은 하고 싶지 않은 경우에는 fetch 명령어를 사용한다.
pull
- 원격 저장소의 내용을 가져와(fetch) 자동으로 병합 작업(merge)을 실행한다.
원격 저장소가 등록되지 않은 상태에서 불가능하다.
Merge
- 두 브랜치의 커밋을 하나의 브랜치로 합치는 방법
- 커밋 이력을 모두 남길 때 사용한다.
- Fast-Forward 방식과 Recursive 방식을 사용하여 통합을 수행한다.
Fast-ForwardMerge
- 새로운 브랜치 my-branch 가 main 브랜치로부터 분기된 이후 main 브랜치에 새로운 커밋이 올라오지 않았다면, my-branch 가 main 와 비교하여 최신의 브랜치라고 할 수 있다.
- 이런 경우 my-branch 의 변경 이력을 그대로 main 으로 가져올 수 있다.
- Fast-Forward Merge 가 가능한 상태에서 git merge 명령에 --no-ff 옵션을 주면 강제로 Merge Commit 을 생성하게 할 수 있다.
Recursive Merge
- my-branch 가 main 브랜치에서 분기되고, main 브랜치에 새로운 커밋이 생겼다면, my-branch 를 최신이라고 간주할 수 없다.
- 따라서 my-branch 와 main 을 공통 부모로 한 새로운 Merge Commit 을 생성하게 된다.
Squash & Merge
- Squash 는 여러 개의 커밋을 하나의 커밋으로 합치는 것을 의미한다.
- Squash Merge 는 병합할 브랜치의 모든 커밋을 하나의 커밋으로 Squash 한 새로운 커밋을 Base 브랜치에 추가하는 방식으로 병합하는 것을 의미한다.
- Squash 를 하게 되면 모든 커밋 이력이 하나의 커밋으로 합쳐지며 사라진다는 점을 주의해야 한다.
- Feature 브랜치에서 기능을 개발하기 위한 지저분한 커밋 내역을 하나의 커밋으로 묶어 Develop 브랜치에 병합하면서, Develop 브랜치에는 기능 단위로 커밋이 추가되도록 정리할 수 있다.
- 예시: Feature 브랜치는 Develop 브랜치에 병합 후 제거하므로, Merge Commit 을 남길 필요가 없다.
Rebase & Merge
- my-branch 가 main 브랜치의 A 커밋에서 분기되었다고 하자. 이때, my-branch 의 Base 는 A 커밋이다.
- Rebase 는 말 그대로 Base 를 다시 설정한다는 의미이다.
- my-branch 가 분기된 main 브랜치의 최신 커밋으로 Base 를 다시 설정한다.
- Rebase 를 하면 커밋들의 Base 가 변경되므로 Commit Hash 또한 변경될 수 있다. 이로 인해 Force Push 를 해야 할 경우도 있으니 주의해야 한다.
- Develop 브랜치를 squash & merge 하게되면 커밋 이력이 모두 사라져, 특정 기능에서 문제가 생겼을 때 롤백할 수 없게 된다. 이때는 Rebase & Merge 가 적합하다.
reset
- 커밋 내역을 삭제하고, 특정 시점의 커밋으로 되돌아간다.
- reset 의 근본적인 문제점은 팀원들과 공유하는 원격 저장소의 커밋 내역을 강제로 조작한다는 것이다. 가능하면 로컬 저장소에서만 실행이 되어야 한다.
- GitHub 와 같은 원격 저장소에 올라간 뒤에 reset 을 실행하면 이전 커밋 내역들이 전부 삭제된다.
- 만약 다른 사람들과 함께 작업을 하고 있었고, 팀원들이 원격 저장소의 커밋을 되돌린 사실을 몰랐다면, 되돌렸던 커밋들이 다시 원격 저장소에 추가된다.
- 그래서 미리 공지를 하거나, 가급적이면 git revert 를 사용하는 것이 안전하다.
- GitHub 와 같은 원격 저장소에 올라간 뒤에 reset 을 실행하면 이전 커밋 내역들이 전부 삭제된다.
- *soft, *mixed, *hard 세 가지 모드로 변경 사항을 관리할 수 있다.
- soft : 돌아가려 했던 이력으로 되돌아 갔지만, 이후의 내용이 지워지지 않으며, 해당 내용의 인덱스(또는 스테이지)도 그대로 존재한다.
- 로컬 저장소의 파일은 삭제되지 않은 채로 스테이지 영역에 파일이 올라와있는 상태이다.
- 즉, git add 가 실행된 직후의 되돌아가고, 바로 commit 을 수행할 수 있는 상태가 되는 것이다.
- 로컬 저장소의 파일은 삭제되지 않은 채로 스테이지 영역에 파일이 올라와있는 상태이다.
- mixed : 이력은 되돌려지지만, 스테이지는 초기화된다.
- 즉, git add 가 실행되기 이전의 상태로 돌아가는 것이다.
- hard : 돌아가려는 이력 이후의 모든 내용을 지우고 모든 상태를 초기화한다.
- commit된 파일들 중 tracked 파일들을 로컬 저장소에서 삭제한다.
- soft : 돌아가려 했던 이력으로 되돌아 갔지만, 이후의 내용이 지워지지 않으며, 해당 내용의 인덱스(또는 스테이지)도 그대로 존재한다.
revert
- 이전 커밋 내역들은 그대로 두고, 되돌리고 싶은 커밋의 코드만 복원시킨다.
- 커밋 내역을 전부 삭제하는 것이 아닌 revert 커밋 자체를 커밋 내역에 쌓는 방식으로 사용한다.
- 즉, 특정 커밋을 되돌리는 작업도 하나의 커밋으로 간주하여 커밋 내역에 추가하므로, 내가 되돌린 작업을 다른 팀원들과 공유할 수 있게 된다.
etc.
GitHub 에 push 된 commit 삭제하는 방법
https://yebeen-study-note.tistory.com/15
Commit Message Convention
https://velog.io/@archivvonjang/Git-Commit-Message-Convention
'안드로이드 > etc.' 카테고리의 다른 글
[CS] 가비지 컬렉션 (Garbase Collection, GC) (0) | 2024.08.27 |
---|---|
[CS] 가상 메모리 (Virtual Memory) (0) | 2024.08.23 |
[Image] 래스터(JPG, PNG, BMP, WebP), 벡터(SVG) 이미지 (0) | 2024.08.19 |