-
Notifications
You must be signed in to change notification settings - Fork 10
09. git best practice
- 주요 원칙
- feature는 가능하면 atomic하게(OCP를 지켜서), 작게 작성한다.
- feature 브랜치를 ISSUE-023 형태로 이슈 관리자의 ticket과 흔히 연결시킨다.
- dev master 등에 직접 커밋하지 않는다.
- git flow에서는 가능하긴하다.
- integration
-
최대한 자주 실행
-
git-show-branch
-
브랜치가 어디서 왔는가? 현재 브랜치의 기원 추적에 편리
! [git] /Users/nephilim/.dotfiles/git/bin 정리 * [master] Merge branch 'shell': md2docx added ! [shell] shell: md2docx added ! [vim-plugin] vim: rnu(relative number unit) 제거 ---- - [master] Merge branch 'shell': md2docx added *+ [shell] shell: md2docx added *+ [shell^] taskit: help message typo fixed * [master^] zsh: JAVA_HOME libexec/javahome 을 이용하여 경로 설정 *+ [shell~2] taskit: weekday(mon, tue, ...) based registration added *+ [shell~3] choojerk: push notification (via parse.io) added *+ [shell~4] choojerk: web crawling script for Google I/O *+ [shell~5] taskit: task list escape added *+ [shell~6] taskit: tast select & done menu added *+ [shell~7] taskit: tasklist selection&store menu *+ [shell~8] google tasks api를 이용한 task adder *+ [shell~9] dev command 수정 +* [git] /Users/nephilim/.dotfiles/git/bin 정리 +*+ [shell~10] git: git-track-branch 추가 --- [shell~11] Merge branch 'vim-plugin' +*++ [vim-plugin] vim: rnu(relative number unit) 제거
-
shell branch에서 실행 결과
! [git] /Users/nephilim/.dotfiles/git/bin 정리 ! [master] Merge branch 'shell': md2docx added * [shell] shell: md2docx added ! [vim-plugin] vim: rnu(relative number unit) 제거
- [master] Merge branch 'shell': md2docx added +* [shell] shell: md2docx added +* [shell^] taskit: help message typo fixed
- [master^] zsh: JAVA_HOME libexec/javahome 을 이용하여 경로 설정
+* [shell
2] taskit: weekday(mon, tue, ...) based registration added +* [shell3] choojerk: push notification (via parse.io) added +* [shell4] choojerk: web crawling script for Google I/O +* [shell5] taskit: task list escape added +* [shell6] taskit: tast select & done menu added +* [shell7] taskit: tasklist selection&store menu +* [shell8] google tasks api를 이용한 task adder +* [shell9] dev command 수정 ++ [git] /Users/nephilim/.dotfiles/git/bin 정리 ++* [shell10] git: git-track-branch 추가 --- [shell11] Merge branch 'vim-plugin' ++*+ [vim-plugin] vim: rnu(relative number unit) 제거
-
-
---
이전 라인(header)- 각 브랜치의 최근 commit 요약
- *은 HEAD를 의미, 나머지는 !
-
---
이후 라인- 각 브랜치 별 들여쓰기
- 각 컬럼에는 해당 브랜치가 도달 가능한지 여부가 표시된다.
-
-
merge branch -
+
branch (other than head-branch) -
*
current branch
-
- feature는 가능하면 atomic하게(OCP를 지켜서), 작게 작성한다.
- 두 개의 브랜치를 머지 후
- 하나를 취소한다
- no-ff가 아니면 주요 브랜치에 들어와 있어서 제거가 번거롭다
-
그렇지 않다. feature 헤드가 남아있다면 큰 차이가 있지는 않다
* e294960 - (HEAD, master, feature-03) feature-03:01 added (36 minutes ago) | * ada416f - (feature-01) feature-01:03 added (46 minutes ago) | * a54c138 - Merge branch 'master' into feature-01 (47 minutes ago) | |\ | |/ |/| * | 247ab63 - Merge branch 'feature-01' (50 minutes ago)
-
위 master 브랜치에서 reset --hard HEAD^ 해도 feature-03이 남아있다.
-
-
back-merge를 하지않는다.
- feature가 충분히 독립적이지 않다는 smell
- cherry-pick을 고려해본다
- feature
-
사례
-
back-merge한 이력이 있는 feature-01을 제거하려면?
* 27ad9e1 - (HEAD, master) Merge branch 'feature-01' (10 minutes ago) |\ | * ada416f - (feature-01) feature-01:03 added (21 minutes ago) | * a54c138 - Merge branch 'master' into feature-01 (22 minutes ago) | |\ * | | e294960 - (feature-03) feature-03:01 added (11 minutes ago) | |/ |/| * | 247ab63 - Merge branch 'feature-01' (25 minutes ago) |\ \ | |/ | * 08f01db - feature-01:02 added (46 minutes ago) | * 40577b5 - feature-01:01 added (47 minutes ago) * | 1f3d63c - Merge branch 'feature-02' (35 minutes ago) |\ \ | |/ |/| | * 9140660 - (feature-02) feature-02:01 added (36 minutes ago) |/ * 6f026d1 - initial commit (53 minutes ago)
-
merge 취소에 대한 주요 법칙(03의 재확인)
- 누구가에게 merge 당한 commit object는 쉽게 취소가 되지 않는다.
- 상대의 내용에 영향을 주었기 때문에 상대 또한 작업을 해야한다.
- 누군가를 merge한 commit object는 취소할 수 있다.
- 상대의 내용에 영향을 준 건 아니기 때문에 merge commit을 취소하면 된다.
- 누구가에게 merge 당한 commit object는 쉽게 취소가 되지 않는다.
-
해보니
- back-merge후 feature의 내용에 집중하지 않고 master브랜치의 내용을 수정하여 feature에 유지한다면 확실히 제거가 안될 것임
- 원격에 피해를 줄까?
- rebase 작업은 back-merge를 하지 않아도 결국 유사
- TODO: revert로 merge 취소 작업 시도
-
-
share
- integration 시 conflict는 너무나도 자연스러운 현상(a fact of life)
- fetch, pull, push를 hooking하여
- rerere
- reuse recorded resolution
- .git/rr-cache에 저장됨
- 충돌 시 처리한 (원본) 내용을 기록함
- git flow의 경우
- dev branch에 커밋이 가능함
- feature로 back-merge를 허락함
- directed acyclic graph
- cherry-pick
- A reasonable middle-ground is cherry-picking.
- 이유:
- 다른 feature가 back-merge시 혼합되어 유입될 수 있다.
- 유입 후 수정까지 되었다면 더욱 최악
-
feature는 독립적으로, dev를 진행 중인 feature에 반영하지 않는다. 특히, back-merge는 하지 않는다. 굳이 필요하다면 dev의 원하는 commit을 cherry-pick 한다. 도식으로 나타내면 다음과 같다.
git merge --no-ff
사용에 유의하자.d-------------d(dev) \ / \ f----f----f f--f(feature) d-------------d(dev) \ / f----f----f---f--f(feature)
참고로 git-flow 모델에서는 다음을 허용한다. 하지만 위의 형태로 유지되는 것이 좋다.
d---d1---d2---d(dev) \ / \ f-----f----f f--f(feature)
back-merge가 허용되는 경우 다음과 같은 tree가 된다. 이런 식으로 feature가 관리되면, 향후 특정 feature를 제거할 경우 작업이 매우 까다로워 진다. back-merge 후 feature에 dev의 내용이 반영되므로 dev에서 제거를 할 수가 없다.
d---d1---d2---d(dev) \ / \ f-----f----f---f---f(feature)
다른 이들이 feature를 작업하고 있지 않다면 다음과 같은 형태로 rebase도 가능하겠지만, 권고하지 않는다.
d--d--d--d(1.6, master) \ f--f--f (feature)
-
feature 브랜치 명
- 관련 issue/ticket이 있다면 해당 id를
[id] commit message
의 형태로 기술 - 공백이 없음(
-
으로 대체)
- 관련 issue/ticket이 있다면 해당 id를
-
commit message
-
개념
- dangling blob과 dangling commit
-
실습: check dangling object
-
TODO: 예제 git commit --amend후 unreachable object를 확인하면 이전 commit 확인 가능
-
TODO: 브랜치 삭제
* 9e820d4 - (HEAD, master) sample markdown document added (4 seconds ago) | * d9fe5bf - (develop) chapter-06 early translate: done (15 minutes ago) | * 984957a - sample formmated-markdown document added (71 minutes ago) |/ * 878d836 - .git ignore added (73 minutes ago) * 311f263 - (origin/master, origin/HEAD) Initial commit (2 weeks ago)
-
-
git fsck
- Verifies the connectivity and validity of the objects in the database
- 그냥 fsck 하면 지워진 브랜치의 commit object가 나오지 않는다.
- --no-reflogs 내용 참고
- --no-reflogs
- reflog에서만 도달할 수 있는 것은 도달가능이라 고려하지 않는다는 의미
-
- TODO: 예제 git commit --amend후 unreachable object를 확인하면 이전 commit 확인 가능
- --unreachable
- reference 노드(reflog포함)에서 도달할 수 없음을 의미
- unreachable object의 확인
-
--no-reflogs와 함께 사용하면 사라진 브랜치를 확인할 수 있다
> git fsck --unreachable --no-reflogs Checking object directories: 100% (256/256), done. unreachable blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 unreachable commit 984957a17d27b0984f0b390c8a50f639698f4d7f unreachable commit d9fe5bf153fb37e14698c76a83b8c2e93ce2f1cf
-
- --dangling
-
만들어지기는 했으나, 직접 사용된(참조된) 적이 없는 object
> git fsck --dangling --no-reflogs Checking object directories: 100% (256/256), done. dangling blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 dangling commit d9fe5bf153fb37e14698c76a83b8c2e93ce2f1cf
-
984957a17d27b0984f0b390c8a50f639698f4d7f
의 경우 자식이 있으므로 dangling에서 제외된다
-
- --full
- .git/object 뿐만 아니라 packed object, GIT_ALTERNATE_OBJECT_DIRECTORIES를 모두 검색함
-
git gc
- housekeeping tasks
- compressing file revisions
- removing unreachable objects
- gc 대상은 dangling object가 아님
- --aggresive
- aggresively compress
- 디스크 공간에 여유가 있어도 압축을 수행
- --auto
- gc.auto 개수를 넘는 loose object는 repack
- git gc --prune=now
- now 이전의 loose object 삭제
- defalut: 2주로 설정되어 있음
- --no-prune: 압축만
- now 이전의 loose object 삭제
- config
- gc.pruneexpire
- gc.reflogexpire
- gc.reflogexpireunreachable
- 다른 git command에서 활용함
- gc.auto 설정
- git config --global gc.auto 0
- gc.auto 설정
- housekeeping tasks
-
git prune
- remove unreachable objects
-
git reflog
- git reflog expire --expire=now --all
-
exampleA
git reflog expire --expire=now --all # will now report unreachable git reflog # nothing to print out git fsck --unreachable # will now actually delete objects git prune -v # gives "bad object ..." git show $dead_commit
- git notes add
- notes are stored only in local repo
- don't change history
- share notes
- use-cases
- notes are stored only in local repo