Git 사용하기

Git에 대한 기본 사용법부터 활용방법까지 정리해 봤습니다.
Let’s go!! :rocket:

시작하기

설치 및 설정

info
Mac은 Terminal에서 git을 실행하는 것으로 설치가 시작됨

  • 버전 확인하기
    $ git --version
    
  • 설정 범위 지정하기
    # 모든 사용자와 모든 저장소에 적용 (/etc/gitconfig 파일)
    $ git config --system
    # 현재 사용자의 모든 저장소에 적용 (~/.gitconfig, ~/config/git/config 파일)
    $ git config --global
    # 특정 저장소에 적용 (.git/config 파일)
    $ git config --local
    
  • 사용자 정보 설정
    # 이름
    $ git config --global user.name "User Name"
    # 이메일
    $ git config --global user.email "User Email"
    
  • 텍스트 편집기 변경
    $ git config --global core.editor <editor name or path>
    # Sublime Text를 편집기로 사용 예시 
    $ git config --global core.editor "/Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl -w"
    # Visual Studio Code를 편집기로 사용 예시
    $ git config --global core.editor "/Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code --wait"
    
  • 설정 확인
    # 전체 확인
    $ git config --list
    # 설정 범위에 대해서 확인하기 (--local, --global 등)
    $ git config --local --list
    # 특정 key에 대한 확인
    $ git config <key>
    # 사용자 이름확인 예시
    $ git config user.name
    
  • 명령어 Alias
    # git commit → git ci
    $ git config --global alias.ci commit
    # 마지막 히스토리 보는 명령어 → git last
    $ git config --global alias.last 'log -1 HEAD'
    # 히스토리 보는 명령어 → git lg (포멧은 보기 편한대로 수정)
    $ git config --global alias.lg "log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold red)%h%C(reset) : %C(bold green)(%ar)%C(reset) - %C(cyan)<%an>%C(reset)%C(bold yellow)%d%C(reset)%n%n%w(90,1,2)%C(white)%B%C(reset)%n'"
    
  • 도움말 보기
    # 상세 도움말
    $ git help <verb>
    # 간략한 명령어에 대한 도움말
    $ git <command> -h
    

사용법

기초

  • 저장소 만들기
    $ git init
    
  • 저장소 복제 (소스 받기)
    # 원격 저장소에서 복제 (묵시적으로 origin 이라는 원격 저장소가 추가됨)
    $ git clone <remote git url>
    # origin이 아닌 다른 이름으로 원격 저장소를 추가하는 경우
    $ git clone -o <remote name> <remote git url>
    
  • 파일 상태 확인하기
    # 상태 확인
    $ git status
    # 간략하게 보기
    $ git status -s
    
  • 파일을 새로 추적하기
    • 파일 추가보다는 다음 커밋에 추가 한다고 의미가 있음
      # 파일 새로 추적하기 (디렉토리 추가 시 하위 모든 파일들이 추가됨)
      $ git add <file or directory>
      # 모든 변경사항 추적하기
      $ git add .
      
  • 파일 무시하기
    # .gitignore 파일 내용 확인 (무시한 파일 추가필요)
    $ cat .gitignore 
    
  • Staged와 Unstaged 상태의 변경 내용 보기
    # Unstaged 상태의 파일 비교
    $ git diff
    # Staging Area에 있는 파일 비교 (--cached 도 같은 옵션)
    $ git diff --staged 
    
  • 변경사항 커밋하기
    # 커밋 요청하기
    $ git commit
    # 커밋 메시지 편집기에 diff 메시지가 추가됨
    $ git commit -v 
    # 커밋 메시지를 입력하고 바로 커밋하기
    $ git commit -m "commit message" 
    # 변경된 파일을 자동으로 Staging Area로 파일을 올리고 바로 커밋하기
    $ git commit -a -m "add 생략하고 commit하기" 
    # 소스 수정없이 커밋만 할 수 있음 (--allow-empty-message 옵션도 있음)
    $ git commit --allow-empty 
    
  • 파일 삭제
    # 실제 파일이 삭제되고, Staged 상태로 변경
    $ git rm <file>
    # 강제 삭제 
    $ git rm -f 
    # 실제 파일은 삭제하지 않을 때
    $ git rm --cached <file> 
    # log 디렉토리 아래에 있는 .log 파일 삭제 예시
    $ git rm log/\*log 
    # ~로 끝나는 파일 모두 삭제 예시
    $ git rm \*~ 
    
  • 파일 이름 변경하기
    $ git mv <currnet> <new>
    
  • 되돌리기
    # 커밋 이후, 간단한 수정이 있는 경우 기존 커밋을 덮어씀 (커밋 메시지 수정에도 사용)
    $ git commit --amend
    # 파일 상태를 Unstage로 변경
    $ git reset HEAD <file>
    # 수정한 파일은 커밋된 버전으로 되돌릴 때 사용
    $ git checkout -- <file>
    

