개발공통/Git과 SourceTree

원격저장소(github)
  - 가입 후 저장소를 만들고, 저장소 http를 복사해놓자
  - 소스트리에서는 Add Remote를 통해 로컬저장소에다가 원격저장소를 연결시킨다.(Remote-origin)
  - 소스트리에서 로컬저장소 내용은 Push해준다.

Clone : 새로운멤버가 프로젝트를 다운받는 것. 대신 폴더명에 작업자를 기재해준다.
  - 원격저장소(github)의 Repository의 Clone with HTTPS 주소 복사
  - 소스트리의 새 탭에 Clone - [ Url 복붙 ] + [ Destination - Browse]를 통해 로컬저장소의 <작업자명의 폴더 생성> / Open in Explorer를 통해 파일 확인

만약 같은 컴퓨터라서 Author를 다르게 지정하는 법
- git config user.name "new"
- git config user.email "new@gmail.com"

Pull : 원격저장소의 버전을 가져오는 것.
  - 작업시작하기 전 / 작업을 Push하기 전 2회에 걸쳐서 해줄 것.
  - 만약 pull안하고push해서 거절당하면, pull을 해서 병합 버전부터 만들어줘야한다.
  - 만약 pull시 충돌이 일어난다면, 충돌해결과정 [직접파일수정 -> Mark Resolved -> commit ]을 거쳐야한다.

----
기존 만들어진 안드로이드 프로젝트의 상위폴더에 github 연결방법
1. 소스트리에서 상위폴더를 생성 -> github저장소 생성 -> 상위폴더에 Add Remote로 연결 -> 각 하위폴더(프로젝트들)을 안스에서 Enable VCS 적용


기존의 상위프로젝트 전체를 github 연결방법

