git은 여러권의 책으로 다루어야 할 만큼 방대하고 다양한 기능을 갖고 있다.

여기에서는 git 을 활용하는 사례로 git을 이용하여 각종 설정 파일(웹서버 설정, system config 설정등)을 버전 관리하는 사례를 보여주고자 한다.

설정 파일 버전 관리 필요성

서비스 운영이나 시스템 변경 작업시에 서비스 데몬이나 시스템 설정 파일들을 수정할 경우가 많이 발생한다. 버전관리를 잘 모르던 시절에는 다음과 같이 기존 설정을 복사하여 혹시 모를 실수에 대비하였다.

    cp httpd.conf httpd.conf.org

혹은 파일명에 변경 날자를 넣어서 백업하기도 하였다.

    cp httpd.conf httpd.conf-201400102

 

위와 같이 백업을 할 경우 다음과 같은 불편함이 있다.

  1. 언제 누가 무엇을 왜 바꿨는지 알기가 어렵다. 변경 과정과 일시가 남아 있지 않으므로 변경 내역 확인이 어렵다. 차이점을 알려면 콘솔에서 diff 등의 명령어를 통해서 두 파일을 비교해야 한다.
  2. 실수할 경우 복구가 어렵다. 설정 파일 수정을 한 번에 끝나고 원하는 결과가 나오면 좋지만 조금씩 수정하고 반영하며 결과를 보아야 하는 경우도 많다. 여러 단계를 거쳐 진행하다가 특정 시점으로 돌아갈 경우가 발생하면 단순 파일 복사로는 실수를 복구하기가 어렵다.

이런 문제를 해결하기 위해서는 설정 파일도 버전 관리 시스템을 이용하여 관리하는게 안정적인 운영 및 서비스 측면에서 유용하다.

 

서브버전대신 git 이 유리한 이유

서브버전은 버전 관리를 하려면 먼저 중앙저장소에 import 하고 checkout 을 한후에 관리해야 한다. 예로 아파치 웹서버의 설정 파일을 관리한다고 가정해 보자. 서브버전이라면 다음 절차를 거쳐야 한다.

  1. 저장소 생성 및 httpd 폴더 생성
    svnadmin create /root/config-repos 
    svn mkdir file:///root/config-repos/httpd 
  2. 프로젝트 임포트
    svn import /etc/httpd file:///root/config-repos/httpd
  3. /etc/httpd 이동
    mv /etc/httpd /etc/httpd.old 
  4. 프로젝트 checkout
     svn checkout file:///root/config-repos/httpd  /etc/httpd 
  5. 설정 파일 편집
  6. 변경 내역 커밋
    svn commit 

위와 같이 import 와 checkout 을 거쳐야 하므로 정해진 경로와 파일명을 갖고 있는 설정 파일들을 관리하기에는 불편하다. 

이제 git 을 사용할 경우의 작업 흐름을 살펴보자

  1. 작업 폴더로 이동
    cd /etc/httpd
  2. 저장소 초기화
    git init
  3. 저장소에 파일 추가
    git add conf conf.d
  4. 설정 편집
  5. 변경 내역 커밋
    git commit

복잡한 저장소 생성 및 체크아웃, 임포트 작업이 줄어들었다. 특히 /etc/httpd, /etc/sysconfig, /etc/postfix 등 여러 데몬들의 설정 파일을 관리할 경우 해당 디렉토리에서 바로 git init 을 수행하면 되므로 매우 간편하게 설정 파일을 버전 관리할 수 있다.


간단한 git 명령어 정리

git 환경 설정

먼저 git 을 사용하여 버전관리할 경우 유용한 git 환경 설정 방법을 알아보자.

git은 분산형이므로 커밋시에 사용자명과 이메일주소가 있어야 한다. 다음 명령어로 global 하게 설정할 수 있다.

    git config --global user.name "Your Name"
    git config --global user.email "your@email.com"

 

서브버전과 마찬가지로 git 도 변경 내역을 보는 diff 라는 명령어가 있다. 다음 설정은 콘솔에서 diff 시 변경 내역을 칼라로 출력하여 가독성을 좋게 해준다.

   

 

git add

서브버전과 다르게 git 은 새로 추가된 파일/디렉터리뿐만 아니라 변경된 파일도 add 를 해주어야 커밋이 가능하다. 사용법은 add 뒤에 커밋할 파일이나 폴더를 입력해 주면 된다.

 

git commit

로컬 저장소에 변경을 반영하는 명령어이다. 커밋할 데이타는 미리 add 가 되어 있어야 한다. 

 

git status

현재 저장소의 상태를 볼수 있다. content 가 추가/삭제/변경된 내역을 볼 수 있다. 

 

git log

저장소의 이력 로그를 볼 수 있다. 매우 다양하고 복잡한 하위 옵션을 갖고 있다. 옵션없이 사용하면 현재 저장소의 가장 최근의 5개 로그를 표시해 준다. 다음처럼 로그를 볼 리비전을 명시하면 해당 리버전을 포함해 이전 5개의 로그를 표시한다.

    

     

 

 

.gitignore

서브버전은 저장소에 추가하지 않을 파일들은 svn:ignore 라는 프로퍼티를 설정해야 했지만 git 은 저장소를 생성한 폴더에 .gitignore 라는 파일을 만들고 무시할 파일이나 디렉터리 이름을 적어주면 된다. 또 * 을 사용한 패턴을 사용할 수도 있다.


git으로 httpd 설정 관리

8장에서 다룬 apache httpd 의 설정을 git 을 이용하여 관리해 보자. 먼저 관리할 설정파일이 있는 곳에 git 저장소를 생성해 보자

    cd /etc/httpd
    git init
   
    Initialized empty Git repository in /etc/httpd/.git/ 

 

