git – Dreaming for the Future 영원한 개발자를 향해서. 월, 13 1월 2025 13:44:09 +0000 ko-KR hourly 1 https://wordpress.org/?v=4.7 108384747 Git 기반 효율적인 이벤트 페이지 배포 환경 만들기 /index.php/2018/01/22/effective-continous-delivery-with-git-and-jenkins-for-publishing/ Sun, 21 Jan 2018 21:43:43 +0000 /?p=508

Continue reading ‘Git 기반 효율적인 이벤트 페이지 배포 환경 만들기’ »]]> 고객과 소통을 많이 할려다보면 이것 저것 알릴 내용들이 많다. 이건 게임 회사이기 때문이 아니라 소통에 대한 의지를 가진 회사라면 당연히 그래야한다.

SVN을 사용했었는데 무엇보다도 변경 사항에 대해 파악하는 것이 너무 힘들었다. 또한 매번 배포 때마다 브랜치를 머지하고 관리하는데 쉽지가 않다. 대부분의 프로젝트들은 모두 git을 사용하고, 전환했지만, 프로모션 영역은 7G라는 덩치의 Hell of Hell이었기 때문에 차일피일 미뤄지고 있었다.

기술 부채를 언제까지 끌고갈 수는 없다. 해야할 것을 미루기만 해서는 두고두고 골치거리가 된다.

이벤트/프로모션 페이지들은 배포되면, 이후의 코드 변경은 거의 발생하지 않는다. 하지만 다른 사이트등을 통한 참조가 발생할 수 있기 때문에 유지는 필요하다. 해당 페이지들을 통해 컨텐츠 혹은 정보들이기 때문에 그냥 404 오류가 발생하도록 놔둘 수는 없다. 따라서 기간이 지나면 관리해야하는 용량이 커질 수밖에 없다.  이렇게 커진 용량을 빌드/배포하는 건 전체 프로세스의 효율성을 확 떨어트린다. 특정 프로모션 영역(디렉토리)별로 배포하는 체계를 이미 갖췄기 망정이지, 그게 아니라면 7G 짜리를 매번 배포하는 최악의 배포 환경이 될 수 밖에는 없었을 것이다.

특정 영역별로 배포하는 방식에서 힌트를 얻었서 전체 코드들을 각 이벤트/프로모션 영역별로 쪼개서 각자 관리하기로 했다. 개별적인 성격의 프로모션 사이트로 볼 수 있기 때문에 각각의 디렉토리는 의존성이 없다. 때문에 개별 Repository로 나눠놓는 것이 완전 독립성 부여라는 관점에서 맞기 때문에 SVN repository를 git organization으로 만들고, 개별 디렉토리를 git repository로 만들었다. 이 방식의 문제점은 SVN 작업 이력을 git 환경으로 가져가지 못한다는 점이다.  하지만 “새 술은 새 부대에“라는 명언이 있지 않은가!!

맘을 정하고, Organization을 생성한 다음에 Repository를 Github을 통해 생성했다. 수련하는 마음으로 열심히 노가다를 하다보니 이내 모든 Repository를 만들긴 했는데… 이렇게 노가다한 결과 Repository를 세어보니 100개가 훌쩍 넘는다. 헐… 올리긴 해야하니까 스크립트의 도움을 받아 push했다.

쪼개놓는 건 일단 이쁘게 정리를 했는데 이제 배포 체계다. 일반적으로 개발 단게에서 master로 머지되는 코드는 자동으로 배포한다. 그래야 과정의 결과물을 관련된 사람들이 즉시즉시 확인할 수 있다. Git을 사용하는 경우, 이를 위해 webhook을 이용한다. Polling을 이용하는 경우도 있긴 하지만 이건 SVN을 쓰때나 써먹는 방법이다. 현대적이지도 않고 아름답지도 않다.  그런데 100개 이상이나 되는 코드에 일일히 webhook을 걸려고 생각해보니 이건 장난이 아니다. 노가다도 개발자의 숙명이라고 이야기하는 사람이 있을지 모르겠다. 하지만 프로모션이 늘어날때마다 webhook을 한땀한땀 설정하는 것도 웃기다. 누가 이 과정을 까먹기라도 한다면 사수에게 괴롭힘을 당할 수도 있기 마련이기도 하고. (안타깝지만 정말 이런게 어느 분야를 막론하고 흔하게 있다. 적폐에 타성으로 물든다고나 할까?)