1. 상위프로젝트 우클릭> git Bash - git init 입력 -> 소스트리에서 Add가능 -> github에 저장소 생성 후 https복사 -> 소스트리에서 remote 연결
(상단 Repository > Repository setting > remote 


git 연결해제 및 히스토리 삭제

해당 폴더의 숨김폴더 .git을 삭제하면 됨

현재까지는 로컬에서 원격저장소로 파일을 업로드하는 Push를 했었다.

하지만 새로운 멤버가 프로젝트에 참여했다고 가정해보자. 그 멤버는 원격저장소에서 로컬저장소로 다운로드해야하는 Clone(복제)을 해야한다.


원격저장소의 소스코드를 Clone하여 --> 소스트리에서 Clone Respository를 통해 새로운 로컬저장소에 다운로드 하게 된다.


새로운 멤버가 Clone하기


이 때, 현재 로컬저장소의 이름은 [operntutorials_git]이다.
새로운 협업자는 [operntutorials_new]라는 이름으로 작업을 할 것이라 가정하고 진행해보자.( _뒤에 작업자 이름을 붙힌다)
  • 소스트리에서 새로운 탭을 만들고, Clone을 선택하자.
    imageimage

  • 원격저장소의 프로젝트에서, Clone with HTTPS 을 통해 https url를 복사해온 뒤, 첫번째 칸에 붙혀넣자

    image


  • Destination Path는 원격저장소의 프로젝트를 저장할 로컬저장소의 위치이다.
    이 위치를 지정하면서, 새로운 작업자의 이름을 붙힌 폴더명으로 수정해준다.
    Browse를 눌러서, 프로젝트를 모아둔 폴더에 간 뒤, 새로운폴더[opentutorials_new]를 만들어서 저장해주자.
    image
    image


  • 원격저장소의 프로젝트를 Clone해서, 새로운작업자의 이름으로 복제하게 되었다.
    [ Open in Explorer ] 를 눌러서  Clone하여 가져온 파일들도 직접 확인해보자.
    image


소스트리의 2개의 탭에서
open~ _git 은 내가 하는 작업
open~ _new는 새로운 멤버가 하는 작업이라고 가정하고 다음을 실습해보자.


하나의 원격저장소로 두 멤버간 협업하기

하나의 원격저장소에 새로운멤버가 push를 할 경우 , 컴퓨터의 이름에 해당하는 Author가 다르게 올라간다.
지금은 하나의 컴퓨터로 작업을 하므로, Author를 터미널에서 일부러 변경해주는 작업을 해보자.
[opentutorials_new]를 선택한 상태에서 우측상단의 [Terminal]을 클릭한 뒤, 아래와 같이 입력해준다.
- git config user.name "new"
- git config user.email new@gmail.com

  • 먼저 git이라는 사용자가, 새로운 내용을 추가해보자.

    image
    image
    Push옆의 숫자는 원격저장소와 로컬저장소의 버전차이다.
    타임라인을 보면, 원격저장소를 의미하는 origin/master와 버전차이가 2개가 나는 것을 확인할 수 있다.


  • 이제 push를 통해 원격저장소로 올려보자.
    원격저장소의 commits에 가보면, push해준 버전이 업로드 된 것을 확인할 수 있다.
    image




  • 이제 새로운멤버인 new가 작업을 시작해야한다.
    협업자는 새로운 작업을 시작하기 전에, 반드시 원격저장소에 새로운 내용이 있는지 없는지 확인해야한다.
    그 때 사용하는 기능이 [ Pull ]이다. 즉,  이전에 Clone을 통해 프로젝트를 다운받아놨다하더라도,
    새로운 내용을 Pull을 통해 다운로드 해야한다.

    image
    image
    원격에 있었던, [ git이 push 버전]이,  새멤버의 프로젝트로 가져와지는 것을 확인할 수 있다.

  • 이제 new라는 새멤버가 작업을 해서 push를 해보자.
    image
    image

    push를 완료하면, 아래와 같이 원격저장소(origin/master)와 new라는 새멤버의 로컬저장소(master)가 버전이 같아진 것을 확인할 수 있다.
    image


  • 만약 git이라는 사람이,   원격저장소의 pull 없이 새로운 작업을 한다고 가정해보자.
    이 상황에서 원격저장소에 push를 하게 되면, 어떤 일이 일어나게 될까?
    image
    git은 push를 거절한다.
    pull을 먼저하고 나서, push를 해야한다!
    image
    image

    이러한 상황에서는 Pull을 먼저해서, 충돌이 없다면 자동으로, 병합(merge)를 한 다음, Push를 해야한다.

  • 먼저, 빠트린 Pull을 해보자.
    원격저장소의 버전을 가져와, 로컬저장소의 버전 과 병합(merge)가 된, 새로운 버전이 만들어지는 것을 확인할 수 있다.
    image
    그래프를 보게 되면, 원격저장소의 new가 push한 버전(분홍색) 과, git이 새로운 작업을 한 버전(파란색) 사이에, pull을 통해  자동으로 병합된 것을 확인할 수 있다.
    git이 자동으로 병합하여, 별도의 버전을 만들어주는 것이다.


원격저장소가 있고, 협업하는 개발자가 있다면, push전에 무조건 pull을 하자!

[ Pull -> ~~~~~~~~~작업~~~~~~~ -> commit -> Push직전에 Pull한번더 -> Push ]이 작업이다.




같은 부분을 수정하여 충돌이 일어나는 경우

서로 같은 부분을 다른 작업자들이 작업할 때, 충돌이 일어나게 된다.

혼자 작업하는 경우에도, 실험적인 작업을 다른브랜치에서 작업하다가 같은 부분을 수정하여 충돌이 일어날 것이다.


  • 먼저 충돌을 발생시키도록 만들어보자. 같은 ul태그 속 라인에서 li를 만들어보자.
    image
    image

  • 이렇게 같은 부분(li마지막 라인)을 수정한 상태에서,
    new라는 사용자에서 먼저 push를 한다. (단, push전에는 pull을 먼저해야한다. 반드시)
    그리고, push를 하자마자, 1초만에 git이라는 사용자가 pull을 했다.

    그랬더니, Uncommited changes와 함께 느낌표의 충돌이 발생한 것을 알 수 있다.
    image


  • 충돌이 일어날 땐, 직접 파일을 수정해야했다.
    git이라는 사람은 push를 하기 직전에 pull을 했을 뿐인데, 같은 부분이 수정되어 충돌이 일어난 것이다.
    image

    마찬가지로, ======위쪽의 HEAD는 git이 작업한 부분이고,
    =====아래쪽은 new라는 사람이 작업한 뒤 원격저장소에 올려놓은 코드이다.
    git입장에서는 같은 곳을 수정했기 때문에, 선택하지 않고, 사람에게 위임한 것이다.
    수정을 통해 정확한 코드만 남겼다고 가정하자.
    image


  • git이라는 사람이 직접파일을 수정하여 충돌을 해결했다면,
    Mark Resolved를 한 뒤, commit해야한다.
    commit하기 전에, Mark Resolved만 한 상태에서, 타임라인의 Graph를 먼저 살펴보자.
    image

    충돌을 해결하고 난 뒤의 Working Copy의 부모를 보자.
    파란색 부모은 원격저장소(origin/master)이고, 분홍색 부모은 로컬저장소(master)이다.

    Pull 버튼을 통해서, 2개의 버전이 병합되었고, 아직 커밋되지않은 버전이 생긴 것이다.
    하지만 같은 부분수정으로 충돌이 발생했기 때문에--> 버전이 생성안되고, Uncommitted 형태로 주어진상태다.


  • commit을 눌러서 충돌을 병합해보자.
    회색동그라미가, 버전이 생기면서 파란색으로 변한 것을 확인할 수 있다.
    image


  • 이제 Push를 통해서 원격저장소에 업로드 시켜보자.
    image


이렇게 먼저 push한 new보다는, 나중에 push한 git에게 충돌해결의 임무가 주어진다.
그리고 원격저장소와 자주 동기화해야지만, 이러한 충돌을 해소할 수 있다.

원격저장소

현재까지는 로컬저장소(내 컴퓨터)만 이용했었다.
만약 버전관리도구(git)의 사용이 어렵다면, 반드시 다른 cloud에다가 자신의 소스코드를 백업해놓기를 권장한다.
이렇게만 한다면, 버전관리는 안될 것이다.
버전관리도구를 사용하면서, 원격저장소에 자신의 코드를 역사적인 버전을 남기면서 백업해야한다.


원격저장소의 종류

네트워크상의 저장소인 원격저장소에 , 현재 사용중인 로컬저장소를 연결한다음, 백업해놓는 기능이 주 기능이다.

직접 원격저장소를 만드는 것은, 서버를 구성할 줄 모르면 쉽지 않다.

그래서 사용하는 것이 github등의 git 서비스이다.
깃헙(github)의 경우에는, 공개버전이 아니라면 어느정도 돈을 내야한다.
깃랩(gitlab)의 경우에는, 깃헙을 벤치마킹 한 것으로, 자신의서버에 설치가능한 오픈소스였으나, 깃헙처럼 서비스로 제공하기 시작했다.
- 깃랩은 특이하게,, 깃헙에서 깃랩을 사용안내하고 있다..


깃헙을 이용해서 원격저장소 만들고 로컬저장소를 연결하기

github에서 아이디를 만들어 준비를 한다

  • 먼저, repository를 public으로 만든다. repository명은 현재 사용하고 있는 프로젝트 폴더와 동일하게 만들어보자.
    image

  • 만들어서 나오는 상단의 HTTPS/SSH 는 방금 만든 원격저장소의 URL같은 것이다.
    그 아래 나오는 명령어들은 명령어기반으로 원격저장소에 로컬저장소를 세팅할 수 있다. 하지만 우리는 GUI환경에서 사용하므로 일단 보류한다.
    image


현재까지는 로컬저장소에서 고립된 상태에서 작업을 해왔다.
이제 원격저장소와 로컬저장소를 연결 후 업로드 해야한다.

원격저장소는 Remote Repository라고 한다. 이제 소스트리로 돌아와서, 원격저장소를 연결해보자.

  • 소스트리로 돌아와, 상단 메뉴 중 [ Repository - Add Remote... ] 로 진입해보자.
    (이미 원격저장소가 추가되어있다면 Repository - Repository Settings에서 수정할 수 있다)
    image
    image


    Add버튼을 눌러서 원격저장소를 추가해주자.

    image

    이제 깃헙의 만든 레퍼지토리의 HTTPS주소를 복사한 뒤,  URL/ PATH 칸에 붙혀넣자.
    이 때, 기본 원격저장소로 설정하기 위해서 Default remote도 체크해주자.
    image


  • 소스트리의 왼쪽메뉴 Remotes를 보면, 우리가 추가해준 원격저장소의 remote name인 orgin이 등장하게 된다.
    image

    origin은 우리가 추가해준 원격저장소의 별명같은 것이다.
    상단 Repository - Repository settings에 들어가보면 확인할 수 있다.
    image

    여기까지만 하면, 로컬저장소 - 원격저장소는 연결만 된 상태다.
    즉, 아직 동기화= 업로드하기 전 상태다.


  • 로컬저장소 --> 원격저장소 로 밀어내는 행위가 바로 Push이다.
    상단 버튼중 Push버튼을 클릭해보자.
    image


    Push할 원격저장소의 별명을 선택할 수 있다.
    그리고 동기화(업로드)하고 싶은 로컬저장소의 여러 Branch를 선택할 수 있다.
    실험적인 업무를 노출하고 싶지 않다면, master 브랜치만 선택해준다.

    image

    image


  • 깃허브로 돌아가 Reload를 해보자.
    연결된 로컬저장소로부터 push된 소스코드가 업로드되어, 코드가 나와있다.
    우리가 수정한 README.md의 내용이 메인설명으로 나온다.
    image

    Commits 메뉴를 선택해보면, 로컬저장소에서 작업했던 버전들이 확인이 된다.
    image


여기까지만 하면, 로컬저장소가 고장나더라도, 원격저장소에서 받을 수 있고 버전도 확인할 수 있다.
백업으로서의 의미가 가장 크다고 생각하면 된다.


이제 로컬의 파일을 수정 후, 버전을 만든 뒤 ---> 원격저장소로 업로드 해보자.

  • 파일을 수정 후, 로컬에서 commit하자.
    image


    그랬더니, 소스트리에서는 Push버튼에 1이라는 표시가 나타나있다.
    이것은 로컬저장소와 원격저장소간에 1개의 버전차이가 존재한다는 것을 의미한다.
    타임라인master는 로컬저장소의 최신버전을 <--> origin(별명)/master는 원격저장소의 최신버전을 의미한다
    image

  • 하나의 버전을 더 commit해보자.
    원격저장소에서는 아직 2개의 버전이 업로드 되지 않았다는 것을 직감적으로 확인할 수 있다.
    image

    이제 2가지 버전을 추가한 프로젝트를 Push해보자.
    로컬의 master와 원격의 origin/master가 같은 버전에 위치하는 것을 확인할 수 있다.
    image

브랜치 : 실험적인 수정이 필요할 때, 프로젝트를 2개로 복사한 것같은 효과를 내어, 실험적인 수정작업을 한 뒤, master에 병합하기 위함
  - 병합 : master를-> 실험으로 주기적으로 병합해주다가, 실험작업이 완료되면, 실험->master로 병합 or 실험 브랜치를 포기한다.
  - 충돌 : 병합시 충돌상황에서는
     (1)충돌난 파일직접수정 ->
     (2)Git에서는 우클릭 - Resolve Conflicts - Mark resolved ->
     (3)commit을 통해 병합버전을 완료한다

image

브랜치를 사용하는 가장 큰 이유는 마스터브랜치와 실험브랜치를 병합하는데 있다.

실험브랜치에서 만든 변경점들을--->  master브랜치에다가 병합merge하는 것이 목표이다.

image


브랜치 병합하기( 실험--> master로)

  • master에다가 병합하기 위해선, 먼저 master브랜치라는 받는 쪽 branch를 선택한 상태여야한다.
    이것을 master브랜치로 checkout했다 라고 한다.
  • 이제 [실험] branch에서 우클릭하여, current branch(체크아웃되어있는 matser브랜치)로 병합해보자.

    image

    나는 merge했더니, conflicts가 발생했다.
    image

    working copy로 가서, index.html을 commit 해주니까 merge된것을 확인할 수 있었다.
    image
    위와 같이 Merge brach '실험'으로서, 실험branch를 master에  merge했다.

  • 해당버전의 수정내용을 살펴보자.
    실험branch에서 실험적인 업무로서 했던, < head태그추가 > + <title태그추가> 부분이 +초록색으로 추가된 것을 확인할 수 있다.

    image
    image


  • 파일을 보면, master브랜치의 일상적인 업무<ul,  li태그 추가> 와 실험 브랜치의 실험적인 업무<head, title태그 추가>가 한 파일에 합쳐져 있는 것을 확인할 수 있다.
    image
    같은 부모인 <h1태그 추가>에서 시작한 것을 유념해두자.


브랜치 병합에 있어서 충돌(Conflict) 해결하고 최소화 하기

브랜치를 통해서, 해당시점에서 마치 프로젝트를 복붙하여 2개처럼, 일상적인 업무 <--> 실험적인 업무를 나누어서, 병합으로 합쳤다.
하지만, 두 branch에서 같은 곳을 수정하게 되면, 충돌(conflict)가 일어난다.

*** 어떤 항목에 대해, 각 브랜치가 하나는 위쪽을 하나는 아래쪽을 따로따로 수정했다면 git은 충돌이 없는 것으로 판단한다.

*** 성공적으로 병합이 끝난 실험branch는 우클릭으로 삭제해도 된다.

  • 이전시간까지 병합이 완료된 master브랜치에서 새로운 브랜치 [ 실험2 ] 를 만들어보자.
    브랜치를 만들 때, 항상 그 시점의 버전을 확인하자.  Merge branch'실험' 버전에서 실험2브랜치를 추가하였다.
    image

  • 실험2 브랜치에서, li태그를 하나 더 추가한 뒤, commit해주자.
    image

    이번에는 master브랜치에서 똑같은 위치에 li태그(다른이름)으로 추가해보자.

    image

  • 이제 master브랜치에 병합해보자.
    받을 쪽인 master브랜치로 checkout하고,  실험2 브랜치에서 우클릭> merge해준다.
    아래와 같은 경고창이 뜬다.
    image

    충돌한 이유는 , 하나의 파일안에서 2개의 브랜치가 같은위치의 내용을 수정했기 때문이다.
    git의 입장에서는 누구의 코드를 우선할지 모르니까, conflict를 낸 뒤, 사람에게 처리를 위임한다.


  • 이제 병합시 conflict가 난 파일로 가보자
    <<< HEAD  와 ===== 와  >>>> 실험2로 나뉘는 것을 알 수 있다.
    이 때, =====를 기준으로 위쪽 HEAD는 현재 선택된 branch 즉, master 브랜치에서 수정한 내용이고,
    =====기준 아래쪽은, 적혀있는 실험2 브랜치에서 수정된 내용이다.
    image

    만약 다 필요한 코드이면,  주석같은 << ==== >>>를 다 제거해주고 저장한다.


  • 이제 소스트리의 Log/History의 Uncommited changes를 살펴보자.
    [ 느낌표모양의 주황색 삼각형 ] 아이콘이 있다. 이 것은 conflict가 났으니, 코드를 보고 판단해달라는 내용이다.
    image\


  • 충돌이 난 파일에서  [ 우클릭 - Resolved Conflicts - Mark Resolved]를 통해서,
    충돌이 난 상황을 << === >>> 수정을 통해서 해결했다고 git에게 알려준다.
    그러면,  [느낌표 삼각형] --> [ 연필 네모]로 바뀌면서, Stage로 자동으로 올라온다. 아직, 병합이 완료되진 않는다.

    image
    image


  • 이 상태에서, commit버튼을 눌러보자.  자동으로 충돌난 내용을 해결했다는 문구가 적혀져있다.
    즉, 실험2내용을 master브랜치에 병합해왔다는 내용과 함께, index.html의 충돌을 일어났었다는 정보를 자동기재해준다.
    image


  • 충돌내용 수정 후,  Mark해주고, commit을 끝내니,  병합된 git(소스트리)의 버전이 새로 생김을 알 수 있다.
    image




충돌을 최소화하는 방법

실험브랜치에서 6개월간의 수정작업 끝에, master브랜치와의 병합하게 된다면,,, 그것은 현실적으로 어려울 수 있다.
이것을 최소화하는 방법은, 실험 브랜치에다가 master브랜치를 끊임없이 동기화하는 것이다.

  • 다시한번, [실험3]라는 브랜치를 만들고, master브랜치로 와서 내용을 수정해보자.
    master브랜치에서 li 충돌이라는 태그를 추가하고 commit한다.
    image


  • 이제 다시, [실험3]브랜치로 와보자. master브랜치에서 추가한 충돌이라는 li태그가 없는 상태일 것이다.

    image

    [실험3]라는 실험적인 branch언젠가는 master브랜치에 병합되어야한다.
    언젠가는 될것이므로, 충돌을 최소화하기 위해, master브랜치의 내용을----주기적으로---> 실험3 branch에 가져다놓자.
    즉, 실험3 브랜치를 checkout한 상태에서, master브랜치 우클릭 - merge를 해준다.
    master브랜치에서 수정한 li충돌 태그가 실험3에 병합된 것을 확인할 수 있다.
    image


  • 실험3branch에서 다른 작업을 해보자. li충돌해결을 추가하고 커밋해주자.
    master branch에서도 li원격저장소 태그를 추가하고 커밋해주자.
    image

  • master와 실험적인 branch 각각에서 작업을 해준 다음,  실험3에서 또다른 작업을 시작할 타이밍이다.
    이때, master의 내용을 가져와서 실험3에 병합해주자.
    같은 곳을 수정하였으니, conflict가 날 것이다.
    위에서 했던 것 처럼 [ 파일에서 conflict해결후 저장  =>  merge받는 곳에서 Mark Resolved => commit ]을 통해 병합을 완료하자.
    image
    image
    image

    *** 이 때, Resolve Conflics  메뉴의 Reslove Using 'Mine' / 'Theirs'는 (직접 파일 수정 없이)
    checkout되어 병합받는쪽(실험3)을 채택 / 병합되는 쪽 (master)을 채택할 수 있다.
    직접 파일을 보고 수정한다면, Mark resolved를 하면 된다.
    이렇게 master의 수정내용을 계속해서 받아들이면서, 실험3의 작업을 계속 이어가게 되면, 충돌이 최소화 될것이다.

  • 이제 실험3에서 하나의 작업만 더 해준 뒤,  master에 최종병합시켜보자.
    실험3 브랜치에서 meta태그를 하나 추가시켜준다.
    image

    master브랜치를 체크아웃한 뒤, 실험3브랜치를 merge해보자.
    충돌이 발생하지 않고, 바로 병합이 된다.
    [ 충돌파일 수정 -> Mark Resolved -> commit]의 과정없이 바로 병합된 것을 확인할 수 있다.
    image


    이러한 방식으로 한다면, 충돌이 발생하더라도 더 작은 충돌이 발생할 것이다.
    image
    master의 입장에서는 한번도 실험3가 존재하지 않았다.
    만약 실험3의 브랜치가 drop되어 폐기되었다면, 그냥 삭제해주면 된다.
    만약 필요하다면 , 이러한 과정을 거쳐서 , 최소한의 충돌로 master로 병합해주면 된다.

브랜치를 사용하는 이유

우리가 진행중인 프로젝트(opentutorials_git)를 하면서 동시에, 불확실하고 실험적인 작업을 동시에 진행할 수 있다.

만약 브랜치를 사용하지 않는다면, 실험적인 작업이 취소되었을 때, 이전버전으로 돌아가도 되지만, 그 부분만 도려내야하는데, 쉽지않다.

폴더를 복사해서 실험적인 작업을 진행할 수 있지만, 완료되었을 때, 원본에 붙혀넣기가 쉽지않다.

이 때, 우리는 브랜치를 사용할 수 있다.
브랜치를 통해서, 마치 2개의 폴더로 나눈 뒤, 각각 따로 작업하는 것과 같은 효과를 내면서 동시에 작업 완료후 실험적인 작업에서 변경된 내용을 원본소스에 간편하게 병합해줄 수 있다.


브랜치 만들기

index.html 파일에 대해, 일상적인 업무실험적인 업무가 있다고 치자.

일상적인 업무는 html코드에 ul태그를 넣는 것.
실험적인 업무는 head태그를 넣는것이라고 가정하자.

우리는 브랜치를 이용해서,
마치 프로젝트폴더를 2개로 복사한 다음, 하나의 프로젝트에서는 ul태그를, 다른 하나의 프로젝트에서는 head태그를 넣는 것처럼 사용해보자.

좌측메뉴의 Branches에는 master라는 현재 브랜치가 표시되어있다.
(기존 default로 만들어진 브랜치 이름이 master일뿐 바꿀 수 있다.)

  • 브랜치를 만들어보자.
    상단의 [ Branch ] 버튼을 누른 뒤, <실험>이라는 New Branch를 만들어보자.
    image
    image
    image

  • master인 상태에서, ul태그만 추가해서 commit해주자.
    image

    이제 ul태그안에 li태그를 추가해서 하나마다 버전을 나누어서 commit해주자.
    image


    위 그림을 보면, 실험branch는 뒤쳐져져있는 것을 확인할 수 있다.


  • 이제 [실험]브랜치를 더블클릭해보자. 이 때, 타임라인의 실험브랜치가 적힌 버전을 확인해주자.
    index.html파일를 확인해보자. ul태그랑 li태그가 사라져있다.

    image

  • 이제 이 상태에서, 실험적인 업무인 head태그를 넣어주고, commit해보자.

    image
    image

    타임라인의 그래프를 보자.
    [master]에서 commit한 3개의 버전은 분홍색으로 가고 있다.
    [실험]에서는 해당 버전의 프로젝트(h1태그 추가)로 돌아간 다음 --> head태그 추가 버전으로 파란색으로 가고 있다.
    *** (실험)head태그추가 와 (master) ul태그 추가의  부모는  둘다 동일하게   h1태그 추가인 것을 확인해두자.
    *** 추가한 브랜치 수만큼, [ 만들어준 시점에서 프로젝트를 복사해둔 효과 ] 가 난다는 것을 알 수 있다.
    my) 실제 윈도우 폴더에서 접근했을 때, 같은 파일이라도, 소스트리의 브랜치 선택상태에 따라 다른상태로 열린다.
    image
    image


  • 서브라임텍스트에서도 브랜치를 바꿀때마다, 같은파일의 내용이 변경되는 것을 확인할 수 있다.

    image
    image
  • Discard : 현재 파일수정후 저장된 상태에서,commit을 하지 않았다면, 다시 직전버전의 파일로 돌아갈 수 있다.
  • Reset - hard : 선택한 버전으로 돌아가고, 현재 파일상태와 상관없이, 그 이후의 버전+파일들은 다 삭제
  • Reset - mixed : 선택한 버전으로 돌아가고, 현재 파일상태는 uncommited changes로 남겨둔다.
  • Revert(Reverse) : <최근버전부터 순차적으로> 선택한 버전을 취소하지만 Revert로 새로만들어남겨두고, 그 직전버전으로 돌아간다.
    - 타임라인(Repository)에 Revert가 있다면-> 그 직전버전으로 돌아간 것

