블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2013. 9. 7. 12:56 Git, GitHub/GitHub

깃헙에 아이디를 가지고 있다면 http://<id>.github.io 형식의 정적 홈페이지를 만들어 퍼블리싱 할 수 있다. AngularJS와 Bootstrap을 가지고 린(Lean)하게 자신의 홈페이지를 만들어 보자. 자신의 홈페이지를 한두시간만에 만들 수 있다. AngularJS와 Bootstrap을 사용하기 때문에 정적 홈페이지를 SPA(Single Page Application) 타입으로 클라이언트(브라우져)에서 서버의 도움(통신)없이 애플리케이션처럼 구동 될 수 있도록 만들 수 있다.  예) 쥔장 홈페이지 : http://ysyun.github.io/



1. 깃헙 계정 및 레파지토리

  - https://github.io/ 에서 계정을 만든다 

  - <id>.github.io 레파지토리를 만든다. 예) 계정이 ysyun 이라면 레파지토리는 ysyun.github.io (저장소 이미 만들었음)

     * 주의 : <id>.github.com 이 아니라 <id>.github.io 이다. 

  

  - 로컬 PC에서 git clone 한다 

$ git clone https://github.io/<ID>/<ID>.github.io.git

예)

$ git clone https://github.io/ysyun/ysyun.github.io.git

   


2. AngularJS와 Bootstrap 템플릿 사용하기

  - AngujarJS+Bootstrap Seed를 git clone 한다 

$ git clone https://github.io/lbehnke/angularjs-bootstrap-seed.git

$ cd angularjs-bootstrap-seed/app 


//app 디렉토리에 있는 모든 파일을 <ID>.github.io 디렉토리에 copy한다

$ copy *  <id.github.io 디렉토리>


  - index.html 에서 보여주고 싶은 메뉴를 수정한다. 반드시 메인 페이지는 index.html이고 root 에 위치해야한다

    간단한 자기소개와 그동안 만들었던 제품에 대한 포트폴리오를 넣었다 

<!-- Navigation -->

    <div class="navbar navbar-inverse navbar-fixed-top">

        <div class="navbar-inner">

            <div class="container">

                <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">

                    <span class="icon-bar"></span>

                    <span class="icon-bar"></span>

                    <span class="icon-bar"></span>

                </a>

                <a class="brand" href="#/intro">Yun Young Sik</a>

                <div class="nav-collapse collapse">

                    <ul class="nav">

                        <li class="active"><a href="#/intro">Intro</a></li>

                        <li class="dropdown">

                            <a href="#" class="dropdown-toggle" data-toggle="dropdown">Portfolio <b class="caret"></b></a>

                            <ul class="dropdown-menu">

                                <li><a href="#/smartdashboard">Smart Dashboard</a></li>

                                <li><a href="#/edashboard">Pharos e-Dashboard</a></li>

                                <li><a href="#/pharosjava">Pharos Java</a></li>

                            </ul>

                        </li>

                        <!-- <li><a href="#/contact">Contact</a></li> -->


                    </ul>

                </div><!--/.nav-collapse -->

            </div>

        </div>

    </div>


  - app.js 에서 routing정보를 수정한다. AngularJS의 routing 정보이다 

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives']).

  config(['$routeProvider', function($routeProvider) {

    $routeProvider.when('/intro', {templateUrl: 'partials/intro.html', controller: GenericViewCtrl});

    $routeProvider.when('/smartdashboard', {templateUrl: 'partials/smartdashboard.html', controller: GenericViewCtrl});

    $routeProvider.when('/edashboard', {templateUrl: 'partials/edashboard.html', controller: GenericViewCtrl});

    $routeProvider.when('/pharosjava', {templateUrl: 'partials/pharosjava.html', controller: GenericViewCtrl});

    $routeProvider.when('/project_b', {templateUrl: 'partials/project_b.html', controller: GenericViewCtrl});

    $routeProvider.when('/contact', {templateUrl: 'partials/contact.html', controller: ContactViewCtrl});

    $routeProvider.when('/imprint', {templateUrl: 'partials/imprint.html', controller: GenericViewCtrl});

    $routeProvider.otherwise({redirectTo: '/intro'});

  }]);



3. GitHub Push

  - git push를 통하여 <id>.github.io 레파지토리에 올린다 

$ git push

Counting objects: 10, done.

Delta compression using up to 4 threads.

Compressing objects: 100% (6/6), done.

Writing objects: 100% (6/6), 680 bytes | 0 bytes/s, done.

Total 6 (delta 4), reused 0 (delta 0)

To https://github.io/ysyun/ysyun.github.io.git

   328f41e..ca12f7e  master -> master


  - push하고 5~10분후에 http://<ID>.github.io 을 호출한다 (웹퍼블리싱에 약간의 시간이 소요된다)


두시간 정도만 투자해 보자. 여러분의 멋진 github 홈페이지를 가질 수 있다 



<참조>

  - http://ID.github.io 홈페이지 만들기 

  - github-pages

posted by 윤영식
2013. 4. 23. 22:08 Git, GitHub

Dogfeet 이분이 Git 전문가라는 생각이 든다. 번역본도 충실하며 끊임없이 노력하는 모습이 마음에 든다. 본받고 싶은분~~~



Git의 성공적인 Branching 전략

  - 성공적인 브랜칭 전략 한글 번역본 읽자

  - 일하는 flow (Workflow) 형태를 이해하고 싶다면 정리한  보자 (Pro Git 한글 번역본중 일부를 정리한 것임)



GitFlow 설치하여 Branching 전략에 맞는 Branch 생성하여 작업하기 

  - 설치 : 다양한 OS 설치 가이드

< 1단계 > 

$ git clone --recursive git://github.com/nvie/gitflow.git

$ sudo make install  (mac 경우 /usr/local/bin 에 설치된다)


 만일 /opt/local/bin에 설치를 원하면 하기와 같이 수행

$ sudo make prefix=/opt/local install


< 2단계 >

$ sudo chmod 755 /usr/local/bin/gitflow* (git-flow*)  

  또는 /opt/local/bin에 설치되었다면 

$ sudo chmod 755 /opt/local/bin/gitflow* (git-flow*)  


< 3단계 > 

/bin/sh^M 오류시 dos2unix 수행 (명령어 없으면 설치)

$ dos2unix /usr/local/bin/gitflow* 


  - 사용법 : 설명 원문

< 1단계 > 

최초 git flow 방식의 branch 전략을 사용할 계획인 git repository로 이동하여 한번만 셋업하기 


$ git flow init

No branches exist yet. Base branches must be created now.

Branch name for production releases: [master]

Branch name for "next release" development: [develop]


How to name your supporting branch prefixes?

Feature branches? [feature/]

Release branches? [release/]

Hotfix branches? [hotfix/]

Support branches? [support/]

Version tag prefix? []   <= 요건 주지 말자. 주게되면 git tag 시에 명칭의 앞에 항상 따라 붙는다. 


< 2단계 > 

feature 디렉토리 밑으로 login 브랜치 생성 

$ git flow feature start login


login commit 하고 develop 브랜치에 merge 하고 login 브랜치 삭제하고 develop 브랜치로 돌아옴 

$ git flow feature finish login


release v0.1.0 브랜치 생성 

$ git flow release start v0.1.0


release v0.1.0 브랜치를 태깅하고 master를 develop에 merge 해준다. 따라서 git checkout develop으로 이동해서 작업가능하다 

$ git flow release finish v0.1.0

  

  - 그래픽컬한 설명 (강추)



그림 보면서 Git 이해하기

  - 비쥬얼 Git 레퍼런스 한글 : 자주 사용하는 명령을 그림과 함께 설명

  - 왜 Git을 사용하는가? : 이제 Git으로 소스, 문서작업을 하자 



Dogfeet 님의 블로그 포스팅 참조

  - http://dogfeet.github.io/ : Git 과 GitHub 그리고 JavaScript, Node.js 에 대한 다양한 주제를 다루고 있다





<참조>

  - GitFlow 적용하기 

posted by 윤영식
2013. 4. 9. 10:49 Git, GitHub/GitHub

.gitignore 설정을 깜빡하고 설정하지 않은 상태에서 git remote(GitHub)로 push 하였을 경우 삭제하는 방법



1) 삭제하기 

  - webstorm의 .idea 디렉토리가 GitHub에 push가 되었음 

  - .idea 를 삭제하자 

  


  - 명령수행 3 단계계

$ ll

total 24

-rw-r--r--   1 nulpulum  staff   59  4  6 16:04 component.css

-rw-r--r--   1 nulpulum  staff  473  4  9 09:30 component.js

-rw-r--r--   1 nulpulum  staff  633  4  9 09:30 component.html

drwxr-xr-x  12 nulpulum  staff  408  4  9 09:30 ..