자동화다. 개발자의 숙명은 적폐를 청산하고 사람의 개입없이도 돌아가는 시스템을 만들어내는 것이다. 다행이도 git의 경우에는 개별 repository에서 발생한 push 이벤트를 repository가 소속된 organization에 전달하는 기능이 있고, wehbook을 oragnization에 설정하는 것을 허용한다. 이 기능을 활용하면 신규 프로모션 작업을 위해 새로운 repository를 만들더라도 별도로 webhook을 설정할 필요가 없다.

(Jenkins는 application/json content-type만을 받아들인다. 괜히 urlencoded 형식으로 해서 안된다고 좌절하지 말자)

이제 배포를 위해 Jenkins에 해당 webhook을 이용해 정보를 전달하면 된다. 근데 어케 webhook payload를 jenkins가 이해하지? 그렇다. 여기서 다시 큰 문제점에 봉착한다. Jenkins에서 활용할 수 있는 git plugin은 이름이 지정된 특정 repository의 webhook을 인식할 수 있지만, 이 경우를 상대할려면 jenkins쪽에 각 repository들에 대응하는 jenkins job을 만들어줘야 한다. 이게 뭔 황당한 시츄에이션인가? 간신히 한 고비를 넘겼다고 생각했는데 앞에 비슷한 역대급 장애물이 기다리고 있다.

하지만 갈구하면 고속도로는 아니지만 길이 나타난다.  Jenkins에서 아래와 같은 두가지 아름다운 기능을 제공한다.

  • Parameterized build – 비드를 할 때 값을 파라미터로 정의할 수 있도록 하고, 이 파라미터 값을 빌드 과정에서 참조할 수 있도록 해준다.
  • Remote build trigger – Job에서 지정한 Token값이 HTTP authorization header를 통해 Jenkins에 전달되면 해당 Job이 실행된다. 와중에 Parameter 값을 별도로 설정도 할 수 있다.

이 두가지 기능을 활용하면, Job 하나만 만들어도 앞서 정의한 100개 이상의 repository의 빌드/배포를 실행할 수 있게 된다. 환경 설정을 위해 아래와 같이 Jenkins Job에 Repository 맵핑을 위해 String parameter를 정의하고, git repository 설정에서 이를 참조하도록 한다.

Jenkins Job을 선택하기 위한 Token은 아래 방식으로 설정한다. Jenkins는 해당 토큰값으로 어느 Job을 실행한지 선택하기 때문에 중복된 값을 사용해서 낭패보지 말길 바란다.

설정이 마무리됐다면 아래와 같이 테스트를 해보자.

 

curl -X POST "http://trigger:jenkins-trigger-user-credential@jenkins.sample.io/job/deploy-promo-dev/buildWithParameters?token=TOKEN&delay=0&PROMOTION=promotion”

Jenkins Host 이름 앞에 들어가는 건 Jenkins 접근을 위한 사용자 정보이다. 일반 사용자의 아이디 및 Credential을 바로 사용하지 말고, API 용도의 별도 계정을 생성해서 사용할 것을 권한다.

하지만 Build trigger를 누가 호출해주지? 누구긴, 당신이 짠 코드가 해야지! 이제 본격적인 코딩의 시간이다.

