본문 바로가기

Back-End 공부/SW공학

GitHub 기본 명령어(add, commit, push), 커밋취소, 충돌해결

📌 Git과 GitHub

✅ Git

  • 분산버전관리 시스템으로서, 소스 코드의 변경사항을 추적하는 데 사용
  • 로컬 시스템과 원격 시스템을 두어, 로컬에서 작업 후 원격공간과 동기화
  • 주요 명령어에는 add, commit, pull, merge, branch, checkout 등
  • 브랜치(branch) 기능을 통해 여러 개발자가 동시에 개발하면서도 충돌 없이 작업
  • git은 리눅스 토르발즈에 의해 개발된 이후 오픈소스프로젝트에서 관리

✅ GitHub

  • GitHub은 소스 코드가 온라인에서 관리되고 협업될 수 있는 플랫폼
  • Git의 리포지토리를 온라인상에서 관리하기 위한 플랫폼
  • ms사에서 인수

 

 

💡 버전관리시스템

 

💡 GitHub 사용을 위한 인증과 환경설정

git clone https://토큰번호:x-oauth-basic@Repository주소

 

 

💡 Git 프로젝트 생성 및 수정절차

방법 1

  • git clone repository주소
  • 해당 폴더로 이동하여 개발 시작

방법 2

  • 로컬 컴퓨터에서부터 이미 개발된 프로젝트가 존재시
  • git init
    • .git 파일 생성
    • .git 파일은 커밋 이력, 원격지 주소, 브랜치 정보를 가지고 있음
    • .git 폴더가 위치한 곳에서 git config --list를 통해 컨피그 정보 조회
  • git remote add origin [repository주소]
    • origin이란, 깃허브 저장소 주소를 의미(원격저장소)
    • 현재 로컬 저장소와 원격저장소를 연결하는 명령어
    • 현재 로컬 저장소의 변경사항을 원격저장소에 관리하겠다는 의미
  • git remote set-url origin
    • url 변경 후 main에 push하면 main의 commit 이력과 함께 업로드
  • git remote remove origin
  • git push --all
    • 모든 브랜치의 커밋이력 push