git의 Revert = 소스트리의 Reverse commit 을 이용하여, 취소할 버전을 남겨두고 직전버전으로 돌아가자.

Reset은 선택버전 이후의 버전들은 모두 삭제하고, 선택한 버전으로 돌아간다. 파일유지만 Hard(삭제)/Mixed(유지)로 결정해준다.
Revert는 취소할 선택버전을 남겨둔 체, 그 직전버전을 [ Revert + 취소버전]이라는 이름으로 새로운 버전을 만들어준다.
(즉, Revert 버전  = 그 버전의 이전 버전으로 돌아간다.)

타임라인에서 취소할 버전을 선택한 뒤, 우클릭 > [Reverse Commit] 을 통해, 직전 버전새로운 이름[Revert 취소버전]으로 만들어준다.
image
image


이름은 [ Revert 취소한 버전 ]이지만,  취소버전의 직전버전[body태그 추가]으로 돌아간 상태라,
수정해준 index.html이 다시 돌아가고, 추가해준 README.md가 삭제되었다.
image


만약, 더 이전버전으로 돌아가고 싶다면, 최신버전부터 -> 취소할 버전까지, 순차적으로 계속 revert를 해줘야한다.
image

예를 들어서,  아래의 상태에서, html태그 추가 버전까지 다 취소하고 싶다면,
[reset-mixed] revert -> [body태그 추가] revert -> [ html태그 추가] revert 후, ===> index.html버전에 도착하게 된다.
image

