Git command

김동현·2022년 11월 11일
0
post-thumbnail

Git Concept

  • working directory: 실제로 프로젝트의 파일을 수정하고 작업하는 영역

    • Untracked : git이 관리하지 않는 파일 영역

    • Tracked : git이 관리하는 파일 영역

      • Modified
        : HEAD가 가리키는 commit 상태에서 변경된 파일 상태

      • Unmodified
        : HEAD가 가리키는 commit 상태에서 변경되지 않은 파일 상태

  • git directory(.git)

    • staging area
      : commit 대기 상태, git add 명령어 실행시 staging area 영역에 파일 상태를 추가, 이후 git commit 명령어 실행시 staging area의 상태를 하나의 commit으로 생성하고 추가

    • local repository
      : 여러 commit들이 연결 리스트 형태로 존재 이를 branch라 하고, 각 commit은 이전 commit의 변경되지 않은 상태는 참조하고, 변경된 상태를 추가적으로 가짐

commit

git은 버전 관리 시스템(Version Control Systme, VCS)으로 commit을 사용하여 버전을 관리합니다.

즉, commit은 "프로젝트의 특정 버전(version)"을 의미합니다. 하나의 commit은 프로젝트의 한 시점의 상태를 나타내는 버전을 의미합니다(commit = version).

각 commit들은 이전 commit을 참조하고 있으며, 변경 사항이 없다면 이전 commit의 내용을 참조합니다.

git checkout 명령어를 통해 commit된 특정 시점으로 이동이 가능합니다.

branch

branch는 여러 commit들이 연결된 하나의 줄기를 의미합니다. 즉, commit들이 연결 리스트 형태로 이어진 하나의 줄기를 branch라고 합니다.

실제로 각 branch는 "언제나 최신 commit"을 가리키는 포인터입니다(branch name === commit hash).

branch는 특정 commit을 가리키므로 commit 대신 사용할 수 있습니다.

"HEAD는 현재 commit"을 가리키며, HEAD가 가리키는 commit이 working directory의 "Tracked 영역에 반영"되어 있습니다.

실제로 HEAD는 특정 branch 또는 특정 commit을 가라킵니다(HEAD === branch name === commit hash).

HEAD는 특정 commit을 가리키므로 commit 대신 사용할 수 있습니다.

  1. HEAD가 가리키는 commit의 상태가 working directory의 Tracked 영역의 Unmodifed에 반영되어 있습니다. 만약 HEAD가 가리키는 commit이 변경되는 경우 변경된 상태가 Tracked 영역의 Modified에 반영됩니다.

  2. commit이 추가 된다면 HEAD가 가리키는 commit을 참조하도록 추가되고, 새롭게 추가된 commit을 HEAD가 가리키게 됩니다.
    HEAD가 가리키는 commit이 변경되었으므로 해당 commit의 상태가 Tracked 영역의 Unmodifed에 반영됩니다.

attached HEAD 상태

"HEAD -> Branch -> 특정 commit"을 가리키는 상태를 의미. HEAD가 특정 branch를 가리키고, 특정 branch는 가장 최근 commit을 가리키는 상태를 말합니다.

아래 그림처럼 HEAD가 master 브랜치를 가리키고 있고, master 브랜치는 최신 commit을 가리키는 상태를 의미.

detached HEAD 상태

"HEAD -> 특정 commit"을 가리키는 상태를 의미합니다.

HEAD가 브랜치를 가리키지 않고 직접적으로 특정 commit을 가리키고 있는 상태이다.

git config : .gitconfig 설정

.gitconfig 파일은 .git폴더 내 존재(.git/.gitconfig)

로컬 영역 내 config 설정만 존재


git config --list : .gitconfig 내용 터미널에 출력

git config -e : .gitconfig 파일 열기

git config --global user.name "name" : 전역적으로 user.name 설정

git config --global user.email "email" : 전역적으로 user.email 설정

git config --global core.autocrlf [input | true] : 전역적으로 commit시 CRLF를 LF로 변경(Mac은 input, window의 경우 true로 설정)

git config --global core.editor "code --wait : 전역적으로 git과 vscode 연동, --wait 옵션으로 열린 파일 닫히기 전까지 명령어 사용 불가

git init : git directory 생성(초기화)

git init : git repository 생성(초기화)(.git 폴더 생성, 프로젝트 루트 경로에서 실행)