파일 라이프 사이클

  • 라이프 사이클

파일 무시하기 (.gitignore)

# 확장자가 .a인 파일 무시
*.a

# 윗 라인에서 확장자가 .a인 파일은 무시하게 했지만 lib.a는 무시하지 않음
!lib.a

# 현재 디렉토리에 있는 TODO파일은 무시하고 subdir/TODO처럼 하위디렉토리에 있는 파일은 무시하지 않음
/TODO

# build/ 디렉토리에 있는 모든 파일은 무시
build/

# doc/notes.txt 파일은 무시하고 doc/server/arch.txt 파일은 무시하지 않음
doc/*.txt

# doc 디렉토리 아래의 모든 .pdf 파일을 무시
doc/**/*.pdf

히스토리 (Log)

  • 히스토리 조회하기
    $ git log
    
  • diff 와 같이 조회하기
    # 각 커밋의 diff 결과를 보여주고 최근 2개의 결과만 보는 옵션
    $ git log -p -2 
    
  • 파일 로그 보기
    $ git log -p -- <file-path>
    
  • 통계 같이 보기
    $ git log --stat
    
  • 다른 형식으로 보여주기
    $ git log --pretty=oneline # short, full, fuller 같은 옵션도 있음
    
  • 그래프 옵션
    $ git log --pretty=format:"%h %s" --graph # format에서 %h은 짧은 해시, %s 요약
    
  • 커밋이 가리키는 브랜치 같이 보기
    # --decorate 옵션 사용
    $ git log --oneline --decorate --graph --all 
    
  • 제한 조건
    # 지난 2주동안 로그 보기 ("2020-01-15"와 같이 날짜 지정도 가능)
    $ git log --since=2.weeks 
    # 저자를 지정해서 검색
    $ git log --author
    # 커밋 메시지 키워드 검색 (--all-mathch 도 같이 사용하는게 좋음)
    $ git log --grep <keyword>
    # 코드에서 특정 텍스트가 포함되었는지 검색
    $ git log -S <function_name>
    # 머지 커밋 표시하지 않기
    $ git log --no-merges 
    
  • 리비전 조회하기
    # 브랜치1에는 없지만, 브랜치2에는 있는 커밋 (..는 범위를 표한하는 문법)
    $ git log <branch1>..<branch2>
    # 브랜치1과 브랜치2에는 있지만, 브랜치3에는 없는 커밋 (^ 문자 대신 --not 도 동일함)
    $ git log <branch1> <branch2> ^<branch3>
    # 서로 다른 커밋 (--left-right 옵션은 어느쪽에 속한 커밋인지 보여줌)
    $ git log --left-right <branch1>...<branch2>
    

원격 저장소 (Remote)

  • 원격 저장소 확인
    $ git remote
    # 단축 이름과 URL 함께 보기
    $ git remote -v
    
  • 원격 저장소 살펴보기
    $ git remote show <remote name>
    
  • 원격 저장소 추가
    $ git remote add <remote name> <remote git url>
    
  • 원격 저장소 이름 변경
    $ git remote rename <current name> <new name>
    
  • 원격 저장소 삭제
    $ git remote remove <remote name> # git remote rm 도 동일
    
  • 원격 저장소 데이터 가져오기
    $ git fetch <remote>
    # 전체 가져오기
    $ git fetch --all
    
  • 원격 저장소 데이터 가져오고, 로컬 브랜치에 Merge하기
    $ git pull <remote>
    
  • 원격 저장소 데이터 올리기
    $ git push <remote> <branch>
    # 로컬과 동일한 브랜치명의 원격 저장소에 데이터 올리기
    $ git push <remote> HEAD 
    # 로컬과 원격의 브랜치명이 다른 경우에 사용
    $ git push <remote> <local branch name:remote branch name> 
    
  • 강제로 데이터 변경하기
    # 로컬 → 원격으로 강제 데이터 변경
    $ git push -f <remote> <branch>
    # 원격 → 로컬로 강제 데이터 변경
    $ git reset --hard <remote/branch>
    
  • 원격 저장소 브랜치 포인터 확인
    $ git ls-remote <remote name>
    