drwxr-xr-x   6 nulpulum  staff  204  4  9 09:30 .

drwxr-xr-x  12 nulpulum  staff  408  4  9 09:56 .idea

$ git rm -r --cached .idea

rm 'angularjs/component/.idea/.name'

rm 'angularjs/component/.idea/component.iml'

rm 'angularjs/component/.idea/dictionaries/nulpulum.xml'

rm 'angularjs/component/.idea/encodings.xml'

rm 'angularjs/component/.idea/jsLibraryMappings.xml'

rm 'angularjs/component/.idea/misc.xml'

rm 'angularjs/component/.idea/modules.xml'

rm 'angularjs/component/.idea/scopes/scope_settings.xml'

rm 'angularjs/component/.idea/vcs.xml'

rm 'angularjs/component/.idea/workspace.xml'

$ git commit -m "remove webstorm .idea directory"

[master 80de3cc] remove webstorm .idea directory

 10 files changed, 352 deletions(-)

 delete mode 100644 angularjs/component/.idea/.name

 delete mode 100644 angularjs/component/.idea/component.iml

 delete mode 100644 angularjs/component/.idea/dictionaries/nulpulum.xml

 delete mode 100644 angularjs/component/.idea/encodings.xml

 delete mode 100644 angularjs/component/.idea/jsLibraryMappings.xml

 delete mode 100644 angularjs/component/.idea/misc.xml

 delete mode 100644 angularjs/component/.idea/modules.xml

 delete mode 100644 angularjs/component/.idea/scopes/scope_settings.xml

 delete mode 100644 angularjs/component/.idea/vcs.xml

 delete mode 100644 angularjs/component/.idea/workspace.xml

$ git push origin master

Counting objects: 7, done.

Delta compression using up to 4 threads.

Compressing objects: 100% (4/4), done.

Writing objects: 100% (4/4), 472 bytes, done.

Total 4 (delta 2), reused 0 (delta 0)

To https://github.com/ysyun/prototyping.git

   cc17d3a..80de3cc  master -> master


  - .idea 디렉토리가 삭제되었음 


  - git rm 옵션들

$ git rm -r --help

usage: git rm [options] [--] <file>...


    -n, --dry-run           dry run

    -q, --quiet              do not list removed files

    --cached                 only remove from the index

    -f, --force               override the up-to-date check

    -r                           allow recursive removal

    --ignore-unmatch      exit with a zero status even if nothing matched




<참조>

  - 원문 : Remove directory from remote repositories

posted by 윤영식
2013. 4. 1. 19:41 Git, GitHub/GitHub

낚시성 제목이지만 한번쯤 링크를 걸어 놓고 궁금한 사항 발생시 첫번째로 확인해 볼 레퍼런스 사이트를 정리해 본다 



Git 메뉴얼

  - git-scm.com 의 한글 번역 메뉴얼

 




명령어 레퍼런스

  - gitref.org : 명령어에 대한 예와 다이어그램이 잘 나와있음






Merge 와 Diff Tool 바꾸기 

  - git의 기본적인 merge, diff 툴을 좀 더 괜찮은 넘으로 바꾸어 사용하기

  - p4merge 툴로 바꾸기 : 다운로드 받아서 설치한다

  - extMerge 파일 생성

/Users/nulpulum> cd /usr/local/bin

/usr/local/bin> cat extMerge

#!/bin/sh

/Applications/p4merge.app/Contents/MacOS/p4merge $*


  - extDiff 파일 생성

/usr/local/bin> cat extDiff

#!/bin/sh

[ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"


  - 환경설정 명령 : git config --global <옵션>

// 옵션들 

merge.tool=extMerge

mergetool.extMerge.cmd=extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"

mergetool.extMerge.trustexitcode=false

diff.external=extDiff


  - ~/.gitconfig 내역 변경

[merge]

tool = extMerge

[mergetool "extMerge"]

cmd = extMerge \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"

[mergetool] <-- 제거

trustExitCode = false

[diff]

external = extDiff


  - 사용법은 p4merge 툴로 바꾸기 참조하시라





기초 문법 다시 보자 





Git 원리 이해하기 


posted by 윤영식
2013. 2. 28. 11:29 Git, GitHub/Git Lec02

rebase를(참조) 통하여 다른 브랜치의 전체 commit 내역을 복사해오지 않고 특정 commit 내역만을 가져오고 싶을 경우 cherry-pick을 사용한다


1) 언제 사용

  - 토픽이나 패치 브랜치에서 개발된 특정 commit만을 가져오고 싶을 경우 

  - 즉, 하나의 commit만 rebase 하는 것이다 



2) 실습

  - cherry-pick을 하기전 상태

  

  [5.26 master브랜치와 별도의 토픽브랜치 ruby_client로 두개의 커밋이 존재]


/////////////////////////////////////////

// ruby_cleint별도 브랜치 만들어진 이후

// master 브랜치 커밋내역

git log --pretty=oneline -since="2 hours"

fatal: unrecognized argument: -since=2 hours

[nulpulum:~/git-repositories/pro_git]git log --pretty=oneline --since="2 hours"

514281f305bd001776ca41efebccf8276a6bfd98 modify dowon.js


/////////////////////////////////////////

// ruby_client 브랜치로 이동

$ git checkout ruby_client

Switched to branch 'ruby_client'

$ git log --pretty=oneline --since="2 hours"

0f79ccda8c4086d57a4b9ed53c87ecaf11e52ba5 modify topci.txt

40396ae5ab8a964704e0ab84809bb499f9c996b2 add topic.txt


  - check-pick 수행하기 

    + 그림에서 e43a6에 해당하는 "40396"에 대해서 master 브랜치에서 check-pick 한다

/////////////////////////////////////////

// master 브랜치로 토픽브랜치의 특정

// commit 내역만을 rebase = cherry-pick

$ git checkout master

Switched to branch 'master'

Your branch is ahead of 'origin/master' by 1 commit.

  (use "git push" to publish your local commits)

[nulpulum:~/git-repositories/pro_git]git branch

* master

  ruby_client


$ git cherry-pick 40396ae5ab8a964704e0ab84809bb499f9c996b2

[master 4963fef] add topic.txt

 1 file changed, 1 insertion(+)

 create mode 100644 topic.txt


/////////////////////////////////////////

// ruby_client의 커밋이 master 브랜치로 

// 새로운 commit을 제일 앞에 놓았다 

$ git log --pretty=oneline --since="2 hours"

4963fef54f1d6760ec4e5ff15c9684e0f5e6ad4e add topic.txt

514281f305bd001776ca41efebccf8276a6bfd98 modify dowon.js

[nulpulum:~/git-repositories/pro_git]git branch

* master

  ruby_client


  

  [5.27 e43a6 커밋내역 하나만 master의 제일 앞으로 새로운 commit이 생성]



<참조>

  - Pro Git : p127

posted by 윤영식
2013. 1. 30. 15:36 Git, GitHub/Git Lec02

공개팀으로 Git을 운영하는데는 비공개팀과 약간의 차이가 있다. 공개팀 운영시에는 모든 사람이 공유 저장소에 대해서 쓰기 권한이 없기 때문이다. 프로젝트 관리자는  Fork를 지원하는 Git 호스팅에서 -GitHub- 기여하는 방법에 대해 가이드 해야 한다. GitHub을 예로 Pull Request는 어떤 절차로 이루어 질까?



1) 갑순이 Fork 질 하기 

  - 갑순이 중앙 저장소(예, ysyun)의 GitHub에서 Fork질 하여 자신의 원격 저장소(예, nulpulum)를 하나 만든다  

    + GitHub의 갑순이 계정으로 로그인한다 

    + GitHub의 중앙 저장소(ysyun)로 이동하여 "Fork" 버튼을 클릭하면 갑순이 계정으로 중앙 저장소(nulpulum)가 clone된다 

     

     [GitHub Fork 클릭]


  - 갑순이 원격 저장소(nulpulum)를 자신의 PC 로컬 저장소로 clone 한다 : git clone <갑순이 원격저장소>

  - 갑순이의 원격 저장소 이름을 origin에서 myfork로 바꾼다

    + git remote -v : default 설정된 origin 명칭 확인 

    + git rename origin myfork : origin을 myfork라는 이름으로 변경 



2) 갑순이 별도 브랜치 만들고 push 질 하기 

  - 갑순이 별도의 featureA 브랜치를 만들고 두번의 commit 질 한다 

    + git checkout -b featureA : featureA 만들기 

  - 간혹 commit  실수 한것은 날려 버리고 싶다 : git reset --hard HEAD^ (참조)

  - 갑순이의 원격 저장소(nulpulum)인 myfork에 featureA를 push 한다 (참조)

    + GitHub 의 commit 내역은 "Commit" 탭에서 확인가능하다 


  [GitHub Commit]