저장소가 생성되었으므로 추가할 파일과 폴더를 선택하고 commit 을 하면 된다. httpd 폴더밑에는 5개의 하위 폴더가 있지만 설정 파일은 conf, conf.d 두 개의 폴더에만 저장되며 다른 세 개 디렉터리는 버전관리할 필요가 없다. 2개 디렉터리만 git으로 관리하고 나머지 3개 디렉터리는 gitignore 를 사용하여 무시해 보자.
     git add conf add conf.d 
     echo -e "logs\nmodules\nrun\n" > .gitignore 

echo 명령어에 -e 옵션을 추가하면 \n 을 줄바꿈으로 처리한다. cat 으로 .gitignore 를 보면 다음과 같이 파일이 생성되어 있을 것이다.

     cat .gitignore

     logs
     modules
     run

 

이제 git status 로 현재 작업공간의 상태를 확인해 보자. 
    git status

    # On branch master
    #
    # Initial commit
    #
    # Changes to be committed:
    # (use "git rm --cached <file>..." to unstage)
    #
    # new file: conf.d/ssl.conf
    # new file: conf.d/subversion.conf
    # new file: conf.d/welcome.conf
    # new file: conf/httpd.conf

현재 저장소의 branch, commit 및 저장소의 상태를 알 수가 있다. 이제 커밋해서 저장소에 반영해 보자. 서브버전처럼 commit 하위 명령어가 있으며 -m 으로 커밋 메시지를 명령창에서 바로 입력할 수 있다.
    git commit -m "최초 커밋" 

    4 files changed, 1787 insertions(+), 0 deletions(-)
    create mode 100644 conf.d/ssl.conf
    create mode 100644 conf.d/subversion.conf    
    create mode 100644 conf/httpd.conf
    create mode 100644 conf/magic

 정상적으로 커밋이 되었다. 이제 이력 조회를 위한 추가 커밋을 만들기 위해 설정 파일을 간단하게 수정하고 커밋해 보자. 

    echo "### test " >> conf/httpd.conf
    git add conf/httpd.conf
    git commit -m "설정 파일 맨뒤에 주석 추가"

 

이제 서브버전의 log 처럼 작업공간의 로그 상태를 볼 수 있다. git 은 분산형 버전관리이므로 리비전을 숫자로 하면 충돌할 우려가 있다. 그래서 리비전으로 변경내역을 SHA1 해쉬값한 값을 사용한다. 

    git log   

    commit dea19d503e5cd0056cb224a05637293f6a05838c
    Author: root <root@localhost.localdomain>
    Date: Wed Apr 9 07:02:07 2014 -0700

            개행 추가

     commit b2efdd968567d7accbbc21e528c21d68826164f2
     Author: root <root@localhost.localdomain>
     Date: Wed Apr 9 06:53:36 2014 -0700

           최초 커밋

 

commit 옆에 b2efdd 로 시작하는게 리비전이다. 특정 리비전부터 보고 싶으면 리비전의 해쉬값중 앞 4자리 이상을 입력하면 된다. 
    git  log b2ef


옵션없이 log 명령어만 주어서는 바뀐점을 확인하기 어렵다. -p 옵션을 주면 줄 단위로 변경 내역을 출력한다. 또 -1 옵션을 주면 최근 한개만 표시한다.

     git log -p -1
   

     commit 197482ad7e4653f27ed014c23cbead2e453d3e8e
     Author: root <root@localhost.localdomain>
     Date: Wed Apr 9 07:15:20 2014 -0700

           설정 파일 맨뒤에 주석 추가

    diff --git a/conf/httpd.conf b/conf/httpd.conf
    index 454aa47..fde7adf 100644
    --- a/conf/httpd.conf
    +++ b/conf/httpd.conf
    @@ -1027,3 +1027,4 @@ BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully
     </VirtualHost>

     +### test

추가된 줄은 + 로 시작하고 삭제된 줄은 - 로 시작하므로 변경 내역을 손쉽게 알 수 있다.

이제 실수했을때 특정 리비전으로 복구하는 방법을 알아보자. 서브버전의 revert 처럼 git 도 revert 명령어를 갖고 있다. 파라미터로는 복구할 리비전을 적어 주면 된다. 서브버전과 다른 점은 git revert 는 로컬 저장소에 커밋까지 수행한다는 점이다.

맨뒤에 주석을 추가하기 전 리비전인 197482ad.. 로 복구해 보자.

    git revert 1974

    [master 3ba64c3] Revert "개행 추가"
    Committer: root <root@localhost.localdomain>

 

이제 git log 를 해보면 다음과 같이 주석을 추가하기 전 상태인 "개행 추가" 상태로 복구되고 해당 리비전은 새로 커밋된 것을 확인할 수 있다. log 명령의 하위 옵션인 --pretty=short 를 추가해서 로그를 요약해서 볼 수 있다.

    git log --pretty=short
    commit 3ba64c37c255348fe04b03b17fb36061f18a69be
    Author: root <root@localhost.localdomain>

        Revert "개행 추가"

    commit 197482ad7e4653f27ed014c23cbead2e453d3e8e
    Author: root <root@localhost.localdomain>

        설정 파일 맨뒤에 주석 추가

    commit dea19d503e5cd0056cb224a05637293f6a05838c
    Author: root <root@localhost.localdomain>

        개행 추가

    commit b2efdd968567d7accbbc21e528c21d68826164f2
    Author: root <root@localhost.localdomain>

       최초 커밋

 

git 은 방대하고 복잡한 기능을 갖고 있지만 위에서 소개한 명령어와 방법을 알면 설정 파일 관리용으로 충분히 사용할 수 있다고 생각된다.