태그 (Tag)

  • 태그 확인
    $ git tag
    # *를 사용하여 태그 목록을 검색할 때는 -l 옵션을 붙임
    $ git tag -l "v1.2.3*"
    # 태그 정보와 커밋 정보를 모두 확인
    $ git show <tag name>
    
  • 태그 추가
    # Annotated 태그 생성
    $ git tag -a <tag name> -m "<tag message>"
    # Lightweight 태그 생성 (별도의 태그 정보가 없음)
    $ git tag <tag name>
    
  • 나중에 태그 추가
    $ git tag -a <tag name> <checksum>
    
  • 태그 공유
    $ git push <remote> <tag name>
    # 여러 개의 태그를 한 번에 공유
    $ git push <remote> --tags
    
  • 태그 체크아웃 하기
    # 브랜치를 체크아웃한 것과 다르며, "detached HEAD"(떨어져나온 HEAD) 상태가 됨
    $ git checkout <tag name>
    # 태그에서 새로 브랜치 생성하기
    $ git checkout -b <branch name> <tag name>
    
  • 태그 삭제
    $ git tag -d <tag name>
    # 원격 저장소의 태그 삭제
    $ git push origin :<tag name>
    

브랜치 (Branch)

  • 브랜치 목록보기
    # 브랜치 목록 (* 기호가 붙어 있는 것이 현재 브랜치)
    $ git branch
    # 브랜치 목록 및 마지막 커밋 메시지
    $ git branch -v
    # 현재 브랜치 기준으로 Merged가 된 브랜치 목록 (뒤에 브랜치 이름을 적으면 해당 브랜치 기준으로 알려줌)
    $ git branch --merged 
    # 현재 브랜치 기준으로 Merged가 안된 브랜치 목록
    $ git branch --no-merged 
    
  • 새 브랜치 생성하기
    # 브랜치를 생성 (현재 작업하고 있는 마지막 커밋을 가르키게 되고, 생성 브랜치로 전환하지 않음)
    $ git branch <name>
    # 새로 브랜치를 만들고, 전환까지 한 번에 진행
    $ git checkout -b <branch name>
    
  • 브랜치 합치기(Merge)
    # 현재 브랜치에 해당 branch 내용을 합침
    $ git merge <branch>
    # 합칠 때 Merge Commit을 추가함 (fast-forward merge가 가능해도 하지않음)
    $ git merge --no-ff <branch>
    
  • 브랜치 합치기 충돌해결 순서 (Merge Conflict)
    $ git status # 충돌이 발생한 경우 Unmerged 상태로 표시됨
    $ git mergetool # Merge 도구로 충돌을 해결 하거나, 직접 수정할 수 있음
    $ git add # mergetool 은 자동으로 수행됨
    $ git commit # 충돌 해결 및 Merge 커밋 생성
    
  • 브랜치 이름변경
    $ git branch -m <current name> <new name>
    
  • 브랜치 삭제
    $ git branch -d <branch>
    # Merge하지 않은 브랜치를 강제 삭제하는 경우
    $ git branch -D <branch>
    # 원격 저장소의 브랜치 삭제
    $ git push <remote> --delete <branch> 
    
  • 브랜치 전환 및 추적
    # 브랜치 전환 (로컬에 해당 브랜치가 없고, 원격에 동일한 이름으로 한 개의 브랜치만 존재하는 경우 자동 생성)
    $ git checkout <branch>
    # 원격 브랜치와 연결고리가 있는 트래킹 브랜치 생성 (git pull 시에 자동으로 Merge 됨)
    $ git checkout -b <branch> <remote>/<branch>
    # 원격 브랜치와 동일한 이름으로 트래킹 브랜치 생성 (--track 도 동일한 옵션)
    $ git checkout -t <remote>/<branch>
    # 현재 브랜치가 특정 원격 브랜치를 추적하도록 설정 (--set-upstream-to 도 동일한 옵션)
    $ git branch -u <remote>/<branch>
    
  • 브랜치 추적 확인
    # 로컬 브랜치가 추적하는 원격 브랜치도 같이 보여줌 (git fetch --all 이후에 확인하면 좋음)
    $ git branch -vv 
    
  • 브랜치 Rebase 하기
    # 현재 브랜치를 base 브랜치의 커밋을 가리키게 하고, 변경사항을 차례대로 적용함
    $ git rebase <base branch>
    # topic 브랜치로 전환하지 않고, base 브랜치로 rebase 처리함
    $ git rebase <base branch> <topic branch> 
    
  • 브랜치 Rebase 활용
    # topic 브랜치에서 갈라져 나온 topic-sub 브랜치에서 base 브랜치로 rebase 처리
    $ git rebase --onto <base branch> <topic branch> <topic-sub branch>
    # 원격 저장소의 데이터를 받을 때, 자동으로 Rebase 처리 (git config --global pull.rebase true 로 설정 가능)
    $ git pull --rebase
    
  • 브랜치 Cherry-pick 하기
    # 현재 브랜치에 커밋 하나만 Rebase 하는 동작
    $ git cherry-pick <commit checksum>
    # 커밋 A 다음부터 커밋 B 까지 Cherry-pick
    $ git cherry-pick <commit A>..<commit B>
    # 커밋 A 부터 커밋 B 까지 Cherry-pick
    $ git cherry-pick <commit A>^..<commit B> 
    

