버전관리의 첫 시작

버전 관리의 큰 그림

GIT 설명

GIT: 버전 관리 시스템 중 하나

버전 관리 시스템

버전: 게임에서 말하는 버전과 동일한 의미

하나의 유의미한 변화가 결과물로 나온 것

즉 패치도 버전을 의미하는 것이 맞음

___________________________________________

버전을 만들 때는 누구는 캐릭터 생성, 누구는 버그 수정 등 여러명이서 함께 이룸

하나의 버전을 관리하는 과정에서 협업이 필요할 수 있다

___________________________________________

만약 새 버전을 만들었는데 별로면 다시 그전 버전으로 돌아가야함

하나의 버전을 관리하는 과정에서 되돌리는 과정이 필요하다

___________________________________________

그때그때 수정될 때 마다 전체를 다 백업할 수 없으니 유의미한 변화만을 중심으로 효율적인 백업을 해야 함

하나의 버전이 관리하는 과정에서 효율적인 백업이 필요하다.

___________________________________________

버전관리

1. 협업

2. 되돌리기

3. 효율적인 백업

___________________________________________

이런 작업들을 해주는게 GIT 이다.

GIT 을 통해 하나의 버전이 만들어지는 과정

2가지로 나뉨

1단계 워킹디렉터리 -> 스테이징 에어리아

2단계 스테이징 에어리아 -> 레퍼지토리

___________________________________________

코드를 담은 파일을 하나의 버전으로 만들어 관리할 것.

이 코드를 담은 파일이 버전이 되기까지 거쳐가는 세개의 공간이 있음

공간 1. 워킹디렉터리(Working directory)

- 내가 코드작업을 하는 공간

- 파일들이 생성, 수정, 삭제되는 공간

- 즉 변경사항이 생기는 공간

공간 2. 스테이징 에어리아(Staging Area)

- 버전이 될 후보들이 올라오는 공간

- Working directory에서 선별

공간 3. 레퍼지토리(Repository)

_________________(정리)______________________

워킹디렉터리에서 만들어지는 모든 파일을 버전으로 만들 필요가 없음.

따라서 스테이징 에어리아에서 만들 버전을 선별.

만들 버전을 저장소로 보냄.

저장소는 여태까지 만들어왔던 버전들이 차곡차곡 저장되어 있음.

git 명령어 소개

모든 git 명령어는 git<명령어> 로 작성해야 함

워킹디렉터리 -> 스테이징 에어리아 로 옮기는 명령어

git add

스테이징 에어리아 -> 레퍼지토리 로 옮기는 명령어

git commit

버전을 만들어보자

git 을 시작할 때 무조건 해야하는 것

의미: 이 폴더 안에서 버전관리를 시작할 것이다

명령어: git init

___________________________________________

입력 시 숨김 폴더 .git 이 생성

만약 안보인다면 사용하는 명령어

명령어: ls -al

버전관리를 하는 현 폴더의 상황을 알려주는 명령어

명령어: git status

메모장 test.txt를 저장 후 사용하면

입력하면 새로 생겼지만 어디서 생긴지 모르는 test.txt 파일이 있습니다. 라고 뜸

___________________________________________

이 test.txt를 스테이징 에어리아로 옮기려면

명령어: git add test.txt

___________________________________________

현재 내 위치에 있는 모든 변경사항들을 스테이징으로 옮겨라

명령어: git add .

___________________________________________

스테이징 에어리아에서 저장소로 옮길 때

자세하게 메세지 작성: git commit

짧게 메세지 작성: git commit -m "commit message"

1. git commit -m "commit message"

commit message란 버전들이 점점 쌓이면 찾기 힘듦. 따라서 어떤 변경사항이 생겨서 이걸 옮겼는지 간략히 작성하는 곳

조금 더 commit message를 자세하게 적고싶으면

2. git commit

commit message를 자세하게 작성할 수 있는 창으로 넘어감

___________________________________________

지금까지 만들어진 commit 확인 방법

명령어: git log

___________________________________________

