• .gitignore 에 아래의 항목을 추가해야 svn의 시스템 파일들이 포함되지 않는다.

*.svn*


  • .svn 밑의 파일들이 git에 포함된 경우 실제파일은 지우지 않고 git내의 색인대상에서만 삭제하는 명령어 ( removing svn system files in git index data instead of doing real data )

$ find . -name "*.svn*" -type f -exec git rm --cached {} \;



XXX is already under version control

분명히 현 repository의 새로운 녀석인데 버전컨트롤대상이라고 한다.

이는 그 디렉토리 밑에 .svn 까지 복사 되었기 때문이다.

따라서 .svn 을 지우고 svn add 를 수행하면 된다.

Tag 생성하기

$ svn copy [source] [target] -m "Message"
   (ex) svn copy http://svn.example.com/project/trunk http://svn.example.com/project/tags/RELEASE-110214 -m "Tag : Release 110214"



참고 사항

  • 특정 태그 이름으로 받은 repository는 해당 tag가 업데이트 하는 내용만 받고 trunk 쪽의 업데이트 내용은 받아오지 않는다. 







간단하게 비교하는거니 
다른 방법으로도 가능하다는 것을 증명하기 위해 성내지 말고
주인장이 이곳에 잘 반영할 수 있게
친절히 커맨트하시기 바랍니다.

  • 마지막 commit 이후 변경된 파일 목록 보기
    • git : git status
    • svn : svn status
    • cvs : cvs diff --brief
  • commit 간 diff 보기
    • git : git diff <commit id>..<commit id> 또는 git diff <commit id>...<commit id>
    • svn : svn diff -r 이전리비전번호:비교할리비전번호