Git org에 설정한 webhook의 로부터 개발 작업이 이뤄진 repository와 branch를 확인하고, 이를 build trigger의 query parameter로 전송하면 된다. 일반적인 웹 어플리케이션처럼 상시적인 트래픽을 받는 시스템이 아니기 때문에 운영을 위해 별도의 어플리케이션 서버를 구축하는 건 비용 낭비다. 이를 경우에 딱 맞는 플랫폼이 AWS Lambda이다.  복잡한 코딩이 필요한 것도 아니기 때문에 Node.js를 활용해서 간단히 어플리케이션을 만들고, S3를 통해 이 어플리케이션이 Lambda에 적용될 수 있도록 했다. 실제 호출이 이뤄지도록 API Gateway를 앞단에 배치하면 끝!

Node.js를 이용한 Lambda 코드는 아래와 같이 작성해주면 된다.

var http = require('http');
var btoa = require('btoa');
exports.handler = (event, context, callback) => {
  var repository = event.repository.name;
  var options = {
    host: 'jenkins.sample.io',
    port: 80,
    headers: {
     'Accept': 'application/json', 
     'Authorization': 'Basic ' + btoa('trigger:jenkins-trigger-user-credential') 
    },
    path: '/job/deploy-promo-dev/buildWithParameters?token=TOKEN&delay=0&PROMOTION=' + repository,
    method: 'POST'
  };

  var refElements = event.ref.split('/');
  var branch = refElements[2];
  if (branch === 'master') {
    http.request(options, function(res) {
      console.log('STATUS: ' + res.statusCode);
      res.on('data', function(chunk) {
        console.log(chunk);
      })
    }).on('error', function(e) {
      console.loge('error',e);
    }).end();
    callback(null, 'Build requested');
  } else {
    callback(null, 'Build ignored for ' + branch + ' pushing');
  }
};

 

이제 개발하시는 분들이 개발을 막~~~ 해주시면 그 내용이 프로모션 웹 영역에 떡하니 표시되고, 프로모션 담당자들이 확인해주면 된다. 그리고 최종적으로 완료되면 라이브 환경에 배포를 해주면 된다.

근데 배포를 누가 해주지?? 라이브 배포는 자동으로 할 수 없으니까 개발 환경과 유사한 라이브용 Jenkins Job으로 개발자가 돌려야 하는거 아니가? 맞다. 걍 개발자가 하면 된다. 흠… 개발자가… 하지만 이 단계에서 개발자가 하는건 배포 버튼을 눌러주는게 다 아닌가? 개발과 라이브의 환경 차이가 물론 있긴하지만 프로모션이라는 특성상 그닥 크지 않다. 이미 개발 환경에서 프로모션을 담당자들이 깔끔하게 확인한 걸 개발자가 한번 더 확인할 필요도 없고 말이다.

게으른 개발자가 더 열열하게 게으르고 싶다. 어떻게 하지?? 뭘 어떻게 하긴, 열 코딩하는거지.

Git이란 환경은 정말 개발자에게 많은 것들을 아낌없이 나눠준다. 그 가운데 하나가 바로 API. 내가 사용하는 Git의 경우에는 Enterprise(Private) Git이기 때문에 적절하게 Credential만 맞춰주면 API를 호출할 수 있다. 보통은 이걸 위해 API 전용 Secrete을 생성해서 사용하는게 안전하다. (어느 바보가 자기 아이디 암호를 API 호출하는데 사용하지는 않겠지??)

Git API를 이용하면 Git org에 속한 모든 repository들을 모두 가져올 수 있다. 그럼 이 가운데 배포 대상을 하나 선택해서 프로모션 담당자가 Jenkins job을 trigger할 수 있도록 해주면 되는거 아닌가!! 쓰는 사람을 위해 배려 하나를 더해 준다면 가장 최근 작업 repository가 배포 대상이 될 것이라 업데이트 시간을 기준으로 최근 repository가 앞에 오게 하자. 아름다운 이야기다.

복잡하지 않다. jQuery를 이용한 간단한 웹 어플리케이션이면 족하다. 100줄 미만으로 구현된다. 물론 미적 추구를 더한다면 더 길어질 수도 있겠지만 개인적으로 절제된 공백의 아름다움이 최고라고 생각하는 1인이기 때문에. 물론 아무나 들어와서 마구 배포 버튼을 누르지 못하도록 적절한 예방 장치들을 마련되야 한다.