*** 스테이징에어리아, 디렉터리 확인은 status로 가능하지만 저장소에 있는 버전 확인은 log를 사용해야 하는 듯 ***

hello, github!

git commit 명령어를 통해 버전을 만들면 그 버전은 내컴퓨터에만 저장이 되어 내 컴퓨터 내에서만 사용할 수 있는데 그렇다면 다른 사람들과 어떻게 원격으로 협업을 할 수 있을까?

=> github

___________________________________________

GitHub

각 컴퓨터에만 존재하는 버전을 저장/관리 해주는 서비스

github에 코드를 업로드 하는 행위: github에 push한다

___________________________________________

인터넷 세상 어딘가의 (github가 관리하는) 컴퓨터의 저장소: 원격 저장소

내 컴퓨터의 저장소: local 저장소

___________________________________________

github에 push하면 마지막 버전만 저장되는 것이 아닌 지금까지의 모든 버전들이 백업됨.

이것이 네이버클라우드 처럼 다른 서비스들과의 차이점

github 회원가입, 둘러보기, 내 코드 push하기

github 홈페이지에서 저장소를 만들 때

create repository 클릭

후에 readme에 파일 추가는 선택 x

git을 github에 push하는 법

1. 파일 생성

2. 버전으로 만들기 (commit 까지 완료하기)

3. 버전을 업로드(code -> 아래에 적혀있는 세줄의 git 명령어를 복사 후 git 터미널에 복붙하면 저장됨)

___________________________________________

만약 파일1을 버전으로 저장한 후 파일2로 내용을 수정한다면 status를 사용했을 때 수정이 되었다고 뜸 그럼 다시 commit으로 추가해야 함

만약 파일 2를 hub에 업로드까지 했는데 파일3이라고 내용을 수정하면 다시 commit으로 추가해야함 그리고"" 명령어: git push ""라고 작성하면 업로드 됨.

이때 모든 변동사항 버전은 저장되어있음 (파일1,2,3)

 

버전을 되돌리고, 나누어 관리하자

git으로 되돌리자

되돌리는 명령어

명령어: $ git reset

___________________________________________

어디까지 되돌릴지에 따라 세가지로 분류

1. 수정한 것 까지 통째로( 쎄게 되돌리자)

$ git reset --hard HEAD^

2. add한 것 까지 (적당히 되돌리자)

$ git reset --mixed HEAD^

3. commit 한 것만 (살짝만 되돌리자)

$ git reset --soft HEAD^

___________________________________________

옵션 생략할 경우 2번으로 적용됨

HEAD: 가장 최근 버전에서

^: 하나 되돌리자

EX) 가장 최근 커밋에서 두개 전으로 되돌려라

-> $ git reset --hard HEAD^^

reset 실습

GIT 말고 visual studio code에서 실습해도 됨 (터미널에서)

//파일에 내용 test 라고 작성
git init  //시작
git add test.txt              //test파일 옮기기
git commit -m "first"    //test 파일 저장소로 보내기

//파일에 내용 test2 라고 작성
git add test.txt
git commit -m "second" 

git log                           // first와 second 두가지가 나옴

//삭제할 때는
git reset --hard HEAD^
git reset --mixed HEAD^    //기본값이라 작성안해도 됨
git reset --soft HEAD^

나누어 관리하자

Branch: 작업을 단위로 나눈 후 각자 작업한 후 합친다

이때 나눈 작업 단위가 브랜치

branch 실습

git init 을 작성하면

자연적으로 master branch 라는 브렌치에 속하게 됨

다른 브랜치가 뻗어나가는 태초의 브랜치

__________________________________________

처음부터 branch 하려면 나오지않음

한번이라도 commit 한 후 사용해야 함

branch 만드는 명령어

명령어: git branch <브랜치 이름>

ex) git branch my_branch

_______________________________________

내가 만든 branch 목록 보는 명령어

명령어: git branch

이때 초록색 글씨는 내가 있는 브랜치

_______________________________________

새 브런치로 옮겨 들어가는 법

명령어: git checkout 브랜치 이름

ex) git checkout my_branch

_______________________________________

매우중요!!!!!!!!!!