해석을 하자면 ) Revert "특정버전" ---> 특정버전하기 전으로 돌아갔구나!
[html태그를 추가]하기 전으로 돌아갔구나!


만약 순차적으로 revert안한다면, 충돌이 일어날 수 있다.

Repository(타임라인)에서 Reset to Current  - Hard을 이용해, 지난 버전+지난파일로 되돌아가기

Reset to current branch에서  current란,, 선택한 지난버전을 의미한다.

타임라인(repository)에서 되돌아가고 싶은 버전 [body태그 추가]을 선택하고,
우클릭 >  [ Reset to current branch ]를 선택 한 뒤, [ Hard - ~ ]를 선택하면
[body태그 추가] 버전 이후의 모든 버전들이 삭제되고, 아직 commit하지 않은 내용, stage에 올려놓은 내용도(파일들도) 모두 사라진다.

image
image
image


실제 파일 [index.html]도 body태그만 추가한 상태로 되돌아갔고,
image

README.md파일도 사라졌다
image

선택버전 이후의 모든 내용 + 파일이 다 사라지니, 조심해서 사용해야한다.



다시 최신버전으로 수기로 대충 만들어보자. html>body>header>h1태그 + README.md

Reset to current - Mixed로 지난버전으로 되돌리면서, 현재파일은 유지하기

