ved_Rony
article thumbnail
Published 2021. 4. 16. 22:07
[코드잇 Git 강의] 노트 Git

프로젝트를 하다 보면 버전 관리는 필수적인 덕목이다.

개인적으로 프로젝트를 진행하며 버전 관리에 대한 중요성을 뒤늦게 나마 깨달아 git에 대해 공부를 하기 위해 코드잇 강의를 보며 강의노트를 만들었다.


git란?

  > 버전관리 프로그램이다. - 파일의 변화를 시간에 따라 정리하고, 특정 시간대의 파일을 가져오는 시스템이다.

  > 여러 개발자와 협업을 할수 있게 해준다.

  > 다른 컴퓨터에 작업물을 보낼수 있다. => 백업기능

    -> 외부컴퓨터를 제공해주는데, 거기에다 버전관리를 할 프로젝트를 올려두는 데 이것이 GitHub이다. 

장점

  1) 지난 과정의 확인 가능

  2) 이전 버전으로 돌아갈수 있음

 

repository & commit

 > 프로젝트를 만들 때 필요한 프로그램들을 담을 디렉토리가 필요하다. 이를 깃으로 프로젝트 디렉토리의 버전을 관리  하여 , 변화과정을 확인 할수있다. 이런 변화과정에 대한 정보를 저장하는곳이 repository이다. 

 > 프로젝트 디렉토리 안에 .git라는 파일이 만들어지는데, 이것이 repository의 정체이다.

 > 프로젝트를 하다보면 여러 변경사항이 생기는 데, 그중 하나의 특정 모습을 하나의 버전으로 만들고 싶다하면, commit이다. 

  -> 스냅샷 사진처럼 그 버전의 특정모습을 찍어서 넣는다 생각하면 편하다.

 > commit 이 저장되는곳 -> repository

 

repository는 어떻게 만드는가?

 > git init - 비어있는 repository를 생성한다.

  -> .git라는 파일이 생기고 .git 안에 버전관리를 위한 파일들이 생성된다.

본격적으로 버전 디렉토리 commit하기

 > git commit - 프로젝트 디렉토리안에 폴더를 생성하고, commit 해주기

   -> 커밋전에, 커밋하는 사람이 누구인가 알려주기

       1) git config user.name "~"

       2) git config user.email "~"

   -> 커밋을 할 파일을 지정해주기 (Untracked Files Present)

     - git add ~(파일이름)

       -> 이후 다시 커밋하면, 에러 x

 > 커밋에 메세지 남기기 git commit -m "~"

   -> 커밋을 할때 마다 변경사항에 대한 설명을 꼭 적어주자. 작은 습관처럼 보이지만, 미래의 나에겐 큰도움이  될것이다.

 

이제 Git의 작업영역들에 대해서 알아보려고 한다.

Git에는 3가지 작업 영역이 존재하는데 > (working directory, staging area, repository)

왜 이렇게 나뉘어져 있는 것일까? 이에 대한 대답은 차근차근 영역별로 나누어 공부하며 알아가 보도록 하자.

 

큰그림으로 보자면

working directory -> 쉽게 말해, 작업을 하고 있는 폴더

staging area -> git add를 한 파일들이 존재하는 영역. 즉, 깃이 인식하고 있는 프로젝트 디렉토리이다. 커밋을 할때 이 영역에 있는 파일들만 커밋에 반영이 된다. +) git status로 이영역을 확인 할수 있다

repository -> working directory의 변경이력들이 저장되는 영역. 즉, 커밋이 저장 되는 영역

 

요약하자면, working directory에서 뭔가 작업을 한다 -> git add를 해준다(staging area) -> commit을 해주면 repository로 작업내용이 들어가게 된다. ( 사실, working directory에 있는 .git파일이 repository이다. )\

 

+) git add는 어떻게 지울까? -> git reset ~

+) Git로 관리되는 파일은 2가지 상태를 갖는다. - tracked, untracked

untracked: 파일을 생성하고 add 하지 않으면 이상태이다.

tracked: 변동사항이 추적되고 있는 상태

       1) staged: 파일의 내용이 수정되고, staging area에 올라와 있는 상태. 즉, add가 된 상태

       2) modified: 최신 커밋과 변경사항이 있는 상태 

       3) unmodified: 최신 커밋과 다를게 없는 상태. 커밋을 하고 난 직후 working directory가 이상태이다.