rm -rf .git : .git 폴더 삭제(해당 프로젝트를 git이 더이상 관리하지 않음)

git status : 현재 상태 확인

git status : 현재 working directory와 staging area의 상태 출력


  • Changes to be committed
    : staging area에 존재하는 파일, commit 대기 상태이며 추후 git commit 명령어를 실행시 하나의 commit으로 사용됨

  • Changes not staged for commit
    : Tracked 영역의 Modified 영역에 존재하는 파일

  • Untracked files
    : Untracked 영역에 존재하는 파일, git이 관리하지 않는 파일

git add : staging area 추가

git add <file name> : 특정 파일을 staging area로 이동(Untracked, Modified -> staging area)

git add * : .gitignore에 명시된 파일을 포함하여 모든 파일들 staging area로 이동

git add . : .gitignore에 명시된 파일 제외한 모든 파일들 staging area로 이동

git commit : commit 생성 & 추가

git commit :

  1. staging area 상태를 하나의 commit으로 생성

  2. 현재 HEAD가 가리키는 commit을 참조하도록 연결

  3. branch는 언제나 최근 commit을 가리키게 되므로 branch는 새롭게 추가된 commit을 가리킴

git commit --amend : 직전 commit을 취소하고 다시 commit을 수행

commit의 규모 & commit message

commit을 생성할 때 commit의 규모는 기능별로 하며, 의미있는 commit message를 지정해야 합니다.

일반적으로 commit message는 "현재형"과 "동사"를 사용합니다. commit은 commit message에 맞는 변경 사항만을 갖고 있어야 하며, 이외 변경 사항들은 이후 commit으로 생성하도록 해야합니다.

만약 commit message의 템플릿을 갖고 있다면 git config --global commit.message "템플릿 경로"를 통해 템플릿을 설정할 수 있습니다.

git log : commit history 출력

git log : HEAD가 가리키는 commit까지의 모든 commit history 출력(git log HEAD와 동일한 명령어)

git log <hash code> : 특정 commit까지의 모든 commit history 출력

git log <hash code>..<hash code> : 두 commit 사이 모든 commit history 출력

git log <file name> : 특정 파일에 대한 모든 commit history 출력

git log -(n) : HEAD가 가리키는 commit의 commit history부터 n개까지 출력

git log --all : 모든 브랜치의 commit history 출력

git log -p | --patch : commit history와 이전 commit간 변경된 내용도 출력

git log --oneline : commit history 간단하게 출력

git log --graph : commit history 그래프로 출력

git log --author="name" : 작성자가 일치하는 commit history만 출력

git log --before="YYYY-MM-DD" : 지정된 날짜 이전의 commit history 출력

git log --after="YYYY-MM-DD" : 지정된 날짜 이후의 commit history 출력

git log --grep="message" : 특정 문자열이 commit message에 포함된 commit history만 출력

git log -S "code" : 특정 코드가 commit 변경 내용에 포함된 commit history만 출력

git diff : 변경 내용 출력

git diff : HEAD가 가리키는 commit 상태와 현재 Tracked 상태의 변경 내용 출력

git diff --[staged | cached] : HEAD가 가리키는 commit 상태와 staging area 상태의 변경 내용 출력

git diff --[staged | cached] <file name> : staging 상태와 HEAD의 commit 비교 대상을 특정 파일의 변경 사항만을 표시합니다.

git diff HEAD : HEAD가 가리키는 commit 상태와 현재 Tracked 상태, staging area 상태 모두 반영한 변경 내용을 출력합니다(git diff + git diff --[staged | cached]).

git diff HEAD <file name> : Tracked, staging과 HEAD의 commit 비교 대상을 특정 파일의 변경 내용만을 표시합니다.

git diff <hash code>..<hash code> : 두 commit을 비교하여 변경된 사항을 표시합니다.

git diff <hash code>..<hash code> <file name> : 두 commit의 특정 파일에 대한 변경 사항만을 표시합니다.

git rm : 파일 삭제

rm 명령어로 파일 삭제후 git add 명령어를 사용하여 파일이 제거되었다는 사실을 git에게 알려주어야 합니다. 이는 git 명령어 중 git rm 명령어를 사용하여 한 번에 위 과정을 실행하도록 할 수 있습니다(git rm = rm + git add).


git rm <file name> : local repository와 remote repository 모두 특정 파일을 즉시 삭제(현재 staging area에 존재하는 경우 불가능)