fast-forward merge

Merge 되는 브랜치의 커밋이 현재 브랜치에 기반한 경우, Merge 과정 없이 최신 커밋으로 이동함

$ git checkout master

fast-forward-1

$ git merge hotfix

fast-forward-2

3-way merge

fast-forward merge 가 아닌 경우
별도의 커밋(Merge Commit)을 만들고, 해당 브랜치가 그 커밋으로 이동

$ git checkout master

3-way-1

$ git merge iss53

3-way-2

rebase

Rebase를 하든지, Merge를 하든지 최종 결과물은 같고 커밋 히스토리만 다름
Rebase 의 경우는 브랜치의 변경사항을 순서대로 다른 브랜치에 적용하면서 합침

$ git checkout experiment

rebase-1

$ git rebase master

rebase-2

$ git checkout master
$ git merge experiment

rebase-3

rebase 활용

$ git checkout client

interesting-rebase-1

$ git rebase --onto master server client

interesting-rebase-2

$ git checkout master
$ git merge client

interesting-rebase-3

cherry-pick

변경사항을 적용하는 시점이 다르므로, 커밋의 checksum 이 달라짐

$ git checkout master

cherry-pick-1

$ git cherry-pick e43a6

cherry-pick-2

숨겨두기 (Stashing)

  • 워킹 디렉토리에서 수정한 파일들을 저장
    $ git stash # git stash save 도 동일
    
  • 저장한 stash 목록
    $ git stash list
    
  • stash 적용하기
    # 가장 최근에 stash 한 항목을 적용
    $ git stash apply
    # 특정 stash를 골라서 적용하기
    $ git stash apply stash@{1}
    # 수정한 파일이 Staged 영역에 있었으면, 해당 상태로 다시 적용해 줌
    $ git stash apply --index
    
  • stash 삭제
    # 특정 stash를 삭제
    $ git stash drop stash@{1}
    # stash를 적용하고, 바로 삭제
    $ git stash pop
    
  • stash 저장 옵션
    # Staged 영역에 있는 파일은 stash로 저장하지 않는 방법
    $ git stash --keep-index
    # stash는 기본적으로 트래킹 파일만 저장하는데, 추적 중이지 않은 파일도 같이 저장하는 방법
    $ git stash -u # --include-untracked 와 동일
    
  • stash 적용한 브랜치 만들기
    # stash 당시의 커밋을 체크아웃 한 후, 새로운 브랜치를 만들고 stash를 반영함 (성공 시 stash 삭제됨)
    $ git stash branch <name> 
    

