📎 tacademy


1. Git

1.1. Version Control System

파일 변경 사항을 저장하고, 원하는 시점의 버전을 다시 꺼내올 수 있는 시스템
Snapshot: 특정 시점에서 파일의 상태
Delta: 파일의 이전 상태와 비교한 변경사항

without VCY

1) 변경 사항 파악 어려움
2) 삭제 파일 되돌리기 어려움
3) 용량 차지
4) 협업 어려움

SVN vs Git

1) SVN: Central VCS으로 파일의 모든 변경 사항을 저장
2) Git: Distributed VCS으로 저장소의 파일 시스템 전체를 snapshot으로 취급, 변경되지 않은 파일은 새로 저장하지 않고 링크만 저장


1.2. Initialization & Repository

사용자가 변경한 모든 내용을 추적하는 공간
current status, modified time, modified user, description 등

1) Local에서 저장 및 버전 관리 가능 (remote server에 나중에 upload 가능)
2) Data 추가만 가능 (삭제 == 삭제 기록 추가)
3) file 및 directory를 추적하지 않음 (각 문자와 line을 추적)

Tracked & Untracked

1) Unmodified: 이전 버전과 비교하여 수정된 부분이 없는 상태
2) Modified: 이전 버전과 비교하여 수정된 부분이 있는 상태
3) Staged: 저장(commit)을 위해 준비된 상태

Staging

1) 여러 작업 중, 일부분만 commit 해야할 때
2) commit 전 상태를 수정 또는 체크할 때

Content-addressable Key-Value Storage

version의 주소 값을 찾을 key: 내용(파일 구조)등을 Hash값으로 만들고 상태를 나타냄


2. Configuration

2.1. .git

버전 관리 정보가 담긴 디렉토리 (config, logs, refs 등)

2.2. .gitignore

file # 특정 파일 file 제외하기

/file  # 현재 경로에 있는 파일 제외하기

folder/  # 특정 폴더 folder 안의 파일 모두 제외하기

folder/file # 특정 경로의 특정 파일 제외하기

folder / ** / files # 특정 경로 아래의 모든 file 제외하기

*.txt # 특정 확장자 파일 제외

!file # 예외 만들기

추적을 무시하려면 정규표현식으로 저장

2.3. README.md

프로젝트 내용(이미지/로고)
설치 방법
코드 예제
개발 환경 설정 방법
contribute방법
로그 변경
credit
license
contact

2.4. initial config

사용자 설정 확인:

git config --list

시작 버전 생성 (master branch에 기록됨):

git init

혹은 기존 프로젝트 이용시에는 remote 저장소에서 다운로드:

git clone [url]

branch 생성, 삭제 및 remote 저장소의 branch 확인:

git branch [name]
git branch -d [branch1]
git branch -r

2.5. Staging 상태

image

staging area에 추가:

git add [file]

staging area에서 제거:

git restore --staged (파일명)

예전 git reset HEAD (파일명)와 동일

staging area와 working directory 동시 제거:

git restore (파일명)

2.5. 그 외

file status 체크(modified, staged):

변경 내용확인:

git status
git diff

message옵션으로 설명과 함께 커밋:

git commit -ㅡ "add README.md"

로컬 변경 내역 remote로 푸시:

git push -u
git push origin master

origin을 remote 프로젝트의 master branch에 업데이트
push -u 옵션을 생략하면 set-upstream 설정을 해야함
git config –global push.default current 설정하면 됨

master혹은 branch로 이동:

git checkout master
git checkout [branch]

branch2를 현재 branch와 합칠 때:

git merge [branch2]

분기가 많아져서 관리가 어려울 때 베이스 재설정:

git rebase master 

base(기존 master)를 future(새로운 master)로 re-base
굳이 다른 branch에서 merge해서 다시 base로 옮기는 (고리생성) 작업 불필요


3. HEAD

현재 속한 브랜치의 가장 최신 커밋

3.1. checkout

익명의 브랜치에 위치하고 다른밋커밋 explore 가능

HEAD 이용해서 이동

^ 또는 ~: 갯수만큼 이전으로 이동

git checkout HEAD^
git checkout HEAD^^^
git checkout HEAD~5

checkout 한 단계 되돌리기

git checkout -

3.2. 실습

main] git log
commit 063a9b9cfbc22d416cd2dbf283c43429d3e126b1 (HEAD -> main)
Author:
Date:
    main 3rd commit

commit 0cef8538cdbff37e94339471dd5ebd815390e547
Author:
Date:
    main 2nd commit