git rm -r <directory name> : local repository와 remote repository 모두 특정 폴더 즉시 삭제(현재 staging area에 존재하는 파일을 갖는 폴더의 경우 불가능)

git rm -f <file name> : 현재 staging area에 있더라도 local repository와 remote repository에서 강제 삭제

git mv : 파일명 변경

git이 관리하는 파일명이 변경된 경우에도 파일명이 변경된 이후 git add를 사용하여 git에게 파일명이 변경되었다고 알려주어야 합니다. 이는 파일명 변경과 git add 명령어를 한 번에 수행하는 명령어인 git mv를 제공합니다(git mv = mv + git add).


git mv <old name> <new name> : local repository와 remote repository 모두 변경된 파일명 적용

git show : 특정 commit history 출력

git show <hashcode> : 특정 commit history에 대한 내용이전 commit과의 변경 사항(소스코드 변경 사항)을 출력

git show <hashcode>:<filename> : 특정 commit과 이전 commit간 특정 파일에 대한 변경 사항(소스코드 변경 사항) 출력

git tag : commit에 별칭 부여

tag는 특정 commit에 별칭을 부여하는 기능이며, 실제로 특정 commit을 가리키는 포인터입니다. 일반적으로 버전 정보(v0.0.0)를 tag로 작성합니다.

즉, Tag는 commit의 id(해시코드) 대신 사용할 수 있습니다.


git tag : 만들어진 모든 태그 출력

git tag -l "pattern" : 특정 문자열을 포함하는 태그 출력, *은 모든 문자열을 의미합니다.

  • git tag -l "*beta*" : beta라는 문자열을 포함하는 모든 태그 출력

  • git tag -l "v16*" : v16으로 시작하는 모든 태그 출력

  • git tag -l "*0.1" : 0.1로 끝나는 모든 태그 출력

git tag <tag name> : 현재 HEAD가 가리키는 commit에 tag name 설정

git tag <tag name> <hash code> : 특정 commit에 tagname 설정

git tag -a <tag name> : 현재 HEAD가 가리키는 commit에 주석(annotation) tag name 설정, 주석 태그의 경우 일반 태그처럼 태그 이름 외 추가적인 태그에 대한 설명을 작성할 수 있습니다.

git tag -d <tag name> : 특정 tagname 삭제


태그에 대한 정보는 push 되지 않습니다. 즉, 수동적으로 태그에 대한 정보를 remote repository에 push 해주어야 합니다.

git push <remote namea> <tag name> : remote repository에 특정 tag에 대한 정보를 push 합니다.

git push <remote name> --tags : remote repository에 모든 tag에 대한 정보를 push 합니다.

git checkout : commit 이동

checkout 명령어로 HEAD의 포인터를 변경할 수 있습니다. 브랜치 전환도 가능하지만 git switch 명령어로 분리되었으므로 브랜치 이동은 switch 명령어를 사용합니다.

checkout한 경우 working directory의 Tracked 영역에 checkout한 commit의 상태를 반영하게 됩니다.

checkout하기 전 프로젝트 상태(Tracked, staging area)는 checkout한 후에도 그대로 존재하게 됩니다.
즉, checkout 한 뒤 Tracked에는 checkout한 commit 상태checkout하기 전 Tracked 상태가 존재하고, staging area는 checkout하기 전 staging area 상태가 유지됩니다.


git checkout <hashcode> : HEAD 포인터를 특정 commit으로 변경(detached HEAD 상태)

git checkout HEAD <filename> : 특정 파일의 내용을 HEAD가 가리키는 commit 상태로 파일 내용을 되돌릴 수 있습니다.

git branch : branch 조작

각 브랜치들은 "언제나 최신 commit"을 가리키고 있습니다.

HEAD는 브랜치를 가리키고, 브랜치가 commit을 가리키는 상태를 attached HEAD 상태라고 하며 브랜치가 가리키는 commit한 시점의 프로젝트 상태가 Tracked 영역에 반영됩니다.


git branch : 로컬 영역 내 모든 브랜치들의 이름 출력

git branch --all : 로컬과 서버에 존재하는 모든 브랜치 이름 출력

git branch -v : 로컬 영역 내 모든 브랜치 이름과 각 브랜치가 가리키는 commit에 대한 정보도 출력

