• 2011-01-04

    Git Tips

    git ignore

    http://github.com/guides/ignore-for-git

    pull 할 때 다음 에러가 뜰 경우

    You asked me to pull without telling me which branch you
    want to merge with, and branch.master.merge in
    your configuration file does not tell me either. Please
    specify which branch you want to merge on the command line and
    try again (e.g. git pull ‘).
    See git-pull(1) for details.
    
    If you often merge with the same branch, you may want to
    configure the following variables in your configuration
    file:
    
    branch.master.remote =
    branch.master.merge =
    remote..url =
    remote..fetch =
    
    See git-config(1) for details.

    git config -l 로 살펴보면 이미 remote 들은 등록이 되어 있다. 여기서 할 일은 branch master 를 설정하는 거다.

    git config branch.master.remote origin
    git config branch.master.merge refs/heads/master

    이걸 해주면 된다. via http://stackoverflow.com/questions/2335343/how-to-tell-git-to-always-pull-the-master-branch

    작업한 모든 파일을 버리고 이전 버전으로 되돌리고 싶을 때

    git reset --hard HEAD

    변경된 모든 파일을 HEAD 버전으로 복구한다.

    git reset --hard origin/master

    변경 사항을 모두 버리고 리모트 브랜치의 내용으로 복구한다.

    git clean -f

    새로 만들어졌지만 아직 stage 상태가 아닌 파일들을 삭제한다.

    이미 커밋한 내용을 수정하고 싶은 경우

    git commit --amend

    이전 커밋 로그를 변경하거나, 이번에 바꾼 파일을 이전 커밋으로 합쳐버릴 때 사용한다.

    git revert HEAD

    가장 마지막 커밋(HEAD)을 취소하고 되돌린다. HEAD^2, HEAD~3

    git revert HEAD^

    마지막 커밋의 바로 이전 커밋(즉 HEAD+1)으로 되돌린다.

    git revert -m 1 {commit}

    파일이나 폴더를 버전관리하고 싶지 않을 때

    .gitignore 에 파일 이름을 등록한다.

    #exclude folder
    TEMP/*
    #include file in exclude folder
    !TEMP/include_me

    이미 추가된 파일이나 폴더를 빼고 싶은 경우

    git rm --cached {FILE}
    git rm --cached -r {DIR}

    특정 폴더를 실제로 지우진 않고, 버전관리에서만 삭제한다. 이때 .gitignore 에 추가해둬야만 다른 사람이 하위 파일을 수정한 경우에 또다시 추가되는 걸 막을 수 있다.

    git ignore 는 아직 커밋되지 않은 파일을 무시할 때 사용한다.

    git update-index assume-unchanged FILENAME 은 커밋된 파일을 더이상 추적하지 않을때 사용한다.

    .gitignore 는 현재 폴더 기준으로 특정 패턴을 무시한다.

    .git/info/exclude 는 글로벌 패턴을 등록한다. 다만 양쪽 모두 웬지 레파지토리에 등록되어 공유되지는 않는 느낌이란 말이지

    파일이 너무 많아서 무엇을 커밋할 지 알기 힘들 때

    git add -i

    인터랙티브 모드를 이용해서 변경된 파일을 stage 상태로 만든다.

    최근 N 개의 커밋을 하나로 만들려면

    git rebase -i HEAD~N

    으로 하면 커밋 편집기가 뜬다. 이때 삭제하고픈 커밋 앞에 pick 대신 squash (또는 s)를 써 넣으면, 최종적으로 커밋 로그 입력모드로 들어간다. 단,

    • rebase 를 취소하고 싶으면 q! 대신 모든 라인을 지워야 된다.
    • 이미 외부 서버로 push 되었을 경우엔 rebase 하면 인생이 꼬인다.

    브랜치끼리 병합하되, 커밋은 하고 싶지 않은 경우

    git merge master..new_branch --no-commit --no-ff

  • 2010-12-14

    jQuery UI Widget _setOption

    jQuery UI widget 은 기본적으로 한번에 여러 개의 옵션을 설정할 수 있다.

    $('...').somewidget('option',{aa:bb, cc:dd});

    하나의 옵션을 설정할 때의 추가적인 로직을 넣으려면 _setOption() 을 재정의하면 된다.

    _setOption: function(key,value){
      if(key=='some'){...do something...}
    }

    가끔은 여러 개의 옵션을 한번에 설정할 때, 그 중 몇몇 옵션이 바뀔 경우에 대한 추가적인 로직을 넣으려면 _setOptions 를 재정의하면 된다. jQuery UI Dialog 의 코드가 가장 좋은 예제일 것이다. 다만 1.8.6 부터 지원하니까 버전에 주의하길.

    _setOptions: function( options ) {
      var self = this,
      resizableOptions = {},
      resize = false;
    
      $.each( options, function( key, value ) {
      self._setOption( key, value );
    
      if ( key in sizeRelatedOptions ) {
      resize = true;
      }
      if ( key in resizableRelatedOptions ) {
      resizableOptions[ key ] = value;
      }
      });
    
      if ( resize ) {
      this._size();
      }
      if ( this.uiDialog.is( ":data(resizable)" ) ) {
      this.uiDialog.resizable( "option", resizableOptions );
      }
    },
  • 2010-11-16

    jquery.ui.tooltip

    개요

    • jquery ui 1.9 에서부터 지원된다. 1.8 에서 사용하려면 약간의 소스 수정이 필요하다.
    • 기본적으로 title 속성을 툴팁 텍스트로 사용한다. 동적으로 컨텐트를 만들려면 content 함수를 이용해서 DOM 을 리턴해야 한다.
    • 툴팁은 dialog 와 마찬가지로 body 에 추가된다. 자동으로 ui-tooltip-1 ui-tooltip-2 와 같이 id 가 붙는다.
    • this.element 는 툴팁을 띄우는 원본 DOM 이고, 툴팁 컨텐트에 직접 접근하려면 this.tooltip 또는 this.widget() 을 이용해야 한다.
    • beforeOpen 같은 걸 지원하면 좋을텐데.. 일단은 없다. 뜨지 않게 하려면 disable 시키는 수 밖에 없다.
    • 툴팁 내부 컨텐트에 jquery ui 위젯을 사용하려면 open 콜백에서 적용할 것.

    툴팁 내부에 템플릿을 적용한 후 Progressbar 넣기

    xxx.tooltip({
      content: function(){
        return $('#building-unit-tooltip-tmpl')
          .tmpl(unit);
      },
      open: function(event){
        var timeRatio = (unit.maxTime-unit.remainTime) / unit.maxTime * 100;
        var $tooltip = $(this).data('tooltip').widget();
        $tooltip
          .find('div.progressbar')
            .progressbar({value:timeRatio})
          .end()
          .find('.ui-progressbar-value')
            .animate({
              width: "100%"
            }, {
              duration: unit.remainTime*1000
            });
      }});
  • 2010-11-15

    DIV layering with z-index

    구글맵처럼 (바닥 - 마커 - 오버레이) 등 여러 개의 레이어로 구성하고, 그 안에 위치한 각종 마커들끼리의 z-index 를 상황(?)에 따라서 코드 레벨에서 정렬해야 한다고 가정하자.

    <div id="map">
      <div id="ground">
      <div id="first" class="marker">1st</div>
      <div id="second" class="marker">2nd</div>
      </div>
      <div id="overlay">
      <div id="third" class="overlay">3rd</div>
      <div id="fourth" class="overlay">4th</div>
      </div>
    </div>

    보통 맵은 relative, 레이어들은 absolute 로 두게 된다. 이때 레이어들의 z-index 를 지정하지 않으면(또는 auto 로 설정하면), #first 마커의 z-index 를 9999 로 잡으면 상위 레이어 위로 올라오게 된다.

    #map {
      position: relative;
      width: 100%;
      height: 500px;
      background-color: gray;
    }
    .marker, .overlay {
      position: absolute;
      text-align: center;
    }
    #ground {
      position: absolute;
      left: 0;
      top: 0;
      background-color: #ededed;
      z-index: 1000;
    }
    #overlay {
      position: absolute;
      left: 0;
      top: 0;
      z-index: 1001;
    }
    #first {
      width: 100px;height: 100px;
      background-color: yellow;
    }
    #second {
      width: 50px;height: 200px;
      background-color: green;
    }
    #third {
      width: 200px;height: 50px;
      background-color: red;
    }
    #fourth {
      width: 50px;height: 300px;
      background-color: blue;
     }

    대신 그냥 각 레이어들의 z-index 를 각각 1000,1001 로 설정하기만 하면, 아무리 하위 레이어의 마커에 높은 z-index 를 줘도, 절대 상위 레이어를 침범하지는 않게 된다.

    관련 테스트 코드는 jsfiddle에서 볼 수 있다.

  • 2010-11-11

    Modify Rendered jQuery Template Before Append

    jQuery 템플릿이 하나의 DIV 가 아니라 여러 개의 엘리먼트로 구성될 경우, append 하기 전에 내부에 있는 위젯들을 손댈 방법을 찾지 못했다. 아래 코드의 샘플은 jsFiddle에 있으니 관심있는 분들은 뜯어보시길..

    <script id="test" type="script/x-jquery-tmpl">
      <div>
      <h1>${name}</h1>
      <p>${description}</p>
      <div class="progressbar"></div>
      </div>
    </script>
    <script id="test2" type="script/x-jquery-tmpl">
      <h1>${name}</h1>
      <p>${description}</p>
      <div class="progressbar"></div>
    </script>
    <div id="here"></div>
    
    $(function() {
      var data = {name: 'Hello', description: 'World', value:50};
      var data2 = {name: 'JavaScript' ,description: 'Rules', value: 80};
      var $tmpl = $('#test').tmpl(data);
    
      $tmpl.find('.progressbar').progressbar({value:data.value});
      $tmpl.appendTo('#here');
    
      var tmpl2 = $('#test2').tmpl(data2);
      tmpl2.find('.progressbar').progressbar({value:data2.value}); // not working
      tmpl2.appendTo('#here');
    
    });

    위 예제처럼, #test 는 하나의 DIV 로 묶여져 있어서 appendTo 하기 전에 위젯을 만들 수 있지만, #test2 처럼 여러 개의 엘리먼트들이 나눠져 있는 경우에는 .tmpl(data) 로 렌더링을 하면 [h1, p, div.progressbar] 의 배열이 튀어나오는데, 이 배열에다가 대고 find 를 해도 아무 일도 발생하지 않는다. (for 를 돌아도 마찬가지)

    일단은 그냥 마음편하게 하나로 묶는게 유일한 해답일 거 같은데, 그나저나 .tmplItem 은 도대체 어디에 쓰는 물건일까?