IT STUDY LOG

[Git과 버전 관리 시스템] 02. Git 본문

devops bootcamp 4/개발 및 배포

[Git과 버전 관리 시스템] 02. Git

roheerumi 2023. 3. 20. 20:26

# 학습 목표

  • Git의 환경설정을 할 수 있다.
    • 버전 관리 시스템의 필요성을 이해할 수 있다.
    • Github과 Git의 관계에 대해 이해할 수 있다.
    • Repository에 대해 이해할 수 있다.
    • Local Repository와 Remote Repository의 차이를 이해할 수 있다.
  • 상황에 따라 Github의 기능과 Git 명령어를 사용할 수 있다.
    • Fork
    • clone
    • status
    • restore
    • add
    • commit
    • reset
    • log
    • pull
    • push
    • init
    • remote add
    • remote -v
  • Git의 세 가지 영역 및 상태를 이해할 수 있다. (Committed, modified, staged)
  • Remote Repository를 페어와 공유하며 협업을 할 수 있다.
  • 충돌이 발생했을 경우 해결할 수 있다.
  • Git Repository의 commit되지 않은 변경 사항을 취소할 수 있다.
    • reset HEAD <file>
    • checkout -- <file>
  • 협업을 위한 git 개념을 이해할 수 있다.
    • branch, merge의 개념
    • remote repository에서 origin과 upstream의 차이점

 


## 학습 내용

1.  Git intro

  • 버전 관리 시스템의 필요성과 사용 이유
    • 파일이 변경되면 변경 이력 저장 가능
    • 이전 버전으로 돌아갈 수 있음
    • 어떤 변경사항이 발생했는지 알아보기 쉬움
    • 협업하기 좋음
    • 백업 가능
  • Git
    • 가장 강력하고 대중적인 버전 관리 시스템
    • 분산형 버전 관리 시스템
    • 소스 코드 기록을 관리하고 추적할 수 있는 버전 관리 시스템
  • Github
    • Git Repository를 관리할 수 있는 클라우드 기반 서비스
  • Git Repository
    • 저장소, 파일이나 폴더를 저장해두는 곳
    • 분류
      • Remote Repository : 원격 온라인 서버 상의 저장소, 여러사람이 함께 공유 가능
      • Local Repository : 내 컴퓨터의 저장소 (개인 전용 저장소)
  • Contributor
    • fork, clone, push, pull를 통해 contribute
      • fork : Remote Repository에 저장된  원격 저장소를 내 원격 저장소로 가져오는 작업
      • clone : 내 원격 저장소에 fork한 파일을 내 로컬 저장소에 clone
      • commit : 내 로컬 저장소에서 수정한 소스 코드를 저장 
      • push :  commit한 소스코드를 Remote Repository에 업로드
      • pull : Remote Repository에서 변경사항이 있을 경우 가져오는 작업

출처 : 코드스테이츠 DevOps 과정
출처 : 코드스테이츠 DevOps 과정

 

출처 : 코드스테이츠 DevOps 과정

 

출처 : 코드스테이츠 DevOps 과정
출처 : 코드스테이츠 DevOps 과정
출처 : 코드스테이츠 DevOps 과정
출처 : 코드스테이츠 DevOps 과정

 

2. 혼자 작업 workflow

  • 나만의 오픈소스 제작하기 workflow overview
    • git init : 오픈소스 코드를 저장할 디렉토리를 만들고 해당 디렉토리를 local Git repository로 만듦
    • git add : 코드를 작성하고 저장하는 공간, 작업 공간(work space)의 파일 및 디렉토리를 git의 관리 하에 있는 상태로 올려 staging area로 만듦
    • git commit : staging area의 파일은 commit이 가능 (local Git repository에 내 오픈소스 코드 기록)
    • git push : local repository에 기록한 내역을 remote repository에 push
    • git clone, fork :  해당 Github repository에 방문한 다른 개발자가 해당 오픈소스 코드를 이용하고 개선 가능
  • git init
# git init : 현재 위치한 디렉토리를 local repository로 생성
roheerumi@devops:~/devops/git_study$ git init
/home/roheerumi/devops/git_study/.git/ 안의 빈 깃 저장소를 다시 초기화했습니다

