์ค๋ฌด์์ ๋ฐ๋ก ์ฐ๋ ํ๋ฆ๋๋ก, ๊ฐ๋ โ๋ช ๋ น์ดโ์ฃผ์์ โ๋ณต๊ตฌ๊น์ง ํ ๋ฒ์ ์ ๋ฆฌํ์ต๋๋ค.
git config --global user.name "ํ๊ธธ๋"
git config --global user.email "me@example.com"
git config --global core.editor "code --wait" # VS Code
git config --global core.autocrlf input # macOS/Linux ๊ถ์ฅ
git config --global core.autocrlf true # Windows ํผ์ ๊ฐ๋ฐ ์
git status
git log --oneline --graph --decorate -20
git remote -v
git clone <url>
cd <repo>
git branch -vv # ํ์ฌ ๋ธ๋์น๊ฐ ์ด๋ค ์๊ฒฉ ๋ธ๋์น๋ฅผ ์ถ์ ํ๋์ง
git push -u origin feature/x # ์ต์ด ํธ์ ์ -u๋ก ์ถ์ ์ค์
fetch vs pull
git fetch origin
git pull --ff-only # ์ค์๋ก merge commit ์๊ธฐ๋ ๊ฒ ๋ฐฉ์ง
# ๋๋
git pull --rebase --autostash # ๊ฐ์ธ ๋ธ๋์น์์ ๊น๋ํ ์ต์ ํํ ๋
git fetch origin
git switch development
git pull --ff-only origin development
git switch -c feature/login # development ์ต์ ์ปค๋ฐ์์ ์ ๋ธ๋์น
git switch feature/login
# (๊ตฌ์) git checkout feature/login
๋ธ๋์น ๋ค์ด๋ฐ(๊ถ์ฅ)
git fetch origin
git switch development
git pull --ff-only origin development
git switch -c feature/awesome
# (์ด๋ฏธ ๋ง๋ ๊ฒฝ์ฐ) git switch feature/awesome
git status
git add -A
git commit -m "feat(awesome): ์ด๊ธฐ ์ปดํฌ๋ํธ ์ถ๊ฐ"
git push -u origin feature/awesome
๊ฐ๋ ๊ทธ๋ฆผ
development: A -- B -- C -- D
feature/app: E -- F
git switch feature/app
git merge development
๊ฒฐ๊ณผ(merge commit M ์์ฑ)
A -- B -- C -- D ----------- M
\ /
E--F
์ต์ :
git merge --no-ff --no-edit development # merge commit์ ํญ์ ๋จ๊น
git switch feature/app
git rebase development
๊ฒฐ๊ณผ(์ง์ ํ)
A -- B -- C -- D -- E' -- F'
๋ฆฌ๋ฒ ์ด์ค ์ค ์ ์ฉํ ๋ช ๋ น:
git rebase --continue
git rebase --skip
git rebase --abort
--force-with-lease
ํญ๋ชฉ | merge | rebase |
---|---|---|
ํ์คํ ๋ฆฌ | ๋ถ๊ธฐ+๋จธ์ง ์ปค๋ฐ ๋จ๊น | ์ง์ ํ(๊น๋) |
์์ ์ฑ | ๋์(๊ณต์ ์ ์ ํฉ) | ๋ฎ์(๊ณต์ ๊ธ์ง) |
์ถฉ๋ ์ฒ๋ฆฌ | ํ ๋ฒ์ | ์ปค๋ฐ๋ง๋ค |
์ฌ์ฉ ๋งฅ๋ฝ | ํ/๊ณต์ | ๊ฐ์ธ/PR ์ |
์ ์ : ํญ์ ๋จผ์ development๋ฅผ ์ต์ ์ผ๋ก
git fetch origin
git switch development
git pull --ff-only origin development
๋ฐฉ๋ฒ A) ๋ด ๋ธ๋์น์์ development๋ฅผ ๋จธ์ง(์์ , ๊ถ์ฅ)
git switch feature/awesome
git merge development
# ์ถฉ๋ ์ ํด๊ฒฐ โ git add -A โ git commit
๋ฐฉ๋ฒ B) ๋ด ๋ธ๋์น๋ฅผ development ์๋ก ๋ฆฌ๋ฒ ์ด์ค(ํ์คํ ๋ฆฌ ๊น๋)
git switch feature/awesome
git rebase development
# ์ถฉ๋ ์ ํด๊ฒฐ โ git add -A โ git rebase --continue
๋ฐฉ๋ฒ C) ์์ ์ต์ development์์ ์๋ก ํ์(ํ์คํ ๋ฆฌ ๊ฐ์ฅ ๊น๋)
git switch development
git pull --ff-only origin development
git switch -c feature/awesome-v2
# ํ์ ์ปค๋ฐ๋ง cherry-pick
git cherry-pick <E> <F> ...
์ด๋ฏธ ๋ง๋ค์ด๋ ๋ธ๋์น์ development ์ต์ ์ ํฉ์น ๋โ๋
git checkout {new\_branch} && git merge development
๋ช ๋ น์ด ์ฌ์ฉ ๊ฐ๋ฅ. ๋จ, ํญ์ ๊ทธ ์ ์ development๋ฅผ ์๊ฒฉ๊ณผ ๋๊ธฐํํด์ผ ํจ.
๊ณตํต
๋จธ์ง ์ค
git merge development
# ์ถฉ๋ ํด๊ฒฐ
git add -A
git commit
# ์ค๋จํ๋ ค๋ฉด: git merge --abort
๋ฆฌ๋ฒ ์ด์ค ์ค
git rebase development
# ์ถฉ๋ ํด๊ฒฐ
git add -A
git rebase --continue
# ์ ์ฒด ์ค๋จ: git rebase --abort
ํ
git add <file>
๋ฐ๋ณตgit status
, git diff
, ์๋ํฐ ๋ด Conflict View ํ์ฉ๊ธฐ๋ณธ
git stash # ์ถ์ ํ์ผ ๋ณ๊ฒฝ๋ง
git stash -u # untracked(์ ํ์ผ)๋ ํฌํจ
git stash -a # .gitignore๊น์ง ํฌํจ(์ฃผ์)
git stash list
git stash show -p stash@{0}
git stash apply stash@{0} # ์ ์ฉ(์คํ์ ๋จ๊น)
git stash pop # ์ ์ฉ+์คํ์์ ์ ๊ฑฐ
๋ถ๋ถ ์ ์ฉ(๋ํํ)
git stash -p
์ธ๋ฑ์ค ์ ์ง/๋ฉ์์ง
git stash --keep-index
git stash push -m "WIP: ๋ก๊ทธ์ธ ํผ"
Conventional Commits(์ถ์ฒ)
type(scope): ๋ฉ์์ง
feat(auth): ๋ก๊ทธ์ธ ํผ ๋ฐ ์ ํจ์ฑ ๊ฒ์ฆ ์ถ๊ฐ
fix(api): 400 ์๋ต ์ ์๋ฌ์ฝ๋ ํ์ฑ ๋ฒ๊ทธ ์์
docs(readme): ์ค์น ๋ฐฉ๋ฒ ๊ฐฑ์
์ปค๋ฐ ์์
git commit --amend # ์ง์ ์ปค๋ฐ ๋ฉ์์ง/๋ด์ฉ ์์
ํ์คํ ๋ฆฌ ์ ๋ฆฌ(์ธํฐ๋ํฐ๋ธ ๋ฆฌ๋ฒ ์ด์ค)
git rebase -i HEAD~5
# pick โ squash/fixup ๋ก ๋ฌถ๊ธฐ
# autosquash
git commit --fixup <commit>
git rebase -i --autosquash HEAD~5
์์ ํ๊ฒ ๋๋๋ฆฌ๊ธฐ(๊ณต์ ๋ธ๋์น OK)
git revert <commit> # ๋ฐ๋ ๋ณ๊ฒฝ ์ปค๋ฐ ์์ฑ
ํ์คํ ๋ฆฌ ์์ฒด๋ฅผ ์ด๋(๊ณต์ ๋ธ๋์น X)
git reset --soft <commit> # ์ธ๋ฑ์ค/์ํฌํธ๋ฆฌ ์ ์ง
git reset --mixed <commit> # ๊ธฐ๋ณธ, ์ธ๋ฑ์ค ํด์
git reset --hard <commit> # ์ ๋ถ ๋๋๋ฆผ(์ฃผ์)
ํ์ผ ๋จ์ ๋ณต์(์ Git)
git restore <path> # ์ํฌํธ๋ฆฌ๋ง ๋ณต์
git restore --staged <path> # ์คํ
์ด์ง ํด์
๋ง์ง๋ง ์์ ๋ง โ reflog
git reflog # ๋ธ๋์น ์ด๋/๋ฆฌ์
/๋ฆฌ๋ฒ ์ด์ค ์ด๋ ฅ
git reset --hard <reflog-id> # ๊ณผ๊ฑฐ ์ง์ ์ผ๋ก ๋ณต์
์๊ฒฉ ๋ฎ์ด์ฐ๊ธฐ(๊ผญ ํ์ํ ๋๋ง)
git push --force-with-lease # ๋ด ๋ณ๊ฒฝ๋ง ๋ฎ๋๋ก ์์ ์ฅ์น
git rm --cached -r path/or/file
git commit -m "chore: ignore ๋น๋ ์ฐ์ถ๋ฌผ"
git push
์ ์ญ ignore(๊ฐ์ธ ํ๊ฒฝ ํ์ผ)
git config --global core.excludesfile ~/.gitignore_global
git push -u origin feature/awesome
PR ์์ฑ(๋ฒ ์ด์ค: development ๋๋ main)
๋ฆฌ๋ทฐ ๋ฐ์ โ ์ถ๊ฐ ์ปค๋ฐ ํธ์
๋ณํฉ ์ ๋ต
๋จธ์ง ํ ๋ธ๋์น ์ ๋ฆฌ
git branch -d feature/awesome
git push origin --delete feature/awesome
A) โYour local changes would be overwritten by checkoutโ
git add -A && git commit -m "wip: ์ ์ฅ"
# ๋๋
git stash
git switch ๋ค๋ฅธ๋ธ๋์น
# ๋๋ ํน์ ํ์ผ๋ง ์์ ๋ฐฑ์
/์ญ์
B) โThe following untracked working tree files would be overwritten by checkoutโ
git add -A && git commit # ์ปค๋ฐ ํ ์ ํ
git stash -u # untracked ํฌํจ ์์์ ์ฅ
git clean -fd # ์ง์ง ์ญ์ (์ฃผ์)
C) .gitignore ์ถ๊ฐํ๋๋ฐ ์ฌ์ ํ ์ฌ๋ผ๊ฐ
git rm --cached -r path/
git commit -m "chore: stop tracking generated files"
git push
D) development๊ฐ โAlready up to dateโ์ธ๋ฐ ์ต์ ์ด ์๋
git fetch origin
git switch development
git reset --hard origin/development # ์๊ฒฉ ๊ธฐ์ค์ผ๋ก ๋ฑ ๋ง์ถค(์ฃผ์)
E) ๋ฆฌ๋ฒ ์ด์ค ๊ผฌ์์ ๋
git rebase --abort
# ๋๋
git reflog # ์ด์ ์ํ ์ฐพ์ ๋ณต๊ตฌ
git reset --hard <reflog-id>
F) ์๋ชป ํธ์ํ ์ปค๋ฐ ๋๋๋ฆฌ๊ธฐ(๊ณต์ ๋ธ๋์น)
git revert <commit>
git push
G) ๊ณผ๊ฑฐ ์ค์๋ก ๋ฏผ๊ฐ์ ๋ณด ํธ์(๋น๋ฐ๋ฒํธ/ํค)
๋ธ๋์น ์ต์ ํ(๊ฐ์ธ ๋ธ๋์น์์ ์์ )
merge:
git switch feature/x
git merge development
rebase:
git switch feature/x
git rebase development
์ ๋ธ๋์น ์์(ํญ์ ์ต์ development์์)
PR ์ ์ปค๋ฐ ์ ๋ฆฌ
๋๋๋ฆฌ๊ธฐ(๊ณต์ ์์ )
์ด๋ฏธ ์ถ์ ์ค์ธ ํ์ผ ignore
๋ธ๋์น ์ ํ ์ค๋ฅ ํด๊ฒฐ
๋ง์ง๋ง ๋ณต๊ตฌ๋ง
์ ๋ ์ด๋ฐ ๋ฐฉ์์ผ๋ก ์์ ์ ์งํํ๊ณ ์์ต๋๋ค.