어떤 웹서버를 관리하다가 인증정보를 모르고 파일에 넣어 오픈소스로 풀려버렸다.
이 때, 지난버전으로 되돌리면서, 현재 수정중인 파일들은 유지(working area 유지)하고 싶다면 역시 reset를 이용하면 된다.


타임라인(repository)에서 되돌아가고 싶은 버전 [body태그 추가]을 선택하고,
우클릭 >  [ Reset to current branch ]를 선택 한 뒤, [ Mixed - ~ ]를 선택하자.
마찬가지로, [body태그추가 버전] 이후의 버전들은 삭제되지만, 현재 작업중인 파일들은 유지가 되어, Uncommitted changes남아있다
특히, 작업중인 파일들이 없을 때로 돌아가면, 버전관리가 안되는 것 같이 [보라색]으로 유지된다.
image
image
image


Mixed/soft/hard의 차이점에 관해서는 다음에 이해하자.

Discard 버튼을 이용해서, 수정사항(추가 혹은 삭제한 코드) 취소하기

어떤 파일을 수정했는데, 아직 commit하진 않았을 때,  discard를 이용해서 가장 최근에 commit한 버전으로 파일을 되돌릴 수 있다.

기존의 index.html 파일에 body태그 안에 있던, header태그를 제거하는 수정을 해주자.
image