commit 8d0330a37e39ebca693e53efa2cfef2ce092462e
Author:
Date:
    First commit

마지막 커밋 전 상태로 checkout

main] git checkout HEAD^ # 혹은 git checkout 0cef8538cdbff37e94339471dd5ebd815390e547
((0cef853...))] git log
commit 0cef8538cdbff37e94339471dd5ebd815390e547 (HEAD)
Author:
Date:
    main 2nd commit

commit 8d0330a37e39ebca693e53efa2cfef2ce092462e
Author:
Date:
    First commit

마지막 커밋 전전 상태로 checkout

((0cef853...))] git checkout HEAD^ # 혹은 git checkout 8d0330a37e39ebca693e53efa2cfef2ce092462e

메인으로 가서 이전전 커밋 상태로 checkout

((0cef853...))] git switch main
main] git checkout HEAD^^ # 혹은 git checkout 8d0330a37e39ebca693e53efa2cfef2ce092462e
((8d0330a...))] git log
Author:
Date:
    First commit

다시 마지막 커밋 전 상태로 checkout

((8d0330a...))] git checkout - # 혹은 git checkout 0cef8538cdbff37e94339471dd5ebd815390e547
((0cef853...))] git log
commit 0cef8538cdbff37e94339471dd5ebd815390e547 (HEAD)
Author:
Date:
    main 2nd commit

commit 8d0330a37e39ebca693e53efa2cfef2ce092462e
Author:
Date:
    First commit


4. 협업

4.1. Remote에서 가져오기

remote 추가 및 삭:

git remote add origin [url]
git remote -v
git remote remove origin

origin이라는 이름으로 remote 저장소의 url(프로젝트)과 연결

4.2. push와 pull

로컬에서 원격으로 변경사항 push:

git push

이미 git push -u origin main로 원격 대상 branch가 지정되어 있으므로 원격 main으로 푸시함

원격에서 변경사항 로컬로 pull:

git pull

pull할 것이 있을 때 push시:

원격에 먼저 적용된 새 버전이 있으므로 적용 불가
pull 해서 원격의 버전을 받아온 다음 push 가능

방법1 - merge (default)

git pull --no-rebase
충돌 수정
git add .
git commit
git push origin main

image 새로 따진 브런치에서 수정 후 main으로 들어가는 방식 적용

방법2 - rebase

git pull --rebase
충돌 수정
git add .
git commit
git rebase --continue
git push origin main

image 브런치 새로 따지지 않고 main에서 main이 local 수정 내역 추가하는 방식 적용

4.3. syncronize 방식

remote repo와 동기화 후 합치기 전에 일단 확인 시 fetch:

git fetch

remote repo와 동기화 및 merge 작업 확인 안하고 그냥 합칠 때:

git pull

remote에 로컬 변경사항 강제 적용

git push --force

4.4. conflict 해결 방식

시나리오 c90a690: file1.txt 생성
dec8f80: file1.txt 삭제 후 file2.txt 생성
99f5791: file1.txt 복원

conflict 시 reset:

일반적으로 생각하는 과거로 돌아가는 방식

git reset [--mode] [commit_id]
git reset --hard c90a690 # 이전으로 돌아감

원하는 commit 시점으로 reset됨 (실무에서 사용하기 위험)
– soft : index 보존(add한 상태, staged 상태), 워킹 디렉터리의 파일 보존. 즉 모두 보존
– mixed : index 취소(add하기 전 상태, unstaged 상태), 워킹 디렉터리의 파일 보존 (기본 옵션)
– hard : index 취소(add하기 전 상태, unstaged 상태), 워킹 디렉터리의 파일 삭제. 즉 모두 취소

conflict 시 revert:

변경한게 있으면 그걸 반대로 수행해서 되돌리는 방식

git revert [commit_id]
git revert dec8f80

수정한 commit 기록 포함하여 이전 commit 시점으로 revert됨 (상대적으로 안전)
특정 시점 커밋만 되돌리고 이후 커밋은 남기고 싶을 때 유용

merge 시 conflict

시나리오 1) main: Tigers의 manager를 Kenneth로 변경
2) branch-1: Tigers의 manager를 Deborah로 변경
3) main: git merge branch-1 시도
4) 충돌 발생
5) 당장 해결이 어려울 경우 git merge –abort로 중단
6) 충돌 해결 후 git add . 및 git commit으로 병합 완료

rebase 시 conflict:

시나리오 1) main: Tigers의 manager를 Kenneth로 변경
2) branch-2: Tigers의 manager를 Deborah로 변경
3) branch-2: git rebase main 시도
4) 충돌 발생
5) 당장 해결이 어려울 경우 git rebase –abort로 중단
6) 충돌 해결 후 git add . 및 git rebase –continue 병합 완료

4.5. 임시저장

commit 없이 branch를 변경하려고 할 때 stash(임시저장):

git stash -m 'temp'
git stash pop

pop 명령으로 이전에 stash로 임시 저장된 내용 불러오기
commit 할 수 없을 때 branch 바꿔줘야하는 작업 시


5. Log 및 Diff

5.1. log

각 커밋마다의 변경사항(diff) 함께 보기

] git log -p
commit 3ec30a226f7538367e973ac6bdc1d11b8d7f0c60 (HEAD -> master, origin/master)
Author:
Date:
    Edit in local

diff --git a/Staff_Functions.yaml b/Staff_Functions.yaml
index c85b1d1..d946631 100644
--- a/Staff_Functions.yaml
+++ b/Staff_Functions.yaml
@@ -4,3 +4,4 @@ members:
 - Priya
 - Darya
 - 시은(remote 수정)
+- 시은(local 수정

image

최근 n개 커밋만 보기

] git log -2
commit 3ec30a226f7538367e973ac6bdc1d11b8d7f0c60 (HEAD -> master, origin/master)
Author:
Date:
    Edit in local

commit 9250a68d37e30c3ed56d1f2afa049781c6ee21e4
Author:
Date:
    Edit in remote

통계 stat 함께 보기

image

] git log --stat
commit 6c84725c779b6cb0e16caab9cb1873d366adc84f (HEAD -> master)
Author:
Date:
    Create, Delete, Modify, and Edit

 Folks.yaml           | 6 ++++++
 Staff_Functions.yaml | 7 -------
 panthers.yaml        | 2 +-
 tigers.yaml          | 2 --
 4 files changed, 7 insertions(+), 10 deletions(-)

각 파일마다 안보고 전체 변화만 확인

] git log --shortstat
commit 6c84725c779b6cb0e16caab9cb1873d366adc84f (HEAD -> master)
Author:
Date:
    Create, Delete, Modify, and Edit

 4 files changed, 7 insertions(+), 10 deletions(-)

한 줄로 보기

] git log --oneline
6c84725 (HEAD -> master) Create, Delete, Modify, and Edit

–pretty=oneline –abbrev-commit의 줄임

변경사항 내 단어 검색

] git log -S Seeeun(검색어)
commit 6c84725c779b6cb0e16caab9cb1873d366adc84f (HEAD -> master)
Author:
Date:
    Create, Delete, Modify, and Edit

커밋 메세지로 검색

] git log --grep Delete(검색어)
commit 6c84725c779b6cb0e16caab9cb1873d366adc84f (HEAD -> master)
Author:
Date:
    Create, Delete, Modify, and Edit

그래프뷰로 보기

] git log --all --decorate --oneline --graph
* 6c84725 (HEAD -> master) Create, Delete, Modify, and Edit
* 3ec30a2 (origin/master) Edit in local
* 9250a68 Edit in remote
* ccad887 Create Staff_Functions.yaml
*   2490d90 Merge branch 'master' of https://github.com/nueees/git-practice
|\
| * 6861d73 Edit in remote
* | faed33a Edit in local
|/
* 83b1e75 Create Staff_Functions.yaml

–decorate : 브랜치, 태그 등 모든 레퍼런스 표시
–decorate=no
–decorate=short : 기본
–decorate=full

그 외 pretty 문법

] git log --graph --all --pretty=format:'%C(yellow) %h  %C(reset)%C(blue)%ad%C(reset) : %C(white)%s %C(bold green)-- %an%C(reset) %C(bold red)%d%C(reset)' --date=short

5.2. diff

워킹 디렉토리의 변경사항 확인

] git diff
diff --git a/Folks.yaml b/Folks.yaml
index 8e899d1..7955c7a 100644
--- a/Folks.yaml
+++ b/Folks.yaml
@@ -3,4 +3,5 @@ manager: Kailas
 members:
 - Priya
 - Darya
-- Seeeun
+- Seeeun
+- Priyanka

파일명만 확인

] git diff --name-only
Folks.yaml

스테이지의 확인

] git diff --staged

–cached와 같음