git와는 다르게 svn에서 반복적인 ignore 를 하는 방법은 아래와 같다.

  1. 각 디렉토리마다 ignore pattern을 property로 등록. (Don't forget the last dot)
    • command : svn -R propset svn:ignore [pattern] .
      $ svn -R svn:ignore *.obj .

  2. svn configuration파일에 global-ignores 패턴 등록

svn의 또다른 어메이징한 것은 global ignores로 지정하지 않을 경우 새로운 디렉토리가 생길때마다 저 패턴을 등록해줘야 한다는 것이다. 

어떤 것을 선택하든 번거롭고 깔끔하지 못하다.

역시 svn 은 cvs가 git로 가는 도중의 중간산출물 같다.

결론 : git가 좋다.
  1. 명현 2011.01.25 09:05 신고

    ㅋㅋㅋ git svn 찾다가 이게 나오네요

  1. apr 및 apr-util 컴파일 및 설치http://archive.apache.org/dist/apr/
    • apr configure 설정(default설정 이용)
      $ ./configure
    • apr-util configure 설정(설치경로 : /usr/local/apr-util) :
      $ ./configure --with-apr=/usr/local/apr --prefix=/usr/local/apr-util

  2. neon 컴파일 및 설치http://www.webdav.org/neon/
    • neon configure 설정 (설치경로 : /usr/local/neon) :
      $ ./configure --prefix=/usr/local/neon

  3. subversion 컴파일 및 설치http://subversion.tigris.org/
    • subversion configure 설정
      $ ./configure --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-neon=/usr/local/neon


Errors


  • git clone 시 fatal: remote end hung up 발생한 경우 : remote end hung up에는 여러가지 요인이 있을 수 있다. 대부분 remote server의 ssh 포트(20)로의 접근이 불가능 하거나 서버에 public_key를 제대로 등록하지 않아서 발생한 이슈들이 대부분이다. 하지만 본인의 경우에는 scp, ssh 로 remote server로 접속하는데 아무런 문제가 없었다. 오랜시간동안의 사투끝에, 윈도우용 git (msysgit) 를 설치하고, cygwin 패키지를 설치할때도 git 를 설치하였는데 그 둘이 충돌이 나는 거였다. 윈도우용 git를 uninstall 하고 나서 문제가 간단히 해결되었다. 
오역이나 오탈자에 대한 것은 덧글활용을 부탁드리며, 내용수정은 허락하지 않습니다.


각자 나름대로 git의 branch을 개성있게 사용하고 있겠지만, 아래 링크된 곳에서는 저자가 여러 프로젝트를 진행하면서 사용했던 브렌치들을  하나의 모델로 정형화하여 잘 설명하고 있다. 그 중에 branch활용방안에 대한 내용들을 번역 및 요약해본다. 







  • The main branches

    • master
      • 기본적으로 git에서 생성되는 branch.
      • 운용 기준
        • HEAD부분은 제품으로 나갈만큼 안정화되어 있어야 한다.

    • develop
      • 개발시 이용하는 branch
      • 운용 기준
        • 최근 개발 현황이 HEAD에 담겨야 한다.
        • 다음 release를 위한 기능 추가가 이루어 진다.
        • auto build 및 test 대상이 된다.
        • 안정화가 끝나면 master 와 merging되고 release tag 번호가 부여된다.
  • Supporting branches : 수시로 생성과 삭제가 반복되는 branch

    • feature
      • 새로운 기능을 추가할때마다 생성하는 branch
      • Naming : master, develop, release-*, hotfix-* 을 제외한 어떠한 이름도 허용가능
      • 운용 기준
        • develop 에서 branching 하며 완성되고 나면 다시 develop branch로 merging 한다.
        • 새로 추가한 기능이 이점을 줄 수 있을때에만 develop branch로 merging한다.
        • merging을 완료하고 나서 생성된 feature branch를 삭제한다.
        • merging 시 "--no-ff" 옵션을 사용한다. 이 옵션은 merging할때 fast-forward와 함께진행될 때에도 항상 새로운 commit을 생성한다. 이로 인해 feature branch에서 저장했던 예전 작업들에 대한 정보들에 대한 손실을 막을 수 있다. 아래의 그림을 보면 그 차이가 드러난다. 오른쪽의 일반적인 merging은 feature에서 merging된 commit들이 기존에 develop에 있던 commit들과 구분이 안된다.



    • release
      • 새로운 release를 내기위해 준비하는 branch
      • Naming : release-* (*는 니 맘대로 문자열을 의미한다.)
      • 운용 방안
        • develop branch로 부터 가져오고 develop와 master로 merging을 실시한다.
        • release branch 생성후 먼저 버전 올려주는 것을 잊지 말자.
        • minor bugs나 meta-data(버전정보, 빌드날짜 등등) 추가는 허용된다.
        • 해당 번호 release시에 목표했던 feature들이 추가되어 만족할만한 기능이 나올때(develop branch가 다음release를 준비할 만한 상태일 때에...)에 release branch를 생성한다. 다음 릴리즈에서 포함되어야 되는 기능들은 절대로 포함시켜서는 안된다. 네이밍을 할때는 next-release같은 것은 피해야 한다. 그 대신 0.5, 1.2.3 같은 구체적인 수치와 그에 해당하는 기준들을 마련한다.
        • 작업이 완료되면 master로 merging한다.merging 후에는 release정보로 바로 tagging한다. master로의 작업이 완료된 후에는 반드시 develop에도 merging을 실시 한다. merging시에 발생하는 conflict는 해결후 commit 한다.
        • merging이 완료되면 해당 release branch를 삭제한다.

    • hotfix
      • 출시된 제품에서 오류가 발견되어 즉시 해결해야 하는경우 이용하는 branch
      • Naming : hotfix-*
      • 운용 방안
        • master의 해당 태그로부터 가져오고 develop과 master로 merging을 실시한다.
        • hotfix branch생성후 먼저 버전 올려주는 것을 잊지 말자.
        • 완료된 후에는 master 적용후 develop에도 적용해야 한다. 이때, release branch가 있는 경우 develop에 merging 하지 말고 release에 한다. 왜냐하면 release시에 테스트가 수반되고, release작업이 완료된 경우 release branch가 다시 develop에 적용되기 때문이다.
        • merging이 완료되면 해당 hotfix branch를 삭제한다.

#!/bin/bash

for dir in /home/dualistmage/git/*; do
    cd $dir
    printf "%-15s : " "${dir/\/home\/dualistmage\/git\//}"
    git log --pretty=oneline -n1
done

GIT 에서 Binary 파일을 자동으로 인식하는데, 가끔 text file로 오동작을 한다. 이는 나중에 merging 시 line process를 할 수 있기 때문에 위험성이 존재한다.

.gitignore 처럼 binary 인식시 .gitattributes 라는 파일안에 특정 파일형식을 등록하게 되면 해당하는 모든 파일들은 모두 binary 로 인식하게 된다. (사실 이 기능은 .gitattributes 파일의 여러 기능중의 하나이므로 다른 기능들을 알아보고 싶은분은 git manual 을 참조 바란다. )

.gitattribute :  http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html 

만약 모든 pdf 파일을 binary 로 인식하게 하고 싶으면, repository 의 적용할 최상단 directory 에 .gitattributes 파일을 만들고 아래와 같이 집어 넣는다.
*.pdf -crlf -diff -merge
<옵션 설명>

-crlf : *.pdf가 carriage return 과 line feed 이 없는 파일이라는 것을 기술한 것이다.
-diff : *.pdf에 대해서는 diff를 binary file differ로 이용하겠다는 것이다. ( text diff 를 unset 했다고 이해하면 됨)
-merge : *.pdf 에서 merging 시 conflict 가 발생한 경우 현재 branch 에 있는 녀석을 취하고 conflict 메시지를 발생시킨다는 것.

  • remote 서버 등록하기

    git remote add [이름] [실주소]
    (ex) $ git remote add TestRemote 192.168.0.1:/git/TestRemote.git

  • 현재 branch 의 remote 서버를 redirect하기

    현재 repository 의 최상단으로 이동하면 .git/config 라는 파일이 있다. 이 파일을 연다. 내가 현재 있는 branch 이름을 "MyBranch", 연결할 Remote branch 를 TestRemote 라고 하면 아래와 같이 되어 있을수도(설정값이 다를수도 있다. 그냥 있다는데에 의의를 두자.) 있고 아얘 없을 수도 있다.

    [branch "MyBranch"]
            remote = origin
            merge = refs/heads/MyBranch

    이것을 아래와 같이 변경한다.

    [branch "MyBranch"]
            remote = TestRemote
            merge = refs/heads/MyBranch




$ git diff --cached

add 가 적용된 상태를 staged 라고 하는데, --cached 는 add한 파일들에 대해서 비교한다.

--cached 뒤에  commit 을 주지 않으면 기본적으로 HEAD 와 비교한다.

괜찮다~!

초, 중반 그리고 고급 사용자들이 궁금해할만한 사항들을 아이템별로 잘 정리된 사이트. .( Kent, Thanks~! )





원격 서버의 특정 브렌치나 tag를 삭제하고자 한다면 아래의 명령어를 이용하면 된다.

< Remove local branch & tag >


$ git push origin :heads/{branch name}
$ git push origin :tags/{tag name}



예를들어 remote repository 의 test 라는 브렌치를 지우고 싶다면,
   $ git push origin :heads/test 
라고 하면 된다.




내 계정 내의 브렌치나 태그를 지우고 싶을 경우에는

< Remove local branch >


$ git branch -d {branch name}

or

$ git branch -D {branch name} // 강제 삭제


< Remove local tag >


$ git tag -d {tag name}



참고로, 서버에서 지우고 fetch 를 한다해도 local 에 남아있다면 자동으로 지워지지 않으므로
내 계정내의 것도 지워야 한다.
cvs 나 subversion 처럼 특정 시점에 이름표를 달수 있는 기능이 git 에도 있다. 

주로 프로젝트의 안정화 버전이라던지 개발 버전같이 버전관리를 할때 tag 가 많이 쓰인다.

tag 와 관련된 기본 명령어는 다음과 같다. 보다 자세한 내용을 알고 싶으면 man git-tag 명령어를 처보기 바란다.



현재 commit 에 Tag 생성하기

$ git tag -a [Tag name]


현재 태그 리스트 보기

$ git tag


특정 태그가 가리키는 commit id 보기

$ git rev-parse [Tag Name]


tag 삭제하기 : tag 는 변경이 되지 않는다 무조건 지우고 다시 생성하여야 한다.

$ git tag -d [Tag Name]


tag 정보를 업로드 하기 : 반드시 -a 나 다른 옵션을 통해 생성된 tag(comment 가 붙은 tag) 여야 한다.

$ git push --tags


tag 정보 받기 : 처음 받는 경우에는 자동으로 받아지나 만약 갱신을 해야 할경우 받는쪽에서도 추가적인 작업이 필요하다. 앞에서 언급했듯이 tag는 변경 할 수 없고, 지우고 새로운 것을 받아야 한다.

$ git tag -d [Tag Name]
$ git fetch origin tag [Tag Name]


Introduction

Branch 를 자유자재로 쓰기위한 기본단계로, 서버단의 branch 를 생성하고 서버의 branch 를 가져오는 방법을 기술하고자 한다. 설명을 좀 쉽게 하기 위해 git push를 하는 곳을 서버라 하고, 서버로 부터 내용을 받아오는 곳을 클라이언트라 가정한다.




Description


0. branch 관련 기본 명령어

   - branch 생성 : git branch [branch이름]
   - branch 변경 : git checkout [branch이름]
   - branch list 보기 : git branch 또는 git branch -a

     (예) 클라이언트에서 만약 서버의 모든 branch 를 보고 싶으면 git branch -a를 하면 된다. 앞에 origin/ 으로 된 것이 서버쪽의 branch list 이다. (버전 1.6.3.1에서는 remotes/origin/ 으로 보임)이 이는 hidden value 이기 때문에 -a 옵션을 주어야 나온다. * 가 붙은 branch 는 현재 내가 있는 곳이다. 단 변경된 사항을 먼저 받고 ( git fetch 나 git pull ) git branch -a 를 해야 최근의 리스트가 나온다.
          $ git branch -a
          * master
             origin/HEAD
             origin/branchtest
             origin/master




1. 서버에 branch를 생성하는 방법 : 서버에 생성을 하는 것으로 아직 클라이언트에는 branch가 만들어지지 않는다.

   $ git push origin [올리고자 하는 branch이름]:[target branch이름]

현재 작업하고 있는 branch 가 project 1 이고 서버의 branchtest 라는 branch 에 올리고 싶은경우 다음과 같이 하면된다.

   (예) $ git push origin project1:branchtest

 

2. 서버쪽 branch를 복사하는 방법 : 클라이언트에 branch 를 생성한 후 서버의 branch 안의 내용을 복사한다.

merge 할 branch로 이동한다.
   $ git checkout [branch name]

   $ git fetch
   $ git merge origin/[가져올 remote branch]

또는

   $ git pull origin/[가져올 remote branch]

   (예) $ git checkout project1
          $ git pull origin/branchtest



3. 현재까지의 변화를 서버쪽 branch 에 적용시키는 방법 : 클라이언트의 적용시키길 원하는 branch 로 이동후 add, commit, push 를 하면 된다. 기존에 master 에서 소스 올릴때 하는것과 동일하다.


p.s 만약 clone 명령을 통해 서버의 내용을 받아오는경우, 서버가 현재 속해있는 branch 만을 가져온다.
  1. Favicon of http://finsternis.tistory.com BlogIcon leanu 2009.06.04 12:00 신고

    특정 branch 나 tag 버전을 새로운 브랜치를 생성하여 적용하고 싶을경우 다음과 같이 하면 된다.

    특정 branch 이름 : remotes/origin/project_branch_1
    새로운 branch 이름 : new_branch

    $ git checkout -b new_branch remotes/origin/project_branch_1

  2. 2011.05.20 09:40

    비밀댓글입니다

    • Favicon of http://finsternis.tistory.com BlogIcon leanu 2011.05.23 13:33 신고

      많은 도움 되었다니 저도 기쁘네요 :)

      모든 내용들은 "명령어 --help" 나 "man 명령어" 로 왠만한 내용들을 습득하실 수 있습니다. 특히나 잘 안쓰는 기능들을 쓰게 되는 경우에는 메뉴얼 참조가 필수니 참고 바래요~!

GIT

Error Msg
------------------------------------------------------------------------------------------
remote: error: remote: unable to find 1a0352d8d664add294d1a47c512aafcac48ccb8d
remote: fatal: unable to get type of object 1a0352d8d664add294d1a47c512aafcac48cremote: cb8d
error: git-upload-pack: git-pack-objects died with error.
fatal: git-upload-pack: aborting due to possible repository corruption on the remote side.
remote: aborting due to possible repository corruption on the remote side.
fatal: protocol error: bad pack header



Cause
------------------------------------------------------------------------------------------
GIT blob 중에 1a0352d8d664add294d1a47c512aafcac48ccb8d 를 찾을 수 없다는 메시지이다. 
Disk 혹은 Memory 상의 문제일 수도 있고, 낮은 버전의 GIT 사용으로 인한 버그일 수도 있다는
말로 보아 이 에러의 근원은 알수 없다는 것으로 보인다. 

본인이 이 에러메시지를 받은 상황은 다음과 같다. A라는 클라이언트에서 디렉토리를 git add하고나서 
다른 클라이언트(B)에서 pull을 통해 받아보았는데, 디렉토리 안의 일부 하위 디렉토리안에 파일이 
추가가 안되어서 다시 A 클라이언트에서 추가안된 하위 디렉토리를 git add하고 B 에서 받아보려는
순간 저 메시지가 발생하였다.

원래 directory 에 대해서는 blob 을 생성하지 않는데, 처음에는 저것을 blob으로 인식했다가
다시 커밋할때 저 파일이 지워저야 하는데, 지워지기 전에 받아서 그런거 같다. 언제 지워지는지는
잘 모르겠지만 일정시간( 한 10분 이내? )이 걸리는거 같다. 왜냐하면 다른쪽에서 저 repository를
복사한 경우 별 문제없이 최신 tree를 가져오기 때문이다.


Solution
------------------------------------------------------------------------------------------
최선의 해결책은 아직 나오지 않은 상태이다. 우선 다음과 같은 명령어로 저 object 가 log에서
어떤 파일이었는지를 알수 있다.

     $ git log --raw | grep 1a0352d8d664add294d1a47c512aafcac48ccb8d

git log --raw 를 하면 커밋트리의 모든 blob 에 대한 hash값을 볼 수 있고, 그 blob이 가리키는
파일도 알 수 있다. 그래서 혹시나 동일 파일이 있으면 그 파일을 add 함으로서(내용이 바뀌지 않았다면
동일한 hash값을 얻을 수 있다) 복구 할 수는 있다. 

최종적으로 선택한 임시방편은 지우고 다시 클론하는 방법이였다. ㅋㅋ 차후에 좀더 알아봐야 겠다.
GIT

이제 대~~충 기본 사용법을 익혔으니 한 번 customize 해서 써볼까 하는 생각에 건들이게 된
git config 명령어. 여기에는 다양한 설정들이 있으니 아래의 커맨드를 입력하여 메뉴얼을 쭈욱 보자.
                   $ man git-config

그중에서 역시나 눈에 들어오는 것은 색깔 바꾸기와 alias 설정 가능한 점들...등등 맘에 든다. ㅋㅋ

우리가 대부분 config 를 사용할때

                   $ git config [설정항목] [설정값]

를 사용하는데, 이렇게 하는 경우 현재 접속해 있을 동안만 적용이 된다. 이것을 자기 계정내에 저장해서 그 값을 계속 이용하고 싶은경우는 config 다음에 --global 을 붙여주면 된다.

                   $ git config --global [설정항목] [설정값]

이렇게 global로 한 경우 자기 계정 밑에 .gitconfig 라는 파일에 저장하게 된다. 물론 이 파일을 직접 수정하여도 환경설정을 할 수 있다. ( 파일을 직접 수정하는 방법을 추천한다. ) 

아래는 .gitconfig 파일이다. 

잘 보면 뭘 의미하는지 알수 있을 것이다. 

좀더 자세한 설명은 메뉴얼을 참조하거나 덧글로 질문하기 바란다.

[user]
	 name = My Name
	 email = my@email.com
[color]
	 branch = auto
	 diff = auto
	 status = auto
[color "branch"]
	 current = yellow reverse
	 local = yellow
	 remote = green
[color "diff"]
	 meta = yellow bold
	 frag = magenta bold
	 old = red bold
	 new = green bold
[color "status"]
	 added = yellow
	 changed = green
	 untracked = cyan
[alias]
	 st = status
	 ci = commit -a
	 co = checkout


git access 권한설정이 참으로 애매한 시점에서 좋은 프로그램이 나와서 소개해본다.

잘 찾아보질 않아서 그런지는 모르겠지만 일단 GIT 자체만으로는 repository 주소만 안다면
바로 가져올 수 있는것 같다. (물론 push는 안된다) 게다가 repository를 관리하려면 꽤나 귀찮은 작업들이 수반되는데(참고 : GIT 관련 이전 글을 읽어보면 간단한 관리용 shall이 있다)  이런것들을 간편하게 관리해주는(마치 계정 관리하듯이) 프로그램이 있다니 참으로 놀라운 일이다.

자세히 읽어보지는 않았지만 꽤나 신선한 프로그램이니 자기 계정에서 public project 나 private project들을 쉽게 관리하고자 한다면 아래의 문서를 참조해서 설정해보기 바란다.

GIT
<Notice>
Modification or re-submission the post with this document is allowd after you let me know about it. Questions or suggestion is welcome. You can contact me at dualistmage@nate.com 

Simple GIT Usage

2008-11-24

Dohyun Yun

 

1.    Get the latest repository from server

$ git pull                                  OR                                  $ git fetch
                                                                                       $ git merge origin


p.s pull is the operation of fetch and merge. But pull merge new contents directly to your repository. When some crash occurs while merging, git could not be recovered. Fetch gets new files to the origin branch which is separated to your master branch. I recommend using fetch and merging.

2.    Do your own work. If you want to remove or move the files or directories which are registered to the git, you must use “git rm” and “git mv” command. If you use “rm” or “mv” instead of those, they are not really removed or moved from repository.

$ git rm [filename]                  OR                                  $ git rm –r [directoryName]
$ git mv [filename]                 OR                                  $ git mv [directoryName]

3.    Get the change list and look at the lists which is in the “Changed but not updated” and “Untracked files”.

$ git status


4.    Add some files recursively. If you want to add whole directory, you can use directory name instead of filename. Do not use “ git add .” if you don’t know exactly all the changed files.  It will add all the changed files of your repository. Recommend to add each file what you work on respectively.

$ git add [filename]                OR                                  $ git add [directoryName]

5.    Commit recent work to register to the repository. Do not use –a option. It commits all the changed files by force.

$ git commit –m “Message What you want to tell”

6.    Push commit to the git. If you reject to use push command, please use 1. Command (pull or fetch & merge) to update your repository.

$ git push

 


=========================::: 당부의 한마디 :::============================
열심히 테스트하고 정리한 자료입니다. 서로 좋은 자료를 공유하고자 복사
방지를 걸어놓지 않았으니  마음껏  가져가셔도  좋습니다만,   짧은 덧글
한마디와 인용시 출처를  밝혀주셨으면  합니다.    내용 수정은 허락하지
않겠습니다.  반드시  댓글이나  이메일을 통하여 수정하고자 하는 부분을
알려주셨으면 좋겠습니다.
=======================================================================


Log

-------------------------------------------------------------------------

2010.02.22 git init-db 에 --bare 설명 추가



Introduction

-------------------------------------------------------------------------
프로그램 소스에 대한 Version 관리 툴로서, CVS와 비슷한 종류이다.
GIT는 강력한 기능들과 효율적인 자원활용성을 자랑한다.



Installation
-------------------------------------------------------------------------




설치는 위의 문서를 참조하도록 하고
문서에 나와있지 않은 주의사항이나 팁을 적고자 한다.

< Stage 1 > Create Template Repository

우선 Repository를 생성하기 전에 기본이 되는 Template Repository를 만든다. 이것을 생성하는 이유는 외부에서 Repository의 파일을 clone 하기 위해서는 적어도 하나의 파일과 그에 따른 commit이 한개 있어야 하기 때문이다. 이 폴더는 나중에 두고두고 쓸 것이므로 GIT의 프로젝트폴더가 담길 곳에 같이 넣어둔다. 우선 지금은 /git/를 모든 Repository의 루트로 가정한다.

:::::::::::::::::::::::::::::::::::::::::::::::::: [ 명령어 ]
        cd /git
        mkdir template            // Template Repository 생성
        git-init-db               // 초기화
        touch dummy               // 더미 파일 생성
        git add dummy
        git commit -m "Initialization"       // Add & Commit
        mv .git /git/template.git
        cd ..
        rm -rf /git/template
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



< Stage 2 > Create Project Repository with template one

이제 본격적으로 Project Repository를 생성해보자. <Stage 1>에서 한번 생성한 Template Repository는 Stage 2에서 Project Repository 를 생성할 때 계속 이용할 것이다. 앞으로 프로젝트 이름은 git_usage_project로, 이 폴더에 업로드 할 수 있는 group id 는 git_usage_team 으로 가정하겠다. 각 유저별 그룹설정에 대해서는 아래의 참고를 확인하기 바란다.

:::::::::::::::::::::::::::::::::::::::::::::::::: [ 명령어 ]
        cd /git
        GIT_DIR=git_usage_project.git
        git --bare init-db --template=/git/template.git --shared=group
        chown -R root:git_usage_team git_usage_project.git
        chmod -R 770 git_usage_project.git
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

맨 마지막 라인은 해당 그룹과 생성한 user에게만 소스를 공개하겠다는 말이다. 만일 open source 로 운영할 것이면 777로, 자기만 하려면 700 을 사용하라.

git init-db 명령어에서 --bare는 repository 를 생성할때 bare형으로 만든다는 것을 선언한다는 것이고 --template 인자는 template 로 사용할 git repository 경로를 지정하는 것이며, --shared=group은 git의 내부 동작에 따른 생성파일들의 그룹 권한을 project.git 폴더의 그룹에게 준다는 의미이다. 만약 이를 지정해 주지 않으면 생성된 파일들은 -r--r--r--로 생성되어 다음 전송시 permission denied 오류를 발생시칼 것이다. 옵션을 적용한 후의 속성은 -rw-rw-r-- 가 되어 그룹의 전송시 아무런 문제를 발생시키지 않는다.

앞으로 자주 사용할 명령어이므로 셸로 만들어 놓으면 간편하다. 아래는 내가 git 프로젝트를 생성할때 쓰는 셸 프로그램 이다. (그룹이름이 잘못된경우 발생하는 에러는 못잡으니 알아서 잘 쓰시길 ㅋ)

====================================================================================

git_create 파일 보기

====================================================================================





<참고0> 프로젝트명.git 를 만드는 이유 : 실제로 git에서는 파일형태로 관리하는게 아니라 object별로 모든 파일 및 디렉토리를 관리한다. 이 모든 정보는 .git폴더에 있는데, 만약 서버에서 .git 폴더 이외에 파일들을 따로 또 관리하게 되는경우 파일을 2중으로 보관하는 비효율성과 더불어 .git에서 수정한 내용들을 파일시스템으로 적용시켜야 하는 불필요한 동작을 수반하게 된다. 서버에서는 프로젝트명.git 만으로 관리하는 것을 추천한다. 이것을 bare repository 라고 한다. (option : git --bare ...)


<참고1> 여러개의 프로젝트를 서로 다른 사람이 관리하는 경우 대부분 git 나 git_root 디렉토리를 만들고 그 하위 디렉토리로서 프로젝트 Repository를 생성하게 되는데, 기억해야할 점은 이 git라는 폴더는 소유자와 그룹명이 모두 root 여야한다. (아래의 명령어로 적용시킬 수 있다.)

chown root /git  
chgrp root /git

왜냐하면 하위로 생성한 프로젝트가 /git/ 의 소유자나 소유 그룹명과 다를경우 프로젝트 Repository 에 대한 권한이 있음에도 불구하고 파일 I/O 과정에서 Permission Denied 문제가 발생할 수 있기 때문이다.


<참고2> 폴더에 여러 그룹 권한 주기 : 만약 root 그룹과 group1에게 test폴더 소유권한을 주고싶으면 아래와 같이 주면 된다.

chown -R root:group1 test

<참고3> 한 유저를 여러 그룹에 속하게 하기.

Unix 계열 운영체제는 아래의 두 파일을 통하여 유저와 그룹정보를 얻어온다.

/etc/passwd : 유저 정보
/etc/group  : 그룹 정보

따라서 한 유저를 여러그룹에 속하게 하려면 /etc/group 을 열어서 수정하면 된다.

(예) ydh 라는 유저를 group1, group2, group3 에 속하게 하고 싶으면 /etc/group 을 열어서 각각을 추가시키면 된다.

::::::::::::::::::::::::::::::::::::::::::[ /etc/group ]:::::
          ....
          group1:x:530:user1, user2, ydh
          ....
          group2:x:533:user1, ydh
          ....
          group3:x:540:user2, ydh
          ...
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


Tips
-------------------------------------------------------------------------
1. GIT Repository에 등록한 파일을 삭제하거나 옮기는 경우 'rm' 'mv' 대신 'git-rm' 'git-mv'를 사용한다.

     git commit 을 통해 등록한 파일들은 GIT내에서 그 구조도 저장되어 있다. 만약 rm 이나 mv를 이용하여 기존의 등록한 파일들을 옮기고 add 및 commit 을 하는경우 GIT는 파일이 삭제되거나 옮겨진 줄 모른다. 이렇게 되는경우 다음번에 pull을 하는경우 지워진 디렉토리나 파일이 다시 되살아나고, mv를 한경우에는 옮기기 전 디렉토리나 파일이 다시 생성된다. 따라서 등록되지 않은 것들을 제외한 모든 파일이나 디렉토리를 지우고 옮기고자 한다면 git-rm 과 git-mv를 통하여 하면 된다. (이를 인지하지 못한다면 꽤나 귀찮은 일들이 많아질 것이다. 하루바삐 몸으로 익히자.)

2. branch로 분기하여 작업을 하자.

     자잘한 작업후에 commit 을 하게 되면 굉장히 지저분한 log를 보게 될 것이다. 따라서 일정 단위의 작업(예를 들면, 하나의 cpp파일의 일부를 만든다던가.. 암튼 조그마한 작업) 들은 branch 를 나누어서 한다. branch 생성 및 전환은 다음과 같다. 그리고 현재 속한 branch 가 어디있는지 확인하는 것은 git branch를 입력하면 브랜치명 앞에 붙은 별로 알수 있다.

    $ git branch test                   (test라는 branch 를 만들었다)

    $ git branch                        (현재 master라는 branch에 있음을 알 수있다)
    * master
      test

    $ git checkout test                 (branch를 change 한다)

    $ git branch                        (현재 branch 는 test로 바뀌어 있다)
      master
    * test

주의할 점은 branch switch를 할 경우, commit된 파일리스트를 가지고 switch가 이루어지기 때문에 switch 전에 commit을 하지않은 파일들은 switch후에 그대로 남아있게 된다. 따라서 반드시 아직 등록되어 있지 않은 파일이 있는지 확인한 후 아무 이상이 없을때 이동을 해야한다. (git status 를 이용하면 된다. 참고로 git branch -a 하면 숨겨저있는 branch인 origin/HEAD 와 origin/master를 볼수 있는데, origin은 git clone으로 repository 내용을 받아온 경우 이곳에 담기게 된다. )

     branch작업이 끝나고 본래의 master 와 통합하기 위해 merge 단계를 수행하게 되는데, 이때 무턱대고 merge를 하게 된다면 파일간 conflict가 발생하게 된다. 그래서 차이점이 어떤건지 아래의 명령어를 통해 하나하나 확인한 다음에 수정해서 넣도록 한다.

     $ git log --stat test..master       (test 와 master의 차이가 있는 파일 목록만 본다.)

     $ got log -p test..master           (test 와 master의 차이가 있는 파일의 내용들을 본다.)

    


Error Recovering Tip
-------------------------------------------------------------------------

<< Error 1 >> git push 명령후 다음과 같은 에러 메시지를 받은 경우

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

   1. 원인 : 현재 작업하고 있는 Repository가 서버에 있는 Repository보다 오래된 내용이다. Push 를 하게 되면 서버에 있는 최신 내용은 날라가고 현재 작업한 내용만 적용이 되는 문제가 발생할 수 있기 때문에 에러가 발생하게 된것이다.

   2. 해결방법

       1) 강제 삽입하기 (추천하지 않음) : git push --force
       2) 최신내용을 Local에 적용한 후 올리기 : git pull 명령을 이용하면 기존 작업한
          내용에 최신 내용을 덧붙이게 된다. 만약 덧붙이는 과정에서 conflict가 발생한
          경우, 그 안에 어느 부분이 conflict가 발생했는지가 나오기 때문에 잘 확인해
          서 소스를 수정한 후 다시 올리면 된다.


<< Error 2 >> git push 명령 후 다음과 같은 에러가 발생한 경우

error: Object 5ae9947eadfd651788caa9b3b6757d375eebad84 is a commit, not a blob

error: pack-objects died with strange error

unpack eof before pack header was fully read

ng refs/heads/master n/a (unpacker error)

error: failed to push to 'yourid@projectAddress:/project.git'

   1. 원인 : 파일 삭제시 rm 만을 이용했다. 그리고 특정 GIT 명령어를 잘못 사용하여 index가 꼬였다. push 를 할때에는 로컬의 정보를 패키징 해서 서버로 보내게 되는데, 패키징 작업중에 꼬인 index를 발견한 경우 패키징을 멈추고 에러를 발생시킨다. (index 와 tree 에는 남아있기 때문에 실제로 pull을 다시 해보면 삭제된 파일이 생성된다)


   2. 해결방법 :

      작업한 파일들을 다른곳에 치워두고 local repository를 싸그리 날린다.
      git clone을 이용하여 서버의 내용을 복사한 후에 작업한 파일들을 넣고
      commit 하면 완료.

   (p.s) GIT 프로젝트 내의 모든 삭제작업(파일이든 폴더이든)은
           git rm 파일명            이나
           git rm -r 디렉토리       를 사용한다.


<< Error 3 >> 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
     name which branch you want to merge on the command line and
     try again (e.g. 'git pull <repository> <refspec>').
     See git-pull(1) for details on the refspec.

     If you often merge with the same branch, you may want to
     configure the following variables in your configuration
     file:

         branch.master.remote = <nickname>
         branch.master.merge = <remote-ref>
         remote.<nickname>.url = <url>
         remote.<nickname>.fetch = <refspec>

     See git-config(1) for details.



References
-------------------------------------------------------------------------
GIT Official site : http://git.or.cz/

SUBversion : http://www.pyrasis.com/main/Subversion-HOWTO (GIT 와 비슷한 버전관리툴)


  1. Favicon of http://finsternis.tistory.com BlogIcon leanu 2008.09.04 14:11 신고

    정리 할 것 :

    fetch 시 origin에 복사됨

    merge 하려면 git merge origin 하면 됨.

  2. Favicon of http://finsternis.tistory.com BlogIcon leanu 2008.11.13 11:52 신고

    $ git pull
    대신

    $ git fetch
    $ git merge origin
    추천한다

    그리고 fetch 후 받은 파일들과 현재 작업중인 파일을 비교하고 싶으면

    $ git log --stat master..origin

  3. Kyoung-hun, Jeon 2008.12.12 13:29 신고

    Very Very Special Thx....
    a few good man...

  4. Favicon of http://finsternis.tistory.com BlogIcon leanu 2009.02.11 14:32 신고

    다른 녀석 계정의 것을 master로 가져오기

    git pull id@address:/directory/repositoryname master

  5. Favicon of http://finsternis.tistory.com BlogIcon leanu 2009.05.13 11:23 신고

    repository 에 등록된 녀석들만 add 하고 싶으면

    git add -u

  6. 아리수 2009.09.16 20:31 신고

    좋은 자료 감사합니다.

  7. Daniel 2010.06.28 21:00 신고

    잘 정리하셨네요 감사합니다~

  8. BlogIcon 이상철 2011.03.25 13:05 신고

    좋은 정보 감사합니다. 담아 갑니다.

  9. 간닥스 2011.05.24 10:34 신고

    와 궁금한게 여기 있었네요 정말 감사합니다 ^^ 담아 갈께요...

+ Recent posts

티스토리 툴바