전체를 그림 하나로 그려면 대강 아래와 같다.

 

– 끝 –

참고한 것들

]]> 508
좋은 코드에 대한 생각 – 3: 작업에 대한 기록 /index.php/2017/11/26/good-coding-about-worklog/ Sat, 25 Nov 2017 23:16:49 +0000 /?p=478

Continue reading ‘좋은 코드에 대한 생각 – 3: 작업에 대한 기록’ »]]> 개발이라는 건 기록의 작업이다. 코드 한줄을 작성하더라도 이유없는 코드가 없다. 이런 이유로 코드를 작성할 때 그 근거를 기록으로 남길려고 하고 권장한다.

당신은 어떤 방식으로 기록하고 있나? Jira와 같은 티켓 관리 시스템을 이용할 수도 있겠고, 혹은 Confluence에 일지를 쓸수도 있겠다. 하지만 당신이 개발자라면 이 문제를 개발자스럽게 풀고 있을 것이라고 생각한다.

코멘트?

가장 흔하게 생각할 수 있는 방법이고 실제로 많은 개발자들이 작업에 대한 이력을 코멘트로 남긴다. 그림에서 보이는 녹색 코멘트가 가장 대표적인 경우다. 코드를 작성한 이유가 무엇이며 동작이 이런 방식으로 움직인다고 설명한다.

하지만 이런 코멘트는 비추다. 첫번째 이유는 이 코멘트에 사람들이 집중하지 않는다. 개발자라면 코드를 읽을려고 하지 문제가 있지 않는한 코멘트를 읽지 않는다. (사실 정말 그런지도 의문이다. 문제가 있다면 디버깅을 하거나 해당 코드 영역에 대한 테스트 코드를 살펴보지 않을까?)

정말 심각한 문제는 코드를 작성한 본인(들)도 본인들의 코멘트를 지키지 않는다는 사실이다. 기록을 해두면 된다라고 생각하지만 수정 가능한 코드에 대한 기록은 관리가 필요하다.  즉 코드가 바뀌면 코멘트도 바뀌어야 하는데 거의 대부분 코드만 수정하지 코멘트는 수정하지 않는다. 여러 이유가 있지만 그만큼 코멘트는 최초 작성자를 포함해 제대로 읽히지 않는다는 것을 의미한다.

코멘트는 남기지 않는게 좋다. 당신이 남기는 코멘트는 100% 쓰레기가 된다. 이런 쓰레기를 남기는 활동은 정신 건강에 좋지 않다. 그럼에도 불구하고 굳이 코멘트를 남기겠다면 코드 중간에 남기지 말고 Docs 문서 생성이 가능한 메소드 상단에 붙혀준다.

코드 중간에 남기는 코멘트는 진심 백퍼 쓰레기다. 되려 상단에 남기는 코멘트는 메소드의 의미를 설명해주기 때문에 사람들의 눈에 보여질 가능성도 훨 높을 뿐만 아니라 수정 가능성도 덩달아 높아진다.

의미에 이름을 주자.

특정 코드 블럭이 의미나 목적을 가진 부분이라면 이걸 굳이 코멘트로 남길려고 하지 말자.

질척거리는 코멘트보다 함수 혹은 메소드로 의미에 이름을 부여하는 것이 백배 좋다. 메소드의 이름을 적어주고 따로 Javadoc를 목적으로 한 것인지는 모르겠지만 따로 코멘트를 남기는 경우가 있다. 그렇게 남기는 설명이 메소드의 의미를 부연하기 위한 것이라면 차라리 이름을 충분히 길게 작성하자. 코드를 읽는 사람이 두 번 읽게 하는 것보다는 한번 읽어서 의미를 파악할 수 있게 하는게 좋다.

