소프트웨어 공학(rebooting now)

[Software Engineering] Version Control System [Git]

코앤미 2023. 1. 9. 17:03

Version Control System

버전 컨트롤 시스템이란?

버전관리 시스템(VCS, Version Control System)이란 파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 불러올 수 있는 시스템을 의미한다.

 

이를 사용하면, 다음과 같은 이점을 누릴 수 있다.

  • 선택한 파일을 이전 상태로 되돌릴 수 있고, 변경 사항을 비교하고, 변경한 사람 및 변경시기를 추적할 수 있다.
  • 파일을 잃어버리거나 잘못 고쳤을 때도 쉽게 복구할 수 있다.
  • 다른 사람들과 동시에 작업을 진행할 수 있다. 

이번 글에선, 가장 유명한 VCS 중 하나인 Git에 대해 알아보겠다.

 

 

Git 버전 컨트롤 시스템의 특징

  • Git으로 적은 규모에서 효울적으로 변화를 track할 수 있다.
  • Cloud-based Git 호스팅으로 다른 유저와 Collaborate할 수 있다.
  • Git 커맨드와 활용을 위해 리소스와 문서 찾기


 


Git은 모든 client가 repository에 대한 자신만의 copy를 보유하고 있다.

 


  
git에서 branch는 commit을 위한 단순한 pointer 일 뿐이다.


 
Git의 각 commit은  특정 시간대의 working directory에 대한 Snapshot, parent commit에 대한 정보로 구성된다.


실제 commit 전에 add 로 staging area를 사용, 수정된 부분만 commit 가능하다.


Tracked: 마지막 snapshot에 있는 파일
Untracked: 마지막 snapshot의 파일 제외 나머지 전부.



Git의 local workflow

 

유저 식별 코드

Git config –global user.name <username>
Git config –global user.email <email>


git에 쓰이는 text에디터 설정

Git config –global.core.editor vim


나의 setting 확인

Git config –list

 

 

 

설정 파일은   ~/.gitconfig  에 있다.



<처음부터 하기>

아래 명령어는 현제 디렉토리에 git 리포지토리 생성한다. ( .git/directory 를 만들고 안에 리포지토리 데이터 저장)

Git init

 

혹은, 아래와 같은 명령어로 서버에 있는 리모트 리포지토리를 복사해서 가져올 수 있다.

Git clone<repository>






Ex) main.c 파일 생성 후 Git status로 상태 확인



Git add <path>   로 path에 있는 파일들을 staging area에 넣는다.

  • Git commit 시   staging area의 변경사항들을 가지고 있는 commit을 생성한다.
  • 커밋 메시지를 텍스트 에디터에 추가 or commit -m <메시지>  ->  commit 완료
  • Git log로 그동안 작업한 내역 log로 보여준다.



Branch

 bug fix, feature develop 등 1개의 토픽을 나타낸다.

 

 

Merge

협업하는 과정에서 각자 개인 브랜치를 만들어서 개발을 했다면, 언젠가는 소스코드를 합쳐서 테스트도 해보고 시스템에 적용도 해보고 해야한다. 그런 상황에서 브랜치를 합치는 것(병합)을 merge라 한다.

Git branch : 브랜치 리스트를 보인다
Git branch <name>   : 새로운 브랜치 생성
Git switch <branch>    : 해당 브랜치로 변경한다.
Git branch -d <branch> 브랜치 삭제

 

특정 브랜치 수정하고 싶다면 switch 통해서 해당 브랜치로 가서 수정 후, add & commit 하면 된다.

만약 branch에서 작업이 끝나면, 한 개로 merge해서 original 브랜치로 돌아가야한다.

Git merge <commit>   -> 현제 브랜치에 merge 한다.

 

 

만약 merge 중 문제 발생한다면, Git status로 문제를 찾고 Git commit으로  그냥 merge하거나, Git merge –abort로  merge를 버리는 것으로 보통 해결하기도 한다.

 

 

예시