소스트리에서 수정사항을 감지하 곳에서, 제거한 부분은 (-) 빨간색으로 표시된다.
image

갑자기, working area에 있는 index.html의 삭제한 저 빨간줄을 다시 복구하고싶다
상단의 Discard버튼을 눌러보자.
image
image
index.html파일을 선택후, discard changes를 눌러서 수정사항을 취소한다.

그러면 아래와 같이, unstage에서 수정을 감지한 index.html이 사라져있고,
실제 파일에서 가장 최신버전의 index.html로 돌아와있다.(지웠던 header태그가 살아나있다)
image
image

staging files(index 혹은 staging area)에서도 discard가 먹힌다. 커밋전에 수정사항취소후 되돌리기는 다 가능.

commit하기 전에, 지금 작업한 내역을 review하는 버릇을 가지자.
working area/staging area(index)의 초록줄/빨간줄은 최종적으로 되돌릴 수 있는 순간이다.

commit으로 버전을 만들었으나, 코드의 변화만 볼 수 있지, 과거의 프로젝트 상태로 돌아갈 순 없다.

  • 새 파일을 만들어보자. sublimeText를 켜고, 루트폴더인 opentutorials_git에 우클릭으로 [readme.md]파일을 만들어보자.
    image

  • 소스트리(버전관리)로 들어가보면, [ Log/Histroy ]탭에는 uncommitted changes가 감지되었고
    unstaged files파일에, 생성하고 수정한 readme.md파일이 감지되었다. 아이콘이 물음표인 것을 기억하자.
    image

    index.html 파일의 body태그안에 수정하고 소스트리를 보자. unstaged files에 index.html로 걸려있지만
    아이콘이 연필모양이다.
    image

    image
    이 2개 아이콘이 다른 의미는 버전관리(소스트리)에서는 다르게 인식하고 있다는 것인데,
    index.html파일의 [주황색연필]아이콘은 git에 의해 추적되고 있는 파일로서, commit으로 버전을 만들어 저장소에 보관이 가능하다.
    readme.md파일의 [보라색물음표]아이콘은 git에게 파일을 추적하고, 관리하라고 명령하기 전의 파일이다.
    - stage위로 올리고 -> [최초커밋]을 통해, 버전을 만들어야지 [git의 추적]이 시작된다.


  • 새 파일을 stage위에 올린 뒤, commit버튼을 눌러 버전을 만들자.
    이 때, commit은 stage위에 올라와있는 readme.md파일만 commit이 된다.(index.html은 안됨)
    imageimageimage

    마지막 버전확인시, [초록색+]는 이 버전에서 추가한 파일이라는 뜻이다.
    다시 uncomiited changes를 더블클릭해 돌아와보면, unstage에는 index.html만 있다.
    image



  • 이제 변화가 생겨 unstage에 감지된 index.html과 readme.md를 stage에 올리지않고 다시 수정해보자.
    index는 h1으로 큰제목의 태그를 달고, readme는 문자몇개 수정한다.
    그리고 2개를 한꺼번에 stage에 올리고, commit해보자.
    image
    하나의 버전에는 여러개의 파일의 변경사항을 모두 포괄할 수 있다.

  • 다시 2개 파일을 수정한 뒤, 각각 따로 stage에 올려서 commit하여 버전을 만들어보자
    비록 2개 파일의 변동사항이 있지만, 하나의 파일 수정사항에 대한 버전을 만들 수 있다.
    imageimage

    readme.md파일은 여전히 commit되지 않은 체, unstage에 남아있다.
    image

    unstaged와 staged 공간의 차이가 드러난다.
    -unstage : 수정된 모든 파일들의 목록이 표시되는 공간
    -stage : commit시 만들어질 버전에 합류할 파일들만 모아놓은 공간. 중간단계!
    staged라는 중간공간을 통해서 변경사항들 중에서, 필요한 or 완결된 or 연관된 파일들만 모아서 하나의 버전(commit)으로 만들 수 있다!!


[git]에서는 소스트리의
unstaged를 [workingcopy]
staged에 올리는 작업을 [add]
staged를 [index 혹은 staging area]
버전들이 표시되는 타임라인을 [repository]라고 부른다.