처음 master 브랜치에 파일1 생성 후 커밋 완료

branch 브랜치 생성

트리모양 구조이기 때문에 branch 에도 파일1이 포함

branch 브랜치에서 파일2를 생성 후 커밋까지 완료

branch 저장소에는 파일1, 파일2 존재

정리

마스터 브랜치: 파일1만 저장소에 존재

브랜치 브랜치: 파일 1,2 저장소에 존재

각자 따로 작업했다고 가정시 마지막 병합하는 법

합치기 전 어떤 브랜치를 어디로 합칠지를 확실히 해야함

병합의 결과가 되는 대상에게 checkout 

___________________ex____________________

상위가 a라고 가정 시

a브랜치에 b브랜치를 합칠 때

git checkout <병합의 대상인 브랜치 이름>  

git merge <합치려는 브랜치 이름>

ex)

git checkout a

git merge a

추가자료 - diff & revert

git diff: 변경 내역들끼리 비교결과를 보여줌

ex)

현재 스테이징 에어리아에 있는 변경 내역과 직전의 커밋을 비교

a브랜치에 있는 커밋과 b브랜치에 있는 커밋을 비교

_____________________________________________

ex) 한 저장소에 text.txt파일이 있고 이에 대한 커밋이 1~5까지 있을 때

명령어: git diff 비교대상커밋 기준커밋

( 비교대상 커밋에 비해 기준 커밋은 무엇이 달라졌니?)

________________________________________

예시

$ git log
commit f7fe32715c4bd705110196134271d8f873384316 (HEAD -> master)
Author: Kang Minchul <tegongkang@gmail.com>
Date:   Tue Dec 1 23:06:03 2020 +0900

    5

commit 2845ce53054627b3381c9f2515dc7545cff2347b
Author: Kang Minchul <tegongkang@gmail.com>
Date:   Tue Dec 1 23:05:49 2020 +0900

    4

git diff f7fe32715c4bd705110196134271d8f873384316 2845ce53054627b3381c9f2515dc7545cff2347b

___________________________________________

이때 보이는 결과 창

$ git diff 2845ce53054627b3381c9f2515dc7545cff2347b f7fe32715c4bd705110196134271d8f873384316
diff --git a/test.txt b/test.txt
index 8422d40..8fda00d 100644
--- a/test.txt
+++ b/test.txt
@@ -2,3 +2,4 @@ A
 B
 C
 D
+E          # 4번 Commit에 비해 E라는 문자열이 추가되었다(+ 표시)

브랜치 끼리 비교

git diff <비교대상 branch 이름> <기준 branch 이름> 

원격 저장소와 로컬 저장소끼리의 비교

원격: github

로컬: 내컴퓨터

git diff <비교대상 branch이름> origin/<branch 이름> 

이전 commit 과 전전 commit 비교

git diff HEAD HEAD^
위에 있는 것 처럼 작성해도 되지만 너무 길어서 복잡할 때 사용하는 방법. 꼭 이렇게 할 필요는 없음

이전 커밋과 현재 수정된 내용 비교

git diff HEAD

위에 나와있는건 현재가 아닌 모두 다 이전 커밋들

지금 하는 건 현재 커밋과 이전커밋 비교

__________________________________________

test파일에 f 문자 추가 후 git diff HEAD 작성하면 

+f 라고 나옴

revert 란?

git revert 또한 reset 과 동일

명령어: git revert <되돌아가고싶은commit>

ex)
git revert de6d5c1148981e15617999c7ecaa6ec2ea21ff29

_________________________________________________

revert와 reset과의 차이점

되돌리는 커밋까지의 이력이 사라지냐 안사라지냐의 차이

reset은 되돌리면 되돌린 버전 이후의 버전이 다 사라짐

revert 는 모두 유지되며 revert되었다는 사실이 담은 새 커밋이 추가됨

___________________________________________

ex) 중요!

3번 커밋으로 reset: 4,5번은 사라지고 3번으로 이동

3번 커밋으로 revert: 4,5번 모두 유지되고 3번으로 이동

원격저장소(Github)를 이용하여 협업하기