//////////////////////////////////////////

// 로컬 저장소에 새로운 브랜치 만들기 

dowon /d/git-nulpulum/jmqtt_client (master)

$ git checkout -b featureA

Switched to a new branch 'featureA'


dowon /d/git-nulpulum/jmqtt_client (featureA)

$ vi license.properties


dowon /d/git-nulpulum/jmqtt_client (featureA)

$ git commit -am "modified license 1"

[featureA 9e5ce9b] modified license 1

 1 file changed, 1 insertion(+)


dowon /d/git-nulpulum/jmqtt_client (featureA)

$ vi licene.properties


dowon /d/git-nulpulum/jmqtt_client (featureA)

$ git commit -am "modified license 2"

[featureA b3787b8] modified license 2

 1 file changed, 1 insertion(+), 1 deletion(-)


////////////////////////////////////////////

// 원격 저장소에 새로운 브랜치 만들기 

dowon /d/git-nulpulum/jmqtt_client (featureA)

$ git push myfork featureA

Username for 'https://github.com': nulpulum@gmail.com

Password for 'https://nulpulum@gmail.com@github.com':

Counting objects: 8, done.

Delta compression using up to 2 threads.

Compressing objects: 100% (4/4), done.

Writing objects: 100% (6/6), 562 bytes, done.

Total 6 (delta 2), reused 0 (delta 0)

To https://github.com/nulpulum/jmqtt_client.git

 * [new branch]      featureA -> featureA


  

 [갑순이 GitHub 저장소(nulpulum)의 featureA 브랜치]



3) 갑순이 Pull Request 질 하기 

  - 갑순이는 수정한 사항에 대하여 중앙 저장소(ysyun)의 관리자에게 Pull Request를 요청하여 자신이 수정한 것을 가져가라 알린다

    + 갑순이 GitHub 계정으로 들어가서 상단의 "Pull Request"를 클릭한다 

 

 [갑순이 GitHub 저장소(nulpulum)의 Pull Request 버튼 클릭]


    + Pull Request 원하는 브랜치를 선택한다 

    + 갑순이 원격 저장소(nulpulum)에서 featureA를 선택하고 중앙 저장소(ysyun)에게 Pull Request를 보낸다

    + featureA에 commit 두번 한것과 파일 수정 정보등이 보인다 -Commits (2) Files Chagned (1)-

  [Pull Request 요청 내역 입력한후 "Send pull request" 보내기]



    + 중앙 저장소 (ysyun)에서 Pull Request온 내역을 볼 수 있다 

 [중앙 저장소(ysyun)의 Pull Request 내역 보기]

  


  - 가급적 Pull Request를 할때는 별도의 토픽 브랜치(갑순이가 만든 featureA)와 같이 만들어서 관리자에게 요청한다 

    + master 브랜치와 구분하고 수정 내용을 거부할 때 쉽게 버릴 수 있다

  - 갑순이 다른 브랜치를 만들어서 작업할 때는 featureA에서 하지 말고 origin/master에서 한다 

    + git checkout -b featureB origin/master



<참조> 

  - Pro Git (p. 110)

  - 2개 아이디의 Public repository를 만들어서 테스트 해보았다.

posted by 윤영식
2013. 1. 28. 10:12 Git, GitHub/Git Lec02

비공개 대규모 팀을 운영할 때는 Git Workflow에서 Integration-Manager 방식을 선택한다. 이는 팀별로 별도의 Master를 두고 Integration Manager가 중앙 Master로 push할 수 있는 권한을 갖도록 한다. 즉, 중간 단계의 master가 하나 더 있는 구조이다. 


1) 가정

  - 갑순이는 두 팀에 속한다 

  - 1팀 갑순이 + 갑돌이

  - 2팀 갑순이 + 갑복이 



2) 1팀 갑순이 featureA만들어 갑돌이와 작업

  - 갑순이는 저장소를 clone하고 featureA 브랜치를 만들고 수정후 커밋한다 

    + feautreA 브랜치 생성 : git checkout -b featureA

    + 커밋 : git commit -am "add function"


  - 갑순이가 해당 브랜치를 갑돌이와 공유하려 한다. 

    + 여기서 갑순이는 Integration Manager가 아니다

    + 갑순이는 운격 저장소에 featureA로 push 하고 갑돌이에게 해당 사실을 알린다 



3) 2팀 갑순이 featureB 브랜치 만들어 갑복이와 작업

  - 갑순이는 갑복이와 원격 저장소의 master 브랜치를 기반으로 featureB작업을 계속 수행하기로 한다

    + 원격저장소에서 로컬 저장소로 fetch 하기 : git fetch origin

    + git checkout -b featureB origin/master


  - 갑순이가 몇가지 작업을 하고 featureB에 커밋을 한다 

    + git fetch origin

    + git checkout -b featureB origin/master

    + 2번의 커밋객체 생성 : git commit -am "modified some function" (e5b0f) -> git commit -am "add new function" (85127)


  


   [그림 5.12] 갑순이 현재 로컬 저장소 커밋 그래프


  - 갑순이 featureB를 push 하려는데 갑복이로부터 이미 featureBee 브랜치로 한번 push 했다고 연락을 받는다

    + 갑복이 내역을 merge 하기위해 fetch 한다 : git fetch origin

    + 갑복이 브랜치를 merge 한다 : git merge origin/featureBee

 

  - 갑순이 이제 featureB를 원겨 저장소로 push 하려는데 갑복이 featureBee 와 이름이 틀리다

    + 로컬 featureB를 원격 featureBee로 push 한다 : git push origin featureB:featureBee (cd685)



4) 1팀 갑돌이 featureA 작업

  - 갑돌이 featureA 작업후에 push 했고 갑순이에게 확인요청한다 

  - 갑순이는 내역확인을 위하여 원격저장소에서 fetch 한다 : git fetch origin 

  - 갑순이는  featureA 브랜치에 어떤 것이 업데이트 되었는지 확인한다 (갑돌이 커밋시 메시지 잘 입력했다 가정함)

    + 변경내역 확인 : git log origin/featureA ^featureA 

    + 확인후 로컬 featureA 브랜치로 이동 : git checkout featureA

    + 원격 featureA를 로컬 featureA에 merge 수행 : git merge origin/featureA

  

  - 갑순이 다시 일부 수정하여 featureA 브랜치를 원격 저장소로 push 한다 

    + git commit -am "small tweak"

    + git push origin featureA (774b3)

    + 갑순이의 저장소를 보자 


  


  [그림 5.13] featureB도 원격으로 push하고 featureA도 원격 저장소로 push한 갑순이 로컬 저장소 



5) 갑순이 메인 브랜치로 merge 요청작업 

  - Integration-Manager는 두 브랜치를 merge 하고 메인 브랜치의 커밋 (5399e) fetch해 온다 

  - 다음과 같은 구조가 될 것이다 


  


  [그림 5.14] integration manager는 774b3 과 ce685 커밋을 merge하여 5399e를 원격저장소에 커밋한 후 갑순이가 fetch 함!



<참조>

  - Pro Git 5장 108p

posted by 윤영식
2013. 1. 28. 09:50 Git, GitHub/Git Lec02

소규모 팀으로 일을 할때 어떤 절차에 의해서 소스를 Merge하고 원격저장소로 Push 할 수 있는지 알아보자. 팀원간 Git 기본 workflow로써 가장 기본적으로 숙지해야할 사항이라 판단된다. 


1) 가정 

  - 3~5명이 하나의 원격 Git - 예, GitHub Private Repository - 에 원본을 합친다 

  - 각자가 local repositor로 내려 받아서 작업을 한다 


2) 갑순이 push 작업

  - 갑순이가 GitHub에서 저장소를 복제한다 : git clone <git address>

  - 갑순이가 하나의 파일에 대해서 수정하고 commit 한다 : git commit -am "modified files"

  - GitHub에 변경된 파일을 push 한다 : git push origin master


3) 갑돌이 push 작업

  - 갑돌이도 GitHub에서 저장소를 복제한다 

  - 값돌이도 다른 파일 하나를 수정하고 commit 한다 

  - GitHub에 변경된 파일을 push 한다 => 오류가 발생하여 파일 push를 하지 못한다 


4) 갑돌이 push 오류 해결하기 

  - 갑돌이는 Push 하기전 원격저장소의 갑순이 commit 내역을 로컬 저장소에 merge 해야 한다 

  - 갑돌이는 먼저 원격 저장소의 내용을 fetch 한다 : git fetch origin

  

   


   [그림 5.4] origin에서 fetch를 하면 origin/master가 된다(fbff5) 로컬의 master (738ee)와 merge는 안된 상태

  

  - 로컬 master와 원격 origin/master를 merge 한다 : git merge origin/master

  - 갑돌이는 merge를 완료하고 push를 재시도 한다 : git push origin master  (origin master 생략가능)


  


  [그림 5.5] merge를 했을 때 새로운 commit object가 생성된다 (72bbc)



  


  [그림 5.6] push를 하게되면 origin/master의 위치도 최신 commit object를 가르키게 된다 (72bbc)