💡 Git 기본명령어

  • git status
    • 현재 작업 디렉토리와 staging area의 상태를 보여주는 명령어
  • git add .
    • staging area로 업로드
    • git status로 staging 상태 확인
  • git commit -m "커밋메시지"
    • local repository로 업로드 및 커밋이력 생성
    • 방법1) git commit -m "제목파트" -m "내용파트"
    • 방법2) git commit만 하게 되면 메시지 입력 모드로 전환. 첫 줄에 title, 두번째 줄부터 contents 
    • 방법3) VSCode Source Control창에 제목 입력 -> (Shift + Enter) -> 내용 입력
    • git log로 커밋이력 확인
  • git commit -am "커밋메시지"
    • add와 커밋을 동시에
  • git log
    • 여태 발생한 커밋 히스토리를 조회
    • head란 마지막 커밋을 의미
    • 만약 push되어 원격저장소에 배포됐다면, origin/main
    • 간결하게 보고싶다면 git log --oneline
  • git push origin branch명
    • 원격저장소의 특정 branch 위치에 local repository의 이력과 변경사항을 업로드
    • 만약 충돌 시 강제 업로드 하고 싶다면 --force 추가
  • git diff
    • 현재 작업 디렉토리와 스테이징 영역(index) 사이의 차이점
    • git diff <commit1> <commit2>
      • 두 커밋간 차이점 비교
      • commit1을 기준으로 commit2와의 비교시 차이점 출력
    • git diff main origin/main
      • local repo의 main과 local repo의 origin main과의 비교
      • main : 로컬저장소, origin/main : 원격저장소
  • git fetch
    •  origin의 데이터를 로컬로 가져오되, 병합은 하지 않는 것
    • local repository까지 커밋이력은 가져오되, staging과 working diectory에는 반영X
    • FETCH_HEAD는 git fetch 명령어를 마지막으로 실행했을 때 원격 저장소에서 가져온 브랜치의 최신 커밋을 가리키는 참조
    • git fetch origin main
      • 원격 저장소인 origin/main과 로컬저장소인 main의 차이점을 가져옴(커밋 이력) 
      • 현재 checkout되어 있는 main과의 차이가 있을경우 차이점을 담은 origin 참조데이터 fetch_head라는 곳에 생성
      • 차이점을 참고하여 일단 merge 후에 파일 수정하고 다시 push
  • git ignore
    • git에서 추적목록에서 제외할 대상 나열
    • ignore파일 생성방법
      • 템플릿을 통한 ignore파일 생성
      • spring boot initializer와 같은 패키지 툴을 통해 생성시 ignore파일 자동 생성 지원
      • ex) HELP.md .gradle build/
  • git stash
    • 작업 준비 중인 변경사항을 임시로 저장하고, 나중에 다시 적용할 수 있게 해주는 명령어
    • git stash list
      • 작업저장목록
    • git stash show 인덱스
      • 복사본 내용 조회
      • git stash show -p 인덱스 : 상세조회
    • git stash pop
      • 작업목록에서 제거하면서 저장사항 적용
    • git stash apply
      • 작업목록에서 놔둔채, 저장사항 적용
      • git stash apply 0 : 가장 최근에 저장한 stash의 적용
    • git stash clear
      • 전체 stash 목록 클리어
  • git tag
    • main브랜치에서 tag를 붙여 버전을 명시하고, release를 하고자 할 때 아래와 같이 tag를 붙인 뒤 push
    • release에는 source코드가 압축파일로 생성
    • git tag 버전명(v1.0)
    • git push origin 버전명 (v1.0)
    • add, commit, push와는 별도로 진행
  • feature branch 작업
    • 실제 협업에선 branch1, branch2, dev, main 등 여러 브랜치로 관리
      • 브랜치란 버전과는 다르게 개발의 경로를 의미
      • 일반적으로 production 관련 브랜치는 main, 개발용 브런치는 dev
      • 나머지는 task별로 기능별로 개별적으로 만들어 사용 -> feature 브랜치라 칭함
      • 각각의 feature branch에서 작업 후 origin/feature로 push
      • Pull request를 통해 dev까지 merge
      • dev에서 main으로 최종 merge하는 과정이 현업에서의 브랜치 관리
  • feature branch 관련 주요 명령어
    • git fetch origin
      • local 레파지토리로 모든 브랜치 정보 fetch
    • git branch
      • 현재 저장소에 있는 모든 브랜치 목록
    • git branch 특정브랜치명
      • 특정브랜치명으로 새로운 브랜치를 생성하는 명령어
      • 기존에 checkout 되어 있던 브랜치 commit base로 신규 브랜치 생성
    • git checkout 브랜치명
      • 현재 브랜치에서 다른 브랜치명으로 전환하는 명령어
    • git checkout –b 브랜치명
      • 새 브랜치를 생성하고 해당 브랜치로 전환
    • branch 삭제
      • 삭제시에는 다른 브랜치로 checkout 한 후에 삭제대상 브랜치 삭제해야 함에 유의
      • git branch -D 브랜치명 : 로컬브랜치삭제
      • git push origin --delete 브랜치명 : 리모트브랜치도 삭제
  • merge전략
    • branch1에서 공용브랜치(dev 또는 main)로 PR을 만든뒤 merge하는 상황
    • merge/ rebase / squash
      • merge
        • merge는 두 브랜치의 변경 사항을 통합하는 기본적인 방법
        • branch1에서 넘어온 commitID와 신규 merge commitID가 dev브랜치에 남게됨
      • rebase
        • 한 브랜치의 커밋을 다른 브랜치의 최신 커밋에 “재적용”(re-apply)하는 방식
        • 이때에는 브랜치에서 넘어온 commitID가 아닌, 새로운 commitID가 발급되어 dev브랜치에 생성
        • 장점
          • merge commitID는 남지 않게 되어, 깔끔한 커밋관리
          • 기존의 commit history는 유지
        • 단점
          • 이후에 branch1에서 다시 merge를 할때 충돌이 발생하므로, 사용하던 branch1은 더이상 사용이 어려움
      • squash
        • squash는 여러 커밋을 하나의 커밋으로 합치는 과정
        • local repository에서 여러 커밋을 발생시켰을때 해당 커밋ID를 통합하여 하나의 commitID로 만들어 dev에는 하나의 commitID로만 이력 생성
      • rebase, squash는 feature브랜치에서 공용브랜치로 merge할때에는 선택에 따라 가능. 다만, 기존의 feature브랜치는 재사용이 어려움에 유의
  • cherry pick
    • main에서 채번된 branch1, branch2가 dev에 merge돼 있을때, branch1만 main으로 merge하고 싶은상황
    • 원하는 특정 commit ID들을 pick하는 것이 cherry-pick
    • 문제점
      • 기존의 commitID 체리픽을 통해 main merge된 이후 생성된 commitID가 일치하지 않아, 원본 커밋과는 다른 고유한 커밋 ID이므로 추후 dev전체를 main으로 다시 merge할 때는 충돌 발생