개발자가 싫어해야할 것은 같은 어떤 의미에서든 중복을 없애는 것이다. 그리고 이 규칙은 메소드 이름과 코멘트의 경우에도 마찬가지다. 그리고 이제 메소드의 코드를 최대한 간결하게 작성해서 술술 읽히게 만든다. 충실한 코멘트보다는 쉽게 읽히는 코드가 다른 개발자 혹은 동료를 위한 배려다.

소스 관리 도구들을 활용하자.

그럼에도 불구하고 다른 기록을 남기고 싶은 욕구가 생기는 경우가 있다. 개인 경험상 특정 버그 혹은 요청 티켓을 처리한 경우가 대표적이다. 지금 변경한 코드가 이 티켓에 해당하는 변경이라는 것으로 남기고 다른 사람도 그 티켓을 참조했으면 하고 바라기 때문이다. 앞서 이야기했지만 그렇다고 이걸 코멘트로 코드안에 남겨봐야 의미없다. 더 좋은 방법이 없을까?

코멘트보다 좀 더 효과적인 방법으로 추천할만한 내용은 커밋 로그(Commit log)를 활용하는 것이다.  커밋은 코드의 “특정 작업 단위가 마무리됐다는 것“을 말한다. 마무리된  작업의 내용을 설명하는 것이 커밋 로그이다. 또한 온라인 코드 리뷰 자체도 이 커밋 단위로 리뷰가 진행된다. 따라서 작업 설명은 충실하면 충실할수록 좋다. 작업 내용의 충분한 이해를 바탕으로, 리뷰어가 코드를 살펴보고 리뷰를 남겨준다면 리뷰를 받는 사람에게 더 도움이 된다.

결론은 충실하면 좋다긴 하지만 Source repository로 뭘 사용할 것인가에 따라 접근 방법이 틀려진다. 국내에서는 아직 SVN을 Repository로 사용하는 회사 혹은 개발팀이 많다. 하지만 알다시피 SVN은 중앙에서 소스를 관리한다. 그게 뭔 문제??? 관리 대상이 작다면 별 문제가 안되지만, 누구나 알듯이 많아지면 주구장창 느려지는 문제점이 있다. 더구나 SVN은 커밋을 하게되면 이를 서버에 전송하여 저장한다. 각 커밋 단위가 가지는 의미가 상당하다.

이런 이유로 SVN을 사용하는 대부분의 팀에서는 한 커밋 단위에서 자잘한 코드 변경을 커버하기 보다는 의미있는 단위로 작업하라고 권고한다. 한 커밋 변경에서 변경되는 작업 분량이 커지게 된다. 이 내용을 상세하기 적을려면 분량이 상당해진다. 바꿔 말하면 변경 내용을 알아보게 로그 형태로 적기 힘들다. 잘 적을까? 당연히 안적게 된다. 남길 수 있다면 티켓 번호 정도? 따라서 변경의 주요 내용을 커밋 로그에서 따라잡기 어렵다. 이 상황이 지속된다면 차라리 변경 주요 내용을 코멘트로 님기는게 더 나은 방법일 수도 있다.

그러니까 git을 사용해야 한다. Distributed source repository가 주는 장점이랄까? 혹은 로컬에서 자신의 Copy를 가지고 움직이기 때문에 갖는 장점일지는 모르겠다. 가볍고 빠른다. 그리고 Remote repository에 push를 통해 업로드하기 때문에 각 Commit 단위가 갖는 무게가 상대적으로 가볍다.

Git을 Source repository 사용한다면 다음의 규칙을 사용해서 로깅을 남겨보자.

» 서로 독립적인 변경이 있다면 각각에 대해 모두 커밋 로그를 남긴다. 예를 들어 불필요한 코멘트를 삭제했다면 그것도 커밋의 단위이고, 오타 한글자를 수정했었도 것도 따로 커밋한다.