로컬과 원격의 상호작용

원격 저장소(GITHUB컴퓨터 저장소)는 그저 또다른 저장소(레퍼지토리)라고 이해하기

협업 : 리퍼지토리끼리의 상호작용

상호작용(협업)의 종류

  1. 원격저장소 조회(추가)하기          -- $git remote
  2. 원격 저장소에 밀어넣기                 -- $git push
  3. 원격저장소 갖고와서 합치기         -- $git pull
  4. 원격저장소 일단 갖고만 오기        -- $git fetch
  5. 원격저장소 복사하기                      -- $git clone

$git remote(-v)

내 로컬 레퍼지토리와 상호작용하고 있는(혹은 할수있는) 원격 저장소들의 목록을 조회

-v: 단축이름과 url 같이 보기

$git remote add <단축이름> <url>

: <url>에 있는 원격저장소를 단축이름이라는 이름으로 추가하기

이 git 명령어는 내 저장소와 상호작용할 원격저장소를 더하는 명령어고 더할 원격저장소 이름은 단축이름, 그거의 url은 이거다

$git push -u origin master

내 레퍼지토리의 master 브랜치를 origin의 master브랜치로 push해라

-u: 디폴트 설정

앞으로 인자를 사용안해도 알아서 디폴트 값으로 origin과 master의 상호작용으로 알아들어라

즉 $git push라고 작성해도 됨

___________________________________________

push는 로컬저장소에서 원격저장소로

pull은 원격저장소에서 로컬저장소로

___________________________________________

$git pull(origin master)

origin을 내 레퍼지토리의 master 브랜치로 갖고와라 (merge)

*** 내가 현재 작업하고 있는 내용은 사라짐. 덮어씌우는 거라서 ***

사라지는게 싫다면 fetch사용

___________________________________________

$git fetch(origin master)

동기화시키지는 말고(merge하지는 말고) origin을 내 레퍼지토리의 master 브랜치로 일단 갖고만 와라

___________________________________________

$git clone <url>

<url>에 있는 원격저장소 내용을 현재 디렉토리에 복사해오기

*origin 자동 생성

로컬과 원격의 상호작용 실습 (+충돌이 난 경우)

git init                                  //git 시작하기
git add hello.txt                   //파일을 스테이징 에어리아로 옮기기
git commit -m "first"           //파일을 내 컴퓨터 저장소(레퍼지토리)로 옮기기
git log                                 //저장소에 있는 내 버전들 조회하기

first                                      //조회 결과로 first 파일이 나옴


git remote                           //현재 내가 등록할 수 있는, 등록한 원격저장소 목록 보여줌
                                           //아무것도 등록하지 않아서 아무것도 안나옴

git remote add practice1 https://github.com/ssy2253/remote-practice1.git     
                                          // practice1이라는 원격저장소를 추가할거고 그거의 url은 이것이다

git remote                                  // git remote 사용 시 practice1이 출력됨
practice

git remote rm practice1            //추가한 원격저장소를 지우는 방법은 git remote rm 저장소이름
 
git push -u practice1 master    //git을 원격저장소로 버전을 옮기는 방법은 git push -u 저장소이름 브랜치이름 
                                                 //즉, practice1 저장소에 이 로컬저장소의 master브랜치에 있는 내용을 push할거야. 그리고 이건 디폴트값으로 저장할거야(-u)

                                              //원격저장소에 가서 새로고침을 하면 hello.txt 버전이 업로드 되어있음


*** hello.txt파일을 수정 후 다시 업로드 해야할 때는 commit 까지 완료한 상태에서 이미 practice1과 master이 기본값이기 때문에 git push만 입력하면 됨 ***


pull 사용하는 방법

새로운 폴더에서 새 파일을 생성한 후
git init
git remote add origin url    //origin 이라는 원격저장소와 이 url을 추가하자
                                             이때 url은 내가 추가하고 싶은 버전이 있는 원격저장소와  url을 작성해 연결시키기
                                              즉 정리해서 이미 원격저장소에 내용이 추가가 되어있는 파일이 있음 나는 그걸 현재 내 폴더에 덮어씌우고 싶음
                                              그렇다면 내 폴더와 연결하고싶은 원격저장소를 remote로 연결시킴 그 후 pull 을 사용해 덮어씌움