💡 Git 취소상황

  • working directory의 수정사항 취소
  • add 이후 취소
  • commit 이후 취소
  • push 후 origin까지 배포된 사항 취소 

- working directory의 수정사항 취소

  • git checkout .
    • 파일 수정사항의 취소
  • git clean -fdx
    • 파일을 신규추가(untracked file)한 경우의 취소
  • git checkout . | git clean -fdx
    • 수정 및 추가 모두 취소
  • 개발툴(intellij, vscode 등) 사용 시 쉽게 수정사항 취소 가능

- add 이후 취소

    • git reset
    • git restore --staged .

- commit 이후 취소 ⭐ ⭐

  • git reset HEAD~1(또는 HEAD~*)   
    • unstaged 상태로 만듬 = working directory로 돌아옴
  • git reset --soft HEAD~1
    • staged 상태 유지 = staging으로 돌아옴

- push 이후 취소

  • push 후 origin까지 배포된 사항 취소
    • git revert 커밋ID
    • 특정 커밋 버전을 취소시키는 새로운 commit을 생성 후에 다시 push

💡 Git Pull과 충돌

  • 수정 후 수정사항 업로드
    • add, commit, push
  • origin이 수정되어 local과의 차이 발생시
    • origin의 변경사항은 local에서 추적 불가능 -> source control의 변경사항인지는 local repository에 대한 변경 인지
  • git pull origin main(브랜치명)
    • origin을 기준으로 local을 update
    • pull은 working directory까지 반영 -> 컴퓨터에서 작업하는 파일들이 아예 수정됨
    • 만약 로컬의 변경파일과 origin의 변경파일이 같이 변경되면 충돌발생 가능성
    • 별도의 브랜치명 명시 안하면서 현재 checkout된 branch에서 pull
⭐⭐⭐ 내가 commit까지 한 상황에서 origin/main과 다를 때 충돌 해결 방법 ⭐⭐⭐

선택지 1.
git pull
-> 바로 병합 직전 상황
-> origin/main 코드 위에 내가 수정한 코드를 올려 push

선택지 2.
git fetch origin main (fetch_head 생성됨)
-> git diff main fetch_head
-> git merge fetch_head(현재 checkout 되어 있는 branch와 병합)
-> 충돌 제거 후 add, commit, push

 

 

 

💡 사용자 지정 ⭐⭐⭐

사용자 지정은 사용자 인증과 상관없이 자유롭게 가능

  • 전역적 선언
    • git config --global user.name "yujeong-shin"
    • git config --global user.email "vouobb@naver.com"
    • 홈 디렉토리 .gitconfig에 저장 (C:\Users\Playdata\.gitconfig)
    • 전역적 사용자 지정하는 방법
      • repo폴더(git_study)에서 한 단계 위로 나온 후 name, email 설정

 

  • 지역적 선언
    • git config --local을 통해 선언
    • .git/config에 저장
    • 지역적 사용자 지정하는 방법
      • repo폴더(git_study)에서 name, email 설정

 

 

 

Git Bracnhing 연습 게임하는 사이트(SH님 감사함다)

https://learngitbranching.js.org/?locale=ko

 

Learn Git Branching

An interactive Git visualization tool to educate and challenge!

learngitbranching.js.org

 

 

 

💻 Git 프로젝트 생성 - 방법 2 실습

 

1. 원격 저장소에 올리고 싶은 폴더를  로컬 저장소에 생성

2. VSCode에서 Terminal -> New Terminal -> git init 입력

해당 폴더에 .git 파일을 만드는 파일 - 원격 저장지 주소를 설정해주기 위해 생성

 

2. GitHub에서 로컬 저장소와 연결할 원격 저장소 생성 "test_spring"

 

3. 로컬-원격 저장소 연결

 

4. 원격 저장소에 올릴 파일 Staging에 올리기

git add .

git commit -m "first commit"

git checkout -b main

git branch

git push origin main

master 브랜치에서 계속 commit 하고 git checkout -b mian 하게되면 commit 내역이 main에 복사된 채로 push됨

 

 

 

💻 Git 실습 1

 

- 강사의 public repository를 clone하되 기존의 commit 이력없이 본인의 repository로 업로드

git clone 강사url
폴더 open
.git 폴더 삭제
git init
git remote add origin repo주소
git checkout -b main
git add .
git commit -m "first commit"
git push origin main

내가 commit한 "first_commit"만 커밋 히스토리에 남음

 

 

 

💻 Git 실습 2

 