청소하기 (Cleaning)

  • 워킹 디렉토리 청소하기
# 추적하고 있지 않은 모든 파일 삭제
$ git clean -d

# 아래 처럼 메시지 발생 시, -f 옵션으로 실행
## fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given; refusing to clean
$ git clean -d -f
  • 미리 확인하기
    # -n 옵션은 실행 시 어떤 파일이 지워질지 알려줌
    $ git clean -d -n
    
  • .gitignore 파일까지 지우기
    # clean은 기본적으로 무시하는 파일은 지우지 않지만, -x 옵션으로 같이 지움
    $ git clean -d -x
    

되돌리기 (Reset)

워크플로

  • Git 에서 관리하는 세 가지 트리
    • HEAD : 마지막 커밋 스냅샷, 다음 커밋의 부모 커밋
    • Index : 다음에 커밋할 스냅샷
    • Working Directory : 샌드박스

reset-workflow

1단계 : HEAD 이동

  • 선행 조건
    • file.txt 파일의 수정 커밋을 3번 반복하고, HEAD가 38eb946 에 있는 상황
  • git reset –soft HEAD~ 명령 시에 여기까지만 진행됨
    • HEAD~ 는 HEAD의 이전 커밋을 가리킴
  • 이 상태에서 git commit 을 하면, git commit –amend 와 동일해 짐

reset-soft

2단계 : Index 업데이트

  • git reset –mixed HEAD~ (또는 git reset HEAD~) 명령 시에 여기까지 진행됨
  • Staging Area 의 내용을 비우게 됨 (Unstaged 상태로 파일 상태 변경)

reset-mixed

3단계 : Working Directory 업데이트

  • git reset –hard HEAD~ 명령 시에 여기까지 진행됨
  • 데이터를 실제로 삭제하는 동작이므로 주의가 필요

reset-hard

경로를 주고 Reset 하기

  • 1단계는 건너뛰고, 정해진 경로의 파일에만 나머지 reset 단계를 적용
  • git add 와 정확히 반대되는 동작
  • git reset file.txt (또는 git reset –mixed HEAD file.txt)

reset-path

Merge 커밋 Reset 하기

# 방금 병합(merge) 커밋을 되돌릴 때 사용함 (merge 후, 시간이 지난 경우 revert 를 사용함)
$ git reset --merge <checksum> # merge 전의 checksum 커밋으로 Reset

되돌리기 (Revert)

  • Revert는 이전 히스토리는 유지하고, 특정 커밋을 되돌리는 커밋을 생성
    # 특정 checksum 커밋을 Revert 처리
    $ git revert <checksum> 
    
  • 여러 commit 을 한꺼번에 되돌리기
    # 커밋 A 다음부터 커밋 B 까지 Revert
    $ git revert <commit A>..<commit B>
    # 커밋 A 부터 커밋 B 까지 Revert
    $ git revert <commit A>^..<commit B>
    

Merge 커밋 Revert 하기

# Git 히스토리
$ git log --oneline --graph

*   6babfa4 Merge branch 'dev'
|\
| * fc3a989 hello git
* | 15a1193 hello world
|/
* a0653bc hello
 
# Case 1. 15a1193 커밋으로 Revert (-m 옵션은 --mainline 과 동일, 병합 커밋 기준 왼쪽부터 1)
$ git revert 6babfa4 -m 1
 
$ git log --oneline --graph

* 5c8e06f Revert "Merge branch 'dev'"
*   6babfa4 Merge branch 'dev'
|\
| * fc3a989 hello git
* | 15a1193 hello world
|/
* a0653bc hello
 
# Case 2. fc3a989 커밋으로 Revert
$ git revert 6babfa4 -m 2
 
$ git log --oneline --graph
* cf2053f Revert "Merge branch 'dev'"
*   6babfa4 Merge branch 'dev'
|\
| * fc3a989 hello git
* | 15a1193 hello world
|/
* a0653bc hello