git branch <branchname> : 새로운 브랜치 생성, 생성된 브랜치는 현재 HEAD가 가리키는 commit을 가리키게 됩니다.

git switch <branchname> : HEAD가 특정 branch를 가리키도록 변경, branch는 해당 브랜치 내 최신 commit을 가리키고 Tracked 영역에는 branch가 가리키는 commit 상태가 반영됨

git switch -c <branchname> : 새로운 브랜치를 생성하고, 해당 브랜치로 이동

git branch -d <branchname> : 특정 브랜치 제거(브랜치 내 커밋이 존재하고, merge 되지 않은 경우 -D 옵션을 사용)

git branch -D <branchname> : 특정 브랜치 강제 제거

git branch -m <branchname> : 현재 위치하고 있는 브랜치 이름 변경

git branch --merge : 현재 브랜치 내 병합된 브랜치 출력

git branch --no-merge : 현재 브랜치 내 병합되지 않은 브랜치 출력

git merge : 브랜치 병합하기

  1. 특정 커밋이 아닌 브랜치를 병합합니다.

  2. 항상 현재 현재 위치하고 있는, HEAD가 가리키고 있는 브랜치에 병합을 진행합니다.

base commit

브랜치가 분기되는 시점의 commit을 base commit이라고 부르겠습니다.

위 그림에서 test-branch의 base commit은 commit e가 됩니다.

1. faster-forward merge

git merge <branchname> : base commit부터 현재 HEAD가 가리키는 branch가 추가적인 commit을 갖지 않는 경우 fast-forward merge가 수행


파생된 test-branch를 master 브랜치에 병합하고자 합니다. 이때 파생된 test-branch의 base는 commit e이며, 병합하고자 하는 master 브랜치가 commit e 이후 추가적인 commit을 갖지 않기 때문에 fast-forward merge가 수행됩니다.

위 그림에서 현재 master 브랜치에 위치하고 있을 때, git merge test-branch 실행시 master 브랜치가 가리키는 commit이 commit 2로 변경됩니다.

이후 git branch -d test-branch를 실행하여 병합된 test-branch 브랜치를 제거합니다.

2. no-faster-forward merge

git merfe --no-ff <branchname> : 파생된 브랜치의 commit들을 하나의 commit으로 생성(merge commit)하고, 현재 브랜치에 commit을 추가하는 방식으로 병합


파생된 브랜치의 commit들을 남겨둔 채로 파생된 브랜치들의 commit들을 하나의 merge commit으로 생성하여 현재 브랜치에 merge commit을추가하는 방식으로 병합할 수 있습니다(git merge --no-ff test-branch).

3. three-way merge

git merge <branchname> : base commit을 기준으로 현재 위치한 브랜치가 추가적인 commit을 갖는 경우 three-way merge가 수행됩니다.


git merge 명령어를 사용할 때 만약 fast-forward merge가 가능한 경우라면 fast-forward가 사용되고, 불가능한 경우라면 three-way merge 방식이 사용됩니다.

위 그림처럼 test-branch의 base commit인 commit d를 기준으로 master 브랜치가 추가적으로 commit e를 갖기 때문에 three-way merge가 수행됩니다.

base commit 이후 파생된 test-branch의 commit들(commit 1, commit 2)와 현재 브랜치의 commit(commit e)가 하나의 commit으로 합쳐 merge commit을 생성한 뒤 이를 master 브랜치에 추가합니다.

merge conflict

  1. three-way merge를 사용하여 branch를 merge하는 경우

  2. merge commit을 생성할 때 파생된 branch의 commit들과 현재 브랜치의 commit들이 서로 동일한 파일의 내용이 서로 다른 경우 merge confilct가 발생

위 그림에서 merge commit을 생성하기 위해 commit1, commit2와 commit e를 하나의 commit으로 생성하는 과정에서 commit 2와 commit e가 동일한 파일에서 같은 위치 내용이 서로 달라 merge confilct이 발생하게 됩니다.

merge 실행시 위 그림처럼 c.txt 파일에 merge conflict가 발생했다고 표시되며, 실제 c.txt 파일에 conflict된 내용을 git이 자동적으로 포함해줍니다.

c.txt 내용이 위 그림과 같으며 동일한 위치에 master 브랜치는 "master branch" 내용이 존재하고, test-branch는 "test-branch"라는 내용을 갖고 있어 merge conflict가 발생하였습니다.