github이란?

이전글에서 설명했다싶이, 따로 프로젝트 저장용 컴퓨터를 제공해주어서 업로드를 해줄수 있게 해주는 Git의 서비스라고 생각하면 쉽다.

- 작업하던 내용을 전송한다. 'repository에 전송한다'는 뜻

- 작업도 할수 있고, 버전관리도 가능하다.

How to use

- 작업하던 내용을 Github에 넣으려면 repository를 생성해야한다.

  -> Github에 있는 repository를 원격 repository 혹은 remote repository라고 하고, 컴퓨터에 있는 repository는 local       repository라고 한다.

*remote repository

  - 안전성이 높다( local repository가 사라져도 프로젝트는 건재하다.)

  - 협업이 가능하다

    -> 단, git push(local -> remote 밑에 글 참조)는 아무나 가능한 것이 아닌데, setting에서 Manage Acess를 들어가 collaborator를 지정해주면 된다.

 

- repository를 처음 만들면,

  1) local repository를 만드록, 커밋을 한후 올리는법

  2) 이미 만든 repository를 업로드 하는 법이 있다. 

 

커밋의 히스토리

-commit 탭을 누르면 history 확인을 할수있다.

 

-local repository 변경내용을 remote repository에도 반영하기

 -> working directory에서 변경사항을 git add . 해준다. 그다음, git commit -m "~" 

    매우 중요!!

     => staging area에 올려준 다음에, local repository에 변경사항을 commit 하는 과정이다.

 ->  git push를 해줌으로서, local -> remote로 전송 +) git push -u origin master 로컬에서 리모트로 처음 올릴때 사용

 

+ README파일은 그 파일의 내용을 설명해주는데, 프로젝트에 대한 개요를 잘 설명 해주는 게 중요하다.

   

- remote repository 변경내을 local repository에도 반영하기

 -> 예를 들어, gitgub에서 코드내용이 수정될 때, 이때에도 커밋을 해준다

 -> git pull을 해줌으로서, remote -> local로 커밋

 

- 커밋 히스토리 확인하기

 git log -> 모든 히스토리 확인가능

 git show [commit id일부] -> 이전 커밋과 이후 커밋을 보여줌

 git commit -> -m 없이 입력하면 수정 창이 나오는 데 i키로 수정하고, esc 누른후, ;wg입력하여 나온다.

 

- 최신 커밋 수정하기

 워킹 디렉토리에서 수정한 내용을 저장하고, git add . 후에 git commit --amend하고 다시 remote에 git push 해주면 된다.

 

-commit 작성요령

 -> commit 에는 3가지 정보가 들어가야 한다.

   1) 커밋을 한 사용자 아이디

   2) 커밋한 날짜, 시간

   3) 커밋 메세지

      -> 제목과 설명 사이에 한줄 띄워준다.

      -> 왜 커밋을 했는지, 무슨 문제가 있었고, 해결책이 어떤 효과를 갖는 지

      -> 하나의 이슈에 대한 해결내용만

      -> 에러가 없는 경우에만 커밋한다

 

- git log 꾸미기

  ->  git log --pretty=oneline 이쁘게 보여준다

  -> aliasing 하려면, git config alias.history 'log --pretty=oneline'

     -> 특정 디렉토리에만, 적용이 되는 데 그 디렉토리로 가서 cat.git/config으로 설정 확인 가능 

  

- 두 커밋간의 차이점 보기

 -> git diff [commit id 1] [commit id 2] 

 