변경사항

Git 2.23

checkout → switch, restore

  • checkout : Switch branches or restore working tree files
  • switch : Switch branches
  • restore : Restore working tree files
# 브랜치 전환 및 추적
$ git checkout <branch>
$ git switch <branch>
 
$ git checkout -b <branch> <remote>/<branch>
$ git switch -c <branch> <remote>/<branch>
 
# 되돌리기
$ git reset HEAD <file>
$ git restore --staged <file>
 
$ git checkout -- <file>
$ git restore <file>

활용 팁

커밋 수정하기

마지막 커밋 수정하기

  • 커밋 메시지 수정
    # 잘못된 메시지의 마지막 커밋
    $ git commit -m "wrong message"
    # 편집기를 열어주고, 커밋 메시지만 수정하면 됨
    $ git commit --amend 
    
  • 커밋에 간단한 수정사항 추가하기
# 마지막 커밋 이후, 간단한 수정이 있는 경우
# Staging Area 에 수정 파일을 넣어줌
$ git add <modified or new file>

# 커밋 자체가 수정 되면서, 추가한 수정사항을 밀어넣어줌
# --no-edit 옵션은 커밋 메시지를 수정하지 않을 때, 사용할 수 있음
$ git commit --amend --no-edit 

warning
커밋에 대한 수정(–amend, rebase 등)은 로컬에서 작업 중인 Commit 에 대해서만 진행하도록 한다.
원격 저장소에 Push 한 Commit을 수정하면, 다른 사람에게 영향을 주게된다.

커밋 메시지 여러 개 수정하기

# 수정하고 싶은 3개의 커밋이 쌓여 있는 경우

# 현재 HEAD 위치에서 3개의 커밋 전으로 이동하고, -i 옵션으로 대화형 모드 실행
$ git rebase -i HEAD~3 
 
# 수정을 원하는 커밋의 pick 을 edit 로 수정하고, 편집기 종료 (위에서 아래로 커밋 순서임)
# 예시
/**
 edit 9133fa0 add 1.txt
 pick 35aa819 add 2.txt
 pick f0fdb1a add 3.txt
**/
 
# 커밋 메시지 수정을 원하는 경우
$ git commit --amend
 
# 수정이 끝난 경우 (다음 edit 항목이 있는 경우 이동)
$ git rebase --continue

커밋 순서 바꾸기

# 수정하고 싶은 3개의 커밋이 쌓여 있는 경우
$ git rebase -i HEAD~3
 
# 위의 예시에서 "add 3.txt" 커밋을 삭제하고, 다른 두 커밋 순서를 바꾸는 경우 (위에서 아래로 커밋 순서임)
# 예시
/**
 pick f0fdb1a add 3.txt
 pick 35aa819 add 2.txt
**/
 
# 편집기 종료 시, 적용됨

커밋 합치기

# 합치고 싶은 3개의 커밋이 쌓여 있는 경우
$ git rebase -i HEAD~3
 
# 이전 커밋과 합치고 싶은 커밋의 pick 을 squash 로 수정하고, 편집기 종료 (위에서 아래로 커밋 순서임)
# 예시
/**
 pick 9133fa0 add 1.txt
 squash 35aa819 add 2.txt
 squash f0fdb1a add 3.txt
**/
 
# 커밋 메시지를 Merge 할 수 있는 편집기 에디터가 실행 됨

커밋 분리하기

# 분리하고 싶은 커밋이 쌓여 있는 경우
$ git rebase -i HEAD~2
 
# 분리하고 싶은 커밋의 pick 을 edit 로 수정하고, 편집기 종료 (위에서 아래로 커밋 순서임)
# 예시
/**
 edit 9a9ed12 add 1.txt / add 2.text
 pick f0fdb1a add 3.txt
**/
 
# 커밋 해제
$ git reset HEAD^ # 수정했던 파일이 Unstaged 상태가 됨
 
# 1.txt 파일 Staged 상태로 변경
$ git add 1.txt
 
# 새로운 커밋
$ git commit -m "add 1.txt"
 
# 2.txt 파일 Staged 상태로 변경
$ git add 2.txt
 
# 새로운 커밋
$ git commit -m "add 2.txt"
 