git status 실행시 Unmerged paths로 c.txt가 같은 부분이 수정되었다고 표시됩니다.

만약 merge conflict가 발생한 경우 git merge --abort 명령어를 통해 진행중인 merge를 취소할 수 있습니다.

1. 수동적으로 수정하기

merge conflict가 발생한 이후 수동적으로 해당 파일을 직접 수정하는 방식으로 conflict를 해결할 수 있습니다.

직접 conflict가 발생한 파일의 내용을 수정한 뒤 git add <filename> 으로 수정 내용을 staging area에 저장하고, git merge --continue 명령어 혹은 git commit를 통해 merge를 수행합니다.

2. VScode에서 수정하기

// .gitconfig

[merge]
  tool = vscode
[mergetool "vscode"]
  cmd = code --wait $MERGED
[mergetool]
  keepBackup = false

.gitconfig 파일에 위 내용을 추가하고, git mergetool 명령어 실행시 vscode에서 confilct를 해결할 수 있습니다.

keepBackup을 false로 설정하는 경우 conflict이 발생하여 생성된 백업 파일(*.orig)을 생성하지 않도록 설정할 수 있습니다.

conflict를 해결한 뒤 git add 명령어로 conflict를 해결한 파일을 staging area에 추가하고 git commit 또는 git merge --continue 명령어를 실행하여 merge를 수행합니다.

즉, git merge <brnach name> -> merge conflict occur! -> conflict resolve -> git add <resolved conflict file name> -> git merge --contniue or git commit

git rebase : base commit 변경

git rebase <branch name> : 현재 branch의 base commit을 특정 브랜치가 가리키는 commit으로 변경


현재 위치한 branch의 시작 commit을 git rebase <branch name> 명령어로 변경 가능합니다.

rebase를 함으로써 fast-forward merge가 불가능한 상황일 때 rebase를 사용하여 fast-forward merge방식을 사용할 수 있게 됩니다.

위 그림과 같이 three-way merge를 해야하는 상황일 때 test-branch의 base commit인 commit d를 commit e로 rebase함으로써 fast-forward merge를 사용할 수 있습니다.

  1. git swtich test-branch -> 2. git rebase master -> 3. git switch master -> 4. git merge test-branch(fast-forward merge)

위 그림처럼 기존 base가 commit d였던 것을 commit e로 rebase하여 변경하였습니다.

rebase를 사용하게 된다면 base commit만을 변경 하는 것이 아니라 실제로는 기존 브랜치의 commit도 모두 새롭게 생성되기 때문에 다른 개발자가 파생된 브랜치에 작업중이라면 merge conflict이 발생할 수 있습니다.

git cherry-pick : 특정 commit 복사하여 추가

특정 커밋을 현재 브랜치에 추가하고자 할 때 cherry-pick을 사용할 수 있습니다.

git cherry-pick <hash code> : 현재 브랜치 내 파생된 브랜치의 특정 commit을 새롭게 생성하여 추가


위 그림에서 master 브랜치에서 파생된 test-branch의 commit 1을 master 브랜치에 추가하고 하는 경우 git cherry-pick <commit 1 hashcode>를 실행합니다.

git stash : stash stack 사용

stash stack이란 현재 프로젝트 상태(Tracked, staging area)를 commit으로 만들지 않고 stash stack에 현재 상태를 push할 수 있으며, 이후 stash stack에서 pop하여 push한 시점의 상태를 가져올 수 있습니다.

즉, stash stack은 임시저장의 역할을 합니다.

위 그림에서 "stash@{n}"이 stash id로 사용되며, 가장 최근에 push된 stash가 상단에 존재하게 됩니다.


git stash: 현재 Tracked와 staging area 상태를 stash stack에 push함, Tracked와 staging area는 빈 상태로 존재

git stash --keep-inex : 현재 Tracked와 staging area 상태를 stash stack에 push, 이때 staging area 영역은 현재 상태 유지(빈 상태로 변경하지 않음)

git stash -u : Untracked 영역도 포함하여 stash stack에 push

git stash pop : stash stack에 가장 최근에 push된 stash 상태를 현재 상태에 적용, pop된 stash 상태 제거

git stash apply : stash stack에 가장 최근에 push된 stash 상태를 현재 프로젝트에 적용, 이때 stash 상태 제거되지 않음

git stash list : stash stack에 저장된 상태 출력

git stash apply stash@{n} : 특정 stash 상태 적용

