git clone [저장소주소] [디렉토리명] : “디렉토리명”으로 저장소 복제git clone --depth 1 [저장소주소] [디렉토리명] : “디렉토리명”으로 저장소를 복제하는데, 히스토리는 복제하지 않는다(빠르다).git clone --branch <branchname/tagname> [저장소주소] : 특정 branch/tag 를 클론한다.git config --list --local # 현재 저장소 설정 git config --list --global # 공통 설정
git add 파일 : 저장소에 추가git commit -m “메시지” : 로컬 커밋git push [origin] : 원격 저장소 origin으로 Pushcommit.template 설정에 있는 파일을 템플릿으로 사용한다.git commit -t <file>/git commit –template=<file> 로 명시적 지정도 된다.# 는 주석이다.git fetch : 원격 저장소 origin에서 받아오기. Merge는 안함.git pull : 원격 저장소 origin에서 최신 데이터를 가져와 Merge까지 하기.git 디렉토리 삭제하기git clone --depth=1 git://someserver/somerepo dirformynewrepo rm -rf !$/.git # !$ 는 직전 명령의 마지막 인자(dirformynewrepo) 를 뜻한다.
git status : 워킹 디렉토리 상태 보기git diff 커밋ID_1 커밋ID_2 [파일명] : 두 커밋로그 사이의 차이점 비교. 파일명을 지정하면 두 커밋간 해당 파일의 차이점 비교git diff HEAD^ [파일명] : 직전 커밋과의 비교git diff HEAD^ HEAD^^ [파일명] : 직전과 그 직전 커밋과의 비교git blame 파일 : 파일을 누가 언제 고쳤는지 보여줌.git diff 브랜치1..브랜치2 : 두 브랜치간의 비교git diff 다른브랜치 -- 파일 : “파일”의 현재 브랜치와 다른 브랜치간의 차이점을 보여준다.git diff --name-status 브랜치1..브랜치2 : 두 브랜치간의 변경된 파일 목록과 상태. --name-only 옵션은 파일 이름만 출력.git diff --stat --color 브랜치1..브랜치2 : 두 브랜치간의 차이를 컬러 차트로 보여줌.git diff --name-only [COMMIT1] [COMMIT2] : 두 커밋간의 변경된 파일 목록git diff --name-only HEAD~10 HEAD~5 : 헤드에서 10번째 커밋과 헤드에서 5번째 커밋간의 변경된 파일 목록git diff --staged : 이미 commit 된 것과 staged 된 파일의 변경 비교git log branchA..branchB : 두 브랜치간의 commit 목록 diff.git log 더적은쪽브랜치..더큰브랜치 : 두 브랜치가 포함관계일 때 더적은쪽을 왼쪽에 둬야했음.git log --oneline --no-merges --no-decorate branchA..BranchB : 두 브랜치간의 commit 목록 diff 인데 머지 커밋은 제외git log --graph --left-right --cherry-pick --oneline 브랜치1...브랜치2 : 브랜치간 빠진 커밋 찾기 diff 와 같은듯. cherry-pick 으로 이 브랜치 저 브랜치 머지하다가 누락된곳 찾기?git log --oneline --no-merges --no-decorate 브랜치1..브랜치2 \
| grep -o "[A-Z]\{6\}-[0-9]\{4\}" | sort | uniq
git show [커밋ID]:/path/to/file : 특정 커밋에서의 파일의 내용을 보여줌git log [파일] : 특정 파일 혹은 워킹 디렉토리에 대한 커밋 로그를 보여줌git log -숫자 : 최근 숫자 갯수만큼의 로그만 보여줌git log --full-history [파일] : 사라진 커밋 히스토리까지 다 보여준다.git log --author="Jon" : 특정 사용자로 커밋 로그 검색git log --grep=“정규표현식” : 정규표현식을 만족하는 커밋 메시지가 있는 로그를 보여줌--all-match : 모든 --grep 옵션을 다 만족시키는 것만 검색.
가끔씩 Commit이 사라지고 git log --full-history [파일] 명령으로 로그를 봐야 커밋 히스토리가 보이는 경우가 발생한다.
이는 브랜치 Merge 시에 다른 사람의 작업(없어진 커밋)과 충돌이 났을 때 IntelliJ로 치면 Accept yours 혹은 Accept theirs 처럼 특정 작업을 모두 무시하는 Merge를 수행했을 때 발생한다.
git checkout [커밋ID] : 특정 커밋 시점으로 모든 소스를 변경한다.git checkout HEAD~1 : 한 단계 전으로 이동git checkout HEAD~10 : 10 단계 전으로 이동git checkout master : 다시 master 브랜치로 원상 복구git rm 파일 : 특정 파일삭제.git mv 파일1 파일2core.ignorecase 참조.$parent_of_flawed_commit에 대해 rebasegit rebase --interactive $parent_of_flawed_commit
pick 을 reword 로 변경하고 저장--interactive == -i# 특정 commit 지정할 경우 git rebase -i -p 원하는커밋바로앞커밋hash ## 바로 앞!!! ## # 특정 갯수 지정할 경우 git rebase -i HEAD~갯수 # Push 안된 모든 커밋을 지정할 경우 git rebase -i $parent_of_flawed_commit # 여기서 나온 편집기 화면에서 고치고자 하는 커밋을 pick 대신 edit로 수정한다. # ------------------------------ # 이제 작성자 변경작업 git commit --amend --author "New Author Name <email@address.com>" git rebase --continue # 이미 push 된 상황이면 --force 로 push 해야만 함. git push --force
git commit --amend --author "New Author Name <email@address.com>"
squash를 사용한다는 점이 다르다.# 특정 갯수를 지정할 경우 git rebase -i HEAD~갯수 # 맨 처음 커밋로그(합쳐진 결과가 될 커밋)을 제외하고 "squash"로 변경하고 저장.
# 변경을 추가하고 git add changelog.md # 마지막 커밋에 넣는다. commit message를 신규로 작성해야 한다. git commit --amend # commit message는 그대로 두고 싶다면 git commit --amend --no-edit
git fetch origin; git reset --hard origin/<BRANCH> : 커밋을 모두 취소하고 origin/<BRANCH> 상태로 변경# 커밋 외의 변경사항이 있을 때 변경 사항들을 stash 해 두어야 한다. git stash git reset --hard origin/master # 올바른 리모트 브랜치로 바꿔줄것 git stash pop
git reset --soft HEAD^ : Local 커밋을 취소하지만 커밋으로 인한 변경사항은 유지한다.git checkout -- [파일] : 아직 스테이지로 안 올라간 파일의 변경 취소git reset --hard HEAD : 커밋 되지 않은 모든 변경사항 취소. 최종 커밋한 상태로 돌아감.git reset HEAD [파일] : 스테이지에 올라간 파일을 스테이지에서 뺌(파일 자체는 변경 상태 유지)git rest HEAD^ : push 전에 마지막 커밋을 취소시키되, 변경을 그대로 유지하게 되돌린다.(파일을 빼먹고 커밋했거나 한 경우)git revert [commit_id …] : 특정 커밋의 변경 사항을 되돌리며, 되돌리는 행위 자체를 하나의 새로운 커밋으로 만든다. 실제 기존 커밋 히스토리가 사라지지는 않는다. 이미 Push된 커밋도 가능.git revert -m [parent] [commit_id] # example git revert -m 1 xxxx
git clean -f : Untracked 파일 모두 삭제git clean -d -f : 디렉토리까지 삭제-x 옵션을 주면 ignore된 파일들까지 모두 삭제# 현재 develop 브랜치일 때 git fetch origin develop git reset --hard origin/develop git clean -d --force
이미 파일이 많은 신규 프로젝트를 Git 리포지토리로 올리는 작업이 필요한 경우. Git – setting up a remote repository and doing an initial push
# 프로젝트 이름과 원격 리포지토리 이름이 my_project 일 때 cd my_project git init # 불필요한 파일들을 모두 정리한 뒤에 git add * # 혹은 git add --all git commit -m '프로젝트 초기 설정' git remote add origin [git_repository]/my_project.git git push -u origin master
git push origin master로 origin master를 명시해줘야 한다.(git 1.8 이상에서는 상관 없는 듯)git remote set-url origin git://new.url.here # origin을 원하는 remote 저장소 이름으로 변경
git branch -vv : 브랜치의 상세 정보 출력. upstream 까지 보여줌git branch --show-current : 현재 브랜치 이름git branch : 브랜치 정보 출력git branch 이름 : 새 브랜치 만들기git checkout 이름 : 예전 방식git checkout -b <branch> --track <remote>/<branch> 명령이 자동 실행된다.(--guess옵션 기본적용)git switch 이름 : 해당 브랜치로 스위치. checkout에서 브랜치 관련된 기능만 수행하는 버전.git switch -c <branch> --track <remote>/<branch> 로 작동한다.(--guess옵션 기본적용)git switch -c 이름 : 브랜치 생성하고 해당 브랜치로 스위치git checkout -b 이름 : 예전 방식git checkout - : 직전 브랜치 체크아웃git branch -d 이름 : 브랜치 삭제, -D는 강제 삭제git branch --merged : 머지가 완료된 브랜치 목록을 보여준다. master를 제외한 머지 완료된 브랜치는 삭제해 버리자.git branch --no-merged : 머지 안된 브랜치 목록을 보여준다.git branch -v : 각 브랜치의 최종 커밋을 보여준다.git branch -a : 전체 브랜치(리모트 포함) 목록git branch -r : 리모트 브랜치 목록git remote prune origin : 정확한 의미 확인 필요. origin 에 브랜치가 없는데 local 에 연결이 있을 경우 이를 끊어주는 역할인듯. 실제로 local branch 를 삭제하는게 아님.아래 명령을 실행하면 master 브랜치의 모든 커밋등이 main으로 넘어간다. git branch -m master main # 올리기 git push -u origin main # HEAD를 main으로 변경 git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main # github/gitlab 등에서 기본 브랜치 변경 # master 브랜치 삭제 git push origin --delete master # 확인 git branch -a
origin은 원격지 이름으로 대체될 수 있다.git switch -t origin/serverfix : 원격 브랜치를 브랜치이름 그대로 생성하며 체크아웃.git checkout --track origin/serverfix : 옛날방식git switch -c [localbranchname] -t origin/[remotebranchname] : 원격 브랜치를 로컬 브랜치를 생성하며 체크아웃한다. 로컬 브랜치 이름을 다르게 가져갈 수 있다.git checkout -b [localbranchname] origin/[remotebranchname] : 옛날방식git push --set-upstream origin [remotebranchname] : 현재 브랜치를 원격 브랜치에 연결하고 푸시한다.git push origin [remotebranchname] : 원격브랜치로 push. 원격브랜치가 없으면 만든다.git push origin [localbranchname]:[remotebranchname] : 특정 로칼 브랜치를 지정하여 원격브랜치로 푸시. 원격 브랜치가 없으면 만든다.git push origin :[remotebranchname] : 원격 브랜치 삭제. 중간의 콜론(:)이 있다는 점에 주의할 것.git clone -b [remotebranchname] [remote_repo 주소] : 원격 브랜치를 바로 clone 한다.git branch --track [localbranchname] origin/[remotebranchname] : 로컬 브랜치와 리모트 브랜치간의 연결git remote add <forkname> <forkgiturl>git fetch <forkname> : 소스 받아오기git merge <forkname>/<branch> : 원본 리포의 특정 브랜치를 내 브랜치에 머지# 현재 상태의 확인 $ git remote -v > origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch) > origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (push) # 원본을 upstream 으로 추가 $ git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git # Remote가 잘 추가 됐는지 확인 $ git remote -v > origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch) > origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (push) > upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (fetch) > upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (push) # upstream 최신화 $ git fetch upstream # 내 리포리토리 master 체크아웃 $ git checkout master # upstream/master 머지 - 끝 $ git merge upstream/master
이미 공개 저장소에 Push 한 커밋을 Rebase 하지 마라
이 지침만 지키면 Rebase를 하는 데 문제 될 게 없다. 하지만, 이 주의사항을 지키지 않으면 사람들에게 욕을 먹을 것이다.
일반적인 해답을 굳이 드리자면 로컬 브랜치에서 작업할 때는 히스토리를 정리하기 위해서 Rebase 할 수도 있지만, 리모트 등 어딘가에 Push로 내보낸 커밋에 대해서는 절대 Rebase 하지 말아야 한다.
git rebase master) 현재 experiment의 커밋들이 가리키는 base 커밋을 마스터의 C10으로 바꾸는 작업이다.git checkout master), experiment를 머지하면(git merge experiment) 머지되는 커밋들이 C5에 대해 머지되지 않고, C10의 뒤로 머지되어 master 입장에서 봤을 때 C10 → C7' → C8'로 깔끔한 순서로 머지가 되는 것이다.git pullgit checkout workingbranchgit rebase mastergit checkout mastergit merge workingbranch--preserve-merges : rebase 시에 머지 커밋을 유지한다.git fetch --tags : remote tag 목록 가져오기git tag -l : 태그의 목록을 보여준다.git tag -a [tagname] [commit] -m “태그 설명” : commit을 지정하지 않으면 현재 커밋.git checkout tags/[tagname] -b [branchname] : 태그이름으로 로컬 브랜치를 체크아웃한다.git checkout [tagname] : 태그 목록의 태그 이름을 이용해 해당 태그를 체크아웃한다.git tag -d [tagname] : 태그 삭제git push --tags : 태그 전체를 리모트로 푸시git push origin [tagname] : 특정 태그를 리모트로 푸시git push origin :[tagname] : 리모트 태그 삭제git push --delete origin [tagname] : 리모트 태그 삭제git describe --tags `git rev-list --tags --max-count=1` : 가장 최근 태그git ls-remote --sort='version:refname' --tags [remoteurl] | tail --line=1 | cut --delimiter='/' --fields=3 원격 저장소에서 clone 받지 않고서 가장 최근 tag 가져오기git merge [내용을 가져올 브랜치명] : 특정 브랜치를 현재 브랜치에 Mergegit merge [내용을 가져올 브랜치명] --squash; #충돌 처리 작업 후 ;git commit : 다른 브랜치로부터 머지를 하되 모든 커밋들을 하나로 뭉쳐서 가져온다. 실제 커밋은 현재 브랜치에서 commit 명령으로 생성한다. How to use git merge squashgit merge -Xignore-space-change [내용을 가져올 브랜치명] : 머지할 때 공백을 무시한다. -Xignore-all-space 도 가능. rebase시에도 동일한 방법으로 사용한다.-Xignore-space-at-eol 참조git merge --abort : 머지 중간 상태일 때 취소git reset --hard HEAD : 머지 중간 상태일 때 취소git stash : 스태시git stash list : 스태시 목록git stash pop : 마지막 스태시 복원하고 목록에서 제거git apply 패치파일.patchgit checkout -- $(git ls-files --modified)
git rm $(git ls-files --deleted)
# 리포지토리 생성 git init --bare newreponame # clone git clone newreponame [clonename]
pull --rebase http://mislav.uniqpath.com/2010/07/git-tips/pull --rebase를 하던가git config --global branch.autosetuprebase always 혹은git config branch.master.rebase true : master 대신 원하는 브랜치명
이미 한 add했던 파일은 ignore해도 적용이 안된다. 캐시돼 있기 때문이라고 한다. 이 때는 다음과 같이 처리한다.
git rm --cached 무시할파일명
# last git config --global alias.last 'log -1 HEAD' git config --global alias.lg \ "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an %ae>%Creset' --abbrev-commit --" git config --global alias.ci commit git config --global alias.co checkout git config --global alias.st status git config --global alias.unstage 'reset HEAD --' # 외부명령 gitk 혹은 gitg git config --global alias.visual '!gitk'
.gitignore : 특정 프로젝트 root 에 두고 해당 프로젝트의 모든 개발자가 공유하는 ignore 목록.gitignore를 직접 편집 못할경우 .git/info/exclude 파일에 추가해주면 본인만 제외 처리할 수 있다.core.excludesfile : 본인 계정에 전역으로 ignoregit config --global core.excludesfile ~/.gitignore-global