- 강사의 public repository를 clone하되 모든 브랜치의 commit을 유지하고 본인의 repository로 업로드

전역적 사용자 변경 필수, 안그러면 강사님 아이디에 잔디 심어짐 !!

 

git clone 강사url
cd 해당 폴더로 이동
git remote set-url origin repo주소
git checkout -b main
git push --all origin

 

 

 

💻 Git 실습 3

 

1. origin main에서 test3.txt파일변경 발생 -> local에서 변경사항 인지 가능한지 VSCode에서 확인

바로는 체크가 안되지만, VSCode를 껐다 키면 자동으로 변경사항을 pull할건지 물어봄

 

 

2. 내 local에서 test3.txt파일 변경하여 push 시도

 

3. 충돌로 push 불가 -> 일단 force를 통해 강제 push

git push origin main --force

 

 

💻 Commit 이후 취소상황 실습 1

 

VSCode(local)에서 test1.txt 파일 수정 후 commit, GitHub에서 test2.txt 파일 수정 후 commit

후 Git pull 결과는?

==> 원격저장소F 로컬저장소F인 상황에서

원격 저장소 test2.txt파일 수정해 G 버전으로 만든 후 commit,

로컬 저장소는 test1.txt파일 수정해 H 버전으로 만든 후 commit

==> 원격 저장소와 로컬 저장소가 다른 파일을 수정하면 에러나지 않는다

==> VSCode가 pull한 commit도 만들고 통합된 버전도 자동으로 만들어줌

 

 

💻 Commit 이후 취소상황 실습 2

 

add까지 한 이후 취소 -> git status로 확인

commit까지 한 이후 취소 -> git status로 확인

 

test1.txt 파일에 this is live code 추가

 

push까지 한 이후 git log확인해서 가장 최근 logID를 사용해 git revert로 되돌리기(this is live code 없애기) 

되돌린 버전의 새로운 commit을 만들어줌 = commit 5922b6c...

자동으로 뜨는 vi화면에서 :wq로 빠져나온 후 push

 

test1.txt 파일에 this is live code 없어졌는지 확인

convert 후 test1.txt

 

(+)

이상한 실행 모드로 들어가져서 안되면 그냥 git push origin main --force한 후에 다시 수행하거나

코드 위에 뜨는 세 가지 선택사항 중 적절한 머지 전략 선택

 

 

 

💻 Fetch 실습

 

origin/main에 변경사항 적용 후 fetch하게되면

origin/main은 commit이 발생했기 때문에 위에 한 줄이 생기고, 현재 local repo는 하나 아래에 위치하게 된다

 

 

git pull 명령어를 통해 원격 저장소의 변경 사항을 로컬 저장소에도 반영한다.

 

 

💻 추가 실습 1

 

내 로컬 test1.txt 수정 및 commit

origin test2.txt 수정 및 commit

git pull

=> 수정한 파일이 다르기 때문에 자동으로 합쳐줌

 

 

💻 충돌해결 최종 실습 1 - pull 사용

 

내 로컬 test1.txt 수정 및 commit

origin test1.txt 수정 및 commit

git pull

=> 충돌

=> 방법1. 로컬 수정사항 다른 곳에 복사해두고, git pull한 후 origin 변경사항 위에 로컬 수정사항 붙여넣거나(권장)

=> 방법2. 아래 문제처럼 fetch, diff, merge로 해결

 

 

💻 충돌해결 최종 실습 2 - fetch, diff, merge 사용

 

내 로컬 test1.txt 수정 및 commit

origin test1.txt 수정 및 commit

=> 충돌

git fetch origin main

git diff main origin/main

git merge fetch_head

 

원격저장소 test1.txt 수정 후 commit

 

로컬저장소 test1.txt 수정 후 commit

 

git fetch origin main

가상의 공간 FETCH_HEAD에 원격저장소와 로컬저장소의 차이점들이 저장됨

 

git diff main fetch_head

로컬 저장소와 FETCH_HEAD 차이 비교

 

git merge fetch_head

 

충돌사항 해결 후 add, commit, push

충돌 해결

 

 

💻 충돌해결 최종 실습 3 - stash 사용

 

내 로컬 test1.txt 수정 및 commit

origin test1.txt 수정 및 commit

=> 충돌

git stash (로컬 저장소에서 원격 저장소와 다른 부분이 삭제되며 수정사항 별도 파일 저장)

git stash list

git stash show 0

 

 

git pull로 원격 내용으로 업데이트

git stash pop 0 혹은 git stash apply 0으로 저장된 다른 부분들 꺼내기

 

수정 후 add, commit, push