# 숨김 파일 확인
roheerumi@devops:~/devops/git_study$ ls -al
합계 12
drwxrwxr-x 3 roheerumi roheerumi 4096  3월 20 11:55 .
drwxrwxr-x 5 roheerumi roheerumi 4096  3월 20 11:55 ..
drwxrwxr-x 7 roheerumi roheerumi 4096  3월 20 11:55 .git
    • git status
      • staging area (tracked)
        • Git에서 변경된 파일들이 일시적으로 저장되는 공간으로  커밋(commit)할 파일들을 선택하고 변경 사항을 검토(review)하는 데 사용
      • work space (untracked)
        • 추적되지 않은 파일(untracked files)은 Git이 아직 추적하고 있지 않은 파일을 의미
        • 새로 생성된 파일 / .gitignore 파일에 명시된 파일
        • 스테이징 영역으로 추가되기 전에 git add 명령어를 사용하여 Git이 추적하도록 설정해야 
# git status : 내 로컬의 staging area, untracked files 확인
roheerumi@devops:~/devops/git_study$ git status
현재 브랜치 master

아직 커밋이 없습니다

커밋할 사항 없음 (파일을 만들거나 복사하고 "git add"를 사용하면 추적합니다)
  • git restore
    • commit 혹은 staged되지 않은 Local Repository의 변경 사항 폐기 (처음 clone 받아왔던 상태로 복원)
    • 명령어 사용법 : git restore <파일명>
  • git add
    • untracked files를 staging area로 추가해서 git의 관리하에 둠
    • 명령어 사용법
      • git add<파일명> : 내 로컬의 untracked file을 명시하여 staging area로 추가
      • git add . : staging area에 모든 파일을 한 번에 추가
  • git commit
    • 수정 작업이 끝났을 때 변경 사항을 저장
    • 명령어 사용법
  • Git의 세가지 영역 및 상태
    • 영역
      • untracked area : Git이 관리하고 있지 않은 영역
      • tracked area : Git의 관리 하에 있는 영역으로, Tracked area 내부에서도 세 가지 상태 분류
        • Commited :  기존에 Commit했던 파일을 수정하지 않은 상태
        • Modified : 기존에 Commit했던 파일을 수정한 상태 (빨간)
        • Staged : commit이 가능한 상태 수정한 파일을 commit 하기 위해서는 staged area에 add 하는 작업이 필요 (초록색)
  • git reset
    • local에서 commit한 내용을 취소할 경우 상숑
    • 명령어 사용법
      • git reset HEAD^ == git reset HEAD~1: 가장 최신 commit 취소
      • git reset HEAD3 == git reset HEAD^^^ 
    • 명령어 옵션
      • --hard
      • --soft
  • git push
    • local에서 변경, commit된 사항을 remote repository에 업로드
    • 원격 github repository가 존재해야 push 가능 (github.com에서 생성하고, 롤컬 리포지토리 디렉토리명과 동일하게 설정하는 것 권고)
      • public : 오픈 소스
      • private : 비공개
    • 원격 github repository 생성 후, local repository와 remote repository를 연결
    • 연결이 끝나고 나면, `git push` 가능
# 새 레파지토리 생성
…or create a new repository on the command line
echo "# git_study" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/username/git_study.git
git push -u origin main

# 존재하는 레파지토리를 푸시
…or push an existing repository from the command line
git remote add origin https://github.com/username/git_study.git
git branch -M main
git push -u origin main

# 다른 레파지토리를 import
…or import code from another repository
You can initialize this repository with code from a Subversion, Mercurial, or TFS project.
# local git repository에 git@~ 경로의 origin remote repository를 추가
roheerumi@devops:~/devops/git_study$ git remote add origin git@github.com:username/git_study.git

# stage 상태로 파일 추가 후 커밋
roheerumi@devops:~/devops/git_study$ git add test.js 
roheerumi@devops:~/devops/git_study$ git commit -m "첫 커밋 테스트"
[master (최상위-커밋) 4b2cb25] 첫 커밋 테스트
 1 file changed, 1 insertion(+)
 create mode 100644 test.js
 
 # 브랜치 이름을 main으로 변경
roheerumi@devops:~/devops/git_study$ git branch -M main

