본문 바로가기
Git

Git 개념 이해하기

by Fastlane 2022. 6. 22.
728x90
반응형

1. The perfect commit!

    1-1. Add the right changes!

    local changes를 하나의 commit으로 다 집어넣는 것 보다는, 하나의 주제에 대한 변경사항은 하나의 commit으로

    처리하는 것이 좋다.

    따라서 commit하고자 하는 topic에 맞는 file을 선별하는 것이 중요하다. Git statging area는 특정 파일들을

    선택하여 commit할 수 있도록 한다. 

    하나의 파일을 부분별로 commit할 수도 있다. 

    $ git add -p index.html

    then select hunk to stage

 

    1-2. Compose a good commit message!

    Subject(간략하게) 와 Body(자세하게)로 작성할 수 있다. 

 

2. Branching Strategies

Long-Running Branches : main or master branch, develop or stage or production branch

                                          Integration branch라고도 한다. 

                                          해당 브랜치에 직접적으로 commit하지 않는다. merge/rebase를 한다. 

                                          제대로 test되지 않은 소스가 commit되는 것을 피하기 위해서이다. 

         

Short-Lived Branches : 특정한 목적을 가진 브랜치이다. integration(merge/rebase) 후에 삭제된다. 

                                      new features, bug fixes, refactoring 등 다양한 목적이 있다. 

 

Two Example Branching Strategies

1) GitHub Flow : only one long-running branch (main) + featuer branches

2) GitFlow : long-running(main + develop) + short-lived(featuers, releases, hotfixes)

project, release cycle, team size에 따라서 최적의 Branching Model을 정해서 사용할 수 있다. 

3. Pull Requests

main branch에 수정한 소스를 merge할 때, 수정한 사항이 복잡하거나 중요하여 코드 리뷰와 제3자의 승인이 필요하다면 Pull Request를 사용할 수 있다. 

 

다른 사람의 저장소(eg. opensource)에 Code를 수정하여 develop하고 싶을 때, Pull Request를 사용할 수 있다. 

1) https://github.com/explore에서 open source repository를 찾아서 fork한다. 

 

2) 내 Remote Repository에 추가된 Forked Repository의 url을 복사해서 local pc에 git clone하여 소스를 다운받는다. 

$ git clone https://github.com/BigExecution/api-template.git
Cloning into 'api-template'...
remote: Enumerating objects: 695, done.
remote: Counting objects: 100% (51/51), done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 695 (delta 22), reused 32 (delta 16), pack-reused 644
Receiving objects: 100% (695/695), 176.22 KiB | 6.08 MiB/s, done.
Resolving deltas: 100% (382/382), done.

3) 임의의 브랜치를 만들고 파일을 수정하고 add, commit, push한다. 

$ git branch test

$ git checkout test
Switched to branch 'test'

$ git status
On branch test
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   README.md
        
$ git push --set-upstream origin test
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 280 bytes | 140.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote:
remote: Create a pull request for 'test' on GitHub by visiting:
remote:      https://github.com/BigExecution/api-template/pull/new/test
remote:
To https://github.com/BigExecution/api-template.git
 * [new branch]      test -> test
Branch 'test' set up to track remote branch 'test' from 'origin'.

4) Pull Request를 통해 변경사항을 제안

 

4. Merge Conflicts

1) 언제 발생하는가? 다른 소스로 부터 Integrating Commits를 할때 발생한다. 

2) 어떻게 해야해야 하는가?

merge 되돌리는 방법 : $ git merge --abort

merge conflict 처리하는 방법 : git merge tool 세팅하여, 충돌난 파일 수정해서 commit 처리한다. 

 

5. Merge vs. Rebase

1) Merge : Case 1

Merge에는 위와 같이, 3가지 commits이 관련되어 있다. 이 3 commits을 합쳐야 한다. 

이 Merge는 간단하다. C1부터 Branch B의 new commits을 추가하면 된다. Fast-Forward Merge라고 한다. 

두 Branch는 동일한 commit history를 가진다. 

 

2) Merge : Case 2

branch A와 B에 서로 다른 commit이 존재하는 경우, merge commit을 해야한다. 

merge commit은 developer가 실행하는 것이 아닌, git에 의해서 자동으로 생성된다. 

 

3) Rebase : Case 2

$ git rebase brach-B

Rebase도 Merge와 동일하게, git에 어떤 Branch와 integrate하고 싶은지 말한다. 

하지만 내부 처리 방법은 다르다. 

  • Step 1 : git은 C1 이후의 branch-A의 모든 commits을 삭제하고, 임시보관한다. 
  • Step 2 : branch B의 C2, C4 commits을 branch A에 반영한다. 
  • Step 3 : C4뒤에 C3이 새로운 commit(C3*)으로 추가된다. 

Rebase는 merge commit이 없다. Rebase는 commit history를 재작성한다. 

C3*는 C3와 내용은 동일하지만, 다른 commit이다. 왜냐하면 Rebase 이전에는 C1이 parent commit이었지만, 이후에는 새로운 parent commit(C4)을 가졌기 때문이다. 

 

commit은 author, date, change set, parent commit의 properties를 갖는데, 이 중 하나라도 변경되면 새로운 commit hash를 갖는 새로운 commit이 생성된다. 

 

push하지 전에는 commit history를 재작성하는 것이 가능하다. 하지만 원격 저장소로 push된 이후에는 문제가 생길 수 있다. 팀원들이 C3 commit을 기반으로 일을 하고 있지만, Rebase이후에는 C3가 존재하지 않기 때문이다. 

 

Do Not use Rebase on commits that you've already pushed/shared on a remote repository!!!

 

local commit history를 정리하는 경우에만 사용해야 한다. 

 

728x90
반응형

댓글