# 수정이 끝난 경우 (다음 edit 항목이 있는 경우 이동)
$ git rebase --continue

모든 커밋 수정하기 (filter-branch)

  • 모든 커밋에서 파일을 제거하기
# 실수로 패스워드 파일을 추가해서, 이런 파일을 삭제해야 하는 경우
# --tree-filter 는 체크아웃 후 각 커밋에 명령을 실행시키고, 다시 커밋함
$ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD  
 
# 백업 파일을 모르고 추가한 경우
# --all 옵션을 주면 모든 브랜치에 적용함
$ git filter-branch --all --tree-filter 'rm -f *~' HEAD 
  • 모든 커밋의 이메일 주소를 수정하기
# 실수로 회사 이메일이 아닌 개인 이메일 주소를 사용한 경우
# --commit-filter 옵션은 해당 커밋만 찾아서 적용함
$ git filter-branch --commit-filter ' 
        if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
        then
                GIT_AUTHOR_NAME="Scott Chacon";
                GIT_AUTHOR_EMAIL="schacon@example.com";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

# 현재 수정 사항으로 원격에 강제 변경하기
$ git push -f <remote> <branch>

# 백업 브랜치(예시 - refs/original/refs/heads/master) 제거 방법
$ git update-ref -d refs/original/refs/heads/master

커밋을 하나로 합쳐서 머지하기

# 머지할 Target 브랜치 체크아웃
$ git checkout <target branch>
 
# 머지 Source 브랜치에는 여러 커밋이 쌓여있는 상황
# 소스 브랜치의 변경사항을 현재 브랜치에 병합함 (Staged 상태)
$ git merge --squash <source branch> 
 
# 커밋 생성 (non-merge 커밋)
$ git commit # 한 개의 커밋으로 모든 변경사항이 머지됨

프로젝트 관리

기존 프로젝트 올리기

# 기존 프로젝트 폴더로 이동
$ cd <existing-project folder>
 
# git 시작하기
$ git init
 
# 모든 파일 Staged 상태로 변경
$ git add --all
 
# 커밋하기
$ git commit -m "<commit message>"
 
# 원격 저장소(origin) 추가하기
$ git remote add origin <remote git url>
 
# 원격 저장소에 데이터 올리기 (-u 옵션으로 브랜치 트래킹)
$ git push -u origin master

기존 Git 원격 저장소 변경

# 기존 프로젝트 폴더로 이동
$ cd <existing-project foler>
 
# 원격 저장소 경로 변경
$ git remote set-url origin <change remote url>
 
# 로컬 브랜치 전체를 원격 저장소에 추가하기 (-u 옵션으로 브랜치 트래킹)
$ git push -u origin --all # 특정 브랜치만 올릴 경우 git push -u origin <branch>
 
# 로컬 태그 정보 전체를 원격 저장소에 추가하기
$ git push origin --tags

원격 저장소 추가

# upstream 이라는 이름으로 원격 저장소 추가
$ git remote add upstream <upstream remote git url>
 
# upstream remote 확인하기
$ git remote -v
 
# upstream 소스 받기
$ git pull upstream

기타

PR(Pull Request) 브랜치 포인터 보기

# origin 의 PR 내용이 보이도록 설정
$ git config --add remote.origin.fetch '+refs/pull-requests/*/from:refs/remotes/origin/pr/*'

특정 브랜치 동시 삭제

# 특정 branch 목록 (feature/v1.1.0 이름이 포함된)
$ git branch | grep "feature/v1.1.0"

# 특정 branch 삭제
$ git branch | grep "feature/v1.1.0" | xargs git branch -D

특정 브랜치 동시 이름 변경

# 특정 branch 이름 변경 미리보기 (v1.1.0 -> v2.0.0)
$ git branch | grep "feature/v1.1.0" | awk '{original=$1; sub("v1.1.0","v2.0.0"); print original, "->" , $1}'

# 특정 branch 이름 변경
$ git branch | grep "feature/v1.1.0" | awk '{original=$1; sub("v1.1.0","v2.0.0"); print original, "->" , $1}' | xargs -n 2 git branch -m

브랜치 모델

참고자료

마지막 수정