5) 갑순이 branch 생성후 push 추가작업

  - 갑순이는 이슈해결을 위하여 별도 issue54 브랜치를 만들었다

  - issue54 브랜치에 대해서 3개의 commit을 수행하였다. 

  - 원격으로 push 하기 위하여 먼저 원격의 갑돌이 push 내역을 fetch 한다 : git fetch origin


  


  [그림 5.8] fetch하여 원격의 origin/master를 가져온다 (72bbc)


  - fetch 해온 origin/master 와 merge할 내용을 확인한다 : git log --no-mergs origin/master ^issue54

  - merge를 위하여 master 브랜치로 checkout 한다 : git checkout master

  - 먼저 issue54 부터 merge 한다 : git  merge issue54

    origin/master 와 issue54 브랜치는 모두 master 보다 fast-forward 된 브랜치 이기 때문에 순서에 상관없이 merge해도 된다

  - 다음 origin/master 를 merge 한다 : git merge origin/master


  


  [그림 5.9] local의 issue54를 merge하고, origin/master와 merge를 하면 새로운 commit object가 생성된다 (8059c)


  - 로컬 저장소에 모드 merge 되었으므로 원격 저장소로 push 한다 : git push origin master 


  


  [그림 5.10] push를 하게되면 origin/master가 가르키는 commit object는 최신 8059c 가 된다. 



6) 최종 Workflow 모습

  - 갑순이 == Jessica

  - 갑돌이 == John


   


  [그림 5.11] push -> fetch -> merge -> push 작업이 이루어진다     


<참조>

  - Pro Git : 5장 page 104

posted by 윤영식
2013. 1. 25. 09:20 Git, GitHub

Git을 배우려면 다음과 같이 하자. 


1. Git 레퍼런스와 강좌 사이트 

  - Pro Git 한글 번역본 완독

  - http://gitimmersion.com : 사이트 튜토리얼 수행 

  - http://gitready.com : 초심자, 중급, 고급 명령 수행

  - http://gitref.org : Git Reference 에서 바로 Cheat

  - Git Cheatsheet : UI에서 명령흐름을 직관적으로 보여줌


2. 도전과제 

  - PPT의 내용을 직접 수행해 보자  


posted by 윤영식
2013. 1. 25. 09:05 Git, GitHub/Git Lec02

Git commit 할 때 가이드 라인을 잘 지켜서 원격 저장소에 소스가 꼬이지 않도록 하고, 커밋된 내역을 잘 이해할 수 있도록 메세지 작성 정책에 대해 알아보자


  - 공백 문자를 깨끗이 제거 한다 : 확인)  git diff --check (공백 문자 오류확인가능, 잘 못 사용한 공백은 X 문자로 바꿈)

  - 최대한 수정사하을 하나의 주제로 요약한다

    + 여러 가지 이슈에 대한 수정사항을 하나의 커밋에 담지 말아라

    + 적절한 메세지를 작성한다 : 반드시 좋으 커밋 메세지를 담는다


  - 같은 파일의 다른부분을 수정하는 경우에는 git add -patch 명령을 이용한다 

    + 한 부분씩 나누어 Stage 영역에 저장해야 한다 


  - 메세지 작성

    + 첫줄엔 50자내로 간략히 요약

    + 두번째줄 비우고 세번째줄에 자세히 설명글 :개발동기, 구현 상황, 제약조건/상황

    + 글은 현재형을 사용한다 

    + 추가 내용은 한줄 띄우고 시작한다 

    + 잘쓰여진 커밋 메세지는 git log --no-merges 명령으로 꼭 살펴본다 

   예)

   

posted by 윤영식
2013. 1. 25. 08:44 Git, GitHub/Git Lec02

Git은 분산 버전관리 시스템이다. 서로 각자의 저장소를 가지고서 어떻게 충돌없이 잘 사용할 수 있을지 알아보자. (5장)


1) 중앙집중식 Workflow

  - 예전의 Subversion에 익숙한 사용자들의 방식

  - 예로 2명이 작업, 한명이 서버로 update코드 push하면 다른한명이 서버에서 update코드를 pull하여 merge 수행

  - 모든 사용자에게 서버에 push 권한을 부여해야 함

  - 그러나 중앙 서버 저장소로 a코드가 다른이에 의해 push 되었고, 다른사람이 a코드를 수정하여 push해도 Git은 이것을 방지해 준다. 즉, 다시 로컬로 fetch 또는 pull 하지 않으면 중앙 서버로 push 할 수 없게 막아준다




2) 통합관리(Integration-Manager) Workflow

  - 여러 리모트 저장소를 두고 한개는 R/W 가능, 다른 한개는 R만 가능하게 설정가능 하다

  - 이것은 GitHub의 운영방식이다. Pull Request 수행하면 통합관리자가 이것을 보고 기여자의 저장소에서 원본 저장소로 pull하여 merge 하게 된다

 



3) 독재자 보조관(Dictator and Lieutenants) Workflow

  - 2)번 형태의 확장판

  - Linux Kernel과 같은 큰 프로젝트에서 사용한다 

 


* 다양한 변종의 Workflow가 존재함 


<참조>

  - 성공적인 Git Branch 전략 (한글번역본 - dogfeet)

    + feature : 기능 만들기 

    + develop : 개발진행

    + release : 릴리즈 

    + hotfixes : 긴급 패치 

    + master : 원본 



posted by 윤영식
2013. 1. 17. 11:13 Git, GitHub/GitHub

Git 서버는 사내에 설치할 수도 있고 GitHub과 같은 서비스를 사용할 수도 있다. 아무래도 스타트업 기업이라면 GitHub의 Private을 이용하는게 좋겠다. GitHub에 대해 알아보자 


1) GitHub 가입하고 저장소 만들기

  - 일반적인 서비스 가입절차와 동일하다 

  - 상단 오른쪽 아이콘 "Create a new repo" 클릭하여 저장소를 만든다. (수동, 자동방식이 존재한다)

  - 최초 저장소에 README.md markdown 형식으로 readme 를 만들어 준다 

  - Admin에서 동료를 추가할 수 있다


2) 프로젝트 Fork

  - 권한이 없는 프로젝트에 참여하고 싶으면 Fork한다. Fork가 되면 자신의 Repository로 복제가 되고 이곳에 마음대로 Push 할 수 있다. 


3) Pull Request 

  - jQuery 원본 repo에서 자신의 리모트 repo로 fork 한다 (in GitHub)

  - 자신의 리모트 repo에서 로컬 repo로 clone 한다 

  - jQuery 원본 repo에서 pull(fetch->merg)한다 (master 브랜치 commit 내역을 맞추기 위함. 물론 conflict 나면 수정해야 겠다)

  - 자신의 로컬 repo -> 자신의 리모트 repo로 push 한다 

  - 자신의 리모트 repo인 jQuery를 jQuery 원본 repo 쪽으로 Pull Request 한다 (Pull Request 받아주는 약속이 OSS마다 틀리니 사전숙지함)

  - 즉, 자신의 리모트 repo 를 원본의 repo의 committer에게 Pull 해달라고 요청을 보내는 것이다


<참조> 

  - http://blog.outsider.ne.kr/866 : GitHub Fetch, Pull, Push, Pull Request

  - http://blog.outsider.ne.kr/644 : GitHub에 Branch, Tag push 하기 

  - http://blog.outsider.ne.kr/641 : GitHub에 있는 Branch 로컬로 가져오기 (git checkout -b [로컬브랜치명] [원격alias]/[원격브랜치명])

posted by 윤영식
2013. 1. 16. 10:53 Git, GitHub/Git Lec02

Git 에서 한 브랜치에서 다른 브랜치로 합치는 방법은 Merge와 Rebase가 있다. Rebase 사용시 좋은 점과 사용하지 말아야 할 때에 대해서 알아보자 (ch 3.6)


