728x90
반응형
- 2024-07-30 : First posting.
- 첫 번째 작업 영역인 working directory 는 작업을 하는 프로젝트 디렉토리를 말합니다. 그러니까 지금 상황에서는 MathTool 디렉토리가 working directory 입니다.
- 두 번째 작업 영역인 staging area 는 git add 를 한 파일들이 존재하는 영역입니다. 커밋을 하게되면 staging area 에 있는 파일들만 커밋에 반영됩니다.
- 세 번째 작업 영역인 repository 는 working directory 의 변경 이력들이 저장되어 있는 영역입니다. 그러니까 커밋들이 저장되는 영역이라는 뜻입니다. (보통 .git 폴더를 나타내기도 하고, .git 폴더 포함 working directory 전체를 이야기하기도 하는듯.)
gitconfig.bat
파일을 만들어서 git_설치폴더\bin
폴더에 넣어놓자. 시스템 환경 변수는 적절히 PATH 값을 설정해줘야 하긴 한다.
```[.scrollable.lang-bat]
// --global 태그를 추가로 달면 터미널 껐다켜도 유지가 되는건가? 잘 모르겠네 ㅡ,.ㅡ;;;
SET BASEDIR=%CD%
set GIT_EDITOR=vim
set VISUAL=vim
set EDITOR=%VISUAL%
git config --global core.editor "vim"
git config --global alias.history "log --pretty=oneline"
git config --global user.name "kipid"
git config --global user.email "kipacti@gmail.com"
git config --global --replace-all init.defaultBranch main
git config --global pull.rebase true
cd [Repo-name directory]
git config --global credential.helper path/to/the/password/github-pwd
git remote set-url origin https://kipid:[password]@github.com/kipid/[Repo-name].git
git pull
```/
Cmd 창이나 Shell 혹은 Cmder 에서 gitconfig
만 치면 설정 완료. 이렇게 해놓으면 다음부터 비번을 물어보지 않는다.
### GitHub Desktop (GUI: Graphical User Interface)
이렇게 GUI (Graphical User Interface) 를 써서 git 을 다루는게 (GitHub 와 같이) 더 배우기도 쉽고 편하긴 한데... 굳이 git command 들을 외우고 Command Line Interface (CLI) 에서 작업해야 하는가가 의문이긴 함. 뭐 여러 복잡스런 작업들은 git command 로만 가능하거나 GUI 로는 더 복잡스러울수도 있을거 같긴 한데... 그럴일이 그렇게 많을거 같지도 않아서...
우선은 수업이 있으니 배워놓긴 할 예정. 안써서 금방 까먹을거 같긴 하지만...
p.s. 수업을 다 듣고 나니 배우는건 좀 많은듯. 이러한 기능들도 있었구나를 느꼈고, 더 잘 GitHub 를 활용할 수 있을거 같음.
## Git commands 정리
git init : 현재 디렉토리를 Git이 관리하는 프로젝트 디렉토리(=working directory)로 설정하고 그 안에 레포지토리(.git 디렉토리) 생성
git config user.name 'codeit' : 현재 사용자의 아이디를 'codeit'으로 설정(커밋할 때 필요한 정보)
git config user.email 'teacher@codeit.kr' : 현재 사용자의 이메일 주소를 'teacher@codeit.kr'로 설정(커밋할 때 필요한 정보)
git add [파일 이름] : 수정사항이 있는 특정 파일을 staging area에 올리기
git add [디렉토리명] : 해당 디렉토리 내에서 수정사항이 있는 모든 파일들을 staging area에 올리기
git add . : working directory 내의 수정사항이 있는 모든 파일들을 staging area에 올리기
git reset [파일 이름] : staging area에 올렸던 파일 다시 내리기
git status : Git이 현재 인식하고 있는 프로젝트 관련 내용들 출력(문제 상황이 발생했을 때 현재 상태를 파악하기 위해 활용하면 좋음)
git commit -m "커밋 메시지" : 현재 staging area에 있는 것들 커밋으로 남기기
git help [커맨드 이름] : 사용법이 궁금한 Git 커맨드의 공식 메뉴얼 내용 출력
## GitHub 와의 연계
```[.scrollable]
git remote add origin https://github.com/kipid/Example_Repository.git
git branch -M main
git branch -d master
// or git branch -d --remote origin/master
git push -u origin main
// Id 비번으로 인증. => GitHub 패스워드가 아닌 토큰(token)을 입력.
git commit -m "Message"
git push
git pull // remote repository 에 있는 commit 들 가져오기.
```/
### 다른 사람도 내 repository 에 git push 할 수 있게 만들기
상단의 여러 탭 중에서 Settings 탭을 클릭하세요. 그 다음 화면 왼쪽의 Manage access 탭을 클릭.
Invite a collaborator => Add ... to Example_Repository
## 다른 사람의 repository 내 컴퓨터로 가져오기
```[.scrollable]
git clone https://github.com/numpy/numpy.git
git push -u origin main : 로컬 레포지토리의 내용을 처음으로 리모트 레포지토리에 올릴 때 사용합니다.(-u origin main 가 무슨 뜻인지는 'Git에서 브랜치 사용하기' 챕터에서 배울 거니까 걱정마세요!)
git push : 로컬 레포지토리의 내용을 리모트 레포지토리에 보내기
git pull : 리모트 레포지토리의 내용을 로컬 레포지토리로 가져오기
git clone [프로젝트의 GitHub 상 주소] : GitHub에 있는 프로젝트를 내 컴퓨터로 가져오기
```/
## Git history
```[.scrollable]
git log
git log --pretty=oneline
git show [commit-id/hash]
git commit // 긴 commit message 를 남길 수 있음.
git commit --amend // 이전 commit 수정하기.
```/
변경 이력: 델타 (delta) - 왜 커밋을 했는지
- 어떤 문제가 있었고
- 적용한 해결책이 어떤 효과를 가지는지
- 나중에 다시 봤을 때 이해하는데 어려움이 없도록
- 다른 동료 개발자와 협업하는 데 방해가 되지 않도록
git log : 커밋 히스토리를 출력
git log --pretty=oneline : --pretty 옵션을 사용하면 커밋 히스토리를 다양한 방식으로 출력할 수 있습니다. --pretty 옵션에 oneline이라는 값을 주면 커밋 하나당 한 줄씩 출력해줍니다. --pretty 옵션에 대해 더 자세히 알고싶으면 이 링크를 참고하세요.
git show [커밋 아이디] : 특정 커밋에서 어떤 변경사항이 있었는지 확인
git commit --amend : 최신 커밋을 다시 수정해서 새로운 커밋으로 만듦
git config alias.[별명] [커맨드] : 길이가 긴 커맨드에 별명을 붙여서 이후로 별명으로 해당 커맨드를 실행할 수 있도록 설정
git diff [커밋 A의 아이디] [커밋 B의 아이디] : 두 커밋 간의 차이 비교
git reset [옵션] [커밋 아이디] : 옵션에 따라 하는 작업이 달라짐(옵션을 생략하면 --mixed 옵션이 적용됨)
## Branch
Branch: 나뭇가지. 하나의 코드 관리 흐름.
master branch or main branch (요새는 main 으로 주로 이름 붙임.)
```[.scrollable]
git branch premium // premium branch 만들기
git checkout premium // premium branch 로 이동
git branch // branch 조회
git branch -d test // delete branch
git checkout -b test // branch 생성 및 이동
git checkout main // main branch 로 이동
```/
### Branch merge 하기
```[.scrollable]
git checkout premium
git merge main // 현재 premium branch 에 main branch merge 하기
```/
#### Merge conflict
1. Conflict 가 발생한 파일을 연다.
2. Merge 의 결과가 되었으면 하는 모습대로 코드를 수정.
3. Commit.
or
```[.scrollable]
git merge --abort // Merge 취소
```/
#### 여러 파일에서 conflict 가 났을 때
파일 하나씩 conflict 를 해결하고 git add [파일 이름] 커맨드로 하나씩 staging area 에 올리거나(중간중간에 git status 커맨드로 현재 상태 확인하면서)
모든 파일들의 conflict 를 다 해결하고, git add . 커맨드로 한번에 staging area 에 올리고
커밋을 하면 됩니다.
### Remote Repository 의 브랜치는 이렇게 보입니다!
#### origin 이란?
```[.scrollable]
git remote add origin https://github.com/kyuri-dev/Math_Box.git
git push -u origin main // -u 는 --set-upstream 이라는 옵션의 약자
```/
Git 에서는 리모트 레포지토리를 최초로 추가할 때 origin 이라는 이름으로 가리키는 것이 관례화되어 있습니다.
origin 은 '근원', '기원' 이라는 뜻을 가집니다. 아마도 다른 사람의 리모트 레포지토리를 자신의 컴퓨터로 가져와서 작업을 하는 사람의 입장에서는 리모트 레포지토리가 프로젝트의 근원이 되는 존재이기 때문에 그런 관습이 생긴 것으로 추측됩니다.
#### Remote Repositoy 에 있는 브랜치
```[.scrollable]
git push origin main:main // origin 은 리모트 레포지토리를 나타내고, main:main 에서 더 먼저 나오는 main 는 로컬 레포지토리의 main 브랜치(~에서)/더 뒤에 나오는 main 는 리모트 레포지토리의 main 브랜치(~으로)를 나타냅니다.
```/
그냥 처음부터 tracking connection 을 설정하고 그 이후부터는 git push, git pull 이라고만 써서 편하게 푸시와 풀을 하는 게 좋겠죠? 이게 바로 제가 맨 처음에 로컬 레포지토리의 내용을 리모트 레포지토리로 보낼 때 -u 라는 옵션을 썼던 이유입니다.
```[.scrollable]
git push -u origin main // tracking connection 설정
```/
#### origin/main 의 의미
git push 를 해준 적이 없다면, Local repository 의 main branch 가 나타내는 commit 들과 origin/main 인 remote repository 의 main branch 를 나타내는 commit 이 다를 수 있음.
git push 로 통합시킬 수 있음.
#### Remote repository 에 새로운 branch 추가하기
```[.scrollable]
git checkout premium
git push --set-upstream origin premium // premium branch 를 remote 로 처음 push 할 때
```/
## HEAD 와 Branch 의 관계
Branch 는 코드를 관리하는 하나의 흐름.
Branch 는 Commit 을 가리키는 포인터.
HEAD 는 branch 를 가리킴.
Merge commit: 두 branch 가 하나로 합쳐짐. 합쳐진 branch 를 HEAD 가 가리킴.
git reset 커맨드를 사용하면
(1) HEAD가 특정 커밋을 가리키도록 이동시킴(--soft는 여기까지 수행)
(2) staging area도 특정 커밋처럼 리셋(--mixed는 여기까지 수행)
(3) working directory도 특정 커밋처럼 리셋(--hard는 여기까지 수행)
그리고 이때 커밋 아이디 대신 HEAD의 위치를 기준으로 한 표기법(예 : HEAD^, HEAD~3)을 사용해도 됨
git tag [태그 이름] [커밋 아이디] : 특정 커밋에 태그를 붙임
- HEAD는 여전히 같은 브랜치를 가리키고,
- HEAD가 가리키는 브랜치가 다른 특정 커밋을 가리키게 됩니다.
- 이 때문에 결국 HEAD가 간접적으로 가리키던 커밋도 바뀌게 되는 겁니다.
- 과거의 커밋으로 git reset을 한다고 그 이후의 커밋들이 삭제되는 게 절대 아닙니다. 계속 남아있습니다.
- git reset은 과거의 커밋뿐만 아니라 현재 HEAD가 가리키는 커밋 이후의 커밋으로도 할 수 있습니다.
git checkout 커맨드로는 HEAD 가 직접적으로 가리키는 것을 바꿀 수 있고
git checkout 뒤에는 커밋 아이디 또는 브랜치의 이름을 줘서
HEAD 가 직접 커밋을 가리키거나, 브랜치를 가리키도록 할 수 있다는 뜻입니다.
git reset: HEAD 가 가리키던 브랜치가 다른 커밋을 가리키도록 한다. HEAD 도 결국 간접적으로 다른 커밋을 가리키게되는 효과가 생긴다
git checkout: HEAD 자체가 다른 커밋이나 브랜치를 가리키도록 한다. 브랜치를 통하지 않고, 커밋을 직접적으로 가리키는 HEAD 를 Detached HEAD 라고 한다
## Merge commit
### 3-way merge
Merge 를 하면 새로운 commit 이 생긴다. 이를 Merge commit 이라고 부른다.
case1
지금 base 가 A이고, main 는 A, premium 은 B죠? 그럼 base 를 기준으로 볼 때, main 에서는 변화가 없었지만, premium 에서는 A 가 B 로 변경된 상태입니다. 3-way merge 는 base 에서 변화가 발생한 것을 우선 채택합니다. 그래서 머지 결과는 'B' 가 됩니다.
case2
지금 base 가 1이고, main 는 2, premium 은 1이죠? 이 경우에도 base 에서 변화가 발생한 2가 머지 결과가 됩니다.
case3
지금 base 가 "hello" 이고, main 는 "hello" 를 삭제한 공백 상태, premium 은 "hello" 입니다. "hello" 를 삭제해서 공백 상태가 된 것이 변화가 더 발생한 것이기 때문에 머지 결과는 공백이 됩니다.
case4
지금 base 가 "bye", main 가 "fighting", premium 이 "please" 인데요. 지금은 이전 경우들과 좀 다르네요. 둘 다 base 때와는 다른 변화가 일어났는데요. 이렇게 두 브랜치에서 다 변화가 있을 때 Git 은 어떤 변화를 선택해야할까요? 정답은 바로 'Git도 모른다!' 입니다. 사실, 바로 이런 경우에 여러분이 배운 Conflict 가 발생합니다. 이전에 Conflict 가 발생했을 때 그것을 해결하고 머지를 마무리했던 거 기억나시죠? 바로 이런 경우였던 겁니다.
종합 정리
base때의 내용과 비교했을 때 달라진 부분이 있는 것이 우선시되고,
두 브랜치에서 둘다 변화가 일어났을 때는 Conflict를 발생시켜서 사용자가 스스로 선택하게끔 한다는 걸 기억하시면 됩니다.
### Merge commit 이 안생기는 경우: Fast-forward merge
커밋 히스토리에서 같은 선 (line) 상에 있는 브랜치를 머지할 때 Fast-forward 머지가 이루어집니다.
## Git commands 정리
git branch [새 브랜치 이름]: 새로운 브랜치를 생성
git checkout -b [새 브랜치 이름]: 새로운 브랜치를 생성하고 그 브랜치로 바로 이동
git branch -d [기존 브랜치 이름]: 브랜치 삭제
git checkout [기존 브랜치 이름]: 그 브랜치로 이동
git merge [기존 브랜치 이름]: 현재 브랜치에 다른 브랜치를 머지
git merge --abort: 머지를 하다가 conflict가 발생했을 때, 일단은 머지 작업을 취소하고 이전 상태로 돌아감
## git pull (or fetch)
git push 를 하기 전에 보통 git pull (or fetch) 을 먼저 해야한다.
이 경우 conflict 가 나는 경우가 많을텐데, 이런 conflict 를 잘 해결한 뒤 git commit 을 해야한다.
git pull = git fetch + git merge
### git fetch
우선 commit 들을 merge 없이 가져오는 명령어.
Remote repository 에서 가져온 branch 의 내용을 merge 하기 전에 점검해야할 필요가 있을 때 사용.
Remote repository 에 있는 branch 의 내용과 내가 작성한 코드를 비교해서 잘못된 부분이 없는지 검토해야 할 때.
```[.scrollable]
git fetch
git diff premium origin/premium // 두 local branch 와 remote branch 를 비교
```/
## git blame [filename]
file 의 각 부분이 어떤 commit 으로 수정되었는지 보여주는 명령어.
(이건 GitHub GUI (Graphical User Interface) 에서 잘 못봤던거 같은데, 찾아봐야겠음.) :: GitHub.com file page 에서 blame 이란 옵션이 왼쪽 위에 있는듯. 그걸 클릭하면 file 의 각 부분이 어떤 commit 으로 수정되었는지 보여줌.
### git show [commit id]
commit 의 내용 (file 의 변화된 부분, commit message 등) 보여주기.
## git revert [commit id]
Commit 을 되돌리는 명령어. Commit 이 하나 더 만들어짐 (Revert commit).
이후 commit 들을 아예 지워버리는 git reset 보다 더 많이 활용될듯.
### git revert [복귀 될 commit id]..[초기화 할 commit 들 중 가장 나중 commit id] // (여러개 commit 들을 한꺼번에 revert 하기)
```[.scrollable]
git revert [복귀 될 commit id]..[초기화 할 commit 들 중 가장 나중 commit id] // 여러개의 revert commit 들이 생김
```/
## Git commands 정리
git fetch: 로컬 레포지토리에서 현재 HEAD 가 가리키는 브랜치의 업스트림 (upstream) 브랜치로부터 최신 커밋들을 가져옴 (가져오기만 한다는 점에서, 가져와서 머지까지 하는 git pull 과는 차이가 있음)
git blame: 특정 파일의 내용 한줄한줄이 어떤 커밋에 의해 생긴 것인지 출력
git revert: 특정 커밋에서 이루어진 작업을 되돌리는 (취소하는) 커밋을 새로 생성
## git reflog: git reset 후의 commit 들 (git reset 을 하고 나서 돌아오려면?)
```[.scrollable]
git reflog // reference log, reset 이전/이후의 commit 들도 보기
```/
## git log --pretty=oneline --all --graph
branch 도 같이 표현해주면서 예쁘게 git history 를 보여주는 명령어.
## Git GUI (Graphical User Interface): SourceTree
SourceTree https://www.sourcetreeapp.com/ 란 Git GUI 가 있다는거 같음. GitHub Desktop 도 좋긴 하던데, 두 프로그램의 장단점이 있긴 할 듯. 둘 다 깔아서 사용해 볼 예정.
## 깔끔한 커밋 히스토리를 원할 땐 git merge 대신 git rebase [branch name]
```[.scrollable]
git rebase [branch name]
git rebase --continue // Conflict 가 발생해서 제대로 진행되지 못한 rebase 를 계속 진행하라
```/
merge 보다 commit history 가 더 깔끔하단 장점이 있음.
상황에 따라 git rebase, git merge 를 잘 활용합시다.
## git stash: 작업 내용 임시 저장하기
```[.scrollable]
git stash // 작업했던/수정했던 파일들을 stack 에 잠기 옮겨둠
git stash list
git stash apply // 작업했던/수정했던 파일들을 복구
```/
### 잘못된 브랜치에서 작업하고 있었다면?
```[.scrollable]
git checkout main
git stash
git checkout premium
git stash apply // 다른 branch 에서도 stash apply 를 쓸 수 있음. 작업 내용의 아이디를 생략하면 가장 최근의 작업 내용이 적용됨.
git stash list
// stash@{0}: WIP on master: 75282b7 Add free License duration info
// stash@{1}: WIP on premium: 84e67c3 Add get_Remainder function
git stash apply stash@{0} // 특정 stash 를 적용하고 싶을 때.
git stash drop stash@{0} // 이미 stash apply 를 하고 commit 을 했다면 stash stack 에서 지워줍시다.
git stash pop [작업 내용의 아이디] // git stash apply 를 해주고 바로 git stash drop 을 해줌. [작업 내용의 아이디] 가 없다면 제일 최근의 stash 에 적용.
```/
일반적으로 git stash pop 이 주로 더 많이 사용됨.
## 필요한 커밋만 가져오는 git cherry-pick
다른 branch 의 더 오래된 commit 을 가져다 오고 싶을때 주로 쓰임.
```[.scrollable]
git cherry-pick [commit id]
```/
## 여러 커밋을 하나의 커밋으로 만들기 (심화)
```[.scrollable]
git reset --soft [commit id] // 없애고 싶은 자잘한 commit 들이 있을때 reset to last commit with --soft option.
git add .
git commit -m "Message"
```/
## .gitignore: git 이 무시하는 파일들
굳이 Git 에 의해 버전 관리될 필요가 없는, 불필요한 파일들의 이름을 정리하여 .gitignore 파일을 생성.
버전 관리를 할 정도의 가치가 없고,
오히려 버전 관리를 하면 용량만 더 차지하고,
나중에 각 버전을 살펴볼 때 가독성을 떨어뜨리기만 하기 때문에
그런데 먼저 commit 을 한 후에 .gitignore 에 추가를 하면, file 들이 계속 추적되는 경우가 있다. 이 경우 아래와 같은 명령어를 치면 되는듯 하다. .gitignore 설정하기
```[.scrollable]
git rm -r --cached .
git add .
git commit -m "Apply .gitignore"
```/
예:
```[.scrollable]
# .gitignore
### Vert.x ###
.vertx/
### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
### Intellij+iml ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
# Gradle:
.idea/**/gradle.xml
.idea/**/libraries
# CMake
cmake-buildTool-debug/
# Mongo Explorer plugin:
.idea/**/mongoSettings.xml
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-buildTool.properties
fabric.properties
### Intellij+iml Patch ###
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
*.iml
modules.xml
.idea/misc.xml
*.ipr
### macOS ###
*.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
!/.mvn/wrapper/maven-wrapper.jar
### Gradle ###
.gradle
/buildTool/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Cache of project
.gradletasknamecache
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties
### NetBeans ###
nbproject/private/
buildTool/
nbbuild/
dist/
nbdist/
.nb-gradle/
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# Sublime text
*.sublime-workspace
*.sublime-project
*.log
*.mdmp
build/distributions/http-1.0.0-SNAPSHOT.tar
build/distributions/http-1.0.0-SNAPSHOT.zip
build/libs/http-1.0.0-SNAPSHOT-fat.jar
build/libs/http-1.0.0-SNAPSHOT.jar
build/distributions/http-shadow-1.0.0-SNAPSHOT.tar
build/distributions/http-shadow-1.0.0-SNAPSHOT.zip
cmder/config/*
cmder/vendor/conemu-maximus5/ConEmu.xml
```/
## Git 토픽 내용 총정리
자, 이제 마지막 챕터까지 모든 내용을 마쳤습니다. 이때까지 배운 Git 커맨드를 챕터별로 한눈에 살펴볼까요? 코드잇 :: Git - 14. Git 토픽 내용 총정리
### Git 써보기
git init : 현재 디렉토리를 Git이 관리하는 프로젝트 디렉토리(=working directory)로 설정하고 그 안에 레포지토리(.git 디렉토리) 생성
git config user.name 'codeit' : 현재 사용자의 아이디를 'codeit'으로 설정(커밋할 때 필요한 정보)
git config user.email 'teacher@codeit.kr' : 현재 사용자의 이메일 주소를 'teacher@codeit.kr'로 설정(커밋할 때 필요한 정보)
git add [파일 이름] : 수정사항이 있는 특정 파일을 staging area에 올리기
git add [디렉토리명] : 해당 디렉토리 내에서 수정사항이 있는 모든 파일들을 staging area에 올리기
git add . : working directory 내의 수정사항이 있는 모든 파일들을 staging area에 올리기
git reset [파일 이름] : staging area에 올렸던 파일 다시 내리기
git status : Git이 현재 인식하고 있는 프로젝트 관련 내용들 출력(문제 상황이 발생했을 때 현재 상태를 파악하기 위해 활용하면 좋음)
git commit -m "커밋 메시지" : 현재 staging area에 있는 것들 커밋으로 남기기
git help [커맨드 이름] : 사용법이 궁금한 Git 커맨드의 공식 메뉴얼 내용 출력
### GitHub 시작하기
git push -u(또는 --set-upstream) origin master : 로컬 레포지토리의 내용을 처음으로 리모트 레포지토리에 올릴 때 사용합니다.
git push : 위의 커맨드를 한번 실행하고 난 후에는 git push라고만 쳐도 로컬 레포지토리의 내용을 리모트 레포지토리에 올릴 수 있습니다.
git pull : 바로 위의 위에 있는 커맨드를 한번 실행하고 난 후에는 git pull이라고만 쳐도 리모트 레포지토리의 내용을 로컬 레포지토리로 가져옵니다.
git clone [프로젝트의 GitHub 상 주소] : GitHub에 있는 프로젝트를 내 컴퓨터로 가져오기
### Git에서 커밋 다루기
git log : 커밋 히스토리를 출력
git log --pretty=oneline : --pretty 옵션을 사용하면 커밋 히스토리를 다양한 방식으로 출력할 수 있습니다. --pretty 옵션에 oneline이라는 값을 주면 커밋 하나당 한 줄씩 출력해줍니다. --pretty 옵션에 대해 더 자세히 알고싶으면 이 링크를 참고하세요.
git show [커밋 아이디] : 특정 커밋에서 어떤 변경사항이 있었는지 확인
git commit --amend : 최신 커밋을 다시 수정해서 새로운 커밋으로 만듦
git config alias.[별명] [커맨드] : 길이가 긴 커맨드에 별명을 붙여서 이후로는 별명으로도 해당 커맨드를 실행할 수 있게 설정
git diff [커밋 A의 아이디] [커밋 B의 아이디] : 두 커밋 간의 차이 비교
git reset [옵션] [커밋 아이디] : 옵션에 따라 하는 작업이 달라짐(옵션을 생략하면 --mixed 옵션이 적용됨)
### Git에서 브랜치 사용하기
(1) HEAD가 특정 커밋을 가리키도록 이동시킴(--soft는 여기까지 수행)
(2) staging area도 특정 커밋처럼 리셋(--mixed는 여기까지 수행)
(3) working directory도 특정 커밋처럼 리셋(--hard는 여기까지 수행)
그리고 이때 커밋 아이디 대신 HEAD의 위치를 기준으로 한 표기법(예 : HEAD^, HEAD~3)을 사용해도 됨
git tag [태그 이름] [커밋 아이디] : 특정 커밋에 태그를 붙임
git branch [새 브랜치 이름] : 새로운 브랜치를 생성
git checkout -b [새 브랜치 이름] : 새로운 브랜치를 생성하고 그 브랜치로 바로 이동
git branch -d [기존 브랜치 이름] : 브랜치 삭제
git checkout [기존 브랜치 이름] : 그 브랜치로 이동
git merge [기존 브랜치 이름] : 현재 브랜치에 다른 브랜치를 머지
git merge --abort : 머지를 하다가 conflict가 발생했을 때, 일단은 머지 작업을 취소하고 이전 상태로 돌아감
### Git 실전
git fetch : 로컬 레포지토리에서 현재 HEAD가 가리키는 브랜치의 업스트림(upstream) 브랜치로부터 최신 커밋들을 가져옴(가져오기만 한다는 점에서, 가져와서 머지까지 하는 git pull과는 차이가 있음)
git blame : 특정 파일의 내용 한줄한줄이 어떤 커밋에 의해 생긴 것인지 출력
git revert : 특정 커밋에서 이루어진 작업을 되돌리는(취소하는) 커밋을 새로 생성
### Git 실전 Ⅱ
git reflog : HEAD가 그동안 가리켜왔던 커밋들의 기록을 출력
git log --all --graph : 모든 브랜치의 커밋 히스토리를, 커밋 간의 관계가 잘 드러나도록 그래프 형식으로 출력
git rebase [브랜치 이름] : A, B 브랜치가 있는 상태에서 지금 HEAD가 A 브랜치를 가리킬 때, git rebase B를 실행하면 A, B 브랜치가 분기하는 시작점이 된 공통 커밋 이후로부터 존재하는 A 브랜치 상의 커밋들이 그대로 B 브랜치의 최신 커밋 이후로 이어붙여짐(git merge와 같은 효과를 가지지만 커밋 히스토리가 한 줄로 깔끔하게 된다는 차이점이 있음)
git stash : 현재 작업 내용을 스택 영역에 저장
git stash apply [커밋 아이디] : 스택 영역에 저장된 가장 최근의(혹은 특정) 작업 내용을 working directory에 적용
git stash drop [커밋 아이디] : 스택 영역에 저장된 가장 최근의(혹은 특정) 작업 내용을 스택에서 삭제
git stash pop [커밋 아이디] : 스택 영역에 저장된 가장 최근의(혹은 특정) 작업 내용을 working directory에 적용하면서 스택에서 삭제
git cherry-pick [커밋 아이디] : 특정 커밋의 내용을 현재 커밋에 반영
### 마무리
자, Git 토픽에서 배운 커맨드들을 쭉 정리해봤는데요. 기억이 다 잘 나시나요? 이 커맨드들만 제대로 이해하고 사용해도 여러분이 어디에서 어떤 일을 하든 Git을 사용할 때 불편함이 없을 겁니다. 혹시라도 Git으로 아주 세밀한 작업 또는 여기서 배우지 않은 새로운 커맨드를 써야한다고 할지라도 겁낼 필요가 없습니다. 이 토픽에서는 커맨드 뿐만 아니라 Git의 내부 동작 원리도 제대로 배웠기 때문에 여러분이 조금만 노력하면 그런 것들도 금방 쉽게 할 수 있을 겁니다.
이제 어디를 가도 '나 Git 쓸 줄 알아!' 라고 자신있게 말할 수 있게 되신 여러분, 축하합니다!
## 추신 (코드 리뷰 시스템: Gerrit)
코드 리뷰 시스템인 Gerrit 도 설치하고 공부해 볼만함. (구글에서 만든 code review framework 인거 같음.) https://gerrit-review.googlesource.com/Documentation/
3개월간 Intern 을 했던 Skelter Labs 란 회사에서 쓰던 시스템인데, git commit 한걸 가지고 변경된 사항마다 이러이러한 부분이 수정이 필요한거 같단 리뷰/코멘트를 Graphical 하게 써서 리뷰를 보내줄 수 있고. 그 수정부분을 반영해서 다시 리뷰를 요청하고, 다시 리뷰 받고를 반복. 리뷰를 통과해야만 main branch 에 리뷰가 다 된 commit 들이 하나로 통합된 commit 하나가 merge 되는 시스템이었던 걸로 기억함.
리눅스 서버에 깔아야 하는거 같긴한데... 큰 회사나 스타트업들이 구축해놓으면 꽤 좋은거 같음.
## 여러 원격 저장소들
! 그 밖에 알아야할 사실
(1) git commit이라고만 쓰고 실행하면 커밋 메시지를 입력할 수 있는 텍스트 에디터 창이 뜹니다. 거기서 커밋 메시지를 입력하고 저장하고 나면 커밋이 이루어집니다.
(2) git push와 git pull은 그 작업 단위가 브랜치입니다. 예를 들어, master 브랜치에서 git push를 하면 master 브랜치의 내용만 리모트 레포지토리의 master 브랜치로 전송되지, premium 브랜치의 내용이 전송되는 것은 아닙니다.(git push에 --all이라는 옵션을 주면 모든 브랜치의 내용을 전송할 수 있기는 합니다.)
GitHub: 서비스가 죽는다. 대란 (업무 마비). 대중적. 관대하다. (많은 서비스들이 무료. 비공개 Repository 등.)
GitLab: 설치형
BigBuckit:
Figma: 서버가 죽으면 대란.
AWS: 서비스 중단이면 대란.
## 협업시 Git/GitHub Tips
참조:
### Windows (윈도우) 에선 .bat
, Mac 에선 .sh
만들어서 활용하면 좋음.
kipid 는 자기 계정 이름으로 바꾸시고 아래와 같은 .bat
파일을 C:/PortableGit/bin 디렉토리에 복붙하면 됨. 환경변수 편집에서 PATH 에 C:/PortableGit/bin 도 추가해 주셔야 하고.
```[.linenums]
@rem copy to C:/PortableGit/bin
:: Current directory
SET BASEDIR=%CD%
set GIT_EDITOR=vim
set VISUAL=vim
set EDITOR=%VISUAL%
git config --global core.editor "vim"
git config --global alias.history "log --pretty=oneline"
git config --global user.name "kipid"
git config --global user.email "kipacti@gmail.com"
git config --global --replace-all init.defaultBranch main
git config --global pull.rebase true
rem 자신의 이름과 이메일을 입력할 것.
rem ssh 인증이 필요하다면 아래와 같은 명령어를 치면, 매번 git push/pull 마다 인증할 필요가 없어짐.
rem call ssh-agent
rem ssh-add C:/path/to/.ssh/github-recoeve-rsa
rem git config --global credential.helper cache
rem cd [Git-repo-name-1]
rem git remote set-url origin git@github.com:kipid/[Git-repo-name-1].git
rem git pull
rem cd [Git-repo-name-1]
rem git remote set-url origin git@github.com:kipid/[Git-repo-name-2].git
rem git pull
git config --global credential.helper C:/[Git-repo-name-2]/.ssh/github-pwd
git remote set-url origin https://kipid:[temporal-password]@github.com/kipid/[Git-repo-name-1].git
git pull
cd C:/[Git-repo-name-2]/
git remote set-url origin https://kipid:[temporal-password]@github.com/kipid/[Git-repo-name-2].git
git pull
:: Back to current directory
cd %BASEDIR%
```/
### 다른 팀원에 의해 dev가 merge 된 경우
우선 dev branch 로 가서 dev 를 최신으로 동기화 한 뒤 내 작업 branch 로 가서 dev 로 merge 후 작업 이어서 진행. Merge 한다고 dev branch 가 바뀌는건 아님.
```[.linenums]
(feature/my-job 브랜치에서 작업 도중 다른 팀원에 의해 dev가 merge 된 경우)
git checkout dev
git pull upstream dev
git checkout feature/my-job
git merge dev
# 커밋메시지 변경 후 저장
# 작업이어서 진행
```/
### Project PR 머지 후 작업
```[.linenums]
git checkout dev
git pull upstream dev
git push origin dev ## 중요
git switch -c feature/next-job
```/
### 빠르게 전체 팀원이 적용해야 할 변경사항을 dev 브랜치로 반영하면서, 동시에 아직 완료되지 않은 feature/my-job 브랜치 작업을 유지하려면
```[.linenums]
git stash
```/
로 현재 feature/my-job branch 에서 작업하고 있는 내용을 임시로 저장.
dev branch 로 가서 최신으로 동기화 시킨 뒤 새로운 branch 를 생성. (dev 기반으로 branch 가 생성됨.)
```[.linenums]
git checkout dev
git pull
git checkout -b feature/hot-fix
```/
필요한 변경 사항만 적용: 데이터베이스 테이블 수정과 같이 빠르게 반영해야 하는 사항만 이 브랜치에 커밋합니다.
```[.linenums]
git add .
git commit -m "fix: apply urgent DB table changes"
git push
```/
To dev from feature/hot-fix 로 PR merge 요청. 바로 self merge 할 수 있음 하고, 1인이상 approve 해야 merge 되는 상황이라면 동료에게 알려서 빠르게 merge.
Merge 된 dev branch 를 다시 최신 동기화. 그리고 원래 작업으로 복귀.
```[.linenums]
git checkout dev
git pull
git checkout feature/my-job
git stash pop
git merge dev
```/
### 충돌이 발생한 경우
충돌이 발생한 파일에서 충돌한 부분을 수정해야 합니다. Git은 충돌 부분을 다음과 같이 표시합니다.
```
<<<<<<< HEAD
이 부분은 feature/my-job 브랜치의 변경 내용입니다.
=======
이 부분은 dev 브랜치의 변경 내용입니다.
>>>>>>> dev
```/
두 내용을 비교하여 충돌을 해결한 후, 필요 없는 표시(<<<<<<<, =======, >>>>>>>)를 삭제합니다.
충돌을 해결한 후, 수정한 파일을 스테이징하고 커밋.
이 과정은 VS code 에서 잘 해결해 줌. (Extension 을 깔아서 그런건가? =ㅇ=)
Accept current, Accept the following, Accept both 등이 충돌난 부분에 떴었던거 같음. 적절히 선택하면 빠르게 충돌을 해결할 수 있음.
### 모든 충돌을 dev 브랜치의 내용으로 해결
```
git checkout --theirs .
```/
라고 치면 충돌 부분에서 상대 브랜치 (dev branch) 의 내용을 선택한다는데... 이건 좀 조심해서 써야할듯.
## RRA
728x90
반응형