git stash drop stash@{n} : stash stack에서 특정 stash 제거

git stash clear : stash stack 모두 제거

git restore : 특정 파일 내용 복구

git restore <file name> : 특정 파일의 내용을 현재 HEAD가 가리키는 commit 상태의 내용으로 복구(git checkout HEAD <filename> 명령어와 동일한 동작)

git restore --soucre <hash code> <file name> : 특정 파일의 내용을 특정 commit의 파일 내용으로 복구

git restore --staged <file name> : staging area 영역 특정 파일을 Unstaging되도록 설정(파일이 삭제되거나 수정되지 않음)

git reset : 특정 commit 상태로 복구

git reset <hash code> :

  1. 특정 commit과 현재 commit 사이 모든 commit들이 제거

  2. 제거된 commit들의 변경 내용들은 모두 Untracked 영역으로 이동

  3. 브랜치가 가리키는 commit을 특정 commit으로 변경

git reset --soft <hash code> :

  1. 특정 commit과 현재 commit 사이 모든 commit들이 제거

  2. 제거된 commit들의 상태들은 모두 staging area 영역으로 이동

  3. 브랜치가 가리키는 commit을 특정 commit으로 변경

git reset --hard <hash code> :

  1. 특정 commit과 현재 commit 사이 모든 commit들이 제거

  2. 제거된 commit들의 상태들은 모두 제거

  3. 브랜치가 가리키는 commit을 특정 commit으로 변경

git reset --hard로 초기화한 경우 삭제된 commit으로 이동하고자 한다면 git reflog 명령어를 실행하여 HEAD가 참조했던 모든 commit 내역을 볼 수 있으며, 이때 제거된 commit의 hash code를 git reset --hard <hash code>로 사용하여 복구할 수 있습니다.

git revert : commit 제거

git revert <hash code> : 특정 commit의 변경 사항을 취소하고, 취소된 내용을 commit으로 생성하고 추가

git revert --no-commit <hash code> : 특정 commit의 변경 사항 취소하는 내용을 현재 staging area에 추가하여 변경 사항 제거(취소 commit 생성하지 않음)

git rebase -i : 특정 commit 수정

git rebase -i <hash code> : 특정 commit 이후 commit들을 수정

위와 같은 commit들이 존재할 때 commit c를 수정하고 싶은 경우 commit c 이전 commit인 commit b로 rebase 해야 합니다.

git rebase -i <commit b hashcode> 입력시 아래와 같은 파일 표시됩니다.

  • Commands

    • p, pick : 그대로 사용

    • r, reword : commit message 수정

    • e, edit : commit 변경 사항 수정

    • s, squash : 이전 commit과 하나로 합친 commit 사용

    • b, break : rebase 중단

    • d, drop : commit 삭제

상단에 존재하는 [command] [hashcode] [commitmessage]에서 command 부분에 수정하고자 하는 명령어를 작성합니다.

git remote

git remote : local에 연결된 remote repository 이름들을 출력

git remote -v : local에 연결된 remote repository 이름과 url 출력

git remote add <remote name> <github url> : local에 remote repository 이름과 url 등록

git remote remove <remote name> : local에 연결된 특정 remote repository 제거

git remote rename <old name> <new name> : local에 연결된 특정 remote repository의 이름을 변경

git remote show <remote name> : 연결된 특정 remote repository 정보 출력

<remote>/<branch>(원격 추적 브랜치)

<remote name>/<branch name>라는 형식의 브랜치는 원격 추적 브랜치로서 remote repository에서 특정 브랜치의 가장 최근 commit을 가리키고 있습니다. 즉, 마지막으로 remote의 브랜치와 연결된 commit 지점을 기억하는 포인터입니다.

원격 추적 브랜치는 push, fetch, pull과 같은 명령어를 실행하면 원격 추적 브랜치가 이동하게 됩니다.

git branch -r : 원격 추적 브랜치들을 리스트로 표시합니다.

원격 추적 브랜치는 깃이 자동적으로 생성해주는 브랜치이며, 만약 해당 원격 추적 브랜치로 이동하고자 한다면 로컬에 해당 브랜치가 존재하지 않더라도 git switch <branch name> 명령어를 실행하면 로컬에 해당 브랜치가 생성되고 원격 추적 브랜치와 연결된 뒤 원격 추적 브랜치가 가리키는 commit을 가리키도록 설정됩니다.