즉, working copy에 있는 수정된 파일들을 add해서 index 혹은 staging area에 올려놓고,
commit을 통해 하나의 버전을 만들어 repository에 저장한다.
image


  • 하나의 파일이라도, 중간단계인 staging area에 있는 상태에서, 다시 수정되면 working copy에 감지되어 올라온다.
    image

Git을 이해하기 위하여, 예제부터 이해하기


Git 저장소(프로젝트의 메인폴더) 만들기

  • 언어를 영어로 바꿔주자.
    소스트리를 켜고,  도구 > 옵션 > 언어를 english로 바꾸자. 참고할 대부분의 자료들은 영어로 되어있기 때문이다.
    재실행해야지 바뀌어 진다.
    image

    [ create]버튼을 눌러서 repository( 저장소 )를 만든다. 한 프로젝트의 디렉토리(폴더)이다. 그것을 git에서는 저장소라 부른다.
    타입은 git으로 고정해두고, destination path 프로젝트의 디렉토리가 어디에 생성할 것인지 지정하는 것이다.
    나는 데스크톱의 cho폴더(C:\Users\cho)에서 폴더에 [ opentutorials_git] 라는 저장소(프로젝트의 폴더)를 만들 것이다.
    image

    소스트리에 프로젝트 폴더(저장소)가 생성된 것을 확인할 수 있다(탭의 이름)
    image


소스트리로 버전관리 해보기

  • SublimeText의 루트폴더를 추가해주자.
    project > Add folder to Projects > 소스트리에서 만든 저장소(프로젝트의 최상위폴더)를 선택
    image

  • 저장소에 수동으로 새로운 파일을 추가해보자.
    저장소(프로젝트 폴더)에서 우클릭으로 생성해도 된다. 여기서는 서브라임텍스트를 이용해서, 지정한 root_폴더에서 파일(index.html)을 생성해보자. 아래 그림과 같이 소스트리에서 해당파일이 [unstaged files ]의 목록에 자동으로 생성된다.
    image
    즉, 저장소(프로젝트 폴더)에서 일어나는 일(파일생성, 삭제 등)을 계속 주시하고 있다가, 변화를 알아채고 바로 띄워준다.

  • 버전관리를 해보자.
    보라색의 물음표의 파일 우측상단에 [Stage All] 이나 [Stage Selected]를 클릭해보자. 아래그림과 같이  [ Staged files]로 올라가면서 초록색 플러스아이콘으로 바뀐 것을 확인할 수 있다.
    image

    이제 초록색 플러스아이콘인 Staged된 index.html을 선택한 뒤, 좌측상단의 Commit 버튼을 눌러보자.
    커밋을 적는 란이 생긴다.  파일을 생성했다고  커밋을 남겨보자.
    커밋이란 ? 버전하나를 만드는 행위이다. ( 만약 커밋사용자의 정보가 없다면 Tools 에 들어가 지정해주자)
    커밋 후 확인은 하단의 [Files Status]탭을 [Log /History]탭으로 바꾸어주면 된다. (혹은  [ BRANCHES ] > master 에 들어가면 확인할 수 있다.)
    image
    commit을 통해서 버전을 최초로 만들었다.

  • 새로운 버전을 추가하기 위해서 파일을 수정해보자.
    index.html파일을 수정했더니 소스트리에 [Uncommiteed changes]가 관찰되었다.
    image
    image

    commit을 통해 새로운 버전을 만들었는데, uncomiited changes는 아직 버전을 만들지 않은 변화가 있다는 뜻이다.
    버전을 만드는 방법은 [Unstaged files] 를 Stage 하여 —>  [ Staged files]에 올린 뒤 –> [commit버튼]을 눌러 버전 정보를 작성해주는 것이다. 방금 한 작업인 html태그 추가를  적어주면서 commit을 눌러 버전을 만들어주자.
    imageimageimage

    아래그림 처럼, BRANCHES에서 새로운 버전(commit)이 생성된 것을 확인할 수 있다.
    커밋 후 확인은 하단의 [Files Status]탭을 [Log /History]탭으로 바꾸어주면 된다.
    image

  • 버전들을 탐색해보자.
    위에서 만든 commit들(버전들)을 확인해보자. 처음에는 내용이 없는 html파일을 생성했으므로, 
    우측에는 아래와 같이 텅빈 화면으로 나타난다.
    image

    2번째 버전에서는 html을 추가한 것에 대해 [ 녹색으로 이전버전에 비해 추가된 코드를 표시 ]해 주고 있다.
    image

    3번째 버전에서는 body태그를 추가하였다. 녹색으로 추가된 부분이 표시 될 것이다.
    image


파일의 변형 –> commit으로 버전으로 만듬 –> 버전 탐색의 과정이었다.

소스트리 : 명령어 기반으로 사용하기 쉽지않은 git을, 그래픽 환경에서 쓸 수 있게 해주는 프로그램.


git 설치

  • 구글에서 git download를 검색하여, 공식사이트에서 다운 받고,  default설정으로 설치한다.
    image

  • 설치하고 난 뒤, 시작메뉴에 보면 Git Bash 아이콘이 생긴다. 클릭해서 열어보면, 유닉스/리눅스 환경과 비슷한 환경에서 윈도우를 제어할 수 있다. [ git ]이라고 쳐서 명령어들이 출력되면 정상적으로 설치 된 것이다.
    image
    image


sourceTree 설치하기

  • 구글에서 sourcetree download를 검색해서 default로 설치한다.
    설치과정에서 Atlassian에 가입을 했고, 구글아이디를 이용하였다.
    image
    image

    동시에 비트버킷에도 가입하였다. 위에서 사용한 Atlassian계정으로 연결하고 비트버켓 닉네임은 nittaku로 하였다.
    image
    image

1. 버전 관리란?

2018. 3. 13. 21:08

버전 관리 시스템(Version Control System)

버전 : 의미있는 변화들 = 기능개선 및 버그 수정
버전관리 시스템 : 이러한 변화들을 관리하는 방법론 ( 이전버전으로 바로 돌아갈 수 있다 !)


유사 버전관리 시스템

제품설명서 :
- 제품설명서1을 복사해놓고 수정하여 제품설명서2를 만든다. 마음에 안들면 되돌릴 수 있다.
image