1) Rebase 기초 

  - 일반적으로 3 way merge로 브랜치 합치기를 함    

    


  - Rebase는 한 브랜치에서 변경된 사항을 다른 브랜치에 적용한다 

    + Rebase할 브랜치를(B) checkout한 브랜치가 가르키는 커밋까지 diff하여 다른 내용을 임시로 저장해 놓음 (temp)

    + temp에 저장한 변경사항을 차례로 적용하여 Rebse될 브랜치(A)에 새로운 commit을 만든다 

    + Rebase될 브랜치(A)는 가장 최신 commit 개체가 되고 브랜치의 포인터는 fast-forward 된다 

    + 즉, Rebase는 기존 commit을 사용하는 것이 아니라 새로운 commit을 만들어 합치는 것이다

  -  Rebase가 merge 보다 좀 더 깔끔한 히스토리를 만든다. 일이 병렬로 하다 rebase 하면 선형적으로 된다 

  - 보통 리모트 브랜치에 커밋을 깔끔하게 적용하고 싶을 때 사용한다 (메인 프로젝트에 패치를 보낼 때)

  - Rebase=브랜치의 변경사항을 순서대로 다른 브랜치에 적용하면서 합치고, Merge는 두 브랜치의 최종결과만 합친다


2) Rebase 위험성 

  - 이미 공개 저장소에 Push 한 커밋을 Rebase 하지 마라 : 동료와 협업시 commit 객체 내용이 삭제되어 버린다 (p. 78)

  - 즉, 로컬에서 작업진행한 내 commit 개체만 Rebase하고 리모트에 있는 commit 개체의 rebase는 불허!!!

  - Push 하기 전에 정리하려고 Rebase하는 것은 괜찮다 


<사용법>

  - http://mobicon.tistory.com/165  : 리모트 저장소에서 pull하고 conflict 날 경우

  - http://mobicon.tistory.com/164  : 로컬 저장소에서 conflict 날 경우 

'Git, GitHub > Git Lec02' 카테고리의 다른 글

[Pro Git] 커밋 가이드라인  (0) 2013.01.25
[Pro Git] 협업 Workflow  (0) 2013.01.25
[Pro Git] Branch 사용하기  (0) 2013.01.16
[Pro Git] Git Alias 사용하기  (0) 2013.01.08
[Pro Git] Tag 사용하기  (0) 2013.01.08
posted by 윤영식
2013. 1. 16. 10:20 Git, GitHub/Git Lec02

Git은 Branch를 자유자래로 사용함으로써 그 진가를 실감할 수 있다. 복잡한 애플리케이션이나 프로젝트일 수도록 더욱 힘을 발휘한다. Branch에 대하여 알아보자. 


1) 분산 버전 관리 시스템

  - 클라이언트가 파일의 마지막 Snapshot을 Checkout 하지 않는다. 그냥 저장소를 전부 복제한다

  - 서버에 문제 생겨도 다시 작업시작 가능하다

  - DVCS 한경에서는 리모트 저장소가 존재하고 여러개 문제없다. 동시 다양한 그룹과 다양한 방법으로 협업이 가능하다. 



2)  Git 철학

  - 2005년 BitKeeper 사용하지 않으며 리누스 토발즈가 개발 

  - 빠른 속도

  - 단순한 구조

  - 비선형적인 개발 (수천 개의 동시 다발적인 브랜치)

  - 완벽한 분산

  - 리눅스 커널같은 대형 프로젝트에도 유용할 것 (속도나 데이터 크기면에서)


3) Git 데이터 저장 방식

  - Git 은 데이터를 일련의 Snapshot으로 기록한다 

  - Staging Area에서 Local Git 저장소에 파일 저장(=Blob). 해당 파일의 Checksum을(SHA-1) 저장한다.

  - Commit을 하면 Local Git 저장소에 

    + 하위 디렉토리의 "트리 개체" 생성

    + 트리 개체 밑으로 "커밋 개체" 생성 : 메타데이터(저자,메시지)와 트리 개체 포인터, 이전 트리 개체 포인터 정보 저장

  - 즉, Git 저장소에 Commit > Tree > Blob 이 생성된다 




4) 브랜치(Branch) 

  - Git 기본 master 브랜치를 만든다. master 브랜치는 자동으로 마지막 Commit 개체를 가르킨다 

   + 즉, 브랜치는 Git 저장소의 Commit 개체를 가르키는 것이다. 

  - 브랜치는 SHA-1 40자의 체크섬 파일에 불과하다. 즉 41바이트(줄바꿈포함) 크기

  


  - Git은 특수한 HEAD 라는 포인터가 존재 = 지금 작업 중인 브랜치를 가르킴 

    + 즉, Head > Master(브랜치) > Commit 포인터를 가르킨다 


  - 브랜치를 나누고 각각의 브랜치가 commit 이후 merge 방법 = 3 way merge

   + Merge시에 Merge에 대한 정보가 들어있는 커밋을 하나 만든다 


5) 충돌(Conflict) 

  - 3 way merge 시에 같은 파일의 한 부분을 각각의 브랜치가 수정하였을 때 발생

  - git status 명령으로 conflict 상황 체크 

  - 충돌부분을 직접 수정후 git add -> git commit 함 

  - Merge 브랜치 필터링 명령

    + git branch --merged : merge한 브랜치 목록 확인 (* 가 없는 브랜치는 이미 다른 브랜치와 merge 한 것임)

    + git branch --no-merged : 현재 ckeckout한 브랜치에 merge 하지 않은 브랜치를 보여줌 


6) 브랜치 접근 in Local

  - master 브랜치 : 배포/안정화 브랜치

  - develop 브랜치 : 개발 브랜치, develop 밑으로 topic 브랜치 (각 브랜치를 하나의 실험실로 생각한다)



  - topic 브랜치 : 어떤 한 가지 주제나 작업의 짧은 호흡의 브랜치이다 예) hotfix 브랜치

    + master merge후에 삭제

    + 내용별 검토, 테스트가 용이하다


7) 리모트 브랜치 

  - 리모트 브랜치란 리모트 저장소에 있는 브랜치이다. 

  - 명칭 = (remote)/(branch) 형식 예) 리모트 저장소가 origin 이고 master 브랜치이면 origin/master 로 표현함 

  - git clone으로 local에 내려 받으면 origin/master가 생기고 마음대로 조종할 수 없다. 

  -  git fetch origin을 할때 자동으로 리모트 저장소의 최신 master 브랜치로 local의 origin/master가 갱신된다

    + 누군가 리모트에 push를 하여 origin의 master commit을 갱신함 

    + 나는 옛날 origin/master를 가지고 있고 그동안 local에서 commit도 했음, pull로 최신으로 update 할 경우 

    + git fetch origin/hotfix01 로 브랜치 지정하여 로컬로 받으면 저장소에 브랜치가 생성되지 않고 포인터만 생성됨

      = git merge origin/hotfix01 로 새로받은 브랜치 내용을 merge 한다

      = 또는 merge 하지 않고 새로운 브랜치로 만들려면 git checkout -b hotfix01 origin/hotfix01  수행 


  - git push [remote] [branch] : 리모트에 쓰기 권한이 있어야 한다. 예) git push origin hotfix01

    + git push [remote] [local branch]:[remote branch] 로 로컬/리모트 브랜치 명이 틀릴 때 사용한다 


8) 브랜치 추적(Tracking)

  - Git은 리모트 저장소에서 Clone시에 master 브랜치를 origin/master 브랜치로 추적 브랜치를 만든다

  - checkout 할 때도 자동으로 추적 브랜치가 만들어 져서 git pull/push 할 때 별도의 옵션을 주지 않고 해당 리모트 브랜치로 수행

  - git checkout -b [branch] [remotename/branch] : 추적 브랜치 만듦 


9) 리모트 브랜치 삭제 

  - git push [remotename] [local branch] :[remote branch] 협업때 사용했던 서브 브랜치를 이제 삭제 하고 싶을 경우 

  - 예) git push origin :hotfix01  [local branch]를 비워두면 "로컬에서 빈 내용을 리모트의 [remote branch]인 hotfix01에 채워 넣어라" 라는 뜻이 된다   

posted by 윤영식
2013. 1. 14. 00:39 Git, GitHub

Remote 저장소인 GitHub과 Local 저장소의 commit 내역이 일치하지 않을 경우 rebase로 어떻게 해결하는지 알아보자. Local 저장소내에서 rebase를 사용하는 것과 약간의 차이점이 존재한다. (참조)


1. Remote 저장소 merge conflict 조건

  - GitHub에 이미 다른 Commit이 존재한다 (분홍색)

  - Local 저장소에 변경된 commit이 존재한다

  - git push 를 수행할 경우 merge conflict가 발생한다

  - 기존에 push후 conflict 발생시 pull 하고 문제 해결하고 다시 push 한다 (해결하기)

  



2. 이제 1)번의 경우 말고 fetch 와 rebase 사용

  - git fetch 를 통하여 local 저장소로 merge 하지 않고 origin/master의 별도 브랜치를 local 저장소로 복사하자 

    


  - git rebase를 수행한다. 이때 다음의 3단계로 진행이 된다. 

    + 브랜칭 된 이후의 master commit 내역을 temporary area로 이동시킨다-origin/master가 아니라- (초록색)

     


    + origin/master를 master 브랜치로 commit 한다. (분홍색)

       


    + temporary area에 있는 master commit 내역을 다시 master로 commit 한다. 

     