» 코드 작성/변경 자체가 좁은 범위에 대해 이뤄진다. 로그에 쓸말도 많지 않아야 한다. 50 ~ 80자 이내로 코멘트를 작성하자. 바꿔 이야기하면 이 정도의 내용으로 커버될 내용이 한번의 커밋 대상이어야 한다.

» 다른 사람들과 공유해야하는 경우에만 Remote branch에 push한다. 모 회사의 광고 아닌 광고에 보면 불이 나도 push는 하고 가라는 말이 있긴 하지만 branch 방식으로 PR을 관리한다면 간간히 push를 하지 말고 자주 push를 하는게 좋다. 그렇게 모인걸 PR 날리면 땡이니 Remote에 얼마나 자주 push를 하던 문제가 안된다. (불날때 먼저 나가는게 중요하지 push는 하고 가라는 우스개 소리 아닌 소리를 하는 회사는 별로다.)

» 최종 PR의 타이틀은 간결해야한다. 내용에는 PR통해 반영될 기능들에 대한 설명과 리뷰를 해줬음 하는 대상자들의 이름을 적어둔다. 그리고 사람들 사이에 대화가 이어지면 된다.

 

Source repository를 쓴다면 이런 목적이어야 하지 않을까? 변경이 왜 일어났고, 언제 일어났으며, 누구에 의해 발생했는지를 한 눈에 명확하게 파악할 수 있다. 와중에 git 같은 툴을 사용하고 있다면, 코드가 발전되어 가는 형상을 관찰할 수도 있다. 그렇기 때문에 git을 써야한다.

개인적으로는 코드에 코멘트를 하나도 남기지 않는 것이 최선이라고 생각한다. 코드에 남기는 코멘트는 파일이 최초로 만들어졌을 때 자동 생성되는 작성자 이름과 작성일 정도면 충분할 것 같다. 그 이외에 자동으로 생성되는 나머지 코멘트들은 모두 지워버린다. 남겨두면 그게 득이 되는 경우를 본적이 없는 것 같다.

코딩 세상에서 미니멀리즘을 추구해야할 부분이 바로 이 포인트이지 않을까 싶다.

]]> 478
.gitignore 파일을 깔끔하게~ /index.php/2016/05/13/gitignore-for-clean-project/ Fri, 13 May 2016 01:47:20 +0000 /?p=145

Continue reading ‘.gitignore 파일을 깔끔하게~’ »]]> 협업하는 다른 친구에게 pull request를 보냈다가 알게된 팁인데 꿀팁인 것 같아서 정리해둔다.

보통 .gitignore 파일은 프로젝트 빌드 혹은 작업 과정에서 생기는 부산물들을 굳이 git에 포함시킬 필요가 없는 파일들 혹은 디렉토리들을 제외시키기 위해서 사용된다. 이런 파일들 가운데 내가 종종 포함시키는 패턴들이 IDE와 관련된 파일들이었다.  하지만 IDE라는건 개인적인 취향에 따라 다름이 있다. 사람마다 서로 다른 IDE에 대한 부분을 .gitignore 파일에 포함시키다보면 .gitignore 파일이 두서없이 변경되기 마련이다. 내가 쓰는 IDE를 저 친구가 안쓴다고 비난할 일은 아니지않은가?

그럼 이 부분을 다른 사람을 방해하지 않고 처리할 수 있을까?  정답은 global .gitignore 파일을 사용하는 방법이다. 사용 방법은 간단히 다음 링크를 참고하면 된다.

내용을 추려서 정리하면

  • 사용자 홈 디렉토리에 ~/.gitignore 파일을 만들어둔다. (파일 이름은 꼭 이게 아니어도 된다.)
  • 이 파일에 내가 작업하는 내 IDE 혹은 생성될 수 있는 불필요한 파일들의 패턴들을 기록해둔다.

gitignore

  • 아래 명령을 한번 돌려준다.  그럼 이후에 다른 프로젝트를 동일한 IDE를 가지고 작업하더라도 해당 파일들은 git 대상에 포함되지 않는다.
