Adjust `makeover` to handle newer AsciiDoc output.
[gitmagic.git] / ko / grandmaster.txt
blobf8cc00e6c1664bf4d1007145f5aa293bc3b51434
1 == Git 마스터링 ==
3 지금까지 배운것만으로도 당신은 *git help* 페이지를 자유롭게 돌아다니며 거의 모든 것을
4 이해할 수 있을 것입니다. 그러나 어떠한 문제를 풀기위해 어느 한 가지의 알맞는 명령어를 찾는 것은 아직 성가실 수 있습니다. 그런 문제에 대해 제가 도와줄 수 있을 것 같습니다: 아래는 제가 Git을 사용하며 유용하게 썼던 몇가지 팁들입니다.
6 === 소스 배포 ===
8 제 프로젝트에서 Git은 제가 저장 및 공개하고 싶은 파일들을 정확히 추적하여 줍니다.
10  $ git archive --format=tar --prefix=proj-1.2.3/ HEAD
12 === 바뀐 것은 꼭 commit ===
14 Git에게 무엇을 추가, 삭제 및 파일이름을 바꾸었는지 일일히 알려주는 것은 귀찮은 짓일지도 모릅니다. 
15 대신에 당신은 다음 명령어를 쓸 수있습니다:
17  $ git add .
18  $ git add -u
20 Git은 현재 작업중인 디렉토리에 있는 파일들을 자동으로 살피며 자세한 사항들을 기록하여 줍니다. 위의 두번째 
21 명령어 (git add -u) 대신에 'git commit -a'를 사용하여 그 명령어와 commit을 동시에 
22 해낼 수 있습니다. *git help ignore*를 참고하여 특별히 지정된 파일을 무시하는 방법을 
23 알아보십시오.
25 위의 모든 것을 한 줄의 명령어로 실행할 수 있습니다.
27  $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove
29 *-z*와 *-0* 옵션은 파일이름이 이상한 문자를 포함하고 있을 때 생길 수 있는 여러가지 문제점들을
30 처리하여 줍니다. 이 옵션들은 무시된 파일들을 포함하여줌으로써 '-x'아니면 '-X'을 같이 써주어야 할
31 것입니다.
33 === 내 commit이 너무 클 경우? ===
35 Commit을 한지 시간이 좀 많이 지난 상황입니까? 코딩을 너무 열심히 한 나머지 버전컨트롤하는 것을
36 깜빡했나요? 프로젝트에 여러가지 연관성없는 수정을 한 상태입니까?
38 걱정하지말고:
40  $ git add -p
42 당신이 만든 모든 수정작업에 대하여 Git은 어떠한 것들이 바뀌였는지 코드로 보여주며 당신에게 
43 다음에 실행할 commit에 부분적인 코드가 포함될 사항인지 물어볼 것입니다. "y"와 "n"를 이용하여 
44 대답할 수 있습니다. 물론 이 대답을 당장하지 않아도 됩니다; "?"로 좀 더 알아보십시요.
46 모든 수정작업이 마음에 든다면:
48  $ git commit
50 위의 간단한 명령어를 사용하여 직접 선택한 작업만을 commit합니다. 이 상황에선 반드시 *-a*옵션을 생략하시길 바랍니다.
51 그렇지 않으면 Git은 모든 수정작업을 commit할 것입니다.
53 만약에 여러군데 다른 디렉토리에 많은 수정작업을 해놓았다면 어떻게 할까요? 수정된 사항을 하나씩
54 검토하는 작업은 정말 귀찮은 짓입니다. 이럴땐 *git add -i*를 사용합니다. 몇 번의 타이핑만으로도
55 특정 파일의 수정작업을 검토할 수 있게됩니다. 또는 *git commit \--interactive*를 사용하여 작업 중
56 자동으로 작업 후 commit하는 방법도 있을 수 있습니다.
58 === 인덱스: Git의 스테이징 구역 ===
60 여태까지 Git의 중요한 기능인 'index'를 피해왔지만 이제 한 번 살펴본 시간이 온 것 같습니다.
61 인덱스는 임시적인 스테이징 구역 (번역주:책갈피처럼)으로 보면 됩니다. Git은 당신의 프로젝트와 프로젝트의
62 기록 사이에 데이터를 직접 옮기는 경우는 드뭅니다. 대신, Git은 인덱스에 파일을 쓰며 그리고 그 파일들을 마지막 목표지점에 카피하여 줍니다.
64 예를 들어 *commit -a*는 원래 두단계 과정을 거치는 하나의 명령어입니다. 첫번째 단계에서는 현 작업상황의
65 스냅샷을 찍어 모든 파일들을 인덱스하는 과정을 거칩니다. 두번째 단계에서는 방금 찍은 스냅샷을 영구적으로
66 보관하게 됩니다. *-a* 옵션을 쓰지않고 commit을 하는 것은 이 두번째 과정만 실행하는 일입니다. 그렇기에
67 *git add* 같은 명령어를 쓴 후에 commit을 하는 것이 당연한 이야기가 되겠지요.
69 대체적으로 인덱스에 관한 컨셉트는 무시하고 파일기록에서 직접적으로 쓰기와 읽기가 실행된다는 개념으로 이해하면 편합니다. 이런 경우에는 우린 인덱스를 제어하는 것 처럼
70 좀 더 세부한 제어를 하기 원할것입니다. 부분적인 스냅샷을 찍은 후 영구적으로 이 '부분스냅샷'을 보존하는 것이죠.
72 === 머리(HEAD)를 잃어버리지 않기 ===
74 HEAD 태그는 문서작업시 보이는 커서처럼 마지막 commit 포인트를 가르키는 포인터 역할을 합니다. Commit을 실행할 때마다 물론 HEAD도 같이 앞으로 움직이겠지요. 어떤 Git 명령어들은 수동으로 HEAD를
75 움직일 수 있게 해줍니다. 예를 들면:
77  $ git reset HEAD~3
79 위 명령어를 사용한다면 HEAD를 commit을 3번 하기 전으로 옮깁니다. 이 후 모든 Git 명령어는 가지고 있던 파일은 현재상태로 그대로 두되 
80 그 3번의 commit을 하지 않은 것으로 이해하죠. 
82 그러나 어떻게 해야 다시 가장 최근으로 돌아갈 수 있을까요? 예전에 했던 commit들은 미래에 대해서 아무것도 모를텐데 말이지요.
84 원래의 HEAD의 SHA1을 가지고 있다면:
86  $ git reset 1b6d
88 그러나 이 것을 어디에도 써두지 않았었더라도 걱정하지 마십시오: Git은 이런 경우를 대비해서 원래의 HEAD를 ORIG_HEAD로 어딘가에는 저장하여 둡니다. 그러고는 다음명령어를 사용하여
89 미래로 안전하게 돌아올 수 있지요:
91  $ git reset ORIG_HEAD
93 === HEAD-헌팅 ===
95 ORIG_HEAD로 돌아가는 것만으로는 충분하지 않을지도 모릅니다. 당신은 방금 엄청나게 큰 실수를 발견하였고 아주 오래전에 했던 commit으로 돌아가야 할지 모릅니다.
97 기본적으로 Git은 branch를 수동으로 삭제하였더라도 2주의 시간동안 commit을 무조건 저장하여 둡니다.
98 문제는 돌아가고 싶은 commit의 hash를 찾는 일입니다. '.git/objects'의 모든 hash 값을
99 조회하여 얻어걸릴 때까지 해보는 방법이 있긴합니다만, 여기 좀 더 쉬운 방법이 있습니다.
101 Git은 모든 commit의 hash를 '.git/logs'에 저장해 둡니다. 하위 디렉토리 'refs'은 모든 branch의 활동기록을 저장하여두고 동시에 'HEAD'파일은 모든 hash 값을 저장하고 있습니다.
102 후자는 실수로 마구 건너 뛴 commit들의 hash도 찾을 수 있게 해줍니다.
104 reflog 명령어는 당신이 사용하기 쉬운 유저인터페이스로 log파일들을 표현하여 줍니다. 다음 명령어를 사용하여 보십시오.
106   $ git reflog
108 hash를 reflog으로부터 자르고 붙여넣기 보다는:
110  $ git checkout "@{10 minutes ago}" 
112 아니면 5번 째 전에 방문했던 commit으로 돌아갈수도 있습니다:
114  $ git checkout "@{5}"
116 좀 더 많은 정보는 *git help rev-parse*의 "재편집 구체화하기" 섹션을 참고하십시오.
118 아까 언급한 commit의 2주살이 생명을 수동으로 연장하여 줄 수 있습니다. 예를 들어:
120   $ git config gc.pruneexpire "30 days"
122 위 명령어는 30일이 지난 후에 지워진 commit들 역시 영구적으로 삭제된다는 의미입니다. 그러고는
123 *git gc*가 실행되지요.
125 *git gc*가 자동실행되는 것을 꺼줄 수도 있습니다:
127   $ git config gc.auto 0
129 이 경우에는 *git gc*를 수동적으로 실행시켜 commit들을 삭제할 수 있지요.
131 === Git을 좀 더 발전시키는 방법 ===
133 진정한 UNIX와 같이 Git의 디자인은 다른 프로그램들의 GUI, 웹 인터페이스와 같은 하위파트들과 호환이 됩니다. 어느 Git 명령어들은 유명인사의 어깨위에 서있는 것처럼
134 Git 그 자체가 스크립팅 언어로 사용될 수도 있습니다. 조금만 시간을 투자하면 Git은 당신의 기호에 더 알맞게 바꿀수 있습니다.
136 한 가지 트릭을 소개하자면 자주 사용할것 같은 명령어들을 짧게 만들어줄 수 있는 방법이 있습니다:
138   $ git config --global alias.co checkout
139   $ git config --global --get-regexp alias  # 현재 설정한 명령어들의 '가명'을 표기해줍니다.
140   alias.co checkout
141   $ git co foo                              # 'git checkout foo'와 같은 것입니다.
143 또 다른 트릭은 현재 작업중인 branch의 이름을 작업표시창에 표시하여주는 명령어도 있습니다.
145   $ git symbolic-ref HEAD
147 위 명령어는 현재 작업중인 branch 이름을 표기하여 줍니다. 실제로는 "refs/heads/"를 없애고
148 잠재적으로 일어날 수 있는 에러들을 무시하는걸 추천드립니다:
150   $ git symbolic-ref HEAD 2> /dev/null | cut -b 12-
152 +contrib+ 하위 디렉토리는 유용한 Git 툴들이 저장되어있는 장소이기도 합니다.
153 시간이 지나면 이곳에 있는 툴들은 공식적으로 인정받아 고유명령어가 생기기도 하겠지요. Debian과 Ubuntu에서는
154 이 디렉토리는 +/usr/share/doc/git-core/contrib+에 위치하고 있습니다.
156 앞으로 +workdir/git-new-workdir+디렉토리에 방문할 일도 많을 것입니다. 시스템링크 기술을 통해서 이 스크립트는 원래의 repository와 작업기록을 공유하는 
157 새로운 작업 디렉토리를 생성하여 줍니다:
159   $ git-new-workdir an/existing/repo new/directory
161 새롭게 생성된 디렉토리는 클론으로 봐도 무방하며 일반클론들과의 한가지 차이점은 어느 한 곳에서 작업을 하던 두 개의 디렉토리는 앞으로 계속 싱크를 진행하며 같은 기록을 가지게 된다는 것입니다.
162 즉, 병합, 밀어넣기, 당겨오기를 해줄 필요가 없어지는 것이지요.
164 === 용감한 스턴트 ===
166 Git은 요즘 유저들이 데이터를 쉽게 지우지 못하도록 하고 있습니다.
167 그러나 몇가지의 상용적인 명령어를 통해서 이런 Git만의 방화벽 쯤은 쉽게 뚫어버릴 수 있지요.
169 *Checkout*: Commit하지 않은 작업들은 checkout을 할 수없습니다. 방금작업한 모든 것들을 없던 일로하고 그래도 굳이 commit을 진행하고 싶다면:
171   $ git checkout -f HEAD^
173 반면에 checkout을 할 위치를 수동으로 설정하여 준다면 Git의 방화벽은 처음부터 작동하지 않을 것입니다. 설정해준 위치는 조용히 덮어씌우게 됩니다.
174 그러니, 이런 방식으로 checkout을 할 때에는 주의 하십시오.
176 *Reset*: 리셋은 commit되지 않은 작업이 있으면 실행되지 않을 것입니다. 그래도 강제로 하고싶다면:
178   $ git reset --hard 1b6d
180 *Branch*: 방금한 작업을 잃어버릴 것같으면 Git은 branch가 지워지지 않게합니다. 그래도 하고싶다면:
182   $ git branch -D dead_branch  # -d 대신 -D
184 비슷한 방식으로, commit을 안한 작업이 있어서 move명령어를 통해서 덮어씌우기가 안될경우에는:
186   $ git branch -M source target  # -m 대신 -M
188 체크아웃과 리셋과는 다르게 위의 두 명령어는 데이터를 직접 삭제하진 않습니다. 모든 변경기록은
189 .git 하위 디렉토리에 남게되고 필요한 hash는 '.git/logs'에서
190 찾을 수 있습니다 (위의 "HEAD-헌팅" 섹션 참고). 기본설정상, 이 기록들은
191 2주 동안은 삭제되지 않습니다.
193 *Clean*: 몇 git 명령어들은 추적되지 않은 파일들을 망쳐놓을까봐 실행이 안되는 경우가 종종 있습니다.
194 만약에 그 파일들이 삭제되도 된다는 확신이 선다면, 가차없이 다음 명령어를 사용하여
195 삭제하십시오:
197   $ git clean -f -d
199 이 후에는 위 모든 명령어들은 다시 잘 실행되기 시작할 것입니다!
201 === 원치않는 commit들을 방지하기 ===
203 바보같은 실수들은 내 repository를 망쳐놓곤 합니다. 그 중에서도 제일 무서운 것은 *git add*를 쓰지 않아서
204 작업해놓은 파일들을 잃어버리는 것이지요. 그나마 코드 뒤에 빈 공간을 마구 넣어놓는다던지
205 병합에서 일어날 수 있는 문제들을 해결해 놓지않는 것은 애교로 보입니다: 별로 문제가 되는 것들은 아니지만
206 남들이 볼 수 있는 repository에서는 보여주기 싫습니다.
208 _hook_ 을 사용하는 것과 같이 제가 바보같은 짓을 할 때마다 경고를 해주는 기능이 있다면 얼마나 좋을까요:
210  $ cd .git/hooks
211  $ cp pre-commit.sample pre-commit  # 예전 Git 버젼에서는: chmod +x pre-commit
213 이제는 아까 설명했던 애교스러운 실수들이 발견될 때 Git은 commit을 도중에 그만 둘것입니다.
215 이 가이드에서는 *pre-commit* 앞에 밑에 써놓은 코드를 넣음으로써 혹시 있을지도 모르는
216 바보같은 짓을 방지하였습니다.
218  if git ls-files -o | grep '\.txt$'; then
219    echo FAIL! Untracked .txt files.
220    exit 1
221  fi
223 많은 git 작업들은 hook과 상호작용합니다; *git help hooks*를 참조하십시오. 우리는 "HTTP를 통한 Git"을을 설명할때
224 *post-update* hook을 활성화시켰습니다. HEAD가 옮겨질때마다 같이 실행되지요. Git over HTTP 예제에서는
225 post-update 스크립트가 통신에 필요한 Git을 업데이트 했었습니다.