git checkout <remote name/branch name>를 사용하여 이동할 수도 있습니다. 이때 Detacehd HEAD 상태가 되며, 추가적인 브랜치가 생성되지는 않습니다.

예를 들어, origin/test라는 원격 추적 브랜치가 존재하고, 로컬에는 test라는 브랜치가 존재하지 않더라도 git switch test 명령어를 실행하면 자동적으로 로컬에 test 브랜치가 생성되고 origin/test 브랜치가 서로 연결되고 test 브랜치는 origin/test 브랜치가 가리키는 commit을 가리키게 됩니다.

git clone

git clone <github url> :

  1. remote repository의 이름과 동일한 이름의 폴더를 생성

  2. 생성된 폴더에 remote repository를 연결(git remote add origin <github url>)

  3. 생성된 폴더의 local repository에 remote repository를 복제(git pull origin)


즉, git clone 명령어는 git remote add 명령어와 git pull 명령어를 동시에 실행시켜주는 것과 동일한 동작을 합니다.

이때 local에 연결된 remote repository의 이름은 자동적으로 origin으로 설정됩니다.

git clone을 사용하는경우 기존 프로젝트 내용들은 모두 제거되고 remote repository가 프로젝트에 적용됩니다.

git push

git push <remote name> <branch name>
: local repository의 branch에 새롭게 추가된 commit들을 remote repository의 동일한 이름을 갖는 branch에 commit을 추가(현재 위치한 브랜치와 상관 없음)

ex) git push origin main : local의 main 브랜치 commit들을 remote의 동일한 이름인 main 브랜치에 추가


git push <remote name> <local brnach name>:<remote branch name>
: local repository의 branch를 다른 이름의 remote repository의 branch에 commit을 추가(현재 위치한 브랜치와 상관 없음)

ex) git push origin master:main : local의 master 브랜치 commit들을 remote의 main 브랜치에 추가


git push -u <remote name> <branch name>
: -u 옵션을 작성한 경우 기존 push처럼 commit들을 remote branch에 추가합니다. 추가적으로 원격 추적 브랜치와 로컬 브랜치가 서로 연결되며 git push 명령어만을 실행하여 remote branch에 commit들을 추가할 수 있습니다.

ex) git push -u origin main : local의 main 브랜치 commit들이 remote의 main 브랜치에 추가됩니다.
추가적으로 origin/main 원격 추적 브랜치와 로컬의 main가 연결되어 이후 git push 명령어만 실행하여 push를 수행할 수 있습니다.

push rejected

push 명령어를 실행할 때 local repository에서 원격 추적 브랜치가 가리키는 commit이외 remote repository가 추가적인 commit을 갖고 있는 경우 push rejected가 발생합니다.

위 그림은 remote repository의 main branch와 local repository의 main branch입니다.

remote repository의 main 브랜치는 Update c.txt commit을 가리키고 있지만 local의 원격 추적 브랜치인 origin/main은 c commit을 가리키고 있습니다. 즉, 브랜치가 서로 동기화가 되어 있지 않은 상황입니다.

이러한 경우 remote repository에 "git push하기 전에 git pull을 먼저 수행하여 통해 remote repository와 local repository를 서로 동기화"한 뒤에 push를 수행해야 합니다.

git fetch

git fetch <remote name> : remote repository의 모든 commit을 local repository에 동기화, 단 merge는 진행되지 않음

git fetch <remote name> <branch name> : remote repository의 특정 branch만 local repository의 브랜치에 동기화, 단 merge는 진행되지 않음

동기화 진행시 remote의 branch와 local의 branch는 별도의 branch가 생성되어 동기화됩니다.
즉, remote branch가 독립된 branch로 local repository에 반영됩니다.

git pull

git pull <remote name>: remote repository의 모든 commit을 local repository에 동기화, 이후 merge를 진행

git pull <remote name> <branch name> : remote repository의 특정 branch의 commit들만 local repository에 동기화, 이후 merge를 진행

  1. remote branch가 local branch에 동기화

  2. base commit 이후 local branch에 추가적인 commit이 없다면 local branch가 remote branch가 가리키는 commit을 가리키게 됨(fast-forward merge)
    만약 base commit이후 local branch가 추가적인 commit을 갖는 경우 three-way merge가 수행되어 merge commit이 생성되고 local branch에 추가됨

profile
Frontend Dev

0개의 댓글