# origin remote repository의 main branch로 현재 local git repository를 push
roheerumi@devops:~/devops/git_study$ git push -u origin main
오브젝트 나열하는 중: 3, 완료.
오브젝트 개수 세는 중: 100% (3/3), 완료.
오브젝트 쓰는 중: 100% (3/3), 237 바이트 | 237.00 KiB/s, 완료.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:username/git_study.git
 * [new branch]      main -> main
'main' 브랜치가 리모트의 'main' 브랜치를 ('origin'에서) 따라가도록 설정되었습니다.
  • git log
    • 현재까지 commit된 내역들을 터미널 창에서 확인 가능
roheerumi@devops:~/devops/git_study$ git log
commit 4b2cb25d2f9f2ebd1f376e072dd9cff50d614b2e (HEAD -> main, origin/main)
Author: roheerumi <username@gmail.com>
Date:   Mon Mar 20 14:28:11 2023 +0900

    첫 커밋 테스트
  • github workflow overview
    • 과정
      • Remote에 있는 다른 Repository에서 Fork를 해서 Remote에 있는 내 Repository에 가지고 옴
      • 해당 코드를 내 컴퓨터에서 작업을 하기 위해서 clone
      • 내 컴퓨터의 작업 공간 (work space) 에서 작업에 들어간 파일들을 git의 관리 하에 있는 staging area로 올림
      • staging area의 파일을 commit해 내 remote repository에 push 해서 commit 기록을 remote 에도 남길 수 있음
      • push를 완료한 후 remote의 원래 레파지토리에 pull request를 보내면 Remote Repository로 내가 수정한 코드를 업로드
  • fork
    • 다른 계정의 remote repository를 내 계정으로 가져올 때 사용
    • 브라우저에서 github.com 접속하여 포크할 레파지토리를 포크해 옴
  • git clone
    • 원격 repository를 내 로컬에서 이용할 수 있도록 복사
    • 명령어 사용법
        • git clone <레파지토리 주소>
      # 내 원격 저장소에 저장한 레파지토리를 SSH 코드로 해서 내 로컬 저장소로 복사
      roheerumi@devops:~/devops/git_study$ git clone git@github.com:username/serverless-patterns-lambda-dynamodb.git
      'serverless-patterns-lambda-dynamodb'에 복제합니다...
      remote: Enumerating objects: 18, done.
      remote: Counting objects: 100% (18/18), done.
      remote: Compressing objects: 100% (15/15), done.
      remote: Total 18 (delta 0), reused 18 (delta 0), pack-reused 0
      오브젝트를 받는 중: 100% (18/18), 9.17 KiB | 9.17 MiB/s, 완료.
      
      # 해당 레파지토리 디렉토리로 이동
      roheerumi@devops:~/devops/git_study$ cd serverless-patterns-lambda-dynamodb/
      
      # 현재 상태 확인
      roheerumi@devops:~/devops/git_study/serverless-patterns-lambda-dynamodb$ git status
      현재 브랜치 main
      브랜치가 'origin/main'에 맞게 업데이트된 상태입니다.
      
      커밋할 사항 없음, 작업 폴더 깨끗함
      roheerumi@devops:~/devops/git_study/serverless-patterns-lambda-dynamodb$ git remote -v
      origin	git@github.com:username/serverless-patterns-lambda-dynamodb.git (fetch)
      origin	git@github.com:username/serverless-patterns-lambda-dynamodb.git (push)
      roheerumi@devops:~/devops/git_study/serverless-patterns-lambda-dynamodb$
  • pull request(PR)
  • 내가 push한 변경 사항에 대해 다른 사람들에게 알리는 것
  • 변경 사항 push 후 github.com 접속하면 compare & pull request 버튼 생성

 