- HEAD

   -> git log를 보면 HEAD가 나오는데, 어떤 커밋 하나를 가리킨다.( aliasing을 하면, 예로 위처럼 history로 한다면 git       history로 보기 편하게 확인 할 수 있다.

   -> 만약에. HEAD가 최근이 아닌 이전 커밋을 가리킨다면, working directory의 내부 구성도 바뀐다.

 

- 이전 커밋으로 돌아가기

  -> git reset [옵션] [commit id]

  -> 옵션에는 세가지 있다

  working directory staging area repository
soft 안바뀜 안바뀜 Head가 해당 커밋을 가리킴
mixed 안바뀜 그커밋 처럼 바뀜 Head가 해당 커밋을 가리킴
hard 그커밋 처럼 바뀜 그커밋 처럼 바뀜 Head가 해당 커밋을 가리킴

 * git reset --soft후, git status로 가장 최근과 이전커밋의 차이가 있는 파일도 보여진다 -> staging area는 그대로 이기 때문

 

- reset이후 복구

  -> git pull - github에서 이전 버전을 끌어오기 때문이다.

- 커밋아이디에 태그 달아주기

  -> git tag [태그이름] [커밋아이디] => 프로젝트 이력확인 할때 도움된다.

branch란?

 하나의 소스관리 흐름이다. 사실, 이친구도 어떤 포인터를 가리키는 존재인데, 여기서 Head와 브랜치의 차이란 무엇인가? 라는 의문이 든다.

 

  • 마스터 브랜치 - repository를 만들고 커밋을 하면 생기는 기본 브랜치
  • 브랜치를 만드는 법 - git branch [브랜치 이름]
  • 해당 브랜치로 이동하는 법 - git checkout [브랜치 이름]
  • 브랜치 이동후 working directory에서 파일을 수정하고 add, commit을 하면 내용이 바뀐다. 하지만 다른 브랜치에선 내용이 바뀌지 않는다.
  • 브랜치 확인 하는 법 - git branch
  • 브랜치 지우는 법 - git branch -d [브랜치 이름]:  브랜치 지우기
  • 브랜치 생성후 바로 이동 - git checkout -b [브랜치 이름]
  • 현재위치의 브랜치에 다른 브랜치 합병 - git merge [합치고자 하는 브랜치 이름]
  • merge중 conflict가 발생했을 때 - 수정후 다시 git add -> git commit (머지의 결과가 되었으면 하는 모습으로 수정후에 커밋해야한다)
  • conflict 해결안하고 이전 커밋으로 돌아가기 - git merge --abort
  • 여러파일에 conflict - 하나씩 수정후 git add [파일이름] 후 커밋 (중간중간 git status로 확인)
  • master브랜치와 또다른 branch를 push 하기 - master 브랜치는 처음 생성될때 remote repository에 tracking을 설정하기위한 set-upstream 옵션이 사용됐기 때문에 git push만 해줘도 되지만, 다른 브랜치를 push 하려고 할때, 처음 푸쉬를 한다면 git push --set-upstream origin [브랜치이름]하면 된다.
  • 매번 커밋이 생길때마다, 마스터 브랜치는 그새로운 브랜치를 가리키게 된다.

HEAD는 보통 branch를 가리키게 되는데, 따라서, 브랜치가 움직이면 HEAD도 같이 움직이게 된다.

 -> 만약에 어떤 커밋 상태에서 새로운 브랜치를 만들고 Head를 그곳으로 움직이고 다시 커밋하면, 그 HEAD와 branch는 새로운 커밋으로 이동하게 된다. 전브랜치는 움직이지 않게 된다. 그러고 다시 HEAD를 전 브랜치로 옮기고 또 commit 을 하게 되면 분기하게 된다.

 

 -> merge란 결국 Head가 가리키던 commit에 다른 브랜치가 가리키던 커밋을 합쳐서 새로운 커밋을 만드는 작업이다

   HEAD +(merge) Branch = new Commit

 -> HEAD가 브랜치를 통해서가 아닌 직접 특정 커밋을 가리킬수 있는데, 과거 특정 커밋에서 새로운 브랜치를 만들고 싶을때 사용된다. (Detached Head) - git checkout로 HEAD가 직접 커밋을 가리키게 할수 있으며, 직접 브랜치를 가리키게도 할수있다.

 

reset checkout
HEAD가 가리키던 브랜치가 다른곳을 가리키게 한다 HEAD 자체가 움직임
HEAD도 결국 간접적으로 다른 커밋을 가리킴  

merge의 종류 - 3way, fast-forward

  • fast-forward - 커밋이 같은 선상에 있을때, 이전 커밋에 브랜치가 있으면 현재브래치를 그 브래치까지로 빨리 감기
  • 3way - 커밋히스토리 상에서 분리된 2개의 선에 각각 브랜치가 존재하여 merge할떄 -> 분기점 (1개), merge되는 브랜치(2개)가 가리키는 두 커밋 (이래서 3way) -> 분기점을 기준으로 차이점이 있는 것을 update. 둘다 차이가 있으면 conflict 발생

local repository -> remote repository로 프로젝트를 넘길때, push

remote repository -> local repository로 프로젝트를 넘길때, pull

 

local repository 수정중에, remote repository에 수정 사항이 생겼다면, git push를 할수 없다.(다른 사람의 업데이트가 날아 갈수 있기 때문이다.) 따라서, git pull을 먼저 해줘야 한다.

 -> conflict가 발생한다면, merge 상황에서 했던 conflict 수정하듯이 하면 된다. 필요없는 부분 지우고, 파일 저장후 git add ->   commit 하고, 다시 push

 

git pull이란, remote repository에 있는 브랜치를 local repository에 가져온다. (브랜치가 가리키고 있는 이전의 모든 커밋들을 가져오는 것- 검토없이 바로 합치고 싶을 때) 이때, git fetch를 하면 merge를 안하고 코드만 가져올수 있는데, 이경우 브랜치내용을 일단 가져온후, 살펴본후에 merge할때 유용하다.(검토)

 

두 커밋간의 차이를 확인할 때 - git diff

 

remote repository에 문제가 생겼을 때, 잘못된 부분 수정후 다시 git push함. merge 하고 다시 커밋(?)

 

어떤 부분의 코딩을 누가 썼는지 알고 싶을 때 - git blame [파일이름] (git show [commit id] 더 자세히 나옴)

 

이미 remote repository에 올라온 커밋을 취소하기 - git revert [commit id] (해당 커밋을 취소하지만 revert에 대한 커밋이 생겨서 history상에서 볼수있다. 그걸 다시 commit을 하면 HEAD가 local, remote와 같은 선상에 존재한다)

 

git reset vs git revert - reset -> remote 와 로컬이 있을때, remote는 그대로  local은 이전 커밋으로

revert -> remote는 그대로, local에서 한단계 높은(그 다음으로의) 커밋으로 간다.

 

한번에 여러 커밋 취소하기 - git revert [commit id]..[commit id + n] 커밋아이디 +1 부터 n번째 까지 취소한다.

 

git reset을 하고 나면 HEAD가 가리키던 브랜치를 옮긴다. 그렇다면, 브랜치가 옮겨진후 상위 커밋들은 어떻게 되나?

 -> 삭제 되지는 않는다. 가장 최신의 commit으로 돌아가려면? git reset [옵션] [commit id] or git reflog(HEAD가 여태까지 가리켜온 커밋들의 정보를 알려준다. HEAD가 가리켰던 commit id를 확인할 때 유용하다.)

 

git rebase [merge하고 싶은 branch 이름] -> conflict 수정후 -> git add . -> git rebase --continue =>리베이스 계속 진행

 

rebase vs merge (결과물은 같다) - rebase는 새로운 커밋을 만들지 않는다.

rebase로 만들면 history가 훨씬 깔끔하다.

두 브랜치가 병합했다는 정보가 필요한 경우 ->  merge

깔끔한 히스토리 -> rebase 

 

작업한 내용 임시 저장하는 법

 - 작업하던 중 다른 브랜치로 이동하면 작업하던 내용이 사라질수도 있기 때문에, git stash(stack에 작업 내용을 저장)로 저장할수 있다.

 git stash -list로 작업내용 리스트 확인

 git stash apply - 스택에 있는 내용을 다시 working directory로 가져와 적용

 

git stash를 사용하는 다른 경우 - 잘못된 브랜치에서 작업을 하고 있었을 때

 git stash로 스택에 내용을 저장하고, 올바른 브래치로 이동해서 git stash apply를 해준다.

 필요없는 작업 내용은 git stash drop [stash list id]

 git stash pop - apply해줌과 동시에 drop해준다.\

 

필요한 커밋만 가져오는 법 - git cherry-pick - 자신이 원하는 커밋들만 가져와 현재 브랜치에 추가 하는 법

profile

ved_Rony

@Rony_chan

검색 태그