$ git config --global core.excludesfile ~/.gitignore

이 방식을 사용하면 프로젝트에 포함된 .gitignore 파일은 프로젝트에 관련되서 생기는 불필요한 파일들만 관리할 수 있기 때문에 프로젝트를 온전히 프로젝트 용도로만 관리할 수 있게 된다.  작지만 협업자들을 위한 배려 차원에서 하나씩은 설정해둘만하다.

]]> 145
git의 ssh key 설정하기 /index.php/2016/03/29/git-ssh-key-terminal/ Tue, 29 Mar 2016 10:11:16 +0000 /?p=85 추가하는 방법은 git의 사용자 셋팅에 SSH Key추가하기를 하면 되는데…

https://help.github.com/articles/generating-an-ssh-key/

이미 예전에 추가를 해놨음에도 불구하고 왜 맥 터미널에서 자꾸 passphrase를 입력하라구 물어보는거야!!

와중에 이전에 입력해둔 문구를 까먹었는데!!!

별다른 방법이 없다. 다시 만들고 등록해두는 방법 밖에는.

다 하고 다음 명령어로 넣어두면 이후에는 안물어볼 것 같다.

ssh-add -K
]]>
85
git: terminal에서 간지나게 써보자. /index.php/2016/03/14/git-in-terminal/ Mon, 14 Mar 2016 06:12:41 +0000 /?p=17

Continue reading ‘git: terminal에서 간지나게 써보자.’ »]]> Git을 이클립스나 IntelliJ에서만 사용해야한다면 좀 쪽팔릴 것 같다.
GUI 없는 상황에서는 바보가 될 거기도 하고 뭔가 Cool하지 않다.

기억력은 역시나 3초말이라 항상 까먹는다. 흔하게 사용하는 것들 위주로 정리해놓는다.

Git Repository 처음 사용하기

$ git init
현재 디렉토리를 git 저장소로 등록한다.

$ git add –all
현재 디렉토리 및 그 하위에 있는 모든 파일들을 git의 변경 대상으로 등록한다. 하기전에 아래 .gitignore 파일에 쓸데없는 파일들을 먼저 정리하자. 안그러면 번거로운 일을 두번할 수 있다.

만약 이전에 .gitignore 파일이 없다면 아래 파일을 먼저 정의한 다음에 –all 옵션으로 실행한다. 이미 실행했다고? 그럼 rm -rf .git 명령으로 git repository 설정을 날려버리면 된다. 쫄지 말자!

.gitignore
이 파일에 만약 git을 통해 관리하기 싫은 파일이 있다면 기록해둔다. .gitignore 파일이 존재하는 디렉토리를 기준으로 상대 경로를 지정하면 해당 파일은 관리 대상에서 빠진다. 생각외로 이거 사용해보면 참 좋다. 이클립스나 IntelliJ를 포함해서 서버에 올릴 파일들을 빼고 설정을 잡는다면 대강 아래와 같다.

*.class

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

# eclipse ignorings
.classpath
.project
.settings/

# intellij ignorings
*.iml
.idea/

 

변경 내용 커밋하기

$ git commit
git add 명령을 통해 등록된 파일들을 커밋한다. git add / rm 되지 않은 파일들은 커밋 대상에 포함되지 않는다. 단순히 변경했다고 하더라도. 이런 상태를 unstaging이라고 부르는데 add/rm을 통해 staged 상태로 만들어줘야 한다.

$ git commit -a
git add 명령을 통해 이전에 등록해둔 파일들의 변경(modified, deleted)된 내역들을 자동으로 커밋한다.

$ git commit file1 file2 file3
지정된 특정 파일들만 커밋한다.

$ git commit -m ‘commit message’
커밋 로그를 작성하지 않고 -m 명령에 붙은 메시지를 커밋 로그로 반영한다. 이렇게 하면 뭔가 쿨해보인다. *^^*

여기까지 했으면 로컬에 설치된 git을 통해 작업할 건 다 했다. 이제 원격에 있는 git repository에 작업된 코드를 반영할 시간이다.

