■git 기본 커맨드 정리 ▨초기화 git init : 현재 디렉토리를 git 저장소로 만들기 (.git 생성) git init --bare --shared <git dir> : Working Directory를 만들지 않고, 여러사람이 작업할 떄 권한을 자동으로 주는 git 저장소 만들기 ▨Staging Area로 보내기 git add . : 현재 디렉토리의 모든 내용을 Staging Area(.git)에 추가 git add -A : Working Directory의 모든 내용을 Staging Area에 추가 git add -p : 변경점을 hunk 단위로 보여주면서 인터랙티브하게 Staging Area에 추가 ▨commit git commit -m "Add: test.py 파일 추가" ▨원격 저장소에서 가져오기 git fetch : 원격 저장소의 변경 내용을 확인하기 git pull origin master : 원격 저장소의 변경 내용을 현재 디렉토리로 가져오기 (원격 서버→.git) git clone : 원격 저장소를 로컬 저장소로 복사하여 새로운 저장소 생성 (기존 commit 로그 없음) git fork : 원격 저장소를 원격 저장소에 복사본 생성 (기존 commit 로그 있음) ▨원격 저장소로 보내기 git push : 변경 사항을 원격 서버에 업로드 (.git→원격 서버) ▨상태 확인 git status : 현재 상태 확인 git log : 로그 확인 git reflog : 커밋 삭제 로그 확인 git log --oneline : 커밋 히스토리 조회 (commit hash 확인) git remote -v : 리모트 확인 ▨설정 git config --global user.name "git user" : 사용자 설정 git config --global user.email "gituser@git.com" : 이메일 설정 git config --unset --global user.name : user.name 설정 삭제 git remote add origin "https://git:git@10.10.10.111/sample_repo.git" git remote remove origin : origin 저장소 삭제 git remote -v : 원격 저장소 확인 git config --list : 전체 설정 확인 ▨remote git remote show origin : origin remote 상세 정보 보기 ▨초기화 git init : 현재 디렉토리를 git 저장소로 만들기 (.git 생성) git init --bare --shared <git dir> : Working Directory를 만들지 않고, 여러사람이 작업할 떄 권한을 자동으로 주는 git 저장소 만들기 ▨삭제 git rm -f --cached <파일명>: 원격 저장소에 있는 파일 삭제 ('*' 가능) git rm -f <파일명>: 원격 저장소와 로컬 저장소에 있는 파일 삭제 ▨commit git commit -m "message" : 커밋 생성 git commit --amend -m "수정된 메시지" : 커밋 생성+커밋 메세지 수정 git commit --amend --no-edit : 커밋 생성+설명은 수정하지 않음 ▨branch git branch git branch -vv : 로컬 분기 브랜치 목록 보기 git branch <branch> : 브랜치 생성 git branch -b <branch> : 브랜치를 생성하고 해당 브랜치로 바로 이동 git checkout <branch> : 브랜치 이동 git branch : 원하는 브랜치로 이동했는지 확인 git branch -a : 모든 브랜치 확인 git branch -d <branch> : 브랜치 삭제 git branch -D <branch> : 브랜치 강제 삭제 git branch -rd <remote>/브랜치 이름> : 원격 추적 브랜치 삭제 git push --delete <remote> <branch> : 원격지 브랜치 삭제 git remote prune <remote> : unreachable 한 git object 들을 local 에서 clean git remote prune --dry-run --verbose : prune 테스트 git diff <branch> <다른 브랜치 이름> : 변경 내용을 merge 하기 전에 바뀐 내용 비교 git merge <다른 브랜치 이름> : 다른 브랜치와 병합 ※브랜치 파일 위치: .git/refs/remotes/<branch name> ▨커밋 되돌리기 (push 전에 사용) git reset HEAD^ : commit 바로 이전 단계로 복구 git reset HEAD~2 : commit 바로 전전 단계로 복구 git reset --hard <commit hash> : <commit hash> 이후의 변경 이력은 파일까지 모두 삭제 git reset --mixed <commit hash> : Working Directory는 변화없이 HEAD와 Staging Area만 <commit hash>로 되돌림 git reset --soft <commit hash> : Staging Area, Working Directory는 변화없이 HEAD만 <commit hash>로 되돌림 ▨커밋 되돌리기 (push 후에 사용) git revert <commit hash> : <commit hash>에 해당하는 커밋을 이전 상태로 되돌림 ▨저수준 커맨드 git cat-file -p HEAD : HEAD를 가리키는 스냅샷 확인 git ls-files -s : 현재 Index 확인 ▨압축 git archive -l (압축 가능한 포맷 확인) git archive --format=tar.gz master -o /backup/20230504_backup.tar.gz ▨저장소 위치에 따른 정리 commit: Staging Area > Local Repository push: Local Repository > Remote Repository pull: Remote Repository > Local Repository clone: Remote Repository > Local Repository (최초 가져오기에 사용) fork: Remote Repository > Remote Repository ■Local Repository→Remote Repository 레포지터리 최초 업로드 cd <Working Directory> git init git remote add origin "https://git:git@10.10.10.111/sample_repo.git" git add -A git commit -m "initial commit" git push ■Remote Repository→Local Repository 최초 다운로드 git clone "https://git:git@10.10.10.111/sample_repo.git" "D:\src\test" git add . git commit git push ■Remote Repository→Local Repository 변경사항 반영 git fetch origin master git pull origin master ■git 개념 Working Directory (.git이 위치한 디렉토리) git Server |-----------------------------------------------------------------------------||------------------------| commit -a +--------------------------------------------------------+ | add commit | push | +-------------------+ +---------------+ | +----------------+ | | | | | | | | | | v | v v | v +-------------------+ +-------------------+ +-------------------+ +-------------------+ | | | | | Local | | Remote | | Working Directory |<---------| Staging Area | | Repository | | Repository | | | checkout | (.git directory) | | (.git directory) | | | +-------------------+ +-------------------+ +-------------------+ +-------------------+ ^ ^ ^ | | ^ | | | | | | | | | | | | +---------------------------------------------+ | +--------------+ | | | checkout HEAD | fetch | | +--------------------------------------------------------+ | | merge | +----------------------------------------------------------------------------------------+ pull = fetch + merge ▨저장소 설명 -Working Directory: 내가 작업하고 있는 프로젝트의 디렉토리 -Staging Area(.git): commit을 하기 위해 git add 명령어로 추가한 파일들이 모여있는 공간. 스테이징 영역(Staging area)란 commit이 가능한 영역으로, commit하기 전 파일을 담아두는 상자라고 볼 수 있다. git add 명령어를 통해 수정된 파일을 스테이징 영역에 담을 수 있다. 즉, 스테이징 영역은 commit하기 위한 파일들을 담는 박스이고, commit 하는 것은 박스에 담긴 파일들을 간단한 코멘트를 남겨 라벨링을 해주는 것이다. 만약, git add 명령어를 통해 파일을 Staging area에 추가한 상태에서 또 파일을 수정한다면, 해당 파일은 스테이징 영역에 존재하면서, 수정(modified)된 상태가 된다. 따라서, git status로 확인하면 스테이징 영역과 modified 영역에 둘 다 표시하게 된다. 이 상태에서 git commit을 하게 된다면, 스테이징 영역에 있는 파일만 commit이 되고, 이후 수정된 내용은 commit이 되지 않는다. 따라서 git add 명령어를 실행한 후 다시 파일을 수정한다면 git add 명령어를 다시 실행하여 파일의 최신 상태가 스테이징 영역에 존재하도록 해야 한다. 만약, git add 명령어를 실행한 후 다시 파일을 수정하였지만, 수정한 파일을 폐기하고 싶다면, git restore 명령어를 통해 폐기가 가능하다. git restore 명령어를 실행하였을 경우, git add 된 파일은 폐기되지 않고, git add 명령어 사용한 이후에 수정된 부분만 폐기된다. -Local Repository(.git): git commit 시 .git\objects\에 이력이 추가되며, 파일과 메타데이터도 저장된다. ▨git의 3가지 상태 ◆Modified ◆Staged ◆Committed +----------------+ +----------------+ +----------------+ | | | | | | | Working | | Staging Area | | Local | | Directory | | | | Repository | | | | | | (.git) | +----------------+ +----------------+ +----------------+ | | | |<----------------------------------------| | checkout the project | |------------------->| | | stage fixes |------------------->| | | commit | -Modified : 수정한 파일을 로컬 데이터베이스에 commit하지 않은 상태 *Working Directory 영역에 있는 파일들 중 수정을 한 파일들의 상태를 의미 -Staged : 수정한 파일들 중 commit 할 것이라고 표시한 상태 *Staging Area 영역에 있는 파일들의 상태 -Commited : Staged 상태의 파일들이 로컬 데이터베이스에 안전하게 저장되었다는 의미 *commit 된 대상 파일은 Working Directory 영역으로 돌아가게 되고 대상 파일의 버전을 관리하는 파일들은 .git에 저장된 상태 *Commited 상태 대상 파일을 수정하게 되면 Modified 상태 ▨git 파일의 LifeCycle 관점에서 본 4가지 상태 +----------------+ +----------------+ +----------------+ +----------------+ | Untracked | | Unmodified | | Modified | | Staged | +----------------+ +----------------+ +----------------+ +----------------+ | | | | |------------------->| | | | Add the file | | | | |----------------->| | | | Edit the file |------------------->| | | | Stage the file | |<-------------------| | | | Remove the file | | | | |<------------------------------------- | | | | Commit | -Untracked : Working Directory에 존재는 하지만 git이 관리를 하지 않는 파일들의 상태 *Working Directory에 새롭게 만들어진 파일들이 이에 해당 -Unmodified : 신규로 파일이 추가되었을 때, new file 상태와 같다. (git add 상태) -Modified : 파일이 추가된 이후 해당 파일이 수정되었을 때의 상태 -Staged : Staging Area에 반영된 상태 ■git 용어 origin: remote(원격 저장소)의 디폴트 이름 (저장소 이름을 origin으로 하면 저장소명 생략가능) master: 기본 branch. branch: Remote Repository의 현재 상태를 복사하여 master branch와 별개의 작업을 진행할 수 있는 공간 head: 현재 작업중인 branch의 최근 commit된 위치 index: Staging Area를 의미 merge: 다른 branch의 내용을 현재 branch로 가져와 합치는 작업 fetch: 원격저장소에 있는 변경사항들을 로컬저장소에 가져오기 전에 변경내용을 확인하고 싶은경우에 사용 (내용을 가져오지 않고 변경한 내역들만 확인) pull: 원격저장소에 있는 변경사항들을 로컬저장소로 가져와 합치는 명령 push: 원격저장소에 코드 변경분을 업로드 checkout: branch 간 전환 또는 현재 작업 중인 파일들을 복원 HEAD: HEAD란 가장 최근에 checkout된 branch의 마지막 commit을 가리키는 포인터. blob 개체 : git 내부적으로 사용되는 파일 개념 tree 개체 : git 내부적으로 사용되는 디렉토리 개념 ■git 기본 환경 설정 git config --global user.name "git_user" git config --global user.email "gituser@gituser.com" git config --global core.autocrlf false git config --global core.editor "'C:/PortableApps/Notepad++Portable/Notepad++Portable.exe' -multiInst -nosession" git config --global core.pager "" git config --global core.protectNTFS false git config --global http.sslVerify false git config --global i18n.commitencoding "UTF-8" git config --global i18n.logoutputencoding "UTF-8" git config --global push.default current git config --global --add diff.guitool kdiff3 git config --global --add difftool.kdiff3.cmd """"C:\PortableApps\GitExtensions_Portable\_3RD_PARTY_APPS\KDiff3\bin\diff3.exe""" """$LOCAL""" """$REMOTE"""" git config --global --add difftool.kdiff3.path "C:\PortableApps\GitExtensions_Portable\_3RD_PARTY_APPS\KDiff3\bin\diff3.exe" git config --global --add difftool.kdiff3.trustExitCode false git config --global --add merge.tool kdiff3 git config --global --add merge.tool.kdiff3.cmd """"C:\PortableApps\GitExtensions_Portable\_3RD_PARTY_APPS\KDiff3\bin\diff3.exe""" """$BASE""" """$LOCAL""" """$REMOTE""" -o """$MERGED"""" git config --global --add merge.tool.kdiff3.path "C:\PortableApps\GitExtensions_Portable\_3RD_PARTY_APPS\KDiff3\bin\diff3.exe" git config --global --add mergetool.kdiff3.trustExitCode false git init git remote add origin "https://git:git@10.10.10.111/sample_repo.git" #git remote remove origin ※global config 파일 위치: ~/.gitconfig ※local config 파일 위치: .git/config ■branch 개념 branch(branch)란 독립적으로 어떤 작업을 진행하기 위한 개념으로 필요에 의해 만들어지는 각각의 branch는 다른 branch의 영향을 받지 않고 영향을 주지도 않기 때문에 여러 작업을 동시에 실행할 수 있다. 현재 작업중인 branch는 HEAD-> 가 가르키는 branch 이다. -master branch란? 저장소 생성 시 자동으로 생성되는 디폴트 branch +-----------+ | 버그 픽스 | +------>| branch +------+ | +-----------+ | +----+---+ | | Master | v | branch +------------------>Merge------->Merge------->Merge--> +----+---+ ^ ^ | +-----------+ | | +------>| 기능 추가 +------------------+ | | | branch | | | +-----------+ | | | | +------------+ | | | 기능 변경 | | +-------------->| branch +----------------------+ +------------+ -branch 만들기: git branch <branch 이름> -작업하고 싶은 branch로 이동하기: git branch <branch 이름> -branch생성과 이동을 동시에 하기: git checkout -b <branch 이름> -branch 삭제하기: git branch -d <branch 이름> ※일반적으로 branch를 삭제를 하는 경우는 master branch와 test branch에서 작업한 것을 병합 한 후 삭제한다. ※test branch를 삭제하고 싶으면 현재 가리키고 있는 branch가 test이면 안된다. ■HEAD와 branch 개념 (출처: https://charles098.tistory.com/24) HEAD와 branch는 상태를 가리키는 포인터로 HEAD는 branch를 통해 commit을 가리키는 포인터. 아래는 commit과 checkout 과정에서 branch와 HEAD의 이동을 보여준다. +------+ | HEAD | +---+--+ | v +------+ | test | +---+--+ | v +-----+ +-----+ +-----+ | +------->| +------->| | +-----+ +-----+ +-----+ 첫번째 commit 두번째 commit 세번째 commit => commit을 하면 HEAD가 가리키는 branch가 최신 commit으로 이동 +------+ | HEAD | +---+--+ | v +------+ +------+ |master| | test | +-----++ ++-----+ | | v v +-----+ +-----+ +-----+ | +------->| +------->| | +-----+ +-----+ +-----+ 첫번째 commit 두번째 commit 세번째 commit => test branch를 만들면 위 그림처럼 HEAD가 가리키던 commit을 test branch가 가리키게 된다. +------+ | HEAD | +---+--+ | v +------+ +------+ |master| | test | +-----++ ++-----+ | | v v +-----+ +-----+ +-----+ | +------->| +------->| | +-----+ +-----+ +-----+ 첫번째 commit 두번째 commit 세번째 commit => git chkeckout test로 branch를 변경하면 HEAD는 test를 가리킨다. +------+ | HEAD | +---+--+ | v +------+ +------+ |master| | test | +---+--+ +---+--+ | | v v +-----+ +-----+ +-----+ +-----+ +-----+ | +------->| +------->| +------->| +------->| + +-----+ +-----+ +-----+ +-----+ +-----+ 첫번째 commit 두번째 commit 세번째 commit 네번째 commit 다섯번째 commit => commit을 두번 더 진행했을 경우 HEAD는 현재 branch인 test를 따라 움직인다. +------+ | HEAD | +---+--+ | v +------+ +------+ |master| | test | +---+--+ +---+--+ | | v v +-----+ +-----+ +-----+ +-----+ +-----+ | +------->| +------->| +------->| +------->| + +-----+ +-----+ +-----+ +-----+ +-----+ 첫번째 commit 두번째 commit 세번째 commit 네번째 commit 다섯번째 commit => git chkeckout master로 branch를 변경하면 HEAD는 다시 master를 가리킨다. +------+ | HEAD | +---+--+ | v +------+ |master| +---+--+ | v +-----+ +------+ | #1 +--------------------->| #2 | +--+--+ +------+ ^ | +------+ | | test | | +---+--+ | | | v +-----+ +-----+ +--+--+ +-----+ +-----+ | +------->| +------->| +------->| +------->| + +-----+ +-----+ +-----+ +-----+ +-----+ 첫번째 commit 두번째 commit 세번째 commit 네번째 commit 다섯번째 commit => commit을 두번 더 했을 경우 코드의 흐름이 두 갈래로 나뉘어 지며, 이를 "분기한다"라고 한다. +------+ | HEAD | +---+--+ | v +------+ |master| +---+--+ | v +-----+ +-----+ +------+ | #1 +------->| #2 |------>|merge |<--+ +--+--+ +-----+ +------+ | ^ | | +------+ | | | test | | | +---+--+ | | | | | v | +-----+ +-----+ +--+--+ +-----+ +-----+ | | +------->| +------->| +------->| +------->| +---+ +-----+ +-----+ +-----+ +-----+ +-----+ 첫번째 commit 두번째 commit 세번째 commit 네번째 commit 다섯번째 commit => git merge test를 하면 HEAD가 가리키던 commit에 test branch가 가리키던 commit을 합쳐 새로운 commit을 만든다.