3. local과 remote의 같은 파일을 commit 하였을 때 rebase 하는 방법

  - master 브랜치에서 rebase하고 있음에 주의한다 

////////////////////////////////////////////////////////////////////////////

// remote 저장소와 commit 내역을 맞추고 확인해 보자 

$ git log --pretty=oneline

bbeb691d80512e17279764312f60416ebf28dd86 add content in rebase of local repo


// rebase.html 파일의 내용 


////////////////////////////////////////////////////////////////////////////

// 로컬에서도 rebase.html 파일을 변경하고 push를 시도하지만 reject 된다.

// 즉, remote 저장소의 rebase.html과 local 저장소의 rebase.html 내역이 틀리다.

$ git push

Username for 'https://github.com':

Password for 'https://ysyun@yuwin.co.kr@github.com':

To https://github.com/ysyun/pro_git.git

 ! [rejected]        master -> master (non-fast-forward)

error: failed to push some refs to 'https://github.com/ysyun/pro_git.git'

hint: Updates were rejected because a pushed branch tip is behind its remote

hint: counterpart. If you did not intend to push that branch, you may want to

hint: specify branches to push or set the 'push.default' configuration

hint: variable to 'current' or 'upstream' to push only the current branch.


////////////////////////////////////////////////////////////////////////////

// origin/master를 local 저장소로 가지고 온다. 

$ git fetch

remote: Counting objects: 5, done.

remote: Compressing objects: 100% (3/3), done.

remote: Total 3 (delta 1), reused 0 (delta 0)

Unpacking objects: 100% (3/3), done.

From https://github.com/ysyun/pro_git

   d895a7e..9274820  master     -> origin/master


////////////////////////////////////////////////////////////////////////////

// rebase를 위하여 master로 이동한다 

$ git branch

* (no branch)

  master


$ git checkout master

Warning: you are leaving 1 commit behind, not connected to

any of your branches:


  bbeb691 add content in rebase of local repo


If you want to keep them by creating a new branch, this may be a good time

to do so with:


 git branch new_branch_name bbeb691d80512e17279764312f60416ebf28dd86


Switched to branch 'master'

Your branch and 'origin/master' have diverged,

and have 1 and 3 different commits each, respectively.


$ git  branch

* master


////////////////////////////////////////////////////////////////////////////

// rebase를 수행한다. 

// rebase.html 파일 내역에서 conflict가 나온다고 메시지를 출력한다 

$ git rebase

First, rewinding head to replay your work on top of it...

Applying: updating rebase in local repo.

Using index info to reconstruct a base tree...

M       rebase.html

Falling back to patching base and 3-way merge...

Auto-merging rebase.html

CONFLICT (content): Merge conflict in rebase.html

Failed to merge in the changes.

Patch failed at 0001 updating rebase in local repo.


When you have resolved this problem run "git rebase --continue".

If you would prefer to skip this patch, instead run "git rebase --skip".

To check out the original branch and stop rebasing run "git rebase --abort".


$ git status

# Not currently on any branch.

# Unmerged paths:

#   (use "git reset HEAD <file>..." to unstage)

#   (use "git add/rm <file>..." as appropriate to mark resolution)

#

#       both modified:      rebase.html

#

no changes added to commit (use "git add" and/or "git commit -a")


////////////////////////////////////////////////////////////////////////////

// rebase.html 파일 내역을 보고 적절히 수정한다 

$ cat rebase.html

 this is rebase html file ok

<<<<<<< HEAD

     updating rebase in remote repo. again

     add content in remote repo.

=======

    updating rebase in local repo.

>>>>>>> updating rebase in local repo.


$ vi rebase.html

$ cat rebase.html

 this is rebase html file ok

     updating rebase in remote repo. again

     add content in remote repo.

    updating rebase in local repo.


////////////////////////////////////////////////////////////////////////////

// rebase.html 을 staging area로 add 한다. 

$ git add rebase.html


////////////////////////////////////////////////////////////////////////////

// rebase를 계속 진행한다 

$ git rebase --continue

Applying: updating rebase in local repo.


////////////////////////////////////////////////////////////////////////////

// commit log를 확인해 보면 rebase가 되어서 remote commit 내역이 local 저장소에 

// 복사되었다. 

$ git log --pretty=oneline

30d42e6785e441c3b515a4f4181dbfa051ad400a updating rebase in local repo.

9274820a9f62b2e08411ffb34d808508c7a74f93 add content in rebase of remote repo

d895a7e83d85d05f2c81585232f9c3e22426383a updating rebase again in remote repo

8c7c04b40d9fce0a1ae5a52b45b438fa14ea95e1 Update rebase.html


////////////////////////////////////////////////////////////////////////////

// 다시 push를 하면 정상적으로 remote 저장소로 push 가 된다 

$ git push

Username for 'https://github.com':

Password for 'https://ysyun@yuwin.co.kr@github.com':

Counting objects: 5, done.

Delta compression using up to 2 threads.

Compressing objects: 100% (3/3), done.

Writing objects: 100% (3/3), 323 bytes, done.

Total 3 (delta 2), reused 0 (delta 0)

To https://github.com/ysyun/pro_git.git

   9274820..30d42e6  master -> master


// remote에 local에서 직접 수정한 내역이 commit 됨 


// local repo(파란색, 30d42e6785)의 SHA 값이 가장 상위에 그 다음 remote repo 의 SHA(927480a9f...)가 밑에 있다. 


posted by 윤영식
2013. 1. 13. 22:00 Git, GitHub

git에서 merge conflict가 발생할 경우 좀 더 쉽게 하고 싶다면 rebase를 사용할 수 있다. rebase의 동작 순서와 언제 사용할지 알아보자. 


1) local rebase 명령 전제 조건

  - master로 부터 현재 commit 내용으로 신규 branch인 admin을 만든다

  - master로 새로운 commit 내용이 있고, 신규 branch(admin)도 새로운 commit이 존재한다 

  - admin 브랜치의 내역을 그대로 master 브랜치로 merge하지 않고 add 하고 싶을 경우 

  


  - git checkout admin : admin 브랜치로 checkout 한다 

  - git rebase master : master의 commit 내역을 admin 브랜치에 add 한다   

  


  - git checkout master : 다시 master로 돌아 온다

  - git merge admin : master에 admin을 merge 한다. 이럴 경우 admin 브랜치로 갈라진 이후 master의 신규 commit이 admin 브랜치에 들어 있으므로 fast-forward merge가 가능해 진다. 

////////////////////////////////////////////////////

// admin 브랜치를 신규로 만들고 checkout 하기 

$ git checkout -b admin

Switched to a new branch 'admin'


$ git branch

* admin

  master


////////////////////////////////////////////////////

// rebase.html 파일을 신규로 만들고 commit 2번 하기 

$ touch rebase.html

$ git add rebase.html

$ git commit -m "add rebase html"

[admin d375a11] add rebase html

 1 file changed, 1 insertion(+)

 create mode 100644 rebase.html


$ vi rebase.html  <- 내용 변경 

$ git commit -am "update rebase html"

[admin 22bbd02] update rebase html

 1 file changed, 1 insertion(+), 1 deletion(-)


////////////////////////////////////////////////////

// master 에서도 신규 파일을 생성하고 두번 commit 하기

$ git checkout master

Switched to branch 'master'


$ touch dowon.js

$ vi dowon.js

$ git add dowon.js

$ git commit -m "add dowon javascript file"

[master cc77217] add dowon javascript file

 1 file changed, 1 insertion(+)

 create mode 100644 dowon.js


$ vi dowon.js

$ git commit -am "add dowon javascript file"

[master 841c14f] add dowon javascript file

 1 file changed, 1 insertion(+), 1 deletion(-)


////////////////////////////////////////////////////

// admin 브랜치로 이동하여 master의 신규 commit 2 개를

// admin 브랜치로 복사하기 

$ git checkout admin

Switched to branch 'admin'


// admin 브랜치의 commit 내역 확인 

$ git log --pretty=oneline

22bbd02cf7c49a96efb5eb4d38768e67d0c120da update rebase html

d375a1105a24ccc69895ef74d041329bc947d204 add rebase html

f42a865365aa53a6071887237057f593b75d236a Merge branch 'master' of https://github.com/ysyun/pro_git

fbf93820f62f1bc1035f2ba38e941fcae6212fb9 change README.md

c917ae5f7787844b63826a460d82a998bad08a7f Update README.md


// admin 브랜치로 갈라진 이후 master에 추가된 commit 내역을 admin 브랜치로 복사하기 