커밋간의 차이 확인

] git diff  6c8472(커밋1) 90a65c(커밋2)
diff --git a/Folks.yaml b/Folks.yaml
index 8e899d1..7955c7a 100644
--- a/Folks.yaml
+++ b/Folks.yaml
@@ -3,4 +3,5 @@ manager: Kailas
 members:
 - Priya
 - Darya
-- Seeeun
+- Seeeun
+- Priyanka

커밋 해시 또는 HEAD 번호로 현재 커밋과 비교하려면 이전 커밋만 명시

브랜치간의 차이 확인

] git diff master(브랜치1) new-team(브랜치2)
diff --git a/FolkB.yaml b/FolkB.yaml
new file mode 100644
index 0000000..5e8e79e
--- /dev/null
+++ b/FolkB.yaml
@@ -0,0 +1,4 @@
+manager: Mike
+
+members:
+- Tam

5.3. blame, bisect

blame

누가 코드 짰는지 확인

] git blame -L 10,+3 app.py
8e899d1 (seeeun 2022-01-04 13:31:27 +0900 10)
7955c7a (priya    2022-01-04 13:31:45 +0900 11) added a new feature.
7955c7a (priya    2022-01-04 13:31:45 +0900 12)

bisect

커밋 목록을 이진트리로 만들어서 오류 시점 탐색
커밋v1~v19 중 커밋v3에서 오류가 의심된다고 가정

(main)] git bisect start
(main|BISECTING)] git bisect bad
(main|BISECTING)] git checkout 7d167e9 # 의심되는 commit(v3)으로 checkout

((7d167e9...)|BISECTING)] git bisect good # 코드 실행결과 정상 작동 -> 다음 commit(v11)트리로 자동으로 checkout
Bisecting: 8 revisions left to test after this (roughly 3 steps)
[74d857091743710c7e1047e54accdd9a441907a7] v11

((74d8570...)|BISECTING)] git bisect good # 코드 실행결과 에러 발생 -> 다음 commit(v7)트리로 자동으로 checkout
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[76081e10f78f2e47dab6cfe6c9d39ac5c3ac9d4a] v7

((76081e1...)|BISECTING)] git bisect bad # 코드 실행결과 에러 발생 -> 다음 commit(v5)트리로 자동으로 checkout
Bisecting: 1 revision left to test after this (roughly 1 step)
[eb18f28cad35687a712ff2c58dbfcba6ac6d97a9] v5

((eb18f28...)|BISECTING)] git bisect bad # 코드 실행결과 에러 발생 -> 다음 commit(v4)트리로 자동으로 checkout
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[9a9304295288c28e0ddf6f66997c1f453831c14d] v4

((9a93042...)|BISECTING)] git bisect good # 코드 실행결과 정상 작동 -> 해당 커밋내역 보여
eb18f28cad35687a712ff2c58dbfcba6ac6d97a9 is the first bad commit
commit eb18f28cad35687a712ff2c58dbfcba6ac6d97a9
Author:
Date:
    v5
 program.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

((9a93042...)|BISECTING)] git bisect reset # main으로 돌아감


6. Git Hooks

gitmoji 설치 및 초기화

] brew install gitmoji
] gitmoji -init # 해당 repo에서 실행
] cat .git/hooks/prepare-commit-msg # hooks 디렉토리 내 생성된 shell 확인 가능
#!/bin/sh
# gitmoji as a commit hook
exec < /dev/tty
gitmoji --hook $1 $2

커밋 실행시 메시지에 깃이모지 보여주고 선택가능

] git add .
] git commit
√ Gitmojis fetched successfully, these are the new emojis:
? Choose a gitmoji: (Use arrow keys or type to search)
> 🎨  - Improve structure / format of the code.
  ⚡️  - Improve performance.
  🔥  - Remove code or files.
  🐛  - Fix a bug.
  🚑️  - Critical hotfix.
  ✨  - Introduce new features.
  📝  - Add or update documentation.
(Move up and down to reveal more choices)


7. Git Submodules

main-project에 sub-project 추가

] cd main-project/
] git submodule add git@github.com:nueees/sub-project.git
Cloning into 'C:/main-project/sub-project'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
starting fsmonitor-daemon in 'C:/main-project/sub-project'
warning: LF will be replaced by CRLF in .gitmodules.
The file will have its original line endings in your working directory

main-project에서 commit

] git status
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   .gitmodules
        new file:   sub-project
] git commit

sub-project 파일 수정 후 main-project에서 trackX

] git status
nothing to commit, working tree clean

sub-project로 들어가서 수정 후 commit

] cd sub-project/
] git status
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:   sub1.txt
] git commit