$ git stash / git stash apply

작업을 하다보면 현재 작업 부분을 마무리하지 못하고 git repository에 반영을 해야만하는 경우가 있다.  작업한 부분이 좀 된다면 Rollback한 다음에 하기에는 좀 아쉬움이 크다.  그렇다고 진행중인 내용을 commit 해버릴 수도 없는 노릇이고…  이런 경우에 활용할 수 있는 명령이 stash 기능이다.  stash 기능을 사용하면 현재 작업중인 결과물을 임시로 별도의 공간에 저장하고, 소스 repository의 상태를 최종 commit한 버전의 상태로 돌려준다.

최종 커밋한 결과물까지를 서버에 push하거나 그 상태에서 추가적인 작업을 마무리하고 commit & push를 하면 된다.  그리고 stash apply 기능을 통해 이전에 작업중인 코드를 현재 branch로 불러들여와 작업을 이어가면 된다.

 

원격 서버와 친해지기

$ git remote add origin git-repo-address
원격 git repository를 현재 디렉토리에 바인딩한다. git repository를 지정하는 방식은

  • https://protocol
  • git:// or
  • user@server:path/to/repo.git

방식 가운데 하나를 사용해서 지정한다.

만약 origin 이라는 이름이 너무 상투적이라고 생각된다면 다른 이름을 사용해도 된다. 하지만 헷갈리지 말자. 지정해놓고 헷갈리면 .git 디렉토리에서 뒤지면 나온다.

$ git clone git-repo-address
만약 이미 원격에 있는 소스를 내가 받아와야 한다면, clone 명령을 사용한다. address 뒤에 별도의 디렉토리 이름을 입력하지 않으면 repository 이름이 그대로 디렉토리 이름으로 사용된다.

$ git pull origin master
원격 서버의 master branch의 변경 내역들을 땡겨온다.

$ git pull origin master
서버에 올린다. 만약 master라는 원격 branch의 이름을 까먹으면 로컬에 있는 모든 브랜치가 서버에 다 올라간다. 작업하다가 임시로 만들어놓은 것까지… 귀찮으니까 가능하면 branch의 이름을 적어주는 습관을 들이는게 좋고, 그게 아니라면 로컬에는 작업이 끝난 branch는 삭제해주는게 좋다.
평소에 보이지 않는 깔끔한 코드 작성할 때는 보여주자.

 

머지하기

다른 git repository와 머지하는 방법은 다음과 같은 방식을 사용한다.

1. 현재 작업 내용을 일단 commit 한다.

2. 현재 branch를 기준으로 머지할 브랜치를 따로 checkout 한다.
$ git checkout -b update_branch current_branch
만약 작업할 branch가 이미 있다면…
$ git checkout update_branch

3. 해당 branch로 다른 repository의 데이터를 땡겨온다.

$ git pull git-repo-address branch_name

이 과정에서 만약 쫑이나면 쫑이난 문제를 해결해야한다.
보통 쫑나면 해당 파일에 > < 와 같은 표식으로 표시가 되고, 그걸 vi 혹은 GUI 편집기를 가지고 편집하면 된다. 분량이 작을 경우에는 vi를 가지고 해도 되겠지만, 분량이 좀 된다면 그냥 이클립스나 IntelliJ를 사용하도록 하자.

4. 이제 현재 branch로 이동
$ git checkout current_branch

5. 머지하기
$ git merge update_branch

이미 앞단계에서 원격 서버와 다 합쳤기 때문에 여기서는 별달리 할게 없이 바로 되야한다. 안되면 뭔가 이상한거야!!

불필요해진 파일 삭제하기

$ git rm filename
그냥 용감하게 rm 명령으로 지운다고 git에서 제거되지 않는다. 꼭 이 명령으로 제거해줘야지 git entry에서도 빠지고, 이후에 작업하는데 번거롭지 않게된다.

]]> 17