Git
원격 저장소 중 하나인 Github
를 사용해보자.
참고: 이전에 작성한 글의 세팅을 먼저해야 됩니다!
사전 준비
C:\study\git_command_with_github
kakao.txt
, naver.txt
, toss.txt
파일 생성 및 내용 작성git init
, git add .
, git commit -m 'First Commit'
입력Github
원격 저장소를 생성해보자.
1. Github에 로그인하고 화면 우측 상단의 +
버튼 클릭 후, New repository
클릭
2. Repository name
지정하고, Create repository
클릭
3. 아래 그림의 빨간색 쳐진 부분을 클릭한다. 그러면 좌측의 문자열이 클립보드에 복사된다.
4. 복사한 내용을 그대로 git bash
에 넣고 엔터를 쳐준다.
5. 이후 원격저장소 페이지를 새로고침하면, 정상적으로 초기화된 것을 확인할 수 있다.
1. github 저장소에 가서 아래 그림처럼 HTTPS
주소를 복사한다.
2. 로컬에 디렉토리 하나 만들고, 해당 디렉토리 내부에서 git bash를 실행한다.
그리고 나서 git clone https://github.com/devToroko/git_command_with_github.git .
하면 된다.
$ git clone https://github.com/devToroko/git_command_with_github.git .
Cloning into '.'...
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Receiving objects: 100% (5/5), done.
$ ls -al
total 7
drwxr-xr-x 1 devToroko 197121 0 Feb 22 08:41 ./
drwxr-xr-x 1 devToroko 197121 0 Feb 22 08:41 ../
drwxr-xr-x 1 devToroko 197121 0 Feb 22 08:41 .git/
-rw-r--r-- 1 devToroko 197121 59 Feb 22 08:41 kakao.txt
-rw-r--r-- 1 devToroko 197121 60 Feb 22 08:41 naver.txt
-rw-r--r-- 1 devToroko 197121 59 Feb 22 08:41 toss.txt
$ git log --all --decorate --oneline --graph # Git 상태 정보까지 가져온다!
* b5d3d86 (HEAD -> main, origin/main, origin/HEAD) First Commit
원격 저장소에 업로드(push) 해보고,
반대로 저장소의 정보를 다운로드(pull) 한번씩 해보자.
로컬에서 간단한 변화를 주고 commit
+ push
$ vim naver.txt # 약간의 변화를 준다.
$ git commit -am 'naver.txt changed'
$ git push
원격 저장소 상태 변화 확인
이번에는 pull을 해보자.
그전에 먼저 원격에서 직접 commit을 주고, 해당 커밋 정보를 로컬에서 pull 해보겠다.
원격 저장소에 가서 아래처럼 따라하자.
Edit this file
버튼을 클릭commit message
작성 및 Commit changed
버튼 클릭$ git pull
Updating 74668fb..5fbf5d2
Fast-forward
kakao.txt | 2 ++
1 file changed, 2 insertions(+)
$ git log -1
commit 5fbf5d286047fb71a3c6c774286f71e90249d9f3 (HEAD -> main, origin/main)
Author: devToroko <51431766+devToroko@users.noreply.github.com>
Date: Tue Feb 22 09:49:09 2022 +0900
Update kakao.txt
git pull
을 하고, git log -1
을 해서 보면 정상적으로git
정보가 최신화 된것을 확인할 수 있다.그런데 원격 저장소의 최신 상태를 pull
하지 않은 상태로 push
가 될까? 안된다.
그래서 push
를 하기 전에는 무조건 pull
해서 로컬을 최신화해야만 push
가 가능하다.
문제는 pull
과정에서 충돌이 자주 발생한다.
이번 실습은 고의적으로 충돌을 일으키고 해결하는 과정을 해보자.
먼저 github 에서 kakao.txt
파일을 수정, 커밋하고
로컬에서도 kakao.txt
파일을 수정, 커밋한다.
$ vim kakao.txt
$ git commit -am 'local change'
$ git pull # git pull --no-rebase 와 같다. merge 방식을 사용한다.
# ... 생략 ...
CONFLICT (content): Merge conflict in kakao.txt
Automatic merge failed; fix conflicts and then commit the result.
# Conflict 가 났음을 알려주고 있다.
# 만약 pull 과정을 취소하고 싶다면 "git reset --hard" 입력
$ git diff --name-only --diff-filter=U
kakao.txt # 충돌 파일 이름 확인
결과
바로 이어서 충돌난 파일을 수정, 커밋, 푸시한다.
$ git add kakao.txt # 충돌 부분 편집
$ git commit
$ git push
결과
--no-rebase
를 쓴 것이다.pull
할 때 로컬과 내용을 합칠 때 merge
방식을 쓴다는 의미다.rebase
방식으로 하고 싶다면 git pull -rebase
를 하면 된다.rebase 방식으로도 해보기
# 미리 github 와 로컬 저장소에 toss.txt 변경하고, 커밋!
devToroko@DESKTOP MINGW64 /c/study/git_command_with_github (main)
$ git pull --rebase
# ... 중간 로그 생략...
CONFLICT (content): Merge conflict in toss.txt
error: could not apply b09f367... git local change
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply b09f367... git local change
# 일단 conflict 가 난 건 확인이 됐다.
devToroko@DESKTOP MINGW64 /c/study/git_command_with_github (main|REBASE 1/1)
# REBASE 1/1 로 봐서 현재 충돌이 났다.
# 충돌 해결 후에 rebase --continue를 해야한다.
$ git diff --name-only --diff-filter=U # 충돌 파일 확인
toss.txt
$ vim toss.txt # 충돌 지점 내용 수정
$ git add .
$ git rebase --continue
git rebase --continue
후 commit message 작성
:wq
하고 나오자.
결과
이 상태에서 git push
를 해서 업데이트까지 해주자.
위에서 사용한 git pull 은 사실 merge(또는 rebase)
의 과정이 섞여 있다.
그런데 merge(또는 rebase)
를 바로 하는 게 아니라,
원격의 상태 정보를 미리 받아서 먼저 눈으로 확인하고 싶다면 어떡할까?
이때 필요한 게 fetch
이다.
이번에도 원격과 로컬에서 같은 파일을 수정하고 커밋까지 해둔 상태로 만들고,
fetch 를 사용해서 이전과 어떤 차이가 있고, 어떻게 쓰면 좋을지 보자.
$ git fetch # 하고 나서 그래프를 보면...
보이는가?! 원격 브랜치의 분기가 일어나는 것을 볼 수 있다!
하지만 이전처럼 병합을 위한 커밋이 미리 생성되어 있지는 않는다!
이 상태에서 로컬 브랜치(main)
와 원격 브랜치(origin/main)
브랜치를 비교하면
아래와 같은 것들을 pull하기 전에 미리 알아낼 수 있다.
# 충돌 예정 파일 목록 조회
$ git diff --name-only main origin/main
naver.txt
# 충돌 예정 파일의 로컬/원격 차이점
$ git diff main origin/main -- naver.txt # 결과는 아래 사진으로!
# 여기서는 - 가 local, + 가 원격이다.
# 참고로 차이점을 알아내는 방식은 위의 방법 말고도 2가지 더 있다.
$ git diff main:naver.txt origin/main:naver.txt
$ git diff main..origin -- naver.txt
협업을 할 때는 핵심인 main
브랜치를 제외하고는 실제 각자 파트에 맞게
브랜치를 main
에서 분기하여 사용하고, 작업이 끝나면 다시 main
브랜치에 병합한다.
그런데 이러면 사실 협업하기가 조금 힘들다.
병합을 시도하려는 branch
의 내용이 실제로도 협업하는 사람들의 허락을 받고 하는 게 좋다.
이런 허락을 받으려는 요청을 우리는 Pull Request
라고 한다.
Pull Request는 주로 아래와 같은 시나리오로 작성된다.
지금부터 위 시나리오로 실습을 진행하겠다.
$ git pull origin # 이미 원격에 같은 브랜치가 있으면 곤란하니 git pull해서 확인!
$ git branch elastic-search # 엘라스틱 서치 기능 구현 branch 생성
$ git switch elastic-search
Switched to branch 'elastic-search'
$ git branch # 현재 선택된 브랜치 확인!
* elastic-search
main
$ git push # 새로운 브랜치에서 바로 push 에러!
fatal: The current branch elastic-search has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin elastic-search
$ git push -u origin elastic-search # 경고문이 알려주는 대로 명령어 입력하면 된다.
# -u 를 썼으니 앞으로는 elastic-search ==> origin/elastic-search 자동으로 push된다.
이러고 나서 github에서 새로고침을 하면 새로운 브랜치 정보가 보일 것이다.
아무렇게나 커밋하자.
나는 위와 같이 커밋 이력이 남도록 했다.
로컬/원격 모두 elastic branch
를 최신 커밋 상태에 뒀다.
github에 가서 위 그림처럼 branches
를 클릭
지금까지 작업했던 브랜치 명(elastic-search
)을 찾고 New pull request
버튼 클릭
여기에서 Pull Request 의 제목과 내용을 작성한다.
다 작성하고 바로 Create pull request
버튼을 클릭해도 된다.
하지만 만약 좀 더 상세하게 Pull Request에 대한 설정을 원하면 위 그림에서 파란색 박스
부분을 잘 지정해주자.
이번에는 협업자인 사람 시점으로 진행해보겠다.
협업자
는 github
에 접속하고 나서 Pull requests
에 알림이 뜬 걸 확인한다. (좌측상단)
새로 올라온 pull request
를 클릭
Pull Request 가 맘에 들면 Merge pull request
버튼을 클릭
맘에 안들면 사유를 적어주고 Close pull request
버튼을 클릭한다.
최종적으로 위와 같은 화면이 나오고 elastic-search 브랜치가 main 브랜치에 병합되었다.
여기서는 Pull Request
를 가볍게 봤다.
하지만 추후에 Pull Request
와 관련된 세세한 작업은 다른 게시물로 작성하겠다.
여태 사용한 명령어들을 정리한다.
보면서 어떤 일이 있었는지 한번 보자.
원격 저장소 정보 추가(add)
git 에 origin이라는 이름으로 원격 저장소를 추가하는 것이다.
참고로 원격저장소는 github 뿐만 아니라, gitbucket 같은 다른 원격 저장소도 추가할 수 있다.
로컬 저장소 기본 브랜치 세팅
메인으로 쓸 branch를 main
으로 하겠다.
나는 앞서서 git config --global init.defaultBranch main
를 했기 때문에
기본으로 main
브랜치가 잡힌다.
로컬 git 상태 정보 업로드
원격에 커밋 정보를 밀어 넣는 것이다.
-u
는 현재 브랜치와 원격의 브랜치를 기본으로 연결하겠다는 뜻이다.
이렇게 하고 동일한 브랜치에서 push
하면 자동으로 origin main
으로 push
된다.
pull
도 마찬가지다.
로컬 저장소 상태 정보 다운로드
옵션 2가지 정도는 알고 가자.
--no-rebase
: merge
방식을 사용해서 원격의 커밋을 로컬에 합친다.--rebase
: rebase
방식을 사용해서 원격의 커밋을 로컬에 합친다.참고로 한번이라도 git push -u {원격 이름} {브랜치 이름}
하면 git pull
만 해도 된다.
원격 저장소의 상세 정보 조회
$ git remote -v
origin https://github.com/devToroko/git_command_with_github.git (fetch)
origin https://github.com/devToroko/git_command_with_github.git (push)
연결된 특정 원격 정보 제거(실제 원격 저장소가 지워지는 게 아님!)
git branch -d elastic-search-dev
git push origin --delete elastic-search-dev
$ git fetch origin
# 차이점 조회(충돌 예정 파일 목록 조회도 가능)
$ git diff --name-status main origin/main
D README-IMG/blo_website_ERD.drawio.svg
A README.md
#########
# A : Added
# C : Copied
# D : Deleted
# M : Modified
# R : Renamed
# T : have their type (mode) changed
# U : Unmerged
# X : Unknown
# B : have had their pairing Broken
# * : All-or-none
#########
# 아래처럼하면 이렇게 하면 워크 스페이스 <-> 최종 커밋과 비교도 가능
## git diff --name-only HEAD~
# 충돌 예정 파일의 로컬/원격 차이점
$ git diff main origin/main -- naver.txt # 결과는 아래 사진으로!
# 여기서는 - 가 local, + 가 원격이다.
# 참고로 차이점을 알아내는 방식은 위의 방법 말고도 2가지 더 있다.
$ git diff main:naver.txt origin/main:naver.txt
$ git diff main..origin -- naver.txt
$ git remote update
$ git checkout -t {원격 브랜치 이름} # 방법1 : 원격이랑 같은 이름의 브랜치명이 생성
$ git checkout -b {생성할 브랜치 이름} {원격 브랜치 이름} # 방법2
만약 원격에서 삭제한 branch 정보가 로컬에서는 정보가 남아 있다면
git fetch --all --prune
을 해주면 된다.