3. 함께 작업 workflow

  • github workflow overview
    • 과정
      • 로컬 저장소에서 생성한 디렉토리를 init 명령어를 통해 Git의 관리하에 들어가게 만듦
      • 로컬 저장소의 Git 디렉토리를 Remote Repository와 연결
      • pair의 변경 사항과 나의 변경 사항을 Remote Repository를 통해서 공유
  • init
    • 기존 디렉토리를 git repository로 변환
    • 명령어 사용법 : git init
  •  remote add origin
    • 내 remote repository를 github에서 생성한 후 local repository와 연결
    • 명령어 사용법 : git remote add origin <나의 repository 주소>
  • remote add pair
    • 다른 사람의 repository와 연결하여 github repository를 공유
    • 명령어 사용법
      • git remote add pair <다른 사람의 repository 주소>
  • remote -v
    • 현재 local repository와 연결된 모든 remote repository 목록 확인 가능
    • 명령어 사용법
      • git remote -v
  • pull
    • remote repository의 작업 내용 가져오기, 받아오는 내용은 자동으로 병합
    • 명령어 사용법
      • git pull <shortname> <branch명>
    • pull 전략
      • default (merge) : 로컬 브랜치와 리모트 브랜치의 Head가 다른 위치에 있을 때, pull 받으면, Merge 커밋을 생성
      • rebase : 로컬 브랜치와 리모트 브랜치의 Head가 다른 위치에 있을 때, pull 받으면, 리모트 브랜치를 rebase 하여 history를 정리
      • fast-forward only : fast-forward 관계에 있을 때만 pull 을 허용
  • 충돌 해결하기
    • 같은 부분을 변경한 내용이 존재해 자동으로 병합할 수 없는 경우로 터미널 화면에 merge conflict, automatic merge failed로 확인 가능
    • git status 명령어를 통해 충돌 파일 확인 가능
    • 변경 방법
      • accept current change : 내가 수정한 내용으로 파일 반영
      • accept incoming change : remote repository 내용으로 파일 반영
      • accept both changes : 변경사항 모두 반영
      • 직접 파일 수정 반영
    • 수정을 마치면 병합 커밋을 위해 파일을 staging area로 추가(git add) 커밋(git commit), 이후 로컬 레파지토리에 푸시(git push origin master)
#################### 혼자 작업 ####################
# 김코딩이는 fork한 codestates 깃헙 리파지토리를 본인의 local에서 작업하려고 합니다. 복사한 깃헙 리파지토리 주소는 https://github.com/kimcoding/test.git 입니다.
git clone https://github.com/kimcoding/test.git

# local working directory에서 index.js 파일을 추가했습니다. 기존과 변경된 파일들이 어떤 것이 있는지 확인해 보려고 합니다.
git stastus

# local 의 index.js 파일을 staging area로 옮기려고 합니다.
git add index.js

# 내 깃헙 리파지토리에 'index.js 수정' 이라고 커밋 기록을 남기려고 합니다.
git commit -m "index.js 수정"

# 앗.. index.js 파일에서 오타를 발견했어요. 수정을 해야하는데 불필요한 커밋을 또 하고 싶지는 않습니다. 커밋한 기록을 되돌려서 이전으로 돌아가는 방법은 없을까요?
git reset HEAD^

# 수정을 완료했어요! 다시 index.js 파일을 staging area로 옮겨볼까요?
git add index.js

# 아까와 같이 'index.js 수정' 이라는 메시지로 커밋 기록을 남겨봅시다.
git commit -m "index.js 수정"

# 내 깃헙 origin 리파지토리의 main으로 푸쉬합니다.
git push origin main

# 내 커밋 로그를 확인하는 명령어를 입력해보세요.
git log


#################### 함께 작업 ####################
# 김코딩은 local working directory를 Git의 관리 하에 들어가게 해 주려고 합니다.
git init

# 혼자 작업을 조금 진행하고 commit 기록을 남겼습니다. 내 Remote Repository와 연결해서 Remote 상에도 이 코드를 적용해야겠어요. origin이라는 이름으로 내 Remote Repository를 등록하세요. 내 Repository 링크는 https://github.com/kimcoding/test 입니다.
git remote add origin https://github.com/kimcoding/test

# 페어와 함께 작업을 진행하려고 합니다. 지금까지 main 브랜치에 커밋한 기록을 방금 등록한 origin remote repository에 올려서, 페어에게 코드를 공유해야겠어요.
git push origin main

# 페어가 내 Remote Repository를 Fork 했다고 합니다. 페어의 Remote Repository를 내 Local에 pair라는 이름으로 등록해야겠어요. 페어의 리파지토리 링크는 https://github.com/pair/test 입니다.
git remote add pair https://github.com/pair/test