$ git rebase master

First, rewinding head to replay your work on top of it...

Applying: add rebase html

Applying: update rebase html


// commit 내역 확인 

// 녹색 부분 : master의 commit 내역이 admin 브랜치로 복사되었다. 단, admin commit 내역 밑으로 복사됨 

$ git log --pretty=oneline

3166e4c833705ffc74295b8cc1465a9131b53ef9 update rebase html

d40464af367bdfddb6303feda754937e228e8d57 add rebase html

841c14fb69239bda408aee262e2aea09fb0b83ca add dowon javascript file

cc772174619fa2989c0b3728144f0b885c7faca8 add dowon javascript file

f42a865365aa53a6071887237057f593b75d236a Merge branch 'master' of https://github.com/ysyun/pro_git

fbf93820f62f1bc1035f2ba38e941fcae6212fb9 change README.md

c917ae5f7787844b63826a460d82a998bad08a7f Update README.md


////////////////////////////////////////////////////

// master 브랜치로 다시 이동하여 admin 브랜치와 merge

$ git checkout master

Switched to branch 'master'

Your branch is ahead of 'origin/master' by 2 commits.


// fast-forward merge를 수행했다. 

$ git merge admin

Updating 841c14f..3166e4c

Fast-forward

 rebase.html | 1 +

 1 file changed, 1 insertion(+)

 create mode 100644 rebase.html


$ git branch

  admin

* master


$ git log --pretty=oneline

3166e4c833705ffc74295b8cc1465a9131b53ef9 update rebase html

d40464af367bdfddb6303feda754937e228e8d57 add rebase html

841c14fb69239bda408aee262e2aea09fb0b83ca add dowon javascript file

cc772174619fa2989c0b3728144f0b885c7faca8 add dowon javascript file

f42a865365aa53a6071887237057f593b75d236a Merge branch 'master' of https://github.com/ysyun/pro_git

fbf93820f62f1bc1035f2ba38e941fcae6212fb9 change README.md

c917ae5f7787844b63826a460d82a998bad08a7f Update README.md


  - Local 저장소에서의 rebase 명령 :master 브랜치로 분기된 이후 신규 branch에서 master 브랜치의 commit 내역을 복사 하고 싶을 경우 사용한다  

posted by 윤영식
2013. 1. 13. 21:14 Git, GitHub

원격저장소로 GitHub을 이용하고 있고, Branch를 만들고 삭제하는 방법에 대해서 알아보자. 


1) 브랜치 생성, 삭제 순서 

  - local 저장소에 branch를 만든다 

  - remote 저장소로 branch를 push 하여 추적(tracking) 한다 

  - 사용하지 않는 branch는 삭제한다 

////////////////////////////////////////////////

// 새로운 브랜치를 생성하고 checkout 한다 

$ git checkout -b shopping_cart

Switched to a new branch 'shopping_cart'


////////////////////////////////////////////////

// 원격 저장소로 브랜치를 push 한다 

$ git push origin shopping_cart

Username for 'https://github.com':

Password for 'https://ysyun@yuwin.co.kr@github.com':

Total 0 (delta 0), reused 0 (delta 0)

To https://github.com/ysyun/pro_git.git

 * [new branch]      shopping_cart -> shopping_cart


// github에 새로운 브랜치가 추가 되었다. 


///////////////////////////////////////////////

// 새로운 파일을 추가하고 원격으로 push 한다 

$ touch cart.js

$ git add cart.js

$ git commit -m "add cart javascript file"

[shopping_cart 4856f8d] add cart javascript file

 0 files changed

 create mode 100644 cart.js


$ git push

Username for 'https://github.com':

Password for 'https://ysyun@yuwin.co.kr@github.com':

Counting objects: 3, done.

Delta compression using up to 2 threads.

Compressing objects: 100% (2/2), done.

Writing objects: 100% (2/2), 245 bytes, done.

Total 2 (delta 1), reused 0 (delta 0)

To https://github.com/ysyun/pro_git.git

   f42a865..4856f8d  shopping_cart -> shopping_cart


///////////////////////////////////////////////

// 로컬 브랜치 내역 과 원격 브랜치 내역을 본다 

$ git branch

  master

* shopping_cart


$ git branch -r

  origin/HEAD -> origin/master

  origin/master

  origin/shopping_cart


////////////////////////////////////////////////////

// 로컬의 새로 추가한 shopping_cart 브랜치를 삭제한다

$ git checkout master

Switched to branch 'master'


$ git branch -d shopping_cart

error: The branch 'shopping_cart' is not fully merged.

If you are sure you want to delete it, run 'git branch -D shopping_cart'.


$ git branch -D shopping_cart

Deleted branch shopping_cart (was 4856f8d).


$ git branch

* master


///////////////////////////////////////////////

// 로컬에 이제 shopping_cart 브랜치가 없다 다시 복구 하고 싶다면

// 원격 저장소를 통하여 checkout 하면 된다 

$ git checkout shopping_cart

Branch shopping_cart set up to track remote branch shopping_cart from origin.

Switched to a new branch 'shopping_cart'


$ git branch

  master

* shopping_cart


///////////////////////////////////////////////

// 원격의 브랜치 내역을 보자

// 어떤 브랜치들이 존재하는지 한눈에 알 수 있다 

$ git remote show origin

* remote origin

  Fetch URL: https://github.com/ysyun/pro_git.git

  Push  URL: https://github.com/ysyun/pro_git.git

  HEAD branch: master

  Remote branches:

    master        tracked

    shopping_cart tracked

  Local branches configured for 'git pull':

    master        merges with remote master

    shopping_cart merges with remote shopping_cart

  Local refs configured for 'git push':

    master        pushes to master        (up to date)

    shopping_cart pushes to shopping_cart (up to date)


///////////////////////////////////////////////

// 원격에 있는 브랜치를 삭제 하자 

$ git push origin :shopping_cart

Username for 'https://github.com':

Password for 'https://ysyun@yuwin.co.kr@github.com':

To https://github.com/ysyun/pro_git.git

 - [deleted]         shopping_cart


// shopping_cart 브랜치가 삭제되었음을 알 수 있다

$ git remote show origin

* remote origin

  Fetch URL: https://github.com/ysyun/pro_git.git

  Push  URL: https://github.com/ysyun/pro_git.git

  HEAD branch: master

  Remote branch:

    master tracked

  Local branch configured for 'git pull':

    master merges with remote master

  Local ref configured for 'git push':

    master pushes to master (up to date)


///////////////////////////////////////////////

// remote 브랜치 clean up 하기 

$ git remote prune origin


UserXP@NUKNALEA /d/Git_repositories/pro_git (master)

$ git remote show origin

* remote origin

  Fetch URL: https://github.com/ysyun/pro_git.git

  Push  URL: https://github.com/ysyun/pro_git.git

  HEAD branch: master

  Remote branch:

    master tracked

  Local branch configured for 'git pull':

    master merges with remote master

  Local ref configured for 'git push':

    master pushes to master (up to date)


2) master가 아닌 local 브랜치를 remote 저장소의 master 브랜치에 push 하기 

  - 조건 : local 저장소의 브랜치가 master가 아닌 다른 브랜치로 checkout 되어 있을 경우 예) shopping_cart

  - 명령 :  git push [원격저장소 주소 alias] [로컬저장소명칭]:master

  - 예 : git push origin shopping_cart:master

  - 의미 : origin 원격 주소의 master 브랜치에 local저장소의 shopping_cart 브랜치를 push 한다


posted by 윤영식
2013. 1. 13. 20:40 Git, GitHub

Git clone후에 두명 이상이 작업을 한다. 그리고 같은 파일을 수정하여 Remote 저장소에 Push 할 경우 merge conflict가 발생한다. 이를 해결하기 위한 과정을 알아보자 


1) merge conflict 조건

  - 한명이 같은 파일을(예, README.md) 수정하고 GitHub(remote repository)에 push하였다. 

  - 다른 사람이 README.md 파일 내역을 수정하고 GitHub에 push 하려고 한다. 

  - 이때 git은 fail 메시지를 뱃으면서 push 되지 않는다. 

   

  - github에 한명이 push하여 분홍색으로 있고, gregg는 local 저장소에 commit된 내역을 push 하려고 할 경우


2) merge conflict 해결하기 

  - push : GitHub에 push하려 했더니 conflict가 발생함 

  - pull : GitHub 변경내용을 local 저장소와 merge 하기 

  - edit : 충돌나는 부분이 있다면 직접 편집하기 

  - commit -a : 다시 모든 파일을 commit 하기 

  - push : 변경된 내역을 다시 GitHub에 push하기 

/////////////////////////////////////////////////////////////////////

// 이미 github에는 README.md 파일이 수정되어 있음 (위 그림의 분홍색)