위키피디아 : 집단지성으로 전 세계사람들이 협업하여 백과사전을 작성
- [ 역사보기 ] 탭의 하나하나의 행이 하나의 버전이라 볼 수 있다. 악의적인 편집에 대해 예전버전으로 되돌릴 수 있다.

DropBox : 구글드라이브나 네이버N드라이브처럼, 파일을 올릴 수 있는 클라우드서버 제품
- subversion과 같은 버전관리시스템의 장점만 모아서 일반인들도 사용할 수 있는 제품이다.
- More > Previous versions를 통해 버전 관리를 확인할 수 있고 –> restore버튼으로 예전버전으로 되돌릴 수 있다.
image
image


git을 못쓰겠다면, dropbox구글드라이브를 반드시 사용할 것!

1. 깃헙 회원가입

첫화면에 보이는 곳에 모두 작성하고 singup을 누른다. 다음화면에서는 개인공간이 필요하다면 결제하라는 것이 나오는데 무시하고 submit해준다.

등록한 이메일로 들어가서 verify해준다.


2. 프로필 꾸미기

우측 상단에 Profile에 들어가 edit profile을 선택한다.

Name / 사진업로드 / Bio(자기소개) 정도만 적어서 update해준다.


3. Git(깃) 설치하기

구글에 git download 를 검색해서git for windows 사이트에 들어간다(http://gitforwindows.org/)

download버튼을 눌러 다운받고 설치한다.


4. 깃 저장소 만들기

프로필 왼쪽의 + 버튼을 눌러서 Create a new repository 페이지에 온뒤 repository name만 적어준다. 설명은 안적어도 된다. 바로 create


5. 저장소에 commit 준비 

빈 폴더를 만들고, 해당폴더에 터미널을 열어줘야한다. 윈도우의 경우 해당폴더에 우클릭하면, git BASH 모양이 뜰 것이다.

나같은 경우 안드로이드 프로젝트 폴더에 GitTest라고 만든 뒤, 폴더에서 우클릭하여 Git BASH를 띄웠다.

여기서 명렁어 git init을 치면, 깃을 사용할 준비가 된 것이다.(master)표시가 나옴.


 -git init


이제 github 저장소로 가서, 서버에 원격위치를 알려주는 명령어를 저장소<code>탭에서 복사해 온다.


 -git remote add origin https://github.com/is2js/test.git


그 다음 현재 git에 저장된 상태를 알려주는 git status를 쳐본다.  아직 커밋한것이 없다고 뜬다. 커밋하지 않았으니.. 커밋은 의견제공 정도다.


-git status


6. 파일 추가(add)하기(git 서버에  add)

지정된 폴더에 아무 파일이나 만들어준다. 교재대로, test.php를 하나 만들어준다. 그리고 다시 Bash에서 git status를 쳐보자. 

-git status


그럼 빨간색으로 test.php가 뜰 것이다. untracked라고 해서 아직 관리하지 않는 파일을 의미한다. 이 파일을 git서버에 add해주자.  또는 git add . 을 쳐서 모든 파일을 add해주자.


-git add test.php or git add . 


다시 git status를 쳐보면 초록색으로 add된 new file이 뜬다. 이제 여기서 test.php를 폴더에서 수정해보고 다시 git status를 쳐보자. 빨간색으로 수정되었으니 새로 add하라고 뜬다.  git add . 을 쳐서 다시 관리대상으로 만들자


7. 커밋(의견남기기)하고 푸쉬(github에 저장하기)

(1)커밋하기 전에 git에 자신의 정보(email과 name)를 알려주어야 한다.


-git config --global user.email "is2js@naver.com"

-git config --global user.name "is2js"


(2)이제 커밋을 해보자

-git commit -m 'test(의견)'


(3) 처음에는 master라는 브런치를 가진다. 그것을 이용해서 github에 push(저장)하는 것이다. 아래 명령어를 치면 github로그인 정보를 입력하도록 뜬다. 입력하고 repository에서 확인해보자.

-git push -u origin master


8. 깃허브 소스관리

(1) 기존 파일을 수정한 뒤, git status를 해보고, modified가 확인되면, git add . 으로 다시 git서버에 add해보자.

(2) 다시 커밋(의견)을 하고 푸쉬(깃헙에 저장)를 해보자.


-git commit -m '2th test'

-git push -u origin master


(3) 깃헙 사이트에서 commits를 확인해본다.


9. 브런치

브런치는 복사본은 아니나 임시저장소 같은 느낌

(1) git checkout -b beta 라고 쳐서, beta라는 이름을 가진 브런치를 만들어서 이동한 뒤(생성과 이동이 동시에 됨)

(2) git branch 를 통해 branch상태가 master에서 beta로 이동한 것을 확인 할 수 있다.

-git branch


10. 새 브런치 beta에서 파일을 새 파일을 커밋, 푸쉬 한

(1)GitTest폴더에 새로운 파일을 하나 만든다. test2.php 

(2) git status를 통해 확인 후, add . 하고, 커밋으로는 베타브런치임을 알려준 뒤, 푸쉬 해준다. 푸쉬할때는 새로운 branch이름으로 푸쉬해준다.


-git status

-git add .

-git commit -m 'beta branch'

-git push -u origin beta


(3) 깃헙사이트에서  Branch 선택창에서 beta를 선택해 확인해본다.


11. 실제 사용하는 브런치인 master로 옮기기(merge)

(1) 먼저 터미널에서 git checkout master를 통해 master브런치로 넘어온다.


-git checkout master


(2) git merge beta 를 입력하면, beta브런치에 있던 것들이 모두 master로 이동해온다.(git 서버에만 옮겨진 것임)


- git merge beta


(3) 이제 깃허브에도 적용해주기 위해, push를 해주자.(add(git)->commit + push(github), merge(git)->push(github))

- git push -u master 


(4) 사이트에서 beta브런치에 push한 test2.php가 master브런치로 옮겨가진 것을 확인한다.

+ Recent posts