# 리모트 리파지토리가 잘 연결된 것이 맞는지 모르겠어요. 연결된 리모트 리파지토리의 목록과 주소들을 확인해 볼까요?
git remote -v

# 리모트 연결이 완료되었으니 페어와 나누어서 작업을 진행했습니다. 내 commit을 Push하기 전에 페어가 작업해서 본인의 Remote Repository에 올려 놓은 내용을 합치려고 합니다. 페어의 코드를 내 Local로 받아올 수 있을까요?
git pull pair main

# 특정 commit 시점으로부터 각기 다른 commit을 만들면, 기본적으로 다음과 같이 자동으로 merge가 됩니다. 이제 내 Remote Repository에도 Local의 내용을 반영합시다.
git push origin main

# 내가 footer.html 파일을 수정했습니다. 작업한 사항을 commit 하기 위해 먼저 staging area에 작업한 파일을 추가해주세요.
git add footer.html

# staging area에 파일이 추가되었습니다. 'footer 수정' 이라는 메시지로 commit 을 진행해주세요.
git commit -m "footer 수정"

# 페어도 footer.html에 변경한 사항이 있다고 합니다. 내 커밋을 Remote에 푸시하기 전에 페어의 코드를 내 컴퓨터로 받아올 수 있을까요?
git pull pair main

# 앗.. 하필 페어도 footer.html 파일의 동일한 라인을 수정했군요. 페어가 작성한 파일과의 충돌이 발생했습니다. 더 진행하기 전에 이 충돌을 해결해야만 합니다. 파일 내 충돌하는 부분은 다음과 같은 모양을 띄고 있습니다. (enter를 눌러 터미널 창에서 확인하세요. 터미널에 나오는 내용은 실제 터미널에는 나오지 않습니다. 여러분이 파일을 어떻게 수정할 지를 보여주는 예시입니다.)
# 충돌이 생긴 부분의 수정을 완료했어요! 다시 Remote Repository에 Push 하기 위해서 수정한 파일을 staging area에 추가해주세요.
git add footer.html

# 충돌이 해결된 후 staging area에 올라간 파일은 자동으로 commit 메시지가 생성됩니다. 자동 생성된 commit 메시지를 적용하는 명령어를 입력하세요.
git commit

# 다음과 같이 merge commit 메시지가 자동으로 생성됩니다. 이제 내 Remote Repository에도 Local Repository의 내용을 반영합시다.
git push origin main


#################### 브랜치 ####################
# Github 에서 공동 프로젝트 Repository를 생성했어요. 각자의 Repository로 Fork 하고 clone 을 받았습니다. 내가 맡은 회원가입 기능을 구현하기 위해서 feat/signup 이라는 브랜치를 생성하고 해당 브랜치로 이동해 볼까요?
git checkout -b feat/signup # 생성. -b 옵션 없을 시 이동

# feat/signup 브랜치를 만들었습니다. 생성한 브랜치 목록과 내가 현재 어떤 브랜치에 있는지 확인해 봅시다.
git branch

# 기본 회원가입 기능 구현을 완료했습니다! 여기에 추가로 페이스북으로 가입하기 기능을 만들고 싶어요. 구현해놓은 기본 회원가입 기능이 망가질 수도 있으니 feat/signup-oauth 브랜치를 하나 더 만들어서 작업해 볼까요?
git switch -c feat/signup-oauth

# 소셜 회원가입 기능까지 구현을 완료했습니다! 구현한 기능을 feat/signup 브랜치에 병합하려고 합니다. 먼저 feat/signup 브랜치로 이동하세요.
git checkout(switch) feat/signup

# feat/signup-oauth 브랜치의 내용을 feat/signup 브랜치로 병합하는 명령어를 입력하세요.
git merge feat/signup-oauth # merge는 현재 내가 있는 위치(HEAD)에서 수행

# 회원가입 기능 구현이 완료된 feat/signup 브랜치를 Remote Repository로 업로드하세요.
git push origin feat/signup

# 구글 로그인 기능도 추가를 해 보려고 시도하다가 어려워서 그만두었습니다. 작업하던 코드를 잠시 다른 공간에 저장해 둘 방법이 있을까요?
git stash
사진 출처 : 코드스테이츠 DevOps 과정, https://younho9.dev/git-config
Comments