// "It was changed in Github directly by yun dowon" 메시지 commit

///////////////////////////////////////////////////////////////////////////////////////

// README.md  파일에 

// "checkout merge conflict with same file when another change it differently." 내용을 추가함

// (위 그림의 초록색 gregg로 보면 됨)

$ cat README.md

pro_git

=======


test pro git books

checkout merge conflict with same file when another change it differently.


// 추가된 내용을 commit 함 

$ git commit -am "change README.md"

[master fbf9382] change README.md

 1 file changed, 2 insertions(+), 1 deletion(-)


/////////////////////////////////////

// GitHub에 반영할려고 함 

$ git push

Username for 'https://github.com':

Password for 'https://ysyun@yuwin.co.kr@github.com':

To https://github.com/ysyun/pro_git.git

 ! [rejected]        master -> master (non-fast-forward)

error: failed to push some refs to 'https://github.com/ysyun/pro_git.git'

hint: Updates were rejected because the tip of your current branch is behind

hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')

hint: before pushing again.

hint: See the 'Note about fast-forwards' in 'git push --help' for details.


////////////////////////////////////////////////

// pull 을 수행 

$ git pull

remote: Counting objects: 5, done.

remote: Compressing objects: 100% (3/3), done.

remote: Total 3 (delta 1), reused 0 (delta 0)

Unpacking objects: 100% (3/3), done.

From https://github.com/ysyun/pro_git

   9ae6fb2..c917ae5  master     -> origin/master

Auto-merging README.md

CONFLICT (content): Merge conflict in README.md

Automatic merge failed; fix conflicts and then commit the result.


// 현재 상태를 확인

$ git status

# On branch master

# Your branch and 'origin/master' have diverged,

# and have 1 and 1 different commit each, respectively.

#

# Unmerged paths:

#   (use "git add/rm <file>..." as appropriate to mark resolution)

#

#       both modified:      README.md

#

no changes added to commit (use "git add" and/or "git commit -a")


////////////////////////////////////////////////////////////////

// README.md 파일이 GitHub내용과 Local 저장소 내용이 합쳐졌다

$ cat README.md

pro_git

=======


test pro git books

<<<<<<< HEAD

checkout merge conflict with same file when another change it differently.  <-- Local 저장소 내역

=======

It was changed in GitHub directly by yun dowon  <-- Remote 저장소 내역

>>>>>>> c917ae5f7787844b63826a460d82a998bad08a7f 


///////////////////////////////////////////

// 변집기를 통하여 직접 내용을 적절히 수정함

$ vi README.md

$ git status

# On branch master

# Your branch and 'origin/master' have diverged,

# and have 1 and 1 different commit each, respectively.

#

# Unmerged paths:

#   (use "git add/rm <file>..." as appropriate to mark resolution)

#

#       both modified:      README.md

#

no changes added to commit (use "git add" and/or "git commit -a")


///////////////////////

// 다시 commit을 한다 

$ git commit -a

[master f42a865] Merge branch 'master' of https://github.com/ysyun/pro_git


UserXP@NUKNALEA /d/Git_repositories/pro_git (master)

$ git status

# On branch master

# Your branch is ahead of 'origin/master' by 2 commits.

#

nothing to commit (working directory clean)


/////////////////////////////////////////////////

// conflict가 해결되었으면 다시 push 하여 통합한다

$ git push

Username for 'https://github.com':

Password for 'https://ysyun@yuwin.co.kr@github.com':

Counting objects: 10, done.

Delta compression using up to 2 threads.

Compressing objects: 100% (6/6), done.

Writing objects: 100% (6/6), 734 bytes, done.

Total 6 (delta 3), reused 0 (delta 0)

To https://github.com/ysyun/pro_git.git

   c917ae5..f42a865  master -> master


////////////////////////

GitHub에 push된 내용 


3) merge conflict 시에 pull 의미 

  - git fetch : remote 브랜치 하나가 local 저장소로 내려온 것이고, local 저장소에 commit 된 상태는 아님 

  - git merge origin/master : local 저장소의 master와 origin/master 브랜치를 merge 함 

  - pull = git fetch + git merge origin/master 두개가 동시에 수행된 것임 

posted by 윤영식
2013. 1. 13. 20:00 Git, GitHub

git에서 merge를 할 경우 내용으로 fast-forward merge라는 용어가 나온다. 이에 대해서 알아보자.


1) fast-forwad merge 의 조건

  - master에서 새로운 branch를 만든다 

  - 새로운 branch에서 추가한 파일을 commit한다. 이때 master에서는 아무런 commit 내용도 없다.

   

//////////////////////////////////////////////////////

// cat branch를 만들고 cat으로 checkout 한다 (-b 옵션)

$ git branch -b cat


$ git branch

* cat

 master


///////////////////////////////////////////////////////////////

// 파일을 하나 만들고 commit 한다. 새로운 commit 이 생긴 것이다. 

$ echo "dowon" > cat.txt

$ git add cat.txt

$ git commit -m "add cat.txt"

[cat 1e6ea90] add cat.txt

The file will have its original line endings in your working directory.

 1 file changed, 1 insertion(+)

 create mode 100644 cat.txt


// cat branch안에 cat.txt 파일이 보인다

$ ls

README.md  build.gradle  cat.txt  todo.txt


// master branch로 이동을 한다 

$ git checkout master

Switched to branch 'master'

Your branch and 'origin/master' have diverged,

and have 1 and 3 different commits each, respectively.


////////////////////////////////////////////

// master에는 cat.txt 파일이 존재하지 않는다. 

$ ls

README.md  build.gradle  todo.txt


////////////////////

// merge를 수행한다

$ git merge cat

Updating 8ee3f5e..1e6ea90

Fast-forward

 cat.txt | 1 +

 1 file changed, 1 insertion(+)

 create mode 100644 cat.txt


////////////////////////////////////////////////
// 사용하지 않는 cat branch는 삭제한다. (-d 옵션)
$ git branch -d cat 


posted by 윤영식
2013. 1. 13. 19:32 Git, GitHub

로컬에서 Git을 사용하다가 실수로 Commit을 할 경우 다시 이전 상태로 원복하고 싶을 때 가장 많이 사용하는 명령를 알아보자.


1) 방금 commit한 내용을 staging area로 돌려 놓고 싶을 경우 

  - 명령 : git reset --soft HEAD^

  - HEAD : 현재 commit의 포인터,  ^ : 이전 것,  --soft : staging으로 옮기기

$ git reset --soft HEAD^


// commit 했던 LICENSE 파일이 staged area에 존해함

$ git status

# On branch master

# Changes to be committed:

#   (use "git reset HEAD <file>..." to unstage)

#

#       new file:   LICENSE

#


2) 방금 commit 한 것에 다른 파일로 추가 하여 넣고 싶을 경우 (commit은 증가하지 않음)

  - 명령 : git commit --amend -m "add new file"

  - --amend : 최근 기존 commit에 추가하기 

// 새로운 파일을 만든다 

$ touch todo.txt

$ touch add todo.txt 


// 기존 commit에 todo.txt 파일 추가하기 

$ git commit --amend -m "new thing file"

[master 18b3bb7] new thing file

  1 file changed, 3 insertions(+)

 create mode 100644 todo.txt

 create mode 100644 LICENSE


3) 현재 commit한 것을 없애버리고 싶을 경우 (방금 commit한 내용이 staging 가지 않고 없어진다)

  - 명령 : git reset --hard HEAD^

//현재 commit 내역을 본다 

$ git log

commit 18b3bb76c5d16c76221d45b1bc61b483001191d4

Author: Yun DoWon <ysyun@yuwin.co.kr>

Date:   Sun Jan 13 18:43:03 2013 +0900


    new thing file


commit 329db048ff7af2d417588e28da50a6c53fb1bd84

Author: Yun DoWon <ysyun@yuwin.co.kr>

Date:   Thu Dec 27 11:07:26 2012 +0900


    add content in build.gradle


// 최신 commit 18b3bb76c5d16c76221d45b1bc61b483001191d4 을 삭제했다

$ git reset --hard HEAD^

HEAD is now at 329db04 add content in build.gradle


UserXP@NUKNALEA /d/Git_repositories/pro_git (master)

$ git log

commit 329db048ff7af2d417588e28da50a6c53fb1bd84

Author: Yun DoWon <ysyun@yuwin.co.kr>

Date:   Thu Dec 27 11:07:26 2012 +0900


    add content in build.gradle


4) 그럼 현재 commit 에서 두단계 이전 commit으로 이동하면서 앞 두단계를 삭제하고 싶다면 

  - 명령 : git reset --hard HEAD^^

  - ^ 이전, ^^ 이전에 이전 (두단계 이전)

posted by 윤영식
prev 1 2 3 next