git remote -v                        // 잘 되었나 조회하기

git pull origin master           // origin 원격 저장소의 내용을 master 브랜치에 덮어씌울거야
                                             // 파일 확인하면 내용이 덮어씌어져있는게 보임

그럼 반대로 원격저장소에서 내용을 바꿔버린다면?

로컬 저장소의 파일 내용은 수정 전 상태임

그럼 둘을 동기화하기위해 git pull origin master 

작성하면 또다시 동기화됨

fetch 는 일단 가져오기만 함

ex)

원격저장소에서 파일 내용을 수정함

아직 내 로컬저장소 파일 내용은 수정 전 상태

그 후 fetch를 하면

git fetch origin   //origin 의 내용을 펫치할거에요

그 후 내 로컬저장소 파일을 다시 봐도 내용이 수정되어있지는 않음 

하지만 특정 브랜치에서 확인할 수 있음

우리는 현재 마스터브랜치에 있고 펫치한 내용은 origin의 마스터 브렌치에 존재함

때문에

git checkout origin/master

또는 git checkout FETCH_HEAD

그 후에 내 로컬저장소의 파일에 가면 수정내용이 있음

확인을 다했다면 다시 되돌아와야함

git checkout master

git clone  url 을 작성하면 그 원격저장소의 내용이 복사됨

협업의 시나리오

만약  github를 혼자쓴다면 내가 바꾸지않으면 아무것도 변하지않음

하지만 여러명이라면 내가 바꾸지않아도 원격저장소의 내용이 바뀔 수 있음

때문에 3가지로 협업을 분류 가능

1. 내 로컬의 변화o 원격의 변화 x

2. 내 로컬의 변화x 원격의 변화 o

3. 내 로컬의 변화o 원격의 변화o

1번의 경우

내 로컬 o 원격 x

그냥 코드 작성 후 push 해버리면 그만

2번의 경우

내 로컬 x 원격 o

git pull origin master 로 동기화 후 코드를 작성한 후 push를 함

___________________________________________

pull request

1. 로컬에 새 브랜치를 만듦

2. 새로 만든 브랜치에 하고싶은 코드 마음껏 작성

3. 브랜치를 commit 함.  즉 버전으로 만듦

4. 이 버전을 원격저장소에 pull 해달라고 요청하기 - pull request

5. 원격 저장소를 관리하는 사람이 이걸 승인해주면 이게 merge가 됨.  즉 반영이 됨

3번의 경우

내 로컬 o 원격 o인 경우

1. rebase

2. pull request (-> merge)

협업하기(1) - 로컬은 변함없는데 원격이 변한 경우

내 로컬 변화 x 원격 변화 o

git init

git pull origin master

git push -u origin master   //안확실

만약 내가 3번째 줄 내용을 추가하고 원격에서도 누군가가 3번째 줄에 내용을 추가했다면 

git push를 사용했을 때 에러가 뜨면서 push가 안됨

pull을 해도 안됨

협업하기(2) - 로컬도 변했는데 원격도 변한 경우

공유하는 방법

1. 개별 초대

github에서 collaborators를 들어가 유저이름 혹은 이메일을 작성하면 초대메일이 가면서 이 저장소에 대해 push를 할 수 있는 권한이 생김

2. pull request (대규모에서 많이 함)

1. 협상 대상 레퍼지터리 fork 하기

2. 내 계정을 누르기 (내 계정 내용이 복사가 됨)

3. 내 계정 아래 co-practice가 생김

4. fork 해온 곳에서 clone (복사) 해오기

** 원래 계정이 아닌 fork 한 계정에서 clone을 해야함 **

복사할 폴더에서 git을 들어가 git clone url 작성해 복붙

5. 브렌치를 만들고 작성하고자 하는 코드 작성하기

git branch 브랜치이름

브랜치 지우는 방법

git branch -d 삭제할브랜치이름