Master 브랜치로 이동한 뒤, 이곳에서 fancy-print의 merge를 수행 ( fancy-print는 내가 변경한 사항.   이를 기존의 master 브랜치와 병합하여 내가 변경한 내역들을 master에 반영)


Rebase

Rebase란?

Branch가 다른 commit으로부터 시작하게 한다 ( rearrange history)

 

Git rebase <commit> : 현재 브랜치가  <commit> 부터 시작하게 만든다.

 


Git-flow  (Vincent Driessen)


Long-running 브랜치

- master: production-ready 상태
develop: feature을 위한 통합 브랜치


Supporting 브랜치

- feature: develop new feature

- release: 새로운 production의 release 준비
- hotfix: production release의 빠른 path


Git with  원격 리포지토리



git remote add <name> <repo>    : 원격 리포지토리에 <name>으로 추가
(보통 origin 이라함)
Git clone <repo>   : <repo> 가 “origin” 이라는 이름으로 원격 리포지토리에 추가.
Git push <remote> <branch>    :  나의 로컬 브랜치를 <remote>에 추가.
Git fetch <remote>    : <remote>  리포지트리의 현재 status를 복사



로컬에서 Origin이라는 이름으로 원격 리포지토리를 가져온 것!

 

 

Git Remote Repository- Detail Examplte

 

git clone

  • 원격 리포지토리를 복사해서 로컬로 가져온다.
  • Origin/master는 원격 리포지토리의 복사시점 commit을 가르킨다.
  • Master는 로컬 복사본의  commit을 가르킨다.

 

사용자가 clone한 이후에, 다른 유저가 remote 에 push

  • origin/master는 기존의 원격 리포지토리 복사본 commit 시점을 가르킨다.
  • master는 내가 수행한 CA,CB 작업을 반영한  commit을 가르킨다.

 

git fetch origin

 

  • 로컬에서 git fetch origin을 통해 origin(가져온 원격 리포지토리) 의 현재 status를 복사한다.
  • 로컬의 origin/master는 그동안 변경된 원격 리포지토리에 맞춰서 새로운 commit을 가르킨다.

git merge

  • 로컬의 master branch에서 Git merge origin/master 를 통해 수정된 원격 리포지토리와 내가 수정한 로컬 복사본을 merge한다. 
     

push origin master


Git push origin master를 통해 로컬의 브랜치인 master 원격저장소 origin에 추가한다.
.

 

 

GitHub- working flow

  1. Collaborate 절차.
  2. Add issue (r각자 자신이 맡을 업무를 Issue로 추가한다.) 
  3. create branch (각자 자신의 업무를 수행할 Branch를 생성한다.)
  4. add commit ( commit을 기점으로 업무를 저장해나간다.)
  5. open a pull request (어느정도 기능이 완성되면, pull-request를 통해 알린다.)
  6. discuess, Review code (pull-request한 코드를 리뷰하고, 문제점 혹은 개선사항을 토의한다.)
  7. Test/Deploy (Merge하기 전, Test를 통해 해당 코드를 반영했을 때 버그를 찾는다)
  8. Merge (메인 브랜치에, 기능이 추가된 로컬 브랜치를 Merge하여 반영한다.)

 

위와 같은 방법 외에도, 나에게 push 권한이 없을 때 fork를 사용하여 협업할 수 도 있다.

Fork란?
나의 계정에 해당 리포지토리의 복사본을 생성한다. 이후 실제 원격 리포지토리에 push 하지 않고, 로컬에 fork로 복사된 리포지토리에 push하여 나의 변경사항을 반영하고,  원본 리포지토리에 pull request를 생성한다. 만약 승낙된다면, 나의 변경사항이 반영되어 해당 코드에 Contribute할 수 있다.


Git object model



Blob object: file의 내용을 저장한다 ( just binary file)
Tree object : blobs로 향하는 pointer들과 이름을 저장한다. ( directory의 콘텐츠를 나타낸다)
Commit object: 특정 시간대에 tree object를 가르킨다. + metadata 보유.
Tag object: 특정 commit을 가르킨다. + metadata 보유